Windows Filtering Platform

Just starting out? Need help? Post your questions and find answers here.
User avatar
JHPJHP
Addict
Addict
Posts: 2257
Joined: Sat Oct 09, 2010 3:47 am

Re: Windows Filtering Platform

Post by JHPJHP »

I'll be glad to put this one behind us. :)

I think the new script matches the original example pretty closely... And if you give it the Ok - I can finally create a PacketInit() Procedure. :wink:
Last edited by JHPJHP on Thu Oct 03, 2013 10:41 pm, edited 1 time in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

Yep. this looks good. But that PacketInit() function isn't going to be easy :p
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

Got it!... Working with the new function now perfectly.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

DING! DING! DING! heh

Code: Select all

#DIVERT_LAYER_NETWORK = 0
#DIVERT_PRIORITY_DEFAULT = 0
#DIVERT_FLAG_DEFAULT = 0
#MAXBUF = $FFFF
#DIVERT_DIRECTION_INBOUND = 1
#DIVERT_HELPER_NO_ICMP_CHECKSUM = 2
#DIVERT_HELPER_NO_ICMPV6_CHECKSUM = 4
#DIVERT_HELPER_NO_UDP_CHECKSUM = 16

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_TCPHDR
  SrcPort.u
  DstPort.u
  SeqNum.l
  AckNum.l
  StructureUnion
    Reserved1.a
    HdrLength.a
  EndStructureUnion
  StructureUnion
    Fin.a
    Syn.a
    Rst.a
    Psh.a
    Ack.a
    Urg.a
    Reserved2.a
  EndStructureUnion
  Window.u
  Checksum.u
  UrgPtr.u
EndStructure

Structure PACKET
  ip.DIVERT_IPHDR
  tcp.DIVERT_TCPHDR
EndStructure

Structure DATAPACKET
  header.PACKET
  Data.a[0]
EndStructure

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

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 protoDivertHelperCalcChecksums(*pPacket, packetLen, flags.q)
Global DivertHelperCalcChecksums.protoDivertHelperCalcChecksums

Prototype.b protoDivertClose(handle)
Global DivertClose.protoDivertClose

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

Procedure PacketInit(*xPACKET.PACKET)
   FillMemory(*xPACKET, SizeOf( *xPACKET ))
  PokeA(@*xPACKET\ip\HdrLength, Val("%" + RSet(Bin(4), 4, "0") + RSet(Bin(SizeOf(DIVERT_IPHDR) / 4), 4, "0")))
  PokeA(@*xPACKET\tcp\HdrLength, Val("%" + RSet(Bin(SizeOf(DIVERT_TCPHDR) / 4), 4, "0") + RSet(Bin(0), 4, "0")))
    *xPACKET\ip\Length = htons_(SizeOf(PACKET) )
    *xPACKET\ip\TTL = 64
    *xPACKET\ip\Protocol = #IPPROTO_TCP    
    
;;;; Original    
;     memset(packet, 0, SizeOf(PACKET));
;     packet->ip.Version = 4;
;     packet->ip.HdrLength = SizeOf(DIVERT_IPHDR) / 4 ; / SizeOf(UINT32);
;     packet->ip.Length = htons(SizeOf(PACKET));
;     packet->ip.TTL = 64;
;     packet->ip.Protocol = IPPROTO_TCP;
;     packet->tcp.HdrLength = SizeOf(DIVERT_TCPHDR) / SizeOf(UINT32);
EndProcedure


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

If IsLibrary(WinDivert)
  DivertOpen = GetFunction(WinDivert, "DivertOpen")
  DivertRecv = GetFunction(WinDivert, "DivertRecv")
  DivertHelperParsePacket = GetFunction(WinDivert, "DivertHelperParsePacket")
  DivertHelperCalcChecksums = GetFunction(WinDivert, "DivertHelperCalcChecksums")
  DivertSend = GetFunction(WinDivert, "DivertSend")
  DivertClose = GetFunction(WinDivert, "DivertClose")
  HdrLength.a = Val("%" + RSet(Bin(4), 4, "0") + RSet(Bin(SizeOf(DIVERT_IPHDR) / 4), 4, "0"))
  Reserved1.a = Val("%" + RSet(Bin(SizeOf(DIVERT_TCPHDR) / 4), 4, "0") + RSet(Bin(0), 4, "0"))
  
  *reset.PACKET = AllocateMemory(SizeOf(PACKET))
  FillMemory(*reset, SizeOf(PACKET), 0)
