- 作 者:安摧
- 时 间:2008-08-31 17:53
- 链 接:http://bbs.pediy.com/showthread.php?t=71775
hook类A的第三个函数
方法:比较麻烦,但是也是不难弄的。将类A的第三个虚函数指针替换成我们自己定义的地址。
如图所示:
http://bbs.pediy.com/attachment.php?attachmentid=17704&d=1220176207
void* g_pAddr = 0;
int g_count = 0;
#include <iostream.h>
#pragma comment(linker,"/SECTION:.rdata,RW")
class A
{
public:
int iVal1;
int iVal2;
virtual void print1()
{
cout<<"iVal1(A) = "<<iVal1<<endl;
}
virtual void print2()
{
cout<<"iVal2(A) = "<<iVal2<<endl;
}
virtual void print_all()
{
cout<<"iVal1(A) = "<<iVal1<<"/t/t"<<"iVal2(A) = "<<iVal2<<endl;
}
virtual void print_extern(int ext)
{
cout<<"ext(A) = "<<(ext+0)<<endl;
}
};
class B
{
public:
int iVal1;
int iVal2;
virtual void print1()
{
cout<<"iVal1(B) = "<<iVal1<<endl;
}
virtual void print2()
{
cout<<"iVal2(B) = "<<iVal2<<endl;
}
virtual void print_all()
{
cout<<"iVal1(B) = "<<iVal1<<"/t/t"<<"iVal2(B) = "<<iVal2<<endl;
}
virtual void print_extern(int ext)
{
cout<<"ext(B) = "<<(ext+100)<<endl;
}
};
void load_hook(A* pA)
{
_asm
{
push eax
push ecx
mov eax,dword ptr [pA] //获取对象指针
mov eax,dword ptr [eax] //获取虚表地址
add eax,8 //获取虚表中类A第三个函数指针的地址
mov ecx,dword ptr [eax] //取出类A第三个函数指针
mov dword ptr [g_pAddr],ecx //保存到g_pAddr变量中
mov ecx,offset hook_proc //替换为hook_proc指针
mov dword ptr [eax],ecx
pop ecx
pop eax
jmp hook_end
}
hook_proc:
_asm
{
push ecx
}
g_count++;
cout<<g_count<<" time(s) to invoke A::print_all()"<<endl;//A::print_all的记数
_asm
{
pop ecx
jmp dword ptr [g_pAddr]
}
hook_end:
cout<<"A::print_all() hooked!"<<endl;
}
void unload_hook(A* pA)
{
_asm
{
push eax
push ecx
mov eax,dword ptr [pA] //获取对象指针
mov eax,dword ptr [eax] //获取虚表地址
add eax,8 //获取虚表中类A第三个函数指针的地址
mov ecx,dword ptr [g_pAddr] //取出事先保存的A::print_all()地址
mov dword ptr [eax],ecx
pop ecx
pop eax
}
g_count = 0;
cout<<"A::print_all() unhooked!"<<endl;
}
void main(void)
{
A a;
a.iVal1 = 0;
a.iVal2 = 1;
B b;
b.iVal1 = 1000;
b.iVal2 = 1001;
A* pA = &a;
B* pB = &b;
load_hook(pA);
pA->print1();
pA->print_all();
pA->print_all();
pA->print_all();
unload_hook(pA);
pA->print1();
pA->print_all();
pA->print_all();
pA->print_all();
}
文章摘自看雪论坛