00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define LDRDBG 0
00024
00025
#include "ntos.h"
00026
#include <nt.h>
00027
#include <ntrtl.h>
00028
#include <nturtl.h>
00029
#include <heap.h>
00030
#include "ldrp.h"
00031
00032
#if DBG // DBG
00033
PUCHAR MonthOfYear[] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
00034
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" };
00035 PUCHAR DaysOfWeek[] = {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat" };
00036 LARGE_INTEGER MapBeginTime, MapEndTime, MapElapsedTime;
00037
#endif // DBG
00038
00039
#if defined (_ALPHA_)
00040
VOID
00041 AlphaFindArchitectureFixups(
00042 PIMAGE_NT_HEADERS NtHeaders,
00043 PVOID ViewBase,
00044 BOOLEAN StaticLink
00045 );
00046
#endif
00047
00048
00049
#if defined (_X86_)
00050
extern PVOID LdrpLockPrefixTable;
00051
00052
00053
00054
00055 IMAGE_LOAD_CONFIG_DIRECTORY _load_config_used = {
00056 0,
00057 0,
00058 0,
00059 0,
00060 0,
00061 0,
00062 0,
00063 0,
00064 0,
00065 (ULONG_PTR) &LdrpLockPrefixTable,
00066 0, 0, 0, 0, 0, 0, 0
00067 };
00068
00069
void
00070 LdrpValidateImageForMp(
00071 IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry
00072 )
00073 {
00074 PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData;
00075 ULONG i;
00076 PUCHAR *pb;
00077 ULONG ErrorParameters;
00078 ULONG ErrorResponse;
00079
00080
00081
00082
00083
00084
00085
00086 ImageConfigData =
RtlImageDirectoryEntryToData( LdrDataTableEntry->DllBase,
00087 TRUE,
00088 IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
00089 &i
00090 );
00091
00092
if (ImageConfigData !=
NULL &&
00093 i ==
sizeof( *ImageConfigData ) &&
00094 ImageConfigData->LockPrefixTable ) {
00095 pb = (PUCHAR *)ImageConfigData->LockPrefixTable;
00096
while ( *pb ) {
00097
if ( **pb == (UCHAR)0x90 ) {
00098
00099
if (
LdrpNumberOfProcessors > 1 ) {
00100
00101
00102
00103
00104
00105 ErrorParameters = (ULONG)&LdrDataTableEntry->BaseDllName;
00106
00107
NtRaiseHardError(
00108 STATUS_IMAGE_MP_UP_MISMATCH,
00109 1,
00110 1,
00111 &ErrorParameters,
00112 OptionOk,
00113 &ErrorResponse
00114 );
00115
00116
if (
LdrpInLdrInit ) {
00117
LdrpFatalHardErrorCount++;
00118 }
00119
00120 }
00121 }
00122 pb++;
00123 }
00124 }
00125 }
00126
#endif
00127
00128
NTSTATUS
00129
LdrpWalkImportDescriptor (
00130 IN PWSTR DllPath OPTIONAL,
00131 IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry
00132 );
00133
00134
VOID
00135
LdrpDphInitializeTargetDll (
00136 PLDR_DATA_TABLE_ENTRY LoadedDllData
00137 );
00138
00139
NTSTATUS
00140 LdrpLoadImportModule(
00141 IN PWSTR DllPath OPTIONAL,
00142 IN LPSTR ImportName,
00143 IN PVOID DllBaseImporter,
00144 OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry,
00145 OUT PBOOLEAN AlreadyLoaded
00146 )
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
00170
00171
00172
00173
00174
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 }
00211
00212
00213
NTSTATUS
00214 LdrpWalkImportDescriptor (
00215 IN PWSTR DllPath OPTIONAL,
00216 IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry
00217 )
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 {
00241 ULONG i, ImportSize, NewImportSize;
00242 BOOLEAN AlreadyLoaded, SnapForwardersOnly, StaleBinding;
00243 PLDR_DATA_TABLE_ENTRY DataTableEntry, FwdDataTableEntry;
00244 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
00245 PIMAGE_BOUND_IMPORT_DESCRIPTOR NewImportDescriptor;
00246 PIMAGE_BOUND_FORWARDER_REF NewImportForwarder;
00247 PSZ ImportName, NewImportName, NewFwdImportName, NewImportStringBase;
00248
NTSTATUS st;
00249 PIMAGE_NT_HEADERS ExportNtHeaders;
00250 PVOID ImportBase;
00251 ULONG RegionSize;
00252 PIMAGE_THUNK_DATA Thunk,
Name;
00253 PIMAGE_THUNK_DATA FirstThunk;
00254 PPEB Peb = NtCurrentPeb();
00255
00256
00257
00258
00259
00260
00261
00262
00263 NewImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)
RtlImageDirectoryEntryToData(
00264 LdrDataTableEntry->DllBase,
00265
TRUE,
00266 IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
00267 &NewImportSize
00268 );
00269
00270 ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)
RtlImageDirectoryEntryToData(
00271 LdrDataTableEntry->DllBase,
00272
TRUE,
00273 IMAGE_DIRECTORY_ENTRY_IMPORT,
00274 &ImportSize
00275 );
00276
00277
00278
if (NewImportDescriptor) {
00279 NewImportStringBase = (LPSTR)NewImportDescriptor;
00280
while (NewImportDescriptor->OffsetModuleName) {
00281 NewImportName = NewImportStringBase +
00282 NewImportDescriptor->OffsetModuleName;
00283
00284
if (
ShowSnaps) {
00285
DbgPrint(
"LDR: %wZ bound to %s\n",
00286 &LdrDataTableEntry->BaseDllName,
00287 NewImportName
00288 );
00289 }
00290
00291 st =
LdrpLoadImportModule( DllPath,
00292 NewImportName,
00293 LdrDataTableEntry->DllBase,
00294 &DataTableEntry,
00295 &AlreadyLoaded
00296 );
00297
if ( !
NT_SUCCESS(st) ) {
00298
return st;
00299 }
00300
00301
00302
00303
00304
00305
if (!AlreadyLoaded) {
00306 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
00307 &DataTableEntry->InInitializationOrderLinks);
00308 }
00309
00310
#if defined (_ALPHA_) && defined (WX86)
00311
ExportNtHeaders =
RtlImageNtHeader(LdrDataTableEntry->DllBase);
00312
00313
if ((ExportNtHeaders->OptionalHeader.SectionAlignment <
PAGE_SIZE) &&
00314 (ExportNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)) {
00315
if (LdrpWx86DllHasRelocatedSharedSection(LdrDataTableEntry->DllBase)) {
00316 DataTableEntry->Flags |= LDRP_IMAGE_NOT_AT_BASE;
00317 }
00318 }
00319
#endif // defined (_ALPHA_) && defined (WX86)
00320
00321
if ( NewImportDescriptor->TimeDateStamp != DataTableEntry->TimeDateStamp ||
00322 (DataTableEntry->Flags & LDRP_IMAGE_NOT_AT_BASE) ) {
00323
if (
ShowSnaps) {
00324
DbgPrint(
"LDR: %wZ has stale binding to %s\n",
00325 &LdrDataTableEntry->BaseDllName,
00326 NewImportName
00327 );
00328 }
00329 StaleBinding =
TRUE;
00330 }
else {
00331
#if DBG
00332
LdrpSnapBypass++;
00333
#endif
00334
if (
ShowSnaps) {
00335
DbgPrint(
"LDR: %wZ has correct binding to %s\n",
00336 &LdrDataTableEntry->BaseDllName,
00337 NewImportName
00338 );
00339 }
00340 StaleBinding =
FALSE;
00341 }
00342
00343 NewImportForwarder = (PIMAGE_BOUND_FORWARDER_REF)(NewImportDescriptor+1);
00344
for (i=0; i<NewImportDescriptor->NumberOfModuleForwarderRefs; i++) {
00345 NewFwdImportName = NewImportStringBase +
00346 NewImportForwarder->OffsetModuleName;
00347
if (
ShowSnaps) {
00348
DbgPrint(
"LDR: %wZ bound to %s via forwarder(s) from %wZ\n",
00349 &LdrDataTableEntry->BaseDllName,
00350 NewFwdImportName,
00351 &DataTableEntry->BaseDllName
00352 );
00353 }
00354
00355 st =
LdrpLoadImportModule( DllPath,
00356 NewFwdImportName,
00357 LdrDataTableEntry->DllBase,
00358 &FwdDataTableEntry,
00359 &AlreadyLoaded
00360 );
00361
if (
NT_SUCCESS(st) ) {
00362
if (!AlreadyLoaded) {
00363 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
00364 &FwdDataTableEntry->InInitializationOrderLinks);
00365 }
00366 }
00367
00368
if ( !
NT_SUCCESS(st) ||
00369 NewImportForwarder->TimeDateStamp != FwdDataTableEntry->TimeDateStamp ||
00370 (FwdDataTableEntry->Flags & LDRP_IMAGE_NOT_AT_BASE ) ) {
00371
if (
ShowSnaps) {
00372
DbgPrint(
"LDR: %wZ has stale binding to %s\n",
00373 &LdrDataTableEntry->BaseDllName,
00374 NewFwdImportName
00375 );
00376 }
00377 StaleBinding =
TRUE;
00378 }
else {
00379
#if DBG
00380
LdrpSnapBypass++;
00381
#endif
00382
if (
ShowSnaps) {
00383
DbgPrint(
"LDR: %wZ has correct binding to %s\n",
00384 &LdrDataTableEntry->BaseDllName,
00385 NewFwdImportName
00386 );
00387 }
00388 }
00389
00390 NewImportForwarder += 1;
00391 }
00392 NewImportDescriptor = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewImportForwarder;
00393
00394
if (StaleBinding) {
00395
#if DBG
00396
LdrpNormalSnap++;
00397
#endif
00398
00399
00400
00401
00402
00403 ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)
RtlImageDirectoryEntryToData(
00404 LdrDataTableEntry->DllBase,
00405
TRUE,
00406 IMAGE_DIRECTORY_ENTRY_IMPORT,
00407 &ImportSize
00408 );
00409
00410
while (ImportDescriptor->Name) {
00411 ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->Name);
00412
if (!_stricmp(ImportName, NewImportName)) {
00413
break;
00414 }
00415
00416 ImportDescriptor += 1;
00417 }
00418
00419
if (!ImportDescriptor->Name) {
00420
return STATUS_OBJECT_NAME_INVALID;
00421 }
00422
00423
if (
ShowSnaps) {
00424
DbgPrint(
"LDR: Stale Bind %s from %wZ\n",ImportName,&LdrDataTableEntry->BaseDllName);
00425 }
00426
00427 st =
LdrpSnapIAT(
00428 DataTableEntry,
00429 LdrDataTableEntry,
00430 ImportDescriptor,
00431
FALSE
00432 );
00433
00434
if (!
NT_SUCCESS(st)) {
00435
return st;
00436 }
00437 }
00438 }
00439 }
00440
else
00441
if (ImportDescriptor) {
00442
00443
00444
00445
00446
00447
while (ImportDescriptor->Name && ImportDescriptor->FirstThunk) {
00448 ImportName = (PSZ)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->Name);
00449
00450
00451
00452
00453 FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)LdrDataTableEntry->DllBase + ImportDescriptor->FirstThunk);
00454
if ( !FirstThunk->u1.Function ) {
00455
goto skipimport;
00456 }
00457
00458
if (
ShowSnaps) {
00459
DbgPrint(
"LDR: %s used by %wZ\n",
00460 ImportName,
00461 &LdrDataTableEntry->BaseDllName
00462 );
00463 }
00464
00465
00466 st =
LdrpLoadImportModule( DllPath,
00467 ImportName,
00468 LdrDataTableEntry->DllBase,
00469 &DataTableEntry,
00470 &AlreadyLoaded
00471 );
00472
if ( !
NT_SUCCESS(st) ) {
00473
return st;
00474 }
00475
00476
if (
ShowSnaps) {
00477
DbgPrint(
"LDR: Snapping imports for %wZ from %s\n",
00478 &LdrDataTableEntry->BaseDllName,
00479 ImportName
00480 );
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490 SnapForwardersOnly =
FALSE;
00491
00492
if ( ImportDescriptor->OriginalFirstThunk ) {
00493
if ( ImportDescriptor->TimeDateStamp &&
00494 ImportDescriptor->TimeDateStamp == DataTableEntry->TimeDateStamp &&
00495 (! DataTableEntry->Flags & LDRP_IMAGE_NOT_AT_BASE) ) {
00496
#if DBG
00497
LdrpSnapBypass++;
00498
#endif
00499
if (
ShowSnaps) {
00500
DbgPrint(
"LDR: Snap bypass %s from %wZ\n",
00501 ImportName,
00502 &LdrDataTableEntry->BaseDllName
00503 );
00504 }
00505
00506
if (ImportDescriptor->ForwarderChain == -1) {
00507
goto bypass_snap;
00508 }
00509
00510 SnapForwardersOnly =
TRUE;
00511
00512 }
00513 }
00514
#if DBG
00515
LdrpNormalSnap++;
00516
#endif
00517
00518
00519
00520
00521
if (!AlreadyLoaded) {
00522 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
00523 &DataTableEntry->InInitializationOrderLinks);
00524 }
00525 st =
LdrpSnapIAT(
00526 DataTableEntry,
00527 LdrDataTableEntry,
00528 ImportDescriptor,
00529 SnapForwardersOnly
00530 );
00531
00532
if (!
NT_SUCCESS(st)) {
00533
return st;
00534 }
00535 AlreadyLoaded =
TRUE;
00536 bypass_snap:
00537
00538
00539
00540
00541
if (!AlreadyLoaded) {
00542 InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
00543 &DataTableEntry->InInitializationOrderLinks);
00544 }
00545
00546 skipimport:
00547 ++ImportDescriptor;
00548 }
00549 }
00550
00551
if (Peb->NtGlobalFlag & FLG_HEAP_ENABLE_TAG_BY_DLL) {
00552 PVOID IATBase;
00553 SIZE_T BigIATSize;
00554 ULONG LittleIATSize;
00555 PVOID *ProcAddresses;
00556 ULONG NumberOfProcAddresses;
00557 ULONG OldProtect;
00558
USHORT TagIndex;
00559
00560
00561
00562
00563
00564
00565
00566
00567 IATBase =
RtlImageDirectoryEntryToData( LdrDataTableEntry->DllBase,
00568
TRUE,
00569 IMAGE_DIRECTORY_ENTRY_IAT,
00570 &LittleIATSize
00571 );
00572 BigIATSize = LittleIATSize;
00573
if (IATBase !=
NULL) {
00574 st =
NtProtectVirtualMemory( NtCurrentProcess(),
00575 &IATBase,
00576 &BigIATSize,
00577 PAGE_READWRITE,
00578 &OldProtect
00579 );
00580
if (!
NT_SUCCESS(st)) {
00581
DbgPrint(
"LDR: Unable to unprotect IAT to enable tagging by DLL.\n" );
00582 }
00583
else {
00584 ProcAddresses = (PVOID *)IATBase;
00585 NumberOfProcAddresses = (ULONG)(BigIATSize /
sizeof(PVOID));
00586
while (NumberOfProcAddresses--) {
00587
if (*ProcAddresses ==
RtlAllocateHeap) {
00588 *ProcAddresses =
LdrpDefineDllTag( LdrDataTableEntry->BaseDllName.Buffer, &TagIndex );
00589
if (*ProcAddresses ==
NULL) {
00590 *ProcAddresses =
RtlAllocateHeap;
00591 }
00592 }
00593
00594 ProcAddresses += 1;
00595 }
00596
00597
NtProtectVirtualMemory( NtCurrentProcess(),
00598 &IATBase,
00599 &BigIATSize,
00600 OldProtect,
00601 &OldProtect
00602 );
00603 }
00604 }
00605 }
00606
00607
00608
00609
00610
00611
00612
if (Peb->NtGlobalFlag & FLG_HEAP_PAGE_ALLOCS) {
00613
00614
LdrpDphInitializeTargetDll (LdrDataTableEntry);
00615 }
00616
00617
return STATUS_SUCCESS;
00618 }
00619
00620
00621 ULONG
00622 LdrpClearLoadInProgress(
00623 VOID
00624 )
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
00639
00640
00641
00642
if ( !(LdrDataTableEntry->Flags & LDRP_ENTRY_PROCESSED) && LdrDataTableEntry->EntryPoint) {
00643 i++;
00644 }
00645
00646 Next = Next->Flink;
00647 }
00648
return i;
00649 }
00650
00651
NTSTATUS
00652 LdrpRunInitializeRoutines(
00653 IN PCONTEXT Context OPTIONAL
00654 )
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
00668
00669
00670
00671
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
00734
00735
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
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
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 }
00830
00831 BOOLEAN
00832 LdrpCheckForLoadedDll (
00833 IN PWSTR DllPath OPTIONAL,
00834 IN PUNICODE_STRING DllName,
00835 IN BOOLEAN StaticLink,
00836 IN BOOLEAN Wx86KnownDll,
00837 OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry
00838 )
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
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
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
00953
00954
00955
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
00968
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
01001
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
01022
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
01046
01047
01048
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 0
L,
01115 0
L,
01116
NULL,
01117 &ViewSize,
01118 ViewShare,
01119 0
L,
01120 PAGE_EXECUTE
01121 );
01122
NtClose(Section);
01123
if (!
NT_SUCCESS(st)) {
01124
goto alldone;
01125 }
01126
01127
01128
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
01144
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
01157
01158
01159
01160
01161 NtHeadersE =
RtlImageNtHeader(Entry->DllBase);
01162
01163
if ( RtlCompareMemory(NtHeadersE,NtHeadersSrc,
sizeof(*NtHeadersE)) ) {
01164
01165
01166
01167
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 }
01193
01194
01195 BOOLEAN
01196 LdrpCheckForLoadedDllHandle (
01197 IN PVOID DllHandle,
01198 OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry
01199 )
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
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
01244
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 }
01259
01260
NTSTATUS
01261 LdrpMapDll (
01262 IN PWSTR DllPath OPTIONAL,
01263 IN PWSTR DllName,
01264 IN PULONG DllCharacteristics OPTIONAL,
01265 IN BOOLEAN StaticLink,
01266 IN BOOLEAN Wx86KnownDll,
01267 OUT PLDR_DATA_TABLE_ENTRY *LdrDataTableEntry
01268 )
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
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
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
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
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 0
L,
01494 0
L,
01495
NULL,
01496 &ViewSize,
01497 ViewShare,
01498 0
L,
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
01546
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
01561
01562 st = Wx86IdentifyPlugin(ViewBase, &FullDllName );
01563
01564
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
01575
01576
01577
NtUnmapViewOfSection(NtCurrentProcess(),ViewBase);
01578 ViewBase =
NULL;
01579
01580
01581
01582
01583
if (Wx86ProcessInit) {
01584
01585
01586
01587 st = LdrpWx86MapDll(
NULL,
01588 DllCharacteristics,
01589 !Wx86KnownDll,
01590 StaticLink,
01591 &FullDllName,
01592 &Entry,
01593 &ViewSize,
01594 &Section
01595 );
01596
01597
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
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
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
01689
01690
01691
01692 ErrorStatus = STATUS_SUCCESS;
01693 ErrorResponse = ResponseCancel;
01694
01695
if ( ImageHeader->OptionalHeader.MajorSubsystemVersion <= 3 ) {
01696
01697 Entry->EntryPoint = 0;
01698
01699
01700
01701
01702
01703
01704
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
01751
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
01771
01772
01773
01774
if ( !ScanEntry->InMemoryOrderLinks.Flink ) {
01775
continue;
01776 }
01777
01778
01779
01780
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
01825
01826
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
01839
01840
01841
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
01859
01860
01861
01862
01863
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
01898
01899
01900
01901
01902
01903
01904
01905 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
01906 Teb->NtTib.ArbitraryUserPointer = (PVOID)FullDllName.Buffer;
01907
NtMapViewOfSection(
01908 Section,
01909 NtCurrentProcess(),
01910 (PVOID *)&ViewBase,
01911 0
L,
01912 0
L,
01913
NULL,
01914 &ViewSize,
01915 ViewShare,
01916 0
L,
01917 PAGE_READWRITE
01918 );
01919 Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer;
01920
01921 st =
LdrpSetProtection(ViewBase,
TRUE, StaticLink);
01922
01923 }
01924 }
01925 skipreloc:
01926
01927
01928
01929
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
01950
01951
01952 ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer;
01953 Teb->NtTib.ArbitraryUserPointer = (PVOID)FullDllName.Buffer;
01954
NtMapViewOfSection(
01955 Section,
01956 NtCurrentProcess(),
01957 (PVOID *)&ViewBase,
01958 0
L,
01959 0
L,
01960
NULL,
01961 &ViewSize,
01962 ViewShare,
01963 0
L,
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
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 }
01992
01993
#if defined (_ALPHA_)
01994
01995
#define asm __asm
01996
#pragma intrinsic (__asm)
01997
01998
VOID
01999 AlphaApplyArchitectureFixups(
02000 IN PIMAGE_ARCHITECTURE_HEADER ArchHeader,
02001 IN ULONG ArchHeaderByteSize,
02002 IN ULONG_PTR BaseAddr
02003 )
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031 {
02032 ULONG
Count, Entry;
02033 ULONG SystemAmask;
02034 ULONG ReplacementInstruction;
02035 PIMAGE_ARCHITECTURE_HEADER ArchHeaderEnd;
02036 PIMAGE_ARCHITECTURE_ENTRY ArchEntry;
02037
02038
02039
02040 ArchHeaderEnd = (PIMAGE_ARCHITECTURE_HEADER)((PCHAR)ArchHeader + ArchHeaderByteSize);
02041
02042
02043
02044
02045
02046
while (*(PULONGLONG)ArchHeader == 0
L)
02047 ArchHeader++;
02048
02049 SystemAmask = ~asm(
"amask $16, $0", -1);
02050
02051
while ((*(PULONGLONG)ArchHeader != 0xffffffff
L) && (ArchHeader < ArchHeaderEnd)) {
02052
if (*(PULONGLONG)ArchHeader != 0
L) {
02053
#if DBG && ARCH_DBG
02054
DbgPrint(
"ARCH: Amask=0x%x, Current Header=0x%08x, Shift=%d, Value=%d\n",
02055 SystemAmask, *ArchHeader,
02056 ArchHeader->AmaskShift, ArchHeader->AmaskValue);
02057
#endif
02058
if (((SystemAmask >> ArchHeader->AmaskShift) & 1) != ArchHeader->AmaskValue) {
02059
02060
02061
02062
02063
02064 PIMAGE_ARCHITECTURE_ENTRY ArchEntry;
02065
02066 ArchEntry = (PIMAGE_ARCHITECTURE_ENTRY)(ArchHeader->FirstEntryRVA + BaseAddr);
02067
02068
while (*(PULONGLONG)ArchEntry != 0xffffffff
L) {
02069
02070
if (*(PULONGLONG)ArchEntry != 0
L) {
02071
#if DBG && ARCH_DBG
02072
DbgPrint(
"ARCH: 0x%08x -> 0x%08x\n",
02073 *(PALPHA_INSTRUCTION)(ArchEntry->FixupInstRVA + BaseAddr),
02074 ArchEntry->NewInst
02075 );
02076
#endif
02077
*(ULONG *)(ArchEntry->FixupInstRVA + BaseAddr) = ArchEntry->NewInst;
02078 }
02079 ArchEntry++;
02080 }
02081 }
02082 }
02083 ArchHeader++;
02084 }
02085 }
02086
02087
VOID
02088 AlphaFindArchitectureFixups(
02089 PIMAGE_NT_HEADERS NtHeaders,
02090 PVOID ViewBase,
02091 BOOLEAN StaticLink
02092 )
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115 {
02116 ULONG
Size;
02117 PIMAGE_ARCHITECTURE_HEADER ImageArchData;
02118
02119
if (NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_ALPHA) {
02120
02121
02122
02123
02124
02125
02126
return;
02127 }
02128
02129 ImageArchData =
02130 (PIMAGE_ARCHITECTURE_HEADER)
RtlImageDirectoryEntryToData(
02131 ViewBase,
02132 TRUE,
02133 IMAGE_DIRECTORY_ENTRY_ARCHITECTURE,
02134 &Size
02135 );
02136
if (ImageArchData) {
02137
NTSTATUS st;
02138
02139 st =
LdrpSetProtection(ViewBase, FALSE, StaticLink);
02140
02141
if (
NT_SUCCESS(st)) {
02142 AlphaApplyArchitectureFixups(ImageArchData, Size, (ULONG_PTR)ViewBase);
02143
LdrpSetProtection(ViewBase, TRUE, StaticLink);
02144 }
02145 }
02146 }
02147
#endif
02148
02149
NTSTATUS
02150 LdrpCreateDllSection(
02151 IN PUNICODE_STRING NtFullDllName,
02152 IN HANDLE DllFile,
02153 IN PUNICODE_STRING BaseName,
02154 IN PULONG DllCharacteristics OPTIONAL,
02155 OUT PHANDLE SectionHandle
02156 )
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
02167
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
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 }
02256
02257
NTSTATUS
02258 LdrpSnapIAT (
02259 IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry_Export,
02260 IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry_Import,
02261 IN PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor,
02262 IN BOOLEAN SnapForwardersOnly
02263 )
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
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
02320
02321
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
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
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
02423
02424
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
02462
02463
02464
NtProtectVirtualMemory( NtCurrentProcess(),
02465 &IATBase,
02466 &IATSize,
02467 OldProtect,
02468 &OldProtect
02469 );
02470
NtFlushInstructionCache( NtCurrentProcess(), IATBase, LittleIATSize );
02471
02472
return st;
02473 }
02474
02475
NTSTATUS
02476 LdrpSnapThunk (
02477 IN PVOID DllBase,
02478 IN PVOID ImageBase,
02479 IN PIMAGE_THUNK_DATA OriginalThunk,
02480 IN OUT PIMAGE_THUNK_DATA Thunk,
02481 IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
02482 IN ULONG ExportSize,
02483 IN BOOLEAN StaticSnap,
02484 IN PSZ DllName
02485 )
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
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
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
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
02548
02549
02550 NameTableBase = (PULONG)((ULONG_PTR)DllBase + (ULONG)ExportDirectory->AddressOfNames);
02551 NameOrdinalTableBase = (
PUSHORT)((ULONG_PTR)DllBase + (ULONG)ExportDirectory->AddressOfNameOrdinals);
02552
02553
02554
02555
02556
02557
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
02591
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
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
02710
02711
02712
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 }
02745
02746
USHORT
02747 LdrpNameToOrdinal (
02748 IN PSZ Name,
02749 IN ULONG NumberOfNames,
02750 IN PVOID DllBase,
02751 IN PULONG NameTableBase,
02752 IN PUSHORT NameOrdinalTableBase
02753 )
02754 {
02755 LONG High;
02756 LONG Low;
02757 LONG Middle;
02758 LONG Result;
02759
02760
02761
02762
02763
02764 Low = 0;
02765 High = NumberOfNames - 1;
02766
while (High >= Low) {
02767
02768
02769
02770
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
02789
02790
02791
02792
02793
if (High < Low) {
02794
return (
USHORT)-1;
02795 }
else {
02796
return NameOrdinalTableBase[Middle];
02797 }
02798
02799 }
02800
02801
VOID
02802 LdrpUpdateLoadCount (
02803 IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry,
02804 IN BOOLEAN IncrementCount
02805 )
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
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
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
02870
02871
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
02986
02987
02988
02989
02990
02991
02992
02993
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 }
03041
03042 PLDR_DATA_TABLE_ENTRY
03043 LdrpAllocateDataTableEntry (
03044 IN PVOID DllBase
03045 )
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
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 }
03082
03083
VOID
03084 LdrpInsertMemoryTableEntry (
03085 IN PLDR_DATA_TABLE_ENTRY LdrDataTableEntry
03086 )
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
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 }
03118
03119 BOOLEAN
03120 LdrpResolveDllName (
03121 IN PWSTR DllPath OPTIONAL,
03122 IN PWSTR DllName,
03123 OUT PUNICODE_STRING FullDllName,
03124 OUT PUNICODE_STRING BaseDllName,
03125 OUT PHANDLE DllFile
03126 )
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
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
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 }
03246
03247
03248 PVOID
03249 LdrpFetchAddressOfEntryPoint (
03250 IN PVOID Base
03251 )
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
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 }
03281
03282 HANDLE
03283 LdrpCheckForKnownDll (
03284 IN PWSTR DllName,
03285 OUT PUNICODE_STRING FullDllName,
03286 OUT PUNICODE_STRING BaseDllName
03287 )
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
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
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
03351
03352
03353 FullDllName->Length = (
USHORT)(
LdrpKnownDllPath.Length +
03354 (
USHORT)
sizeof(WCHAR) +
03355 BaseDllName->Length
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
03377
03378
03379
Unicode.Buffer = (PWSTR)p;
03380
Unicode.Length = BaseDllName->Length;
03381
Unicode.MaximumLength =
Unicode.Length + (
USHORT)
sizeof(UNICODE_NULL);
03382
03383 RtlMoveMemory(p,BaseDllName->Buffer,BaseDllName->MaximumLength);
03384
03385
03386
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 }
03415
03416
NTSTATUS
03417 LdrpSetProtection (
03418 IN PVOID Base,
03419 IN BOOLEAN Reset,
03420 IN BOOLEAN StaticLink
03421 )
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
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
03466
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
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 }
03515
03519
03520 BOOLEAN
LdrpDphKernel32Snapped;
03521 BOOLEAN
LdrpDphMsvcrtSnapped;
03522
03523 #define SNAP_ROUTINE_GLOBALALLOC 0
03524 #define SNAP_ROUTINE_GLOBALREALLOC 1
03525 #define SNAP_ROUTINE_GLOBALFREE 2
03526 #define SNAP_ROUTINE_LOCALALLOC 3
03527 #define SNAP_ROUTINE_LOCALREALLOC 4
03528 #define SNAP_ROUTINE_LOCALFREE 5
03529 #define SNAP_ROUTINE_HEAPALLOC 6
03530 #define SNAP_ROUTINE_HEAPREALLOC 7
03531 #define SNAP_ROUTINE_HEAPFREE 8
03532 #define SNAP_ROUTINE_HEAPCREATE 9
03533 #define SNAP_ROUTINE_MALLOC 10
03534 #define SNAP_ROUTINE_CALLOC 11
03535 #define SNAP_ROUTINE_REALLOC 12
03536 #define SNAP_ROUTINE_FREE 13
03537 #define SNAP_ROUTINE_NEW 14
03538 #define SNAP_ROUTINE_DELETE 15
03539 #define SNAP_ROUTINE_NEW_ARRAY 16
03540 #define SNAP_ROUTINE_DELETE_ARRAY 17
03541 #define SNAP_ROUTINE_MAX_INDEX 18
03542
03543 PVOID
LdrpDphSnapRoutines [
SNAP_ROUTINE_MAX_INDEX];
03544
03545 typedef struct _DPH_SNAP_NAME {
03546
03547 PSTR
Name;
03548 ULONG
Index;
03549
03550 }
DPH_SNAP_NAME, *
PDPH_SNAP_NAME;
03551
03552
DPH_SNAP_NAME
03553 LdrpDphSnapNamesForKernel32 [] = {
03554
03555 {
"GlobalAlloc", 0 },
03556 {
"GlobalReAlloc", 1 },
03557 {
"GlobalFree", 2 },
03558 {
"LocalAlloc", 3 },
03559 {
"LocalReAlloc", 4 },
03560 {
"LocalFree", 5 },
03561 {
"HeapAlloc", 6 },
03562 {
"HeapReAlloc", 7 },
03563 {
"HeapFree", 8 },
03564 {
"HeapCreate", 9 },
03565 {
NULL, 0 }
03566 };
03567
03568
DPH_SNAP_NAME
03569 LdrpDphSnapNamesForMsvcrt [] = {
03570
03571 {
"malloc", 10},
03572 {
"calloc", 11},
03573 {
"realloc", 12},
03574 {
"free", 13},
03575 {
"??2@YAPAXI@Z", 14},
03576 {
"??3@YAXPAX@Z", 15},
03577 {
"??_U@YAPAXI@Z", 16},
03578 {
"??_V@YAXPAX@Z", 17},
03579 {
NULL, 0 }
03580 };
03581
03582
03583
03584
03585
03586 PVOID
03587
RtlpDphDllHeapAlloc (
03588 IN PVOID HeapHandle,
03589 IN ULONG Flags,
03590 IN SIZE_T Size
03591 );
03592
03593 PVOID
03594
RtlpDphDllHeapReAlloc (
03595 IN PVOID HeapHandle,
03596 IN ULONG Flags,
03597 IN PVOID Address,
03598 IN SIZE_T Size
03599 );
03600
03601 BOOLEAN
03602
RtlpDphDllHeapFree(
03603 IN PVOID HeapHandle,
03604 IN ULONG Flags,
03605 IN PVOID Address
03606 );
03607
03608 PVOID
03609
RtlpDphDllLocalAlloc (
03610 IN ULONG Flags,
03611 IN SIZE_T Size
03612 );
03613
03614 PVOID
03615
RtlpDphDllLocalReAlloc (
03616 IN PVOID Address,
03617 IN SIZE_T Size,
03618 IN ULONG Flags
03619 );
03620
03621 PVOID
03622
RtlpDphDllLocalFree(
03623 IN PVOID Address
03624 );
03625
03626 PVOID
03627
RtlpDphDllGlobalAlloc (
03628 IN ULONG Flags,
03629 IN SIZE_T Size
03630 );
03631
03632 PVOID
03633
RtlpDphDllGlobalReAlloc (
03634 IN PVOID Address,
03635 IN SIZE_T Size,
03636 IN ULONG Flags
03637 );
03638
03639 PVOID
03640
RtlpDphDllGlobalFree(
03641 IN PVOID Address
03642 );
03643
03644 PVOID __cdecl
03645
RtlpDphDllmalloc (
03646 IN SIZE_T Size
03647 );
03648
03649 PVOID __cdecl
03650
RtlpDphDllcalloc (
03651 IN SIZE_T Number,
03652 IN SIZE_T Size
03653 );
03654
03655 PVOID __cdecl
03656
RtlpDphDllrealloc (
03657 IN PVOID Address,
03658 IN SIZE_T Size
03659 );
03660
03661
VOID __cdecl
03662
RtlpDphDllfree (
03663 IN PVOID Address
03664 );
03665
03666 PVOID __cdecl
03667
RtlpDphDllNew (
03668 IN SIZE_T Size
03669 );
03670
03671
VOID __cdecl
03672
RtlpDphDllDelete (
03673 IN PVOID Address
03674 );
03675
03676 PVOID __cdecl
03677
RtlpDphDllNewArray (
03678 IN SIZE_T Size
03679 );
03680
03681
VOID __cdecl
03682
RtlpDphDllDeleteArray (
03683 IN PVOID Address
03684 );
03685
03686
03687
03688
03689
03690
03691 PVOID
03692
RtlpDphDllHeapCreate (
03693 ULONG Options,
03694 SIZE_T InitialSize,
03695 SIZE_T MaximumSize
03696 );
03697
03698
03699
03700
03701
03702
03703 PVOID
RtlpDphMsvcrtHeap;
03704
03705
03706
03707
03708
03709 BOOLEAN
03710 LdrpDphDetectSnapRoutines (
03711 PWSTR DllString,
03712 PDPH_SNAP_NAME SnapNames
03713 )
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 }
03779
03780 BOOLEAN
03781 LdrpDphSnapImports (
03782 PLDR_DATA_TABLE_ENTRY LdrDataTableEntry,
03783 BOOLEAN CallToDetectCrtHeap
03784 )
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
03797
03798
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
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
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
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 }
03968
03969
VOID
03970 LdrpDphInitializeTargetDll (
03971 PLDR_DATA_TABLE_ENTRY LoadedDllData
03972 )
03973 {
03974 BOOLEAN Kernel32JustSnapped =
FALSE;
03975 BOOLEAN MsvcrtJustSnapped =
FALSE;
03976
03977
03978
03979
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
04006
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
04068
04069
04070
04071
if (_wcsicmp (LoadedDllData->BaseDllName.Buffer,
L"msvcrt.dll") == 0) {
04072
04073
LdrpDphSnapImports (LoadedDllData,
TRUE);
04074 }
04075
04076
04077
04078
04079
04080
04081
if (
RtlpDphIsDllTargeted (LoadedDllData->BaseDllName.Buffer)) {
04082
04083
LdrpDphSnapImports (LoadedDllData,
FALSE);
04084 }
04085 }
04086
04090
04091
04092
04093
04094
04095
04096
04097 #define BIAS_POINTER(p) ((PVOID)((ULONG_PTR)(p) | 0x01))
04098
04099 PVOID
04100 RtlpDphDllHeapAlloc (
04101 IN PVOID HeapHandle,
04102 IN ULONG Flags,
04103 IN SIZE_T Size
04104 )
04105 {
04106
return RtlpDebugPageHeapAllocate (
04107
BIAS_POINTER(
HeapHandle),
04108 Flags,
04109
Size);
04110 }
04111
04112 PVOID
04113 RtlpDphDllHeapReAlloc (
04114 IN PVOID HeapHandle,
04115 IN ULONG Flags,
04116 IN PVOID Address,
04117 IN SIZE_T Size
04118 )
04119 {
04120
return RtlpDebugPageHeapReAllocate (
04121
BIAS_POINTER(
HeapHandle),
04122 Flags,
04123 Address,
04124
Size);
04125 }
04126
04127 BOOLEAN
04128 RtlpDphDllHeapFree(
04129 IN PVOID HeapHandle,
04130 IN ULONG Flags,
04131 IN PVOID Address
04132 )
04133 {
04134
return RtlpDebugPageHeapFree (
04135
HeapHandle,
04136 Flags,
04137 Address);
04138 }
04139
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149 #define LMEM_MOVEABLE 0x0002
04150 #define LMEM_ZEROINIT 0x0040
04151
04152
#if defined(_IA64_) || defined(_AXP64_)
04153
#define BASE_HANDLE_MARK_BIT 0x08
04154
#else
04155 #define BASE_HANDLE_MARK_BIT 0x04
04156
#endif
04157
04158
typedef PVOID
04159 (* FUN_LOCAL_ALLOC) (
04160 IN ULONG Flags,
04161 IN SIZE_T
Size
04162 );
04163
04164
typedef PVOID
04165 (* FUN_LOCAL_REALLOC) (
04166 IN PVOID Address,
04167 IN SIZE_T
Size,
04168 IN ULONG Flags
04169 );
04170
04171
typedef PVOID
04172 (* FUN_LOCAL_FREE)(
04173 IN PVOID Address
04174 );
04175
04176
typedef PVOID
04177 (* FUN_GLOBAL_ALLOC) (
04178 IN ULONG Flags,
04179 IN SIZE_T
Size
04180 );
04181
04182
typedef PVOID
04183 (* FUN_GLOBAL_REALLOC) (
04184 IN PVOID Address,
04185 IN SIZE_T
Size,
04186 IN ULONG Flags
04187 );
04188
04189
typedef PVOID
04190 (* FUN_GLOBAL_FREE)(
04191 IN PVOID Address
04192 );
04193
04194 PVOID
04195 RtlpDphDllLocalAlloc (
04196 IN ULONG Flags,
04197 IN SIZE_T Size
04198 )
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 }
04222
04223 PVOID
04224 RtlpDphDllLocalReAlloc (
04225 IN PVOID Address,
04226 IN SIZE_T Size,
04227 IN ULONG Flags
04228 )
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 }
04249
04250 PVOID
04251 RtlpDphDllLocalFree(
04252 IN PVOID Address
04253 )
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 }
04278
04279 PVOID
04280 RtlpDphDllGlobalAlloc (
04281 IN ULONG Flags,
04282 IN SIZE_T Size
04283 )
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 }
04307
04308 PVOID
04309 RtlpDphDllGlobalReAlloc (
04310 IN PVOID Address,
04311 IN SIZE_T Size,
04312 IN ULONG Flags
04313 )
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 }
04334
04335 PVOID
04336 RtlpDphDllGlobalFree(
04337 IN PVOID Address
04338 )
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 }
04363
04364
04365
04366
04367
04368 PVOID __cdecl
04369 RtlpDphDllmalloc (
04370 IN SIZE_T Size
04371 )
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 }
04384
04385 PVOID __cdecl
04386 RtlpDphDllcalloc (
04387 IN SIZE_T Number,
04388 IN SIZE_T Size
04389 )
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 }
04403
04404 PVOID __cdecl
04405 RtlpDphDllrealloc (
04406 IN PVOID Address,
04407 IN SIZE_T Size
04408 )
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 }
04432
04433
VOID __cdecl
04434 RtlpDphDllfree (
04435 IN PVOID Address
04436 )
04437 {
04438
ASSERT(
RtlpDphMsvcrtHeap !=
NULL);
04439
04440
RtlpDebugPageHeapFree (
04441
RtlpDphMsvcrtHeap,
04442 0,
04443 Address);
04444 }
04445
04446
04447
04448
04449
04450
04451 PVOID __cdecl
04452 RtlpDphDllNew (
04453 IN SIZE_T Size
04454 )
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 }
04467
04468
VOID __cdecl
04469 RtlpDphDllDelete (
04470 IN PVOID Address
04471 )
04472 {
04473
ASSERT(
RtlpDphMsvcrtHeap !=
NULL);
04474
04475
RtlpDebugPageHeapFree (
04476
RtlpDphMsvcrtHeap,
04477 0,
04478 Address);
04479 }
04480
04481 PVOID __cdecl
04482 RtlpDphDllNewArray (
04483 IN SIZE_T Size
04484 )
04485 {
04486
ASSERT(
RtlpDphMsvcrtHeap !=
NULL);
04487
04488
return RtlpDebugPageHeapAllocate (
04489
BIAS_POINTER(
RtlpDphMsvcrtHeap),
04490 0,
04491
Size);
04492 }
04493
04494
VOID __cdecl
04495 RtlpDphDllDeleteArray (
04496 IN PVOID Address
04497 )
04498 {
04499
ASSERT(
RtlpDphMsvcrtHeap !=
NULL);
04500
04501
RtlpDebugPageHeapFree (
04502
RtlpDphMsvcrtHeap,
04503 0,
04504 Address);
04505 }
04506
04507
04508
04509
04510
04511
typedef PVOID
04512 (* FUN_HEAP_CREATE) (
04513 ULONG Options,
04514 SIZE_T InitialSize,
04515 SIZE_T MaximumSize
04516 );
04517
04518 PVOID
04519 RtlpDphDllHeapCreate (
04520 ULONG Options,
04521 SIZE_T InitialSize,
04522 SIZE_T MaximumSize
04523 )
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 }
04536
04537