1

私はまだスタック関連の操作でよく迷子になります。この場合、問題はRET命令であり、eipレジスタの間違ったアドレスをポップします。私はNASMを使用しており、私のコードは次のようになります。

start:
    call GiveMeAHandler
    call GetCommandLine
    ret

GiveMeAHandler:
    push ebp
    mov ebp, esp
    push edi
    push esi
    push dword -11
    call dword [F_GetStdHandle] ; It executes correctly and returns
    mov [StdHandler], eax ; StdHandler is stored in BSS
    add esp, 4
    pop esi
    pop edi
    pop ebp
    ret ; This returns to some weird address

GetCommandLine:
    ; ...
    ; I don't get here because the function above wrong return

プッシュとポッピングを少し誇張したのかもしれませんが(最終的ebp, edi, esiには変更されません)、それらを削除しても、命令は0040100Aretではなく間違ったアドレス ( 77AE7094 ) を返します。ここで 2 番目の関数を呼び出します。

4

2 に答える 2

2

既定では、Windows は、stdcall関数の引数が (右から左に) スタックにプッシュされ、呼び出し先がスタックをクリーンアップする呼び出し規約を使用します。つまり、GetStdHandleリターン時に、スタックはすでに命令の前に復元されていますpush dword -11。行を削除してみて、add esp, 4問題が解決するかどうかを確認してください。

于 2013-07-10T13:55:38.497 に答える