c++反汇编与逆向分析技术揭秘_C++反汇编与逆向分析技术揭秘

4b21441e8d1fdecc38c94eddc88c8fcc.png

一、单类继承

  • 在父类中声明为私有的成员,子类对象无法直接访问,但是在子类对象的内存结构中,父类私有的成员数据依然存在。C++语法规定的访问限制仅限于编译层面,在编译过程中进行语法检查,因此访问控制不会影响对象的内存结构。
  • 子类未提供构造函数或析构函数,而父类却需要构造函数与析构函数时,编译器会为子类提供默认的构造函数与析构函数。但是子类有构造函数,而父类不存在构造函数,且没有虚函数,则编译器不会为父类提供默认的构造函数。1. 内存结构:
    ①先安排父类的数据
    ②后安排子类新定义的数据说明:基于上述的内存排列方法,即父类数据成员被安排前面。不管是父类的对象,还是子类的对象,父类的数据成员在内存中相对于对象的首地址的偏移值都是一样的。而且成员数据访问都是基于this指针间接寻址的。所以,对于子类对象而言,使用父类指针或者子类指针都可以正确访问其父类数据。2. 虚表:
    虚表的排列顺序是按虚函数在类继承层次中首次声明的顺序依次排列的。只要继承了父类,其派生类的虚函数表中的父类部分的排列就与父类一样。子类新定义的虚函数会按照声明顺序紧跟其后。 3. 构造函数:
    ①先调用父类构造函数
    ②然后按照声明顺序调用成员数据变量的构造函数和初始化列表中指定的成员
    ③最后再执行子类构造函数的函数体。说明
    ①父类构造函数,虚表指针修改为指向父类的虚表,所以在父类构造函数内调用虚函数,调用的是父类的虚函数。
    ②子类构造函数,虚表指针修改为指向子类的虚表4. 析构函数:
    ①先调用子类析造函数
    ②然后成员对象的析构函数,按照声明的顺序以倒序方式依次调用成员对象的析构函数。
    ③再执行父类构造函数说明
  • 析构函数执行会首先设置虚表指针为自身虚表,再调用自身的析构函数。防止父类析构函数内调用子类对象的虚函数。
  • 类有派生与继承关系,需要声明析构函数为虚函数。若析构函数不是虚函数时,当使用父类指针指向堆中的子类对象,并使用delete释放对象空间时,编译器会按照指针类型调用父类的析构函数,从而引发错误。

识别类之间的关系:
先定位构造函数,根据构造先后顺序得到与之相关的其他类。
再根据虚表,利用IDA中使用引用参考功能可得到所有的构造和析构函数。

二、多重继承1. 内存排列:

  • 数据成员的排列顺序由继承父类的先后顺序所决定,从左向右依次排列。
  • 子类虚表指针的个数取决于所继承的父类的个数,有几个父类便对应几个虚表指针(虚基类除外)。
  • 将一个子类对象赋值给某个父类指针时,该父类指针便指向该父类所对应的虚表指针。

三、单类继承与多重继承比较:

  • 单继承类
    • 在类对象占用的内存空间中,只保存一份虚表指针
    • 只有一个虚表指针,对应的也只有一个虚表
    • 虚表中各项保存了类中各虚函数的首地址
    • 构造时先构造父类,再构造自身,并且只调用一次父类构造函数
    • 析构时限析构自身,再析构父类,并且只调用一次父类析构函数
  • 多重继承类
    • 在类中所占用的内存空间中,根据继承父类的个数保存对应的虚表指针
    • 根据所保存的虚表指针的个数,对应产生相应个数的虚表。
    • 转换父类指针时,需要跳转到对象的首地址。
    • 构造时需要按照继承顺序调用多个父类构造函数。
    • 析构时先析构自身,然后以与构造函数相反的顺序调用所有父类的析构函数
    • 当对象作为成员时,整个类对象的内存结构和多重继承相似。当类中无虚函数时,整个类对象内存结构和多重继承完全一样,可酌情还原;当父类或成员对象存在虚函数时,通过过观察虚表指针的位置和构造函数、析构函数中填写虚表指针的数目及目标地址,来还原继承或成员关系。

四、工程案例分析

1. 单类继承:

#include <iostream>

using namespace std;

class Base {

public:

Base(){ nBase= 1;printf("CBase"); }

~Base(){ printf("~CBase"); }

virtual void f() { printf("Base:f()");}

virtual void g() { printf("Base:g()");}

private:

int nBase;

};

class Derive : public Base {

public:

Derive(){ nDerive=2;printf("Derive"); }

~Derive(){ printf("~Derive"); }

virtual void g(){ printf("Dervie:g()");}

virtual void h(){ printf("Dervie:h()");}

private:

int nDerive;

};

int main()

