Defense in depth -- the Microsoft way (part 27): the command line you get differs from the command line I use to call you Jan 31 2015 12:31PM
Stefan Kanthak (stefan kanthak nexgo de)
Hi @ll,

on Windows, the command line an application receives can differ
from the command line the calling application supplies to

The documentation of GetCommandLine()
<https://msdn.microsoft.com/en-us/library/ms683156.aspx> tells:

| Note The name of the executable in the command line that
| the operating system provides to a process is not necessarily
| identical to that in the command line that the calling process
| gives to the CreateProcess function. The operating system may
| prepend a fully qualified path to an executable name that is
| provided without a fully qualified path.

This is not the whole truth, another "Note" is missing there:
when CreateProcess*() is called using a command line with an
UNQUOTED "long" filename/pathname containing spaces (a well-known
VULNERABILITY: <https://cwe.mitre.org/data/definitions/428.html>)
it uses try&error to guess the pathname of the executable.

The documentation of CreateProcess()
<https://msdn.microsoft.com/en-us/library/ms682425.aspx> tells:

| [...] 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

In the latter 3 cases the command line is but modified too:
Windows adds quotes around the part of the command line which
forms the result of this "interpretation" and yields the path
to the executable if this part contains a space.

The 4 command lines shown above are transformed into:

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"

JFTR: without this transformation splitting of the command line
into the "argv" vector would give wrong results ... in
presense of CreateProcess*() braindead behaviour!

Stay tuned!

Stefan Kanthak

PS: the documentation of CommandLineToArgvW()
contains a "funny" and surprising remark:

| This function accepts command lines that contain a program name;
| the program name can be enclosed in quotation marks or not.

This does but NOT mean that CommandLineToArgvW() tries to
guess like CreateProcess()!
It treats c:\program files\sub dir\program name
as "c:\program" "files\sub" "dir\program" "name".

[ reply ]


Privacy Statement
Copyright 2010, SecurityFocus