Figure 1 Loader APIs
API | NTDLL APIs | LoadResource | LdrAccessResource LdrAlternateResourcesEnabled | DisableThreadLibraryCalls | LdrDisableThreadCalloutsForDll LdrEnumResources LdrFindAppCompatVariableInfo LdrFindEntryForAddress | EnumResourceTypesW | LdrFindResourceDirectory_U | FindResourceExA | LdrFindResource_U LdrFlushAlternateResourceModules LdrGetAlternateResourceModuleHandle | GetModuleHandleForUnicodeString | LdrGetDllHandle | GetProcAddress | LdrGetProcedureAddress LdrInitializeThunk | LoadLibraryEx (LOAD_LIBRARY_AS_DATAFILE) | LdrLoadAlternateResourceModule | LoadLibrary | LdrLoadDll LdrProcessRelocationBlock LdrQueryApplicationCompatibilityGoo LdrQueryImageFileExecutionOptions LdrQueryProcessModuleInformation LdrRelocateImage | ExitProcess | LdrShutdownProcess | ExitThread | LdrShutdownThread LdrUnloadAlternateResourceModule | FreeLibrary | LdrUnloadDll LdrVerifyImageMatchesChecksum LdrVerifyMappedImageMatchesChecksum | Figure 2 Private Loader APIs LdrpAccessResourceData
LdrpAllocateDataTableEntry
LdrpAllocateTls
LdrpCallInitRoutine
LdrpCallTlsInitializers
LdrpCheckForKnownDll
LdrpCheckForLoadedDll
LdrpCheckForLoadedDllHandle
LdrpClearLoadInProgress
LdrpCompareResourceNames_U
LdrpCreateDllSection
LdrpDefineDllTag
LdrpDllTagProcedures
LdrpDphDetectSnapRoutines
LdrpDphInitializeTargetDll
LdrpDphSnapImports
LdrpFetchAddressOfEntryPoint
LdrpForkProcess
LdrpFreeTls
LdrpGetProcedureAddress
LdrpInitializationFailure
LdrpInitialize
LdrpInitializeProcess
LdrpInitializeThread
LdrpInitializeTls
LdrpInsertMemoryTableEntry
LdrpLoadDll
LdrpLoadImportModule
LdrpMapDll
LdrpNameToOrdinal
LdrpRelocateStartContext
LdrpResolveDllName
LdrpRunInitializeRoutines
LdrpSearchResourceSection_U
LdrpSetAlternateResourceModuleHandle
LdrpSetProtection
LdrpSnapIAT
LdrpSnapThunk
LdrpTagAllocateHeap0...LdrpTagAllocateHeap63
LdrpTagAllocateHeap
LdrpUpdateLoadCount
LdrpValidateImageForMp
LdrpWalkImportDescriptor
Figure 3 Internal Loader Routines #1 - LoadLibraryExW 3rd parameter is 0:
LdrLoadDll (0x77f889a9)
LdrpLoadDll 0x77f887e0
LdrpCheckForLoadedDll (0x77f87122)
LdrpMapDll (0x77f8bc77)
LdrpCheckForKnownDll (0x77f8c62b)
LdrpResolveDllName (0x77f8c3df)
LdrpCreateDllSection (0x77f8c355)
LdrpAllocateDataTableEntry (0x77f8be69)
LdrpFetchAddressOfEntryPoint (0x77f8bf23)
LdrpInsertMemoryTableEntry (0x77f8bebb)
LdrpWalkImportDescriptor (0x77f8be15)
LdrpLoadImportModule (0x77f8bfd1)
*LdrpCheckForLoadedDll
LdrpSnapIAT (0x77f8c047)
LdrpSnapThunk (0x77f87bd1)
LdrpNameToOrdinal (0x77f87cf0)
**LdrpLoadDll
LdrpGetProcedureAddress (0x77f87a20)
LdrpCheckforLoadedDllHandle (0x77f870cc)
**LdrpSnapThunk
LdrpUpdateLoadCount (0x77f88afa)
*LdrpCheckForLoadedDll
**LdrpUpdateLoadCount
LdrpRunInitializeRoutines (0x77f8bcb8)
LdrpClearLoadInProgress (0x77f88c12)
#2 - LoadLibraryExW 3rd parameter is 0 and DLL has been bound:
LdrLoadDll (0x77f889a9)
LdrpLoadDll 0x77f887e0
LdrpCheckForLoadedDll (0x77f87122)
LdrpMapDll (0x77f8bc77)
LdrpCheckForKnownDll (0x77f8c62b)
LdrpResolveDllName (0x77f8c3df)
LdrpCreateDllSection (0x77f8c355)
LdrpAllocateDataTableEntry (0x77f8be69)
LdrpFetchAddressOfEntryPoint (0x77f8bf23)
LdrpInsertMemoryTableEntry (0x77f8bebb)
LdrpWalkImportDescriptor (0x77f8be15)
LdrpLoadImportModule (0x77f8bfd1)
*LdrpCheckForLoadedDll
LdrpUpdateLoadCount (0x77f88afa)
*LdrpCheckForLoadedDll
**LdrpUpdateLoadCount
LdrpRunInitializeRoutines (0x77f8bcb8)
LdrpClearLoadInProgress (0x77f88c12)
#3 - LoadLibraryExW 3rd Parameter is DONT_RESOLVE_DLL_REFERENCES:
LdrLoadDll (0x77f889a9)
LdrpLoadDll 0x77f887e0
LdrpCheckForLoadedDll (0x77f87122)
LdrpMapDll (0x77f8bc77)
LdrpCheckForKnownDll (0x77f8c62b)
LdrpResolveDllName (0x77f8c3df)
LdrpCreateDllSection (0x77f8c355)
LdrpAllocateDataTableEntry (0x77f8be69)
LdrpFetchAddressOfEntryPoint (0x77f8bf23)
LdrpInsertMemoryTableEntry (0x77f8bebb)
#4 - LoadLibraryExW 3rd Parameter is LOAD_WITH_ALTERED_SEARCH_PATH:
LdrLoadDll (0x77f889a9)
LdrpLoadDll 0x77f887e0
LdrpCheckForLoadedDll (0x77f87122)
LdrpMapDll (0x77f8bc77)
LdrpCheckForKnownDll (0x77f8c62b)
LdrpResolveDllName (0x77f8c3df)
LdrpCreateDllSection (0x77f8c355)
LdrpAllocateDataTableEntry (0x77f8be69)
LdrpFetchAddressOfEntryPoint (0x77f8bf23)
LdrpInsertMemoryTableEntry (0x77f8bebb)
LdrpWalkImportDescriptor (0x77f8be15)
LdrpLoadImportModule (0x77f8bfd1)
*LdrpCheckForLoadedDll
LdrpUpdateLoadCount (0x77f88afa)
*LdrpCheckForLoadedDll
**LdrpUpdateLoadCount
LdrpRunInitializeRoutines (0x77f8bcb8)
LdrpClearLoadInProgress (0x77f88c12)
#5 - LoadLibraryExW 3rd Parameter is LOAD_LIBRARY_AS_DATAFILE:
LdrpCheckForLoadedDll (0x77f87122)
All addresses based upon Windows 2000 Professional (Build 2195: Service Pack 1)
* previously documented
** recursive call
Figure 4 APIs Forwarded to NTDLL
API | Destination | DeleteCriticalSection | Forwarded to NTDLL.RtlDeleteCriticalSection | EnterCriticalSection | Forwarded to NTDLL.RtlEnterCriticalSection | HeapAlloc | Forwarded to NTDLL.RtlAllocateHeap | HeapFree | Forwarded to NTDLL.RtlFreeHeap | HeapReAlloc | Forwarded to NTDLL.RtlReAllocateHeap | HeapSize | Forwarded to NTDLL.RtlSizeHeap | LeaveCriticalSection | Forwarded to NTDLL.RtlLeaveCriticalSection | RtlFillMemory | Forwarded to NTDLL.RtlFillMemory | RtlMoveMemory | Forwarded to NTDLL.RtlMoveMemory | RtlUnwind | Forwarded to NTDLL.RtlUnwind | RtlZeroMemory | Forwarded to NTDLL.RtlZeroMemory | SetCriticalSectionSpinCount | Forwarded to NTDLL.RtlSetCriticalSection-
SpinCount | TryEnterCriticalSection | Forwarded to NTDLL.RtlTryEnterCriticalSection | VerSetConditionMask | Forwarded to NTDLL.VerSetConditionMask | Figure 5 Binding via LdrpSnapIAT and LdrpSnapThunk for Forwarded.DLL IAT IAT
Address File Memory API Name (* - Forwarded APIs)
1200B000 0000C314 => 77E851E1 HeapCreate
* 1200B004 0000C322 => 77FCA535 HeapFree (RtlFreeHeap)
1200B008 0000C0AA => 77E8F07F GetCommandLineA
1200B00C 0000C0BC => 77E85C77 GetVersion
1200B010 0000C0CA => 77EA83DE DbgBreakPoint
1200B014 0000C0D8 => 77E8F043 GetStdHandle
1200B018 0000C0E8 => 77E8334F WriteFile
1200B01C 0000C0F4 => 77E82EF1 InterlockedDecrement
1200B020 0000C10C => 77E9E0C8 OutputDebugStringA
1200B024 0000C122 => 77E87031 GetProcAddress
1200B028 0000C134 => 77E87273 LoadLibraryA
1200B02C 0000C144 => 77E82EE0 InterlockedIncrement
1200B030 0000C15C => 77E88885 GetModuleFileNameA
1200B034 0000C172 => 77E8F32D ExitProcess
1200B038 0000C180 => 77EB45FF TerminateProcess
1200B03C 0000C194 => 77E8304F GetCurrentProcess
1200B040 0000C1A8 => 77E83510 GetCurrentThreadId
1200B044 0000C1BE => 77E836DD TlsSetValue
1200B048 0000C1CC => 77E8C512 TlsAlloc
1200B04C 0000C1D8 => 77E8F254 TlsFree
1200B050 0000C1E2 => 77E83008 SetLastError
1200B054 0000C1F2 => 77E83025 TlsGetValue
1200B058 0000C200 => 77E8301B GetLastError
1200B05C 0000C210 => 77E831E7 SetHandleCount
1200B060 0000C222 => 77E84C93 GetFileType
1200B064 0000C230 => 77E8F10A GetStartupInfoA
* 1200B068 0000C242 => 77F837C4 DeleteCriticalSection (RtlDeleteCriticalSection)
1200B06C 0000C25A => 77E83A61 IsBadWritePtr
1200B070 0000C26A => 77E84F4F IsBadReadPtr
1200B074 0000C27A => 77E8BC6C HeapValidate
1200B078 0000C28A => 77E82116 FreeEnvironmentStringsA
1200B07C 0000C2A4 => 77E8F085 FreeEnvironmentStringsW
1200B080 0000C2BE => 77E8593F WideCharToMultiByte
1200B084 0000C2D4 => 77E9C60D GetEnvironmentStrings
1200B088 0000C2EC => 77E8324E GetEnvironmentStringsW
1200B08C 0000C306 => 77E8523C HeapDestroy
1200B090 0000C41E => 77E841B6 LCMapStringW
1200B094 0000C40E => 77E95278 LCMapStringA
1200B098 0000C32E => 77E85194 VirtualFree
1200B09C 0000C33C => 77E83833 InitializeCriticalSection
* 1200B0A0 0000C358 => 77F81B42 EnterCriticalSection (RtlEnterCriticalSection)
* 1200B0A4 0000C370 => 77F81B73 LeaveCriticalSection (RtlLeaveCriticalSection)
* 1200B0A8 0000C388 => 77FCA055 HeapAlloc (RtlAllocateHeap)
* 1200B0AC 0000C394 => 77F85B48 HeapReAlloc (RtlReAllocateHeap)
1200B0B0 0000C3A2 => 77E850EC VirtualAlloc
1200B0B4 0000C3B2 => 77E8EFB8 GetCPInfo
1200B0B8 0000C3BE => 77E83852 GetACP
1200B0BC 0000C3C8 => 77E8724D GetOEMCP
1200B0C0 0000C3D4 => 77E84035 MultiByteToWideChar
1200B0C4 0000C3EA => 77E9740C GetStringTypeA
1200B0C8 0000C3FC => 77E867D4 GetStringTypeW
1200B0CC 0000C42E => 77E853E8 SetFilePointer
* 1200B0D0 0000C440 => 77F8E13A RtlUnwind (RtlUnwind)
1200B0D4 0000C44C => 77E8F3BC SetStdHandle
1200B0D8 0000C45C => 77E863C1 FlushFileBuffers
1200B0DC 0000C470 => 77E83053 CloseHandle
1200B0E0 00000000 00000000
1200B0E4 0000C090 => 77E1F098 MessageBoxW
1200B0E8 00000000 00000000
**********************************************************************************
LdrSnap Display (Note the displays of forwarded APIs):
LDR: LdrLoadDll, loading Forwarder.DLL from
E:\PROJECTS\TEMP\Test\debug;.;D:\WINNT\System32;D:\WINNT\system;D:\WINNT;...
LDR: Loading (DYNAMIC) E:\PROJECTS\TEMP\Test\debug\Forwarder.DLL
LDR: KERNEL32.dll used by Forwarder.DLL
LDR: Snapping imports for Forwarder.DLL from KERNEL32.dll
LDR: LdrLoadDll, loading NTDLL.dll from
LDR: LdrGetProcedureAddress by NAME - RtlEnterCriticalSection
LDR: LdrLoadDll, loading NTDLL.dll from
LDR: LdrGetProcedureAddress by NAME - RtlDeleteCriticalSection
LDR: LdrLoadDll, loading NTDLL.dll from
LDR: LdrGetProcedureAddress by NAME - RtlFreeHeap
LDR: LdrLoadDll, loading NTDLL.dll from
LDR: LdrGetProcedureAddress by NAME - RtlLeaveCriticalSection
LDR: LdrLoadDll, loading NTDLL.dll from
LDR: LdrGetProcedureAddress by NAME - RtlAllocateHeap
LDR: LdrLoadDll, loading NTDLL.dll from
LDR: LdrGetProcedureAddress by NAME - RtlReAllocateHeap
LDR: LdrLoadDll, loading NTDLL.dll from
LDR: LdrGetProcedureAddress by NAME - RtlUnwind
LDR: Real INIT LIST
E:\PROJECTS\TEMP\Test\debug\Forwarder.DLL init routine 110010e9
LDR: Forwarder.DLL loaded. - Calling init routine at 110010e9
Figure 6 Pre-binding using SDK Bind IAT
File &
Address Memory API Name (* - Forwarded APIs)
10004000 77E851E1 HeapCreate
10004004 77E85C77 GetVersion
10004008 77E8F32D ExitProcess
1000400C 77EB45FF TerminateProcess
10004010 77E8304F GetCurrentProcess
10004014 77E83510 GetCurrentThreadId
10004018 77E836DD TlsSetValue
1000401C 77E8C512 TlsAlloc
10004020 77E8F254 TlsFree
10004024 77E83025 TlsGetValue
10004028 77E831E7 SetHandleCount
1000402C 77E8F043 GetStdHandle
10004030 77E84C93 GetFileType
10004034 77E8F10A GetStartupInfoA
* 10004038 77F837C4 DeleteCriticalSection (RtlDeleteCriticalSection)
1000403C 77E88885 GetModuleFileNameA
10004040 77E82116 FreeEnvironmentStringsA
10004044 77E8F085 FreeEnvironmentStringsW
10004048 77E8593F WideCharToMultibyte
1000404C 77E9C60D GetEnvironmentStrings
10004050 77E8324E GetEnvironmentStringsW
10004054 77E8523C HeapDestroy
10004058 77E8F07F GetCommandLineA
1000405C 77E85194 VirtualFree
* 10004060 77FCA535 HeapFree (RtlFreeHeap)
10004064 77E8334F WriteFile
10004068 77E83833 InitializeCriticalSection
* 1000406C 77F81B42 EnterCriticalSection (RtlEnterCriticalSection)
* 10004070 77F81B73 LeaveCriticalSection (RtlLeaveCriticalSection)
* 10004074 77FCA055 HeapAlloc (RtlAllocateHeap)
10004078 77E8EFB8 GetCPInfo
1000407C 77E83852 GetACP
10004080 77E8724D GetOEMCP
10004084 77E850EC VirtualAlloc
* 10004088 77F85B48 HeapReAlloc (RtlReAllocateHeap)
1000408C 77E87031 GetProcAddress
10004090 77E87273 LoadLibraryA
10004094 77E84035 MultiByteToWideChar
10004098 77E95278 LCMapStringA
1000409C 77E841B6 LCMapStringW
100040A0 77E9740C GetStringTypeA
100040A4 77E867D4 GetStringTypeW
* 100040A8 77F8E13A RtlUnwind (RtlUnwind)
**********************************************************************************
LdrSnap Display (Note there are no displays of forwarded APIs):
LDR: LdrLoadDll, loading TestDll.DLL from
E:\PROJECTS\TEMP\Test\debug;.;D:\WINNT\System32;D:\WINNT\system;D:\WINNT;...
LDR: Loading (DYNAMIC) E:\PROJECTS\TEMP\Test\debug\TestDll.DLL
LDR: TestDll.DLL bound to KERNEL32.dll
LDR: TestDll.DLL has correct binding to KERNEL32.dll
LDR: TestDll.DLL bound to NTDLL.DLL via forwarder(s) from KERNEL32.dll
LDR: TestDll.DLL has correct binding to NTDLL.DLL
LDR: Real INIT LIST
E:\PROJECTS\TEMP\Test\debug\TestDll.DLL init routine 10001109
LDR: TestDll.DLL loaded. - Calling init routine at 10001109
|