- Rename ModuleListHead to PsLoadedModulesList.

- Start implementing some routines of the Mm SysLdr. Implemented MiSnapThunk and most of MiResolveImageReferences. The SysLdr has a lot of restrictions that the typical Ldr in user-mode doesn't, as well as manages imports and reference counts them, so the code can't be shared with ntdll's Ldr (this is also why real NT doesn't have an Ldr component, and this is in Mm).
- Fix some PE Header types that were wrong in our PSDK.

svn path=/trunk/; revision=25872
This commit is contained in:
Alex Ionescu
2007-02-22 00:01:52 +00:00
parent 6751f1721e
commit 40e1082e3d
13 changed files with 738 additions and 551 deletions
+8
View File
@@ -3813,6 +3813,14 @@ RtlAllocateHeap (
IN ULONG Size
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendStringToString(
PSTRING Destination,
const STRING *Source
);
NTSYSAPI
USHORT
NTAPI
+2
View File
@@ -248,6 +248,8 @@ typedef struct _ADAPTER_OBJECT *PADAPTER_OBJECT;
#define MAXIMUM_SUSPEND_COUNT MAXCHAR
#define MAXIMUM_FILENAME_LENGTH 256
#define FILE_SUPERSEDED 0x00000000
#define FILE_OPENED 0x00000001
#define FILE_CREATED 0x00000002
+9
View File
@@ -118,6 +118,15 @@ typedef struct _LDR_DATA_TABLE_ENTRY
PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
//
// Loaded Imports Reference Counting in Kernel
//
typedef struct _LOAD_IMPORTS
{
SIZE_T Count;
PLDR_DATA_TABLE_ENTRY Entry[1];
} LOAD_IMPORTS, *PLOAD_IMPORTS;
//
// Loader Resource Information
//
+5 -5
View File
@@ -3119,21 +3119,21 @@ typedef struct _IMAGE_IMPORT_BY_NAME {
} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
typedef struct _IMAGE_THUNK_DATA {
union {
PBYTE ForwarderString;
PDWORD Function;
ULONG ForwarderString;
ULONG Function;
DWORD Ordinal;
PIMAGE_IMPORT_BY_NAME AddressOfData;
ULONG AddressOfData;
} u1;
} IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA;
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
_ANONYMOUS_UNION union {
DWORD Characteristics;
PIMAGE_THUNK_DATA OriginalFirstThunk;
ULONG OriginalFirstThunk;
} DUMMYUNIONNAME;
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name;
PIMAGE_THUNK_DATA FirstThunk;
ULONG FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {
DWORD TimeDateStamp;
+2 -2
View File
@@ -952,8 +952,8 @@ QSI_DEF(SystemCallTimeInformation)
/* Class 11 - Module Information */
QSI_DEF(SystemModuleInformation)
{
extern LIST_ENTRY ModuleListHead;
return ExpQueryModuleInformation(&ModuleListHead,
extern LIST_ENTRY PsLoadedModuleList;
return ExpQueryModuleInformation(&PsLoadedModuleList,
NULL,
(PRTL_PROCESS_MODULES)Buffer,
Size,
+1 -1
View File
@@ -384,7 +384,7 @@ extern GENERIC_MAPPING PspJobMapping;
extern POBJECT_TYPE PsJobType;
extern LARGE_INTEGER ShortPsLockDelay;
extern UNICODE_STRING PsNtDllPathName;
extern LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
extern LIST_ENTRY PsLoadedModuleList;
//
// Inlined Functions
+2 -3
View File
@@ -107,13 +107,12 @@ KdbpSymFindModule(IN PVOID Address OPTIONAL,
{
PLIST_ENTRY current_entry;
PLDR_DATA_TABLE_ENTRY current;
extern LIST_ENTRY ModuleListHead;
INT Count = 0;
INT Length;
current_entry = ModuleListHead.Flink;
current_entry = PsLoadedModuleList.Flink;
while (current_entry != &ModuleListHead)
while (current_entry != &PsLoadedModuleList)
{
current = CONTAINING_RECORD(current_entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
+5 -5
View File
@@ -37,15 +37,15 @@ KiRosPrintAddress(PVOID address)
{
PLIST_ENTRY current_entry;
PLDR_DATA_TABLE_ENTRY current;
extern LIST_ENTRY ModuleListHead;
extern LIST_ENTRY PsLoadedModuleList;
ULONG_PTR RelativeAddress;
ULONG i = 0;
do
{
current_entry = ModuleListHead.Flink;
current_entry = PsLoadedModuleList.Flink;
while (current_entry != &ModuleListHead)
while (current_entry != &PsLoadedModuleList)
{
current = CONTAINING_RECORD(current_entry,
LDR_DATA_TABLE_ENTRY,
@@ -267,13 +267,13 @@ KiPcToFileHeader(IN PVOID Eip,
PVOID ImageBase, EipBase = NULL;
PLDR_DATA_TABLE_ENTRY Entry;
PLIST_ENTRY ListHead, NextEntry;
extern LIST_ENTRY ModuleListHead;
extern LIST_ENTRY PsLoadedModuleList;
/* Assume no */
*InKernel = FALSE;
/* Set list pointers and make sure it's valid */
ListHead = &ModuleListHead;
ListHead = &PsLoadedModuleList;
NextEntry = ListHead->Flink;
if (NextEntry)
{
+111 -529
View File
@@ -20,44 +20,21 @@
/* GLOBALS *******************************************************************/
LIST_ENTRY ModuleListHead;
LIST_ENTRY PsLoadedModuleList;
KSPIN_LOCK ModuleListLock;
LDR_DATA_TABLE_ENTRY NtoskrnlModuleObject;
LDR_DATA_TABLE_ENTRY HalModuleObject;
/* FUNCTIONS *****************************************************************/
static PVOID
LdrPEGetExportByName (
PVOID BaseAddress,
PUCHAR SymbolName,
USHORT Hint );
static VOID
LdrpBuildModuleBaseName (
PUNICODE_STRING BaseName,
PUNICODE_STRING FullName )
{
PWCHAR p;
DPRINT("LdrpBuildModuleBaseName()\n");
DPRINT("FullName %wZ\n", FullName);
p = wcsrchr(FullName->Buffer, L'\\');
if (p == NULL)
{
p = FullName->Buffer;
}
else
{
p++;
}
DPRINT("p %S\n", p);
RtlInitUnicodeString(BaseName, p);
}
NTSTATUS
NTAPI
MiResolveImageReferences(IN PVOID ImageBase,
IN PUNICODE_STRING ImageFileDirectory,
IN PUNICODE_STRING NamePrefix OPTIONAL,
OUT PCHAR *MissingApi,
OUT PWCHAR *MissingDriver,
OUT PLOAD_IMPORTS *LoadImports);
static LONG
LdrpCompareModuleNames (
@@ -128,380 +105,128 @@ LdrpCompareModuleNames (
return(0);
}
#ifndef PATH_MAX
#define PATH_MAX 260
#endif
static NTSTATUS
LdrPEGetOrLoadModule (
PWCHAR ModuleName,
PCHAR ImportedName,
PLDR_DATA_TABLE_ENTRY* ImportedModule)
VOID
INIT_FUNCTION
NTAPI
LdrInit1(VOID)
{
UNICODE_STRING DriverName;
UNICODE_STRING NameString;
WCHAR NameBuffer[PATH_MAX];
NTSTATUS Status = STATUS_SUCCESS;
PLDR_DATA_TABLE_ENTRY HalModuleObject, NtoskrnlModuleObject, LdrEntry;
RtlCreateUnicodeStringFromAsciiz (&DriverName, ImportedName);
DPRINT("Import module: %wZ\n", &DriverName);
/* Initialize the module list and spinlock */
InitializeListHead(&PsLoadedModuleList);
KeInitializeSpinLock(&ModuleListLock);
*ImportedModule = LdrGetModuleObject(&DriverName);
if (*ImportedModule == NULL)
{
PWCHAR PathEnd;
ULONG PathLength;
/* Get the NTOSKRNL Entry from the loader */
LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
PathEnd = wcsrchr(ModuleName, L'\\');
if (NULL != PathEnd)
{
PathLength = (PathEnd - ModuleName + 1) * sizeof(WCHAR);
RtlCopyMemory(NameBuffer, ModuleName, PathLength);
RtlCopyMemory(NameBuffer + (PathLength / sizeof(WCHAR)), DriverName.Buffer, DriverName.Length);
NameString.Buffer = NameBuffer;
NameString.MaximumLength = NameString.Length = (USHORT)PathLength + DriverName.Length;
/* Initialize ModuleObject for NTOSKRNL */
NtoskrnlModuleObject = ExAllocatePoolWithTag(PagedPool,
sizeof(LDR_DATA_TABLE_ENTRY),
TAG('M', 'm', 'L', 'd'));
NtoskrnlModuleObject->DllBase = LdrEntry->DllBase;
RtlInitUnicodeString(&NtoskrnlModuleObject->FullDllName, KERNEL_MODULE_NAME);
NtoskrnlModuleObject->BaseDllName = NtoskrnlModuleObject->FullDllName;
NtoskrnlModuleObject->EntryPoint = LdrEntry->EntryPoint;
NtoskrnlModuleObject->SizeOfImage = LdrEntry->SizeOfImage;
/* NULL-terminate */
NameString.MaximumLength += sizeof(WCHAR);
NameBuffer[NameString.Length / sizeof(WCHAR)] = 0;
/* Insert it into the list */
InsertTailList(&PsLoadedModuleList, &NtoskrnlModuleObject->InLoadOrderLinks);
Status = LdrLoadModule(&NameString, ImportedModule);
}
else
{
DPRINT("Module '%wZ' not loaded yet\n", &DriverName);
wcscpy(NameBuffer, L"\\SystemRoot\\system32\\drivers\\");
wcsncat(NameBuffer, DriverName.Buffer, DriverName.Length / sizeof(WCHAR));
RtlInitUnicodeString(&NameString, NameBuffer);
Status = LdrLoadModule(&NameString, ImportedModule);
}
if (!NT_SUCCESS(Status))
{
wcscpy(NameBuffer, L"\\SystemRoot\\system32\\");
wcsncat(NameBuffer, DriverName.Buffer, DriverName.Length / sizeof(WCHAR));
RtlInitUnicodeString(&NameString, NameBuffer);
Status = LdrLoadModule(&NameString, ImportedModule);
if (!NT_SUCCESS(Status))
{
DPRINT1("Unknown import module: %wZ (Status %lx)\n", &DriverName, Status);
}
}
}
RtlFreeUnicodeString(&DriverName);
return Status;
/* Get the HAL Entry from the loader */
LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink->Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
/* Initialize ModuleObject for HAL */
HalModuleObject = ExAllocatePoolWithTag(PagedPool,
sizeof(LDR_DATA_TABLE_ENTRY),
TAG('M', 'm', 'L', 'd'));
HalModuleObject->DllBase = LdrEntry->DllBase;
RtlInitUnicodeString(&HalModuleObject->FullDllName, HAL_MODULE_NAME);
HalModuleObject->BaseDllName = HalModuleObject->FullDllName;
HalModuleObject->EntryPoint = LdrEntry->EntryPoint;
HalModuleObject->SizeOfImage = LdrEntry->SizeOfImage;
/* Insert it into the list */
InsertTailList(&PsLoadedModuleList, &HalModuleObject->InLoadOrderLinks);
/* Hook for KDB on initialization of the loader. */
KDB_LOADERINIT_HOOK(NtoskrnlModuleObject, HalModuleObject);
}
static PVOID
LdrPEFixupForward ( PCHAR ForwardName )
//
// Used for checking if a module is already in the module list.
// Used during loading/unloading drivers.
//
PLDR_DATA_TABLE_ENTRY
NTAPI
LdrGetModuleObject ( PUNICODE_STRING ModuleName )
{
CHAR NameBuffer[128];
UNICODE_STRING ModuleName;
PCHAR p;
PLDR_DATA_TABLE_ENTRY ModuleObject;
PLDR_DATA_TABLE_ENTRY Module;
PLIST_ENTRY Entry;
KIRQL Irql;
DPRINT("LdrPEFixupForward (%s)\n", ForwardName);
DPRINT("LdrGetModuleObject(%wZ) called\n", ModuleName);
strcpy(NameBuffer, ForwardName);
p = strchr(NameBuffer, '.');
if (p == NULL)
KeAcquireSpinLock(&ModuleListLock,&Irql);
Entry = PsLoadedModuleList.Flink;
while (Entry != &PsLoadedModuleList)
{
return NULL;
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
DPRINT("Comparing %wZ and %wZ\n",
&Module->BaseDllName,
ModuleName);
if (!LdrpCompareModuleNames(&Module->BaseDllName, ModuleName))
{
DPRINT("Module %wZ\n", &Module->BaseDllName);
KeReleaseSpinLock(&ModuleListLock, Irql);
return(Module);
}
Entry = Entry->Flink;
}
*p = 0;
KeReleaseSpinLock(&ModuleListLock, Irql);
DPRINT("Driver: %s Function: %s\n", NameBuffer, p+1);
DPRINT("Could not find module '%wZ'\n", ModuleName);
RtlCreateUnicodeStringFromAsciiz(&ModuleName,
NameBuffer);
ModuleObject = LdrGetModuleObject(&ModuleName);
RtlFreeUnicodeString(&ModuleName);
DPRINT("ModuleObject: %p\n", ModuleObject);
if (ModuleObject == NULL)
{
DPRINT("LdrPEFixupForward: failed to find module %s\n", NameBuffer);
return NULL;
}
return LdrPEGetExportByName(ModuleObject->DllBase, (PUCHAR)(p+1), 0xffff);
return(NULL);
}
static PVOID
LdrPEGetExportByOrdinal (
PVOID BaseAddress,
ULONG Ordinal )
{
PIMAGE_EXPORT_DIRECTORY ExportDir;
ULONG ExportDirSize;
PULONG * ExFunctions;
PVOID Function;
ExportDir = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData (
BaseAddress,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportDirSize);
ExFunctions = (PULONG *)RVA(BaseAddress,
ExportDir->AddressOfFunctions);
DPRINT("LdrPEGetExportByOrdinal(Ordinal %d) = %x\n",
Ordinal,
RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base]));
Function = 0 != ExFunctions[Ordinal - ExportDir->Base]
? RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
: NULL;
if (((ULONG_PTR)Function >= (ULONG_PTR)ExportDir) &&
((ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrPEFixupForward((PCHAR)Function);
}
return Function;
}
static PVOID
LdrPEGetExportByName (
PVOID BaseAddress,
PUCHAR SymbolName,
USHORT Hint )
{
PIMAGE_EXPORT_DIRECTORY ExportDir;
PULONG * ExFunctions;
PULONG * ExNames;
USHORT * ExOrdinals;
PVOID ExName;
ULONG Ordinal;
PVOID Function;
LONG minn, maxn, mid, res;
ULONG ExportDirSize;
DPRINT("LdrPEGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint);
ExportDir = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(BaseAddress,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportDirSize);
if (ExportDir == NULL)
{
DPRINT1("LdrPEGetExportByName(): no export directory!\n");
return NULL;
}
/* The symbol names may be missing entirely */
if (ExportDir->AddressOfNames == 0)
{
DPRINT("LdrPEGetExportByName(): symbol names missing entirely\n");
return NULL;
}
/*
* Get header pointers
*/
ExNames = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfNames);
ExOrdinals = (USHORT *)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals);
ExFunctions = (PULONG *)RVA(BaseAddress, ExportDir->AddressOfFunctions);
/*
* Check the hint first
*/
if (Hint < ExportDir->NumberOfNames)
{
ExName = RVA(BaseAddress, ExNames[Hint]);
if (strcmp(ExName, (PCHAR)SymbolName) == 0)
{
Ordinal = ExOrdinals[Hint];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
(ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrPEFixupForward((PCHAR)Function);
if (Function == NULL)
{
DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
}
return Function;
}
if (Function != NULL)
{
return Function;
}
}
}
/*
* Binary search
*/
minn = 0;
maxn = ExportDir->NumberOfNames - 1;
while (minn <= maxn)
{
mid = (minn + maxn) / 2;
ExName = RVA(BaseAddress, ExNames[mid]);
res = strcmp(ExName, (PCHAR)SymbolName);
if (res == 0)
{
Ordinal = ExOrdinals[mid];
Function = RVA(BaseAddress, ExFunctions[Ordinal]);
if ((ULONG_PTR)Function >= (ULONG_PTR)ExportDir &&
(ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize)
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrPEFixupForward((PCHAR)Function);
if (Function == NULL)
{
DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
}
return Function;
}
if (Function != NULL)
{
return Function;
}
}
else if (res > 0)
{
maxn = mid - 1;
}
else
{
minn = mid + 1;
}
}
ExName = RVA(BaseAddress, ExNames[mid]);
DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
return (PVOID)NULL;
}
static NTSTATUS
LdrPEProcessImportDirectoryEntry(
PVOID DriverBase,
PLDR_DATA_TABLE_ENTRY ImportedModule,
PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory )
{
PVOID* ImportAddressList;
PULONG FunctionNameList;
ULONG Ordinal;
if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
{
return STATUS_UNSUCCESSFUL;
}
/* Get the import address list. */
ImportAddressList = (PVOID*)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
/* Get the list of functions to import. */
if (ImportModuleDirectory->OriginalFirstThunk != 0)
{
FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->OriginalFirstThunk);
}
else
{
FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
}
/* Walk through function list and fixup addresses. */
while (*FunctionNameList != 0L)
{
if ((*FunctionNameList) & 0x80000000)
{
Ordinal = (*FunctionNameList) & 0x7fffffff;
*ImportAddressList = LdrPEGetExportByOrdinal(ImportedModule->DllBase, Ordinal);
if ((*ImportAddressList) == NULL)
{
DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
return STATUS_UNSUCCESSFUL;
}
}
else
{
IMAGE_IMPORT_BY_NAME *pe_name;
pe_name = RVA(DriverBase, *FunctionNameList);
*ImportAddressList = LdrPEGetExportByName(ImportedModule->DllBase, pe_name->Name, pe_name->Hint);
if ((*ImportAddressList) == NULL)
{
DPRINT1("Failed to import %s from %wZ\n", pe_name->Name, &ImportedModule->FullDllName);
return STATUS_UNSUCCESSFUL;
}
}
ImportAddressList++;
FunctionNameList++;
}
return STATUS_SUCCESS;
}
typedef struct _LOAD_IMPORTS
{
SIZE_T Count;
PLDR_DATA_TABLE_ENTRY Entry[1];
} LOAD_IMPORTS, *PLOAD_IMPORTS;
//
// Used when unloading drivers
//
NTSTATUS
NTAPI
MiResolveImageReferences(IN PVOID ImageBase,
IN PUNICODE_STRING ImageFileDirectory,
IN PUNICODE_STRING NamePrefix OPTIONAL,
OUT PCHAR *MissingApi,
OUT PWCHAR *MissingDriver,
OUT PLOAD_IMPORTS *LoadImports)
LdrUnloadModule ( PLDR_DATA_TABLE_ENTRY ModuleObject )
{
/* We don't do anything for now */
return STATUS_SUCCESS;
KIRQL Irql;
/* Remove the module from the module list */
KeAcquireSpinLock(&ModuleListLock,&Irql);
RemoveEntryList(&ModuleObject->InLoadOrderLinks);
KeReleaseSpinLock(&ModuleListLock, Irql);
/* Hook for KDB on unloading a driver. */
KDB_UNLOADDRIVER_HOOK(ModuleObject);
/* Free module section */
// MmFreeSection(ModuleObject->DllBase);
ExFreePool(ModuleObject->FullDllName.Buffer);
ExFreePool(ModuleObject);
return(STATUS_SUCCESS);
}
static NTSTATUS
LdrPEFixupImports (IN PVOID DllBase,
IN PWCHAR DllName)
{
PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
PCHAR ImportedName;
PLDR_DATA_TABLE_ENTRY ImportedModule;
NTSTATUS Status;
ULONG Size;
/* Process each import module */
ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
RtlImageDirectoryEntryToData(DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
&Size);
DPRINT("Processeing import directory at %p\n", ImportModuleDirectory);
while (ImportModuleDirectory->Name)
{
/* Check to make sure that import lib is kernel */
ImportedName = (PCHAR) DllBase + ImportModuleDirectory->Name;
Status = LdrPEGetOrLoadModule(DllName, ImportedName, &ImportedModule);
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = LdrPEProcessImportDirectoryEntry(DllBase, ImportedModule, ImportModuleDirectory);
if (!NT_SUCCESS(Status))
{
while (TRUE);
return Status;
}
ImportModuleDirectory++;
}
return STATUS_SUCCESS;
}
static NTSTATUS
LdrPEProcessModule(
PVOID ModuleLoadBase,
PUNICODE_STRING FileName,
PLDR_DATA_TABLE_ENTRY *ModuleObject )
//
// Used for images already loaded (boot drivers)
//
NTSTATUS
LdrProcessModule(PVOID ModuleLoadBase,
PUNICODE_STRING FileName,
PLDR_DATA_TABLE_ENTRY *ModuleObject)
{
unsigned int DriverSize, Idx;
ULONG CurrentSize;
@@ -641,7 +366,7 @@ LdrPEProcessModule(
BaseLength *= sizeof(WCHAR);
/* Setup the string */
BaseName.Length = BaseLength;
BaseName.Length = (USHORT)BaseLength;
BaseName.Buffer = p;
}
else
@@ -698,7 +423,7 @@ LdrPEProcessModule(
NtHeader->OptionalHeader.AddressOfEntryPoint);
LdrEntry->SizeOfImage = DriverSize;
LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
LdrEntry->SectionPointer = NULL; // FIXME
LdrEntry->SectionPointer = LdrEntry;
/* Now write the DLL name */
LdrEntry->BaseDllName.Buffer = NameBuffer;
@@ -737,7 +462,7 @@ LdrPEProcessModule(
/* Insert the entry */
KeAcquireSpinLock(&ModuleListLock, &Irql);
InsertTailList(&ModuleListHead, &LdrEntry->InLoadOrderLinks);
InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks);
KeReleaseSpinLock(&ModuleListLock, Irql);
/* Resolve imports */
@@ -748,10 +473,6 @@ LdrPEProcessModule(
&MissingApiName,
&MissingDriverName,
&LoadedImports);
/* Resolve imports */
Status = LdrPEFixupImports(LdrEntry->DllBase,
LdrEntry->FullDllName.Buffer);
if (!NT_SUCCESS(Status))
{
/* Fail */
@@ -765,145 +486,6 @@ LdrPEProcessModule(
return STATUS_SUCCESS;
}
VOID
INIT_FUNCTION
NTAPI
LdrInit1(VOID)
{
PLDR_DATA_TABLE_ENTRY HalModuleObject, NtoskrnlModuleObject, LdrEntry;
/* Initialize the module list and spinlock */
InitializeListHead(&ModuleListHead);
KeInitializeSpinLock(&ModuleListLock);
/* Get the NTOSKRNL Entry from the loader */
LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
/* Initialize ModuleObject for NTOSKRNL */
NtoskrnlModuleObject = ExAllocatePoolWithTag(PagedPool,
sizeof(LDR_DATA_TABLE_ENTRY),
TAG('M', 'm', 'L', 'd'));
NtoskrnlModuleObject->DllBase = LdrEntry->DllBase;
RtlInitUnicodeString(&NtoskrnlModuleObject->FullDllName, KERNEL_MODULE_NAME);
LdrpBuildModuleBaseName(&NtoskrnlModuleObject->BaseDllName, &NtoskrnlModuleObject->FullDllName);
NtoskrnlModuleObject->EntryPoint = LdrEntry->EntryPoint;
NtoskrnlModuleObject->SizeOfImage = LdrEntry->SizeOfImage;
/* Insert it into the list */
InsertTailList(&ModuleListHead, &NtoskrnlModuleObject->InLoadOrderLinks);
/* Get the HAL Entry from the loader */
LdrEntry = CONTAINING_RECORD(KeLoaderBlock->LoadOrderListHead.Flink->Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
/* Initialize ModuleObject for HAL */
HalModuleObject = ExAllocatePoolWithTag(PagedPool,
sizeof(LDR_DATA_TABLE_ENTRY),
TAG('M', 'm', 'L', 'd'));
HalModuleObject->DllBase = LdrEntry->DllBase;
RtlInitUnicodeString(&HalModuleObject->FullDllName, HAL_MODULE_NAME);
LdrpBuildModuleBaseName(&HalModuleObject->BaseDllName, &HalModuleObject->FullDllName);
HalModuleObject->EntryPoint = LdrEntry->EntryPoint;
HalModuleObject->SizeOfImage = LdrEntry->SizeOfImage;
/* Insert it into the list */
InsertTailList(&ModuleListHead, &HalModuleObject->InLoadOrderLinks);
/* Hook for KDB on initialization of the loader. */
KDB_LOADERINIT_HOOK(NtoskrnlModuleObject, HalModuleObject);
}
//
// Used for checking if a module is already in the module list.
// Used during loading/unloading drivers.
//
PLDR_DATA_TABLE_ENTRY
NTAPI
LdrGetModuleObject ( PUNICODE_STRING ModuleName )
{
PLDR_DATA_TABLE_ENTRY Module;
PLIST_ENTRY Entry;
KIRQL Irql;
DPRINT("LdrGetModuleObject(%wZ) called\n", ModuleName);
KeAcquireSpinLock(&ModuleListLock,&Irql);
Entry = ModuleListHead.Flink;
while (Entry != &ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
DPRINT("Comparing %wZ and %wZ\n",
&Module->BaseDllName,
ModuleName);
if (!LdrpCompareModuleNames(&Module->BaseDllName, ModuleName))
{
DPRINT("Module %wZ\n", &Module->BaseDllName);
KeReleaseSpinLock(&ModuleListLock, Irql);
return(Module);
}
Entry = Entry->Flink;
}
KeReleaseSpinLock(&ModuleListLock, Irql);
DPRINT("Could not find module '%wZ'\n", ModuleName);
return(NULL);
}
//
// Used when unloading drivers
//
NTSTATUS
NTAPI
LdrUnloadModule ( PLDR_DATA_TABLE_ENTRY ModuleObject )
{
KIRQL Irql;
/* Remove the module from the module list */
KeAcquireSpinLock(&ModuleListLock,&Irql);
RemoveEntryList(&ModuleObject->InLoadOrderLinks);
KeReleaseSpinLock(&ModuleListLock, Irql);
/* Hook for KDB on unloading a driver. */
KDB_UNLOADDRIVER_HOOK(ModuleObject);
/* Free module section */
// MmFreeSection(ModuleObject->DllBase);
ExFreePool(ModuleObject->FullDllName.Buffer);
ExFreePool(ModuleObject);
return(STATUS_SUCCESS);
}
//
// Used for images already loaded (boot drivers)
//
NTSTATUS
LdrProcessModule(
PVOID ModuleLoadBase,
PUNICODE_STRING ModuleName,
PLDR_DATA_TABLE_ENTRY *ModuleObject )
{
PIMAGE_DOS_HEADER PEDosHeader;
/* If MZ header exists */
PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
if (PEDosHeader->e_magic == IMAGE_DOS_SIGNATURE && PEDosHeader->e_lfanew != 0L)
{
return LdrPEProcessModule(ModuleLoadBase,
ModuleName,
ModuleObject);
}
DPRINT("Module wasn't PE\n");
return STATUS_UNSUCCESSFUL;
}
//
// Used by NtLoadDriver/IoMgr
//
+3 -3
View File
@@ -409,7 +409,7 @@ MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)
ANSI_STRING AnsiRoutineName;
NTSTATUS Status;
PLIST_ENTRY NextEntry;
extern LIST_ENTRY ModuleListHead;
extern LIST_ENTRY PsLoadedModuleList;
PLDR_DATA_TABLE_ENTRY LdrEntry;
BOOLEAN Found = FALSE;
UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
@@ -422,8 +422,8 @@ MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)
if (!NT_SUCCESS(Status)) return NULL;
/* Loop the loaded module list */
NextEntry = ModuleListHead.Flink;
while (NextEntry != &ModuleListHead)
NextEntry = PsLoadedModuleList.Flink;
while (NextEntry != &PsLoadedModuleList)
{
/* Get the entry */
LdrEntry = CONTAINING_RECORD(NextEntry,
+586
View File
@@ -0,0 +1,586 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/mm/sysldr.c
* PURPOSE: Contains the Kernel Loader (SYSLDR) for loading PE files.
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
MiSnapThunk(IN PVOID DllBase,
IN PVOID ImageBase,
IN PIMAGE_THUNK_DATA Name,
IN PIMAGE_THUNK_DATA Address,
IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
IN ULONG ExportSize,
IN BOOLEAN SnapForwarder,
OUT PCHAR *MissingApi)
{
BOOLEAN IsOrdinal;
USHORT Ordinal;
PULONG NameTable;
PUSHORT OrdinalTable;
PIMAGE_IMPORT_BY_NAME NameImport;
USHORT Hint;
ULONG Low = 0, Mid = 0, High;
LONG Ret;
NTSTATUS Status;
PCHAR MissingForwarder;
CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];
PULONG ExportTable;
ANSI_STRING DllName;
UNICODE_STRING ForwarderName;
PLIST_ENTRY NextEntry;
PLDR_DATA_TABLE_ENTRY LdrEntry;
ULONG ForwardExportSize;
PIMAGE_EXPORT_DIRECTORY ForwardExportDirectory;
PIMAGE_IMPORT_BY_NAME ForwardName;
ULONG ForwardLength;
IMAGE_THUNK_DATA ForwardThunk;
PAGED_CODE();
/* Check if this is an ordinal */
IsOrdinal = IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal);
if ((IsOrdinal) && !(SnapForwarder))
{
/* Get the ordinal number and set it as missing */
Ordinal = (USHORT)(IMAGE_ORDINAL(Name->u1.Ordinal) -
ExportDirectory->Base);
*MissingApi = (PCHAR)(ULONG_PTR)Ordinal;
}
else
{
/* Get the VA if we don't have to snap */
if (!SnapForwarder) Name->u1.AddressOfData += (ULONG_PTR)ImageBase;
NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData;
/* Copy the procedure name */
strncpy(*MissingApi,
(PCHAR)&NameImport->Name[0],
MAXIMUM_FILENAME_LENGTH - 1);
/* Setup name tables */
DPRINT("Import name: %s\n", NameImport->Name);
NameTable = (PULONG)((ULONG_PTR)DllBase +
ExportDirectory->AddressOfNames);
OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
ExportDirectory->AddressOfNameOrdinals);
/* Get the hint and check if it's valid */
Hint = NameImport->Hint;
if ((Hint < ExportDirectory->NumberOfNames) &&
!(strcmp(NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
{
/* We have a match, get the ordinal number from here */
Ordinal = OrdinalTable[Hint];
}
else
{
/* Do a binary search */
High = ExportDirectory->NumberOfNames - 1;
while (High >= Low)
{
/* Get new middle value */
Mid = (Low + High) >> 1;
/* Compare name */
Ret = strcmp(NameImport->Name, (PCHAR)DllBase + NameTable[Mid]);
if (Ret < 0)
{
/* Update high */
High = Mid - 1;
}
else if (Ret > 0)
{
/* Update low */
Low = Mid + 1;
}
else
{
/* We got it */
break;
}
}
/* Check if we couldn't find it */
if (High < Low) return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
/* Otherwise, this is the ordinal */
Ordinal = OrdinalTable[Mid];
}
}
/* Check if the ordinal is invalid */
if (Ordinal >= ExportDirectory->NumberOfFunctions)
{
/* Fail */
Status = STATUS_DRIVER_ORDINAL_NOT_FOUND;
}
else
{
/* In case the forwarder is missing */
MissingForwarder = NameBuffer;
/* Resolve the address and write it */
ExportTable = (PULONG)((ULONG_PTR)DllBase +
ExportDirectory->AddressOfFunctions);
Address->u1.Function = (ULONG_PTR)DllBase + ExportTable[Ordinal];
/* Assume success from now on */
Status = STATUS_SUCCESS;
/* Check if the function is actually a forwarder */
if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
(Address->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
{
/* Now assume failure in case the forwarder doesn't exist */
Status = STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
/* Build the forwarder name */
DllName.Buffer = (PCHAR)Address->u1.Function;
DllName.Length = strchr(DllName.Buffer, '.') -
DllName.Buffer +
sizeof(ANSI_NULL);
DllName.MaximumLength = DllName.Length;
/* Convert it */
if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ForwarderName,
&DllName,
TRUE)))
{
/* We failed, just return an error */
return Status;
}
/* Loop the module list */
NextEntry = PsLoadedModuleList.Flink;
while (NextEntry != &PsLoadedModuleList)
{
/* Get the loader entry */
LdrEntry = CONTAINING_RECORD(NextEntry,
LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
/* Check if it matches */
if (RtlPrefixString((PSTRING)&ForwarderName,
(PSTRING)&LdrEntry->BaseDllName,
TRUE))
{
/* Get the forwarder export directory */
ForwardExportDirectory =
RtlImageDirectoryEntryToData(LdrEntry->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ForwardExportSize);
if (!ForwardExportDirectory) break;
/* Allocate a name entry */
ForwardLength = strlen(DllName.Buffer + DllName.Length) +
sizeof(ANSI_NULL);
ForwardName = ExAllocatePoolWithTag(PagedPool,
sizeof(*ForwardName) +
ForwardLength,
TAG_LDR_WSTR);
if (!ForwardName) break;
/* Copy the data */
RtlCopyMemory(&ForwardName->Name[0],
DllName.Buffer + DllName.Length,
ForwardLength);
ForwardName->Hint = 0;
/* Set the new address */
*(PULONG)&ForwardThunk.u1.AddressOfData = (ULONG)ForwardName;
/* Snap the forwarder */
Status = MiSnapThunk(LdrEntry->DllBase,
ImageBase,
&ForwardThunk,
&ForwardThunk,
ForwardExportDirectory,
ForwardExportSize,
TRUE,
&MissingForwarder);
/* Free the forwarder name and set the thunk */
ExFreePool(ForwardName);
Address->u1 = ForwardThunk.u1;
break;
}
/* Go to the next entry */
NextEntry = NextEntry->Flink;
}
/* Free the name */
RtlFreeUnicodeString(&ForwarderName);
}
}
/* Return status */
return Status;
}
NTSTATUS
NTAPI
MiResolveImageReferences(IN PVOID ImageBase,
IN PUNICODE_STRING ImageFileDirectory,
IN PUNICODE_STRING NamePrefix OPTIONAL,
OUT PCHAR *MissingApi,
OUT PWCHAR *MissingDriver,
OUT PLOAD_IMPORTS *LoadImports)
{
PCHAR MissingApiBuffer = *MissingApi, ImportName;
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;
ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;
PLOAD_IMPORTS LoadedImports;
ULONG GdiLink, NormalLink, i;
BOOLEAN ReferenceNeeded, Loaded;
ANSI_STRING TempString;
UNICODE_STRING NameString, DllName;
PLDR_DATA_TABLE_ENTRY LdrEntry = NULL, DllEntry, ImportEntry = NULL;
PVOID ImportBase, DllBase;
PLIST_ENTRY NextEntry;
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
NTSTATUS Status;
PIMAGE_THUNK_DATA OrigThunk, FirstThunk;
PAGED_CODE();
DPRINT("%s - ImageBase: %p. ImageFileDirectory: %wZ\n",
__FUNCTION__, ImageBase, ImageFileDirectory);
/* Assume no imports */
*LoadImports = (PVOID)-2;
/* Get the import descriptor */
ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
&ImportSize);
if (!ImportDescriptor) return STATUS_SUCCESS;
/* Loop all imports to count them */
for (CurrentImport = ImportDescriptor;
(CurrentImport->Name) && (CurrentImport->OriginalFirstThunk);
CurrentImport++)
{
/* One more */
ImportCount++;
}
/* Make sure we have non-zero imports */
if (ImportCount)
{
/* Calculate and allocate the list we'll need */
LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
LoadedImports = ExAllocatePoolWithTag(PagedPool,
LoadedImportsSize,
TAG_LDR_WSTR);
if (LoadedImports)
{
/* Zero it and set the count */
RtlZeroMemory(LoadedImports, LoadedImportsSize);
LoadedImports->Count = ImportCount;
}
}
else
{
/* No table */
LoadedImports = NULL;
}
/* Reset the import count and loop descriptors again */
ImportCount = GdiLink = NormalLink = 0;
while ((ImportDescriptor->Name) && (ImportDescriptor->OriginalFirstThunk))
{
/* Get the name */
ImportName = (PCHAR)((ULONG_PTR)ImageBase + ImportDescriptor->Name);
/* Check if this is a GDI driver */
GdiLink = GdiLink |
!(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1));
/* We can also allow dxapi */
NormalLink = NormalLink |
((_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) &&
(_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)));
/* Check if this is a valid GDI driver */
if ((GdiLink) && (NormalLink))
{
/* It's not, it's importing stuff it shouldn't be! */
DPRINT1("Invalid driver!\n");
//MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePool(LoadedImports);
return STATUS_PROCEDURE_NOT_FOUND;
}
/* Check if this is a "core" import, which doesn't get referenced */
if (!(_strnicmp(ImportName, "ntoskrnl", sizeof("ntoskrnl") - 1)) ||
!(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) ||
!(_strnicmp(ImportName, "hal", sizeof("hal") - 1)))
{
/* Don't reference this */
ReferenceNeeded = FALSE;
}
else
{
/* Reference these modules */
ReferenceNeeded = TRUE;
}
/* Now setup a unicode string for the import */
RtlInitAnsiString(&TempString, ImportName);
Status = RtlAnsiStringToUnicodeString(&NameString, &TempString, TRUE);
if (!NT_SUCCESS(Status))
{
/* Failed */
//MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePool(LoadedImports);
return Status;
}
/* We don't support name prefixes yet */
if (NamePrefix) DPRINT1("Name Prefix not yet supported!\n");
/* Remember that we haven't loaded the import at this point */
CheckDllState:
Loaded = FALSE;
ImportBase = NULL;
/* Loop the driver list */
NextEntry = PsLoadedModuleList.Flink;
while (NextEntry != &PsLoadedModuleList)
{
/* Get the loader entry and compare the name */
LdrEntry = CONTAINING_RECORD(NextEntry,
LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
if (RtlEqualUnicodeString(&NameString,
&LdrEntry->BaseDllName,
TRUE))
{
/* Get the base address */
ImportBase = LdrEntry->DllBase;
/* Check if we haven't loaded yet, and we need references */
if (!(Loaded) && (ReferenceNeeded))
{
/* Make sure we're not already loading */
if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
{
/* Increase the load count */
LdrEntry->LoadCount++;
}
}
/* Done, break out */
break;
}
/* Go to the next entry */
NextEntry = NextEntry->Flink;
}
/* Check if we haven't loaded the import yet */
if (!ImportBase)
{
/* Setup the import DLL name */
DllName.MaximumLength = NameString.Length +
ImageFileDirectory->Length +
sizeof(UNICODE_NULL);
DllName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
DllName.MaximumLength,
TAG_LDR_WSTR);
if (DllName.Buffer)
{
/* Setup the base length and copy it */
DllName.Length = ImageFileDirectory->Length;
RtlCopyMemory(DllName.Buffer,
ImageFileDirectory->Buffer,
ImageFileDirectory->Length);
/* Now add the import name and null-terminate it */
RtlAppendStringToString((PSTRING)&DllName,
(PSTRING)&NameString);
DllName.Buffer[(DllName.MaximumLength - 1) / 2] = UNICODE_NULL;
/* Load the image */
Status = LdrLoadModule(&DllName, &DllEntry);
if (NT_SUCCESS(Status))
{
/* We can free the DLL Name */
ExFreePool(DllName.Buffer);
}
else
{
/* Fill out the information for the error */
DPRINT1("Failed to import: %S\n", DllName.Buffer);
*MissingDriver = DllName.Buffer;
*(PULONG)MissingDriver |= 1;
*MissingApi = NULL;
}
}
else
{
/* We're out of resources */
Status = STATUS_INSUFFICIENT_RESOURCES;
}
/* Check if we're OK until now */
if (NT_SUCCESS(Status))
{
/* We're now loaded */
Loaded = TRUE;
/* Get the base address and other information */
DllBase = DllEntry->DllBase;
ASSERT(DllBase = DllEntry->DllBase);
/* Call the initialization routines */
#if 0
Status = MmCallDllInitialize(DllEntry, &PsLoadedModuleList);
if (!NT_SUCCESS(Status))
{
/* We failed, unload the image */
MmUnloadSystemImage(DllEntry);
while (TRUE);
Loaded = FALSE;
}
#endif
}
/* Check if we failed by here */
if (!NT_SUCCESS(Status))
{
/* Cleanup and return */
DPRINT1("Failed loading import\n");
RtlFreeUnicodeString(&NameString);
//MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePool(LoadedImports);
return Status;
}
/* Loop again to make sure that everything is OK */
goto CheckDllState;
}
/* Check if we're support to reference this import */
if ((ReferenceNeeded) && (LoadedImports))
{
/* Make sure we're not already loading */
if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
{
/* Add the entry */
LoadedImports->Entry[ImportCount] = LdrEntry;
ImportCount++;
}
}
/* Free the import name */
RtlFreeUnicodeString(&NameString);
/* Set the missing driver name and get the export directory */
*MissingDriver = LdrEntry->BaseDllName.Buffer;
ExportDirectory = RtlImageDirectoryEntryToData(ImportBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportSize);
if (!ExportDirectory)
{
/* Cleanup and return */
DPRINT1("Invalid driver: %wZ\n", &LdrEntry->BaseDllName);
//MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePool(LoadedImports);
return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
}
/* Make sure we have an IAT */
if (ImportDescriptor->OriginalFirstThunk)
{
/* Get the first thunks */
OrigThunk = (PVOID)((ULONG_PTR)ImageBase +
ImportDescriptor->OriginalFirstThunk);
FirstThunk = (PVOID)((ULONG_PTR)ImageBase +
ImportDescriptor->FirstThunk);
/* Loop the IAT */
while (OrigThunk->u1.AddressOfData)
{
/* Snap thunk */
Status = MiSnapThunk(ImportBase,
ImageBase,
OrigThunk++,
FirstThunk++,
ExportDirectory,
ExportSize,
FALSE,
MissingApi);
if (!NT_SUCCESS(Status))
{
/* Cleanup and return */
//MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePool(LoadedImports);
return Status;
}
/* Reset the buffer */
*MissingApi = MissingApiBuffer;
}
}
/* Go to the next import */
ImportDescriptor++;
}
/* Check if we have an import list */
if (LoadedImports)
{
/* Reset the count again, and loop entries*/
ImportCount = 0;
for (i = 0; i < LoadedImports->Count; i++)
{
if (LoadedImports->Entry[i])
{
/* Got an entry, OR it with 1 in case it's the single entry */
ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] | 1);
ImportCount++;
}
}
/* Check if we had no imports */
if (!ImportCount)
{
/* Free the list and set it to no imports */
ExFreePool(LoadedImports);
LoadedImports = (PVOID)-2;
}
else if (ImportCount == 1)
{
/* Just one entry, we can free the table and only use our entry */
ExFreePool(LoadedImports);
LoadedImports = (PLOAD_IMPORTS)ImportEntry;
}
else if (ImportCount != LoadedImports->Count)
{
/* FIXME: Can this happen? */
DPRINT1("Unhandled scenario\n");
while (TRUE);
}
/* Return the list */
*LoadImports = LoadedImports;
}
/* Return success */
return STATUS_SUCCESS;
}
+3 -3
View File
@@ -19,7 +19,7 @@ LIST_ENTRY MiVerifierDriverAddedThunkListHead;
KMUTANT MmSystemLoadLock;
ULONG MiActiveVerifierThunks;
extern LIST_ENTRY ModuleListHead;
extern LIST_ENTRY PsLoadedModuleList;
/* PRIVATE FUNCTIONS *********************************************************/
@@ -32,7 +32,7 @@ MiLookupDataTableEntry(IN PVOID Address)
PAGED_CODE();
/* Loop entries */
NextEntry = ModuleListHead.Flink;
NextEntry = PsLoadedModuleList.Flink;
do
{
/* Get the loader entry */
@@ -51,7 +51,7 @@ MiLookupDataTableEntry(IN PVOID Address)
/* Move on */
NextEntry = NextEntry->Flink;
} while(NextEntry != &ModuleListHead);
} while(NextEntry != &PsLoadedModuleList);
/* Return the entry */
return FoundEntry;
+1
View File
@@ -275,6 +275,7 @@
<file>region.c</file>
<file>rmap.c</file>
<file>section.c</file>
<file>sysldr.c</file>
<file>verifier.c</file>
<file>virtual.c</file>
<file>wset.c</file>