我一直在使用与Microsoft Detours相同的方法练习弯路(用jmp和地址替换前五个字节)。最近我一直在通过修改虚拟表来阅读关于绕行的内容。如果有人能够通过提及这种方法的一些优点和缺点,与前面提到的方法相比,我会很感激的。有关绕行虚拟表的问题
我也想问一下堆栈上的vatch和对象。考虑以下情况:
// 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)
法)。这是因为如果可能的话,编译器会在编译时尝试决定任何虚拟调用(如果我错了,请纠正我)。这是否意味着你是否修补虚拟表并不重要,只要你使用栈上的对象(不是堆分配)?