对象不使用默认析构函数

class Test
{
public:
char cNum1;
int iNum2;
int* pInt;
}; Test _ReturnObject()
{
Test stLocalObject;
stLocalObject.cNum1 = 0;
stLocalObject.iNum2 = 1; stLocalObject.pInt = new int;
*stLocalObject.pInt = 0x55;
return stLocalObject;
} int main(int argc, char* argv[])
{
Test stObject;
stObject = _ReturnObject(); return 0;
}

分析以上代码的反汇编代码,发现编译器并没有调用析构函数。其会将_ReturnObject()函数内的局部对象先保存到main函数的栈空间中(实际是在函数内部调用了拷贝构造函数,进行了对象的复制),返回值eax为其首地址,接着会将保存在此处的对象复制到另一处栈空间中,接着利用此栈空间对接收返回对象的实际对象赋值。



我们产生疑问!既然eax地址处和从eax复制的另一处栈地址处都保存着返回对象的数据,是否两处地址都可以认为是实际的对象。如果其是实际的对象那么其一定会再生命周期快结束时调用析构函数,因为这里编译器没有调用默认的析构函数所以我们无法判断,我们下面需要自己指定析构函数来分析。

对象使用析构函数

我们在上述代码的基础上加上自己的析构函数,此析构函数会将对象动态申请的内存释放掉。

~Test()
{
if(pInt != NULL)
delete pInt;
}

我们查看其对应的汇编代码,发现其在对象返回的过程中将对象保存到eax地址后,直接将eax地址对应的对象保存到stObject中,当然这两处的对象也会分别调用析构函数。此eax地址对应的对象被称为临时对象,临时对象的生命周期仅限当前语句,因此当执行完stObject = _ReturnObject();语句后临时对象就会调用析构函数。(我们可以看到在一开始其就会为临时对象在栈中申请内存空间,接着让临时对象的地址作为参数入栈从而在_ReturnObject函数内部对临时对象进行复制)



值得注意的是我们这里的代码是会报错的,因为返回对象在_ReturnObject函数结束时就会调用析构函数将int* pInt对应的内存给撤销了,当eax地址对应的临时对象在调用析构函数是就会报错。(因为我们没有定义拷贝构造函数,所以其在复制对象时使用默认的浅拷贝构造函数)要想避免这样的错误我们需要自己定义拷贝构造函数(深拷贝)。

临时对象

临时对象存在是为了可以使代码编写者像这样_ReturnObject().cNum1在返回对象后直接使用相关数据成员。

不使用临时对象

如果我们用此形式 Test stObject = _ReturnObject(); 直接调用返回对象的函数则会以定义的实际对象的地址为参数而不是以临时对象的地址为参数,从而不使用临时对象。

使用拷贝构造函数

Test(Test& Object)
{
cNum1 = Object.cNum1;
iNum2 = Object.iNum2;
pInt = Object.pInt; }

我们来给类加上我们的拷贝构造函数,我们发现在_ReturnObject函数结束前会利用调用拷贝构造函数实现将返回对象保存到临时对象下(对象的复制),从而实现“返回对象”。

浅拷贝和深拷贝

浅拷贝和深拷贝主要是针对C++类中存在指针型数据成员而言的。浅拷贝就是单纯的进行成员值的复制,而深拷贝是对指针型变量所指向的内存重新申请新的内存,并将内存中的数据复制过去。上面我们所给出的拷贝构造函数就是一个典型的浅拷贝(默认拷贝构造函数也是浅拷贝)。

