Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ldrp.h File Reference

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <string.h>
#include "wdbgexts.h"
#include <ntdbg.h>

Go to the source code of this file.

Classes

struct  _LDRP_PATH_CACHE
struct  _LDRP_TLS_ENTRY

Defines

#define NOEXTAPI
#define LDRP_MAX_KNOWN_PATH   128
#define NATIVE_PAGE_SIZE   PAGE_SIZE
#define NATIVE_PAGE_SHIFT   PAGE_SHIFT
#define NATIVE_BYTES_TO_PAGES(Size)   BYTES_TO_PAGES(Size)
#define LDRP_HASH_TABLE_SIZE   32
#define LDRP_HASH_MASK   (LDRP_HASH_TABLE_SIZE-1)
#define LDRP_COMPUTE_HASH_INDEX(wch)   ( (RtlUpcaseUnicodeChar((wch)) - (WCHAR)'A') & LDRP_HASH_MASK )
#define LDRP_BAD_DLL   LongToPtr(0xffbadd11)
#define LdrpReferenceLoadedDll(lde)   LdrpUpdateLoadCount( lde, TRUE )
#define LdrpDereferenceLoadedDll(lde)   LdrpUpdateLoadCount( lde, FALSE )
#define MAKE_TAG(t)   (RTL_HEAP_MAKE_TAG( NtdllBaseTag, t ))
#define CSR_TAG   0
#define LDR_TAG   1
#define CURDIR_TAG   2
#define TLS_TAG   3
#define DBG_TAG   4
#define SE_TAG   5
#define TEMP_TAG   6
#define ATOM_TAG   7
#define LdrpCallInitRoutine(InitRoutine, DllHandle, Reason, Context)   (InitRoutine)((DllHandle), (Reason), (Context))

Typedefs

typedef _LDRP_PATH_CACHE LDRP_PATH_CACHE
typedef _LDRP_PATH_CACHEPLDRP_PATH_CACHE
typedef _LDRP_TLS_ENTRY LDRP_TLS_ENTRY
typedef _LDRP_TLS_ENTRYPLDRP_TLS_ENTRY

Functions

NTSTATUS LdrpSnapIAT (IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry_Export, IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry_Import, IN PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, IN BOOLEAN SnapForwardersOnly)
NTSTATUS LdrpSnapLinksToDllHandle (IN PVOID DllHandle, IN ULONG NumberOfThunks, IN OUT PIMAGE_THUNK_DATA FirstThunk)
NTSTATUS LdrpSnapThunk (IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA OriginalThunk, IN OUT PIMAGE_THUNK_DATA Thunk, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN StaticSnap, IN PSZ DllName OPTIONAL)
USHORT LdrpNameToOrdinal (IN PSZ Name, IN ULONG NumberOfNames, IN PVOID DllBase, IN PULONG NameTableBase, IN PUSHORT NameOrdinalTableBase)
PLDR_DATA_TABLE_ENTRY LdrpAllocateDataTableEntry (IN PVOID DllBase)
BOOLEAN LdrpCheckForLoadedDll (IN PWSTR DllPath OPTIONAL, IN PUNICODE_STRING DllName, IN BOOLEAN StaticLink, IN BOOLEAN Wx86KnownDll, OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry)
BOOLEAN LdrpCheckForLoadedDllHandle (IN PVOID DllHandle, OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry)
NTSTATUS LdrpMapDll (IN PWSTR DllPath OPTIONAL, IN PWSTR DllName, IN PULONG DllCharacteristics OPTIONAL, IN BOOLEAN StaticLink, IN BOOLEAN Wx86KnownDll, OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry)
NTSTATUS LdrpWalkImportDescriptor (IN PWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
NTSTATUS LdrpRunInitializeRoutines (IN PCONTEXT Context OPTIONAL)
VOID LdrpUpdateLoadCount (IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry, IN BOOLEAN IncrementCount)
NTSTATUS LdrpInitializeProcess (IN PCONTEXT Context OPTIONAL, IN PVOID SystemDllBase, IN PUNICODE_STRING UnicodeImageName)
VOID LdrpInitialize (IN PCONTEXT Context, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
VOID LdrpInsertMemoryTableEntry (IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
BOOLEAN LdrpResolveDllName (IN PWSTR DllPath OPTIONAL, IN PWSTR DllName, OUT PUNICODE_STRING FullDllName, OUT PUNICODE_STRING BaseDllName, OUT PHANDLE DllFile)
NTSTATUS LdrpCreateDllSection (IN PUNICODE_STRING FullDllName, IN HANDLE DllFile, IN PUNICODE_STRING BaseName, IN PULONG DllCharacteristics OPTIONAL, OUT PHANDLE SectionHandle)
VOID LdrpInitializePathCache (VOID)
PVOID LdrpFetchAddressOfEntryPoint (IN PVOID Base)
BOOLEAN xRtlDosPathNameToNtPathName (IN PSZ DosFileName, OUT PSTRING NtFileName, OUT PSZ *FilePart OPTIONAL, OUT PRTL_RELATIVE_NAME RelativeName OPTIONAL)
ULONG xRtlDosSearchPath (PSZ lpPath, PSZ lpFileName, PSZ lpExtension, ULONG nBufferLength, PSZ lpBuffer, PSZ *lpFilePart OPTIONAL)
ULONG xRtlGetFullPathName (PSZ lpFileName, ULONG nBufferLength, PSZ lpBuffer, PSZ *lpFilePart OPTIONAL)
PSZ UnicodeToAnsii (IN PWSTR String)
HANDLE LdrpCheckForKnownDll (IN PWSTR DllName, OUT PUNICODE_STRING FullDllName, OUT PUNICODE_STRING BaseDllName)
NTSTATUS LdrpSetProtection (IN PVOID Base, IN BOOLEAN Reset, IN BOOLEAN StaticLink)
NTSTATUS LdrpInitializeTls (VOID)
NTSTATUS LdrpAllocateTls (VOID)
VOID LdrpFreeTls (VOID)
VOID LdrpCallTlsInitializers (PVOID DllBase, ULONG Reason)
NTSTATUS NTAPI LdrpLoadDll (IN PWSTR DllPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *DllHandle, IN BOOLEAN RunInitRoutines)
NTSTATUS NTAPI LdrpGetProcedureAddress (IN PVOID DllHandle, IN PANSI_STRING ProcedureName OPTIONAL, IN ULONG ProcedureNumber OPTIONAL, OUT PVOID *ProcedureAddress, IN BOOLEAN RunInitRoutines)
PLIST_ENTRY RtlpLockProcessHeapsList (VOID)
VOID RtlpUnlockProcessHeapsList (VOID)
BOOLEAN RtlpSerializeHeap (IN PVOID HeapHandle)
PVOID LdrpDefineDllTag (PWSTR TagName, PUSHORT TagIndex)

Variables

BOOLEAN LdrpImageHasTls
UNICODE_STRING LdrpDefaultPath
HANDLE LdrpKnownDllObjectDirectory
WCHAR LdrpKnownDllPathBuffer [LDRP_MAX_KNOWN_PATH]
UNICODE_STRING LdrpKnownDllPath
LIST_ENTRY LdrpHashTable [LDRP_HASH_TABLE_SIZE]
LIST_ENTRY LdrpDefaultPathCache
BOOLEAN ShowSnaps
BOOLEAN RtlpTimoutDisable
LARGE_INTEGER RtlpTimeout
ULONG NtGlobalFlag
LIST_ENTRY RtlCriticalSectionList
RTL_CRITICAL_SECTION RtlCriticalSectionLock
BOOLEAN LdrpShutdownInProgress
BOOLEAN LdrpInLdrInit
BOOLEAN LdrpLdrDatabaseIsSetup
BOOLEAN LdrpVerifyDlls
PLDR_DATA_TABLE_ENTRY LdrpImageEntry
LIST_ENTRY LdrpUnloadHead
BOOLEAN LdrpActiveUnloadCount
PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache
PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache
ULONG LdrpFatalHardErrorCount
RTL_CRITICAL_SECTION FastPebLock
HANDLE LdrpShutdownThreadId
ULONG LdrpNumberOfProcessors
LIST_ENTRY LdrpTlsList
ULONG LdrpNumberOfTlsEntries
ULONG NtdllBaseTag


Define Documentation

#define ATOM_TAG   7
 

Definition at line 466 of file ldrp.h.

Referenced by LdrpInitializeProcess().

#define CSR_TAG   0
 

Definition at line 459 of file ldrp.h.

Referenced by CsrClientConnectToServer(), and CsrpConnectToServer().

#define CURDIR_TAG   2
 

Definition at line 461 of file ldrp.h.

#define DBG_TAG   4
 

Definition at line 463 of file ldrp.h.

Referenced by DbgSsHandleKmApiMsg().

#define LDR_TAG   1
 

Definition at line 460 of file ldrp.h.

Referenced by LdrpAllocateDataTableEntry(), LdrpCheckForKnownDll(), LdrpInitializeProcess(), and LdrpResolveDllName().

#define LDRP_BAD_DLL   LongToPtr(0xffbadd11)
 

Definition at line 166 of file ldrp.h.

Referenced by LdrpSnapThunk().

#define LDRP_COMPUTE_HASH_INDEX wch   )     ( (RtlUpcaseUnicodeChar((wch)) - (WCHAR)'A') & LDRP_HASH_MASK )
 

Definition at line 161 of file ldrp.h.

Referenced by LdrpCheckForLoadedDll(), and LdrpInsertMemoryTableEntry().

#define LDRP_HASH_MASK   (LDRP_HASH_TABLE_SIZE-1)
 

Definition at line 160 of file ldrp.h.

#define LDRP_HASH_TABLE_SIZE   32
 

Definition at line 159 of file ldrp.h.

Referenced by LdrpInitializeProcess().

#define LDRP_MAX_KNOWN_PATH   128
 

Definition at line 35 of file ldrp.h.

#define LdrpCallInitRoutine InitRoutine,
DllHandle,
Reason,
Context   )     (InitRoutine)((DllHandle), (Reason), (Context))
 

Definition at line 484 of file ldrp.h.

Referenced by LdrpCallTlsInitializers(), LdrpInitializeThread(), LdrpRunInitializeRoutines(), LdrShutdownProcess(), LdrShutdownThread(), and LdrUnloadDll().

#define LdrpDereferenceLoadedDll lde   )     LdrpUpdateLoadCount( lde, FALSE )
 

Definition at line 254 of file ldrp.h.

Referenced by LdrUnloadDll().

#define LdrpReferenceLoadedDll lde   )     LdrpUpdateLoadCount( lde, TRUE )
 

Definition at line 253 of file ldrp.h.

Referenced by LdrpInitializeProcess(), and LdrpLoadDll().

#define MAKE_TAG  )     (RTL_HEAP_MAKE_TAG( NtdllBaseTag, t ))
 

Definition at line 457 of file ldrp.h.

Referenced by AddAlias(), AddCommand(), AddExeAliasList(), AddFaceNode(), AllocateCommandHistory(), AllocateConsole(), AllocateScrollBuffer(), BeginPopup(), ConsoleAddProcessRoutine(), ConsoleClientConnectRoutine(), ConvertOutputToOem(), ConvertOutputToUnicode(), CookedRead(), CreateConsoleBitmap(), CreateDbcsScreenBuffer(), CreateInputBuffer(), CreateScreenBuffer(), CsrClientConnectToServer(), CsrpConnectToServer(), DbgSsHandleKmApiMsg(), DoStringPaste(), DrawCommandListPopup(), EnumerateFonts(), FalseUnicodeToRealUnicode(), FE_WriteRegionToScreenHW(), FindExe(), FindExeCommandHistory(), FlushAllButKeys(), FontEnum(), GrowConsoleHandleTable(), GrowIoHandleTable(), InheritIoHandleTable(), InitializeInputHandle(), InitializeScrollBuffer(), LdrpAllocateDataTableEntry(), LdrpAllocateTls(), LdrpCheckForKnownDll(), LdrpGetProcedureAddress(), LdrpInitializeProcess(), LdrpInitializeTls(), LdrpResolveDllName(), LdrpRunInitializeRoutines(), LdrQueryImageFileExecutionOptions(), MatchandCopyAlias(), MergeAttrStrings(), MyRegQueryValue(), PrependInputBuffer(), ProcessCommandListInput(), ProcessCtrlEvents(), QueueConsoleMessage(), QueueThreadMessage(), RawReadWaitRoutine(), ReadChars(), ReadOutputString(), ReallocCommandHistory(), RealUnicodeToFalseUnicode(), ReCreateDbcsScreenBuffer(), ReplaceAlias(), ResizeScreenBuffer(), RtlCopySecurityDescriptor(), RtlCreateAndSetSD(), RtlpConvertAclToAutoInherit(), RtlpConvertToAutoInheritSecurityObject(), RtlpCreateServerAcl(), RtlpGetDefaultsSubjectContext(), RtlpInheritAcl(), RtlpNewSecurityObject(), RtlpSetSecurityObject(), SetInputBufferSize(), SetRAMFont(), SetRAMFontCodePage(), SrvAddConsoleAlias(), SrvAllocConsole(), SrvGetConsoleAlias(), SrvSetConsoleTitle(), SrvVDMConsoleOperation(), SrvWriteConsoleOutput(), StoreSelection(), StoreTextBufferFontInfo(), TranslateConsoleTitle(), UpdateComplexRegion(), WaitForMoreToRead(), WWSB_DoSrvWriteConsole(), WWSB_DoWriteConsole(), WWSB_WriteChars(), WWSB_WriteOutputString(), WWSB_WriteRectToScreenBuffer(), and WWSB_WriteRegionToScreen().

#define NATIVE_BYTES_TO_PAGES Size   )     BYTES_TO_PAGES(Size)
 

Definition at line 155 of file ldrp.h.

#define NATIVE_PAGE_SHIFT   PAGE_SHIFT
 

Definition at line 154 of file ldrp.h.

#define NATIVE_PAGE_SIZE   PAGE_SIZE
 

Definition at line 153 of file ldrp.h.

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

#define NOEXTAPI
 

Definition at line 28 of file ldrp.h.

#define SE_TAG   5
 

Definition at line 464 of file ldrp.h.

Referenced by RtlCopySecurityDescriptor(), RtlCreateAndSetSD(), RtlpConvertAclToAutoInherit(), RtlpConvertToAutoInheritSecurityObject(), RtlpCreateServerAcl(), RtlpGetDefaultsSubjectContext(), RtlpInheritAcl(), RtlpNewSecurityObject(), and RtlpSetSecurityObject().

#define TEMP_TAG   6
 

Definition at line 465 of file ldrp.h.

Referenced by LdrpGetProcedureAddress(), LdrpResolveDllName(), LdrpRunInitializeRoutines(), and LdrQueryImageFileExecutionOptions().

#define TLS_TAG   3
 

Definition at line 462 of file ldrp.h.

Referenced by LdrpAllocateTls(), and LdrpInitializeTls().


Typedef Documentation

typedef struct _LDRP_PATH_CACHE LDRP_PATH_CACHE
 

typedef struct _LDRP_TLS_ENTRY LDRP_TLS_ENTRY
 

Referenced by LdrpAllocateTls().

typedef struct _LDRP_PATH_CACHE * PLDRP_PATH_CACHE
 

typedef struct _LDRP_TLS_ENTRY * PLDRP_TLS_ENTRY
 

Referenced by LdrpInitializeTls().


Function Documentation

PLDR_DATA_TABLE_ENTRY LdrpAllocateDataTableEntry IN PVOID  DllBase  ) 
 

Definition at line 3043 of file ldrsnap.c.

References LDR_TAG, MAKE_TAG, NULL, RtlAllocateHeap, and RtlImageNtHeader().

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

03049 : 03050 03051 This function allocates an entry in the loader data table. If the 03052 table is going to overflow, then a new table is allocated. 03053 03054 Arguments: 03055 03056 DllBase - Supplies the address of the base of the DLL Image. 03057 be added to the loader data table. 03058 03059 Return Value: 03060 03061 Returns the address of the allocated loader data table entry 03062 03063 --*/ 03064 03065 { 03066 PLDR_DATA_TABLE_ENTRY Entry; 03067 PIMAGE_NT_HEADERS NtHeaders; 03068 03069 NtHeaders = RtlImageNtHeader(DllBase); 03070 03071 Entry = NULL; 03072 if ( NtHeaders ) { 03073 Entry = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( LDR_TAG ) | HEAP_ZERO_MEMORY,sizeof( *Entry )); 03074 if ( Entry ) { 03075 Entry->DllBase = DllBase; 03076 Entry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage; 03077 Entry->TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp; 03078 } 03079 } 03080 return Entry; 03081 }

NTSTATUS LdrpAllocateTls VOID   ) 
 

Definition at line 2071 of file ldrinit.c.

References DbgPrint, LDRP_TLS_ENTRY, LdrpNumberOfTlsEntries, LdrpTlsList, MAKE_TAG, RtlAllocateHeap, ShowSnaps, _LDRP_TLS_ENTRY::Tls, and TLS_TAG.

Referenced by LdrpInitializeThread(), and LdrpInitializeTls().

