有没有一种方法可以在不使用 call
后跟 pop
的情况下访问指令指针 (RIP) 中的值?或者是否有可以做到这一点的机器代码操作码?
我一直在谷歌搜索,没有明确的结果。
我的问题是机器代码中不能有任何零,否则我会收到 SIGSEGV 错误。这是由于服务器加载代码并从字节串执行它的方式。近调用在到子例程的距离中为零,因此使用调用不是一种选择。
我在 64 位 linux 上,有 nasm 和 yasm。
最佳答案
在 x86_64 中,标准方法是使用 RIP 相对寻址,而不是像在 x86 中那样使用 CALL
。即使这样,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
GetCurrentAddress:
mov eax, [esp]
ret
...
call GetCurrentAddress
mov [currentInstruction], eax
为了避免调用栈和返回栈缓冲区(RSB)不匹配。但在 shellcode 中可能并不重要
关于assembly - 如何在没有 0x00 或 0xFF 字节的情况下获取 x86_64 中的指令指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52049481/