当前位置:  开发笔记 > 运维 > 正文

Stack Smashing尝试给出段错误

如何解决《StackSmashing尝试给出段错误》经验,为你挑选了2个好方法。

我试图通过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;
}

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

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

此致,努曼



1> Paul..:

我使用的每个架构上的'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



2> codelogic..:

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

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

gdb ./myprogram
break main
run
display/4i $eip
stepi
stepi
...
info registers
...

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

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有