Ассемблер: Получение параметров WinMain в стеке Win32 - PullRequest
4 голосов
/ 10 мая 2011

Мне нужно получить доступ к параметрам 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[MessageBoxA@USER32.DLL]
pop ebp

Однако, если я использую 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]

Где ошибка в первом блоке кода? Что мне нужно, чтобы получить параметры и возможность реализовать собственный код для возврата действительного указателя на lpszCmdLine, как GetCommandLine, и в результате на другие WinMain параметры? Если я могу не получит указатель командной строки из стека, тогда я, вероятно, не смогу получить другие параметры, такие как nCmdShow, для других важных инициализаций.

Пожалуйста, дайте мне знать, если вам нужно больше кода, чем указано выше. Если вам полезно знать, я использовал не компоновщик, а полностью ручную генерацию EXE (это делает любую разницу в WinMain, как и другие параметры стека?), Но в основном это просто программа, для которой Windows автоматически вызывает свою точку входа, и выше будет 2 различных варианта того, какую программу она будет содержать.

1 Ответ

6 голосов
/ 10 мая 2011
#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.Я не уверен, почему это так, но запуск в режиме отладки без единого шага, а также запуск финального двоичного файла дает ожидаемый результат, т.е.окно сообщения с заголовком / сообщением в качестве аргумента

...