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

在NASM 32位汇编中调用MessageBoxA程序崩溃,求错误排查

程序崩溃的核心原因分析

1. WinAPI参数压栈顺序完全错误

MessageBoxA采用stdcall调用约定,要求从右往左依次压入参数,正确的参数入栈顺序应为:
uType → lpCaption → lpText → hWnd
你的代码将参数顺序完全颠倒,导致函数接收到的参数全部错位,触发非法内存访问或逻辑错误,直接引发崩溃。

2. 字符串构造的隐性问题(非直接崩溃原因,但需注意)

你通过push 0x74657374传递"test",x86小端序下这个十六进制值确实对应ASCII字节t e s t,且后续压入的eax(0)能提供字符串终止符,但这种构造方式仅适用于长度为4的字符串,通用性差,若字符串长度非4字节会直接导致非预期的字符串内容。

3. 栈平衡的潜在风险

虽然stdcall由被调用者负责清理栈,但参数顺序错误会导致函数执行时错误计算栈清理的字节数,进而破坏栈指针的正确性,后续代码执行会出现不可预测的错误。

修正后的示例代码
[BITS 32]

section .data

section .text
    global  _start

_start:
    ; int MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
    ; stdcall参数入栈顺序:uType → lpCaption → lpText → hWnd

    ; 在栈上构造带null终止符的"test"字符串
    xor   eax, eax
    push  eax                ; 4字节null终止符
    push  0x74657374         ; "test"的小端序字节
    mov   ecx, esp           ; 指向lpText的指针

    push  eax                ; 4字节null终止符
    push  0x74657374         ; "test"的小端序字节
    mov   edx, esp           ; 指向lpCaption的指针

    ; 按正确顺序压入参数
    push  eax                ; uType = MB_OK(0)
    push  edx                ; lpCaption
    push  ecx                ; lpText
    push  eax                ; hWnd = NULL(0)

    mov   esi, 0x307be275    ; MessageBoxA的有效地址
    call  esi

    ; 调用ExitProcess正常退出
    xor   eax, eax
    push  eax                ; 退出码为0
    mov   eax, 0x778a9fe0    ; ExitProcess的有效地址
    call  eax

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 22:05:24