asm rip 相对寻址
asm rip-relative addressing
我正在做某种 CTF 挑战,我有一个程序可以检查缓冲区,如果其中有系统调用、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 [=10=]x3b,%al
37: 0f 05 syscall
以及重写系统调用的两条额外指令:
...
37: b1 05 mov [=11=]x5,%cl
39: 88 0d 01 00 00 00 mov %cl,0x1(%rip)
3f: 0f 05 syscall
但是,我看到 39 编码后有一些尾随零,而 23 例如相似但位置是相对于 rdi 而不是 rip,不是。
所以我的问题是,这样看起来合适吗?如果是这样,为什么在 rip 的情况下会有尾随零。它是否是一些相对于 rip 的寻址特定的东西,例如 4 个字节必须跟在后面?
Is it some rip-relative addressing specific thing that for example 4 bytes must follow?
是的。如果您查看 指令集参考,第 2.2.1.6 RIP 相对寻址 部分,您会看到唯一的选项是 RIP + disp32
,表示 32 位位移。如果您需要避免零字节,则必须以不同的方式进行。一种可能的解决方法是执行以下操作:
lea -1(%rip), %rax # -1 is needed to avoid zero bytes
movb , XX(%rax) # with appropriate value of `XX`
我正在做某种 CTF 挑战,我有一个程序可以检查缓冲区,如果其中有系统调用、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 [=10=]x3b,%al
37: 0f 05 syscall
以及重写系统调用的两条额外指令:
...
37: b1 05 mov [=11=]x5,%cl
39: 88 0d 01 00 00 00 mov %cl,0x1(%rip)
3f: 0f 05 syscall
但是,我看到 39 编码后有一些尾随零,而 23 例如相似但位置是相对于 rdi 而不是 rip,不是。
所以我的问题是,这样看起来合适吗?如果是这样,为什么在 rip 的情况下会有尾随零。它是否是一些相对于 rip 的寻址特定的东西,例如 4 个字节必须跟在后面?
Is it some rip-relative addressing specific thing that for example 4 bytes must follow?
是的。如果您查看 指令集参考,第 2.2.1.6 RIP 相对寻址 部分,您会看到唯一的选项是 RIP + disp32
,表示 32 位位移。如果您需要避免零字节,则必须以不同的方式进行。一种可能的解决方法是执行以下操作:
lea -1(%rip), %rax # -1 is needed to avoid zero bytes
movb , XX(%rax) # with appropriate value of `XX`