SMB traffic not captured in TDI filter driver

Recently I met a problem in one of my TDI filters when filtering SMB traffic. The filter driver was able to see outgoing TDI_CONNECT requests to 139 and 445 ports, but during the heavy file upload there was no TDI_SEND requests issued.

Usually in such cases you start to googlize for a solution, and I found a few posts explaining the same problem, but they were actually dead – no reply since 2002 :). I also asked for a question at popular DDK newsgroups assuming this was a well-known issue, and still got no answer.

Well, it started to be more and more interesting, especially taking into account that TDI lacks a lot of documentation and many things have to be resolved myself. I also used IrpTracker, TdiMon, TdiScoup utilities trying to see any missed IRPs but I was failed to see them. I need a point to start researches from. The best in this case is, I believe, a breakpoint to IoCallDriver. So, I opened share, started a file upload on a share, and put breakpoint in debugger:

0: kd> bp IofCallDriver

… and continue by pressing F5. Then break occures:

f62b281c f6e04139 nt!IofCallDriver
f62b2824 f6e03a47 rdbss!RxCeSubmitAsynchronousTdiRequest+0x28
f62b285c f6e0d0a0 rdbss!RxTdiSend+0x1ca
f62b28b8 f6d57609 rdbss!RxCeSend+0x74
f62b28e0 f6d35152 mrxsmb!VctTranceive+0x66
f62b2924 f6d597de mrxsmb!SmbCeTranceive+0x233
f62b2960 f6d5c350 mrxsmb!SmbPseOrdinaryExchange+0x18e
f62b29b0 f6d59668 mrxsmb!SmbPseExchangeStart_Write+0x1e3
f62b29c0 f6d57ab4 mrxsmb!SmbPseExchangeStart_default+0x12
f62b29e4 f6d5be6e mrxsmb!SmbCeInitiateExchange+0x287
f62b2a24 f6e0d49f mrxsmb!MRxSmbWrite+0x309
f62b2a4c f6e110e7 rdbss!RxLowIoSubmit+0x1c3
f62b2a6c f6e1183f rdbss!RxLowIoWriteShell+0x77
f62b2b90 f6e02d51 rdbss!RxCommonWrite+0x116f
f62b2c28 f6e0cbb0 rdbss!RxFsdCommonDispatch+0x353
f62b2c50 f6d57217 rdbss!RxFsdDispatch+0xda
f62b2c70 804ef095 mrxsmb!MRxSmbFsdDispatch+0x134
f62b2c80 8057e70a nt!IopfCallDriver+0x31
f62b2c94 8057c2cd nt!IopSynchronousServiceTail+0x60
f62b2d38 8054086c nt!NtWriteFile+0x5d7

As it seems from stack, the network file redirector is calling TDI (look at function name RxTdiSend) and this confuses me even more, as my filter has to receive IRP in this case. Continue more step by step debugging and I see actually that the request of file system redirector is sent to netbt.sys and not to TDI:

nt!IopfCallDriver:
804ef064 fe4a23          dec     byte ptr [edx+23h]
804ef067 8a4223          mov     al,byte ptr [edx+23h]
804ef06a 84c0            test    al,al
804ef06c 7f0e            jg      nt!IopfCallDriver+0x18 (804ef07c)
804ef06e 6a00            push    0
804ef070 6a00            push    0
804ef072 6a00            push    0
804ef074 52              push    edx
804ef075 6a35            push    35h
804ef077 e854ad0000      call    nt!KeBugCheckEx (804f9dd0)
804ef07c 8b4260          mov     eax,dword ptr [edx+60h]
804ef07f 83e824          sub     eax,24h
804ef082 56              push    esi
804ef083 894260          mov     dword ptr [edx+60h],eax
804ef086 894814          mov     dword ptr [eax+14h],ecx
804ef089 0fb600          movzx   eax,byte ptr [eax]
804ef08c 8b7108          mov     esi,dword ptr [ecx+8]
804ef08f 52              push    edx
804ef090 51              push    ecx
804ef091 ff548638        call    dword ptr [esi+eax*4+38h] ds:0023:81f486e4={netbt!NbtDispatchInternalCtrl (f6da29ef)}

In dispatch function of netbt.sys I see the call to NtSend function: netbt!NbtDispatchInternalCtrl:

f6da29ef 8bff            mov     edi,edi
f6da29f1 55              push    ebp
f6da29f2 8bec            mov     ebp,esp
f6da29f4 56              push    esi
f6da29f5 8b750c          mov     esi,dword ptr [ebp+0Ch]
f6da29f8 57              push    edi
f6da29f9 8b7e60          mov     edi,dword ptr [esi+60h]
f6da29fc 807f0107        cmp     byte ptr [edi+1],7
f6da2a00 897d0c          mov     dword ptr [ebp+0Ch],edi
f6da2a03 0f85b6120000    jne     netbt!NbtDispatchInternalCtrl+0x24 (f6da3cbf)
f6da2a09 56              push    esi
f6da2a0a ff7508          push    dword ptr [ebp+8]
f6da2a0d e838060000      call    netbt!NTSend (f6da304a)

In netbt.NtSend function I see a code which is preparing an IRP to be processed:

f6da310e 83ee24          sub     esi,24h
f6da3111 83c004          add     eax,4
f6da3114 894604          mov     dword ptr [esi+4],eax
f6da3117 c7461c832fdaf6  mov     dword ptr [esi+1Ch],offset netbt!SendCompletion (f6da2f83)
f6da311e 897e20          mov     dword ptr [esi+20h],edi
f6da3121 c64603e0        mov     byte ptr [esi+3],0E0h
f6da3125 c6060f          mov     byte ptr [esi],0Fh
f6da3128 c6460107        mov     byte ptr [esi+1],7
f6da312c 8b0b            mov     ecx,dword ptr [ebx]
f6da312e 014f48          add     dword ptr [edi+48h],ecx
f6da3131 8b4730          mov     eax,dword ptr [edi+30h]
f6da3134 8b1d08d1dbf6    mov     ebx,dword ptr [netbt!_imp__IoGetRelatedDeviceObject (f6dbd108)]
f6da313a 83574c00        adc     dword ptr [edi+4Ch],0
f6da313e 50              push    eax
f6da313f 8945f0          mov     dword ptr [ebp-10h],eax
f6da3142 894618          mov     dword ptr [esi+18h],eax
f6da3145 ffd3            call    ebx {nt!IoGetRelatedDeviceObject (804ef658)}

And at the end of a function I see the code which is sending the IRP directly to tcpip.sys TcpSendData handler:

f6da3166 834060dc        add     dword ptr [eax+60h],0FFFFFFDCh
f6da316a 56              push    esi
f6da316b 50              push    eax
f6da316c ff5764          call    dword ptr [edi+64h]  ds:0023:8200c324={tcpip!TCPSendData (f6ea04f0)}
f6da316f 6a00            push    0
f6da3171 6a00            push    0
f6da3173 ff7508          push    dword ptr [ebp+8]
f6da3176 8bf0            mov     esi,eax
f6da3178 e81df8ffff      call    netbt!NBT_DEREFERENCE_DEVICE (f6da299a)
f6da317d 5f              pop     edi
f6da317e 8bc6            mov     eax,esi
f6da3180 5e              pop     esi
f6da3181 5b              pop     ebx
f6da3182 c9              leave
f6da3183 c20800          ret     8
f6da3186 90              nop

Thats actually an answer to the question, why TDI filters are unable to filter SMB session traffic. Netbt.sys simply sends data directly to tcpip.sys via TCPSendData function and I believe, this is done for perfomance purposes.

3 Comments

  1. Pingback: SMB traffic not captured in TDI filter driver - ab origine ...

Leave a Reply

Your email address will not be published. Required fields are marked *


7 − = three

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>