cwindowsdriverwdkwdm

Access denied while using ObRegisterCallbacks from Windows Driver Kit


I have been making a kernel mode application for my side project, and I have been experiencing some issue. I used ObRegisterCallback function in my code as below.

NTSTATUS
RegisterCallback(
    VOID
)
{
    UNICODE_STRING              szAltitude;
    OB_CALLBACK_REGISTRATION    ocr;

// ...

    return ObRegisterCallbacks(&ocr, pCallbackRegHandle);
}

Which returned STATUS_ACCESS_DENIED. The documentation provided by Microsoft says that this NTSTATUS code is returned by the function when the callback routine is not situated in a signed kernel binary image.

I tried signing the driver as Rick64's answer in this question like this:

signtool.exe sign /v /a /d nstlockguard.cat /t http://timestamp.digicert.com /fd SHA256 NstLockGuard.sys

And installed the .inf following file to the testing machine.

;
; NstLockGuard.inf
;

[Version]
Signature   = "$WINDOWS NT$"
Class       = System ; TODO: specify appropriate Class
ClassGuid   = {...} ; TODO: specify appropriate ClassGuid
Provider    = %ManufacturerName%
CatalogFile = NstLockGuard.cat
DriverVer = 09/14/2024,22.40.2.461
PnpLockdown = 1

[DestinationDirs]
DefaultDestDir = 13

[SourceDisksNames]
1 = %DiskName%,,,""

[SourceDisksFiles]
NstLockGuard.sys = 1,,

;*****************************************
; Install Section
;*****************************************

[Manufacturer]
%ManufacturerName% = Standard,NTamd64.10.0...16299 ; %13% support introduced in build 16299

[Standard.NTamd64.10.0...16299]
%NstLockGuard.DeviceDesc% = NstLockGuard_Device, Root\NstLockGuard ; TODO: edit hw-id

[NstLockGuard_Device.NT]
CopyFiles = File_Copy

[File_Copy]
NstLockGuard.sys

;-------------- Service installation
[NstLockGuard_Device.NT.Services]
AddService = NstLockGuard,%SPSVCINST_ASSOCSERVICE%, NstLockGuard_Service_Inst

; -------------- NstLockGuard driver install sections
[NstLockGuard_Service_Inst]
DisplayName    = %NstLockGuard.SVCDESC%
ServiceType    = 1               ; SERVICE_KERNEL_DRIVER
StartType      = 3               ; SERVICE_DEMAND_START
ErrorControl   = 1               ; SERVICE_ERROR_NORMAL
ServiceBinary  = %13%\NstLockGuard.sys

[NstLockGuard_Device.NT.Wdf]
KmdfService = NstLockGuard, NstLockGuard_wdfsect

[NstLockGuard_wdfsect]
KmdfLibraryVersion = 1.15

[Strings]
SPSVCINST_ASSOCSERVICE = 0x00000002
ManufacturerName = "Nascity" ;TODO: Replace with your manufacturer name
DiskName = "NstLockGuard Installation Disk"
NstLockGuard.DeviceDesc = "NstLockGuard Device"
NstLockGuard.SVCDESC = "NstLockGuard Service"

But typing the command sc start (service name) still returns 'access denied' error.

I'm kind of new to Windows kernel development. Maybe I am missing something. Anyways, thank you in advance for your help.


Edit:

Here's my full source code:

callback.c:

#include "../inc/callback.h"
#include "../inc/debug_print.h"

extern PVOID                pCallbackRegHandle;
OB_OPERATION_REGISTRATION   oor[OP_REG_COUNT];

VOID
InitOOR(
    VOID
)
{
    POB_OPERATION_REGISTRATION  pOor = &oor[0];

    pOor->ObjectType = PsThreadType;
    pOor->Operations = OB_OPERATION_HANDLE_CREATE;
    pOor->PreOperation = NULL;
    pOor->PostOperation = ProcessHandleCreationCallback;
}

NTSTATUS
RegisterCallback(
    VOID
)
{
    UNICODE_STRING              szAltitude;
    OB_CALLBACK_REGISTRATION    ocr;

    RtlInitUnicodeString(&szAltitude, ALTITUDE);
    InitOOR();

    // Init OCR
    ocr.Version = OB_FLT_REGISTRATION_VERSION;
    ocr.OperationRegistrationCount = OP_REG_COUNT;
    ocr.Altitude = szAltitude;
    ocr.RegistrationContext = NULL;
    ocr.OperationRegistration = oor;

    return ObRegisterCallbacks(&ocr, pCallbackRegHandle);
}

VOID
ProcessHandleCreationCallback(
    PVOID                           pRegContext,
    POB_POST_OPERATION_INFORMATION  pOpInfo
)
{
    UNREFERENCED_PARAMETER(pRegContext);
    UNREFERENCED_PARAMETER(pOpInfo);

    DbgPrintEx(0, 0, "Here");
}

main.c:

#include "../inc/callback.h"
#include "../inc/debug_print.h"

PVOID   pCallbackRegHandle;

VOID
UnloadDriver(
    _In_    PDRIVER_OBJECT  pDriverObj
)
{
    UNREFERENCED_PARAMETER(pDriverObj);

    ObUnRegisterCallbacks(pCallbackRegHandle);
}

NTSTATUS
DriverEntry(
    _In_    PDRIVER_OBJECT  pDriverObj,
    _In_    PUNICODE_STRING szRegPath
)
{
    NTSTATUS    ntstat;

    UNREFERENCED_PARAMETER(szRegPath);
    pDriverObj->DriverUnload = UnloadDriver;

    ntstat = RegisterCallback();
    if (!NT_SUCCESS(ntstat))
    {
        DBGPRINT("Failed to register callback.\n");
        return ntstat;
    }
    DBGPRINT("Successfully registered callback.\n");

    return STATUS_SUCCESS;
}

callback.h:

#pragma once

#include <ntddk.h>
#include <wdf.h>

#define OP_REG_COUNT    1
#define ALTITUDE        L"29999"

NTSTATUS
RegisterCallback(
    VOID
);

VOID
ProcessHandleCreationCallback(
    PVOID                           pRegContext,
    POB_POST_OPERATION_INFORMATION  pOpInfo
);

debug_print.h:

#pragma once

#define DBGPRINT(x) DbgPrintEx(0, 0, x)

Solution

  • Credits to @Luke.

    First of all, the parameter passed to the ObRegisterCallbacks function was a wrong value. Instead of PVOID*, I passed PVOID as the parameter, which led to memory access violation.

    Secondly, /INTEGRITYCHECK linker flag had to be specified. After fixing the parameter for the function, the driver didn't load when the flag wasn't specified. I should have studied more about Windows driver development.