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.
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)
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.