C++多重继承汇编分析

《C++反汇编与逆向分析技术揭秘》笔记-第12章从内存角度看继承和多重继承 C++反汇编揭秘 阅读详情
class CSofa{
public:
CSofa(){
m_nColor = 2;
}


virtual ~CSofa(){
printf("virtual ~CSofa()\r\n");
}


virtual int GetColor(){
return m_nColor;
}


virtual void SitDown(){
printf("CSofa::Sit Down\r\n");
}
protected:
int m_nColor;
};

class CBed{
public:
CBed(){
m_nLength = 4;
m_nWidth = 5;
}

virtual ~CBed(){
printf("virtual ~CBed()\r\n");
}


virtual int GetArea(){
return m_nLength*m_nWidth;
}


virtual void Sleep(){
printf("go to Sleep\r\n");
}


protected:
int m_nLength;
int m_nWidth;

};


class CSofaBed: public CSofa,public CBed{
public:
CSofaBed(){
m_nHeight = 6;
}

virtual ~CSofaBed(){
printf("virtual ~CSofaBed()\r\n");
}

virtual void SitDown(){
printf("CSofaBed::Sit Down\r\n");
}

virtual void Sleep(){
printf("CSofaBed::go to Sleep\r\n");
}

virtual int GetHeight(){
return m_nHeight;
}

protected:
int m_nHeight;
};

int main(int argc, char* argv[])
{
CSofaBed SofaBed;

return 0;

}


多重继承类CSofaBed在内存中的布局

0042501C  50 10 40 00           jmp         CSofaBed::`vector deleting destructor' (00401790)
00425020  32 10 40 00  jmp         CBed::GetArea (00401410)
00425024  19 10 40 00   jmp         CSofaBed::Sleep (00401690)
00425028  00 00 00 00  

0042502C  0F 10 40 00           jmp         CSofaBed::`scalar deleting destructor' (00401720)
00425030  1E 10 40 00   jmp         CSofa::GetColor (004012b0)
00425034  05 10 40 00   jmp         CSofaBed::SitDown (00401640)
00425038  3C 10 40 00            jmp         CSofaBed::GetHeight (004016e0)
0042503C  00 00 00 00  


CSofa类中内存中的布局

00425040  23 10 40 00            jmp         CSofa::`scalar deleting destructor' (00401340)
00425044  1E 10 40 00             jmp         CSofa::GetColor (004012b0)
00425048  14 10 40 00  jmp         CSofa::SitDown (004012f0)
0042504C  00 00 00 00  

CBed类在内存中的布局
00425080  5A 10 40 00  jmp         CBed::`scalar deleting destructor' (004014a0)
00425084  32 10 40 00   jmp         CBed::GetArea (00401410)
00425088  2D 10 40 00  jmp         CBed::Sleep (00401450)
0042508C  00 00 00 00  


SofaBed类对象在内存中的布局

- &SofaBed 0x0012ff30
- CSofa {...}
+ __vfptr 0x0042502c const CSofaBed::`vftable'{for `CSofa'}
m_nColor 0x00000002
- CBed {...}
+ __vfptr 0x0042501c const CSofaBed::`vftable'{for `CBed'}
m_nLength 0x00000004
m_nWidth 0x00000005
m_nHeight 0x00000006
sizeof(SofaBed)0x00000018


0012FF30  2C 50 42 00  
0012FF34  02 00 00 00  
0012FF38  1C 50 42 00  
0012FF3C  04 00 00 00 
0012FF40  05 00 00 00 
0012FF44  06 00 00 00  


CSofaBed类的构造函数汇编:

55:   class CSofaBed: public CSofa,public CBed{
56:   public:
57:       CSofaBed(){
00401140   push        ebp
00401141   mov         ebp,esp
00401143   push        0FFh
00401145   push        offset __ehhandler$??0CSofaBed@@QAE@XZ (00413919)
0040114A   mov         eax,fs:[00000000]
00401150   push        eax
00401151   mov         dword ptr fs:[0],esp
00401158   sub         esp,44h
0040115B   push        ebx
0040115C   push        esi
0040115D   push        edi
0040115E   push        ecx
0040115F   lea         edi,[ebp-50h]
00401162   mov         ecx,11h
00401167   mov         eax,0CCCCCCCCh
0040116C   rep stos    dword ptr [edi]
0040116E   pop         ecx
0040116F   mov         dword ptr [ebp-10h],ecx
00401172   mov         ecx,dword ptr [ebp-10h]
00401175   call        @ILT+70(CSofa::CSofa) (0040104b)   ; 在地址0012FF30处写入00425040
0040117A   mov         dword ptr [ebp-4],0
00401181   mov         ecx,dword ptr [ebp-10h]
00401184   add         ecx,8
00401187   call        @ILT+95(CBed::CBed) (00401064)   ; 在地址0012FF38处写入00425080
0040118C   mov         eax,dword ptr [ebp-10h]
0040118F   mov         dword ptr [eax],offset CSofaBed::`vftable' (0042502c); 在地址0012FF30处写入0042502c
00401195   mov         ecx,dword ptr [ebp-10h]
00401198   mov         dword ptr [ecx+8],offset CSofaBed::`vftable' (0042501c); 在地址0012FF38处写入0042501C
58:           m_nHeight = 6;
0040119F   mov         edx,dword ptr [ebp-10h]
004011A2   mov         dword ptr [edx+14h],6
59:       }
004011A9   mov         dword ptr [ebp-4],0FFFFFFFFh
004011B0   mov         eax,dword ptr [ebp-10h]
004011B3   mov         ecx,dword ptr [ebp-0Ch]
004011B6   mov         dword ptr fs:[0],ecx
004011BD   pop         edi
004011BE   pop         esi
004011BF   pop         ebx
004011C0   add         esp,50h
004011C3   cmp         ebp,esp
004011C5   call        __chkesp (004017a0)
004011CA   mov         esp,ebp
004011CC   pop         ebp
004011CD   ret


SofaBed类对象在内存中的布局

0012FF30  2C 50 42 00  
0012FF34  02 00 00 00  
0012FF38  1C 50 42 00  
0012FF3C  04 00 00 00 
0012FF40  05 00 00 00 
0012FF44  06 00 00 00  


CSofaBed对象的析构函数

61:       virtual ~CSofaBed(){
00401570   push        ebp
00401571   mov         ebp,esp
00401573   push        0FFh
00401575   push        offset __ehhandler$??1CSofaBed@@UAE@XZ (00413939)
0040157A   mov         eax,fs:[00000000]
00401580   push        eax
00401581   mov         dword ptr fs:[0],esp
00401588   sub         esp,48h
0040158B   push        ebx
0040158C   push        esi
0040158D   push        edi
0040158E   push        ecx
0040158F   lea         edi,[ebp-54h]
00401592   mov         ecx,12h
00401597   mov         eax,0CCCCCCCCh
0040159C   rep stos    dword ptr [edi]
0040159E   pop         ecx
0040159F   mov         dword ptr [ebp-10h],ecx
004015A2   mov         eax,dword ptr [ebp-10h]
004015A5   mov         dword ptr [eax],offset CSofaBed::`vftable' (0042502c)   ; 在地址0012FF30处写入0042502c
004015AB   mov         ecx,dword ptr [ebp-10h]
004015AE   mov         dword ptr [ecx+8],offset CSofaBed::`vftable' (0042501c) ; 在地址0012FF38处写入0042501C
004015B5   mov         dword ptr [ebp-4],0
62:           printf("virtual ~CSofaBed()\r\n");
004015BC   push        offset string "virtual ~CSofaBed()\r\n" (004250b8)
004015C1   call        printf (00401cb0)
004015C6   add         esp,4
63:       }
004015C9   cmp         dword ptr [ebp-10h],0
004015CD   je          CSofaBed::~CSofaBed+6Ah (004015da)
004015CF   mov         edx,dword ptr [ebp-10h]
004015D2   add         edx,8
004015D5   mov         dword ptr [ebp-14h],edx
004015D8   jmp         CSofaBed::~CSofaBed+71h (004015e1)   
004015DA   mov         dword ptr [ebp-14h],0
004015E1   mov         ecx,dword ptr [ebp-14h]
004015E4   call        @ILT+50(CBed::~CBed) (00401037)   ; 在地址0012FF38处写入00425080
004015E9   mov         dword ptr [ebp-4],0FFFFFFFFh
004015F0   mov         ecx,dword ptr [ebp-10h]
004015F3   call        @ILT+90(CSofa::~CSofa) (0040105f)    ; 在地址0012FF30处写入00425040
004015F8   mov         ecx,dword ptr [ebp-0Ch]
004015FB   mov         dword ptr fs:[0],ecx
00401602   pop         edi
00401603   pop         esi
00401604   pop         ebx
00401605   add         esp,54h
00401608   cmp         ebp,esp
0040160A   call        __chkesp (004017a0)
0040160F   mov         esp,ebp
00401611   pop         ebp
00401612   ret



【c++】深入剖析虚拟继承与各种继承关系中派生类内成员内存分布情况及虚基类表的内容 单继承 多继承 多重继承 菱形继承 单继承与虚继承 多继承与虚继承 多重继承与虚继承 菱形继承与虚继承 虚基类表指针 虚基类表 不同继承方式成员对面模型 内存分布情况 赋值顺序 阅读详情

相关推荐

从汇编看c++的虚拟继承以及其内存布局

先看第一种简单的情形,所有类中没有任何虚函数的菱形继承。   下面是c++源码: class Top {//虚基类 public:     int i;     Top(int ii) {         i = ii;     } }; class Left : public virtual Top { public:     int j;     Left(int jj, int ii) : Top(ii) {         j = jj;     } }; class Right : public virtual Top { public:

用汇编的眼光看C++(之类继承)

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】     继承是类的一个基本属性,可是在类的继承过程中,函数是怎么初始化?怎么析构的呢?我们不妨看看下面这样的一段代码? class employee { pu

嵌入式-老费,一个分享专业嵌入式知识的blog 5691

MobileNet V3 图像分类

MobileNet V3

Henry的博客 1768

C++ 类的继承机制梳理

类的继承 什么是继承? 继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。这样产生新的类,称 派生类。继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程 为什么要有继承? 纠其根本,最主要的目的就是要提高代码的复用率,更加容易切合大型的项目工程,但是为了提高复用率让编译器过多的参与到代码之中,代码的理...

Mr___Song的博客 1603

Windows 10 下 DockerToolbox 安装全攻略:从下载到配置阿里云镜像加速

本文详细介绍了在Windows 10系统上安装和配置DockerToolbox的完整流程。从下载安装包、执行初步安装,到关键步骤——修改虚拟机存储路径以及配置阿里云镜像加速器,旨在帮助开发者,尤其是初次接触Docker的新手,快速搭建高效的本地容器开发环境,并解决国内镜像下载缓慢的痛点。

moon9的博客 476

程序自动化填写网页表单数据

如何让程序自动化填写网页表单数据,特别是涉及到批量数据情况时,可以减少人力。下面是涉及到的一些场景,都可以通过相关自动化程序实现。

Y 2427

【汇编 C++】C++继承浅谈

继承就是数据的复制struct Master // 父类(基类){int a;int b;};struct Slave:Master // 子类(派生类){int c;int d;};int main(){// 此处下断点查看x的大小(子类的大小)return 0;

qq_52572621的博客 744

小波变换(深入浅出)

小波变换

weixin_46713695的博客 3万+

基础:C++的继承机制

C++的继承机制4.6.1 继承的基本语法4.6.2 继承方式4.6.3 继承中的对象模型4.6.4 继承中构造和析构顺序4.6.5 继承同名成员处理方式4.6.6 继承同名静态成员处理方式4.6.7 多继承语法(不推荐使用)4.6.8 菱形继承 继承是面向对象三大特性之一 我们发现,定义这些类时,下级别的成员除了拥有上一级的共性,还有自己的特性。 这个时候我们就可以考虑利用继承的技术,减少重复代码 4.6.1 继承的基本语法 例如我们看到很多网站中,都有公共的头部,公共的底部,甚至公共的左侧列表,只有中心

david2000999的博客 345

TVS 管击穿电压与钳位电压的工程解析

TVS二极管的核心参数击穿电压(VBR)和钳位电压(VC)常被混淆,但二者具有本质区别。VBR是

硬核科技 480

YOLOv11改进策略【模型轻量化】| 替换骨干网络为 2024轻量化网络MoblieNetV4:移动生态系统的通用模型

一、本文介绍 本文记录的是基于MobileNet V4的YOLOv11目标检测轻量化改进方法研究。MobileNet V4通过整合UIB、Mobile MQA以及优化的NAS策略,能够在在不降低性能指标的前提下,降低计算成本。本文配置了原论文中MNv4-Conv-S、MNv4-Conv-M、MNv4-Conv-L、MNv4-Hybrid-M和MNv4-Hybrid-L五种模型,以满足不同的需求。 模型 参数量 计算量 推理速度 YOLOv11m 20.0M 67.6GFLOPs 3.5ms

Limiiiing的博客 4458

《C++反汇编与逆向分析技术揭秘》学习之第12章 从内存角度看继承和多重继承 (1)

本章讲解了对象之间发生继承和派生关系后的内存布局情况以及相关的处理和操作。因为对象之间的关系结构不同,所以它们的内存布局、构造函数、析构函数都有差别,这些是编译器作者为了实现C++的语法而设计的内存结构和执行代码。要分析由其他编译器创建的程序,可以先编写一些简单的语法示例(类似本章体现各个语法知识点的示例),然后用其他编译器编译,通过反汇编观察其内存布局、构造函数和析构函数的处理流程。

chenyijun的专栏 528

2026.3.21:Ubuntu26.04 apt换国内源 清华源 阿里源 中科大源 163源

作为 LTS 版本,它会有 5 年的常规维护和安全更新。如果订阅 Ubuntu Pro,还能享受额外7年的支持。也就是说, Ubuntu Pro将享有长达 12 年的系统更新保障!接下来,我们将重点介绍 Ubuntu 24.04 LTS 中那些值得关注的新特性,以方便你决定是否进行升级。Ubuntu 24.04 LTS,代号 「Noble Numbat」,即将与我们见面!Canonical 已经宣布, Ubuntu 24.04 LTS。源文件地址 已经更换为。

拥抱具身智能,昇腾Ascend C 9074

《C++反汇编与逆向分析技术揭秘》学习之第12章 从内存角度看继承和多重继承 (2)

本章讲解了对象之间发生继承和派生关系后的内存布局情况以及相关的处理和操作。因为对象之间的关系结构不同,所以它们的内存布局、构造函数、析构函数都有差别,这些是编译器作者为了实现C++的语法而设计的内存结构和执行代码。要分析由其他编译器创建的程序,可以先编写一些简单的语法示例(类似本章体现各个语法知识点的示例),然后用其他编译器编译,通过反汇编观察其内存布局、构造函数和析构函数的处理流程。

chenyijun的专栏 596

在 SAP BTP ABAP 环境里直连 ABAP On-Premise OData

摘要 SAP BTP ABAP Environment 2311版本后,OData集成链路迎来重大改进:Service Consumption Model升级为v2版本,通过压缩模型到单一类减少对象数量;通信管理推荐采用Communication Arrangement替代传统Destination,提供更清晰的治理边界。新版支持同时生成OData v2/v4消费模型,并通过标准工厂类创建代理。配置需关注四层对象:Outbound Service声明协议入口,Scenario定义认证方式,System描述通

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1920

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

C++反汇编第四讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式....

目录:   1.多重继承在内存中的表现形式     多重继承在汇编中的表现形式   2.菱形继承     普通的菱形继承     虚继承     汇编中的表现形式 一丶多重继承在内存中的表现形式 高级代码: class Father1 { public: Father1(){}//空构造 virtual ~Father1(){}...

weixin_30724853的博客 108

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

揭秘C++对象模型:成员函数指针中的this究竟如何绑定?

深入解析成员函数指针的 this 绑定机制,揭示C++对象模型中调用成员函数时this指针的底层绑定原理。涵盖多态、虚函数与函数指针的交互,适用于高性能回调设计与系统级编程,理解本质提升代码控制力,值得收藏。

IterLoom的博客 984

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

C++反汇编-继承和多重继承

学无止尽,积土成山,积水成渊-《C++反汇编与逆向分析技术揭秘》 读书笔记 一、单类继承 在父类中声明为私有的成员,子类对象无法直接访问,但是在子类对象的内存结构中,父类私有的成员数据依然存在。C++语法规定的访问限制仅限于编译层面,在编译过程中进行语法检查,因此访问控制不会影响对象的内存结构。 子类未提供构造函数或析构函数,而父类却需要构造函数与析构函数时,编译器会为子类提供默认的...

weixin_30649641的博客 377

继承和多继承反汇编

再看看第二个虚表指针指向的虚表:

静下心来,做好每一件事 1164

从反汇编角度深入理解C++继承和多态

从反汇编角度理解C++继承和多态

只为改变自己 1176

从汇编看c++多重继承中this指针的变化

先来看一下下面的c++源码: #include <iostream> using namespace std; class X { public: virtual void print1() { cout << "X::print1 = " << (long)this << endl; ...

chaoguo1234的专栏 425

C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式....

      C++反汇编第五讲,认识多重继承,菱形继承的内存结构,以及反汇编中的表现形式. 目录:   1.多重继承在内存中的表现形式     多重继承在汇编中的表现形式   2.菱形继承     普通的菱形继承     虚继承     汇编中的表现形式 一丶多重继承在内存中的表现形式 高级代码:    class Father1 { publ...

weixin_30247307的博客 66

C++多重继承对象模型深度解析(虚继承构造函数调用全过程曝光)

深入解析C++多重继承对象模型,揭秘虚继承的构造函数调用全过程。涵盖菱形继承场景、构造顺序规则与内存布局优化,助你掌握虚基类初始化机制,避免重复继承问题,提升程序稳定性,值得收藏。

SimTrans的博客 352

C++虚函数表的逆向工程实战:从内存布局到动态调用解析

本文深入探讨了C++虚函数表在逆向工程中的关键作用,详细解析了其内存布局和动态调用机制。通过VC2008编译环境下的实战案例,展示了如何利用调试器分析虚表指针和虚函数地址排列,帮助开发者掌握多态性在二进制层面的实现原理。

weixin_29011993的博客 581

深入C++底层原理(成员函数指针与this绑定全揭秘)

掌握成员函数指针的 this 绑定机制,深入解析C++底层原理。涵盖多态调用、类成员函数指针转换与通用回调实现方法,揭示隐式this传递的关键细节。适用于高性能框架设计与泛型编程,提升代码灵活性与执行效率,值得收藏。

CodeVibe的博客 788

汇编 align_C++ GCC 对象模型 从汇编代码分析虚函数、动态绑定原理 (Part 1)

写在前面(本专栏仅是个人笔记本,有胡言乱语和错漏之处, )这篇笔记结合汇编代码和fdump-class-hierarchy分析了GCC中多重继承下的对象在内存中的对象模型,以及虚函数表、动态绑定的底层实现。更具体的说,将一个派生类赋给基类指针(引用)时发生了什么?使用基类指针调用虚函数的时候又发生了什么?编译器会在这两个过程中做一些幕后工作,使得正确的虚函数被调用,正确的数据成员被访问。看完这篇笔...

weixin_39585070的博客 213
上一篇: 在Release版本中输出打印信息,实现TRACE功能
下一篇: 'scalar deleting destructor' 和 'vector deleting destructor'的区别
jiangdf
博客等级 码龄19年 86粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值