偷樑換柱虛函數

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.  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章