3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ldr/loader.c
6 * PURPOSE: Loaders for PE executables
8 * PROGRAMMERS: Jean Michault
9 * Rex Jolliff (rex@lvcablemodem.com)
10 * Jason Filby (jasonfilby@yahoo.com)
11 * Casper S. Hornstrup (chorns@users.sourceforge.net)
15 /* INCLUDES *****************************************************************/
20 #include <internal/ntosdbg.h>
31 #define ps(args...) DPRINT1(args)
35 #include <internal/debug.h>
37 /* GLOBALS *******************************************************************/
39 LIST_ENTRY ModuleListHead
;
40 KSPIN_LOCK ModuleListLock
;
41 LDR_DATA_TABLE_ENTRY NtoskrnlModuleObject
;
42 LDR_DATA_TABLE_ENTRY HalModuleObject
;
46 /* FORWARD DECLARATIONS ******************************************************/
51 PUNICODE_STRING ModuleName
,
52 PLDR_DATA_TABLE_ENTRY
*ModuleObject
);
55 LdrpBuildModuleBaseName (
56 PUNICODE_STRING BaseName
,
57 PUNICODE_STRING FullName
);
60 LdrpCompareModuleNames (
61 IN PUNICODE_STRING String1
,
62 IN PUNICODE_STRING String2
);
65 /* PE Driver load support */
69 PUNICODE_STRING FileName
,
70 PLDR_DATA_TABLE_ENTRY
*ModuleObject
);
73 LdrPEGetExportByName (
79 LdrPEFixupForward ( PCHAR ForwardName
);
82 LdrPEPerformRelocations (
87 LdrPEFixupImports ( PLDR_DATA_TABLE_ENTRY Module
);
89 /* FUNCTIONS *****************************************************************/
93 LdrInitDebug ( PLOADER_MODULE Module
, PWCH Name
)
102 /* Hook for KDB on initialization of the loader. */
103 KDB_LOADERINIT_HOOK(&NtoskrnlModuleObject
, &HalModuleObject
);
109 LdrInitModuleManagement ( VOID
)
111 PIMAGE_NT_HEADERS NtHeader
;
113 /* Initialize the module list and spinlock */
114 InitializeListHead(&ModuleListHead
);
115 KeInitializeSpinLock(&ModuleListLock
);
117 /* Initialize ModuleObject for NTOSKRNL */
118 RtlZeroMemory(&NtoskrnlModuleObject
, sizeof(LDR_DATA_TABLE_ENTRY
));
119 NtoskrnlModuleObject
.DllBase
= (PVOID
) KERNEL_BASE
;
120 RtlInitUnicodeString(&NtoskrnlModuleObject
.FullDllName
, KERNEL_MODULE_NAME
);
121 LdrpBuildModuleBaseName(&NtoskrnlModuleObject
.BaseDllName
, &NtoskrnlModuleObject
.FullDllName
);
123 NtHeader
= RtlImageNtHeader((PVOID
)KERNEL_BASE
);
124 NtoskrnlModuleObject
.EntryPoint
= (PVOID
) ((ULONG_PTR
) NtoskrnlModuleObject
.DllBase
+ NtHeader
->OptionalHeader
.AddressOfEntryPoint
);
125 DPRINT("ModuleObject:%08x entrypoint at %x\n", &NtoskrnlModuleObject
, NtoskrnlModuleObject
.EntryPoint
);
126 NtoskrnlModuleObject
.SizeOfImage
= NtHeader
->OptionalHeader
.SizeOfImage
;
128 InsertTailList(&ModuleListHead
, &NtoskrnlModuleObject
.InLoadOrderModuleList
);
130 /* Initialize ModuleObject for HAL */
131 RtlZeroMemory(&HalModuleObject
, sizeof(LDR_DATA_TABLE_ENTRY
));
132 HalModuleObject
.DllBase
= (PVOID
) LdrHalBase
;
134 RtlInitUnicodeString(&HalModuleObject
.FullDllName
, HAL_MODULE_NAME
);
135 LdrpBuildModuleBaseName(&HalModuleObject
.BaseDllName
, &HalModuleObject
.FullDllName
);
137 NtHeader
= RtlImageNtHeader((PVOID
)LdrHalBase
);
138 HalModuleObject
.EntryPoint
= (PVOID
) ((ULONG_PTR
) HalModuleObject
.DllBase
+ NtHeader
->OptionalHeader
.AddressOfEntryPoint
);
139 DPRINT("ModuleObject:%08x entrypoint at %x\n", &HalModuleObject
, HalModuleObject
.EntryPoint
);
140 HalModuleObject
.SizeOfImage
= NtHeader
->OptionalHeader
.SizeOfImage
;
142 InsertTailList(&ModuleListHead
, &HalModuleObject
.InLoadOrderModuleList
);
148 PUNICODE_STRING DriverName
,
150 PVOID
*SectionPointer
,
152 PVOID
*ExportSectionPointer
)
154 PLDR_DATA_TABLE_ENTRY ModuleObject
;
157 ModuleObject
= LdrGetModuleObject(DriverName
);
158 if (ModuleObject
== NULL
)
160 Status
= LdrLoadModule(DriverName
, &ModuleObject
);
161 if (!NT_SUCCESS(Status
))
168 *ModuleBase
= ModuleObject
->DllBase
;
171 *SectionPointer
= ModuleObject
;
174 *EntryPoint
= ModuleObject
->EntryPoint
;
176 //if (ExportSectionPointer)
177 // *ExportSectionPointer = ModuleObject->
179 return(STATUS_SUCCESS
);
185 LdrpUnloadImage ( PVOID ModuleBase
)
187 return(STATUS_NOT_IMPLEMENTED
);
193 LdrpLoadAndCallImage ( PUNICODE_STRING ModuleName
)
195 PDRIVER_INITIALIZE DriverEntry
;
196 PLDR_DATA_TABLE_ENTRY ModuleObject
;
197 DRIVER_OBJECT DriverObject
;
200 ModuleObject
= LdrGetModuleObject(ModuleName
);
201 if (ModuleObject
!= NULL
)
203 return(STATUS_IMAGE_ALREADY_LOADED
);
206 Status
= LdrLoadModule(ModuleName
, &ModuleObject
);
207 if (!NT_SUCCESS(Status
))
212 DriverEntry
= (PDRIVER_INITIALIZE
)ModuleObject
->EntryPoint
;
214 RtlZeroMemory(&DriverObject
, sizeof(DriverObject
));
215 // DriverObject.DriverStart = ModuleObject->DllBase;
217 Status
= DriverEntry(&DriverObject
, NULL
);
218 if (!NT_SUCCESS(Status
))
220 LdrUnloadModule(ModuleObject
);
230 PUNICODE_STRING Filename
,
231 PLDR_DATA_TABLE_ENTRY
*ModuleObject
)
233 PVOID ModuleLoadBase
;
236 OBJECT_ATTRIBUTES ObjectAttributes
;
237 PLDR_DATA_TABLE_ENTRY Module
;
238 FILE_STANDARD_INFORMATION FileStdInfo
;
239 IO_STATUS_BLOCK IoStatusBlock
;
241 *ModuleObject
= NULL
;
243 DPRINT("Loading Module %wZ...\n", Filename
);
245 /* Open the Module */
246 InitializeObjectAttributes(&ObjectAttributes
,
248 OBJ_CASE_INSENSITIVE
,
252 Status
= ZwOpenFile(&FileHandle
,
257 FILE_SYNCHRONOUS_IO_NONALERT
);
259 if (!NT_SUCCESS(Status
))
261 CPRINT("Could not open module file: %wZ (Status 0x%08lx)\n", Filename
, Status
);
266 /* Get the size of the file */
267 Status
= ZwQueryInformationFile(FileHandle
,
271 FileStandardInformation
);
272 if (!NT_SUCCESS(Status
))
274 CPRINT("Could not get file size\n");
280 /* Allocate nonpageable memory for driver */
281 ModuleLoadBase
= ExAllocatePoolWithTag(NonPagedPool
,
282 FileStdInfo
.EndOfFile
.u
.LowPart
,
284 if (ModuleLoadBase
== NULL
)
286 CPRINT("Could not allocate memory for module");
288 return(STATUS_INSUFFICIENT_RESOURCES
);
292 /* Load driver into memory chunk */
293 Status
= ZwReadFile(FileHandle
,
297 FileStdInfo
.EndOfFile
.u
.LowPart
,
299 if (!NT_SUCCESS(Status
))
301 CPRINT("Could not read module file into memory");
302 ExFreePool(ModuleLoadBase
);
310 Status
= LdrProcessModule(ModuleLoadBase
,
313 if (!NT_SUCCESS(Status
))
315 CPRINT("Could not process module\n");
316 ExFreePool(ModuleLoadBase
);
321 ExFreePool(ModuleLoadBase
);
323 *ModuleObject
= Module
;
325 /* Hook for KDB on loading a driver. */
326 KDB_LOADDRIVER_HOOK(Filename
, Module
);
328 return(STATUS_SUCCESS
);
334 LdrUnloadModule ( PLDR_DATA_TABLE_ENTRY ModuleObject
)
338 /* Remove the module from the module list */
339 KeAcquireSpinLock(&ModuleListLock
,&Irql
);
340 RemoveEntryList(&ModuleObject
->InLoadOrderModuleList
);
341 KeReleaseSpinLock(&ModuleListLock
, Irql
);
343 /* Hook for KDB on unloading a driver. */
344 KDB_UNLOADDRIVER_HOOK(ModuleObject
);
346 /* Free module section */
347 // MmFreeSection(ModuleObject->DllBase);
349 ExFreePool(ModuleObject
->FullDllName
.Buffer
);
350 ExFreePool(ModuleObject
);
352 return(STATUS_SUCCESS
);
358 PVOID ModuleLoadBase
,
359 PUNICODE_STRING ModuleName
,
360 PLDR_DATA_TABLE_ENTRY
*ModuleObject
)
362 PIMAGE_DOS_HEADER PEDosHeader
;
364 /* If MZ header exists */
365 PEDosHeader
= (PIMAGE_DOS_HEADER
) ModuleLoadBase
;
366 if (PEDosHeader
->e_magic
== IMAGE_DOS_SIGNATURE
&& PEDosHeader
->e_lfanew
!= 0L)
368 return LdrPEProcessModule(ModuleLoadBase
,
373 CPRINT("Module wasn't PE\n");
374 return STATUS_UNSUCCESSFUL
;
379 LdrpQueryModuleInformation (
384 PLIST_ENTRY current_entry
;
385 PLDR_DATA_TABLE_ENTRY current
;
386 ULONG ModuleCount
= 0;
387 PSYSTEM_MODULE_INFORMATION Smi
;
388 ANSI_STRING AnsiName
;
392 KeAcquireSpinLock(&ModuleListLock
,&Irql
);
394 /* calculate required size */
395 current_entry
= ModuleListHead
.Flink
;
396 while (current_entry
!= (&ModuleListHead
))
399 current_entry
= current_entry
->Flink
;
402 *ReqSize
= sizeof(SYSTEM_MODULE_INFORMATION
)+
403 (ModuleCount
- 1) * sizeof(SYSTEM_MODULE_INFORMATION_ENTRY
);
407 KeReleaseSpinLock(&ModuleListLock
, Irql
);
408 return(STATUS_INFO_LENGTH_MISMATCH
);
411 /* fill the buffer */
412 memset(Buffer
, '=', Size
);
414 Smi
= (PSYSTEM_MODULE_INFORMATION
)Buffer
;
415 Smi
->Count
= ModuleCount
;
418 current_entry
= ModuleListHead
.Flink
;
419 while (current_entry
!= (&ModuleListHead
))
421 current
= CONTAINING_RECORD(current_entry
,LDR_DATA_TABLE_ENTRY
,InLoadOrderModuleList
);
423 Smi
->Module
[ModuleCount
].Unknown1
= 0; /* Always 0 */
424 Smi
->Module
[ModuleCount
].Unknown2
= 0; /* Always 0 */
425 Smi
->Module
[ModuleCount
].Base
= current
->DllBase
;
426 Smi
->Module
[ModuleCount
].Size
= current
->SizeOfImage
;
427 Smi
->Module
[ModuleCount
].Flags
= 0; /* Flags ??? (GN) */
428 Smi
->Module
[ModuleCount
].Index
= (USHORT
)ModuleCount
;
429 Smi
->Module
[ModuleCount
].NameLength
= 0;
430 Smi
->Module
[ModuleCount
].LoadCount
= 0; /* FIXME */
433 AnsiName
.MaximumLength
= 256;
434 AnsiName
.Buffer
= Smi
->Module
[ModuleCount
].ImageName
;
435 RtlUnicodeStringToAnsiString(&AnsiName
,
436 ¤t
->FullDllName
,
439 p
= strrchr(AnsiName
.Buffer
, '\\');
442 Smi
->Module
[ModuleCount
].PathLength
= 0;
447 Smi
->Module
[ModuleCount
].PathLength
= p
- AnsiName
.Buffer
;
451 current_entry
= current_entry
->Flink
;
454 KeReleaseSpinLock(&ModuleListLock
, Irql
);
456 return(STATUS_SUCCESS
);
461 LdrpBuildModuleBaseName (
462 PUNICODE_STRING BaseName
,
463 PUNICODE_STRING FullName
)
467 DPRINT("LdrpBuildModuleBaseName()\n");
468 DPRINT("FullName %wZ\n", FullName
);
470 p
= wcsrchr(FullName
->Buffer
, L
'\\');
473 p
= FullName
->Buffer
;
482 RtlInitUnicodeString(BaseName
, p
);
487 LdrpCompareModuleNames (
488 IN PUNICODE_STRING String1
,
489 IN PUNICODE_STRING String2
)
495 if (String1
&& String2
)
497 /* Search String1 for last path component */
498 len1
= String1
->Length
/ sizeof(WCHAR
);
499 s1
= String1
->Buffer
;
500 for (i
= 0, p
= String1
->Buffer
; i
< String1
->Length
; i
= i
+ sizeof(WCHAR
), p
++)
504 if (i
== String1
->Length
- sizeof(WCHAR
))
512 len1
= (String1
->Length
- i
) / sizeof(WCHAR
);
517 /* Search String2 for last path component */
518 len2
= String2
->Length
/ sizeof(WCHAR
);
519 s2
= String2
->Buffer
;
520 for (i
= 0, p
= String2
->Buffer
; i
< String2
->Length
; i
= i
+ sizeof(WCHAR
), p
++)
524 if (i
== String2
->Length
- sizeof(WCHAR
))
532 len2
= (String2
->Length
- i
) / sizeof(WCHAR
);
537 /* Compare last path components */
542 c1
= len1
-- ? RtlUpcaseUnicodeChar (*s1
++) : 0;
543 c2
= len2
-- ? RtlUpcaseUnicodeChar (*s2
++) : 0;
544 if ((c1
== 0 && c2
== L
'.') || (c1
== L
'.' && c2
== 0))
546 if (!c1
|| !c2
|| c1
!= c2
)
555 PLDR_DATA_TABLE_ENTRY
557 LdrGetModuleObject ( PUNICODE_STRING ModuleName
)
559 PLDR_DATA_TABLE_ENTRY Module
;
563 DPRINT("LdrGetModuleObject(%wZ) called\n", ModuleName
);
565 KeAcquireSpinLock(&ModuleListLock
,&Irql
);
567 Entry
= ModuleListHead
.Flink
;
568 while (Entry
!= &ModuleListHead
)
570 Module
= CONTAINING_RECORD(Entry
, LDR_DATA_TABLE_ENTRY
, InLoadOrderModuleList
);
572 DPRINT("Comparing %wZ and %wZ\n",
573 &Module
->BaseDllName
,
576 if (!LdrpCompareModuleNames(&Module
->BaseDllName
, ModuleName
))
578 DPRINT("Module %wZ\n", &Module
->BaseDllName
);
579 KeReleaseSpinLock(&ModuleListLock
, Irql
);
583 Entry
= Entry
->Flink
;
586 KeReleaseSpinLock(&ModuleListLock
, Irql
);
588 DPRINT("Could not find module '%wZ'\n", ModuleName
);
594 /* ---------------------------------------------- PE Module support */
597 LdrLookupPageProtection (
600 PIMAGE_FILE_HEADER PEFileHeader
,
601 PIMAGE_SECTION_HEADER PESectionHeaders
)
603 BOOLEAN Write
= FALSE
;
604 BOOLEAN Execute
= FALSE
;
605 ULONG Characteristics
;
610 for (Idx
= 0; Idx
< PEFileHeader
->NumberOfSections
&& (!Write
|| !Execute
); Idx
++)
612 Characteristics
= PESectionHeaders
[Idx
].Characteristics
;
613 if (!(Characteristics
& IMAGE_SCN_TYPE_NOLOAD
))
615 Length
= max(PESectionHeaders
[Idx
].Misc
.VirtualSize
, PESectionHeaders
[Idx
].SizeOfRawData
);
616 BaseAddress
= PESectionHeaders
[Idx
].VirtualAddress
+ (char*)DriverBase
;
617 if (BaseAddress
< (PVOID
)((ULONG_PTR
)PageStart
+ PAGE_SIZE
) &&
618 PageStart
< (PVOID
)((ULONG_PTR
)BaseAddress
+ Length
))
620 if (Characteristics
& IMAGE_SCN_CNT_CODE
)
624 if (Characteristics
& (IMAGE_SCN_MEM_WRITE
|IMAGE_SCN_CNT_UNINITIALIZED_DATA
))
631 if (Write
&& Execute
)
633 return PAGE_EXECUTE_READWRITE
;
637 return PAGE_EXECUTE_READ
;
641 return PAGE_READWRITE
;
645 return PAGE_READONLY
;
651 PVOID ModuleLoadBase
,
652 PUNICODE_STRING FileName
,
653 PLDR_DATA_TABLE_ENTRY
*ModuleObject
)
655 unsigned int DriverSize
, Idx
;
658 PIMAGE_DOS_HEADER PEDosHeader
;
659 PIMAGE_NT_HEADERS PENtHeaders
;
660 PIMAGE_SECTION_HEADER PESectionHeaders
;
661 PLDR_DATA_TABLE_ENTRY CreatedModuleObject
;
665 DPRINT("Processing PE Module at module base:%08lx\n", ModuleLoadBase
);
667 /* Get header pointers */
668 PEDosHeader
= (PIMAGE_DOS_HEADER
) ModuleLoadBase
;
669 PENtHeaders
= RtlImageNtHeader(ModuleLoadBase
);
670 PESectionHeaders
= IMAGE_FIRST_SECTION(PENtHeaders
);
673 /* Check file magic numbers */
674 if (PEDosHeader
->e_magic
!= IMAGE_DOS_SIGNATURE
)
676 CPRINT("Incorrect MZ magic: %04x\n", PEDosHeader
->e_magic
);
677 return STATUS_UNSUCCESSFUL
;
679 if (PEDosHeader
->e_lfanew
== 0)
681 CPRINT("Invalid lfanew offset: %08x\n", PEDosHeader
->e_lfanew
);
682 return STATUS_UNSUCCESSFUL
;
684 if (PENtHeaders
->Signature
!= IMAGE_NT_SIGNATURE
)
686 CPRINT("Incorrect PE magic: %08x\n", PENtHeaders
->Signature
);
687 return STATUS_UNSUCCESSFUL
;
689 if (PENtHeaders
->FileHeader
.Machine
!= IMAGE_FILE_MACHINE_I386
)
691 CPRINT("Incorrect Architechture: %04x\n", PENtHeaders
->FileHeader
.Machine
);
692 return STATUS_UNSUCCESSFUL
;
696 /* FIXME: if image is fixed-address load, then fail */
698 /* FIXME: check/verify OS version number */
700 DPRINT("OptionalHdrMagic:%04x LinkVersion:%d.%d\n",
701 PENtHeaders
->OptionalHeader
.Magic
,
702 PENtHeaders
->OptionalHeader
.MajorLinkerVersion
,
703 PENtHeaders
->OptionalHeader
.MinorLinkerVersion
);
704 DPRINT("Entry Point:%08lx\n", PENtHeaders
->OptionalHeader
.AddressOfEntryPoint
);
706 /* Determine the size of the module */
708 for (Idx
= 0; Idx
< PENtHeaders
->FileHeader
.NumberOfSections
; Idx
++)
710 if (!(PESectionHeaders
[Idx
].Characteristics
& IMAGE_SCN_TYPE_NOLOAD
))
712 CurrentSize
= PESectionHeaders
[Idx
].VirtualAddress
+ PESectionHeaders
[Idx
].Misc
.VirtualSize
;
713 DriverSize
= max(DriverSize
, CurrentSize
);
716 DriverSize
= ROUND_UP(DriverSize
, PENtHeaders
->OptionalHeader
.SectionAlignment
);
717 DPRINT("DriverSize %x, SizeOfImage %x\n",DriverSize
, PENtHeaders
->OptionalHeader
.SizeOfImage
);
719 /* Allocate a virtual section for the module */
721 DriverBase
= MmAllocateSection(DriverSize
, DriverBase
);
724 CPRINT("Failed to allocate a virtual section for driver\n");
725 return STATUS_UNSUCCESSFUL
;
727 DPRINT("DriverBase for %wZ: %x\n", FileName
, DriverBase
);
729 /* Copy headers over */
730 memcpy(DriverBase
, ModuleLoadBase
, PENtHeaders
->OptionalHeader
.SizeOfHeaders
);
732 /* Copy image sections into virtual section */
733 for (Idx
= 0; Idx
< PENtHeaders
->FileHeader
.NumberOfSections
; Idx
++)
735 CurrentSize
= PESectionHeaders
[Idx
].VirtualAddress
+ PESectionHeaders
[Idx
].Misc
.VirtualSize
;
736 /* Copy current section into current offset of virtual section */
737 if (CurrentSize
<= DriverSize
&&
738 PESectionHeaders
[Idx
].SizeOfRawData
)
740 DPRINT("PESectionHeaders[Idx].VirtualAddress + DriverBase %x\n",
741 PESectionHeaders
[Idx
].VirtualAddress
+ (ULONG_PTR
)DriverBase
);
742 memcpy((PVOID
)((ULONG_PTR
)DriverBase
+ PESectionHeaders
[Idx
].VirtualAddress
),
743 (PVOID
)((ULONG_PTR
)ModuleLoadBase
+ PESectionHeaders
[Idx
].PointerToRawData
),
744 PESectionHeaders
[Idx
].Misc
.VirtualSize
> PESectionHeaders
[Idx
].SizeOfRawData
745 ? PESectionHeaders
[Idx
].SizeOfRawData
: PESectionHeaders
[Idx
].Misc
.VirtualSize
);
749 /* Perform relocation fixups */
750 Status
= LdrPEPerformRelocations(DriverBase
, DriverSize
);
751 if (!NT_SUCCESS(Status
))
753 // MmFreeSection(DriverBase);
757 /* Create the module */
758 CreatedModuleObject
= ExAllocatePoolWithTag (
759 NonPagedPool
, sizeof(LDR_DATA_TABLE_ENTRY
), TAG_MODULE_OBJECT
);
760 if (CreatedModuleObject
== NULL
)
762 // MmFreeSection(DriverBase);
763 return STATUS_INSUFFICIENT_RESOURCES
;
766 RtlZeroMemory(CreatedModuleObject
, sizeof(LDR_DATA_TABLE_ENTRY
));
768 /* Initialize ModuleObject data */
769 CreatedModuleObject
->DllBase
= DriverBase
;
771 CreatedModuleObject
->FullDllName
.Length
= 0;
772 CreatedModuleObject
->FullDllName
.MaximumLength
= FileName
->Length
+ sizeof(UNICODE_NULL
);
773 CreatedModuleObject
->FullDllName
.Buffer
=
774 ExAllocatePoolWithTag(PagedPool
, CreatedModuleObject
->FullDllName
.MaximumLength
, TAG_LDR_WSTR
);
775 if (CreatedModuleObject
->FullDllName
.Buffer
== NULL
)
777 ExFreePool(CreatedModuleObject
);
778 // MmFreeSection(DriverBase);
779 return STATUS_INSUFFICIENT_RESOURCES
;
782 RtlCopyUnicodeString(&CreatedModuleObject
->FullDllName
, FileName
);
783 CreatedModuleObject
->FullDllName
.Buffer
[FileName
->Length
/ sizeof(WCHAR
)] = 0;
784 LdrpBuildModuleBaseName(&CreatedModuleObject
->BaseDllName
,
785 &CreatedModuleObject
->FullDllName
);
787 CreatedModuleObject
->EntryPoint
=
788 (PVOID
)((ULONG_PTR
)DriverBase
+
789 PENtHeaders
->OptionalHeader
.AddressOfEntryPoint
);
790 CreatedModuleObject
->SizeOfImage
= DriverSize
;
791 DPRINT("EntryPoint at %x\n", CreatedModuleObject
->EntryPoint
);
793 /* Perform import fixups */
794 Status
= LdrPEFixupImports(CreatedModuleObject
);
795 if (!NT_SUCCESS(Status
))
797 // MmFreeSection(DriverBase);
798 ExFreePool(CreatedModuleObject
->FullDllName
.Buffer
);
799 ExFreePool(CreatedModuleObject
);
803 MmSetPageProtect(NULL
, DriverBase
, PAGE_READONLY
);
804 /* Set the protections for the various parts of the driver */
805 for (Idx
= 0; Idx
< PENtHeaders
->FileHeader
.NumberOfSections
; Idx
++)
807 ULONG Characteristics
= PESectionHeaders
[Idx
].Characteristics
;
812 Length
= PESectionHeaders
[Idx
].Misc
.VirtualSize
;
813 BaseAddress
= PESectionHeaders
[Idx
].VirtualAddress
+ (char*)DriverBase
;
814 PageAddress
= (PVOID
)PAGE_ROUND_DOWN(BaseAddress
);
816 Protect
= LdrLookupPageProtection(PageAddress
, DriverBase
, &PENtHeaders
->FileHeader
, PESectionHeaders
);
820 * This driver modifies a string in the first page of the text section while initialising.
822 if (0 == _wcsicmp(L
"fireport.sys", FileName
->Buffer
))
824 Protect
= PAGE_EXECUTE_READWRITE
;
827 if (PageAddress
< RVA(DriverBase
, DriverSize
))
829 MmSetPageProtect(NULL
, PageAddress
, Protect
);
832 if (Characteristics
& IMAGE_SCN_CNT_CODE
)
834 if (Characteristics
& IMAGE_SCN_MEM_WRITE
)
836 Protect
= PAGE_EXECUTE_READWRITE
;
840 Protect
= PAGE_EXECUTE_READ
;
843 else if (Characteristics
& (IMAGE_SCN_MEM_WRITE
|IMAGE_SCN_CNT_UNINITIALIZED_DATA
))
845 Protect
= PAGE_READWRITE
;
849 Protect
= PAGE_READONLY
;
851 PageAddress
= (PVOID
)((ULONG_PTR
)PageAddress
+ PAGE_SIZE
);
852 while ((ULONG_PTR
)PageAddress
+ PAGE_SIZE
< (ULONG_PTR
)BaseAddress
+ Length
)
854 if (PageAddress
< RVA(DriverBase
, DriverSize
))
856 MmSetPageProtect(NULL
, PageAddress
, Protect
);
858 PageAddress
= (PVOID
)((ULONG_PTR
)PageAddress
+ PAGE_SIZE
);
860 if (PageAddress
< (PVOID
)((ULONG_PTR
)BaseAddress
+ Length
) &&
861 PageAddress
< RVA(DriverBase
, DriverSize
))
863 Protect
= LdrLookupPageProtection(PageAddress
, DriverBase
, &PENtHeaders
->FileHeader
, PESectionHeaders
);
864 MmSetPageProtect(NULL
, PageAddress
, Protect
);
869 KeAcquireSpinLock(&ModuleListLock
, &Irql
);
870 InsertTailList(&ModuleListHead
,
871 &CreatedModuleObject
->InLoadOrderModuleList
);
872 KeReleaseSpinLock(&ModuleListLock
, Irql
);
874 *ModuleObject
= CreatedModuleObject
;
876 DPRINT("Loading Module %wZ...\n", FileName
);
878 DPRINT("Module %wZ loaded at 0x%.08x.\n",
879 FileName
, CreatedModuleObject
->DllBase
);
881 return STATUS_SUCCESS
;
888 LdrSafePEProcessModule (
889 PVOID ModuleLoadBase
,
891 PVOID ImportModuleBase
,
896 PIMAGE_DOS_HEADER PEDosHeader
;
897 PIMAGE_NT_HEADERS PENtHeaders
;
898 PIMAGE_SECTION_HEADER PESectionHeaders
;
901 ps("Processing PE Module at module base:%08lx\n", ModuleLoadBase
);
903 /* Get header pointers */
904 PEDosHeader
= (PIMAGE_DOS_HEADER
) ModuleLoadBase
;
905 PENtHeaders
= RtlImageNtHeader(ModuleLoadBase
);
906 PESectionHeaders
= IMAGE_FIRST_SECTION(PENtHeaders
);
909 /* Check file magic numbers */
910 if (PEDosHeader
->e_magic
!= IMAGE_DOS_SIGNATURE
)
914 if (PEDosHeader
->e_lfanew
== 0)
918 if (PENtHeaders
->Signature
!= IMAGE_NT_SIGNATURE
)
922 if (PENtHeaders
->FileHeader
.Machine
!= IMAGE_FILE_MACHINE_I386
)
927 ps("OptionalHdrMagic:%04x LinkVersion:%d.%d\n",
928 PENtHeaders
->OptionalHeader
.Magic
,
929 PENtHeaders
->OptionalHeader
.MajorLinkerVersion
,
930 PENtHeaders
->OptionalHeader
.MinorLinkerVersion
);
931 ps("Entry Point:%08lx\n", PENtHeaders
->OptionalHeader
.AddressOfEntryPoint
);
933 /* Determine the size of the module */
934 *DriverSize
= PENtHeaders
->OptionalHeader
.SizeOfImage
;
935 ps("DriverSize %x\n",*DriverSize
);
937 /* Copy headers over */
938 if (DriverBase
!= ModuleLoadBase
)
940 memcpy(DriverBase
, ModuleLoadBase
, PENtHeaders
->OptionalHeader
.SizeOfHeaders
);
943 ps("Hdr: 0x%X\n", PENtHeaders
);
944 ps("Hdr->SizeOfHeaders: 0x%X\n", PENtHeaders
->OptionalHeader
.SizeOfHeaders
);
945 ps("FileHdr->NumberOfSections: 0x%X\n", PENtHeaders
->FileHeader
.NumberOfSections
);
947 /* Ntoskrnl.exe need no relocation fixups since it is linked to run at the same
948 address as it is mapped */
949 if (DriverBase
!= ModuleLoadBase
)
953 /* Copy image sections into virtual section */
954 for (Idx
= 0; Idx
< PENtHeaders
->FileHeader
.NumberOfSections
; Idx
++)
956 PIMAGE_SECTION_HEADER Section
= &PESectionHeaders
[Idx
];
957 // Copy current section into current offset of virtual section
958 if (Section
->SizeOfRawData
)
960 // ps("PESectionHeaders[Idx].VirtualAddress (%X) + DriverBase %x\n",
961 // PESectionHeaders[Idx].VirtualAddress, PESectionHeaders[Idx].VirtualAddress + DriverBase);
962 memcpy(Section
->VirtualAddress
+ (char*)DriverBase
,
963 Section
->PointerToRawData
+ (char*)ModuleLoadBase
,
964 Section
->Misc
.VirtualSize
> Section
->SizeOfRawData
? Section
->SizeOfRawData
: Section
->Misc
.VirtualSize
);
966 if (Section
->SizeOfRawData
< Section
->Misc
.VirtualSize
)
968 memset(Section
->VirtualAddress
+ Section
->SizeOfRawData
+ (char*)DriverBase
,
970 Section
->Misc
.VirtualSize
- Section
->SizeOfRawData
);
972 CurrentSize
+= ROUND_UP(Section
->Misc
.VirtualSize
,
973 PENtHeaders
->OptionalHeader
.SectionAlignment
);
976 /* Perform relocation fixups */
977 Status
= LdrPEPerformRelocations(DriverBase
, *DriverSize
);
978 if (!NT_SUCCESS(Status
))
984 /* Perform import fixups */
985 Status
= LdrPEFixupImports(DriverBase
== ModuleLoadBase
? &NtoskrnlModuleObject
: &HalModuleObject
);
986 if (!NT_SUCCESS(Status
))
991 /* Set the page protection for the virtual sections */
992 MmSetPageProtect(NULL
, DriverBase
, PAGE_READONLY
);
993 for (Idx
= 0; Idx
< PENtHeaders
->FileHeader
.NumberOfSections
; Idx
++)
995 ULONG Characteristics
= PESectionHeaders
[Idx
].Characteristics
;
1000 Length
= PESectionHeaders
[Idx
].Misc
.VirtualSize
;
1001 BaseAddress
= PESectionHeaders
[Idx
].VirtualAddress
+ (char*)DriverBase
;
1002 PageAddress
= (PVOID
)PAGE_ROUND_DOWN(BaseAddress
);
1004 if (Characteristics
& IMAGE_SCN_MEM_EXECUTE
)
1006 if (Characteristics
& IMAGE_SCN_MEM_WRITE
)
1008 Protect
= PAGE_EXECUTE_READWRITE
;
1012 Protect
= PAGE_EXECUTE_READ
;
1015 else if (Characteristics
& IMAGE_SCN_MEM_WRITE
)
1017 Protect
= PAGE_READWRITE
;
1021 Protect
= PAGE_READONLY
;
1023 while ((ULONG_PTR
)PageAddress
< (ULONG_PTR
)BaseAddress
+ Length
)
1025 MmSetPageProtect(NULL
, PageAddress
, Protect
);
1026 PageAddress
= (PVOID
)((ULONG_PTR
)PageAddress
+ PAGE_SIZE
);
1028 if (DriverBase
== ModuleLoadBase
&&
1029 Characteristics
& IMAGE_SCN_CNT_UNINITIALIZED_DATA
)
1031 /* For ntoskrnl, we must stop after the bss section */
1041 LdrPEFixupForward ( PCHAR ForwardName
)
1043 CHAR NameBuffer
[128];
1044 UNICODE_STRING ModuleName
;
1046 PLDR_DATA_TABLE_ENTRY ModuleObject
;
1048 DPRINT("LdrPEFixupForward (%s)\n", ForwardName
);
1050 strcpy(NameBuffer
, ForwardName
);
1051 p
= strchr(NameBuffer
, '.');
1059 DPRINT("Driver: %s Function: %s\n", NameBuffer
, p
+1);
1061 RtlCreateUnicodeStringFromAsciiz(&ModuleName
,
1063 ModuleObject
= LdrGetModuleObject(&ModuleName
);
1064 RtlFreeUnicodeString(&ModuleName
);
1066 DPRINT("ModuleObject: %p\n", ModuleObject
);
1068 if (ModuleObject
== NULL
)
1070 CPRINT("LdrPEFixupForward: failed to find module %s\n", NameBuffer
);
1073 return LdrPEGetExportByName(ModuleObject
->DllBase
, (PUCHAR
)(p
+1), 0xffff);
1077 LdrPEPerformRelocations (
1081 PIMAGE_NT_HEADERS NtHeaders
;
1082 PIMAGE_DATA_DIRECTORY RelocationDDir
;
1083 PIMAGE_BASE_RELOCATION RelocationDir
, RelocationEnd
;
1085 PVOID Address
, MaxAddress
;
1093 NtHeaders
= RtlImageNtHeader(DriverBase
);
1095 if (NtHeaders
->FileHeader
.Characteristics
& IMAGE_FILE_RELOCS_STRIPPED
)
1097 return STATUS_UNSUCCESSFUL
;
1100 RelocationDDir
= &NtHeaders
->OptionalHeader
.DataDirectory
[IMAGE_DIRECTORY_ENTRY_BASERELOC
];
1102 if (RelocationDDir
->VirtualAddress
== 0 || RelocationDDir
->Size
== 0)
1104 return STATUS_SUCCESS
;
1107 Delta
= (ULONG_PTR
)DriverBase
- NtHeaders
->OptionalHeader
.ImageBase
;
1108 RelocationDir
= (PIMAGE_BASE_RELOCATION
)((ULONG_PTR
)DriverBase
+ RelocationDDir
->VirtualAddress
);
1109 RelocationEnd
= (PIMAGE_BASE_RELOCATION
)((ULONG_PTR
)RelocationDir
+ RelocationDDir
->Size
);
1110 MaxAddress
= RVA(DriverBase
, DriverSize
);
1112 while (RelocationDir
< RelocationEnd
&&
1113 RelocationDir
->SizeOfBlock
> 0)
1115 Count
= (RelocationDir
->SizeOfBlock
- sizeof(IMAGE_BASE_RELOCATION
)) / sizeof(USHORT
);
1116 Address
= RVA(DriverBase
, RelocationDir
->VirtualAddress
);
1117 TypeOffset
= (PUSHORT
)(RelocationDir
+ 1);
1119 for (i
= 0; i
< Count
; i
++)
1121 Offset
= *TypeOffset
& 0xFFF;
1122 Type
= *TypeOffset
>> 12;
1123 ShortPtr
= (PUSHORT
)(RVA(Address
, Offset
));
1125 /* Don't relocate after the end of the loaded driver */
1126 if ((PVOID
)ShortPtr
>= MaxAddress
)
1132 * Don't relocate within the relocation section itself.
1133 * GCC/LD generates sometimes relocation records for the relocation section.
1134 * This is a bug in GCC/LD.
1136 if ((ULONG_PTR
)ShortPtr
< (ULONG_PTR
)RelocationDir
||
1137 (ULONG_PTR
)ShortPtr
>= (ULONG_PTR
)RelocationEnd
)
1141 case IMAGE_REL_BASED_ABSOLUTE
:
1144 case IMAGE_REL_BASED_HIGH
:
1145 *ShortPtr
+= HIWORD(Delta
);
1148 case IMAGE_REL_BASED_LOW
:
1149 *ShortPtr
+= LOWORD(Delta
);
1152 case IMAGE_REL_BASED_HIGHLOW
:
1153 LongPtr
= (PULONG
)ShortPtr
;
1157 case IMAGE_REL_BASED_HIGHADJ
:
1158 case IMAGE_REL_BASED_MIPS_JMPADDR
:
1160 DPRINT1("Unknown/unsupported fixup type %hu.\n", Type
);
1161 DPRINT1("Address %x, Current %d, Count %d, *TypeOffset %x\n", Address
, i
, Count
, *TypeOffset
);
1162 return STATUS_UNSUCCESSFUL
;
1167 RelocationDir
= (PIMAGE_BASE_RELOCATION
)((ULONG_PTR
)RelocationDir
+ RelocationDir
->SizeOfBlock
);
1170 return STATUS_SUCCESS
;
1173 #define PATH_MAX 260
1177 LdrPEGetOrLoadModule (
1178 PLDR_DATA_TABLE_ENTRY Module
,
1180 PLDR_DATA_TABLE_ENTRY
* ImportedModule
)
1182 UNICODE_STRING DriverName
;
1183 UNICODE_STRING NameString
;
1184 WCHAR NameBuffer
[PATH_MAX
];
1185 NTSTATUS Status
= STATUS_SUCCESS
;
1187 if (0 == _stricmp(ImportedName
, "ntoskrnl") ||
1188 0 == _stricmp(ImportedName
, "ntoskrnl.exe"))
1190 *ImportedModule
= &NtoskrnlModuleObject
;
1191 return STATUS_SUCCESS
;
1194 if (0 == _stricmp(ImportedName
, "hal") ||
1195 0 == _stricmp(ImportedName
, "hal.dll"))
1197 *ImportedModule
= &HalModuleObject
;
1198 return STATUS_SUCCESS
;
1201 RtlCreateUnicodeStringFromAsciiz (&DriverName
, ImportedName
);
1202 DPRINT("Import module: %wZ\n", &DriverName
);
1204 *ImportedModule
= LdrGetModuleObject(&DriverName
);
1205 if (*ImportedModule
== NULL
)
1210 PathEnd
= wcsrchr(Module
->FullDllName
.Buffer
, L
'\\');
1211 if (NULL
!= PathEnd
)
1213 PathLength
= (PathEnd
- Module
->FullDllName
.Buffer
+ 1) * sizeof(WCHAR
);
1214 RtlCopyMemory(NameBuffer
, Module
->FullDllName
.Buffer
, PathLength
);
1215 RtlCopyMemory(NameBuffer
+ (PathLength
/ sizeof(WCHAR
)), DriverName
.Buffer
, DriverName
.Length
);
1216 NameString
.Buffer
= NameBuffer
;
1217 NameString
.MaximumLength
= NameString
.Length
= PathLength
+ DriverName
.Length
;
1219 /* NULL-terminate */
1220 NameString
.MaximumLength
++;
1221 NameBuffer
[NameString
.Length
/ sizeof(WCHAR
)] = 0;
1223 Status
= LdrLoadModule(&NameString
, ImportedModule
);
1227 DPRINT("Module '%wZ' not loaded yet\n", &DriverName
);
1228 wcscpy(NameBuffer
, L
"\\SystemRoot\\system32\\drivers\\");
1229 wcsncat(NameBuffer
, DriverName
.Buffer
, DriverName
.Length
/ sizeof(WCHAR
));
1230 RtlInitUnicodeString(&NameString
, NameBuffer
);
1231 Status
= LdrLoadModule(&NameString
, ImportedModule
);
1233 if (!NT_SUCCESS(Status
))
1235 wcscpy(NameBuffer
, L
"\\SystemRoot\\system32\\");
1236 wcsncat(NameBuffer
, DriverName
.Buffer
, DriverName
.Length
/ sizeof(WCHAR
));
1237 RtlInitUnicodeString(&NameString
, NameBuffer
);
1238 Status
= LdrLoadModule(&NameString
, ImportedModule
);
1239 if (!NT_SUCCESS(Status
))
1241 DPRINT1("Unknown import module: %wZ (Status %lx)\n", &DriverName
, Status
);
1245 RtlFreeUnicodeString(&DriverName
);
1250 LdrPEGetExportByName (
1255 PIMAGE_EXPORT_DIRECTORY ExportDir
;
1256 PDWORD
* ExFunctions
;
1258 USHORT
* ExOrdinals
;
1262 LONG minn
, maxn
, mid
, res
;
1263 ULONG ExportDirSize
;
1265 DPRINT("LdrPEGetExportByName %x %s %hu\n", BaseAddress
, SymbolName
, Hint
);
1267 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)RtlImageDirectoryEntryToData(BaseAddress
,
1269 IMAGE_DIRECTORY_ENTRY_EXPORT
,
1271 if (ExportDir
== NULL
)
1273 DPRINT1("LdrPEGetExportByName(): no export directory!\n");
1278 /* The symbol names may be missing entirely */
1279 if (ExportDir
->AddressOfNames
== 0)
1281 DPRINT("LdrPEGetExportByName(): symbol names missing entirely\n");
1286 * Get header pointers
1288 ExNames
= (PDWORD
*)RVA(BaseAddress
, ExportDir
->AddressOfNames
);
1289 ExOrdinals
= (USHORT
*)RVA(BaseAddress
, ExportDir
->AddressOfNameOrdinals
);
1290 ExFunctions
= (PDWORD
*)RVA(BaseAddress
, ExportDir
->AddressOfFunctions
);
1293 * Check the hint first
1295 if (Hint
< ExportDir
->NumberOfNames
)
1297 ExName
= RVA(BaseAddress
, ExNames
[Hint
]);
1298 if (strcmp(ExName
, (PCHAR
)SymbolName
) == 0)
1300 Ordinal
= ExOrdinals
[Hint
];
1301 Function
= RVA(BaseAddress
, ExFunctions
[Ordinal
]);
1302 if ((ULONG_PTR
)Function
>= (ULONG_PTR
)ExportDir
&&
1303 (ULONG_PTR
)Function
< (ULONG_PTR
)ExportDir
+ ExportDirSize
)
1305 DPRINT("Forward: %s\n", (PCHAR
)Function
);
1306 Function
= LdrPEFixupForward((PCHAR
)Function
);
1307 if (Function
== NULL
)
1309 DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName
);
1313 if (Function
!= NULL
)
1324 maxn
= ExportDir
->NumberOfNames
- 1;
1325 while (minn
<= maxn
)
1327 mid
= (minn
+ maxn
) / 2;
1329 ExName
= RVA(BaseAddress
, ExNames
[mid
]);
1330 res
= strcmp(ExName
, (PCHAR
)SymbolName
);
1333 Ordinal
= ExOrdinals
[mid
];
1334 Function
= RVA(BaseAddress
, ExFunctions
[Ordinal
]);
1335 if ((ULONG_PTR
)Function
>= (ULONG_PTR
)ExportDir
&&
1336 (ULONG_PTR
)Function
< (ULONG_PTR
)ExportDir
+ ExportDirSize
)
1338 DPRINT("Forward: %s\n", (PCHAR
)Function
);
1339 Function
= LdrPEFixupForward((PCHAR
)Function
);
1340 if (Function
== NULL
)
1342 DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName
);
1346 if (Function
!= NULL
)
1361 ExName
= RVA(BaseAddress
, ExNames
[mid
]);
1362 DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName
);
1367 LdrPEGetExportByOrdinal (
1371 PIMAGE_EXPORT_DIRECTORY ExportDir
;
1372 ULONG ExportDirSize
;
1373 PDWORD
* ExFunctions
;
1376 ExportDir
= (PIMAGE_EXPORT_DIRECTORY
)RtlImageDirectoryEntryToData (
1379 IMAGE_DIRECTORY_ENTRY_EXPORT
,
1382 ExFunctions
= (PDWORD
*)RVA(BaseAddress
,
1383 ExportDir
->AddressOfFunctions
);
1384 DPRINT("LdrPEGetExportByOrdinal(Ordinal %d) = %x\n",
1386 RVA(BaseAddress
, ExFunctions
[Ordinal
- ExportDir
->Base
]));
1388 Function
= 0 != ExFunctions
[Ordinal
- ExportDir
->Base
]
1389 ? RVA(BaseAddress
, ExFunctions
[Ordinal
- ExportDir
->Base
] )
1392 if (((ULONG_PTR
)Function
>= (ULONG_PTR
)ExportDir
) &&
1393 ((ULONG_PTR
)Function
< (ULONG_PTR
)ExportDir
+ ExportDirSize
))
1395 DPRINT("Forward: %s\n", (PCHAR
)Function
);
1396 Function
= LdrPEFixupForward((PCHAR
)Function
);
1403 LdrPEProcessImportDirectoryEntry(
1405 PLDR_DATA_TABLE_ENTRY ImportedModule
,
1406 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory
)
1408 PVOID
* ImportAddressList
;
1409 PULONG FunctionNameList
;
1412 if (ImportModuleDirectory
== NULL
|| ImportModuleDirectory
->Name
== 0)
1414 return STATUS_UNSUCCESSFUL
;
1417 /* Get the import address list. */
1418 ImportAddressList
= (PVOID
*)RVA(DriverBase
, ImportModuleDirectory
->FirstThunk
);
1420 /* Get the list of functions to import. */
1421 if (ImportModuleDirectory
->OriginalFirstThunk
!= 0)
1423 FunctionNameList
= (PULONG
)RVA(DriverBase
, ImportModuleDirectory
->OriginalFirstThunk
);
1427 FunctionNameList
= (PULONG
)RVA(DriverBase
, ImportModuleDirectory
->FirstThunk
);
1430 /* Walk through function list and fixup addresses. */
1431 while (*FunctionNameList
!= 0L)
1433 if ((*FunctionNameList
) & 0x80000000)
1435 Ordinal
= (*FunctionNameList
) & 0x7fffffff;
1436 *ImportAddressList
= LdrPEGetExportByOrdinal(ImportedModule
->DllBase
, Ordinal
);
1437 if ((*ImportAddressList
) == NULL
)
1439 DPRINT1("Failed to import #%ld from %wZ\n", Ordinal
, &ImportedModule
->FullDllName
);
1440 return STATUS_UNSUCCESSFUL
;
1445 IMAGE_IMPORT_BY_NAME
*pe_name
;
1446 pe_name
= RVA(DriverBase
, *FunctionNameList
);
1447 *ImportAddressList
= LdrPEGetExportByName(ImportedModule
->DllBase
, pe_name
->Name
, pe_name
->Hint
);
1448 if ((*ImportAddressList
) == NULL
)
1450 DPRINT1("Failed to import %s from %wZ\n", pe_name
->Name
, &ImportedModule
->FullDllName
);
1451 return STATUS_UNSUCCESSFUL
;
1454 ImportAddressList
++;
1457 return STATUS_SUCCESS
;
1461 LdrPEFixupImports ( PLDR_DATA_TABLE_ENTRY Module
)
1463 PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory
;
1465 PLDR_DATA_TABLE_ENTRY ImportedModule
;
1469 /* Process each import module */
1470 ImportModuleDirectory
= (PIMAGE_IMPORT_DESCRIPTOR
)
1471 RtlImageDirectoryEntryToData(Module
->DllBase
,
1473 IMAGE_DIRECTORY_ENTRY_IMPORT
,
1475 DPRINT("Processeing import directory at %p\n", ImportModuleDirectory
);
1476 while (ImportModuleDirectory
->Name
)
1478 if (Module
->SizeOfImage
<= ImportModuleDirectory
->Name
)
1480 DPRINT1("Invalid import directory in %wZ\n", &Module
->FullDllName
);
1481 return STATUS_SECTION_NOT_IMAGE
;
1484 /* Check to make sure that import lib is kernel */
1485 ImportedName
= (PCHAR
) Module
->DllBase
+ ImportModuleDirectory
->Name
;
1487 Status
= LdrPEGetOrLoadModule(Module
, ImportedName
, &ImportedModule
);
1488 if (!NT_SUCCESS(Status
))
1493 Status
= LdrPEProcessImportDirectoryEntry(Module
->DllBase
, ImportedModule
, ImportModuleDirectory
);
1494 if (!NT_SUCCESS(Status
))
1499 ImportModuleDirectory
++;
1501 return STATUS_SUCCESS
;