From 2c56aadeb47574b8cf62ccbee834595363e2b675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=B6glinger-Stelzer?= Date: Sat, 1 Jul 2023 04:14:20 +0200 Subject: [PATCH] Added code from https://github.com/nefarius/WDF-Utils/blob/master/Snippets/WDM/GetProcAddress.md --- Domito.sln.DotSettings | 3 + src/Domito.cpp | 155 +++++++++++++++++++++++++++++++++++++ src/Domito.h | 84 ++++++++++++++++++++ src/Domito.vcxproj | 21 ++++- src/Domito.vcxproj.filters | 10 +++ 5 files changed, 269 insertions(+), 4 deletions(-) create mode 100644 Domito.sln.DotSettings create mode 100644 src/Domito.cpp create mode 100644 src/Domito.h diff --git a/Domito.sln.DotSettings b/Domito.sln.DotSettings new file mode 100644 index 0000000..e94b454 --- /dev/null +++ b/Domito.sln.DotSettings @@ -0,0 +1,3 @@ + + True + True \ No newline at end of file diff --git a/src/Domito.cpp b/src/Domito.cpp new file mode 100644 index 0000000..b0aa6ff --- /dev/null +++ b/src/Domito.cpp @@ -0,0 +1,155 @@ +#include +#include + +#include "Domito.h" + + +// +// Finds the base address of a driver module +// +_Success_(return == STATUS_SUCCESS) +_Must_inspect_result_ +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +DomitoFindDriverBaseAddress( + _In_ STRING ModuleName, + _Inout_opt_ PVOID* ModuleBase +) +{ + ULONG bufferSize = 0; + PSYSTEM_MODULE_INFORMATION moduleInfo = NULL; + + const ULONG SystemModuleInformation = 11; + + // Query the required buffer size for module information + NTSTATUS status = ZwQuerySystemInformation( + SystemModuleInformation, + &bufferSize, + 0, + &bufferSize + ); + + if (status != STATUS_INFO_LENGTH_MISMATCH) + { + return status; + } + +#pragma warning(disable:4996) + // Allocate memory for the module information + moduleInfo = (PSYSTEM_MODULE_INFORMATION)ExAllocatePoolWithTag( + NonPagedPool, + bufferSize, + 'looP' + ); +#pragma warning(default:4996) + + if (moduleInfo == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + // Retrieve the module information + status = ZwQuerySystemInformation( + SystemModuleInformation, + moduleInfo, + bufferSize, + NULL + ); + + if (!NT_SUCCESS(status)) + { + ExFreePool(moduleInfo); + return status; + } + + STRING currentImageName; + + status = STATUS_NOT_FOUND; + // Iterate through the loaded modules and find the desired module + for (ULONG i = 0; i < moduleInfo->Count; i++) + { + RtlInitAnsiString(¤tImageName, moduleInfo->Module[i].ImageName); + + if (0 == RtlCompareString(&ModuleName, ¤tImageName, TRUE)) + { + // Found the module, store the base address + if (ModuleBase) + { + status = STATUS_SUCCESS; + *ModuleBase = moduleInfo->Module[i].Base; + } + break; + } + } + + ExFreePool(moduleInfo); + + return status; +} + +_Success_(return == STATUS_SUCCESS) +_Must_inspect_result_ +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +DomitoFindExportedFunctionAddress( + _In_ PVOID ModuleBase, + _In_ STRING FunctionName, + _Inout_opt_ PVOID* FunctionAddress +) +{ + NTSTATUS status = STATUS_NOT_FOUND; + ULONG exportSize; + + DECLARE_CONST_UNICODE_STRING(routineName, L"RtlImageDirectoryEntryToData"); + + const t_RtlImageDirectoryEntryToData fp_RtlImageDirectoryEntryToData = + (t_RtlImageDirectoryEntryToData)MmGetSystemRoutineAddress((PUNICODE_STRING)&routineName); + + if (fp_RtlImageDirectoryEntryToData == NULL) + { + return STATUS_NOT_IMPLEMENTED; + } + + // Retrieve the export directory information + const PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)fp_RtlImageDirectoryEntryToData( + ModuleBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &exportSize + ); + + if (exportDirectory == NULL) + { + return STATUS_INVALID_IMAGE_FORMAT; + } + + STRING currentFunctionName; + + const PULONG functionAddresses = (PULONG)((ULONG_PTR)ModuleBase + exportDirectory->AddressOfFunctions); + const PULONG functionNames = (PULONG)((ULONG_PTR)ModuleBase + exportDirectory->AddressOfNames); + const PUSHORT functionOrdinals = (PUSHORT)((ULONG_PTR)ModuleBase + exportDirectory->AddressOfNameOrdinals); + + for (ULONG i = 0; i < exportDirectory->NumberOfNames; i++) + { + const char* functionName = (const char*)((ULONG_PTR)ModuleBase + functionNames[i]); + const USHORT functionOrdinal = functionOrdinals[i]; + UNREFERENCED_PARAMETER(functionOrdinal); + + const ULONG functionRva = functionAddresses[i]; + const PVOID functionAddress = (PVOID)((ULONG_PTR)ModuleBase + functionRva); + + RtlInitAnsiString(¤tFunctionName, functionName); + + if (0 == RtlCompareString(&FunctionName, ¤tFunctionName, TRUE)) + { + if (FunctionAddress) + { + status = STATUS_SUCCESS; + *FunctionAddress = functionAddress; + } + break; + } + } + + return status; +} diff --git a/src/Domito.h b/src/Domito.h new file mode 100644 index 0000000..df385df --- /dev/null +++ b/src/Domito.h @@ -0,0 +1,84 @@ +#pragma once + +// Structure representing a loaded module +typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY +{ + PVOID Unknown1; + PVOID Unknown2; + PVOID Base; + ULONG Size; + ULONG Flags; + USHORT Index; + USHORT NameLength; + USHORT LoadCount; + USHORT PathLength; + CHAR ImageName[256]; +} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY; + +// Structure representing the loaded module information +typedef struct _SYSTEM_MODULE_INFORMATION +{ + ULONG Count; + SYSTEM_MODULE_INFORMATION_ENTRY Module[1]; +} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; + +// Function prototype for ZwQuerySystemInformation +NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation( + ULONG SystemInformationClass, + PVOID SystemInformation, + ULONG SystemInformationLength, + PULONG ReturnLength +); + +typedef struct _LDR_DATA_TABLE_ENTRY +{ + LIST_ENTRY64 InLoadOrderLinks; + PVOID ExceptionTable; + ULONG ExceptionTableSize; + PVOID GpValue; + PVOID NonPagedDebugInfo; + PVOID ImageBase; + PVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullImageName; + UNICODE_STRING BaseImageName; + ULONG Flags; + USHORT LoadCount; + USHORT TlsIndex; + LIST_ENTRY64 HashLinks; + PVOID SectionPointer; + ULONG CheckSum; + ULONG TimeDateStamp; + PVOID LoadedImports; + PVOID EntryPointActivationContext; + PVOID PatchInformation; +} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; + +typedef PVOID (NTAPI* t_RtlImageDirectoryEntryToData)( + IN PVOID Base, + IN BOOLEAN MappedAsImage, + IN USHORT DirectoryEntry, + OUT PULONG Size +); + + +_Success_(return == STATUS_SUCCESS) +_Must_inspect_result_ +_IRQL_requires_max_(PASSIVE_LEVEL) +EXTERN_C +NTSTATUS +DomitoFindDriverBaseAddress( + _In_ STRING ModuleName, + _Inout_opt_ PVOID* ModuleBase +); + +_Success_(return == STATUS_SUCCESS) +_Must_inspect_result_ +_IRQL_requires_max_(PASSIVE_LEVEL) +EXTERN_C +NTSTATUS +DomitoFindExportedFunctionAddress( + _In_ PVOID ModuleBase, + _In_ STRING FunctionName, + _Inout_opt_ PVOID* FunctionAddress +); diff --git a/src/Domito.vcxproj b/src/Domito.vcxproj index c90c4a9..12b21e2 100644 --- a/src/Domito.vcxproj +++ b/src/Domito.vcxproj @@ -26,34 +26,35 @@ Debug x64 Domito + $(LatestTargetPlatformVersion) Windows10 true WindowsKernelModeDriver10.0 - Driver + StaticLibrary WDM Windows10 false WindowsKernelModeDriver10.0 - Driver + StaticLibrary WDM Windows10 true WindowsKernelModeDriver10.0 - Driver + StaticLibrary WDM Windows10 false WindowsKernelModeDriver10.0 - Driver + StaticLibrary WDM @@ -66,15 +67,21 @@ DbgengKernelDebugger + $(SolutionDir)lib\$(DDKPlatform)\$(ConfigurationName)\ DbgengKernelDebugger + true + $(SolutionDir)lib\$(DDKPlatform)\$(ConfigurationName)\ DbgengKernelDebugger + $(SolutionDir)lib\$(DDKPlatform)\$(ConfigurationName)\ DbgengKernelDebugger + true + $(SolutionDir)lib\$(DDKPlatform)\$(ConfigurationName)\ @@ -89,6 +96,12 @@ + + + + + + diff --git a/src/Domito.vcxproj.filters b/src/Domito.vcxproj.filters index 99cea20..05eca6c 100644 --- a/src/Domito.vcxproj.filters +++ b/src/Domito.vcxproj.filters @@ -18,4 +18,14 @@ inf;inv;inx;mof;mc; + + + Source Files + + + + + Header Files + + \ No newline at end of file