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

使用C++ DLL挂钩x86程序指令后执行崩溃的问题排查求助

C++ DLL挂钩x86程序指令后执行崩溃的问题排查求助

看起来你的挂钩核心思路是通顺的,但程序崩溃大概率是栈/寄存器上下文被破坏导致的,我帮你梳理几个关键的问题点和修复方案:


1. 裸函数中的push esp/pop esp是致命错误

你的MyFun_Wrapper里的push esp和pop esp完全多余,而且会直接破坏栈结构:

  • 执行push esp时,esp已经因为之前的push ebx/push ecx等操作被修改,此时压栈的是当前的esp值
  • 后续pop esp会把esp强制恢复到这个被修改后的值,导致后面的pop ebp/pop edi等操作从错误的栈地址取值,直接造成栈不平衡,程序必然崩溃

解决方法:直接删掉push esp和pop esp这两行代码。


2. 通用寄存器的保存可以更可靠(避免遗漏)

你手动push/pop了多个寄存器,但x86平台有pushad/popad指令可以一次性保存/恢复所有8个通用寄存器(EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI),不仅代码更简洁,还能避免漏存寄存器的问题。

修改后的裸函数可以简化成这样:

extern "C" __declspec(dllexport) __declspec(naked) noinl void MyFun_Wrapper() {
    __asm {
        pushfd          // 保存标志寄存器
        pushad          // 一次性保存所有通用寄存器
        // 传递参数:原EAX和EDI(此时寄存器值还没被修改)
        push edi
        push eax
        call MyFun
        add esp, 8      // 清理栈上的两个参数
        // MyFun的返回值已经在EAX里,不需要额外操作
        popad           // 恢复所有通用寄存器
        // 执行原ADD指令的等效逻辑:用新EAX值更新结构体
        add [edi + 0x194], eax
        popfd           // 恢复标志寄存器
        jmp jump_back   // 跳回原程序继续执行
    }
}

3. 浮点数寄存器上下文的破坏(你提到了浮点数操作)

如果MyFun里用到了x87浮点数寄存器(比如fld/fstp等指令)或者SSE寄存器(xmm0-xmm7),这些寄存器的状态没有被保存,原程序后续执行时会因为浮点数上下文被篡改而崩溃。

解决方法:
用fxsave/fxrestore指令保存和恢复浮点数/SSE寄存器状态,需要注意缓冲区要按16字节对齐:

// 在DLL全局区域定义对齐的浮点数状态缓冲区
alignas(16) char fxsave_buf[512];

extern "C" __declspec(dllexport) __declspec(naked) noinl void MyFun_Wrapper() {
    __asm {
        pushfd
        pushad
        // 保存浮点数/SSE寄存器状态
        lea eax, fxsave_buf
        fxsave [eax]
        
        push edi
        push eax
        call MyFun
        add esp, 8
        
        // 恢复浮点数/SSE寄存器状态
        lea eax, fxsave_buf
        fxrestore [eax]
        
        popad
        add [edi + 0x194], eax
        popfd
        jmp jump_back
    }
}

4. 额外验证建议

按照上面的修改后,你还可以做两个验证:

  1. 确认jump_back的地址是否正确:原ADD指令地址是base + 0x1a0d39,加6字节后正好是base + 0x1a0d3f,这部分你是对的,但要确保赋值的是虚拟地址而非相对偏移
  2. 用x64dbg等调试器挂到目标程序,在MyFun_Wrapper的jmp jump_back处下断点,检查此时的ESP、EBP寄存器是否和进入包装器时一致(除了EAX被修改为自定义值)

按照这些步骤调整后,应该能解决崩溃问题。


内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 11:58:08