逆向程序分析:C++的一个空类,为什么在内存中占1字节

C/C++—— C++中一个空对象为什么还要占用一个字节空间 C++中一个空对象为什么还要占用一个字节空间? 阅读详情

普通的空类

空类的定义

空类就是没有任何数据成员的类。

空类的内存大小

按道理讲,没有数据成员,就不会占用内存,那么空类的大小就为0。
但是真实场景下,即便是空类在内存中,也占一个字节。

#include <iostream>
class CPeople
{

};

int main()
{
    std::cout << "sizeof(CPeople): " << sizeof(CPeople) << std::endl;
    CPeople *v1;
    return 0;
}

输出结果为:

sizeof(CPeople): 1

为了对比,我们建一个新类,里面增加一个数据成员。


#include <iostream>
class A
{

};

class B
{
    int i;
};

int main()
{
    std::cout << "sizeof(A): " << sizeof(A) << std::endl;
    std::cout << "sizeof(B): " << sizeof(B) << std::endl;

    return 0;
}


输出结果为:

sizeof(A): 1
sizeof(B): 4

为什么呢?

从其他地方看到的解释:

C++标准指出,
不允许一个对象(当然包括类对象)的大小为0,不同的对象不能具有相同的地址。
这是由于:
new需要分配不同的内存地址,不能分配内存大小为0的空间
避免除以 sizeof(T)时得到除以0错误 故使用一个字节来区分空类。

带有虚函数的空类

虚类空类在内存中的大小

给空类A加一个虚成员函数,那么这个类也变成了虚类。

#include <iostream>
class A
{
public:
    virtual int a() {
        
    }
};

class B
{
public:
    virtual int b() { }
    int i;
};

int main()
{
    
    std::cout << "sizeof(A): " << sizeof(A) << std::endl;
    std::cout << "sizeof(B): " << sizeof(B) << std::endl;

    return 0;
}


输出结果:

sizeof(A): 4
sizeof(B): 8

为什么?

因为,虚类中有一个虚表存放着虚函数的地址,虚类对象调用虚函数的时候,是通过虚表指针去寻址的,所以内存中存放着虚表指针,在32位下,占4字节。
在这里插入图片描述

