Code: Select all
#DIVERT_LAYER_NETWORK = 0
#DIVERT_PRIORITY_DEFAULT = 0
#DIVERT_FLAG_DEFAULT = 0
#MAXBUF = $FFFF
#DIVERT_DIRECTION_INBOUND = 1
#DIVERT_HELPER_NO_ICMP_CHECKSUM = 2
#DIVERT_HELPER_NO_ICMPV6_CHECKSUM = 4
#DIVERT_HELPER_NO_UDP_CHECKSUM = 16
Structure DIVERT_ADDRESS
IfIdx.l
SubIfIdx.l
Direction.a
EndStructure
Structure DIVERT_IPHDR
StructureUnion
HdrLength.a
Version.a
EndStructureUnion
TOS.a
Length.u
Id.u
FragOff0.u
TTL.a
Protocol.a
Checksum.u
SrcAddr.l
DstAddr.l
EndStructure
Structure DIVERT_TCPHDR
SrcPort.u
DstPort.u
SeqNum.l
AckNum.l
StructureUnion
Reserved1.a
HdrLength.a
EndStructureUnion
StructureUnion
Fin.a
Syn.a
Rst.a
Psh.a
Ack.a
Urg.a
Reserved2.a
EndStructureUnion
Window.u
Checksum.u
UrgPtr.u
EndStructure
Structure PACKET
ip.DIVERT_IPHDR
tcp.DIVERT_TCPHDR
EndStructure
Structure DATAPACKET
header.PACKET
Data.a[0]
EndStructure
Prototype protoDivertOpen(filter.s, layer, priority.u, flags.q)
Global DivertOpen.protoDivertOpen
Prototype.b protoDivertRecv(handle, *pPacket, packetLen, pAddr, recvLen)
Global DivertRecv.protoDivertRecv
Prototype.b protoDivertSend(handle, *pPacket, packetLen, pAddr, sendLen)
Global DivertSend.protoDivertSend
Prototype.b protoDivertHelperParsePacket(*pPacket, packetLen, *ppIpHdr, *ppIpv6Hdr, *ppIcmpHdr, *ppIcmpv6Hdr, *ppTcpHdr, *ppUdpHdr, *ppData, pDataLen)
Global DivertHelperParsePacket.protoDivertHelperParsePacket
Prototype protoDivertHelperCalcChecksums(*pPacket, packetLen, flags.q)
Global DivertHelperCalcChecksums.protoDivertHelperCalcChecksums
Prototype.b protoDivertClose(handle)
Global DivertClose.protoDivertClose
Procedure.s TestForError()
Result.s = ""
dwMessageId = GetLastError_()
*lpBuffer = AllocateMemory(255)
FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, #Null, dwMessageId, #Null, *lpBuffer, MemorySize(*lpBuffer), #Null)
dwDescription.s = PeekS(*lpBuffer)
Result = "Error: " + Str(dwMessageId) + " - " + Left(dwDescription, Len(dwDescription) - 1)
FreeMemory(*lpBuffer)
ProcedureReturn Result
EndProcedure
Procedure PacketInit(*xPACKET.PACKET)
FillMemory(*xPACKET, SizeOf( *xPACKET ))
PokeA(@*xPACKET\ip\HdrLength, Val("%" + RSet(Bin(4), 4, "0") + RSet(Bin(SizeOf(DIVERT_IPHDR) / 4), 4, "0")))
PokeA(@*xPACKET\tcp\HdrLength, Val("%" + RSet(Bin(SizeOf(DIVERT_TCPHDR) / 4), 4, "0") + RSet(Bin(0), 4, "0")))
*xPACKET\ip\Length = htons_(SizeOf(PACKET) )
*xPACKET\ip\TTL = 64
*xPACKET\ip\Protocol = #IPPROTO_TCP
;;;; Original
; memset(packet, 0, SizeOf(PACKET));
; packet->ip.Version = 4;
; packet->ip.HdrLength = SizeOf(DIVERT_IPHDR) / 4 ; / SizeOf(UINT32);
; packet->ip.Length = htons(SizeOf(PACKET));
; packet->ip.TTL = 64;
; packet->ip.Protocol = IPPROTO_TCP;
; packet->tcp.HdrLength = SizeOf(DIVERT_TCPHDR) / SizeOf(UINT32);
EndProcedure
WinDivert = OpenLibrary(#PB_Any, "WinDivert.dll")
If IsLibrary(WinDivert)
DivertOpen = GetFunction(WinDivert, "DivertOpen")
DivertRecv = GetFunction(WinDivert, "DivertRecv")
DivertHelperParsePacket = GetFunction(WinDivert, "DivertHelperParsePacket")
DivertHelperCalcChecksums = GetFunction(WinDivert, "DivertHelperCalcChecksums")
DivertSend = GetFunction(WinDivert, "DivertSend")
DivertClose = GetFunction(WinDivert, "DivertClose")
HdrLength.a = Val("%" + RSet(Bin(4), 4, "0") + RSet(Bin(SizeOf(DIVERT_IPHDR) / 4), 4, "0"))
Reserved1.a = Val("%" + RSet(Bin(SizeOf(DIVERT_TCPHDR) / 4), 4, "0") + RSet(Bin(0), 4, "0"))
*reset.PACKET = AllocateMemory(SizeOf(PACKET))
FillMemory(*reset, SizeOf(PACKET), 0)
; PokeA(@*reset\ip\HdrLength, HdrLength)
PacketInit(*reset)
*reset\ip\Length = htons_(SizeOf(PACKET))
*reset\ip\TTL = 64
*reset\ip\Protocol = #IPPROTO_TCP
; PokeA(@*reset\tcp\Reserved1, Reserved1)
PokeA(@*reset\tcp\Fin, %00010100)
blockdata.s = "HTTP/1.1 200 OK" + #CRLF$ +
"Connection: close" + #CRLF$ +
"Content-Type: text/html" + #CRLF$ +
#CRLF$ +
"<!doctype html>" + #LF$ +
"<html>" + #LF$ +
"<head>" + #LF$ +
"<title>BLOCKED!</title>" + #LF$ +
"</head>" + #LF$ +
"<body>" + #LF$ +
"<h1>BLOCKED!</h1>" + #LF$ +
"<hr>" + #LF$ +
"<p>This URL has been blocked!</p>" + #LF$ +
"</body>" + #LF$ +
"</html>"
blocklength = SizeOf(DATAPACKET) + StringByteLength(blockdata)
*blockpage.DATAPACKET = AllocateMemory(blocklength)
FillMemory(*blockpage, blocklength, 0)
; PokeA(@*blockpage\header\ip\HdrLength, HdrLength)
PacketInit(*blockpage\header);
*blockpage\header\ip\Length = htons_(blocklength)
*blockpage\header\ip\TTL = 64
*blockpage\header\ip\Protocol = #IPPROTO_TCP
*blockpage\header\tcp\SrcPort = htons_(80)
; PokeA(@*blockpage\header\tcp\Reserved1, Reserved1)
PokeA(@*blockpage\header\tcp\Fin, %00011000)
PokeS(@*blockpage\Data[0], blockdata, StringByteLength(blockdata), #PB_UTF8)
*finish.PACKET = AllocateMemory(SizeOf(PACKET))
FillMemory(*finish, SizeOf(PACKET), 0)
; PokeA(@*finish\ip\HdrLength, HdrLength)
PacketInit(*finish)
*finish\ip\Length = htons_(SizeOf(PACKET))
*finish\ip\TTL = 64
*finish\ip\Protocol = #IPPROTO_TCP
; PokeA(@*finish\tcp\Reserved1, Reserved1)
PokeA(@*finish\tcp\Fin, %00010001)
filter.s = "outbound && ip && tcp.DstPort == 80 && tcp.PayloadLength > 0"
hWndDivert = DivertOpen(filter, #DIVERT_LAYER_NETWORK, #DIVERT_PRIORITY_DEFAULT, #DIVERT_FLAG_DEFAULT)
If hWndDivert <> #INVALID_HANDLE_VALUE
pAddr.DIVERT_ADDRESS
*ppIpHdr.DIVERT_IPHDR
*ppTcpHdr.DIVERT_TCPHDR
RunProgram("iexplore", "http://www.purebasic.com/", "")
Repeat
*pPacket = AllocateMemory(#MAXBUF)
If DivertRecv(hWndDivert, *pPacket, #MAXBUF, @pAddr, @recvLen)
DivertHelperParsePacket(*pPacket, recvLen, @*ppIpHdr, #Null, #Null, #Null, @*ppTcpHdr, #Null, @*ppData, @pDataLen)
If *ppData
If FindString(PeekS(*ppData, pDataLen), "purebasic")
*reset\ip\SrcAddr = *ppIpHdr\SrcAddr
*reset\ip\DstAddr = *ppIpHdr\DstAddr
*reset\tcp\SrcPort = *ppTcpHdr\SrcPort
*reset\tcp\DstPort = htons_(80)
*reset\tcp\SeqNum = *ppTcpHdr\SeqNum
*reset\tcp\AckNum = *ppTcpHdr\AckNum
DivertHelperCalcChecksums(*reset, SizeOf(PACKET), #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)
If Not DivertSend(hWndDivert, *reset, SizeOf(PACKET), @pAddr, #Null)
Debug TestForError()
Continue
EndIf
*blockpage\header\ip\SrcAddr = *ppIpHdr\DstAddr
*blockpage\header\ip\DstAddr = *ppIpHdr\SrcAddr
*blockpage\header\tcp\DstPort = *ppTcpHdr\SrcPort
*blockpage\header\tcp\SeqNum = *ppTcpHdr\AckNum
*blockpage\header\tcp\AckNum = htonl_(ntohl_(PeekL(@*ppTcpHdr\SeqNum)) + pDataLen)
pAddr\Direction = #DIVERT_DIRECTION_INBOUND
DivertHelperCalcChecksums(*blockpage, blocklength, #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)
If Not DivertSend(hWndDivert, *blockpage, blocklength, @pAddr, #Null)
Debug TestForError()
Continue
EndIf
*finish\ip\SrcAddr = *ppIpHdr\DstAddr
*finish\ip\DstAddr = *ppIpHdr\SrcAddr
*finish\tcp\SrcPort = htons_(80)
*finish\tcp\DstPort = *ppTcpHdr\SrcPort
*finish\tcp\SeqNum = htonl_(ntohl_(PeekL(@*ppTcpHdr\AckNum)) + StringByteLength(blockdata))
*finish\tcp\AckNum = htonl_(ntohl_(PeekL(@*ppTcpHdr\SeqNum)) + pDataLen)
DivertHelperCalcChecksums(*finish, SizeOf(PACKET), #DIVERT_HELPER_NO_ICMP_CHECKSUM | #DIVERT_HELPER_NO_ICMPV6_CHECKSUM | #DIVERT_HELPER_NO_UDP_CHECKSUM)
If Not DivertSend(hWndDivert, *finish, SizeOf(PACKET), @pAddr, #Null) : Debug TestForError() : EndIf
Else
DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)
EndIf
Else
DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)
EndIf
Else
DivertSend(hWndDivert, *pPacket, recvLen, @pAddr, #Null)
EndIf
FreeMemory(*pPacket)
ForEver
DivertClose(hWndDivert)
FreeMemory(*finish)
FreeMemory(*reset)
EndIf
CloseLibrary(WinDivert)
RunProgram("sc", "stop WinDivert1.0", "", #PB_Program_Hide)
RunProgram("sc", "delete WinDivert1.0", "", #PB_Program_Hide)
EndIf