Page 8 of 14

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 4:01 am
by JHPJHP
That's the problem with writing, the true meaning can get lost unless an entire gambit of emotion is translated correctly. :)

It was meant rhetorically, as a segue into the next thing. We translated (most) of a packet, redirected packets, blocked packets, and this was the start of replacing "things" in the packets; the PureBasic image was replaced by a Visa image (an idea I got from using Fiddler2).

The post also talked about reassembling the data (payload) part of the packet. But you probably read it before I had my thoughts fully organized, and written that part... :P

Now I may be getting ahead of myself, as you might not be interested in continuing, crediting how much we accomplished already?

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 4:41 am
by Thunder93
Hi. Still interested. It is fun but annoying. I was working on the problems you experienced the other day. But you cheated to overcome them :mrgreen:

I'm heading off to bed early, or compared to lately.. :p


I'll leave you with what I was working on, and how far I got. You might be-able do something more now with some push in the right direction ... no cheating this time! :lol:

Code: Select all

#DIVERT_LAYER_NETWORK = 0
#DIVERT_PRIORITY_DEFAULT = 0
#DIVERT_FLAG_DEFAULT = 0

#DIVERT_DIRECTION_INBOUND = 1
#DIVERT_HELPER_NO_ICMP_CHECKSUM = 2
#DIVERT_HELPER_NO_ICMPV6_CHECKSUM = 4
#DIVERT_HELPER_NO_UDP_CHECKSUM = 16

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#MAXBUF = $FFFF
#MAXURL = 4096

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
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(*packet.PACKET)
    FillMemory(*PACKET, SizeOf( *PACKET )) : IPHdrLengthIs.l = 4 ;;;; <--- Header Length variable exists for show
    
    *packet\ip\Version = Val("$"+Str(SizeOf(DIVERT_IPHDR) / 4) + IPHdrLengthIs)
    *packet\ip\Length = htons_(SizeOf(PACKET) )
    *packet\ip\TTL = 64
    *packet\ip\Protocol = #IPPROTO_TCP    
    ;     *packet\tcp\HdrLength = Val("$0"+Str(SizeOf(DIVERT_TCPHDR) / 4))
    *packet\tcp\HdrLength = SizeOf(PACKET\tcp) * 4
    
;;;; 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