;   PokeA(@*reset\ip\HdrLength, HdrLength)

 PacketInit(*reset)
  *reset\ip\Length = htons_(SizeOf(PACKET))
  *reset\ip\TTL = 64
  *reset\ip\Protocol = #IPPROTO_TCP
;   PokeA(@*reset\tcp\Reserved1, Reserved1)
  PokeA(@*reset\tcp\Fin, %00010100)
  blockdata.s = "HTTP/1.1 200 OK" + #CRLF$ +
                "Connection: close" + #CRLF$ +
                "Content-Type: text/html" + #CRLF$ +
                #CRLF$ +
                "<!doctype html>" + #LF$ +
                "<html>" + #LF$ +
                "<head>" + #LF$ +
                "<title>BLOCKED!</title>" + #LF$ +
                "</head>" + #LF$ +
                "<body>" + #LF$ +
                "<h1>BLOCKED!</h1>" + #LF$ +
                "<hr>" + #LF$ +
                "<p>This URL has been blocked!</p>" + #LF$ +
                "</body>" + #LF$ +
                "</html>"
  blocklength = SizeOf(DATAPACKET) + StringByteLength(blockdata)
  *blockpage.DATAPACKET = AllocateMemory(blocklength)
  FillMemory(*blockpage, blocklength, 0)
;   PokeA(@*blockpage\header\ip\HdrLength, HdrLength)
   PacketInit(*blockpage\header);

  *blockpage\header\ip\Length = htons_(blocklength)
  *blockpage\header\ip\TTL = 64
  *blockpage\header\ip\Protocol = #IPPROTO_TCP
  *blockpage\header\tcp\SrcPort = htons_(80)