02074 { 02075 PTEB Teb; 02076 PLIST_ENTRY Head, Next; 02077 PLDRP_TLS_ENTRY TlsEntry; 02078 PVOID *TlsVector; 02079 02080 Teb = NtCurrentTeb(); 02081 02082 // 02083 // Allocate the array of thread local storage pointers 02084 // 02085 02086 if ( LdrpNumberOfTlsEntries ) { 02087 TlsVector = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( TLS_TAG ),sizeof(PVOID)*LdrpNumberOfTlsEntries); 02088 if ( !TlsVector ) { 02089 return STATUS_NO_MEMORY; 02090 } 02091 02092 Teb->ThreadLocalStoragePointer = TlsVector; 02093 Head = &LdrpTlsList; 02094 Next = Head->Flink; 02095 02096 while ( Next != Head ) { 02097 TlsEntry = CONTAINING_RECORD(Next, LDRP_TLS_ENTRY, Links); 02098 Next = Next->Flink; 02099 TlsVector[TlsEntry->Tls.Characteristics] = RtlAllocateHeap( 02100 RtlProcessHeap(), 02101 MAKE_TAG( TLS_TAG ), 02102 TlsEntry->Tls.EndAddressOfRawData - TlsEntry->Tls.StartAddressOfRawData 02103 ); 02104 if (!TlsVector[TlsEntry->Tls.Characteristics] ) { 02105 return STATUS_NO_MEMORY; 02106 } 02107 02108 if (ShowSnaps) { 02109 DbgPrint("LDR: TlsVector %x Index %d = %x copied from %x to %x\n", 02110 TlsVector, 02111 TlsEntry->Tls.Characteristics, 02112 &TlsVector[TlsEntry->Tls.Characteristics], 02113 TlsEntry->Tls.StartAddressOfRawData, 02114 TlsVector[TlsEntry->Tls.Characteristics] 02115 ); 02116 } 02117 02118 RtlCopyMemory( 02119 TlsVector[TlsEntry->Tls.Characteristics], 02120 (PVOID)TlsEntry->Tls.StartAddressOfRawData, 02121 TlsEntry->Tls.EndAddressOfRawData - TlsEntry->Tls.StartAddressOfRawData 02122 ); 02123 02124 // 02125 // Do the TLS Callouts 02126 // 02127 02128 } 02129 } 02130 return STATUS_SUCCESS; 02131 }

VOID LdrpCallTlsInitializers PVOID  DllBase,
ULONG  Reason
 

Definition at line 2178 of file ldrinit.c.

References DbgPrint, EXCEPTION_EXECUTE_HANDLER, LdrpCallInitRoutine, NULL, RtlImageDirectoryEntryToData(), ShowSnaps, and TRUE.

Referenced by LdrpInitializeThread(), LdrpRunInitializeRoutines(), LdrShutdownProcess(), and LdrShutdownThread().

02182 { 02183 PIMAGE_TLS_DIRECTORY TlsImage; 02184 ULONG TlsSize; 02185 PIMAGE_TLS_CALLBACK *CallBackArray; 02186 PIMAGE_TLS_CALLBACK InitRoutine; 02187 02188 TlsImage = (PIMAGE_TLS_DIRECTORY)RtlImageDirectoryEntryToData( 02189 DllBase, 02190 TRUE, 02191 IMAGE_DIRECTORY_ENTRY_TLS, 02192 &TlsSize 02193 ); 02194 02195 02196 try { 02197 if ( TlsImage ) { 02198 CallBackArray = (PIMAGE_TLS_CALLBACK *)TlsImage->AddressOfCallBacks; 02199 if ( CallBackArray ) { 02200 if (ShowSnaps) { 02201 DbgPrint( "LDR: Tls Callbacks Found. Imagebase %lx Tls %lx CallBacks %lx\n", 02202 DllBase, 02203 TlsImage, 02204 CallBackArray 02205 ); 02206 } 02207 02208 while(*CallBackArray){ 02209 InitRoutine = *CallBackArray++; 02210 02211 if (ShowSnaps) { 02212 DbgPrint( "LDR: Calling Tls Callback Imagebase %lx Function %lx\n", 02213 DllBase, 02214 InitRoutine 02215 ); 02216 } 02217 02218 #if defined (WX86) 02219 if (!Wx86ProcessInit || 02220 LdrpRunWx86DllEntryPoint( 02221 (PDLL_INIT_ROUTINE)InitRoutine, 02222 NULL, 02223 DllBase, 02224 Reason, 02225 NULL 02226 ) == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) 02227 #endif 02228 { 02229 LdrpCallInitRoutine((PDLL_INIT_ROUTINE)InitRoutine, 02230 DllBase, 02231 Reason, 02232 0); 02233 } 02234 02235 } 02236 } 02237 } 02238 } 02239 except (EXCEPTION_EXECUTE_HANDLER) { 02240 ; 02241 } 02242 }

HANDLE LdrpCheckForKnownDll IN PWSTR  DllName,
OUT PUNICODE_STRING  FullDllName,
OUT PUNICODE_STRING  BaseDllName
 

Definition at line 3283 of file ldrsnap.c.

References LDR_TAG, LdrpKnownDllObjectDirectory, LdrpKnownDllPath, MAKE_TAG, NT_SUCCESS, NtOpenSection(), NTSTATUS(), NULL, RtlAllocateHeap, RtlFreeHeap, RtlInitUnicodeString(), Status, Unicode, and USHORT.

Referenced by LdrpMapDll().

03291 : 03292 03293 This function checks to see if the specified DLL is a known DLL. 03294 It assumes it is only called for static DLL's, and when 03295 the know DLL directory structure has been set up. 03296 03297 Arguments: 03298 03299 DllName - Supplies the name of the DLL. 03300 03301 FullDllName - Returns the fully qualified pathname of the 03302 DLL. The Buffer field of this string is dynamically 03303 allocated from the processes heap. 03304 03305 BaseDLLName - Returns the base dll name of the dll. The base name 03306 is the file name portion of the dll path without the trailing 03307 extension. The Buffer field of this string is dynamically 03308 allocated from the processes heap. 03309 03310 Return Value: 03311 03312 NON-NULL - Returns an open handle to the section associated with 03313 the DLL. 03314 03315 NULL - The DLL is not known. 03316 03317 --*/ 03318 03319 { 03320 03321 UNICODE_STRING Unicode; 03322 HANDLE Section; 03323 NTSTATUS Status; 03324 OBJECT_ATTRIBUTES Obja; 03325 PSZ p; 03326 PWSTR pw; 03327 03328 Section = NULL; 03329 03330 // 03331 // calculate base name 03332 // 03333 03334 RtlInitUnicodeString(&Unicode,DllName); 03335 03336 03337 BaseDllName->Length = Unicode.Length; 03338 BaseDllName->MaximumLength = Unicode.MaximumLength; 03339 BaseDllName->Buffer = RtlAllocateHeap( 03340 RtlProcessHeap(),MAKE_TAG( LDR_TAG ), 03341 Unicode.MaximumLength 03342 ); 03343 if ( !BaseDllName->Buffer ) { 03344 return NULL; 03345 } 03346 03347 RtlMoveMemory(BaseDllName->Buffer,Unicode.Buffer,Unicode.MaximumLength); 03348 03349 // 03350 // now compute the full name for the dll 03351 // 03352 03353 FullDllName->Length = (USHORT)(LdrpKnownDllPath.Length + // path prefix 03354 (USHORT)sizeof(WCHAR) + // seperator 03355 BaseDllName->Length // base 03356 ); 03357 03358 FullDllName->MaximumLength = FullDllName->Length + (USHORT)sizeof(UNICODE_NULL); 03359 FullDllName->Buffer = RtlAllocateHeap( 03360 RtlProcessHeap(),MAKE_TAG( LDR_TAG ), 03361 FullDllName->MaximumLength 03362 ); 03363 if ( !FullDllName->Buffer ) { 03364 RtlFreeHeap(RtlProcessHeap(),0,BaseDllName->Buffer); 03365 return NULL; 03366 } 03367 03368 p = (PSZ)FullDllName->Buffer; 03369 RtlMoveMemory(p,LdrpKnownDllPath.Buffer,LdrpKnownDllPath.Length); 03370 p += LdrpKnownDllPath.Length; 03371 pw = (PWSTR)p; 03372 *pw++ = (WCHAR)'\\'; 03373 p = (PSZ)pw; 03374 03375 // 03376 // This is the relative name of the section 03377 // 03378 03379 Unicode.Buffer = (PWSTR)p; 03380 Unicode.Length = BaseDllName->Length; // base 03381 Unicode.MaximumLength = Unicode.Length + (USHORT)sizeof(UNICODE_NULL); 03382 03383 RtlMoveMemory(p,BaseDllName->Buffer,BaseDllName->MaximumLength); 03384 03385 // 03386 // open the section object 03387 // 03388 03389 InitializeObjectAttributes( 03390 &Obja, 03391 &Unicode, 03392 OBJ_CASE_INSENSITIVE, 03393 LdrpKnownDllObjectDirectory, 03394 NULL 03395 ); 03396 03397 Status = NtOpenSection( 03398 &Section, 03399 SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_MAP_WRITE, 03400 &Obja 03401 ); 03402 03403 if ( !NT_SUCCESS(Status) ) { 03404 Section = NULL; 03405 RtlFreeHeap(RtlProcessHeap(),0,BaseDllName->Buffer); 03406 RtlFreeHeap(RtlProcessHeap(),0,FullDllName->Buffer); 03407 } 03408 #if DBG 03409 else { 03410 LdrpSectionOpens++; 03411 } 03412 #endif // DBG 03413 return Section; 03414 }

BOOLEAN LdrpCheckForLoadedDll IN PWSTR DllPath  OPTIONAL,
IN PUNICODE_STRING  DllName,
IN BOOLEAN  StaticLink,
IN BOOLEAN  Wx86KnownDll,
OUT PLDR_DATA_TABLE_ENTRY *  LdrDataTableEntry
 

Definition at line 832 of file ldrsnap.c.

References CHAR, DbgPrint, EXCEPTION_EXECUTE_HANDLER, FALSE, File, L, LDRP_COMPUTE_HASH_INDEX, LdrpDefaultPath, LdrpHashTable, NT_SUCCESS, NtAreMappedFilesTheSame(), NtClose(), NtCreateSection(), NtMapViewOfSection(), NtOpenFile(), NTSTATUS(), NtUnmapViewOfSection(), NULL, ObjectAttributes, RtlCopyUnicodeString(), RtlDosPathNameToNtPathName_U(), RtlDosSearchPath_U(), RtlEqualUnicodeString(), RtlFreeHeap, RtlImageNtHeader(), ShowSnaps, TRUE, and USHORT.

Referenced by LdrGetDllHandle(), LdrpDphDetectSnapRoutines(), LdrpDphInitializeTargetDll(), LdrpLoadDll(), LdrpLoadImportModule(), and LdrpUpdateLoadCount().

00842 : 00843 00844 This function scans the loader data table looking to see if 00845 the specified DLL has already been mapped into the image. If 00846 the dll has been loaded, the address of its data table entry 00847 is returned. 00848 00849 Arguments: 00850 00851 DllPath - Supplies an optional search path used to locate the DLL. 00852 00853 DllName - Supplies the name to search for. 00854 00855 StaticLink - TRUE if performing a static link. 00856 00857 Wx86KnownDll - TRUE, treat Importer as x86 00858 00859 LdrDataTableEntry - Returns the address of the loader data table 00860 entry that describes the first dll section that implements the 00861 dll. 00862 00863 Return Value: 00864 00865 TRUE- The dll is already loaded. The address of the data table 00866 entries that implement the dll, and the number of data table 00867 entries are returned. 00868 00869 FALSE - The dll is not already mapped. 00870 00871 --*/ 00872 00873 { 00874 BOOLEAN Result; 00875 PLDR_DATA_TABLE_ENTRY Entry; 00876 PLIST_ENTRY Head, Next; 00877 UNICODE_STRING FullDllName; 00878 HANDLE DllFile; 00879 BOOLEAN HardCodedPath; 00880 PWCH p; 00881 WCHAR wch; 00882 ULONG i; 00883 CHAR FullDllNameBuffer[530+sizeof(UNICODE_NULL)]; 00884 ULONG Length = 0; 00885 PWCH src,dest; 00886 00887 00888 00889 if (!DllName->Buffer || !DllName->Buffer[0]) { 00890 return FALSE; 00891 } 00892 00893 #if defined (WX86) 00894 if (Wx86ProcessInit) { 00895 00896 FullDllName.Buffer = (PWCHAR)FullDllNameBuffer; 00897 FullDllName.MaximumLength = sizeof(FullDllNameBuffer); 00898 FullDllName.Length = 0; 00899 00900 Entry = LdrpWx86CheckForLoadedDll(DllPath, 00901 DllName, 00902 Wx86KnownDll, 00903 &FullDllName 00904 ); 00905 00906 if (Entry) { 00907 RtlCopyUnicodeString(DllName, &FullDllName); 00908 *LdrDataTableEntry = Entry; 00909 return TRUE; 00910 } 00911 else { 00912 return FALSE; 00913 } 00914 } 00915 00916 #endif 00917 00918 00919 00920 // 00921 // for static links, just go to the hash table 00922 // 00923 staticlink: 00924 if ( StaticLink ) { 00925 00926 i = LDRP_COMPUTE_HASH_INDEX(DllName->Buffer[0]); 00927 Head = &LdrpHashTable[i]; 00928 Next = Head->Flink; 00929 while ( Next != Head ) { 00930 Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, HashLinks); 00931 #if DBG 00932 LdrpCompareCount++; 00933 #endif 00934 if (RtlEqualUnicodeString(DllName, 00935 &Entry->BaseDllName, 00936 TRUE 00937 )) { 00938 00939 *LdrDataTableEntry = Entry; 00940 return TRUE; 00941 } 00942 Next = Next->Flink; 00943 } 00944 } 00945 00946 if ( StaticLink ) { 00947 return FALSE; 00948 } 00949 00950 00951 // 00952 // If the dll name contained a hard coded path 00953 // (dynamic link only), then the fully qualified 00954 // name needs to be compared to make sure we 00955 // have the correct dll. 00956 // 00957 00958 p = DllName->Buffer; 00959 HardCodedPath = FALSE; 00960 while (*p) { 00961 wch = *p++; 00962 if (wch == (WCHAR)'\\' || wch == (WCHAR)'/' ) { 00963 00964 HardCodedPath = TRUE; 00965 00966 // 00967 // We have a hard coded path, so we have to search path 00968 // for the DLL. We need the full DLL name so we can 00969 00970 FullDllName.Buffer = (WCHAR *)FullDllNameBuffer; 00971 00972 Length = RtlDosSearchPath_U( 00973 ARGUMENT_PRESENT(DllPath) ? DllPath : LdrpDefaultPath.Buffer, 00974 DllName->Buffer, 00975 NULL, 00976 sizeof(FullDllNameBuffer)-sizeof(UNICODE_NULL), 00977 FullDllName.Buffer, 00978 NULL 00979 ); 00980 if ( !Length || Length > sizeof(FullDllNameBuffer)-sizeof(UNICODE_NULL) ) { 00981 00982 if (ShowSnaps) { 00983 DbgPrint("LDR: LdrpCheckForLoadedDll - Unable To Locate "); 00984 DbgPrint("%ws from %ws\n", 00985 DllName->Buffer, 00986 ARGUMENT_PRESENT(DllPath) ? DllPath : LdrpDefaultPath.Buffer 00987 ); 00988 } 00989 00990 return FALSE; 00991 } 00992 00993 FullDllName.Length = (USHORT)Length; 00994 FullDllName.MaximumLength = FullDllName.Length + (USHORT)sizeof(UNICODE_NULL); 00995 break; 00996 } 00997 } 00998 00999 // 01000 // if this is a dynamic load lib, and there is not a hard 01001 // coded path, then go to the static lib hash table for resolution 01002 // 01003 01004 if ( !HardCodedPath ) { 01005 01006 StaticLink = TRUE; 01007 01008 goto staticlink; 01009 } 01010 01011 01012 Result = FALSE; 01013 Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; 01014 Next = Head->Flink; 01015 01016 while ( Next != Head ) { 01017 Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 01018 Next = Next->Flink; 01019 01020 // 01021 // when we unload, the memory order links flink field is nulled. 01022 // this is used to skip the entry pending list removal. 01023 // 01024 01025 if ( !Entry->InMemoryOrderLinks.Flink ) { 01026 continue; 01027 } 01028 01029 01030 if (RtlEqualUnicodeString( 01031 &FullDllName, 01032 &Entry->FullDllName, 01033 TRUE 01034 ) ) { 01035 01036 Result = TRUE; 01037 *LdrDataTableEntry = Entry; 01038 break; 01039 } 01040 } 01041 01042 if ( !Result ) { 01043 01044 // 01045 // no names matched. This might be a long short name mismatch or 01046 // any kind of alias pathname. Deal with this by opening and mapping 01047 // full dll name and then repeat the scan this time checking for 01048 // timedatestamp matches 01049 // 01050 01051 HANDLE File; 01052 HANDLE Section; 01053 NTSTATUS st; 01054 OBJECT_ATTRIBUTES ObjectAttributes; 01055 IO_STATUS_BLOCK IoStatus; 01056 PVOID ViewBase; 01057 SIZE_T ViewSize; 01058 PIMAGE_NT_HEADERS NtHeadersSrc,NtHeadersE; 01059 UNICODE_STRING NtFileName; 01060 01061 01062 if (!RtlDosPathNameToNtPathName_U( FullDllName.Buffer, 01063 &NtFileName, 01064 NULL, 01065 NULL 01066 ) 01067 ) { 01068 goto alldone; 01069 } 01070 01071 InitializeObjectAttributes( 01072 &ObjectAttributes, 01073 &NtFileName, 01074 OBJ_CASE_INSENSITIVE, 01075 NULL, 01076 NULL 01077 ); 01078 01079 st = NtOpenFile( 01080 &File, 01081 SYNCHRONIZE | FILE_EXECUTE, 01082 &ObjectAttributes, 01083 &IoStatus, 01084 FILE_SHARE_READ | FILE_SHARE_DELETE, 01085 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT 01086 ); 01087 RtlFreeHeap(RtlProcessHeap(), 0, NtFileName.Buffer); 01088 01089 if (!NT_SUCCESS(st)) { 01090 goto alldone; 01091 } 01092 01093 st = NtCreateSection( 01094 &Section, 01095 SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_MAP_WRITE, 01096 NULL, 01097 NULL, 01098 PAGE_EXECUTE, 01099 SEC_COMMIT, 01100 File 01101 ); 01102 NtClose( File ); 01103 01104 if (!NT_SUCCESS(st)) { 01105 goto alldone; 01106 } 01107 01108 ViewBase = NULL; 01109 ViewSize = 0; 01110 st = NtMapViewOfSection( 01111 Section, 01112 NtCurrentProcess(), 01113 (PVOID *)&ViewBase, 01114 0L, 01115 0L, 01116 NULL, 01117 &ViewSize, 01118 ViewShare, 01119 0L, 01120 PAGE_EXECUTE 01121 ); 01122 NtClose(Section); 01123 if (!NT_SUCCESS(st)) { 01124 goto alldone; 01125 } 01126 01127 // 01128 // The section is mapped. Now find the headers 01129 // 01130 NtHeadersSrc = RtlImageNtHeader(ViewBase); 01131 if ( !NtHeadersSrc ) { 01132 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01133 goto alldone; 01134 } 01135 Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; 01136 Next = Head->Flink; 01137 01138 while ( Next != Head ) { 01139 Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 01140 Next = Next->Flink; 01141 01142 // 01143 // when we unload, the memory order links flink field is nulled. 01144 // this is used to skip the entry pending list removal. 01145 // 01146 01147 if ( !Entry->InMemoryOrderLinks.Flink ) { 01148 continue; 01149 } 01150 01151 try { 01152 if ( Entry->TimeDateStamp == NtHeadersSrc->FileHeader.TimeDateStamp && 01153 Entry->SizeOfImage == NtHeadersSrc->OptionalHeader.SizeOfImage ) { 01154 01155 // 01156 // there is a very good chance we have an image match. Check the 01157 // entire file header and optional header. If they match, declare 01158 // this a match 01159 // 01160 01161 NtHeadersE = RtlImageNtHeader(Entry->DllBase); 01162 01163 if ( RtlCompareMemory(NtHeadersE,NtHeadersSrc,sizeof(*NtHeadersE)) ) { 01164 01165 // 01166 // Now that it looks like we have a match, compare 01167 // volume serial number's and file index's 01168 // 01169 01170 st = NtAreMappedFilesTheSame(Entry->DllBase,ViewBase); 01171 01172 if ( !NT_SUCCESS(st) ) { 01173 continue; 01174 } 01175 else { 01176 Result = TRUE; 01177 *LdrDataTableEntry = Entry; 01178 break; 01179 } 01180 } 01181 } 01182 } 01183 except (EXCEPTION_EXECUTE_HANDLER) { 01184 break; 01185 } 01186 } 01187 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01188 } 01189 01190 alldone: 01191 return Result; 01192 }

BOOLEAN LdrpCheckForLoadedDllHandle IN PVOID  DllHandle,
OUT PLDR_DATA_TABLE_ENTRY *  LdrDataTableEntry
 

Definition at line 1196 of file ldrsnap.c.

References FALSE, LdrpLoadedDllHandleCache, and TRUE.

Referenced by LdrDisableThreadCalloutsForDll(), LdrpGetProcedureAddress(), and LdrUnloadDll().

01203 : 01204 01205 This function scans the loader data table looking to see if 01206 the specified DLL has already been mapped into the image address 01207 space. If the dll has been loaded, the address of its data table 01208 entry that describes the dll is returned. 01209 01210 Arguments: 01211 01212 DllHandle - Supplies the DllHandle of the DLL being searched for. 01213 01214 LdrDataTableEntry - Returns the address of the loader data table 01215 entry that describes the dll. 01216 01217 Return Value: 01218 01219 TRUE- The dll is loaded. The address of the data table entry is 01220 returned. 01221 01222 FALSE - The dll is not loaded. 01223 01224 --*/ 01225 01226 { 01227 PLDR_DATA_TABLE_ENTRY Entry; 01228 PLIST_ENTRY Head,Next; 01229 01230 if ( LdrpLoadedDllHandleCache && 01231 (PVOID) LdrpLoadedDllHandleCache->DllBase == DllHandle ) { 01232 *LdrDataTableEntry = LdrpLoadedDllHandleCache; 01233 return TRUE; 01234 } 01235 01236 Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; 01237 Next = Head->Flink; 01238 01239 while ( Next != Head ) { 01240 Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 01241 Next = Next->Flink; 01242 // 01243 // when we unload, the memory order links flink field is nulled. 01244 // this is used to skip the entry pending list removal. 01245 // 01246 01247 if ( !Entry->InMemoryOrderLinks.Flink ) { 01248 continue; 01249 } 01250 01251 if (DllHandle == (PVOID)Entry->DllBase ){ 01252 LdrpLoadedDllHandleCache = Entry; 01253 *LdrDataTableEntry = Entry; 01254 return TRUE; 01255 } 01256 } 01257 return FALSE; 01258 }

NTSTATUS LdrpCreateDllSection IN PUNICODE_STRING  FullDllName,
IN HANDLE  DllFile,
IN PUNICODE_STRING  BaseName,
IN PULONG DllCharacteristics  OPTIONAL,
OUT PHANDLE  SectionHandle
 

Definition at line 2150 of file ldrsnap.c.

References DbgPrint, File, LdrpFatalHardErrorCount, LdrpInLdrInit, NT_SUCCESS, NtClose(), NtCreateSection(), NtOpenFile(), NtRaiseHardError(), NTSTATUS(), NULL, and ObjectAttributes.

Referenced by LdrpMapDll().

02157 { 02158 HANDLE File; 02159 HANDLE Section; 02160 NTSTATUS st; 02161 OBJECT_ATTRIBUTES ObjectAttributes; 02162 IO_STATUS_BLOCK IoStatus; 02163 02164 if ( !DllFile ) { 02165 // 02166 // Since ntsdk does not search paths well, we can't use 02167 // relative object names 02168 // 02169 02170 InitializeObjectAttributes( 02171 &ObjectAttributes, 02172 NtFullDllName, 02173 OBJ_CASE_INSENSITIVE, 02174 NULL, 02175 NULL 02176 ); 02177 02178 st = NtOpenFile( 02179 &File, 02180 SYNCHRONIZE | FILE_EXECUTE, 02181 &ObjectAttributes, 02182 &IoStatus, 02183 FILE_SHARE_READ | FILE_SHARE_DELETE, 02184 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT 02185 ); 02186 if (!NT_SUCCESS(st)) { 02187 02188 #if DBG 02189 DbgPrint("LDR: LdrCreateDllSection - NtOpenFile( %wZ ) failed. Status == %X\n", 02190 NtFullDllName, 02191 st 02192 ); 02193 #endif 02194 *SectionHandle = NULL; 02195 return st; 02196 } 02197 02198 02199 } else { 02200 File = DllFile; 02201 } 02202 02203 02204 st = NtCreateSection( 02205 SectionHandle, 02206 SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_MAP_WRITE | SECTION_QUERY, 02207 NULL, 02208 NULL, 02209 PAGE_EXECUTE, 02210 SEC_IMAGE, 02211 File 02212 ); 02213 NtClose( File ); 02214 02215 if (!NT_SUCCESS(st)) { 02216 02217 // 02218 // hard error time 02219 // 02220 02221 ULONG_PTR ErrorParameters[1]; 02222 ULONG ErrorResponse; 02223 02224 *SectionHandle = NULL; 02225 ErrorParameters[0] = (ULONG_PTR)NtFullDllName; 02226 02227 NtRaiseHardError( 02228 STATUS_INVALID_IMAGE_FORMAT, 02229 1, 02230 1, 02231 ErrorParameters, 02232 OptionOk, 02233 &ErrorResponse 02234 ); 02235 02236 if ( LdrpInLdrInit ) { 02237 LdrpFatalHardErrorCount++; 02238 } 02239 02240 02241 #if DBG 02242 if (st != STATUS_INVALID_IMAGE_NE_FORMAT && 02243 st != STATUS_INVALID_IMAGE_LE_FORMAT && 02244 st != STATUS_INVALID_IMAGE_WIN_16 02245 ) { 02246 DbgPrint("LDR: LdrCreateDllSection - NtCreateSection %wZ failed. Status == %X\n", 02247 NtFullDllName, 02248 st 02249 ); 02250 } 02251 #endif 02252 } 02253 02254 return st; 02255 }

PVOID LdrpDefineDllTag PWSTR  TagName,
PUSHORT  TagIndex
 

Definition at line 191 of file heaptag.c.

References LDRP_MAXIMUM_DLL_TAGS, LdrpDllTagProcedures, LdrpDllTags, LdrpDllTagsInitialized, LdrpNumberOfDllTags, NULL, RtlAllocateHeap, RtlCreateTagHeap(), RtlpGlobalTagHeap, TRUE, USHORT, and _HEAP::VirtualAllocdBlocks.

Referenced by LdrpWalkImportDescriptor().

00195 { 00196 PVOID Result; 00197 WCHAR TagNameBuffer[ 260 ]; 00198 00199 if (RtlpGlobalTagHeap == NULL) { 00200 RtlpGlobalTagHeap = RtlAllocateHeap( RtlProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( HEAP )); 00201 if (RtlpGlobalTagHeap == NULL) { 00202 return NULL; 00203 } 00204 } 00205 00206 if (!LdrpDllTagsInitialized) { 00207 // 00208 // Keep QUERY.C happy 00209 // 00210 InitializeListHead( &RtlpGlobalTagHeap->VirtualAllocdBlocks ); 00211 LdrpDllTagsInitialized = TRUE; 00212 } 00213 00214 Result = NULL; 00215 if (LdrpNumberOfDllTags < LDRP_MAXIMUM_DLL_TAGS) { 00216 memset( TagNameBuffer, 0, sizeof( TagNameBuffer ) ); 00217 wcscpy( TagNameBuffer, TagName ); 00218 LdrpDllTags[ LdrpNumberOfDllTags ] = 00219 RtlCreateTagHeap( NULL, 00220 0, 00221 NULL, 00222 TagNameBuffer 00223 ); 00224 00225 if (LdrpDllTags[ LdrpNumberOfDllTags ] != 0) { 00226 Result = LdrpDllTagProcedures[ LdrpNumberOfDllTags ]; 00227 } 00228 00229 if (Result != NULL) { 00230 *TagIndex = (USHORT)(LdrpDllTags[ LdrpNumberOfDllTags ] >> HEAP_TAG_SHIFT); 00231 LdrpNumberOfDllTags += 1; 00232 } 00233 } 00234 00235 return Result; 00236 }

PVOID LdrpFetchAddressOfEntryPoint IN PVOID  Base  ) 
 

Definition at line 3249 of file ldrsnap.c.

References RtlImageNtHeader().

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

03255 : 03256 03257 This function returns the address of the initialization routine. 03258 03259 Arguments: 03260 03261 Base - Base of image. 03262 03263 Return Value: 03264 03265 Status value 03266 03267 --*/ 03268 03269 { 03270 PIMAGE_NT_HEADERS NtHeaders; 03271 ULONG_PTR ep; 03272 03273 NtHeaders = RtlImageNtHeader(Base); 03274 ep = NtHeaders->OptionalHeader.AddressOfEntryPoint; 03275 if (ep) { 03276 ep += (ULONG_PTR)Base; 03277 } 03278 03279 return (PVOID)ep; 03280 }

VOID LdrpFreeTls VOID   ) 
 

Definition at line 2134 of file ldrinit.c.

References LdrpTlsList, RtlFreeHeap, and _LDRP_TLS_ENTRY::Tls.

Referenced by LdrShutdownThread().

02137 { 02138 PTEB Teb; 02139 PLIST_ENTRY Head, Next; 02140 PLDRP_TLS_ENTRY TlsEntry; 02141 PVOID *TlsVector; 02142 02143 Teb = NtCurrentTeb(); 02144 02145 TlsVector = Teb->ThreadLocalStoragePointer; 02146 02147 if ( TlsVector ) { 02148 Head = &LdrpTlsList; 02149 Next = Head->Flink; 02150 02151 while ( Next != Head ) { 02152 TlsEntry = CONTAINING_RECORD(Next, LDRP_TLS_ENTRY, Links); 02153 Next = Next->Flink; 02154 02155 // 02156 // Do the TLS callouts 02157 // 02158 02159 if ( TlsVector[TlsEntry->Tls.Characteristics] ) { 02160 RtlFreeHeap( 02161 RtlProcessHeap(), 02162 0, 02163 TlsVector[TlsEntry->Tls.Characteristics] 02164 ); 02165 02166 } 02167 } 02168 02169 RtlFreeHeap( 02170 RtlProcessHeap(), 02171 0, 02172 TlsVector 02173 ); 02174 } 02175 }

NTSTATUS NTAPI LdrpGetProcedureAddress IN PVOID  DllHandle,
IN PANSI_STRING ProcedureName  OPTIONAL,
IN ULONG ProcedureNumber  OPTIONAL,
OUT PVOID *  ProcedureAddress,
IN BOOLEAN  RunInitRoutines
 

Definition at line 851 of file ldrapi.c.

References DbgPrint, EXCEPTION_EXECUTE_HANDLER, FALSE, LdrpCheckForLoadedDllHandle(), LdrpInLdrInit, LdrpRunInitializeRoutines(), LdrpSnapThunk(), LoaderLock, MAKE_TAG, NT_SUCCESS, NTSTATUS(), NULL, RtlAllocateHeap, RtlFreeHeap, RtlImageDirectoryEntryToData(), RtlImageNtHeader(), ShowSnaps, TEMP_TAG, TRUE, and USHORT.

Referenced by LdrGetProcedureAddress(), and LdrpSnapThunk().

00861 : 00862 00863 This function locates the address of the specified procedure in the 00864 specified DLL and returns its address. 00865 00866 Arguments: 00867 00868 DllHandle - Supplies a handle to the DLL that the address is being 00869 looked up in. 00870 00871 ProcedureName - Supplies that address of a string that contains the 00872 name of the procedure to lookup in the DLL. If this argument is 00873 not specified, then the ProcedureNumber is used. 00874 00875 ProcedureNumber - Supplies the procedure number to lookup. If 00876 ProcedureName is specified, then this argument is ignored. 00877 Otherwise, it specifies the procedure ordinal number to locate 00878 in the DLL. 00879 00880 ProcedureAddress - Returns the address of the procedure found in 00881 the DLL. 00882 00883 Return Value: 00884 00885 TBD 00886 00887 --*/ 00888 00889 { 00890 NTSTATUS st; 00891 UCHAR FunctionNameBuffer[64]; 00892 PUCHAR src, dst; 00893 ULONG cb, ExportSize; 00894 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; 00895 IMAGE_THUNK_DATA Thunk; 00896 PVOID ImageBase; 00897 PIMAGE_IMPORT_BY_NAME FunctionName; 00898 PIMAGE_EXPORT_DIRECTORY ExportDirectory; 00899 PLIST_ENTRY Next; 00900 #if defined (WX86) 00901 PTEB Teb; 00902 BOOLEAN Wx86KnownDll = FALSE; 00903 #endif 00904 00905 if (ShowSnaps) { 00906 DbgPrint("LDR: LdrGetProcedureAddress by "); 00907 } 00908 00909 #if defined (WX86) 00910 Teb = NtCurrentTeb(); 00911 if (Teb->Wx86Thread.UseKnownWx86Dll) { 00912 Wx86KnownDll = Teb->Wx86Thread.UseKnownWx86Dll; 00913 Teb->Wx86Thread.UseKnownWx86Dll = FALSE; 00914 } 00915 #endif 00916 00917 FunctionName = NULL; 00918 if ( ARGUMENT_PRESENT(ProcedureName) ) { 00919 00920 if (ShowSnaps) { 00921 DbgPrint("NAME - %s\n", ProcedureName->Buffer); 00922 } 00923 00924 // 00925 // BUGBUG need STRING to PSZ 00926 // 00927 00928 00929 if (ProcedureName->Length >= sizeof( FunctionNameBuffer )-1 ) { 00930 FunctionName = RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( TEMP_TAG ),ProcedureName->Length+1+sizeof(USHORT)); 00931 if ( !FunctionName ) { 00932 return STATUS_INVALID_PARAMETER; 00933 } 00934 } else { 00935 FunctionName = (PIMAGE_IMPORT_BY_NAME) FunctionNameBuffer; 00936 } 00937 00938 FunctionName->Hint = 0; 00939 00940 cb = ProcedureName->Length; 00941 src = ProcedureName->Buffer; 00942 dst = FunctionName->Name; 00943 00944 while (cb--) { 00945 *dst++ = *src++; 00946 } 00947 *dst = '\0'; 00948 00949 // 00950 // Make sure we don't pass in address with high bit set so we 00951 // can still use it as ordinal flag 00952 // 00953 00954 ImageBase = FunctionName; 00955 Thunk.u1.AddressOfData = 0; 00956 00957 } else { 00958 ImageBase = NULL; 00959 if (ShowSnaps) { 00960 DbgPrint("ORDINAL - %lx\n", ProcedureNumber); 00961 } 00962 00963 if (ProcedureNumber) { 00964 Thunk.u1.Ordinal = ProcedureNumber | IMAGE_ORDINAL_FLAG; 00965 } else { 00966 return STATUS_INVALID_PARAMETER; 00967 } 00968 } 00969 00970 if ( LdrpInLdrInit == FALSE ) { 00971 RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00972 } 00973 try { 00974 00975 if (!LdrpCheckForLoadedDllHandle(DllHandle, &LdrDataTableEntry)) { 00976 st = STATUS_DLL_NOT_FOUND; 00977 return st; 00978 } 00979 00980 ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData( 00981 LdrDataTableEntry->DllBase, 00982 TRUE, 00983 IMAGE_DIRECTORY_ENTRY_EXPORT, 00984 &ExportSize 00985 ); 00986 00987 if (!ExportDirectory) { 00988 return STATUS_PROCEDURE_NOT_FOUND; 00989 } 00990 00991 st = LdrpSnapThunk(LdrDataTableEntry->DllBase, 00992 ImageBase, 00993 &Thunk, 00994 &Thunk, 00995 ExportDirectory, 00996 ExportSize, 00997 FALSE, 00998 NULL 00999 ); 01000 01001 if ( RunInitRoutines ) { 01002 PLDR_DATA_TABLE_ENTRY LdrInitEntry; 01003 01004 // 01005 // Look at last entry in init order list. If entry processed 01006 // flag is not set, then a forwarded dll was loaded during the 01007 // getprocaddr call and we need to run init routines 01008 // 01009 01010 Next = NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Blink; 01011 LdrInitEntry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks); 01012 if ( !(LdrInitEntry->Flags & LDRP_ENTRY_PROCESSED) ) { 01013 try { 01014 st = LdrpRunInitializeRoutines(NULL); 01015 } 01016 except( EXCEPTION_EXECUTE_HANDLER ) { 01017 st = GetExceptionCode(); 01018 } 01019 01020 } 01021 } 01022 01023 if ( NT_SUCCESS(st) ) { 01024 *ProcedureAddress = (PVOID)Thunk.u1.Function; 01025 #if defined (WX86) 01026 // For dlls loaded as a Wx86 plugin ... 01027 01028 if (Wx86ProcessInit && (LdrDataTableEntry->Flags & LDRP_WX86_PLUGIN)) { 01029 PVOID ExportThunk = NULL; 01030 USHORT MachineType = RtlImageNtHeader(LdrDataTableEntry->DllBase)->FileHeader.Machine; 01031 01032 // and the GetProcAddress call is cross-architecture ... 01033 01034 if ((!Wx86KnownDll && (MachineType == IMAGE_FILE_MACHINE_I386)) 01035 || (Wx86KnownDll && (MachineType != IMAGE_FILE_MACHINE_I386))) { 01036 01037 // Thunk the export 01038 01039 st = Wx86ThunkPluginExport(LdrDataTableEntry->DllBase, 01040 FunctionName? FunctionName->Name : NULL, 01041 ProcedureNumber, 01042 (PVOID)(Thunk.u1.Function), 01043 &ExportThunk 01044 ); 01045 if (NT_SUCCESS(st) && ExportThunk) { 01046 *ProcedureAddress = ExportThunk; 01047 } else { 01048 // Don't let unthunked cross-architecture addresses get out 01049 *ProcedureAddress = NULL; 01050 st = STATUS_INVALID_IMAGE_FORMAT; 01051 } 01052 } 01053 } 01054 #endif 01055 } 01056 } finally { 01057 if ( FunctionName && (FunctionName != (PIMAGE_IMPORT_BY_NAME) FunctionNameBuffer) ) { 01058 RtlFreeHeap(RtlProcessHeap(),0,FunctionName); 01059 } 01060 if ( LdrpInLdrInit == FALSE ) { 01061 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 01062 } 01063 } 01064 return st; 01065 }

VOID LdrpInitialize IN PCONTEXT  Context,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2
 

Definition at line 186 of file ldrinit.c.

References DbgPrint, EXCEPTION_EXECUTE_HANDLER, FALSE, L, LdrpForkProcess(), LdrpInitializationFailure(), LdrpInitializeProcess(), LdrpInitializeThread(), LdrpInLdrInit, LdrQueryImageFileExecutionOptions(), LoaderLock, LoaderLockInitialized, NT_SUCCESS, NtDelayExecution(), NtQueryPerformanceCounter(), NtQueryVirtualMemory(), NTSTATUS(), NtTestAlert(), NULL, RtlImageDirectoryEntryToData(), RtlImageNtHeader(), RtlpDebugPageHeap, RtlpDisableHeapLookaside, RtlpDphDllRangeEnd, RtlpDphDllRangeStart, RtlpDphGlobalFlags, RtlpDphRandomProbability, RtlpDphSizeRangeEnd, RtlpDphSizeRangeStart, RtlpDphTargetDlls, RtlRaiseStatus(), and TRUE.

00194 : 00195 00196 This function is called as a User-Mode APC routine as the first 00197 user-mode code executed by a new thread. It's function is to initialize 00198 loader context, perform module initialization callouts... 00199 00200 Arguments: 00201 00202 Context - Supplies an optional context buffer that will be restore 00203 after all DLL initialization has been completed. If this 00204 parameter is NULL then this is a dynamic snap of this module. 00205 Otherwise this is a static snap prior to the user process 00206 gaining control. 00207 00208 SystemArgument1 - Supplies the base address of the System Dll. 00209 00210 SystemArgument2 - not used. 00211 00212 Return Value: 00213 00214 None. 00215 00216 --*/ 00217 00218 { 00219 NTSTATUS st, InitStatus; 00220 PPEB Peb; 00221 PTEB Teb; 00222 UNICODE_STRING UnicodeImageName; 00223 MEMORY_BASIC_INFORMATION MemInfo; 00224 BOOLEAN AlreadyFailed; 00225 LARGE_INTEGER DelayValue; 00226 #if defined(_WIN64) 00227 PIMAGE_NT_HEADERS NtHeader; 00228 #endif 00229 00230 SystemArgument2; 00231 00232 AlreadyFailed = FALSE; 00233 Peb = NtCurrentPeb(); 00234 Teb = NtCurrentTeb(); 00235 00236 if (!Peb->Ldr) { 00237 #if defined(_ALPHA_) 00238 ULONG temp; 00239 00240 // 00241 // Set GP register 00242 // 00243 00244 LdrpGpValue = (ULONG_PTR)RtlImageDirectoryEntryToData( 00245 Peb->ImageBaseAddress, 00246 TRUE, 00247 IMAGE_DIRECTORY_ENTRY_GLOBALPTR, 00248 &temp 00249 ); 00250 if (Context != NULL) { 00251 LdrpSetGp( LdrpGpValue ); 00252 Context->IntGp = LdrpGpValue; 00253 } 00254 #endif // ALPHA 00255 00256 //#if DBG 00257 if (TRUE) 00258 //#else 00259 // if (Peb->BeingDebugged || Peb->ReadImageFileExecOptions) 00260 //#endif 00261 { 00262 PWSTR pw; 00263 00264 pw = (PWSTR)Peb->ProcessParameters->ImagePathName.Buffer; 00265 if (!(Peb->ProcessParameters->Flags & RTL_USER_PROC_PARAMS_NORMALIZED)) { 00266 pw = (PWSTR)((PCHAR)pw + (ULONG_PTR)(Peb->ProcessParameters)); 00267 } 00268 UnicodeImageName.Buffer = pw; 00269 UnicodeImageName.Length = Peb->ProcessParameters->ImagePathName.Length; 00270 UnicodeImageName.MaximumLength = UnicodeImageName.Length; 00271 00272 // 00273 // Hack for NT4 SP4. So we don't overload another GlobalFlag 00274 // bit that we have to be "compatible" with for NT5, look for 00275 // another value named "DisableHeapLookaside". 00276 // 00277 00278 LdrQueryImageFileExecutionOptions( &UnicodeImageName, 00279 L"DisableHeapLookaside", 00280 REG_DWORD, 00281 &RtlpDisableHeapLookaside, 00282 sizeof( RtlpDisableHeapLookaside ), 00283 NULL 00284 ); 00285 00286 st = LdrQueryImageFileExecutionOptions( &UnicodeImageName, 00287 L"GlobalFlag", 00288 REG_DWORD, 00289 &Peb->NtGlobalFlag, 00290 sizeof( Peb->NtGlobalFlag ), 00291 NULL 00292 ); 00293 if (!NT_SUCCESS( st )) { 00294 00295 if (Peb->BeingDebugged) { 00296 Peb->NtGlobalFlag |= FLG_HEAP_ENABLE_FREE_CHECK | 00297 FLG_HEAP_ENABLE_TAIL_CHECK | 00298 FLG_HEAP_VALIDATE_PARAMETERS; 00299 } 00300 } 00301 00302 #if defined(_WIN64) 00303 NtHeader = RtlImageNtHeader(Peb->ImageBaseAddress); 00304 if (NtHeader && NtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { 00305 UseWOW64 = TRUE; 00306 } 00307 #endif 00308 } 00309 00310 if ( Peb->NtGlobalFlag & FLG_HEAP_PAGE_ALLOCS ) { 00311 00312 // 00313 // We will enable page heap (RtlpDebugPageHeap) only after 00314 // all other initializations for page heap are finished. 00315 // 00316 00317 // 00318 // If page heap is enabled we need to disable any flag that 00319 // might force creation of debug heaps for normal NT heaps. 00320 // This is due to a dependency between page heap and NT heap 00321 // where the page heap within PageHeapCreate tries to create 00322 // a normal NT heap to accomodate some of the allocations. 00323 // If we do not disable these flags we will get an infinite 00324 // recursion between RtlpDebugPageHeapCreate and RtlCreateHeap. 00325 // 00326 00327 Peb->NtGlobalFlag &= ~( FLG_HEAP_ENABLE_TAGGING | 00328 FLG_HEAP_ENABLE_TAG_BY_DLL | 00329 FLG_HEAP_ENABLE_TAIL_CHECK | 00330 FLG_HEAP_ENABLE_FREE_CHECK | 00331 FLG_HEAP_VALIDATE_PARAMETERS | 00332 FLG_HEAP_VALIDATE_ALL | 00333 FLG_USER_STACK_TRACE_DB ); 00334 00335 // 00336 // Read page heap per process global flags. If we fail 00337 // to read a value, the default ones are kept. 00338 // 00339 00340 LdrQueryImageFileExecutionOptions( 00341 &UnicodeImageName, 00342 L"PageHeapFlags", 00343 REG_DWORD, 00344 &RtlpDphGlobalFlags, 00345 sizeof(RtlpDphGlobalFlags), 00346 NULL 00347 ); 00348 00349 // 00350 // Read several page heap parameters. 00351 // 00352 00353 LdrQueryImageFileExecutionOptions( 00354 &UnicodeImageName, 00355 L"PageHeapSizeRangeStart", 00356 REG_DWORD, 00357 &RtlpDphSizeRangeStart, 00358 sizeof(RtlpDphSizeRangeStart), 00359 NULL 00360 ); 00361 00362 LdrQueryImageFileExecutionOptions( 00363 &UnicodeImageName, 00364 L"PageHeapSizeRangeEnd", 00365 REG_DWORD, 00366 &RtlpDphSizeRangeEnd, 00367 sizeof(RtlpDphSizeRangeEnd), 00368 NULL 00369 ); 00370 00371 LdrQueryImageFileExecutionOptions( 00372 &UnicodeImageName, 00373 L"PageHeapRandomProbability", 00374 REG_DWORD, 00375 &RtlpDphRandomProbability, 00376 sizeof(RtlpDphRandomProbability), 00377 NULL 00378 ); 00379 00380 // 00381 // The two values below should be read as PVOIDs so that 00382 // this works on 64-bit architetures. However since this 00383 // feature relies on good stack traces and since we can get 00384 // reliable stack traces only on X86 architectures we will 00385 // leave it as it is. 00386 // 00387 00388 LdrQueryImageFileExecutionOptions( 00389 &UnicodeImageName, 00390 L"PageHeapDllRangeStart", 00391 REG_DWORD, 00392 &RtlpDphDllRangeStart, 00393 sizeof(RtlpDphDllRangeStart), 00394 NULL 00395 ); 00396 00397 LdrQueryImageFileExecutionOptions( 00398 &UnicodeImageName, 00399 L"PageHeapDllRangeEnd", 00400 REG_DWORD, 00401 &RtlpDphDllRangeEnd, 00402 sizeof(RtlpDphDllRangeEnd), 00403 NULL 00404 ); 00405 00406 LdrQueryImageFileExecutionOptions( 00407 &UnicodeImageName, 00408 L"PageHeapTargetDlls", 00409 REG_SZ, 00410 &RtlpDphTargetDlls, 00411 512, 00412 NULL 00413 ); 00414 00415 // 00416 // Turn on BOOLEAN RtlpDebugPageHeap to indicate that 00417 // new heaps should be created with debug page heap manager 00418 // when possible. 00419 // 00420 00421 RtlpDebugPageHeap = TRUE; 00422 } 00423 } 00424 #if defined(_ALPHA_) 00425 else 00426 if (Context != NULL) { 00427 LdrpSetGp( LdrpGpValue ); 00428 Context->IntGp = LdrpGpValue; 00429 } 00430 #endif // ALPHA 00431 00432 // 00433 // Serialize for here on out 00434 // 00435 00436 Peb->LoaderLock = (PVOID)&LoaderLock; 00437 00438 if ( !RtlTryEnterCriticalSection(&LoaderLock) ) { 00439 if ( LoaderLockInitialized ) { 00440 RtlEnterCriticalSection(&LoaderLock); 00441 } 00442 else { 00443 00444 // 00445 // drop into a 30ms delay loop 00446 // 00447 00448 DelayValue.QuadPart = Int32x32To64( 30, -10000 ); 00449 while ( !LoaderLockInitialized ) { 00450 NtDelayExecution(FALSE,&DelayValue); 00451 } 00452 RtlEnterCriticalSection(&LoaderLock); 00453 } 00454 } 00455 00456 if (Teb->DeallocationStack == NULL) { 00457 st = NtQueryVirtualMemory( 00458 NtCurrentProcess(), 00459 Teb->NtTib.StackLimit, 00460 MemoryBasicInformation, 00461 (PVOID)&MemInfo, 00462 sizeof(MemInfo), 00463 NULL 00464 ); 00465 if ( !NT_SUCCESS(st) ) { 00466 LdrpInitializationFailure(st); 00467 RtlRaiseStatus(st); 00468 return; 00469 } 00470 else { 00471 Teb->DeallocationStack = MemInfo.AllocationBase; 00472 #if defined(_IA64_) 00473 Teb->DeallocationBStore = (PVOID)((ULONG_PTR)MemInfo.AllocationBase + MemInfo.RegionSize); 00474 #endif // defined(_IA64_) 00475 } 00476 } 00477 00478 InitStatus = STATUS_SUCCESS; 00479 try { 00480 if (!Peb->Ldr) { 00481 LdrpInLdrInit = TRUE; 00482 #if DBG 00483 // 00484 // Time the load. 00485 // 00486 00487 if (LdrpDisplayLoadTime) { 00488 NtQueryPerformanceCounter(&BeginTime, NULL); 00489 } 00490 #endif // DBG 00491 00492 try { 00493 InitStatus = LdrpInitializeProcess( Context, 00494 SystemArgument1, 00495 &UnicodeImageName 00496 ); 00497 } 00498 except ( EXCEPTION_EXECUTE_HANDLER ) { 00499 InitStatus = GetExceptionCode(); 00500 AlreadyFailed = TRUE; 00501 LdrpInitializationFailure(GetExceptionCode()); 00502 } 00503 00504 #if DBG 00505 if (LdrpDisplayLoadTime) { 00506 NtQueryPerformanceCounter(&EndTime, NULL); 00507 NtQueryPerformanceCounter(&ElapsedTime, &Interval); 00508 ElapsedTime.QuadPart = EndTime.QuadPart - BeginTime.QuadPart; 00509 DbgPrint("\nLoadTime %ld In units of %ld cycles/second \n", 00510 ElapsedTime.LowPart, 00511 Interval.LowPart 00512 ); 00513 00514 ElapsedTime.QuadPart = EndTime.QuadPart - InitbTime.QuadPart; 00515 DbgPrint("InitTime %ld\n", 00516 ElapsedTime.LowPart 00517 ); 00518 DbgPrint("Compares %d Bypasses %d Normal Snaps %d\nSecOpens %d SecCreates %d Maps %d Relocates %d\n", 00519 LdrpCompareCount, 00520 LdrpSnapBypass, 00521 LdrpNormalSnap, 00522 LdrpSectionOpens, 00523 LdrpSectionCreates, 00524 LdrpSectionMaps, 00525 LdrpSectionRelocates 00526 ); 00527 } 00528 #endif // DBG 00529 00530 00531 } else { 00532 if ( Peb->InheritedAddressSpace ) { 00533 InitStatus = LdrpForkProcess(); 00534 } 00535 else { 00536 00537 #if defined (WX86) 00538 if (Teb->Vdm) { 00539 InitStatus = LdrpInitWx86(Teb->Vdm, Context, TRUE); 00540 } 00541 #endif 00542 00543 #if defined(_WIN64) 00544 // 00545 // Load in WOW64 if the image is supposed to run simulated 00546 // 00547 if (UseWOW64) { 00548 RtlLeaveCriticalSection(&LoaderLock); 00549 (*Wow64LdrpInitialize)(Context); 00550 // This never returns. It will destroy the process. 00551 } 00552 #endif 00553 LdrpInitializeThread(Context); 00554 } 00555 } 00556 } finally { 00557 LdrpInLdrInit = FALSE; 00558 RtlLeaveCriticalSection(&LoaderLock); 00559 } 00560 00561 NtTestAlert(); 00562 00563 if (!NT_SUCCESS(InitStatus)) { 00564 00565 if ( AlreadyFailed == FALSE ) { 00566 LdrpInitializationFailure(InitStatus); 00567 } 00568 RtlRaiseStatus(InitStatus); 00569 } 00570 00571 00572 }

VOID LdrpInitializePathCache VOID   ) 
 

NTSTATUS LdrpInitializeProcess IN PCONTEXT Context  OPTIONAL,
IN PVOID  SystemDllBase,
IN PUNICODE_STRING  UnicodeImageName
 

Definition at line 616 of file ldrinit.c.

References ASSERT, ATOM_TAG, CommandLine, DbgPrint, FALSE, FastPebLock, HeapParameters, InitTableInfo, L, LDR_TAG, LdrGetProcedureAddress(), LdrLoadDll(), LDRP_HASH_TABLE_SIZE, LdrpAllocateDataTableEntry(), LdrpDefaultPath, LdrpFetchAddressOfEntryPoint(), LdrpHashTable, LdrpImageEntry, LdrpInitializationFailure(), LdrpInitializeTls(), LdrpInsertMemoryTableEntry(), LdrpKnownDllObjectDirectory, LdrpKnownDllPath, LdrpKnownDllPathBuffer, LdrpLdrDatabaseIsSetup, LdrpNumberOfProcessors, LdrpReferenceLoadedDll, LdrpRelocateStartContext(), LdrpRunInitializeRoutines(), LdrpSetProtection(), LdrpVerifyDlls, LdrpWalkImportDescriptor(), LdrQueryApplicationCompatibilityGoo(), LdrQueryImageFileExecutionOptions(), LdrRelocateImage(), LoaderLock, LoaderLockInitialized, MAKE_TAG, NATIVE_PAGE_SIZE, NT_SUCCESS, NtAllocateVirtualMemory(), NtClose(), NtDllBase, NtdllBaseTag, NtdllpAllocateStringRoutine(), NtdllpFreeStringRoutine(), NtFreeVirtualMemory(), NtOpenDirectoryObject(), NtOpenSymbolicLinkObject(), NtQueryPerformanceCounter(), NtQuerySymbolicLinkObject(), NtSetInformationProcess(), NTSTATUS(), NtSystemRoot, NULL, PAGE_SIZE, RtlAllocateHeap, RtlAllocateStringRoutine, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), RtlCreateHeap(), RtlCreateTagHeap(), RtlCriticalSectionList, RtlFreeStringRoutine, RtlFreeUnicodeString(), RtlImageDirectoryEntryToData(), RtlImageNtHeader(), RtlInitAnsiString(), RtlInitializeAtomPackage(), RtlInitializeBitMap(), RtlInitializeCriticalSection(), RtlInitializeHeapManager(), RtlInitNlsTables(), RtlInitUnicodeString(), RtlNormalizeProcessParams(), RtlpDebugPageHeap, RtlpInitDeferedCriticalSection(), RtlpTimeout, RtlpTimoutDisable, RtlRaiseStatus(), RtlResetRtlTranslations(), RtlSetCurrentDirectory_U(), ShowSnaps, TlsBitMap, TlsExpansionBitMap, TRUE, Unicode, and USHORT.

Referenced by LdrpInitialize().

00624 : 00625 00626 This function initializes the loader for the process. 00627 This includes: 00628 00629 - Initializing the loader data table 00630 00631 - Connecting to the loader subsystem 00632 00633 - Initializing all staticly linked DLLs 00634 00635 Arguments: 00636 00637 Context - Supplies an optional context buffer that will be restore 00638 after all DLL initialization has been completed. If this 00639 parameter is NULL then this is a dynamic snap of this module. 00640 Otherwise this is a static snap prior to the user process 00641 gaining control. 00642 00643 SystemDllBase - Supplies the base address of the system dll. 00644 00645 Return Value: 00646 00647 Status value 00648 00649 --*/ 00650 00651 { 00652 PPEB Peb; 00653 NTSTATUS st; 00654 PWCH p, pp; 00655 UNICODE_STRING CurDir; 00656 UNICODE_STRING FullImageName; 00657 UNICODE_STRING CommandLine; 00658 ULONG DebugProcessHeapOnly = 0 ; 00659 HANDLE LinkHandle; 00660 WCHAR SystemDllPathBuffer[DOS_MAX_PATH_LENGTH]; 00661 UNICODE_STRING SystemDllPath; 00662 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; 00663 PRTL_USER_PROCESS_PARAMETERS ProcessParameters; 00664 UNICODE_STRING Unicode; 00665 OBJECT_ATTRIBUTES Obja; 00666 BOOLEAN StaticCurDir = FALSE; 00667 ULONG i; 00668 PIMAGE_NT_HEADERS NtHeader = RtlImageNtHeader( NtCurrentPeb()->ImageBaseAddress ); 00669 PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData; 00670 ULONG ProcessHeapFlags; 00671 RTL_HEAP_PARAMETERS HeapParameters; 00672 NLSTABLEINFO InitTableInfo; 00673 LARGE_INTEGER LongTimeout; 00674 UNICODE_STRING NtSystemRoot; 00675 LONG_PTR Diff; 00676 ULONG_PTR OldBase; 00677 00678 NtDllBase = SystemDllBase; 00679 00680 if ( 00681 #if defined(_WIN64) 00682 NtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC && 00683 #endif 00684 NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE ) { 00685 00686 // 00687 // Native subsystems load slower, but validate their DLLs 00688 // This is to help CSR detect bad images faster 00689 // 00690 00691 LdrpVerifyDlls = TRUE; 00692 00693 } 00694 00695 00696 Peb = NtCurrentPeb(); 00697 00698 #if defined(BUILD_WOW6432) 00699 { 00700 // 00701 // The process is running in WOW64. Sort out the optional header 00702 // format and reformat the image if its page size is smaller than 00703 // the native page size. 00704 // 00705 PIMAGE_NT_HEADERS32 NtHeader32 = (PIMAGE_NT_HEADERS32)NtHeader; 00706 00707 if (NtHeader32->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 && 00708 NtHeader32->OptionalHeader.SectionAlignment < NATIVE_PAGE_SIZE && 00709 !NT_SUCCESS(st = LdrpWx86FormatVirtualImage(NtHeader32, 00710 NtCurrentPeb()->ImageBaseAddress 00711 //bugbug: should be: (PVOID)NtHeader32->OptionalHeader.ImageBase 00712 ))) { 00713 return st; 00714 } 00715 } 00716 #elif defined (_ALPHA_) && defined (WX86) 00717 // 00718 // Deal with the native page size which is larger than x86 00719 // This needs to be done before any code reads beyond the file headers. 00720 // 00721 if (NtHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 && 00722 NtHeader->OptionalHeader.SectionAlignment < PAGE_SIZE && 00723 !NT_SUCCESS(st = LdrpWx86FormatVirtualImage((PIMAGE_NT_HEADERS32)NtHeader, 00724 (PVOID)NtHeader->OptionalHeader.ImageBase 00725 ))) 00726 { 00727 return st; 00728 } 00729 #endif 00730 00731 00732 LdrpNumberOfProcessors = Peb->NumberOfProcessors; 00733 RtlpTimeout = Peb->CriticalSectionTimeout; 00734 LongTimeout.QuadPart = Int32x32To64( 3600, -10000000 ); 00735 00736 if (ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters)) { 00737 FullImageName = *(PUNICODE_STRING)&ProcessParameters->ImagePathName; 00738 CommandLine = *(PUNICODE_STRING)&ProcessParameters->CommandLine; 00739 } 00740 else { 00741 RtlInitUnicodeString( &FullImageName, NULL ); 00742 RtlInitUnicodeString( &CommandLine, NULL ); 00743 } 00744 00745 00746 RtlInitNlsTables( 00747 Peb->AnsiCodePageData, 00748 Peb->OemCodePageData, 00749 Peb->UnicodeCaseTableData, 00750 &InitTableInfo 00751 ); 00752 00753 RtlResetRtlTranslations(&InitTableInfo); 00754 00755 #if defined(_WIN64) 00756 if (UseWOW64) { 00757 // 00758 // Ignore image config data when initializing the 64-bit loader. 00759 // The 32-bit loader in ntdll32 will look at the config data 00760 // and do the right thing. 00761 // 00762 ImageConfigData = NULL; 00763 } else 00764 #endif 00765 { 00766 00767 ImageConfigData = RtlImageDirectoryEntryToData( Peb->ImageBaseAddress, 00768 TRUE, 00769 IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, 00770 &i 00771 ); 00772 } 00773 00774 RtlZeroMemory( &HeapParameters, sizeof( HeapParameters ) ); 00775 ProcessHeapFlags = HEAP_GROWABLE | HEAP_CLASS_0; 00776 HeapParameters.Length = sizeof( HeapParameters ); 00777 if (ImageConfigData != NULL && i == sizeof( *ImageConfigData )) { 00778 Peb->NtGlobalFlag &= ~ImageConfigData->GlobalFlagsClear; 00779 Peb->NtGlobalFlag |= ImageConfigData->GlobalFlagsSet; 00780 00781 if (ImageConfigData->CriticalSectionDefaultTimeout != 0) { 00782 // 00783 // Convert from milliseconds to NT time scale (100ns) 00784 // 00785 RtlpTimeout.QuadPart = Int32x32To64( (LONG)ImageConfigData->CriticalSectionDefaultTimeout, 00786 -10000 00787 ); 00788 00789 } 00790 00791 if (ImageConfigData->ProcessHeapFlags != 0) { 00792 ProcessHeapFlags = ImageConfigData->ProcessHeapFlags; 00793 } 00794 00795 if (ImageConfigData->DeCommitFreeBlockThreshold != 0) { 00796 HeapParameters.DeCommitFreeBlockThreshold = ImageConfigData->DeCommitFreeBlockThreshold; 00797 } 00798 00799 if (ImageConfigData->DeCommitTotalFreeThreshold != 0) { 00800 HeapParameters.DeCommitTotalFreeThreshold = ImageConfigData->DeCommitTotalFreeThreshold; 00801 } 00802 00803 if (ImageConfigData->MaximumAllocationSize != 0) { 00804 HeapParameters.MaximumAllocationSize = ImageConfigData->MaximumAllocationSize; 00805 } 00806 00807 if (ImageConfigData->VirtualMemoryThreshold != 0) { 00808 HeapParameters.VirtualMemoryThreshold = ImageConfigData->VirtualMemoryThreshold; 00809 } 00810 } 00811 00812 // // 00813 // // Check if the image has the fast heap flag set 00814 // // 00815 // 00816 // if (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_FAST_HEAP) { 00817 // RtlpDisableHeapLookaside = 0; 00818 // } else { 00819 // RtlpDisableHeapLookaside = 1; 00820 // } 00821 00822 ShowSnaps = (BOOLEAN)(FLG_SHOW_LDR_SNAPS & Peb->NtGlobalFlag); 00823 00824 00825 00826 // 00827 // This field is non-zero if the image file that was used to create this 00828 // process contained a non-zero value in its image header. If so, then 00829 // set the affinity mask for the process using this value. It could also 00830 // be non-zero if the parent process created us suspended and poked our 00831 // PEB with a non-zero value before resuming. 00832 // 00833 if (Peb->ImageProcessAffinityMask) { 00834 st = NtSetInformationProcess( NtCurrentProcess(), 00835 ProcessAffinityMask, 00836 &Peb->ImageProcessAffinityMask, 00837 sizeof( Peb->ImageProcessAffinityMask ) 00838 ); 00839 if (NT_SUCCESS( st )) { 00840 KdPrint(( "LDR: Using ProcessAffinityMask of 0x%x from image.\n", 00841 Peb->ImageProcessAffinityMask 00842 )); 00843 } 00844 else { 00845 KdPrint(( "LDR: Failed to set ProcessAffinityMask of 0x%x from image (Status == %08x).\n", 00846 Peb->ImageProcessAffinityMask, st 00847 )); 00848 } 00849 } 00850 00851 if (RtlpTimeout.QuadPart < LongTimeout.QuadPart) { 00852 RtlpTimoutDisable = TRUE; 00853 } 00854 00855 if (ShowSnaps) { 00856 DbgPrint( "LDR: PID: 0x%x started - '%wZ'\n", 00857 NtCurrentTeb()->ClientId.UniqueProcess, 00858 &CommandLine 00859 ); 00860 } 00861 00862 for(i=0;i<LDRP_HASH_TABLE_SIZE;i++) { 00863 InitializeListHead(&LdrpHashTable[i]); 00864 } 00865 00866 // 00867 // Initialize the critical section package. 00868 // 00869 00870 RtlpInitDeferedCriticalSection(); 00871 00872 Peb->TlsBitmap = (PVOID)&TlsBitMap; 00873 Peb->TlsExpansionBitmap = (PVOID)&TlsExpansionBitMap; 00874 00875 RtlInitializeBitMap ( 00876 &TlsBitMap, 00877 &Peb->TlsBitmapBits[0], 00878 TLS_MINIMUM_AVAILABLE 00879 ); 00880 00881 RtlInitializeBitMap ( 00882 &TlsExpansionBitMap, 00883 &Peb->TlsExpansionBitmapBits[0], 00884 TLS_EXPANSION_SLOTS 00885 ); 00886 00887 InsertTailList(&RtlCriticalSectionList, &LoaderLock.DebugInfo->ProcessLocksList); 00888 LoaderLock.DebugInfo->CriticalSection = &LoaderLock; 00889 LoaderLockInitialized = TRUE; 00890 00891 // 00892 // Initialize the stack trace data base if requested 00893 // 00894 00895 #if i386 00896 if (Peb->NtGlobalFlag & FLG_USER_STACK_TRACE_DB) { 00897 PVOID BaseAddress = NULL; 00898 ULONG ReserveSize = 2 * 1024 * 1024; 00899 00900 st = NtAllocateVirtualMemory( NtCurrentProcess(), 00901 (PVOID *)&BaseAddress, 00902 0, 00903 &ReserveSize, 00904 MEM_RESERVE, 00905 PAGE_READWRITE 00906 ); 00907 if ( NT_SUCCESS( st ) ) { 00908 st = RtlInitializeStackTraceDataBase( BaseAddress, 00909 0, 00910 ReserveSize 00911 ); 00912 if ( !NT_SUCCESS( st ) ) { 00913 NtFreeVirtualMemory( NtCurrentProcess(), 00914 (PVOID *)&BaseAddress, 00915 &ReserveSize, 00916 MEM_RELEASE 00917 ); 00918 } 00919 else { 00920 Peb->NtGlobalFlag |= FLG_HEAP_VALIDATE_PARAMETERS; 00921 } 00922 } 00923 } 00924 #endif // i386 00925 00926 // 00927 // Initialize the loader data based in the PEB. 00928 // 00929 00930 st = RtlInitializeCriticalSection(&FastPebLock); 00931 if ( !NT_SUCCESS(st) ) { 00932 return st; 00933 } 00934 Peb->FastPebLock = &FastPebLock; 00935 Peb->FastPebLockRoutine = (PVOID)&RtlEnterCriticalSection; 00936 Peb->FastPebUnlockRoutine = (PVOID)&RtlLeaveCriticalSection; 00937 00938 RtlInitializeHeapManager(); 00939 #if defined(_WIN64) 00940 if (UseWOW64) { 00941 // 00942 // Create a heap using all defaults. The 32-bit process heap 00943 // will be created later by ntdll32 using the parameters from the exe. 00944 // 00945 Peb->ProcessHeap = RtlCreateHeap( ProcessHeapFlags, 00946 NULL, 00947 0, 00948 0, 00949 NULL, 00950 &HeapParameters 00951 ); 00952 } else 00953 #endif 00954 { 00955 00956 if (NtHeader->OptionalHeader.MajorSubsystemVersion <= 3 && 00957 NtHeader->OptionalHeader.MinorSubsystemVersion < 51 00958 ) { 00959 ProcessHeapFlags |= HEAP_CREATE_ALIGN_16; 00960 } 00961 00962 Peb->ProcessHeap = RtlCreateHeap( ProcessHeapFlags, 00963 NULL, 00964 NtHeader->OptionalHeader.SizeOfHeapReserve, 00965 NtHeader->OptionalHeader.SizeOfHeapCommit, 00966 NULL, // Lock to use for serialization 00967 &HeapParameters 00968 ); 00969 } 00970 if (Peb->ProcessHeap == NULL) { 00971 return STATUS_NO_MEMORY; 00972 } 00973 00974 NtdllBaseTag = RtlCreateTagHeap( Peb->ProcessHeap, 00975 0, 00976 L"NTDLL!", 00977 L"!Process\0" // Heap Name 00978 L"CSRSS Client\0" 00979 L"LDR Database\0" 00980 L"Current Directory\0" 00981 L"TLS Storage\0" 00982 L"DBGSS Client\0" 00983 L"SE Temporary\0" 00984 L"Temporary\0" 00985 L"LocalAtom\0" 00986 ); 00987 00988 RtlAllocateStringRoutine = NtdllpAllocateStringRoutine; 00989 RtlFreeStringRoutine = NtdllpFreeStringRoutine; 00990 00991 RtlInitializeAtomPackage( MAKE_TAG( ATOM_TAG ) ); 00992 00993 // 00994 // Allow only the process heap to have page allocations turned on 00995 // 00996 00997 st = LdrQueryImageFileExecutionOptions( UnicodeImageName, 00998 L"DebugProcessHeapOnly", 00999 REG_DWORD, 01000 &DebugProcessHeapOnly, 01001 sizeof( DebugProcessHeapOnly ), 01002 NULL 01003 ); 01004 if (NT_SUCCESS( st )) { 01005 01006 if ( RtlpDebugPageHeap && 01007 ( DebugProcessHeapOnly != 0 ) ) { 01008 01009 RtlpDebugPageHeap = FALSE ; 01010 01011 } 01012 01013 } 01014 01015 SystemDllPath.Buffer = SystemDllPathBuffer; 01016 SystemDllPath.Length = 0; 01017 SystemDllPath.MaximumLength = sizeof( SystemDllPathBuffer ); 01018 RtlInitUnicodeString( &NtSystemRoot, USER_SHARED_DATA->NtSystemRoot ); 01019 RtlAppendUnicodeStringToString( &SystemDllPath, &NtSystemRoot ); 01020 RtlAppendUnicodeToString( &SystemDllPath, L"\\System32\\" ); 01021 01022 RtlInitUnicodeString(&Unicode,L"\\KnownDlls"); 01023 InitializeObjectAttributes( &Obja, 01024 &Unicode, 01025 OBJ_CASE_INSENSITIVE, 01026 NULL, 01027 NULL 01028 ); 01029 st = NtOpenDirectoryObject( 01030 &LdrpKnownDllObjectDirectory, 01031 DIRECTORY_QUERY | DIRECTORY_TRAVERSE, 01032 &Obja 01033 ); 01034 if ( !NT_SUCCESS(st) ) { 01035 LdrpKnownDllObjectDirectory = NULL; 01036 // KnownDlls directory doesn't exist - assume it's system32. 01037 RtlInitUnicodeString(&LdrpKnownDllPath, SystemDllPath.Buffer); 01038 LdrpKnownDllPath.Length -= sizeof(WCHAR); // remove trailing '\' 01039 } 01040 else { 01041 01042 // 01043 // Open up the known dll pathname link 01044 // and query its value 01045 // 01046 01047 RtlInitUnicodeString(&Unicode,L"KnownDllPath"); 01048 InitializeObjectAttributes( &Obja, 01049 &Unicode, 01050 OBJ_CASE_INSENSITIVE, 01051 LdrpKnownDllObjectDirectory, 01052 NULL 01053 ); 01054 st = NtOpenSymbolicLinkObject( &LinkHandle, 01055 SYMBOLIC_LINK_QUERY, 01056 &Obja 01057 ); 01058 if (NT_SUCCESS( st )) { 01059 LdrpKnownDllPath.Length = 0; 01060 LdrpKnownDllPath.MaximumLength = sizeof(LdrpKnownDllPathBuffer); 01061 LdrpKnownDllPath.Buffer = LdrpKnownDllPathBuffer; 01062 st = NtQuerySymbolicLinkObject( LinkHandle, 01063 &LdrpKnownDllPath, 01064 NULL 01065 ); 01066 NtClose(LinkHandle); 01067 if ( !NT_SUCCESS(st) ) { 01068 return st; 01069 } 01070 } 01071 else { 01072 return st; 01073 } 01074 } 01075 01076 if (ProcessParameters) { 01077 01078 // 01079 // If the process was created with process parameters, 01080 // than extract: 01081 // 01082 // - Library Search Path 01083 // 01084 // - Starting Current Directory 01085 // 01086 01087 if (ProcessParameters->DllPath.Length) { 01088 LdrpDefaultPath = *(PUNICODE_STRING)&ProcessParameters->DllPath; 01089 } 01090 else { 01091 LdrpInitializationFailure( STATUS_INVALID_PARAMETER ); 01092 } 01093 01094 StaticCurDir = TRUE; 01095 CurDir = ProcessParameters->CurrentDirectory.DosPath; 01096 if (CurDir.Buffer == NULL || CurDir.Buffer[ 0 ] == UNICODE_NULL || CurDir.Length == 0) { 01097 CurDir.Buffer = (RtlAllocateStringRoutine)( (3+1) * sizeof( WCHAR ) ); 01098 ASSERT(CurDir.Buffer != NULL); 01099 RtlMoveMemory( CurDir.Buffer, 01100 USER_SHARED_DATA->NtSystemRoot, 01101 3 * sizeof( WCHAR ) 01102 ); 01103 CurDir.Buffer[ 3 ] = UNICODE_NULL; 01104 } 01105 } 01106 01107 // 01108 // Make sure the module data base is initialized before we take any 01109 // exceptions. 01110 // 01111 01112 Peb->Ldr = RtlAllocateHeap(Peb->ProcessHeap, MAKE_TAG( LDR_TAG ), sizeof(PEB_LDR_DATA)); 01113 if ( !Peb->Ldr ) { 01114 RtlRaiseStatus(STATUS_NO_MEMORY); 01115 } 01116 01117 Peb->Ldr->Length = sizeof(PEB_LDR_DATA); 01118 Peb->Ldr->Initialized = TRUE; 01119 Peb->Ldr->SsHandle = NULL; 01120 InitializeListHead(&Peb->Ldr->InLoadOrderModuleList); 01121 InitializeListHead(&Peb->Ldr->InMemoryOrderModuleList); 01122 InitializeListHead(&Peb->Ldr->InInitializationOrderModuleList); 01123 01124 // 01125 // Allocate the first data table entry for the image. Since we 01126 // have already mapped this one, we need to do the allocation by hand. 01127 // Its characteristics identify it as not a Dll, but it is linked 01128 // into the table so that pc correlation searching doesn't have to 01129 // be special cased. 01130 // 01131 01132 LdrDataTableEntry = LdrpImageEntry = LdrpAllocateDataTableEntry(Peb->ImageBaseAddress); 01133 LdrDataTableEntry->LoadCount = (USHORT)0xffff; 01134 LdrDataTableEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(LdrDataTableEntry->DllBase); 01135 LdrDataTableEntry->FullDllName = FullImageName; 01136 LdrDataTableEntry->Flags = 0; 01137 01138 // p = strrchr(FullImageName, '\\'); 01139 pp = UNICODE_NULL; 01140 p = FullImageName.Buffer; 01141 while (*p) { 01142 if (*p++ == (WCHAR)'\\') { 01143 pp = p; 01144 } 01145 } 01146 01147 LdrDataTableEntry->FullDllName.Length = (USHORT)((ULONG_PTR)p - (ULONG_PTR)FullImageName.Buffer); 01148 LdrDataTableEntry->FullDllName.MaximumLength = LdrDataTableEntry->FullDllName.Length + (USHORT)sizeof(UNICODE_NULL); 01149 01150 if (pp) { 01151 LdrDataTableEntry->BaseDllName.Length = (USHORT)((ULONG_PTR)p - (ULONG_PTR)pp); 01152 LdrDataTableEntry->BaseDllName.MaximumLength = LdrDataTableEntry->BaseDllName.Length + (USHORT)sizeof(UNICODE_NULL); 01153 LdrDataTableEntry->BaseDllName.Buffer = RtlAllocateHeap(Peb->ProcessHeap, MAKE_TAG( LDR_TAG ), 01154 LdrDataTableEntry->BaseDllName.MaximumLength 01155 ); 01156 RtlMoveMemory(LdrDataTableEntry->BaseDllName.Buffer, 01157 pp, 01158 LdrDataTableEntry->BaseDllName.MaximumLength 01159 ); 01160 } else { 01161 LdrDataTableEntry->BaseDllName = LdrDataTableEntry->FullDllName; 01162 } 01163 LdrpInsertMemoryTableEntry(LdrDataTableEntry); 01164 LdrDataTableEntry->Flags |= LDRP_ENTRY_PROCESSED; 01165 01166 if (ShowSnaps) { 01167 DbgPrint( "LDR: NEW PROCESS\n" ); 01168 DbgPrint( " Image Path: %wZ (%wZ)\n", 01169 &LdrDataTableEntry->FullDllName, 01170 &LdrDataTableEntry->BaseDllName 01171 ); 01172 DbgPrint( " Current Directory: %wZ\n", &CurDir ); 01173 DbgPrint( " Search Path: %wZ\n", &LdrpDefaultPath ); 01174 } 01175 01176 // 01177 // The process references the system DLL, so map this one next. Since 01178 // we have already mapped this one, we need to do the allocation by 01179 // hand. Since every application will be statically linked to the 01180 // system Dll, we'll keep the LoadCount initialized to 0. 01181 // 01182 01183 LdrDataTableEntry = LdrpAllocateDataTableEntry(SystemDllBase); 01184 LdrDataTableEntry->Flags = (USHORT)LDRP_IMAGE_DLL; 01185 LdrDataTableEntry->EntryPoint = LdrpFetchAddressOfEntryPoint(LdrDataTableEntry->DllBase); 01186 LdrDataTableEntry->LoadCount = (USHORT)0xffff; 01187 01188 LdrDataTableEntry->BaseDllName.Length = SystemDllPath.Length; 01189 RtlAppendUnicodeToString( &SystemDllPath, L"ntdll.dll" ); 01190 LdrDataTableEntry->BaseDllName.Length = SystemDllPath.Length - LdrDataTableEntry->BaseDllName.Length; 01191 LdrDataTableEntry->BaseDllName.MaximumLength = LdrDataTableEntry->BaseDllName.Length + sizeof( UNICODE_NULL ); 01192 01193 LdrDataTableEntry->FullDllName.Buffer = 01194 (RtlAllocateStringRoutine)( SystemDllPath.Length + sizeof( UNICODE_NULL ) ); 01195 ASSERT(LdrDataTableEntry->FullDllName.Buffer != NULL); 01196 RtlMoveMemory( LdrDataTableEntry->FullDllName.Buffer, 01197 SystemDllPath.Buffer, 01198 SystemDllPath.Length 01199 ); 01200 LdrDataTableEntry->FullDllName.Buffer[ SystemDllPath.Length / sizeof( WCHAR ) ] = UNICODE_NULL; 01201 LdrDataTableEntry->FullDllName.Length = SystemDllPath.Length; 01202 LdrDataTableEntry->FullDllName.MaximumLength = SystemDllPath.Length + sizeof( UNICODE_NULL ); 01203 LdrDataTableEntry->BaseDllName.Buffer = (PWSTR) 01204 ((PCHAR)(LdrDataTableEntry->FullDllName.Buffer) + 01205 LdrDataTableEntry->FullDllName.Length - 01206 LdrDataTableEntry->BaseDllName.Length 01207 ); 01208 LdrpInsertMemoryTableEntry(LdrDataTableEntry); 01209 01210 // 01211 // Add init routine to list 01212 // 01213 01214 InsertHeadList(&Peb->Ldr->InInitializationOrderModuleList, 01215 &LdrDataTableEntry->InInitializationOrderLinks); 01216 01217 // 01218 // Inherit the current directory 01219 // 01220 01221 st = RtlSetCurrentDirectory_U(&CurDir); 01222 if (!NT_SUCCESS(st)) { 01223 if ( !StaticCurDir ) { 01224 RtlFreeUnicodeString(&CurDir); 01225 } 01226 CurDir = NtSystemRoot; 01227 st = RtlSetCurrentDirectory_U(&CurDir); 01228 } 01229 else { 01230 if ( !StaticCurDir ) { 01231 RtlFreeUnicodeString(&CurDir); 01232 } 01233 } 01234 01235 #if defined(WX86) 01236 01237 // 01238 // Load in x86 emulator for risc (Wx86.dll) 01239 // 01240 01241 if (NtHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) { 01242 st = LdrpLoadWx86Dll(Context); 01243 if (!NT_SUCCESS(st)) { 01244 return st; 01245 } 01246 } 01247 01248 #endif 01249 01250 #if defined(_WIN64) 01251 // 01252 // Load in WOW64 if the image is supposed to run simulated 01253 // 01254 if (UseWOW64) { 01255 UNICODE_STRING Wow64Name; 01256 ANSI_STRING ProcName; 01257 RtlInitUnicodeString(&Wow64Name, L"wow64.dll"); 01258 st = LdrLoadDll(NULL, NULL, &Wow64Name, &Wow64Handle); 01259 if (!NT_SUCCESS(st)) { 01260 if (ShowSnaps) { 01261 DbgPrint("wow64.dll not found. Status=%x\n", st); 01262 } 01263 return st; 01264 } 01265 01266 // 01267 // Get the entrypoints. They are roughly cloned from ntos\ps\psinit.c 01268 // PspInitSystemDll(). 01269 // 01270 RtlInitAnsiString(&ProcName, "Wow64LdrpInitialize"); 01271 st = LdrGetProcedureAddress(Wow64Handle, 01272 &ProcName, 01273 0, 01274 (PVOID *)&Wow64LdrpInitialize); 01275 if (!NT_SUCCESS(st)) { 01276 if (ShowSnaps) { 01277 DbgPrint("Wow64LdrpInitialize not found. Status=%x\n", st); 01278 } 01279 return st; 01280 } 01281 01282 RtlInitAnsiString(&ProcName, "Wow64PrepareForException"); 01283 st = LdrGetProcedureAddress(Wow64Handle, 01284 &ProcName, 01285 0, 01286 (PVOID *)&Wow64PrepareForException); 01287 if (!NT_SUCCESS(st)) { 01288 if (ShowSnaps) { 01289 DbgPrint("Wow64PrepareForException not found. Status=%x\n", st); 01290 } 01291 return st; 01292 } 01293 01294 DbgPrint("WARNING: PROCESS HAS BEEN CONVERTED TO WOW64!!!\n"); 01295 if (Peb->ProcessParameters) { 01296 DbgPrint("CommandLine: %wZ\n", &Peb->ProcessParameters->CommandLine); 01297 DbgPrint("ImagePathName: %wZ\n", &Peb->ProcessParameters->ImagePathName); 01298 } 01299 01300 // 01301 // Now that all DLLs are loaded, if the process is being debugged, 01302 // signal the debugger with an exception 01303 // 01304 01305 if ( Peb->BeingDebugged ) { 01306 DbgBreakPoint(); 01307 } 01308 01309 // 01310 // Release the loaderlock now - this thread doesn't need it any more. 01311 // 01312 RtlLeaveCriticalSection(&LoaderLock); 01313 01314 // 01315 // Call wow64 to load and run 32-bit ntdll.dll. 01316 // 01317 (*Wow64LdrpInitialize)(Context); 01318 // This never returns. It will destroy the process. 01319 } 01320 #endif 01321 01322 01323 st = LdrpWalkImportDescriptor( 01324 LdrpDefaultPath.Buffer, 01325 LdrpImageEntry 01326 ); 01327 01328 if ((PVOID)NtHeader->OptionalHeader.ImageBase != NtCurrentPeb()->ImageBaseAddress ) { 01329 01330 // 01331 // The executable is not at its original address. It must be 01332 // relocated now. 01333 // 01334 01335 PVOID ViewBase; 01336 NTSTATUS status; 01337 01338 ViewBase = NtCurrentPeb()->ImageBaseAddress; 01339 01340 status = LdrpSetProtection(ViewBase, FALSE, TRUE); 01341 01342 if (!NT_SUCCESS(status)) { 01343 return status; 01344 } 01345 01346 status = (NTSTATUS)LdrRelocateImage(ViewBase, 01347 "LDR", 01348 (ULONG)STATUS_SUCCESS, 01349 (ULONG)STATUS_CONFLICTING_ADDRESSES, 01350 (ULONG)STATUS_INVALID_IMAGE_FORMAT 01351 ); 01352 01353 if (!NT_SUCCESS(status)) { 01354 return status; 01355 } 01356 01357 // 01358 // Update the initial thread context record as per the relocation. 01359 // 01360 01361 if (Context) { 01362 01363 OldBase = NtHeader->OptionalHeader.ImageBase; 01364 Diff = (PCHAR)ViewBase - (PCHAR)OldBase; 01365 01366 LdrpRelocateStartContext(Context, Diff); 01367 } 01368 01369 status = LdrpSetProtection(ViewBase, TRUE, TRUE); 01370 01371 if (!NT_SUCCESS(status)) { 01372 return status; 01373 } 01374 } 01375 01376 #if defined (_ALPHA_) 01377 01378 // 01379 // Find and apply Alpha architecture fixups for this image 01380 // 01381 01382 AlphaFindArchitectureFixups(NtHeader, NtCurrentPeb()->ImageBaseAddress, TRUE); 01383 #endif 01384 01385 LdrpReferenceLoadedDll(LdrpImageEntry); 01386 01387 // 01388 // Lock the loaded DLLs to prevent dlls that back link to the exe to 01389 // cause problems when they are unloaded. 01390 // 01391 01392 { 01393 PLDR_DATA_TABLE_ENTRY Entry; 01394 PLIST_ENTRY Head,Next; 01395 01396 Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; 01397 Next = Head->Flink; 01398 01399 while ( Next != Head ) { 01400 Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 01401 Entry->LoadCount = 0xffff; 01402 Next = Next->Flink; 01403 } 01404 } 01405 01406 // 01407 // All static DLLs are now pinned in place. No init routines have been run yet 01408 // 01409 01410 LdrpLdrDatabaseIsSetup = TRUE; 01411 01412 01413 if (!NT_SUCCESS(st)) { 01414 #if DBG 01415 DbgPrint("LDR: Initialize of image failed. Returning Error Status\n"); 01416 #endif 01417 return st; 01418 } 01419 01420 if ( !NT_SUCCESS(LdrpInitializeTls()) ) { 01421 return st; 01422 } 01423 01424 // 01425 // Now that all DLLs are loaded, if the process is being debugged, 01426 // signal the debugger with an exception 01427 // 01428 01429 if ( Peb->BeingDebugged ) { 01430 DbgBreakPoint(); 01431 ShowSnaps = (BOOLEAN)(FLG_SHOW_LDR_SNAPS & Peb->NtGlobalFlag); 01432 } 01433 01434 #if defined (_X86_) 01435 if ( LdrpNumberOfProcessors > 1 ) { 01436 LdrpValidateImageForMp(LdrDataTableEntry); 01437 } 01438 #endif 01439 01440 #if DBG 01441 if (LdrpDisplayLoadTime) { 01442 NtQueryPerformanceCounter(&InitbTime, NULL); 01443 } 01444 #endif // DBG 01445 01446 // 01447 // Get all application goo here (hacks, flags, etc.) 01448 // 01449 LdrQueryApplicationCompatibilityGoo(UnicodeImageName); 01450 01451 st = LdrpRunInitializeRoutines(Context); 01452 01453 if ( NT_SUCCESS(st) && Peb->PostProcessInitRoutine ) { 01454 (Peb->PostProcessInitRoutine)(); 01455 } 01456 01457 return st; 01458 }

NTSTATUS LdrpInitializeTls VOID   ) 
 

Definition at line 1978 of file ldrinit.c.

References DbgPrint, FALSE, LdrpAllocateTls(), LdrpImageHasTls, LdrpNumberOfTlsEntries, LdrpTlsList, MAKE_TAG, PLDRP_TLS_ENTRY, RtlAllocateHeap, RtlImageDirectoryEntryToData(), RtlpSerializeHeap(), ShowSnaps, TLS_TAG, TRUE, and USHORT.

Referenced by LdrpInitializeProcess().

01981 { 01982 PLDR_DATA_TABLE_ENTRY Entry; 01983 PLIST_ENTRY Head,Next; 01984 PIMAGE_TLS_DIRECTORY TlsImage; 01985 PLDRP_TLS_ENTRY TlsEntry; 01986 ULONG TlsSize; 01987 BOOLEAN FirstTimeThru = TRUE; 01988 01989 InitializeListHead(&LdrpTlsList); 01990 01991 // 01992 // Walk through the loaded modules an look for TLS. If we find TLS, 01993 // lock in the module and add to the TLS chain. 01994 // 01995 01996 Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; 01997 Next = Head->Flink; 01998 01999 while ( Next != Head ) { 02000 Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 02001 Next = Next->Flink; 02002 02003 TlsImage = (PIMAGE_TLS_DIRECTORY)RtlImageDirectoryEntryToData( 02004 Entry->DllBase, 02005 TRUE, 02006 IMAGE_DIRECTORY_ENTRY_TLS, 02007 &TlsSize 02008 ); 02009 02010 // 02011 // mark whether or not the image file has TLS 02012 // 02013 02014 if ( FirstTimeThru ) { 02015 FirstTimeThru = FALSE; 02016 if ( TlsImage && !LdrpImageHasTls) { 02017 RtlpSerializeHeap( RtlProcessHeap() ); 02018 LdrpImageHasTls = TRUE; 02019 } 02020 } 02021 02022 if ( TlsImage ) { 02023 if (ShowSnaps) { 02024 DbgPrint( "LDR: Tls Found in %wZ at %lx\n", 02025 &Entry->BaseDllName, 02026 TlsImage 02027 ); 02028 } 02029 02030 TlsEntry = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( TLS_TAG ),sizeof(*TlsEntry)); 02031 if ( !TlsEntry ) { 02032 return STATUS_NO_MEMORY; 02033 } 02034 02035 // 02036 // Since this DLL has TLS, lock it in 02037 // 02038 02039 Entry->LoadCount = (USHORT)0xffff; 02040 02041 // 02042 // Mark this as having thread local storage 02043 // 02044 02045 Entry->TlsIndex = (USHORT)0xffff; 02046 02047 TlsEntry->Tls = *TlsImage; 02048 InsertTailList(&LdrpTlsList,&TlsEntry->Links); 02049 02050 // 02051 // Update the index for this dll's thread local storage 02052 // 02053 02054 02055 *(PLONG)TlsEntry->Tls.AddressOfIndex = LdrpNumberOfTlsEntries; 02056 TlsEntry->Tls.Characteristics = LdrpNumberOfTlsEntries++; 02057 } 02058 } 02059 02060 // 02061 // We now have walked through all static DLLs and know 02062 // all DLLs that reference thread local storage. Now we 02063 // just have to allocate the thread local storage for the current 02064 // thread and for all subsequent threads 02065 // 02066 02067 return LdrpAllocateTls(); 02068 }

VOID LdrpInsertMemoryTableEntry IN PLDR_DATA_TABLE_ENTRY  LdrDataTableEntry  ) 
 

Definition at line 3084 of file ldrsnap.c.

References LDRP_COMPUTE_HASH_INDEX, and LdrpHashTable.

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

03090 : 03091 03092 This function inserts a loader data table entry into the 03093 list of loaded modules for this process. The insertion is 03094 done in "image memory base order". 03095 03096 Arguments: 03097 03098 LdrDataTableEntry - Supplies the address of the loader data table 03099 entry to insert in the list of loaded modules for this process. 03100 03101 Return Value: 03102 03103 None. 03104 03105 --*/ 03106 03107 { 03108 PPEB_LDR_DATA Ldr; 03109 ULONG i; 03110 03111 Ldr = NtCurrentPeb()->Ldr; 03112 03113 i = LDRP_COMPUTE_HASH_INDEX(LdrDataTableEntry->BaseDllName.Buffer[0]); 03114 InsertTailList(&LdrpHashTable[i],&LdrDataTableEntry->HashLinks); 03115 InsertTailList(&Ldr->InLoadOrderModuleList, &LdrDataTableEntry->InLoadOrderLinks); 03116 InsertTailList(&Ldr->InMemoryOrderModuleList, &LdrDataTableEntry->InMemoryOrderLinks); 03117 }

NTSTATUS NTAPI LdrpLoadDll IN PWSTR DllPath  OPTIONAL,
IN PULONG DllCharacteristics  OPTIONAL,
IN PUNICODE_STRING  DllName,
OUT PVOID *  DllHandle,
IN BOOLEAN  RunInitRoutines
 

Definition at line 70 of file ldrapi.c.

References DbgPrint, DLLEXTENSION, EXCEPTION_EXECUTE_HANDLER, FALSE, L, LdrpCheckForLoadedDll(), LdrpClearLoadInProgress(), LdrpInLdrInit, LdrpLdrDatabaseIsSetup, LdrpMapDll(), LdrpReferenceLoadedDll, LdrpRunInitializeRoutines(), LdrpWalkImportDescriptor(), LdrUnloadDll(), LoaderLock, NT_SUCCESS, NTSTATUS(), NULL, RtlInitUnicodeString(), and ShowSnaps.

Referenced by LdrLoadDll(), and LdrpSnapThunk().

00078 { 00079 PPEB Peb; 00080 PTEB Teb; 00081 NTSTATUS st; 00082 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; 00083 PWSTR ActualDllName; 00084 PWCH p, pp; 00085 UNICODE_STRING ActualDllNameStr; 00086 BOOLEAN Wx86KnownDll = FALSE; 00087 WCHAR FreeBuffer[266]; 00088 00089 Peb = NtCurrentPeb(); 00090 Teb = NtCurrentTeb(); 00091 00092 st = STATUS_SUCCESS; 00093 00094 try { 00095 00096 // 00097 // Grab Peb lock and Snap All Links to specified DLL 00098 // 00099 00100 if ( LdrpInLdrInit == FALSE ) { 00101 RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00102 } 00103 00104 00105 00106 #if defined (WX86) 00107 00108 if (Teb->Wx86Thread.UseKnownWx86Dll) { 00109 Wx86KnownDll = Teb->Wx86Thread.UseKnownWx86Dll; 00110 Teb->Wx86Thread.UseKnownWx86Dll = FALSE; 00111 } 00112 #endif 00113 00114 00115 00116 p = DllName->Buffer; 00117 pp = NULL; 00118 while (*p) { 00119 if (*p++ == (WCHAR)'.') { 00120 // 00121 // pp will point to first character after last '.' 00122 // 00123 pp = p; 00124 } 00125 } 00126 00127 00128 ActualDllName = FreeBuffer; 00129 if ( DllName->Length >= sizeof(FreeBuffer)) { 00130 return STATUS_NAME_TOO_LONG; 00131 } 00132 RtlMoveMemory(ActualDllName, DllName->Buffer, DllName->Length); 00133 00134 00135 if (!pp || *pp == (WCHAR)'\\') { 00136 // 00137 // No extension found (just ..\) 00138 // 00139 if ( DllName->Length+10 >= sizeof(FreeBuffer) ) { 00140 return STATUS_NAME_TOO_LONG; 00141 } 00142 00143 RtlMoveMemory((PCHAR)ActualDllName+DllName->Length, DLLEXTENSION, 10); 00144 } 00145 else { 00146 ActualDllName[DllName->Length >> 1] = UNICODE_NULL; 00147 } 00148 00149 if (ShowSnaps) { 00150 DbgPrint("LDR: LdrLoadDll, loading %ws from %ws\n", 00151 ActualDllName, 00152 ARGUMENT_PRESENT(DllPath) ? DllPath : L"" 00153 ); 00154 } 00155 00156 00157 RtlInitUnicodeString(&ActualDllNameStr,ActualDllName); 00158 ActualDllNameStr.MaximumLength = sizeof(FreeBuffer); 00159 00160 if (!LdrpCheckForLoadedDll( DllPath, 00161 &ActualDllNameStr, 00162 FALSE, 00163 Wx86KnownDll, 00164 &LdrDataTableEntry 00165 ) 00166 ) { 00167 st = LdrpMapDll(DllPath, 00168 ActualDllName, 00169 DllCharacteristics, 00170 FALSE, 00171 Wx86KnownDll, 00172 &LdrDataTableEntry 00173 ); 00174 00175 if (!NT_SUCCESS(st)) { 00176 return st; 00177 } 00178 00179 if (ARGUMENT_PRESENT( DllCharacteristics ) && 00180 *DllCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE 00181 ) { 00182 LdrDataTableEntry->EntryPoint = 0; 00183 LdrDataTableEntry->Flags &= ~LDRP_IMAGE_DLL; 00184 } 00185 00186 // 00187 // and walk the import descriptor. 00188 // 00189 00190 if (LdrDataTableEntry->Flags & LDRP_IMAGE_DLL) { 00191 00192 try { 00193 st = LdrpWalkImportDescriptor( 00194 DllPath, 00195 LdrDataTableEntry 00196 ); 00197 } 00198 except(EXCEPTION_EXECUTE_HANDLER) { 00199 st = GetExceptionCode(); 00200 } 00201 if ( LdrDataTableEntry->LoadCount != 0xffff ) { 00202 LdrDataTableEntry->LoadCount++; 00203 } 00204 LdrpReferenceLoadedDll(LdrDataTableEntry); 00205 if (!NT_SUCCESS(st)) { 00206 LdrDataTableEntry->EntryPoint = NULL; 00207 InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList, 00208 &LdrDataTableEntry->InInitializationOrderLinks); 00209 LdrpClearLoadInProgress(); 00210 LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase); 00211 return st; 00212 } 00213 } 00214 else { 00215 if ( LdrDataTableEntry->LoadCount != 0xffff ) { 00216 LdrDataTableEntry->LoadCount++; 00217 } 00218 } 00219 00220 // 00221 // Add init routine to list 00222 // 00223 00224 InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList, 00225 &LdrDataTableEntry->InInitializationOrderLinks); 00226 00227 00228 // 00229 // If the loader data base is not fully setup, this load was because 00230 // of a forwarder in the static load set. Can't run init routines 00231 // yet because the load counts are NOT set 00232 // 00233 00234 if ( RunInitRoutines && LdrpLdrDatabaseIsSetup ) { 00235 00236 try { 00237 st = LdrpRunInitializeRoutines(NULL); 00238 if ( !NT_SUCCESS(st) ) { 00239 LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase); 00240 } 00241 } 00242 except( EXCEPTION_EXECUTE_HANDLER ) { 00243 LdrUnloadDll((PVOID)LdrDataTableEntry->DllBase); 00244 return GetExceptionCode(); 00245 } 00246 } 00247 else { 00248 st = STATUS_SUCCESS; 00249 } 00250 00251 } 00252 else { 00253 00254 // 00255 // Count it. And everything that it imports. 00256 // 00257 00258 if ( LdrDataTableEntry->Flags & LDRP_IMAGE_DLL && 00259 LdrDataTableEntry->LoadCount != 0xffff ) { 00260 00261 LdrDataTableEntry->LoadCount++; 00262 00263 LdrpReferenceLoadedDll(LdrDataTableEntry); 00264 00265 // 00266 // Now clear the Load in progress bits 00267 // 00268 00269 LdrpClearLoadInProgress(); 00270 00271 } 00272 else { 00273 if ( LdrDataTableEntry->LoadCount != 0xffff ) { 00274 LdrDataTableEntry->LoadCount++; 00275 } 00276 } 00277 } 00278 } 00279 finally { 00280 if ( LdrpInLdrInit == FALSE ) { 00281 RtlLeaveCriticalSection((PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock); 00282 } 00283 00284 } 00285 if ( NT_SUCCESS(st) ) { 00286 *DllHandle = (PVOID)LdrDataTableEntry->DllBase; 00287 } 00288 else { 00289 *DllHandle = NULL; 00290 } 00291 return st; 00292 }

NTSTATUS LdrpMapDll IN PWSTR DllPath  OPTIONAL,
IN PWSTR  DllName,
IN PULONG DllCharacteristics  OPTIONAL,
IN BOOLEAN  StaticLink,
IN BOOLEAN  Wx86KnownDll,
OUT PLDR_DATA_TABLE_ENTRY *  LdrDataTableEntry
 

Definition at line 1261 of file ldrsnap.c.

References Action, DbgPrint, FALSE, L, LdrpAllocateDataTableEntry(), LdrpCheckForKnownDll(), LdrpCreateDllSection(), LdrpDefaultPath, LdrpFatalHardErrorCount, LdrpFetchAddressOfEntryPoint(), LdrpInLdrInit, LdrpInsertMemoryTableEntry(), LdrpKnownDllObjectDirectory, LdrpNumberOfProcessors, LdrpResolveDllName(), LdrpSetProtection(), LdrRelocateImage(), NATIVE_PAGE_SIZE, NT_ERROR, NT_SUCCESS, NtClose(), NtMapViewOfSection(), NtQueryPerformanceCounter(), NtRaiseHardError(), NTSTATUS(), NtUnmapViewOfSection(), NULL, PAGE_SIZE, RtlDosPathNameToNtPathName_U(), RtlEqualUnicodeString(), RtlFreeHeap, RtlFreeUnicodeString(), RtlImageDirectoryEntryToData(), RtlImageNtHeader(), RtlInitUnicodeString(), ShowSnaps, TRUE, type, and USHORT.

Referenced by LdrpLoadDll(), and LdrpLoadImportModule().

01272 : 01273 01274 This routine maps the DLL into the users address space. 01275 01276 Arguments: 01277 01278 DllPath - Supplies an optional search path to be used to locate the DLL. 01279 01280 DllName - Supplies the name of the DLL to load. 01281 01282 StaticLink - TRUE if this DLL has a static link to it. 01283 01284 Wx86KnownDll - TRUE, treat Importer as x86 01285 01286 LdrDataTableEntry - Supplies the address of the data table entry. 01287 01288 Return Value: 01289 01290 Status value. 01291 01292 --*/ 01293 01294 { 01295 NTSTATUS st; 01296 PVOID ViewBase; 01297 PTEB Teb = NtCurrentTeb(); 01298 SIZE_T ViewSize; 01299 HANDLE Section, DllFile; 01300 UNICODE_STRING FullDllName, BaseDllName; 01301 UNICODE_STRING NtFileName; 01302 PLDR_DATA_TABLE_ENTRY Entry; 01303 PIMAGE_NT_HEADERS NtHeaders; 01304 PVOID ArbitraryUserPointer; 01305 BOOLEAN KnownDll; 01306 UNICODE_STRING CollidingDll; 01307 PUCHAR ImageBase, ImageBounds, ScanBase, ScanTop; 01308 PLDR_DATA_TABLE_ENTRY ScanEntry; 01309 PLIST_ENTRY ScanHead,ScanNext; 01310 BOOLEAN CollidingDllFound; 01311 NTSTATUS ErrorStatus; 01312 ULONG_PTR ErrorParameters[2]; 01313 ULONG ErrorResponse; 01314 #if defined (WX86) 01315 BOOLEAN Wx86Plugin = FALSE; 01316 #endif 01317 01318 01319 // 01320 // Get section handle of DLL being snapped 01321 // 01322 01323 #if LDRDBG 01324 if (ShowSnaps) { 01325 DbgPrint("LDR: LdrpMapDll: Image Name %ws, Search Path %ws\n", 01326 DllName, 01327 ARGUMENT_PRESENT(DllPath) ? DllPath : L"" 01328 ); 01329 } 01330 #endif 01331 01332 Entry = NULL; 01333 KnownDll = FALSE; 01334 Section = NULL; 01335 01336 if ( LdrpKnownDllObjectDirectory && !Wx86KnownDll) { 01337 01338 PWCH p = DllName; 01339 WCHAR wch; 01340 01341 // 01342 // Skip the KnownDll check if this is an explicit path. 01343 // 01344 01345 while (*p) { 01346 wch = *p++; 01347 if (wch == (WCHAR)'\\' || wch == (WCHAR)'/' ) { 01348 goto SkipKnownDllCheck; 01349 } 01350 } 01351 Section = LdrpCheckForKnownDll( 01352 DllName, 01353 &FullDllName, 01354 &BaseDllName 01355 ); 01356 01357 } 01358 01359 SkipKnownDllCheck: 01360 01361 if ( !Section ) { 01362 01363 #if defined (WX86) 01364 if (Wx86ProcessInit) { 01365 RtlInitUnicodeString(&BaseDllName, DllName); 01366 st = LdrpWx86MapDll(DllPath, 01367 DllCharacteristics, 01368 Wx86KnownDll, 01369 StaticLink, 01370 &BaseDllName, 01371 &Entry, 01372 &ViewSize, 01373 &Section 01374 ); 01375 01376 if (st == STATUS_DLL_NOT_FOUND) { 01377 goto Wx86MapDllNotFound; 01378 } 01379 01380 if (!NT_SUCCESS(st)) { 01381 return st; 01382 } 01383 01384 01385 ViewBase = Entry->DllBase; 01386 FullDllName = Entry->FullDllName; 01387 BaseDllName = Entry->BaseDllName; 01388 NtHeaders = RtlImageNtHeader(ViewBase); 01389 01390 goto Wx86MapComplete; 01391 01392 } else 01393 #endif 01394 01395 if (LdrpResolveDllName( DllPath, 01396 DllName, 01397 &FullDllName, 01398 &BaseDllName, 01399 &DllFile 01400 ) 01401 ) { 01402 if (ShowSnaps) { 01403 PSZ type; 01404 type = StaticLink ? "STATIC" : "DYNAMIC"; 01405 DbgPrint("LDR: Loading (%s) %wZ\n", 01406 type, 01407 &FullDllName 01408 ); 01409 } 01410 01411 if (!RtlDosPathNameToNtPathName_U( FullDllName.Buffer, 01412 &NtFileName, 01413 NULL, 01414 NULL 01415 ) 01416 ) { 01417 return STATUS_OBJECT_PATH_SYNTAX_BAD; 01418 } 01419 01420 st = LdrpCreateDllSection(&NtFileName, 01421 DllFile, 01422 &BaseDllName, 01423 DllCharacteristics, 01424 &Section 01425 ); 01426 01427 RtlFreeHeap(RtlProcessHeap(), 0, NtFileName.Buffer); 01428 01429 if (!NT_SUCCESS(st)) { 01430 RtlFreeUnicodeString(&FullDllName); 01431 RtlFreeUnicodeString(&BaseDllName); 01432 return st; 01433 } 01434 #if DBG 01435 LdrpSectionCreates++; 01436 #endif 01437 01438 } else { 01439 01440 #ifdef WX86 01441 Wx86MapDllNotFound: 01442 #endif 01443 if ( StaticLink ) { 01444 PUNICODE_STRING ErrorStrings[2]; 01445 UNICODE_STRING ErrorDllName, ErrorDllPath; 01446 ULONG ErrorResponse; 01447 01448 ErrorStrings[0] = &ErrorDllName; 01449 ErrorStrings[1] = &ErrorDllPath; 01450 RtlInitUnicodeString(&ErrorDllName,DllName); 01451 RtlInitUnicodeString(&ErrorDllPath, 01452 ARGUMENT_PRESENT(DllPath) ? DllPath : LdrpDefaultPath.Buffer); 01453 NtRaiseHardError( 01454 (NTSTATUS)STATUS_DLL_NOT_FOUND, 01455 2, 01456 0x00000003, 01457 (PULONG_PTR)ErrorStrings, 01458 OptionOk, 01459 &ErrorResponse 01460 ); 01461 if ( LdrpInLdrInit ) { 01462 LdrpFatalHardErrorCount++; 01463 } 01464 } 01465 01466 return STATUS_DLL_NOT_FOUND; 01467 } 01468 } else { 01469 KnownDll = TRUE; 01470 } 01471 01472 ViewBase = NULL; 01473 ViewSize = 0; 01474 01475 01476 #if DBG 01477 LdrpSectionMaps++; 01478 if (LdrpDisplayLoadTime) { 01479 NtQueryPerformanceCounter(&MapBeginTime, NULL); 01480 } 01481 #endif 01482 01483 // 01484 // arrange for debugger to pick up the image name 01485 // 01486 01487 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer; 01488 Teb->NtTib.ArbitraryUserPointer = (PVOID)FullDllName.Buffer; 01489 st = NtMapViewOfSection( 01490 Section, 01491 NtCurrentProcess(), 01492 (PVOID *)&ViewBase, 01493 0L, 01494 0L, 01495 NULL, 01496 &ViewSize, 01497 ViewShare, 01498 0L, 01499 PAGE_READWRITE 01500 ); 01501 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer; 01502 01503 if (!NT_SUCCESS(st)) { 01504 NtClose(Section); 01505 return st; 01506 } 01507 01508 NtHeaders = RtlImageNtHeader(ViewBase); 01509 if ( !NtHeaders ) { 01510 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01511 NtClose(Section); 01512 return STATUS_INVALID_IMAGE_FORMAT; 01513 } 01514 01515 #if DBG 01516 if (LdrpDisplayLoadTime) { 01517 NtQueryPerformanceCounter(&MapEndTime, NULL); 01518 MapElapsedTime.QuadPart = MapEndTime.QuadPart - MapBeginTime.QuadPart; 01519 DbgPrint("Map View of Section Time %ld %ws\n", 01520 MapElapsedTime.LowPart, 01521 DllName 01522 ); 01523 } 01524 #endif 01525 01526 #if defined (BUILD_WOW6432) 01527 if (NtHeaders->OptionalHeader.SectionAlignment < NATIVE_PAGE_SIZE && 01528 !NT_SUCCESS(LdrpWx86FormatVirtualImage((PIMAGE_NT_HEADERS32)NtHeaders, ViewBase))) 01529 { 01530 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01531 NtClose(Section); 01532 return st; 01533 } 01534 #elif defined (_ALPHA_) && defined (WX86) 01535 if ((NtHeaders->OptionalHeader.SectionAlignment < PAGE_SIZE) && 01536 !NT_SUCCESS(LdrpWx86FormatVirtualImage((PIMAGE_NT_HEADERS32)NtHeaders, ViewBase))) 01537 { 01538 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01539 NtClose(Section); 01540 return STATUS_INVALID_IMAGE_FORMAT; 01541 } 01542 01543 if (st == STATUS_IMAGE_MACHINE_TYPE_MISMATCH && !StaticLink) { 01544 01545 // Attempt to find a plugin provider dll that can thunk this interface 01546 // temporarily insert the image in the loaded-module-list 01547 01548 Entry = LdrpAllocateDataTableEntry(ViewBase); 01549 if (!Entry) { 01550 return STATUS_NO_MEMORY; 01551 } 01552 01553 Entry->Flags = 0; 01554 Entry->LoadCount = 0; 01555 Entry->FullDllName = FullDllName; 01556 Entry->BaseDllName = BaseDllName; 01557 Entry->EntryPoint = LdrpFetchAddressOfEntryPoint(Entry->DllBase); 01558 LdrpInsertMemoryTableEntry(Entry); 01559 01560 // Determine if this dll can be thunked using a plugin 01561 01562 st = Wx86IdentifyPlugin(ViewBase, &FullDllName ); 01563 01564 // remove the image from the loaded-module-list 01565 01566 RemoveEntryList(&Entry->InLoadOrderLinks); 01567 RemoveEntryList(&Entry->InMemoryOrderLinks); 01568 RemoveEntryList(&Entry->HashLinks); 01569 RtlFreeHeap(RtlProcessHeap(), 0, Entry); 01570 Entry = NULL; 01571 01572 if (st == STATUS_SUCCESS) { 01573 01574 // Release the previous mapping because it's going to 01575 // be reloaded via Wx86. 01576 01577 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01578 ViewBase = NULL; 01579 01580 // The plugin providers must be statically bound to Wx86 01581 // or dynamically load it in their DllInit. 01582 01583 if (Wx86ProcessInit) { 01584 01585 // Load the dll again using Wx86. 01586 01587 st = LdrpWx86MapDll(NULL, 01588 DllCharacteristics, 01589 !Wx86KnownDll, // swap sense so we don't get mismatch 01590 StaticLink, 01591 &FullDllName, 01592 &Entry, 01593 &ViewSize, 01594 &Section 01595 ); 01596 01597 // Load and thunk the plugin dll 01598 01599 if (NT_SUCCESS(st)) { 01600 01601 ViewBase = Entry->DllBase; 01602 FullDllName = Entry->FullDllName; 01603 BaseDllName = Entry->BaseDllName; 01604 NtHeaders = RtlImageNtHeader(ViewBase); 01605 01606 } 01607 } 01608 01609 if (!Wx86ProcessInit || NT_ERROR(st)) { 01610 Wx86UnloadProviders(ViewBase); 01611 st = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; 01612 } 01613 } 01614 01615 // Need to save the status here to put in loader ENTRY after it's allocated. 01616 01617 Wx86Plugin = (st == STATUS_SUCCESS); 01618 01619 if (ShowSnaps) { 01620 PCHAR Action; 01621 01622 if (st == STATUS_SUCCESS) { 01623 Action = "Loaded"; 01624 } else if (st == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { 01625 Action = "Unsupported"; 01626 } else { 01627 Action = "Failed"; 01628 } 01629 01630 DbgPrint("LDRWx86: Plugin: %wZ %s.\n", 01631 &FullDllName, Action 01632 ); 01633 } 01634 } 01635 01636 if (!NT_SUCCESS(st) || (ViewBase == NULL)) { 01637 if (ViewBase) NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01638 NtClose(Section); 01639 return st; 01640 } else if (Entry) { 01641 goto Wx86MapComplete; 01642 } 01643 #endif 01644 01645 // 01646 // Allocate a data table entry. 01647 // 01648 01649 Entry = LdrpAllocateDataTableEntry(ViewBase); 01650 01651 if (!Entry) { 01652 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01653 NtClose(Section); 01654 return STATUS_NO_MEMORY; 01655 } 01656 01657 01658 Entry->Flags = (USHORT)(StaticLink ? LDRP_STATIC_LINK : 0); 01659 Entry->LoadCount = 0; 01660 Entry->FullDllName = FullDllName; 01661 Entry->BaseDllName = BaseDllName; 01662 Entry->EntryPoint = LdrpFetchAddressOfEntryPoint(Entry->DllBase); 01663 01664 #ifdef WX86 01665 Wx86MapComplete: 01666 if (Wx86Plugin) { 01667 Entry->Flags |= LDRP_WX86_PLUGIN; 01668 } 01669 #endif 01670 01671 01672 #if LDRDBG 01673 if (ShowSnaps) { 01674 DbgPrint("LDR: LdrpMapDll: Full Name %wZ, Base Name %wZ\n", 01675 &FullDllName, 01676 &BaseDllName 01677 ); 01678 } 01679 #endif 01680 01681 LdrpInsertMemoryTableEntry(Entry); 01682 01683 if ( st == STATUS_IMAGE_MACHINE_TYPE_MISMATCH ) { 01684 01685 PIMAGE_NT_HEADERS ImageHeader = RtlImageNtHeader( NtCurrentPeb()->ImageBaseAddress ); 01686 01687 // 01688 // apps compiled for NT 3.x and below can load cross architecture 01689 // images 01690 // 01691 01692 ErrorStatus = STATUS_SUCCESS; 01693 ErrorResponse = ResponseCancel; 01694 01695 if ( ImageHeader->OptionalHeader.MajorSubsystemVersion <= 3 ) { 01696 01697 Entry->EntryPoint = 0; 01698 01699 // 01700 // Hard Error Time 01701 // 01702 01703 // 01704 // Its error time... 01705 // 01706 01707 ErrorParameters[0] = (ULONG_PTR)&FullDllName; 01708 01709 ErrorStatus = NtRaiseHardError( 01710 STATUS_IMAGE_MACHINE_TYPE_MISMATCH, 01711 1, 01712 1, 01713 ErrorParameters, 01714 OptionOkCancel, 01715 &ErrorResponse 01716 ); 01717 } 01718 if ( NT_SUCCESS(ErrorStatus) && ErrorResponse == ResponseCancel ) { 01719 RemoveEntryList(&Entry->InLoadOrderLinks); 01720 RemoveEntryList(&Entry->InMemoryOrderLinks); 01721 RemoveEntryList(&Entry->HashLinks); 01722 RtlFreeHeap(RtlProcessHeap(), 0, Entry ); 01723 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01724 NtClose(Section); 01725 01726 if ( ImageHeader->OptionalHeader.MajorSubsystemVersion <= 3 ) { 01727 if ( LdrpInLdrInit ) { 01728 LdrpFatalHardErrorCount++; 01729 } 01730 } 01731 return STATUS_INVALID_IMAGE_FORMAT; 01732 } 01733 } 01734 else { 01735 if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) { 01736 Entry->Flags |= LDRP_IMAGE_DLL; 01737 } 01738 01739 if (!(Entry->Flags & LDRP_IMAGE_DLL)) { 01740 Entry->EntryPoint = 0; 01741 } 01742 } 01743 *LdrDataTableEntry = Entry; 01744 01745 if (st == STATUS_IMAGE_NOT_AT_BASE) { 01746 01747 Entry->Flags |= LDRP_IMAGE_NOT_AT_BASE; 01748 01749 // 01750 // now find the colliding dll. If we can not find a dll, 01751 // then the colliding dll must be dynamic memory 01752 // 01753 01754 ImageBase = (PUCHAR)NtHeaders->OptionalHeader.ImageBase; 01755 ImageBounds = ImageBase + ViewSize; 01756 01757 CollidingDllFound = FALSE; 01758 01759 ScanHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; 01760 ScanNext = ScanHead->Flink; 01761 01762 while ( ScanNext != ScanHead ) { 01763 ScanEntry = CONTAINING_RECORD(ScanNext, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 01764 ScanNext = ScanNext->Flink; 01765 01766 ScanBase = (PUCHAR)ScanEntry->DllBase; 01767 ScanTop = ScanBase + ScanEntry->SizeOfImage; 01768 01769 // 01770 // when we unload, the memory order links flink field is nulled. 01771 // this is used to skip the entry pending list removal. 01772 // 01773 01774 if ( !ScanEntry->InMemoryOrderLinks.Flink ) { 01775 continue; 01776 } 01777 01778 // 01779 // See if the base address of the scan image is within the relocating dll 01780 // or if the top address of the scan image is within the relocating dll 01781 // 01782 01783 if ( (ImageBase >= ScanBase && ImageBase <= ScanTop) 01784 01785 || 01786 01787 (ImageBounds >= ScanBase && ImageBounds <= ScanTop) 01788 01789 || 01790 01791 (ScanBase >= ImageBase && ScanBase <= ImageBounds) 01792 01793 ){ 01794 01795 CollidingDllFound = TRUE; 01796 CollidingDll = ScanEntry->FullDllName; 01797 break; 01798 } 01799 } 01800 01801 if ( !CollidingDllFound ) { 01802 RtlInitUnicodeString(&CollidingDll,L"Dynamically Allocated Memory"); 01803 } 01804 01805 #if DBG 01806 if ( BeginTime.LowPart || BeginTime.HighPart ) { 01807 DbgPrint("\nLDR: LdrpMapDll Relocateing Image Name %ws\n", 01808 DllName 01809 ); 01810 } 01811 LdrpSectionRelocates++; 01812 #endif 01813 if (Entry->Flags & LDRP_IMAGE_DLL) { 01814 01815 BOOLEAN AllowRelocation; 01816 UNICODE_STRING SystemDll; 01817 01818 if (!(NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED)) { 01819 01820 PVOID pBaseRelocs; 01821 ULONG BaseRelocCountBytes = 0; 01822 01823 // 01824 // If the iamge doesn't have the reloc stripped bit set and there's no 01825 // relocs in the data directory, allow this through. This is probably 01826 // a pure forwarder dll or data w/o relocs. 01827 // 01828 01829 pBaseRelocs = RtlImageDirectoryEntryToData( 01830 ViewBase, TRUE, IMAGE_DIRECTORY_ENTRY_BASERELOC, &BaseRelocCountBytes); 01831 01832 if (!pBaseRelocs && !BaseRelocCountBytes) { 01833 goto NoRelocNeeded; 01834 } 01835 } 01836 01837 // 01838 // decide whether or not to allow the relocation 01839 // certain system dll's like user32 and kernel32 are not relocatable 01840 // since addresses within these dll's are not always stored per process 01841 // do not allow these dll's to be relocated 01842 // 01843 01844 AllowRelocation = TRUE; 01845 RtlInitUnicodeString(&SystemDll,L"user32.dll"); 01846 if ( RtlEqualUnicodeString(&BaseDllName,&SystemDll,TRUE) ) { 01847 AllowRelocation = FALSE; 01848 } 01849 else { 01850 RtlInitUnicodeString(&SystemDll,L"kernel32.dll"); 01851 if ( RtlEqualUnicodeString(&BaseDllName,&SystemDll,TRUE) ) { 01852 AllowRelocation = FALSE; 01853 } 01854 } 01855 if ( !AllowRelocation && KnownDll ) { 01856 01857 // 01858 // totally disallow the relocation since this is a knowndll 01859 // that matches our system binaries and is being relocated 01860 // 01861 01862 // 01863 // Hard Error Time 01864 // 01865 01866 ErrorParameters[0] = (ULONG_PTR)&SystemDll; 01867 ErrorParameters[1] = (ULONG_PTR)&CollidingDll; 01868 01869 NtRaiseHardError( 01870 STATUS_ILLEGAL_DLL_RELOCATION, 01871 2, 01872 3, 01873 ErrorParameters, 01874 OptionOk, 01875 &ErrorResponse 01876 ); 01877 01878 if ( LdrpInLdrInit ) { 01879 LdrpFatalHardErrorCount++; 01880 } 01881 01882 st = STATUS_CONFLICTING_ADDRESSES; 01883 goto skipreloc; 01884 } 01885 01886 st = LdrpSetProtection(ViewBase, FALSE, StaticLink ); 01887 if (NT_SUCCESS(st)) { 01888 st = (NTSTATUS)LdrRelocateImage(ViewBase, 01889 "LDR", 01890 (ULONG)STATUS_SUCCESS, 01891 (ULONG)STATUS_CONFLICTING_ADDRESSES, 01892 (ULONG)STATUS_INVALID_IMAGE_FORMAT 01893 ); 01894 if (NT_SUCCESS(st)) { 01895 01896 // 01897 // If we did relocations, then map the section again. 01898 // this will force the debug event 01899 // 01900 01901 // 01902 // arrange for debugger to pick up the image name 01903 // 01904 01905 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer; 01906 Teb->NtTib.ArbitraryUserPointer = (PVOID)FullDllName.Buffer; 01907 NtMapViewOfSection( 01908 Section, 01909 NtCurrentProcess(), 01910 (PVOID *)&ViewBase, 01911 0L, 01912 0L, 01913 NULL, 01914 &ViewSize, 01915 ViewShare, 01916 0L, 01917 PAGE_READWRITE 01918 ); 01919 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer; 01920 01921 st = LdrpSetProtection(ViewBase, TRUE, StaticLink); 01922 01923 } 01924 } 01925 skipreloc: 01926 // 01927 // if the set protection failed, or if the relocation failed, then 01928 // remove the partially loaded dll from the lists and clear entry 01929 // that it has been freed. 01930 // 01931 01932 if ( !NT_SUCCESS(st) ) { 01933 RemoveEntryList(&Entry->InLoadOrderLinks); 01934 RemoveEntryList(&Entry->InMemoryOrderLinks); 01935 RemoveEntryList(&Entry->HashLinks); 01936 NtUnmapViewOfSection(NtCurrentProcess(),ViewBase); 01937 Entry = NULL; 01938 } 01939 01940 if (ShowSnaps) { 01941 DbgPrint("LDR: Fixups %successfully re-applied @ %lx\n", 01942 NT_SUCCESS(st) ? "s" : "uns", ViewBase); 01943 } 01944 } else { 01945 NoRelocNeeded: 01946 st = STATUS_SUCCESS; 01947 01948 // 01949 // arrange for debugger to pick up the image name 01950 // 01951 01952 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer; 01953 Teb->NtTib.ArbitraryUserPointer = (PVOID)FullDllName.Buffer; 01954 NtMapViewOfSection( 01955 Section, 01956 NtCurrentProcess(), 01957 (PVOID *)&ViewBase, 01958 0L, 01959 0L, 01960 NULL, 01961 &ViewSize, 01962 ViewShare, 01963 0L, 01964 PAGE_READWRITE 01965 ); 01966 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer; 01967 01968 if (ShowSnaps) { 01969 DbgPrint("LDR: Fixups won't be re-applied to non-Dll @ %lx\n", 01970 ViewBase); 01971 } 01972 } 01973 } 01974 01975 #if defined (_ALPHA_) 01976 01977 // 01978 // Find and apply Alpha architecture fixups for this dll 01979 // 01980 if (Entry->Flags & LDRP_IMAGE_DLL) 01981 AlphaFindArchitectureFixups(NtHeaders, ViewBase, StaticLink); 01982 #endif 01983 01984 #if defined(_X86_) 01985 if ( LdrpNumberOfProcessors > 1 && Entry && (Entry->Flags & LDRP_IMAGE_DLL) ) { 01986 LdrpValidateImageForMp(Entry); 01987 } 01988 #endif 01989 NtClose(Section); 01990 return st; 01991 }

USHORT LdrpNameToOrdinal IN PSZ  Name,
IN ULONG  NumberOfNames,
IN PVOID  DllBase,
IN PULONG  NameTableBase,
IN PUSHORT  NameOrdinalTableBase
 

Definition at line 2747 of file ldrsnap.c.

References Name, and USHORT.

Referenced by LdrpSnapThunk().

02754 { 02755 LONG High; 02756 LONG Low; 02757 LONG Middle; 02758 LONG Result; 02759 02760 // 02761 // Lookup the import name in the name table using a binary search. 02762 // 02763 02764 Low = 0; 02765 High = NumberOfNames - 1; 02766 while (High >= Low) { 02767 02768 // 02769 // Compute the next probe index and compare the import name 02770 // with the export name entry. 02771 // 02772 02773 Middle = (Low + High) >> 1; 02774 Result = strcmp(Name, (PCHAR)((ULONG_PTR)DllBase + NameTableBase[Middle])); 02775 02776 if (Result < 0) { 02777 High = Middle - 1; 02778 02779 } else if (Result > 0) { 02780 Low = Middle + 1; 02781 02782 } else { 02783 break; 02784 } 02785 } 02786 02787 // 02788 // If the high index is less than the low index, then a matching 02789 // table entry was not found. Otherwise, get the ordinal number 02790 // from the ordinal table. 02791 // 02792 02793 if (High < Low) { 02794 return (USHORT)-1; 02795 } else { 02796 return NameOrdinalTableBase[Middle]; 02797 } 02798 02799 }

BOOLEAN LdrpResolveDllName IN PWSTR DllPath  OPTIONAL,
IN PWSTR  DllName,
OUT PUNICODE_STRING  FullDllName,
OUT PUNICODE_STRING  BaseDllName,
OUT PHANDLE  DllFile
 

Definition at line 3120 of file ldrsnap.c.

References DbgPrint, FALSE, LDR_TAG, LdrpDefaultPath, MAKE_TAG, NULL, RtlAllocateHeap, RtlDosSearchPath_U(), RtlFreeHeap, RtlFreeUnicodeString(), ShowSnaps, TEMP_TAG, TRUE, and USHORT.

Referenced by LdrpMapDll().

03130 : 03131 03132 This function computes the DLL pathname and base dll name (the 03133 unqualified, extensionless portion of the file name) for the specified 03134 DLL. 03135 03136 Arguments: 03137 03138 DllPath - Supplies the DLL search path. 03139 03140 DllName - Supplies the name of the DLL. 03141 03142 FullDllName - Returns the fully qualified pathname of the 03143 DLL. The Buffer field of this string is dynamically 03144 allocated from the processes heap. 03145 03146 BaseDLLName - Returns the base dll name of the dll. The base name 03147 is the file name portion of the dll path without the trailing 03148 extension. The Buffer field of this string is dynamically 03149 allocated from the processes heap. 03150 03151 DllFile - Returns an open handle to the DLL file. This parameter may 03152 still be NULL even upon success. 03153 03154 Return Value: 03155 03156 TRUE - The operation was successful. A DLL file was found, and the 03157 FullDllName->Buffer & BaseDllName->Buffer field points to the 03158 base of process heap allocated memory. 03159 03160 FALSE - The DLL could not be found. 03161 03162 --*/ 03163 03164 { 03165 ULONG Length; 03166 PWCH p, pp; 03167 PWCH FullBuffer; 03168 03169 *DllFile = NULL; 03170 FullDllName->Buffer = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( TEMP_TAG ),530+sizeof(UNICODE_NULL)); 03171 if (FullDllName->Buffer == NULL) { 03172 return FALSE; 03173 } 03174 03175 Length = RtlDosSearchPath_U( 03176 ARGUMENT_PRESENT(DllPath) ? DllPath : LdrpDefaultPath.Buffer, 03177 DllName, 03178 NULL, 03179 530, 03180 FullDllName->Buffer, 03181 &BaseDllName->Buffer 03182 ); 03183 03184 if ( !Length || Length > 530 ) { 03185 03186 if (ShowSnaps) { 03187 DbgPrint("LDR: LdrResolveDllName - Unable To Locate "); 03188 DbgPrint("%ws from %ws\n", 03189 DllName, 03190 ARGUMENT_PRESENT(DllPath) ? DllPath : LdrpDefaultPath.Buffer 03191 ); 03192 } 03193 03194 RtlFreeUnicodeString(FullDllName); 03195 return FALSE; 03196 } 03197 03198 FullDllName->Length = (USHORT)Length; 03199 FullDllName->MaximumLength = FullDllName->Length + (USHORT)sizeof(UNICODE_NULL); 03200 FullBuffer = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( LDR_TAG ),FullDllName->MaximumLength); 03201 if ( FullBuffer ) { 03202 RtlCopyMemory(FullBuffer,FullDllName->Buffer,FullDllName->MaximumLength); 03203 RtlFreeHeap(RtlProcessHeap(), 0, FullDllName->Buffer); 03204 FullDllName->Buffer = FullBuffer; 03205 } 03206 else { 03207 return FALSE; 03208 } 03209 // 03210 // Compute Length of base dll name 03211 // 03212 03213 pp = UNICODE_NULL; 03214 p = FullDllName->Buffer; 03215 while (*p) { 03216 if (*p++ == (WCHAR)'\\') { 03217 pp = p; 03218 } 03219 } 03220 03221 p = pp ? pp : DllName; 03222 pp = p; 03223 03224 while (*p) { 03225 ++p; 03226 } 03227 03228 BaseDllName->Length = (USHORT)((ULONG_PTR)p - (ULONG_PTR)pp); 03229 BaseDllName->MaximumLength = BaseDllName->Length + (USHORT)sizeof(UNICODE_NULL); 03230 BaseDllName->Buffer = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( LDR_TAG ), BaseDllName->MaximumLength); 03231 if ( BaseDllName->Buffer ) { 03232 RtlMoveMemory(BaseDllName->Buffer, 03233 pp, 03234 BaseDllName->Length 03235 ); 03236 03237 BaseDllName->Buffer[BaseDllName->Length >> 1] = UNICODE_NULL; 03238 } 03239 else { 03240 RtlFreeHeap(RtlProcessHeap(), 0, FullBuffer); 03241 return FALSE; 03242 } 03243 03244 return TRUE; 03245 }

NTSTATUS LdrpRunInitializeRoutines IN PCONTEXT Context  OPTIONAL  ) 
 

Definition at line 652 of file ldrsnap.c.

References DbgPrint, L, LdrpCallInitRoutine, LdrpCallTlsInitializers(), LdrpClearLoadInProgress(), LdrpImageHasTls, LdrQueryImageFileExecutionOptions(), MAKE_TAG, NT_SUCCESS, NTSTATUS(), NULL, RtlAllocateHeap, RtlFreeHeap, RtlImageNtHeader(), ShowSnaps, Status, TEMP_TAG, and TRUE.

Referenced by LdrpGetProcedureAddress(), LdrpInitializeProcess(), and LdrpLoadDll().

00655 { 00656 PLIST_ENTRY Head, Next; 00657 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; 00658 PLDR_DATA_TABLE_ENTRY *LdrDataTableBase; 00659 PDLL_INIT_ROUTINE InitRoutine; 00660 BOOLEAN InitStatus; 00661 ULONG NumberOfRoutines; 00662 ULONG i; 00663 NTSTATUS Status; 00664 ULONG BreakOnDllLoad; 00665 00666 // 00667 // Run the Init routines 00668 // 00669 00670 // 00671 // capture the entries that have init routines 00672 // 00673 00674 NumberOfRoutines = LdrpClearLoadInProgress(); 00675 if ( NumberOfRoutines ) { 00676 LdrDataTableBase = RtlAllocateHeap(RtlProcessHeap(),MAKE_TAG( TEMP_TAG ),NumberOfRoutines*sizeof(LdrDataTableBase)); 00677 if ( !LdrDataTableBase ) { 00678 return STATUS_NO_MEMORY; 00679 } 00680 } 00681 else { 00682 LdrDataTableBase = NULL; 00683 } 00684 00685 Head = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList; 00686 Next = Head->Flink; 00687 if (ShowSnaps) { 00688 DbgPrint("LDR: Real INIT LIST\n"); 00689 } 00690 00691 i = 0; 00692 while ( Next != Head ) { 00693 LdrDataTableEntry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks); 00694 00695 #if defined (WX86) 00696 if (Wx86ProcessInit && !(LdrDataTableEntry->Flags & LDRP_ENTRY_PROCESSED)) { 00697 PIMAGE_NT_HEADERS NtHeaders; 00698 00699 NtHeaders = RtlImageNtHeader(LdrDataTableEntry->DllBase); 00700 if (NtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) { 00701 LdrpWx86DllMapNotify(LdrDataTableEntry->DllBase, TRUE); 00702 } 00703 } 00704 #endif 00705 00706 if ( !(LdrDataTableEntry->Flags & LDRP_ENTRY_PROCESSED) && LdrDataTableEntry->EntryPoint) { 00707 LdrDataTableBase[i] = LdrDataTableEntry; 00708 if (ShowSnaps) { 00709 DbgPrint(" %wZ init routine %x\n", 00710 &LdrDataTableEntry->FullDllName, 00711 LdrDataTableEntry->EntryPoint 00712 ); 00713 } 00714 00715 i++; 00716 } 00717 LdrDataTableEntry->Flags |= LDRP_ENTRY_PROCESSED; 00718 00719 Next = Next->Flink; 00720 } 00721 if ( !LdrDataTableBase ) { 00722 return STATUS_SUCCESS; 00723 } 00724 00725 try { 00726 i = 0; 00727 while ( i < NumberOfRoutines ) { 00728 LdrDataTableEntry = LdrDataTableBase[i]; 00729 i++; 00730 InitRoutine = (PDLL_INIT_ROUTINE)LdrDataTableEntry->EntryPoint; 00731 00732 // 00733 // Walk through the entire list looking for un-processed 00734 // entries. For each entry, set the processed flag 00735 // and optionally call it's init routine 00736 // 00737 00738 BreakOnDllLoad = 0; 00739 #if DBG 00740 if (TRUE) { 00741 #else 00742 if (NtCurrentPeb()->BeingDebugged || NtCurrentPeb()->ReadImageFileExecOptions) { 00743 #endif 00744 Status = LdrQueryImageFileExecutionOptions( &LdrDataTableEntry->BaseDllName, 00745 L"BreakOnDllLoad", 00746 REG_DWORD, 00747 &BreakOnDllLoad, 00748 sizeof( BreakOnDllLoad ), 00749 NULL 00750 ); 00751 if (!NT_SUCCESS( Status )) { 00752 BreakOnDllLoad = 0; 00753 } 00754 } 00755 00756 if (BreakOnDllLoad) { 00757 if (ShowSnaps) { 00758 DbgPrint( "LDR: %wZ loaded.", &LdrDataTableEntry->BaseDllName ); 00759 DbgPrint( " - About to call init routine at %lx\n", InitRoutine ); 00760 } 00761 DbgBreakPoint(); 00762 00763 } 00764 else if (ShowSnaps) { 00765 if ( InitRoutine ) { 00766 DbgPrint( "LDR: %wZ loaded.", &LdrDataTableEntry->BaseDllName ); 00767 DbgPrint(" - Calling init routine at %lx\n", InitRoutine); 00768 } 00769 } 00770 00771 if ( InitRoutine ) { 00772 00773 // 00774 // If the DLL has TLS data, then call the optional initializers 00775 // 00776 00777 00778 00779 if ( LdrDataTableEntry->TlsIndex && Context) { 00780 LdrpCallTlsInitializers(LdrDataTableEntry->DllBase,DLL_PROCESS_ATTACH); 00781 } 00782 00783 #if defined (WX86) 00784 if (!Wx86ProcessInit || 00785 LdrpRunWx86DllEntryPoint(InitRoutine, 00786 &InitStatus, 00787 LdrDataTableEntry->DllBase, 00788 DLL_PROCESS_ATTACH, 00789 Context 00790 ) == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) 00791 { 00792 InitStatus = LdrpCallInitRoutine(InitRoutine, 00793 LdrDataTableEntry->DllBase, 00794 DLL_PROCESS_ATTACH, 00795 Context 00796 ); 00797 } 00798 00799 #else 00800 InitStatus = LdrpCallInitRoutine(InitRoutine, 00801 LdrDataTableEntry->DllBase, 00802 DLL_PROCESS_ATTACH, 00803 Context 00804 ); 00805 #endif 00806 00807 LdrDataTableEntry->Flags |= LDRP_PROCESS_ATTACH_CALLED; 00808 00809 if ( !InitStatus ) { 00810 return STATUS_DLL_INIT_FAILED; 00811 } 00812 } 00813 } 00814 00815 // 00816 // If the image has tls than call its initializers 00817 // 00818 00819 if ( LdrpImageHasTls && Context ) { 00820 LdrpCallTlsInitializers(NtCurrentPeb()->ImageBaseAddress,DLL_PROCESS_ATTACH); 00821 } 00822 00823 } 00824 finally { 00825 RtlFreeHeap(RtlProcessHeap(),0,LdrDataTableBase); 00826 } 00827 00828 return STATUS_SUCCESS; 00829 }

NTSTATUS LdrpSetProtection IN PVOID  Base,
IN BOOLEAN  Reset,
IN BOOLEAN  StaticLink
 

Definition at line 3417 of file ldrsnap.c.

References NT_SUCCESS, NtFlushInstructionCache(), NtProtectVirtualMemory(), NTSTATUS(), NULL, PAGE_SIZE, and RtlImageNtHeader().

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

03425 : 03426 03427 This function loops thru the images sections/objects, setting 03428 all sections/objects marked r/o to r/w. It also resets the 03429 original section/object protections. 03430 03431 Arguments: 03432 03433 Base - Base of image. 03434 03435 Reset - If TRUE, reset section/object protection to original 03436 protection described by the section/object headers. 03437 If FALSE, then set all sections/objects to r/w. 03438 03439 StaticLink - TRUE if this is a static link. 03440 03441 Return Value: 03442 03443 SUCCESS or reason NtProtectVirtualMemory failed. 03444 03445 --*/ 03446 03447 { 03448 HANDLE CurrentProcessHandle; 03449 SIZE_T RegionSize; 03450 ULONG NewProtect, OldProtect; 03451 PVOID VirtualAddress; 03452 ULONG i; 03453 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry; 03454 PIMAGE_NT_HEADERS NtHeaders; 03455 PIMAGE_SECTION_HEADER SectionHeader; 03456 NTSTATUS st; 03457 03458 CurrentProcessHandle = NtCurrentProcess(); 03459 03460 NtHeaders = RtlImageNtHeader(Base); 03461 03462 #if defined (_ALPHA_) 03463 if (NtHeaders->OptionalHeader.SectionAlignment < PAGE_SIZE) { 03464 // 03465 // if SectionAlignment < PAGE_SIZE the entire image is 03466 // exec-copy on write, so we have nothing to do. 03467 // 03468 return STATUS_SUCCESS; 03469 } 03470 #endif 03471 03472 SectionHeader = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NtHeaders + sizeof(ULONG) + 03473 sizeof(IMAGE_FILE_HEADER) + 03474 NtHeaders->FileHeader.SizeOfOptionalHeader 03475 ); 03476 03477 for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) { 03478 if (!(SectionHeader->Characteristics & IMAGE_SCN_MEM_WRITE) && 03479 (SectionHeader->SizeOfRawData)) 03480 { 03481 // 03482 // Object isn't writeable and has a non-zero on disk size, change it. 03483 // 03484 if (Reset) { 03485 if (SectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) { 03486 NewProtect = PAGE_EXECUTE; 03487 } else { 03488 NewProtect = PAGE_READONLY; 03489 } 03490 NewProtect |= (SectionHeader->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) ? PAGE_NOCACHE : 0; 03491 } else { 03492 NewProtect = PAGE_READWRITE; 03493 } 03494 VirtualAddress = (PVOID)((ULONG_PTR)Base + SectionHeader->VirtualAddress); 03495 RegionSize = SectionHeader->SizeOfRawData; 03496 03497 if (RegionSize != 0) { 03498 st = NtProtectVirtualMemory(CurrentProcessHandle, &VirtualAddress, 03499 &RegionSize, NewProtect, &OldProtect); 03500 03501 if (!NT_SUCCESS(st)) { 03502 return st; 03503 } 03504 } 03505 03506 } 03507 ++SectionHeader; 03508 } 03509 03510 if (Reset) { 03511 NtFlushInstructionCache(NtCurrentProcess(), NULL, 0); 03512 } 03513 return STATUS_SUCCESS; 03514 }

NTSTATUS LdrpSnapIAT IN PLDR_DATA_TABLE_ENTRY  LdrDataTableEntry_Export,
IN PLDR_DATA_TABLE_ENTRY  LdrDataTableEntry_Import,
IN PIMAGE_IMPORT_DESCRIPTOR  ImportDescriptor,
IN BOOLEAN  SnapForwardersOnly
 

Definition at line 2258 of file ldrsnap.c.

References EXCEPTION_EXECUTE_HANDLER, LdrpSnapThunk(), NT_SUCCESS, NtFlushInstructionCache(), NtProtectVirtualMemory(), NTSTATUS(), NULL, RtlImageDirectoryEntryToData(), RtlImageNtHeader(), and TRUE.

Referenced by LdrpWalkImportDescriptor().

02267 : 02268 02269 This function snaps the Import Address Table for this 02270 Import Descriptor. 02271 02272 Arguments: 02273 02274 LdrDataTableEntry_Export - Information about the image to import from. 02275 02276 LdrDataTableEntry_Import - Information about the image to import to. 02277 02278 ImportDescriptor - Contains a pointer to the IAT to snap. 02279 02280 SnapForwardersOnly - TRUE if just snapping forwarders only. 02281 02282 Return Value: 02283 02284 Status value 02285 02286 --*/ 02287 02288 { 02289 PPEB Peb; 02290 NTSTATUS st; 02291 ULONG ExportSize; 02292 PIMAGE_EXPORT_DIRECTORY ExportDirectory; 02293 PIMAGE_THUNK_DATA Thunk, OriginalThunk; 02294 PSZ ImportName; 02295 ULONG ForwarderChain; 02296 PIMAGE_NT_HEADERS NtHeaders; 02297 PIMAGE_SECTION_HEADER NtSection; 02298 ULONG i, Rva; 02299 PVOID IATBase; 02300 SIZE_T IATSize; 02301 ULONG LittleIATSize; 02302 ULONG OldProtect; 02303 02304 Peb = NtCurrentPeb(); 02305 02306 ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData( 02307 LdrDataTableEntry_Export->DllBase, 02308 TRUE, 02309 IMAGE_DIRECTORY_ENTRY_EXPORT, 02310 &ExportSize 02311 ); 02312 02313 if (!ExportDirectory) { 02314 KdPrint(("LDR: %wZ doesn't contain an EXPORT table\n", &LdrDataTableEntry_Export->BaseDllName)); 02315 return STATUS_INVALID_IMAGE_FORMAT; 02316 } 02317 02318 // 02319 // Determine the location and size of the IAT. If the linker did 02320 // not tell use explicitly, then use the location and size of the 02321 // image section that contains the import table. 02322 // 02323 02324 IATBase = RtlImageDirectoryEntryToData( LdrDataTableEntry_Import->DllBase, 02325 TRUE, 02326 IMAGE_DIRECTORY_ENTRY_IAT, 02327 &LittleIATSize 02328 ); 02329 IATSize = LittleIATSize; 02330 if (IATBase == NULL) { 02331 NtHeaders = RtlImageNtHeader( LdrDataTableEntry_Import->DllBase ); 02332 NtSection = IMAGE_FIRST_SECTION( NtHeaders ); 02333 Rva = NtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress; 02334 if (Rva != 0) { 02335 for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) { 02336 if (Rva >= NtSection->VirtualAddress && 02337 Rva < (NtSection->VirtualAddress + NtSection->SizeOfRawData) 02338 ) { 02339 IATBase = (PVOID) 02340 ((ULONG_PTR)(LdrDataTableEntry_Import->DllBase) + NtSection->VirtualAddress); 02341 02342 LittleIATSize = NtSection->Misc.VirtualSize; 02343 if (LittleIATSize == 0) { 02344 LittleIATSize = NtSection->SizeOfRawData; 02345 } 02346 break; 02347 } 02348 02349 ++NtSection; 02350 } 02351 } 02352 02353 if (IATBase == NULL) { 02354 KdPrint(( "LDR: Unable to unprotect IAT for %wZ (Image Base %x)\n", 02355 &LdrDataTableEntry_Import->BaseDllName, 02356 LdrDataTableEntry_Import->DllBase 02357 )); 02358 return STATUS_INVALID_IMAGE_FORMAT; 02359 } 02360 IATSize = LittleIATSize; 02361 } 02362 02363 st = NtProtectVirtualMemory( NtCurrentProcess(), 02364 &IATBase, 02365 &IATSize, 02366 PAGE_READWRITE, 02367 &OldProtect 02368 ); 02369 if (!NT_SUCCESS(st)) { 02370 KdPrint(( "LDR: Unable to unprotect IAT for %wZ (Status %x)\n", 02371 &LdrDataTableEntry_Import->BaseDllName, 02372 st 02373 )); 02374 return st; 02375 } 02376 02377 // 02378 // If just snapping forwarded entries, walk that list 02379 // 02380 if (SnapForwardersOnly) { 02381 ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry_Import->DllBase + ImportDescriptor->Name); 02382 ForwarderChain = ImportDescriptor->ForwarderChain; 02383 while (ForwarderChain != -1) { 02384 OriginalThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry_Import->DllBase + 02385 ImportDescriptor->OriginalFirstThunk + 02386 (ForwarderChain * sizeof(IMAGE_THUNK_DATA))); 02387 Thunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry_Import->DllBase + 02388 ImportDescriptor->FirstThunk + 02389 (ForwarderChain * sizeof(IMAGE_THUNK_DATA))); 02390 ForwarderChain = (ULONG) Thunk->u1.Ordinal; 02391 try { 02392 st = LdrpSnapThunk(LdrDataTableEntry_Export->DllBase, 02393 LdrDataTableEntry_Import->DllBase, 02394 OriginalThunk, 02395 Thunk, 02396 ExportDirectory, 02397 ExportSize, 02398 TRUE, 02399 ImportName 02400 ); 02401 Thunk++; 02402 } 02403 except (EXCEPTION_EXECUTE_HANDLER) { 02404 st = GetExceptionCode(); 02405 } 02406 if (!NT_SUCCESS(st) ) { 02407 break; 02408 } 02409 } 02410 } 02411 else 02412 02413 // 02414 // Otherwise, walk through the IAT and snap all the thunks. 02415 // 02416 02417 if ( ImportDescriptor->FirstThunk ) { 02418 Thunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry_Import->DllBase + ImportDescriptor->FirstThunk); 02419 02420 NtHeaders = RtlImageNtHeader( LdrDataTableEntry_Import->DllBase ); 02421 // 02422 // If the OriginalFirstThunk field does not point inside the image, then ignore 02423 // it. This is will detect bogus Borland Linker 2.25 images that did not fill 02424 // this field in. 02425 // 02426 02427 if (ImportDescriptor->Characteristics < NtHeaders->OptionalHeader.SizeOfHeaders || 02428 ImportDescriptor->Characteristics >= NtHeaders->OptionalHeader.SizeOfImage 02429 ) { 02430 OriginalThunk = Thunk; 02431 } else { 02432 OriginalThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry_Import->DllBase + 02433 ImportDescriptor->OriginalFirstThunk); 02434 } 02435 ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry_Import->DllBase + ImportDescriptor->Name); 02436 while (OriginalThunk->u1.AddressOfData) { 02437 try { 02438 st = LdrpSnapThunk(LdrDataTableEntry_Export->DllBase, 02439 LdrDataTableEntry_Import->DllBase, 02440 OriginalThunk, 02441 Thunk, 02442 ExportDirectory, 02443 ExportSize, 02444 TRUE, 02445 ImportName 02446 ); 02447 OriginalThunk++; 02448 Thunk++; 02449 } 02450 except (EXCEPTION_EXECUTE_HANDLER) { 02451 st = GetExceptionCode(); 02452 } 02453 02454 if (!NT_SUCCESS(st) ) { 02455 break; 02456 } 02457 } 02458 } 02459 02460 // 02461 // Restore protection for IAT and flush instruction cache. 02462 // 02463 02464 NtProtectVirtualMemory( NtCurrentProcess(), 02465 &IATBase, 02466 &IATSize, 02467 OldProtect, 02468 &OldProtect 02469 ); 02470 NtFlushInstructionCache( NtCurrentProcess(), IATBase, LittleIATSize ); 02471 02472 return st; 02473 }

NTSTATUS LdrpSnapLinksToDllHandle IN PVOID  DllHandle,
IN ULONG  NumberOfThunks,
IN OUT PIMAGE_THUNK_DATA  FirstThunk
 

NTSTATUS LdrpSnapThunk IN PVOID  DllBase,
IN PVOID  ImageBase,
IN PIMAGE_THUNK_DATA  OriginalThunk,
IN OUT PIMAGE_THUNK_DATA  Thunk,
IN PIMAGE_EXPORT_DIRECTORY  ExportDirectory,
IN ULONG  ExportSize,
IN BOOLEAN  StaticSnap,
IN PSZ DllName  OPTIONAL
 

Definition at line 2476 of file ldrsnap.c.

References DbgPrint, FALSE, LDRP_BAD_DLL, LdrpFatalHardErrorCount, LdrpGetProcedureAddress(), LdrpInLdrInit, LdrpLoadDll(), LdrpNameToOrdinal(), NT_SUCCESS, NtRaiseHardError(), NTSTATUS(), NULL, PAGE_SIZE, PUSHORT, RtlAnsiStringToUnicodeString(), RtlCharToInteger(), RtlFreeUnicodeString(), RtlImageNtHeader(), RtlInitAnsiString(), RtlRaiseStatus(), ShowSnaps, TRUE, and USHORT.

Referenced by LdrpGetProcedureAddress(), and LdrpSnapIAT().

02489 : 02490 02491 This function snaps a thunk using the specified Export Section data. 02492 If the section data does not support the thunk, then the thunk is 02493 partially snapped (Dll field is still non-null, but snap address is 02494 set). 02495 02496 Arguments: 02497 02498 DllBase - Base of Dll. 02499 02500 ImageBase - Base of image that contains the thunks to snap. 02501 02502 Thunk - On input, supplies the thunk to snap. When successfully 02503 snapped, the function field is set to point to the address in 02504 the DLL, and the DLL field is set to NULL. 02505 02506 ExportDirectory - Supplies the Export Section data from a DLL. 02507 02508 StaticSnap - If TRUE, then loader is attempting a static snap, 02509 and any ordinal/name lookup failure will be reported. 02510 02511 Return Value: 02512 02513 STATUS_SUCCESS or STATUS_PROCEDURE_NOT_FOUND 02514 02515 --*/ 02516 02517 { 02518 BOOLEAN Ordinal; 02519 USHORT OrdinalNumber; 02520 ULONG OriginalOrdinalNumber; 02521 PIMAGE_IMPORT_BY_NAME AddressOfData; 02522 PULONG NameTableBase; 02523 PUSHORT NameOrdinalTableBase; 02524 PULONG Addr; 02525 USHORT HintIndex; 02526 NTSTATUS st; 02527 PSZ ImportString; 02528 02529 // 02530 // Determine if snap is by name, or by ordinal 02531 // 02532 02533 Ordinal = (BOOLEAN)IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal); 02534 02535 if (Ordinal) { 02536 OriginalOrdinalNumber = (ULONG)IMAGE_ORDINAL(OriginalThunk->u1.Ordinal); 02537 OrdinalNumber = (USHORT)(OriginalOrdinalNumber - ExportDirectory->Base); 02538 } else { 02539 // 02540 // Change AddressOfData from an RVA to a VA. 02541 // 02542 02543 AddressOfData = (PIMAGE_IMPORT_BY_NAME)((ULONG_PTR)ImageBase + ((ULONG_PTR)OriginalThunk->u1.AddressOfData & 0xffffffff)); 02544 ImportString = (PSZ)AddressOfData->Name; 02545 02546 // 02547 // Lookup Name in NameTable 02548 // 02549 02550 NameTableBase = (PULONG)((ULONG_PTR)DllBase + (ULONG)ExportDirectory->AddressOfNames); 02551 NameOrdinalTableBase = (PUSHORT)((ULONG_PTR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals); 02552 02553 // 02554 // Before dropping into binary search, see if 02555 // the hint index results in a successful 02556 // match. If the hint index is zero, then 02557 // drop into binary search. 02558 // 02559 02560 HintIndex = AddressOfData->Hint; 02561 if ((ULONG)HintIndex < ExportDirectory->NumberOfNames && 02562 !strcmp(ImportString, (PSZ)((ULONG_PTR)DllBase + NameTableBase[HintIndex]))) { 02563 OrdinalNumber = NameOrdinalTableBase[HintIndex]; 02564 #if LDRDBG 02565 if (ShowSnaps) { 02566 DbgPrint("LDR: Snapping %s\n", ImportString); 02567 } 02568 #endif 02569 } else { 02570 #if LDRDBG 02571 if (HintIndex) { 02572 DbgPrint("LDR: Warning HintIndex Failure. Name %s (%lx) Hint 0x%lx\n", 02573 ImportString, 02574 (ULONG)ImportString, 02575 (ULONG)HintIndex 02576 ); 02577 } 02578 #endif 02579 OrdinalNumber = LdrpNameToOrdinal( 02580 ImportString, 02581 ExportDirectory->NumberOfNames, 02582 DllBase, 02583 NameTableBase, 02584 NameOrdinalTableBase 02585 ); 02586 } 02587 } 02588 02589 // 02590 // If OrdinalNumber is not within the Export Address Table, 02591 // then DLL does not implement function. Snap to LDRP_BAD_DLL. 02592 // 02593 02594 if ((ULONG)OrdinalNumber >= ExportDirectory->NumberOfFunctions) { 02595 baddllref: 02596 #if DBG 02597 if (StaticSnap) { 02598 if (Ordinal) { 02599 DbgPrint("LDR: Can't locate ordinal 0x%lx\n", OriginalOrdinalNumber); 02600 } 02601 else { 02602 DbgPrint("LDR: Can't locate %s\n", ImportString); 02603 } 02604 } 02605 #endif 02606 if ( StaticSnap ) { 02607 // 02608 // Hard Error Time 02609 // 02610 02611 ULONG_PTR ErrorParameters[3]; 02612 UNICODE_STRING ErrorDllName, ErrorEntryPointName; 02613 ANSI_STRING AnsiScratch; 02614 ULONG ParameterStringMask; 02615 ULONG ErrorResponse; 02616 02617 RtlInitAnsiString(&AnsiScratch,DllName ? DllName : "Unknown"); 02618 RtlAnsiStringToUnicodeString(&ErrorDllName,&AnsiScratch,TRUE); 02619 ErrorParameters[1] = (ULONG_PTR)&ErrorDllName; 02620 ParameterStringMask = 2; 02621 02622 if ( Ordinal ) { 02623 ErrorParameters[0] = OriginalOrdinalNumber; 02624 } 02625 else { 02626 RtlInitAnsiString(&AnsiScratch,ImportString); 02627 RtlAnsiStringToUnicodeString(&ErrorEntryPointName,&AnsiScratch,TRUE); 02628 ErrorParameters[0] = (ULONG_PTR)&ErrorEntryPointName; 02629 ParameterStringMask = 3; 02630 } 02631 02632 02633 NtRaiseHardError( 02634 Ordinal ? STATUS_ORDINAL_NOT_FOUND : STATUS_ENTRYPOINT_NOT_FOUND, 02635 2, 02636 ParameterStringMask, 02637 ErrorParameters, 02638 OptionOk, 02639 &ErrorResponse 02640 ); 02641 02642 if ( LdrpInLdrInit ) { 02643 LdrpFatalHardErrorCount++; 02644 } 02645 RtlFreeUnicodeString(&ErrorDllName); 02646 if ( !Ordinal ) { 02647 RtlFreeUnicodeString(&ErrorEntryPointName); 02648 RtlRaiseStatus(STATUS_ENTRYPOINT_NOT_FOUND); 02649 } 02650 RtlRaiseStatus(STATUS_ORDINAL_NOT_FOUND); 02651 } 02652 Thunk->u1.Function = (ULONG_PTR)LDRP_BAD_DLL; 02653 st = Ordinal ? STATUS_ORDINAL_NOT_FOUND : STATUS_ENTRYPOINT_NOT_FOUND; 02654 } else { 02655 Addr = (PULONG)((ULONG_PTR)DllBase + (ULONG)ExportDirectory->AddressOfFunctions); 02656 Thunk->u1.Function = ((ULONG_PTR)DllBase + Addr[OrdinalNumber]); 02657 if (Thunk->u1.Function > (ULONG_PTR)ExportDirectory && 02658 Thunk->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize) 02659 ) { 02660 UNICODE_STRING UnicodeString; 02661 ANSI_STRING ForwardDllName; 02662 PVOID ForwardDllHandle; 02663 PUNICODE_STRING ForwardProcName; 02664 ULONG ForwardProcOrdinal; 02665 02666 ImportString = (PSZ)Thunk->u1.Function; 02667 ForwardDllName.Buffer = ImportString, 02668 ForwardDllName.Length = (USHORT)(strchr(ImportString, '.') - ImportString); 02669 ForwardDllName.MaximumLength = ForwardDllName.Length; 02670 st = RtlAnsiStringToUnicodeString(&UnicodeString, &ForwardDllName, TRUE); 02671 02672 if (NT_SUCCESS(st)) { 02673 #if defined (WX86) 02674 if (Wx86ProcessInit) { 02675 NtCurrentTeb()->Wx86Thread.UseKnownWx86Dll = RtlImageNtHeader(DllBase)->FileHeader.Machine 02676 == IMAGE_FILE_MACHINE_I386; 02677 02678 } 02679 #endif 02680 02681 02682 st = LdrpLoadDll(NULL, NULL, &UnicodeString, &ForwardDllHandle,FALSE); 02683 RtlFreeUnicodeString(&UnicodeString); 02684 } 02685 02686 if (!NT_SUCCESS(st)) { 02687 goto baddllref; 02688 } 02689 02690 RtlInitAnsiString( &ForwardDllName, 02691 ImportString + ForwardDllName.Length + 1 02692 ); 02693 if (ForwardDllName.Length > 1 && 02694 *ForwardDllName.Buffer == '#' 02695 ) { 02696 ForwardProcName = NULL; 02697 st = RtlCharToInteger( ForwardDllName.Buffer+1, 02698 0, 02699 &ForwardProcOrdinal 02700 ); 02701 if (!NT_SUCCESS(st)) { 02702 goto baddllref; 02703 } 02704 } 02705 else { 02706 ForwardProcName = (PUNICODE_STRING)&ForwardDllName; 02707 02708 // 02709 // Following line is not needed since this is a by name lookup 02710 // 02711 // 02712 //ForwardProcOrdinal = (ULONG)&ForwardDllName; 02713 // 02714 } 02715 02716 st = LdrpGetProcedureAddress( ForwardDllHandle, 02717 (PANSI_STRING )ForwardProcName, 02718 ForwardProcOrdinal, 02719 &(PVOID)Thunk->u1.Function, 02720 FALSE 02721 ); 02722 if (!NT_SUCCESS(st)) { 02723 goto baddllref; 02724 } 02725 } 02726 else { 02727 if ( !Addr[OrdinalNumber] ) { 02728 goto baddllref; 02729 } 02730 #if defined (_ALPHA_) && defined (WX86) 02731 else { 02732 PIMAGE_NT_HEADERS ExportNtHeaders = RtlImageNtHeader(DllBase); 02733 02734 if ((ExportNtHeaders->OptionalHeader.SectionAlignment < PAGE_SIZE) && 02735 (ExportNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)) { 02736 Thunk->u1.Function += LdrpWx86RelocatedFixupDiff(DllBase, Addr[OrdinalNumber]); 02737 } 02738 } 02739 #endif // defined (_ALPHA_) && defined (WX86) 02740 } 02741 st = STATUS_SUCCESS; 02742 } 02743 return st; 02744 }

VOID LdrpUpdateLoadCount IN PLDR_DATA_TABLE_ENTRY  LdrDataTableEntry,
IN BOOLEAN  IncrementCount
 

Definition at line 2802 of file ldrsnap.c.

References DbgPrint, FALSE, LdrpCheckForLoadedDll(), NT_SUCCESS, NTSTATUS(), NULL, RtlAnsiStringToUnicodeString(), RtlImageDirectoryEntryToData(), RtlImageNtHeader(), RtlInitAnsiString(), ShowSnaps, and TRUE.

02809 : 02810 02811 This function dereferences a loaded DLL adjusting its reference 02812 count. It then dereferences each dll referenced by this dll. 02813 02814 Arguments: 02815 02816 LdrDataTableEntry - Supplies the address of the DLL to dereference 02817 02818 IncrementCount - TRUE if adding one to LoadCount, O.W. subtracting one 02819 02820 Return Value: 02821 02822 None. 02823 02824 --*/ 02825 02826 { 02827 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor; 02828 PIMAGE_BOUND_IMPORT_DESCRIPTOR NewImportDescriptor; 02829 PIMAGE_BOUND_FORWARDER_REF NewImportForwarder; 02830 PSZ ImportName, NewImportStringBase; 02831 ULONG i, ImportSize, NewImportSize; 02832 ANSI_STRING AnsiString; 02833 PUNICODE_STRING ImportDescriptorName_U; 02834 PLDR_DATA_TABLE_ENTRY Entry; 02835 NTSTATUS st; 02836 BOOLEAN Wx86KnownDll = FALSE; 02837 PIMAGE_THUNK_DATA FirstThunk; 02838 02839 if (IncrementCount) 02840 if (LdrDataTableEntry->Flags & LDRP_LOAD_IN_PROGRESS) { 02841 return; 02842 } else { 02843 LdrDataTableEntry->Flags |= LDRP_LOAD_IN_PROGRESS; 02844 } 02845 else 02846 if (LdrDataTableEntry->Flags & LDRP_UNLOAD_IN_PROGRESS) { 02847 return; 02848 } else { 02849 LdrDataTableEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS; 02850 } 02851 02852 // 02853 // For each DLL used by this DLL, reference or dereference the DLL. 02854 // 02855 02856 ImportDescriptorName_U = &NtCurrentTeb()->StaticUnicodeString; 02857 02858 #if defined (WX86) 02859 if (Wx86ProcessInit) { 02860 Wx86KnownDll = RtlImageNtHeader(LdrDataTableEntry->DllBase)->FileHeader.Machine 02861 == IMAGE_FILE_MACHINE_I386; 02862 } 02863 #endif 02864 02865 02866 02867 02868 // 02869 // See if there is a bound import table. If so, walk that to 02870 // determine DLL names to reference or dereference. Avoids touching 02871 // the .idata section 02872 // 02873 NewImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData( 02874 LdrDataTableEntry->DllBase, 02875 TRUE, 02876 IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT, 02877 &NewImportSize 02878 ); 02879 if (NewImportDescriptor) { 02880 if (IncrementCount) { 02881 LdrDataTableEntry->Flags |= LDRP_LOAD_IN_PROGRESS; 02882 } else { 02883 LdrDataTableEntry->Flags |= LDRP_UNLOAD_IN_PROGRESS; 02884 } 02885 02886 NewImportStringBase = (LPSTR)NewImportDescriptor; 02887 while (NewImportDescriptor->OffsetModuleName) { 02888 ImportName = NewImportStringBase + 02889 NewImportDescriptor->OffsetModuleName; 02890 RtlInitAnsiString(&AnsiString, ImportName); 02891 st = RtlAnsiStringToUnicodeString(ImportDescriptorName_U, &AnsiString, FALSE); 02892 if ( NT_SUCCESS(st) ) { 02893 if (LdrpCheckForLoadedDll( NULL, 02894 ImportDescriptorName_U, 02895 TRUE, 02896 Wx86KnownDll, 02897 &Entry 02898 ) 02899 ) { 02900 if ( Entry->LoadCount != 0xffff ) { 02901 if (IncrementCount) { 02902 Entry->LoadCount++; 02903 02904 if (ShowSnaps) { 02905 DbgPrint("LDR: Refcount %wZ (%lx)\n", 02906 ImportDescriptorName_U, 02907 (ULONG)Entry->LoadCount 02908 ); 02909 } 02910 } else { 02911 Entry->LoadCount--; 02912 02913 if (ShowSnaps) { 02914 DbgPrint("LDR: Derefcount %wZ (%lx)\n", 02915 ImportDescriptorName_U, 02916 (ULONG)Entry->LoadCount 02917 ); 02918 } 02919 } 02920 } 02921 LdrpUpdateLoadCount(Entry, IncrementCount); 02922 } 02923 } 02924 02925 NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(NewImportDescriptor+1); 02926 for (i=0; i<NewImportDescriptor->NumberOfModuleForwarderRefs; i++) { 02927 ImportName = NewImportStringBase + 02928 NewImportForwarder->OffsetModuleName; 02929 02930 RtlInitAnsiString(&AnsiString, ImportName); 02931 st = RtlAnsiStringToUnicodeString(ImportDescriptorName_U, &AnsiString, FALSE); 02932 if ( NT_SUCCESS(st) ) { 02933 if (LdrpCheckForLoadedDll( NULL, 02934 ImportDescriptorName_U, 02935 TRUE, 02936 Wx86KnownDll, 02937 &Entry 02938 ) 02939 ) { 02940 if ( Entry->LoadCount != 0xffff ) { 02941 if (IncrementCount) { 02942 Entry->LoadCount++; 02943 02944 if (ShowSnaps) { 02945 DbgPrint("LDR: Refcount %wZ (%lx)\n", 02946 ImportDescriptorName_U, 02947 (ULONG)Entry->LoadCount 02948 ); 02949 } 02950 } else { 02951 Entry->LoadCount--; 02952 02953 if (ShowSnaps) { 02954 DbgPrint("LDR: Derefcount %wZ (%lx)\n", 02955 ImportDescriptorName_U, 02956 (ULONG)Entry->LoadCount 02957 ); 02958 } 02959 } 02960 } 02961 LdrpUpdateLoadCount(Entry, IncrementCount); 02962 } 02963 } 02964 02965 NewImportForwarder += 1; 02966 } 02967 02968 NewImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewImportForwarder; 02969 } 02970 02971 return; 02972 } 02973 02974 ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData( 02975 LdrDataTableEntry->DllBase, 02976 TRUE, 02977 IMAGE_DIRECTORY_ENTRY_IMPORT, 02978 &ImportSize 02979 ); 02980 if (ImportDescriptor) { 02981 02982 while (ImportDescriptor->Name && ImportDescriptor->FirstThunk) { 02983 02984 // 02985 // Match code in walk that skips references like this. IE3 had 02986 // some dll's with these bogus links to url.dll. On load, the url.dll 02987 // ref was skipped. On unload, it was not skipped because 02988 // this code was missing. 02989 // 02990 // Since the skip logic is only in the old style import 02991 // descriptor path, it is only duplicated here. 02992 // 02993 // check for import that has no references 02994 // 02995 FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->FirstThunk); 02996 if ( !FirstThunk->u1.Function ) { 02997 goto skipskippedimport; 02998 } 02999 03000 ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->Name); 03001 03002 RtlInitAnsiString(&AnsiString, ImportName); 03003 st = RtlAnsiStringToUnicodeString(ImportDescriptorName_U, &AnsiString, FALSE); 03004 if ( NT_SUCCESS(st) ) { 03005 if (LdrpCheckForLoadedDll( NULL, 03006 ImportDescriptorName_U, 03007 TRUE, 03008 Wx86KnownDll, 03009 &Entry 03010 ) 03011 ) { 03012 if ( Entry->LoadCount != 0xffff ) { 03013 if (IncrementCount) { 03014 Entry->LoadCount++; 03015 03016 if (ShowSnaps) { 03017 DbgPrint("LDR: Refcount %wZ (%lx)\n", 03018 ImportDescriptorName_U, 03019 (ULONG)Entry->LoadCount 03020 ); 03021 } 03022 } else { 03023 Entry->LoadCount--; 03024 03025 if (ShowSnaps) { 03026 DbgPrint("LDR: Derefcount %wZ (%lx)\n", 03027 ImportDescriptorName_U, 03028 (ULONG)Entry->LoadCount 03029 ); 03030 } 03031 } 03032 } 03033 LdrpUpdateLoadCount(Entry, IncrementCount); 03034 } 03035 } 03036 skipskippedimport: 03037 ++ImportDescriptor; 03038 } 03039 } 03040 }

NTSTATUS LdrpWalkImportDescriptor IN PWSTR DllPath  OPTIONAL,
IN PLDR_DATA_TABLE_ENTRY  LdrDataTableEntry
 

Definition at line 214 of file ldrsnap.c.

References DbgPrint, FALSE, LdrpDefineDllTag(), LdrpDphInitializeTargetDll(), LdrpLoadImportModule(), LdrpSnapIAT(), Name, NT_SUCCESS, NtProtectVirtualMemory(), NTSTATUS(), NULL, PAGE_SIZE, RtlAllocateHeap, RtlImageDirectoryEntryToData(), RtlImageNtHeader(), ShowSnaps, TRUE, and USHORT.

00221 : 00222 00223 This is a recursive routine which walks the Import Descriptor 00224 Table and loads each DLL that is referenced. 00225 00226 Arguments: 00227 00228 DllPath - Supplies an optional search path to be used to locate 00229 the DLL. 00230 00231 LdrDataTableEntry - Supplies the address of the data table entry 00232 to initialize. 00233 00234 Return Value: 00235 00236 Status value. 00237 00238 --*/ 00239 00240 { 00241 ULONG i, ImportSize, NewImportSize; 00242 BOOLEAN AlreadyLoaded, SnapForwardersOnly, StaleBinding; 00243 PLDR_DATA_TABLE_ENTRY DataTableEntry, FwdDataTableEntry; 00244 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor; 00245 PIMAGE_BOUND_IMPORT_DESCRIPTOR NewImportDescriptor; 00246 PIMAGE_BOUND_FORWARDER_REF NewImportForwarder; 00247 PSZ ImportName, NewImportName, NewFwdImportName, NewImportStringBase; 00248 NTSTATUS st; 00249 PIMAGE_NT_HEADERS ExportNtHeaders; 00250 PVOID ImportBase; 00251 ULONG RegionSize; 00252 PIMAGE_THUNK_DATA Thunk,Name; 00253 PIMAGE_THUNK_DATA FirstThunk; 00254 PPEB Peb = NtCurrentPeb(); 00255 00256 // 00257 // See if there is a bound import table. If so, walk that to 00258 // verify if the binding is good. If so, then succeed with 00259 // having touched the .idata section, as all the information 00260 // in the bound imports table is stored in the header. If any 00261 // are stale, then fall out into the unbound case. 00262 // 00263 NewImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData( 00264 LdrDataTableEntry->DllBase, 00265 TRUE, 00266 IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT, 00267 &NewImportSize 00268 ); 00269 00270 ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData( 00271 LdrDataTableEntry->DllBase, 00272 TRUE, 00273 IMAGE_DIRECTORY_ENTRY_IMPORT, 00274 &ImportSize 00275 ); 00276 00277 00278 if (NewImportDescriptor) { 00279 NewImportStringBase = (LPSTR)NewImportDescriptor; 00280 while (NewImportDescriptor->OffsetModuleName) { 00281 NewImportName = NewImportStringBase + 00282 NewImportDescriptor->OffsetModuleName; 00283 00284 if (ShowSnaps) { 00285 DbgPrint("LDR: %wZ bound to %s\n", 00286 &LdrDataTableEntry->BaseDllName, 00287 NewImportName 00288 ); 00289 } 00290 00291 st = LdrpLoadImportModule( DllPath, 00292 NewImportName, 00293 LdrDataTableEntry->DllBase, 00294 &DataTableEntry, 00295 &AlreadyLoaded 00296 ); 00297 if ( !NT_SUCCESS(st) ) { 00298 return st; 00299 } 00300 00301 // 00302 // Add to initialization list. 00303 // 00304 00305 if (!AlreadyLoaded) { 00306 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, 00307 &DataTableEntry->InInitializationOrderLinks); 00308 } 00309 00310 #if defined (_ALPHA_) && defined (WX86) 00311 ExportNtHeaders = RtlImageNtHeader(LdrDataTableEntry->DllBase); 00312 00313 if ((ExportNtHeaders->OptionalHeader.SectionAlignment < PAGE_SIZE) && 00314 (ExportNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)) { 00315 if (LdrpWx86DllHasRelocatedSharedSection(LdrDataTableEntry->DllBase)) { 00316 DataTableEntry->Flags |= LDRP_IMAGE_NOT_AT_BASE; 00317 } 00318 } 00319 #endif // defined (_ALPHA_) && defined (WX86) 00320 00321 if ( NewImportDescriptor->TimeDateStamp != DataTableEntry->TimeDateStamp || 00322 (DataTableEntry->Flags & LDRP_IMAGE_NOT_AT_BASE) ) { 00323 if (ShowSnaps) { 00324 DbgPrint("LDR: %wZ has stale binding to %s\n", 00325 &LdrDataTableEntry->BaseDllName, 00326 NewImportName 00327 ); 00328 } 00329 StaleBinding = TRUE; 00330 } else { 00331 #if DBG 00332 LdrpSnapBypass++; 00333 #endif 00334 if (ShowSnaps) { 00335 DbgPrint("LDR: %wZ has correct binding to %s\n", 00336 &LdrDataTableEntry->BaseDllName, 00337 NewImportName 00338 ); 00339 } 00340 StaleBinding = FALSE; 00341 } 00342 00343 NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(NewImportDescriptor+1); 00344 for (i=0; i<NewImportDescriptor->NumberOfModuleForwarderRefs; i++) { 00345 NewFwdImportName = NewImportStringBase + 00346 NewImportForwarder->OffsetModuleName; 00347 if (ShowSnaps) { 00348 DbgPrint("LDR: %wZ bound to %s via forwarder(s) from %wZ\n", 00349 &LdrDataTableEntry->BaseDllName, 00350 NewFwdImportName, 00351 &DataTableEntry->BaseDllName 00352 ); 00353 } 00354 00355 st = LdrpLoadImportModule( DllPath, 00356 NewFwdImportName, 00357 LdrDataTableEntry->DllBase, 00358 &FwdDataTableEntry, 00359 &AlreadyLoaded 00360 ); 00361 if ( NT_SUCCESS(st) ) { 00362 if (!AlreadyLoaded) { 00363 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, 00364 &FwdDataTableEntry->InInitializationOrderLinks); 00365 } 00366 } 00367 00368 if ( !NT_SUCCESS(st) || 00369 NewImportForwarder->TimeDateStamp != FwdDataTableEntry->TimeDateStamp || 00370 (FwdDataTableEntry->Flags & LDRP_IMAGE_NOT_AT_BASE ) ) { 00371 if (ShowSnaps) { 00372 DbgPrint("LDR: %wZ has stale binding to %s\n", 00373 &LdrDataTableEntry->BaseDllName, 00374 NewFwdImportName 00375 ); 00376 } 00377 StaleBinding = TRUE; 00378 } else { 00379 #if DBG 00380 LdrpSnapBypass++; 00381 #endif 00382 if (ShowSnaps) { 00383 DbgPrint("LDR: %wZ has correct binding to %s\n", 00384 &LdrDataTableEntry->BaseDllName, 00385 NewFwdImportName 00386 ); 00387 } 00388 } 00389 00390 NewImportForwarder += 1; 00391 } 00392 NewImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewImportForwarder; 00393 00394 if (StaleBinding) { 00395 #if DBG 00396 LdrpNormalSnap++; 00397 #endif 00398 // 00399 // Find the unbound import descriptor that matches this bound 00400 // import descriptor 00401 // 00402 00403 ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData( 00404 LdrDataTableEntry->DllBase, 00405 TRUE, 00406 IMAGE_DIRECTORY_ENTRY_IMPORT, 00407 &ImportSize 00408 ); 00409 00410 while (ImportDescriptor->Name) { 00411 ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->Name); 00412 if (!_stricmp(ImportName, NewImportName)) { 00413 break; 00414 } 00415 00416 ImportDescriptor += 1; 00417 } 00418 00419 if (!ImportDescriptor->Name) { 00420 return STATUS_OBJECT_NAME_INVALID; 00421 } 00422 00423 if (ShowSnaps) { 00424 DbgPrint("LDR: Stale Bind %s from %wZ\n",ImportName,&LdrDataTableEntry->BaseDllName); 00425 } 00426 00427 st = LdrpSnapIAT( 00428 DataTableEntry, 00429 LdrDataTableEntry, 00430 ImportDescriptor, 00431 FALSE 00432 ); 00433 00434 if (!NT_SUCCESS(st)) { 00435 return st; 00436 } 00437 } 00438 } 00439 } 00440 else 00441 if (ImportDescriptor) { 00442 // 00443 // For each DLL used by this DLL, load the dll. Then snap 00444 // the IAT, and call the DLL's init routine. 00445 // 00446 00447 while (ImportDescriptor->Name && ImportDescriptor->FirstThunk) { 00448 ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->Name); 00449 00450 // 00451 // check for import that has no references 00452 // 00453 FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->FirstThunk); 00454 if ( !FirstThunk->u1.Function ) { 00455 goto skipimport; 00456 } 00457 00458 if (ShowSnaps) { 00459 DbgPrint("LDR: %s used by %wZ\n", 00460 ImportName, 00461 &LdrDataTableEntry->BaseDllName 00462 ); 00463 } 00464 00465 00466 st = LdrpLoadImportModule( DllPath, 00467 ImportName, 00468 LdrDataTableEntry->DllBase, 00469 &DataTableEntry, 00470 &AlreadyLoaded 00471 ); 00472 if ( !NT_SUCCESS(st) ) { 00473 return st; 00474 } 00475 00476 if (ShowSnaps) { 00477 DbgPrint("LDR: Snapping imports for %wZ from %s\n", 00478 &LdrDataTableEntry->BaseDllName, 00479 ImportName 00480 ); 00481 } 00482 00483 // 00484 // If the image has been bound and the import date stamp 00485 // matches the date time stamp in the export modules header, 00486 // and the image was mapped at it's prefered base address, 00487 // then we are done. 00488 // 00489 00490 SnapForwardersOnly = FALSE; 00491 00492 if ( ImportDescriptor->OriginalFirstThunk ) { 00493 if ( ImportDescriptor->TimeDateStamp && 00494 ImportDescriptor->TimeDateStamp == DataTableEntry->TimeDateStamp && 00495 (! DataTableEntry->Flags & LDRP_IMAGE_NOT_AT_BASE) ) { 00496 #if DBG 00497 LdrpSnapBypass++; 00498 #endif 00499 if (ShowSnaps) { 00500 DbgPrint("LDR: Snap bypass %s from %wZ\n", 00501 ImportName, 00502 &LdrDataTableEntry->BaseDllName 00503 ); 00504 } 00505 00506 if (ImportDescriptor->ForwarderChain == -1) { 00507 goto bypass_snap; 00508 } 00509 00510 SnapForwardersOnly = TRUE; 00511 00512 } 00513 } 00514 #if DBG 00515 LdrpNormalSnap++; 00516 #endif 00517 // 00518 // Add to initialization list. 00519 // 00520 00521 if (!AlreadyLoaded) { 00522 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, 00523 &DataTableEntry->InInitializationOrderLinks); 00524 } 00525 st = LdrpSnapIAT( 00526 DataTableEntry, 00527 LdrDataTableEntry, 00528 ImportDescriptor, 00529 SnapForwardersOnly 00530 ); 00531 00532 if (!NT_SUCCESS(st)) { 00533 return st; 00534 } 00535 AlreadyLoaded = TRUE; 00536 bypass_snap: 00537 // 00538 // Add to initialization list. 00539 // 00540 00541 if (!AlreadyLoaded) { 00542 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, 00543 &DataTableEntry->InInitializationOrderLinks); 00544 } 00545 00546 skipimport: 00547 ++ImportDescriptor; 00548 } 00549 } 00550 00551 if (Peb->NtGlobalFlag & FLG_HEAP_ENABLE_TAG_BY_DLL) { 00552 PVOID IATBase; 00553 SIZE_T BigIATSize; 00554 ULONG LittleIATSize; 00555 PVOID *ProcAddresses; 00556 ULONG NumberOfProcAddresses; 00557 ULONG OldProtect; 00558 USHORT TagIndex; 00559 00560 // 00561 // Determine the location and size of the IAT. If found, scan the 00562 // IAT address to see if any are pointing to RtlAllocateHeap. If so 00563 // replace when with a pointer to a unique thunk function that will 00564 // replace the tag with a unique tag for this image. 00565 // 00566 00567 IATBase = RtlImageDirectoryEntryToData( LdrDataTableEntry->DllBase, 00568 TRUE, 00569 IMAGE_DIRECTORY_ENTRY_IAT, 00570 &LittleIATSize 00571 ); 00572 BigIATSize = LittleIATSize; 00573 if (IATBase != NULL) { 00574 st = NtProtectVirtualMemory( NtCurrentProcess(), 00575 &IATBase, 00576 &BigIATSize, 00577 PAGE_READWRITE, 00578 &OldProtect 00579 ); 00580 if (!NT_SUCCESS(st)) { 00581 DbgPrint( "LDR: Unable to unprotect IAT to enable tagging by DLL.\n" ); 00582 } 00583 else { 00584 ProcAddresses = (PVOID *)IATBase; 00585 NumberOfProcAddresses = (ULONG)(BigIATSize / sizeof(PVOID)); 00586 while (NumberOfProcAddresses--) { 00587 if (*ProcAddresses == RtlAllocateHeap) { 00588 *ProcAddresses = LdrpDefineDllTag( LdrDataTableEntry->BaseDllName.Buffer, &TagIndex ); 00589 if (*ProcAddresses == NULL) { 00590 *ProcAddresses = RtlAllocateHeap; 00591 } 00592 } 00593 00594 ProcAddresses += 1; 00595 } 00596 00597 NtProtectVirtualMemory( NtCurrentProcess(), 00598 &IATBase, 00599 &BigIATSize, 00600 OldProtect, 00601 &OldProtect 00602 ); 00603 } 00604 } 00605 } 00606 00607 // 00608 // Check if we need to redirect some imports in case page heap 00609 // is enabled and we target specific dlls. 00610 // 00611 00612 if (Peb->NtGlobalFlag & FLG_HEAP_PAGE_ALLOCS) { 00613 00614 LdrpDphInitializeTargetDll (LdrDataTableEntry); 00615 } 00616 00617 return STATUS_SUCCESS; 00618 }

PLIST_ENTRY RtlpLockProcessHeapsList VOID   ) 
 

BOOLEAN RtlpSerializeHeap IN PVOID  HeapHandle  ) 
 

Definition at line 323 of file heapdbg.c.

References FALSE, _HEAP::Flags, _HEAP::ForceFlags, HeapHandle, IF_DEBUG_PAGE_HEAP_THEN_RETURN, Lock, _HEAP::LockVariable, NT_SUCCESS, NTSTATUS(), NULL, RtlAllocateHeap, RtlFreeHeap, RtlInitializeLockRoutine, RtlpCheckHeapSignature(), RtlpDebugPageHeapSerialize(), RtlpValidateHeapHeaders(), Status, and TRUE.

Referenced by LdrpInitializeTls().

00329 : 00330 00331 Arguments: 00332 00333 Return Value: 00334 00335 --*/ 00336 00337 { 00338 NTSTATUS Status; 00339 PHEAP Heap = (PHEAP)HeapHandle; 00340 PHEAP_LOCK Lock; 00341 00342 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 00343 RtlpDebugPageHeapSerialize( HeapHandle )); 00344 00345 // 00346 // Validate that HeapAddress points to a HEAP structure. 00347 // 00348 00349 if (!RtlpCheckHeapSignature( Heap, "RtlpSerializeHeap" )) { 00350 00351 return FALSE; 00352 } 00353 00354 // 00355 // Lock the heap. 00356 // 00357 00358 if (Heap->Flags & HEAP_NO_SERIALIZE) { 00359 00360 Lock = RtlAllocateHeap( HeapHandle, HEAP_NO_SERIALIZE, sizeof( *Lock ) ); 00361 00362 if ( Lock == NULL ) { 00363 00364 return FALSE; 00365 } 00366 00367 Status = RtlInitializeLockRoutine( Lock ); 00368 00369 if (!NT_SUCCESS( Status )) { 00370 00371 RtlFreeHeap( HeapHandle, HEAP_NO_SERIALIZE, Lock ); 00372 00373 return FALSE; 00374 } 00375 00376 Heap->LockVariable = Lock; 00377 Heap->Flags &= ~HEAP_NO_SERIALIZE; 00378 Heap->ForceFlags &= ~HEAP_NO_SERIALIZE; 00379 00380 RtlpValidateHeapHeaders( Heap, TRUE ); 00381 } 00382 00383 return TRUE; 00384 }

VOID RtlpUnlockProcessHeapsList VOID   ) 
 

PSZ UnicodeToAnsii IN PWSTR  String  ) 
 

BOOLEAN xRtlDosPathNameToNtPathName IN PSZ  DosFileName,
OUT PSTRING  NtFileName,
OUT PSZ *FilePart  OPTIONAL,
OUT PRTL_RELATIVE_NAME RelativeName  OPTIONAL
 

ULONG xRtlDosSearchPath PSZ  lpPath,
PSZ  lpFileName,
PSZ  lpExtension,
ULONG  nBufferLength,
PSZ  lpBuffer,
PSZ *lpFilePart  OPTIONAL
 

ULONG xRtlGetFullPathName PSZ  lpFileName,
ULONG  nBufferLength,
PSZ  lpBuffer,
PSZ *lpFilePart  OPTIONAL
 


Variable Documentation

RTL_CRITICAL_SECTION FastPebLock
 

Definition at line 388 of file ldrp.h.

Referenced by LdrpForkProcess(), and LdrpInitializeProcess().

BOOLEAN LdrpActiveUnloadCount
 

Definition at line 383 of file ldrp.h.

Referenced by LdrUnloadDll().

UNICODE_STRING LdrpDefaultPath
 

Definition at line 387 of file ldrp.h.

Referenced by LdrpCheckForLoadedDll(), LdrpInitializeProcess(), LdrpMapDll(), and LdrpResolveDllName().

LIST_ENTRY LdrpDefaultPathCache
 

Definition at line 168 of file ldrp.h.

ULONG LdrpFatalHardErrorCount
 

Definition at line 386 of file ldrp.h.

Referenced by LdrpCreateDllSection(), LdrpInitializationFailure(), LdrpMapDll(), and LdrpSnapThunk().

PLDR_DATA_TABLE_ENTRY LdrpGetModuleHandleCache
 

Definition at line 384 of file ldrp.h.

Referenced by LdrGetDllHandle(), and LdrUnloadDll().

LIST_ENTRY LdrpHashTable[LDRP_HASH_TABLE_SIZE]
 

Definition at line 162 of file ldrp.h.

Referenced by LdrpCheckForLoadedDll(), LdrpInitializeProcess(), and LdrpInsertMemoryTableEntry().

PLDR_DATA_TABLE_ENTRY LdrpImageEntry
 

Definition at line 390 of file ldrp.h.

Referenced by LdrpInitializeProcess().

BOOLEAN LdrpImageHasTls
 

Definition at line 32 of file ldrp.h.

Referenced by LdrpInitializeThread(), LdrpInitializeTls(), LdrpRunInitializeRoutines(), LdrShutdownProcess(), and LdrShutdownThread().

BOOLEAN LdrpInLdrInit
 

Definition at line 374 of file ldrp.h.

Referenced by LdrDisableThreadCalloutsForDll(), LdrGetDllHandle(), LdrpCreateDllSection(), LdrpGetProcedureAddress(), LdrpInitialize(), LdrpLoadDll(), LdrpMapDll(), LdrpSnapThunk(), LdrQueryProcessModuleInformation(), and LdrUnloadDll().

HANDLE LdrpKnownDllObjectDirectory
 

Definition at line 34 of file ldrp.h.

Referenced by LdrpCheckForKnownDll(), LdrpInitializeProcess(), and LdrpMapDll().

UNICODE_STRING LdrpKnownDllPath
 

Definition at line 37 of file ldrp.h.

Referenced by LdrpCheckForKnownDll(), and LdrpInitializeProcess().

WCHAR LdrpKnownDllPathBuffer[LDRP_MAX_KNOWN_PATH]
 

Definition at line 36 of file ldrp.h.

Referenced by LdrpInitializeProcess().

BOOLEAN LdrpLdrDatabaseIsSetup
 

Definition at line 375 of file ldrp.h.

Referenced by LdrpInitializeProcess(), and LdrpLoadDll().

PLDR_DATA_TABLE_ENTRY LdrpLoadedDllHandleCache
 

Definition at line 385 of file ldrp.h.

Referenced by LdrpCheckForLoadedDllHandle(), and LdrUnloadDll().

ULONG LdrpNumberOfProcessors
 

Definition at line 391 of file ldrp.h.

Referenced by LdrpInitializeProcess(), and LdrpMapDll().

ULONG LdrpNumberOfTlsEntries
 

Definition at line 401 of file ldrp.h.

Referenced by LdrpAllocateTls(), and LdrpInitializeTls().

BOOLEAN LdrpShutdownInProgress
 

Definition at line 373 of file ldrp.h.

HANDLE LdrpShutdownThreadId
 

Definition at line 389 of file ldrp.h.

Referenced by LdrShutdownProcess(), RtlpNotOwnerCriticalSection(), and RtlpWaitForCriticalSection().

LIST_ENTRY LdrpTlsList
 

Definition at line 400 of file ldrp.h.

Referenced by LdrpAllocateTls(), LdrpFreeTls(), and LdrpInitializeTls().

LIST_ENTRY LdrpUnloadHead
 

Definition at line 382 of file ldrp.h.

Referenced by LdrUnloadDll().

BOOLEAN LdrpVerifyDlls
 

Definition at line 376 of file ldrp.h.

Referenced by LdrpInitializeProcess().

ULONG NtdllBaseTag
 

Definition at line 455 of file ldrp.h.

Referenced by LdrpInitializeProcess().

ULONG NtGlobalFlag
 

Definition at line 370 of file ldrp.h.

Referenced by ExAllocatePoolWithQuotaTag(), ExInitializeResource(), ExInitializeResourceLite(), InitializePool(), IoInitSystem(), KdpTrap(), MiLoadImageSection(), MiLoadSystemImage(), MiMapViewOfImageSection(), MmCreatePeb(), MmInPageKernelStack(), MmOutPageKernelStack(), NtClose(), NtDuplicateObject(), NtQuerySystemInformation(), NtSetEvent(), NtSetSystemInformation(), NtWaitForMultipleObjects(), ObCreateObjectType(), ObDupHandleProcedure(), ObpCaptureHandleInformation(), ObpCreateHandle(), ObpCreateUnnamedHandle(), ObpEnumFindHandleProcedure(), ObReferenceObjectByHandle(), RtlCreateHeap(), RtlDispatchException(), RtlGetNtGlobalFlags(), RtlpInitializeHeapSegment(), and UserInitialize().

LIST_ENTRY RtlCriticalSectionList
 

Definition at line 371 of file ldrp.h.

Referenced by LdrpForkProcess(), LdrpInitializeProcess(), RtlCheckForOrphanedCriticalSections(), RtlInitializeCriticalSectionAndSpinCount(), RtlpInitDeferedCriticalSection(), and RtlQueryProcessLockInformation().

RTL_CRITICAL_SECTION RtlCriticalSectionLock
 

Definition at line 372 of file ldrp.h.

Referenced by RtlCheckForOrphanedCriticalSections(), RtlDeleteCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), RtlpInitDeferedCriticalSection(), and RtlQueryProcessLockInformation().

LARGE_INTEGER RtlpTimeout
 

Definition at line 369 of file ldrp.h.

Referenced by LdrpInitializeProcess(), RtlAcquireResourceExclusive(), RtlAcquireResourceShared(), RtlConvertSharedToExclusive(), and RtlpWaitForCriticalSection().

BOOLEAN RtlpTimoutDisable
 

Definition at line 368 of file ldrp.h.

Referenced by LdrpInitializeProcess(), and RtlpWaitForCriticalSection().

BOOLEAN ShowSnaps
 

Definition at line 367 of file ldrp.h.

Referenced by LdrGetDllHandle(), LdrpAllocateTls(), LdrpCallTlsInitializers(), LdrpCheckForLoadedDll(), LdrpGetProcedureAddress(), LdrpInitializeProcess(), LdrpInitializeTls(), LdrpLoadDll(), LdrpMapDll(), LdrpResolveDllName(), LdrpRunInitializeRoutines(), LdrpSnapThunk(), LdrpUpdateLoadCount(), LdrpWalkImportDescriptor(), LdrShutdownProcess(), and LdrUnloadDll().


Generated on Sat May 15 19:44:31 2004 for test by doxygen 1.3.7