Ensamblador: Obtener los parámetros de la pila WinMain de Win32

Necesito acceder al WinMain parámetros usando el ensamblaje, pero parece que no puedo hacerlo a pesar de que supuestamente sé dónde están en la pila (DWORD compensa de 0 a 16 y de 0 a 20 al presionar EBP antes de las operaciones). A continuación hay un ejemplo para mostrar el lpszCmdline cadena que contiene el de línea de comandos del programa, pero siempre parece contener 0, por lo que no se muestra nada. Si trato de usar otros argumentos en el código ensamblador, no parece haber un puntero de cadena válido y / o el programa se bloquea, como se esperaba.


;[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

Sin embargo, si uso GetCommandLine Puedo obtener un puntero válido a la cadena de línea de comando y se muestra.


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]

¿Dónde está el error en el primer bloque de código? ¿Qué necesito para obtener los parámetros y poder implementar mi propio código para devolver un puntero válido a lpszCmdLine al igual que GetCommandLine y como resultado, al otro WinMain parámetros? Si no puedo obtener el puntero de la línea de comando de la pila, entonces presumiblemente no podré obtener los otros parámetros, como nCmdShow, para otras inicializaciones importantes.

Por favor, avíseme si necesita más código que el proporcionado anteriormente. Si le resulta útil saberlo, no utilicé un enlazador, sino una generación EXE totalmente manual (¿hace cualquier diferencia en WinMain, ¿como más parámetros de pila?), pero básicamente es solo un programa para el cual Windows llama automáticamente a su punto de entrada y lo anterior serían las 2 opciones diferentes de qué programa contendría.

preguntado el 10 de mayo de 11 a las 13:05

StackOverflow no es un foro; si necesita agregar más detalles, por favor edita tu pregunta o utilice los comentarios para comunicarse con las personas que han respondido. Se supone que las respuestas son respuestas, no información adicional sobre la pregunta. -

1 Respuestas

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

Esto funciona bien para mí dentro de Visual Studio. Curiosamente, ejecutarlo en un depurador y un solo paso provoca una infracción de acceso cuando se llama al MessageBox. No estoy seguro de por qué es así, pero ejecutar en depuración sin un solo paso, así como ejecutar el binario final, da el resultado esperado, es decir. un cuadro de mensaje con título / mensaje como argumento

contestado el 10 de mayo de 11 a las 18:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.