c++逆向分析----返回对象的更多相关文章

  1. HQL查询——查询返回对象类型分析

    关于HQL查询,我们可以结合hibernate的API文档,重点围绕org.hibernate.Query接口,分析其方法,此接口的实例对象是通过通过session.对象的creatQuery(Str ...

  2. C++反汇编与逆向分析技术揭秘

    C++反汇编-继承和多重继承   学无止尽,积土成山,积水成渊-<C++反汇编与逆向分析技术揭秘> 读书笔记 一.单类继承 在父类中声明为私有的成员,子类对象无法直接访问,但是在子类对象的 ...

  3. Android逆向分析(2) APK的打包与安装背后的故事

    前言 上一次我们反编译了手Q,并遇到了Apktool反编译直接crash的问题,虽然笔者很想在这次解决这个问题,但在解决途中,发现该保护依赖于很多知识,所以本次先插入一下,正所谓知其然知其所以然,授之 ...

  4. Android逆向分析(2) APK的打包与安装

    http://blog.zhaiyifan.cn/2016/02/13/android-reverse-2/ 2/18日增加对aidl和java编译的描述. 前言 上一次我们反编译了手Q,并遇到了Ap ...

  5. [Android Security] Smali和逆向分析

    copy : https://blog.csdn.net/u012573920/article/details/44034397 1.Smali简介 Smali是Dalvik的寄存器语言,它与Java ...

  6. RE-1 逆向分析基础

    逆向分析基础 0x01-0x0C 本笔记使用汇编指令为x86架构下汇编指令,ARM架构汇编指令不做介绍 0x01. 关于RE 逆向工程(Reverse Engineering RE) 逆向分析方法: ...

  7. 《C++反汇编与逆向分析技术揭秘》--认识启动函数,找到用户入口

    <C++反汇编与逆向分析>和<程序员的自我修养>都是以VC6的代码作为例子讲解的.这里是在vs2017下,CRT代码有些区别,但整体流程上都是初始化环境,设置参数,最后转到用户 ...

  8. 病毒木马查杀实战第012篇:QQ盗号木马之逆向分析

    前言 在本系列的文章中,对每一个病毒分析的最后一个部分,若无特殊情况,我都会采用逆向分析的手段来为读者彻底剖析目标病毒.但是之前的"熊猫烧香"病毒,我用了三篇文章的篇幅(每篇250 ...

  9. 【C++】从零开始的CS:GO逆向分析3——写出一个透视

    [C++]从零开始的CS:GO逆向分析3--写出一个透视 本篇内容包括: 1. 透视实现的方法介绍 2. 通过进程名获取进程id和进程句柄 3. 通过进程id获取进程中的模块信息(模块大小,模块地址, ...

随机推荐

  1. 【python+selenium的web自动化】- 针对上传操作的实现方案

    如果想从头学起selenium,可以去看看这个系列的文章哦! https://www.cnblogs.com/miki-peng/category/1942527.html 关于上传操作 ​ 上传有两 ...

  2. The League of Sequence Designers Gym - 102460E

    题目链接:https://vjudge.net/problem/Gym-102460E 思路:求: 题目当中给了一段伪代码算法,仔细一看发现它是不会记录负数情况,所以与正确答案会有误差,现在题目给定K ...

  3. 开灯问题3_2(JAVA语言)

    package 第三章; public class 开灯问题3_2 { public static void main(String[] args) { // TODO Auto-generated ...

  4. TEB 、TIB、PEB--Vista 32

    TEB struct TEB typedef struct _TEB { NT_TIB NtTib; PVOID EnvironmentPointer; CLIENT_ID ClientId; PVO ...

  5. 攻防世界 reverse 进阶 notsequence

    notsequence  RCTF-2015 关键就是两个check函数 1 signed int __cdecl check1_80486CD(int a1[]) 2 { 3 signed int ...

  6. Java之继承和抽象类

    继承 继承的实现 继承通过extends实现 格式:class 子类 extends 父类 { } 举例:class Dog extends Animal { }   继承带来的好处 继承可以让类与类 ...

  7. (4)MySQL进阶篇SQL优化(常用SQL的优化)

    1.概述 前面我们介绍了MySQL中怎么样通过索引来优化查询.日常开发中,除了使用查询外,我们还会使用一些其他的常用SQL,比如 INSERT.GROUP BY等.对于这些SQL语句,我们该怎么样进行 ...

  8. [源码解析] 并行分布式框架 Celery 之 worker 启动 (1)

    [源码解析] 并行分布式框架 Celery 之 worker 启动 (1) 目录 [源码解析] 并行分布式框架 Celery 之 worker 启动 (1) 0x00 摘要 0x01 Celery的架 ...

  9. Spring的循环依赖

    本文简要介绍了循环依赖以及Spring解决循环依赖的过程 一.定义 循环依赖是指对象之间的循环依赖,即2个或以上的对象互相持有对方,最终形成闭环.这里的对象特指单例对象. 二.表现形式 对象之间的循环 ...

  10. SIP (Session Initiation Protocol) 协议

    Session Initiation Protocol 介绍 SIP是VoIP技术最常使用的协议,它是一种应用程序层协议,可与其他应用程序层协议配合使用,以控制Internet上的多媒体通信会话. V ...