内存

来源:互联网 发布:淘宝没生意怎么推广 编辑:程序博客网 时间:2024/05/01 23:30

1.                       内存布局

Kernelspace           0xffffffff

 

操作系统挪用出来的kernel空间

 

Stack                  0xc0000000

 

Dynamiclibraries       0x40000000

 

Heap

 

Read/writesections(.data .bss)

 

Readonlysections(.init, .rodata, .text)

 

Reserved              0x08048000

(保留区是对内存中受到保护而禁止访问的内存区域,如NULL)

 

一般的非法操作内存, 就是访问到了保留区的内存了。

 

2. 

栈总是向下增长的,栈顶由称为esp的寄存器进行定位.

栈保存了一个函数调用所需要维护的信息,常常被称为 堆栈帧:

包括了:

1.  函数的返回地址和参数

2.  临时变量: 包括函数的非静态局部变量以及编译器自动生成的临时变量

3.  保存上下文:包括在函数条用前后需要保持不变的寄存器。

 

汇编代码解析:

 

Push  ebp

Move ebp, esp (保存ebp,让ebp指向目前的栈顶)

 

Sub esp, 0C0h (在栈上开辟一块空间)

 

Push ebx

Push esi

Push edi (保存ebx,esi,edi 寄存器)

 

Xxxxxx

xxxxxx

 

 

mov eax, 7bh (返回值通过eax寄存器传递的)

pop edi

pop esi

pop ebx  (恢复edi,esi,ebx寄存器)

 

push esp,ebp

pop ebp (恢复esp,ebp)

 

 

hook 函数的实现原理,在实际函数调用前加入的函数,可以得函数执行的信息或者参数,甚至可以改变某些数据,控制函数的执行。

 

函数返回值的传递

1. 首先main函数在栈上额外开辟了一片空间,并将这块空间的一部分作为传递返回值的临时对象。

2. 将临时对象的地址作为隐藏参数传递给调用函数,

3. 调用函数将数据拷贝给临时对象,并将临时对象的地址用eax传出。

4. Main函数将eax 指向的临时对象的内容拷贝出来。

 

 

 

书上的例子很说明问题。

 

 

4. 

 

栈上面分配的变量, 尽尽只能在这个函数里使用,出了这个函数就没有了(因为函数已经被pop出栈了),所以我们需要在堆上进行内存分配, 使变量能贯穿整个工程。

 

堆分配的过程

1. 运行库向操作系统“批发”一块比较大的堆空间

Mmap()函数来分配大块空间,一般大于128K的内存,调用malloc函数 其实就是在调用mmap();

 

3.  运行库在大块内存分配给我们程序员使用

3种算法:

1.  空间链表,实现简单.

2.  位图, 速度快,但是容易产生碎片。

3.  对象池。

 

原创粉丝点击