版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq78442761/article/details/84816417
虚表的基本概念
在此链接中
https://blog.csdn.net/qq78442761/article/details/84800688
获取虚表中函数的原理
对象空间的最开始四字节内容,就是虚表(虚函数列表)的地址,叫虚指针
把虚表强转为int*,这样虚表就刚好是一个int型数组了
如:
Base *base = new SubClass;
*(int*)base 这个是指得到对象空间最开始的4字节内容,也就是虚表地址
(int*)*(int*)base 这样做虚表的首地址就变成了int*了
*(int*)*(int*)base 得到这个数组的首元素了!
可以改为如下的写法:
*((int*)*(int*)base + 0) 第1个虚函数
*((int*)*(int*)base + 1) 第2个虚函数
定义函数指针去调用,如下所示:
typedef void (*p)();
((p)(*((int*)*(int*)base + 0)))(); 这样就可以调用了
如何找虚表的尾巴:
int *pp = (int*)*((int*)*(int*)base + 3);
完整例子
这里给出完整的例子,源码如下:
#include <iostream>
using namespace std;
class Base{
public:
virtual void print1(){
cout << "Base print1 called" << endl;
}
virtual void print2(){
cout << "Base print2 called" << endl;
}
virtual void print3(){
cout << "Base print3 called" << endl;
}
virtual ~Base(){
cout << "Base disconstruction called" << endl;
}
};
class SubClass: public Base{
public:
void print1(){
cout << "SubClass print1 called" << endl;
}
void print3(){
cout << "SubClass print3 called" << endl;
}
virtual ~SubClass(){
cout << "SubClass disconstruction called" << endl;
}
};
void main(){
Base *base = new SubClass;
typedef void (*p)();
((p)(*((int*)*(int*)base + 0)))();
((p)(*((int*)*(int*)base + 1)))();
((p)(*((int*)*(int*)base + 2)))();
int *tail = (int*)*((int*)*(int*)base + 3);
int *tailAdd1 = (int*)((int*)*(int*)base +4);
delete base;
getchar();
}
运行截图如下:
尾部如下: