正好昨天讲到认识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,注入等等一系列的操做,都在最适合本身的场合能发挥出最大的做用.