标签:
原理分析
当调用一个虚函数时, 编译器生成的代码会调用 虚表地址[0](param1, param2)这样的函数. 已经不是在调用函数名了.
当我们将虚表地址[n]中的函数实现改为另外的函数, 虚函数的实现就由我们来控制了.
实验
根据虚表原理, 实验一下修改自己程序的虚函数表项地址.
使编译器生成的代码执行一个虚函数A时, 执行的是我们自己定义的非虚函数B.
知识点
* 使用union赋值, 绕过编译器函数与变量强转赋值的限制
* 类成员函数指针的执行
* 修改和恢复自己的代码段属性
* 虚函数表项的定位和读写
实验代码
- typedef void (CC::*PFN_fnFoo)();
-
- typedef union un_function_pt
- {
- PFN_fnFoo pfn;
- int ifunAddr;
- }UN_FUNCTION_PT;
-
- void fnReplaceVirtualFunction()
- {
-
-
-
-
-
-
-
- int iVirtualTblAddr = 0;
- int iVirtualFunctionAddr_CC_fnFoo = 0;
- UN_FUNCTION_PT unFunPt;
- DWORD dwOldProtect = 0;
-
- CA* pCA = new CC();
-
- iVirtualTblAddr = *((int*)pCA);
- iVirtualFunctionAddr_CC_fnFoo = *((int*)iVirtualTblAddr + 1);
-
-
- unFunPt.ifunAddr = iVirtualFunctionAddr_CC_fnFoo;
- (((CC*)pCA)->*unFunPt.pfn)();
-
-
-
-
- unFunPt.pfn = &CC::fnNewFunctionSameDefineAsfnFoo;
- (((CC*)pCA)->*unFunPt.pfn)();
-
-
- if (VirtualProtect((void*)iVirtualTblAddr, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect))
- {
-
- unFunPt.pfn = &CC::fnNewFunctionSameDefineAsfnFoo;
-
-
- *((int*)iVirtualTblAddr + 1) = unFunPt.ifunAddr;
-
-
- VirtualProtect((void*)iVirtualTblAddr, 8, dwOldProtect, NULL);
-
-
- pCA->fnFoo();
-
-
-
- }
- }
-
- #if !defined(AFX_CLASSTEST_H__D794CC4B_D79E_4A61_9D5A_95110788AE39__INCLUDED_)
- #define AFX_CLASSTEST_H__D794CC4B_D79E_4A61_9D5A_95110788AE39__INCLUDED_
-
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
-
- #include <iostream>
-
- using namespace std;
-
- class CA
- {
- public:
- CA();
- virtual ~CA();
- virtual void fnFoo();
- };
-
- class CB : public CA
- {
- public:
- CB();
- virtual ~CB();
- virtual void fnFoo();
- };
-
- class CC : public CB
- {
- public:
- CC();
- virtual ~CC();
- virtual void fnFoo();
- void fnNewFunctionSameDefineAsfnFoo();
- };
-
-
- #endif // !defined(AFX_CLASSTEST_H__D794CC4B_D79E_4A61_9D5A_95110788AE39__INCLUDED_)
-
- #include "ClassTest.h"
-
-
- CA::CA()
- {
- cout << "CA::CA" << endl;
- }
-
- CA::~CA()
- {
- cout << "CA::~CA" << endl;
- }
-
- void CA::fnFoo()
- {
- cout << "CA::fnFoo" << endl;
- }
-
-
- CB::CB()
- {
- cout << "CB::CB" << endl;
- }
-
- CB::~CB()
- {
- cout << "CB::~CB" << endl;
- }
-
- void CB::fnFoo()
- {
- cout << "CB::fnFoo" << endl;
- }
-
-
- CC::CC()
- {
- cout << "CC::CC" << endl;
- }
-
- CC::~CC()
- {
- cout << "CC::~CC" << endl;
- }
-
- void CC::fnFoo()
- {
- cout << "CC::fnFoo" << endl;
- }
-
- void CC::fnNewFunctionSameDefineAsfnFoo()
- {
-
- cout << "CC::fnNewFunctionSameDefineAsfnFoo" << endl;
- }
实行效果
- CA::CA
- CB::CB
- CC::CC
- CC::fnFoo
- CC::fnNewFunctionSameDefineAsfnFoo
- CC::fnNewFunctionSameDefineAsfnFoo
http://blog.csdn.net/lostspeed/article/details/50359445
类虚函数表原理实现分析(当我们将虚表地址[n]中的函数替换,那么虚函数的实现就由我们来控制了)
标签:
原文地址:http://www.cnblogs.com/findumars/p/5187277.html