Page 2 of 14
Re: Windows Filtering Platform
Posted: Sat Sep 21, 2013 7:15 pm
by Thunder93
Nice!
Yes :4 :2 :1 do represents bit lengths. Odd why PB don't yet support bit values in Structures.

Re: Windows Filtering Platform
Posted: Sat Sep 21, 2013 8:46 pm
by Thunder93
Using PureBasic 5.20 LTS (x64) and even tested on x86. Lot of the returned values are null. And the limited few that returns are still gibberish. There shouldn't be anything fancy to get the right ports information?
I don't know what is going on here.
Re: Windows Filtering Platform
Posted: Sat Sep 21, 2013 8:57 pm
by JHPJHP
My returned values - is this similar to your results?
---------------
DivertOpen
---------------
hWndDivert: 320
filter: outbound && ip && tcp.DstPort == 80 && tcp.PayloadLength > 0
---------------
DivertRecv
---------------
pAddr\IfIdx: 11
pAddr\SubIfIdx: 0
pAddr\Direction: 0
---------------
DivertHelperParsePacket
---------------
ppIpHdr\HdrLength: 128
ppIpHdr\Version: 0
ppIpHdr\TOS: 208
ppIpHdr\Length: 4
ppIpHdr\Id: 0
ppIpHdr\FragOff0: 0
ppIpHdr\TTL: 0
ppIpHdr\Protocol: 0
ppIpHdr\Checksum: 0
ppIpHdr\SrcAddr: 0
ppIpHdr\DstAddr: 0
---------------
ppIcmpHdr\Type: 0
ppIcmpHdr\Code: 0
---------------
ppTcpHdr\SrcPort: 148
ppTcpHdr\DstPort: 1232
---------------
ppUdpHdr\SrcPort: 0
ppUdpHdr\DstPort: 0
---------------
*ppData
---------------
GET / HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-US
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
Accept-Encoding: gzip, deflate
Host: duckduckgo.com
DNT: 1
Connection: Keep-Alive
Re: Windows Filtering Platform
Posted: Sat Sep 21, 2013 9:02 pm
by Thunder93
Indeed.
Re: Windows Filtering Platform
Posted: Sat Sep 21, 2013 9:31 pm
by Thunder93
For the outgoing www-HTTP (80tcp) packets the destination port should be showing 80. The source which be using dynamic port range 49152-65535 or 1025-5000 for systems earlier than Vista.
DIVERT_ADDRESS gets correct information that is properly read.
DIVERT_IPHDR and DIVERT_TCPHDR (the two that we are using for our HTTP outgoing packets) doesn't seem to be returning much of anything.
IP Header - Version should be returning 4 or 6, 4 for Ipv4. Not be returning a 0.
The ICMP Info like type and code is understandably returning 0, we aren't working with ICMP and the same for UDP.
IP_Header containing the source and destination IP information, where is that? Only 0 being returned nothing that we can change over to aaa.bbb.ccc.ddd
The protocol info shouldn't be 0, it should be showing 6 for TCP, 17 for UDP for when we do use.
Other information that should be there ... or returned, but only with 0 here.
Re: Windows Filtering Platform
Posted: Sat Sep 21, 2013 10:00 pm
by Thunder93
First step would be to setup and use arrays in our structures. lol
Re: Windows Filtering Platform
Posted: Sat Sep 21, 2013 10:27 pm
by JHPJHP
Good information, thanks.
I see what you mean with the "0" values being returned, but I was just happy that the *ppData parameter returning successfully, which meant that DivertHelperParsePacket() is being called correctly, which in turn narrows our problem to the Structures... baby steps.
Here is how I decided on the Structure's data types:
https://github.com/ToniPB/PureBasic_Win ... aseTsd.pbi
I also updated the link to include the resources I've downloaded from the WinDivert website... you probably already have them.
I have to get back to the weekend

but I thought it was important to post the small changes after hearing back from -basil (WinDivert).
Later,
Re: Windows Filtering Platform
Posted: Sun Sep 22, 2013 12:59 am
by Thunder93
Thanks JHPJHP!
I'll take it all in and report back if I make any progress.

