C++逆向分析New_Delete

本文通过C/C++代码示例和汇编分析,解释了堆区在程序运行中的作用,以及malloc和New函数在本质上的区别,揭示了New是对malloc的封装,同时介绍了堆头的存在和Delete函数的原理。
摘要由CSDN通过智能技术生成

一个运行程序是一定有四个区域,分别是:代码区,数据区,栈区,堆区。

栈区我们知道,是函数传参保存临时变量的一段内存空间。那么堆区是干嘛的呢?

堆区就是动态开辟的一块内存空间,用于存放数据。在C语言中,我们是用malloc函数去开辟空间的,释放空间是free函数。而在C++中用的是New关键字,释放空间用的是Delete关键字。

C语言的malloc和C++中的New有啥区别?

其实本质上他们没有什么区别。New相当于对malloc又做了一层封装,调用new会自动调用构造函数,而malloc不会。

我们写一个小的demo从汇编的角度看待问题,代码如下:

#include<iostream>

using namespace std;

int *func1(){
  int *p=new int(10);
  return p;
}

int main(){

  int *ret=func1();
  cout<<"number= "<<*ret<<endl;

  return 0;
}

代码非常简单。就是在堆区创建一个int大小的空间并赋值为10。


下面我们观察下过程:


一进来就是调用我们的fun1函数。s跟进看看:


一开始我们看到传参4字节大小。因为我们创建的Int类型就是四字节。紧接着就去调用一个目前未知的函数,跟进去看看:


反汇编跟进这个地址我们看到是会调用一个函数。这个函数应该就是New的构造函数。紧接着s跟进,就会来到这里:


我们观察到,做了一些初始化后,最后还是调用C语言的malloc函数。因此验证了我们上述的New其实就是对malloc做的再一次封装。供C++调用。更加符合C++的语法规范。


单步到这,我们发现edi就是我们的malloc函数的参数。相当于调用malloc(0x4)。执行完malloc返回值将会放到rax中:


我们看到堆的返回地址已经在RAX寄存器中了。现在我们看这片空间是没有东西的,只是初始化了这么一块空间给用户:


因为在C语言的malloc管理中,64位下的堆其实是有0x10大小的堆头的也就是16字节。0x555555767e70的位置才是用户可操作的空间。


接下来如果我们执行,堆上将会写入一个0xa我们观察下效果:


结果是符合预期的。那么相同道理,Delete的操作应该类似。将free函数进行一层封装,底层依然是调用的free函数:



  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值