汇编器:获取 Win32 的 WinMain 堆栈参数

发布于 2024-11-06 18:17:12 字数 1848 浏览 1 评论 0原文

我需要使用程序集访问 WinMain 参数,但我似乎无法这样做,尽管我应该知道它们在堆栈中的位置(DWORD 偏移量 0 到 16,以及 0 到20 在操作前按下 EBP 时)。下面是一个显示 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[[email protected]]
pop ebp

但是,如果我使用 GetCommandLine,我可以获得指向命令行字符串的有效指针,并将其显示出来。


call dword[[email protected]]
   push dword 0x00001030              ;UINT uType
   push eax                           ;LPCTSTR lpCaption
   push eax                           ;LPCTSTR lpText
   push dword 0                       ;HWND hWnd
   call dword[[email protected]]

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

如果您需要比上面提供的更多的代码,请告诉我。如果您知道这一点有用的话,我没有使用链接器,而是完全手动生成 EXE(它在 WinMain 中是否有任何差异,例如进一步的堆栈参数?),但基本上它只是 Windows 自动调用其入口点的一个程序,上面是它包含的程序的 2 个不同选项。

I need to access the WinMain parameters using assembly, but I don't seem to be able to do so despite that I supposedly know where they are in the stack (DWORD offsets 0 to 16, and 0 to 20 when pushing EBP before operations). Below there's an example for showing the lpszCmdline string which contains the command line of the program, but it always seems to contain 0, so nothing is displayed. If I try to use other arguments in the assembly code, no valid string pointer seems to be present and/or the program crashes, as expected.


;[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[[email protected]]
pop ebp

However, if I use GetCommandLine I can get a valid pointer to the command line string, and it displays.


call dword[[email protected]]
   push dword 0x00001030              ;UINT uType
   push eax                           ;LPCTSTR lpCaption
   push eax                           ;LPCTSTR lpText
   push dword 0                       ;HWND hWnd
   call dword[[email protected]]

Where's the error in the first code block? What do I need to get the parameters, and being able to implement my own code to return a valid pointer to lpszCmdLine just like GetCommandLine and as a result, to the other WinMain parameters? If I can't get the command line pointer from the stack, then I presumably won't be able to get the other parameters, like nCmdShow, for other important initializations.

Please let me know if you need more code than the provided above. If it is useful for you to know, I used no linker but fully manual EXE generation (does it make any difference in WinMain, like further stack parameters?), but basically it's just a program for which Windows automatically calls its entry point and the above would be the 2 different options of what program it would contain.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哆兒滾 2024-11-13 18:17:12
#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 时,在调试器和单步执行中运行它会导致访问冲突。我不确定为什么会这样,但是在调试中运行而无需单步执行以及运行最终的二进制文件会给出预期的结果,即。以标题/消息作为参数的消息框

#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;
}

This runs just fine for me within Visual Studio. Oddly running it in a debugger and single stepping causes an access violation when the MessageBox is called. I'm unsure why this is, but running in debug without single stepping as well as running the final binary gives the expected result, ie. a messagebox with caption/message as the argument

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文