C 中的字符串溢出检测
我们使用 DevPartnersboundchecker 来检测内存泄漏问题。它做得非常出色,尽管它没有发现像下面的
char szTest [1] = "";
for (i = 0; i < 100; i ++) {
strcat (szTest, "hi");
}
问题 1 那样的字符串溢出:我可以让 BoundsChecker 检测到这一点吗?
问题 2:还有其他工具可以检测此类问题吗?
We are using DevPartners boundchecker for detecting memory leak issues. It is doing a wonderful job, though it does not find string overflows like the following
char szTest [1] = "";
for (i = 0; i < 100; i ++) {
strcat (szTest, "hi");
}
Question-1: Is their any way, I can make BoundsChecker to detect this?
Question-2: Is their any other tool that can detect such issues?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
一种选择是简单地禁止使用没有目标缓冲区信息的字符串函数。通用包含的标头中的一组宏(如下所示)可能会有所帮助:
因此,任何尝试使用“禁止”例程的行为都将导致链接器错误,该错误还会告诉您应该使用什么。 MSVC 做了类似的事情,可以使用
_CRT_SECURE_NO_DEPRECATE
等宏进行控制。这种技术的缺点是,如果您有大量现有代码,那么将代码转移到使用新的、更安全的例程可能会是一项艰巨的任务。它会让你发疯,直到你摆脱那些被认为是危险的功能。
One option is to simply ban the use of string functions that don't have information about the destination buffer. A set of macros like the following in a universally included header can be helpful:
So any attempted uses of the 'banned' routines will result in a linker error that also tells you what you should use instead. MSVC has done something similar that can be controlled using macros like
_CRT_SECURE_NO_DEPRECATE
.The drawback to this technique is that if you have a large set of existing code, it can be a huge chore to get things moved over to using the new, safer routines. It can drive you crazy until you've gotten rid of the functions considered dangerous.
valgrind
将检测过去动态分配的数据的写入,但我认为它不能像您的示例中那样对于自动数组执行此操作。如果您使用strcat
、strcpy
等,则必须确保目标足够大。编辑:我关于 valgrind 的看法是正确的 ,但还是有一些希望:
我没有使用过 Ptrcheck。
valgrind
will detect writing past dynamically allocated data, but I don't think it can do so for automatic arrays like in your example. If you are usingstrcat
,strcpy
, etc., you have to make sure that the destination is big enough.Edit: I was right about valgrind, but there is some hope:
I haven't used Ptrcheck.
您可能会发现您的编译器可以提供帮助。例如,在 Visual Studio 2008 中,检查项目属性 - C/C++ - 代码生成页面。有一个“缓冲区安全检查”选项。
我的猜测是它保留了一些额外的内存并在其中写入了一个已知的序列。如果该序列被修改,则假定缓冲区溢出。但我不确定 - 我记得在某处读过这篇文章,但我不确定它是否是关于 VC++ 的。
You may find that your compiler can help. For example, in Visual Studio 2008, check the project properties - C/C++ - Code Generation page. Theres a "Buffer Security Check" option.
My guess would be that it reserves a bit of extra memory and writes a known sequence in there. If that sequence gets modified, it assumes a buffer overrun. I'm not sure, though - I remember reading this somewhere, but I don't remember for certain if it was about VC++.
既然您已经标记了这个 C++,为什么还要使用指向 char 的指针呢?
Given that you've tagged this C++, why use a pointer to char at all?
如果启用/RTCs 编译器开关,可能有助于发现问题像这样。启用此开关后,测试仅运行一次
strcat
就会导致访问冲突。另一个有用的实用程序可以帮助解决此类问题(比堆栈更面向堆,但非常有用)是 应用程序验证器。它是免费的,可以捕获很多与堆溢出相关的问题。
If you enable the /RTCs compiler switch, it may help catch problems like this. With this switch on, the test caused an access violation when running the
strcat
only one time.Another useful utility that helps with problems like this (more heap-oriented than stack but extremely helpful) is application verifier. It is free and can catch a lot of problems related to heap overflow.
另一种选择:我们的内存安全检查器。
我认为它会处理这个案子。
An alternative: our Memory Safety Checker.
I think it will handle this case.
问题是,默认情况下,API 验证子系统未启用,并且您感兴趣的消息来自那里。
我不能代表旧版本的 BoundsChecker,但 10.5 版在这个测试中没有特别的问题。它报告正确的结果,并且 BoundsChecker 本身不会崩溃。然而,测试应用程序确实如此,因为这个特定的测试用例完全破坏了导致测试代码所在函数的调用堆栈,并且一旦该函数终止,应用程序也会这样做。
结果:100 条关于局部变量写入溢出的消息,99 条关于目标字符串不是 null 终止的消息。从技术上讲,第二条消息是不正确的,但 BoundsChecker 仅在目标字符串本身的范围内搜索空终止符,并且在第一个 strcat 调用之后,它在其范围内不再包含零字节。
免责声明:我在 MicroFocus 担任 BoundsChecker 开发人员。
The problem was that by default, the API Validation subsystem is not enabled, and the messages you were interested in come from there.
I can't speak for older versions of BoundsChecker, but version 10.5 has no particular problems with this test. It reports the correct results and BoundsChecker itself does not crash. The test application does, however, because this particular test case completely corrupts the call stack that led to the function where the test code was, and as soon as that function terminated, the application did too.
The results: 100 messages about write overrun to a local variable, and 99 messages about the destination string not being null terminated. Technically, that second message is not right, but BoundsChecker only searches for the null termination within the bounds of the destination string itself, and after the first strcat call, it no longer contains a zero byte within its bounds.
Disclaimer: I work for MicroFocus as a developer working on BoundsChecker.
我在我的 devpartner (msvc6.6) (devpartner 7.2.0.372) 中尝试过,
我确认了您观察到的行为。
在循环大约 63 次之后,我遇到了访问冲突。
compuware对此问题有什么看法?
CppCheck 将检测到此问题。
I tried it in my devpartner (msvc6.6) (devpartner 7.2.0.372)
I confirm your observed behavior.
I get an access violation after about 63 passes of the loop.
What does compuware have to say about the issue?
CppCheck will detect this issue.