### 学习笔记:栈相关知识点 #### 0x310 目标 本章节旨在探讨如何通过操纵函数的栈帧来执行任意代码。在实际应用中,这种技术经常被用于安全研究、逆向工程等领域,特别是针对缓冲区溢出攻击的研究与防御。 #### 0x320 前置条件 为了更好地理解本文档中的概念和技术,读者需具备以下基础知识: 1. **本地栈溢出基础模块**:了解基本的栈溢出原理及其攻击方式。 2. **本地栈溢出高级模块**:深入理解复杂情况下的栈溢出攻击机制,并掌握相应的防御措施。 #### 0x330 引言 **栈帧**是专门用来存储函数局部变量以及传递给其他函数参数的一个特定区域。每个函数都有其自己的栈帧,并负责创建、保存及恢复调用者栈帧。本章节将详细讨论栈帧的工作机制,以及如何利用缓冲区溢出漏洞来操纵局部变量。 #### 0x340 栈布局 下面通过一个具体的源代码示例来进一步解释栈布局: ```c void func(char *buf) { printf("%s\n", buf); } int main() { char buf[256]; func(buf); } ``` 编译并反汇编上述程序,可以得到如下汇编代码片段: ```assembly Dump of assembler code for function main: 0x0804822f<main+0>: push %ebp 0x08048230<main+1>: mov %esp, %ebp 0x08048232<main+3>: sub $0x118, %esp 0x08048238<main+9>: and $0xfffffff0, %esp 0x0804823b<main+12>: mov $0x0, %eax 0x08048240<main+17>: sub %eax, %esp 0x08048242<main+19>: lea 0xfffffef8(%ebp), %eax 0x08048248<main+25>: mov %eax, (%esp) 0x0804824b<main+28>: call 0x8048214<func> 0x08048250<main+33>: leave 0x08048251<main+34>: ret End of assembler dump. Dump of assembler code for function func: 0x08048214<func+0>: push %ebp 0x08048215<func+1>: mov %esp, %ebp 0x08048217<func+3>: sub $0 ``` 从上面的汇编代码中可以看出: 1. **main() 的栈帧**:首先通过 `push %ebp` 保存当前基址寄存器(Base Pointer Register)的值,然后通过 `mov %esp, %ebp` 将栈顶指针(Stack Pointer)赋值给新的基址寄存器,接下来通过 `sub $0x118, %esp` 减少栈空间以分配局部变量。最后通过 `lea 0xfffffef8(%ebp), %eax` 和 `mov %eax, (%esp)` 来设置参数并调用 `func()`。 2. **func() 的栈帧**:同样地,通过 `push %ebp` 和 `mov %esp, %ebp` 来初始化新的栈帧。但在这个函数中并未分配额外的局部变量空间。 #### 0x341 main() 的栈帧 在 `main()` 函数中,我们注意到栈空间减少了 `0x118` 字节。这通常是为了给局部变量 `buf` 分配足够的空间,并且可能还包含了函数调用所需的其他临时数据。 #### 0x342 func() 的栈帧 `func()` 函数的栈帧相对简单,没有分配额外的空间给局部变量。这意味着该函数主要处理通过参数传入的数据。 #### 0x343 栈帧销毁 当函数执行完毕后,需要恢复之前的状态。这通常涉及到通过 `leave` 指令恢复基址寄存器的值,然后通过 `ret` 返回到调用者。 #### 0x350 操纵栈帧 通过对栈帧的理解,可以尝试改变函数的行为。例如,在 `main()` 函数中,如果 `buf` 数组足够大并且可以通过某种方式控制,那么就有可能通过向 `buf` 写入特殊数据来改变函数的行为。 #### 0x360 通过栈帧操纵的乐趣 通过操纵栈帧,不仅可以执行任意代码,还可以实现许多有趣的效果。例如: 1. **修改返回地址**:通过修改栈上的返回地址,可以跳转到任意位置执行代码。 2. **更改局部变量**:通过覆盖局部变量,可以改变函数的执行逻辑。 3. **调用未预期的函数**:通过修改栈上的参数,可以使函数调用另一个未预期的函数。 #### 0x370 结论 栈帧是计算机程序运行时的重要组成部分,它不仅承载着函数的局部状态,还直接影响着程序的安全性和稳定性。通过理解和掌握栈帧的运作机制,可以在安全领域进行更深入的研究和实践。同时,对于软件开发人员而言,深入理解栈帧也有助于编写更加安全、高效的代码。
(GSC)
---------[ Chapter : 0x300 ]
---------[ Subject : Function Stack Frame Manipulation ]
---------[ Author : barros A.K.A Carlos Barros ]
---------[ Date : 09/15/2005 ]
---------[ Version : 1.1 ]
|=-----------------------------------------------------------------------------=|
---------[ Table of Contents ]
0x310 - Objective
0x320 - Requisites
0x330 - Introduction
0x340 - Stack layout
0x341 - main()'s stack frame
0x342 - func()'s stack frame
0x343 - Stack frame destruction
0x350 - Manipulating the stack frame
0x360 - Having fun with stack frame manipulation
0x370 - Conclusion
|=-----------------------------------------------------------------------------=|
---------[ 0x310 - Objective ]
Manipulate the stack frame of a function in order to execute arbitrary
---------[ 0x320 - Requisites ]
Introduction to Local Stack Overflow (Basic Module);
Local Stack Overflow (Advcanced Module).
---------[ 0x330 - Introduction ]
Stack frame is a region reserverd to store function's local variables,
as well as to store parameter to be passed to other functions. Each function
has you own stack frame and is responsible to create it and save/restore the
caller's stack frame. In this paper we will discuss how the stack frame works
and how buffer overflows can be used to manipulate local variables.
---------[ 0x340 - Stack layout ]
Lets consider this source code:
barros@gotfault:sources$ cat source1.c
void func(char *buf)
{
printf("%s\n",buf);
}
int main()
{
char buf[256];
func(buf);
}
barros@gotfault:sources$ gcc source1.c -o source
剩余19页未读,继续阅读
- 粉丝: 0
- 资源: 4
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助