C 中的字符串溢出检测

发布于 2024-08-23 02:44:20 字数 256 浏览 9 评论 0原文

我们使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

俯瞰星空 2024-08-30 02:44:21

一种选择是简单地禁止使用没有目标缓冲区信息的字符串函数。通用包含的标头中的一组宏(如下所示)可能会有所帮助:

#define strcpy  strcpy_is_banned_use_strlcpy
#define strcat  strcat_is_banned_use_strlcat
#define strncpy strncpy_is_banned_use_strlcpy
#define strncat strncat_is_banned_use_strlcat
#define sprintf sprintf_is_banned_use_snprintf

因此,任何尝试使用“禁止”例程的行为都将导致链接器错误,该错误还会告诉您应该使用什么。 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:

#define strcpy  strcpy_is_banned_use_strlcpy
#define strcat  strcat_is_banned_use_strlcat
#define strncpy strncpy_is_banned_use_strlcpy
#define strncat strncat_is_banned_use_strlcat
#define sprintf sprintf_is_banned_use_snprintf

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.

梦开始←不甜 2024-08-30 02:44:21

valgrind 将检测过去动态分配的数据的写入,但我认为它不能像您的示例中那样对于自动数组执行此操作。如果您使用 strcatstrcpy 等,则必须确保目标足够大。

编辑:我关于 valgrind 的看法是正确的 ,但还是有一些希望:

不幸的是,Memcheck 不对静态或堆栈数组进行边界检查。我们很愿意,但不可能以符合 Memcheck 工作方式的合理方式来实现。抱歉。

然而,实验工具Ptrcheck可以检测到这样的错误。使用 --tool=exp-ptrcheck 选项运行 Valgrind 进行尝试,但要注意它不如 Memcheck 强大。

我没有使用过 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 using strcat, strcpy, etc., you have to make sure that the destination is big enough.

Edit: I was right about valgrind, but there is some hope:

Unfortunately, Memcheck doesn't do bounds checking on static or stack arrays. We'd like to, but it's just not possible to do in a reasonable way that fits with how Memcheck works. Sorry.

However, the experimental tool Ptrcheck can detect errors like this. Run Valgrind with the --tool=exp-ptrcheck option to try it, but beware that it is not as robust as Memcheck.

I haven't used Ptrcheck.

£冰雨忧蓝° 2024-08-30 02:44:21

您可能会发现您的编译器可以提供帮助。例如,在 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++.

巨坚强 2024-08-30 02:44:21

既然您已经标记了这个 C++,为什么还要使用指向 char 的指针呢?

std::stringstream test;
std::fill_n(std::ostream_iterator<std::string>(test), 100, "hi");

Given that you've tagged this C++, why use a pointer to char at all?

std::stringstream test;
std::fill_n(std::ostream_iterator<std::string>(test), 100, "hi");
独闯女儿国 2024-08-30 02:44:21

如果启用/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.

八巷 2024-08-30 02:44:21

另一种选择:我们的内存安全检查器
我认为它会处理这个案子。

An alternative: our Memory Safety Checker.
I think it will handle this case.

不回头走下去 2024-08-30 02:44:21

问题是,默认情况下,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.

胡大本事 2024-08-30 02:44:20

我在我的 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文