A::A:
00A716E0 55                   push        ebp  
00A716E1 8B EC                mov         ebp,esp  
00A716E3 81 EC CC 00 00 00    sub         esp,0CCh  
00A716E9 53                   push        ebx  
00A716EA 56                   push        esi  
00A716EB 57                   push        edi  
00A716EC 51                   push        ecx  
00A716ED 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  
00A716F3 B9 33 00 00 00       mov         ecx,33h  
00A716F8 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00A716FD F3 AB                rep stos    dword ptr es:[edi]  
00A716FF 59                   pop         ecx  
00A71700 89 4D F8             mov         dword ptr [this],ecx  
00A71703 8B 45 F8             mov         eax,dword ptr [this]  
00A71706 C7 00 34 6B A7 00    mov         dword ptr [eax],offset A::`vftable' (0A76B34h)  
00A7170C 8B 45 F8             mov         eax,dword ptr [this]  
00A7170F 5F                   pop         edi  
00A71710 5E                   pop         esi  
00A71711 5B                   pop         ebx  
00A71712 8B E5                mov         esp,ebp  
00A71714 5D                   pop         ebp  
00A71715 C3                   ret  
第八章 Android 原生程序开发与逆向分析(六)(原生 C++ 程序逆向分析 - C++ 类的逆向分析) 文章目录C++ 类的逆向分析 C++ 类的逆向分析 实例:app8.cpp #include <iostream> #include <stdio.h> class Person { public: Person() { age = 31; printf("Person: Person() called\n"); ... 阅读详情

相关推荐

微信小程序逆向解密

拿到解密出的文件后可以用相应的解包脚本进行解压,网上不乏解压脚本,遗憾的是笔者并没有找到能够彻底解压并且还原出微信开发者工具能够识别的对应各式的文件(微信开发者工具对js等的样式做了一层封装,想要能够调试源代码需要将解包后的文件还原成其能够识别的格式,网上确实有相关脚本,但大多比较老,微信开发工具对样式进行了更新,格式化出现了一些问题,笔者水平有限,就不去修复。事实确实如此,我们取消硬件断点,在上一步断下出的循环中循环几次简单分析就可以确定,这确实是一个解密点,而且是非常简单的异或解密。

2503_90751789的博客 3356

C++中空类占一字节原因详解

C++中空类占一字节原因详解 - XSH的博客 - 优快云博客https://blog.youkuaiyun.com/xiong452980729/article/details/71077144 在C++中空类会占一个字节,这是为了让对象的实例能够相互区别。具体来说,空类同样可以被实例化,并且每个实例在内存中都有独一无二的地址,因此,编译器会给空类隐含加上一个字节,这样空类实例化之后就会拥有独一无...

MatthewMao 698

Android逆向分析

Android 逆向开发是指对已发布的 Android 应用进行分析和破解,以了解应用程序的内部工作原理,获取应用程序的敏感信息,或者修改应用程序的行为。Android应用 Java编写的,利用Android SDK编译代码,并并且把所有的数据和资源文件打包成一个APK(Android Package)文件这是一个后缀名为.apk的压缩文件,apk文件中包含了一个Anddroid应用程序的所有内容,是Android平台用于安装应用程序的文件。

qq_51598534的博客 6294

20170814_为什么C++ 中空类的大小是1个字节?

为什么C++ 中空类的大小是1个字节?

风暴计划 1044

Unity IL2CPP逆向实战:Cpp2IL工具原理与逆向分析全解析

在软件逆向工程领域,理解编译后程序的内部逻辑是安全分析、漏洞挖掘和竞品研究的基础。传统.NET程序可通过中间语言(IL)进行反编译分析,但Unity引擎的IL2CPP技术将C#代码编译为C++并进一步优化为原生机器码,导致符号信息和代码结构严重丢失,形成逆向分析的“黑盒”。Cpp2IL作为专门针对IL2CPP的逆向工具,通过解析global-metadata.dat元数据文件和游戏二进制文件,重建出可读的IL代码和类型系统,其核心价值在于突破了IL2CPP的逆向壁垒。该工具在游戏安全审计、外挂原理分析、协议

weixin_34306593的博客 449

游戏逆向实战:C++内存管理与虚函数表解析

在软件逆向工程领域,理解程序在内存中的运行机制是核心基础。从计算机科学原理出发,程序编译后形成的二进制代码在内存中遵循特定的布局规则,这涉及到指针寻址、数据结构对齐和函数调用约定等底层概念。这些原理在游戏逆向中具有极高的技术价值,因为现代游戏引擎普遍采用C++编写,其面向对象特性如虚函数表(VTable)和多态机制,直接决定了游戏对象在内存中的组织方式。掌握内存布局分析和VTable解析,能够帮助开发者或安全研究人员定位关键游戏逻辑、数据结构和函数调用流,广泛应用于单机游戏分析、安全研究和软件调试等场景。本

weixin_30843121的博客 916

为什么C++空类的大小是1个字节

#include class EmptyA {}; int main() { std::cout << "sizeof EmptyA " << sizeof(EmptyA) << std::endl; return 0; }; 结果如下: sizeof EmptyA 1 然而在C语言中空结构体的大小是0,空结构体大小是0我们貌似可以理解,但为什么到C++中,空类的大小却是1呢? 实际上, 这是类结构体实例化的原因, 空的类或结构体同样可以被实例化, 如果定义对空的类或者

FUHAILIANG_2015的博客 2509

C++游戏逆向实战:从内存操作到Hook技术的完整路径

游戏逆向工程是深入理解软件运行机制的重要领域,其核心在于分析已编译程序的内存结构、数据流和逻辑流程。从原理上看,程序在内存中的布局直接反映了源代码的数据结构设计,尤其是C++这类系统级语言编写的应用。掌握内存操作、指针运算和数据结构对齐等底层知识,能够帮助开发者准确解读程序运行时的状态。这项技术的工程价值在于,它不仅是安全研究和漏洞分析的基础,也是性能优化、兼容性调试和遗留系统维护的关键手段。在实际应用场景中,游戏逆向常被用于单机游戏模组开发、反作弊机制研究、以及软件行为分析等。本文聚焦于C++在游戏逆向中

weixin_34242819的博客 506

C++中空的结构、类对象为什么是1字节?

结构、类中可以有成员函数。 成员函数需要识别哪个对象调用的它,它需要获取到对象地址。 0字节的结构、类对象,在内存中没有存储位置也就没有了对象地址,这样就无法调用成员函数了。 所以为了让对象能正常调用成员函数,C++规定空的结构,类对象填充一个字节,为对象在内存中占据一个位置,这样对象就有的地址来传递给成员函数了。 ...

iiicesea的博客 405

C++实现内存特征码定位:游戏安全逆向分析实战指南

在软件逆向工程与安全分析领域,内存特征码定位是一项基础且关键的技术。其核心原理是在程序的内存映像中,通过匹配一段独特的字节序列来快速定位目标函数或数据结构的地址,类似于通过DNA比对锁定目标。这项技术的核心价值在于其不依赖符号信息,对代码混淆和加壳具有一定的抵抗能力,能极大提升在大型、复杂或频繁更新的二进制程序(如现代游戏客户端)中定位关键代码的效率。从工程实践角度看,它广泛应用于游戏安全研究、反作弊系统分析、漏洞挖掘以及软件兼容性测试等场景。本文将以C++为工具,详细拆解如何构建一个高效、稳定的内存特征码

weixin_32175665的博客 275

S7-200 Smart 控制运动轴(脉冲电机/伺服)教程

S7-200 Smart 控制运动轴(脉冲电机/伺服) 结合本人刚接触触摸屏时候的踩坑经验,编写S7-200 Smart 控制运动轴(脉冲电机/伺服)的详细流程,给刚接触PLC的朋友提供一些经验指导。 本文详细介绍了S7-200 Smart 控制脉冲步进/伺服电机流程,包含接线方法及梯形图。希望对初学者有所帮助

xjbsw0的博客 5万+

C/C++逆向:结构体逆向分析

在C/C++程序的逆向分析中,结构体的逆向分析是非常重要的。结构体是C/C++中管理和组织数据的一种主要方式。了解它们的布局可以帮助你理解程序是如何存储、处理和传递数据的,结构体常用于组织和管理复杂的数据,理解结构体有助于我们更好地还原程序的逻辑、推断数据布局,并解读与操作这些数据的函数。因此,识别并分析结构体可以帮助你更全面地理解程序的内存布局和数据流。接着我们可以来简单说一下如何识别结构体。

WolvenSec的博客 1847

别再乱选离散化方法了!从零到一用Matlab对比差分、双线性Tustin和预矫正的实战效果

本文深入探讨了Matlab中四种主流离散化方法(差分、双线性Tustin和预矫正)的实战效果对比,帮助工程师在数字控制系统设计中做出明智选择。通过详细的理论分析和Matlab代码示例,展示了不同方法在稳定性、频率响应和计算复杂度上的差异,并提供了针对不同场景的工程选用指南。

weixin_28737603的博客 141

1.逆向基础

逆向基础逆向真的是一个很宏大的话题,而且大多数都是相当复杂且繁琐的,我目前对其了解的其实也并不深。但既然C/C++都学了,不学一下逆向,又总会有点不得劲的感觉。所以本系列就想尝试一下,看能不能写好逆向这一领域的相关东西。不过由于我目前对逆向了解的真的不够多,所以本系列教程的第一版,大部分内容都会直接采用**《加密与解密》**这本书的结构与知识点分布进行讲解。当然,我也不可能直接复制粘贴。因为这书说实话,其实也有点年代感了,很多东西现在看来并不是很适用,并且新手估计也很难理解书中的专业术语。

余识- 3257

运维与软件实施课表

运维与软件实施课表 课程 章节编号 章节 课程地址 软件及操作系统基础 ch01 软件及操作系统基础01 实施、运维工程师基本技能:https://blog.youkuaiyun.com/qq_28189423/article/details/82700539 老毛桃制作winPE镜像:https://blog.youkuaiyun.com/qq_2818942...

Mr.O~的博客 1万+

6-2 GPU GART 绑定机制与 TLB 失效

本文详细解析了AMD GPU的GART(Graphics Address Remapping Table)绑定机制实现。主要内容包括: 绑定流程:从ttm_tt_bind()到硬件PTE更新的完整调用链,重点分析amdgpu_gart_bind()函数实现。 关键函数: amdgpu_gart_bind():执行安全检查、记录映射关系、更新页表等操作 amdgpu_gart_map():将CPU页映射为多个GPU页并填充PTE amdgpu_gmc_set_pte_pde():处理硬件特定的PTE格式 内存

图形/计算GPU的驱动与虚拟化技术分享园地 2656

C/C++逆向:虚函数逆向分析

(Virtual Function)是C++中实现的一种机制,它允许在运行时通过基类的指针或引用调用派生类中的函数,而不是基类中的版本。虚函数通常与和结合使用。通过在基类中使用virtual关键字声明函数,允许派生类重写该函数。当通过基类指针或引用调用时,根据对象的实际类型决定调用哪个版本的函数;它依赖虚函数表(vtable)实现,用于动态绑定,常用于多态场景下的接口设计和扩展。每个包含虚函数的类都有一张虚函数表:如果类没有派生类,则虚函数表存储类自身的虚函数地址。

WolvenSec的博客 1714

Jenkins自动化部署服务到Kubernetes环境

通过Jenkins实现自动化部署可以大大提高软件交付的效率和质量。本文介绍的部署流程涵盖了从代码编译、Maven依赖管理、Docker镜像构建到Kubernetes部署的完整流程,并提供了通知机制以便及时了解部署状态。特别需要注意的是Maven与私服的配置,这是确保构建过程能够正常访问依赖包的关键。通过Jenkins的凭据管理功能,可以安全地管理私服的认证信息,避免敏感信息泄露。在实际应用中,您可能需要根据具体的项目需求和环境特点调整部署脚本。

探索云原生与智能化驱动下的安全运维新范式。关注DevSecOps、可观测性、AIOps等前沿领域,与您共赴技术前沿。 528

C/C++逆向:数组逆向分析

数组在逆向工程中是一个重要的分析对象,数组是存储数据的重要数据结构,尤其在程序中用于存储一系列相同类型的元素。通过逆向分析数组,可以理解程序是如何处理和组织这些数据的,从而揭示程序的内部逻辑。在软件安全领域,逆向分析数组可以帮助安全研究人员发现程序中的潜在安全漏洞,例如缓冲区溢出、数组越界访问等。这些漏洞可能会被恶意利用,因此通过逆向分析可以增强软件的安全性。

WolvenSec的博客 1175

锁的艺术:Java并发中的常用锁策略与实践

对java锁相关内容进行整理分析:乐观锁 VS 悲观锁+自旋锁 VS 适应性自旋锁+无锁 VS 偏向锁 VS 轻量级锁 VS 重量级锁+公平锁 VS 非公平锁+可重入锁 VS 非可重入锁+独享锁 VS 共享锁

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 171万+

Far planner 部署真实小车 & 树莓派部署lego_loam

今天开一贴Far planner的部署,也算是lego loam的部署吧 因为state_estimation用的是lego loam小车底盘: 轮趣的mini差速底盘外加多一层钢板,中间层用来放velodyne的电池(小的电池还没到,大的电池塞不进去目前)和velodyne信号盒子。前面还可以加一个相机。底层用来放小车的电池和马达等设备了,底层不用动。最上面一层用来安装velodyne16线雷达,需要额外钻孔(如果买轮趣的话可以找老板钻个孔?我也不确定,我自己钻的)。 雷达固定螺丝用的是 1/4-20*3

博客 4303

C/C++逆向:对象布局&thiscall

在逆向工程中,类的逆向分析非常重要,尤其逆向分析的对象为面向对象的编程语言(如C++)所编写的程序时类的分析就显得更加重要。这是因为类结构往往承载了程序的核心逻辑和设计模式。通过还原类的结构、继承关系和成员函数,逆向工程师能够理解程序的整体架构、功能实现以及开发者的设计意图,从而有效识别关键模块、提升分析效率。类的分析比结构体更复杂,因为类除了数据成员外,还包含了方法(函数)和继承关系。

WolvenSec的博客 1288

AI Agent在医疗诊断中的智能应用研究

本文探讨了AIAgent在医疗诊断中的智能应用,分析了其技术原理、实际案例及发展挑战。AIAgent通过机器学习算法处理医疗数据,提升诊断准确性和效率,市场规模预计2025年达200亿美元。核心技术包括数据预处理、深度学习模型和隐私保护方法。应用案例涵盖肺癌筛查、阿尔茨海默病预测等,但面临数据偏差、伦理责任等挑战。未来趋势包括多模态学习、个性化医疗和量子计算融合。随着技术优化和伦理完善,AIAgent将成为医疗体系的重要组成部分。

郑伟强dev的专栏 96

C++内存汇编逆向安全全集

法律声明:教程不会涉及指定公司的网游测试,不会提供任何游戏的数据或者侵害游戏公司的版本问题。教程目的是数据分析原理和提高安全技术。逆向技术必须按照国家法律来实施。测试的游戏纯属技术研究,禁止非法用途。 第1章:底层C和汇编知识(19节基础知识,从0开始) 学习建议,前言。为什么学习C++ 站在制高点 逆向讲解分析,数据分析,注入源码 开发环境vs2017安装和搭建 初次逆向分析C++程序 变量逆向...

mutashizhe的博客 1133

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

从逆向分析角度看C++虚函数

从逆向分析角度,粗略地分析了虚拟表的结构,本人才疏学浅,有误之处,望各位指正

个人技术博客 6220

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

逆向分析实战(第一章)

逆向实战分析(笔记+实战) 不断更新哦!!!

2301_80175230的博客 2761

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: 俩句话理解VS的MT/MD和MTD/MDD。
下一篇: 工程实践:C++接口设计指北
CodeBowl
博客等级 码龄5年 7664粉丝 67原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值