Skip to content

Files

Latest commit

439dcc7 · May 9, 2020

History

History
40 lines (32 loc) · 1.77 KB

23.md

File metadata and controls

40 lines (32 loc) · 1.77 KB

内存,第 3 部分:粉碎栈示例

原文:https://github.com/angrave/SystemProgramming/wiki/Memory%2C-Part-3%3A-Smashing-the-Stack-Example

每个线程使用栈内存。栈“向下增长” - 如果函数调用另一个函数,则栈扩展到较小的内存地址。栈内存包括非静态自动(临时)变量,参数值和返回地址。如果缓冲区太小某些数据(例如来自用户的输入值),那么很可能会覆盖其他栈变量甚至返回地址。栈内容的精确布局和自动变量的顺序取决于体系结构和编译器。然而,通过一些调查工作,我们可以学习如何故意粉碎特定架构的栈。

下面的示例演示了返回地址如何存储在栈中。对于特定的 32 位架构 Live Linux Machine ,我们确定返回地址存储在自动变量地址上方两个指针(8 个字节)的地址处。代码故意更改栈值,以便在输入函数返回时,而不是继续在 main 方法内部,它会跳转到 exploit 函数。

// 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;
}

有很多计算机倾向于解决这个问题。