Detect & Block Read/WriteProcessMemory calls from a Driver

4k views Asked by At

Hi i'm relativly new to kernel programming (i've got a lot of c++ development experience though) and have a goal that i want to achieve:

Detecting and conditionally blocking attempts from userland programs to write or read to specific memory addresses located in my own userland process. This has to be done from a driver.

I've setup a development enviorment (virtual machine running the latest windows 10 + virtualkd + windbg) and already successfully deployed a small kmdf test driver via the visual studio integration (over lan).

So my question is now: How do i detect/intercept Read/WriteProcessMemory calls to my ring3 application? Simply blocking handles isn't enough here.

It would be nice if some one could point me into the right direction either by linking (a non outdated) example or just by telling me how to do this.

Update: Read a lot about filter drivers and hooking Windows Apis from kernel mode, but i really dont want to mess with Patchguard and dont really know how to filter RPM calls from userland. Its not important to protect my program from drivers, only from ring3 applications.

Thank you :)

1

There are 1 answers

1
AudioBubble On

This code from here should do the trick.

OB_PREOP_CALLBACK_STATUS PreCallback(PVOID RegistrationContext, 
POB_PRE_OPERATION_INFORMATION OperationInformation)
    {
UNREFERENCED_PARAMETER(RegistrationContext);

PEPROCESS OpenedProcess = (PEPROCESS)OperationInformation->Object,
    CurrentProcess = PsGetCurrentProcess();

PsLookupProcessByProcessId(ProtectedProcess, &ProtectedProcessProcess); // Getting the PEPROCESS using the PID 
PsLookupProcessByProcessId(Lsass, &LsassProcess); // Getting the PEPROCESS using the PID 
PsLookupProcessByProcessId(Csrss1, &Csrss1Process); // Getting the PEPROCESS using the PID 
PsLookupProcessByProcessId(Csrss2, &Csrss2Process); // Getting the PEPROCESS using the PID 


if (OpenedProcess == Csrss1Process) // Making sure to not strip csrss's Handle, will cause BSOD
    return OB_PREOP_SUCCESS;

if (OpenedProcess == Csrss2Process) // Making sure to not strip csrss's Handle, will cause BSOD
    return OB_PREOP_SUCCESS;

if (OpenedProcess == CurrentProcess) // make sure the driver isnt getting stripped ( even though we have a second check )
    return OB_PREOP_SUCCESS;

if (OpenedProcess == ProtectedProcess) // Making sure that the game can open a process handle to itself
    return OB_PREOP_SUCCESS;

if (OperationInformation->KernelHandle) // allow drivers to get a handle
    return OB_PREOP_SUCCESS;


// PsGetProcessId((PEPROCESS)OperationInformation->Object) equals to the created handle's PID, so if the created Handle equals to the protected process's PID, strip
if (PsGetProcessId((PEPROCESS)OperationInformation->Object) == ProtectedProcess)
{

    if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) // striping handle 
    {
        OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION);
    }
    else
    {
        OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION);
    }

    return OB_PREOP_SUCCESS;
}
}

This code, once registered with ObRegisterCallback, will detect when a new handle is created to your protected process and will kill it if it's not coming from Lsass, Csrss, or itself. This is to prevent blue screens from critical process being denied a handle to your application.