Версия Windows когда-либо вела себя так?

36

Вдохновлен сегодняшней статьей 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 было такое умопомрачительное поведение, как описано в статье. Это слишком большой недостаток безопасности, чтобы остаться незамеченным, пока какая-то случайная ежедневная отправка WTF не обнаружит его, по крайней мере, десятилетие спустя, поскольку это должна была быть версия Windows, предшествующая XP.

Отредактируйте для ясности: вот как я сам это проверял.

  1. Нужно скопировать файл notepad.exe в C: \ program.exe.
  2. Запустите C: \ program files \ Internet explorer \ iexplore.exe
  3. Блокнот открывается. Это ожидается, потому что он находит что-то под названием C: \ program
  4. Переместите progam.exe в C: \ program files \ Internet.exe
  5. Запустите C: \ program files \ Internet explorer \ iexplore.exe

По словам автора статьи ( и этой статьи от Microsoft ), блокнот все равно должен открываться. Но это не так, команда завершается с этим сообщением:

C:\program is not recognized as an internal or external command, operable program or batch file.

Опять же, я не обсуждаю утверждение статьи о том, что будет вызвана программа C: \. Я спорю, что Windows рекурсивно пытается каждый каталог, пока он не совпадет.

Итак, какая-нибудь версия Windows когда-либо работала таким образом?

dpatchery
источник
1
Да ! Смотрите ответ @ grawity здесь: superuser.com/a/373756/100787
iglvzx,
2
Вы должны быть проверены все комментарии;) msdn.microsoft.com/en-us/library/windows/desktop/...
Baarn
Кажется, что здесь происходит два (или более) отдельных вопроса: позволит ли Windows создать ярлык для C:\Program Files\..., и интерпретирует ли Windows такой ярлык (или команду «Выполнить», или команду командной строки, или какой-либо другой метод) как "C:\Program" Files\.... Первая часть кажется маловероятной, но вторая часть кажется вероятной и ожидаемой для меня.
mwfearnley
Третий вопрос, я думаю, таков: будет ли интерпретироваться какой-либо из методов выполнения команд Windows C:\Program Filesкак "C:\Program Files"? После небольшого прочтения, похоже, что ответ в некоторых случаях может быть «да», что является единственной действительно неожиданной областью.
mwfearnley

Ответы:

32

Каждая версия Windows с тех пор, как добавлены длинные имена файлов, работает таким образом, начиная с Windows 95 и вплоть до Windows 7.

Это поведение задокументировано :

Параметр lpApplicationName может иметь значение NULL . В этом случае имя модуля должно быть первым токеном с пробелами в строке lpCommandLine . Если вы используете длинное имя файла, которое содержит пробел, используйте строки в кавычках, чтобы указать, где заканчивается имя файла и начинаются аргументы; в противном случае имя файла неоднозначно. Например, рассмотрим строку «c: \ program files \ sub dir \ имя программы». Эта строка может быть интерпретирована несколькими способами. Система пытается интерпретировать возможности в следующем порядке:

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функции напрямую, что большинство приложений будет использовать для запуска команды.

Видите это поведение в действии:

  1. Откройте административную командную строку
  2. Бег: copy c:\Windows\System32\notepad.exe c:\program.exe
  3. Бег: c:\Program Files\Internet Explorer\iexplore.exe
  4. Блокнот откроется, сообщив, что не может найти Files\Internet Explorer\iexplore.exe
  5. Введите c:\Program Files\Internet Explorer\iexplore.exeопцию Run, и 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);
}
shf301
источник
1
Посмотрите мои изменения, почему это не отвечает на мой вопрос. Вы проверяли только первое в указанном порядке, я спрашиваю о втором.
dpatchery
Я сам провел немного больше исследований и согласен с вашим последним редактированием - похоже, расхождение между cmd.exe и функцией CreateProcess. Цвет меня убедил!
dpatchery
Эта часть кажется неправильной: ваш пример C: \ program files \ internet.exe запустит C: \ program files \ internet.exe
Даниэль Бек
Согласно CreateProcessстранице на MSDN, это происходит только в том случае, если для параметра lpApplicationName задано значение NULL . В противном случае система будет использовать этот параметр в качестве программы для запуска и не будет искать ее. Я бы предположил, что команда «Выполнить» НЕ предоставляет здесь параметр NULL , поэтому она не будет искать программу таким образом.
Кевин Панко
1
@ shf301 Он действительно использует, ShellExecuteExа потом звонитCreateProcess
Кевин Панко
5

Я просто хочу добавить что-то к предыдущим ответам.

Хотя можно заставить это поведение с помощью усилий, плохого программирования (не RTFM) или не поддающегося проверке идеального шторма, вызванного этой конкретной антивирусной программой, ничто не могло бы вызвать поведение, описанное в статье. Абсолютно ни в коем случае не будет правильно создан ярлык, например, который нацелен на "C: \ Program Files \ Microsoft \ Office \ Word.exe", с кавычками, и запустите C: \ Program.exe. То же самое с Firefox. Черт, в принципе невозможно создать ярлык, который бы не был экранирован должным образом, потому что это сделано разумно.

Если вы создадите ярлык на рабочем столе, указывающий на 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 не допустит этой ошибки.

lordcheeto
источник