#endif /* __GNUC__ */
#endif
+#if 0
+#undef ps
+#define ps(args...) DPRINT1(args)
+#endif
+
#define NDEBUG
#include <internal/debug.h>
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, LdrInit1)
+#pragma alloc_text(INIT, LdrInitModuleManagement)
+#pragma alloc_text(INIT, LdrSafePEProcessModule)
+#endif
+
/* GLOBALS *******************************************************************/
LIST_ENTRY ModuleListHead;
KSPIN_LOCK ModuleListLock;
-MODULE_OBJECT NtoskrnlModuleObject;
-MODULE_OBJECT HalModuleObject;
+LDR_DATA_TABLE_ENTRY NtoskrnlModuleObject;
+LDR_DATA_TABLE_ENTRY HalModuleObject;
-LIST_ENTRY ModuleTextListHead;
-STATIC MODULE_TEXT_SECTION NtoskrnlTextSection;
-STATIC MODULE_TEXT_SECTION LdrHalTextSection;
ULONG_PTR LdrHalBase;
-#define TAG_DRIVER_MEM TAG('D', 'R', 'V', 'M') /* drvm */
-#define TAG_MODULE_OBJECT TAG('k', 'l', 'm', 'o') /* klmo - kernel ldr module object */
-#define TAG_LDR_WSTR TAG('k', 'l', 'w', 's') /* klws - kernel ldr wide string */
-#define TAG_MODULE_TEXT_SECTION TAG('k', 'l', 'm', 't') /* klmt - kernel ldr module text */
-
-#ifndef HIWORD
-#define HIWORD(X) ((WORD) (((DWORD) (X) >> 16) & 0xFFFF))
-#endif
-#ifndef LOWORD
-#define LOWORD(X) ((WORD) (X))
-#endif
-
/* FORWARD DECLARATIONS ******************************************************/
NTSTATUS
LdrProcessModule (
PVOID ModuleLoadBase,
PUNICODE_STRING ModuleName,
- PMODULE_OBJECT *ModuleObject );
+ PLDR_DATA_TABLE_ENTRY *ModuleObject );
static VOID
LdrpBuildModuleBaseName (
LdrPEProcessModule (
PVOID ModuleLoadBase,
PUNICODE_STRING FileName,
- PMODULE_OBJECT *ModuleObject );
+ PLDR_DATA_TABLE_ENTRY *ModuleObject );
static PVOID
LdrPEGetExportByName (
ULONG DriverSize );
static NTSTATUS
-LdrPEFixupImports ( PMODULE_OBJECT Module );
+LdrPEFixupImports ( PLDR_DATA_TABLE_ENTRY Module );
/* FUNCTIONS *****************************************************************/
VOID
+NTAPI
LdrInitDebug ( PLOADER_MODULE Module, PWCH Name )
{
- PLIST_ENTRY current_entry;
- MODULE_TEXT_SECTION* current;
-
- current_entry = ModuleTextListHead.Flink;
- while (current_entry != &ModuleTextListHead)
- {
- current =
- CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry);
- if (wcscmp(current->Name, Name) == 0)
- {
- break;
- }
- current_entry = current_entry->Flink;
- }
-
- if (current_entry == &ModuleTextListHead)
- {
- return;
- }
}
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
LdrInit1 ( VOID )
{
- PIMAGE_NT_HEADERS NtHeader;
- PIMAGE_SECTION_HEADER SectionList;
-
- InitializeListHead(&ModuleTextListHead);
-
- /* Setup ntoskrnl.exe text section */
- /*
- * This isn't the base of the text segment, but the start of the
- * full image (in memory)
- * Also, the Length field isn't set to the length of the segment,
- * but is more like the offset, from the image base, to the end
- * of the segment.
- */
- NtHeader = RtlImageNtHeader((PVOID)KERNEL_BASE);
- SectionList = IMAGE_FIRST_SECTION(NtHeader);
- NtoskrnlTextSection.Base = KERNEL_BASE;
- NtoskrnlTextSection.Length = SectionList[0].Misc.VirtualSize
- + SectionList[0].VirtualAddress;
- NtoskrnlTextSection.Name = KERNEL_MODULE_NAME;
- NtoskrnlTextSection.OptionalHeader = OPTHDROFFSET(KERNEL_BASE);
- InsertTailList(&ModuleTextListHead, &NtoskrnlTextSection.ListEntry);
-
- /* Setup hal.dll text section */
- /* Same comment as above applies */
- NtHeader = RtlImageNtHeader((PVOID)LdrHalBase);
- SectionList = IMAGE_FIRST_SECTION(NtHeader);
- LdrHalTextSection.Base = LdrHalBase;
- LdrHalTextSection.Length = SectionList[0].Misc.VirtualSize
- + SectionList[0].VirtualAddress;
- LdrHalTextSection.Name = HAL_MODULE_NAME;
- LdrHalTextSection.OptionalHeader = OPTHDROFFSET(LdrHalBase);
- InsertTailList(&ModuleTextListHead, &LdrHalTextSection.ListEntry);
-
/* Hook for KDB on initialization of the loader. */
- KDB_LOADERINIT_HOOK(&NtoskrnlTextSection, &LdrHalTextSection);
+ KDB_LOADERINIT_HOOK(&NtoskrnlModuleObject, &HalModuleObject);
}
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
LdrInitModuleManagement ( VOID )
{
PIMAGE_NT_HEADERS NtHeader;
KeInitializeSpinLock(&ModuleListLock);
/* Initialize ModuleObject for NTOSKRNL */
- RtlZeroMemory(&NtoskrnlModuleObject, sizeof(MODULE_OBJECT));
- NtoskrnlModuleObject.Base = (PVOID) KERNEL_BASE;
- NtoskrnlModuleObject.Flags = MODULE_FLAG_PE;
- RtlInitUnicodeString(&NtoskrnlModuleObject.FullName, KERNEL_MODULE_NAME);
- LdrpBuildModuleBaseName(&NtoskrnlModuleObject.BaseName, &NtoskrnlModuleObject.FullName);
+ RtlZeroMemory(&NtoskrnlModuleObject, sizeof(LDR_DATA_TABLE_ENTRY));
+ NtoskrnlModuleObject.DllBase = (PVOID) KERNEL_BASE;
+ RtlInitUnicodeString(&NtoskrnlModuleObject.FullDllName, KERNEL_MODULE_NAME);
+ LdrpBuildModuleBaseName(&NtoskrnlModuleObject.BaseDllName, &NtoskrnlModuleObject.FullDllName);
NtHeader = RtlImageNtHeader((PVOID)KERNEL_BASE);
- NtoskrnlModuleObject.Image.PE.FileHeader = &NtHeader->FileHeader;
- NtoskrnlModuleObject.Image.PE.OptionalHeader = &NtHeader->OptionalHeader;
- NtoskrnlModuleObject.Image.PE.SectionList = IMAGE_FIRST_SECTION(NtHeader);
- NtoskrnlModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) NtoskrnlModuleObject.Base + NtHeader->OptionalHeader.AddressOfEntryPoint);
+ NtoskrnlModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) NtoskrnlModuleObject.DllBase + NtHeader->OptionalHeader.AddressOfEntryPoint);
DPRINT("ModuleObject:%08x entrypoint at %x\n", &NtoskrnlModuleObject, NtoskrnlModuleObject.EntryPoint);
- NtoskrnlModuleObject.Length = NtoskrnlModuleObject.Image.PE.OptionalHeader->SizeOfImage;
- NtoskrnlModuleObject.TextSection = &NtoskrnlTextSection;
+ NtoskrnlModuleObject.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
- InsertTailList(&ModuleListHead,
- &NtoskrnlModuleObject.ListEntry);
+ InsertTailList(&ModuleListHead, &NtoskrnlModuleObject.InLoadOrderLinks);
/* Initialize ModuleObject for HAL */
- RtlZeroMemory(&HalModuleObject, sizeof(MODULE_OBJECT));
- HalModuleObject.Base = (PVOID) LdrHalBase;
- HalModuleObject.Flags = MODULE_FLAG_PE;
+ RtlZeroMemory(&HalModuleObject, sizeof(LDR_DATA_TABLE_ENTRY));
+ HalModuleObject.DllBase = (PVOID) LdrHalBase;
- RtlInitUnicodeString(&HalModuleObject.FullName, HAL_MODULE_NAME);
- LdrpBuildModuleBaseName(&HalModuleObject.BaseName, &HalModuleObject.FullName);
+ RtlInitUnicodeString(&HalModuleObject.FullDllName, HAL_MODULE_NAME);
+ LdrpBuildModuleBaseName(&HalModuleObject.BaseDllName, &HalModuleObject.FullDllName);
NtHeader = RtlImageNtHeader((PVOID)LdrHalBase);
- HalModuleObject.Image.PE.FileHeader = &NtHeader->FileHeader;
- HalModuleObject.Image.PE.OptionalHeader = &NtHeader->OptionalHeader;
- HalModuleObject.Image.PE.SectionList = IMAGE_FIRST_SECTION(NtHeader);
- HalModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) HalModuleObject.Base + NtHeader->OptionalHeader.AddressOfEntryPoint);
+ HalModuleObject.EntryPoint = (PVOID) ((ULONG_PTR) HalModuleObject.DllBase + NtHeader->OptionalHeader.AddressOfEntryPoint);
DPRINT("ModuleObject:%08x entrypoint at %x\n", &HalModuleObject, HalModuleObject.EntryPoint);
- HalModuleObject.Length = HalModuleObject.Image.PE.OptionalHeader->SizeOfImage;
- HalModuleObject.TextSection = &LdrHalTextSection;
+ HalModuleObject.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
- InsertTailList(&ModuleListHead,
- &HalModuleObject.ListEntry);
+ InsertTailList(&ModuleListHead, &HalModuleObject.InLoadOrderLinks);
}
NTSTATUS
+NTAPI
LdrpLoadImage (
PUNICODE_STRING DriverName,
PVOID *ModuleBase,
PVOID *EntryPoint,
PVOID *ExportSectionPointer )
{
- PMODULE_OBJECT ModuleObject;
+ PLDR_DATA_TABLE_ENTRY ModuleObject;
NTSTATUS Status;
ModuleObject = LdrGetModuleObject(DriverName);
}
if (ModuleBase)
- *ModuleBase = ModuleObject->Base;
+ *ModuleBase = ModuleObject->DllBase;
- //if (SectionPointer)
- // *SectionPointer = ModuleObject->
+ if (SectionPointer)
+ *SectionPointer = ModuleObject;
if (EntryPoint)
*EntryPoint = ModuleObject->EntryPoint;
NTSTATUS
+NTAPI
LdrpUnloadImage ( PVOID ModuleBase )
{
return(STATUS_NOT_IMPLEMENTED);
NTSTATUS
+NTAPI
LdrpLoadAndCallImage ( PUNICODE_STRING ModuleName )
{
PDRIVER_INITIALIZE DriverEntry;
- PMODULE_OBJECT ModuleObject;
+ PLDR_DATA_TABLE_ENTRY ModuleObject;
+ DRIVER_OBJECT DriverObject;
NTSTATUS Status;
ModuleObject = LdrGetModuleObject(ModuleName);
DriverEntry = (PDRIVER_INITIALIZE)ModuleObject->EntryPoint;
- Status = DriverEntry(NULL, NULL);
+ RtlZeroMemory(&DriverObject, sizeof(DriverObject));
+// DriverObject.DriverStart = ModuleObject->DllBase;
+
+ Status = DriverEntry(&DriverObject, NULL);
if (!NT_SUCCESS(Status))
{
LdrUnloadModule(ModuleObject);
NTSTATUS
+NTAPI
LdrLoadModule(
PUNICODE_STRING Filename,
- PMODULE_OBJECT *ModuleObject )
+ PLDR_DATA_TABLE_ENTRY *ModuleObject )
{
PVOID ModuleLoadBase;
NTSTATUS Status;
HANDLE FileHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
- PMODULE_OBJECT Module;
+ PLDR_DATA_TABLE_ENTRY Module;
FILE_STANDARD_INFORMATION FileStdInfo;
IO_STATUS_BLOCK IoStatusBlock;
NULL);
CHECKPOINT;
Status = ZwOpenFile(&FileHandle,
- FILE_ALL_ACCESS,
+ GENERIC_READ,
&ObjectAttributes,
&IoStatusBlock,
- 0,
+ FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT);
CHECKPOINT;
if (!NT_SUCCESS(Status))
{
- CPRINT("Could not open module file: %wZ\n", Filename);
+ CPRINT("Could not open module file: %wZ (Status 0x%08lx)\n", Filename, Status);
return(Status);
}
CHECKPOINT;
NTSTATUS
-LdrUnloadModule ( PMODULE_OBJECT ModuleObject )
+NTAPI
+LdrUnloadModule ( PLDR_DATA_TABLE_ENTRY ModuleObject )
{
KIRQL Irql;
/* Remove the module from the module list */
KeAcquireSpinLock(&ModuleListLock,&Irql);
- RemoveEntryList(&ModuleObject->ListEntry);
+ RemoveEntryList(&ModuleObject->InLoadOrderLinks);
KeReleaseSpinLock(&ModuleListLock, Irql);
/* Hook for KDB on unloading a driver. */
KDB_UNLOADDRIVER_HOOK(ModuleObject);
- /* Free text section */
- if (ModuleObject->TextSection != NULL)
- {
- ExFreePool(ModuleObject->TextSection->Name);
- RemoveEntryList(&ModuleObject->TextSection->ListEntry);
- ExFreePool(ModuleObject->TextSection);
- ModuleObject->TextSection = NULL;
- }
-
/* Free module section */
- // MmFreeSection(ModuleObject->Base);
+ // MmFreeSection(ModuleObject->DllBase);
- ExFreePool(ModuleObject->FullName.Buffer);
+ ExFreePool(ModuleObject->FullDllName.Buffer);
ExFreePool(ModuleObject);
return(STATUS_SUCCESS);
LdrProcessModule(
PVOID ModuleLoadBase,
PUNICODE_STRING ModuleName,
- PMODULE_OBJECT *ModuleObject )
+ PLDR_DATA_TABLE_ENTRY *ModuleObject )
{
PIMAGE_DOS_HEADER PEDosHeader;
}
NTSTATUS
+NTAPI
LdrpQueryModuleInformation (
PVOID Buffer,
ULONG Size,
PULONG ReqSize )
{
PLIST_ENTRY current_entry;
- PMODULE_OBJECT current;
+ PLDR_DATA_TABLE_ENTRY current;
ULONG ModuleCount = 0;
- PSYSTEM_MODULE_INFORMATION Smi;
+ PRTL_PROCESS_MODULES Smi;
ANSI_STRING AnsiName;
PCHAR p;
KIRQL Irql;
+ PUNICODE_STRING UnicodeName;
+ ULONG tmpBufferSize = 0;
+ PWCHAR tmpNameBuffer;
KeAcquireSpinLock(&ModuleListLock,&Irql);
while (current_entry != (&ModuleListHead))
{
ModuleCount++;
+ current = CONTAINING_RECORD(current_entry,LDR_DATA_TABLE_ENTRY,InLoadOrderLinks);
+ tmpBufferSize += current->FullDllName.Length + sizeof(WCHAR) + sizeof(UNICODE_STRING);
current_entry = current_entry->Flink;
}
- *ReqSize = sizeof(SYSTEM_MODULE_INFORMATION)+
- (ModuleCount - 1) * sizeof(SYSTEM_MODULE_INFORMATION_ENTRY);
+ *ReqSize = sizeof(RTL_PROCESS_MODULES)+
+ (ModuleCount - 1) * sizeof(RTL_PROCESS_MODULE_INFORMATION);
if (Size < *ReqSize)
{
return(STATUS_INFO_LENGTH_MISMATCH);
}
+ /* allocate a temp buffer to store the module names */
+ UnicodeName = ExAllocatePool(NonPagedPool, tmpBufferSize);
+ if (UnicodeName == NULL)
+ {
+ KeReleaseSpinLock(&ModuleListLock, Irql);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ tmpNameBuffer = (PWCHAR)((ULONG_PTR)UnicodeName + ModuleCount * sizeof(UNICODE_STRING));
+
/* fill the buffer */
memset(Buffer, '=', Size);
- Smi = (PSYSTEM_MODULE_INFORMATION)Buffer;
- Smi->Count = ModuleCount;
+ Smi = (PRTL_PROCESS_MODULES)Buffer;
+ Smi->NumberOfModules = ModuleCount;
ModuleCount = 0;
current_entry = ModuleListHead.Flink;
while (current_entry != (&ModuleListHead))
{
- current = CONTAINING_RECORD(current_entry,MODULE_OBJECT,ListEntry);
+ current = CONTAINING_RECORD(current_entry,LDR_DATA_TABLE_ENTRY,InLoadOrderLinks);
+
+ Smi->Modules[ModuleCount].Section = 0; /* Always 0 */
+ Smi->Modules[ModuleCount].MappedBase = 0; /* Always 0 */
+ Smi->Modules[ModuleCount].ImageBase = current->DllBase;
+ Smi->Modules[ModuleCount].ImageSize = current->SizeOfImage;
+ Smi->Modules[ModuleCount].Flags = 0; /* Flags ??? (GN) */
+ Smi->Modules[ModuleCount].LoadOrderIndex = (USHORT)ModuleCount;
+ Smi->Modules[ModuleCount].InitOrderIndex = 0;
+ Smi->Modules[ModuleCount].LoadCount = 0; /* FIXME */
+ UnicodeName[ModuleCount].Buffer = tmpNameBuffer;
+ UnicodeName[ModuleCount].MaximumLength = current->FullDllName.Length + sizeof(WCHAR);
+ tmpNameBuffer += UnicodeName[ModuleCount].MaximumLength / sizeof(WCHAR);
+ RtlCopyUnicodeString(&UnicodeName[ModuleCount], ¤t->FullDllName);
- Smi->Module[ModuleCount].Unknown1 = 0; /* Always 0 */
- Smi->Module[ModuleCount].Unknown2 = 0; /* Always 0 */
- Smi->Module[ModuleCount].Base = current->Base;
- Smi->Module[ModuleCount].Size = current->Length;
- Smi->Module[ModuleCount].Flags = 0; /* Flags ??? (GN) */
- Smi->Module[ModuleCount].Index = (USHORT)ModuleCount;
- Smi->Module[ModuleCount].NameLength = 0;
- Smi->Module[ModuleCount].LoadCount = 0; /* FIXME */
+ ModuleCount++;
+ current_entry = current_entry->Flink;
+ }
+
+ KeReleaseSpinLock(&ModuleListLock, Irql);
+ for (ModuleCount = 0; ModuleCount < Smi->NumberOfModules; ModuleCount++)
+ {
AnsiName.Length = 0;
- AnsiName.MaximumLength = 256;
- AnsiName.Buffer = Smi->Module[ModuleCount].ImageName;
- RtlUnicodeStringToAnsiString(&AnsiName,
- ¤t->FullName,
- FALSE);
+ AnsiName.MaximumLength = 255;
+ AnsiName.Buffer = Smi->Modules[ModuleCount].FullPathName;
+ RtlUnicodeStringToAnsiString(&AnsiName, &UnicodeName[ModuleCount], FALSE);
+ AnsiName.Buffer[AnsiName.Length] = 0;
+ Smi->Modules[ModuleCount].InitOrderIndex = AnsiName.Length;
p = strrchr(AnsiName.Buffer, '\\');
if (p == NULL)
{
- Smi->Module[ModuleCount].PathLength = 0;
+ Smi->Modules[ModuleCount].OffsetToFileName = 0;
}
else
{
p++;
- Smi->Module[ModuleCount].PathLength = p - AnsiName.Buffer;
+ Smi->Modules[ModuleCount].OffsetToFileName = p - AnsiName.Buffer;
}
-
- ModuleCount++;
- current_entry = current_entry->Flink;
}
- KeReleaseSpinLock(&ModuleListLock, Irql);
+ ExFreePool(UnicodeName);
return(STATUS_SUCCESS);
}
return(0);
}
-PMODULE_OBJECT
+PLDR_DATA_TABLE_ENTRY
+NTAPI
LdrGetModuleObject ( PUNICODE_STRING ModuleName )
{
- PMODULE_OBJECT Module;
+ PLDR_DATA_TABLE_ENTRY Module;
PLIST_ENTRY Entry;
KIRQL Irql;
Entry = ModuleListHead.Flink;
while (Entry != &ModuleListHead)
{
- Module = CONTAINING_RECORD(Entry, MODULE_OBJECT, ListEntry);
+ Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
DPRINT("Comparing %wZ and %wZ\n",
- &Module->BaseName,
+ &Module->BaseDllName,
ModuleName);
- if (!LdrpCompareModuleNames(&Module->BaseName, ModuleName))
+ if (!LdrpCompareModuleNames(&Module->BaseDllName, ModuleName))
{
- DPRINT("Module %wZ\n", &Module->BaseName);
+ DPRINT("Module %wZ\n", &Module->BaseDllName);
KeReleaseSpinLock(&ModuleListLock, Irql);
return(Module);
}
LdrPEProcessModule(
PVOID ModuleLoadBase,
PUNICODE_STRING FileName,
- PMODULE_OBJECT *ModuleObject )
+ PLDR_DATA_TABLE_ENTRY *ModuleObject )
{
unsigned int DriverSize, Idx;
DWORD CurrentSize;
PIMAGE_DOS_HEADER PEDosHeader;
PIMAGE_NT_HEADERS PENtHeaders;
PIMAGE_SECTION_HEADER PESectionHeaders;
- PMODULE_OBJECT CreatedModuleObject;
- MODULE_TEXT_SECTION* ModuleTextSection;
+ PLDR_DATA_TABLE_ENTRY CreatedModuleObject;
NTSTATUS Status;
KIRQL Irql;
CPRINT("Failed to allocate a virtual section for driver\n");
return STATUS_UNSUCCESSFUL;
}
- DbgPrint("DriverBase for %wZ: %x\n", FileName, DriverBase);
+ DPRINT("DriverBase for %wZ: %x\n", FileName, DriverBase);
/* Copy headers over */
memcpy(DriverBase, ModuleLoadBase, PENtHeaders->OptionalHeader.SizeOfHeaders);
/* Create the module */
CreatedModuleObject = ExAllocatePoolWithTag (
- NonPagedPool, sizeof(MODULE_OBJECT), TAG_MODULE_OBJECT );
+ NonPagedPool, sizeof(LDR_DATA_TABLE_ENTRY), TAG_MODULE_OBJECT );
if (CreatedModuleObject == NULL)
{
// MmFreeSection(DriverBase);
return STATUS_INSUFFICIENT_RESOURCES;
}
- RtlZeroMemory(CreatedModuleObject, sizeof(MODULE_OBJECT));
+ RtlZeroMemory(CreatedModuleObject, sizeof(LDR_DATA_TABLE_ENTRY));
/* Initialize ModuleObject data */
- CreatedModuleObject->Base = DriverBase;
- CreatedModuleObject->Flags = MODULE_FLAG_PE;
-
- CreatedModuleObject->FullName.Length = 0;
- CreatedModuleObject->FullName.MaximumLength = FileName->Length + sizeof(UNICODE_NULL);
- CreatedModuleObject->FullName.Buffer =
- ExAllocatePoolWithTag(PagedPool, CreatedModuleObject->FullName.MaximumLength, TAG_LDR_WSTR);
- if (CreatedModuleObject->FullName.Buffer == NULL)
+ CreatedModuleObject->DllBase = DriverBase;
+
+ CreatedModuleObject->FullDllName.Length = 0;
+ CreatedModuleObject->FullDllName.MaximumLength = FileName->Length + sizeof(UNICODE_NULL);
+ CreatedModuleObject->FullDllName.Buffer =
+ ExAllocatePoolWithTag(PagedPool, CreatedModuleObject->FullDllName.MaximumLength, TAG_LDR_WSTR);
+ if (CreatedModuleObject->FullDllName.Buffer == NULL)
{
ExFreePool(CreatedModuleObject);
// MmFreeSection(DriverBase);
return STATUS_INSUFFICIENT_RESOURCES;
}
- RtlCopyUnicodeString(&CreatedModuleObject->FullName, FileName);
- LdrpBuildModuleBaseName(&CreatedModuleObject->BaseName,
- &CreatedModuleObject->FullName);
+ RtlCopyUnicodeString(&CreatedModuleObject->FullDllName, FileName);
+ CreatedModuleObject->FullDllName.Buffer[FileName->Length / sizeof(WCHAR)] = 0;
+ LdrpBuildModuleBaseName(&CreatedModuleObject->BaseDllName,
+ &CreatedModuleObject->FullDllName);
CreatedModuleObject->EntryPoint =
(PVOID)((ULONG_PTR)DriverBase +
PENtHeaders->OptionalHeader.AddressOfEntryPoint);
- CreatedModuleObject->Length = DriverSize;
+ CreatedModuleObject->SizeOfImage = DriverSize;
DPRINT("EntryPoint at %x\n", CreatedModuleObject->EntryPoint);
- CreatedModuleObject->Image.PE.FileHeader =
- (PIMAGE_FILE_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG));
-
- DPRINT("FileHeader at %x\n", CreatedModuleObject->Image.PE.FileHeader);
- CreatedModuleObject->Image.PE.OptionalHeader =
- (PIMAGE_OPTIONAL_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG) +
- sizeof(IMAGE_FILE_HEADER));
- DPRINT("OptionalHeader at %x\n", CreatedModuleObject->Image.PE.OptionalHeader);
- CreatedModuleObject->Image.PE.SectionList =
- (PIMAGE_SECTION_HEADER) ((unsigned int) DriverBase + PEDosHeader->e_lfanew + sizeof(ULONG) +
- sizeof(IMAGE_FILE_HEADER) + CreatedModuleObject->Image.PE.FileHeader->SizeOfOptionalHeader);
- DPRINT("SectionList at %x\n", CreatedModuleObject->Image.PE.SectionList);
-
/* Perform import fixups */
Status = LdrPEFixupImports(CreatedModuleObject);
if (!NT_SUCCESS(Status))
{
// MmFreeSection(DriverBase);
- ExFreePool(CreatedModuleObject->FullName.Buffer);
+ ExFreePool(CreatedModuleObject->FullDllName.Buffer);
ExFreePool(CreatedModuleObject);
return Status;
}
Protect = PAGE_EXECUTE_READWRITE;
}
#endif
- if (PageAddress < DriverBase + DriverSize)
+ if (PageAddress < RVA(DriverBase, DriverSize))
{
MmSetPageProtect(NULL, PageAddress, Protect);
}
PageAddress = (PVOID)((ULONG_PTR)PageAddress + PAGE_SIZE);
while ((ULONG_PTR)PageAddress + PAGE_SIZE < (ULONG_PTR)BaseAddress + Length)
{
- if (PageAddress < DriverBase + DriverSize)
+ if (PageAddress < RVA(DriverBase, DriverSize))
{
MmSetPageProtect(NULL, PageAddress, Protect);
}
PageAddress = (PVOID)((ULONG_PTR)PageAddress + PAGE_SIZE);
}
if (PageAddress < (PVOID)((ULONG_PTR)BaseAddress + Length) &&
- PageAddress < DriverBase + DriverSize)
+ PageAddress < RVA(DriverBase, DriverSize))
{
Protect = LdrLookupPageProtection(PageAddress, DriverBase, &PENtHeaders->FileHeader, PESectionHeaders);
MmSetPageProtect(NULL, PageAddress, Protect);
/* Insert module */
KeAcquireSpinLock(&ModuleListLock, &Irql);
InsertTailList(&ModuleListHead,
- &CreatedModuleObject->ListEntry);
+ &CreatedModuleObject->InLoadOrderLinks);
KeReleaseSpinLock(&ModuleListLock, Irql);
-
- ModuleTextSection = ExAllocatePoolWithTag (
- NonPagedPool,
- sizeof(MODULE_TEXT_SECTION),
- TAG_MODULE_TEXT_SECTION );
- ASSERT(ModuleTextSection);
- RtlZeroMemory(ModuleTextSection, sizeof(MODULE_TEXT_SECTION));
- ModuleTextSection->Base = (ULONG)DriverBase;
- ModuleTextSection->Length = DriverSize;
- ModuleTextSection->Name = ExAllocatePoolWithTag (
- NonPagedPool,
- (CreatedModuleObject->BaseName.Length + 1) * sizeof(WCHAR),
- TAG_LDR_WSTR );
- RtlCopyMemory(ModuleTextSection->Name,
- CreatedModuleObject->BaseName.Buffer,
- CreatedModuleObject->BaseName.Length);
- ModuleTextSection->Name[CreatedModuleObject->BaseName.Length / sizeof(WCHAR)] = 0;
- ModuleTextSection->OptionalHeader =
- CreatedModuleObject->Image.PE.OptionalHeader;
- InsertTailList(&ModuleTextListHead, &ModuleTextSection->ListEntry);
-
- CreatedModuleObject->TextSection = ModuleTextSection;
-
*ModuleObject = CreatedModuleObject;
DPRINT("Loading Module %wZ...\n", FileName);
- if (KdDebuggerEnabled && (KdDebugState & KD_DEBUG_GDB))
- {
- DPRINT("Module %wZ loaded at 0x%.08x.\n",
- FileName, CreatedModuleObject->Base);
- }
+ DPRINT("Module %wZ loaded at 0x%.08x.\n",
+ FileName, CreatedModuleObject->DllBase);
return STATUS_SUCCESS;
}
-PVOID INIT_FUNCTION
+PVOID
+INIT_FUNCTION
+NTAPI
LdrSafePEProcessModule (
PVOID ModuleLoadBase,
PVOID DriverBase,
CHAR NameBuffer[128];
UNICODE_STRING ModuleName;
PCHAR p;
- PMODULE_OBJECT ModuleObject;
+ PLDR_DATA_TABLE_ENTRY ModuleObject;
DPRINT("LdrPEFixupForward (%s)\n", ForwardName);
CPRINT("LdrPEFixupForward: failed to find module %s\n", NameBuffer);
return NULL;
}
- return LdrPEGetExportByName(ModuleObject->Base, (PUCHAR)(p+1), 0xffff);
+ return LdrPEGetExportByName(ModuleObject->DllBase, (PUCHAR)(p+1), 0xffff);
}
static NTSTATUS
Delta = (ULONG_PTR)DriverBase - NtHeaders->OptionalHeader.ImageBase;
RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)DriverBase + RelocationDDir->VirtualAddress);
RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
- MaxAddress = DriverBase + DriverSize;
+ MaxAddress = RVA(DriverBase, DriverSize);
while (RelocationDir < RelocationEnd &&
RelocationDir->SizeOfBlock > 0)
{
Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
- Address = DriverBase + RelocationDir->VirtualAddress;
+ Address = RVA(DriverBase, RelocationDir->VirtualAddress);
TypeOffset = (PUSHORT)(RelocationDir + 1);
for (i = 0; i < Count; i++)
{
Offset = *TypeOffset & 0xFFF;
Type = *TypeOffset >> 12;
- ShortPtr = (PUSHORT)(Address + Offset);
+ ShortPtr = (PUSHORT)(RVA(Address, Offset));
/* Don't relocate after the end of the loaded driver */
if ((PVOID)ShortPtr >= MaxAddress)
/*
* Don't relocate within the relocation section itself.
- * GCC/LD generates sometimes relocation records for the relecotion section.
+ * GCC/LD generates sometimes relocation records for the relocation section.
* This is a bug in GCC/LD.
*/
if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir ||
return STATUS_SUCCESS;
}
+#ifndef PATH_MAX
+#define PATH_MAX 260
+#endif
static NTSTATUS
LdrPEGetOrLoadModule (
- PMODULE_OBJECT Module,
+ PLDR_DATA_TABLE_ENTRY Module,
PCHAR ImportedName,
- PMODULE_OBJECT* ImportedModule)
+ PLDR_DATA_TABLE_ENTRY* ImportedModule)
{
UNICODE_STRING DriverName;
UNICODE_STRING NameString;
PWCHAR PathEnd;
ULONG PathLength;
- PathEnd = wcsrchr(Module->FullName.Buffer, L'\\');
+ PathEnd = wcsrchr(Module->FullDllName.Buffer, L'\\');
if (NULL != PathEnd)
{
- PathLength = (PathEnd - Module->FullName.Buffer + 1) * sizeof(WCHAR);
- RtlCopyMemory(NameBuffer, Module->FullName.Buffer, PathLength);
+ PathLength = (PathEnd - Module->FullDllName.Buffer + 1) * sizeof(WCHAR);
+ RtlCopyMemory(NameBuffer, Module->FullDllName.Buffer, PathLength);
RtlCopyMemory(NameBuffer + (PathLength / sizeof(WCHAR)), DriverName.Buffer, DriverName.Length);
NameString.Buffer = NameBuffer;
NameString.MaximumLength = NameString.Length = PathLength + DriverName.Length;
PDWORD * ExFunctions;
PDWORD * ExNames;
USHORT * ExOrdinals;
- ULONG i;
PVOID ExName;
ULONG Ordinal;
PVOID Function;
- LONG minn, maxn;
+ LONG minn, maxn, mid, res;
ULONG ExportDirSize;
DPRINT("LdrPEGetExportByName %x %s %hu\n", BaseAddress, SymbolName, Hint);
}
/*
- * Try a binary search first
+ * Binary search
*/
minn = 0;
maxn = ExportDir->NumberOfNames - 1;
while (minn <= maxn)
{
- LONG mid;
- LONG res;
-
mid = (minn + maxn) / 2;
ExName = RVA(BaseAddress, ExNames[mid]);
return Function;
}
}
- else if (minn == maxn)
- {
- DPRINT("LdrPEGetExportByName(): binary search failed\n");
- break;
- }
else if (res > 0)
{
maxn = mid - 1;
}
}
- /*
- * Fall back on a linear search
- */
- DPRINT("LdrPEGetExportByName(): Falling back on a linear search of export table\n");
- for (i = 0; i < ExportDir->NumberOfNames; i++)
- {
- ExName = RVA(BaseAddress, ExNames[i]);
- if (strcmp(ExName, (PCHAR)SymbolName) == 0)
- {
- Ordinal = ExOrdinals[i];
- Function = RVA(BaseAddress, ExFunctions[Ordinal]);
- DPRINT("%x %x %x\n", Function, ExportDir, ExportDir + ExportDirSize);
- 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)
- {
- break;
- }
- return Function;
- }
- }
+ ExName = RVA(BaseAddress, ExNames[mid]);
DPRINT1("LdrPEGetExportByName(): failed to find %s\n",SymbolName);
return (PVOID)NULL;
}
? RVA(BaseAddress, ExFunctions[Ordinal - ExportDir->Base] )
: NULL;
- if (((ULONG)Function >= (ULONG)ExportDir) &&
- ((ULONG)Function < (ULONG)ExportDir + (ULONG)ExportDirSize))
+ if (((ULONG_PTR)Function >= (ULONG_PTR)ExportDir) &&
+ ((ULONG_PTR)Function < (ULONG_PTR)ExportDir + ExportDirSize))
{
DPRINT("Forward: %s\n", (PCHAR)Function);
Function = LdrPEFixupForward((PCHAR)Function);
static NTSTATUS
LdrPEProcessImportDirectoryEntry(
PVOID DriverBase,
- PMODULE_OBJECT ImportedModule,
+ PLDR_DATA_TABLE_ENTRY ImportedModule,
PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory )
{
PVOID* ImportAddressList;
}
/* Get the import address list. */
- ImportAddressList = (PVOID*)(DriverBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
+ ImportAddressList = (PVOID*)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
/* Get the list of functions to import. */
if (ImportModuleDirectory->OriginalFirstThunk != 0)
{
- FunctionNameList = (PULONG) (DriverBase + (ULONG_PTR)ImportModuleDirectory->OriginalFirstThunk);
+ FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->OriginalFirstThunk);
}
else
{
- FunctionNameList = (PULONG)(DriverBase + (ULONG_PTR)ImportModuleDirectory->FirstThunk);
+ FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
}
/* Walk through function list and fixup addresses. */
if ((*FunctionNameList) & 0x80000000)
{
Ordinal = (*FunctionNameList) & 0x7fffffff;
- *ImportAddressList = LdrPEGetExportByOrdinal(ImportedModule->Base, Ordinal);
+ *ImportAddressList = LdrPEGetExportByOrdinal(ImportedModule->DllBase, Ordinal);
if ((*ImportAddressList) == NULL)
{
- DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullName);
+ DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName);
return STATUS_UNSUCCESSFUL;
}
}
{
IMAGE_IMPORT_BY_NAME *pe_name;
pe_name = RVA(DriverBase, *FunctionNameList);
- *ImportAddressList = LdrPEGetExportByName(ImportedModule->Base, pe_name->Name, pe_name->Hint);
+ *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->FullName);
+ DPRINT1("Failed to import %s from %wZ\n", pe_name->Name, &ImportedModule->FullDllName);
return STATUS_UNSUCCESSFUL;
}
}
}
static NTSTATUS
-LdrPEFixupImports ( PMODULE_OBJECT Module )
+LdrPEFixupImports ( PLDR_DATA_TABLE_ENTRY Module )
{
PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
PCHAR ImportedName;
- PMODULE_OBJECT ImportedModule;
+ PLDR_DATA_TABLE_ENTRY ImportedModule;
NTSTATUS Status;
+ ULONG Size;
/* Process each import module */
ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
- RtlImageDirectoryEntryToData(Module->Base,
+ RtlImageDirectoryEntryToData(Module->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
- NULL);
+ &Size);
DPRINT("Processeing import directory at %p\n", ImportModuleDirectory);
while (ImportModuleDirectory->Name)
{
- if (Module->Length <= ImportModuleDirectory->Name)
+ if (Module->SizeOfImage <= ImportModuleDirectory->Name)
{
- DPRINT1("Invalid import directory in %wZ\n", &Module->FullName);
+ DPRINT1("Invalid import directory in %wZ\n", &Module->FullDllName);
return STATUS_SECTION_NOT_IMAGE;
}
/* Check to make sure that import lib is kernel */
- ImportedName = (PCHAR) Module->Base + ImportModuleDirectory->Name;
+ ImportedName = (PCHAR) Module->DllBase + ImportModuleDirectory->Name;
Status = LdrPEGetOrLoadModule(Module, ImportedName, &ImportedModule);
if (!NT_SUCCESS(Status))
return Status;
}
- Status = LdrPEProcessImportDirectoryEntry(Module->Base, ImportedModule, ImportModuleDirectory);
+ Status = LdrPEProcessImportDirectoryEntry(Module->DllBase, ImportedModule, ImportModuleDirectory);
if (!NT_SUCCESS(Status))
{
return Status;