WinMain入口点 - 汇编代码看起来好像没有传递给入口点的参数

use*_*520 3 c assembly winapi entry-point visual-c++

我正在玩Win32程序集.

一段时间以来,我一直在努力处理WinMain的汇编入口点.从我手写的asm和MSVC提出的NASM和link.exe之间的区别,有一个奇怪的 - 对我而言.

1)C(++)代码 - 只是另一个MessageBox hello世界

#include <Windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MessageBoxA(NULL, "Hello world", "Window title", MB_OK | MB_ICONEXCLAMATION);
}
Run Code Online (Sandbox Code Playgroud)


2)装配等效

global _main
    extern  _MessageBoxA@16
    extern _ExitProcess@4

section .text
_main:
    push 0x30
    push wintitle
    push message
    push 0
    call _MessageBoxA@16

    push    0
    call    _ExitProcess@4

    section .data
message:
    db      'Hello, World', 0
wintitle:
    db      'Window title', 0
Run Code Online (Sandbox Code Playgroud)


技术"规范":
- 操作系统是32位Win7
- C++程序已经用MS VC++ 2013编译
- 汇编程序已经编译nasm -fwin32 msgbox.asm,然后链接到link /nodefaultlib /subsystem:windows msgbox.obj kernel32.lib user32.lib -entry:main


现在来看实际的问题.

当我用OllyDbg 2.01拆解它们时,这就是我所看到的:

1)C++版本
在此输入图像描述

2)ASM版本:
在此输入图像描述



现在,如果我们看一下堆栈窗口,看起来好像Windows实际上没有将正确的参数传递给我的汇编入口点.返回到ntdll之前只有两个垃圾整数,而不是C++版本,其中存在所有四个参数.

这对我来说是一个问题,因为我想在(在另一个汇编程序中)获取入口点内的hInstance变量.使用[EBP+8]给我上面提到的垃圾而不是正确的hInstance值.

任何帮助是极大的赞赏.

Har*_*ton 6

WinMainC++代码中的入口点由C运行时库调用,而不是由Windows调用.

实际的Win32入口点签名是

void __stdcall NoCRTMain(void);
Run Code Online (Sandbox Code Playgroud)

您可以使用命令行获取GetCommandLine,如果需要将其转换为argc/argv格式,则可以使用CommandLineToArgvW.

你可以hInstance通过GetModuleHandle设置参数调用来获得NULL.(请注意,在Win32中,不像16位Windows,HINSTANCE并且HMODULE是同一个东西.)