{

Derive d;

Base *b = &d;

b->g();

return 0;

}

1. 内存分布

类Derive对象

0019FD30 0139583C =>.rdata:const Derive::`vftable'

0019FD34 00000001 =>Base.nBase

0019FD38 00000002 =>Derive.nDerive

虚函数表

0139583C 01391163 Base::f(void)

01395840 0139110E Derive::g(void)

01395844 013911AE Derive::h(void)

2. 构造函数

pop ecx ;=>this指针出栈

mov [ebp+this], ecx ;=>保存this指针

mov ecx, [ebp+this]

call j_??0Base@@QAE@XZ ;=>调用基类构造函数Base::Base(void)

mov eax, [ebp+this] ;=>eax=this指针

mov dword ptr [eax], offset ??_7Derive@@6B@ ;=>初始化虚表指针为const Derive::`vftable'

3. 析构函数

pop ecx ;=>this指针出栈

mov [ebp+this], ecx ;=>保存this指针

mov eax, [ebp+this]

mov dword ptr [eax], offset ??_7Derive@@6B@ ;=>重置虚表指针为const Derive::`vftable'

mov esi, esp

push offset aDerive ; "~Derive"

call ds:__imp__printf

add esp, 4

cmp esi, esp

call j___RTC_CheckEsp

mov ecx, [ebp+this] ;=>ecx传参this指针

call j_??1Base@@QAE@XZ ; =>调用基类析构函数 Base::~Base(void)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246015.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

std::atomic原子操作

第十一节std::atomic原子操作_HITXJ的博客-CSDN博客_std::atomic用法

php与mysql列表_PHP+Mysql+jQuery实现的查询和列表框选择

本篇文章主要介绍PHPMysqljQuery实现的查询和列表框选择&#xff0c;感兴趣的朋友参考下&#xff0c;希望对大家有所帮助。本文讲解如何通过ajax查询mysql数据&#xff0c;并将返回的数据显示在待选列表中&#xff0c;再通过选择最终将选项加入到已选区&#xff0c;可以用在许多…

range函数python2和3区别_range函数python2和3区别

range函数是一个用来创建算数级数序列的通用函数&#xff0c;返回一个[start, start step, start 2 * step, ...]结构的整数序列&#xff1b;py2中的range()函数用法&#xff1a;&#xff08;推荐学习&#xff1a;Python视频教程&#xff09; range()返回的是一个列表>>&…

Unity SRP自定义渲染管线 -- 2.Custom Shaders

本章将接着上一篇文章&#xff0c;在初步实现一个渲染管线后来创建自定义的shader。上一篇文章的链接 https://blog.csdn.net/yinfourever/article/details/90516602。在本章中&#xff0c;将完成以下内容&#xff1a; 写一个HLSL Shader定义constant buffer&#xff08;常量缓…

tcp 三次握手与四次挥手_TCP三次握手与四次挥手详解

TCP报文结构源端口和目的端口&#xff1a;各占2个字节&#xff0c;分别写入源端口号和目的端口号。序号&#xff1a;占4个字节。序号使用mod运算。TCP是面向字节流的&#xff0c;在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。故该字段也叫做“报文段序号”。确认序…

网关和路由器的区别_5G工业路由器与5G DTU的区别介绍详解

5G工业路由器和5G DTU都是实现无线网络数据传输功能&#xff0c;而两者间的区别主要从使用方法、外观接口以及应用环境等方面区分&#xff0c;今天给大家介绍5G工业路由器和5G DTU的一些不同点。使用方法的不同:5G工业路由器&#xff1a;5G路由器可对以太网、现场总线通信协议进…

7628刷breed_自制各类路由原厂直刷Breed的文件,无需修改mac无需重刷无线

本帖最后由 showme99 于 2017-3-25 16:35 编辑在原厂页面直接选择相应的刷机文件刷机&#xff0c;文件很小256K&#xff0c;大约十秒左右就自动进入Breed后直接刷入dd-wrt,opentwrt,gargoyle等固件即可。无需在Breed里设置MAC地址&#xff0c;也无需刷入ART无线文件&#xff0c…

c语言获取系统剩余内存_C语言编程中的“堆”和“栈”七大不同之处

更多精彩&#xff0c;请点击上方蓝字关注我们&#xff01;对于编程初学者来说会接触到一些难以理解的名称&#xff0c;比如堆(heap)、栈(stack)、堆栈(stack)等。初学开发过程中往往让人混淆不清。今天我们来谈谈堆和栈的具体区别&#xff0c;来帮助初学者理清思路。堆和栈的区…

sql between包括两端吗_SQL大全

作者&#xff1a;静默虚空排版&#xff1a;MarkerHub原文&#xff1a;https://juejin.im/post/5c7e524af265da2d914db18f本文针对关系型数据库的一般语法。限于篇幅&#xff0c;本文侧重说明用法&#xff0c;不会展开讲解特性、原理。一、基本概念数据库术语数据库(database) -…

python交互模式什么意思_Python中的交互模式是什么

让开发者能快速学习、测试 Python 的各种功能&#xff0c;Python 提供的“python”命令不仅能用于运行 Python 程序&#xff0c;也可作为一个交互式解释器一一开发者逐行输入 Python 代码&#xff0c;它逐行解释执行。 当输入“python”命令时&#xff0c;可以看到如下输出结果…

idea创建springboot项目+mybatis_Spring Boot + MyBatis 多模块项目搭建教程

Java后端&#xff0c;选择“”优质文章&#xff0c;及时送达作者 | 枫本非凡链接 | cnblogs.com/orzlin/p/9717399.html上篇 | IDEA 远程一键部署 Spring Boot 到 Docker一、前言最近公司项目准备开始重构&#xff0c;框架选定为SpringBootMybatis&#xff0c;本篇主要记录了在…

下载nodejs的mysql安装包下载安装_Node.js安装 下载

1、安装Node.jshttps://nodejs.org/en/安装步骤&#xff1a;点击安装包按提示进行安装Node.js 安装配置本章节我们将向大家介绍在 Windows 和 Linux 上安装 Node.js 的方法。本安装教程以 Node.js v4.4.3 LTS(长期支持版本)版本为例。你可以根据不同平台系统选择你需要的 Node.…

redistemplate注入为null_Windows DLL 注入技术

Windows DLL 注入技术 本文主要介绍四种常见的 Windows DLL 注入技术。分别为全局钩子、远线程钩子、突破 SESSION 0 隔离的远线程注入和 APC 注入。全局钩子注入Windows 中大部分应用是基于 Windows 的消息机制&#xff0c;Windows提供截获这些消息的钩子函数。根据钩子作用的…

nginx location 正则表达式匹配多个地址_就是要让你搞懂Nginx,这篇就够了!

Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;特点是占用内存少&#xff0c;并发能力强&#xff0c;事实上 Nginx 的并发能力确实在同类型的网页服务器中表现较好。Nginx 专为性能优化而开发&#xff0c;性能是其最重要的要求&#xff0c;十分注重效率&#xff0c;有…

mysql查询网址_bootstrap+flask+mysql实现网站查询

之前那篇文章是flaskredis的&#xff0c;如果用flaskmysql怎么实现呢&#xff1f;创建数据库&#xff1a;CREATE DATABASE web12306 DEFAULT CHARACTER SET utf8;创建表&#xff1a;CREATE TABLE web12306 (user_email varchar(100) NOT NULL DEFAULT ,user_pass varchar(100)…

dubbo官方文档_不可忽视的Dubbo线程池

问题描述线上突然出现Dubbo超时调用&#xff0c;时间刚好为Consumer端设置的超时时间。有好几个不同的接口都报超时了第1次调用超时&#xff0c;第2次&#xff08;或第3次&#xff09;重试调用非常快&#xff08;正常水平&#xff09;Dubbo调用超时的情况集中出现了3次&#xf…

python中比较重要的几个函数_Python 几个重要的内置函数 python中的内置函数和关键字需要背过吗...

python重要的几个内置函数用法python内置函数什么用忘不掉的是回忆&#xff0c;继续的是生活&#xff0c;错过的&#xff0c;就当是路过吧。来来往往身边出现很多人&#xff0c;总有一个位置&#xff0c;一直没有变。看看温暖的阳光&#xff0c;偶尔还是会想一想。Python内置函…

netty worker线程数量_Dubbo线程模型

Dubbo中线程池的应用还是比较广泛的&#xff0c;按照consumer端到provider的RPC的方向来看&#xff0c;consumer端的应用业务线程到netty线程、consuemr端dubbo业务线程池&#xff0c;到provider端的netty boss线程、worker线程和dubbo业务线程池等。这些线程各司其职相互配合&…

function click_click事件的累加问题解决

click事件的 累加问题解决&#xff1a;$判断是否隐藏&#xff1a;hidden.c>span 只包含儿子.c span 包含儿子和孙子data-*嵌入自定义数据 .data(to)获取数据remove是移除标签 delete删除数组元素each()函数$(".layui-table-total .layui-table-cell").each(functi…

知道python语言应用2020答案_热点:大学moocPython语言基础与应用答案

2020年智慧树网课答案为您详细解读azMisb热点&#xff1a;大学moocPython语言基础与应用答案的详情,题主的教授应该是想要同学们找出一个值得研究和讨论的theory&#xff0c;简单来说就是你论文探讨的中心。然后需要你们定topic&#xff0c;然后搜索大量靠谱的资料&#xff0c;…