C 如何找到缓冲区溢出和内存损坏的位置?

C 如何找到缓冲区溢出和内存损坏的位置?,c,valgrind,buffer-overflow,memory-corruption,C,Valgrind,Buffer Overflow,Memory Corruption,valgrind找不到任何有用的东西。我很困惑 症状: 我的数据被malloc()调用损坏 我的函数的返回地址被错误的内容替换 PS:代码不存在故障 目前,通过mmap()+mprotect() 修复所有悬空指针、所有缓冲区 溢出 仅在以下位置使用指针 他们真的很需要 请参阅以下链接::Valgrind memcheck在检测缓冲区溢出方面不是很好。但是你可以尝试一种可能的方法。你是在什么环境下开发的 如果您在Windows上开发,请尝试本文您可能正在覆盖堆栈,或者您可能正在覆盖堆 您可以尝试将

valgrind找不到任何有用的东西。我很困惑

症状:

  • 我的数据被malloc()调用损坏
  • 我的函数的返回地址被错误的内容替换
  • PS:代码不存在故障

    目前,通过
    mmap()
    +
    mprotect()

  • 修复所有悬空指针、所有缓冲区 溢出
  • 仅在以下位置使用指针 他们真的很需要

  • 请参阅以下链接::

    Valgrind memcheck在检测缓冲区溢出方面不是很好。但是你可以尝试一种可能的方法。

    你是在什么环境下开发的


    如果您在Windows上开发,请尝试本文

    您可能正在覆盖堆栈,或者您可能正在覆盖堆

    您可以尝试将该标志添加到GCC命令行选项中,以要求在程序中内置一些堆栈破坏报告。这可能会导致它更快地失败

    另一种可能是查看
    dmesg
    输出中报告的地址,查看是否无法跟踪正在被破坏的功能/内存:

    [68303.941351] broken[13301]: segfault at 7f0061616161 ip 000000000040053d sp 00007fffd4ad3980 error 4 in broken[400000+1000]
    
    readelf-s
    将转储符号表,我们可以查找触发问题的函数:

    $ readelf -s broken | grep 4005
    40: 00000000004005e0     0 FUNC    LOCAL  DEFAULT   13 __do_global_ctors_aux
    47: 0000000000400540     2 FUNC    GLOBAL DEFAULT   13 __libc_csu_fini
    57: 0000000000400550   137 FUNC    GLOBAL DEFAULT   13 __libc_csu_init
    63: 0000000000400515    42 FUNC    GLOBAL DEFAULT   13 main
    
    main
    例程是使用坏指针时执行的例程:

    #include <string.h>
    
    void f(const char *s) {
        char buf[4];
        strcpy(buf, s);
        return;
    }
    
    int main(int argc, char* argv[]) {
        f("aaaa");
        f("aaaaaaaaaaaaaaaaaaaa");
        return 0;
    }
    
    #包括
    空f(常量字符*s){
    char-buf[4];
    strcpy(buf,s);
    返回;
    }
    int main(int argc,char*argv[]){
    f(“aaaa”);
    f(“aaaaaaaaaaaaaaaa”);
    返回0;
    }
    
    main
    试图返回C库退出时,它使用了存储在堆栈框架中的错误指针。因此,看看
    main
    调用的函数,(在这种简单的情况下很容易)
    f
    显然是在堆栈框架上乱涂乱画的bug


    如果要覆盖堆,那么也许可以尝试。缺点是非常严重的(大量内存使用),但这可能正是您需要找到问题的地方。

    您也可以尝试IBM Rational Purify的试用版-一个检测缓冲区溢出、内存泄漏和任何其他内存损坏错误的非常好的工具。按照此链接下载

    在Linux上对您没有帮助。但是您说您没有使用任何字符串函数,这表明您的应用程序可能是相当可移植的。它在Windows下会失败吗


    如果确实如此,我们的工具可能能够找到问题。它比Valgrind更仔细地检查程序如何使用指针,因为它可以看到代码中的结构和声明,并且它了解各种存储使用(堆栈帧与堆)。Valgrind只看到机器指令,无法判断堆栈帧何时超出范围。

    也许您至少可以提供一些代码行?否则,没有人能够帮助你。纠正所有错误,这应该会解决它。[/sarcasm]请至少提供一些信息。你看到的症状是什么?分割错误?数据损坏?你试过什么?结果如何?如果你不努力回答你的问题,你希望我们如何回答?悬空指针已经修复,但我需要找到缓冲区溢出位置的指南我已经使用了-fstack protect all,但目前还没有产生任何有用的结果result@vitaly.v.ch,我也很失望。StackGuard可以抓住这一点,GCC团队最终排除的专有补丁在哪些例程“需要保护”方面相当聪明;我希望
    -all
    变体能够解决这个问题。….@vitaly.v.ch,当我向Ubuntu提交了一份关于
    -fstack-protect-all
    的错误报告时,它被标记为重复,其中提到了Natty版本的gcc-4.4:
    debian/patches/gcc default ssp.patch
    。希望这能帮助您在空闲时间获得固定版本的GCC。根据强化检查的输出,我的GCC dos没有此错误。我还没有在Linux上编写任何本机代码,但我知道由于缓冲区溢出攻击,最常见的字符串函数正在被弃用。您应该检查它们是否是您希望使用的任何所需字符串的安全版本,如果没有可用的字符串,您可以编写自己的版本。只需检查目标缓冲区并验证它是否大于源缓冲区。我不使用任何字符串函数。在我的情况下,这是没有用的-我用预编译的应用程序调试共享库。