Assembly 如何绕过调用指令挂起程序?
我几乎可以肯定它是挂起的,因为外壳代码应该打印一个字符串,而程序只是挂起 我将自己应用程序中的返回地址改写为自己的外壳代码。Assembly 如何绕过调用指令挂起程序?,assembly,x86,stack-overflow,Assembly,X86,Stack Overflow,我几乎可以肯定它是挂起的,因为外壳代码应该打印一个字符串,而程序只是挂起 我将自己应用程序中的返回地址改写为自己的外壳代码。jmp 0x7fffffffdbc7是它遇到的第一条指令。 在跳转到0x7FFFFFDBC7后,它调用第一条指令正下方的地址,该指令假定对堆栈进行递减,然后在将控制流设置为0x7FFFFFDBB2(而不是返回地址)之前,推送位于顶部0x7fffffffdbcc的字符串 下面是我实际运行漏洞利用时发生的情况 (gdb) nexti 0x00007fffffffdbc7 in
jmp 0x7fffffffdbc7
是它遇到的第一条指令。
在跳转到0x7FFFFFDBC7后,它调用第一条指令正下方的地址,该指令假定对堆栈进行递减,然后在将控制流设置为0x7FFFFFDBB2(而不是返回地址)之前,推送位于顶部0x7fffffffdbcc的字符串
下面是我实际运行漏洞利用时发生的情况
(gdb) nexti
0x00007fffffffdbc7 in ?? ()
(gdb) nexti
^C
Program received signal SIGINT, Interrupt.
0x00007fffffffdbc1 in ?? ()
程序挂起,我必须手动退出,然后才能将控制转移到完全随机的指令。您需要使用64位系统调用。32位系统调用不支持指向字符串的64位指针。尝试单步执行反汇编(
stepi
)?int 0x80
是32位系统调用。它无法处理不能用32位表示的地址。最后,您只能通过ECX将RCX的下32位部分(完整地址)传递给sys_write,而这不是字符串所在的位置。您需要使用syscall指令并遵循64位Linux系统调用ABI。这里有更多内容:这是在ubuntu上作为一个本机OSA进行测试的。write()
返回rax=-EFAULT,您只将低位字节设置为1
,因此下一个int 0x80
返回-ENOSYS,而不是运行sys\u exit
,创建一个无限循环。您已经在使用调试器,请查看寄存器。(例如,info-reg
,print$eax
,或layout-reg
。请参阅的底部)@MichaelPetch:在Win10上,int 0x80
将出现故障,而不是SIGINT。这是一个无限循环,GBD输出显示来自OP的信号,手动按^C。我也有一段时间对此感到困惑,因为RIP就在int0x80
指令之后。
(gdb) nexti
0x00007fffffffdbc7 in ?? ()
(gdb) nexti
^C
Program received signal SIGINT, Interrupt.
0x00007fffffffdbc1 in ?? ()