Entry Point Not Found, and other DLL Loading Problems

Occasionally I come across DLL load problems:

The verbosity of the error messages varies greatly. In their raw form these include at least the DLL name, but as various frameworks come into play (for the error message above, it’s .net) – native exceptions are caught and re-thrown, and more often than not helpful information is lost on the way.

Turns out there’s a built in way to get verbose windows-loader output: the Show Loader Snaps flag. The easiest way to mark it is with the GFlags utility, bundled with debugging tools for windows:

Under the hood, it merely adds a FLG_SHOW_LDR_SNAPS flag (0x00000002), to a DWORD value in the relevant IFEO registry key. This in turn causes Windows Loader to set the _ShowSnaps variable in the ntdll copy specific to the named process.

And now, behold the new and shiny loader trace (dumped to the debugger output window):

…    

2724:245c @ 11813487 – LdrpFindOrMapDll – RETURN: Status: 0x00000000

2724:245c @ 11813487 – LdrpLoadImportModule – RETURN: Status: 0x00000000

2724:245c @ 11813487 – LdrpLoadImportModule – RETURN: Status: 0x00000000

2724:245c @ 11813487 – LdrpLoadImportModule – RETURN: Status: 0x00000000

2724:245c @ 11813487 – LdrpSnapThunk – WARNING: Hint index 0x70a for procedure “?Revert@CStreamMemory@@UAGJXZ” in DLL “YaddaYadda.dll” is invalid

2724:245c @ 11813487 – LdrpSnapThunk – ERROR: Procedure “?Revert@CStreamMemory@@UAGJXZ” could not be located in DLL “YaddaYadda.dll”

First-chance exception at 0x77321d32 (ntdll.dll) in Strategist.exe: 0xC0000139: Entry Point Not Found.

Bam! There’s the offending DLL and the offending imported function, right there in the debugger.

Like many other useful features – it is documented, but very low on discoverability. Which is a fancy way of saying you can find it only if you already know exactly what you are looking for. I personally got around to it after digging around in ntdll assembly (just like Matt Pietrek, 14 years ago), trying to get to a string containing the name of an offending DLL.

The windows-copycat-opensource ReactOS source gives a nice view of the internal usage of this flag – called ShowSnaps in their source. The ‘snapping’ verb in this context refers to one of the actions performed by the loader: after rebasing the loaded DLL in the loading process memory space, the DLL’s exported function addresses are updated and must be copied to the importing process (or other dll) Import Address Table. This – in this context – is called snapping, and that’s where the extra tracing is hooked.

This entry was posted in Debugging, Win32. Bookmark the permalink.

19 Responses to Entry Point Not Found, and other DLL Loading Problems

  1. Anonymous says:

    hi Ofek, greate discovery.
    however, in case this happens in a deploy machine, with no debugger, how can I log the trace to a file instead of the not installed Visual-Studio’s output window.
    M>

  2. smirkingman says:

    Saved my bacon, many thanks!

  3. Pingback: On API-MS-WIN-XXXXX.DLL, And Other Dependency Walker Glitches | 神刀安全网

  4. It’s probably only me that is an idiot, but in the Image field you should only put the EXE name, not full path. Otherwise it won’t work.
    I’m not sure how the launch button is suppose to work.

  5. The debug log is going to a function named vDbgPrintExWithPrefix in ntdll.dll.
    So detouring this function can give you the messages.

    ULONG NTAPI vDbgPrintExWithPrefix(PCH Prefix, ULONG ComponentId, ULONG Level, PCH Format, va_list arglist)

    • Suyuan Chang says:

      I detoured all [v]DbgPrint* API in ntdll.dll, but still not work (on Windows 10). Can you share more information about how you get the messages?

      • Suyuan Chang says:

        I successfully capture those debug log using WaitForDebugEvent(). Basically, I create another process to act like a debugger attaching original process and get debug output for original process. Then I can use my own way to pass those message back to original process
        Basically, this should work for all user-mode DbgPrint() messages.

    • Ofek Shilon says:

      ShowSnaps does not call OutputDebugString, but LdrpLogDbgPrint – which I believe doesn’t use vDbgPrintExWithPrefix. Years ago Mark Russinovic declined my request to support LdrpLogDbgPrint in DebugView.

  6. Pingback: 更多信息如下0xc0000139错误在windows上的应用。 – 运维实战侠

  7. Pingback: 更多信息如下0xc0000139错误在windows上的应用。 – 实战宝典

Leave a reply to Ofek Shilon Cancel reply