Page 4 of 14

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 4:07 am
by JHPJHP
Ok, that's great!

Added a bunch more Constants that will be needed later, and fixed a few things; also started DivertSend - Packet (re)Injection...

It's REM'd out at the moment - reading the documentation, I think it needs to be multi-threaded (refer to passthru.c).

I'll probably take a stab at it tomorrow.

NB*: Link updated :)

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 4:28 am
by Thunder93
I have had the chance to test out the returns for all three frag flags, and it is working beautifully now (0 = Off, 1 = On). Great job on that!

I have concerns regarding the Frag Offset return.. I'll look into it some more I guess.

I noticed something unusual when I was sending test packets, I'll check into that and tell you my observations later.

JHPJHP wrote:Just because it returns the correct number - doesn't make it right. :shock:

Code: Select all

FragOff0.u = PeekU(@*ppIpHdr\FragOff0)
Debug "ppIpHdr\FragOff0 (" + Str(FragOff0) + ")"
Debug "--Bit 0 (Reseverd): " + Str((FragOff0 & $0080) >> 7)
Debug "--Bit 1 (May Fragment = 0 / Don't Fragment = 1): " + Str((FragOff0 & $0040) >> 6)
Debug "--Bit 2 (Last Fragment = 0 / More Fragments = 1): " + Str((FragOff0 & $0020) >> 5)
Debug "--Fragment Offset: " + Str(FragOff0 & $FF1F)
Do you have a way to test this?

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 5:12 am
by Thunder93
I guess I had merits for my concerns... Here's the fix;

Code: Select all

Debug "--Fragment Offset: " + Str(htons_(FragOff0) * 8)

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 5:35 am
by Thunder93
Here's something I really don't like about this driver package... If the outgoing packet source-IP doesn't match that of your own, the driver won't trigger and show anything for it. Likewise but reversed, if the incoming packet doesn't have destination IP matching target (or in this case...) your IP address.

..... regardless one's opinion about filtering such traffic, it is important that you see EVERYTHING coming in and going out.


This is disappointing for me.

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 9:03 am
by JHPJHP
All the documentation seems to suggest:

Code: Select all

Debug "--Fragment Offset: " + ntohs_(FragOff0 & $FF1F)
But I trust your tests first... can you double check the results, only because I'm getting data that doesn't match what's returned from Wireshark.
If the outgoing packet source-IP doesn't match that of your own, the driver won't trigger and show anything for it. Likewise but reversed, if the incoming packet doesn't have destination IP matching target (or in this case...) your IP address.
There are a few exceptions to this - Broadcast packets & Loopback Packets:
192.168.x.255
127.0.0.1
255.255.255.255
0.0.0.0

