汇编程序:获取Win32的WinMain on-stack参数

alt*_*126 4 parameters assembly winapi winmain

我需要WinMain使用程序集访问参数,但我似乎无法这样做,尽管我应该知道它们在堆栈中的位置(DWORD在操作之前按下EBP时偏移0到16和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
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用,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]
Run Code Online (Sandbox Code Playgroud)

第一个代码块中的错误在哪里?我需要什么来获取参数,并能够实现我自己的代码以返回一个有效的指针,lpszCmdLine就像GetCommandLine其他WinMain参数一样?如果我无法从堆栈中获取命令行指针,那么我可能无法获得其他参数,例如nCmdShow,用于其他重要的初始化.

如果您需要的代码多于上面提供的代码,请与我们联系.如果你知道它是有用的,我没有使用链接器,而是完全手动EXE生成(它有什么区别WinMain,比如进一步的堆栈参数?),但基本上它只是一个程序,Windows自动调用它的入口点和上面将是它将包含哪个程序的2个不同选项.

Mik*_*wan 6

#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;
}
Run Code Online (Sandbox Code Playgroud)

这在Visual Studio中运行得很好.奇怪地在调试器中运行它并单步执行会在调用MessageBox时导致访问冲突.我不确定为什么会这样,但是在没有单步执行的情况下运行调试以及运行最终的二进制文件会产生预期的结果,即.带有标题/消息作为参数的消息框