正好昨天講到認識C++中虛表指針,以及虛表位置在反彙編中的表達方式,這裏就說一下咱們的新技術,虛表HOOKhtml
昨天的博客連接: http://www.cnblogs.com/iBinary/p/8001749.htmlwindows
PS: 今天所講內容和昨天沒有管理,不過理解了昨天的帖子結合今天的知識,你就能夠找東西練手了,好比你能夠結合的知識,隨便找一款C++寫的遊戲,將它的虛表HOOK了,這樣你想幹啥就幹啥 ^_^函數
講解以前咱們要認識一下類在內存中的表現形式,以及認識虛表指針.測試
1.首先咱們知道,當類中有虛函數的時候,則會生成虛表指針,虛表指針指向了虛表,虛表中保存的則是當前類中全部虛函數的函數地址.spa
內存結構圖:指針
第一個是類的內存結構,第二個是虛表.code
那麼咱們就有想法了,當咱們調用虛函數的時候,會經過虛表指針,找到虛表,然後找到虛函數地址htm
那麼如今咱們是否能夠將虛函數的地址改成咱們的函數地址.blog
聰明: 其實就是很簡單,理解了內存結構,理解了虛表指針,虛表那麼就能夠進行操做了.遊戲
咱們只須要將虛表中的虛函數地址更改爲咱們的便可.
上面都是原理,下面說一下步驟
總共分爲三個步驟 1.得到虛表指針 2.修改虛表的內存保護屬性 3.修改虛表中的虛函數地址爲咱們的函數地址. 很簡單三步
高級代碼:
#include "stdafx.h" #include <windows.h> class MyTest { public: MyTest(); ~MyTest(); void print(); virtual void ShowHelloWorld(); int m_Number; }; MyTest::MyTest() { printf("MyTest::MyTest()\r\n"); } MyTest::~MyTest() { printf("MyTest::~MyTest()\r\n"); } void MyTest::ShowHelloWorld() { printf("Hello World!\n"); } void ShowData() //咱們將虛表中的函數地址換爲咱們的函數地址 { printf("有木有被坑的感受\r\n"); } void MyTest::print() { printf("void MyTest::print()\r\n"); } int main(int argc, char* argv[]) { MyTest test; MyTest &obj = test; //能夠虛調用 int DwAddress = *(int *)&test; //第一步,獲取本身的虛表指針 obj.ShowHelloWorld(); //虛函數調用,測試做用 DWORD dwOld = 0; //第二步修改虛表指針的內存保護屬性,下方更改虛表 VirtualProtect((void *)DwAddress,0x1000,PAGE_EXECUTE_READWRITE,&dwOld);//修改內存保護屬性,其地址是虛表指針地址 (*(int *)DwAddress) = (int)ShowData;//第三步,HOOK,也就是將咱們的函數地址,寫入到虛表中. obj.ShowHelloWorld(); //從新調用,看看是否被HOOK return 0; }
上面代碼能夠直接拷貝粘貼, VS2013測試成功.
貼上測試圖:
這裏只是簡單的HOOK了一下本身類的虛表,你能夠經過本身的分析,找到別的進程中的虛表,而後更改.
固然這個HOOK很簡單,也有本身的適用場合,俗話說,各類HOOK,注入等等一系列的操做,都在最適合本身的場合能發揮出最大的做用.