test: ldrsnap.c File Reference

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

# ldrsnap.c File Reference

`#include "ntos.h"`
`#include <nt.h>`
`#include <ntrtl.h>`
`#include <nturtl.h>`
`#include <heap.h>`
`#include "ldrp.h"`

Go to the source code of this file.

## Classes

struct | _DPH_SNAP_NAME

## Defines

#define | LDRDBG 0
#define | SNAP_ROUTINE_GLOBALALLOC 0
#define | SNAP_ROUTINE_GLOBALREALLOC 1
#define | SNAP_ROUTINE_GLOBALFREE 2
#define | SNAP_ROUTINE_LOCALALLOC 3
#define | SNAP_ROUTINE_LOCALREALLOC 4
#define | SNAP_ROUTINE_LOCALFREE 5
#define | SNAP_ROUTINE_HEAPALLOC 6
#define | SNAP_ROUTINE_HEAPREALLOC 7
#define | SNAP_ROUTINE_HEAPFREE 8
#define | SNAP_ROUTINE_HEAPCREATE 9
#define | SNAP_ROUTINE_MALLOC 10
#define | SNAP_ROUTINE_CALLOC 11
#define | SNAP_ROUTINE_REALLOC 12
#define | SNAP_ROUTINE_FREE 13
#define | SNAP_ROUTINE_NEW 14
#define | SNAP_ROUTINE_DELETE 15
#define | SNAP_ROUTINE_NEW_ARRAY 16
#define | SNAP_ROUTINE_DELETE_ARRAY 17
#define | SNAP_ROUTINE_MAX_INDEX 18
#define | BIAS_POINTER(p) ((PVOID)((ULONG_PTR)(p) | 0x01))
#define | LMEM_MOVEABLE 0x0002
#define | LMEM_ZEROINIT 0x0040
#define | BASE_HANDLE_MARK_BIT 0x04

## Typedefs

typedef _DPH_SNAP_NAME | DPH_SNAP_NAME
typedef _DPH_SNAP_NAME * | PDPH_SNAP_NAME
typedef PVOID(* | FUN_LOCAL_ALLOC )(IN ULONG Flags, IN SIZE_T Size)
typedef PVOID(* | FUN_LOCAL_REALLOC )(IN PVOID Address, IN SIZE_T Size, IN ULONG Flags)
typedef PVOID(* | FUN_LOCAL_FREE )(IN PVOID Address)
typedef PVOID(* | FUN_GLOBAL_ALLOC )(IN ULONG Flags, IN SIZE_T Size)
typedef PVOID(* | FUN_GLOBAL_REALLOC )(IN PVOID Address, IN SIZE_T Size, IN ULONG Flags)
typedef PVOID(* | FUN_GLOBAL_FREE )(IN PVOID Address)
typedef PVOID(* | FUN_HEAP_CREATE )(ULONG Options, SIZE_T InitialSize, SIZE_T MaximumSize)

## Functions

NTSTATUS | LdrpWalkImportDescriptor (IN PWSTR DllPath OPTIONAL, IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry)
VOID | LdrpDphInitializeTargetDll (PLDR_DATA_TABLE_ENTRY LoadedDllData)
NTSTATUS | LdrpLoadImportModule (IN PWSTR DllPath OPTIONAL, IN LPSTR ImportName, IN PVOID DllBaseImporter, OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry, OUT PBOOLEAN AlreadyLoaded)
ULONG | LdrpClearLoadInProgress (VOID)
NTSTATUS | LdrpRunInitializeRoutines (IN PCONTEXT Context OPTIONAL)
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 | LdrpCreateDllSection (IN PUNICODE_STRING NtFullDllName, IN HANDLE DllFile, IN PUNICODE_STRING BaseName, IN PULONG DllCharacteristics OPTIONAL, OUT PHANDLE SectionHandle)
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 | 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)
USHORT | LdrpNameToOrdinal (IN PSZ Name, IN ULONG NumberOfNames, IN PVOID DllBase, IN PULONG NameTableBase, IN PUSHORT NameOrdinalTableBase)
VOID | LdrpUpdateLoadCount (IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry, IN BOOLEAN IncrementCount)
PLDR_DATA_TABLE_ENTRY | LdrpAllocateDataTableEntry (IN PVOID DllBase)
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)
PVOID | LdrpFetchAddressOfEntryPoint (IN PVOID Base)
HANDLE | LdrpCheckForKnownDll (IN PWSTR DllName, OUT PUNICODE_STRING FullDllName, OUT PUNICODE_STRING BaseDllName)
NTSTATUS | LdrpSetProtection (IN PVOID Base, IN BOOLEAN Reset, IN BOOLEAN StaticLink)
PVOID | RtlpDphDllHeapAlloc (IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
PVOID | RtlpDphDllHeapReAlloc (IN PVOID HeapHandle, IN ULONG Flags, IN PVOID Address, IN SIZE_T Size)
BOOLEAN | RtlpDphDllHeapFree (IN PVOID HeapHandle, IN ULONG Flags, IN PVOID Address)
PVOID | RtlpDphDllLocalAlloc (IN ULONG Flags, IN SIZE_T Size)
PVOID | RtlpDphDllLocalReAlloc (IN PVOID Address, IN SIZE_T Size, IN ULONG Flags)
PVOID | RtlpDphDllLocalFree (IN PVOID Address)
PVOID | RtlpDphDllGlobalAlloc (IN ULONG Flags, IN SIZE_T Size)
PVOID | RtlpDphDllGlobalReAlloc (IN PVOID Address, IN SIZE_T Size, IN ULONG Flags)
PVOID | RtlpDphDllGlobalFree (IN PVOID Address)
PVOID __cdecl | RtlpDphDllmalloc (IN SIZE_T Size)
PVOID __cdecl | RtlpDphDllcalloc (IN SIZE_T Number, IN SIZE_T Size)
PVOID __cdecl | RtlpDphDllrealloc (IN PVOID Address, IN SIZE_T Size)
VOID __cdecl | RtlpDphDllfree (IN PVOID Address)
PVOID __cdecl | RtlpDphDllNew (IN SIZE_T Size)
VOID __cdecl | RtlpDphDllDelete (IN PVOID Address)
PVOID __cdecl | RtlpDphDllNewArray (IN SIZE_T Size)
VOID __cdecl | RtlpDphDllDeleteArray (IN PVOID Address)
PVOID | RtlpDphDllHeapCreate (ULONG Options, SIZE_T InitialSize, SIZE_T MaximumSize)
BOOLEAN | LdrpDphDetectSnapRoutines (PWSTR DllString, PDPH_SNAP_NAME SnapNames)
BOOLEAN | LdrpDphSnapImports (PLDR_DATA_TABLE_ENTRY LdrDataTableEntry, BOOLEAN CallToDetectCrtHeap)

## Variables

BOOLEAN | LdrpDphKernel32Snapped
BOOLEAN | LdrpDphMsvcrtSnapped
PVOID | LdrpDphSnapRoutines [SNAP_ROUTINE_MAX_INDEX]
DPH_SNAP_NAME | LdrpDphSnapNamesForKernel32 []
DPH_SNAP_NAME | LdrpDphSnapNamesForMsvcrt []
PVOID | RtlpDphMsvcrtHeap

## Define Documentation

#define BASE_HANDLE_MARK_BIT 0x04

| Definition at line 4155 of file ldrsnap.c. Referenced by RtlpDphDllGlobalFree(), and RtlpDphDllLocalFree().

#define BIAS_POINTER | ( | p |  | ) | ((PVOID)((ULONG_PTR)(p) | 0x01))

| Definition at line 4097 of file ldrsnap.c. Referenced by RtlpDebugPageHeapReAllocate(), RtlpDphDllcalloc(), RtlpDphDllGlobalAlloc(), RtlpDphDllGlobalReAlloc(), RtlpDphDllHeapAlloc(), RtlpDphDllHeapReAlloc(), RtlpDphDllLocalAlloc(), RtlpDphDllLocalReAlloc(), RtlpDphDllmalloc(), RtlpDphDllNew(), RtlpDphDllNewArray(), and RtlpDphDllrealloc().

#define LDRDBG 0

| Definition at line 23 of file ldrsnap.c.

#define LMEM_MOVEABLE 0x0002

| Definition at line 4149 of file ldrsnap.c. Referenced by GetClipboardData(), RtlpDphDllGlobalAlloc(), RtlpDphDllGlobalReAlloc(), RtlpDphDllLocalAlloc(), and RtlpDphDllLocalReAlloc().

#define LMEM_ZEROINIT 0x0040

| Definition at line 4150 of file ldrsnap.c. Referenced by GetHardErrorText(), RtlLoadStringOrError(), RtlpDphDllGlobalAlloc(), RtlpDphDllLocalAlloc(), and SoftModalMessageBox().

#define SNAP_ROUTINE_CALLOC 11

| Definition at line 3534 of file ldrsnap.c. Referenced by LdrpDphSnapImports().

#define SNAP_ROUTINE_DELETE 15

| Definition at line 3538 of file ldrsnap.c. Referenced by LdrpDphSnapImports().

#define SNAP_ROUTINE_DELETE_ARRAY 17

| Definition at line 3540 of file ldrsnap.c. Referenced by LdrpDphSnapImports().

#define SNAP_ROUTINE_FREE 13

| Definition at line 3536 of file ldrsnap.c. Referenced by LdrpDphSnapImports().

#define SNAP_ROUTINE_GLOBALALLOC 0

| Definition at line 3523 of file ldrsnap.c. Referenced by LdrpDphSnapImports(), and RtlpDphDllGlobalAlloc().

#define SNAP_ROUTINE_GLOBALFREE 2

| Definition at line 3525 of file ldrsnap.c. Referenced by LdrpDphSnapImports(), and RtlpDphDllGlobalFree().

#define SNAP_ROUTINE_GLOBALREALLOC 1

| Definition at line 3524 of file ldrsnap.c. Referenced by LdrpDphSnapImports(), and RtlpDphDllGlobalReAlloc().

#define SNAP_ROUTINE_HEAPALLOC 6

| Definition at line 3529 of file ldrsnap.c. Referenced by LdrpDphSnapImports().

#define SNAP_ROUTINE_HEAPCREATE 9

| Definition at line 3532 of file ldrsnap.c. Referenced by LdrpDphSnapImports(), and RtlpDphDllHeapCreate().

#define SNAP_ROUTINE_HEAPFREE 8

| Definition at line 3531 of file ldrsnap.c. Referenced by LdrpDphSnapImports().

#define SNAP_ROUTINE_HEAPREALLOC 7

| Definition at line 3530 of file ldrsnap.c. Referenced by LdrpDphSnapImports().

#define SNAP_ROUTINE_LOCALALLOC 3

| Definition at line 3526 of file ldrsnap.c. Referenced by LdrpDphSnapImports(), and RtlpDphDllLocalAlloc().

#define SNAP_ROUTINE_LOCALFREE 5

| Definition at line 3528 of file ldrsnap.c. Referenced by LdrpDphSnapImports(), and RtlpDphDllLocalFree().

#define SNAP_ROUTINE_LOCALREALLOC 4

| Definition at line 3527 of file ldrsnap.c. Referenced by LdrpDphSnapImports(), and RtlpDphDllLocalReAlloc().

#define SNAP_ROUTINE_MALLOC 10

| Definition at line 3533 of file ldrsnap.c. Referenced by LdrpDphSnapImports().

#define SNAP_ROUTINE_MAX_INDEX 18

| Definition at line 3541 of file ldrsnap.c.

#define SNAP_ROUTINE_NEW 14

| Definition at line 3537 of file ldrsnap.c. Referenced by LdrpDphSnapImports().

#define SNAP_ROUTINE_NEW_ARRAY 16

| Definition at line 3539 of file ldrsnap.c. Referenced by LdrpDphSnapImports().

#define SNAP_ROUTINE_REALLOC 12

| Definition at line 3535 of file ldrsnap.c. Referenced by LdrpDphSnapImports().

## Typedef Documentation

typedef struct _DPH_SNAP_NAME DPH_SNAP_NAME

typedef PVOID(* FUN_GLOBAL_ALLOC)(IN ULONG Flags, IN SIZE_T Size)

| Definition at line 4177 of file ldrsnap.c. Referenced by RtlpDphDllGlobalAlloc().

typedef PVOID(* FUN_GLOBAL_FREE)(IN PVOID Address)

| Definition at line 4190 of file ldrsnap.c. Referenced by RtlpDphDllGlobalFree().

typedef PVOID(* FUN_GLOBAL_REALLOC)(IN PVOID Address, IN SIZE_T Size, IN ULONG Flags)

| Definition at line 4183 of file ldrsnap.c. Referenced by RtlpDphDllGlobalReAlloc().

typedef PVOID(* FUN_HEAP_CREATE)(ULONG Options, SIZE_T InitialSize, SIZE_T MaximumSize)

| Definition at line 4512 of file ldrsnap.c. Referenced by RtlpDphDllHeapCreate().

typedef PVOID(* FUN_LOCAL_ALLOC)(IN ULONG Flags, IN SIZE_T Size)

| Definition at line 4159 of file ldrsnap.c. Referenced by RtlpDphDllLocalAlloc().

typedef PVOID(* FUN_LOCAL_FREE)(IN PVOID Address)

| Definition at line 4172 of file ldrsnap.c. Referenced by RtlpDphDllLocalFree().

typedef PVOID(* FUN_LOCAL_REALLOC)(IN PVOID Address, IN SIZE_T Size, IN ULONG Flags)

| Definition at line 4165 of file ldrsnap.c. Referenced by RtlpDphDllLocalReAlloc().

typedef struct _DPH_SNAP_NAME * PDPH_SNAP_NAME

| Referenced by LdrpDphDetectSnapRoutines().

## 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 }

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 }

ULONG LdrpClearLoadInProgress | ( | VOID |  | ) |

Definition at line 622 of file ldrsnap.c.

Referenced by LdrpLoadDll(), and LdrpRunInitializeRoutines().

    00625 {
    00626     PLIST_ENTRY Head, Next;
    00627     PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
    00628     ULONG i;
    00629
    00630     Head = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList;
    00631     Next = Head->Flink;
    00632     i = 0;
    00633     while ( Next != Head ) {
    00634         LdrDataTableEntry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
    00635         LdrDataTableEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
    00636
    00637         //
    00638         // return the number of entries that have not been processed, but
    00639         // have init routines
    00640         //
    00641
    00642         if ( !(LdrDataTableEntry->Flags & LDRP_ENTRY_PROCESSED) && LdrDataTableEntry->EntryPoint) {
    00643             i++;
    00644             }
    00645
    00646         Next = Next->Flink;
    00647         }
    00648     return i;
    00649 }

NTSTATUS LdrpCreateDllSection | ( | IN PUNICODE_STRING | NtFullDllName,
|  | 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 }

BOOLEAN LdrpDphDetectSnapRoutines | ( | PWSTR | DllString,
|  | PDPH_SNAP_NAME | SnapNames
| ) |

Definition at line 3710 of file ldrsnap.c.

References DbgPrint, Directory(), FALSE, _DPH_SNAP_NAME::Index, Index, LdrpCheckForLoadedDll(), LdrpDphSnapRoutines, _DPH_SNAP_NAME::Name, NULL, PDPH_SNAP_NAME, RtlImageDirectoryEntryToData(), RtlInitUnicodeString(), Size, TRUE, and USHORT.

Referenced by LdrpDphInitializeTargetDll().

    03714 {
    03715     PLDR_DATA_TABLE_ENTRY DllData;
    03716     PIMAGE_EXPORT_DIRECTORY Directory;
    03717     ULONG Size;
    03718     PCHAR NameAddress;
    03719     PCHAR FunctionAddress;
    03720     PCHAR Base;
    03721     PCHAR IndexAddress;
    03722     ULONG Index;
    03723     ULONG RealIndex;
    03724     BOOLEAN Result;
    03725     UNICODE_STRING DllName;
    03726     PDPH_SNAP_NAME CurrentSnapName;
    03727
    03728     RtlInitUnicodeString (
    03729         &DllName,
    03730         DllString);
    03731
    03732     Result = LdrpCheckForLoadedDll (
    03733         NULL,
    03734         &DllName,
    03735         TRUE,
    03736         FALSE,
    03737         &DllData);
    03738
    03739     if (Result == FALSE) {
    03740         return FALSE;
    03741     }
    03742
    03743     Base = DllData->DllBase;
    03744
    03745     Directory = RtlImageDirectoryEntryToData (
    03746         DllData->DllBase,
    03747         TRUE,
    03748         IMAGE_DIRECTORY_ENTRY_EXPORT,
    03749         &Size
    03750         );
    03751
    03752     if (Directory == NULL) {
    03753         return FALSE;
    03754     }
    03755
    03756     for (CurrentSnapName = SnapNames; CurrentSnapName->Name; CurrentSnapName += 1) {
    03757
    03758         for (Index = 0; Index < Directory->NumberOfFunctions; Index += 1) {
    03759
    03760             NameAddress = Base + Directory->AddressOfNames;
    03761             NameAddress = Base + ((ULONG *)NameAddress)[Index];
    03762
    03763             IndexAddress = Base + Directory->AddressOfNameOrdinals;
    03764             RealIndex = (ULONG)(((USHORT *)IndexAddress)[Index]);
    03765
    03766             if (_stricmp (NameAddress, CurrentSnapName->Name) == 0) {
    03767
    03768                 FunctionAddress = Base + Directory->AddressOfFunctions;
    03769                 FunctionAddress = Base + ((ULONG *)FunctionAddress)[RealIndex];
    03770
    03771                 LdrpDphSnapRoutines[CurrentSnapName->Index] = FunctionAddress;
    03772                 DbgPrint ("Page heap: found %s @ address %p \n", NameAddress, FunctionAddress);
    03773             }
    03774         }
    03775     }
    03776
    03777     return TRUE;
    03778 }

VOID LdrpDphInitializeTargetDll | ( | PLDR_DATA_TABLE_ENTRY | LoadedDllData | ) |

Definition at line 3970 of file ldrsnap.c.

References DbgPrint, End, FALSE, L, LdrpCheckForLoadedDll(), LdrpDphDetectSnapRoutines(), LdrpDphKernel32Snapped, LdrpDphMsvcrtSnapped, LdrpDphSnapImports(), LdrpDphSnapNamesForKernel32, LdrpDphSnapNamesForMsvcrt, NULL, RtlInitUnicodeString(), RtlpDphGlobalFlags, RtlpDphIsDllTargeted(), RtlpDphTargetDlls, and TRUE.

Referenced by LdrpWalkImportDescriptor().

    03973 {
    03974     BOOLEAN Kernel32JustSnapped = FALSE;
    03975     BOOLEAN MsvcrtJustSnapped = FALSE;
    03976
    03977     //
    03978     // If we do not have per dll page heap feature enabled
    03979     // we return immediately.
    03980     //
    03981
    03982     if (! (RtlpDphGlobalFlags & PAGE_HEAP_USE_DLL_NAMES)) {
    03983         return;
    03984     }
    03985
    03986     if (! LdrpDphKernel32Snapped) {
    03987
    03988         Kernel32JustSnapped = LdrpDphDetectSnapRoutines (
    03989             L"kernel32.dll",
    03990             LdrpDphSnapNamesForKernel32);
    03991
    03992         LdrpDphKernel32Snapped = Kernel32JustSnapped;
    03993     }
    03994
    03995     if (! LdrpDphMsvcrtSnapped) {
    03996
    03997         MsvcrtJustSnapped = LdrpDphDetectSnapRoutines (
    03998             L"msvcrt.dll",
    03999             LdrpDphSnapNamesForMsvcrt);
    04000
    04001         LdrpDphMsvcrtSnapped = MsvcrtJustSnapped;
    04002     }
    04003
    04004     //
    04005     // Snap everything already loaded if we just managed
    04006     // to detect snap routines.
    04007     //
    04008
    04009     if (Kernel32JustSnapped || MsvcrtJustSnapped) {
    04010
    04011         PWSTR Current;
    04012         PWSTR End;
    04013         WCHAR SavedChar;
    04014         PLDR_DATA_TABLE_ENTRY DllData;
    04015         BOOLEAN Result;
    04016         UNICODE_STRING DllName;
    04017
    04018         Current = RtlpDphTargetDlls;
    04019
    04020         while (*Current) {
    04021
    04022             while (*Current == L' ') {
    04023                 Current += 1;
    04024             }
    04025
    04026             End = Current;
    04027
    04028             while (*End && *End != L' ') {
    04029                 End += 1;
    04030             }
    04031
    04032             if (*Current == L'\0') {
    04033                 break;
    04034             }
    04035
    04036             SavedChar = *End;
    04037             *End = L'\0';
    04038
    04039             RtlInitUnicodeString (
    04040                 &DllName,
    04041                 Current);
    04042
    04043             Result = LdrpCheckForLoadedDll (
    04044                 NULL,
    04045                 &DllName,
    04046                 TRUE,
    04047                 FALSE,
    04048                 &DllData);
    04049
    04050             if (Result) {
    04051
    04052                 if (DllData->DllBase == LoadedDllData->DllBase) {
    04053 #if DBG
    04054                     DbgPrint ("Page heap: oversnapping %ws \n", DllData->BaseDllName);
    04055 #endif
    04056                 }
    04057
    04058                 LdrpDphSnapImports (DllData, FALSE);
    04059             }
    04060
    04061             *End = SavedChar;
    04062             Current = End;
    04063         }
    04064     }
    04065
    04066     //
    04067     // If we just loaded msvcrt.dll we need to redirect HeapCreate call
    04068     // in order to detect when the CRT heap gets created.
    04069     //
    04070
    04071     if (_wcsicmp (LoadedDllData->BaseDllName.Buffer, L"msvcrt.dll") == 0) {
    04072
    04073         LdrpDphSnapImports (LoadedDllData, TRUE);
    04074     }
    04075
    04076     //
    04077     // Call back into page heap manager to figure out if the
    04078     // currently loaded dll is a target for page heap.
    04079     //
    04080
    04081     if (RtlpDphIsDllTargeted (LoadedDllData->BaseDllName.Buffer)) {
    04082
    04083         LdrpDphSnapImports (LoadedDllData, FALSE);
    04084     }
    04085 }

BOOLEAN LdrpDphSnapImports | ( | PLDR_DATA_TABLE_ENTRY | LdrDataTableEntry,
|  | BOOLEAN | CallToDetectCrtHeap
| ) |

Definition at line 3781 of file ldrsnap.c.

References DbgPrint, FALSE, LdrpDphSnapRoutines, NT_SUCCESS, NtProtectVirtualMemory(), NTSTATUS(), NULL, RtlAllocateHeap, RtlFreeHeap, RtlImageDirectoryEntryToData(), RtlpDphDllcalloc(), RtlpDphDllDelete(), RtlpDphDllDeleteArray(), RtlpDphDllfree(), RtlpDphDllGlobalAlloc(), RtlpDphDllGlobalFree(), RtlpDphDllGlobalReAlloc(), RtlpDphDllHeapAlloc(), RtlpDphDllHeapCreate(), RtlpDphDllHeapFree(), RtlpDphDllHeapReAlloc(), RtlpDphDllLocalAlloc(), RtlpDphDllLocalFree(), RtlpDphDllLocalReAlloc(), RtlpDphDllmalloc(), RtlpDphDllNew(), RtlpDphDllNewArray(), RtlpDphDllrealloc(), RtlReAllocateHeap(), SNAP_ROUTINE_CALLOC, SNAP_ROUTINE_DELETE, SNAP_ROUTINE_DELETE_ARRAY, SNAP_ROUTINE_FREE, SNAP_ROUTINE_GLOBALALLOC, SNAP_ROUTINE_GLOBALFREE, SNAP_ROUTINE_GLOBALREALLOC, SNAP_ROUTINE_HEAPALLOC, SNAP_ROUTINE_HEAPCREATE, SNAP_ROUTINE_HEAPFREE, SNAP_ROUTINE_HEAPREALLOC, SNAP_ROUTINE_LOCALALLOC, SNAP_ROUTINE_LOCALFREE, SNAP_ROUTINE_LOCALREALLOC, SNAP_ROUTINE_MALLOC, SNAP_ROUTINE_NEW, SNAP_ROUTINE_NEW_ARRAY, SNAP_ROUTINE_REALLOC, TRUE, and USHORT.

Referenced by LdrpDphInitializeTargetDll().

    03785 {
    03786     PVOID IATBase;
    03787     SIZE_T BigIATSize;
    03788     ULONG  LittleIATSize;
    03789     PVOID *ProcAddresses;
    03790     ULONG NumberOfProcAddresses;
    03791     ULONG OldProtect;
    03792     USHORT TagIndex;
    03793     NTSTATUS st;
    03794
    03795     //
    03796     // Determine the location and size of the IAT.  If found, scan the
    03797     // IAT address to see if any are pointing to alloc/free functions
    03798     // and replace those thunks.
    03799     //
    03800
    03801     IATBase = RtlImageDirectoryEntryToData(
    03802         LdrDataTableEntry->DllBase,
    03803         TRUE,
    03804         IMAGE_DIRECTORY_ENTRY_IAT,
    03805         &LittleIATSize);
    03806
    03807     BigIATSize = LittleIATSize;
    03808
    03809     if (IATBase != NULL) {
    03810         st = NtProtectVirtualMemory(
    03811             NtCurrentProcess(),
    03812             &IATBase,
    03813             &BigIATSize,
    03814             PAGE_READWRITE,
    03815             &OldProtect);
    03816
    03817         if (!NT_SUCCESS(st)) {
    03818             DbgPrint( "LDR: Unable to unprotect IAT to enable per DLL page heap.\n" );
    03819             return FALSE;
    03820         }
    03821         else {
    03822             ProcAddresses = (PVOID *)IATBase;
    03823             NumberOfProcAddresses = (ULONG)(BigIATSize / sizeof(PVOID));
    03824             while (NumberOfProcAddresses--) {
    03825
    03826                 if (CallToDetectCrtHeap) {
    03827                     if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_HEAPCREATE]) {
    03828                         *ProcAddresses = RtlpDphDllHeapCreate;
    03829                         DbgPrint ("Snapped (%ws) HeapCreate ... \n",
    03830                             LdrDataTableEntry->BaseDllName.Buffer);
    03831                     }
    03832                 }
    03833                 else {
    03834
    03835                     //
    03836                     // ntdll imports
    03837                     //
    03838
    03839                     if (*ProcAddresses == RtlAllocateHeap) {
    03840                         *ProcAddresses = RtlpDphDllHeapAlloc;
    03841                         DbgPrint ("Snapped (%ws) RtlAllocateHeap ... \n",
    03842                                   LdrDataTableEntry->BaseDllName.Buffer);
    03843                     }
    03844                     else if (*ProcAddresses == RtlReAllocateHeap) {
    03845                         *ProcAddresses = RtlpDphDllHeapReAlloc;
    03846                         DbgPrint ("Snapped (%ws) RtlReAllocateHeap ... \n",
    03847                                   LdrDataTableEntry->BaseDllName.Buffer);
    03848                     }
    03849                     else if (*ProcAddresses == RtlFreeHeap) {
    03850                         *ProcAddresses = RtlpDphDllHeapFree;
    03851                         DbgPrint ("Snapped (%ws) RtlFreeHeap ... \n",
    03852                                   LdrDataTableEntry->BaseDllName.Buffer);
    03853                     }
    03854
    03855                     //
    03856                     // kernel32 imports
    03857                     //
    03858
    03859                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_HEAPALLOC]) {
    03860                         *ProcAddresses = RtlpDphDllHeapAlloc;
    03861                         DbgPrint ("Snapped (%ws) HeapAlloc ... \n",
    03862                                   LdrDataTableEntry->BaseDllName.Buffer);
    03863                     }
    03864                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_HEAPREALLOC]) {
    03865                         *ProcAddresses = RtlpDphDllHeapReAlloc;
    03866                         DbgPrint ("Snapped (%ws) HeapReAlloc ... \n",
    03867                                   LdrDataTableEntry->BaseDllName.Buffer);
    03868                     }
    03869                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_HEAPFREE]) {
    03870                         *ProcAddresses = RtlpDphDllHeapFree;
    03871                         DbgPrint ("Snapped (%ws) HeapFree ... \n",
    03872                                   LdrDataTableEntry->BaseDllName.Buffer);
    03873                     }
    03874
    03875                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_LOCALALLOC]) {
    03876                         *ProcAddresses = RtlpDphDllLocalAlloc;
    03877                         DbgPrint ("Snapped (%ws) LocalAlloc ... \n",
    03878                                   LdrDataTableEntry->BaseDllName.Buffer);
    03879                     }
    03880                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_LOCALREALLOC]) {
    03881                         *ProcAddresses = RtlpDphDllLocalReAlloc;
    03882                         DbgPrint ("Snapped (%ws) LocalReAlloc ... \n",
    03883                                   LdrDataTableEntry->BaseDllName.Buffer);
    03884                     }
    03885                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_LOCALFREE]) {
    03886                         *ProcAddresses = RtlpDphDllLocalFree;
    03887                         DbgPrint ("Snapped (%ws) LocalFree ... \n",
    03888                                   LdrDataTableEntry->BaseDllName.Buffer);
    03889                     }
    03890
    03891                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_GLOBALALLOC]) {
    03892                         *ProcAddresses = RtlpDphDllGlobalAlloc;
    03893                         DbgPrint ("Snapped (%ws) GlobalAlloc ... \n",
    03894                                   LdrDataTableEntry->BaseDllName.Buffer);
    03895                     }
    03896                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_GLOBALREALLOC]) {
    03897                         *ProcAddresses = RtlpDphDllGlobalReAlloc;
    03898                         DbgPrint ("Snapped (%ws) GlobalReAlloc ... \n",
    03899                                   LdrDataTableEntry->BaseDllName.Buffer);
    03900                     }
    03901                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_GLOBALFREE]) {
    03902                         *ProcAddresses = RtlpDphDllGlobalFree;
    03903                         DbgPrint ("Snapped (%ws) GlobalFree ... \n",
    03904                                   LdrDataTableEntry->BaseDllName.Buffer);
    03905                     }
    03906
    03907                     //
    03908                     // msvcrt imports
    03909                     //
    03910
    03911                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_MALLOC]) {
    03912                         *ProcAddresses = RtlpDphDllmalloc;
    03913                         DbgPrint ("Snapped (%ws) malloc ... \n",
    03914                                   LdrDataTableEntry->BaseDllName.Buffer);
    03915                     }
    03916                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_REALLOC]) {
    03917                         *ProcAddresses = RtlpDphDllrealloc;
    03918                         DbgPrint ("Snapped (%ws) realloc ... \n",
    03919                                   LdrDataTableEntry->BaseDllName.Buffer);
    03920                     }
    03921                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_CALLOC]) {
    03922                         *ProcAddresses = RtlpDphDllcalloc;
    03923                         DbgPrint ("Snapped (%ws) calloc ... \n",
    03924                                   LdrDataTableEntry->BaseDllName.Buffer);
    03925                     }
    03926                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_FREE]) {
    03927                         *ProcAddresses = RtlpDphDllfree;
    03928                         DbgPrint ("Snapped (%ws) free ... \n",
    03929                                   LdrDataTableEntry->BaseDllName.Buffer);
    03930                     }
    03931
    03932                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_NEW]) {
    03933                         *ProcAddresses = RtlpDphDllNew;
    03934                         DbgPrint ("Snapped (%ws) operator new ... \n",
    03935                                   LdrDataTableEntry->BaseDllName.Buffer);
    03936                     }
    03937                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_DELETE]) {
    03938                         *ProcAddresses = RtlpDphDllDelete;
    03939                         DbgPrint ("Snapped (%ws) operator delete ... \n",
    03940                                   LdrDataTableEntry->BaseDllName.Buffer);
    03941                     }
    03942                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_NEW_ARRAY]) {
    03943                         *ProcAddresses = RtlpDphDllNewArray;
    03944                         DbgPrint ("Snapped (%ws) operator new[] ... \n",
    03945                                   LdrDataTableEntry->BaseDllName.Buffer);
    03946                     }
    03947                     else if (*ProcAddresses == LdrpDphSnapRoutines[SNAP_ROUTINE_DELETE_ARRAY]) {
    03948                         *ProcAddresses = RtlpDphDllDeleteArray;
    03949                         DbgPrint ("Snapped (%ws) operator delete[] ... \n",
    03950                                   LdrDataTableEntry->BaseDllName.Buffer);
    03951                     }
    03952                 }
    03953
    03954                 ProcAddresses += 1;
    03955             }
    03956
    03957             NtProtectVirtualMemory(
    03958                 NtCurrentProcess(),
    03959                 &IATBase,
    03960                 &BigIATSize,
    03961                 OldProtect,
    03962                 &OldProtect);
    03963         }
    03964     }
    03965
    03966     return TRUE;
    03967 }

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 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 LdrpLoadImportModule | ( | IN PWSTR DllPath | OPTIONAL,
|  | IN LPSTR | ImportName,
|  | IN PVOID | DllBaseImporter,
|  | OUT PLDR_DATA_TABLE_ENTRY * | DataTableEntry,
|  | OUT PBOOLEAN | AlreadyLoaded
| ) |

Definition at line 140 of file ldrsnap.c.

References FALSE, LdrpCheckForLoadedDll(), LdrpMapDll(), LdrpWalkImportDescriptor(), NT_SUCCESS, NTSTATUS(), NULL, RtlAnsiStringToUnicodeString(), RtlImageNtHeader(), RtlInitAnsiString(), and TRUE.

Referenced by LdrpWalkImportDescriptor().

    00147 {
    00148     NTSTATUS st;
    00149     ANSI_STRING AnsiString;
    00150     PUNICODE_STRING ImportDescriptorName_U;
    00151     BOOLEAN Wx86KnownDll = FALSE;
    00152
    00153     ImportDescriptorName_U = &NtCurrentTeb()->StaticUnicodeString;
    00154     RtlInitAnsiString(&AnsiString, ImportName);
    00155     st = RtlAnsiStringToUnicodeString(ImportDescriptorName_U, &AnsiString, FALSE);
    00156     if (!NT_SUCCESS(st)) {
    00157         return st;
    00158     }
    00159
    00160
    00161 #if defined (WX86)
    00162     if (Wx86ProcessInit) {
    00163         Wx86KnownDll = RtlImageNtHeader(DllBaseImporter)->FileHeader.Machine == IMAGE_FILE_MACHINE_I386;
    00164         }
    00165 #endif
    00166
    00167
    00168     //
    00169     // BUGBUG If a DLL refers to itself we will recurse and blow up
    00170     //
    00171
    00172     //
    00173     // Check the LdrTable to see if Dll has already been mapped
    00174     // into this image. If not, map it.
    00175     //
    00176
    00177     if (LdrpCheckForLoadedDll( DllPath,
    00178                                ImportDescriptorName_U,
    00179                                TRUE,
    00180                                Wx86KnownDll,
    00181                                DataTableEntry
    00182                              )
    00183        ) {
    00184         *AlreadyLoaded = TRUE;
    00185     } else {
    00186         *AlreadyLoaded = FALSE;
    00187
    00188         st = LdrpMapDll(DllPath,
    00189                         ImportDescriptorName_U->Buffer,
    00190                         NULL,
    00191                         TRUE,
    00192                         Wx86KnownDll,
    00193                         DataTableEntry
    00194                         );
    00195
    00196         if (!NT_SUCCESS(st)) {
    00197             return st;
    00198         }
    00199         st = LdrpWalkImportDescriptor(
    00200                 DllPath,
    00201                 *DataTableEntry
    00202                 );
    00203         if (!NT_SUCCESS(st)) {
    00204             InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList,
    00205                            &(*DataTableEntry)->InInitializationOrderLinks);
    00206         }
    00207     }
    00208
    00209     return st;
    00210 }

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 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
| ) |

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
| ) |

| Referenced by LdrpInitializeProcess(), LdrpLoadDll(), and LdrpLoadImportModule().

PVOID __cdecl RtlpDphDllcalloc | ( | IN SIZE_T | Number,
|  | IN SIZE_T | Size
| ) |

Definition at line 4386 of file ldrsnap.c.

References ASSERT, BIAS_POINTER, NULL, RtlpDebugPageHeapAllocate(), RtlpDphMsvcrtHeap, and Size.

Referenced by LdrpDphSnapImports().

    04390 {
    04391     PVOID Block;
    04392
    04393     ASSERT(RtlpDphMsvcrtHeap != NULL);
    04394
    04395     Block =  RtlpDebugPageHeapAllocate (
    04396         BIAS_POINTER(RtlpDphMsvcrtHeap),
    04397         0,
    04398         Size * Number);
    04399
    04400     RtlZeroMemory (Block, Size * Number);
    04401     return Block;
    04402 }

VOID __cdecl RtlpDphDllDelete | ( | IN PVOID | Address | ) |

Definition at line 4469 of file ldrsnap.c.

References ASSERT, NULL, RtlpDebugPageHeapFree(), and RtlpDphMsvcrtHeap.

Referenced by LdrpDphSnapImports().

    04472 {
    04473     ASSERT(RtlpDphMsvcrtHeap != NULL);
    04474
    04475     RtlpDebugPageHeapFree (
    04476         RtlpDphMsvcrtHeap,
    04477         0,
    04478         Address);
    04479 }

VOID __cdecl RtlpDphDllDeleteArray | ( | IN PVOID | Address | ) |

Definition at line 4495 of file ldrsnap.c.

References ASSERT, NULL, RtlpDebugPageHeapFree(), and RtlpDphMsvcrtHeap.

Referenced by LdrpDphSnapImports().

    04498 {
    04499     ASSERT(RtlpDphMsvcrtHeap != NULL);
    04500
    04501     RtlpDebugPageHeapFree (
    04502         RtlpDphMsvcrtHeap,
    04503         0,
    04504         Address);
    04505 }

VOID __cdecl RtlpDphDllfree | ( | IN PVOID | Address | ) |

Definition at line 4434 of file ldrsnap.c.

References ASSERT, NULL, RtlpDebugPageHeapFree(), and RtlpDphMsvcrtHeap.

Referenced by LdrpDphSnapImports().

    04437 {
    04438     ASSERT(RtlpDphMsvcrtHeap != NULL);
    04439
    04440     RtlpDebugPageHeapFree (
    04441         RtlpDphMsvcrtHeap,
    04442         0,
    04443         Address);
    04444 }

PVOID RtlpDphDllGlobalAlloc | ( | IN ULONG | Flags,
|  | IN SIZE_T | Size
| ) |

Definition at line 4280 of file ldrsnap.c.

References BIAS_POINTER, FUN_GLOBAL_ALLOC, LdrpDphSnapRoutines, LMEM_MOVEABLE, LMEM_ZEROINIT, RtlpDebugPageHeapAllocate(), Size, and SNAP_ROUTINE_GLOBALALLOC.

Referenced by LdrpDphSnapImports().

    04284 {
    04285     PVOID Block;
    04286     FUN_GLOBAL_ALLOC Original;
    04287
    04288     if (!(Flags & LMEM_MOVEABLE)) {
    04289
    04290         Block = RtlpDebugPageHeapAllocate (
    04291             BIAS_POINTER(RtlProcessHeap()),
    04292             0,
    04293             Size);
    04294
    04295         if ((Flags & LMEM_ZEROINIT)) {
    04296             RtlZeroMemory (Block, Size);
    04297         }
    04298
    04299         return Block;
    04300     }
    04301     else {
    04302
    04303         Original = (FUN_GLOBAL_ALLOC)(LdrpDphSnapRoutines[SNAP_ROUTINE_GLOBALALLOC]);
    04304         return (* Original) (Flags, Size);
    04305     }
    04306 }

PVOID RtlpDphDllGlobalFree | ( | IN PVOID | Address | ) |

Definition at line 4336 of file ldrsnap.c.

References BASE_HANDLE_MARK_BIT, FUN_GLOBAL_FREE, LdrpDphSnapRoutines, NULL, RtlpDebugPageHeapFree(), and SNAP_ROUTINE_GLOBALFREE.

Referenced by LdrpDphSnapImports().

    04339 {
    04340     BOOLEAN Result;
    04341     FUN_GLOBAL_FREE Original;
    04342
    04343     if ((ULONG_PTR)Address & BASE_HANDLE_MARK_BIT) {
    04344
    04345         Original = (FUN_GLOBAL_FREE)(LdrpDphSnapRoutines[SNAP_ROUTINE_GLOBALFREE]);
    04346         return (* Original) (Address);
    04347     }
    04348     else {
    04349
    04350         Result = RtlpDebugPageHeapFree (
    04351             RtlProcessHeap(),
    04352             0,
    04353             Address);
    04354
    04355         if (Result) {
    04356             return NULL;
    04357         }
    04358         else {
    04359             return Address;
    04360         }
    04361     }
    04362 }

PVOID RtlpDphDllGlobalReAlloc | ( | IN PVOID | Address,
|  | IN SIZE_T | Size,
|  | IN ULONG | Flags
| ) |

Definition at line 4309 of file ldrsnap.c.

References BIAS_POINTER, FUN_GLOBAL_REALLOC, LdrpDphSnapRoutines, LMEM_MOVEABLE, RtlpDebugPageHeapReAllocate(), Size, and SNAP_ROUTINE_GLOBALREALLOC.

Referenced by LdrpDphSnapImports().

    04314 {
    04315     PVOID Block;
    04316     FUN_GLOBAL_REALLOC Original;
    04317
    04318     if (!(Flags & LMEM_MOVEABLE)) {
    04319
    04320         Block = RtlpDebugPageHeapReAllocate (
    04321             BIAS_POINTER(RtlProcessHeap()),
    04322             0,
    04323             Address,
    04324             Size);
    04325
    04326         return Block;
    04327     }
    04328     else {
    04329
    04330         Original = (FUN_GLOBAL_REALLOC)(LdrpDphSnapRoutines[SNAP_ROUTINE_GLOBALREALLOC]);
    04331         return (* Original) (Address, Size, Flags);
    04332     }
    04333 }

PVOID RtlpDphDllHeapAlloc | ( | IN PVOID | HeapHandle,
|  | IN ULONG | Flags,
|  | IN SIZE_T | Size
| ) |

Definition at line 4100 of file ldrsnap.c.

References BIAS_POINTER, HeapHandle, RtlpDebugPageHeapAllocate(), and Size.

Referenced by LdrpDphSnapImports().

    04105 {
    04106     return RtlpDebugPageHeapAllocate (
    04107         BIAS_POINTER(HeapHandle),
    04108         Flags,
    04109         Size);
    04110 }

PVOID RtlpDphDllHeapCreate | ( | ULONG | Options,
|  | SIZE_T | InitialSize,
|  | SIZE_T | MaximumSize
| ) |

Definition at line 4519 of file ldrsnap.c.

References DbgPrint, FUN_HEAP_CREATE, LdrpDphSnapRoutines, RtlpDphMsvcrtHeap, and SNAP_ROUTINE_HEAPCREATE.

Referenced by LdrpDphSnapImports().

    04524 {
    04525     PVOID Heap;
    04526     FUN_HEAP_CREATE Original;
    04527
    04528     Original = (FUN_HEAP_CREATE)(LdrpDphSnapRoutines[SNAP_ROUTINE_HEAPCREATE]);
    04529     Heap = (* Original) (Options, InitialSize, MaximumSize);
    04530
    04531     RtlpDphMsvcrtHeap = Heap;
    04532     DbgPrint ("Page heap: detected CRT heap @ %p \n", RtlpDphMsvcrtHeap);
    04533
    04534     return Heap;
    04535 }

BOOLEAN RtlpDphDllHeapFree | ( | IN PVOID | HeapHandle,
|  | IN ULONG | Flags,
|  | IN PVOID | Address
| ) |

Definition at line 4128 of file ldrsnap.c.

References HeapHandle, and RtlpDebugPageHeapFree().

Referenced by LdrpDphSnapImports().

    04133 {
    04134     return RtlpDebugPageHeapFree (
    04135         HeapHandle,
    04136         Flags,
    04137         Address);
    04138 }

PVOID RtlpDphDllHeapReAlloc | ( | IN PVOID | HeapHandle,
|  | IN ULONG | Flags,
|  | IN PVOID | Address,
|  | IN SIZE_T | Size
| ) |

Definition at line 4113 of file ldrsnap.c.

References BIAS_POINTER, HeapHandle, RtlpDebugPageHeapReAllocate(), and Size.

Referenced by LdrpDphSnapImports().

    04119 {
    04120     return RtlpDebugPageHeapReAllocate (
    04121         BIAS_POINTER(HeapHandle),
    04122         Flags,
    04123         Address,
    04124         Size);
    04125 }

PVOID RtlpDphDllLocalAlloc | ( | IN ULONG | Flags,
|  | IN SIZE_T | Size
| ) |

Definition at line 4195 of file ldrsnap.c.

References BIAS_POINTER, FUN_LOCAL_ALLOC, LdrpDphSnapRoutines, LMEM_MOVEABLE, LMEM_ZEROINIT, RtlpDebugPageHeapAllocate(), Size, and SNAP_ROUTINE_LOCALALLOC.

Referenced by LdrpDphSnapImports().

    04199 {
    04200     PVOID Block;
    04201     FUN_LOCAL_ALLOC Original;
    04202
    04203     if (!(Flags & LMEM_MOVEABLE)) {
    04204
    04205         Block = RtlpDebugPageHeapAllocate (
    04206             BIAS_POINTER(RtlProcessHeap()),
    04207             0,
    04208             Size);
    04209
    04210         if ((Flags & LMEM_ZEROINIT)) {
    04211             RtlZeroMemory (Block, Size);
    04212         }
    04213
    04214         return Block;
    04215     }
    04216     else {
    04217
    04218         Original = (FUN_LOCAL_ALLOC)(LdrpDphSnapRoutines[SNAP_ROUTINE_LOCALALLOC]);
    04219         return (* Original) (Flags, Size);
    04220     }
    04221 }

PVOID RtlpDphDllLocalFree | ( | IN PVOID | Address | ) |

Definition at line 4251 of file ldrsnap.c.

References BASE_HANDLE_MARK_BIT, FUN_LOCAL_FREE, LdrpDphSnapRoutines, NULL, RtlpDebugPageHeapFree(), and SNAP_ROUTINE_LOCALFREE.

Referenced by LdrpDphSnapImports().

    04254 {
    04255     BOOLEAN Result;
    04256     FUN_LOCAL_FREE Original;
    04257
    04258     if ((ULONG_PTR)Address & BASE_HANDLE_MARK_BIT) {
    04259
    04260         Original = (FUN_LOCAL_FREE)(LdrpDphSnapRoutines[SNAP_ROUTINE_LOCALFREE]);
    04261         return (* Original) (Address);
    04262     }
    04263     else {
    04264
    04265         Result = RtlpDebugPageHeapFree (
    04266             RtlProcessHeap(),
    04267             0,
    04268             Address);
    04269
    04270         if (Result) {
    04271             return NULL;
    04272         }
    04273         else {
    04274             return Address;
    04275         }
    04276     }
    04277 }

PVOID RtlpDphDllLocalReAlloc | ( | IN PVOID | Address,
|  | IN SIZE_T | Size,
|  | IN ULONG | Flags
| ) |

Definition at line 4224 of file ldrsnap.c.

References BIAS_POINTER, FUN_LOCAL_REALLOC, LdrpDphSnapRoutines, LMEM_MOVEABLE, RtlpDebugPageHeapReAllocate(), Size, and SNAP_ROUTINE_LOCALREALLOC.

Referenced by LdrpDphSnapImports().

    04229 {
    04230     PVOID Block;
    04231     FUN_LOCAL_REALLOC Original;
    04232
    04233     if (!(Flags & LMEM_MOVEABLE)) {
    04234
    04235         Block = RtlpDebugPageHeapReAllocate (
    04236             BIAS_POINTER(RtlProcessHeap()),
    04237             0,
    04238             Address,
    04239             Size);
    04240
    04241         return Block;
    04242     }
    04243     else {
    04244
    04245         Original = (FUN_LOCAL_REALLOC)(LdrpDphSnapRoutines[SNAP_ROUTINE_LOCALREALLOC]);
    04246         return (* Original) (Address, Size, Flags);
    04247     }
    04248 }

PVOID __cdecl RtlpDphDllmalloc | ( | IN SIZE_T | Size | ) |

Definition at line 4369 of file ldrsnap.c.

References ASSERT, BIAS_POINTER, NULL, RtlpDebugPageHeapAllocate(), RtlpDphMsvcrtHeap, and Size.

Referenced by LdrpDphSnapImports().

    04372 {
    04373     PVOID Block;
    04374
    04375     ASSERT(RtlpDphMsvcrtHeap != NULL);
    04376
    04377     Block = RtlpDebugPageHeapAllocate (
    04378         BIAS_POINTER(RtlpDphMsvcrtHeap),
    04379         0,
    04380         Size);
    04381
    04382     return Block;
    04383 }

PVOID __cdecl RtlpDphDllNew | ( | IN SIZE_T | Size | ) |

Definition at line 4452 of file ldrsnap.c.

References ASSERT, BIAS_POINTER, NULL, RtlpDebugPageHeapAllocate(), RtlpDphMsvcrtHeap, and Size.

Referenced by LdrpDphSnapImports().

    04455 {
    04456     PVOID Block;
    04457
    04458     ASSERT(RtlpDphMsvcrtHeap != NULL);
    04459
    04460     Block = RtlpDebugPageHeapAllocate (
    04461         BIAS_POINTER(RtlpDphMsvcrtHeap),
    04462         0,
    04463         Size);
    04464
    04465     return Block;
    04466 }

PVOID __cdecl RtlpDphDllNewArray | ( | IN SIZE_T | Size | ) |

Definition at line 4482 of file ldrsnap.c.

References ASSERT, BIAS_POINTER, NULL, RtlpDebugPageHeapAllocate(), RtlpDphMsvcrtHeap, and Size.

Referenced by LdrpDphSnapImports().

    04485 {
    04486     ASSERT(RtlpDphMsvcrtHeap != NULL);
    04487
    04488     return RtlpDebugPageHeapAllocate (
    04489         BIAS_POINTER(RtlpDphMsvcrtHeap),
    04490         0,
    04491         Size);
    04492 }

PVOID __cdecl RtlpDphDllrealloc | ( | IN PVOID | Address,
|  | IN SIZE_T | Size
| ) |

Definition at line 4405 of file ldrsnap.c.

References ASSERT, BIAS_POINTER, NULL, RtlpDebugPageHeapAllocate(), RtlpDebugPageHeapReAllocate(), RtlpDphMsvcrtHeap, and Size.

Referenced by LdrpDphSnapImports().

    04409 {
    04410     PVOID Block;
    04411
    04412     ASSERT(RtlpDphMsvcrtHeap != NULL);
    04413
    04414     if (Address == NULL) {
    04415
    04416         Block = RtlpDebugPageHeapAllocate (
    04417             BIAS_POINTER(RtlpDphMsvcrtHeap),
    04418             0,
    04419             Size);
    04420     }
    04421     else {
    04422
    04423         Block = RtlpDebugPageHeapReAllocate (
    04424             BIAS_POINTER(RtlpDphMsvcrtHeap),
    04425             0,
    04426             Address,
    04427             Size);
    04428     }
    04429
    04430     return Block;
    04431 }

## Variable Documentation

BOOLEAN LdrpDphKernel32Snapped

| Definition at line 3520 of file ldrsnap.c. Referenced by LdrpDphInitializeTargetDll().

BOOLEAN LdrpDphMsvcrtSnapped

| Definition at line 3521 of file ldrsnap.c. Referenced by LdrpDphInitializeTargetDll().

DPH_SNAP_NAME LdrpDphSnapNamesForKernel32[]

Initial value:

     {

        { "GlobalAlloc",   0 },
        { "GlobalReAlloc", 1 },
        { "GlobalFree",    2 },
        { "LocalAlloc",    3 },
        { "LocalReAlloc",  4 },
        { "LocalFree",     5 },
        { "HeapAlloc",     6 },
        { "HeapReAlloc",   7 },
        { "HeapFree",      8 },
        { "HeapCreate",    9 },
        { NULL, 0 }
    }

Definition at line 3553 of file ldrsnap.c.

Referenced by LdrpDphInitializeTargetDll().

DPH_SNAP_NAME LdrpDphSnapNamesForMsvcrt[]

Initial value:

     {

        { "malloc",        10},
        { "calloc",        11},
        { "realloc",       12},
        { "free",          13},
        { "??2@YAPAXI@Z",  14},
        { "??3@YAXPAX@Z",  15},
        { "??_U@YAPAXI@Z", 16},
        { "??_V@YAXPAX@Z", 17},
        { NULL, 0 }
    }

Definition at line 3569 of file ldrsnap.c.

Referenced by LdrpDphInitializeTargetDll().

PVOID LdrpDphSnapRoutines[SNAP_ROUTINE_MAX_INDEX]

| Definition at line 3543 of file ldrsnap.c. Referenced by LdrpDphDetectSnapRoutines(), LdrpDphSnapImports(), RtlpDphDllGlobalAlloc(), RtlpDphDllGlobalFree(), RtlpDphDllGlobalReAlloc(), RtlpDphDllHeapCreate(), RtlpDphDllLocalAlloc(), RtlpDphDllLocalFree(), and RtlpDphDllLocalReAlloc().

PVOID RtlpDphMsvcrtHeap

| Definition at line 3703 of file ldrsnap.c. Referenced by RtlpDphDllcalloc(), RtlpDphDllDelete(), RtlpDphDllDeleteArray(), RtlpDphDllfree(), RtlpDphDllHeapCreate(), RtlpDphDllmalloc(), RtlpDphDllNew(), RtlpDphDllNewArray(), and RtlpDphDllrealloc().