From d018a599d816b38d1afb1478360cc159269ef8de Mon Sep 17 00:00:00 2001 From: Nodir Temirkhodjaev Date: Sun, 30 Jan 2022 02:43:50 +0300 Subject: [PATCH] DriverLoader: Windows 8+: Try to load HAL.dll functions from ntoskrnl.exe first --- src/driver/loader/fortdl_amalg.c | 1 + src/driver/loader/fortmm.c | 42 +++++++++++++++++++++++++++++--- src/driver/wdm/um_wdm.c | 6 +++++ src/driver/wdm/um_wdm.h | 2 ++ 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/driver/loader/fortdl_amalg.c b/src/driver/loader/fortdl_amalg.c index 4a612e5e..b0b2971f 100644 --- a/src/driver/loader/fortdl_amalg.c +++ b/src/driver/loader/fortdl_amalg.c @@ -2,6 +2,7 @@ #define FORT_AMALG #define FORT_DRIVER +#define FORT_DEBUG #include "../fortutl.c" diff --git a/src/driver/loader/fortmm.c b/src/driver/loader/fortmm.c index 13c640d6..b234a6b5 100644 --- a/src/driver/loader/fortmm.c +++ b/src/driver/loader/fortmm.c @@ -208,7 +208,7 @@ static NTSTATUS PerformBaseRelocation( /* Build the import address table: Library functions. */ static NTSTATUS BuildImportTableLibrary(PUCHAR codeBase, const PIMAGE_IMPORT_DESCRIPTOR importDesc, - LPCSTR libName, LOADEDMODULE libModule) + LPCSTR libName, PLOADEDMODULE libModule, PLOADEDMODULE forwardModule) { NTSTATUS status = STATUS_SUCCESS; @@ -228,8 +228,18 @@ static NTSTATUS BuildImportTableLibrary(PUCHAR codeBase, const PIMAGE_IMPORT_DES funcName = (LPCSTR) &thunkData->Name; } - *funcRef = ModuleGetProcAddress(&libModule, funcName); - if (*funcRef == 0) { + if (forwardModule != NULL) { + *funcRef = ModuleGetProcAddress(forwardModule, funcName); + if (*funcRef != NULL) { +#ifdef FORT_DEBUG + LOG("Loader Module: Import forwarded: %s: %s: %p\n", libName, funcName, *funcRef); +#endif + continue; + } + } + + *funcRef = ModuleGetProcAddress(libModule, funcName); + if (*funcRef == NULL) { LOG("Loader Module: Error: Procedure Not Found: %s: %s\n", libName, funcName); status = STATUS_PROCEDURE_NOT_FOUND; } else { @@ -258,6 +268,21 @@ static NTSTATUS BuildImportTable(PUCHAR codeBase, PIMAGE_NT_HEADERS pHeaders) if (!NT_SUCCESS(status)) return status; +#if defined(FORT_WIN7_COMPAT) + LOADEDMODULE kernelModule = { NULL }; + { + RTL_OSVERSIONINFOW osvi; + RtlZeroMemory(&osvi, sizeof(osvi)); + osvi.dwOSVersionInfoSize = sizeof(osvi); + RtlGetVersion(&osvi); + const BOOL isWindows7 = (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1); + + if (!isWindows7) { + GetModuleInfo(&kernelModule, "ntoskrnl.exe", modules, modulesCount); + } + } +#endif + status = STATUS_SUCCESS; PIMAGE_IMPORT_DESCRIPTOR importDesc = @@ -273,7 +298,16 @@ static NTSTATUS BuildImportTable(PUCHAR codeBase, PIMAGE_NT_HEADERS pHeaders) break; } - status = BuildImportTableLibrary(codeBase, importDesc, libName, libModule); + PLOADEDMODULE forwardModule = NULL; +#if defined(FORT_WIN7_COMPAT) + if (kernelModule.codeBase != NULL && _stricmp(libName, "hal.dll") == 0) { + /* Functions of HAL.dll are exported from kernel on Windows 8+ */ + LOG("Loader Module: Forward to kernel: %s\n", libName); + forwardModule = &kernelModule; + } +#endif + + status = BuildImportTableLibrary(codeBase, importDesc, libName, &libModule, forwardModule); if (!NT_SUCCESS(status)) { LOG("Loader Module: Library Import Error: %s\n", libName); break; diff --git a/src/driver/wdm/um_wdm.c b/src/driver/wdm/um_wdm.c index 947b1dd3..390f524b 100644 --- a/src/driver/wdm/um_wdm.c +++ b/src/driver/wdm/um_wdm.c @@ -271,6 +271,12 @@ void RtlTimeToTimeFields(PLARGE_INTEGER time, PTIME_FIELDS timeFields) UNUSED(timeFields); } +NTSTATUS RtlGetVersion(PRTL_OSVERSIONINFOW versionInformation) +{ + UNUSED(versionInformation); + return STATUS_SUCCESS; +} + NTSTATUS ZwOpenKey( PHANDLE keyHandle, ACCESS_MASK desiredAccess, POBJECT_ATTRIBUTES objectAttributes) { diff --git a/src/driver/wdm/um_wdm.h b/src/driver/wdm/um_wdm.h index 20e32b16..601375a9 100644 --- a/src/driver/wdm/um_wdm.h +++ b/src/driver/wdm/um_wdm.h @@ -286,6 +286,8 @@ FORT_API void KeQuerySystemTime(PLARGE_INTEGER time); FORT_API void ExSystemTimeToLocalTime(PLARGE_INTEGER systemTime, PLARGE_INTEGER localTime); FORT_API void RtlTimeToTimeFields(PLARGE_INTEGER time, PTIME_FIELDS timeFields); +FORT_API NTSTATUS RtlGetVersion(PRTL_OSVERSIONINFOW versionInformation); + FORT_API NTSTATUS ZwOpenKey( PHANDLE keyHandle, ACCESS_MASK desiredAccess, POBJECT_ATTRIBUTES objectAttributes); FORT_API NTSTATUS ZwClose(HANDLE handle);