I am writing my first kernel driver, and it's crashing on the following line in DriverEntry
:
status = FwpsCalloutRegister(wdfDevice, &sCallout, &Globals.FlowCalloutId);
!analyze v
in WinDbg
outputs the following:
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
IRQL_NOT_LESS_OR_EQUAL (a)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 00001df79f0fe5b8, memory referenced
Arg2: 0000000000000002, IRQL
Arg3: 0000000000000001, bitfield :
bit 0 : value 0 = read operation, 1 = write operation
bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
Arg4: fffff803392e1640, address which referenced memory
Debugging Details:
------------------
DUMP_CLASS: 1
DUMP_QUALIFIER: 0
BUILD_VERSION_STRING: 16299.15.amd64fre.rs3_release.170928-1534
DUMP_TYPE: 0
BUGCHECK_P1: 1df79f0fe5b8
BUGCHECK_P2: 2
BUGCHECK_P3: 1
BUGCHECK_P4: fffff803392e1640
WRITE_ADDRESS: 00001df79f0fe5b8
CURRENT_IRQL: 2
FAULTING_IP:
nt!ObfReferenceObject+20
fffff803`392e1640 f0480fc11f lock xadd qword ptr [rdi],rbx
CPU_COUNT: 4
CPU_MHZ: 8f7
CPU_VENDOR: GenuineIntel
CPU_FAMILY: 6
CPU_MODEL: 2a
CPU_STEPPING: 7
CPU_MICROCODE: 6,2a,7,0 (F,M,S,R) SIG: 29'00000000 (cache) 29'00000000 (init)
DEFAULT_BUCKET_ID: WIN8_DRIVER_FAULT
BUGCHECK_STR: AV
PROCESS_NAME: System
ANALYSIS_SESSION_HOST: ELI-DESKTOP
ANALYSIS_SESSION_TIME: 04-28-2018 22:38:52.0588
ANALYSIS_VERSION: 10.0.16299.15 amd64fre
TRAP_FRAME: ffff8905265e2200 -- (.trap 0xffff8905265e2200)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=0000000000000001 rbx=0000000000000000 rcx=00001df79f0fe5e8
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=fffff803392e1640 rsp=ffff8905265e2390 rbp=0000000000000126
r8=0000000000000000 r9=0000000000000006 r10=0000000000000000
r11=fffff800601e7c17 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl zr na po nc
nt!ObfReferenceObject+0x20:
fffff803`392e1640 f0480fc11f lock xadd qword ptr [rdi],rbx ds:00000000`00000000=????????????????
Resetting default scope
LAST_CONTROL_TRANSFER: from fffff80339499a02 to fffff80339414bf0
STACK_TEXT:
ffff8905`265e18f8 fffff803`39499a02 : 00001df7`9f0fe5b8 ffffe208`5d475700 ffff8905`265e1a60 fffff803`393d6540 : nt!DbgBreakPointWithStatus
ffff8905`265e1900 fffff803`39499287 : 00000000`00000003 ffff8905`265e1a60 fffff803`394212c0 00000000`0000000a : nt!KiBugCheckDebugBreak+0x12
ffff8905`265e1960 fffff803`3940ca37 : 00000000`00000000 fffff803`39383e01 00000000`00000001 ffff8a81`d7f52a20 : nt!KeBugCheck2+0x937
ffff8905`265e2080 fffff803`3941eae9 : 00000000`0000000a 00001df7`9f0fe5b8 00000000`00000002 00000000`00000001 : nt!KeBugCheckEx+0x107
ffff8905`265e20c0 fffff803`3941b1fe : ffff8905`265e2310 fffff803`3932e308 fffff803`38db3180 fffff800`00000000 : nt!KiBugCheckDispatch+0x69
ffff8905`265e2200 fffff803`392e1640 : ffffe208`5dfebba0 fffff800`5fa7f5ab ffffc985`1b0b4090 ffff8905`265e25a8 : nt!KiPageFault+0x47e
ffff8905`265e2390 fffff800`601e5273 : ffffe208`5e805be0 00000000`00000000 00000000`00000000 fffff803`392e1776 : nt!ObfReferenceObject+0x20
ffff8905`265e23d0 fffff800`60103e4f : ffff8905`265e25a8 00000000`00000000 ffffc985`13eca4c0 00001df7`9f0fe5e8 : NETIO!KfdAddCalloutEntry+0x1d3
ffff8905`265e2420 fffff800`6010321a : 00000000`00000000 ffffc985`13eca4c0 fffff800`63b44380 00001df7`9f0fe5e8 : fwpkclnt!FwppCalloutRegister+0x9f
ffff8905`265e2490 fffff800`63b4145d : 00000000`00000000 00000000`00000000 fffff800`63b43120 badbadfa`badbadfa : fwpkclnt!FwpsCalloutRegister3+0x6a
ffff8905`265e24d0 fffff800`63b4290d : ffffe208`60827940 ffffe208`5f3b9000 ffffc985`1cb31c90 ffffe208`6083fe10 : KmdfStart!DriverEntry+0x45d [c:\develop\tanwash\kmdfstart\driver.c @ 272]
ffff8905`265e2940 fffff803`39741ad6 : 00000000`00000000 ffff8905`265e2a70 ffffe208`60827940 ffffffff`80002d58 : KmdfStart!FxDriverEntryWorker+0xb9 [d:\th\minkernel\wdf\framework\kmdf\src\dynamic\stub\stub.cpp @ 325]
ffff8905`265e2970 fffff803`3980b7d7 : 00000000`00000000 00000000`00000000 00000000`00000000 fffff803`395f5b40 : nt!IopLoadDriver+0x4da
ffff8905`265e2b40 fffff803`392d24d5 : ffffe208`00000000 ffffffff`80002d58 ffffe208`5d4ce300 ffffe208`5d475700 : nt!IopLoadUnloadDriver+0x57
ffff8905`265e2b80 fffff803`393adc07 : ffffe208`5d475700 00000000`00000080 ffffe208`5d450440 ffffe208`5d475700 : nt!ExpWorkerThread+0xf5
ffff8905`265e2c10 fffff803`39414366 : ffff8a81`d7ec0180 ffffe208`5d475700 fffff803`393adbc0 00000000`00000000 : nt!PspSystemThreadStartup+0x47
ffff8905`265e2c60 00000000`00000000 : ffff8905`265e3000 ffff8905`265dd000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x16
THREAD_SHA1_HASH_MOD_FUNC: 3968ac24ad304ae3e12d211656861bc3d31ba01b
THREAD_SHA1_HASH_MOD_FUNC_OFFSET: 42d7be29acc2a96618b5dfd9cf0528fdc2d10bc5
THREAD_SHA1_HASH_MOD: d06099ec8ea3db5426a6cfa7d3673b217e8490ba
FOLLOWUP_IP:
NETIO!KfdAddCalloutEntry+1d3
fffff800`601e5273 48897340 mov qword ptr [rbx+40h],rsi
FAULT_INSTR_CODE: 40738948
SYMBOL_STACK_INDEX: 7
SYMBOL_NAME: NETIO!KfdAddCalloutEntry+1d3
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: NETIO
IMAGE_NAME: NETIO.SYS
DEBUG_FLR_IMAGE_TIMESTAMP: 5b0597f3
STACK_COMMAND: .thread ; .cxr ; kb
BUCKET_ID_FUNC_OFFSET: 1d3
FAILURE_BUCKET_ID: AV_NETIO!KfdAddCalloutEntry
BUCKET_ID: AV_NETIO!KfdAddCalloutEntry
PRIMARY_PROBLEM_CLASS: AV_NETIO!KfdAddCalloutEntry
TARGET_TIME: 2018-04-28T19:25:44.000Z
OSBUILD: 16299
OSSERVICEPACK: 0
SERVICEPACK_NUMBER: 0
OS_REVISION: 0
SUITE_MASK: 784
PRODUCT_TYPE: 1
OSPLATFORM_TYPE: x64
OSNAME: Windows 10
OSEDITION: Windows 10 WinNt TerminalServer SingleUserTS Personal
OS_LOCALE:
USER_LCID: 0
OSBUILD_TIMESTAMP: 2018-03-29 20:22:49
BUILDDATESTAMP_STR: 170928-1534
BUILDLAB_STR: rs3_release
BUILDOSVER_STR: 10.0.16299.15.amd64fre.rs3_release.170928-1534
ANALYSIS_SESSION_ELAPSED_TIME: d13
ANALYSIS_SOURCE: KM
FAILURE_ID_HASH_STRING: km:av_netio!kfdaddcalloutentry
FAILURE_ID_HASH: {70a7358f-b067-d8c1-c0fa-9641a6376c65}
Followup: MachineOwner
---------
I am trying to understand the issue, and there are 2 things I don't understand - firstly why there is any pageable memory involved, since I'm just passing in to the function global variables and local variables, both of which are non-paged. (See here and here.)
Secondly why IRQL is above 0, since I'm in DriverEntry. (See here the DriverEntry runs at PASSIVE_LEVEL
.
My code is as follows. It crashes on the last line posted - anything else is not relevant as it never gets there.
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
WDF_DRIVER_CONFIG config;
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES attributes;
PWDFDEVICE_INIT pInit = NULL;
WDFDRIVER wdfDriver;
WDFDEVICE wdfDevice;
//
// Initialize WPP Tracing
//
WPP_INIT_TRACING(DriverObject, RegistryPath);
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
//driver
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.EvtCleanupCallback = KmdfStartEvtDriverContextCleanup;
WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK);
status = WdfDriverCreate(DriverObject, RegistryPath, &attributes, &config, &wdfDriver);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status);
//EvtCleanupCallback won't be called here, since the driver wasn't created
WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)DriverObject));
goto DriverEntryErr;
}
//setup device
pInit = WdfControlDeviceInitAllocate(wdfDriver, &SDDL_DEVOBJ_KERNEL_ONLY);
if (pInit == NULL) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfControlDeviceInitAllocate failed");
status = STATUS_INSUFFICIENT_RESOURCES;
goto DriverEntryErr;
}
WdfDeviceInitSetCharacteristics(pInit, FILE_AUTOGENERATED_DEVICE_NAME, TRUE);
WdfDeviceInitSetDeviceClass(pInit, &WFP_DRIVER_CLASS_GUID);
WdfDeviceInitSetCharacteristics(pInit, FILE_DEVICE_SECURE_OPEN, TRUE);
status = WdfDeviceCreate(&pInit, WDF_NO_OBJECT_ATTRIBUTES, &wdfDevice);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status);
WdfDeviceInitFree(pInit);
goto DriverEntryErr;
}
WdfControlFinishInitializing(wdfDevice);
//engine
FWPM_SESSION session = { 0 };
session.flags = FWPM_SESSION_FLAG_DYNAMIC;
status = FwpmEngineOpen(NULL, RPC_C_AUTHN_WINNT, NULL, &session, &Globals.EngineHandle);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "FwpmEngineOpen failed %!STATUS!", status);
goto DriverEntryErr;
}
//start transaction
status = FwpmTransactionBegin(Globals.EngineHandle, 0);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "FwpmTransactionBegin failed %!STATUS!", status);
goto DriverEntryErr;
}
//sublayer
FWPM_SUBLAYER0 kstSubLayer = { 0 };
kstSubLayer.subLayerKey = KST_SUBLAYER;
kstSubLayer.displayData.name = L"KmdfStart Sub-Layer";
kstSubLayer.displayData.description = L"KmdfStart Sub-Layer for callouts";
kstSubLayer.weight = 0x40;
status = FwpmSubLayerAdd(Globals.EngineHandle, &kstSubLayer, NULL);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "FwpmSubLayerAdd failed %!STATUS!", status);
goto DriverEntryErr;
}
//flow callout register
FWPS_CALLOUT sCallout = { 0 };
sCallout.calloutKey = KST_FLOW_ESTABLISHED_CALLOUT_V4;
sCallout.classifyFn = KmdfStartFlowEstablishedClassify;
sCallout.notifyFn = KmdfStartNotifyFunction;
status = FwpsCalloutRegister(wdfDevice, &sCallout, &Globals.FlowCalloutId);
The first parameter of FwpsCalloutRegister is of type *deviceObject
, not wdfDevice
.
You can get an instance of *deviceObject
by calling WdfDeviceWdmGetDeviceObject(wdfDevice);
.