Are you referring to having the ability to enable Promiscuous Mode on the NIC - that would be nice? :wink:
(as you most certainly know - in a wired Ethernet network this normally wouldn't make a difference)?

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 12:50 pm
by Thunder93
Apologies.... I pasted the wrong line. It was late!

Code: Select all

Debug "--Fragment Offset: " + Str(ntohs_(FragOff0 & $FF1F) * 8)
JHPJHP wrote:All the documentation seems to suggest:

Code: Select all

Debug "--Fragment Offset: " + ntohs_(FragOff0 & $FF1F)
But I trust your tests first... can you double check the results, only because I'm getting data that doesn't match what's returned from Wireshark.

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 5:35 pm
by Thunder93
Here are my updates.

Code: Select all

;Activate 'threadsafe executable' and 'Request Administrator' in PB Compiler Options, and deactivate 'unicode executable' for this version.


Structure DIVERT_ADDRESS
  IfIdx.l
  SubIfIdx.l
  Direction.a
EndStructure

Structure DIVERT_IPHDR
  StructureUnion
    HdrLength.a
    Version.a
  EndStructureUnion
  TOS.a
  Length.u
  Id.u
  FragOff0.u
  TTL.a
  Protocol.a
  Checksum.u
  SrcAddr.l
  DstAddr.l
EndStructure

Structure DIVERT_IPV6HDR
  StructureUnion
    TrafficClass0.a
    Version.a
    FlowLabel0.a
    TrafficClass1.a
  EndStructureUnion
  FlowLabel1.u
  Length.u
  NextHdr.a
  HopLimit.a
  SrcAddr.l[4]
  DstAddr.l[4]
EndStructure

Structure DIVERT_ICMPHDR
  Type.a
  Code.a
  Checksum.u
  Body.l
EndStructure

Structure DIVERT_ICMPV6HDR
  Type.a
  Code.a
  Checksum.u
  Body.l
EndStructure

Structure DIVERT_TCPHDR
  SrcPort.u
  DstPort.u
  SeqNum.l
  AckNum.l
  StructureUnion
    Reserved1.a
    HdrLength.a
    
    ;;;;HdrLength.u
    ;;;;Reserved1.u
  EndStructureUnion
  StructureUnion
    Fin.a
    Syn.a
    Rst.a
    Psh.a
    Ack.a
    Urg.a
    Reserved2.a

    ;;;;Fin.u
    ;;;;Syn.u
    ;;;;Rst.u
    ;;;;Psh.u
    ;;;;Ack.u
    ;;;;Urg.u
  EndStructureUnion

  ;;;;StructureUnion
  ;;;;  Reserved2.u
  ;;;;EndStructureUnion
  
  Window.u
  Checksum.u
  UrgPtr.u
EndStructure

Structure DIVERT_UDPHDR
  SrcPort.u
  DstPort.u
  Length.u
  Checksum.u
EndStructure

#MAXBUF = $FFFF

#DIVERT_DIRECTION_OUTBOUND = 0
#DIVERT_DIRECTION_INBOUND = 1

#ERROR_INVALID_PARAMETER  = 87  ;This indicates an invalid packet filter string, layer, priority, Or flags.  
#ERROR_FILE_NOT_FOUND  = 2  ;One Or more of the WinDivert.sys, WinDivert.inf, And WdfCoInstaller*.dll files were Not found.  
#ERROR_ACCESS_DENIED  = 5  ;The calling application does Not have Administrator privileges.  
#ERROR_INVALID_IMAGE_HASH  = 577  ;The WinDivert.sys driver does Not have a valid digital signature (see the driver signing requirements above), Or  


; / *
#DIVERT_FLAG_SNIFF = 1 ;
;This flag opens the WinDivert handle in packet sniffing mode. In packet sniffing mode the original packet is 
; Not dropped-And-diverted (the Default) but copied-And-diverted. This mode is useful For implementing packet 
; sniffing tools similar To those applications that currently use Winpcap. 

#DIVERT_FLAG_DROP = 2
;This flag indicates that the user application does not intend to read matching packets with DivertRecv(), instead the 
; packets should be silently dropped. This is useful For implementing simple packet filters using the WinDivert filter language. 

;If both DIVERT_FLAG_SNIFF and DIVERT_FLAG_DROP flags are set, the WinDivert handle will be in "passthru" mode that neither captures 
;nor drops any packet. Such a handle is useful For applications that only require packet injection
; * \

; #DIVERT_PARAM_QUEUE_LEN  = 0,  ; /* Packet queue length. */
;Sets the maximum length of the packet queue for DivertRecv(). Currently the default value is 512, the minimum is 1, and the maximum is 8192. 

; #DIVERT_PARAM_QUEUE_TIME = 1  ; /* Packet queue time. */
;Sets the minimum time, in milliseconds, a packet can be queued before it is automatically dropped. Packets cannot be queued indefinitely, 
;  And ideally, packets should be processed by the application As soon As is possible. Note that this sets the minimum time a packet can be
;  queued before it can be dropped. The actual time may be exceed this value. 
;  Currently the Default value is 256, the minimum is 32, And the maximum is 1024.  


#IP_CE     = $8000          ; Congestion Experienced
#IP_DF     = $000            ; Don't Fragment
#IP_MF    = $2000          ; More Fragments
#IP_OFFMASK = $1FFF   ; Offset mask value

#tcp_FlagFIN      = $0001
#tcp_FlagSYN    = $0002
#tcp_FlagRST     = $0004
#tcp_FlagPUSH  = $0008
#tcp_FlagACK    = $0010
#tcp_FlagURG    = $0020
#tcp_FlagECN    = $0040   ; ECN-Echo
#tcp_FlagCWR   = $0080   ; Congestion Window reduced

#tcp_FlagNS       = $0100
#tcp_FlagRS       = $0E00

#tcp_FlagMASK = $003F   ; All Flags considered.
#tcp_FlagDO      = $F000

#tcp_flagsAll = #tcp_FlagFIN | #tcp_FlagSYN | #tcp_FlagRST | #tcp_FlagPUSH | #tcp_FlagACK | #tcp_FlagURG ; #tcp_FlagECN | #tcp_FlagCWR | ; #tcp_FlagNS | #tcp_FlagRS

#DIVERT_HELPER_NO_IP_CHECKSUM = 1
#DIVERT_HELPER_NO_ICMP_CHECKSUM = 2
#DIVERT_HELPER_NO_ICMPV6_CHECKSUM = 4
#DIVERT_HELPER_NO_TCP_CHECKSUM = 8
#DIVERT_HELPER_NO_UDP_CHECKSUM = 16

Prototype protoDivertOpen(filter.s, layer, priority.u, flags.q)
Global DivertOpen.protoDivertOpen

Prototype.b protoDivertGetParam(handle, param, pValue.q)
Global DivertGetParam.protoDivertGetParam

Prototype.b protoDivertSetParam(handle, param, value.q)
Global DivertSetParam.protoDivertSetParam

Prototype.b protoDivertRecv(handle, *pPacket, packetLen, pAddr, recvLen)
Global DivertRecv.protoDivertRecv

Prototype.b protoDivertSend(handle, *pPacket, packetLen, pAddr, sendLen)
Global DivertSend.protoDivertSend

Prototype.b protoDivertHelperParsePacket(*pPacket, packetLen, *ppIpHdr, *ppIpv6Hdr, *ppIcmpHdr, *ppIcmpv6Hdr, *ppTcpHdr, *ppUdpHdr, *ppData, pDataLen)
Global DivertHelperParsePacket.protoDivertHelperParsePacket

Prototype.b protoDivertHelperParseIPv4Address(addrStr.s, *pAddr)
Global DivertHelperParseIPv4Address.protoDivertHelperParseIPv4Address

Prototype.b protoDivertHelperParseIPv6Address(addrStr.s, *pAddr)
Global DivertHelperParseIPv6Address.protoDivertHelperParseIPv6Address

Prototype protoDivertHelperCalcChecksums(*pPacket, packetLen, flags.q)
Global DivertHelperCalcChecksums.protoDivertHelperCalcChecksums

Prototype.b protoDivertClose(handle)
Global DivertClose.protoDivertClose

Procedure.s MatchFlags(tp.s)  
  tcpFlags.s = "RS NS CWR ECE URG ACK PSH RST SYN FIN"
  
  len = Len(tp) : If len > 13 : len = 13 : EndIf : tcpMultiFlags.s = ""
  While  len > 0 ;And len < 12      
    If 0 < len : 
      If Mid(tp, len, 1) <> "1" : len-1 : Continue : EndIf
      tcpMultiFlags + ", " + StringField(tcpFlags,len-3, " ") : 
    EndIf
    len-1
  Wend   
  
  If Mid(tcpMultiFlags, 1, 2) = ", " : tcpMultiFlags = "("+Mid(tcpMultiFlags,2)+")" : EndIf 
  
  ProcedureReturn tcpMultiFlags
EndProcedure

Procedure.s TestForError()
  Result.s = ""
  dwMessageId = GetLastError_()
  *lpBuffer = AllocateMemory(255)
  FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, #Null, dwMessageId, #Null, *lpBuffer, MemorySize(*lpBuffer), #Null)
  dwDescription.s = PeekS(*lpBuffer)
  Result = "Error: " + Str(dwMessageId) + " - " + Left(dwDescription, Len(dwDescription) - 1)
  FreeMemory(*lpBuffer)
  ProcedureReturn Result
EndProcedure


WinDivert = OpenLibrary(#PB_Any, "WinDivert.dll")

If IsLibrary(WinDivert)
  DivertOpen = GetFunction(WinDivert, "DivertOpen")
  ;   filter.s = "true" ;true - Divert all traffic, false - Diverts no traffic
    filter.s = "outbound && ip && (tcp.DstPort == 80 && tcp.PayloadLength > 0)"  
  
  
  #DIVERT_LAYER_NETWORK = 0                        ; /* The network layer. 0 is the default. */
  #DIVERT_LAYER_NETWORK_FORWARD = 1   ; /* The network layer (forwarded packets). */
  #DIVERT_PRIORITY_DEFAULT = -1000 
  
  hWndDivert = DivertOpen(filter, #DIVERT_LAYER_NETWORK, #DIVERT_PRIORITY_DEFAULT, #DIVERT_FLAG_SNIFF)
  
  If hWndDivert <> #INVALID_HANDLE_VALUE
    Debug "---------------"
    Debug "DivertOpen"
    Debug "---------------"
    Debug "hWndDivert: " + Str(hWndDivert)
    Debug "   filter: " + filter
    #DIVERT_PARAM_QUEUE_LEN = 0
    #DIVERT_PARAM_QUEUE_TIME = 1
    DivertSetParam = GetFunction(WinDivert, "DivertSetParam")
    DivertSetParam(hWndDivert, #DIVERT_PARAM_QUEUE_LEN, 8192)
    DivertSetParam(hWndDivert, #DIVERT_PARAM_QUEUE_TIME, 1024)
    *pPacket = AllocateMemory(#MAXBUF)
    pAddr.DIVERT_ADDRESS
    DivertRecv = GetFunction(WinDivert, "DivertRecv")
    
    
    If DivertRecv(hWndDivert, *pPacket, MemorySize(*pPacket), @pAddr, @recvLen)
      Debug "---------------"
      Debug "DivertRecv"
      Debug "---------------"
      Debug "pAddr\IfIdx: " + PeekL(@pAddr\IfIdx)
      Debug "pAddr\SubIfIdx: " + PeekL(@pAddr\SubIfIdx)
      If  PeekA(@pAddr\Direction) : pDirection.s = "1 for Inbound" : Else : pDirection.s = "0 for Outbound" : EndIf
      Debug "pAddr\Direction: " + pDirection : Debug ""
      
      
      *ppIpHdr.DIVERT_IPHDR : *ppIpv6Hdr.DIVERT_IPV6HDR : *ppIcmpHdr.DIVERT_ICMPHDR
      *ppIcmpv6Hdr.DIVERT_ICMPV6HDR : *ppTcpHdr.DIVERT_TCPHDR : *ppUdpHdr.DIVERT_UDPHDR
      
      DivertHelperParsePacket = GetFunction(WinDivert, "DivertHelperParsePacket")
      DivertHelperParsePacket(*pPacket, recvLen, @*ppIpHdr, @*ppIpv6Hdr, @*ppIcmpHdr, @*ppIcmpv6Hdr, @*ppTcpHdr, @*ppUdpHdr, @*ppData, @pDataLen)
      
      
      If *ppIpHdr
        Debug "ppIpHdr\Version: " + Str(PeekA(@*ppIpHdr\Version) >> 4 & %1111)
        Debug "ppIpHdr\HdrLength: " + Str((PeekA(@*ppIpHdr\HdrLength) & %1111) * 4) + " bytes"
        Debug "ppIpHdr\TOS: " + ntohs_(PeekA(@*ppIpHdr\TOS))
        Debug "ppIpHdr\Length: " + ntohs_(PeekU(@*ppIpHdr\Length))
        ipHdrId.u = ntohs_(PeekU(@*ppIpHdr\Id))
        Debug "ppIpHdr\Id: 0x"+RSet (Hex(ipHdrId), 4, "0") + " (" + ipHdrId + ")"
        ;;;;Debug "ppIpHdr\Id: " + ntohs_(PeekU(@*ppIpHdr\Id))


        FragOff0.u = PeekU(@*ppIpHdr\FragOff0)
        FragCalc1.l = (FragOff0 & $0080) >> 7 : FragCalc2.l = (FragOff0 & $0040) >> 6
        FragCalc3.l = (FragOff0 & $0020) >> 5 : FragCalc4.l = ntohs_(FragOff0 & $FF1F) * 8
        
        FragOff_Str.s = "0x0" 
        If FragCalc1 : FragOff_Str + "3 (Reserved)"
        ElseIf FragCalc2 : FragOff_Str + "2 (Don't Fragment)"
        ElseIf FragCalc3 : FragOff_Str + "1 (More  Fragment)"
        Else : FragOff_Str + "0 (Fragment Offset)"
        EndIf 
        
        Debug "ppIpHdr\FragOff0"
        Debug "_Flags: "+FragOff_Str
        Debug "   --Bit 0 (Reseverd): " + Str(FragCalc1)
        Debug "   --Bit 1 (May Fragment = 0 / Don't Fragment = 1): " + Str(FragCalc2)
        Debug "   --Bit 2 (Last Fragment = 0 / More Fragments = 1): " + Str(FragCalc3)
        Debug "   --Fragment Offset: " + Str(FragCalc4)        
        Debug ""
        Debug "ppIpHdr\TTL: " + PeekA(@*ppIpHdr\TTL)
        
        IpHdrProtocol.a = PeekA(@*ppIpHdr\Protocol) : IpProtocol.s    
        Select IpHdrProtocol
          Case 1 : IpProtocol = "ICMP"
          Case 2 : IpProtocol = "IGMP" 
          Case 6 : IpProtocol = "TCP"
          Case 17 : IpProtocol = "UDP"
          Case 47 : IpProtocol = "GRE"
          Default : IpProtocol = "Other"           
        EndSelect                
        Debug "ppIpHdr\Protocol: " + IpProtocol + " ("+IpHdrProtocol+")"      
        
        ipHdrChksum.u = ntohs_(PeekU(@*ppIpHdr\Checksum))
        Debug "ppIpHdr\Checksum: 0x" + RSet (Hex(ipHdrChksum), 4, "0") + " (" + ipHdrChksum + ")"
        
        ;;;;;;;;Debug "ppIpHdr\Checksum: " + ntohs_(PeekU(@*ppIpHdr\Checksum))             
        Debug "ppIpHdr\SrcAddr: " + IPString(PeekL(@*ppIpHdr\SrcAddr))
        Debug "ppIpHdr\DstAddr: " + IPString(PeekL(@*ppIpHdr\DstAddr))
      EndIf      
      
      If *ppIpv6Hdr
        Debug "---------------"
        Debug "ppIpv6Hdr\TrafficClass0: " + PeekA(@*ppIpv6Hdr\TrafficClass0)
        Debug "ppIpv6Hdr\Version: " + PeekA(@*ppIpv6Hdr\Version)
        Debug "ppIpv6Hdr\FlowLabel0: " + PeekA(@*ppIpv6Hdr\FlowLabel0)
        Debug "ppIpv6Hdr\TrafficClass1: " + PeekA(@*ppIpv6Hdr\TrafficClass1)
        Debug "ppIpv6Hdr\FlowLabel1: " + ntohs_(PeekU(@*ppIpv6Hdr\FlowLabel1))
        Debug "ppIpv6Hdr\Length: " + ntohs_(PeekU(@*ppIpv6Hdr\Length))
        Debug "ppIpv6Hdr\NextHdr: " + PeekA(@*ppIpv6Hdr\NextHdr)
        Debug "ppIpv6Hdr\HopLimit: " + PeekA(@*ppIpv6Hdr\HopLimit)
        Debug "ppIpv6Hdr\SrcAddr[1]: " + IPString(PeekL(@*ppIpv6Hdr\SrcAddr[0]))
        Debug "ppIpv6Hdr\SrcAddr[2]: " + IPString(PeekL(@*ppIpv6Hdr\SrcAddr[1]))
        Debug "ppIpv6Hdr\SrcAddr[3]: " + IPString(PeekL(@*ppIpv6Hdr\SrcAddr[2]))
        Debug "ppIpv6Hdr\SrcAddr[4]: " + IPString(PeekL(@*ppIpv6Hdr\SrcAddr[3]))
        Debug "ppIpv6Hdr\DstAddr[1]: " + IPString(PeekL(@*ppIpv6Hdr\DstAddr[0]))
        Debug "ppIpv6Hdr\DstAddr[2]: " + IPString(PeekL(@*ppIpv6Hdr\DstAddr[1]))
        Debug "ppIpv6Hdr\DstAddr[3]: " + IPString(PeekL(@*ppIpv6Hdr\DstAddr[2]))
        Debug "ppIpv6Hdr\DstAddr[4]: " + IPString(PeekL(@*ppIpv6Hdr\DstAddr[3]))
      EndIf      
      
      If *ppIcmpHdr
        Debug "---------------"
        Debug "ppIcmpHdr\Type: " + PeekA(@*ppIcmpHdr\Type)
        Debug "ppIcmpHdr\Code: " + PeekA(@*ppIcmpHdr\Code)
        icmpHdrChksum.u = ntohs_(PeekU(@*ppIcmpHdr\Checksum))
        Debug "ppIcmpHdr\Checksum: 0x" + RSet (Hex(icmpHdrChksum), 4, "0") + " ("+ icmpHdrChksum+")"   
        ;;;;;;;;Debug "ppIcmpHdr\Checksum: " + ntohs_(PeekU(ppIcmpHdr\Checksum))
        Debug "ppIcmpHdr\Body: " + ntohl_(PeekL(@*ppIcmpHdr\Body))
      EndIf      
      
      If *ppIcmpv6Hdr
        Debug "---------------"
        Debug "ppIcmpv6Hdr\Type: " + PeekA(@*ppIcmpv6Hdr\Type)
        Debug "ppIcmpv6Hdr\Code: " + PeekA(@*ppIcmpv6Hdr\Code)
        Debug "ppIcmpv6Hdr\Checksum: " + ntohs_(PeekU(@*ppIcmpv6Hdr\Checksum))
        Debug "ppIcmpv6Hdr\Body: " + ntohl_(PeekL(@*ppIcmpv6Hdr\Body))
      EndIf
      
      If *ppTcpHdr
        Debug "---------------"
        Debug "ppTcpHdr\SrcPort: " + ntohs_(PeekU(@*ppTcpHdr\SrcPort))
        Debug "ppTcpHdr\DstPort: " + ntohs_(PeekU(@*ppTcpHdr\DstPort))
        Debug "ppTcpHdr\SeqNum: " + ntohl_(PeekL(@*ppTcpHdr\SeqNum))
        Debug "ppTcpHdr\AckNum: " + ntohl_(PeekL(@*ppTcpHdr\AckNum))
        Debug "ppTcpHdr\HdrLength: " + Str((PeekB(@*ppTcpHdr\HdrLength) >> 4 & %1111) * 4) + " bytes"
        Debug "ppTcpHdr\Reserved1: " +  Str(PeekB(@*ppTcpHdr\Reserved1) & %1111)
        ;         Debug "ppTcpHdr\Reserved1: " + PeekU(@*ppTcpHdr\Reserved1)
        ;         Debug "ppTcpHdr\HdrLength: " + PeekU(@*ppTcpHdr\HdrLength)
        
        
        Debug "ppTcpHdr\[Reserved2, Urg, Ack, Psh, Rst, Syn, Fin]" : tcpFlags.b = PeekB(@*ppTcpHdr\Urg)
        Debug "_TCP Flags: (0x"+ Hex(tcpFlags) +") "+MatchFlags(RSet(Bin(tcpFlags),10,"0"))
        
        
        ;;;;;;;;Debug "ppTcpHdr\Fin: " + PeekU(@*ppTcpHdr\Fin)
        ;;;;;;;;Debug "ppTcpHdr\Syn: " + PeekU(@*ppTcpHdr\Syn)
        ;;;;;;;;Debug "ppTcpHdr\Rst: " + PeekU(@*ppTcpHdr\Rst)
        ;;;;;;;;Debug "ppTcpHdr\Psh: " + PeekU(@*ppTcpHdr\Psh)
        ;;;;;;;;Debug "ppTcpHdr\Ack: " + PeekU(@*ppTcpHdr\Ack)
        ;;;;;;;;Debug "ppTcpHdr\Urg: " + PeekU(@*ppTcpHdr\Urg)
        ;;;;;;;;Debug "ppTcpHdr\Reserved2: " + PeekU(@*ppTcpHdr\Reserved2)
        
        Debug "ppTcpHdr\Window: " + ntohs_(PeekU(@*ppTcpHdr\Window))        
        tcpHdrChksum.u = ntohs_(PeekU(@*ppTcpHdr\Checksum))
        Debug "ppTcpHdr\Checksum: 0x" + RSet (Hex(tcpHdrChksum), 4, "0") + " ("+ tcpHdrChksum+")"         
        
        ;;;;;;;;Debug "ppTcpHdr\Checksum: " + ntohs_(PeekU(@*ppTcpHdr\Checksum))        
        Debug "ppTcpHdr\UrgPtr: " + ntohs_(PeekU(@*ppTcpHdr\UrgPtr))
      EndIf
      
      If *ppUdpHdr
        Debug "---------------"
        Debug "ppUdpHdr\SrcPort: " + ntohs_(PeekU(@*ppUdpHdr\SrcPort))
        Debug "ppUdpHdr\DstPort: " + ntohs_(PeekU(@*ppUdpHdr\DstPort))
        Debug "ppUdpHdr\Length: " + ntohs_(PeekU(@*ppUdpHdr\Length))
        udpHdrChksum.u = ntohs_(PeekU(@*ppUdpHdr\Checksum))
        Debug "ppUcpHdr\Checksum: 0x" + RSet (Hex(udpHdrChksum), 4, "0") + " ("+ udpHdrChksum+")"
        ;;;;;;;;Debug "ppUdpHdr\Checksum: " + ntohs_(PeekU(@*ppUdpHdr\Checksum))
      EndIf
      
            Debug "---------------"
            Debug "*ppData"
            Debug "---------------"
            Debug PeekS(ppData, pDataLen)    ; Show Packet's data/payload.      
    Else
      Debug "---------------"
      Debug "DivertRecv"
      Debug TestForError()
      Debug "---------------"
    EndIf
    FreeMemory(*pPacket)
    DivertClose = GetFunction(WinDivert, "DivertClose")
    DivertClose(hWndDivert)
  Else
    Debug "---------------"
    Debug "DivertOpen"
    GetErrorCode = GetLastError_()
    If GetErrorCode = #ERROR_INVALID_PARAMETER 
      Debug "Error Code: 87,  This indicates an invalid packet filter string, layer, priority, Or flags. "
    ElseIf GetErrorCode =#ERROR_FILE_NOT_FOUND  
      Debug "Error Code: 2 , One Or more of the WinDivert.sys, WinDivert.inf, And WdfCoInstaller*.dll files were Not found. "
    ElseIf GetErrorCode =#ERROR_ACCESS_DENIED
      Debug "Error Code: 5, The calling application does Not have Administrator privileges."
    ElseIf GetErrorCode = #ERROR_INVALID_IMAGE_HASH
      Debug "Error Code: 577, The WinDivert.sys driver does Not have a valid digital signature (see the driver signing requirements above), Or"
      Debug "WinDivert.sys is the wrong version, i.e. 32-bit on 64-bit Windows Or vice versa"
    Else 
      Debug "Error Code: "+Str(GetErrorCode)+" unknown."
      If GetLastError_() > 0 : Debug TestForError() : EndIf
    EndIf
    Debug "WinDivert error: failed to open Divert device."
    Debug "---------------"
    
    ;;;;;;;;Debug "---------------"
    ;;;;;;;;Debug "DivertOpen"
    ;;;;;;;;Debug TestForError()
    ;;;;;;;;Debug "---------------"
  EndIf
  CloseLibrary(WinDivert)
    RunProgram("sc", "stop WinDivert1.0", "")
    RunProgram("sc", "delete WinDivert1.0", "")
  
Else : Debug "WinDivert - 'WinDivert.dll' file might not have been found."
EndIf

Edit: Updated, Rev6 (28/09/2013).

Rev 5 (28/09/2013) - Altered a little the appearance of the logging little more.
Rev 4 (28/09/2013) - Made several corrections and adjustments mainly to the TCP Header related stuff.
Rev 3 - Moved FreeMemory(*pPacket) to proper spot
Rev 2 - Change: styled the most of the checksums.

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 9:42 pm
by JHPJHP
Looking good, starting to build momentum now. :)

*** move FreeMemory(*pPacket) down one level - I had it in the wrong spot - to just before DivertClose ***
*** there are a couple Constants in your update that have been duplicated: #DIVERT_FLAG_SNIFF, #DIVERT_FLAG_DROP ***

Here is something else to add:
- Multithreaded Packet (re)Injection example - multithreaded not required, but on a large project it would be effective.

Code: Select all

Structure PACKET_SEND
  hWndDivert.l
  *pPacket
  recvLen.l
  pAddr.DIVERT_ADDRESS
EndStructure

Procedure PassthruPacket(*Data.PACKET_SEND)
  Protected WinDivert = OpenLibrary(#PB_Any, "WinDivert.dll")

  If IsLibrary(WinDivert)
    DivertSend = GetFunction(WinDivert, "DivertSend")

    If DivertSend(*Data\hWndDivert, *Data\pPacket, *Data\recvLen, @*Data\pAddr, @sendLen)
      Debug "---------------"
      Debug "Packet Successfully Reinjected!!!"
      Debug "---------------"
    EndIf
    CloseLibrary(WinDivert)
  EndIf
  ClearStructure(*Data, PACKET_SEND)
  FreeMemory(*Data)
EndProcedure
*Data.PACKET_SEND = AllocateMemory(SizeOf(PACKET_SEND))
*Data\hWndDivert = hWndDivert
*Data\pPacket = *pPacket
*Data\recvLen = recvLen
*Data\pAddr = pAddr
CreateThread(@PassthruPacket(), *Data)
Delay(1000)
FreeMemory(*pPacket)
Link updated as well (don't overwrite your version with this one - I'm still working from my original).

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 9:52 pm
by Thunder93
Thanks. Corrected the FreeMemory misalignment few minutes ago... There is no duplication on those two constants.

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 9:56 pm
by Thunder93
Indeed! I do see momentum! :lol:

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 10:04 pm
by JHPJHP
There is no duplication on those two constants.
My mistake.

About my previous question, were you referring to promiscuous mode? I only ask because I'm wondering if there is a work around, or if -basil has it planned for a later release - maybe something I can follow up with?

My next step with Packet Injection will be to redirect the webpage to a new address - seems straight forward, but that kinda thinking usually gets me in trouble.

Re: Windows Filtering Platform

Posted: Tue Sep 24, 2013 10:20 pm
by Thunder93
Yes.. About that! I kept getting around to responding on that but then I got caught up in other things.

There seems to be some sort of simple form checking (or something else) that causes certain types of packets, ignored or not forwarded. These are however seen coming in and seen going out with sniffers, but not seen with this. I'll investigate it further, but there does seem to be a problem. And one thing can be ruled out..., no excessive amount of packets causing what I'm throwing at it to be placed on a back burner and timed-out, or simply ignored.

Re: Windows Filtering Platform

Posted: Wed Sep 25, 2013 2:09 am
by JHPJHP
*** update ***

So I spent the past few hours downloading and installing the Windows Driver Kit, and creating the new drivers... only to find out that WinDivert.sys is not signed - like that shouldn't have been obvious. For now we will have to stick with our current version.

*** update ***

WinDivert has an updated version (1.1 we're currently using 1.05) found here: https://github.com/basil00/Divert - windivert.html explains how to compile the new source code.

Re: Windows Filtering Platform

Posted: Sat Sep 28, 2013 6:32 am
by Thunder93
JHPJHP. I just had the opportunity to have another look at the code. I noticed that the TCP flags values all return the same information due to being union-ified. Also since we are sharing memory space, it might be best to also include Reserved2 field in that shared memory space. It contains the other TCP flags like CWR and ECE and the two newer ones defined now. :wink:

Re: Windows Filtering Platform

Posted: Sat Sep 28, 2013 6:47 am
by Thunder93
Yes. With the signed package it seems to do some simple checks and decides what's appropriate to be forwarded / monitored. I would actually prefer to see a separate package offered and digitally signed that doesn't take it upon itself and force restrictions to what Is monitored and handled.

I also wish it was explained why the administrator privileges is required to not only install the drivers, but to use it? ... at least that is what was stated on the site. What features requires administrator privileges?

Yea... when I wanted to see if there is a difference in results using the other bit version, the 32bit driver usage on the 64bit Windows caused the blocked driver event.