在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
相关产品推荐
相关产品推荐

