简单的符号(^)在Windows批处理文件末尾会占用所有内存

57

这个简单的批处理文件在相对短的时间内会消耗掉Windows 7(x64)上所有可用的内存。发生了什么?有什么预防措施可以采取来避免这种情况发生?

any-invalid-command-you-like-here ^

显然,展示此效果需要满足以下必要条件:

  • 插入符号 ^ 必须是文件的最后一个字符,并且脚本末尾没有换行符
  • 插入符号前面至少有两个空格或字符,例如在下面的代码中,如果点号(.)代表空格,则不会触发内存泄漏:.^,而这个代码则会触发:..^(但速度较慢)

在这张进程管理器截图中,该脚本已运行约30秒,使用了2.9GB内存,而且内存使用量还在持续稳定地上升:

已使用2.9GB内存,而且内存使用量还在持续稳定地上升

如果您要尝试使用此功能,请确保能够找到“关闭窗口[X]”控件,或者已经打开任务管理器或者进程管理器以备用,因为按下 Ctrl-C, Ctrl-Break, Alt-F4没有作用

多个插入符号将导致内存使用量更快速地升高。第一次遇到此问题时,1-2分钟内没有足够的可用内存进行简单操作,例如Alt-Tab,即使是三指敬礼的Ctrl-Alt-Del也无效。我不得不强制关闭机器。


不,我收到了两个错误信息(XP):以下字符串太长语法错误(已翻译)。之后脚本终止。 - Endoro
1
我添加了标签:[tag:security],因为这个可以被恶意使用而不需要太多麻烦就能让机器崩溃。如果这是不合适的使用,请删除该标签。 - matt wilkie
5
当同事离开工作机时没有锁屏,我可以想象成千上万的人在地球上运行这个程序...只需打开命令提示窗口,执行程序,最小化窗口然后离开即可。 - NotMe
3
已修复于Windows 10系统中。 - user202729
1个回答

46

想法

从我的理解来看,这是由于cmd解释器正在寻找一个字符进行转义,因为^是批处理的转义字符。在这种情况下,cmd没有正确地识别文件结束标志符eof,并继续循环和初始化某些东西,同时寻找要转义的字符。

在Windows 8 Pro (64)上使用cc^^^(多个脱字符用于加速泄漏)进行复制。

试验

cc^会无限循环和缓慢泄漏。

cc^^崩溃并显示普通的无效命令错误。

cc^^^会无限循环和更快地泄漏。

cc ^会无限循环和缓慢泄漏。

cc ^^崩溃并显示普通的无效命令错误。

cc ^^^会无限循环和更快地泄漏。

cc"^崩溃并显示普通的无效命令错误。

cc"^^崩溃并显示普通的无效命令错误。

cc"^^^崩溃并显示普通的无效命令错误。

注意

  • 只有在引号之外使用插入符^时才会出现无限循环和泄漏。当添加引号时,脚本会崩溃并显示标准的无效命令错误。
  • 只有在批处理文件以UTF-8ASCII编码时才会出现无限循环和泄漏。当以UTF-16编码时,脚本会崩溃并显示标准的无效命令错误。
  • 必须是奇数个插入符^,以避免转义最后一个插入符。

预防措施

  • 确保没有批处理脚本以插入符^(0x5E)结尾,或者至少有奇数个插入符。
  • 或者将它们编码为UTF-16。

6
感谢提供的延长试用信息和可能的解释。我没有考虑过测试编码。第一个预防措施的另一种表达方式可能是“总是以空行结束”,这是记事本应用程序一直以来都做的事情,也许这就是其中之一的原因。;) - matt wilkie
1
@mattwilkie 谢谢,我觉得你的预防措施措辞最好。 “总是以一行空白结束” :) - David Ruhmann
14
事实证明,这实际上是命令行解析器中的一个漏洞以及它如何解析批处理文件。更具体地说,这是一个逻辑错误;如果一个插入符在 EOF,那么真正的 EOF 就会被“忽略”和“跳过”,将文件句柄重置为 0,从而重新解析脚本。请参阅我在此处的详细问题,了解更多相关信息:http://stackoverflow.com/questions/23284131/could-this-cmd-exe-batch-file-parsing-bug-lead-to-other-exploits-nul-in - txtechhelp
5
@txtechhelp,这是您的问题的存档版本,因为原始问题已被移除。 - Engineer Toast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接