[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Defense in depth -- the Microsoft way (part 14): incomplete, misleading and dangerous documentation
here's another (well-known, but undocumented) idiosyncrasy of Windows'
CreateProcess*() functions with a "nice" side-effect:-P
| BOOL WINAPI CreateProcess(
| _In_opt_ LPCTSTR lpApplicationName,
| _Inout_opt_ LPTSTR lpCommandLine,
| To run a batch file, you must start the command interpreter; set
| lpApplicationName to cmd.exe and set lpCommandLine to the following
| arguments: /c plus the name of the batch file.
This is but wrong (and of course dangerous too: you should NEVER set
lpApplicationName to an unqualified filename, but ALWAYS use the fully
qualified pathname; see <http://support.microsoft.com/kb/2269637>
Now the REAL behaviour (of Windows NT4, Windows NT5.x, Windows NT6.x):
CreateProcess(NULL, "<pathname>.cmd[ ...]", ...)
CreateProcess(NULL, "<pathname>.bat[ ...]", ...)
(and of course CreateProcessAsUser(), CreateProcessWithLogonW() and
CreateProcessWithTokenW() too) execute a rogue program CMD.EXE from
the 'application directory' (i.e. the directory where the program that
calls CreateProcess*() is located) instead of the expected %COMSPEC%
alias %SystemRoot%\System32\cmd.exe, with the command line set to
"cmd /c \"<pathname>.cmd\"" resp. "cmd /c <pathname>.cmd[ ...]".
| lpCommandLine [in, out, optional]
| If the file name does not contain an extension, .exe is appended.
| If the file name does not contain a directory path, the system
| searches for the executable file in the following sequence:
| 1. The directory from which the application loaded.
| 2. The current directory for the parent process.
| 3. The 32-bit Windows system directory.
JFTR: ShellExecute*() calls CreateProcess*() to start <pathname>.bat
and <pathname>.cmd, so Windows Explorer (and of course any
other program calling ShellExecute*() too) start CMD.EXE from
their 'application directory' or the 'current working directory'
The 'application directory' of Windows Explorer is %SystemRoot%,
and Windows Explorer sets the 'current working directory' to the
path of the file to be opened.
%SystemRoot%\System32\CMD.EXE is found via the documented search
path ... until someone creates a CMD.EXE in %SystemRoot% or the
'current working directory' (i.e. the directory where
<filename>.bat or <filename>.cmd is located).
FIX (for ShellExecute*() and Windows Explorer):
change the value of the default registry entries of
[HKEY_CLASSES_ROOT\batfile] and [HKEY_CLASSES_ROOT\cmdfile]
from @="%1 %*"
to @=expand:"%SystemRoot%\\System32\\cmd.exe /C Call \"%L\" %*"
or @=expand:"\"%COMSPEC%\" /C Call \"%L\" %*"
Additionally, see <http://support.microsoft.com/kb/905890> as well
as <http://msdn.microsoft.com/library/aa365527.aspx> and set
PS: when <filename>.bat or <filename>.cmd are started from Windows
Explorer the console window of the new process shows the icon of
the CMD.EXE found in the 'current working directory' (i.e. the
directory where <filename>.bat or <filename>.cmd is located), not
the icon of the command processor %SystemRoot%\System32\cmd.exe
... independent of the above mentioned fixes!
But that's just another of Windows' many idiosyncrasies!
2013-10-23 informed vendor
2013-10-24 vendor replies: see
2013-10-24 NO, this does NOT describe the behaviour of CreateProcess()
or ShellExecute() for *.CMD and *.BAT
2013-10-24 vendor replies: MSRC case 15734 opened
2013-11-18 requested status from vendor
2013-11-24 no answer, report published