找到虚函数表地址和调用虚函数
class Base
{
virtual void fun1(void){printf("this is fun1().\n");};
virtual void fun2(void){printf("this is fun2().\n");};
virtual void fun3(void){printf("this is fun3().\n");};
};
typedef void(*Func)(void);
int _tmain(int argc, _TCHAR* argv[])
{
Base base;
Func func = nullptr;
printf("虚函数表地址:%p \n", (int*)&base); // &base强转后得到虚函数表地址
printf("虚函数表第一个函数地址:%p \n", (int*)(*(int*)&base)); // //对虚函数表再次取指
func = (Func)* ((int *) *(int*)(&base) + 1 ); // 第一个函数,第二个+1...
func();
return 0;
}
![](https://img2018.cnblogs.com/blog/1559355/201912/1559355-20191230112429955-309376688.png)
虚函数在虚函数表中的位置(无覆盖)
class Base
{
virtual void fun1(void){printf("this is fun1().\n");};
virtual void fun2(void){printf("this is fun2().\n");};
virtual void fun3(void){printf("this is fun3().\n");};
};
class Derive : public Base
{
virtual void fun4(void){printf("this is fun4().\n");};
virtual void fun5(void){printf("this is fun5().\n");};
virtual void fun6(void){printf("this is fun6().\n");};
};
typedef void(*Func)(void);
int _tmain(int argc, _TCHAR* argv[])
{
Derive derive;
Func func1, func2, func3, func4, func5, func6;
func1 = (Func)* ( (int*) *(int*)(&derive) + 0 );
func2 = (Func)* ( (int*) *(int*)(&derive) + 1 );
func3 = (Func)* ( (int*) *(int*)(&derive) + 2 );
func4 = (Func)* ( (int*) *(int*)(&derive) + 3 );
func5 = (Func)* ( (int*) *(int*)(&derive) + 4 );
func6 = (Func)* ( (int*) *(int*)(&derive) + 5 );
func1();
func2();
func3();
func4();
func5();
func6();
return 0;
}
![](https://img2018.cnblogs.com/blog/1559355/201912/1559355-20191230135003364-537143794.png)
虚函数在虚函数表中的位置(有覆盖)
class Base
{
virtual void fun1(void){printf("this is Base fun1().\n");};
virtual void fun2(void){printf("this is Base fun2().\n");};
virtual void fun3(void){printf("this is Base fun3().\n");};
virtual void fun4(void){printf("this is Base fun4().\n");};
virtual void fun5(void){printf("this is Base fun5().\n");};
virtual void fun6(void){printf("this is Base fun6().\n");};
};
class Derive : public Base
{
virtual void fun1(void){printf("this is Derive fun1().\n");};
virtual void fun2(void){printf("this is Derive fun2().\n");};
virtual void fun3(void){printf("this is Derive fun3().\n");};
};
typedef void(*Func)(void);
int _tmain(int argc, _TCHAR* argv[])
{
Derive derive;
Func func1, func2, func3, func4, func5, func6;
func1 = (Func)* ( (int*) *(int*)(&derive) + 0 );
func2 = (Func)* ( (int*) *(int*)(&derive) + 1 );
func3 = (Func)* ( (int*) *(int*)(&derive) + 2 );
func4 = (Func)* ( (int*) *(int*)(&derive) + 3 );
func5 = (Func)* ( (int*) *(int*)(&derive) + 4 );
func6 = (Func)* ( (int*) *(int*)(&derive) + 5 );
func1();
func2();
func3();
func4();
func5();
func6();
return 0;
}
![](https://img2018.cnblogs.com/blog/1559355/201912/1559355-20191230135625371-1885959377.png)
参考https://coolshell.cn/articles/12165.html