4

アセンブリを使用してパラメーターにアクセスする必要がありますWinMainが、スタック内のどこにあるかを知っていると思われるにもかかわらず、アクセスできないようです (DWORD オフセット 0 から 16、および操作前に EBP をプッシュする場合は 0 から 20)。以下に、プログラムのコマンド ライン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ようにする必要がありますか? GetCommandLineWinMainスタックからコマンド ライン ポインターを取得できない場合は、nCmdShow他の重要な初期化用の などの他のパラメーターを取得できない可能性があります。

上記以外のコードが必要な場合はお知らせください。知っておくと便利な場合は、リンカを使用せずに完全に手動で EXE を生成しました (追加のスタック パラメータのように、.NET に違いはありますか?) WinMain含まれるプログラムの2つの異なるオプションになります。

4

1 に答える 1

7
#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 内で問題なく動作します。デバッガーで奇妙に実行すると、メッセージ ボックスが呼び出されたときにシングル ステップでアクセス違反が発生します。これがなぜなのかはわかりませんが、シングルステッピングなしでデバッグで実行し、最終的なバイナリを実行すると、期待される結果が得られます。キャプション/メッセージを引数とするメッセージボックス

于 2011-05-10T14:11:26.773 に答える