1 little known secret of ShellExec_RunDLL

The ShellExec_RunDLL API is now exposed by both shell32.dll and windows.storage.dll.

It is not the only curiosity about this function. Analysing its code one can discover that is accepts a secret command line argument.

If we provide a question mark in the command line argument, the function will interpret the string that follows the question mark as a number. It will then convert that numerical value into a number using StrToIntExW with a STIF_SUPPORT_HEX flag (accepts either decimal or hexadecimal number), and then add that value to 0x100 (SEE_MASK_NOASYNC/SEE_MASK_FLAG_DDEWAIT). Finally, use the resulting total to set the SHELLEXECUTEINFO.fMask value passed to ShellExecuteEx. The function then searches for the second question mark and then uses the position following that question mark as a place where the actual command line passed to ShellExecuteEx starts:

If it sounds too complicated, the basic idea is that function can be invoked in 2 modes:

  • regular invocation
shell32.dll, ShellExec_RunDLL <cmd line argument>
windows.storage.dll, ShellExec_RunDLL <cmd line argument>
  • invocation that modifies fmask
shell32.dll, ShellExec_RunDLL <?fmaskvalue?> <cmd line argument> 
windows.storage.dll, ShellExec_RunDLL <?fmaskvalue?> <cmd line argument>

f.ex.:

ShellExec_RunDLL ?100?calc.exe

And if you are looking for a better example:

ShellExec_RunDLL ?0x00800000?<file>

can be used to bypass Zone.Identifier checks (0x00800000 = SEE_MASK_NOZONECHECKS) for the executed file.

Since the parsing of the fmask value is done with a code that allows for many different inputs, many interesting invocations are possible:

ShellExec_RunDLL ?100?calc.exe
ShellExec_RunDLL ? 100 ?calc.exe
ShellExec_RunDLL ? 0x100 0x200 ?calc.exe
ShellExec_RunDLL ?0x100 notepad.exe?calc.exe
ShellExec_RunDLL ?0x100 format c: ?calc.exe
ShellExec_RunDLL ?0x100 https://google.com ?calc.exe
ShellExec_RunDLL ?0x100 c:\programdata\malware\calc.exe ?calc.exe

Every single one of them will launch Calculator.

1 little known secret of explorer.exe

Windows Explorer is a beast. It does so many things when it starts that it hurts…

Sometimes, literally.

One of the things it checks during its startup routine is the comparison of the Registry value HKEY_CURRENT_USER\Control Panel\Appearance\SchemeLangID and the result of the call to GetUserDefaultUILanguage API. If they do not match, it attempts to load a ‘desk.cpl’ library and call its UpdateCharsetChanges function.

So….

We can create a dodgy desk.cpl, copy explorer.exe to the same folder, kill all the explorer.exe instances, and then make sure the Registry value doesn’t match the result of the call to GetUserDefaultUILanguage API. Then we can run explorer.exe from that folder and the lame lolbin magic happens: