cwindowswinapikernelkernel-module

How can i get handle information from PreOperationCallback?


I am currently curious about anti-cheat development and am currenley experimenting and writing a kernel driver. I have found out that OB Register Callbacks can let you intercept handle creation, and therefore disallow access to a process. My issue is getting the handle information, right now im stuck with only getting the processID of the program that called openprocess. For example i have game.exe that has a PID of 1234 and i have ProcessHacker.exe with a PID of 4321. In my driver,

case OB_OPERATION_HANDLE_CREATE:
        DesiredAccess = &OP_INFO->Parameters->CreateHandleInformation.DesiredAccess;
        OriginalDesiredAccess = OP_INFO->Parameters->CreateHandleInformation.OriginalDesiredAccess;
        
        PEPROCESS peProcessC;
        PsLookupProcessByProcessId((PEPROCESS)OP_INFO->Object, &peProcessC);


        if (peProcessC == (HANDLE)1234) { //game.exe PID
            *DesiredAccess = 0;
        }

        OperationName = L"OB_OPERATION_HANDLE_CREATE";
        break;

When I get processhacker to inject a DLL into game.exe, My driver returns the processhacker PID. My goal is to only protect game.exe, and for that ive been trying to get the handle information, i.e DesiredAccess, Binherit and dwProcessID. I want to be able to see what the handle is pointing to and not the program that called OpenProcess. There are no other topics on this that i was able to find.

Sorry for all the text, english is not my first language.

I have been looking though the MS documentation on POB_PRE_OPERATION_INFORMATION, and cannot find anything relating to what i am trying to do. If there is a better way to accomplish this or i am doing it wrong please say so.


Solution

  • you need use PsGetProcessId for check id of process which caller try open. also you at first need ensure that this is process object:

    if (*PsProcessType == OperationInformation->ObjectType)

    also need check that request not from game.exe itself, or from protected process ( csrss.exe as example or from kernel mode )

    OB_PREOP_CALLBACK_STATUS ObjectPreCallback(PVOID /*RegistrationContext*/, POB_PRE_OPERATION_INFORMATION OperationInformation)
    {
        if (OperationInformation->KernelHandle)
        {
            return OB_PREOP_SUCCESS;
        }
    
        ACCESS_MASK *pDesiredAccess;
    
        switch (OperationInformation->Operation)
        {
        case OB_OPERATION_HANDLE_CREATE:
            pDesiredAccess = &OperationInformation->Parameters->CreateHandleInformation.DesiredAccess;
            break;
        case OB_OPERATION_HANDLE_DUPLICATE:
            pDesiredAccess = &OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess;
            break;
        default:
            // unknown operation ?!
            return OB_PREOP_SUCCESS;
        }
        
        union {
            PVOID Object;
            PEPROCESS Process;
            PETHREAD Thread;
        };
    
        Object = OperationInformation->Object;
    
        POBJECT_TYPE ObjectType = OperationInformation->ObjectType;
    
        if (*PsProcessType == ObjectType)
        {
            PEPROCESS CurrentProcess = IoGetCurrentProcess();
    
            if (Process != CurrentProcess &&
                PsGetProcessId(Process) == _G_gamePID &&
                !PsIsProtectedProcess(CurrentProcess))
            {
                // block access
                *pDesiredAccess &= PROCESS_QUERY_LIMITED_INFORMATION;
            }
                
        }
        return OB_PREOP_SUCCESS;
    }