What is so special about the instance handle 0x10000000?

A customer wanted to know what it means when the Load­Library function returns the special value 0x10000000.

Um, it means that the library was loaded at 0x10000000?

Okay, here's some more information: "We're trying to debug an application which loads DLLs and attempts to hook their registry accesses when they call Dll­Register­Server. It looks like when the special handle is returned from Load­Library, the registry writes go through and bypass the hook. On the other hand, when a normal value is returned by Load­Library, the hook works."

There is nothing special about the value 0x10000000. It's an address like any other address.

At this point, your psychic powers might start tingling. Everybody who does Win32 programming should recognize that 0x10000000 is the default DLL base address assigned by the linker. If you don't specify a custom base address, the linker will base you at 0x10000000.

Now things are starting to make sense. The DLL being monitored was probably built with the default base address. The value 0x10000000 is special not because of its numeric value, but because it matches the DLL's preferred address, which means that no rebasing has occurred. And this in turn suggests that there's a bug in the registry hooks if the DLL is loaded at its preferred address.

The code in question was copied from a book, so now they get to debug code copied from a book.

Wait, we're not finished yet.

You may have answered the customer's question, but you haven't solved their problem.

Hooking and patching DLLs like this is not supported. But what is supported is the Reg­Override­Predef­Key function. In fact, the Reg­Override­Predef­Key was designed specifically to solve this very problem:

The Reg­Override­Predef­Key function is intended for software installation programs. It allows them to remap a predefined key, load a DLL component that will be installed on the system, call an entry point in the DLL, and examine the changes to the registry that the component attempted to make.

The documentation continues, explaining how such an installation program might use the Reg­Override­Predef­Key function to accomplish the desired task.

Comments (12)
  1. google says:

    According to bing your blog entry is the only reference in the web to Reg­Override­Predef­Key.

    [Someday, the Bing folks will understand the soft hyphen. Unfortunately, that day is not today. -Raymond]
  2. cdman says:

    A better search engine gives a lot of results, including this one: msdn.microsoft.com/…/ms724901%28v=vs.85%29.aspx

  3. Why do you use a soft hyphen?

    [The same reason everybody else uses a soft hyphen. It's not like I'm using it in any special way. -Raymond]
  4. I guess I just don't understand how potentially adding line breaks to a function name makes it more readable. I use nobr for function/method names.

    [Paragraphs look better when each line is roughly the same length. And you probably don't care to look good when visited from a phone. -Raymond]
  5. @Mike Dimmick

    How many results do you get for that search?  I get one: this blog entry.

  6. Marc Durdin says:

    The danger with RegOverridePredefKey is, as Mike notes, that it changes the registry environment that the target is expecting.  In my own experience, we ran into this problem using the WiX tool heat to extract SelfReg data: marc.durdin.net/…/case-of-hidden-exception.html

    @Maurits: I am guessing Mike retyped RegOverridePredefKey instead of copying and pasting…

  7. @Marc Durdin

    But Mike's link has the %c2%ad values.

  8. Mike: That kind of issue can be infuriating; I've had quite a few "fun" debugging sessions trying to get various applications to run without Admin permissions on our shared student lab machines – then the added complication of mandatory user profiles. One tried to ensure only one copy was running at a time by creating a lockfile in the root of C … another felt the need to install itself each time it was run, by copying a few components into c:Windows. The automatic redirection stuff proved very useful when we finally managed to move to Windows 7.

    I've even had broken installers mangle the file association for .exe files, so running any application from the shell failed. That was … interesting.

    Good to know about Reg­Override­Predef­Key though; as an alternative route, aren't the filtering techniques the Sysinternals regmon (now part of procmon) tool used more robust? (I was quite fond of one free snapshot tool, but it used a 'brute force' approach of dumping the whole registry before and after, then comparing.)

  9. Mike Dimmick says:

    Works on my computer:


    Trying to reverse engineer what a DLL writes to the registry is a very bad practice. I've seen components fail to write *everything* they need when presented with an empty key. I've also seen other components writing absolutely everything they could possibly need including things they don't own and should never touch (e.g. standard Automation registry keys).

  10. This comment needs to be put in a more accurate context – "Everybody who does Win32 programming should recognize that 0x10000000 is the default DLL base address assigned by the linker". Are you referring to the Visual Studio linker? Any particular version? It's obviously not true, let alone evident to everybody who does Win32 programming, in general. For example, I am using Delphi 7 and it appears to be 0x400000 (or as they like to call it, $00400000).

  11. GregM says:

    The base address 0x00400000 is the default for EXEs.  The 0x10000000 is the default for DLLs.

  12. 640k says:

    [Paragraphs look better when each line is roughly the same length. And you probably don't care to look good when visited from a phone. -Raymond]

    This blog doesn't look good on iPhone (mobile safari). It's a "feature" I suppose.

Comments are closed.