関数の引数はスタック上またはレジスタに渡されますか?
-
13-09-2019 - |
質問
私は現在、私はアセンブリで書いたプログラムを解析していますし、アセンブリ内の周りにいくつかのコードを移動を考えていました。私は1つの引数を取る手続きを持っていますが、それは、スタックやレジスタに渡された場合、私はわからない。
私はIDA Proで私のプログラムを開くと、手順の最初の行があります:
ThreadID= dword ptr -4
私は宣言の上に私のカーソルを合わせると、次のようにも表示されます:
ThreadID dd ?
r db 4 dup(?)
これは私が引き受けるスタック変数を指すのでしょうか?
私は、スタック上のこの場所で、しかしOllyDbgで同じプログラムを開くと、それはレジスタに渡されることを信じて私をリードし、渡された可能性が任意のパラメータと矛盾だろう大きな価値があります。
誰が正しい方向に私を指すことができますか?
解決
引数が関数に渡される方法は、関数の呼び出し規約に依存します。デフォルトの呼び出し規約は、言語、コンパイラやアーキテクチャに依存します。
私は、多くの場合、プログラムをリバースエンジニアリングするヒューリスティックを使用して、しかし、あなたは、IDAのようなそのアセンブリレベルのOllyDbgのようなデバッガや逆アセンブラを忘れてはならない、あなたが提供する情報と確かに何も言うことはできません。コンパイラによって生成されたコードを研究するための最良の方法は、アセンブリリストを書くためにそれを指示することです。ほとんどのコンパイラはこれを行うためのオプションがあります。
他のヒント
これは確かにローカル変数です。チェックアウトするには、引数は、[ESP + XXX]の値を探してください。 IDA名に自動的にそれらの[ESP + arg_XXX]。
.text:0100346A sub_100346A proc near ; CODE XREF: sub_100347C+44p
.text:0100346A ; sub_100367A+C6p ...
.text:0100346A
.text:0100346A arg_0 = dword ptr 4
.text:0100346A
.text:0100346A mov eax, [esp+arg_0]
.text:0100346E add dword_1005194, eax
.text:01003474 call sub_1002801
.text:01003474
.text:01003479 retn 4
.text:01003479
.text:01003479 sub_100346A endp
そしてfastcall規則上のコメントで概説されたように引数を渡すためにレジスタを使用しています。彼らはより広く使用されているように私には、MicrosoftまたはGCCコンパイラに賭ける思います。だから、ECXをチェックアウトし、EDXは、最初に登録します。
マイクロソフトまたはGCC [2] __fastcall [3] 条約(通称__msfastcall)のパス 最初の二つの引数(評価を ECXに適合している)左から右へ EDX。残りの引数はプッシュされます 右から左にスタックに。 http://en.wikipedia.org/wiki/X86_calling_conventions#fastcallする