Microsoft Detours と同じアプローチを使用して迂回を練習してきました (最初の 5 バイトを jmp とアドレスに置き換えます)。最近、仮想テーブルを変更して迂回することについて読んでいます。前述の方法と比較して、この方法の長所と短所をいくつか挙げて、誰かがこの問題に光を当てることができれば幸いです!
また、パッチを適用した vtable とスタック上のオブジェクトについてもお尋ねしたいと思います。次の状況を考慮してください。
// Class definition
struct Foo
{
virtual void Call(void) { std::cout << "FooCall\n"; }
};
// If it's GCC, 'this' is passed as the first parameter
void MyCall(Foo * object)
{
std::cout << "MyCall\n";
}
// In some function
Foo * foo = new Foo; // Allocated on the heap
Foo foo2; // Created on the stack
// Arguments: void ** vtable, uint offset, void * replacement
PatchVTable(*reinterpret_cast<void***>(foo), 0, MyCall);
// Call the methods
foo->Call(); // Outputs: 'MyCall'
foo2.Call(); // Outputs: 'FooCall'
この場合、元の関数 (つまりメソッド)foo->Call()
を呼び出しMyCall(Foo * object)
ながら呼び出すことになります。これは、可能な場合、コンパイラがコンパイル時に仮想呼び出しを決定しようとするためです (間違っている場合は修正してください)。スタック上のオブジェクトを使用する限り (ヒープが割り当てられていない場合)、仮想テーブルにパッチを適用するかどうかは問題ではないということですか?foo2.Call()
Foo::Call(void)