有没有一种方法可以在不使用汇编语言的call
后跟pop
的情况下访问指令指针(RIP)中的值?还是有可以做到的机器码操作码?
我一直在搜索,没有明确的结果。
我的问题是机器代码中不能有任何零,否则会收到SIGSEGV错误。这是由于服务器加载代码并从字节字符串执行代码的方式所致。 Near调用到子例程的距离为零,因此不能使用call。
我使用的是64位Linux,并且具有nasm和yasm。
答案 0 :(得分:4)
在x86_64中,标准方法是使用相对RIP寻址,而不是像x86中那样使用CALL
。即使这样,也不建议使用通话/弹出 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中可能并不重要