Re: Windows Filtering Platform
Posted: Sun Sep 22, 2013 11:25 pm
by JHPJHP
Using the new Structure configuration from your other post (great catch Josh & Danilo):
Code: Select all
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
*ppIpHdr.DIVERT_IPHDR
DivertHelperParsePacket(*pPacket, recvLen, @*ppIpHdr, #Null, @ppIcmpHdr, #Null, @ppTcpHdr, @ppUdpHdr, @ppData, @pDataLen)
Debug "---------------"
Debug "DivertHelperParsePacket"
Debug "---------------"
Debug "ppIpHdr\HdrLength: " + PeekA(@*ppIpHdr\HdrLength)
Debug "ppIpHdr\Version: " + PeekA(@*ppIpHdr\Version)
Debug "ppIpHdr\TOS: " + PeekA(@*ppIpHdr\TOS)
Debug "ppIpHdr\Length: " + PeekU(@*ppIpHdr\Length)
Debug "ppIpHdr\Id: " + PeekU(@*ppIpHdr\Id)
Debug "ppIpHdr\FragOff0: " + PeekU(@*ppIpHdr\FragOff0)
Debug "ppIpHdr\TTL: " + PeekA(@*ppIpHdr\TTL)
Debug "ppIpHdr\Protocol: " + PeekA(@*ppIpHdr\Protocol)
Debug "ppIpHdr\Checksum: " + PeekU(@*ppIpHdr\Checksum)
Debug "ppIpHdr\SrcAddr: " + PeekL(@*ppIpHdr\SrcAddr)
Debug "ppIpHdr\DstAddr: " + PeekL(@*ppIpHdr\DstAddr)
Re: Windows Filtering Platform
Posted: Sun Sep 22, 2013 11:34 pm
by Thunder93
LOL.
The source IP address is there.... but it is just been put in backwards LOL!
I mean.... instead of it 192.168.x.y it is y.x.168.192
Re: Windows Filtering Platform
Posted: Sun Sep 22, 2013 11:54 pm
by JHPJHP
I knew we would eventually get there.
Also (for Long),
I bet the other Structures need some support as well.
Re: Windows Filtering Platform
Posted: Mon Sep 23, 2013 12:08 am
by Thunder93
Looking good so far.

Re: Windows Filtering Platform
Posted: Mon Sep 23, 2013 1:53 am
by Thunder93
Code: Select all
ipHdr_Length = PeekA(@*ppIpHdr\HdrLength) & %1111
ipHdr_Version = (PeekA(@*ppIpHdr\Version) >> 4)
ipHdr_TOS = htons_(PeekA(@*ppIpHdr\TOS))
ipHdr_TotalLength = htons_(PeekU(@*ppIpHdr\Length))
ipHdr_Id = htons_(PeekU(@*ppIpHdr\Id))
ipHdr_FragsOff = PeekU(@*ppIpHdr\FragOff0)
ipHdr_TTL = PeekA(@*ppIpHdr\TTL)
ipHdr_Protocol = PeekA(@*ppIpHdr\Protocol)
ipHdr_Checksum = PeekU(@*ppIpHdr\Checksum)
ipHdr_SrcAddr.s = IPString(PeekL(@*ppIpHdr\SrcAddr)) ;Dropped htonl_(), Native PB command sufficient.
ipHdr_DstAddr.s = IPString(PeekL(@*ppIpHdr\DstAddr))
Here's a small update.
Re: Windows Filtering Platform
Posted: Mon Sep 23, 2013 2:47 am
by JHPJHP
That's a great update - now using IPString, and you beat me to the (post) punch.
I added StructureUnion to the other datatypes with bit references.
(split StructureUnion by bit length - DIVERT_TCPHDR)
Other stuff added and fixed (updated original link as well).
Code: Select all
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_IPV6HDR
StructureUnion
TrafficClass0.a
Version.a
FlowLabel0.a
TrafficClass1.a
EndStructureUnion
FlowLabel1.u
Length.u
NextHdr.u
HopLimit.u
SrcAddr.l[4]
DstAddr.l[4]
EndStructure
Structure DIVERT_ICMPHDR
Type.a
Code.a
Checksum.u
Body.l
EndStructure
Structure DIVERT_ICMPV6HDR
Type.a
Code.a
Checksum.u
Body.l
EndStructure
Structure DIVERT_TCPHDR
SrcPort.u
DstPort.u
SeqNum.l
AckNum.l
StructureUnion
Reserved1.u
HdrLength.u
EndStructureUnion
StructureUnion
Fin.u
Syn.u
Rst.u
Psh.u
Ack.u
Urg.u
EndStructureUnion
StructureUnion
Reserved2.u
EndStructureUnion
Window.u
Checksum.u
UrgPtr.u
EndStructure
Structure DIVERT_UDPHDR
SrcPort.u
DstPort.u
Length.u
Checksum.u
EndStructure
Prototype protoDivertOpen(filter.s, layer, priority.u, flags.q)
Global DivertOpen.protoDivertOpen
Prototype.b protoDivertSetParam(handle, param, value.q)
Global DivertSetParam.protoDivertSetParam
Prototype.b protoDivertRecv(handle, *pPacket, packetLen, pAddr, recvLen)
Global DivertRecv.protoDivertRecv
Prototype.b protoDivertHelperParsePacket(*pPacket, packetLen, *ppIpHdr, *ppIpv6Hdr, *ppIcmpHdr, *ppIcmpv6Hdr, *ppTcpHdr, *ppUdpHdr, *ppData, pDataLen)
Global DivertHelperParsePacket.protoDivertHelperParsePacket
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)
#DIVERT_LAYER_NETWORK = 0
#DIVERT_PRIORITY_DEFAULT = 0
#DIVERT_FLAG_SNIFF = 1
DivertOpen = GetFunction(WinDivert, "DivertOpen")
filter.s = "outbound && ip && tcp.DstPort == 80 && tcp.PayloadLength > 0"
hWndDivert = DivertOpen(filter, #DIVERT_LAYER_NETWORK, #DIVERT_PRIORITY_DEFAULT, #DIVERT_FLAG_SNIFF)
If hWndDivert <> #INVALID_HANDLE_VALUE
Debug "---------------"
Debug "DivertOpen"
Debug "---------------"
Debug "hWndDivert: " + Str(hWndDivert)
Debug "filter: " + filter
#DIVERT_PARAM_QUEUE_LEN = 0
#DIVERT_PARAM_QUEUE_TIME = 1
DivertSetParam = GetFunction(WinDivert, "DivertSetParam")
DivertSetParam(hWndDivert, #DIVERT_PARAM_QUEUE_LEN, 8192)
DivertSetParam(hWndDivert, #DIVERT_PARAM_QUEUE_TIME, 1024)
*pPacket = AllocateMemory($FFFF)
pAddr.DIVERT_ADDRESS
DivertRecv = GetFunction(WinDivert, "DivertRecv")
If DivertRecv(hWndDivert, *pPacket, MemorySize(*pPacket), @pAddr, @recvLen)
Debug "---------------"
Debug "DivertRecv"
Debug "---------------"
Debug "pAddr\IfIdx: " + PeekL(@pAddr\IfIdx)
Debug "pAddr\SubIfIdx: " + PeekL(@pAddr\SubIfIdx)
Debug "pAddr\Direction: " + PeekA(@pAddr\Direction)
*ppIpHdr.DIVERT_IPHDR
*ppIpv6Hdr.DIVERT_IPV6HDR
*ppIcmpHdr.DIVERT_ICMPHDR
*ppIcmpv6Hdr.DIVERT_ICMPV6HDR
*ppTcpHdr.DIVERT_TCPHDR
*ppUdpHdr.DIVERT_UDPHDR
DivertHelperParsePacket = GetFunction(WinDivert, "DivertHelperParsePacket")
DivertHelperParsePacket(*pPacket, recvLen, @*ppIpHdr, @*ppIpv6Hdr, @*ppIcmpHdr, @*ppIcmpv6Hdr, @*ppTcpHdr, @*ppUdpHdr, @*ppData, @pDataLen)
Debug "---------------"
Debug "DivertHelperParsePacket"
Debug "---------------"
If *ppIpHdr
Debug "ppIpHdr\HdrLength: " + Str(PeekA(@*ppIpHdr\HdrLength) & %1111)
Debug "ppIpHdr\Version: " + Str(PeekA(@*ppIpHdr\Version) >> 4)
Debug "ppIpHdr\TOS: " + PeekA(@*ppIpHdr\TOS)
Debug "ppIpHdr\Length: " + htons_(PeekU(@*ppIpHdr\Length))
Debug "ppIpHdr\Id: " + htons_(PeekU(@*ppIpHdr\Id))
Debug "ppIpHdr\FragOff0: " + htons_(PeekU(@*ppIpHdr\FragOff0))
Debug "ppIpHdr\TTL: " + PeekA(@*ppIpHdr\TTL)
Debug "ppIpHdr\Protocol: " + PeekA(@*ppIpHdr\Protocol)
Debug "ppIpHdr\Checksum: " + htons_(PeekU(@*ppIpHdr\Checksum))
Debug "ppIpHdr\SrcAddr: " + IPString(PeekL(@*ppIpHdr\SrcAddr))
Debug "ppIpHdr\DstAddr: " + IPString(PeekL(@*ppIpHdr\DstAddr))
EndIf
Debug "---------------"
If *ppIpv6Hdr
Debug "ppIpv6Hdr\TrafficClass0: " + PeekA(@*ppIpv6Hdr\TrafficClass0)
Debug "ppIpv6Hdr\Version: " + PeekA(@*ppIpv6Hdr\Version)
Debug "ppIpv6Hdr\FlowLabel0: " + PeekA(@*ppIpv6Hdr\FlowLabel0)
Debug "ppIpv6Hdr\TrafficClass1: " + PeekA(@*ppIpv6Hdr\TrafficClass1)
Debug "ppIpv6Hdr\FlowLabel1: " + PeekU(@*ppIpv6Hdr\FlowLabel1)
Debug "ppIpv6Hdr\Length: " + PeekU(@*ppIpv6Hdr\Length)
Debug "ppIpv6Hdr\NextHdr: " + PeekU(@*ppIpv6Hdr\NextHdr)
Debug "ppIpv6Hdr\HopLimit: " + PeekU(@*ppIpv6Hdr\HopLimit)
Debug "ppIpv6Hdr\SrcAddr[1]: " + PeekL(@*ppIpv6Hdr\SrcAddr[0])
Debug "ppIpv6Hdr\SrcAddr[2]: " + PeekL(@*ppIpv6Hdr\SrcAddr[1])
Debug "ppIpv6Hdr\SrcAddr[3]: " + PeekL(@*ppIpv6Hdr\SrcAddr[2])
Debug "ppIpv6Hdr\SrcAddr[4]: " + PeekL(@*ppIpv6Hdr\SrcAddr[3])
Debug "ppIpv6Hdr\DstAddr[1]: " + PeekL(@*ppIpv6Hdr\DstAddr[0])
Debug "ppIpv6Hdr\DstAddr[2]: " + PeekL(@*ppIpv6Hdr\DstAddr[1])
Debug "ppIpv6Hdr\DstAddr[3]: " + PeekL(@*ppIpv6Hdr\DstAddr[2])
Debug "ppIpv6Hdr\DstAddr[4]: " + PeekL(@*ppIpv6Hdr\DstAddr[3])
EndIf
Debug "---------------"
If *ppIcmpHdr
Debug "ppIcmpHdr\Type: " + PeekA(@*ppIcmpHdr\Type)
Debug "ppIcmpHdr\Code: " + PeekA(@*ppIcmpHdr\Code)
Debug "ppIcmpHdr\Checksum: " + PeekU(@*ppIcmpHdr\Checksum)
Debug "ppIcmpHdr\Body: " + PeekL(@*ppIcmpHdr\Body)
EndIf
Debug "---------------"
If *ppIcmpv6Hdr
Debug "ppIcmpv6Hdr\Type: " + PeekA(@*ppIcmpv6Hdr\Type)
Debug "ppIcmpv6Hdr\Code: " + PeekA(@*ppIcmpv6Hdr\Code)
Debug "ppIcmpv6Hdr\Checksum: " + PeekU(@*ppIcmpv6Hdr\Checksum)
Debug "ppIcmpv6Hdr\Body: " + PeekL(@*ppIcmpv6Hdr\Body)
EndIf
Debug "---------------"
If *ppTcpHdr
Debug "ppTcpHdr\SrcPort: " + PeekU(@*ppTcpHdr\SrcPort)
Debug "ppTcpHdr\DstPort: " + PeekU(@*ppTcpHdr\DstPort)
Debug "ppTcpHdr\SeqNum: " + PeekL(@*ppTcpHdr\SeqNum)
Debug "ppTcpHdr\AckNum: " + PeekL(@*ppTcpHdr\AckNum)
Debug "ppTcpHdr\Reserved1: " + PeekU(@*ppTcpHdr\Reserved1)
Debug "ppTcpHdr\HdrLength: " + PeekU(@*ppTcpHdr\HdrLength)
Debug "ppTcpHdr\Fin: " + PeekU(@*ppTcpHdr\Fin)
Debug "ppTcpHdr\Syn: " + PeekU(@*ppTcpHdr\Syn)
Debug "ppTcpHdr\Rst: " + PeekU(@*ppTcpHdr\Rst)
Debug "ppTcpHdr\Psh: " + PeekU(@*ppTcpHdr\Psh)
Debug "ppTcpHdr\Ack: " + PeekU(@*ppTcpHdr\Ack)
Debug "ppTcpHdr\Urg: " + PeekU(@*ppTcpHdr\Urg)
Debug "ppTcpHdr\Reserved2: " + PeekU(@*ppTcpHdr\Reserved2)
Debug "ppTcpHdr\Window: " + PeekU(@*ppTcpHdr\Window)
Debug "ppTcpHdr\Checksum: " + PeekU(@*ppTcpHdr\Checksum)
Debug "ppTcpHdr\UrgPtr: " + PeekU(@*ppTcpHdr\UrgPtr)
EndIf
Debug "---------------"
If *ppUdpHdr
Debug "ppUdpHdr\SrcPort: " + PeekU(@*ppUdpHdr\SrcPort)
Debug "ppUdpHdr\DstPort: " + PeekU(@*ppUdpHdr\DstPort)
Debug "ppUdpHdr\Length: " + PeekU(@*ppUdpHdr\Length)
Debug "ppUdpHdr\Checksum: " + PeekU(@*ppUdpHdr\Checksum)
EndIf
If *ppData
Debug "---------------"
Debug "*ppData"
Debug "---------------"
Debug PeekS(*ppData, pDataLen)
EndIf
FreeMemory(*pPacket)
Else
Debug "---------------"
Debug "DivertRecv"
Debug TestForError()
Debug "---------------"
EndIf
DivertClose = GetFunction(WinDivert, "DivertClose")
DivertClose(hWndDivert)
Else
Debug "---------------"
Debug "DivertOpen"
Debug TestForError()
Debug "---------------"
EndIf
CloseLibrary(WinDivert)
RunProgram("sc", "stop WinDivert1.0", "")
RunProgram("sc", "delete WinDivert1.0", "")
EndIf
Re: Windows Filtering Platform
Posted: Mon Sep 23, 2013 4:23 am
by Thunder93
Looking good!
I was trying to figure how to have PB handle the first three-bit fields in \FragOff0.
#define DIVERT_IPHDR_GET_FRAGOFF(hdr) \
(((hdr)->FragOff0) & 0xFF1F)
#define DIVERT_IPHDR_GET_MF(hdr) \
((((hdr)->FragOff0) & 0x0020) != 0)
#define DIVERT_IPHDR_GET_DF(hdr) \
((((hdr)->FragOff0) & 0x0040) != 0)
#define DIVERT_IPHDR_GET_RESERVED(hdr) \
((((hdr)->FragOff0) & 0x0080) != 0)