C++逆向分析New_Delete

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

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

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

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

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

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

#include

using namespace std;

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

int main(){

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

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

C++逆向分析New_Delete_第1张图片


下面我们观察下过程:

C++逆向分析New_Delete_第2张图片


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

C++逆向分析New_Delete_第3张图片


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

C++逆向分析New_Delete_第4张图片


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

C++逆向分析New_Delete_第5张图片


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


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

C++逆向分析New_Delete_第7张图片


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

C++逆向分析New_Delete_第8张图片


因为在C语言的malloc管理中,64位下的堆其实是有0x10大小的堆头的也就是16字节。0x555555767e70的位置才是用户可操作的空间。C++逆向分析New_Delete_第9张图片


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

C++逆向分析New_Delete_第10张图片


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

C++逆向分析New_Delete_第11张图片


C++逆向分析New_Delete_第12张图片


你可能感兴趣的:(逆向,c++,java,开发语言)