这个缓冲区溢出的后果?

Kev*_*enK 20 c c++ printf buffer-overflow

所以在这里我相信我在查看其他人的代码时发现了一个小的缓冲区溢出问题.它立刻让我觉得不正确,而且有潜在危险,但不可否认,我无法解释这个"错误"的实际后果,如果有的话.

我写了一个测试应用程序来演示错误,但发现(令我沮丧的是)无论溢出如何,它似乎都能正常运行.我想相信这只是偶然的,但是需要一些反馈来确定我的想法是否错误,或者是否真的存在问题,而不是在我的测试应用程序中显示出来.

问题代码(我认为无论如何):

char* buffer = new char[strlen("This string is 27 char long" + 1)];
sprintf(buffer, "This string is 27 char long");
Run Code Online (Sandbox Code Playgroud)

现在,这对我来说很突出,我想把它标记为可能的缓冲区溢出是因为第一个strlen.由于指针运算,"错误"放置+ 1将导致strlen返回26而不是27(取"他的字符串的长度为27个字符长").sprintf我相信,然后将27个字符打印到缓冲区并导致缓冲区溢出.

这是正确的评估吗?

我编写了一个测试应用程序来为我正在查看的代码演示这个,并发现即使在调试器中字符串也会正确打印.我还尝试在此代码之前和之后将其他变量放在堆栈和堆上,以查看是否可以影响邻近的内存区域,但仍然收到正确的输出.我意识到我新分配的堆内存可能不相邻,这可以解释缺乏有用的溢出,但我真的想确认其他人的意见,如果这实际上是一个问题.

由于这是一个非常简单的"问题",如果你能通过某种参考来支持你的答案,那就太好了.虽然我重视并欢迎您的意见,但我不会接受"是的"作为最终答案.提前谢谢你.




更新:许多有很多额外见解的好答案.不幸的是,我无法接受所有这些.感谢您分享您的知识并成为我的"第二意见".我很感激帮助.

pet*_*hen 14

您的评估是正确的.[编辑]加上James Curran提到的修正.[/ edit]

可能,您的测试应用程序没有显示问题,因为分配被四舍五入到下一个4,8或16的倍数(这是常见的分配粒度).

这意味着您应该能够使用31个字符长的字符串进行演示.

或者,使用"仪器化"本机内存分析器,它可以将保护字节紧密围绕这样的分配.


Jam*_*ran 6

您的评估是正确的,除了springf将在缓冲区中放入28个字符,计算结束时字符串结尾的NUL(这就是为什么你首先需要放错位置的"+1")

请注意,根据我的经验,如果某些内容在调试器之外失败,但在调试器中逐步执行,则在100%的时间内,您已超出本地缓冲区.调试器将更多内容推送到堆栈上,因此重写的内容不太可能被覆盖.