C 如何找到缓冲区溢出和内存损坏的位置?
valgrind找不到任何有用的东西。我很困惑 症状:C 如何找到缓冲区溢出和内存损坏的位置?,c,valgrind,buffer-overflow,memory-corruption,C,Valgrind,Buffer Overflow,Memory Corruption,valgrind找不到任何有用的东西。我很困惑 症状: 我的数据被malloc()调用损坏 我的函数的返回地址被错误的内容替换 PS:代码不存在故障 目前,通过mmap()+mprotect() 修复所有悬空指针、所有缓冲区 溢出 仅在以下位置使用指针 他们真的很需要 请参阅以下链接::Valgrind memcheck在检测缓冲区溢出方面不是很好。但是你可以尝试一种可能的方法。你是在什么环境下开发的 如果您在Windows上开发,请尝试本文您可能正在覆盖堆栈,或者您可能正在覆盖堆 您可以尝试将
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上编写任何本机代码,但我知道由于缓冲区溢出攻击,最常见的字符串函数正在被弃用。您应该检查它们是否是您希望使用的任何所需字符串的安全版本,如果没有可用的字符串,您可以编写自己的版本。只需检查目标缓冲区并验证它是否大于源缓冲区。我不使用任何字符串函数。在我的情况下,这是没有用的-我用预编译的应用程序调试共享库。