偷梁换柱虚函数

 

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();
}
 


文章摘自看雪论坛

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值