Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ENTIRE CODE IS WRITEN BY AI, AND THIS WAS ONLY A TEST PROJECT TO LEARN MORE ABOUT ORCHESTRATION

KernelMemReader

A Windows x64 kernel-mode project that:

  1. Hooks \Driver\Beep → IRP_MJ_DEVICE_CONTROL at runtime
  2. Intercepts a secret IOCTL (IOCTL_KMR_READ_PHYSICAL)
  3. Resolves the target process's CR3 via PsLookupProcessByProcessId
  4. Walks the x64 4-level page tables (PML4 → PDPT → PD → PT) using MmCopyMemory(MM_COPY_MEMORY_PHYSICAL) — supporting 4 KB, 2 MB and 1 GB pages
  5. Returns the raw physical bytes to user-mode through the IRP SystemBuffer

Project layout

KernelMemReader/
│
├── KernelMemReader.sln          Visual Studio 2022 solution
│
├── shared/
│   └── protocol.h               COMMAND_PACKET / RESPONSE_PACKET / IOCTL
│                                 (included by BOTH driver and client)
│
├── driver/
│   ├── driver.c                 DriverEntry, Hook install/remove,
│   │                             HandleReadPhysical dispatcher
│   ├── paging.h                 x64 page-table walker
│   ├── process_cr3.h            Version-aware DirectoryTableBase resolver
│   └── KernelMemReader.vcxproj  WDK WDM driver project (x64)
│
└── usermode/
    ├── client.c                 DeviceIoControl demo (CLI)
    └── KmrClient.vcxproj        Plain Win32 console app project (x64)

Communication protocol

User-mode                            Kernel (hook on \Driver\Beep)
─────────                            ──────────────────────────────
DeviceIoControl(
  IOCTL_KMR_READ_PHYSICAL,
  in  = COMMAND_PACKET,       ──►   validate magic / version
  out = RESPONSE_PACKET)            GetProcessCr3(pid)  →  CR3
                                    GetPhysicalAddress(va, cr3) → PA
                                    MmCopyMemory(PA, n bytes)
                              ◄──   RESPONSE_PACKET { NtStatus,
                                      PhysicalAddress, BytesRead,
                                      Data[4096] }

COMMAND_PACKET (32 bytes, packed)

Field Type Description
Magic ULONG Must be 0x4D524B55 ("UKRM")
Version ULONG Must be 1
TargetPid uintptr_t PID of the process to read from
VirtualAddress uintptr_t VA inside that process to translate
ReadSize ULONG 1 – 4096 bytes
_Reserved ULONG Zero

RESPONSE_PACKET (24 + 4096 = 4120 bytes, packed)

Field Type Description
NtStatus LONG STATUS_SUCCESS (0) or error code
PhysicalAddress uintptr_t Resolved physical address
BytesRead ULONG Valid bytes in Data[]
Data[4096] UCHAR[] Raw memory content

Build requirements

Component Version
Visual Studio 2019 or 2022
WDK 10.0.26100+
Target OS Windows 10 / 11 x64

Open KernelMemReader.sln, select x64 Debug or x64 Release, build.


Running (test environment only)

1 – Enable test signing

bcdedit /set testsigning on
shutdown /r /t 0

2 – Sign the driver with a test certificate

makecert -r -pe -ss PrivateCertStore -n "CN=KmrTest" KmrTest.cer
signtool sign /fd sha256 /a /s PrivateCertStore /n "KmrTest" ^
              x64\Debug\KernelMemReader.sys
certutil -addstore root KmrTest.cer

3 – Load the driver

sc create KmrDrv type= kernel start= demand ^
          binPath= "C:\path\to\x64\Debug\KernelMemReader.sys"
sc start KmrDrv

4 – Run the client

:: Read 64 bytes from PID 4 (System) at its load address
KmrClient.exe 4 0xFFFFF80000000000 64

:: Read 128 bytes from a user process
KmrClient.exe 1234 0x00007FF712340000 128

5 – Unload

sc stop  KmrDrv
sc delete KmrDrv

Viewing debug output

Use DebugView (Sysinternals) with [x] Capture Kernel enabled, or attach WinDbg and watch the [KMR] prefixed log lines.


Security notes

  • PatchGuard: Modifying DRIVER_OBJECT.MajorFunction[] at runtime is monitored by Kernel Patch Protection on x64 Windows 8+. This project is strictly for controlled research / lab environments.

  • Recommended alternative: For production filtering use IoAttachDeviceToDeviceStack (device-stack filter) or a WDF minifilter rather than a raw dispatch-table hook.

  • IRQL: All code runs at PASSIVE_LEVEL (inherited from the user-mode calling thread). MmCopyMemory and RtlGetVersion require this level.

  • Privilege: Opening \Device\Beep does not require administrator rights; however loading the driver does.


Architecture summary

DriverEntry
 └─ InstallHook()
     └─ ObReferenceObjectByName(\Driver\Beep)
         └─ InterlockedExchangePointer(MajorFunction[DEVICE_CONTROL],
                                       HookedDeviceControl)

IRP_MJ_DEVICE_CONTROL received
 └─ HookedDeviceControl()
     ├─ ioctl == IOCTL_KMR_READ_PHYSICAL ?
     │    └─ HandleReadPhysical()
     │         ├─ Validate COMMAND_PACKET (magic, version, size)
     │         ├─ GetProcessCr3(pid)
     │         │    ├─ EnsureDtbOffsetInitialised()  [RtlGetVersion, cached]
     │         │    └─ PsLookupProcessByProcessId()
     │         │         └─ *(EPROCESS + 0x28)  →  CR3
     │         ├─ GetPhysicalAddressEx(va, cr3)
     │         │    PML4[va[47:39]] → PDPT[va[38:30]] → PD[va[29:21]]
     │         │    → PT[va[20:12]] + offset  (or 2MB/1GB early-exit)
     │         ├─ MmCopyMemory(physAddr, n, MM_COPY_MEMORY_PHYSICAL)
     │         └─ Write RESPONSE_PACKET → IRP SystemBuffer
     └─ else → g_OriginalBeepDispatch(DevObj, Irp)

DriverUnload
 └─ RemoveHook()
     └─ InterlockedExchangePointer(MajorFunction[DEVICE_CONTROL], original)

About

very very simple kernel read driver using IRP_MJ_DEVICE_CONTROL to hook on \Driver\Beep as well as a Version aware CR3 extraction from PEPROCESS

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages