内存

6 篇文章 0 订阅
6 篇文章 0 订阅

1.                        内存布局

Kernel space           0xffffffff

 

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

 

Stack                    0xc0000000

 

Dynamic libraries       0x40000000

 

Heap

 

Read/write sections(.data .bss)

 

Readonly sections(.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.  对象池。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值