;   PokeA(@*blockpage\header\tcp\Reserved1, Reserved1)
  PokeA(@*blockpage\header\tcp\Fin, %00011000)
  
  PokeS(@*blockpage\Data[0], blockdata, StringByteLength(blockdata), #PB_UTF8)
  
  
  *finish.PACKET = AllocateMemory(SizeOf(PACKET))
  FillMemory(*finish, SizeOf(PACKET), 0)
;   PokeA(@*finish\ip\HdrLength, HdrLength)

   PacketInit(*finish)
  *finish\ip\Length = htons_(SizeOf(PACKET))
  *finish\ip\TTL = 64
  *finish\ip\Protocol = #IPPROTO_TCP
;   PokeA(@*finish\tcp\Reserved1, Reserved1)
  PokeA(@*finish\tcp\Fin, %00010001)
  filter.s = "outbound && ip && tcp.DstPort == 80 && tcp.PayloadLength > 0"
   
  hWndDivert = DivertOpen(filter, #DIVERT_LAYER_NETWORK, #DIVERT_PRIORITY_DEFAULT, #DIVERT_FLAG_DEFAULT)

  If hWndDivert <> #INVALID_HANDLE_VALUE
    pAddr.DIVERT_ADDRESS
    *ppIpHdr.DIVERT_IPHDR
    *ppTcpHdr.DIVERT_TCPHDR
    RunProgram("iexplore", "http://www.purebasic.com/", "")

    Repeat
      *pPacket = AllocateMemory(#MAXBUF)

      If DivertRecv(hWndDivert, *pPacket, #MAXBUF, @pAddr, @recvLen)
        DivertHelperParsePacket(*pPacket, recvLen, @*ppIpHdr, #Null, #Null, #Null, @*ppTcpHdr, #Null, @*ppData, @pDataLen)

        If *ppData
          If FindString(PeekS(*ppData, pDataLen), "purebasic")
            *reset\ip\SrcAddr = *ppIpHdr\SrcAddr
            *reset\ip\DstAddr = *ppIpHdr\DstAddr
            *reset\tcp\SrcPort = *ppTcpHdr\SrcPort
            *reset\tcp\DstPort = htons_(80)
            *reset\tcp\SeqNum = *ppTcpHdr\SeqNum
            *reset\tcp\AckNum = *ppTcpHdr\AckNum
            DivertHelperCalcChecksums(*reset, SizeOf(PACKET), #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)

            If Not DivertSend(hWndDivert, *reset, SizeOf(PACKET), @pAddr, #Null)
              Debug TestForError()
              Continue
            EndIf
            *blockpage\header\ip\SrcAddr = *ppIpHdr\DstAddr
            *blockpage\header\ip\DstAddr = *ppIpHdr\SrcAddr
            *blockpage\header\tcp\DstPort = *ppTcpHdr\SrcPort
            *blockpage\header\tcp\SeqNum = *ppTcpHdr\AckNum
            *blockpage\header\tcp\AckNum = htonl_(ntohl_(PeekL(@*ppTcpHdr\SeqNum)) + pDataLen)
            pAddr\Direction = #DIVERT_DIRECTION_INBOUND
            DivertHelperCalcChecksums(*blockpage, blocklength, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)

            If Not DivertSend(hWndDivert, *blockpage, blocklength, @pAddr, #Null)
              Debug TestForError()
              Continue
            EndIf
            *finish\ip\SrcAddr = *ppIpHdr\DstAddr
            *finish\ip\DstAddr = *ppIpHdr\SrcAddr
            *finish\tcp\SrcPort = htons_(80)
            *finish\tcp\DstPort = *ppTcpHdr\SrcPort
            *finish\tcp\SeqNum = htonl_(ntohl_(PeekL(@*ppTcpHdr\AckNum)) + StringByteLength(blockdata))
            *finish\tcp\AckNum = htonl_(ntohl_(PeekL(@*ppTcpHdr\SeqNum)) + pDataLen)
            DivertHelperCalcChecksums(*finish, SizeOf(PACKET), #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)

            If Not DivertSend(hWndDivert, *finish, SizeOf(PACKET), @pAddr, #Null) : Debug TestForError() : EndIf

          Else
            DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)
          EndIf
        Else
          DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)
        EndIf
      Else
        DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)
      EndIf
      FreeMemory(*pPacket)
    ForEver
    DivertClose(hWndDivert)
    FreeMemory(*finish)
    FreeMemory(*reset)
  EndIf
  CloseLibrary(WinDivert)
  RunProgram("sc", "stop WinDivert1.0", "", #PB_Program_Hide)
  RunProgram("sc", "delete WinDivert1.0", "", #PB_Program_Hide)
EndIf

*** Updated: Rev1, read the following post for explanation.
Last edited by Thunder93 on Thu Oct 03, 2013 4:05 am, edited 1 time in total.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

There is/was a problem when sending the browser the data. The closing bracket on the </HTML> tag gone amiss e.g: </HTML

Remove all -1 after every StringByteLength(blockdata) command

:lol:
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

I feel a whole lot better now! Before you came up with this little project I was doing something else. Then you got me hooked and I'm somewhat of a perfectionist, and I needed to get that just right.


... that'll teach ya! :lol:
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
sec
Enthusiast
Enthusiast
Posts: 792
Joined: Sat Aug 09, 2003 3:13 am
Location: 90-61-92 // EU or ASIA
Contact:

Re: Windows Filtering Platform

Post by sec »

Ohah, doing Man-in-the-middle (aka MITM) for inject the iframe to web packet is proxy/hacking stuff :twisted:
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

Get your mind out of the gutter! :lol:
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
JHPJHP
Addict
Addict
Posts: 2257
Joined: Sat Oct 09, 2010 3:47 am

Re: Windows Filtering Platform

Post by JHPJHP »

Too be honest, I was cursing your name or at least your moniker, with each error you found. :twisted:

I also pride myself on being a perfectionist, so I'm very happy that you pushed... I mean motivated me to not leave that last script in its previous state.
Before you came up with this little project I was doing something else.
Lets keep things accurate - this is your project, and I'm just along for the ride. :P

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

LOL! Yea... that is pretty bad! I only have a few hours of programming time. Heh

But I figured you might have been cursing me some lol. But it all worked out for the better.

Your here more than just along for the ride. I seen you looking at those banks that we driven by.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

Here's the PB version of Divert.h.

Like you suggested way back when.... I did use Macros for the GET and SET procedures. IPv6 GET and SET isn't completed, and with REM lines. When time permits I'll complete, and update this post.

Code: Select all

; /****************************************************************************/
; /* DIVERT API                                                               */
; /****************************************************************************/

; Divert address. 
Structure DIVERT_ADDRESS
  IfIdx.l
  SubIfIdx.l
  Direction.a
EndStructure : Global pAddr.DIVERT_ADDRESS

#DIVERT_DIRECTION_OUTBOUND = 0
#DIVERT_DIRECTION_INBOUND = 1


;  * Divert layers.
#DIVERT_LAYER_NETWORK = 0                        ; /* The network layer. 0 is the default. */
#DIVERT_LAYER_NETWORK_FORWARD = 1   ; /* The network layer (forwarded packets). */

; * Divert flags.
#DIVERT_FLAG_SNIFF = 1
#DIVERT_FLAG_DROP = 2

;  * Divert parameters.
#DIVERT_PARAM_QUEUE_LEN = 0       ;  /* Packet queue length. */
#DIVERT_PARAM_QUEUE_TIME = 1     ; /* Packet queue time. */


;  * Open a divert handle.
Prototype protoDivertOpen(filter.s, layer, priority.u, flags.q)
Global DivertOpen.protoDivertOpen

;  * Receive (Read) a packet from a divert handle
Prototype.b protoDivertRecv(handle, *pPacket, packetLen, pAddr, recvLen)
Global DivertRecv.protoDivertRecv

;  * Send (write/inject) a packet To a divert handle.
Prototype.b protoDivertSend(handle, *pPacket, packetLen, pAddr, sendLen)
Global DivertSend.protoDivertSend

;  * Close a divert handle.
Prototype.b protoDivertClose(handle)
Global DivertClose.protoDivertClose

;  * Set a divert handle parameter.
Prototype.b protoDivertSetParam(handle, param, value.q)
Global DivertSetParam.protoDivertSetParam

;  * Get a divert handle parameter.
Prototype.b protoDivertGetParam(handle, param, pValue.q)
Global DivertGetParam.protoDivertGetParam

; /****************************************************************************/
; /* DIVERT HELPER API                                                        */
; /****************************************************************************/

;  * IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
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 : Global *pIpHdr.DIVERT_IPHDR


Macro  DIVERT_IPHDR_GET_FRAGOFF
 (*pIpHdr \FragOff0 & $FF1F)
EndMacro

Macro DIVERT_IPHDR_GET_MF
  ((*pIpHdr\FragOff0 & $0020) >> 5)
EndMacro

Macro DIVERT_IPHDR_GET_DF
   ((*pIpHdr\FragOff0 & $0040) >> 6)
 EndMacro
 
 Macro  DIVERT_IPHDR_GET_RESERVED
  ((*pIpHdr\FragOff0 & $0080) >> 7)
EndMacro


Macro DIVERT_IPHDR_SET_FRAGOFF(val)
  *pIpHdr\FragOff0 = ((*pIpHdr\FragOff0 & $00E0) | ((val) & $FF1F))
EndMacro


Macro DIVERT_IPHDR_SET_MF(val) 
  *pIpHdr\FragOff0 = (*pIpHdr\FragOff0 & $FFDF) | (((val) & $0001) << 5)
EndMacro
 

Macro DIVERT_IPHDR_SET_DF(val) 
  *pIpHdr\FragOff0 = (*pIpHdr\FragOff0 & $FFBF) | (((val) & $0001) << 6)
EndMacro


Macro DIVERT_IPHDR_SET_RESERVED(val) 
  *pIpHdr\FragOff0 = (*pIpHdr\FragOff0 & $FF7F) | (((val) & $0001) << 7)
EndMacro

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 : Global *pIpv6Hdr.DIVERT_IPV6HDR

; ; ; Macro DIVERT_IPV6HDR_GET_TRAFFICCLASS
; ; ;   ((*pIpv6Hdr\TrafficClass0 << 4) | (*pIpv6Hdr\TrafficClass1))
; ; ; EndMacro
; ; ; 
; ; ; Macro DIVERT_IPV6HDR_GET_FLOWLABEL
; ; ;   ((*pIpv6Hdr\FlowLabel0 << 16) | (*pIpv6Hdr\FlowLabel1))
; ; ; EndMacro
; ; ; 
; ; ; Macro DIVERT_IPV6HDR_SET_TRAFFICCLASS
; ; ;   ((*pIpv6Hdr\FlowLabel0 << 16) | (*pIpv6Hdr\FlowLabel1))
; ; ; EndMacro
; ; ; 
; ; ; Procedure DIVERT_IPV6HDR_SET_TRAFFICCLASS(val)
; ; ;   *pIpv6Hdr\TrafficClass0 = val >> 4
; ; ;   *pIpv6Hdr\TrafficClass1 = val
; ; ; EndProcedure
; ; ; 
; ; ; Procedure DIVERT_IPV6HDR_SET_FLOWLABEL(val)
; ; ;   *pIpv6Hdr\FlowLabel0 = val >> 16
; ; ;   *pIpv6Hdr\FlowLabel1 = val
; ; ; EndProcedure

Structure DIVERT_ICMPHDR
  Type.a
  Code.a
  Checksum.u
  Body.l
EndStructure : Global *pIcmpHdr.DIVERT_ICMPHDR

Structure DIVERT_ICMPV6HDR
  Type.a
  Code.a
  Checksum.u
  Body.l
EndStructure : Global *pIcmpv6Hdr.DIVERT_ICMPV6HDR

Structure DIVERT_TCPHDR
  SrcPort.u
  DstPort.u
  SeqNum.l
  AckNum.l
  StructureUnion
    Reserved1.a
    HdrLength.a
  EndStructureUnion
  StructureUnion  
    Fin.a
    Syn.a
    Rst.a
    Psh.a
    Ack.a
    Urg.a
    Reserved2.a
  EndStructureUnion
  
  Window.u
  Checksum.u
  UrgPtr.u
EndStructure : Global *pTcpHdr.DIVERT_TCPHDR

Structure DIVERT_UDPHDR
  SrcPort.u
  DstPort.u
  Length.u
  Checksum.u
EndStructure : Global *pUdpHdr.DIVERT_UDPHDR


;  * Flags For DivertHelperCalcChecksums()
#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

;  * Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
Prototype.b protoDivertHelperParsePacket(*pPacket, packetLen, *pIpHdr, *pIpv6Hdr, *pIcmpHdr, *pIcmpv6Hdr, *pTcpHdr, *pUdpHdr, *pData, pDataLen)
Global DivertHelperParsePacket.protoDivertHelperParsePacket

; * Parse an IPv4 address.
Prototype.b protoDivertHelperParseIPv4Address(addrStr.s, *pAddr)
Global DivertHelperParseIPv4Address.protoDivertHelperParseIPv4Address

;  * Parse an IPv6 address.
Prototype.b protoDivertHelperParseIPv6Address(addrStr.s, *pAddr)
Global DivertHelperParseIPv6Address.protoDivertHelperParseIPv6Address

;  * Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
Prototype protoDivertHelperCalcChecksums(*pPacket, packetLen, flags.q)
Global DivertHelperCalcChecksums.protoDivertHelperCalcChecksums
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

Hi JHPJHP.

When I said I was working on something else, I still meant WinDivert related. I also didn't mean that I was upset or anything to that nature. I'm actually very excited to see someone else taking shared interests. Like I was thinking to myself days ago.., and I'm pretty sure you on the same boat. It is good to be covering all bases now, and knocking out any and all possible porting issues to PB.

You and I together are making big strides on this, amazing how 1 mind and a half can make a difference. :lol:

The web content filtering that you was working on and experienced problems. Addressing the lengths problem made it stable. Something else to remember, if you replacing a string with a new string and the length is different, you'll need to update the headers information.

Code: Select all

replacedata = ReplaceString(replacedata, "images/logopb.gif", "images/Xogopb.gif")
Keeping the length but making a minor change to prevent the image from loading is okay. If you going to replace it to load another image on the server and this string is different length. The other parts of the page may be affected, like the other image on the page, and it wouldn't load. But your intentions were to replace the first image and not the second one.


Here is the update, but it doesn't address string replacements with different lengths.

Code: Select all

#DIVERT_LAYER_NETWORK = 0
#DIVERT_PRIORITY_DEFAULT = 0
#DIVERT_FLAG_DEFAULT = 0
#MAXBUF = $FFFF
#DIVERT_HELPER_NO_ICMP_CHECKSUM = 2
#DIVERT_HELPER_NO_ICMPV6_CHECKSUM = 4
#DIVERT_HELPER_NO_UDP_CHECKSUM = 16

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_TCPHDR
  SrcPort.u
  DstPort.u
  SeqNum.l
  AckNum.l
  StructureUnion
    Reserved1.a
    HdrLength.a
  EndStructureUnion
  StructureUnion
    Fin.a
    Syn.a
    Rst.a
    Psh.a
    Ack.a
    Urg.a
    Reserved2.a
  EndStructureUnion
  Window.u
  Checksum.u
  UrgPtr.u
EndStructure

Structure PACKET
  ip.DIVERT_IPHDR
  tcp.DIVERT_TCPHDR
EndStructure

Structure DATAPACKET
  header.PACKET
  Data.a[0]
EndStructure

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

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 protoDivertHelperCalcChecksums(*pPacket, packetLen, flags.q)
Global DivertHelperCalcChecksums.protoDivertHelperCalcChecksums

Prototype.b protoDivertClose(handle)
Global DivertClose.protoDivertClose

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")
  DivertRecv = GetFunction(WinDivert, "DivertRecv")
  DivertHelperParsePacket = GetFunction(WinDivert, "DivertHelperParsePacket")
  DivertHelperCalcChecksums = GetFunction(WinDivert, "DivertHelperCalcChecksums")
  DivertSend = GetFunction(WinDivert, "DivertSend")
  DivertClose = GetFunction(WinDivert, "DivertClose")
  
;   filter.s = "ip.SrcAddr == 88.191.144.148 or ip.DstAddr == 88.191.144.148"
  filter.s = "(ip.SrcAddr == 88.191.144.148 or ip.DstAddr == 88.191.144.148) && tcp.Ack && tcp.PayloadLength > 0"
hWndDivert = DivertOpen(filter, #DIVERT_LAYER_NETWORK, #DIVERT_PRIORITY_DEFAULT, #DIVERT_FLAG_DEFAULT)

  If hWndDivert <> #INVALID_HANDLE_VALUE
    pAddr.DIVERT_ADDRESS
    *ppIpHdr.DIVERT_IPHDR
    *ppTcpHdr.DIVERT_TCPHDR
    RunProgram("iexplore", "http://www.purebasic.com/", "")

    Repeat
      *pPacket = AllocateMemory(#MAXBUF)

      If DivertRecv(hWndDivert, *pPacket, #MAXBUF, @pAddr, @recvLen)
        DivertHelperParsePacket(*pPacket, recvLen, @*ppIpHdr, #Null, #Null, #Null, @*ppTcpHdr, #Null, @*ppData, @pDataLen)

        If *ppData
          replacedata.s = PeekS(*ppData, pDataLen)

          If FindString(replacedata, "images/logopb.gif")       
            Debug "DAMN! A MATCH! HOW COOL IS THAT?!?!?"
            replacedata = ReplaceString(replacedata, "images/logopb.gif", "images/Xogopb.gif")
;             replacelength = SizeOf(DATAPACKET) + Len(replacedata) - 1
            replacelength = SizeOf(DATAPACKET) + StringByteLength(replacedata)
            *replace.DATAPACKET = AllocateMemory(replacelength)
            FillMemory(*replace, replacelength, 0)
            *replace\header\ip\HdrLength = *ppIpHdr\HdrLength
            *replace\header\ip\TOS = *ppIpHdr\TOS
            *replace\header\ip\Length = *ppIpHdr\Length
            *replace\header\ip\Id = *ppIpHdr\Id
            *replace\header\ip\FragOff0 = *ppIpHdr\FragOff0
            *replace\header\ip\TTL = *ppIpHdr\TTL
            *replace\header\ip\Protocol = *ppIpHdr\Protocol
            *replace\header\ip\SrcAddr = *ppIpHdr\SrcAddr
            *replace\header\ip\DstAddr = *ppIpHdr\DstAddr
            *replace\header\tcp\SrcPort = *ppTcpHdr\SrcPort
            *replace\header\tcp\DstPort = *ppTcpHdr\DstPort
            *replace\header\tcp\SeqNum = *ppTcpHdr\SeqNum
            *replace\header\tcp\AckNum = *ppTcpHdr\AckNum
            *replace\header\tcp\Reserved1 = *ppTcpHdr\Reserved1
            *replace\header\tcp\Fin = *ppTcpHdr\Fin
            *replace\header\tcp\Window = *ppTcpHdr\Window
            *replace\header\tcp\UrgPtr = *ppTcpHdr\UrgPtr
;             *replace\Data[0] = AllocateMemory(Len(replacedata) - 1)
;             FillMemory(@*replace\Data[0], Len(replacedata) - 1)
;             PokeS(@*replace\Data[0], replacedata, Len(replacedata), #PB_UTF8)

           *replace\Data[0] = AllocateMemory(StringByteLength(replacedata))
            FillMemory(@*replace\Data[0], StringByteLength(replacedata))
            PokeS(@*replace\Data[0], replacedata, StringByteLength(replacedata))
            DivertHelperCalcChecksums(*replace, recvLen, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)

            If Not DivertSend(hWndDivert, *replace, recvLen, @pAddr, #Null) : Debug TestForError() : EndIf

            FreeMemory(*replace)
          Else
            DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)
          EndIf
        Else
          DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)
        EndIf
      Else
        DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)
      EndIf
      FreeMemory(*pPacket)
    ForEver
    DivertClose(hWndDivert)
    FreeMemory(*finish)
  EndIf
  CloseLibrary(WinDivert)
  RunProgram("sc", "stop WinDivert1.0", "", #PB_Program_Hide)
  RunProgram("sc", "delete WinDivert1.0", "", #PB_Program_Hide)
EndIf
JHPJHP wrote:Just something I'm playing with, I would like to flesh this one out... but it's very temperamental - I'm guessing based on header size, possibly others. It would be cool to get it to work with external images / text.

There is a lot more to do, such as intercepting / reassembling the data packets (payload) to something readable, and that's just a start - but it seems like the natural progression of events - what do you think?

Run the script: Can you spot what is out of place? :)
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
JHPJHP
Addict
Addict
Posts: 2257
Joined: Sat Oct 09, 2010 3:47 am

Re: Windows Filtering Platform

Post by JHPJHP »

I was just in the process of posting this, and like some other instances after I hit the Submit button the post disappeared :?:

...And now I see that you beat me to the punch, but great minds (or at least busy ones) :P think alike:

One is what I posted before, but with the string length thing partially worked out. The second is the beginning of a Packet Data assembly script, but it needs a gzip inflate / deflate routine - and that's just for a start.
- notice after the data is reordered, it makes a lot more sense
-- on my system there is a max packet size of 1460, based on the MTU setting of 1500
Last edited by JHPJHP on Fri Oct 04, 2013 10:53 pm, edited 1 time in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

You have to watch your language when posting on here... Otherwise your submission is futile. :lol:

Busy minds likely... Or at least one in a half :twisted:

Downloaded and had a look at your samples. Both looks good JHP.

JHPJHP wrote:I was just in the process of posting this, and like some other instances after I hit the Submit button the post disappeared :?:

...And now I see that you beat me to the punch, but great minds (or at least busy ones) :P think alike - see the following two examples:

https://www.dropbox.com/s/fp7li05bfzivs0t/WinDivert.zip

One is what I posted before, but with the string length thing partially worked out. The second is the beginning of a Packet Data assembly script, but it needs a gzip inflate / deflate routine - and that's just for a start.
- notice after the data is reordered, it makes a lot more sense
-- on my system there is a max packet size of 1460, based on the MTU setting of 1500
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
JHPJHP
Addict
Addict
Posts: 2257
Joined: Sat Oct 09, 2010 3:47 am

Re: Windows Filtering Platform

Post by JHPJHP »

Just a quick note: Don't have the PureBasic site (forum included) loaded prior to testing the Replace script - it can cause a browser crash - otherwise it works pretty good, providing the "replacelength" value is set correctly.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Post Reply