如何找到缓冲区溢出和内存损坏的地方?

时间:2011-02-21 10:04:11

标签: c valgrind buffer-overflow memory-corruption

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

Symptomes:

  1. 我的数据被malloc()调用
  2. 损坏
  3. 我的功能的返回地址被错误的替换
  4. PS:代码不会出现段错误

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

    替换我的所有malloc()取得了一些进展

6 个答案:

答案 0 :(得分:7)

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

您可以尝试将标志-fstack-protector-all添加到您的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;
}

main尝试返回C库退出时,它使用存储在堆栈帧中的错误指针。所以看看main调用的函数,并且(在这个简单的情况下它很容易)f显然是遍布堆栈框架的bugger。

如果你要覆盖堆,那么也许你可以尝试electric fence。缺点是相当陡峭(大量使用内存),但它可能正是你需要找到问题的。

答案 1 :(得分:2)

  1. 修复所有悬空指针,所有缓冲区 溢出
  2. 仅在指定位置使用指针 他们真的需要
  3. 请参阅以下链接:: What C/C++ tools can check for buffer overflows?

答案 2 :(得分:2)

Valgrind memcheck在检测缓冲区溢出方面不是很擅长。但你可以尝试一下patch

答案 3 :(得分:2)

您还可以尝试IBM Rational Purify的试用版 - 这是一个非常好的工具,可以检测缓冲区溢出,内存泄漏和任何其他内存损坏错误。点击此链接下载http://www-01.ibm.com/software/awdtools/purify/unix/

答案 4 :(得分:0)

你在开发什么环境?

如果您在Windows上进行开发,请尝试使用此文章http://msdn.microsoft.com/en-us/library/cc500347.aspx

答案 5 :(得分:0)

无法帮助您使用Linux。但是你说你没有使用任何字符串函数,这表明你的应用程序可能相当便携。它在Windows下失败吗?

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