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[MessageBoxA@USER32.DLL]
pop ebp
However, if I use GetCommandLine
I can get a valid pointer to the command line string, and it displays.
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]
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 basica开发者_高级运维lly 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.
#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
精彩评论