Injecting on wireless adapter causes KMODE_EXCEPTION_NOT_HANDLED

I’m sending packets via NdisFSendNetBufferLists. Everything works great for wired adapters but if I try to send via the wireless adapter the system crashes with KMODE_EXCEPTION_NOT_HANDLED. The actual crashing instruction is so far removed from the Ndis call that I have no clear idea what it may be trying to reference. Before disassembling all of these calls, hopefully someone can point out issues with my code or things to check.

Here is the code that setups the Ndis call (shortened for posting so ignore lack of status checks).

NTSTATUS			status = STATUS_SUCCESS;
PMDL				pMdl = NULL;
NET_BUFFER_LIST* 		nbl = NULL;
NET_BUFFER_LIST_POOL_PARAMETERS nblpp;
NDIS_HANDLE			nh = NULL;

NdisZeroMemory(&nblpp, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));
nblpp.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
nblpp.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
nblpp.Header.Size = sizeof(NET_BUFFER_LIST_POOL_PARAMETERS);
nblpp.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
nblpp.fAllocateNetBuffer = TRUE;
nblpp.PoolTag = TAG_NDIS_POOL;

nh = NdisAllocateNetBufferListPool(gFilterDriverHandle, &nblpp);
pMdl = NdisAllocateMdl(gFilterDriverHandle, buffer, wpl);
nbl = NdisAllocateNetBufferAndNetBufferList(nh, 0, 0, pMdl, 0, wpl);

status = NdisAllocateNetBufferListContext(nbl, sizeof(SEND_CONTEXT), 0, TAG_NDIS_NBL);
((PSEND_CONTEXT)NET_BUFFER_LIST_CONTEXT_DATA_START(nbl))->buffer = buffer;
((PSEND_CONTEXT)NET_BUFFER_LIST_CONTEXT_DATA_START(nbl))->nh = nh;

nbl->SourceHandle = pFilter->FilterHandle;
NET_BUFFER_LIST_INFO(nbl, TcpIpChecksumNetBufferListInfo) = 0;

NdisFSendNetBufferLists(pFilter->FilterHandle, nbl, NDIS_DEFAULT_PORT_NUMBER, NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK);

3: kd> !analyze -v


  •                                                                         *
    
  •                    Bugcheck Analysis                                    *
    
  •                                                                         *
    

KMODE_EXCEPTION_NOT_HANDLED (1e)
This is a very common bugcheck. Usually the exception address pinpoints
the driver/function that caused the problem. Always note this address
as well as the link date of the driver/image that contains this address.
Arguments:
Arg1: ffffffffc0000005, The exception code that was not handled
Arg2: fffff80017011e45, The address that the exception occurred at
Arg3: fffff88a675aeb78, Parameter 0 of the exception
Arg4: fffff88a675ae3b0, Parameter 1 of the exception

Debugging Details:

DUMP_TYPE: 0

BUGCHECK_P1: ffffffffc0000005

BUGCHECK_P2: fffff80017011e45

BUGCHECK_P3: fffff88a675aeb78

BUGCHECK_P4: fffff88a675ae3b0

WRITE_ADDRESS: fffff88a675ae3b0

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

FAULTING_IP:
wdiwifi!CTxMgr::InitializeTxWfcFrame+3e1
fffff800`17011e45 0fb74804 movzx ecx,word ptr [rax+4]

EXCEPTION_PARAMETER1: fffff88a675aeb78

EXCEPTION_PARAMETER2: fffff88a675ae3b0

BUGCHECK_STR: 0x1E_c0000005

EXCEPTION_RECORD: 0000000000001000 – (.exr 0x1000)
Cannot read Exception record @ 0000000000001000

TRAP_FRAME: ffff800000000000 – (.trap 0xffff800000000000)
Unable to read trap frame at ffff8000`00000000

LAST_CONTROL_TRANSFER: from fffff8000c70ee6f to fffff8000c5f5c50

