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


Вдохновлен сегодняшняя статья 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: \ program будет вызываться. Я обсуждаю, что Windows рекурсивно пробует каждый каталог, пока он не достигнет совпадения.

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


36
2018-04-18 17:49


происхождения


да! См. Ответ @ grawity: superuser.com/a/373756/100787 - iglvzx
Вы должны были проверить все комментарии;) 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


ответы:


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

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

lpApplicationName параметр может быть НОЛЬ, В таком случае,   имя модуля должно быть первым маркером, ограниченным пробелом в    lpCommandLine строка.   Если вы используете длинное имя файла, содержащее пробел, используйте цитируемый   строки, указывающие, где заканчивается имя файла и начинаются аргументы;   в противном случае имя файла неоднозначно. Например, рассмотрим   string "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

Что касается того, почему он спрашивает этот путь - так, чтобы он не прерывает программы, которые не могут корректно обрабатывать пробелы в именах файлов,

редактировать Похоже, команда «Run» не ведет себя так: у нее должна быть добавлена ​​дополнительная логика для обработки этого точного случая. Однако попытка запустить из любого места - в том числе с помощью 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);
}

31
2018-04-18 18:06



См. Мое редактирование, почему это не отвечает на мой вопрос. Вы только проверили первое в заданном порядке, я спрашиваю о втором. - dpatchery
Я сделал немного больше исследований самостоятельно, и я согласен с вашим последним правлением - похоже, что расхождение лежит между cmd.exe и функцией CreateProcess. Цвет меня убедил! - dpatchery
Эта часть кажется неправильной: Ваш пример C: \ program files \ internet.exe запустит C: \ program files \ internet.exe - Daniel Beck♦
Согласно CreateProcess в MSDN, это происходит только в том случае, если lpApplicationName параметр НОЛЬ, В противном случае система будет использовать этот параметр для запуска программы и не будет искать ее. Я бы предположил, что команда «Run» НЕ предоставляет НОЛЬ параметр здесь, поэтому он не будет искать программу таким образом. - Kevin Panko
@ shf301 Он действительно использует ShellExecuteEx и затем вызывает CreateProcess - Kevin Panko


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

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

Если вы создадите ярлык на рабочем столе, указывающий на Firefox, он будет экранирован должным образом. Если вы правильно пометили -> свойства и попытались удалить кавычки, они автоматически вставляют их при наложении, даже если C: \ Program.exe существует. Когда он анализирует это, я предполагаю, что он либо отдает предпочтение папке, либо обрабатывает все до последнего «\» как часть пути. Только если вы вставляете два пробела между программой и файлами, он будет разбираться как указывающий на C: \ Program.exe с аргументами. Если вы можете отредактировать ярлык в текстовом редакторе (это не открытый текст), это может сработать.

Подобно ярлыкам, Run Dialog правильно разбирает строку. Только в относительно низкоуровневой командной консоли будет неправильно называть 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 не допустит эту ошибку.


5
2018-04-19 16:47