NULLs in the Windows Registry

December 1, 2017
3 min. read

I ran into an interesting issue with my Windows development machine when trying to test a Flask web app. This was due to werkzeug running the simple web server for flask that is created when you us app.run().

The error had me confused at first, as it has nothing to do with what I was changing at the time:

TypeError: OpenKey() argument 2 must be str without null characters or None, not str

I tracked back through the stack to see that werkzeug is looking at the Windows Registry. So I open regedit to see what we have. From what I can tell everything is fine.

Finding the bad keys

I found some uses of winreg and cobbled together a script to print all keys with NULL in string or with type not string. This is what the error seems to be suggesting.

import winreg as _winreg

# This script will print all classes that have NULL in string.

# Use SysInternals RegDelNull to delete these.


hkcr = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, "")

i = 0
try:
    while True:
        ctype = _winreg.EnumKey(hkcr, i)
        if '\x00' in ctype:
            print(ctype)
        if not isinstance(ctype, str):
            print("{} -> {}".format(type(ctype), ctype))
        i += 1
except WindowsError:
    # Will always go off the end of EnumKey to escape the while

    pass

This is available to download from my Github.

If you run this and get any output, you have an issue. I did not see any instances where my ctype was not a str, but I had a mess of NULL characters in registry keys.

You will see NULL in my output as \x00. This was at the end of typical {GUID}\x00 keys for me. So I figured out what caused the error, but needed to fix it.

Fixing the bad keys

Knowing the key name that was problematic, I went back into RegEdit and did a search for a portion of the GUID. As soon as RedEdit highlighted the key, I received an error that the key could not be read.

I tried to delete it. No joy there either. These NULL characters cause havok with RegEdit too. It was useless as a tool to fix my problems.

After some more searching, I came across the SysInternals RegDelNull, a utility created for fixing this problem.

Running this in an Administrator Shell as RegDelNull HKLM -s (where HKLM is the appropriate problem area), prompts you to delete NULL filled keys.

I had to clean up two branches of the registry. I’m not sure how they were created, but they are gone now.

This solved my issue and I could get back to bugs I created in my Flask code.

Rant time

Microsoft has created some good software. However, the Windows Registry is not one of them.

The Windows Registry is a single-file implementation of a file system. Not a good implementation. It is fragile, endian specific, slow and undocumented. It is tied to the data structures of the C version with which it was originally built.

OK, really a memory dump of the 32-bit C structures from the heap. No, I’m not joking. Make sure you follow the conventions of memory packing from your early 1990s C compiler!

This just goes to show that data structures are usually more important than code. The structure they were looking for in this case is a database not a file system.

This all might have been fine if Windows kept it to themselves and stored their settings in it. But instead of allowing .ini files (which worked fine), every program gets to fill your registry full of junk.

The use of AppData is trying to get rid of the Registry, if everyone would stop using it. But even Windows versions are still using it. It is the terrible idea that will not die.

Sorry, thus endith my rant.

comments powered by Disqus