Stack Smashing尝试给出段错误

use*_*103 26 c buffer-overflow shellcode

我试图通过Smashing the Stack for Fun和Profit在C中做一个例子,但我有点卡在一点,以下是代码(我有一个64位机器与Ubuntu 64位):

int main()
{
    int x;

    x = 0;
    func(1,2,3);
    x = 1;
    printf("x is : %d\n", x);
}

void func(int a, int b, int c)
{
    char buffer[1];
    int *ret;

    ret = buffer + 17;
    (*ret) += 7;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码工作正常,并且在返回x=1行时没有执行,但我无法理解背后的逻辑ret = buffer + 17;,不应该是ret = buffer + 16;8字节用于缓冲区,8用于保存的栈指针上的指针.

其次,我的理解是char buffer[1]占用8个字节(由于64位拱)并且如果我增加这个缓冲区来说buffer[2],仍然相同的代码应该工作正常,但这不会发生并且它开始给出seg错误.

此致,努曼

Pau*_*aul 13

我使用的每个架构上的'char'是8位宽,无论它是8位微,16位微,32位PC还是64位新PC.另一方面,Int往往是单词大小.

本地人放在堆栈上的顺序可以是特定于实现的.我的猜测是你的编译器在"char buffer 1 " 之前将"int*ret"放在堆栈上.因此,要获得返回地址,我们必须通过"char buffer 1 "(1字节),"int*ret"(8字节)和保存的基本指针(8字节),总共17个字节.

这是x86 64位上堆栈帧的描述:http: //ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-035-computer-language-engineering-spring-2010/projects/X86-64


cod*_*gic 9

逐步完成gdb中的反汇编(反汇编,stepi,nexti),并查看每一步的寄存器(信息寄存器).

在这里您可以如何逐步完成反汇编:

gdb ./myprogram
break main
run
display/4i $eip
stepi
stepi
...
info registers
...
Run Code Online (Sandbox Code Playgroud)

你也应该知道(你可能已经做过,因为你有一部分工作了)在许多发行版中,默认情况下在gcc中启用堆栈保护程序.您可以手动禁用它-fno-stack-protector.


Chr*_*nch 3

对于很多这种堆栈粉碎的东西,你最好的朋友是gdb。由于您已经出现了段错误,因此您已经在写入内存,而您不应该这样做(一个好兆头)。正确执行此操作的更有效方法是将返回地址更改为其他有效地址(例如 tofunc的地址或您拥有的某些 shellcode)。我推荐的一个很好的资源是Shellcoder's Handbook,但由于您使用的是 64 位架构,所以很多示例需要做一些工作才能开始。