[英]asm rip-relative addressing
我正在做一些CTF挑战,我有一个程序,如果那里有一个syscall,sysenter或int 80指令,则检查用户输入的缓冲区是否逐字节地传递。
我要做的是编写一个shellcode,将syscall指令的第二个字节修改为有效的。 也就是说,输入的最后两个字节是\\x0f\\x01
,我希望shellcode本身将其覆盖为\\x0f\\x05
(系统调用)。
所以原始shellcode的最后几条指令看起来像这样:
....
21: 31 c0 xor %eax,%eax
23: 88 47 07 mov %al,0x7(%rdi)
26: 48 89 7f 08 mov %rdi,0x8(%rdi)
2a: 48 89 47 10 mov %rax,0x10(%rdi)
2e: 48 8d 77 08 lea 0x8(%rdi),%rsi
32: 48 89 c2 mov %rax,%rdx
35: b0 3b mov $0x3b,%al
37: 0f 05 syscall
并使用两个额外的指令来重写系统调用:
...
37: b1 05 mov $0x5,%cl
39: 88 0d 01 00 00 00 mov %cl,0x1(%rip)
3f: 0f 05 syscall
但是,我看到39用一些尾随零编码,而23例如相似但位置相对于rdi而不是rip,则不是。
所以我的问题是,这看起来不错吗? 如果是这样的话,为什么rip会出现尾随零。 是否有一些rip-relative寻址特定的东西,例如4个字节必须遵循?
是否有一些rip-relative寻址特定的东西,例如4个字节必须遵循?
是。 如果查看指令集参考,2.2.1.6 RIP相对寻址,您将看到唯一的选项是RIP + disp32
意味着32位位移。 如果您需要避免零字节,则必须采用不同的方式。 可能的解决方法是执行以下操作:
lea -1(%rip), %rax # -1 is needed to avoid zero bytes
movb $5, XX(%rax) # with appropriate value of `XX`
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.