..and then he deleted something

..and his computer froze and never booted back up again. I love those stories about the Registry; the critical box gets hosed because Billy decides to start editing
the Registry on the fly, network scripts that delete some vital key and take down an entire department ..ignorance is bliss I suppose - but not always..
and certainly not where it concerns the systems Registry.

The Registry though, is just a kind of hierarchal database, storing varied information on the Operating System and installed components.
In the beginning, it was intended only to store configuration information for COM components,
but later became a vehicle for peripheral application storage in an attempt to reduce reliance on .ini files, and now.. it seems we are moving in yet another direction, back towards
modular design principles, with application data stored within the application assemblies. That not withstanding, the Registry will continue to be a core element in the Windows
Operating System for some time to come.

So what does a Registry cleaner do, and do I really need one? Primarily, what it does is path testing, whether it be paths in the file system, or links between elements within
the Registry itself. I realized this a few years ago, when it so happened that I needed a Registry cleaner.. A friend had a particularly nasty virus on her computer,
one that disabled the anti-virus, and set itself up with system level access. I managed to remove it, but after deleting its components, the networking no longer worked.
It had inserted itself into the networking stack, and without knowing what or where these entries were, I needed a Registry cleaner to fix it. The one I used cleared
it right up (though without purchasing it, I had to manually delete the entries.. which in turn led me to writing the first version of this application). It was then that
I began examining the match entries to try and figure out how these applications worked, and started understanding the complex relationship between various Registry entries.

I'm not going to bore you with some long essay on how the Registry works, there are plenty of tutorials on the internet, Wikipedia
has a good one. What I will do, is give you a mile high view of how this application works, if you want to understand it better, or expand on this application; some serious debugging
and reading of the class notes will be required..

Accessing the Registry using API

At the heart of this application is the Registry class cLightning, something I wrote in VB6 many years ago, and translated to C# as one of my first
projects in this language. Most of the data types and Registry API in advapi.dll
are accessible with this class. There are also a number of useful methods like RunAs, ShellOpen, Rot13, and access escalation routines.

Enumerating through hundreds of thousands of Registry keys requires a 'need for speed' approach, ergo the inbuilt Registry methods are simply out
of the question (at least a 2:1 speed advantage using PInvoke). There are individual methods for each data type:

There are also routines that delete keys and values, test key existence, test for empty values, etc.

Beating a path..

By far the most challenging portion of this project was file and directory path testing. This is because there are literally half a dozen different ways to list the same path.
Unicode, psuedo paths, truncated, prefixed, postfixed.. an absolute nightmare. As you can imagine, it took some tweaking to eliminate false positives, first by testing the path with
a Regular Expression, then if the file could not be found, going through a number of path conversions and extraction methods:

Yes, a little cryptic I know.. but basically all routines (except MRU, which is kind of a heuristic scan for MRU lists) are doing path testing in various areas of the Registry.
The control scan is the most complicated, it tests for paths to shell/edit/default/icon paths and IDs under a CLSID subkey, it also tests for valid type, proxy, and interface
registration UIDs associated with that class.

As an example, one of the control scan segments tests for registered type libraries under the HKEY_CLASSES_ROOT\Clsid{xxxx}\Typelib subkey:

The scanning engine compares this to the list of registered type libraries under the HKEY_CLASSES_ROOT\Typelib branch. If the type library UID is absent,
the scan reports this as an invalid entry. The same method is used for AppId, ProxyStub, etc.

The best way to get a handle on what all this does, is just spending time both stepping through the methods and examining the paths in Regedit to try and make the logical connections.

UAC and Virtualization

In yet another patch meant to address 30 years of security complacency, we now have file and Registry Virtualization. Essentially, it just redirects write requests to more secure
areas of the Registry or file system. This shouldn't affect the application scan though, because we are running under administrator credentials.
This is just one of those apps that has to run as administrator, because many areas of the Registry are now write protected under Vista/W7. This is accomplished
by changing the app.manifestrequestedExecutionLevel to:

The application will also need to be published with an external compiler, as the VS Publisher will throw an error with this setting (apparently by design).

Breaks like the wind..

There used to be a website that had a repository of trojans, virii, worms, etc., available for download (long gone, no doubt sued into oblivion),
some exploits even had original source code. While writing a spyware scanner, I took the time to go through some of the more nefarious examples, learning
what I could about how they worked. What I took away from that experience was that some of the original authors were real hard-core programmers, and that
it took a great deal of knowledge of the low level Windows internals to pull off some of these exploits. So, I noticed while testing *this* application that
some of the entries were not being deleted. Checking those entries permissions via Regedit, I saw something new, the 'Trusted Installer' [service] has full control
of the key, with all other users, even System, having only read access. My first thought was.. did someone in Redmond finally figure out how to keep us from modifying
selected NTFS objects, even the Administrator? So, I clicked on the owner tab, changed the ownership to the Administrators group, and gave myself back full control
(and if you can do it in Regedit, you can do it in code). So, it makes me wonder.. who do they create these security controls for, I mean, if I (a humble amateur)
can subvert this easily, what is one of those hard-core cracker dudes going to think?

Anyways.. the first thing you need to do, is change the object's ownership:

What we are doing here is modifying the access token of the current process to include the rights required to take ownership of an object, then changing
the object's owner. This happens if a value or key fails to be deleted.

Now it's not just enough to own the object, you also require the rights to modify or delete the object. This is accomplished by rebuilding the object's DACL,
or access control lists, a series of bitmasks compared to the users access token that determine the rights available to the process. The object's DACL is composed
of ACE entries, or Access Control Entries, individual bitmasks for read/write/execute etc. So what we need to do is rebuild the DACL and apply the new list to the object.

First the setup, get the account information including the user's SID, and the handle to the subkey to be altered:

Yes.. long spaghetti code is the order of the day.. but that's just how it's done, no simplified .NET methods for this kind of access,
at least none that I am aware of.. With just a few changes, most NTFS objects can have their security descriptors modified, including files,
named pipes, etc. If you want a hint at how this can be done, it's all in a VB6 project I wrote some years back, called NTMasterClass.

System restore

Creating a restore point is probably a good idea for any application that makes serious modifications to the Registry, and included in the scan library
is a class that can do just that. It's also a good idea to launch this on a background worker thread, and provide a visual indicator for the user:

Final thoughts..

Though I have tested this on several different machines (Vista/W7) with no problems or surprises, remember, it is beta.. though I think even in a worst case scenario,
you might have to run system restore.. just don't let Billy play with your Regedit ;0)

Updates

Dec 20, 2011 -Added a visual to system restore process, which is now launching as a background thread.

Dec 31, 2011 -Added updated code and expanded article.

Jan 1, 2012 - Did a heap of bug fixing, so it's pretty much done now (perhaps a couple of cosmetic todo's), If you find a bug, shout out (and if you're nice, I might even fix it.. ;o).

Share

About the Author

Network and programming specialist. Started in C, and have learned about 14 languages since then. Cisco programmer, and lately writing a lot of C# and WPF code, (learning Java too). If I can dream it up, I can probably put it to code. My software company, (VTDev), is on the verge of releasing a couple of very cool things.. keep you posted.