Inspired by today's DailyWTF article.
The author claims that a file C:\Program.exe
would be executed when clicking on a shortcut to, for example, C:\Program Files\Doom 2\doom2.exe -nomusic
.
Supposedly, Windows first attempts to invoke C:\Program
with the arguments Files\Doom 2/doom2.exe -nomusic
.
If there is no C:\Program.exe
, it then tries C:\Program Files\Doom
with the arguments 2/doom2.exe -nomusic
.
And if there is no C:\Program Files\Doom.exe\
, it finally tries C:\Program Files\Doom 2\doom2.exe -nomusic
and succeeds.
This sounds like complete nonsense to me. I can't believe it ever worked this way. A commenter puts it well:
I find it hard to believe that any released version of Windows ever did the trial-and-error approach described by OP.
I absolutely believe that a released version of Windows had brain-dead behavior as a default. I have experienced it firsthand many, many times.
What I don't believe is that a released version of Windows had this brain-dead behavior, as described by the article. It's too huge a security flaw to have gone by unnoticed until some random Daily WTF submission uncovered it, at least a decade later since it would have had to be a version of Windows that predated XP.
Edit for clarity: Here's how I tested this myself.
- Copy notepad.exe to C:\program.exe
- Run C:\program files\Internet explorer\iexplore.exe
- Notepad opens. This is expected because it finds something called C:\program
- Move progam.exe to C:\program files\Internet.exe
- Run C:\program files\Internet explorer\iexplore.exe
According to the author of the article (and this article from Microsoft), notepad should still open. But it doesn't, the command fails with this message:
C:\program is not recognized as an internal or external command, operable program or batch file.
Again, I am not debating the article's claim that C:\program would be invoked. I am debating that Windows recursively tries every directory until it hits a match.
So, did any version of Windows ever work this way?
Answer
Every version of Windows since long file names where added works this way from Windows 95 and up to including Windows 7.
This is behavior is documented:
The lpApplicationName parameter can be NULL. In that case,
the module name must be the first white space–delimited token in the
lpCommandLine string.
If you are using a long file name that contains a space, use quoted
strings to indicate where the file name ends and the arguments begin;
otherwise, the file name is ambiguous. For example, consider the
string "c:\program files\sub dir\program name". This string can be
interpreted in a number of ways. The system tries to interpret the
possibilities in the following order: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
As to why it asks this way - so that it doesn't break programs that can't handle spaces in file names correctly.
Edit
It appears the the "Run" command doesn't behave like this - it must have some extra logic added to handle this exact case. However trying to run from anywhere else - including using the CreateProcess
function directly which is what most applications would use to run a command.
The see this behavior in action:
- Open an administrative Command Prompt
- Run:
copy c:\Windows\System32\notepad.exe c:\program.exe
- Run:
c:\Program Files\Internet Explorer\iexplore.exe
- Notepad will open telling you it can't find
Files\Internet Explorer\iexplore.exe
- Type
c:\Program Files\Internet Explorer\iexplore.exe
into the Run option and IE will open correctly.
Edit 2 In the case of your C:\program files\internet.exe
example; I believe this is the command line interpreter getting in the way. It tries to process and tokenize the command line into parameters broken up by spaces. So it takes C:\program
as the first token and interprets that as the program name as the rest as parameters.
For a test I created a small application that calls CreateProcess
directly and it behaves exactly as documented. Your C:\program files\internet.exe
example will launch C:\program files\internet.exe
. So it appears that the behavior depends on exactly how the command is run - something may be processing the command line before passing it to CreateProcess
.
Example program:
#include
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);
}
No comments:
Post a Comment