偷梁换柱虚函数

hook类A的第三个函数

方法:比较麻烦,但是也是不难弄的。将类A的第三个虚函数指针替换成我们自己定义的地址。
如图所示:

http://bbs.pediy.com/attachment.php?attachmentid=17704&d=1220176207

  1. void* g_pAddr = 0;  
  2. int g_count = 0;  
  3. #include <iostream.h>  
  4. #pragma comment(linker,"/SECTION:.rdata,RW")  
  5. class A  
  6. {  
  7. public:  
  8.        int iVal1;  
  9.        int iVal2;  
  10.        virtual void print1()  
  11.        {  
  12.               cout<<"iVal1(A) = "<<iVal1<<endl;  
  13.        }  
  14.        virtual void print2()  
  15.        {  
  16.               cout<<"iVal2(A) = "<<iVal2<<endl;  
  17.        }  
  18.        virtual void print_all()  
  19.        {  
  20.               cout<<"iVal1(A) = "<<iVal1<<"/t/t"<<"iVal2(A) = "<<iVal2<<endl;  
  21.        }  
  22.        virtual void print_extern(int ext)  
  23.        {  
  24.               cout<<"ext(A) = "<<(ext+0)<<endl;  
  25.        }  
  26. };  
  27. class B  
  28. {  
  29. public:  
  30.        int iVal1;  
  31.        int iVal2;  
  32.        virtual void print1()  
  33.        {  
  34.               cout<<"iVal1(B) = "<<iVal1<<endl;  
  35.        }  
  36.        virtual void print2()  
  37.        {  
  38.               cout<<"iVal2(B) = "<<iVal2<<endl;  
  39.        }  
  40.        virtual void print_all()  
  41.        {  
  42.               cout<<"iVal1(B) = "<<iVal1<<"/t/t"<<"iVal2(B) = "<<iVal2<<endl;  
  43.        }  
  44.        virtual void print_extern(int ext)  
  45.        {  
  46.               cout<<"ext(B) = "<<(ext+100)<<endl;  
  47.        }  
  48. };  
  49. void load_hook(A* pA)  
  50. {  
  51.        _asm  
  52.        {  
  53.               push eax  
  54.               push ecx  
  55.               mov eax,dword ptr [pA]              //获取对象指针  
  56.               mov eax,dword ptr [eax]              //获取虚表地址  
  57.               add eax,8                             //获取虚表中类A第三个函数指针的地址  
  58.               mov ecx,dword ptr [eax]              //取出类A第三个函数指针  
  59.               mov dword ptr [g_pAddr],ecx      //保存到g_pAddr变量中  
  60.               mov ecx,offset hook_proc     //替换为hook_proc指针  
  61.               mov dword ptr [eax],ecx  
  62.      pop ecx  
  63.               pop eax  
  64.               jmp hook_end  
  65.        }  
  66. hook_proc:  
  67.        _asm  
  68.        {  
  69.               push ecx  
  70.        }  
  71.        g_count++;  
  72.        cout<<g_count<<" time(s) to invoke A::print_all()"<<endl;//A::print_all的记数  
  73.        _asm  
  74.        {  
  75.               pop ecx  
  76.               jmp dword ptr [g_pAddr]  
  77.        }  
  78. hook_end:  
  79.        cout<<"A::print_all() hooked!"<<endl;  
  80. }  
  81. void unload_hook(A* pA)  
  82. {  
  83.  _asm  
  84.     {  
  85.               push eax  
  86.               push ecx  
  87.               mov eax,dword ptr [pA]              //获取对象指针  
  88.               mov eax,dword ptr [eax]              //获取虚表地址  
  89.               add eax,8                             //获取虚表中类A第三个函数指针的地址  
  90.               mov ecx,dword ptr [g_pAddr]      //取出事先保存的A::print_all()地址  
  91.               mov dword ptr [eax],ecx  
  92.               pop ecx  
  93.               pop eax  
  94.        }  
  95.        g_count = 0;  
  96.        cout<<"A::print_all() unhooked!"<<endl;  
  97. }  
  98. void main(void)  
  99. {  
  100.        A a;  
  101.        a.iVal1 = 0;  
  102.        a.iVal2 = 1;  
  103.        B b;  
  104.        b.iVal1 = 1000;  
  105.        b.iVal2 = 1001;  
  106.        A* pA = &a;  
  107.        B* pB = &b;  
  108.        load_hook(pA);  
  109.        pA->print1();  
  110.        pA->print_all();  
  111.        pA->print_all();  
  112.        pA->print_all();  
  113.        unload_hook(pA);  
  114.        pA->print1();  
  115.        pA->print_all();  
  116.        pA->print_all();  
  117.        pA->print_all();  
  118. }  
  119.  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值