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 »

Broke it down to the magic bit of code - so I was missing an Else (and a clear understanding of reversing the address) :mrgreen: - you sure know your packet stuff:
- did you notice that the Address Bar still holds the original Web Address (can be dangerous), enough said.
- what tool(s) are you using to test with? I'm using Wireshark.
- just waiting for you to fix the "blocking" script. :)

Code: Select all

If pAddr\Direction
  DivertHelperParseIPv4Address("88.191.144.148", @AddrRedirect)
  *ppIpHdr\SrcAddr = htonl_(AddrRedirect)
Else
  DivertHelperParseIPv4Address("199.231.215.189", @AddrRedirect)
  *ppIpHdr\DstAddr = htonl_(AddrRedirect)
EndIf

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

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")
  filter.s = "tcp.DstPort == 80 or tcp.SrcPort == 80"
  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 pAddr\Direction
          DivertHelperParseIPv4Address("88.191.144.148", @AddrRedirect)
          *ppIpHdr\SrcAddr = htonl_(AddrRedirect)
        Else
          DivertHelperParseIPv4Address("199.231.215.189", @AddrRedirect)
          *ppIpHdr\DstAddr = htonl_(AddrRedirect)
        EndIf
        DivertHelperCalcChecksums(*pPacket, recvLen, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)
        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
Last edited by JHPJHP on Tue Oct 01, 2013 7:26 pm, edited 2 times 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
JHPJHP
Addict
Addict
Posts: 2257
Joined: Sat Oct 09, 2010 3:47 am

Re: Windows Filtering Platform

Post by JHPJHP »

Cleaned out my Dropbox, so I'm posting the (non-working) code:
(updated to fix the Bit to Structure problem you noticed)

Bit to Structure may still be the problem:
(coincidentally the same fields I was concerned with)

Code: Select all

StructureUnion
  HdrLength.a
  Version.a
EndStructureUnion

StructureUnion
  Reserved1.a
  HdrLength.a
EndStructureUnion

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
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")
  block_data.s = "HTTP/1.1 200 OK\r\n" +
               "Connection: close\r\n" +
               "Content-Type: text/html\r\n" +
               "\r\n" +
               "<!doctype html>\n" +
               "<html>\n" +
               "\t<head>\n" +
               "\t\t<title>BLOCKED!</title>\n" +
               "\t</head>\n" +
               "\t<body>\n" +
               "\t\t<h1>BLOCKED!</h1>\n" +
               "\t\t<hr>\n" +
               "\t\t<p>This URL has been blocked!</p>\n" +
               "\t</body>\n" +
               "</html>\n"
  blockpage_len = SizeOf(DATAPACKET) + Len(block_data) - 1
  *blockpage.DATAPACKET = AllocateMemory(blockpage_len)
  FillMemory(*blockpage, SizeOf(DATAPACKET), 0)
  *blockpage\header\ip\Version = 4
  *blockpage\header\ip\TTL = 64
  *blockpage\header\ip\Protocol = #IPPROTO_TCP
  *blockpage\header\tcp\SrcPort = htons_(80)
  PokeA(@*blockpage\header\tcp\Psh, %00011000)
  PokeA(@*blockpage\header\tcp\Ack, %00011000)
  *blockpage\Data = AllocateMemory(blockpage_len)
  CopyMemory(@block_data, *blockpage\Data, Len(block_data) - 1)
  *reset.PACKET = AllocateMemory(SizeOf(PACKET))
  FillMemory(*reset, SizeOf(PACKET), 0)
  *reset\ip\Version = 4
  *reset\ip\TTL = 64
  *reset\ip\Protocol = #IPPROTO_TCP
  PokeA(@*reset\tcp\Rst, %00101000)
  PokeA(@*reset\tcp\Ack, %00101000)
  *finish.PACKET = AllocateMemory(SizeOf(PACKET))
  FillMemory(*finish, SizeOf(PACKET), 0)
  *finish\ip\Version = 4
  *finish\ip\TTL = 64
  *finish\ip\Protocol = #IPPROTO_TCP
  PokeA(@*finish\tcp\Fin, %10001000)
  PokeA(@*finish\tcp\Ack, %10001000)
  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
            *reset\ip\SrcAddr = *ppIpHdr\SrcAddr
            *reset\ip\DstAddr = *ppIpHdr\DstAddr
            *reset\tcp\HdrLength = *ppTcpHdr\HdrLength
            *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 TestForError()
              Continue
            EndIf
            *blockpage\header\ip\HdrLength = *ppIpHdr\HdrLength
            *blockpage\header\ip\Length = *ppIpHdr\Length
            *blockpage\header\ip\SrcAddr = *ppIpHdr\DstAddr
            *blockpage\header\ip\DstAddr = *ppIpHdr\SrcAddr
            *blockpage\header\tcp\HdrLength = *ppTcpHdr\HdrLength
            *blockpage\header\tcp\DstPort = *ppTcpHdr\SrcPort
            *blockpage\header\tcp\SeqNum = *ppTcpHdr\AckNum
            *blockpage\header\tcp\AckNum = htonl_(ntohl_(*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 TestForError()
              Continue
            EndIf
            *finish\ip\HdrLength = *ppIpHdr\HdrLength
            *finish\ip\Length = *ppIpHdr\Length
            *finish\ip\SrcAddr = *ppIpHdr\DstAddr
            *finish\ip\DstAddr = *ppIpHdr\SrcAddr
            *finish\tcp\HdrLength = *ppTcpHdr\HdrLength
            *finish\tcp\SrcPort = htons_(80)
            *finish\tcp\DstPort = *ppTcpHdr\SrcPort
            *finish\tcp\SeqNum = htonl_(ntohl_(*ppTcpHdr\AckNum) + Len(block_data) - 1)
            *finish\tcp\AckNum = htonl_(ntohl_(*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 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
Last edited by JHPJHP on Tue Oct 01, 2013 2:25 am, 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 »

Apologies for the delay, I was pretty busy .. still am actually. :x

You are making a mistake with adding x2 the same very flag info....

It works for the most part... Except the data sent back to the browser is gibberish.

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
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")
  block_data.s = "HTTP/1.1 200 OK\r\n" +
               "Connection: close\r\n" +
               "Content-Type: text/html\r\n" +
               "\r\n" +
               "<!doctype html>\n" +
               "<html>\n" +
               "\t<head>\n" +
               "\t\t<title>BLOCKED!</title>\n" +
               "\t</head>\n" +
               "\t<body>\n" +
               "\t\t<h1>BLOCKED!</h1>\n" +
               "\t\t<hr>\n" +
               "\t\t<p>This URL has been blocked!</p>\n" +
               "\t</body>\n" +
               "</html>\n"
  blockpage_len = SizeOf(DATAPACKET) + Len(block_data) - 1
  *blockpage.DATAPACKET = AllocateMemory(blockpage_len)
  FillMemory(*blockpage, SizeOf(DATAPACKET), 0)
  *blockpage\header\ip\Version = 4
  *blockpage\header\ip\TTL = 64
  *blockpage\header\ip\Protocol = #IPPROTO_TCP
  *blockpage\header\tcp\SrcPort = htons_(80)
;   *blockpage\header\tcp\Psh = %00011000
;   *blockpage\header\tcp\Ack = %00011000

  *blockpage\header\tcp\Reserved2 = %00011000

  *blockpage\Data = AllocateMemory(blockpage_len)
  CopyMemory(@block_data, *blockpage\Data, Len(block_data) - 1)
  
  *reset.PACKET = AllocateMemory(SizeOf(PACKET))
  FillMemory(*reset, SizeOf(PACKET), 0)
  *reset\ip\Version = 4
  *reset\ip\TTL = 64
  *reset\ip\Protocol = #IPPROTO_TCP
;   *reset\tcp\Rst = %00101000
;   *reset\tcp\Ack = %00101000

  *reset\tcp\Reserved2 = %00010100

  *finish.PACKET = AllocateMemory(SizeOf(PACKET))
  FillMemory(*finish, SizeOf(PACKET), 0)
  *finish\ip\Version = 4
  *finish\ip\TTL = 64
  *finish\ip\Protocol = #IPPROTO_TCP
;   *finish\tcp\Fin = %10001000
;   *finish\tcp\Ack = %10001000

*finish\tcp\Reserved2 = %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\HdrLength = *ppIpHdr\HdrLength
            *reset\ip\Length = *ppIpHdr\Length
            *reset\ip\SrcAddr = *ppIpHdr\SrcAddr
            *reset\ip\DstAddr = *ppIpHdr\DstAddr
            *reset\tcp\HdrLength = *ppTcpHdr\HdrLength
            *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 TestForError()
              Continue
            EndIf
            *blockpage\header\ip\HdrLength = *ppIpHdr\HdrLength
            *blockpage\header\ip\Length = *ppIpHdr\Length
            *blockpage\header\ip\SrcAddr = *ppIpHdr\DstAddr
            *blockpage\header\ip\DstAddr = *ppIpHdr\SrcAddr
            *blockpage\header\tcp\HdrLength = *ppTcpHdr\HdrLength
            *blockpage\header\tcp\DstPort = *ppTcpHdr\SrcPort
            *blockpage\header\tcp\SeqNum = *ppTcpHdr\AckNum
            *blockpage\header\tcp\AckNum = htonl_(ntohl_(*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 TestForError()
              Continue
            EndIf
            *finish\ip\HdrLength = *ppIpHdr\HdrLength
            *finish\ip\Length = *ppIpHdr\Length
            *finish\ip\SrcAddr = *ppIpHdr\DstAddr
            *finish\ip\DstAddr = *ppIpHdr\SrcAddr
            *finish\tcp\HdrLength = *ppTcpHdr\HdrLength
            *finish\tcp\SrcPort = htons_(80)
            *finish\tcp\DstPort = *ppTcpHdr\SrcPort
            *finish\tcp\SeqNum = htonl_(ntohl_(*ppTcpHdr\AckNum) + Len(block_data) - 1)
            *finish\tcp\AckNum = htonl_(ntohl_(*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 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
ʽʽ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 »

Yep. I know a little something about packets. :)
Using the same, Wireshark but also a bunch of mouse left-clicks. :lol:
JHPJHP wrote:Broke it down to the magic bit of code - so I was missing an Else (and a clear understanding of reversing the address) :mrgreen: - you sure know your packet stuff:
- did you notice that the Address Bar still holds the original Web Address (can be dangerous), enough said.
- what tool(s) are you using to test with? I'm using Wireshark.
- just waiting for you to fix the "blocking" script :) ... seriously! :D
ʽʽ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 »

Working...

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

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")
  *reset.PACKET = AllocateMemory(SizeOf(PACKET))
  FillMemory(*reset, SizeOf(PACKET), 0)
  *reset\ip\Version = 4
  *reset\ip\TTL = 64
  *reset\ip\Protocol = #IPPROTO_TCP
  PokeA(@*reset\tcp\Fin, %00010100)
  blockdata.s = "HTTP/1.1 200 OK" + Chr(10) + Chr(13) +
                "Connection: close" + Chr(10) + Chr(13) +
                "Content-Type: text/html" + Chr(10) + Chr(13) +
                "<!doctype html>" + Chr(10) + Chr(13) +
                "<html>" + Chr(10) + Chr(13) +
                "<head>" + Chr(10) + Chr(13) +
                "<title>BLOCKED!</title>" + Chr(10) + Chr(13) +
                "</head>" + Chr(10) + Chr(13) +
                "<body>" + Chr(10) + Chr(13) +
                "<h1>BLOCKED!</h1>" + Chr(10) + Chr(13) +
                "<hr>" + Chr(10) + Chr(13) +
                "<p>This URL has been blocked!</p>" + Chr(10) + Chr(13) +
                "</body>" + Chr(10) + Chr(13) +
                "</html>"
  blocklength = SizeOf(DATAPACKET) + Len(blockdata) - 1
  *blockpage.DATAPACKET = AllocateMemory(blocklength)
  FillMemory(*blockpage, blocklength, 0)
  *blockpage\header\ip\Version = 4
  *blockpage\header\ip\TTL = 64
  *blockpage\header\ip\Protocol = #IPPROTO_TCP
  *blockpage\header\tcp\SrcPort = htons_(80)
  PokeA(@*blockpage\header\tcp\Fin, %00011000)
  *blockpage\Data[0] = AllocateMemory(Len(blockdata) - 1)
  FillMemory(@*blockpage\Data[0], Len(blockdata) + 100)
  PokeS(@*blockpage\Data[0], blockdata, Len(blockdata), #PB_UTF8)
  *finish.PACKET = AllocateMemory(SizeOf(PACKET))
  FillMemory(*finish, SizeOf(PACKET), 0)
  *finish\ip\Version = 4
  *finish\ip\TTL = 64
  *finish\ip\Protocol = #IPPROTO_TCP
  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\HdrLength = *ppIpHdr\HdrLength
            *reset\ip\Length = *ppIpHdr\Length
            *reset\ip\SrcAddr = *ppIpHdr\SrcAddr
            *reset\ip\DstAddr = *ppIpHdr\DstAddr
            *reset\tcp\HdrLength = *ppTcpHdr\HdrLength
            *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 TestForError()
              Continue
            EndIf
            *blockpage\header\ip\HdrLength = *ppIpHdr\HdrLength
            *blockpage\header\ip\Length = *ppIpHdr\Length
            *blockpage\header\ip\SrcAddr = *ppIpHdr\DstAddr
            *blockpage\header\ip\DstAddr = *ppIpHdr\SrcAddr
            *blockpage\header\tcp\HdrLength = *ppTcpHdr\HdrLength
            *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 TestForError()
              Continue
            EndIf
            *finish\ip\HdrLength = *ppIpHdr\HdrLength
            *finish\ip\Length = *ppIpHdr\Length
            *finish\ip\SrcAddr = *ppIpHdr\DstAddr
            *finish\ip\DstAddr = *ppIpHdr\SrcAddr
            *finish\tcp\HdrLength = *ppTcpHdr\HdrLength
            *finish\tcp\SrcPort = htons_(80)
            *finish\tcp\DstPort = *ppTcpHdr\SrcPort
            *finish\tcp\SeqNum = htonl_(ntohl_(PeekL(@*ppTcpHdr\AckNum)) + Len(blockdata) - 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 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
Last edited by JHPJHP on Tue Oct 01, 2013 8:27 am, edited 6 times 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 »

The results are mixed... Without even changing anything. It can work, then trying again and waiting and waiting.
ʽʽ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 »

*** Update *** Working : Previous post updated *** Update ***

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

Made some minor changes... but I think what your seeing is because you have a locked IE process... close all IE windows and check Task Manager.

By setting [ - 1 ] to length, it doesn't matter if you close the browser - it keeps the process open.

If it's not that... I'm not seeing it then - I ran the script over a dozen times with no hiccup's.
Last edited by JHPJHP on Tue Oct 01, 2013 8:31 am, edited 3 times 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.
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 »

I worder, why don't compile with C,C++ then importC, it will saving many times :D
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

What's the fun in that? This is a training exercise. While it might be troublesome, frustrating at times. When finally accomplishing something is very rewarding. Besides .... I'm not one to betray PB by running to C++ every-time to make things easier. :twisted:
sec wrote:I worder, why don't compile with C,C++ then importC, it will saving many times :D
ʽʽ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 »

Good job JHPJHP! Working wonderfully for me.

There was only a minor problem I noticed. html script was being cut from the top some. Simply update your blockdata.s with the following;

"HTTP/1.1 200 OK" + Chr(10) + Chr(13) +
"Connection: close" + Chr(10) + Chr(13) +
"Content-Type: text/html" + Chr(10) + Chr(13) +
Chr(10) +
"<!doctype html>" + Chr(10) + Chr(13) +
"<html>" + Chr(10) + Chr(13) +
"<head>" + Chr(10) + Chr(13) +
"<title>BLOCKED!</title>" + Chr(10) + Chr(13) +
"</head>" + Chr(10) + Chr(13) +
"<body>" + Chr(10) + Chr(13) +
"<h1>BLOCKED!</h1>" + Chr(10) + Chr(13) +
"<hr>" + Chr(10) + Chr(13) +
"<p>This URL has been blocked!</p>" + Chr(10) + Chr(13) +
"</body>" + Chr(10) + Chr(13) +
"</html>"

Even something else that's sufficient is the following...

blockdata.s = "HTTP/1.1 200 OK" + Chr(10) +
"Connection: close" + Chr(10) +
"Content-Type: text/html" + Chr(10) +
Chr(10) +
"<!doctype html>" + Chr(10) +
"<html>" + Chr(10) +
"<head>" + Chr(10) +
"<title>BLOCKED!</title>" + Chr(10) +
"</head>" + Chr(10) +
"<body>" + Chr(10) +
"<h1>BLOCKED!</h1>" + Chr(10) +
"<hr>" + Chr(10) +
"<p>This URL has been blocked!</p>" + Chr(10) +
"</body>" + Chr(10) +
"</html>"

...see what I did there? :wink:

Or... which is more preferred by me;

Code: Select all

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

JHPJHP wrote:*** Update *** Working : Previous post updated *** Update ***

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

Made some minor changes... but I think what your seeing is because you have a locked IE process... close all IE windows and check Task Manager.

By setting [ - 1 ] to length, it doesn't matter if you close the browser - it keeps the process open.

If it's not that... I'm not seeing it then - I ran the script over a dozen times with no hiccup's.
Last edited by Thunder93 on Tue Oct 01, 2013 1:03 pm, 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
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 »

Thunder93 wrote:What's the fun in that? This is a training exercise. While it might be troublesome, frustrating at times. When finally accomplishing something is very rewarding. Besides .... I'm not one to betray PB by running to C++ every-time to make things easier. :twisted:
sec wrote:I worder, why don't compile with C,C++ then importC, it will saving many times :D
:mrgreen: the fun is in SIMPLE word :mrgreen:
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Windows Filtering Platform

Post by Thunder93 »

simple word is boring to me and JHPJHP.. :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 »

... which is more preferred by me
A much cleaner approach, and another one to check off the list. 8)
simple word is boring to me and JHPJHP
Exactly, and I've managed to increase my PureBasic Knowledge to boot; what better way then an exercise like this.

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
JHPJHP
Addict
Addict
Posts: 2257
Joined: Sat Oct 09, 2010 3:47 am

Re: Windows Filtering Platform

Post by JHPJHP »

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? :)

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"
  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")
            replacedata = ReplaceString(replacedata, "/images/logopb.gif", "/images/visa.gif")
            replacelength = SizeOf(DATAPACKET) + Len(replacedata) - 1
            *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)
            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

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 »

Yes. The PB box is hit in addition... :?
ʽʽ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
Post Reply