有没有一种方法可以访问指令指针 (RIP) 中的值,而无需在汇编语言中使用 acall
后跟 a ?pop
还是有可以做到的机器码操作码?
我一直在谷歌搜索没有明确的结果。
我的问题是机器代码中不能有任何零,否则我会收到 SIGSEGV 错误。这是由于服务器加载代码并从一串字节执行它的方式。近距离调用与子程序的距离为零,因此不能选择使用调用。
我在 linux 上,64 位,并且有 nasm 和 yasm。
有没有一种方法可以访问指令指针 (RIP) 中的值,而无需在汇编语言中使用 acall
后跟 a ?pop
还是有可以做到的机器码操作码?
我一直在谷歌搜索没有明确的结果。
我的问题是机器代码中不能有任何零,否则我会收到 SIGSEGV 错误。这是由于服务器加载代码并从一串字节执行它的方式。近距离调用与子程序的距离为零,因此不能选择使用调用。
我在 linux 上,64 位,并且有 nasm 和 yasm。
在 x86_64 中,标准方法是使用 RIP 相对寻址,而不是CALL
在 x86 中。即使那样,call/pop 也不是推荐的方式1
通常,您将使用lea rax, [rip]
RIP 进入 RAX(它实际上被编码为lea rax, [rip + 0]
最后立即数的四个字节)。但是,由于LEA
不取消引用内存地址,您可以将任何常量位移添加到 RIP 并稍后减去
0: 48 8d 05 04 03 02 01 lea rax,[rip+0x1020304]
7: 48 2d 04 03 02 01 sub rax,0x1020304
您可以选择任何不具有零或 0xFF 字节的立即值。如果您想要之后的指令地址lea
(长度为 7 个字节),您可以使用sub rax, 0x01020304 - 7
1推荐的方法是
GetCurrentAddress:
mov eax, [esp]
ret
...
call GetCurrentAddress
mov [currentInstruction], eax
为了避免调用堆栈和返回堆栈缓冲区(RSB)之间的不匹配。但可能它在 shellcode 中并不重要