aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2019-05-07 22:23:34 +0200
committerToni Uhlig <matzeton@googlemail.com>2019-05-07 22:23:34 +0200
commit3b8ee025edd045b962c21d09dd1ef86e1e48aae4 (patch)
tree294f2015bf65813b6cd23d7cfa265ccd21cd1ac3
initial commit
-rw-r--r--.gitattributes63
-rw-r--r--.gitignore261
-rw-r--r--KMemDriver.sln33
-rw-r--r--KMemDriver/Driver.c805
-rw-r--r--KMemDriver/Imports.h112
-rw-r--r--KMemDriver/KMemDriver.vcxproj185
-rw-r--r--KMemDriver/KMemDriver.vcxproj.filters29
-rw-r--r--KMemDriver/Native.h82
-rw-r--r--KTest-Only.bat5
-rw-r--r--KTest/KInterface.cpp326
-rw-r--r--KTest/KInterface.h120
-rw-r--r--KTest/KTest.cpp400
-rw-r--r--KTest/KTest.vcxproj193
-rw-r--r--KTest/KTest.vcxproj.filters39
-rw-r--r--KTest/pch.cpp5
-rw-r--r--KTest/pch.h14
-rw-r--r--PastDSE-Manual-Map-Debug.bat13
-rw-r--r--PastDSE-Manual-Map-Release.bat13
-rw-r--r--include/Driver.h131
19 files changed, 2829 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3c4efe2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,261 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc \ No newline at end of file
diff --git a/KMemDriver.sln b/KMemDriver.sln
new file mode 100644
index 0000000..3d32609
--- /dev/null
+++ b/KMemDriver.sln
@@ -0,0 +1,33 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.421
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KMemDriver", "KMemDriver\KMemDriver.vcxproj", "{5B65BD0E-C43C-41E3-A016-1CD0B092998F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KTest", "KTest\KTest.vcxproj", "{8661069D-CE09-4A70-8C75-8F33E77732E6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5B65BD0E-C43C-41E3-A016-1CD0B092998F}.Debug|x64.ActiveCfg = Debug|x64
+ {5B65BD0E-C43C-41E3-A016-1CD0B092998F}.Debug|x64.Build.0 = Debug|x64
+ {5B65BD0E-C43C-41E3-A016-1CD0B092998F}.Debug|x64.Deploy.0 = Debug|x64
+ {5B65BD0E-C43C-41E3-A016-1CD0B092998F}.Release|x64.ActiveCfg = Release|x64
+ {5B65BD0E-C43C-41E3-A016-1CD0B092998F}.Release|x64.Build.0 = Release|x64
+ {5B65BD0E-C43C-41E3-A016-1CD0B092998F}.Release|x64.Deploy.0 = Release|x64
+ {8661069D-CE09-4A70-8C75-8F33E77732E6}.Debug|x64.ActiveCfg = Debug|x64
+ {8661069D-CE09-4A70-8C75-8F33E77732E6}.Debug|x64.Build.0 = Debug|x64
+ {8661069D-CE09-4A70-8C75-8F33E77732E6}.Release|x64.ActiveCfg = Release|x64
+ {8661069D-CE09-4A70-8C75-8F33E77732E6}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {8F34A429-695E-48D4-A0EF-9840BABAE3BF}
+ EndGlobalSection
+EndGlobal
diff --git a/KMemDriver/Driver.c b/KMemDriver/Driver.c
new file mode 100644
index 0000000..12af90d
--- /dev/null
+++ b/KMemDriver/Driver.c
@@ -0,0 +1,805 @@
+#include "Driver.h"
+#include "Imports.h"
+#include "Native.h"
+
+#include <ntddk.h>
+#include <Ntstrsafe.h>
+
+#define CHEAT_EXE L"KTest.exe"
+
+#ifdef _DEBUG_
+#define KDBG(fmt, ...) DbgPrint("KMemDriver[%01d]: " fmt, KeGetCurrentIrql(), __VA_ARGS__)
+#else
+#define KDBG(fmt, ...)
+#endif
+
+#ifndef _DEBUG_
+#define FNZERO_MARKER() \
+ do { \
+ volatile UINT32 marker = 0xDEADC0DE;\
+ UNREFERENCED_PARAMETER(marker); \
+ } while (0)
+#define FNZERO_FN(fn_start) \
+ do { fn_zero_text((PVOID)fn_start); } while (0)
+#define FNZERO(fn_start) \
+ FNZERO_MARKER(); \
+ FNZERO_FN(fn_start)
+#else
+#define FNZERO_MARKER()
+#define FNZERO_FN(fn_start)
+#define FNZERO(fn_start)
+#endif
+
+#define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 )
+
+DRIVER_INITIALIZE DriverEntry;
+#pragma alloc_text(INIT, DriverEntry)
+void OnImageLoad(
+ PUNICODE_STRING FullImageName,
+ HANDLE ProcessId,
+ PIMAGE_INFO ImageInfo
+);
+#pragma alloc_text(PAGE, OnImageLoad)
+
+NTSTATUS WaitForControlProcess(OUT PEPROCESS *ppEProcess);
+NTSTATUS VerifyControlProcess(IN PEPROCESS pEProcess);
+NTSTATUS InitSharedMemory(IN PEPROCESS pEProcess);
+NTSTATUS WaitForHandshake(IN PEPROCESS pEProcess,
+ OUT HANDLE *pKEvent, OUT HANDLE *pUEvent);
+NTSTATUS OpenEventReference(IN PEPROCESS pEProcess,
+ IN KAPC_STATE *pKAPCState, IN HANDLE hEvent,
+ OUT PKEVENT *pPKEvent);
+NTSTATUS UpdatePPEPIfRequired(IN HANDLE wantedPID,
+ IN HANDLE lastPID, OUT HANDLE *lastPROC,
+ OUT PEPROCESS *lastPEP);
+NTSTATUS GetPages(IN PEPROCESS Process,
+ OUT MEMORY_BASIC_INFORMATION *mbiArr,
+ IN SIZE_T mbiArrLen, OUT SIZE_T *mbiUsed,
+ IN PVOID start_addr);
+NTSTATUS GetModules(IN PEPROCESS pEProcess,
+ OUT PMODULE_DATA pmod, IN OUT SIZE_T *psiz,
+ IN SIZE_T start_index);
+NTSTATUS KeReadVirtualMemory(IN PEPROCESS pEProcess,
+ IN PVOID SourceAddress,
+ IN PVOID TargetAddress, IN PSIZE_T Size);
+NTSTATUS KeWriteVirtualMemory(IN PEPROCESS pEProcess,
+ IN PVOID SourceAddress,
+ IN PVOID TargetAddress, IN PSIZE_T Size);
+NTSTATUS KeProtectVirtualMemory(IN HANDLE hProcess,
+ IN PVOID addr, IN SIZE_T siz,
+ IN ULONG new_prot, OUT ULONG *old_prot);
+NTSTATUS KeRestoreProtectVirtualMemory(IN HANDLE hProcess,
+ IN PVOID addr, IN SIZE_T siz,
+ IN ULONG old_prot);
+NTSTATUS GetDriverObject(PDRIVER_OBJECT *lpObj, WCHAR* DriverDirName);
+NTSTATUS KRThread(IN PVOID pArg);
+
+#pragma alloc_text(PAGE, WaitForControlProcess)
+#pragma alloc_text(PAGE, VerifyControlProcess)
+#pragma alloc_text(PAGE, InitSharedMemory)
+#pragma alloc_text(PAGE, WaitForHandshake)
+#pragma alloc_text(PAGE, OpenEventReference)
+#pragma alloc_text(PAGE, UpdatePPEPIfRequired)
+#pragma alloc_text(PAGE, GetPages)
+#pragma alloc_text(PAGE, GetModules)
+#pragma alloc_text(PAGE, KeReadVirtualMemory)
+#pragma alloc_text(PAGE, KeWriteVirtualMemory)
+#pragma alloc_text(PAGE, KeProtectVirtualMemory)
+#pragma alloc_text(PAGE, KeRestoreProtectVirtualMemory)
+#pragma alloc_text(PAGE, GetDriverObject)
+#pragma alloc_text(PAGE, KRThread)
+
+static void fn_zero_text(PVOID fn_start);
+static HANDLE ctrlPID;
+static PVOID imageBase;
+
+static PVOID mmapedBase = NULL;
+static INT hijacked = 0;
+static PDRIVER_OBJECT hijackedDriver = NULL;
+static DRIVER_OBJECT hijackedDriverOriginal;
+
+
+NTSTATUS DriverEntry(
+ _In_ DRIVER_OBJECT *DriverObject,
+ _In_ PUNICODE_STRING RegistryPath
+)
+{
+ NTSTATUS status;
+ HANDLE hThread = NULL;
+ CLIENT_ID clientID = { 0 };
+ OBJECT_ATTRIBUTES obAttr = { 0 };
+
+ UNREFERENCED_PARAMETER(DriverObject);
+ UNREFERENCED_PARAMETER(RegistryPath);
+
+ KDBG("Driver Loaded\n");
+ if (!DriverObject && RegistryPath) {
+ /* assume that we are manual mapped by PastDSE */
+ mmapedBase = RegistryPath;
+ KDBG("Manual mapped image base: 0x%p\n", mmapedBase);
+ }
+ InitializeObjectAttributes(&obAttr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
+ status = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &obAttr, NULL, &clientID, &KRThread, NULL);
+ if (!NT_SUCCESS(status))
+ {
+ KDBG("Failed to create worker thread. Status: 0x%X\n", status);
+ return status;
+ }
+
+ FNZERO(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;
+
+ if (!ppEProcess)
+ return STATUS_INVALID_ADDRESS;
+
+ imageBase = NULL;
+ ctrlPID = NULL;
+
+ status = PsSetLoadImageNotifyRoutine(OnImageLoad);
+ if (!NT_SUCCESS(status)) {
+ KDBG("PsSetLoadImageNotifyRoutine failed with 0x%X\n", status);
+ return status;
+ }
+
+ while (!ctrlPID) {
+ LARGE_INTEGER wait = { .QuadPart = -1000000 };
+ KeDelayExecutionThread(KernelMode, TRUE, &wait);
+ }
+
+ status = PsRemoveLoadImageNotifyRoutine(OnImageLoad);
+ if (!NT_SUCCESS(status)) {
+ KDBG("PsRemoveLoadImageNotifyRoutine failed with 0x%X\n", status);
+ return status;
+ }
+
+ status = PsLookupProcessByProcessId(ctrlPID, ppEProcess);
+ if (!NT_SUCCESS(status)) {
+ KDBG("PsLookupProcessByProcessId failed with 0x%X\n", status);
+ return status;
+ }
+
+ KDBG("Got Ctrl Process PID: 0x%X (%d)\n",
+ ctrlPID, ctrlPID);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS VerifyControlProcess(IN PEPROCESS pEProcess)
+{
+ NTSTATUS status;
+ UCHAR pefile[4] = { 0 };
+ SIZE_T pesiz = sizeof pefile;
+
+ status = KeReadVirtualMemory(pEProcess,
+ imageBase, pefile, &pesiz);
+ if (!NT_SUCCESS(status) || pesiz != sizeof pefile) {
+ KDBG("KeReadVirtualMemory failed with 0x%X\n", status);
+ return status;
+ }
+ if (pefile[0] != 0x4D || pefile[1] != 0x5A ||
+ pefile[2] != 0x90 || pefile[3] != 0x00)
+ {
+ KDBG("Invalid PE file\n");
+ return status;
+ }
+
+ return status;
+}
+
+NTSTATUS InitSharedMemory(IN PEPROCESS pEProcess)
+{
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+ SIZE_T maxWaits = 20;
+
+ KDBG("Init Shmem ..\n");
+ while (--maxWaits) {
+ UCHAR buf[4] = { 0 };
+ SIZE_T bufsiz = sizeof buf;
+ LARGE_INTEGER wait = { .QuadPart = -5000000 };
+ status = KeReadVirtualMemory(pEProcess,
+ (PVOID)SHMEM_ADDR, buf, &bufsiz);
+ if (NT_SUCCESS(status) && bufsiz == sizeof buf)
+ break;
+ KDBG("Waiting until 0x%X alloc'd by user space app ..\n", SHMEM_ADDR);
+ KeDelayExecutionThread(KernelMode, TRUE, &wait);
+ }
+
+ return status;
+}
+
+NTSTATUS WaitForHandshake(IN PEPROCESS pEProcess,
+ OUT HANDLE *pKEvent, OUT HANDLE *pUEvent)
+{
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+ SIZE_T maxWaits = 20;
+
+ KDBG("Wait for Handshake ..\n");
+ while (--maxWaits) {
+ KERNEL_HANDSHAKE hnds;
+ SIZE_T siz = sizeof hnds;
+ LARGE_INTEGER wait = { .QuadPart = -5000000 };
+ status = KeReadVirtualMemory(pEProcess, (PVOID)SHMEM_ADDR, &hnds, &siz);
+ if (NT_SUCCESS(status) && siz == sizeof hnds &&
+ hnds.kevent)
+ {
+ if (validateRequest(&hnds) != MEM_HANDSHAKE) {
+ KDBG("Invalid Handshake received: 0x%X\n", hnds.hdr.magic);
+ return STATUS_INVALID_CONNECTION;
+ }
+ *pKEvent = hnds.kevent;
+ *pUEvent = hnds.uevent;
+ KDBG("Got Event Handle 0x%X (Kernel) and 0x%X (User)\n",
+ *pKEvent, *pUEvent);
+ break;
+ }
+ KDBG("Waiting for handshake at 0x%X ..\n", SHMEM_ADDR);
+ KeDelayExecutionThread(KernelMode, TRUE, &wait);
+ }
+
+ return status;
+}
+
+NTSTATUS OpenEventReference(IN PEPROCESS pEProcess,
+ IN KAPC_STATE *pKAPCState, IN HANDLE hEvent,
+ OUT PKEVENT *pPKEvent)
+{
+ NTSTATUS status;
+
+ KeStackAttachProcess((PRKPROCESS)pEProcess, pKAPCState);
+ status = ObReferenceObjectByHandle(
+ hEvent, SYNCHRONIZE | EVENT_MODIFY_STATE,
+ *ExEventObjectType, UserMode, pPKEvent, NULL
+ );
+ KeUnstackDetachProcess(pKAPCState);
+ if (!NT_SUCCESS(status))
+ KDBG("ObReferenceObjectByHandle for Handle 0x%X failed with 0x%X\n",
+ hEvent, status);
+
+ return status;
+}
+
+NTSTATUS KRThread(IN PVOID pArg)
+{
+ NTSTATUS status;
+ INT reinit;
+ HANDLE kevent, uevent;
+ PEPROCESS ctrlPEP;
+ KAPC_STATE apcstate;
+ PKEVENT pk_kevent, pk_uevent;
+
+ UNREFERENCED_PARAMETER(pArg);
+
+ do {
+ reinit = 0;
+ ctrlPEP = NULL;
+ pk_kevent = pk_uevent = NULL;
+
+ KeLowerIrql(0);
+ KDBG("Init ..\n");
+
+ if (mmapedBase && !hijackedDriver &&
+ NT_SUCCESS(GetDriverObject(&hijackedDriver, L"\\Driver\\ahcache")))
+ {
+ if (hijackedDriver) {
+#ifdef _DEBUG_
+ KDBG("Got DriverObject at 0x%p\n", hijackedDriver);
+ PKLDR_DATA_TABLE_ENTRY drv_section = hijackedDriver->DriverSection;
+ KDBG("PDrvObj: base -> 0x%p , name -> '%wZ' , flags -> 0x%X\n",
+ drv_section->DllBase, drv_section->BaseDllName, drv_section->Flags);
+#endif
+ /* !!! EXPERIMENTAL !!! */
+#if 0
+ hijacked = 1;
+ /* the following lines are known to cause a bugcheck */
+ hijackedDriverOriginal = *hijackedDriver;
+ hijackedDriver->DriverStart = mmapedBase;
+ //hijackedDriver->DriverSection = (PVOID)((ULONG_PTR)mmapedBase + 100);
+#endif
+#if 0
+ /* the following lines are known to not work with ahcache driver */
+ hijackedDriver->DriverInit = (PDRIVER_INITIALIZE)DriverEntry;
+ hijackedDriver->DriverStartIo = NULL;
+ hijackedDriver->DriverUnload = NULL;
+ SIZE_T funcs = sizeof hijackedDriver->MajorFunction / sizeof hijackedDriver->MajorFunction[0];
+ for (SIZE_T i = 0; i < funcs; ++i) {
+ hijackedDriver->MajorFunction[i] = NULL;
+ }
+#endif
+ }
+ }
+
+ status = WaitForControlProcess(&ctrlPEP);
+ if (!NT_SUCCESS(status))
+ goto finish;
+
+ if (hijackedDriver && hijacked) {
+ *hijackedDriver = hijackedDriverOriginal;
+ }
+
+ status = VerifyControlProcess(ctrlPEP);
+ if (!NT_SUCCESS(status))
+ goto finish_ctrlpep;
+
+ status = InitSharedMemory(ctrlPEP);
+ if (!NT_SUCCESS(status))
+ goto finish_ctrlpep;
+
+ status = WaitForHandshake(ctrlPEP,
+ &kevent, &uevent);
+ if (!NT_SUCCESS(status))
+ goto finish_ctrlpep;
+
+ status = OpenEventReference(ctrlPEP,
+ &apcstate, kevent, &pk_kevent);
+ if (!NT_SUCCESS(status))
+ goto finish_ctrlpep;
+
+ status = OpenEventReference(ctrlPEP,
+ &apcstate, uevent, &pk_uevent);
+ if (!NT_SUCCESS(status))
+ goto finish_kevent;
+
+ KeClearEvent(pk_kevent);
+ KeClearEvent(pk_uevent);
+
+ PVOID shm_buf = MmAllocateNonCachedMemory(SHMEM_SIZE);
+ if (!shm_buf) {
+ KDBG("MmAllocateNonCachedMemory with size 0x%X failed\n", SHMEM_SIZE);
+ goto nomem;
+ }
+
+ reinit = 1;
+ KeSetEvent(pk_uevent, FILE_DEVICE_MOUSE, TRUE);
+ HANDLE lastPID = NULL, lastPROC = NULL;
+ PEPROCESS lastPEP = NULL;
+ INT running = 1;
+ SIZE_T maxWaits = 20;
+ do {
+ LARGE_INTEGER wait = { .QuadPart = -10000000 };
+ status = KeWaitForSingleObject(pk_kevent, Executive, UserMode, FALSE, &wait);
+ if (NT_SUCCESS(status) && status == WAIT_OBJECT_0) {
+ maxWaits = 20;
+ /* parse memory request */
+ SIZE_T siz = SHMEM_SIZE;
+ status = KeReadVirtualMemory(ctrlPEP, (PVOID)SHMEM_ADDR, shm_buf, &siz);
+
+ if (NT_SUCCESS(status) && siz == SHMEM_SIZE) {
+ switch (validateRequest(shm_buf))
+ {
+ case MEM_HANDSHAKE:
+ KDBG("Invalid Request MEM_HANDSHAKE\n");
+ break;
+ case MEM_PING: {
+ PKERNEL_PING ping = (PKERNEL_PING)shm_buf;
+ KDBG("Got a PING with rng 0x%X, sending PONG !\n",
+ ping->rnd_user);
+ ping->rnd_kern = ping->rnd_user;
+ siz = sizeof *ping;
+ KeWriteVirtualMemory(ctrlPEP, ping, (PVOID)SHMEM_ADDR, &siz);
+ break;
+ }
+ case MEM_PAGES: {
+ PKERNEL_PAGE pages = (PKERNEL_PAGE)shm_buf;
+ KDBG("Got a PAGES request for process 0x%X start at address 0x%p\n",
+ pages->ProcessId, pages->StartAddress);
+ if (!NT_SUCCESS(UpdatePPEPIfRequired(pages->ProcessId,
+ lastPID, &lastPROC, &lastPEP)))
+ {
+ running = 0;
+ break;
+ }
+ siz = (SHMEM_SIZE - sizeof *pages + sizeof pages->pages_start)
+ / sizeof pages->pages_start;
+ pages->StatusRes = GetPages(lastPEP, &pages->pages_start, siz,
+ &pages->pages, pages->StartAddress);
+ siz = (sizeof *pages - sizeof pages->pages_start) +
+ sizeof pages->pages_start * pages->pages;
+ KeWriteVirtualMemory(ctrlPEP, pages, (PVOID)SHMEM_ADDR, &siz);
+ break;
+ }
+ case MEM_MODULES: {
+ PKERNEL_MODULES mods = (PKERNEL_MODULES)shm_buf;
+ KDBG("Got a MODULES request for process 0x%X start at index 0x%X\n",
+ mods->ProcessId, mods->StartIndex);
+ if (!NT_SUCCESS(UpdatePPEPIfRequired(mods->ProcessId,
+ lastPID, &lastPROC, &lastPEP)))
+ {
+ running = 0;
+ break;
+ }
+ siz = (SHMEM_SIZE - sizeof *mods + sizeof mods->modules_start)
+ / sizeof mods->modules_start;
+ PMODULE_DATA entries = &mods->modules_start;
+ KDBG("GetModules max entries: %u\n", siz);
+ KeStackAttachProcess((PRKPROCESS)lastPEP, &apcstate);
+ mods->StatusRes = GetModules(lastPEP, entries, &siz, mods->StartIndex);
+ KeUnstackDetachProcess(&apcstate);
+ mods->modules = siz;
+ siz = (sizeof *mods - sizeof mods->modules_start) +
+ sizeof mods->modules_start * mods->modules;
+ KeWriteVirtualMemory(ctrlPEP, mods, (PVOID)SHMEM_ADDR, &siz);
+ break;
+ }
+ case MEM_RPM: {
+ PKERNEL_READ_REQUEST rr = (PKERNEL_READ_REQUEST)shm_buf;
+ KDBG("Got a RPM to process 0x%X, address 0x%p with size 0x%lX\n",
+ rr->ProcessId, rr->Address, rr->SizeReq);
+ if (!NT_SUCCESS(UpdatePPEPIfRequired(rr->ProcessId,
+ lastPID, &lastPROC, &lastPEP)))
+ {
+ running = 0;
+ break;
+ }
+ if (rr->SizeReq > SHMEM_SIZE - sizeof *rr) {
+ siz = SHMEM_SIZE - sizeof *rr;
+ }
+ else {
+ siz = rr->SizeReq;
+ }
+ ULONG new_prot = PAGE_EXECUTE_READWRITE, old_prot = 0;
+ KeProtectVirtualMemory(lastPROC, rr->Address, rr->SizeReq, new_prot, &old_prot);
+ KDBG("RPM to 0x%p size 0x%X bytes (protection before/after: 0x%X/0x%X)\n",
+ rr->Address, rr->SizeReq, old_prot, new_prot);
+ rr->StatusRes = KeReadVirtualMemory(lastPEP, (PVOID)rr->Address,
+ (PVOID)((ULONG_PTR)shm_buf + sizeof *rr), &siz);
+ KeRestoreProtectVirtualMemory(lastPROC, rr->Address, rr->SizeReq, old_prot);
+ if (NT_SUCCESS(rr->StatusRes)) {
+ rr->SizeRes = siz;
+ siz += sizeof *rr;
+ }
+ else {
+ rr->SizeRes = 0;
+ siz = sizeof *rr;
+ }
+ KeWriteVirtualMemory(ctrlPEP, rr, (PVOID)SHMEM_ADDR, &siz);
+ break;
+ }
+ case MEM_WPM: {
+ PKERNEL_WRITE_REQUEST wr = (PKERNEL_WRITE_REQUEST)shm_buf;
+ KDBG("Got a WPM to process 0x%X, address 0x%p with size 0x%lX\n",
+ wr->ProcessId, wr->Address, wr->SizeReq);
+ if (!NT_SUCCESS(UpdatePPEPIfRequired(wr->ProcessId,
+ lastPID, &lastPROC, &lastPEP)))
+ {
+ running = 0;
+ break;
+ }
+ if (wr->SizeReq > SHMEM_SIZE - sizeof *wr) {
+ siz = SHMEM_SIZE - sizeof *wr;
+ }
+ else {
+ siz = wr->SizeReq;
+ }
+ ULONG new_prot = PAGE_EXECUTE_READWRITE, old_prot = 0;
+ KeProtectVirtualMemory(lastPEP, wr->Address, wr->SizeReq, new_prot, &old_prot);
+ KDBG("WPM to 0x%p size 0x%X bytes (protection before/after: 0x%X/0x%X)\n",
+ wr->Address, wr->SizeReq, old_prot, new_prot);
+ wr->StatusRes = KeWriteVirtualMemory(lastPEP, (PVOID)((ULONG_PTR)shm_buf + sizeof *wr),
+ (PVOID)wr->Address, &siz);
+ KeRestoreProtectVirtualMemory(lastPROC, wr->Address, wr->SizeReq, old_prot);
+ if (NT_SUCCESS(wr->StatusRes)) {
+ wr->SizeRes = siz;
+ siz += sizeof *wr;
+ }
+ else {
+ wr->SizeRes = 0;
+ siz = sizeof *wr;
+ }
+ KeWriteVirtualMemory(ctrlPEP, wr, (PVOID)SHMEM_ADDR, &siz);
+ break;
+ }
+ case MEM_EXIT:
+ KDBG("Gracefully exiting ..\n");
+ KeClearEvent(pk_kevent);
+ KeClearEvent(pk_uevent);
+ running = 0;
+ reinit = 0;
+ break;
+ default:
+ KDBG("Invalid Request\n");
+ running = 0;
+ reinit = 0;
+ break;
+ }
+ }
+
+ if (KeSetEvent(pk_uevent, FILE_DEVICE_MOUSE, TRUE)) {
+ KDBG("Previous signal state wasn't consumed!?\n");
+ }
+ }
+ else {
+ if (!maxWaits--) {
+ KDBG("No activity, abort ..\n");
+ running = 0;
+ }
+ }
+ } while (running);
+ KeSetEvent(pk_uevent, FILE_DEVICE_MOUSE, TRUE);
+
+ if (lastPEP)
+ ObDereferenceObject(lastPEP);
+ if (lastPROC)
+ ZwClose(lastPROC);
+ MmFreeNonCachedMemory(shm_buf, SHMEM_SIZE);
+ nomem:
+ ObDereferenceObject(pk_uevent);
+ finish_kevent:
+ ObDereferenceObject(pk_kevent);
+ finish_ctrlpep:
+ ObDereferenceObject(ctrlPEP);
+ finish:
+ if (reinit) {
+ LARGE_INTEGER wait = { .QuadPart = -50000000 };
+ KeDelayExecutionThread(KernelMode, TRUE, &wait);
+ }
+ } while (reinit);
+
+ KDBG("Terminating ..\n");
+ PsTerminateSystemThread(status);
+ return status;
+}
+
+NTSTATUS UpdatePPEPIfRequired(IN HANDLE wantedPID,
+ IN HANDLE lastPID, OUT HANDLE *lastPROC,
+ OUT PEPROCESS *lastPEP)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ if (wantedPID != lastPID) {
+ if (lastPID) {
+ ObDereferenceObject(*lastPEP);
+ *lastPEP = NULL;
+ ZwClose(*lastPROC);
+ *lastPROC = NULL;
+ }
+ status = PsLookupProcessByProcessId(wantedPID, lastPEP);
+ if (!NT_SUCCESS(status)) {
+ KDBG("PsLookupProcessByProcessId failed with 0x%X\n", status);
+ }
+ else {
+ status = ObOpenObjectByPointer(*lastPEP,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, GENERIC_ALL,
+ *PsProcessType, KernelMode, lastPROC
+ );
+ if (!NT_SUCCESS(status)) {
+ KDBG("ObOpenObjectByPointer failed with 0x%X\n", status);
+ }
+ }
+ }
+ return status;
+}
+
+NTSTATUS GetPages(IN PEPROCESS Process,
+ OUT MEMORY_BASIC_INFORMATION *mbiArr,
+ IN SIZE_T mbiArrLen, OUT SIZE_T *mbiUsed,
+ IN PVOID start_addr)
+{
+ NTSTATUS status;
+ HANDLE procHandle;
+ SIZE_T i, mbiLength, mbiReturn;
+ ULONG_PTR baseAddr = (ULONG_PTR)start_addr;
+
+ status = ObOpenObjectByPointer(Process,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, GENERIC_ALL,
+ *PsProcessType, KernelMode, &procHandle
+ );
+ if (!NT_SUCCESS(status)) {
+ KDBG("ObOpenObjectByPointer failed with 0x%X\n", status);
+ return status;
+ }
+
+ KDBG("ZwQueryVirtualMemory max entries: %u\n", mbiArrLen);
+ *mbiUsed = 0;
+ do {
+ mbiReturn = 0;
+ status = ZwQueryVirtualMemory(procHandle, (PVOID)baseAddr,
+ MemoryBasicInformation, mbiArr, sizeof *mbiArr * mbiArrLen, &mbiReturn);
+ mbiLength = mbiReturn / sizeof *mbiArr;
+ if (!NT_SUCCESS(status)) {
+ if (status == STATUS_INVALID_PARAMETER)
+ status = STATUS_SUCCESS;
+ else
+ KDBG("ZwQueryVirtualMemory failed with 0x%X\n", status);
+ break;
+ }
+ else {
+ for (i = 0; i < mbiLength; ++i)
+ KDBG("Page #%03u: base -> %p, prot -> 0x%02X, size -> 0x%X\n",
+ (*mbiUsed) + i, (*(mbiArr + i)).BaseAddress, (*(mbiArr + i)).Protect,
+ (*(mbiArr + i)).RegionSize);
+ }
+ baseAddr += (SIZE_T)(mbiArr + mbiLength - 1)->RegionSize;
+ *mbiUsed += mbiLength;
+ mbiArr += mbiLength;
+ } while (*mbiUsed < mbiArrLen && mbiReturn > 0);
+
+ ZwClose(procHandle);
+ return status;
+}
+
+NTSTATUS GetModules(IN PEPROCESS Process,
+ OUT PMODULE_DATA pmod, IN OUT SIZE_T *psiz,
+ IN SIZE_T start_index)
+{
+ SIZE_T used = 0, index = 0;
+ INT waitCount = 0;
+
+ PPEB peb = PsGetProcessPeb(Process);
+ if (!peb) {
+ KDBG("PsGetProcessPeb failed");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ PPEB_LDR_DATA ldr = peb->Ldr;
+
+ if (!ldr) {
+ KDBG("peb->Ldr is invalid");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (!ldr->Initialized) {
+ while (!ldr->Initialized && waitCount++ < 4) {
+ LARGE_INTEGER wait = { .QuadPart = -2500 };
+ KeDelayExecutionThread(KernelMode, TRUE, &wait);
+ }
+
+ if (!ldr->Initialized) {
+ KDBG("ldr->Initialized is 0");
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ for (PLIST_ENTRY listEntry = (PLIST_ENTRY)ldr->InLoadOrderModuleList.Flink;
+ listEntry != &ldr->InLoadOrderModuleList && used < *psiz;
+ listEntry = (PLIST_ENTRY)listEntry->Flink, ++pmod, ++index) {
+ if (index < start_index)
+ continue;
+ used++;
+
+ PLDR_DATA_TABLE_ENTRY ldrEntry = CONTAINING_RECORD(listEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
+ ANSI_STRING name;
+ if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&name, &ldrEntry->BaseDllName, sizeof pmod->BaseDllName))) {
+ RtlCopyMemory(pmod->BaseDllName, name.Buffer,
+ (name.Length > sizeof pmod->BaseDllName ?
+ sizeof pmod->BaseDllName : name.Length)
+ );
+ }
+ pmod->DllBase = ldrEntry->DllBase;
+ pmod->SizeOfImage = ldrEntry->SizeOfImage;
+ KDBG("DLL #%02lu: base -> 0x%p, size -> 0x%06X, name -> '%s'\n", used,
+ pmod->DllBase, pmod->SizeOfImage, pmod->BaseDllName);
+ }
+
+ *psiz = used;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS KeReadVirtualMemory(IN PEPROCESS Process,
+ IN PVOID SourceAddress,
+ IN PVOID TargetAddress, IN PSIZE_T Size)
+{
+ NTSTATUS status;
+ SIZE_T Bytes = 0;
+
+ status = MmCopyVirtualMemory(Process, SourceAddress, PsGetCurrentProcess(),
+ TargetAddress, *Size, KernelMode, &Bytes);
+ if (NT_SUCCESS(status))
+ {
+ *Size = Bytes;
+ return STATUS_SUCCESS;
+ }
+ else {
+ return status;
+ }
+}
+
+NTSTATUS KeWriteVirtualMemory(IN PEPROCESS Process,
+ IN PVOID SourceAddress,
+ IN PVOID TargetAddress, IN PSIZE_T Size)
+{
+ NTSTATUS status;
+ SIZE_T Bytes = 0;
+
+ status = MmCopyVirtualMemory(PsGetCurrentProcess(), SourceAddress, Process,
+ TargetAddress, *Size, KernelMode, &Bytes);
+ if (NT_SUCCESS(status))
+ {
+ *Size = Bytes;
+ return STATUS_SUCCESS;
+ }
+ else {
+ return status;
+ }
+}
+
+NTSTATUS KeProtectVirtualMemory(IN HANDLE hProcess,
+ IN PVOID addr, IN SIZE_T siz, IN ULONG new_prot,
+ OUT ULONG *old_prot)
+{
+ NTSTATUS status;
+ PVOID prot_addr = addr;
+ SIZE_T prot_size = siz;
+ ULONG prot = 0;
+
+ status = ZwProtectVirtualMemory(hProcess, &prot_addr,
+ &prot_size, new_prot, &prot);
+ if (NT_SUCCESS(status)) {
+ *old_prot = prot;
+ }
+ return status;
+}
+
+NTSTATUS KeRestoreProtectVirtualMemory(IN HANDLE hProcess,
+ IN PVOID addr, IN SIZE_T siz,
+ IN ULONG old_prot)
+{
+ NTSTATUS status;
+ PVOID prot_addr = addr;
+ SIZE_T prot_size = siz;
+ ULONG prot = 0;
+
+ status = ZwProtectVirtualMemory(hProcess, &prot_addr,
+ &prot_size, old_prot, &prot);
+ return status;
+}
+
+static void fn_zero_text(PVOID fn_start)
+{
+ SIZE_T i;
+ UINT32 marker = 0xDEADC0DE;
+ PUCHAR fnbuf = (PUCHAR)fn_start;
+
+ KDBG("Fn: %p\n", fn_start);
+ for (i = 0; i < 0x1000; ++i && fnbuf++) {
+ if (*(UINT32 *)fnbuf == marker) {
+ KDBG("Marker: 0x%X\n", i);
+ RtlSecureZeroMemory(fn_start, i + 4);
+ }
+ }
+}
+
+NTSTATUS GetDriverObject(PDRIVER_OBJECT *lpObj, WCHAR* DriverDirName)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PDRIVER_OBJECT pBeepObj = NULL;
+ UNICODE_STRING DevName = { 0 };
+
+ if (!MmIsAddressValid(lpObj))
+ return STATUS_INVALID_ADDRESS;
+
+ RtlInitUnicodeString(&DevName, DriverDirName);
+
+ status = ObReferenceObjectByName(&DevName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, &pBeepObj);
+
+ if (NT_SUCCESS(status))
+ *lpObj = pBeepObj;
+ else
+ {
+ *lpObj = NULL;
+ }
+
+ return status;
+} \ No newline at end of file
diff --git a/KMemDriver/Imports.h b/KMemDriver/Imports.h
new file mode 100644
index 0000000..44f53cc
--- /dev/null
+++ b/KMemDriver/Imports.h
@@ -0,0 +1,112 @@
+#pragma once
+
+#include <ntddk.h>
+#include <wdm.h>
+
+
+extern POBJECT_TYPE* IoDriverObjectType;
+
+NTKERNELAPI
+NTSTATUS
+NTAPI
+MmCopyVirtualMemory
+(
+ PEPROCESS SourceProcess,
+ PVOID SourceAddress,
+ PEPROCESS TargetProcess,
+ PVOID TargetAddress,
+ SIZE_T BufferSize,
+ KPROCESSOR_MODE PreviousMode,
+ PSIZE_T ReturnSize
+);
+
+NTKERNELAPI
+NTSTATUS
+NTAPI
+PsLookupProcessByProcessId(
+ _In_ HANDLE ProcessId,
+ _Outptr_ PEPROCESS *Process
+);
+
+typedef struct _KAPC_STATE
+{
+ LIST_ENTRY ApcListHead[2];
+ PKPROCESS Process;
+ UCHAR KernelApcInProgress;
+ UCHAR KernelApcPending;
+ UCHAR UserApcPending;
+} KAPC_STATE, *PKAPC_STATE, *PRKAPC_STATE;
+
+NTKERNELAPI
+VOID
+NTAPI
+KeStackAttachProcess(
+ PRKPROCESS PROCESS,
+ PRKAPC_STATE ApcState
+);
+
+NTKERNELAPI
+VOID
+NTAPI
+KeUnstackDetachProcess(
+ PRKAPC_STATE ApcState
+);
+
+NTKERNELAPI
+PPEB
+NTAPI
+PsGetProcessPeb(PEPROCESS Process);
+
+NTKERNELAPI
+NTSTATUS
+NTAPI
+ObOpenObjectByPointer(
+ PVOID Object,
+ ULONG HandleAttributes,
+ PACCESS_STATE PassedAccessState,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_TYPE ObjectType,
+ KPROCESSOR_MODE AccessMode,
+ PHANDLE Handle
+);
+
+typedef enum _MEMORY_INFORMATION_CLASS {
+ MemoryBasicInformation
+} MEMORY_INFORMATION_CLASS;
+
+NTKERNELAPI
+NTSTATUS
+NTAPI
+ZwQueryVirtualMemory(
+ _In_ HANDLE ProcessHandle,
+ _In_opt_ PVOID BaseAddress,
+ _In_ MEMORY_INFORMATION_CLASS MemoryInformationClass,
+ _Out_ PVOID MemoryInformation,
+ _In_ SIZE_T MemoryInformationLength,
+ _Out_opt_ PSIZE_T ReturnLength
+);
+
+NTKERNELAPI
+NTSTATUS
+NTAPI
+ZwProtectVirtualMemory(
+ IN HANDLE ProcessHandle,
+ IN PVOID* BaseAddress, /* THIS IS ACTUALLY AN IN_OUT */
+ IN SIZE_T* NumberOfBytesToProtect,
+ IN ULONG NewAccessProtection,
+ OUT PULONG OldAccessProtection
+);
+
+NTKERNELAPI
+NTSTATUS
+NTAPI
+ObReferenceObjectByName(
+ PUNICODE_STRING ObjectName,
+ ULONG Attributes,
+ PACCESS_STATE Passed,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_TYPE ObjectType,
+ KPROCESSOR_MODE Access,
+ PVOID ParseContext,
+ PVOID* ObjectPtr
+); \ No newline at end of file
diff --git a/KMemDriver/KMemDriver.vcxproj b/KMemDriver/KMemDriver.vcxproj
new file mode 100644
index 0000000..1c84ef0
--- /dev/null
+++ b/KMemDriver/KMemDriver.vcxproj
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{5B65BD0E-C43C-41E3-A016-1CD0B092998F}</ProjectGuid>
+ <TemplateGuid>{1bc93793-694f-48fe-9372-81e2b05556fd}</TemplateGuid>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
+ <Configuration>Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <RootNamespace>KMemDriver</RootNamespace>
+ <ProjectName>KMemDriver</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <SpectreMitigation>false</SpectreMitigation>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <SpectreMitigation>false</SpectreMitigation>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <SpectreMitigation>false</SpectreMitigation>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <SpectreMitigation>false</SpectreMitigation>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>_DEBUG_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>_DEBUG_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>KERNEL_MODULE;_DEBUG_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)$(SolutionName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile />
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)include;$(SolutionDir)$(SolutionName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>KERNEL_MODULE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(TargetPath)" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Driver.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\include\Driver.h" />
+ <ClInclude Include="Imports.h" />
+ <ClInclude Include="Native.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/KMemDriver/KMemDriver.vcxproj.filters b/KMemDriver/KMemDriver.vcxproj.filters
new file mode 100644
index 0000000..99f5bcc
--- /dev/null
+++ b/KMemDriver/KMemDriver.vcxproj.filters
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Driver.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Imports.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Native.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\Driver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/KMemDriver/Native.h b/KMemDriver/Native.h
new file mode 100644
index 0000000..e421bda
--- /dev/null
+++ b/KMemDriver/Native.h
@@ -0,0 +1,82 @@
+#pragma once
+
+#include <ntddk.h>
+
+typedef struct _PEB_LDR_DATA
+{
+ ULONG Length;
+ UCHAR Initialized;
+ PVOID SsHandle;
+ LIST_ENTRY InLoadOrderModuleList;
+ LIST_ENTRY InMemoryOrderModuleList;
+ LIST_ENTRY InInitializationOrderModuleList;
+} PEB_LDR_DATA, *PPEB_LDR_DATA;
+
+typedef struct _LDR_DATA_TABLE_ENTRY
+{
+ LIST_ENTRY InLoadOrderLinks;
+ LIST_ENTRY InMemoryOrderLinks;
+ LIST_ENTRY InInitializationOrderLinks;
+ PVOID DllBase;
+ PVOID EntryPoint;
+ ULONG SizeOfImage;
+ UNICODE_STRING FullDllName;
+ UNICODE_STRING BaseDllName;
+ ULONG Flags;
+ USHORT LoadCount;
+ USHORT TlsIndex;
+ LIST_ENTRY HashLinks;
+ ULONG TimeDateStamp;
+} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
+
+typedef struct _PEB
+{
+ UCHAR InheritedAddressSpace;
+ UCHAR ReadImageFileExecOptions;
+ UCHAR BeingDebugged;
+ UCHAR BitField;
+ PVOID Mutant;
+ PVOID ImageBaseAddress;
+ PPEB_LDR_DATA Ldr;
+ PVOID ProcessParameters;
+ PVOID SubSystemData;
+ PVOID ProcessHeap;
+ PVOID FastPebLock;
+ PVOID AtlThunkSListPtr;
+ PVOID IFEOKey;
+ PVOID CrossProcessFlags;
+ PVOID KernelCallbackTable;
+ ULONG SystemReserved;
+ ULONG AtlThunkSListPtr32;
+ PVOID ApiSetMap;
+} PEB, *PPEB;
+
+typedef struct _MEMORY_BASIC_INFORMATION {
+ PVOID BaseAddress;
+ PVOID AllocationBase;
+ ULONG AllocationProtect;
+ SIZE_T RegionSize;
+ ULONG State;
+ ULONG Protect;
+ ULONG Type;
+} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
+
+typedef struct _KLDR_DATA_TABLE_ENTRY {
+ LIST_ENTRY InLoadOrderLinks;
+ PVOID ExceptionTable;
+ ULONG ExceptionTableSize;
+ PVOID GpValue;
+ PVOID NonPagedDebugInfo;
+ PVOID DllBase;
+ PVOID EntryPoint;
+ ULONG SizeOfImage;
+ UNICODE_STRING FullDllName;
+ UNICODE_STRING BaseDllName;
+ ULONG Flags;
+ USHORT LoadCount;
+ USHORT __Unused;
+ PVOID SectionPointer;
+ ULONG CheckSum;
+ PVOID LoadedImports;
+ PVOID PatchInformation;
+} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY; \ No newline at end of file
diff --git a/KTest-Only.bat b/KTest-Only.bat
new file mode 100644
index 0000000..9dadcbe
--- /dev/null
+++ b/KTest-Only.bat
@@ -0,0 +1,5 @@
+@echo off
+
+REM fsutil usn deleteJournal /D C:
+%~dp0\x64\Release\KTest.exe
+timeout /t 3 \ No newline at end of file
diff --git a/KTest/KInterface.cpp b/KTest/KInterface.cpp
new file mode 100644
index 0000000..dae57e3
--- /dev/null
+++ b/KTest/KInterface.cpp
@@ -0,0 +1,326 @@
+#include "pch.h"
+#include "KInterface.h"
+#include "Driver.h"
+
+#include <sstream>
+#include <ctime>
+#include <stdexcept>
+
+
+KInterface::KInterface()
+{
+}
+
+bool KInterface::Init()
+{
+ std::srand((unsigned int)std::time(nullptr));
+ m_shmem = VirtualAlloc((PVOID)SHMEM_ADDR, SHMEM_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+ m_kevent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ m_uevent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ return m_shmem && m_kevent != INVALID_HANDLE_VALUE && m_uevent != INVALID_HANDLE_VALUE;
+}
+
+bool KInterface::Handshake()
+{
+ PKERNEL_HANDSHAKE hnds = (PKERNEL_HANDSHAKE)getBuffer();
+ hnds->kevent = m_kevent;
+ hnds->uevent = m_uevent;
+ m_last_ntstatus = INVALID_NTSTATUS;
+ return SendRecvWait(MEM_HANDSHAKE) == SRR_SIGNALED;
+}
+
+bool KInterface::Ping()
+{
+ SendRecvReturn srr;
+ PKERNEL_PING ping = (PKERNEL_PING)getBuffer();
+ m_last_ping_value = ping->rnd_user = (std::rand() << 16) | std::rand();
+ std::srand(m_last_ping_value);
+ m_last_ntstatus = INVALID_NTSTATUS;
+ srr = SendRecvWait(MEM_PING);
+ if (ping->rnd_kern != getLastPingValue())
+ return false;
+ return srr == SRR_SIGNALED;
+}
+
+bool KInterface::Pages(HANDLE targetPID,
+ std::vector<MEMORY_BASIC_INFORMATION>& dest,
+ PVOID start_address)
+{
+ PKERNEL_PAGE pages = (PKERNEL_PAGE)getBuffer();
+ const ULONGLONG max_pages = (SHMEM_SIZE - sizeof *pages +
+ sizeof pages->pages_start) / sizeof pages->pages_start;
+ SendRecvReturn srr;
+ bool success = false;
+
+ do {
+ m_last_ntstatus = INVALID_NTSTATUS;
+ pages->pages = 0;
+ pages->ProcessId = targetPID;
+ pages->StartAddress = start_address;
+ srr = SendRecvWait(MEM_PAGES);
+ if (srr == SRR_SIGNALED) {
+ m_last_ntstatus = pages->StatusRes;
+ if (validateRespone(getBuffer()) == MEM_PAGES &&
+ !pages->StatusRes &&
+ pages->pages * sizeof(pages->pages_start) <= SHMEM_SIZE)
+ {
+ for (SIZE_T i = 0; i < pages->pages; ++i) {
+ dest.push_back((&pages->pages_start)[i]);
+ start_address = (PVOID)
+ ((ULONG_PTR)((&pages->pages_start)[i].BaseAddress)
+ + (&pages->pages_start)[i].RegionSize);
+ }
+ success = true;
+ }
+ else {
+ success = false;
+ break;
+ }
+ }
+ } while (srr == SRR_SIGNALED && pages->pages == max_pages && pages->pages);
+ return success && srr == SRR_SIGNALED;;
+}
+
+bool KInterface::Modules(HANDLE targetPID,
+ std::vector<MODULE_DATA>& dest)
+{
+ PKERNEL_MODULES mods = (PKERNEL_MODULES)getBuffer();
+ SIZE_T start_index = 0;
+ const ULONGLONG max_mods = (SHMEM_SIZE - sizeof *mods +
+ sizeof mods->modules_start) / sizeof mods->modules_start;
+ SendRecvReturn srr;
+ bool success = false;
+
+ do {
+ m_last_ntstatus = INVALID_NTSTATUS;
+ mods->modules = 0;
+ mods->ProcessId = targetPID;
+ mods->StartIndex = start_index;
+ srr = SendRecvWait(MEM_MODULES);
+ if (srr == SRR_SIGNALED) {
+ m_last_ntstatus = mods->StatusRes;
+ if (validateRespone(getBuffer()) == MEM_MODULES &&
+ !mods->StatusRes &&
+ mods->modules * sizeof(mods->modules_start) <= SHMEM_SIZE)
+ {
+ for (SIZE_T i = 0; i < mods->modules; ++i) {
+ dest.push_back((&mods->modules_start)[i]);
+ start_index++;
+ }
+ success = true;
+ }
+ else {
+ success = false;
+ break;
+ }
+ }
+ } while (srr == SRR_SIGNALED && mods->modules == max_mods && mods->modules);
+ return success && srr == SRR_SIGNALED;
+}
+
+bool KInterface::Exit()
+{
+ m_last_ntstatus = INVALID_NTSTATUS;
+ return SendRecvWait(MEM_EXIT, INFINITE) == SRR_SIGNALED;
+}
+
+bool KInterface::RPM(HANDLE targetPID, PVOID address, BYTE *buf, SIZE_T size,
+ PKERNEL_READ_REQUEST result)
+{
+ PKERNEL_READ_REQUEST rr = (PKERNEL_READ_REQUEST)getBuffer();
+ m_last_ntstatus = INVALID_NTSTATUS;
+ if (size > SHMEM_SIZE - sizeof *rr)
+ return false;
+ rr->ProcessId = targetPID;
+ rr->Address = address;
+ rr->SizeReq = size;
+ rr->SizeRes = (SIZE_T)-1;
+ rr->StatusRes = (NTSTATUS)-1;
+ if (SendRecvWait(MEM_RPM) == SRR_SIGNALED) {
+ m_last_ntstatus = rr->StatusRes;
+ if (rr->StatusRes ||
+ rr->SizeRes != size)
+ {
+ std::stringstream err_str;
+ err_str << "Call RPM(0x" << std::hex << address
+ << "," << std::dec << size
+ << ") failed with 0x"
+ << std::hex << rr->StatusRes
+ << " (Size Req/Res: "
+ << std::dec << rr->SizeReq << "/" << (SSIZE_T)rr->SizeRes
+ << ")";
+ throw std::runtime_error(err_str.str());
+ }
+ memcpy(buf, (BYTE *)rr + sizeof *rr, size);
+ if (result)
+ *result = *rr;
+ return true;
+ }
+ return false;
+}
+
+bool KInterface::WPM(HANDLE targetPID, PVOID address, BYTE *buf, SIZE_T size,
+ PKERNEL_WRITE_REQUEST result)
+{
+ PKERNEL_WRITE_REQUEST wr = (PKERNEL_WRITE_REQUEST)getBuffer();
+ m_last_ntstatus = INVALID_NTSTATUS;
+ if (size > SHMEM_SIZE - sizeof *wr)
+ return false;
+ wr->ProcessId = targetPID;
+ wr->Address = address;
+ wr->SizeReq = size;
+ wr->SizeRes = (SIZE_T)-1;
+ wr->StatusRes = (NTSTATUS)-1;
+ memcpy((BYTE *)wr + sizeof *wr, buf, size);
+ if (SendRecvWait(MEM_WPM) == SRR_SIGNALED) {
+ m_last_ntstatus = wr->StatusRes;
+ if (wr->StatusRes ||
+ wr->SizeRes != size)
+ {
+ std::stringstream err_str;
+ err_str << "Call WPM(0x" << std::hex << address
+ << "," << std::dec << size
+ << ") failed with 0x"
+ << std::hex << wr->StatusRes
+ << " (Size Req/Res: "
+ << std::dec << wr->SizeReq << "/" << (SSIZE_T)wr->SizeRes
+ << ")";
+ throw std::runtime_error(err_str.str());
+ }
+ if (result)
+ *result = *wr;
+ return true;
+ }
+ return false;
+}
+
+PVOID KInterface::getBuffer() {
+ if (!m_shmem)
+ throw std::runtime_error("Call Init() before..");
+ return m_shmem;
+}
+
+HANDLE KInterface::getKHandle() {
+ if (!m_kevent)
+ throw std::runtime_error("Call Init() before..");
+ return m_kevent;
+}
+
+HANDLE KInterface::getUHandle() {
+ if (!m_uevent)
+ throw std::runtime_error("Call Init() before..");
+ return m_uevent;
+}
+
+UINT32 KInterface::getLastPingValue() {
+ return m_last_ping_value;
+}
+
+UINT32 KInterface::getLastNtStatus() {
+ return m_last_ntstatus;
+}
+
+SendRecvReturn KInterface::SendRecvWait(UINT32 type, DWORD timeout)
+{
+ prepareRequest(getBuffer(), type);
+ if (!SetEvent(m_kevent))
+ return SRR_ERR_KEVENT;
+ return RecvWait(timeout);
+}
+
+SendRecvReturn KInterface::RecvWait(DWORD timeout)
+{
+ switch (WaitForSingleObject(m_uevent, timeout)) {
+ case WAIT_OBJECT_0:
+ return validateRespone(getBuffer()) != INVALID_REQUEST ? SRR_SIGNALED : SRR_ERR_HEADER;
+ case WAIT_TIMEOUT:
+ return SRR_TIMEOUT;
+ }
+ return SRR_ERR_UEVENT;
+}
+
+SSIZE_T KScan::KScanSimple(HANDLE targetPID, PVOID start_address, SIZE_T max_scansize,
+ PVOID scanbuf, SIZE_T scanbuf_size)
+{
+ ULONG_PTR max_addr;
+ ULONG_PTR cur_addr = (ULONG_PTR)start_address;
+ BYTE tmp_rpmbuf[SHMEM_SIZE];
+ SIZE_T scan_index, processed, real_size, diff_size;
+ std::vector<MEMORY_BASIC_INFORMATION> mbis;
+ KERNEL_READ_REQUEST rr = { 0 };
+
+ if (max_scansize < scanbuf_size)
+ return -1;
+ if (!KInterface::getInstance().Pages(targetPID, mbis, start_address))
+ return -1;
+
+ diff_size = (ULONG_PTR)start_address - (ULONG_PTR)mbis.at(0).BaseAddress;
+ real_size = (mbis.at(0).RegionSize - diff_size > max_scansize ?
+ max_scansize : (ULONG_PTR)mbis.at(0).RegionSize - diff_size);
+ max_addr = (ULONG_PTR)start_address + real_size;
+
+ while (cur_addr < max_addr) {
+ if (!KInterface::getInstance().RPM(targetPID, (PVOID)cur_addr,
+ tmp_rpmbuf, (sizeof tmp_rpmbuf > real_size ? real_size : sizeof tmp_rpmbuf), &rr))
+ {
+ break;
+ }
+
+ if (rr.StatusRes || rr.SizeRes < scanbuf_size)
+ break;
+
+ for (processed = 0, scan_index = 0; processed < rr.SizeRes; ++processed) {
+ if (tmp_rpmbuf[processed] != *((BYTE*)scanbuf + scan_index)) {
+ scan_index = 0;
+ }
+ else {
+ scan_index++;
+ if (scan_index == scanbuf_size) {
+ return cur_addr + processed - scanbuf_size + 1;
+ }
+ }
+ }
+ cur_addr += processed;
+ real_size -= processed;
+ }
+ return -1;
+}
+
+SSIZE_T KScan::KBinDiffSimple(HANDLE targetPID, PVOID start_address,
+ BYTE *curbuf, BYTE *oldbuf, SIZE_T siz, std::vector<std::pair<SIZE_T, SIZE_T>> *diffs)
+{
+ SSIZE_T scanned, diff_start;
+ SIZE_T diff_size;
+ KERNEL_READ_REQUEST rr = { 0 };
+
+ if (!KInterface::getInstance().RPM(targetPID, start_address,
+ curbuf, siz, &rr))
+ {
+ scanned = -1;
+ }
+ else scanned = rr.SizeRes;
+
+ if (scanned > 0) {
+ diffs->clear();
+ diff_start = -1;
+ diff_size = 0;
+ for (SIZE_T i = 0; i < (SIZE_T)scanned; ++i) {
+ if (curbuf[i] != oldbuf[i]) {
+ if (diff_start < 0)
+ diff_start = i;
+ diff_size++;
+ }
+ else if (diff_start >= 0) {
+ diffs->push_back(std::pair<SIZE_T, SIZE_T>
+ (diff_start, diff_size));
+ diff_start = -1;
+ diff_size = 0;
+ }
+ }
+ memcpy(oldbuf, curbuf, scanned);
+ if ((SIZE_T)scanned < siz)
+ memset(oldbuf + scanned, 0, siz - scanned);
+ }
+
+ return scanned;
+} \ No newline at end of file
diff --git a/KTest/KInterface.h b/KTest/KInterface.h
new file mode 100644
index 0000000..a8a7ee2
--- /dev/null
+++ b/KTest/KInterface.h
@@ -0,0 +1,120 @@
+#pragma once
+
+#include "Driver.h"
+
+#include <vector>
+#include <Windows.h>
+
+#define DEFAULT_TIMEOUT 2500
+#define INVALID_NTSTATUS (UINT32)-1
+
+typedef enum SendRecvReturn {
+ SRR_INVALID = 0, SRR_SIGNALED, SRR_TIMEOUT, SRR_ERR_UEVENT, SRR_ERR_KEVENT, SRR_ERR_HEADER
+} SendRecvReturn;
+
+class KInterface
+{
+public:
+ static KInterface& getInstance()
+ {
+ static KInterface instance;
+ return instance;
+ }
+ KInterface();
+ KInterface(KInterface const&) = delete;
+ void operator=(KInterface const&) = delete;
+
+ bool Init();
+ bool Handshake();
+ bool Ping();
+ bool Pages(HANDLE targetPID,
+ std::vector<MEMORY_BASIC_INFORMATION>& dest,
+ PVOID start_address = NULL);
+ bool Modules(HANDLE targetPID,
+ std::vector<MODULE_DATA>& dest);
+ bool Exit();
+ bool RPM(HANDLE targetPID, PVOID address, BYTE *buf, SIZE_T size,
+ PKERNEL_READ_REQUEST result);
+ bool WPM(HANDLE targetPID, PVOID address, BYTE *buf, SIZE_T size,
+ PKERNEL_WRITE_REQUEST result);
+
+ PVOID getBuffer();
+ HANDLE getKHandle();
+ HANDLE getUHandle();
+ UINT32 getLastPingValue();
+ UINT32 getLastNtStatus();
+ SendRecvReturn RecvWait(DWORD timeout = DEFAULT_TIMEOUT);
+
+private:
+ SendRecvReturn SendRecvWait(UINT32 type, DWORD timeout = DEFAULT_TIMEOUT);
+
+ PVOID m_shmem = NULL;
+ HANDLE m_kevent = NULL, m_uevent = NULL;
+
+ UINT32 m_last_ping_value = 0;
+ UINT32 m_last_ntstatus = INVALID_NTSTATUS;
+};
+
+class KMemory
+{
+public:
+ template <class T>
+ static T Rpm(HANDLE targetPID, PVOID address) {
+ T buf;
+ if (!KInterface::getInstance().RPM(targetPID, address, (BYTE*)&buf, sizeof buf, NULL))
+ throw std::runtime_error("KMemory RPM failed");
+ return buf;
+ }
+ template <class T>
+ static void Wpm(HANDLE targetPID, PVOID address, T *buf) {
+ if (!KInterface::getInstance().WPM(targetPID, address, (BYTE*)buf, sizeof *buf, NULL))
+ throw std::runtime_error("KMemory WPM failed");
+ }
+};
+
+class KMemoryBuf
+{
+public:
+ template <size_t SIZE>
+ static SSIZE_T Rpm(HANDLE targetPID, PVOID address, BYTE *dest) {
+ KERNEL_READ_REQUEST rr = { 0 };
+ if (!KInterface::getInstance().RPM(targetPID, address, &dest[0], SIZE, &rr))
+ return -1;
+ return rr.SizeRes;
+ }
+ template <size_t SIZE>
+ static SSIZE_T Wpm(HANDLE targetPID, PVOID address, BYTE *dest) {
+ KERNEL_WRITE_REQUEST wr = { 0 };
+ if (!KInterface::getInstance().WPM(targetPID, address, &dest[0], SIZE, &wr))
+ return -1;
+ return wr.SizeRes;
+ }
+};
+
+template <SIZE_T SIZE>
+struct Diff {
+ BYTE current_buffer[SIZE];
+ BYTE old_buffer[SIZE];
+ std::vector<std::pair<SIZE_T, SIZE_T>> diffs;
+};
+
+class KScan
+{
+public:
+ template <typename T, SIZE_T SIZE>
+ static SSIZE_T ScanSimple(HANDLE targetPID, PVOID start_address, SIZE_T max_scansize, T(&a)[SIZE])
+ {
+ return KScanSimple(targetPID, start_address, max_scansize, a, sizeof T * SIZE);
+ }
+ template <SIZE_T SIZE>
+ static SSIZE_T BinDiffSimple(HANDLE targetPID, PVOID start_address, Diff<SIZE> *diff)
+ {
+ return KBinDiffSimple(targetPID, start_address, diff->current_buffer,
+ diff->old_buffer, SIZE, &diff->diffs);
+ }
+private:
+ static SSIZE_T KScanSimple(HANDLE targetPID, PVOID start_address, SIZE_T max_scansize,
+ PVOID scanbuf, SIZE_T scanbuf_size);
+ static SSIZE_T KBinDiffSimple(HANDLE targetPid, PVOID start_address,
+ BYTE *curbuf, BYTE *oldbuf, SIZE_T siz, std::vector<std::pair<SIZE_T, SIZE_T>> *diffs);
+}; \ No newline at end of file
diff --git a/KTest/KTest.cpp b/KTest/KTest.cpp
new file mode 100644
index 0000000..4dad138
--- /dev/null
+++ b/KTest/KTest.cpp
@@ -0,0 +1,400 @@
+#include "pch.h"
+#include "Driver.h"
+#include "KInterface.h"
+
+#include <iostream>
+#include <iomanip>
+#include <windows.h>
+
+#pragma comment(lib, "User32.lib")
+
+#define WHEXOUT std::setfill(L'0') << std::setw(16) << std::hex
+
+BOOL running = false;
+const wchar_t *wName = L"HUNT";
+
+typedef struct SSystemGlobalEnvironment
+{
+ PVOID pDialogSystem;
+ PVOID p3DEngine;
+ PVOID pNetwork;
+ PVOID pNetContext;
+ PVOID pLobby;
+ PVOID pScriptSystem;
+ PVOID pPhysicalWorld;
+ PVOID pFlowSystem;
+ PVOID pInput;
+ PVOID pStatoscope;
+ PVOID pCryPak;
+ PVOID pFileChangeMonitor;
+ PVOID pProfileLogSystem;
+ PVOID pParticleManager;
+ PVOID pOpticsManager;
+ PVOID pFrameProfileSystem;
+ PVOID pTimer;
+ PVOID pCryFont;
+ PVOID pGameFramework;
+ PVOID pLocalMemoryUsage;
+ PVOID pEntitySystem;
+ PVOID pConsole;
+ PVOID pAudioSystem;
+ PVOID pSystem;
+ PVOID pCharacterManager;
+ PVOID pAISystem;
+ PVOID pLog;
+ PVOID pCodeCheckpointMgr;
+ PVOID pMovieSystem;
+ PVOID pNameTable;
+ PVOID pRenderer;
+ PVOID pAuxGeomRenderer;
+ PVOID pHardwareMouse;
+ PVOID pMaterialEffects;
+ PVOID pJobManager;
+ PVOID pOverloadSceneManager;
+ PVOID pFlashUI;
+ PVOID pUIFramework;
+ PVOID pServiceNetwork;
+ PVOID pRemoteCommandManager;
+ PVOID pDynamicResponseSystem;
+ PVOID pThreadManager;
+ PVOID pScaleformHelper; // nullptr when Scaleform support is not enabled
+ PVOID pSchematyc;
+ PVOID pSchematyc2;
+ PVOID pReflection;
+
+ PVOID pLiveCreateManager;
+ PVOID pLiveCreateHost;
+ PVOID pMonoRuntime;
+ UINT32 mMainThreadId; //!< The main thread ID is used in multiple systems so should be stored globally.
+ UINT32 nMainFrameID;
+ const char* szCmdLine = ""; //!< Startup command line.
+
+ //! Generic debug string which can be easily updated by any system and output by the debug handler
+ enum { MAX_DEBUG_STRING_LENGTH = 128 };
+ char szDebugStatus[MAX_DEBUG_STRING_LENGTH];
+
+ //! Used to tell if this is a server/multiplayer instance
+ bool bServer;
+ bool bMultiplayer;
+ bool bHostMigrating;
+ int bDeepProfiling;
+ bool bBootProfilerEnabledFrames;
+ PVOID callbackStartSection;
+ PVOID callbackEndSection;
+ //////////////////////////////////////////////////////////////////////////
+
+ //! Whether we are running unattended, disallows message boxes and other blocking events that require human intervention
+ bool bUnattendedMode;
+ //! Whether we are unit testing
+ bool bTesting;
+
+ bool bNoRandomSeed;
+} SSystemGlobalEnvironment;
+
+
+
+bool consoleHandler(int signal) {
+ if (signal == CTRL_C_EVENT) {
+ if (!running)
+ exit(EXIT_FAILURE);
+ running = false;
+ std::wcout << L"Waiting for graceful shutdown .." << std::endl;
+ }
+ return true;
+}
+
+void printBuf(UCHAR *buf, SIZE_T siz, SIZE_T bytesBeforeNewline) {
+ unsigned int i, j;
+ const unsigned char colors[] = { 10,11,12,13,14,15 };
+ HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ for (i = 0, j = 0; i < siz; ++i) {
+ if (i % bytesBeforeNewline == 0) {
+ SetConsoleTextAttribute(hConsole, colors[j++ % (sizeof colors)]);
+ wprintf(L"\n0x%04X: ", i);
+ }
+ wprintf(L"%02X ", buf[i]);
+ }
+ wprintf(L"\n");
+ SetConsoleTextAttribute(hConsole, 15);
+}
+
+BOOL CALLBACK enumWindowsProc(HWND hWnd, LPARAM lParam)
+{
+ int length = GetWindowTextLength(hWnd);
+ TCHAR* buffer;
+ buffer = new TCHAR[length + 1];
+ memset(buffer, 0, (length + 1) * sizeof(TCHAR));
+ GetWindowText(hWnd, buffer, length + 1);
+ if (!wcscmp(buffer, wName))
+ *(HWND *)lParam = hWnd;
+ delete[] buffer;
+ return TRUE;
+}
+
+int wmain(int argc, wchar_t **argv)
+{
+ HANDLE targetPID = 0;
+ PVOID buf;
+ HANDLE kevent;
+ HANDLE uevent;
+
+ KInterface &ki = KInterface::getInstance();
+ std::vector<MEMORY_BASIC_INFORMATION> pages;
+ std::vector<MODULE_DATA> modules;
+
+ if (argc > 1 && !wcscmp(argv[1], L"test")) {
+ return 0;
+ }
+
+ if (argc > 1 && !wcscmp(argv[1], L"wnd")) {
+ if (argc < 3) {
+ std::wcout << L"Window title required!" << std::endl;
+ return 1;
+ }
+ wName = argv[2];
+ std::wcout << L"Waiting for window title: '" << wName << L"'" << std::endl;
+
+ HWND targetHWND = NULL;
+ while (1) {
+ if (!EnumWindows(enumWindowsProc, (LPARAM)&targetHWND)) {
+ return 1;
+ }
+ if (targetHWND) {
+ std::wcout << L"Found window '" << wName << L"' with Handle 0x"
+ << std::hex << targetHWND << std::endl;
+ break;
+ }
+ Sleep(1000);
+ }
+ GetWindowThreadProcessId(targetHWND, (LPDWORD)&targetPID);
+ }
+
+ SetConsoleCtrlHandler((PHANDLER_ROUTINE)consoleHandler, TRUE);
+
+ if (!ki.Init()) {
+ std::wcout << L"Kernel Interface Init() failed" << std::endl;
+ return 1;
+ }
+
+ try {
+ buf = ki.getBuffer();
+ kevent = ki.getKHandle();
+ uevent = ki.getUHandle();
+ }
+ catch (std::runtime_error& err) {
+ std::wcout << err.what() << std::endl;
+ return 1;
+ }
+
+ std::wcout << L"Buffer.: " << buf << std::endl;
+ std::wcout << L"KHandle: " << kevent << std::endl;
+ std::wcout << L"UHandle: " << uevent << std::endl;
+
+ if (!ki.Handshake()) {
+ std::wcout << L"Kernel Interface Handshake() failed" << std::endl;
+ return 1;
+ }
+ if (targetPID) {
+ if (!ki.Modules(targetPID, modules))
+ std::wcout << L"Kernel Interface Modules() failed with 0x"
+ << std::hex << ki.getLastNtStatus() << std::endl;
+ else std::wcout << L"Got " << std::dec << modules.size() << L" modules for pid 0x"
+ << std::hex << targetPID << std::endl;
+ if (!ki.Pages(targetPID, pages))
+ std::wcout << L"Kernel Interface Pages() failed with 0x"
+ << std::hex << ki.getLastNtStatus() << std::endl;
+ else std::wcout << L"Got " << std::dec << pages.size() << L" mapped pages for pid 0x"
+ << std::hex << targetPID << std::endl;
+ }
+
+ running = TRUE;
+ do {
+ if (ki.RecvWait() == SRR_TIMEOUT) {
+ std::wcout << L"Ping -> ";
+ if (!ki.Ping()) {
+ std::wcout << L"Got no valid PONG, abort!" << std::endl;
+ running = FALSE;
+ }
+ else std::wcout << L"PONG!" << std::endl;
+ }
+
+ if (!running)
+ break;
+
+ try {
+ if (targetPID) {
+ for (MODULE_DATA& md : modules) {
+ if (!strncmp(md.BaseDllName, "CrySystem.dll",
+ sizeof md.BaseDllName))
+ {
+ std::wcout << L"CrySystem.dll......: 0x" << WHEXOUT << md.DllBase << std::endl;
+ UINT64 g_pEnv = KMemory::Rpm<UINT64>(targetPID,
+ (PVOID)((UINT64)md.DllBase + 0xA37708));
+
+ std::wcout << L"g_pEnv.............: 0x" << WHEXOUT << g_pEnv << std::endl;
+ }
+ else
+ if (!strncmp(md.BaseDllName, "CryEntitySystem.dll",
+ sizeof md.BaseDllName))
+ {
+ std::wcout << L"CryEntitySystem.dll: 0x" << std::hex << md.DllBase << std::endl;
+#if 1
+ /* Found: void CEntitySystem::LoadInternalState(IDataReadStream& reader) */
+ UINT64 g_pEnv = KMemory::Rpm<UINT64>(targetPID,
+ (PVOID)((UINT64)md.DllBase + 0x28C400));
+
+ std::wcout << L"g_pEnv.............: 0x" << WHEXOUT << g_pEnv << std::endl;
+#if 1
+ BYTE tmp[sizeof SSystemGlobalEnvironment * 2] = { 0 };
+ SSIZE_T siz = KMemoryBuf::Rpm<sizeof tmp>(targetPID, (PVOID)(g_pEnv), tmp);
+
+ SSystemGlobalEnvironment *gEnv = (SSystemGlobalEnvironment *)&tmp[0];
+ std::wcout << std::hex
+ << gEnv->p3DEngine << ", "
+ << gEnv->pEntitySystem << ", "
+ << gEnv->bMultiplayer << ", "
+ << gEnv->mMainThreadId << ", "
+ << gEnv->nMainFrameID << ", "
+ << gEnv->szDebugStatus << ", "
+ << gEnv->pMonoRuntime << ", "
+ << gEnv->callbackStartSection << ", "
+ << gEnv->callbackEndSection << ", "
+ << gEnv->bUnattendedMode << ", "
+ << gEnv->bTesting << ", "
+ << gEnv->bNoRandomSeed << ", "
+ << gEnv->bDeepProfiling << ", "
+ << std::endl;
+
+ /* Found: void CEntitySystem::LoadInternalState(IDataReadStream& reader)
+ * search for String "ExistingEntity: '%s' '%s'"
+ */
+ UINT64 m_EntityArray = KMemory::Rpm<UINT64>(targetPID,
+ (PVOID)((UINT64)gEnv->pEntitySystem + 0x40078));
+ //m_EntityArray += 0x40078;
+ std::wcout << WHEXOUT
+ << m_EntityArray
+ << std::endl;
+
+ USHORT nops;
+ nops = KMemory::Rpm<USHORT>(targetPID,
+ (PVOID)((UINT64)md.DllBase + 0x12C3C7));
+ std::wcout << std::hex << "+++ " << nops << std::endl;
+ nops = 0x9090;
+ KMemory::Wpm<USHORT>(targetPID,
+ (PVOID)((UINT64)md.DllBase + 0x12C3C7), &nops);
+#if 0
+ UINT64 tmp2[1024];
+ SSIZE_T siz2 = KMemoryBuf::Rpm<sizeof tmp2>(targetPID, (PVOID)(m_EntityArray), (PBYTE)tmp2);
+ SIZE_T i = 0;
+ for (UINT64 val : tmp2) {
+ if (val)
+ std::wcout << WHEXOUT << val << ", ";
+ if (++i % 16 == 0)
+ std::wcout << std::endl;
+ }
+ /*
+ if (siz2 > 0)
+ printBuf(tmp2, sizeof tmp2, 64);
+ */
+#endif
+#endif
+#if 0
+ SSIZE_T siz3;
+ static Diff<65535> diff = { 0 };
+ siz3 = KScan::BinDiffSimple(targetPID, (PVOID)(m_EntityArray), &diff);
+ if (siz3 > 0) {
+ std::wcout << L"Got " << std::dec << diff.diffs.size() << L" diffs" << std::endl;
+ for (auto& e : diff.diffs) {
+ std::wcout << std::dec << L"0x"
+ << std::hex << (PVOID)(/*(ULONG_PTR)(m_EntityArray)+*/e.first)
+ << " - " << std::hex << e.second
+ << L": ";
+ printBuf((UCHAR *)((ULONG_PTR)(diff.current_buffer) + e.first), e.second, e.second);
+ }
+ }
+#endif
+#if 0
+#if 1
+ //UCHAR scan[1024] = { 0 };
+ UCHAR scan[] = "anti_alles";
+ SSIZE_T found = KScan::ScanSimple<UCHAR, sizeof scan>(targetPID,
+ (PVOID)(m_EntityArray), 65535, scan);
+#else
+ SSIZE_T found = (SSIZE_T)(pIEntitySystem)+8192;
+#endif
+ if (found >= 0) {
+ std::wcout << "FOUND: 0x" << std::hex << (PVOID)found << std::endl;
+ UCHAR tmp[4096] = { 0 };
+ SSIZE_T siz = KMemoryBuf::Rpm<UCHAR, sizeof tmp>(targetPID, (PVOID)found, tmp);
+ if (siz > 0) {
+ printBuf(tmp, sizeof tmp, 64);
+#if 0
+ UINT64 i;
+ for (i = 0; i < sizeof tmp; i += 8) {
+ UINT64 value = *(UINT64 *)&tmp[i];
+ if (value)
+ printf("0x%p ", (PVOID)value);
+ }
+ printf("\nGot %llu entities ..\n", i);
+#endif
+ }
+ }
+#endif
+#endif
+ }
+#if 0
+ else if (!strncmp(md.BaseDllName, "CryRenderD3D11.dll",
+ sizeof md.BaseDllName))
+ {
+ UINT32 displayWidth = KMemory::Rpm<UINT32>(targetPID,
+ (PVOID)((ULONGLONG)md.DllBase + /* 0x19F0FE */ 0x5EA870));
+ UINT32 displayHeight = KMemory::Rpm<UINT32>(targetPID,
+ (PVOID)((ULONGLONG)md.DllBase + /* 0x19F0F0 */ 0x5EA9DC));
+ std::wcout << L"Display.........: " << std::dec << displayWidth
+ << " x " << displayHeight << std::endl;
+ }
+#endif
+#if 0
+ else if (!strncmp(md.BaseDllName, "ntdll.dll",
+ sizeof md.BaseDllName))
+ {
+ UCHAR tmp[8192] = { 0 };
+ SSIZE_T siz = KMemoryBuf::Rpm<UCHAR, sizeof tmp>(targetPID, (PVOID)((ULONGLONG)md.DllBase), tmp);
+ /*
+ if (siz > 0)
+ printBuf(tmp, sizeof tmp, 64);
+
+ UCHAR scan[] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC };
+ SSIZE_T found = KScan::ScanSimple<UCHAR, sizeof scan>(targetPID,
+ (PVOID)((ULONGLONG)md.DllBase), sizeof tmp, scan);
+ std::wcout << "FOUND: 0x" << std::hex << (found - (ULONGLONG)md.DllBase) << std::endl;
+ */
+ static Diff<10> diff = { 0 };
+ siz = KScan::BinDiffSimple(targetPID, (PVOID)((ULONGLONG)md.DllBase), &diff);
+ if (siz > 0) {
+ std::wcout << L"Got " << std::dec << diff.diffs.size() << L" diffs" << std::endl;
+ for (auto& e : diff.diffs) {
+ printBuf((UCHAR *)((ULONGLONG)md.DllBase + e.first), e.second, e.second);
+ /*
+ std::wcout << std::dec << L" addr: " << e.first
+ << std::endl << L" size: " << e.second
+ << std::endl;
+ */
+ }
+ }
+ }
+#endif
+ }
+ }
+ }
+ catch (std::runtime_error& err) {
+ std::wcout << err.what() << std::endl;
+ }
+ } while (running);
+
+ std::wcout << L"Driver shutdown .." << std::endl;
+ ki.Exit();
+
+ return 0;
+} \ No newline at end of file
diff --git a/KTest/KTest.vcxproj b/KTest/KTest.vcxproj
new file mode 100644
index 0000000..952a888
--- /dev/null
+++ b/KTest/KTest.vcxproj
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>15.0</VCProjectVersion>
+ <ProjectGuid>{8661069D-CE09-4A70-8C75-8F33E77732E6}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>KTest</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <SpectreMitigation>false</SpectreMitigation>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <SpectreMitigation>false</SpectreMitigation>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <UseOfMfc>Static</UseOfMfc>
+ <SpectreMitigation>false</SpectreMitigation>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <SpectreMitigation>false</SpectreMitigation>
+ <UseOfMfc>Static</UseOfMfc>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <ExceptionHandling>SyncCThrow</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(VCToolsInstallDir)lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <ExceptionHandling>SyncCThrow</ExceptionHandling>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(VCToolsInstallDir)lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="..\include\Driver.h" />
+ <ClInclude Include="KInterface.h" />
+ <ClInclude Include="pch.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="KInterface.cpp" />
+ <ClCompile Include="KTest.cpp" />
+ <ClCompile Include="pch.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/KTest/KTest.vcxproj.filters b/KTest/KTest.vcxproj.filters
new file mode 100644
index 0000000..80c6481
--- /dev/null
+++ b/KTest/KTest.vcxproj.filters
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="pch.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="KInterface.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\include\Driver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="pch.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="KTest.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="KInterface.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/KTest/pch.cpp b/KTest/pch.cpp
new file mode 100644
index 0000000..3a3d12b
--- /dev/null
+++ b/KTest/pch.cpp
@@ -0,0 +1,5 @@
+// pch.cpp: source file corresponding to pre-compiled header; necessary for compilation to succeed
+
+#include "pch.h"
+
+// In general, ignore this file, but keep it around if you are using pre-compiled headers.
diff --git a/KTest/pch.h b/KTest/pch.h
new file mode 100644
index 0000000..b04e71e
--- /dev/null
+++ b/KTest/pch.h
@@ -0,0 +1,14 @@
+// Tips for Getting Started:
+// 1. Use the Solution Explorer window to add/manage files
+// 2. Use the Team Explorer window to connect to source control
+// 3. Use the Output window to see build output and other messages
+// 4. Use the Error List window to view errors
+// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
+// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file
+
+#ifndef PCH_H
+#define PCH_H
+
+// TODO: add headers that you want to pre-compile here
+
+#endif //PCH_H
diff --git a/PastDSE-Manual-Map-Debug.bat b/PastDSE-Manual-Map-Debug.bat
new file mode 100644
index 0000000..316075b
--- /dev/null
+++ b/PastDSE-Manual-Map-Debug.bat
@@ -0,0 +1,13 @@
+@echo off
+
+set PDSECTRL="%~dp0\..\PastDSE\x64\Debug\PastDSECtrl.exe"
+if not exist %PDSECTRL% set PDSECTRL="%~dp0\..\PastDSE\bin\x64\Debug\PastDSECtrl.exe"
+
+call %~dp0\..\PastDSE\driver-start.bat
+%PDSECTRL% %~dp0\x64\Debug\KMemDriver.sys
+call %~dp0\..\PastDSE\driver-stop.bat
+REM fsutil usn deleteJournal /D C:
+
+REM set /p wndtitle="Enter Window Title: "
+REM IF [%wndtitle%] == [] (%~dp0\x64\Release\KTest.exe) ELSE (%~dp0\x64\Release\KTest.exe wnd "%wndtitle%")
+timeout /t 3 \ No newline at end of file
diff --git a/PastDSE-Manual-Map-Release.bat b/PastDSE-Manual-Map-Release.bat
new file mode 100644
index 0000000..2276725
--- /dev/null
+++ b/PastDSE-Manual-Map-Release.bat
@@ -0,0 +1,13 @@
+@echo off
+
+set PDSECTRL="%~dp0\..\PastDSE\x64\Debug\PastDSECtrl.exe"
+if not exist %PDSECTRL% set PDSECTRL="%~dp0\..\PastDSE\bin\x64\Debug\PastDSECtrl.exe"
+
+call %~dp0\..\PastDSE\driver-start.bat
+%PDSECTRL% %~dp0\x64\Release\KMemDriver.sys
+call %~dp0\..\PastDSE\driver-stop.bat
+REM fsutil usn deleteJournal /D C:
+
+REM set /p wndtitle="Enter Window Title: "
+REM IF [%wndtitle%] == [] (%~dp0\x64\Release\KTest.exe) ELSE (%~dp0\x64\Release\KTest.exe wnd "%wndtitle%")
+timeout /t 3 \ No newline at end of file
diff --git a/include/Driver.h b/include/Driver.h
new file mode 100644
index 0000000..6a41fe2
--- /dev/null
+++ b/include/Driver.h
@@ -0,0 +1,131 @@
+#pragma once
+
+#ifdef KERNEL_MODULE
+#include "Native.h"
+#else
+#include <windows.h>
+#endif
+
+#define HDR_MAGIC 0xDEADC0DE
+#define SHMEM_ADDR 0x60000000
+#define SHMEM_SIZE 8192*8*2
+#define INVALID_REQUEST (UINT32)-1
+
+#define MEM_HANDSHAKE 0x800
+#define MEM_PING 0x801
+#define MEM_MODULES 0x802
+#define MEM_PAGES 0x803
+#define MEM_RPM 0x804
+#define MEM_WPM 0x805
+#define MEM_EXIT 0x806
+
+typedef struct _KERNEL_HEADER
+{
+ UINT32 magic;
+ UINT32 type;
+} KERNEL_HEADER, *PKERNEL_HEADER;
+
+typedef struct _KERNEL_HANDSHAKE
+{
+ KERNEL_HEADER hdr;
+ HANDLE kevent;
+ HANDLE uevent;
+} KERNEL_HANDSHAKE, *PKERNEL_HANDSHAKE;
+
+typedef struct _KERNEL_PING
+{
+ KERNEL_HEADER hdr;
+ UINT32 rnd_user;
+ UINT32 rnd_kern;
+} KERNEL_PING, *PKERNEL_PING;
+
+typedef struct _KERNEL_PAGE
+{
+ KERNEL_HEADER hdr;
+ HANDLE ProcessId;
+ PVOID StartAddress;
+
+ NTSTATUS StatusRes;
+ SIZE_T pages;
+ MEMORY_BASIC_INFORMATION pages_start;
+} KERNEL_PAGE, *PKERNEL_PAGE;
+
+typedef struct _MODULE_DATA
+{
+ PVOID DllBase;
+ ULONG SizeOfImage;
+ CHAR BaseDllName[64];
+} MODULE_DATA, *PMODULE_DATA;
+
+typedef struct _KERNEL_MODULES
+{
+ KERNEL_HEADER hdr;
+ HANDLE ProcessId;
+ SIZE_T StartIndex;
+
+ NTSTATUS StatusRes;
+ SIZE_T modules;
+ MODULE_DATA modules_start;
+} KERNEL_MODULES, *PKERNEL_MODULES;
+
+typedef struct _KERNEL_EXIT
+{
+ KERNEL_HEADER hdr;
+} KERNEL_EXIT, *PKERNEL_EXIT;
+
+typedef struct _KERNEL_READ_REQUEST
+{
+ KERNEL_HEADER hdr;
+ HANDLE ProcessId;
+ PVOID Address;
+ SIZE_T SizeReq;
+
+ NTSTATUS StatusRes;
+ SIZE_T SizeRes;
+} KERNEL_READ_REQUEST, *PKERNEL_READ_REQUEST;
+
+typedef struct _KERNEL_WRITE_REQUEST
+{
+ KERNEL_HEADER hdr;
+ HANDLE ProcessId;
+ PVOID Address;
+ SIZE_T SizeReq;
+
+ NTSTATUS StatusRes;
+ SIZE_T SizeRes;
+} KERNEL_WRITE_REQUEST, *PKERNEL_WRITE_REQUEST;
+
+
+#ifndef KERNEL_MODULE
+static inline VOID prepareRequest(PVOID buf, UINT32 type)
+{
+ PKERNEL_HEADER hdr = (PKERNEL_HEADER)buf;
+ hdr->magic = HDR_MAGIC;
+ hdr->type = type;
+}
+#endif
+
+static inline UINT32
+#ifndef KERNEL_MODULE
+validateRespone
+#else
+validateRequest
+#endif
+(PVOID buf)
+{
+ PKERNEL_HEADER hdr = (PKERNEL_HEADER)buf;
+ if (hdr->magic != HDR_MAGIC)
+ return INVALID_REQUEST;
+ switch (hdr->type) {
+ case MEM_HANDSHAKE:
+ case MEM_PING:
+ case MEM_PAGES:
+ case MEM_MODULES:
+ case MEM_RPM:
+ case MEM_WPM:
+ case MEM_EXIT:
+ return hdr->type;
+ default:
+ return INVALID_REQUEST;
+ }
+} \ No newline at end of file