
靈感來自今天的 DailyWTF 文章。
作者聲稱,C:\Program.exe
當單擊快捷方式時,例如C:\Program Files\Doom 2\doom2.exe -nomusic
.
據推測,Windows 首先嘗試C:\Program
使用參數進行呼叫Files\Doom 2/doom2.exe -nomusic
。
如果沒有C:\Program.exe
,它就會嘗試C:\Program Files\Doom
使用參數2/doom2.exe -nomusic
。
如果沒有C:\Program Files\Doom.exe\
,它最終會嘗試C:\Program Files\Doom 2\doom2.exe -nomusic
並成功。
這對我來說完全是無稽之談。我不敢相信它曾經以這種方式運作過。有網友評論說得好:
我很難相信任何已發布的 Windows 版本都採用了 OP 描述的試誤方法。
我絕對相信 Windows 的發布版本預設具有腦死行為。我已經親身經歷過很多很多次了。
我不相信 Windows 的發布版本有這正如文章所描述的,腦死行為。這是一個太大的安全缺陷,不可能被忽視,直到一些隨機的 Daily WTF 提交發現了它,至少十年後,因為它必須是 XP 之前的 Windows 版本。
為了清楚起見編輯:這是我自己測試的方法。
- 將notepad.exe複製到C:\program.exe
- 執行 C:\program files\Internet explorer\iexplore.exe
- 記事本打開。這是預期的,因為它找到了名為 C:\program 的東西
- 將 progam.exe 移到 C:\program files\Internet.exe
- 執行 C:\program files\Internet explorer\iexplore.exe
據文章作者介紹(以及微軟的這篇文章),記事本應該仍然打開。但事實並非如此,該命令失敗並顯示以下訊息:
C:\program is not recognized as an internal or external command, operable program or batch file.
再次強調,我並不是爭論文章中關於 C:\program 將被呼叫的說法。我正在爭論 Windows 會遞歸地嘗試每個目錄,直到找到匹配的目錄。
那麼,是否有任何版本的 Windows 都以這種方式運行過呢?
答案1
從 Windows 95 到 Windows 7,新增長檔名後的每個 Windows 版本都以這種方式運作。
這是行為記錄在案:
這lp應用程式名稱參數可以是無效的。在這種情況下,模組名稱必須是模組名稱中的第一個空格分隔的標記。 lp命令列細繩。如果您使用包含空格的長檔名,請使用引號的字串來指示檔名結束位置和參數開始位置;否則,檔名不明確。例如,考慮字串「c:\program files\sub dir\program name」。該字串可以用多種方式解釋。系統嘗試以以下順序解釋可能性:
c:\program.exe files\sub dir\program name c:\program files\sub.exe dir\program name c:\program files\sub dir\program.exe name c:\program files\sub dir\program name.exe
至於為什麼會這樣問——所以它不會破壞無法正確處理檔案名稱中空格的程序。
編輯
看來「運行」命令的行為並非如此 - 它必須添加一些額外的邏輯來處理這種確切的情況。然而,嘗試從其他任何地方運行 - 包括CreateProcess
直接使用該函數,這是大多數應用程式用來運行命令的方法。
查看此行為的實際效果:
- 開啟管理命令提示符
- 跑步:
copy c:\Windows\System32\notepad.exe c:\program.exe
- 跑步:
c:\Program Files\Internet Explorer\iexplore.exe
- 記事本將打開告訴你找不到
Files\Internet Explorer\iexplore.exe
- 輸入
c:\Program Files\Internet Explorer\iexplore.exe
“運行”選項,IE 將正確開啟。
編輯2就你的C:\program files\internet.exe
例子而言;我相信這是命令列解釋器的阻礙。它嘗試將命令列處理並標記為由空格分隔的參數。因此,它C:\program
作為第一個標記並將其解釋為程式名稱,其餘部分解釋為參數。
為了進行測試,我創建了一個CreateProcess
直接調用的小型應用程序,並且其行為與文件完全相同。您的C:\program files\internet.exe
範例將啟動C:\program files\internet.exe
。因此,該行為似乎完全取決於命令的運作方式 - 在將命令列傳遞給 之前,某些東西可能正在處理命令列CreateProcess
。
範例程式:
#include <Windows.h>
void main()
{
STARTUPINFO si = {0};
si.cb= sizeof(si);
PROCESS_INFORMATION pi = {0};
CreateProcess(NULL, "c:\\program files\\internet explorer\\iexplore.exe",
NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
}
答案2
我只是想在之前的答案中添加一些內容。
雖然可以透過努力、不良程式設計(不是 RTFM)或此特定防毒程式引起的無法驗證的完美風暴來強制執行此行為,但沒有任何東西會導致本文描述的行為。絕對不可能正確建立捷徑,例如,以「C:\Program Files\Microsoft\Office\Word.exe」為目標的捷徑(帶引號)執行 C:\Program.exe。與火狐瀏覽器相同。天哪,創建一個無法正確轉義的快捷方式基本上是不可能的,因為它是明智地完成的。
如果您在桌面上建立指向 Firefox 的捷徑,它將正確轉義。如果您右鍵單擊 -> 屬性並嘗試刪除引號,那麼當您點擊「應用」時,即使 C:\Program.exe 存在,它也會自動插入它們。當它解析它時,我猜測它要么優先考慮資料夾,要么將最後一個“\”之前的所有內容視為路徑的一部分。只有當您在 Program 和 Files 之間插入兩個空格時,它才會被解析為帶參數指向 C:\Program.exe。如果您可以在文字編輯器中編輯快捷方式(它不是純文字),那麼它可能會起作用。
與快捷方式非常相似,「運行對話框」也能正確解析字串。只有在較低階的指令控制台中才會錯誤地呼叫C:\Program.exe,但不會嘗試其他各種可能性。也就是說,它會錯誤地嘗試呼叫“C:\Program.exe”,但不會嘗試呼叫“C:\Program Files\Internet.exe”或其他任何內容,即使有這些可能性。它將傳回一個錯誤,指出找不到 C:\Program.exe。
最重要的是,當 C:\ 資料夾中有 Program.exe 時,它會在啟動時警告您並詢問您是否要重新命名它。這已經針對 XP、Vista、Windows 7 進行了驗證,我現在可以驗證 Windows 8 (http://goo.gl/eeNCp)。或許這在 Windows 9x 中是可能的,但我對此表示懷疑。
底線是,這是顯而易見的,沒有 Windows 程式設計師會犯這個錯誤。