したがって、IDAを使用してdllを逆アセンブルしているときに、次のクラス関数に遭遇しました。
mov eax, [ecx+4]
mov eax, [eax]
retn
ecx
意味this
とeax
は戻り値ですが、何が返されるのか理解できません。何か助けはありますか?
したがって、IDAを使用してdllを逆アセンブルしているときに、次のクラス関数に遭遇しました。
mov eax, [ecx+4]
mov eax, [eax]
retn
ecx
意味this
とeax
は戻り値ですが、何が返されるのか理解できません。何か助けはありますか?
この関数は、どのポイントeax
からでもオフセット4にポインタを(に)ロードします。ecx
次に、そのポインタに続いて、関数から返される32ビット値をにロードしeax
ます。
それは関数が行うことですが、それが何を意味するのかをもっと多くの文脈なしで言うことは不可能です。
class C
{
int a;
int *b; // ecx+4
int get_b()
{
return *b;
}
}
もちろん、との実際のタイプa
は*b
不明ですが、どちらも32ビットタイプです。a
クラスに仮想メソッドまたはデストラクタがある場合は、VMTへのポインタになることもあります。
私のアセンブリは少し錆びていますが、最初の命令はEAXに何かをロードします... ECXレジスタの内容によってポイントされているもの...しかし、そこからオフセットされたワード(4バイト)です。次の命令は、EAXが指しているものをEAXにロード(上書き)します。
この表記(これらのMOV(ロード)命令の2番目または「ソース」操作を囲む角括弧は、間接アドレッシングモードが使用されていることを示します。
一種の二重間接参照を実装する方法にすぎないと思います。レジスタECXのアドレスは、スタックフレームを指しているか、参照したC++の「this」の属性ポインタを指している可能性があります。そのアドレスは、次に、戻り値のアドレスを保持します。したがって、このコードはアドレスをレジスタにプルし、次にレジスタ内のそのアドレスを使用して値をプルします(偶然にも同じレジスタに)。このアプローチは、他のすべてのレジスタを保持するという点で優れています。
(ちなみに、ほとんどのx86関数呼び出しパラダイム---システムコール、DOS関数コールなどは、関数のリターンコードまたはシステムエラーを残します... errnoはstdlibCライブラリのEAXレジスタにあります)。
何の質問。ecxが「this」構造へのポインターを保持している場合、それがどのように正確に行われるかを知る必要があります。最初の命令は、2番目のdword、別のポインターを取得します。それは何でしょうか?わかりません。このポインタは現在eaxに保持されており、おそらく別の構造体などを指しています。最初のポイント値はeaxに入れられ、これがfuncが返すものです。
ecx -------> dword dataA offset 0
dword dataB offset 4
mov eax, [ecx + 4]
eax = dataB ----> dword dataC offset 0
mov eax, [eax]
eax = dataC
dataCとは正確には、私たちが知ることができない多くのことに依存します。
これは、元のコンパイラで使用されている呼び出し規約に大きく依存します。たとえばMSVCのかなり通常の設定は、eaxレジスタに32ビット値を返すことです。@Gregsの回答はそれが何をするかを示していますが、彼が言うように、その意味は実装言語とコンパイラの詳細を知ることに依存します。
逆アセンブリを理解したい場合は、独自の(C / C ++)コードで結果を表示してみてください。これは、他のDLLで何が起こっているのかを知る唯一の方法です。