💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 内存,第 3 部分:粉碎栈示例 > 原文:<https://github.com/angrave/SystemProgramming/wiki/Memory%2C-Part-3%3A-Smashing-the-Stack-Example> 每个线程使用栈内存。栈“向下增长” - 如果函数调用另一个函数,则栈扩展到较小的内存地址。栈内存包括非静态自动(临时)变量,参数值和返回地址。如果缓冲区太小某些数据(例如来自用户的输入值),那么很可能会覆盖其他栈变量甚至返回地址。栈内容的精确布局和自动变量的顺序取决于体系结构和编译器。然而,通过一些调查工作,我们可以学习如何故意粉碎特定架构的栈。 下面的示例演示了返回地址如何存储在栈中。对于特定的 32 位架构 [Live Linux Machine](http://cs-education.github.io/sys/) ,我们确定返回地址存储在自动变量地址上方两个指针(8 个字节)的地址处。代码故意更改栈值,以便在输入函数返回时,而不是继续在 main 方法内部,它会跳转到 exploit 函数。 ```c // Overwrites the return address on the following machine: // http://cs-education.github.io/sys/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> void breakout() { puts("Welcome. Have a shell..."); system("/bin/sh"); } void input() { void *p; printf("Address of stack variable: %p\n", &p); printf("Something that looks like a return address on stack: %p\n", *((&p)+2)); // Let's change it to point to the start of our sneaky function. *((&p)+2) = breakout; } int main() { printf("main() code starts at %p\n",main); input(); while (1) { puts("Hello"); sleep(1); } return 0; } ``` [有很多](https://en.wikipedia.org/wiki/Stack_buffer_overflow)计算机倾向于解决这个问题。