#block_data = "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>"

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")  

  reset0.PACKET : *reset.PACKET = @reset0  
  finish0.PACKET : *finish.PACKET = @finish0   
  
  blockpage_len = SizeOf(DATAPACKET) + Len(#block_data) - 1
  *blockpage.DATAPACKET = AllocateMemory(blockpage_len)
  
  If Not *blockpage : Debug  "*blockpage error: memory allocation failed" : End : EndIf 
  
  PacketInit(@*blockpage\header)
  *blockpage\header\ip\Length = htons_(blockpage_len)
  *blockpage\header\tcp\SrcPort = htons_(80)
  *blockpage\header\tcp\Reserved2 = %00011000 ;;; <--- ACK+PSH   
  
  *blockpage\Data = AllocateMemory(Len(#block_data) - 1)
  FillMemory(@*blockpage\Data, Len(#block_data) + 100)
  PokeS(@*blockpage\Data, #block_data, Len(#block_data))
  
;   *reset.PACKET = AllocateMemory(SizeOf(PACKET))
;   FillMemory(*reset, SizeOf(PACKET), 0)
PacketInit(*reset)
; *reset\tcp\Reserved2 = $14
    *reset\tcp\Reserved2 = %00010100  ;<---- ACK+RST   <-------- Makes gibberish addition to browser block data. I believe It is narrowed to the IP length needing to be adjusted properly. 
    
;   *finish.PACKET = AllocateMemory(SizeOf(PACKET))
;   FillMemory(*finish, SizeOf(PACKET), 0)
  PacketInit(*finish)
  *finish\tcp\Reserved2 = %00010001  ;<---- ACK+FIN    <-------- Makes gibberish addition to browser block data 
;   *finish\tcp\Reserved2 = $11

  
  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\HdrLength = *ppIpHdr\HdrLength
;             *reset\ip\Length = *ppIpHdr\Length                        ;<---- Not Needed now

;          // (1) Send a TCP RST To the server; immediately closing the connection at the server's end.
            *reset\ip\SrcAddr = *ppIpHdr\SrcAddr
            *reset\ip\DstAddr = *ppIpHdr\DstAddr
;             *reset\tcp\HdrLength = *ppTcpHdr\HdrLength         ;<----- Not Needed now
            *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 "*reset.DrivertSend: warning: failed To send reset packet"
              Debug TestForError()
              Continue
            EndIf

;             // (2) Send the blockpage To the browser:
            *blockpage\header\ip\HdrLength = *ppIpHdr\HdrLength      ; <---- Needed

            Debug "Not gone in correctly, via PacketInit()..... Wrong Value: "+Str(*blockpage\header\ip\Length)
            Debug "*ppIpHdr\Length has more accurate value."+Str(*ppIpHdr\Length)
            
            
            *blockpage\header\ip\Length = *ppIpHdr\Length                   ; <---- Needed            
            
            *blockpage\header\ip\SrcAddr = *ppIpHdr\DstAddr
            *blockpage\header\ip\DstAddr = *ppIpHdr\SrcAddr            
;           *blockpage\header\tcp\HdrLength = *ppTcpHdr\HdrLength         ;<----- Not Needed now
            *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, recvLen, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)

            If Not DivertSend(hWndDivert, *blockpage, recvLen, @pAddr, #Null)
              Debug "*blockpage.DrivertSend: warning: failed To send block page packet"
              Debug TestForError()
              Continue
            EndIf
            
;            // (3) Send a TCP FIN To the browser; closing the connection at the browser's end.
            *finish\ip\HdrLength = *ppIpHdr\HdrLength       ; <---- Needed for complete operation
            *finish\ip\Length = *ppIpHdr\Length                   ; <---- Needed for complete operation
            *finish\ip\SrcAddr = *ppIpHdr\DstAddr
            *finish\ip\DstAddr = *ppIpHdr\SrcAddr
;             *finish\tcp\HdrLength = *ppTcpHdr\HdrLength           ; <---- Not Needed now.
            *finish\tcp\SrcPort = htons_(80)
            *finish\tcp\DstPort = *ppTcpHdr\SrcPort
            *finish\tcp\SeqNum = htonl_(ntohl_(PeekL(@*ppTcpHdr\AckNum)) + Len(#block_data) - 1)
            *finish\tcp\AckNum = htonl_(ntohl_(PeekL(@*ppTcpHdr\SeqNum)) + pDataLen)
            DivertHelperCalcChecksums(*finish, recvLen, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)

            If Not DivertSend(hWndDivert, *finish, recvLen, @pAddr, #Null)
              Debug "*finish.DivertSend: warning: failed to send finish packet"
              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

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 8:44 am
by JHPJHP
Noticed a couple of things:
- not being used: overridden by ip\HdrLength (shared memory in Structure)

Code: Select all

*packet\ip\Version = Val("$"+Str(SizeOf(DIVERT_IPHDR) / 4) + IPHdrLengthIs)
- not needed for *reset, overridden by *blockpage, *finish

Code: Select all

*packet\ip\Length = htons_(SizeOf(PACKET) )
Don't know about cheating :shock: :P ...

I'll probably be away for a couple days, I've had more coffee then hours sleep... and have a stack of unread papers.

Cheers!

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 9:19 am
by sec
@JHPJHP: i saw 'Block': Could you to make a small network tool for block network connection: block all incomming, allow all outcomming (or allow only selected?) with WinDivert-Block?

Thanks

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 12:45 pm
by Thunder93
Reading and blocking packets is the easy part. The problem now is with packet manipulation. If you cloning existing packet information by such (*blockpage\header\ip\HdrLength = *ppIpHdr\HdrLength) you are going to run into problems with anything more serious.

The PacketInit() function is suppose to handle several things automatically including

> ip\HdrLength
> ip\Version
> tcp\HdrLength

... which should make those added additions x3 (to use / clone and write existing packet information) in our code irrelevant. I think it is better to address this now than later. If we don't understand how to properly write back (not just to read the info) then we are asking for further troubles.

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 9:46 pm
by JHPJHP
Hi sec,

WinDivert was designed for that and more... the existing code should work with only a few modifications:
- change the filter to fit your needs
- adjust the Repeat loop, probably in favor of a service
- the If command filtering packets further was only for testing (refer to original script [ webfilter.c ] for a better solution)

------------------------------------------------------

I'm not going get any sleep am I? :x :P

Two of the three (I think) resolved:
- funny enough this is code I was testing with since my first "block script" post (shared memory Structure).
- haven't looked into [ ip\Length ] yet - directly related to [ recvLen ]...

Code: Select all

Debug htons_(*ppIpHdr\Length)
Debug recvLen

Code: Select all

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"))
NB*: There is a method to my madness - I haven't created the PacketInit Procedure yet, to assist with testing; what might pass for *reset may not work for *blockpage or *finish.

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 9:55 pm
by Thunder93
Yes. I already have those changes in.

I killed most of the duplications... Just one small bug I think left.

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 10:01 pm
by JHPJHP
You already have these changes?.. I just wrote them. :?

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 10:05 pm
by Thunder93
Of course... I had that figured out hours ago... I'm just stuck basically on the IP Length incorrectness with PacketInit() function usage.

JHPJHP wrote:You already have these changes?.. I just wrote them. :?

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 10:09 pm
by Thunder93
Here is where I'm at thus far...

Code: Select all

#DIVERT_LAYER_NETWORK = 0
#DIVERT_PRIORITY_DEFAULT = 0
#DIVERT_FLAG_DEFAULT = 0

#DIVERT_DIRECTION_INBOUND = 1
#DIVERT_HELPER_NO_ICMP_CHECKSUM = 2
#DIVERT_HELPER_NO_ICMPV6_CHECKSUM = 4
#DIVERT_HELPER_NO_UDP_CHECKSUM = 16

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#MAXBUF = $FFFF
#MAXURL = 4096

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
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(*PACKET.PACKET)
  FillMemory(*PACKET, SizeOf( *PACKET ))  
    *packet\ip\Version = Val("%" +RSet(Bin(4),4,"0")+RSet(Bin((SizeOf(DIVERT_IPHDR)  / #PB_Long) + 1),4,"0") )
;    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 = Val("%" + RSet(Bin(SizeOf(DIVERT_TCPHDR)+1  / #PB_Long),4,"0") + "0000")

    
;;;; 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


#block_data = "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>"

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")  

 Packet.u = #MAXBUF

 reset0.Packet : *reset.PACKET = @reset0
 finish0.Packet : *finish.PACKET = @reset0 

  
  blockpage_len = SizeOf(DATAPACKET) + Len(#block_data) - 1
  *blockpage.DATAPACKET = AllocateMemory(blockpage_len)  
  If Not *blockpage : Debug  "*blockpage error: memory allocation failed" : End : EndIf 
  
  PacketInit(@*blockpage\header)
  
  *blockpage\header\ip\Length = htons_(blockpage_len)
  *blockpage\header\tcp\SrcPort = htons_(80)
  *blockpage\header\tcp\Reserved2 = %00011000 ;;; <--- ACK+PSH   
  
  *blockpage\Data = AllocateMemory(Len(#block_data) - 1)
  FillMemory(@*blockpage\Data, Len(#block_data) + 100)
  PokeS(@*blockpage\Data, #block_data, Len(#block_data))
  

PacketInit(*reset)
  *reset\tcp\Reserved2 = %00010100  ;<---- ACK+RST

    
  PacketInit(*finish)
  *finish\tcp\Reserved2 = %00010001  ;<---- ACK+FIN

  
  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")
;          // (1) Send a TCP RST To the server; immediately closing the connection at the server's end.
;            *reset\ip\HdrLength = *ppIpHdr\HdrLength         ; <---- Not Needed now.
           *reset\ip\Length = *ppIpHdr\Length                        ;<---- Needed
            *reset\ip\SrcAddr = *ppIpHdr\SrcAddr
            *reset\ip\DstAddr = *ppIpHdr\DstAddr
;             *reset\tcp\HdrLength = *ppTcpHdr\HdrLength         ;<----- Not Needed now
            *reset\tcp\SrcPort = *ppTcpHdr\SrcPort
            *reset\tcp\DstPort = htons_(80)
            *reset\tcp\SeqNum = *ppTcpHdr\SeqNum
            *reset\tcp\AckNum = *ppTcpHdr\AckNum
            DivertHelperCalcChecksums(*reset, recvLen, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)

            If Not DivertSend(hWndDivert, *reset, recvLen, @pAddr, #Null)
              Debug "*reset.DrivertSend: warning: failed To send reset packet"
              Debug TestForError()
              Continue
            EndIf

;             // (2) Send the blockpage To the browser:
;             *blockpage\header\ip\HdrLength = *ppIpHdr\HdrLength      ; <---- Not Needed now   
            *blockpage\header\ip\Length = *ppIpHdr\Length                   ; <---- Needed            
            
            *blockpage\header\ip\SrcAddr = *ppIpHdr\DstAddr
            *blockpage\header\ip\DstAddr = *ppIpHdr\SrcAddr            
;             *blockpage\header\tcp\HdrLength = *ppTcpHdr\HdrLength         ;<----- Not Needed now            
            *blockpage\header\tcp\DstPort = *ppTcpHdr\SrcPort
            *blockpage\header\tcp\SeqNum = *ppTcpHdr\AckNum
            *blockpage\header\tcp\AckNum = htonl_(ntohl_(*ppTcpHdr\SeqNum) + pDataLen)
            pAddr\Direction ! pAddr\Direction
            DivertHelperCalcChecksums(*blockpage, recvLen, 0)

            If Not DivertSend(hWndDivert, *blockpage, recvLen, @pAddr, #Null)
              Debug "*blockpage.DrivertSend: warning: failed To send block page packet"
              Debug TestForError()
              Continue
            EndIf
            
;            // (3) Send a TCP FIN To the browser; closing the connection at the browser's end.
;             *finish\ip\HdrLength = *ppIpHdr\HdrLength      ; <---- Not Needed now.
;             *finish\ip\Length = *ppIpHdr\Length                   ; <---- Not Needed now.
            *finish\ip\SrcAddr = *ppIpHdr\DstAddr
            *finish\ip\DstAddr = *ppIpHdr\SrcAddr
;             *finish\tcp\HdrLength = *ppTcpHdr\HdrLength           ; <---- Not Needed now.
            *finish\tcp\SrcPort = htons_(80)
            *finish\tcp\DstPort = *ppTcpHdr\SrcPort
            *finish\tcp\SeqNum = htonl_(ntohl_(PeekL(@*ppTcpHdr\AckNum)) + Len(#block_data) - 1)
            *finish\tcp\AckNum = htonl_(ntohl_(PeekL(@*ppTcpHdr\SeqNum)) + pDataLen)
            DivertHelperCalcChecksums(*finish, recvLen, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)

            If Not DivertSend(hWndDivert, *finish, recvLen, @pAddr, #Null)
              Debug "*finish.DivertSend: warning: failed to send finish packet"
              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

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 10:26 pm
by Thunder93
Earlier I noticed but didn't make the change yet, that blockpage_len is suppose to store the size in bytes. We used SizeOf on the structure but then we used +Len() on the block_data constant or string in your case. Here is the new change

Code: Select all

blockpage_len = SizeOf(DATAPACKET) + StringByteLength(#block_data)

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 11:08 pm
by JHPJHP
Don't you hate that you put all that work into resolving two of the three issues, and while holding the code, working out the third issue - I spoil the surprise with my post? :twisted:

-----------------------------------------------------------

Thanks, makes sense for future (UNICODE) use... looks like you might not have noticed my previous change:
(what I originally thought you meant when joking about cheating)

Modified (now includes your StringByteLength fix):

Code: Select all

blocklength = SizeOf(DATAPACKET) + StringByteLength(blockdata) * 2 - 1
...
PokeS(@*blockpage\Data, blockdata, StringByteLength(blockdata) * 2 - 1, #PB_UTF8)
Gone:

Code: Select all

*blockpage\Data = AllocateMemory(Len(#block_data) - 1)
FillMemory(@*blockpage\Data, Len(#block_data) + 100)

Re: Windows Filtering Platform

Posted: Wed Oct 02, 2013 11:30 pm
by Thunder93
LOL! Trying to squash problems and I keep finding more. :shock: We'll get there. :|

Re: Windows Filtering Platform

Posted: Thu Oct 03, 2013 1:08 am
by JHPJHP
Ok - figured it out... will post something shortly, just want to clean it up a bit (I think I got all the issues).

Re: Windows Filtering Platform

Posted: Thu Oct 03, 2013 1:17 am
by Thunder93
I knew you'd have it figured out. :lol: