Page 6 of 14

Re: Windows Filtering Platform

Posted: Sun Sep 29, 2013 3:55 am
by JHPJHP
On another note - here is what I've been working on (not as straight forward as I thought).
(does not work at the moment, but is the basis for other things)

Stuff to Note:
- #DIVERT_FLAG_DEFAULT = 0 (injection, etc.)
- DivertHelperParseIPv4Address (same as PB: MakeIPAddress)
- DivertHelperCalcChecksums (it's that easy)

NB*: It takes more then just changing the DstAddr to redirect a webpage; why at this point I don't know, but I was in contact with -basil and he put me on to some script examples.

NB**: DivertHelperCalcChecksums will calculate even if nothing has changed - so if you change the DivertHelperParseIPv4Address to match *ppIpHdr\DstAddr it passes through correctly... means I'm on the right track.

Code: Select all

#DIVERT_LAYER_NETWORK = 0
#DIVERT_LAYER_NETWORK_FORWARD = 1

#DIVERT_PRIORITY_DEFAULT = 0

#DIVERT_FLAG_DEFAULT = 0
#DIVERT_FLAG_SNIFF = 1
#DIVERT_FLAG_DROP = 2

#MAXBUF = $FFFF

#DIVERT_DIRECTION_OUTBOUND = 0
#DIVERT_DIRECTION_INBOUND = 1

#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

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

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.b protoDivertHelperParseIPv4Address(addrStr.s, pAddr)
Global DivertHelperParseIPv4Address.protoDivertHelperParseIPv4Address

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

Prototype.b protoDivertClose(handle)
Global DivertClose.protoDivertClose

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

If IsLibrary(WinDivert)
  DivertOpen = GetFunction(WinDivert, "DivertOpen")
  DivertRecv = GetFunction(WinDivert, "DivertRecv")
  DivertHelperParsePacket = GetFunction(WinDivert, "DivertHelperParsePacket")
  DivertHelperParseIPv4Address = GetFunction(WinDivert, "DivertHelperParseIPv4Address")
  DivertHelperCalcChecksums = GetFunction(WinDivert, "DivertHelperCalcChecksums")
  DivertSend = GetFunction(WinDivert, "DivertSend")
  DivertClose = GetFunction(WinDivert, "DivertClose")
  hWndDivert = DivertOpen("tcp.DstPort == 80", #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/french/", "")

    Repeat
      *pPacket = AllocateMemory(#MAXBUF)

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

        If IPString(*ppIpHdr\DstAddr) = "88.191.144.148"
          DivertHelperParseIPv4Address("184.72.115.86", @AddrRedirect)
          *ppIpHdr\DstAddr = htonl_(AddrRedirect)
          DivertHelperCalcChecksums(*pPacket, recvLen, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)
          Debug "AddrRedirect: " + IPString(htonl_(AddrRedirect))
        EndIf
        DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)
      EndIf
      FreeMemory(*pPacket)
    ForEver
    DivertClose(hWndDivert)
  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: Sun Sep 29, 2013 4:08 am
by Thunder93
Yours works but its not going to return 1 or 0 without using bin(). And for speed and other reasons, you shouldn't keep reading from the memory that way when it is absolutely unnecessary. Since the structure fields are unionized, reading simply the Reserved2 field and having that stored and reference to with the other calls.


JHPJHP wrote:Isn't that the truth...

At least I know I'm not doing it wrong, but same results - can you take a look at my test script:
https://www.dropbox.com/s/hu4m8ek71xrpk ... rt-Data.pb

- 8 bits are always the same?

Note: the script is in an infinite loop - you will need to kill it after viewing the debug output, it will also automatically load the webpage (explorer).

Thanks,

Re: Windows Filtering Platform

Posted: Sun Sep 29, 2013 4:15 am
by Thunder93
What is stored in the 8bits depends on what you have set for the filter string. Currently you'll be seeing mostly 16 value (ACK returns) because your linking to http packet with payload for data show. If you want different results, see flag combinations. Toggle with the following lines.

Code: Select all

;   filter.s = "outbound && ip && (tcp.DstPort == 80 && tcp.PayloadLength > 0)"  
   filter.s = "outbound && ip && (tcp.Ack && tcp.Fin) && (tcp.DstPort == 80)"  
;   filter.s = "outbound && ip && tcp.Syn && (tcp.DstPort == 80)"  
;    filter.s = "outbound && ip && (tcp.Psh && tcp.DstPort == 80)"  

Re: Windows Filtering Platform

Posted: Sun Sep 29, 2013 4:30 am
by JHPJHP
Ahhh man do know how much time I spent on this... Very very nice!!! Thank you. :lol:
- Bin not needed - taken care of with Modulo.
- you're right about the memory stuff - I have a lot to clean up there.

Re: Windows Filtering Platform

Posted: Sun Sep 29, 2013 4:38 am
by Thunder93
Tested this out... I do see packets duplication but addressed over (forwarded) to the specified IP. Therefore that works... But I think you want to discontinue the original packets and work with the manipulated traffic? Never had time to look at this closely.
JHPJHP wrote:On another note - here is what I've been working on (not as straight forward as I thought).
(does not work at the moment, but is the basis for other things)

Stuff to Note:
- #DIVERT_FLAG_DEFAULT = 0 (injection, etc.)
- DivertHelperParseIPv4Address (same as PB: MakeIPAddress)
- DivertHelperCalcChecksums (it's that easy)

NB*: It takes more then just changing the DstAddr to redirect a webpage; why at this point I don't know, but I was in contact with -basil and he put me on to some script examples.

NB**: DivertHelperCalcChecksums will calculate even if nothing has changed - so if you change the DivertHelperParseIPv4Address to match *ppIpHdr\DstAddr it passes through correctly... means I'm on the right track.

Code: Select all

#DIVERT_LAYER_NETWORK = 0
#DIVERT_LAYER_NETWORK_FORWARD = 1

#DIVERT_PRIORITY_DEFAULT = 0

#DIVERT_FLAG_DEFAULT = 0
#DIVERT_FLAG_SNIFF = 1
#DIVERT_FLAG_DROP = 2

#MAXBUF = $FFFF

#DIVERT_DIRECTION_OUTBOUND = 0
#DIVERT_DIRECTION_INBOUND = 1

#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

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

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.b protoDivertHelperParseIPv4Address(addrStr.s, pAddr)
Global DivertHelperParseIPv4Address.protoDivertHelperParseIPv4Address

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

Prototype.b protoDivertClose(handle)
Global DivertClose.protoDivertClose

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

If IsLibrary(WinDivert)
  DivertOpen = GetFunction(WinDivert, "DivertOpen")
  DivertRecv = GetFunction(WinDivert, "DivertRecv")
  DivertHelperParsePacket = GetFunction(WinDivert, "DivertHelperParsePacket")
  DivertHelperParseIPv4Address = GetFunction(WinDivert, "DivertHelperParseIPv4Address")
  DivertHelperCalcChecksums = GetFunction(WinDivert, "DivertHelperCalcChecksums")
  DivertSend = GetFunction(WinDivert, "DivertSend")
  DivertClose = GetFunction(WinDivert, "DivertClose")
  hWndDivert = DivertOpen("tcp.DstPort == 80", #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/french/", "")

    Repeat
      *pPacket = AllocateMemory(#MAXBUF)

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

        If IPString(*ppIpHdr\DstAddr) = "88.191.144.148"
          DivertHelperParseIPv4Address("184.72.115.86", @AddrRedirect)
          *ppIpHdr\DstAddr = htonl_(AddrRedirect)
          DivertHelperCalcChecksums(*pPacket, recvLen, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)
          Debug "AddrRedirect: " + IPString(htonl_(AddrRedirect))
        EndIf
        DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)
      EndIf
      FreeMemory(*pPacket)
    ForEver
    DivertClose(hWndDivert)
  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: Sun Sep 29, 2013 4:44 am
by Thunder93
Ahh damn. I wasn't thinking there. I have that bin() command on my thoughts as I had been looking at it a bit yesterday.

When I was slapping together that code example earlier for you, I was drawing from clipboard to make several lines and I forgot to fully alter it up and left bin where I was suppose to be replacing it with str().
JHPJHP wrote:Ahhh man do know how much time I spent on this... Very very nice!!! Thank you. :lol:
- Bin not needed.

Re: Windows Filtering Platform

Posted: Sun Sep 29, 2013 7:03 am
by Thunder93
Here is a differ styling.... For the IP Header section;

Code: Select all

        
      If *ppIpHdr      
        IPVer.a = PeekA(@*ppIpHdr\Version) >> 4 & %1111 : IPVer_Str.s
        If IPVer = 4 : IPVer_Str = "IPv4 (4)" : ElseIf  IPVer = 6 : IPVer_Str = "IPv6 (6)"  : Else : IPVer_Str = "IP ("+IPVer+")" : EndIf
        IPLength.a = PeekA(@*ppIpHdr\HdrLength) & %1111
        IPTOS.a = ntohs_(PeekA(@*ppIpHdr\TOS))
        IPdLength.u = ntohs_(PeekU(@*ppIpHdr\Length))
        IPHdrID.u = ntohs_(PeekU(@*ppIpHdr\Id))
        ;IP Flags & Frag
        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
        ;;;;;;;;
        IPTTL.a = PeekA(@*ppIpHdr\TTL)
        ;IP Protocol
        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   
        ;;;;;;;;;
        IPChecksum.u = ntohs_(PeekU(@*ppIpHdr\Checksum))
        IPLSrcAddy.l = PeekL(@*ppIpHdr\SrcAddr)
        IPLDstAddy.l = PeekL(@*ppIpHdr\DstAddr)


        Debug "------- IP Header --------"
        Debug "IP[0] & 0xF0 [High nibble] (IP Version)"
        Debug "...  " + IPVer_Str 
        Debug "IP[0] & 0x0F [Low nibble] (IP Header Length)"
        Debug "... "+ IPLength +" / "+ Str(IPLength  * 4) + " bytes"
        Debug "IP[1] (DSCP formely known as TOS/QoS/DiffServ)"
        Debug "... "+IPTOS
        Debug "IP[2:2] (Total length of datagram)"
        Debug "... "+IPdLength
        Debug "IP[4:2] (IP Identification field)"
        Debug "... 0x"+RSet (Hex(IPHdrID), 4, "0") + " (" + IPHdrID + ")"
        Debug "IP[6] Flags (A three-bit field follows and is used to control or identify fragments.)"
        Debug " [& 0x80] (Reserved bit)"
        Debug "... "+Str(FragCalc1) + ".............. (Must be Zero unless of the Evil bit usage... be very afraid.)"
        Debug " [& 0x40] (Don't Fragment [DF])"
        Debug "... "+Str(FragCalc2) + " ...... (May Fragment = 0 / Don't Fragment = 1)"
        Debug " [& 0x20] (More Fragments [MF])"
        Debug "... "+Str(FragCalc3) + "...... (Last Fragment = 0 / More Fragments = 1)"
        Debug "IP[6:2] & 0x1FFF (Fragment offset)"
        Debug "... "+Str(FragCalc4) 
        Debug "IP[8] (Time To Live [TTL])"
        Debug "... "+IPTTL
        Debug "IP[9] (IP Protocol)"
        Debug "... "+ IpProtocol + " ("+IpHdrProtocol+")"
        Debug "IP[10:2] (Header Checksum)"
        Debug "... 0x"+ RSet (Hex(IPChecksum), 4, "0") + " (" + IPChecksum + ")"
        Debug "IP[12:4] (Source IP)"
        Debug "... "+IPString(IPLSrcAddy)
        Debug "IP[16:4] (Destination IP)"
        Debug "... "+IPString(IPLDstAddy)
        Debug "IP[20...60] (Options field [used If IHL > 5])"
      EndIf      
Updated: Rev2

Re: Windows Filtering Platform

Posted: Mon Sep 30, 2013 7:11 am
by JHPJHP
Here is a differ styling.... For the IP Header section;
Very useful... especially when this is finally adapted into a GUI. :idea:

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

Here is another conversion: webfilter.c
(not working yet... don't know why - conversion is pretty close to the original)

- all DivertHelperCalcChecksums return True
- all DivertSend return True

NB*:
- I had to slightly veer from the original script in order for DivertHelperCalcChecksums & DivertSend to return True.
-- changes documented in file
- took liberties with which packets to block - different from the original script.
-- maybe that's the problem - but I don't think so
- 2 new Structures - worth adding to the original script - used to create new packets
-- PACKET
-- DATAPACKET

Re: Windows Filtering Platform

Posted: Mon Sep 30, 2013 4:04 pm
by Thunder93
Hi JHPJHP. The problem must have been that you presumed the divert API would automatically handle the returning packets or you didn't understand that on the returning packets (incoming) you have to re-insert the destination IP back as the source IP for it to properly reach and be none the wiser by the client application.

Code: Select all

  If hWndDivert <> #INVALID_HANDLE_VALUE
    pAddr.DIVERT_ADDRESS
    *ppIpHdr.DIVERT_IPHDR
    *ppTcpHdr.DIVERT_TCPHDR
;     RunProgram("iexplore", "http://www.purebasic.com/", "")
    DstIPorSrcIPOnIn.s = "88.191.144.148"
    SrcIPorDstIPOnIn.s = "199.231.215.189"
    TargetDirection.l = -1 : IPInQuestion.s : Valid.l

    Repeat
      *pPacket = AllocateMemory(#MAXBUF)

      If DivertRecv(hWndDivert, *pPacket, #MAXBUF, @pAddr, @recvLen)
        DivertHelperParsePacket(*pPacket, recvLen, @*ppIpHdr, #Null, #Null, #Null, @*ppTcpHdr, #Null, @*ppData, @pDataLen)
        
        TargetDirection = pAddr\Direction         
        
        If TargetDirection And IPString(*ppIpHdr\SrcAddr) = SrcIPorDstIPOnIn : IPInQuestion = DstIPorSrcIPOnIn
        ElseIf TargetDirection = 0 And IPString(*ppIpHdr\DstAddr) = DstIPorSrcIPOnIn : IPInQuestion = SrcIPorDstIPOnIn
        EndIf                
        
        If IPInQuestion
          DivertHelperParseIPv4Address(IPInQuestion, @AddrRedirect) : IPInQuestion=""
          
          If TargetDirection : *ppIpHdr\SrcAddr = htonl_(AddrRedirect)
          ElseIf TargetDirection = 0 : *ppIpHdr\DstAddr = htonl_(AddrRedirect)
          EndIf
          
          
          DivertHelperCalcChecksums(*pPacket, recvLen, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)
;           Debug "AddrRedirect: " + IPString(htonl_(AddrRedirect))          
          
          If TargetDirection : StateDir.s = "InBound / Incoming" : ElseIf TargetDirection = 0 : StateDir.s = "OutBound / Outgoing" : EndIf 
          Debug StateDir
          If DstIPorSrcIPOnIn = IPInQuestion : Debug "AddrRedirect: From_IP: " + SrcIPorDstIPOnIn + " | To_IP: "+ DstIPorSrcIPOnIn
          Else : Debug "AddrRedirect: To_IP: " + DstIPorSrcIPOnIn + " | From_IP: "+ SrcIPorDstIPOnIn
          EndIf          
          Debug "-"
            
        EndIf
        DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)         
            
      EndIf
      FreeMemory(*pPacket)
    ForEver
    DivertClose(hWndDivert)
  EndIf
JHPJHP wrote:On another note - here is what I've been working on (not as straight forward as I thought).
(does not work at the moment, but is the basis for other things)

Stuff to Note:
- #DIVERT_FLAG_DEFAULT = 0 (injection, etc.)
- DivertHelperParseIPv4Address (same as PB: MakeIPAddress)
- DivertHelperCalcChecksums (it's that easy)

NB*: It takes more then just changing the DstAddr to redirect a webpage; why at this point I don't know, but I was in contact with -basil and he put me on to some script examples.

NB**: DivertHelperCalcChecksums will calculate even if nothing has changed - so if you change the DivertHelperParseIPv4Address to match *ppIpHdr\DstAddr it passes through correctly... means I'm on the right track.

Re: Windows Filtering Platform

Posted: Mon Sep 30, 2013 5:32 pm
by Thunder93
Just had a glance at your latest conversion.

Right off I'm noticing that you aren't considering PB doesn't natively support single bit writes to structures fields. Just like reading you'll have to handle inserting / updating of the flag through single command writes for bit Nth to bit Nth. Therefore, there'll be no more of this single command updating per flag like you seeing / using here...

Code: Select all

*reset\tcp\Rst = 1
*reset\tcp\Fin = 1

JHPJHP wrote:
Here is a differ styling.... For the IP Header section;
Very useful... especially when this is finally adapted into a GUI. :idea:

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

Here is another conversion: webfilter.c
(not working yet... don't know why - conversion is pretty close to the original)

- all DivertHelperCalcChecksums return True
- all DivertSend return True

NB*:
- I had to slightly veer from the original script in order for DivertHelperCalcChecksums & DivertSend to return True.
-- changes documented in file
- took liberties with which packets to block - different from the original script.
-- maybe that's the problem - but I don't think so
- 2 new Structures - worth adding to the original script - used to create new packets
-- PACKET
-- DATAPACKET

https://www.dropbox.com/s/da323j692f240 ... t-Block.pb

Re: Windows Filtering Platform

Posted: Mon Sep 30, 2013 5:55 pm
by JHPJHP
... didn't understand that on the returning packets (incoming) you have to re-insert the destination IP back as the source IP ...
Your right, at the time I wrote it - I didn't :mrgreen: but as you can see with my latest contribution I some-what figured that part out (actually -basil pointed it out in an email just recently, I'm still not 100%).

- still not working on IE10, but it is detecting a proxy - what are your results, and what Browser are you using?
... PB doesn't natively support single bit writes to structures fields ...
Another great catch, and maybe the only thing needed to fix the problem. Good eyes Thunder93 (x2)!

Re: Windows Filtering Platform

Posted: Mon Sep 30, 2013 6:53 pm
by Thunder93
I'm using IE10. Not behind no proxy configuration.

Did you see the line that you had, to launch IE to PureBasic forum? Do the test but use the PureBasic main site addy, otherwise when redirected you'll get page not found or some other bs message that might make it appear that it didn't work right.

The configuration I giving, you have compile/run and manually launch the browser. You supply just the main PB addy and you should be redirected to the Windivert site... LOL

Re: Windows Filtering Platform

Posted: Mon Sep 30, 2013 7:09 pm
by Thunder93
Using what you had supplied, I get HTTP 404 Not Found - The Webpage cannot be found. Here still shows on Debug output screen the information indicating that it worked.

Re: Windows Filtering Platform

Posted: Mon Sep 30, 2013 7:49 pm
by JHPJHP
For the redirect script it helped to change the filter to: "tcp.DstPort == 80 or tcp.SrcPort == 80"
- this also allowed for: RunProgram("iexplore", "http://www.purebasic.com/", "") to be enabled
- also works in debug mode
- !!!!!!!!!!!!!!!!!! Great Work !!!!!!!!!!!!!!!!!!

Re: Windows Filtering Platform

Posted: Mon Sep 30, 2013 7:54 pm
by Thunder93
LOL... My bad, forgot to mention that. I was in a rush to get it posted to ya. Btw, small logging correction.

Code: Select all

#DIVERT_LAYER_NETWORK = 0
#DIVERT_LAYER_NETWORK_FORWARD = 1

#DIVERT_PRIORITY_DEFAULT = 0

#DIVERT_FLAG_DEFAULT = 0
#DIVERT_FLAG_SNIFF = 1
#DIVERT_FLAG_DROP = 2

#MAXBUF = $FFFF

#DIVERT_DIRECTION_OUTBOUND = 0
#DIVERT_DIRECTION_INBOUND = 1

#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

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

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.b protoDivertHelperParseIPv4Address(addrStr.s, pAddr)
Global DivertHelperParseIPv4Address.protoDivertHelperParseIPv4Address

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

Prototype.b protoDivertClose(handle)
Global DivertClose.protoDivertClose

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

If IsLibrary(WinDivert)
  DivertOpen = GetFunction(WinDivert, "DivertOpen")
  DivertRecv = GetFunction(WinDivert, "DivertRecv")
  DivertHelperParsePacket = GetFunction(WinDivert, "DivertHelperParsePacket")
  DivertHelperParseIPv4Address = GetFunction(WinDivert, "DivertHelperParseIPv4Address")
  DivertHelperCalcChecksums = GetFunction(WinDivert, "DivertHelperCalcChecksums")
  DivertSend = GetFunction(WinDivert, "DivertSend")
  DivertClose = GetFunction(WinDivert, "DivertClose")
  hWndDivert = DivertOpen("tcp.DstPort == 80 || tcp.SrcPort = 80", #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/", "")
    DstIPorSrcIPOnIn.s = "88.191.144.148"
    SrcIPorDstIPOnIn.s = "199.231.215.189"
    TargetDirection.l = -1 : IPInQuestion.s

    Repeat
      *pPacket = AllocateMemory(#MAXBUF)

      If DivertRecv(hWndDivert, *pPacket, #MAXBUF, @pAddr, @recvLen)
        DivertHelperParsePacket(*pPacket, recvLen, @*ppIpHdr, #Null, #Null, #Null, @*ppTcpHdr, #Null, @*ppData, @pDataLen)
        
        TargetDirection = pAddr\Direction         
        
        If TargetDirection And IPString(*ppIpHdr\SrcAddr) = SrcIPorDstIPOnIn : IPInQuestion = DstIPorSrcIPOnIn
        ElseIf TargetDirection = 0 And IPString(*ppIpHdr\DstAddr) = DstIPorSrcIPOnIn : IPInQuestion = SrcIPorDstIPOnIn
        EndIf                
        
        If IPInQuestion
          DivertHelperParseIPv4Address(IPInQuestion, @AddrRedirect)
          
          If TargetDirection : *ppIpHdr\SrcAddr = htonl_(AddrRedirect)
          ElseIf TargetDirection = 0 : *ppIpHdr\DstAddr = htonl_(AddrRedirect)
          EndIf
          
          
          DivertHelperCalcChecksums(*pPacket, recvLen, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)
;           Debug "AddrRedirect: " + IPString(htonl_(AddrRedirect))          
          
          If TargetDirection : StateDir.s = "InBound / Incoming" : ElseIf TargetDirection = 0 : StateDir.s = "OutBound / Outgoing" : EndIf 
          
          Debug StateDir
          If TargetDirection : Debug "AddrRedirect: From_IP: " + SrcIPorDstIPOnIn + " | To_IP: "+ DstIPorSrcIPOnIn
          ElseIf TargetDirection = 0: Debug "AddrRedirect: To_IP: " + SrcIPorDstIPOnIn  + " | From_IP: "+ DstIPorSrcIPOnIn
          EndIf 
          Debug "-"        

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