C++逆向分析----多重继承和菱形继承
多重继承
多重继承是指C++类同时继承两个类或两个以上的类。
class Test
{
public:
int num1;
Test()
{
num1 = 1;
}
virtual void Proc1();
virtual void Proc2();
};
class Test1
{
public:
int num2;
Test1()
{
num2 = 2;
}
virtual void Proc3();
virtual void Proc4();
};
class Test2:public Test, public Test1
{
public:
int num3;
Test2()
{
num3 = 3;
}
virtual void Proc2();
virtual void Proc4();
virtual void Proc5();
};
Test2 test;
对于多重继承而言,对象会有多个虚表指针。首先调用第一个继承的类Test的构造函数(传递的this指针就是对象首地址),接着会调用第二个继承类Test1的构造函数(传递的this指针是对应类数据在对象中的地址,将对象首地址偏移指定地址后传入。这样就可以避免访问到Test类的成员变量)。接着回到Test2的构造函数中初始化两个虚表指针(也就是说其含有两个虚表)。

我们看一下调用完Test2的构造函数后对象内存处的值,发现会有两个虚表指针。分别在连个父类的前4个字节中。

查看两个虚表发现,第一个虚表中存储的是继承第一个类的虚函数地址,如果其虚函数在子类Test2中被覆盖则地址也会被覆盖。第二个虚表中存储的是继承第二个类的虚函数地址,同样其虚函数在子类Test2中被覆盖则地址也会被覆盖。那么如果在Test2类中新增的虚函数其地址存放到哪呢?一般编译器都会将其存在第一个虚表中靠后的地址处。

菱形继承
class Test
{
public:
int num1;
virtual void Proc1();
virtual void Proc2();
virtual void Proc3();
};
class Test1:virtual public Test
{
public:
int num2;
Test1(){
num2 = 0x02;
num1 = 0x01;
};
virtual void Proc1();
virtual void Proc4();
};
class Test2:virtual public Test
{
public:
int num3;
Test2(){
num3 = 0x03;
}
};
class Test3:public Test1, public Test2
{
public:
int num4;
Test3(){
num4 = 0x04;
}
};

上面的示例就是一个典型的菱形继承,且为了保证Test数据成员在Test3类对象中的唯一性,需要Test1继承Test(Test2继承Test)时采用虚继承。

菱形继承内存的布局如下,其有三个虚表指针。父类除了包含虚表指针外还包含一个vt_offset域,此域包含两个字段,第一个字段是本类虚表指针相对于vt_Offset域的偏移,第二个字段是本类的父类(祖父类)的虚表指针相对于vt_offset域的偏移。

注意两个父类虚表指针中包含的是父类中新定义的虚函数,如果其覆盖祖父类中的虚函数其地址应该在祖父类的那个虚表指针中。其中子类也会覆盖父类中的虚函数,那如果其新增虚函数地址应该放在哪呢?编译器一般是将其放在第一个继承的类的虚表指针中,也就是虚表指针1指向的虚表靠后的位置。

调用两个父类或祖父类的构造函数时都会将对象首地址往后偏移到对应的类处的地址后当this指针传递,这样可以在父类或祖父类的构造函数中直接通过偏移访问其自己的类成员。那么现在有个问题在父类的构造函数中访问子类的成员变量应该如何访问呢,祖父类的数据成员在对象的最底部如果单单利用顺序偏移的关系是无法正确访问的,实际其实利用vt_offset域的第二个字段父类对应虚表指针相对于vt_offset的偏移来访问的,因为对于祖父类而言其虚表指针后面跟着的就是自己的成员变量。

参考《C++反汇编与逆向分析技术揭秘》
C++逆向分析----多重继承和菱形继承的更多相关文章
- Python多重继承之菱形继承
继承是面向对象编程的一个重要的方式,通过继承,子类就可以扩展父类的功能.在python中一个类能继承自不止一个父类,这叫做python的多重继承(Multiple Inheritance ). 语法 ...
- C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式.
C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式. 目录: 1.多重继承在内存中的表现形式 多重继承在汇编中的表现形式 2.菱形继承 普通的菱形继承 虚继承 汇编中的表现形 ...
- 《C++反汇编与逆向分析技术揭秘》之12——继承
识别类和类之间的关系 在父类中声明为私有的成员,虽然子类对象无法直接访问,但是在子类对象的内存结构中,父类私有的成员数据依然存在. 在没有提供构造函数的时候,系统会尝试提供默认的构造函数: 当子类中没 ...
- C++反汇编第四讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式.
目录: 1.多重继承在内存中的表现形式 多重继承在汇编中的表现形式 2.菱形继承 普通的菱形继承 虚继承 汇编中的表现形式 一丶多重继承在内存中的表现形式 高级代码: class Father1 { ...
- C++反汇编-菱形继承
学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记.马上就要出差了,回来后接着写吧. 一.概述 菱形继承是最复杂的对象结构,菱形结构会将单一继承与多重继承进行组合. ...
- C++中的多重继承与虚继承的问题
1.C++支持多重继承,但是一般情况下,建议使用单一继承. 类D继承自B类和C类,而B类和C类都继承自类A,因此出现下图所示情况: A A \ / B C ...
- C++反汇编与逆向分析技术揭秘
C++反汇编-继承和多重继承 学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记 一.单类继承 在父类中声明为私有的成员,子类对象无法直接访问,但是在子类对象的 ...
- C++中的类继承(4)继承种类之单继承&多继承&菱形继承
单继承是一般的单一继承,一个子类只 有一个直接父类时称这个继承关系为单继承.这种关系比较简单是一对一的关系: 多继承是指 一个子类有两个或以上直接父类时称这个继承关系为多继承.这种继承方式使一个子类可 ...
- c++继承汇总(单继承、多继承、虚继承、菱形继承)
多重继承中,一个基类可以在派生层次中出现多次,如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多分同名成员.C++提供虚基类的方法使得在 ...
随机推荐
- Android 之 手动创建活动
•活动是什么 活动(Activity)是最容易吸引用户的地方,它是一种可以包含用户界面的组件: 主要用于和用户进行交互: 一个应用程序可以包含零个或多个活动. 接下来,我们来学习一下活动的基本用法. ...
- PAT (Advanced Level) Practice 1035 Password (20 分) 凌宸1642
PAT (Advanced Level) Practice 1035 Password (20 分) 凌宸1642 题目描述: To prepare for PAT, the judge someti ...
- PAT (Basic Level) Practice (中文)1070 结绳 (25 分) 凌宸1642
PAT (Basic Level) Practice (中文)1070 结绳 (25 分) 凌宸1642 题目描述 给定一段一段的绳子,你需要把它们串成一条绳.每次串连的时候,是把两段绳子对折,再如下 ...
- Logtash遇到的异常和注意点
1.Logtash遇到的异常和注意点 1.1 logstash使用kafka插件和es集成 如果logstash使用kafka插件和es集成,必须设置kafka插件参数 session_timeout ...
- ClickHouse性能优化?试试物化视图
一.前言 ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS):目前我们使用CH作为实时数仓用于统计分析,在做性能优化的时候使用了 物化视图 这一特性作为优化手段,本文主 ...
- 敏捷史话(十一):敏捷宣言“间谍”——Steve Mellor
Steve Mellor 是敏捷宣言的签署人之一,他自称是作为" 间谍"去参加雪鸟会议的. 起初收到会议邀请时,Steve 非常惊讶,因为他所做的工作一直都是关于建模方面的,很少将 ...
- 记录给树莓派刷Raspberry Pi OS(Raspbian)系统的配置流程
准备材料 树莓派(一定要贴散热片,最好再加个小风扇) TF内存卡 (记得选传输规范为Class10标准的) 读卡器 电脑(这里我使用的电脑是Windows系统,其它系统可能与下面的步骤有出入,还望悉知 ...
- CIE标准色度系统(下)
四.色温与相关色温 根据绝对黑体光谱分布特性的普朗克定律,由普朗克公式可以计算出黑体对应于某一温度的光谱分布,并由此应用CIE标准色度系统可获得该温度下黑体发光的三刺激值和色品坐标,从而在色品图上得到 ...
- 说一下的dubbo的工作原理?注册中心挂了可以继续通信吗?
(1)dubbo工作原理 第一层:service层,接口层,给服务提供者和消费者来实现的 第二层:config层,配置层,主要是对dubbo进行各种配置的 第三层:proxy层,服务代理层,透明生成客 ...
- es的分布式架构原理能说一下么(es是如何实现分布式的啊)?
在搜索这块,lucene是最流行的搜索库.几年前业内一般都问,你了解lucene吗?你知道倒排索引的原理吗?现在早已经out了,因为现在很多项目都是直接用基于lucene的分布式搜索引擎--elast ...