I encountered a strange problem:
When our application spawns child process with CreateProcessWithLogonW
switch language with alt-shift stops working in the windows of the new process.
What might be the problem? The OS is XP SP3. The same setup is ok on Win 7.
Additional thing I discovered: This problem only occurs on Win XP Hebrew.
On English XP it works fine.
As Hans Passant has said CreateProcessWithLogonW requires the LOGON_WITH_PROFILE to be set as dwLogonFlags which is the fourth argument of the function in order to load the user registry hive into HKEY_USERS. This will ensure that access to information in the HKEY_CURRENT_USER registry key will produce results that are consistent with a normal interactive logon.
Alternately you can call the LoadUserProfile function beforecalling CreateProcessWithLogonW.
Registry settings you will want to verify exist for the user whose profile you are loading include
[HKEY_CURRENT_USER\Keyboard Layout\Toggle]
"Hotkey"="3"
"Language Hotkey"="3"
"Layout Hotkey"="3"
[HKEY_CURRENT_USER\Keyboard Layout\Preload]
"1"="00000809"
"2"="e00e0804"
[HKEY_CURRENT_USER\Software\Microsoft\CTF\LangBar]
"ShowStatus"=dword:00000000"
The values of [HKEY_CURRENT_USER\Keyboard Layout\Toggle] are
1 Key Sequence enabled; use Left-ALT+SHIFT to switch between locales.
2 Key Sequence enabled; use CTRL+SHIFT to switch between locales.
3 Key Sequences disabled.
4 If the default locale is Thai, the accent grave key toggles input locales; otherwise key sequences are disabled.
The values of [HKEY_CURRENT_USER\Keyboard Layout\Preload] are listed here under the KeyName column.
The values of [HKEY_CURRENT_USER\Software\Microsoft\CTF\LangBar] are
0 Floating on desktop
4 Docked on the taskbar
3 when set to Hidden which is the default.
Relevant resources include
Similar Stack Overflow Question
CreateProcessWithLogonW function MSDN Reference
Managed CreateProcessWithLogonW
Related
I'm doing some poking around in Windows internals for my general edification, and I'm trying to understand the mechanism behind Image File Execution Options. Specifically, I've set a Debugger entry for calc.exe, with "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -NoExit -Command "& { start-process -filepath $args[0] -argumentlist $args[1..($args.Length - 1)] -nonewwindow -wait}" as the payload. This results in recursion, with many powershell instances being launched, which makes sense given that I'm intercepting their calls to calc.exe.
That begs the question, though: how do normal debuggers launch a program under test without causing this sort of recursive behavior?
It is anyway a good question about Windows internals, but the reason it has my interest right now is that it has become a practical question for me. At somewhere that I do paid work are three computers, each with a different Windows version and even different debuggers, for which using this IFEO trick results in the debugger debugging itself, apparently trapped in this very same circularity that troubles the OP.
How do debuggers usually avoid this circularity? Well, they themselves don't. Windows avoids it for them.
But let's look first at the circularity. Simple demonstrations are hardly ever helped by PowerShell concoctions and calc.exe is not what it used to be. Let's instead set the Debugger value for notepad.exe to c:\windows\system32\cmd.exe /k. Windows will interpret this as meaning that attempting to run notepad.exe should ordinarily run c:\windows\system32\cmd.exe /k notepad.exe instead. CMD will interpret this as meaning to run notepad.exe and hang about. But this execution too of notepad.exe will be turned into c:\windows\system32\cmd.exe /k notepad.exe, and so on. The Task Manager will soon show you many hundreds of cmd.exe instances. (The good news it that they're all on the one console and can be killed together.)
The OP's question is then why does CMD and its /k (or /c) switch for running a child go circular in a Debugger value but WinDbg, for instance, does not.
In one sense, the answer is down to one bit in an undocumented structure, the PS_CREATE_INFO, that's exchanged between user and kernel modes for the NtCreateUserProcess function. This structure has become fairly well known in some circles, not that they ever seem to say how. I think the structure dates from Windows Vista, but it's not known from Microsoft's public symbol files until Windows 8 and even then not from the kernel but from such things as the Internet Explorer component URLMON.DLL.
Anyway, in the modern form of the PS_CREATE_INFO structure, the 0x04 bit at offset 0x08 (32-bit) or 0x10 (64-bit) controls whether the kernel checks for the Debugger value. Symbol files tell us this bit is known to Microsoft as IFEOSkipDebugger. If this bit is clear and there's a Debugger value, then NtCreateUserProcess fails. Other feedback through the PS_CREATE_INFO structure tells KERNELBASE, for its handling of CreateProcessInternalW, to have its own look at the Debugger value and call NtCreateUserProcess again but for (presumably) some other executable and command line.
When instead the bit is set, the kernel doesn't care about the Debugger value and NtCreateUserProcess can succeed. How the bit ordinarily gets set is by KERNELBASE because the caller is asking not just to create a process but is specifically asking to be the debugger of the new process, i.e., has set either DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS in the process creation flags. This is what I mean by saying that debuggers don't do anything themselves to avoid the circularity. Windows does it for them just for their wanting to debug the executable.
One way to look at the Debugger value as an Image File Execution Option for an executable X is that the value's presence means X cannot execute except under a debugger and the value's content may tell how to do that. As hackers have long noticed, and the kernel's programmers will have noticed well before, the content need not specify a debugger and the value can be adapted so that attempts to run X instead run Y. Less noticed is that Y won't be able to run X unless Y debugs X (or disables the Debugger value). Also less noticed is that not all attempts to run X will instead run Y: a debugger's attempt to run X as a debuggee will not be diverted.
TLDR of Geoff's great answer - use DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS to bypass the Debugger / Image File Execution Options (IFEO) global flag and avoid the recursion.
In C#, using the excellent Vanara.PInvoke.Kernel32 NuGet:
var startupInfo = new STARTUPINFO();
var creationFlags = Kernel32.CREATE_PROCESS.DEBUG_ONLY_THIS_PROCESS;
CreateProcess(path, null, null, null, false, creationFlags, null, null, startupInfo, out var pi);
DebugActiveProcessStop(pi.dwProcessId);
Note that DebugActiveProcessStop was key for me (couldn't see a window when opened notepad.exe otherwise) - and makes sense anyway if your program is not really a debugger and you just want the bypass.
I have a very weird issue when my application is run under "Windows Vista Compatibility mode" (right-click the EXE, enable compatibility mode and select windows vista).
The issue is the return buffer length value from the "RegEnumValue" function returns a different value.
For example, with a registry value of "Zoom Player MAX" (15 characters):
With compatibility mode diabled, RegEnumValue's "lpcbData" field return a value of 16 (including the trailing null termination).
With compatibility mode enabled, RegEnumValue's "lpcbData" field return a value of 15 (doesn't include the trailing null termination).
Is there a work-around/patch for this that doesn't require changing my string conversion code?
It should not matter. When reading from the Registry using low-level classic functions, you must be able to handle strings with and without null-terminators:
Beware of non-null-terminated registry strings
The easy way to do this is to secretly allocate one extra character that you don't tell the API about when reading, and then append the '\0' character to the end of however many characters it returns.
Newer functions like RegGetValue() handle this for you.
the application tries to access the registry key values using advapi.dll regqueryvalueex method which works fine in xp (32-bit) but return 2 on windows 7(64-bit). however regopenkeyex opens the registry keys successfully in both the machines.
tried these below steps already but still couldn't read the registry key values
1. tried running vb 6 ide as admin
2. moved the registry keys to wow64node in regedit
For some reason, you are targeting the advapi.dll library, which was created for 16-bit Windows. I don't know how you are even getting it to work even in Windows XP, since this is a 16-bit only DLL, which will not load into a Win32 process, unless there is some kind of thunking layer.
As for the return value of "2" for RegOpenKeyEx(), the documentation tells you:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724911%28v=vs.85%29.aspx
Return value
If the function succeeds, the return value is ERROR_SUCCESS.
If the function fails, the return value is a system error code.
If the lpData buffer is too small to receive the data, the function
returns ERROR_MORE_DATA.
If the lpValueName registry value does not exist, the function returns
ERROR_FILE_NOT_FOUND.
Googling "System error code" gives you: http://msdn.microsoft.com/en-gb/library/windows/desktop/ms681382%28v=vs.85%29.aspx
The bit you need is:
ERROR_FILE_NOT_FOUND
2 (0x2)
The system cannot find the file specified.
It is very likely that if you were trying to use advapi.dll in your declare statement you would get this error when trying to run the API call. Basically, check your declare statements.
Of course, if you could supply your code, we would know for sure, rather than trying to do psychic debugging.
While processing keys I assumed that the virtual key VK_PRINT (0x2A) is the print key on my keyboard. But this assumption was false. I need to work with VK_SNAPSHOT (0x2C) which is VK_PRINT+2. But what is VK_PRINT for? Looking at MSDN I got the feeling we should all forget about this keycode...
What's up with VK_PRINT?
I believe the VK_PRINT keycode is from back in the days of the 83/84 key keyboard (think IBM XT and the IBM AT machines). The 'Print' key on this keyboards was shared with the numeric keypad's '*' key (instead of the PrtSc/SysRq key as is usual today).
See http://www.quadibloc.com/comp/scan.htm for some details on the history of IBM PC compatible keyboards.
I'm writing a very long registry Key name (it's a list of programs for a combined uninstall) and I think it's too big.
What's the max size the key can be (in characters) ?
(The smallest maximum among Win xp, vista, 7 since it'll need to work on all of them)
Key Name: 255 characters
Value name: 16,383 characters
Value: Available memory (latest format)
or 1 MB (standard format)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724872%28v=vs.85%29.aspx
According to this support article, it is 255 characters.
here's a key that's longer than 255:
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\DeviceClasses{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}##?#STORAGE#VOLUME#_??_USBSTOR#DISK&VEN_LEXAR&PROD_USB_FLASH_DRIVE&REV_1100#AANL1B891R5GCDV6&0#{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}#{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}#
I found this when I was writing a tool to search all keys in the registry. I created a buffer that was 256 which caused a stack corruption exception.
When I tried to view this key using regedit I noticed it shows an arrow indicating there are subkeys but won't respond when clicked on. I only guess at the final '#' key because other keys in that area end with it.
When I doubled the buffer everything went smoothly.