首页 > 编程语言 >C++逆向分析——new和delete new[]和delete[]

C++逆向分析——new和delete new[]和delete[]

时间:2023-08-02 18:33:24浏览次数:32  
标签:00 C++ Person FF dword new delete

在堆中创建对象

我们可以在什么地方创建对象?

  1. 全局变量区,在函数外面
  2. 在栈中创建对象,也就是函数内
  3. 在堆中创建对象

注意:之前一直提到的堆栈实际上是两个概念->堆、栈,我们之前所讲的就是栈,从本章开始要严格区分。

在C语言中,我们可以通过一个函数去申请一块内存,就是malloc(N);申请的这一块内存就是在堆中的。

在堆中创建对象我们可以使用new、delete这两个关键词来创建和释放:

Person* p = new Person();

delete p;

我们可以来实际的看一下new、delete这两个关键词主要做了什么。

首先我们使用new关键词的时候会发现,其除了在堆中创建了对象还会调用构造函数:

C++逆向分析——new和delete new[]和delete[]_创建对象

再跟进看看使用delete,它会释放空间并调用析构函数:

C++逆向分析——new和delete new[]和delete[]_构造函数_02

我们想要了解其本质,还是要去跟一下汇编代码,这里跟一下new关键词的执行流程看看其分别调用的函数(跟进call operator new (004012e0)):

C++逆向分析——new和delete new[]和delete[]_构造函数_03

而后调用了构造函数:call @ILT+0(Person::Person) (00401005)

我们再来跟下malloc函数的调用步骤:

call malloc (00401a20) → _nh_malloc_dbg → _heap_alloc_dbg → _heap_alloc_base → HeapAlloc

那么这时候一下就清楚了new的本质,实际上就是malloc+构造函数,同样的方法可以跟下delete看下它跟free函数。

跟进delete关键词,会发现其会先调用析构函数函数然后再去调用operator delete然后就是_free_dbg:

C++逆向分析——new和delete new[]和delete[]_创建对象_04

所以delete的本质就是析构函数+free。

如果我们想要在堆中申请数组,需要使用new[]、delete[]这两个关键词来创建和释放。

// C、C++的方式在堆中申请、释放int数组

int* p = (int*)malloc(sizeof(int)*10); free(p);


int* p = newint[10]; delete[] p;

 
// C、C++的方式在堆中申请、释放Class类型数组

Person* p = (Person*)malloc(sizeof(Person)*10); free(p);


Person* p = new Person[10]; delete[] p;

malloc和new[]的区别:

  1. malloc不会调用构造函数
  2. new[]会调用构造函数,创建一次则调用一次,例如new Person[10]则调用10次

同理也可以知道free和delete[]的区别。

delete和delete[]是有区别的,如果使用new[]在堆中创建对象,使用delete去释放则只会释放第一个对象,其他的不会释放。

 

手动实践下:

 

#include <stdio.h>
class Person {
private:
	int age;
	int sex;

public:
	Person(int a, int b) {
		age = a;
		sex = b;
	}

	Person() {
		age = 0;
		sex = -1;
	}
};


void main() {
	Person* p = new Person;
	delete p;
	// Person* p = new Person[3];
	// delete[] p;
	p = nullptr;
	return;
}

 反汇编的代码贴下:

Person* p = new Person;
00275914 6A 08                push        8  ;size==8,因为person空间大小
00275916 E8 FD B7 FF FF       call        operator new (0271118h) ;malloc好  
0027591B 83 C4 04             add         esp,4  
0027591E 89 85 14 FF FF FF    mov         dword ptr [ebp-0ECh],eax  
00275924 C7 45 FC 00 00 00 00 mov         dword ptr [ebp-4],0  
0027592B 83 BD 14 FF FF FF 00 cmp         dword ptr [ebp-0ECh],0  
00275932 74 13                je          __$EncStackInitStart+5Dh (0275947h)  
00275934 8B 8D 14 FF FF FF    mov         ecx,dword ptr [ebp-0ECh]  
0027593A E8 CC BA FF FF       call        Person::Person (027140Bh)  ;在malloc地址基础上去调用构造函数
0027593F 89 85 00 FF FF FF    mov         dword ptr [ebp-100h],eax  
00275945 EB 0A                jmp         __$EncStackInitStart+67h (0275951h)  
00275947 C7 85 00 FF FF FF 00 00 00 00 mov         dword ptr [ebp-100h],0  
00275951 8B 85 00 FF FF FF    mov         eax,dword ptr [ebp-100h]  
00275957 89 85 20 FF FF FF    mov         dword ptr [ebp-0E0h],eax  
0027595D C7 45 FC FF FF FF FF mov         dword ptr [ebp-4],0FFFFFFFFh  
00275964 8B 8D 20 FF FF FF    mov         ecx,dword ptr [ebp-0E0h]  
0027596A 89 4D EC             mov         dword ptr [p],ecx  
	delete p;
0027596D 8B 45 EC             mov         eax,dword ptr [p]  
00275970 89 85 08 FF FF FF    mov         dword ptr [ebp-0F8h],eax  
00275976 6A 08                push        8  
00275978 8B 8D 08 FF FF FF    mov         ecx,dword ptr [ebp-0F8h]  
0027597E 51                   push        ecx  
0027597F E8 FE B6 FF FF       call        operator delete (0271082h)  ;delete
00275984 83 C4 08             add         esp,8  
00275987 83 BD 08 FF FF FF 00 cmp         dword ptr [ebp-0F8h],0  
0027598E 75 0C                jne         __$EncStackInitStart+0B2h (027599Ch)  
00275990 C7 85 00 FF FF FF 00 00 00 00 mov         dword ptr [ebp-100h],0  
0027599A EB 10                jmp         __$EncStackInitStart+0C2h (02759ACh)  
0027599C C7 45 EC 23 81 00 00 mov         dword ptr [p],8123h  
002759A3 8B 55 EC             mov         edx,dword ptr [p]  
002759A6 89 95 00 FF FF FF    mov         dword ptr [ebp-100h],edx  
	// Person* p = new Person[3];
	// delete[] p;
	p = nullptr;
002759AC C7 45 EC 00 00 00 00 mov         dword ptr [p],0  

	return;

 类似的讲解:

C++逆向分析——new和delete new[]和delete[]_数组_05

换成数组:

#include <stdio.h>
class Person {
private:
	int age;
	int sex;

public:
	Person(int a, int b) {
		age = a;
		sex = b;
	}

	Person() {
		age = 0;
		sex = -1;
	}
};


void main() {
	Person* p = new Person[3];
	delete[] p;
	p = nullptr;
	return;
}

 反汇编比较复杂,todo吧。

 

 

标签:00,C++,Person,FF,dword,new,delete
From: https://blog.51cto.com/u_11908275/6941584

相关文章

  • C++逆向分析——继承
    继承structPerson{intage;intsex;};structTeacher{intage;intsex;intlevel;intclassId;};如上代码中可以看见,Teacher类与Person类都存在着相同的2个成员age和sex,那么这就相当于重复编写了,我们可以通过继承的方式避免这样重复的编写(当前类名称:要......
  • C++逆向分析——this指针
    this指针概述C++是对C的拓展,C原有的语法C++都支持,并在此基础上拓展了一些语法:封装、继承、多态、模板等等。C++拓展新的语法是为了让使用更加方便、高效,这样就需要编译器多做了很多事情,接下来我们就需要一一学习这些概念。封装之前我们学习过结构体这个概念,那么结构体可以做参数传......
  • 【C++数据结构】启航,打开新世界的大门!
    @TOC一、学习数据结构的原因学习数据结构对于计算机科学和软件开发非常重要,它提供了处理和组织数据的有效方法和技术。以下是几个学习数据结构的重要原因:提高问题解决能力:数据结构教会了我们如何选择和使用适当的数据结构来解决问题。了解各种数据结构的特性和性能可以帮助我们分......
  • I - Wish I Knew How to Sort
    I-WishIKnewHowtoSort题意每次随机选择下标\(i,j\)交换\(a[i],a[j]\),求变成不讲序列的期望次数。思路dp,同样也是期望dp,先考虑暴力,可以状态压缩,那么\(010\)可以转移到:\(100\),\(010\),\(001\)这三种,然后我们发现,其实只有\(001\)有点用,而其他的就有点鸡肋,所以......
  • protobuf在c++中的使用
    一、安装sudoaptinstalllibprotobuf-devprotobuf-compiler二、编辑proto文件,生成代码文件proto语法分为“proto2”和”proto3“两个版本,指定方法是在proto文件中第一行写入:syntax="proto3";,这样指定使用proto3版本的语法,如果不指定,默认是使用proto2的语法。两个语法的......
  • C/C++ 数据结构五大核心算法之分治法
    分治法——见名思义,即分而治之,从而得到我们想要的最终结果。分治法的思想是将一个规模为N的问题分解为k个较小的子问题,这些子问题遵循的处理方式就是互相独立且与原问题相同。两部分组成:分(divide):递归解决较小的问题治(conquer):然后从子问题的解构建原问题的解三个步骤:1、......
  • 第三阶段C++提高编程(黑马程序员)——Day9
    2STL初识2.1STL的诞生长久以来,软件界一直希望建立一种可重复利用的东西C++的面向对象和泛型编程思想,目的就是复用性的提升大多情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作为了建立数据结构和算法的一套标准诞生了STL2.2STL基本概念STL(StandardTemplateLib......
  • 【八股文 02】C++ 进程内存布局及其相关知识
    1引言本文环境为Linux操作系统(x86)+C++。目的是了解进程内存布局,但是在了解的过程中发现需要前置一些知识,因此内容概览如下所示:1C/C++程序从源代码到可执行程序的构建过程1.1预处理,也叫预编译1.2编译1.3汇编1.4链接2各平台文件格式3ELF文件3.1ELF文......
  • 【八股文 00】C++ 八股文合集
    1前言1.1八股文是什么八股文本来是明清科举考试的一种文体,绝对不允许自由发挥,而句子的长短、字的繁简、声调的高低等也都要相对成文,字数也有限制。那么总结一下,八股文的特点是:不允许自由发挥,题目,内容,格式都被严格限制,必须遵守相应的定式那么计算机八股文就比较好理解了,就是......
  • c++求平均年纪
    班上有学生若干名,给出每名学生的年龄(整数),求班上所有学生的平均年龄,保留到小数点后两位。#include<cstdio>usingnamespacestd;intmain(){ intn,t; doubles; s=0;   //s储存班上同学年龄之和,初始值赋值为0 scanf("%d",&n);   for(inti=1;i<=n;++i) //循环累加班......