From be751c6dc97bac1334968047408bcf3184c2a0eb Mon Sep 17 00:00:00 2001 From: segfault Date: Thu, 1 Oct 2020 15:08:06 -0700 Subject: Replaced PsSetLoadImageNotifyRoutine with a PatchGuard safe version. --- KMemDriver/Imports.h | 15 +++++++++++ KMemDriver/KMemDriver.c | 66 ++++++++++++++++++++++++------------------------- KMemDriver/Native.h | 27 ++++++++++++++++++++ 3 files changed, 75 insertions(+), 33 deletions(-) (limited to 'KMemDriver') diff --git a/KMemDriver/Imports.h b/KMemDriver/Imports.h index ed70956..8a33dbb 100644 --- a/KMemDriver/Imports.h +++ b/KMemDriver/Imports.h @@ -138,4 +138,19 @@ NTAPI RtlAvlRemoveNode( IN PRTL_AVL_TREE pTree, IN PMMADDRESS_NODE pNode +); + +__kernel_entry +NTSTATUS +ZwQuerySystemInformation( + IN int SystemInformationClass, + OUT PVOID SystemInformation, + IN ULONG SystemInformationLength, + OUT OPTIONAL PULONG ReturnLength +); + +NTKERNELAPI +PVOID +PsGetProcessSectionBaseAddress( + IN PEPROCESS Process ); \ No newline at end of file diff --git a/KMemDriver/KMemDriver.c b/KMemDriver/KMemDriver.c index 23916ef..741f932 100644 --- a/KMemDriver/KMemDriver.c +++ b/KMemDriver/KMemDriver.c @@ -188,24 +188,6 @@ NTSTATUS DriverEntry( return status; } -void OnImageLoad( - PUNICODE_STRING FullImageName, - HANDLE ProcessId, - PIMAGE_INFO ImageInfo -) -{ - UNREFERENCED_PARAMETER(ImageInfo); -#if 0 - KDBG("ProcessID: 0x%X\n", ProcessId); - KDBG("FullImage: %wZ\n", FullImageName); -#endif - if (wcsstr(FullImageName->Buffer, CHEAT_EXE)) { - ctrlPID = ProcessId; - imageBase = ImageInfo->ImageBase; - KDBG("Found Target !!!\n"); - } -} - NTSTATUS WaitForControlProcess(OUT PEPROCESS *ppEProcess) { NTSTATUS status; @@ -216,22 +198,34 @@ NTSTATUS WaitForControlProcess(OUT PEPROCESS *ppEProcess) imageBase = NULL; ctrlPID = NULL; - status = PsSetLoadImageNotifyRoutine(OnImageLoad); - if (!NT_SUCCESS(status)) { - KDBG("PsSetLoadImageNotifyRoutine failed with 0x%X\n", status); - return status; - } + SYSTEM_PROCESS_INFORMATION * procs = MmAllocateNonCachedMemory(1024 * sizeof(*procs)); + ULONG mem_needed = 0; - while (!ctrlPID) { - LARGE_INTEGER wait = { .QuadPart = -1000000 }; - KeDelayExecutionThread(KernelMode, TRUE, &wait); + if (procs == NULL) { + return STATUS_MEMORY_NOT_ALLOCATED; } + while (ctrlPID == NULL) { + status = ZwQuerySystemInformation(0x05, (PVOID)&procs[0], 1024 * sizeof(*procs), &mem_needed); + if (!NT_SUCCESS(status)) { + KDBG("NtQuerySystemInformation failed with 0x%X\n", status); + return status; + } - status = PsRemoveLoadImageNotifyRoutine(OnImageLoad); - if (!NT_SUCCESS(status)) { - KDBG("PsRemoveLoadImageNotifyRoutine failed with 0x%X\n", status); - return status; + SYSTEM_PROCESS_INFORMATION * cur_proc = procs; + while (cur_proc->NextEntryOffset > 0) { + cur_proc = (SYSTEM_PROCESS_INFORMATION *)((PUCHAR)cur_proc + cur_proc->NextEntryOffset); + + if (wcsstr(cur_proc->ImageName.Buffer, CHEAT_EXE)) { + KDBG("FOUND %wZ with PID 0x%X\n", cur_proc->ImageName, cur_proc->UniqueProcessId); + ctrlPID = cur_proc->UniqueProcessId; + break; + } + + LARGE_INTEGER wait = { .QuadPart = -100000 }; + KeDelayExecutionThread(KernelMode, FALSE, &wait); + } } + MmFreeNonCachedMemory(procs, 1024 * sizeof(*procs)); status = PsLookupProcessByProcessId(ctrlPID, ppEProcess); if (!NT_SUCCESS(status)) { @@ -239,8 +233,14 @@ NTSTATUS WaitForControlProcess(OUT PEPROCESS *ppEProcess) return status; } - KDBG("Got Ctrl Process PID: 0x%X (%d)\n", - ctrlPID, ctrlPID); + imageBase = PsGetProcessSectionBaseAddress(*ppEProcess); + if (imageBase == NULL) + { + KDBG("ImageBase is NULL\n"); + } + + KDBG("Got Ctrl Process PID/ImageBase: 0x%X (%d) / %p\n", + ctrlPID, ctrlPID, imageBase); return STATUS_SUCCESS; } @@ -762,7 +762,7 @@ NTSTATUS GetDriverObject( } return status; - } +} PHANDLE_TABLE_ENTRY ExpLookupHandleTableEntry(PVOID pHandleTable, HANDLE handle) { diff --git a/KMemDriver/Native.h b/KMemDriver/Native.h index 6d7d684..6344eed 100644 --- a/KMemDriver/Native.h +++ b/KMemDriver/Native.h @@ -376,5 +376,32 @@ typedef struct _HANDLE_TABLE PVOID DebugInfo; } PHANDLE_TABLE; +typedef struct _SYSTEM_PROCESS_INFORMATION { + ULONG NextEntryOffset; + ULONG NumberOfThreads; + UINT8 Reserved1[48]; + UNICODE_STRING ImageName; + KPRIORITY BasePriority; + ULONG Reserved2; + HANDLE UniqueProcessId; + PVOID Reserved3; + ULONG HandleCount; + ULONG SessionId; + PVOID Reserved4; + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG Reserved5; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + PVOID Reserved6; + SIZE_T QuotaPagedPoolUsage; + PVOID Reserved7; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + SIZE_T PrivatePageCount; + LARGE_INTEGER Reserved8[6]; +} SYSTEM_PROCESS_INFORMATION; + #pragma pack(pop) #pragma warning(default : 4214 4201) \ No newline at end of file -- cgit v1.2.3 From db67fda2a689da4a8a8d8dd32aa6bc1a47246b12 Mon Sep 17 00:00:00 2001 From: segfault Date: Thu, 1 Oct 2020 16:32:42 -0700 Subject: Added some PTE code for future use. --- KMemDriver/Memory.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'KMemDriver') diff --git a/KMemDriver/Memory.c b/KMemDriver/Memory.c index 9a064c3..2b0621b 100644 --- a/KMemDriver/Memory.c +++ b/KMemDriver/Memory.c @@ -315,4 +315,89 @@ NTSTATUS FreeMemoryFromProcess(IN PEPROCESS pep, IN PVOID baseAddr, IN SIZE_T si MmFreeNonCachedMemory(apc, sizeof(*apc)); return status; +} + +NTSTATUS WritePhysicalPage(IN PVOID addr, IN PUCHAR content, IN OUT PSIZE_T content_size_and_transferred) +{ + PHYSICAL_ADDRESS pa = { 0 }; + MM_COPY_ADDRESS mm = { 0 }; + PVOID vaddr; + + if (content_size_and_transferred == NULL || *content_size_and_transferred > 4096) + { + return STATUS_UNSUCCESSFUL; + } + + pa.QuadPart = (LONGLONG)addr; + mm.VirtualAddress = content; + vaddr = MmGetVirtualForPhysical(pa); + + if (vaddr == NULL) + { + return STATUS_UNSUCCESSFUL; + } + return MmCopyMemory(vaddr, mm, 4096, MM_COPY_MEMORY_VIRTUAL, content_size_and_transferred); +} + +NTSTATUS ReadPhysicalPage(IN PHYSICAL_ADDRESS * addr, OUT PUCHAR content, IN OUT PSIZE_T content_size_and_transferred) +{ + MM_COPY_ADDRESS mm = { 0 }; + + if (content_size_and_transferred == NULL || *content_size_and_transferred > 4096) + { + return STATUS_UNSUCCESSFUL; + } + + mm.PhysicalAddress = *(PHYSICAL_ADDRESS *)addr; + return MmCopyMemory(content, mm, 4096, MM_COPY_MEMORY_PHYSICAL, content_size_and_transferred); +} + +SIZE_T GetCR3(IN PEPROCESS pep) +{ + SIZE_T ret; + KAPC_STATE apcState; + + KeStackAttachProcess((PRKPROCESS)pep, &apcState); + ret = __readcr3(); + KeUnstackDetachProcess(&apcState); + + return ret; +} + +void SetCR3(IN PEPROCESS pep, IN SIZE_T value) +{ + KAPC_STATE apcState; + + KeStackAttachProcess((PRKPROCESS)pep, &apcState); + __writecr3(value); + KeUnstackDetachProcess(&apcState); +} + +static ULONG_PTR invalidate_tlb(ULONG_PTR addr) +{ + __invlpg(addr); + return 0; +} + +void FlushTLB(IN PVOID addr) +{ + KeIpiGenericCall(invalidate_tlb, (ULONG_PTR)addr); +} + +#define IA32_PAT 0x277 + +SIZE_T GetIA32PAT(void) +{ + return __readmsr(IA32_PAT); +} + +static ULONG_PTR set_pat(ULONG_PTR pat) +{ + __writemsr(IA32_PAT, pat); + return 0; +} + +void SetIA32PAT(IN SIZE_T value) +{ + KeIpiGenericCall(set_pat, value); } \ No newline at end of file -- cgit v1.2.3 From 780127138ef45e4e0baee5a8616bd5c335f5ebe6 Mon Sep 17 00:00:00 2001 From: segfault Date: Sun, 11 Oct 2020 10:01:32 -0700 Subject: Added simple x86_64-ASM source to get the current IP. --- KMemDriver/KMemDriver.c | 5 ++++- KMemDriver/KMemDriver.vcxproj | 5 +++++ KMemDriver/KMemDriver.vcxproj.filters | 5 +++++ KMemDriver/Utils.asm | 11 +++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 KMemDriver/Utils.asm (limited to 'KMemDriver') diff --git a/KMemDriver/KMemDriver.c b/KMemDriver/KMemDriver.c index 741f932..3865b67 100644 --- a/KMemDriver/KMemDriver.c +++ b/KMemDriver/KMemDriver.c @@ -26,6 +26,8 @@ #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) +extern PVOID getCurrentRIP(void); + DRIVER_INITIALIZE DriverEntry; #pragma alloc_text(INIT, DriverEntry) void OnImageLoad( @@ -184,7 +186,6 @@ NTSTATUS DriverEntry( return status; } - FNZERO(DriverEntry); return status; } @@ -195,6 +196,8 @@ NTSTATUS WaitForControlProcess(OUT PEPROCESS *ppEProcess) if (!ppEProcess) return STATUS_INVALID_ADDRESS; + KDBG("CurrentRIP: %p\n", getCurrentRIP()); + imageBase = NULL; ctrlPID = NULL; diff --git a/KMemDriver/KMemDriver.vcxproj b/KMemDriver/KMemDriver.vcxproj index 5264a6f..0c97b63 100644 --- a/KMemDriver/KMemDriver.vcxproj +++ b/KMemDriver/KMemDriver.vcxproj @@ -182,6 +182,11 @@ + + + true + + diff --git a/KMemDriver/KMemDriver.vcxproj.filters b/KMemDriver/KMemDriver.vcxproj.filters index e69aafd..ff05a79 100644 --- a/KMemDriver/KMemDriver.vcxproj.filters +++ b/KMemDriver/KMemDriver.vcxproj.filters @@ -32,4 +32,9 @@ Source Files + + + Source Files + + \ No newline at end of file diff --git a/KMemDriver/Utils.asm b/KMemDriver/Utils.asm new file mode 100644 index 0000000..d95a64e --- /dev/null +++ b/KMemDriver/Utils.asm @@ -0,0 +1,11 @@ +PUBLIC getCurrentRIP + +.code _text + +getCurrentRIP PROC PUBLIC +pop rax +push rax +ret +getCurrentRIP ENDP + +END \ No newline at end of file -- cgit v1.2.3 From 639f1137e3f7e5ef845e3f69ad34b514749c87fc Mon Sep 17 00:00:00 2001 From: segfault Date: Sun, 11 Oct 2020 13:17:25 -0700 Subject: Added code de/encryption on function level (WiP). --- KMemDriver/Crypto.c | 15 +++++++++++++++ KMemDriver/Crypto.h | 18 ++++++++++++++++++ KMemDriver/KMemDriver.c | 4 +++- KMemDriver/KMemDriver.vcxproj | 2 ++ KMemDriver/KMemDriver.vcxproj.filters | 6 ++++++ 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 KMemDriver/Crypto.c create mode 100644 KMemDriver/Crypto.h (limited to 'KMemDriver') diff --git a/KMemDriver/Crypto.c b/KMemDriver/Crypto.c new file mode 100644 index 0000000..1999d5f --- /dev/null +++ b/KMemDriver/Crypto.c @@ -0,0 +1,15 @@ +#include "Crypto.h" + +struct crypt_data { + UINT64 key; + UINT8 crypted; + UINT32 marker; +}; + +#define MAX_CRYPTED_FUNCTIONS 64 +static struct crypt_data data[MAX_CRYPTED_FUNCTIONS]; +static size_t data_used = 0; + +void crypt_fn(void) +{ +} \ No newline at end of file diff --git a/KMemDriver/Crypto.h b/KMemDriver/Crypto.h new file mode 100644 index 0000000..09413aa --- /dev/null +++ b/KMemDriver/Crypto.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +void crypt_fn(void); + +#define CRYPT_PROLOGUE() \ + do { \ + crypt_fn(); \ + volatile UINT64 index_and_marker = { 0x11111111C0DEC0DE }; \ + UNREFERENCED_PARAMETER(index_and_marker); \ + } while (0) +#define CRYPT_EPILOGUE() \ + do { \ + volatile UINT32 marker = 0xDEADDEAD;\ + UNREFERENCED_PARAMETER(marker); \ + crypt_fn(); \ + } while (0) \ No newline at end of file diff --git a/KMemDriver/KMemDriver.c b/KMemDriver/KMemDriver.c index 3865b67..921ab0f 100644 --- a/KMemDriver/KMemDriver.c +++ b/KMemDriver/KMemDriver.c @@ -1,6 +1,7 @@ #include "KMemDriver.h" #include "Imports.h" #include "Native.h" +#include "Crypto.h" #include #include @@ -164,6 +165,7 @@ NTSTATUS DriverEntry( _In_ PUNICODE_STRING RegistryPath ) { + CRYPT_PROLOGUE(); NTSTATUS status; HANDLE hThread = NULL; CLIENT_ID clientID = { 0 }; @@ -183,8 +185,8 @@ NTSTATUS DriverEntry( if (!NT_SUCCESS(status)) { KDBG("Failed to create worker thread. Status: 0x%X\n", status); - return status; } + CRYPT_EPILOGUE(); return status; } diff --git a/KMemDriver/KMemDriver.vcxproj b/KMemDriver/KMemDriver.vcxproj index 0c97b63..0161cdf 100644 --- a/KMemDriver/KMemDriver.vcxproj +++ b/KMemDriver/KMemDriver.vcxproj @@ -173,12 +173,14 @@ + + diff --git a/KMemDriver/KMemDriver.vcxproj.filters b/KMemDriver/KMemDriver.vcxproj.filters index ff05a79..a02c6eb 100644 --- a/KMemDriver/KMemDriver.vcxproj.filters +++ b/KMemDriver/KMemDriver.vcxproj.filters @@ -20,6 +20,9 @@ Header Files + + Header Files + @@ -31,6 +34,9 @@ Source Files + + Source Files + -- cgit v1.2.3