STACK_TEXT:
fffff88a675adb38 fffff8000c70ee6f : 000000000000001e ffffffffc0000005 fffff80017011e45 fffff88a675aeb78 : nt!KeBugCheckEx
fffff88a675adb40 fffff8000c611d86 : fffff88a675ae3b0 fffff8000c5038a5 fffff88a675aedb0 fffff80017011e45 : nt!KiFatalFilter+0x1f
fffff88a675adb80 fffff8000c5cc0df : fffff80000000002 fffff8000c2d8e34 fffff88a675a9000 fffff88a675b0000 : nt!KeExpandKernelStackAndCalloutInternal$filt$0+0x16
fffff88a675adbc0 fffff8000c5feb0f : fffff8000c2d8e34 fffff88a675ae1a0 fffff8000c5cc040 0000000000000000 : nt!_C_specific_handler+0x9f
fffff88a675adc30 fffff8000c52bff7 : fffff88a675ae1a0 0000000000000000 fffff88a675af340 fffff8000c554518 : nt!RtlpExecuteHandlerForException+0xf
fffff88a675adc60 fffff8000c52abe6 : fffff88a675aeb78 fffff88a675ae8b0 fffff88a675aeb78 ffffe604e0555cb0 : nt!RtlDispatchException+0x297
fffff88a675ae380 fffff8000c607cac : 0000000000001000 fffff88a675aec20 ffff800000000000 0000000000000000 : nt!KiDispatchException+0x186
fffff88a675aea40 fffff8000c603e43 : 0000000000000a71 0000000000000000 0000000000001001 0000000000000fff : nt!KiExceptionDispatch+0x12c
fffff88a675aec20 fffff80017011e45 : 0000000000000001 0000000000000018 ffffe604df03bda0 ffffe604e0555cb0 : nt!KiPageFault+0x443
fffff88a675aedb0 fffff80017061e74 : 0000000000000000 0000000000000000 ffffe604dd7d0350 0000000000000000 : wdiwifi!CTxMgr::InitializeTxWfcFrame+0x3e1
fffff88a675aee70 fffff80017020213 : 0000000000000000 0000000000000000 ffffe604d9c11000 fffff80008493400 : wdiwifi!CPort::SendNetBufferLists+0x384
fffff88a675aeef0 fffff8000fcc50af : 0000000000000000 ffffe604d6b9c1a0 0000000000000000 ffffe604d6c3ce02 : wdiwifi!MPWrapperSendNetBufferLists+0xf3
fffff88a675aef50 fffff8000fcc4f9e : 0000019000000001 ffffe604df03bda0 ffffa48200000000 0000000000000000 : ndis!ndisMSendNBLToMiniportInternal+0xff
fffff88a675af020 fffff8000fcc553c : 0000000000000000 0000000000000000 0000000000000000 00000000ffffffff : ndis!ndisMSendNBLToMiniport+0xe
fffff88a675af060 fffff8000fcc5afb : ffffe604df03bda0 fffff88a675af100 0000000000000000 0000000000000082 : ndis!ndisFilterSendNetBufferLists+0xec
fffff88a675af140 fffff80010281175 : ffffe604df03bd01 0000000000000001 ffffe60400000000 00000000000000a2 : ndis!NdisFSendNetBufferLists+0x5b
fffff88a675af1f0 fffff8000fcc58e9 : 000df048d3a0ff01 ffffe604df03bda0 ffffe604dd579a60 0000000000000000 : wfplwfs!LwfLowerSendNetBufferLists+0x165
fffff88a675af2a0 fffff8000fcd83be : ffffe604dcfef080 fffff88a675af469 fffff88a675af450 0000000000000000 : ndis!ndisCallSendHandler+0x59
fffff88a675af2f0 fffff8000c554518 : fffff88a675af469 0000000000000000 0000000000000000 ffffe604dd4d0a20 : ndis!ndisDataPathExpandStackCallback+0x3e
fffff88a675af340 fffff8000c55448d : fffff8000fcd8380 fffff88a675af450 0000000000000002 0000000000000030 : nt!KeExpandKernelStackAndCalloutInternal+0x78
fffff88a675af3b0 fffff8000fcc55ca : 00000000000003b5 0000000000000000 0000000000001001 0000000000000fff : nt!KeExpandKernelStackAndCalloutEx+0x1d
fffff88a675af3f0 fffff8000fcc5afb : ffffe604df03bda0 0000000000000000 0000000000000000 fffff8000cbb1094 : ndis!ndisFilterSendNetBufferLists+0x17a
fffff88a675af4d0 fffff80008bc3a3d : ffffe604df03bd00 ffffe604df9f8290 ffffe60400000000 0000000000000000 : ndis!NdisFSendNetBufferLists+0x5b
fffff88a675af580 fffff80008bc3752 : 00000000c0000001 0000000000000000 0000000000000004 00000000c0000001 : MYDRIVER+0x3a3d
fffff88a675af620 fffff80008bc1a6d : 00000000c000000d ffffe604e08f83a0 000000000000001f fffff88a675af6d8 : MYDRIVER+0x3752
fffff88a675af660 fffff8000fcc7d40 : ffffe604ddbe0cc0 fffff8000fda3048 ffffe604ddbe0b70 ffffe604e08f82d0 : MYDRIVER+0x1a6d
fffff88a675af6b0 fffff8000c452f55 : ffffe604e08f82d0 0000000000000002 0000000000000001 ffffe604e210a200 : ndis!ndisDummyIrpHandler+0x100
fffff88a675af700 fffff8000c7fd898 : fffff88a675afa80 ffffe604e08f82d0 0000000000000001 ffffe604df1b2080 : nt!IofCallDriver+0x55
fffff88a675af740 fffff8000c7fd165 : 00000000cf81001c fffff88a675afa80 0000000000000005 fffff88a675afa80 : nt!IopSynchronousServiceTail+0x1a8
fffff88a675af7e0 fffff8000c7fcb66 : 0000000000000000 0000000000000000 0000000000000000 0000000000000000 : nt!IopXxxControlFile+0x5e5
fffff88a675af920 fffff8000c6075b5 : fffff88a675afa80 fffff8000c82e0f5 0000000000000000 0000009f9c53d638 : nt!NtDeviceIoControlFile+0x56
fffff88a675af990 00007ffcd9acccf4 : 00007ffcd758396b 0000000000000000 000000020000000c 0000000000000101 : nt!KiSystemServiceCopyEnd+0x25
0000009f9c53e468 00007ffcd758396b : 0000000000000000 000000020000000c 0000000000000101 00001e35df3a503c : ntdll!NtDeviceIoControlFile+0x14
0000009f9c53e470 00007ffcd7ca5611 : 00000000cf81001c 0000000000000053 0000009f9c53e500 0000020900000000 : KERNELBASE!DeviceIoControl+0x6b
0000009f9c53e4e0 00007ffcb3011fd3 : 0000000000000053 0000000000000000 0000000000000000 0000000000000b34 : KERNEL32!DeviceIoControlImplementation+0x81
0000009f9c53e530 0000000000000053 : 0000000000000000 0000000000000000 0000000000000b34 0000000000000000 : MYDLL+0xe3

