You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何绕过导致程序挂起的call指令?Shellcode执行异常问询

绕过导致程序挂起的Call指令方案

看来你在自定义shellcode的栈溢出利用中碰到了棘手的问题——那个call指令直接导致程序停滞,打断了原本的字符串打印流程。结合你描述的执行链(jmp 0x7fffffffdbc7 → call栈递减地址 → 压字符串 → 跳转至0x7fffffffdbb2),我整理了几个可行的绕过思路:

1. 直接跳过Call指令

最简单的方法就是让程序完全绕过这个call。首先确定这个call指令的字节长度(x86架构下,普通的相对call通常是5字节,短调用是2字节,取决于指令编码),然后修改初始的jmp目标,让它直接跳转到call指令之后的地址。

举个例子:如果call指令从0x7fffffffdbc7开始,占5字节,那么跳过它的目标地址就是0x7fffffffdbc7 + 5。把你的跳转指令改成jmp 0x7fffffffdbcc(假设计算后是这个地址),就能直接跳过call,继续执行后面的压栈和跳转逻辑。

2. 将Call替换为NOP空操作

如果你的shellcode字节是完全可控的,你可以把call指令的所有字节替换成NOP(字节码0x90)。NOP是无操作指令,执行时只会占用CPU周期但不做任何实际操作,这样程序就能平稳地跳过原本的call,继续执行后续的字符串处理逻辑。

注意:一定要准确替换call的全部字节,比如5字节的call就需要替换5个0x90,避免破坏后续指令的编码结构。

3. 修正Call的目标地址

如果这个call原本的意图是执行栈递减操作,但目标地址有问题(比如指向了栈上的无效代码、或者会导致阻塞的系统调用),你可以自己在shellcode里添加一段正确的栈调整代码,然后把call的目标指向这段代码。

比如你可以在shellcode里插入:

sub rsp, 0x20  ; 根据你的需求调整栈大小,比如减去32字节
ret            ; 返回到call之后的指令

然后把原来的call目标改成这段代码的地址,这样既完成了栈递减的需求,又不会导致程序挂起。

4. 重构Shellcode执行流程

如果前面的方法都不太方便,你可以直接重构shellcode的逻辑,绕过整个包含call的代码块。比如直接构造一段shellcode,先把目标字符串压入栈中,然后直接跳转到0x7fffffffdbb2执行打印逻辑,完全跳过中间的jmp和call步骤。

举个x86_64架构下的示例(假设打印依赖write系统调用):

; 构造null结尾的字符串(比如"test")
push 0x00747365
push 0x74
mov rsi, rsp    ; 字符串地址存入rsi(write的第二个参数)
mov rdx, 0x5    ; 字符串长度(含null)
; 直接跳转到目标执行地址
jmp 0x7fffffffdbb2

这样就能直接触发你需要的打印逻辑,完全避开那个麻烦的call指令。


内容的提问来源于stack exchange,提问作者Gabriel Reyes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:40:42