4

プログラムのリバースエンジニアリングに取り組んでいます。IDA Pro と Hex-Rays Decompiler を使用しています。オブジェクトがあり、オブジェクトにメソッド呼び出しがあることを知っているコードのチャンクに直面していますが、それは私が理解できない方法で示されています。例えば:

 if ( (*(*interfacePtr + 24))(interfacePtr, &v23) >= 0 )

ここで、interfacePtr が ICLRRuntimeHost オブジェクトを指していることがわかります。(C++、.NET CLR ランタイム) しかし.... *(*interfacePtr + 24) に何があるかわかりません。メソッドであることがわかりますが、+24 にあるものをどのように把握すればよいでしょうか?

4

2 に答える 2

2

クラスの vtable は、関数へのポインターの単なるリストです。これには、仮想関数ごとに 1 つのポインターが次の順序で含まれます: 非常に、非常に最上位の基本クラス、次の基本クラス、そのサブクラス、. . . 最派生クラス。

例:

struct A {
    virtual ~A() {}
    virtual void foo() = 0;
}
struct B : public A {
    virtual void foo() { // do something }
    virtual void bar() { // do something else }
}

B の vtable には、次の順序で含まれます。

  • ~A
  • ふー
  • バー

(このオブジェクトへの型 A のポインターを持つコードの一部で同じ vtable を使用できるように、A のものが最初に来る必要があります。そのコードは、基になるオブジェクトが実際に B であることを知りません。)

32 ビット ソースを参照している場合、ポインターは 4 バイトなので、24 = 4 * 6 であり、7 番目の仮想関数を参照しています (インデックスは 0 から始まります)。64 ビットを使用している場合、ポインターは 8 バイトなので、24 = 8 * 3 となり、4 番目を探しています。実際、私は IDA の「C++ への変換」機能を使用していないため、24 は実際には表の 24 番目のエントリである可能性があります。

確認する簡単な方法: 独自のプログラムを作成します。タイプ ICLRRuntimeHost の変数を宣言します。疑わしい関数を呼び出します(ヘッダーファイルを見て、ビット数に応じて7または4までカウントするか、例を誤解した場合は24までカウントします)。生成されたアセンブリ コードを見て、インデックスが正しいかどうかを確認します。(私はいつもそのようなことで1つずれているので、これはチェックを提供します。)

于 2012-08-12T04:53:42.217 に答える
0

ICLRRuntimeHostVtblICLRRuntimeHostVtblの定義を見てください。mscoree.h

ヘックスレイが理解できるものに大まかに翻訳すると、次のようになります。

struct ICLRRuntimeHost {
    ICLRRuntimeHostVtbl *vtbl;
};
struct ICLRRuntimeHostVtbl {
    _DWORD (*QueryInterface)(ICLRRuntimeHost*, _DWORD*, void**);
    _DWORD (*AddRef)(ICLRRuntimeHost*);
    _DWORD (*Release)(ICLRRuntimeHost*);
    _DWORD (*Start)(ICLRRuntimeHost*);
    _DWORD (*Stop)(ICLRRuntimeHost*);
    _DWORD (*SetHostControl)(ICLRRuntimeHost*, void*);
    _DWORD (*GetCLRControl)(ICLRRuntimeHost*, void**);
};

変数 interfacePtr はタイプ: ICLRRuntimeHost である必要があり、コードは次のように逆コンパイルする必要があります。

interfacePtr->GetCLRControl(&v23);
于 2012-09-12T08:14:35.113 に答える