The address shown on the Ldr line is a pointer to the PEB_LDR_DATA structure described earlier. Notice that WinDbg shows you the address of the three lists and dumps the initialization order list for you, displaying the full path, time stamp, and base address of each module.
You can also analyze each module entry on its own by going through the module list and then dumping the data at each address, formatted as a LDR_DATA_TABLE_ENTRY structure. Instead of doing this for each entry, however, WinDbg can do most of the work by using the
Note that the last number is variable: it depends on whatever is shown on your machine under
You should then see the entries for each module:0:001> !list –t ntdll!_LIST_ENTRY.Flink –x "dt ntdll!_LDR_DATA_TABLE_ENTRY @$extret\" 001c1cf8 +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x1c1d68 - 0x76fd4ccc ] +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x1c1d70 - 0x76fd4cd4 ] +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ] +0x018 DllBase : 0x00d80000 +0x01c EntryPoint : 0x00d831ed +0x020 SizeOfImage : 0x28000 +0x024 FullDllName : _UNICODE_STRING "C:\Windows\notepad.exe" +0x02c BaseDllName : _UNICODE_STRING "notepad.exe" +0x034 Flags : 0x4010
Although this section covers the user-mode loader in Ntdll.dll, note that the kernel also employs its own loader for drivers and dependent DLLs, with a similar loader entry structure. Likewise, the kernel-mode loader has its own database of such entries, which is directly accessible through the
Looking at the list in this raw format gives you some extra insight into the loader’s
Flag
Meaning
LDRP_STATIC_LINK (0x2)
This module is referenced by an import table and is required.
LDRP_IMAGE_DLL (0x4)
The module is an image DLL (and not a data DLL or executable).
LDRP_IMAGE_INTEGRITY_FORCED (0x20)
The module was linked with /FORCEINTEGRITY (contains IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY_in its PE header).
LDRP_LOAD_IN_PROGRESS (0x1000)
This module is currently being loaded.
LDRP_UNLOAD_IN_PROGRESS (0x2000)
This module is currently being unloaded.
LDRP_ENTRY_PROCESSED (0x4000)
The loader has finished processing this module.
LDRP_ENTRY_INSERTED (0x8000)
The loader has finished inserting this entry into the loaded module database.
LDRP_FAILED_BUILTIN_LOAD (0x20000)
Indicates this boot driver failed to load.
LDRP_DONT_CALL_FOR_THREADS (0x40000)
Do not send DLL_THREAD_ATTACH/DETACH notifications to this DLL.
LDRP_PROCESS_ATTACH_CALLED (0x80000)
This DLL has been sent the DLL_PROCESS_ATTACH notification.
LDRP_DEBUG_SYMBOLS_LOADED (0x100000)
The debug symbols for this module have been loaded by the kernel or user debugger.
LDRP_IMAGE_NOT_AT_BASE (0x200000)
This image was relocated from its original base address.
LDRP_COR_IMAGE (0x400000)
This module is a .NET application.
LDRP_COR_OWNS_UNMAP (0x800000)
This module should be unmapped by the .NET runtime.
LDRP_SYSTEM_MAPPED (0x1000000)
This module is mapped into kernel address space with System PTEs (versus being in the initial boot loader’s memory).
LDRP_IMAGE_VERIFYING (0x2000000)
This module is currently being verified by Driver Verifier.
LDRP_DRIVER_DEPENDENT_DLL (0x4000000)
This module is a DLL that is in a driver’s import table.
LDRP_ENTRY_NATIVE (0x8000000)
This module was compiled for Windows 2000 or later. It’s used by Driver Verifier as an indication that a driver might be suspect.
LDRP_REDIRECTED (0x10000000)
The manifest file specified a redirected file for this DLL.
LDRP_NON_PAGED_DEBUG_INFO (0x20000000)
The debug information for this module is in nonpaged memory.
LDRP_MM_LOADED (0x40000000)
This module was loaded by the kernel loader through
LDRP_COMPAT_DATABASE_PROCESSED (0x80000000)
The shim engine has processed this DLL.
Import Parsing
Now that we’ve explained the way the loader keeps track of all the modules loaded for a process, you can continue analyzing the startup initialization tasks performed by the loader. During this step, the loader will do the following:
Load each DLL referenced in the import table of the process’ executable image.