类中有虚函数就会存在虚表。
主要是一种间接call:
call dword ptr [xxxxxxx];
因此就可以修改间接跳转的地址实现hook。
主要步骤:
- 找到虚表
- 修改虚表的物理页属性可写
- 修改虚函数地址
代码如下:
#include <stdio.h>
#include <windows.h>
class Base{
public:
virtual void output(){
printf("i am base
");
}
};
void hook_print(){
printf("你被hook了
");
}
int main(int argc, char* argv[]){
Base *pb = new Base(); // 此对象的第一个DWORD指向虚表
DWORD *pVtAddr = (DWORD *)(*(DWORD*)pb); // 强转类型指向虚表
// 由于虚表的属性是只读不可写,所以要改成可写
DWORD dwOldProct = 0;
VirtualProtect(pVtAddr, 4, PAGE_READWRITE, &dwOldProct);
*pVtAddr = (DWORD)hook_print; // hook函数的地址
pb->output();
delete pb;
return 0;
}