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

64位转32位汇编求助:注入LoadLibraryA时程序崩溃的栈问题

32位程序DLL注入崩溃问题分析与修复

你的64位注入逻辑没问题,但32位下崩溃的核心原因是栈平衡、寄存器破坏、原指令缺失这几个点没处理好,下面逐个拆解并给出修复方案:


1. 栈平衡与调用约定问题

32位下LoadLibraryA采用__stdcall调用约定:函数会在返回时自动通过ret 4清理栈上的参数(因为只有一个4字节的字符串地址参数)。你当前的代码逻辑本身栈是平衡的,但崩溃可能来自跳转位置错误:

  • 确认entryfunc的跳转目标:你替换了入口处的指令为JMP codecave,所以最后应该跳转到原指令的下一条地址,而非原指令的位置(原位置已经被改成跳转指令了)。

2. 寄存器破坏问题

32位Windows API允许修改EAX、ECX、EDX寄存器,但原程序的入口逻辑可能依赖这些寄存器的初始值。你只保存了EAX,但如果ECX/EDX被LoadLibraryA修改,就会导致后续流程出错。最稳妥的方式是在codecave开头保存所有寄存器,结尾恢复:

; 保存所有通用寄存器
PUSHAD

; 执行你的DLL加载逻辑
PUSH dllstr
CALL dword ptr [loadlibrarya]

; 恢复所有寄存器
POPAD

3. 原指令缺失问题

如果入口处你替换的不是空指令(NOP),而是一条有效业务指令,必须在codecave中补执行这条指令,否则程序会缺失关键流程直接崩溃。比如原入口指令是MOV EAX, [EBX+0x10],那codecave里要先执行这条指令,再加载DLL:

PUSHAD

; 补执行被替换的原指令
MOV EAX, [EBX+0x10]

; 加载DLL
PUSH dllstr
CALL dword ptr [loadlibrarya]

POPAD
JMP entryfunc_after_original

4. 其他验证点

  • 确认dllstr是以null结尾的ANSI字符串,且地址是有效的32位内存地址,所在内存页有读权限(codecave在.text段的话默认是可读可执行,没问题)。
  • 确认loadlibrarya的地址是从目标程序导入表中获取的正确32位地址,不是64位的地址。

修复后的完整32位Codecave示例

; codecave起始位置
PUSHAD                   ; 保存所有寄存器

; 补执行被替换的原入口指令(根据实际情况修改)
; MOV EAX, [EBX+0x4]

; 加载目标DLL
PUSH dllstr              ; 压入ANSI字符串地址
CALL dword ptr [loadlibrarya] ; 调用LoadLibraryA(stdcall自动清理参数栈)

POPAD                    ; 恢复所有寄存器
JMP entryfunc_next       ; 跳回原入口指令的下一条位置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 20:05:27