## 2.2 栈
在开发调试器的时候,栈是一个非常重要的结构。栈存储了与函数调用相关的各种信息, 包括函数的参数和函数执行完成后返回的方法。 ESP 负责跟踪栈顶,EBP 负责跟踪栈底。 栈从内存的高地址像低地址增长。让我们用前面编写的函数 my_sock()作为例子讲解栈是如 何工作的。
Function Call in C
```
int my_socks(color_one, color_two, color_three);
```
Function Call in x86 Assembly
```
push color_three
push color_two
push color_one
call my_socks
```
栈框架的结构将如图 2-1。
![image](https://box.kancloud.cn/2016-03-11_56e23615c5e36.gif)
图 2-1: my_socks() 函数调用的栈结构
如你所见,这是一个非常简单的数据结构,同时也是所有程序中函数调用的基础。当 my_sock()函数返回的时候,它会弹出栈里所有的参数(返回地址弹到 EIP),然后跳到返回 地址(Return address)指向的地方(父函数的代码段)继续执行。另一个需要考虑的概念就是 本地函数。把我们的 my_socks()函数扩展一点,让我们假定函数被调用后做的第一件事就是 申请一个字符串数组,将参数 color_one 复制到数组里。代码应该像这样:
```
int my_socks(color_one, color_)
{
char stinky_sock_color_on[10];
...
}
```
函数将在棧里申请 stinky_sock_color_on 变量的空间,以便在栈里调用(当然会随着函 数的执行完毕而释放,不过在函数内部访问时,效率会高很多)。申请成功以后,堆栈的结 构将像图 2-2 看到的这样。
![image](https://box.kancloud.cn/2016-03-11_56e236196420a.gif)
Figure 2-2: 在 stinky_sock_color_one 申请后的栈框架
现在你到了本地函数是如何在棧里申请的以及栈指针是如何不断的增长指向栈顶 的。调试器对堆栈结构的捕捉能力是相当有用的,特别是在我们捕捉程序崩溃,跟踪调查基 于栈的缓冲区溢出的时候。
- 序
- 1 搭建开发环境
- 1.1 操作系统准备
- 1.2 获取和安装 Python2.5
- 1.3 配置 Eclipse 和 PyDev
- 2 调试器设计
- 2.1 通用 CPU 寄存器
- 2.2 栈
- 2.3 调试事件
- 2.4 断点
- 3 自己动手写一个 windows 调试器
- 3.2 获得 CPU 寄存器状态
- 3.3 实现调试事件处理
- 3.4 全能的断点
- 4 PyDBG---纯 PYTHON 调试器
- 4.1 扩展断点处理
- 4.2 处理访问违例
- 4.3 进程快照
- 5 IMMUNITY----最好的调试器
- 5.1 安装 Immunity 调试器
- 5.2 Immunity Debugger 101
- 5.3 Exploit 开发
- 5.4 搞定反调试机制
- 6 HOOKING
- 6.1 用 PyDbg 实现 Soft Hooking
- 6.2 Hard Hooking
- 7 Dll 和代码注入
- 7.1 创建远线程
- 7.2 邪恶的代码
- 8 FUZZING
- 8.1 Bug 的分类
- 8.2 File Fuzzer
- 8.3 改进你的 Fuzzer
- 9 SULLEY
- 9.1 安装 Sulley
- 9.2 Sulley primitives
- 9.3 猎杀 WarFTPD
- 10 Fuzzing Windows 驱动
- 10.1 驱动通信
- 10.2 用 Immunity fuzzing 驱动
- 10.4 构建 Driver Fuzzer
- 11 IDAPYTHON --- IDA 脚本
- 11.1 安装 IDAPython
- 11.2 IDAPython 函数
- 11.3 脚本例子
- 12 PyEmu
- 12.1 安装 PyEmu
- 12.2 PyEmu 一览
- 12.3 IDAPyEmu