3

私はWindows実行可能ファイルをリバースエンジニアリングしているところです。実行可能ファイル(別のスレッド、独自のスタック)に挿入するコードから、使用したいクラスを見つけました。メソッドアドレスとメンバー変数の構造を指定して、このようなクラスを宣言するにはどうすればよいですか?

たとえば、コンストラクター@0x4012D30と関数doTheMario@40125D4を持つfooというクラスを見つけたとします。また、3つのDWORDのプライベートデータを保持していることも知っています。どちらのメソッドも_thiscallsなので、コードでそのようなクラスを宣言します。

class GuessedFoo {
    private:
        int bar;
        char *cafebabe;
        float deadbeef;
    public:
        GuessedFoo(int a, int b);
        void doTheMario();
};

さて、これは完全にダンディなクラスですが、コンパイラ/リンカにクラスメソッドを前に述べた2つのアドレスにバインドさせる方法はありますか?もちろん、使用する必要のあるすべてのメソッドに対してstdcallをthiscallに変換するasmラッパーを記述し、クラスの代わりに構造体を使用することもできますが、より良い方法が必要です。

現在はgcc/g ++を使用していますが、VC ++に切り替えることができます(gccのインラインasmはとにかく頭痛の種になるため)。

4

4 に答える 4

4

クラスにvtableがない場合は、原則として、独自のコードでそのようなクラスを作成できます。この場合、すべての関数呼び出しが適切な実際の実装を呼び出します。これを行うには、メンバー関数を、実際の実装へのアセンブリジャンプ命令を含むネイキッド関数として絞り込みます。

クラスにvtableがある場合、状況はさらに複雑になる可能性があります。関数ポインタの構造体としてvtableを明示的に作成し、関数スタブでそれらを呼び出す必要がある可能性があります。これは、より複雑なシム機能を意味します。ジャンプを伴う単純な裸の関数では不十分な場合があり、実際の関数を使用する方がよい場合があります。ただし、win32のメンバー関数は異なる呼び出し規約を使用することに注意してください。これは、通常のメンバー関数呼び出しが機能しないことを意味します。メンバー関数へのポインターを作成することで逃げることができるかもしれませんが、それらはかなり奇妙な構造を持っていることに注意してください。vtableポインターと同じ表現を持つものと一致させる必要があります。幸運を!

于 2010-08-06T05:35:30.653 に答える
1

ここではリバースエンジニアリングを行っているため、既存のコードとのやり取りに関しては(ほとんどの場合)低くする必要があります。

純粋なアセンブリコードを使用してこの関数を呼び出します。
EXEのベースアドレスが固定されていると、さらに簡単になります。
コード例:

void main()
{
    int bar = 5;
    int * cafebabe = &bar;
    __asm
    {
        push [bar];
        push [cafebabe];
        mov eax, 123456; // address of the function
        call eax;
    }
}

この関数が元のコードによってどのように呼び出されているかを確認するだけで、引数をプッシュする必要がある順序を確認できます。一部の引数をレジスタに渡す必要がある場合があることを忘れないでください。

于 2010-08-06T05:39:42.970 に答える
0

私があなたを正しく理解していることを完全には確信していませんが、とにかく:「手動検索」メソッドへの最も簡単なルートは関数ポインタを使用することだと思います。

于 2010-08-06T05:05:08.263 に答える
0

C ++は、いかなる種類のバイナリインターフェイスも定義していないため、c++クラスにあらゆる種類の動的バインディングを実装することはほとんど不可能です。

最善の方法は、2つの構造体を宣言することです。1つはメソッドごとにc関数typedefを含み、もう1つはクラスデータレイアウトをミラーリングします。

もちろん、クラスメソッドの__thiscallはecsレジスタを介して'this'を渡すため、同じ効果を持つ明示的なc関数宣言を実際に作成できるとは思わないので、カスタムを介してすべての呼び出しを実行する必要がある場合がありますアセンブリに書き込んだ「CallThisCallMethodWithParameters」。

于 2010-08-06T05:23:47.577 に答える