Here’s a little more info for the NDIS experts that hopefully read this board.

According to the Ghidra decompiler, the function in wdiwifi.sys that is crashing (CTxMgr::InitializeTxWfcFrame) is trying to access MediaSpecificInformation from the NetBufferListInfo of the input NetBufferList. Decompiled code is below with the crashing parts highlighted.

NdisAdvanceNetBufferListDataStart(param_1,iVar6,0);
lVar10 = NdisGetDataBuffer(*(undefined8 *)&(param_1->field_0x0).field_0x8);
if (lVar10 == 0) {
  if ((undefined **)WPP_RECORDER_INITIALIZED != &WPP_RECORDER_INITIALIZED) {
    WPP_RECORDER_SF_(*(undefined8 *)(WPP_GLOBAL_Control + 0x40),2,1,0x6c,
                     &WPP_dd2bdbfdffac3ff261685ba7117dc32a_Traceguids);
  }
  NdisRetreatNetBufferListDataStart(param_1,iVar6,0,0);
  iVar8 = -0x3ffeffeb;
  goto LAB_1c0011b6a;
}
*(undefined2 *)&(_Dst->WiFiFrameMetadata).u.field_0x8 = *(undefined2 *)(lVar10 + 6);
uVar13 = 0;

//**********************************************************************
//  call    ndis!NdisRetreatNetBufferListDataStart
//  mov     rax,qword ptr [rsi+0C0h]
//  movzx   ecx,word ptr [rax+4]	<-BOOM

NdisRetreatNetBufferListDataStart(param_1,iVar6);
uVar11 = (uint)*(ushort *)((longlong)param_1->NetBufferListInfo[6] + 4);
//**********************************************************************

*(uint *)&(_Dst->WiFiFrameMetadata).u.field_0x10 = uVar11;
if ((uVar11 == 2) && (local_58 == '\0')) {
  *(undefined4 *)&(_Dst->WiFiFrameMetadata).u.field_0x10 = 1;
}

If you refer to my previous message, you can see how I’m crafting the NBL. I’m not setting any MediaSpecificInformation and based on the docs, it doesn’t seem like I need to either. Does anyone have any thoughts on what is going on here?

Last update on this as I’ve mostly figured it out and thought I’d share.

The problem was the binding. In my INF, I set FilterClass to ms_medium_converter_128 and FilterMediaTypes to “vwifi,vchannel,wlan”. I did this so I could capture raw 802.11 packets but apparently injecting at those levels is not easy to do. Found this little nugget from Jeffrey Tippet (was hoping he’d respond to this question) from 2015 (https://community.osr.com/discussion/265127):

“I’m not too surprised that the packets don’t work if your driver gets stuck below NWIFI. We don’t support drivers doing that, because you need to decorate your packets in a special way & synchronize with the WLAN state machine, etc.”

While that OP was not using the same bindings it was related to wifi issues so I assume that Jeff’s comment applies to my situation as well. Instead of reversing the packet requirements I simply changed the filter binding and everything works as it should.