Чи вела себе версія версії 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 коли-небудь робила підхід проб і помилок, описаний ОП.

Я абсолютно вважаю, що випущена версія Windows за замовчуванням мала поведінку, що загинула мозку. Я переживав це з перших вуст багато, багато разів.

Я не вірю в те, що випущена версія Windows мала таку смертельну поведінку, як описано у статті. Це занадто величезний недолік безпеки, щоб він пройшов непомітно, поки деякі випадкові щоденні подання WTF не розкрили його, принаймні через десятиліття, оскільки це повинно було бути версією Windows, що передувала XP.

Редагування для наочності: Ось як я сам це перевірив.

  1. Скопіюйте notepad.exe в C: \ program.exe
  2. Запустіть C: \ програмні файли \ Internet Explorer \ iexplore.exe
  3. Відкриється блокнот. Це очікується, оскільки він знаходить щось, що називається програмою C: \
  4. Перемістіть файл progam.exe на C: \ програмні файли \ Internet.exe
  5. Запустіть C: \ програмні файли \ Internet Explorer \ iexplore.exe

За словами автора статті ( і цієї статті від Microsoft ), блокнот все одно повинен відкриватися. Але це не так, команда не працює з цим повідомленням:

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

Знову ж таки, я не обговорюю заяву статті про те, що буде викликано програму C: \. Я обговорюю, що Windows рекурсивно намагається виконувати всі каталоги, поки не потрапить у відповідність.

Отже, чи працювала будь-яка версія Windows таким чином?


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: \ програмні файли \ 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у параметр «Виконати» і IE відкриється правильно.

Edit 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);
}

1
Перегляньте мою редакцію, чому це не відповідає на моє запитання. Ви випробували лише перше, що було в заданому наказі, я прошу про друге.
dpatchery

Я трохи провів більше досліджень, і я погоджуюся з вашою останньою редакцією - схоже, що невідповідність лежить між cmd.exe і функцією CreateProcess. Колір мене переконав!
dpatchery

Ця частина не здається правильною: Ваш приклад C: \ програмні файли \ internet.exe запустить C: \ програмні файли \ internet.exe
Daniel Beck

Відповідно до 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 існує. Коли він аналізує це, я здогадуюсь, що він або надає перевагу папці, або обробляє все до останнього "\" як частину шляху. Тільки якщо ви вставите два проміжки між програмою та файлами, вони будуть розбиратися як вказівки на аргументи C: \ Program.exe. Якщо ви можете відредагувати ярлик у текстовому редакторі (це не простий текст), він може працювати.

Так само, як і ярлики, діалогове вікно Run також правильно аналізує рядок. Тільки на відносно низькому рівні консолі команд він буде неправильно викликати 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 не допустив би цієї помилки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.