Program
今天突然在 的根目录下出现了一个名为 的文件C:\
,登录系统时,弹出一条消息:
文件名警告
您的计算机上有一个名为“C:\Program”的文件或文件夹,它可能会导致某些应用程序无法正常运行。将其重命名为“C:\Program1”即可解决问题。您要立即重命名吗?
虽然消息是不言自明的,但我想知道为什么这个文件会有这么大的影响?事实上,位于中的一些程序(可能是所有程序,我没有检查)C:\Program Files...
根本没有启动。我可以理解如何创建这样的文件(例如,尝试写入文件夹C:\Program Files\Something...
但不带引号),但我几乎不明白它如何影响其他程序。
答案1
它之所以影响如此之大,是因为 Win32 API 中存在一个众所周知的弱点。
在 Win32 中,程序是通过CreateProcess()
系统调用生成的。它可以以多种方式使用。来自 Unix、Linux 或 OS/2 背景的人通常会认为它需要两个单独的参数,用于生成的程序(图像文件)和要传递给新进程的命令尾,因为文件名和参数向量/命令尾在这些操作系统的 API 中是两个独立的东西。但实际上,系统调用可以以另一种形式调用,将程序名称和参数混合在一个大字符串中。 CreateProcess()
将尝试将程序文件名与命令尾分开。
问题在于,它会通过在每个连续的空格字符处逐步将字符串一分为二来实现这一点,直到左侧部分与文件或目录匹配。许多 Win32 程序会尝试将字符串传递C:\Program Files\Contoso\TakeOver.exe StackExchange.com
给系统调用。这将运行正确的程序 — C:\Program Files\Contoso\TakeOver.exe
— 使用正确的命令尾 — StackExchange.com
— 直到某个明显危险的人出现并C:\Program
像您一样创建一个文件。
此时,系统调用最终会尝试C:\Program
使用命令 tail运行程序映像文件。如果它实际上是一个可执行程序映像,Files\Contoso\TakeOver.exe StackExchange.com
那就太可惜了。C:\Program
这是一个普遍的弱点,它适用于任何包含空格的程序文件名以及任何使用一个大字符串来生成其他程序的程序。但最普通受此影响的情况是所有运行于该模式的程序C:\Program Files\
以及大量使用“一个大字符串”方法的 Win32 程序。
现在改变 Win32 API 已经太迟了。十年前就已经太迟了。微软无法改变所有的程序其他人写的向 传递一个大字符串而不是两个CreateProcess()
。因此,Microsoft 让 Windows 在用户登录时检查是否存在C:\Program
并显示您看到的警告。
而且,正如你所看到的,微软的 Win32 文档中有一个巨大的“安全”警告,告诉开发人员不写程序使用“One Big String”方法,该方法已经存在好几年了。
进一步阅读
- CreateProcess() 函数. MSDN。微软公司。
- Raymond Chen(2011-08-08)。 如果程序名称和参数之间没有空格,CreateProcess 函数会做什么?. 旧新事物。
- Rajorshi(2009-05-13)。 CreateProcess 漏洞. 开发者文档。
- 2005-11-15。 安全公告:多个供应商对 CreateProcess() 的不安全调用漏洞。防御。