对于c++函数的虚函数的学习
基础
1 |
|
g++编译g++ -m32 -fno-rtti -O1 file.cpp
然后用strip命令去掉所有符号信息 strip -s --strip-all a.out
对比前后文件大小
逆向部分
IDA 载入后
完全没法分析,下面我们开始分析虚函数表
C++虚函数基础:对于每种有虚函数的类,编译器将一个被称为vtable的函数指针表插入生成的二进制文件。这种类型的每个实例对象将多出一个被称为vptr的额外成员指向正确的vtable。用来以正确值初始化这个指针的代码将被添加到构造函数里
首先我们根据已知的信息找到虚表的位置
由于我们有源码这里我们知道有三个类,根据这些函数的内容,我们确定这三个分别是哺乳动物,猫,狗的虚表vtable
但是我们知道cat和dog明明只有四个虚函数,为何这是五个呢,跟踪进去后我们发现前面两个都是析构函数,查资料知道第一个只会破坏对象的成员,第二个将删除对象的已分配内存
,我们跟踪进去也发现第二个函数多一个delete删除内存的操作
最终修改如下
但是重新对main函数进行反编译仍然不可读
这就需要定义并应用structure了
下面我们开始
先定义每个类的vptr额外成员
而后我们定义各自的虚表
而后很关键一步:为每个vptr成员设置类型
具体操作和在伪代码界面设置变量类型一样
以Dog类为例子
后重新对main函数进行反编译,并更改v0类型为Cat *
这样一看简单多了
如果更改类型为 Mammal * ,那么
很明显会出异常,而终止的
但是很奇怪的是我们在编写代码的时候明明是定义的Mammal * 类型,这是因为我们定义的是编译时类型(即静态类型),但是v0的动态类型(或运行时类型)才能决定在一个虚拟函数调用里哪个函数将被调用。
over!!!
参考文章 :
逆向C++虚函数(一)