Detecting registry virtualization - windows-7

I have a set of C# (v2) apps and I am struggling with registry virtualization in Win7 (and to a lesser extent Vista).
I have a shared registry configuration area that my applications need to access in HKLM\Software\Company... Prior to Vista, everything was just written to and read from that location as needed.
The code appropriately detected failures to write to that registry key and would fall back appropriately (writing to HKCU instead and notifying the user that the settings they had applied would only affect the current user).
In Vista, registry virtualization broke all of this because the access check we were using for the HKLM write would "succeed" silently and virtualize to HKCR\VirtualStore\Machine... instead. In this case, the user would think that they had saved machine-wide configuration, but had instead only written to the virtual store.
Sadly, even attempting to enumerate the permissions on the HKLM reg key explicitly returns results indicating that the user has access whether they do or not.
When we added Vista support, the workaround we used was to perform a probe write to HKLM... and then check in HKCR\VirtualStore\Machine... for the same value and note that virtualization had occurred if the value was found.
Win7 seems to have broken this (again) because queries against the explicit virtual location (HKCR) now show merged results from the HKLM location even if the write was not virtualized.
Does anyone have any suggestions for working around this?
Constraints:
- I need a solution that works without requiring elevation (when I don't have administrator level permissions I will fallback to a per-user configuration in HKCU but I need to be able to detect this case reliably).
It needs to work with a v2 C# app (One option I have seen for C++ code is to embed a manifest which disables virtualization for the .exe but I haven't been able to do that in C# V2 see disable folder virtualization in windows).
It needs to work without an "installer" (this precludes the ability to disable virtualization on the registry key that we need ala the REG FLAGS... command).

This is an excellently put question, +1 (Why is it community wiki, it deserves points!)
In general, there are a set of rules (which [as you've run into] will vary over time) which control whether UAC [and thus implicitly Registry] virtualization are in play.
Some salient parts of the Registry Virtualization rulesets documentation in MSDN are:
[as jeffamaphone says] if the manifest has a requestedPrivileges/requestedExecutionLevel set, it's turned off. You dont seem to have ruled out adding a manifest, so can you please indicate why this won't work for you? (You say "I haven't been able to do that in C# V2" - there is an Add Item option to add an application manifest file, and that's available in VS2005)
if the exe is running 64 bit, its off by default
if it's not an interactive process (such as a service, or hosted in IIS etc.), it's off
If you're not in a position to influence any of the above, which is the ideal, and you thus want to detect whether UAC virtualisation applies in the current context, use this answer to a what might at first not appeat to be a related question. (Obviously you'd still need to decide whether it applies to the specific key you're operating on, which is a moving target which you obviously wouldnt want to implement code that needs to track changes if it can at all be avoided - but in most cases it should be relatively clear.)

You can enable / disable virtualization on a per key basis, according to this, but it tells you to use a command line tool. But there must be a way to do it programmatically.
It might be easiest just to turn off virtualization in your app completely by setting requestedExecutionLevel in your manifest. You can try highestAvailable, but that might mean your app always runs as Administrator. It seems to imply just setting it to asInvoker will turn off virtualization. See also.

Note that HKCR is a virtualized store itself, a combination of HKLM\Software\Classes and HKCU\Software\Classes.
The best approach would be to not even let the registry virtualization take place. Firstly check to see the user is is elevated at runtime and then you can notify the user that changes will only be applied to the current user before they even start making changes.
By detecting if you are an elevated administrator in the first place you can simply avoid writing to HKLM when it's going to be virtualized.
Example:
private bool IsAdministrator
{
get
{
WindowsIdentity wi = WindowsIdentity.GetCurrent();
WindowsPrincipal wp = new WindowsPrincipal(wi);
return wp.IsInRole(WindowsBuiltInRole.Administrator);
}
}
Note: I don't code in C#, example is lifted from question How can I detect if my process is running UAC-elevated or not?

I had a similar problem and the introduction of a manifest solved it.
I was relying on the registry security to prevent the (Win32) application from creating keys in the HKLM/Software/Wow6432Node when running as standard user, and was quite surprised to see that it was succeceding regardless, but no key was present and it was created instead under this new VirtualStore area.
The registry virtualization is switched off when the PE manifest is found to contain information related to the security. To not require elevation of privileges my manifest contains the following node:
<trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker">
</requestedExecutionLevel>
</requestedPrivileges>
</security>
</trustInfo>
For the executable to be compatible with Vista and XP, apparently each node in the TrustInfo section must contain the namespace:
<ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
<ms_asmv2:security>
<ms_asmv2:requestedPrivileges>
<ms_asmv2:requestedExecutionLevel level="asInvoker">
</ms_asmv2:requestedExecutionLevel>
</ms_asmv2:requestedPrivileges>
</ms_asmv2:security>
</ms_asmv2:trustInfo>
Once the manifest was correctly embedded in my .exe (it took me a couple of attempts by modifying the appropriate properties of the project), the program was at last failing as I was expecting.
For managed code, the manifest can be included as a post-build step by running the mt.exe tool. For instance, as reported in the MSDN article
mt.exe –manifest YourFile.manifest –outputresource:YourApp.exe;#1
I prefer using the manifest approach rather than modifying the flags of the registry nodes using reg.exe as explained in this article as this makes the behaviour consistent on all machines.
Hope that helps (even if, after having read the date of the original posting, I'm pretty sure the problem has been solved long ago!!)
Alberto

Related

Create file or registry key without calling NTDLL.DLL

I know that ntdll is always present in the running process but is there a way (not necessarily supported/stable/guaranteed to work) to create a file/key without ever invoking ntdll functions?
NTDLL is at the bottom of the user-mode hierarchy, some of its functions switch to kernel mode to perform their tasks. If you want to duplicate its code then I suppose there is nothing stopping you from decompiling NtCreateFile to figure out how it works. Keep in mind that on 32-bit Windows there are 3 different instructions used to enter kernel mode (depending on the CPU type), the exact way and where the transition code lives changes between versions and the system call ids change between versions (and even service packs). You can find a list of system call ids here.
I assume you are doing this to avoid people hooking your calls? Detecting your calls? Either way, I can't recommend that you try to do this. Having to test on a huge set of different Windows versions is unmanageable and your software might break on a simple Windows update at any point.
You could create a custom kernel driver that does the work for you but then you are on the hook for getting all the security correct. At least you would have documented functions to call in the kernel.
Technically, registry is stored in %WINDIR%\System32\config / %WINDIR%\SysWOW64\config, excepted your own user's registry which is stored in your own profile, in %USERPROFILE%\NTUSER.DAT.
And now, the problems...
You don't normally have even a read access to this folder, and this is true even from an elevated process. You'll need to change (and mess up a lot...) the permissions to simply read it.
Even for your own registry, you can't open the binary file - "Sharing violation"... So, for system/local machine registries... You can't in fact open ANY registry file for the current machine/session. You would need to shut down your Windows and mount its system drive in another machine/OS to be able to open - and maybe edit - registry files.
Real registry isn't a simple file like the .reg files. It's a database (you can look here for some elements on its structure). Even when having a full access to the binary files, it won't be fun to add something inside "from scratch", without any sotware support.
So, it's technically possible - after all, Windows does it, right? But I doubt that it can be done in a reasonable amount of time, and I simply can't see any benefit from doing that since, as you said, ntdll is ALWAYS present, loaded and available to be used.
If the purpose is to hack the current machine and/or bypass some lack of privileges, it's a hopeless approach, since you'll need even more privileges to do it - like being able to open your case and extract the system drive or being able to boot on another operating system on the same machine... If it's possible, then there is already tools to access the offline Windows, found on a well-known "Boot CD", so still no need to write in registry without any Windows support.

How to enable Windows Error Reporting LocalDumps for one process only, not system-wide

The user mode dump collection feature in Windows is well documented. As long as the LocalDumps key under HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting is created, every application crash on the system produces a core dump using the default setting. A subkey under it, named after the executable file for the process I am interested in, is overriding the global (default) setting, and I am getting the crash dumps just nominally, full memory burp in the location I specify.
However, there is apparently no setting in the documentation under the LocalDumps that would tell the system not to create dumps, such that I would override one for my service's subkey. In our milieu, there are multiple service processes running under multiple identities, so there are going to be many core dumps scattered around all there identities' %LOCALAPPDATA%\CrashDumps directories, needlessly. These are unattended servers, and more trash means more scripted cleanup.
Is there a documented way to disable core dumps by default for all programs, and override the prohibition for just one?
It is documented that dumps are not created if the location is not writable by the crashing process' identity, but I do not want them for LocalSystem services too, and this guy can write anywhere. Also, it seems that the dumps are not created if the DumpFolder points to an invalid filepath. To make it even maybe a little less hacky, I set it to the NUL device in the device namespace (: stands for "value under key" below):
LocalDumps:DumpFolder=\\.\NUL
LocalDumps:DumpCount=1
LocalDumps\myservice.exe:DumpFolder=C:\Program Files\myservice\data\crash_dumps
LocalDumps\myservice.exe:DumpType=2
LocalDumps\myservice.exe:DumpCount=5
This ostensibly works in Server 2012, 2012R2 and 2016. But I must keep fingers crossed that a next update would not change this (undocumented) behavior.

Failure to launch Windows program via URI after adding to HKCU/Software/Classes

I'm trying to set up a test application on Windows to launch via a "myapp://website.com"-style URI. Mostly, I'm basing myself off of tutorials like this:
http://msdn.microsoft.com/en-us/library/ie/aa767914(v=vs.85).aspx
While I got the initial setup working inside HKEY_CLASSES_ROOT, a new constraint is for the installation to happen without requiring administrator access. So, I deleted all changes in CLASSES_ROOT, and decided to retry the registry additions, instead using the HKEY_CURRENT_USER branch, at HKEY_CURRENT_USER/Software/Classes/myapp.
This appears to be detected by the browsers, and they display their confirmation dialog. However, they never actually run the app. Internet Explorer gives the most helpful error message, with a dialog saying "Unable to open this helper application for {uri}. The protocol specified in this address is not valid. Make sure the address is correct, and try again.
Is there some part of the registry I'm missing for a non-administrator setup? This is an export of my changes as a .reg. (Dashes censoring my username). EditFlags was added as a guess, but didn't work without it either.
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\myapp]
"URL Protocol"=""
#="URL:David Protocol"
"EditFlags"=dword:02000000
[HKEY_CURRENT_USER\Software\Classes\myapp\DefaultIcon]
#="C:\\Users\\------\\AppData\\Roaming\\-----s Stuffs\\URISchemeTest.exe,1"
[HKEY_CURRENT_USER\Software\Classes\myapp\shell]
[HKEY_CURRENT_USER\Software\Classes\myapp\shell\open]
[HKEY_CURRENT_USER\Software\Classes\myapp\shell\open\command]
#="\"C:\\Users\\-------\\AppData\\Roaming\\------s Stuffs\\URISchemeText.exe\" \"%1\""
Now that I have this working, I can't be perfectly certain of what it was that was causing problems, but I can at least give an account of what I tried to do differently in the hopes this helps future researchers.
%-sign directory accessors might not be supported by the path declaration. If they are, they may need to be encoded a certain way. Lower down In the article linked in the question, it mentions how Internet Explorer may decode certain URL parameters, but other browsers may not. Either way, if you've been specifying the command line as "%APPDATA%/MyProgram.exe", it may be more reliable starting from "C:/" until you can work through that issue.
EDIT: One other thing I just noticed, if the Paste from my question is correct: My working version of the registry changes set the default key of the root to "URI :David Protocol". Note "URI", not "URL". It's possible that mis-naming that (easy since another value is declared as "URL Protocol") could break the resulting effects.
While you might not have to specify a DefaultIcon, you may want to be careful that you're not referring to an invalid one. For safety, I set up mine to point specifically to a .ico file, rather than ".exe,1"
As some other commenters mentioned, I don't think EditFlags is really necessary, and might not be related.
A cautionary rebuttal to the highly-voted answer near this one, though: This. Works. No UAC access necessary. From the outset of my research, I personally would have believed an explanation that it's too risky to allow without a UAC admin prompt, etc. However, I took the time to test it, and could write a simple program with a button that sets itself up under HKCU/Software/Classes, and is accessible to the browser. I then tested it from the computer of a developer who had never taken part in any of my research (clean environment), and without any admin prompts, it worked fine. (Obviously, this program will only be accessible to the current user)
(For easy reading, a reminder: HKCU = HKEY_CURRENT_USER. HKCR = HKEY_CLASSES_ROOT. HKLM = HKEY_LOCAL_MACHINE)
Anything that could write to the user's HKCU registry already has non-admin binary access. Furthermore, all browsers will show a warning message about launching the program before opening it (perfectly understandable, given that it's local code). Several of them even give the full folder path of the executable you'll be launching.
I know the tutorial said to put the key in HKCR; and that this is known to come from HKLM/Software. However, it's worth reading up the whole story here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724475(v=vs.85).aspx
This key is partially derived from the HKCU hive - and in fact, the user's settings will override the local machine settings. There is nothing specifically indicating that HKLM will override HKCU when displaying this type of key inside of HKCR.
You cannot ignore what the MSDN article tells you, registering the protocol handler in a HKCR key is a hard requirement.
There's a good reason for that, also fairly explicitly stated in the article, protocol handlers are dangerous. They allow an arbitrary web page to start a program on your machine. They even work inside a Store app, another example of a heavily secured runtime environment that runs code inside a sandbox that stops dangerous operations.
Documenting HKCR doesn't help much unravel this, it was meant for appcompat with 16-bit code and today is an alias. Shows a merged view of both HKCU and HKLM keys. The HKLM keys are different from HKCU keys, writing key values require elevation. Only a program that can acquire a elevated security token can create new values or alter them, normally obtained by going through the UAC prompt. The problem with HKCU keys is that any program can write keys there without elevation. Which would open up a security hole if protocol handlers could be registered in a HKCU key. So this cannot work, urlmon simply doesn't look at the HKCU keys to find the protocol handler.

Is Windows registry redirection a "bad thing"?

I have my own installer program which I use to install several applications I have written.
I have been updating this program to avoid the application's data file updates going to the user's VirtualStore, as I read this was a "bad thing". I am doing this by storing the program and common data files separately in their correct locations, instead of sticking everything in Program Files like we used to do in the days of XP.
I am also now using SHGetFolderPath (yes, it's deprecated, but I still need to support my XP users), to get known folders instead of trawling the registry, which is another "bad thing" (I read).
The next thing I was trying to do was rewrite the installer code to avoid registry redirection to Wow6432Node when writing stuff to HKLM, as I thought this was another "bad thing".
However, although I could put the application specific stuff that goes there (like the install folder, if the user decides to install in other than the default), the killer is the need to put the uninstall info in HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall. For 32-bit stuff running on a 64-bit system, this is redirected to Wow6432Node. I don't see any way round this - is it in fact possible?
UAC registry redirection could reasonably be described as a "bad thing" because it is designed specifically to provide compatibility with improperly written software, i.e., software that assumes it is going to be run with administrator privilege.
WOW64 registry redirection is a different beast; it's designed to provide compatibility with properly written 32-bit software. If your software is 32-bit, and has no specific need to be 64-bit aware, there's nothing wrong with letting it run in the emulation environment as-is, including allowing registry settings to be redirected to Wow6432Node.
You can bypass WOW64 registry redirection if necessary, but you shouldn't do this arbitrarily, only if there is a specific reason. If WOW64 redirection worries you, the only good alternative is to provide a 64-bit version of your program.
This is a very "BAD THING" !
Microsoft solves a security problem by hiding thing at another place !
I've created a programm to ask the user for some additional parameters (language, directory for lessons) during installation of the app. I tested the programm profoundly, and the registry entries were made perfectly. However during setup the entries were hidden at some strange place!
If Microsoft wants to redirect these enties it should at least be some option to be set.
Never hide things, and think they will not notice, because it's transparant.
Doing this properly would involve an option to be set, so users are aware of the redirection !

Is There Any Reason Not To Use The Windows Registry For Program Settings?

To me its a no-brainer. The settings for my program go into the Windows Registry. After all, that's what it's for, isn't it?
But some programmers are still hesitant in using the Registry. They state that as it grows it slows down your computer. Or they state that it gets corrupted and causes your computer to malfunction.
So they write their own configuration files, or may use the INI files that Microsoft has depreciated since a few OS's ago.
From what I hear, the problems with the registry that occurred in early Windows OS's were mostly fixed as of Windows XP. It may be the plethora of companies that make Registry Cleaners that are keeping up the rumors that "registry bloat" and "orphaned entries" are still bad.
So I ask, is there any reason today not to use the Windows Registry to store my program configuration settings?
If the user does not allow registry access, you're screwed.
If the user reinstalls Windows and he wants to migrate his settings, it's much more complicated than with a simple file
Working with a config file means your app is portable
Much simpler for the user to change a setting manually
When you'll want to port your app to other OS, what are you gonna do with your registry settings ?
Windows Registry is bloated. Do you really want to contribute to this chaos?
For me, quickly installing, migrating and moving applications is a key point to productivity. I can't if I need to care of hundreds of possible registry keys. If there's a simple .ini or .cfg or .xml file somewhere in my user folder (or even the application directory if it is a portable app), migration is easy.
Often-heard argument pro registry: easy to write and read (assuming you're using plain WinAPI). Really? I consider the RegXXXfamily of functions pretty verbose ... too many function calls and typing work for storing just a few bits of information. So you always end up wrapping the registry away .. and now compare this effort with a simple text configuration file, maybe just key=value-like.
It depends, when you have small entries that need to read by multiple programs registry is ok, as database have locking issues, and config files are application based.
The problem happens when the user does not allow registry access, that are lots of software in the market that will show a pop up when anyone tries to modify registry and the user can cancel or allow the users. These programs are too common with the anti virus programs.
Putting your settings into the Registry means that if your user wants to move your program and its settings to another computer, he can't. Backup, ditto. Those settings are in a mysterious invisible place. I find this to be a hostile approach to one's users.
I've written numerous small-to-medium programs, and always used a .ini file. A tech-savy user can edit this file using an editor, he can check the settings in it, he can email it to a tech supporter, he can do a large variety of things that are significantly harder to do with registry entries.
And my programs don't contribute to slowing the computer down.
Personally speaking, I just don't like binary configuration of any type. I much prefer text file format which can be easily copied, edited, diffed & merged, and put under change control complete with history.
The last of these is the biggest reason not to use the registry - I can stick configuration files into SVN (or similar) with the full support given to text files, instead of having to treat it as a blob.
I don't really have much of an opinion for or against using the registry, but I'd like to note something... Many answers here indicate that registry access may be restricted for a certain user. I'd say the exact same thing goes for config files.
With registry you need to write to the "current user" to be fairly certain about having access (and should do so anyway, in many cases). Config files should be put in a user based area as well (e.g. AppData/Local) if you want "guaranteed" access without questions asked. As far as I know putting config files in "global" areas are as likely to yield access problems as the registry is.

Resources