https://git.reactos.org/?p=reactos.git;a=commitdiff;h=658d5a3ff5e9f1dcf88d6…
commit 658d5a3ff5e9f1dcf88d602ac443039faa6c7a8c
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Thu Sep 19 02:47:29 2019 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Thu Sep 19 02:53:57 2019 +0200
[FREELDR] Rename the PE loader functions 'PeLdr*' instead of
'WinLdr*'.
---
boot/freeldr/freeldr/disk/scsiport.c | 12 +-
boot/freeldr/freeldr/include/peloader.h | 32 +-
boot/freeldr/freeldr/lib/peloader.c | 1341 +++++++++++++++----------------
boot/freeldr/freeldr/ntldr/winldr.c | 30 +-
4 files changed, 703 insertions(+), 712 deletions(-)
diff --git a/boot/freeldr/freeldr/disk/scsiport.c b/boot/freeldr/freeldr/disk/scsiport.c
index 6cb204d4c31..a42cadc6164 100644
--- a/boot/freeldr/freeldr/disk/scsiport.c
+++ b/boot/freeldr/freeldr/disk/scsiport.c
@@ -1639,7 +1639,7 @@ LoadBootDeviceDriver(VOID)
strcat(NtBootDdPath, "\\NTBOOTDD.SYS");
/* Load file */
- Success = WinLdrLoadImage(NtBootDdPath, LoaderBootDriver, &ImageBase);
+ Success = PeLdrLoadImage(NtBootDdPath, LoaderBootDriver, &ImageBase);
if (!Success)
{
/* That's OK. File simply doesn't exist */
@@ -1647,15 +1647,15 @@ LoadBootDeviceDriver(VOID)
}
/* Allocate a DTE for ntbootdd */
- Success = WinLdrAllocateDataTableEntry(&ModuleListHead,
"ntbootdd.sys",
- "NTBOOTDD.SYS", ImageBase, &BootDdDTE);
+ Success = PeLdrAllocateDataTableEntry(&ModuleListHead, "ntbootdd.sys",
+ "NTBOOTDD.SYS", ImageBase,
&BootDdDTE);
if (!Success)
return EIO;
/* Add the PE part of freeldr.sys to the list of loaded executables, it
contains ScsiPort* exports, imported by ntbootdd.sys */
- Success = WinLdrAllocateDataTableEntry(&ModuleListHead,
"scsiport.sys",
- "FREELDR.SYS", &__ImageBase, &FreeldrDTE);
+ Success = PeLdrAllocateDataTableEntry(&ModuleListHead, "scsiport.sys",
+ "FREELDR.SYS", &__ImageBase,
&FreeldrDTE);
if (!Success)
{
RemoveEntryList(&BootDdDTE->InLoadOrderLinks);
@@ -1663,7 +1663,7 @@ LoadBootDeviceDriver(VOID)
}
/* Fix imports */
- Success = WinLdrScanImportDescriptorTable(&ModuleListHead, "",
BootDdDTE);
+ Success = PeLdrScanImportDescriptorTable(&ModuleListHead, "",
BootDdDTE);
/* Now unlinkt the DTEs, they won't be valid later */
RemoveEntryList(&BootDdDTE->InLoadOrderLinks);
diff --git a/boot/freeldr/freeldr/include/peloader.h
b/boot/freeldr/freeldr/include/peloader.h
index 9d4b1178819..a582f760c29 100644
--- a/boot/freeldr/freeldr/include/peloader.h
+++ b/boot/freeldr/freeldr/include/peloader.h
@@ -19,23 +19,27 @@
#pragma once
BOOLEAN
-WinLdrLoadImage(IN PCHAR FileName,
- TYPE_OF_MEMORY MemoryType,
- OUT PVOID *ImageBasePA);
+PeLdrLoadImage(
+ IN PCHAR FileName,
+ IN TYPE_OF_MEMORY MemoryType,
+ OUT PVOID *ImageBasePA);
BOOLEAN
-WinLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead,
- IN PCCH BaseDllName,
- IN PCCH FullDllName,
- IN PVOID BasePA,
- OUT PLDR_DATA_TABLE_ENTRY *NewEntry);
+PeLdrAllocateDataTableEntry(
+ IN OUT PLIST_ENTRY ModuleListHead,
+ IN PCCH BaseDllName,
+ IN PCCH FullDllName,
+ IN PVOID BasePA,
+ OUT PLDR_DATA_TABLE_ENTRY *NewEntry);
BOOLEAN
-WinLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead,
- IN PCCH DirectoryPath,
- IN PLDR_DATA_TABLE_ENTRY ScanDTE);
+PeLdrScanImportDescriptorTable(
+ IN OUT PLIST_ENTRY ModuleListHead,
+ IN PCCH DirectoryPath,
+ IN PLDR_DATA_TABLE_ENTRY ScanDTE);
BOOLEAN
-WinLdrCheckForLoadedDll(IN OUT PLIST_ENTRY ModuleListHead,
- IN PCH DllName,
- OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);
+PeLdrCheckForLoadedDll(
+ IN OUT PLIST_ENTRY ModuleListHead,
+ IN PCH DllName,
+ OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);
diff --git a/boot/freeldr/freeldr/lib/peloader.c b/boot/freeldr/freeldr/lib/peloader.c
index c306375816e..53462a574fa 100644
--- a/boot/freeldr/freeldr/lib/peloader.c
+++ b/boot/freeldr/freeldr/lib/peloader.c
@@ -16,854 +16,841 @@
*
http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/
*/
-/* INCLUDES ***************************************************************/
+/* INCLUDES ******************************************************************/
#include <freeldr.h>
#include <debug.h>
DBG_DEFAULT_CHANNEL(PELOADER);
-/* FUNCTIONS **************************************************************/
-
-static BOOLEAN
-WinLdrpCompareDllName(IN PCH DllName,
- IN PUNICODE_STRING UnicodeName);
-
-static BOOLEAN
-WinLdrpBindImportName(IN OUT PLIST_ENTRY ModuleListHead,
- IN PVOID DllBase,
- IN PVOID ImageBase,
- IN PIMAGE_THUNK_DATA ThunkData,
- IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
- IN ULONG ExportSize,
- IN BOOLEAN ProcessForwards,
- IN PCSTR DirectoryPath);
+/* PRIVATE FUNCTIONS *********************************************************/
+/* DllName - physical, UnicodeString->Buffer - virtual */
static BOOLEAN
-WinLdrpLoadAndScanReferencedDll(PLIST_ENTRY ModuleListHead,
- PCCH DirectoryPath,
- PCH ImportName,
- PLDR_DATA_TABLE_ENTRY *DataTableEntry);
+PeLdrpCompareDllName(
+ IN PCH DllName,
+ IN PUNICODE_STRING UnicodeName)
+{
+ PWSTR Buffer;
+ SIZE_T i, Length;
-static BOOLEAN
-WinLdrpScanImportAddressTable(IN OUT PLIST_ENTRY ModuleListHead,
- IN PVOID DllBase,
- IN PVOID ImageBase,
- IN PIMAGE_THUNK_DATA ThunkData,
- IN PCSTR DirectoryPath);
+ /* First obvious check: for length of two names */
+ Length = strlen(DllName);
+#if DBG
+ {
+ UNICODE_STRING UnicodeNamePA;
+ UnicodeNamePA.Length = UnicodeName->Length;
+ UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength;
+ UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer);
+ TRACE("PeLdrpCompareDllName: %s and %wZ, Length = %d "
+ "UN->Length %d\n", DllName, &UnicodeNamePA, Length,
UnicodeName->Length);
+ }
+#endif
-/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */
-BOOLEAN
-WinLdrCheckForLoadedDll(IN OUT PLIST_ENTRY ModuleListHead,
- IN PCH DllName,
- OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
-{
- PLDR_DATA_TABLE_ENTRY DataTableEntry;
- LIST_ENTRY *ModuleEntry;
+ if ((Length * sizeof(WCHAR)) > UnicodeName->Length)
+ return FALSE;
- TRACE("WinLdrCheckForLoadedDll: DllName %s\n", DllName);
+ /* Store pointer to unicode string's buffer */
+ Buffer = VaToPa(UnicodeName->Buffer);
- /* Just go through each entry in the LoadOrderList and compare loaded module's
- name with a given name */
- ModuleEntry = ModuleListHead->Flink;
- while (ModuleEntry != ModuleListHead)
+ /* Loop character by character */
+ for (i = 0; i < Length; i++)
{
- /* Get pointer to the current DTE */
- DataTableEntry = CONTAINING_RECORD(ModuleEntry,
- LDR_DATA_TABLE_ENTRY,
- InLoadOrderLinks);
-
- TRACE("WinLdrCheckForLoadedDll: DTE %p, EP %p, base %p name
'%.*ws'\n",
- DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase,
- DataTableEntry->BaseDllName.Length / 2,
VaToPa(DataTableEntry->BaseDllName.Buffer));
+ /* Compare two characters, uppercasing them */
+ if (toupper(*DllName) != toupper((CHAR)*Buffer))
+ return FALSE;
- /* Compare names */
- if (WinLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
- {
- /* Yes, found it, report pointer to the loaded module's DTE
- to the caller and increase load count for it */
- *LoadedEntry = DataTableEntry;
- DataTableEntry->LoadCount++;
- TRACE("WinLdrCheckForLoadedDll: LoadedEntry %X\n",
DataTableEntry);
- return TRUE;
- }
+ /* Move to the next character */
+ DllName++;
+ Buffer++;
+ }
- /* Go to the next entry */
- ModuleEntry = ModuleEntry->Flink;
+ /* Check, if strings either fully match, or match till the "." (w/o
extension) */
+ if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.'))
+ {
+ /* Yes they do */
+ return TRUE;
}
- /* Nothing found */
+ /* Strings don't match, return FALSE */
return FALSE;
}
-BOOLEAN
-WinLdrScanImportDescriptorTable(IN OUT PLIST_ENTRY ModuleListHead,
- IN PCCH DirectoryPath,
- IN PLDR_DATA_TABLE_ENTRY ScanDTE)
+static BOOLEAN
+PeLdrpLoadAndScanReferencedDll(
+ IN OUT PLIST_ENTRY ModuleListHead,
+ IN PCCH DirectoryPath,
+ IN PCH ImportName,
+ OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry);
+
+static BOOLEAN
+PeLdrpBindImportName(
+ IN OUT PLIST_ENTRY ModuleListHead,
+ IN PVOID DllBase,
+ IN PVOID ImageBase,
+ IN PIMAGE_THUNK_DATA ThunkData,
+ IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
+ IN ULONG ExportSize,
+ IN BOOLEAN ProcessForwards,
+ IN PCSTR DirectoryPath)
{
- PLDR_DATA_TABLE_ENTRY DataTableEntry;
- PIMAGE_IMPORT_DESCRIPTOR ImportTable;
- ULONG ImportTableSize;
- PCH ImportName;
+ ULONG Ordinal;
+ PULONG NameTable, FunctionTable;
+ PUSHORT OrdinalTable;
+ LONG High, Low, Middle, Result;
+ ULONG Hint;
+ PIMAGE_IMPORT_BY_NAME ImportData;
+ PCHAR ExportName, ForwarderName;
BOOLEAN Success;
- /* Get a pointer to the import table of this image */
- ImportTable =
(PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
- TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);
+ //TRACE("PeLdrpBindImportName(): DllBase 0x%X, ImageBase 0x%X, ThunkData 0x%X,
ExportDirectory 0x%X, ExportSize %d, ProcessForwards 0x%X\n",
+ // DllBase, ImageBase, ThunkData, ExportDirectory, ExportSize,
ProcessForwards);
-#if DBG
+ /* Check passed DllBase param */
+ if(DllBase == NULL)
{
- UNICODE_STRING BaseName;
- BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
- BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
- BaseName.Length = ScanDTE->BaseDllName.Length;
- TRACE("WinLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n",
- &BaseName, ImportTable);
+ WARN("DllBase == NULL!\n");
+ return FALSE;
}
-#endif
- /* If image doesn't have any import directory - just return success */
- if (ImportTable == NULL)
- return TRUE;
+ /* Convert all non-critical pointers to PA from VA */
+ ThunkData = VaToPa(ThunkData);
- /* Loop through all entries */
- for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk !=
0);ImportTable++)
+ /* Is the reference by ordinal? */
+ if (IMAGE_SNAP_BY_ORDINAL(ThunkData->u1.Ordinal) && !ProcessForwards)
{
- /* Get pointer to the name */
- ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
- TRACE("WinLdrScanImportDescriptorTable(): Looking at %s\n",
ImportName);
-
- /* In case we get a reference to ourselves - just skip it */
- if (WinLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
- continue;
-
- /* Load the DLL if it is not already loaded */
- if (!WinLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
+ /* Yes, calculate the ordinal */
+ Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkData->u1.Ordinal) -
(UINT32)ExportDirectory->Base);
+ //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
+ }
+ else
+ {
+ /* It's reference by name, we have to look it up in the export directory */
+ if (!ProcessForwards)
{
- Success = WinLdrpLoadAndScanReferencedDll(ModuleListHead,
- DirectoryPath,
- ImportName,
- &DataTableEntry);
- if (!Success)
- {
- ERR("WinLdrpLoadAndScanReferencedDll() failed\n");
- return Success;
- }
+ /* AddressOfData in thunk entry will become a virtual address (from relative)
*/
+ //TRACE("PeLdrpBindImportName(): ThunkData->u1.AOD was %p\n",
ThunkData->u1.AddressOfData);
+ ThunkData->u1.AddressOfData =
+ (ULONG_PTR)RVA(ImageBase, ThunkData->u1.AddressOfData);
+ //TRACE("PeLdrpBindImportName(): ThunkData->u1.AOD became %p\n",
ThunkData->u1.AddressOfData);
}
- /* Scan its import address table */
- Success = WinLdrpScanImportAddressTable(ModuleListHead,
- DataTableEntry->DllBase,
- ScanDTE->DllBase,
-
(PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk),
- DirectoryPath);
+ /* Get the import name */
+ ImportData = VaToPa((PVOID)ThunkData->u1.AddressOfData);
- if (!Success)
+ /* Get pointers to Name and Ordinal tables (RVA -> VA) */
+ NameTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames));
+ OrdinalTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals));
+
+ //TRACE("NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X,
ED->AOFO 0x%X\n",
+ // NameTable, OrdinalTable, ExportDirectory->AddressOfNames,
ExportDirectory->AddressOfNameOrdinals);
+
+ /* Get the hint, convert it to a physical pointer */
+ Hint =
((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Hint;
+ //TRACE("HintIndex %d\n", Hint);
+
+ /* Get the export name from the hint */
+ ExportName = VaToPa(RVA(DllBase, NameTable[Hint]));
+
+ /* If Hint is less than total number of entries in the export directory,
+ and import name == export name, then we can just get it from the OrdinalTable
*/
+ if ((Hint < ExportDirectory->NumberOfNames) &&
+ (strcmp(ExportName, (PCHAR)ImportData->Name) == 0))
{
- ERR("WinLdrpScanImportAddressTable() failed: ImportName = '%s',
DirectoryPath = '%s'\n",
- ImportName, DirectoryPath);
- return Success;
+ Ordinal = OrdinalTable[Hint];
+ //TRACE("PeLdrpBindImportName(): Ordinal %d\n", Ordinal);
}
- }
+ else
+ {
+ /* It's not the easy way, we have to lookup import name in the name
table.
+ Let's use a binary search for this task. */
- return TRUE;
-}
+ //TRACE("PeLdrpBindImportName() looking up the import name using binary
search...\n");
-BOOLEAN
-WinLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead,
- IN PCCH BaseDllName,
- IN PCCH FullDllName,
- IN PVOID BasePA,
- OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
-{
- PVOID BaseVA = PaToVa(BasePA);
- PWSTR Buffer;
- PLDR_DATA_TABLE_ENTRY DataTableEntry;
- PIMAGE_NT_HEADERS NtHeaders;
- USHORT Length;
+ /* Low boundary is set to 0, and high boundary to the maximum index */
+ Low = 0;
+ High = ExportDirectory->NumberOfNames - 1;
- TRACE("WinLdrAllocateDataTableEntry(, '%s', '%s', %p)\n",
- BaseDllName, FullDllName, BasePA);
+ /* Perform a binary-search loop */
+ while (High >= Low)
+ {
+ /* Divide by 2 by shifting to the right once */
+ Middle = (Low + High) / 2;
- /* Allocate memory for a data table entry, zero-initialize it */
- DataTableEntry = (PLDR_DATA_TABLE_ENTRY)FrLdrHeapAlloc(sizeof(LDR_DATA_TABLE_ENTRY),
- TAG_WLDR_DTE);
- if (DataTableEntry == NULL)
- return FALSE;
- RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));
+ /* Get the name from the name table */
+ ExportName = VaToPa(RVA(DllBase, NameTable[Middle]));
- /* Get NT headers from the image */
- NtHeaders = RtlImageNtHeader(BasePA);
+ /* Compare the names */
+ Result = strcmp(ExportName, (PCHAR)ImportData->Name);
- /* Initialize corresponding fields of DTE based on NT headers value */
- DataTableEntry->DllBase = BaseVA;
- DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
- DataTableEntry->EntryPoint = RVA(BaseVA,
NtHeaders->OptionalHeader.AddressOfEntryPoint);
- DataTableEntry->SectionPointer = 0;
- DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
+ // TRACE("Binary search: comparing Import '__', Export
'%s'\n",
+ //
VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]),
+ // (PCHAR)VaToPa(RVA(DllBase, NameTable[Middle])));
- /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
- by simple conversion - copying each character */
- Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
- Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
- if (Buffer == NULL)
- {
- FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
- return FALSE;
- }
- RtlZeroMemory(Buffer, Length);
+ // TRACE("TE->u1.AOD %p, fulladdr %p\n",
+ // ThunkData->u1.AddressOfData,
+ //
((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name );
- DataTableEntry->BaseDllName.Length = Length;
- DataTableEntry->BaseDllName.MaximumLength = Length;
- DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
- while (*BaseDllName != 0)
- {
- *Buffer++ = *BaseDllName++;
+ /* Depending on result of strcmp, perform different actions */
+ if (Result > 0)
+ {
+ /* Adjust top boundary */
+ High = Middle - 1;
+ }
+ else if (Result < 0)
+ {
+ /* Adjust bottom boundary */
+ Low = Middle + 1;
+ }
+ else
+ {
+ /* Yay, found it! */
+ break;
+ }
+ }
+
+ /* If high boundary is less than low boundary, then no result found */
+ if (High < Low)
+ {
+ ERR("Did not find export '%s'!\n",
(PCHAR)ImportData->Name);
+ return FALSE;
+ }
+
+ /* Everything alright, get the ordinal */
+ Ordinal = OrdinalTable[Middle];
+
+ //TRACE("PeLdrpBindImportName() found Ordinal %d\n", Ordinal);
+ }
}
- /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
- using the same method */
- Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
- Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
- if (Buffer == NULL)
+ /* Check ordinal number for validity! */
+ if (Ordinal >= ExportDirectory->NumberOfFunctions)
{
- FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
+ ERR("Ordinal number is invalid!\n");
return FALSE;
}
- RtlZeroMemory(Buffer, Length);
- DataTableEntry->FullDllName.Length = Length;
- DataTableEntry->FullDllName.MaximumLength = Length;
- DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
- while (*FullDllName != 0)
+ /* Get a pointer to the function table */
+ FunctionTable = (PULONG)VaToPa(RVA(DllBase,
ExportDirectory->AddressOfFunctions));
+
+ /* Save a pointer to the function */
+ ThunkData->u1.Function = (ULONG_PTR)RVA(DllBase, FunctionTable[Ordinal]);
+
+ /* Is it a forwarder? (function pointer is within the export directory) */
+ ForwarderName = (PCHAR)VaToPa((PVOID)ThunkData->u1.Function);
+ if (((ULONG_PTR)ForwarderName > (ULONG_PTR)ExportDirectory) &&
+ ((ULONG_PTR)ForwarderName < ((ULONG_PTR)ExportDirectory + ExportSize)))
{
- *Buffer++ = *FullDllName++;
- }
+ PLDR_DATA_TABLE_ENTRY DataTableEntry;
+ CHAR ForwardDllName[255];
+ PIMAGE_EXPORT_DIRECTORY RefExportDirectory;
+ ULONG RefExportSize;
- /* Initialize what's left - LoadCount which is 1, and set Flags so that
- we know this entry is processed */
- DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
- DataTableEntry->LoadCount = 1;
+ TRACE("PeLdrpBindImportName(): ForwarderName %s\n", ForwarderName);
- /* Insert this DTE to a list in the LPB */
- InsertTailList(ModuleListHead, &DataTableEntry->InLoadOrderLinks);
- TRACE("Inserting DTE %p, name='%.*S' DllBase=%p \n",
DataTableEntry,
- DataTableEntry->BaseDllName.Length / 2,
- VaToPa(DataTableEntry->BaseDllName.Buffer),
- DataTableEntry->DllBase);
+ /* Save the name of the forward dll */
+ RtlCopyMemory(ForwardDllName, ForwarderName, sizeof(ForwardDllName));
- /* Save pointer to a newly allocated and initialized entry */
- *NewEntry = DataTableEntry;
+ /* Strip out the symbol name */
+ *strrchr(ForwardDllName,'.') = '\0';
- /* Return success */
+ /* Check if the target image is already loaded */
+ if (!PeLdrCheckForLoadedDll(ModuleListHead, ForwardDllName,
&DataTableEntry))
+ {
+ /* Check if the forward dll name has an extension */
+ if (strchr(ForwardDllName, '.') == NULL)
+ {
+ /* Name does not have an extension, append '.dll' */
+ strcat(ForwardDllName, ".dll");
+ }
+
+ /* Now let's try to load it! */
+ Success = PeLdrpLoadAndScanReferencedDll(ModuleListHead,
+ DirectoryPath,
+ ForwardDllName,
+ &DataTableEntry);
+ if (!Success)
+ {
+ ERR("PeLdrpLoadAndScanReferencedDll() failed to load forwarder
dll.\n");
+ return Success;
+ }
+ }
+
+ /* Get pointer to the export directory of loaded DLL */
+ RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
+ RtlImageDirectoryEntryToData(VaToPa(DataTableEntry->DllBase),
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &RefExportSize);
+
+ /* Fail if it's NULL */
+ if (RefExportDirectory)
+ {
+ UCHAR Buffer[128];
+ IMAGE_THUNK_DATA RefThunkData;
+ PIMAGE_IMPORT_BY_NAME ImportByName;
+ PCHAR ImportName;
+
+ /* Get pointer to the import name */
+ ImportName = strrchr(ForwarderName, '.') + 1;
+
+ /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */
+ ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer;
+
+ /* Fill the name with the import name */
+ RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1);
+
+ /* Set Hint to 0 */
+ ImportByName->Hint = 0;
+
+ /* And finally point ThunkData's AddressOfData to that structure */
+ RefThunkData.u1.AddressOfData = (ULONG_PTR)ImportByName;
+
+ /* And recursively call ourselves */
+ Success = PeLdrpBindImportName(ModuleListHead,
+ DataTableEntry->DllBase,
+ ImageBase,
+ &RefThunkData,
+ RefExportDirectory,
+ RefExportSize,
+ TRUE,
+ DirectoryPath);
+
+ /* Fill out the ThunkData with data from RefThunkData */
+ ThunkData->u1 = RefThunkData.u1;
+
+ /* Return what we got from the recursive call */
+ return Success;
+ }
+ else
+ {
+ /* Fail if ExportDirectory is NULL */
+ return FALSE;
+ }
+ }
+
+ /* Success! */
return TRUE;
}
-/*
- * WinLdrLoadImage loads the specified image from the file (it doesn't
- * perform any additional operations on the filename, just directly
- * calls the file I/O routines), and relocates it so that it's ready
- * to be used when paging is enabled.
- * Addressing mode: physical
- */
-BOOLEAN
-WinLdrLoadImage(IN PCHAR FileName,
- TYPE_OF_MEMORY MemoryType,
- OUT PVOID *ImageBasePA)
+static BOOLEAN
+PeLdrpLoadAndScanReferencedDll(
+ IN OUT PLIST_ENTRY ModuleListHead,
+ IN PCCH DirectoryPath,
+ IN PCH ImportName,
+ OUT PLDR_DATA_TABLE_ENTRY *DataTableEntry)
{
- ULONG FileId;
- PVOID PhysicalBase;
- PVOID VirtualBase = NULL;
- UCHAR HeadersBuffer[SECTOR_SIZE * 2];
- PIMAGE_NT_HEADERS NtHeaders;
- PIMAGE_SECTION_HEADER SectionHeader;
- ULONG VirtualSize, SizeOfRawData, NumberOfSections;
- ARC_STATUS Status;
- LARGE_INTEGER Position;
- ULONG i, BytesRead;
+ CHAR FullDllName[256];
+ BOOLEAN Success;
+ PVOID BasePA = NULL;
- TRACE("WinLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType);
+ /* Prepare the full path to the file to be loaded */
+ strcpy(FullDllName, DirectoryPath);
+ strcat(FullDllName, ImportName);
- /* Open the image file */
- Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
- if (Status != ESUCCESS)
- {
- WARN("ArcOpen(FileName: '%s') failed. Status: %u\n", FileName,
Status);
- return FALSE;
- }
+ TRACE("Loading referenced DLL: %s\n", FullDllName);
- /* Load the first 2 sectors of the image so we can read the PE header */
- Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
- if (Status != ESUCCESS)
+ /* Load the image */
+ Success = PeLdrLoadImage(FullDllName, LoaderBootDriver, &BasePA);
+ if (!Success)
{
- ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName,
Status);
- UiMessageBox("Error reading from file.");
- ArcClose(FileId);
- return FALSE;
+ ERR("PeLdrLoadImage() failed\n");
+ return Success;
}
- /* Now read the MZ header to get the offset to the PE Header */
- NtHeaders = RtlImageNtHeader(HeadersBuffer);
- if (!NtHeaders)
+ /* Allocate DTE for newly loaded DLL */
+ Success = PeLdrAllocateDataTableEntry(ModuleListHead,
+ ImportName,
+ FullDllName,
+ BasePA,
+ DataTableEntry);
+ if (!Success)
{
- ERR("No NT header found in \"%s\"\n", FileName);
- UiMessageBox("Error - no NT header found.");
- ArcClose(FileId);
- return FALSE;
+ ERR("PeLdrAllocateDataTableEntry() failed\n");
+ return Success;
}
- /* Ensure this is executable image */
- if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) ==
0))
+ /* Scan its dependencies too */
+ TRACE("PeLdrScanImportDescriptorTable() calling ourselves for %S\n",
+ VaToPa((*DataTableEntry)->BaseDllName.Buffer));
+ Success = PeLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath,
*DataTableEntry);
+ if (!Success)
{
- ERR("Not an executable image \"%s\"\n", FileName);
- UiMessageBox("Not an executable image.");
- ArcClose(FileId);
- return FALSE;
+ ERR("PeLdrScanImportDescriptorTable() failed\n");
+ return Success;
}
- /* Store number of sections to read and a pointer to the first section */
- NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
- SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
+ return TRUE;
+}
- /* Try to allocate this memory, if fails - allocate somewhere else */
- PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
- (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase &
(KSEG0_BASE - 1)),
- MemoryType);
+static BOOLEAN
+PeLdrpScanImportAddressTable(
+ IN OUT PLIST_ENTRY ModuleListHead,
+ IN PVOID DllBase,
+ IN PVOID ImageBase,
+ IN PIMAGE_THUNK_DATA ThunkData,
+ IN PCSTR DirectoryPath)
+{
+ PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
+ BOOLEAN Success;
+ ULONG ExportSize;
- if (PhysicalBase == NULL)
- {
- /* It's ok, we don't panic - let's allocate again at any other
"low" place */
- PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage,
MemoryType);
+ TRACE("PeLdrpScanImportAddressTable(): DllBase 0x%X, "
+ "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData);
- if (PhysicalBase == NULL)
- {
- ERR("Failed to alloc %lu bytes for image %s\n",
NtHeaders->OptionalHeader.SizeOfImage, FileName);
- UiMessageBox("Failed to alloc pages for image.");
- ArcClose(FileId);
- return FALSE;
- }
+ /* Obtain the export table from the DLL's base */
+ if (DllBase == NULL)
+ {
+ ERR("Error, DllBase == NULL!\n");
+ return FALSE;
+ }
+ else
+ {
+ ExportDirectory =
+ (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(VaToPa(DllBase),
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &ExportSize);
}
- /* This is the real image base - in form of a virtual address */
- VirtualBase = PaToVa(PhysicalBase);
-
- TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);
+ TRACE("PeLdrpScanImportAddressTable(): ExportDirectory 0x%X\n",
ExportDirectory);
- /* Set to 0 position and fully load the file image */
- Position.QuadPart = 0;
- Status = ArcSeek(FileId, &Position, SeekAbsolute);
- if (Status != ESUCCESS)
+ /* If pointer to Export Directory is */
+ if (ExportDirectory == NULL)
{
- ERR("ArcSeek(File: '%s') failed. Status: 0x%lx\n", FileName,
Status);
- UiMessageBox("Error seeking the start of a file.");
- ArcClose(FileId);
+ ERR("DllBase=%p(%p)\n", DllBase, VaToPa(DllBase));
return FALSE;
}
- Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders,
&BytesRead);
- if (Status != ESUCCESS)
+ /* Go through each entry in the thunk table and bind it */
+ while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0)
{
- ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName,
Status);
- UiMessageBox("Error reading headers.");
- ArcClose(FileId);
- return FALSE;
+ /* Bind it */
+ Success = PeLdrpBindImportName(ModuleListHead,
+ DllBase,
+ ImageBase,
+ ThunkData,
+ ExportDirectory,
+ ExportSize,
+ FALSE,
+ DirectoryPath);
+
+ /* Move to the next entry */
+ ThunkData++;
+
+ /* Return error if binding was unsuccessful */
+ if (!Success)
+ return Success;
}
- /* Reload the NT Header */
- NtHeaders = RtlImageNtHeader(PhysicalBase);
+ /* Return success */
+ return TRUE;
+}
- /* Load the first section */
- SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
- /* Fill output parameters */
- *ImageBasePA = PhysicalBase;
+/* FUNCTIONS *****************************************************************/
- /* Walk through each section and read it (check/fix any possible
- bad situations, if they arise) */
- for (i = 0; i < NumberOfSections; i++)
- {
- VirtualSize = SectionHeader->Misc.VirtualSize;
- SizeOfRawData = SectionHeader->SizeOfRawData;
+/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */
+BOOLEAN
+PeLdrCheckForLoadedDll(
+ IN OUT PLIST_ENTRY ModuleListHead,
+ IN PCH DllName,
+ OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry)
+{
+ PLDR_DATA_TABLE_ENTRY DataTableEntry;
+ LIST_ENTRY *ModuleEntry;
- /* Handle a case when VirtualSize equals 0 */
- if (VirtualSize == 0)
- VirtualSize = SizeOfRawData;
+ TRACE("PeLdrCheckForLoadedDll: DllName %s\n", DllName);
- /* If PointerToRawData is 0, then force its size to be also 0 */
- if (SectionHeader->PointerToRawData == 0)
- {
- SizeOfRawData = 0;
- }
- else
- {
- /* Cut the loaded size to the VirtualSize extents */
- if (SizeOfRawData > VirtualSize)
- SizeOfRawData = VirtualSize;
- }
-
- /* Actually read the section (if its size is not 0) */
- if (SizeOfRawData != 0)
- {
- /* Seek to the correct position */
- Position.LowPart = SectionHeader->PointerToRawData;
- Status = ArcSeek(FileId, &Position, SeekAbsolute);
-
- TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);
+ /* Just go through each entry in the LoadOrderList and compare loaded module's
+ name with a given name */
+ ModuleEntry = ModuleListHead->Flink;
+ while (ModuleEntry != ModuleListHead)
+ {
+ /* Get pointer to the current DTE */
+ DataTableEntry = CONTAINING_RECORD(ModuleEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
- /* Read this section from the file, size = SizeOfRawData */
- Status = ArcRead(FileId, (PUCHAR)PhysicalBase +
SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
- if (Status != ESUCCESS)
- {
- ERR("WinLdrLoadImage(): Error reading section from file!\n");
- break;
- }
- }
+ TRACE("PeLdrCheckForLoadedDll: DTE %p, EP %p, base %p name
'%.*ws'\n",
+ DataTableEntry, DataTableEntry->EntryPoint, DataTableEntry->DllBase,
+ DataTableEntry->BaseDllName.Length / 2,
VaToPa(DataTableEntry->BaseDllName.Buffer));
- /* Size of data is less than the virtual size - fill up the remainder with zeroes
*/
- if (SizeOfRawData < VirtualSize)
+ /* Compare names */
+ if (PeLdrpCompareDllName(DllName, &DataTableEntry->BaseDllName))
{
- TRACE("WinLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData,
VirtualSize);
- RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress +
(ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
+ /* Yes, found it, report pointer to the loaded module's DTE
+ to the caller and increase load count for it */
+ *LoadedEntry = DataTableEntry;
+ DataTableEntry->LoadCount++;
+ TRACE("PeLdrCheckForLoadedDll: LoadedEntry %X\n", DataTableEntry);
+ return TRUE;
}
- SectionHeader++;
- }
-
- /* We are done with the file - close it */
- ArcClose(FileId);
-
- /* If loading failed - return right now */
- if (Status != ESUCCESS)
- return FALSE;
-
- /* Relocate the image, if it needs it */
- if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
- {
- WARN("Relocating %p -> %p\n",
NtHeaders->OptionalHeader.ImageBase,
- VirtualBase);
- return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
- (ULONG_PTR)VirtualBase -
(ULONG_PTR)PhysicalBase,
- "FreeLdr",
- TRUE,
- TRUE, /* in case of conflict still
return success */
- FALSE);
+ /* Go to the next entry */
+ ModuleEntry = ModuleEntry->Flink;
}
- TRACE("WinLdrLoadImage() done, PA = %p\n", *ImageBasePA);
- return TRUE;
+ /* Nothing found */
+ return FALSE;
}
-/* PRIVATE FUNCTIONS *******************************************************/
-
-/* DllName - physical, UnicodeString->Buffer - virtual */
-static BOOLEAN
-WinLdrpCompareDllName(IN PCH DllName,
- IN PUNICODE_STRING UnicodeName)
+BOOLEAN
+PeLdrScanImportDescriptorTable(
+ IN OUT PLIST_ENTRY ModuleListHead,
+ IN PCCH DirectoryPath,
+ IN PLDR_DATA_TABLE_ENTRY ScanDTE)
{
- PWSTR Buffer;
- SIZE_T i, Length;
+ PLDR_DATA_TABLE_ENTRY DataTableEntry;
+ PIMAGE_IMPORT_DESCRIPTOR ImportTable;
+ ULONG ImportTableSize;
+ PCH ImportName;
+ BOOLEAN Success;
- /* First obvious check: for length of two names */
- Length = strlen(DllName);
+ /* Get a pointer to the import table of this image */
+ ImportTable =
(PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(ScanDTE->DllBase),
+ TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);
#if DBG
{
- UNICODE_STRING UnicodeNamePA;
- UnicodeNamePA.Length = UnicodeName->Length;
- UnicodeNamePA.MaximumLength = UnicodeName->MaximumLength;
- UnicodeNamePA.Buffer = VaToPa(UnicodeName->Buffer);
- TRACE("WinLdrpCompareDllName: %s and %wZ, Length = %d "
- "UN->Length %d\n", DllName, &UnicodeNamePA, Length,
UnicodeName->Length);
+ UNICODE_STRING BaseName;
+ BaseName.Buffer = VaToPa(ScanDTE->BaseDllName.Buffer);
+ BaseName.MaximumLength = ScanDTE->BaseDllName.MaximumLength;
+ BaseName.Length = ScanDTE->BaseDllName.Length;
+ TRACE("PeLdrScanImportDescriptorTable(): %wZ ImportTable = 0x%X\n",
+ &BaseName, ImportTable);
}
#endif
- if ((Length * sizeof(WCHAR)) > UnicodeName->Length)
- return FALSE;
-
- /* Store pointer to unicode string's buffer */
- Buffer = VaToPa(UnicodeName->Buffer);
+ /* If image doesn't have any import directory - just return success */
+ if (ImportTable == NULL)
+ return TRUE;
- /* Loop character by character */
- for (i = 0; i < Length; i++)
+ /* Loop through all entries */
+ for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk !=
0);ImportTable++)
{
- /* Compare two characters, uppercasing them */
- if (toupper(*DllName) != toupper((CHAR)*Buffer))
- return FALSE;
+ /* Get pointer to the name */
+ ImportName = (PCH)VaToPa(RVA(ScanDTE->DllBase, ImportTable->Name));
+ TRACE("PeLdrScanImportDescriptorTable(): Looking at %s\n",
ImportName);
- /* Move to the next character */
- DllName++;
- Buffer++;
- }
+ /* In case we get a reference to ourselves - just skip it */
+ if (PeLdrpCompareDllName(ImportName, &ScanDTE->BaseDllName))
+ continue;
- /* Check, if strings either fully match, or match till the "." (w/o
extension) */
- if ((UnicodeName->Length == Length * sizeof(WCHAR)) || (*Buffer == L'.'))
- {
- /* Yes they do */
- return TRUE;
+ /* Load the DLL if it is not already loaded */
+ if (!PeLdrCheckForLoadedDll(ModuleListHead, ImportName, &DataTableEntry))
+ {
+ Success = PeLdrpLoadAndScanReferencedDll(ModuleListHead,
+ DirectoryPath,
+ ImportName,
+ &DataTableEntry);
+ if (!Success)
+ {
+ ERR("PeLdrpLoadAndScanReferencedDll() failed\n");
+ return Success;
+ }
+ }
+
+ /* Scan its import address table */
+ Success = PeLdrpScanImportAddressTable(ModuleListHead,
+ DataTableEntry->DllBase,
+ ScanDTE->DllBase,
+
(PIMAGE_THUNK_DATA)RVA(ScanDTE->DllBase, ImportTable->FirstThunk),
+ DirectoryPath);
+
+ if (!Success)
+ {
+ ERR("PeLdrpScanImportAddressTable() failed: ImportName = '%s',
DirectoryPath = '%s'\n",
+ ImportName, DirectoryPath);
+ return Success;
+ }
}
- /* Strings don't match, return FALSE */
- return FALSE;
+ return TRUE;
}
-static BOOLEAN
-WinLdrpBindImportName(IN OUT PLIST_ENTRY ModuleListHead,
- IN PVOID DllBase,
- IN PVOID ImageBase,
- IN PIMAGE_THUNK_DATA ThunkData,
- IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
- IN ULONG ExportSize,
- IN BOOLEAN ProcessForwards,
- IN PCSTR DirectoryPath)
+BOOLEAN
+PeLdrAllocateDataTableEntry(
+ IN OUT PLIST_ENTRY ModuleListHead,
+ IN PCCH BaseDllName,
+ IN PCCH FullDllName,
+ IN PVOID BasePA,
+ OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
{
- ULONG Ordinal;
- PULONG NameTable, FunctionTable;
- PUSHORT OrdinalTable;
- LONG High, Low, Middle, Result;
- ULONG Hint;
- PIMAGE_IMPORT_BY_NAME ImportData;
- PCHAR ExportName, ForwarderName;
- BOOLEAN Success;
+ PVOID BaseVA = PaToVa(BasePA);
+ PWSTR Buffer;
+ PLDR_DATA_TABLE_ENTRY DataTableEntry;
+ PIMAGE_NT_HEADERS NtHeaders;
+ USHORT Length;
- //TRACE("WinLdrpBindImportName(): DllBase 0x%X, ImageBase 0x%X, ThunkData 0x%X,
ExportDirectory 0x%X, ExportSize %d, ProcessForwards 0x%X\n",
- // DllBase, ImageBase, ThunkData, ExportDirectory, ExportSize,
ProcessForwards);
+ TRACE("PeLdrAllocateDataTableEntry(, '%s', '%s', %p)\n",
+ BaseDllName, FullDllName, BasePA);
- /* Check passed DllBase param */
- if(DllBase == NULL)
- {
- WARN("DllBase == NULL!\n");
+ /* Allocate memory for a data table entry, zero-initialize it */
+ DataTableEntry = (PLDR_DATA_TABLE_ENTRY)FrLdrHeapAlloc(sizeof(LDR_DATA_TABLE_ENTRY),
+ TAG_WLDR_DTE);
+ if (DataTableEntry == NULL)
return FALSE;
- }
+ RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));
- /* Convert all non-critical pointers to PA from VA */
- ThunkData = VaToPa(ThunkData);
+ /* Get NT headers from the image */
+ NtHeaders = RtlImageNtHeader(BasePA);
- /* Is the reference by ordinal? */
- if (IMAGE_SNAP_BY_ORDINAL(ThunkData->u1.Ordinal) && !ProcessForwards)
+ /* Initialize corresponding fields of DTE based on NT headers value */
+ DataTableEntry->DllBase = BaseVA;
+ DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
+ DataTableEntry->EntryPoint = RVA(BaseVA,
NtHeaders->OptionalHeader.AddressOfEntryPoint);
+ DataTableEntry->SectionPointer = 0;
+ DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
+
+ /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
+ by simple conversion - copying each character */
+ Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
+ Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
+ if (Buffer == NULL)
{
- /* Yes, calculate the ordinal */
- Ordinal = (ULONG)(IMAGE_ORDINAL(ThunkData->u1.Ordinal) -
(UINT32)ExportDirectory->Base);
- //TRACE("WinLdrpBindImportName(): Ordinal %d\n", Ordinal);
+ FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
+ return FALSE;
}
- else
- {
- /* It's reference by name, we have to look it up in the export directory */
- if (!ProcessForwards)
- {
- /* AddressOfData in thunk entry will become a virtual address (from relative)
*/
- //TRACE("WinLdrpBindImportName(): ThunkData->u1.AOD was %p\n",
ThunkData->u1.AddressOfData);
- ThunkData->u1.AddressOfData =
- (ULONG_PTR)RVA(ImageBase, ThunkData->u1.AddressOfData);
- //TRACE("WinLdrpBindImportName(): ThunkData->u1.AOD became
%p\n", ThunkData->u1.AddressOfData);
- }
-
- /* Get the import name */
- ImportData = VaToPa((PVOID)ThunkData->u1.AddressOfData);
-
- /* Get pointers to Name and Ordinal tables (RVA -> VA) */
- NameTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNames));
- OrdinalTable = VaToPa(RVA(DllBase, ExportDirectory->AddressOfNameOrdinals));
-
- //TRACE("NameTable 0x%X, OrdinalTable 0x%X, ED->AddressOfNames 0x%X,
ED->AOFO 0x%X\n",
- // NameTable, OrdinalTable, ExportDirectory->AddressOfNames,
ExportDirectory->AddressOfNameOrdinals);
-
- /* Get the hint, convert it to a physical pointer */
- Hint =
((PIMAGE_IMPORT_BY_NAME)VaToPa((PVOID)ThunkData->u1.AddressOfData))->Hint;
- //TRACE("HintIndex %d\n", Hint);
-
- /* Get the export name from the hint */
- ExportName = VaToPa(RVA(DllBase, NameTable[Hint]));
-
- /* If Hint is less than total number of entries in the export directory,
- and import name == export name, then we can just get it from the OrdinalTable
*/
- if ((Hint < ExportDirectory->NumberOfNames) &&
- (strcmp(ExportName, (PCHAR)ImportData->Name) == 0))
- {
- Ordinal = OrdinalTable[Hint];
- //TRACE("WinLdrpBindImportName(): Ordinal %d\n", Ordinal);
- }
- else
- {
- /* It's not the easy way, we have to lookup import name in the name
table.
- Let's use a binary search for this task. */
-
- //TRACE("WinLdrpBindImportName() looking up the import name using binary
search...\n");
-
- /* Low boundary is set to 0, and high boundary to the maximum index */
- Low = 0;
- High = ExportDirectory->NumberOfNames - 1;
+ RtlZeroMemory(Buffer, Length);
- /* Perform a binary-search loop */
- while (High >= Low)
- {
- /* Divide by 2 by shifting to the right once */
- Middle = (Low + High) / 2;
+ DataTableEntry->BaseDllName.Length = Length;
+ DataTableEntry->BaseDllName.MaximumLength = Length;
+ DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
+ while (*BaseDllName != 0)
+ {
+ *Buffer++ = *BaseDllName++;
+ }
- /* Get the name from the name table */
- ExportName = VaToPa(RVA(DllBase, NameTable[Middle]));
+ /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
+ using the same method */
+ Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
+ Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
+ if (Buffer == NULL)
+ {
+ FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
+ return FALSE;
+ }
+ RtlZeroMemory(Buffer, Length);
- /* Compare the names */
- Result = strcmp(ExportName, (PCHAR)ImportData->Name);
+ DataTableEntry->FullDllName.Length = Length;
+ DataTableEntry->FullDllName.MaximumLength = Length;
+ DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
+ while (*FullDllName != 0)
+ {
+ *Buffer++ = *FullDllName++;
+ }
- // TRACE("Binary search: comparing Import '__', Export
'%s'\n",
- //
VaToPa(&((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name[0]),
- // (PCHAR)VaToPa(RVA(DllBase, NameTable[Middle])));
+ /* Initialize what's left - LoadCount which is 1, and set Flags so that
+ we know this entry is processed */
+ DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
+ DataTableEntry->LoadCount = 1;
- // TRACE("TE->u1.AOD %p, fulladdr %p\n",
- // ThunkData->u1.AddressOfData,
- //
((PIMAGE_IMPORT_BY_NAME)VaToPa(ThunkData->u1.AddressOfData))->Name );
+ /* Insert this DTE to a list in the LPB */
+ InsertTailList(ModuleListHead, &DataTableEntry->InLoadOrderLinks);
+ TRACE("Inserting DTE %p, name='%.*S' DllBase=%p \n",
DataTableEntry,
+ DataTableEntry->BaseDllName.Length / 2,
+ VaToPa(DataTableEntry->BaseDllName.Buffer),
+ DataTableEntry->DllBase);
- /* Depending on result of strcmp, perform different actions */
- if (Result > 0)
- {
- /* Adjust top boundary */
- High = Middle - 1;
- }
- else if (Result < 0)
- {
- /* Adjust bottom boundary */
- Low = Middle + 1;
- }
- else
- {
- /* Yay, found it! */
- break;
- }
- }
+ /* Save pointer to a newly allocated and initialized entry */
+ *NewEntry = DataTableEntry;
- /* If high boundary is less than low boundary, then no result found */
- if (High < Low)
- {
- ERR("Did not find export '%s'!\n",
(PCHAR)ImportData->Name);
- return FALSE;
- }
+ /* Return success */
+ return TRUE;
+}
- /* Everything alright, get the ordinal */
- Ordinal = OrdinalTable[Middle];
+/*
+ * PeLdrLoadImage loads the specified image from the file (it doesn't
+ * perform any additional operations on the filename, just directly
+ * calls the file I/O routines), and relocates it so that it's ready
+ * to be used when paging is enabled.
+ * Addressing mode: physical
+ */
+BOOLEAN
+PeLdrLoadImage(
+ IN PCHAR FileName,
+ IN TYPE_OF_MEMORY MemoryType,
+ OUT PVOID *ImageBasePA)
+{
+ ULONG FileId;
+ PVOID PhysicalBase;
+ PVOID VirtualBase = NULL;
+ UCHAR HeadersBuffer[SECTOR_SIZE * 2];
+ PIMAGE_NT_HEADERS NtHeaders;
+ PIMAGE_SECTION_HEADER SectionHeader;
+ ULONG VirtualSize, SizeOfRawData, NumberOfSections;
+ ARC_STATUS Status;
+ LARGE_INTEGER Position;
+ ULONG i, BytesRead;
- //TRACE("WinLdrpBindImportName() found Ordinal %d\n", Ordinal);
- }
- }
+ TRACE("PeLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType);
- /* Check ordinal number for validity! */
- if (Ordinal >= ExportDirectory->NumberOfFunctions)
+ /* Open the image file */
+ Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
+ if (Status != ESUCCESS)
{
- ERR("Ordinal number is invalid!\n");
+ WARN("ArcOpen(FileName: '%s') failed. Status: %u\n", FileName,
Status);
return FALSE;
}
- /* Get a pointer to the function table */
- FunctionTable = (PULONG)VaToPa(RVA(DllBase,
ExportDirectory->AddressOfFunctions));
+ /* Load the first 2 sectors of the image so we can read the PE header */
+ Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
+ if (Status != ESUCCESS)
+ {
+ ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName,
Status);
+ UiMessageBox("Error reading from file.");
+ ArcClose(FileId);
+ return FALSE;
+ }
- /* Save a pointer to the function */
- ThunkData->u1.Function = (ULONG_PTR)RVA(DllBase, FunctionTable[Ordinal]);
+ /* Now read the MZ header to get the offset to the PE Header */
+ NtHeaders = RtlImageNtHeader(HeadersBuffer);
+ if (!NtHeaders)
+ {
+ ERR("No NT header found in \"%s\"\n", FileName);
+ UiMessageBox("Error: No NT header found.");
+ ArcClose(FileId);
+ return FALSE;
+ }
- /* Is it a forwarder? (function pointer is within the export directory) */
- ForwarderName = (PCHAR)VaToPa((PVOID)ThunkData->u1.Function);
- if (((ULONG_PTR)ForwarderName > (ULONG_PTR)ExportDirectory) &&
- ((ULONG_PTR)ForwarderName < ((ULONG_PTR)ExportDirectory + ExportSize)))
+ /* Ensure this is executable image */
+ if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) ==
0))
{
- PLDR_DATA_TABLE_ENTRY DataTableEntry;
- CHAR ForwardDllName[255];
- PIMAGE_EXPORT_DIRECTORY RefExportDirectory;
- ULONG RefExportSize;
+ ERR("Not an executable image \"%s\"\n", FileName);
+ UiMessageBox("Not an executable image.");
+ ArcClose(FileId);
+ return FALSE;
+ }
- TRACE("WinLdrpBindImportName(): ForwarderName %s\n", ForwarderName);
+ /* Store number of sections to read and a pointer to the first section */
+ NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
+ SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
- /* Save the name of the forward dll */
- RtlCopyMemory(ForwardDllName, ForwarderName, sizeof(ForwardDllName));
+ /* Try to allocate this memory, if fails - allocate somewhere else */
+ PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
+ (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase &
(KSEG0_BASE - 1)),
+ MemoryType);
- /* Strip out the symbol name */
- *strrchr(ForwardDllName,'.') = '\0';
+ if (PhysicalBase == NULL)
+ {
+ /* It's ok, we don't panic - let's allocate again at any other
"low" place */
+ PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage,
MemoryType);
- /* Check if the target image is already loaded */
- if (!WinLdrCheckForLoadedDll(ModuleListHead, ForwardDllName,
&DataTableEntry))
+ if (PhysicalBase == NULL)
{
- /* Check if the forward dll name has an extension */
- if (strchr(ForwardDllName, '.') == NULL)
- {
- /* Name does not have an extension, append '.dll' */
- strcat(ForwardDllName, ".dll");
- }
-
- /* Now let's try to load it! */
- Success = WinLdrpLoadAndScanReferencedDll(ModuleListHead,
- DirectoryPath,
- ForwardDllName,
- &DataTableEntry);
- if (!Success)
- {
- ERR("WinLdrpLoadAndScanReferencedDll() failed to load forwarder
dll.\n");
- return Success;
- }
+ ERR("Failed to alloc %lu bytes for image %s\n",
NtHeaders->OptionalHeader.SizeOfImage, FileName);
+ UiMessageBox("Failed to alloc pages for image.");
+ ArcClose(FileId);
+ return FALSE;
}
+ }
- /* Get pointer to the export directory of loaded DLL */
- RefExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
- RtlImageDirectoryEntryToData(VaToPa(DataTableEntry->DllBase),
- TRUE,
- IMAGE_DIRECTORY_ENTRY_EXPORT,
- &RefExportSize);
+ /* This is the real image base - in form of a virtual address */
+ VirtualBase = PaToVa(PhysicalBase);
- /* Fail if it's NULL */
- if (RefExportDirectory)
- {
- UCHAR Buffer[128];
- IMAGE_THUNK_DATA RefThunkData;
- PIMAGE_IMPORT_BY_NAME ImportByName;
- PCHAR ImportName;
+ TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);
- /* Get pointer to the import name */
- ImportName = strrchr(ForwarderName, '.') + 1;
+ /* Set to 0 position and fully load the file image */
+ Position.QuadPart = 0;
+ Status = ArcSeek(FileId, &Position, SeekAbsolute);
+ if (Status != ESUCCESS)
+ {
+ ERR("ArcSeek(File: '%s') failed. Status: 0x%lx\n", FileName,
Status);
+ UiMessageBox("Error seeking the start of a file.");
+ ArcClose(FileId);
+ return FALSE;
+ }
- /* Create a IMAGE_IMPORT_BY_NAME structure, pointing to the local Buffer */
- ImportByName = (PIMAGE_IMPORT_BY_NAME)Buffer;
+ Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders,
&BytesRead);
+ if (Status != ESUCCESS)
+ {
+ ERR("ArcRead(File: '%s') failed. Status: %u\n", FileName,
Status);
+ UiMessageBox("Error reading headers.");
+ ArcClose(FileId);
+ return FALSE;
+ }
- /* Fill the name with the import name */
- RtlCopyMemory(ImportByName->Name, ImportName, strlen(ImportName)+1);
+ /* Reload the NT Header */
+ NtHeaders = RtlImageNtHeader(PhysicalBase);
- /* Set Hint to 0 */
- ImportByName->Hint = 0;
+ /* Load the first section */
+ SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
- /* And finally point ThunkData's AddressOfData to that structure */
- RefThunkData.u1.AddressOfData = (ULONG_PTR)ImportByName;
+ /* Fill output parameters */
+ *ImageBasePA = PhysicalBase;
- /* And recursively call ourselves */
- Success = WinLdrpBindImportName(ModuleListHead,
- DataTableEntry->DllBase,
- ImageBase,
- &RefThunkData,
- RefExportDirectory,
- RefExportSize,
- TRUE,
- DirectoryPath);
+ /* Walk through each section and read it (check/fix any possible
+ bad situations, if they arise) */
+ for (i = 0; i < NumberOfSections; i++)
+ {
+ VirtualSize = SectionHeader->Misc.VirtualSize;
+ SizeOfRawData = SectionHeader->SizeOfRawData;
- /* Fill out the ThunkData with data from RefThunkData */
- ThunkData->u1 = RefThunkData.u1;
+ /* Handle a case when VirtualSize equals 0 */
+ if (VirtualSize == 0)
+ VirtualSize = SizeOfRawData;
- /* Return what we got from the recursive call */
- return Success;
+ /* If PointerToRawData is 0, then force its size to be also 0 */
+ if (SectionHeader->PointerToRawData == 0)
+ {
+ SizeOfRawData = 0;
}
else
{
- /* Fail if ExportDirectory is NULL */
- return FALSE;
+ /* Cut the loaded size to the VirtualSize extents */
+ if (SizeOfRawData > VirtualSize)
+ SizeOfRawData = VirtualSize;
}
- }
-
- /* Success! */
- return TRUE;
-}
-
-static BOOLEAN
-WinLdrpLoadAndScanReferencedDll(PLIST_ENTRY ModuleListHead,
- PCCH DirectoryPath,
- PCH ImportName,
- PLDR_DATA_TABLE_ENTRY *DataTableEntry)
-{
- CHAR FullDllName[256];
- BOOLEAN Success;
- PVOID BasePA = NULL;
-
- /* Prepare the full path to the file to be loaded */
- strcpy(FullDllName, DirectoryPath);
- strcat(FullDllName, ImportName);
-
- TRACE("Loading referenced DLL: %s\n", FullDllName);
-
- /* Load the image */
- Success = WinLdrLoadImage(FullDllName, LoaderBootDriver, &BasePA);
- if (!Success)
- {
- ERR("WinLdrLoadImage() failed\n");
- return Success;
- }
-
- /* Allocate DTE for newly loaded DLL */
- Success = WinLdrAllocateDataTableEntry(ModuleListHead,
- ImportName,
- FullDllName,
- BasePA,
- DataTableEntry);
- if (!Success)
- {
- ERR("WinLdrAllocateDataTableEntry() failed\n");
- return Success;
- }
- /* Scan its dependencies too */
- TRACE("WinLdrScanImportDescriptorTable() calling ourselves for %S\n",
- VaToPa((*DataTableEntry)->BaseDllName.Buffer));
- Success = WinLdrScanImportDescriptorTable(ModuleListHead, DirectoryPath,
*DataTableEntry);
- if (!Success)
- {
- ERR("WinLdrScanImportDescriptorTable() failed\n");
- return Success;
- }
+ /* Actually read the section (if its size is not 0) */
+ if (SizeOfRawData != 0)
+ {
+ /* Seek to the correct position */
+ Position.LowPart = SectionHeader->PointerToRawData;
+ Status = ArcSeek(FileId, &Position, SeekAbsolute);
- return TRUE;
-}
+ TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);
-static BOOLEAN
-WinLdrpScanImportAddressTable(IN OUT PLIST_ENTRY ModuleListHead,
- IN PVOID DllBase,
- IN PVOID ImageBase,
- IN PIMAGE_THUNK_DATA ThunkData,
- IN PCSTR DirectoryPath)
-{
- PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL;
- BOOLEAN Success;
- ULONG ExportSize;
+ /* Read this section from the file, size = SizeOfRawData */
+ Status = ArcRead(FileId, (PUCHAR)PhysicalBase +
SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
+ if (Status != ESUCCESS)
+ {
+ ERR("PeLdrLoadImage(): Error reading section from file!\n");
+ break;
+ }
+ }
- TRACE("WinLdrpScanImportAddressTable(): DllBase 0x%X, "
- "ImageBase 0x%X, ThunkData 0x%X\n", DllBase, ImageBase, ThunkData);
+ /* Size of data is less than the virtual size - fill up the remainder with zeroes
*/
+ if (SizeOfRawData < VirtualSize)
+ {
+ TRACE("PeLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData,
VirtualSize);
+ RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress +
(ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
+ }
- /* Obtain the export table from the DLL's base */
- if (DllBase == NULL)
- {
- ERR("Error, DllBase == NULL!\n");
- return FALSE;
- }
- else
- {
- ExportDirectory =
- (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(VaToPa(DllBase),
- TRUE,
- IMAGE_DIRECTORY_ENTRY_EXPORT,
- &ExportSize);
+ SectionHeader++;
}
- TRACE("WinLdrpScanImportAddressTable(): ExportDirectory 0x%X\n",
ExportDirectory);
+ /* We are done with the file - close it */
+ ArcClose(FileId);
- /* If pointer to Export Directory is */
- if (ExportDirectory == NULL)
- {
- ERR("DllBase=%p(%p)\n", DllBase, VaToPa(DllBase));
+ /* If loading failed - return right now */
+ if (Status != ESUCCESS)
return FALSE;
- }
- /* Go through each entry in the thunk table and bind it */
- while (((PIMAGE_THUNK_DATA)VaToPa(ThunkData))->u1.AddressOfData != 0)
+ /* Relocate the image, if it needs it */
+ if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
{
- /* Bind it */
- Success = WinLdrpBindImportName(ModuleListHead,
- DllBase,
- ImageBase,
- ThunkData,
- ExportDirectory,
- ExportSize,
- FALSE,
- DirectoryPath);
-
- /* Move to the next entry */
- ThunkData++;
-
- /* Return error if binding was unsuccessful */
- if (!Success)
- return Success;
+ WARN("Relocating %p -> %p\n",
NtHeaders->OptionalHeader.ImageBase, VirtualBase);
+ return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
+ (ULONG_PTR)VirtualBase -
(ULONG_PTR)PhysicalBase,
+ "FreeLdr",
+ TRUE,
+ TRUE, /* in case of conflict still
return success */
+ FALSE);
}
- /* Return success */
+ TRACE("PeLdrLoadImage() done, PA = %p\n", *ImageBasePA);
return TRUE;
}
diff --git a/boot/freeldr/freeldr/ntldr/winldr.c b/boot/freeldr/freeldr/ntldr/winldr.c
index fd3104060aa..4ad35a21f6a 100644
--- a/boot/freeldr/freeldr/ntldr/winldr.c
+++ b/boot/freeldr/freeldr/ntldr/winldr.c
@@ -258,7 +258,7 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
TRACE("DriverPath: '%s', DllName: '%s', LPB\n", DriverPath,
DllName);
// Check if driver is already loaded
- Success = WinLdrCheckForLoadedDll(LoadOrderListHead, DllName, DriverDTE);
+ Success = PeLdrCheckForLoadedDll(LoadOrderListHead, DllName, DriverDTE);
if (Success)
{
// We've got the pointer to its DTE, just return success
@@ -267,15 +267,15 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
// It's not loaded, we have to load it
RtlStringCbPrintfA(FullPath, sizeof(FullPath), "%s%wZ", BootPath,
FilePath);
- Success = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
+ Success = PeLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
if (!Success)
return FALSE;
// Allocate a DTE for it
- Success = WinLdrAllocateDataTableEntry(LoadOrderListHead, DllName, DllName,
DriverBase, DriverDTE);
+ Success = PeLdrAllocateDataTableEntry(LoadOrderListHead, DllName, DllName,
DriverBase, DriverDTE);
if (!Success)
{
- ERR("WinLdrAllocateDataTableEntry() failed\n");
+ ERR("PeLdrAllocateDataTableEntry() failed\n");
return FALSE;
}
@@ -284,10 +284,10 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
// Look for any dependencies it may have, and load them too
RtlStringCbPrintfA(FullPath, sizeof(FullPath), "%s%s", BootPath,
DriverPath);
- Success = WinLdrScanImportDescriptorTable(LoadOrderListHead, FullPath, *DriverDTE);
+ Success = PeLdrScanImportDescriptorTable(LoadOrderListHead, FullPath, *DriverDTE);
if (!Success)
{
- ERR("WinLdrScanImportDescriptorTable() failed for %s\n", FullPath);
+ ERR("PeLdrScanImportDescriptorTable() failed for %s\n", FullPath);
return FALSE;
}
@@ -451,7 +451,7 @@ LoadModule(
RtlStringCbCopyA(FullFileName, sizeof(FullFileName), Path);
RtlStringCbCatA(FullFileName, sizeof(FullFileName), File);
- Success = WinLdrLoadImage(FullFileName, MemoryType, &BaseAddress);
+ Success = PeLdrLoadImage(FullFileName, MemoryType, &BaseAddress);
if (!Success)
{
TRACE("Loading %s failed\n", File);
@@ -464,11 +464,11 @@ LoadModule(
* the Kernel Debugger Transport DLL, to make the
* PE loader happy.
*/
- Success = WinLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead,
- ImportName,
- FullFileName,
- BaseAddress,
- Dte);
+ Success = PeLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead,
+ ImportName,
+ FullFileName,
+ BaseAddress,
+ Dte);
return Success;
}
@@ -640,11 +640,11 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
}
/* Load all referenced DLLs for Kernel, HAL and Kernel Debugger Transport DLL */
- Success = WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead,
DirPath, *KernelDTE);
- Success &=
WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, HalDTE);
+ Success = PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead,
DirPath, *KernelDTE);
+ Success &= PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead,
DirPath, HalDTE);
if (KdComDTE)
{
- Success &=
WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath,
KdComDTE);
+ Success &=
PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath,
KdComDTE);
}
return Success;