0day2安全——笔记2
第二章
内存的不同用途
windows应用—>编译连接—>PE文件—>进程
进程使用的内存
1.代码区:储存着被装入执行的二进制机器代码,处理器会到这个区域取指和执行
2.数据区:用于储存全局变量等。
3.堆区:进程可以在堆区动态请求一定大小的内存空间,用完之后还给堆区。动态分配和回收是堆区的特点。
4.栈区:用于动态的存储函数直接的调用关系,以保证被调用函数在返回时恢复到母函数中继续执行。
栈和系统栈
栈:(后进先出表)
栈的操作:POP(出栈),PUSH(入栈)
标识栈的属性:TOP(栈顶),BASE(栈低)
系统栈(运行栈,调用栈):内存中的栈就是系统栈,系统栈由系统自动维护。
以下代码流程图如表1-1所示:
intfunc_B(int arg_B1) { return arg_B1+1; } intfunc_A(int arg_A1) { int var_A; var_A=func_B(arg_A1)+1 return var_A; } int main() { int var_main; var_main=intfunc_A(1); }
代码空间 | 系统栈空间 | |
1 | 程序装载进代码空间,在main函数依次取指执行 | 系统栈站顶为当前执行的main函数 |
2 | 执行到main函数的call指令时,跳转到fun_A函数的代码区继续执行 | 系统栈开辟新的栈帧给fun_A函数使用并压入,此时系统栈栈顶为func_A函数 |
3 | func_A函数执行到call指令时,跳转到fun_B函数的代码区继续执行 | 系统栈开辟新的栈帧给fun_A函数使用并压入,此时系统栈栈顶为func_B函数 |
4 | func_B函数执行完毕后弹出func_B函数的栈帧,并从中获取到返回值,进入到fun_A函数代码区中继续执行 | 系统栈弹出func_B的栈帧,系统栈栈顶指针为func_A函数栈帧 |
5 | func_A函数执行完毕后弹出func_A函数的栈帧,并从中获取到返回值,进入到main函数代码区中继续执行 | 系统栈弹出func_A的栈帧,系统栈栈顶指针此时为main函数栈帧 |
表1-1 函数调用时系统栈和代码空间的变化
寄存器与函数栈帧
ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈第一个栈帧的栈顶
EBP:基指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈第一个栈帧的栈底
EIP :指令寄存器(extended instruction pointer),其内存放着一个指针,该指针永远指向下一条等待执行的指令地址
函数栈帧:函数栈帧是执行到call指令时开辟的属于函数的栈帧。ESP和EBP之间的内存空间为当前的栈帧,ESP标识了栈帧的栈顶,EBP标识了栈帧的栈底
函数栈帧内容:
- 局部变量:为函数局部变量开辟的内存空间
- 函数的返回地址:保存当前函数调用前的“断点”信息——函数调用前的指令位置,以便函数在返回时能恢复到函数调用前的指令位置,并继续执行指令
- 栈帧状态值:保存前栈帧(前栈帧指的是栈底向下的栈帧)的顶部和底部(实际只保存前栈帧的底部,前栈帧的顶部可以通过对战平衡得到),用于当前栈帧被弹出后恢复上一个栈帧