我需要使用汇编来访问WinMain
参数,但我似乎无法这样做,尽管我应该知道它们在堆栈中的位置(DWORD 偏移 0 到 16,在操作前推送 EBP 时偏移 0 到 20)。下面是一个显示包含程序命令行的lpszCmdline
字符串的示例,但它似乎总是包含 0,因此不显示任何内容。如果我尝试在汇编代码中使用其他参数,则似乎不存在有效的字符串指针和/或程序崩溃,正如预期的那样。
;[esp+20]==nCmdShow
;[esp+16]==lpszCmdLine
;[esp+12]==0 in win32
;[esp+8]==hInst
;[esp+4]==EIP
;[esp+0]==EBP
push ebp
mov ebp,esp
mov eax,[ebp+16]
push dword 0x00001030 ;UINT uType
push eax ;LPCTSTR lpCaption
push eax ;LPCTSTR lpText
push dword 0 ;HWND hWnd
call dword[MessageBoxA@USER32.DLL]
pop ebp
但是,如果我使用GetCommandLine
我可以获取指向命令行字符串的有效指针,并且它会显示。
call dword[GetCommandLineA@KERNEL32.DLL]
push dword 0x00001030 ;UINT uType
push eax ;LPCTSTR lpCaption
push eax ;LPCTSTR lpText
push dword 0 ;HWND hWnd
call dword[MessageBoxA@USER32.DLL]
第一个代码块中的错误在哪里?我需要什么来获取参数,并能够实现我自己的代码来返回一个有效的指针,就像GetCommandLine
一样,lpszCmdLine
,因此,返回到其他WinMain
参数?如果我无法从堆栈中获取命令行指针,那么我大概将无法获取其他参数,例如 nCmdShow
,用于其他重要的初始化。
如果您需要比上面提供的更多代码,请告诉我。如果您知道它对您有用,我没有使用链接器,而是完全手动生成 EXE(它对WinMain
有什么影响,比如进一步的堆栈参数?),但基本上它只是一个 Windows 自动调用其入口点的程序,以上将是它将包含的程序的 2 个不同选项。
#include <Windows.h>
int CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {
__asm {
mov eax, [ebp+16]
push 0
push eax
push eax
push 0
call dword ptr ds:[MessageBoxA]
}
return ERROR_SUCCESS;
}
这在Visual Studio中对我来说运行得很好。奇怪的是,在调试器和单步运行它会导致调用 MessageBox 时出现访问冲突。我不确定为什么会这样,但是在没有单步执行的情况下在调试中运行以及运行最终二进制文件会给出预期的结果,即。以标题/消息作为参数的消息框