Windows Filtering Platform

Just starting out? Need help? Post your questions and find answers here.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Windows Filtering Platform

Post by Thunder93 »

Hi.

I've been exploring 'Windows Filtering Platform' - http://msdn.microsoft.com/en-us/windows ... 63267.aspx

I was trying for several hours today to have a working PB example to show the traversing packets (simply Packet logging system). Unfortunately I'm stuck in a deep black hole. The only thing giving on the subject that I could find on PB forums was the PB user SFSxOI 2008 post. Giving PB example how to open a session to the filtering engine http://www.purebasic.fr/english/viewtop ... 27#p252827.
ʽʽ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 »

Black hole is right, the more you dig into this the deeper it gets, but if your still interested - what I have so far should get you started:

Modified from: http://www.codeproject.com/Articles/290 ... g-Platform

Code: Select all

Enumeration FWP_DATA_TYPE
  #FWP_EMPTY
  #FWP_UINT8
  #FWP_UINT16
  #FWP_UINT32
  #FWP_UINT64
  #FWP_INT8
  #FWP_INT16
  #FWP_INT32
  #FWP_INT64
  #FWP_FLOAT
  #FWP_DOUBLE
  #FWP_BYTE_ARRAY16_TYPE
  #FWP_BYTE_BLOB_TYPE
  #FWP_SID
  #FWP_SECURITY_DESCRIPTOR_TYPE
  #FWP_TOKEN_INFORMATION_TYPE
  #FWP_TOKEN_ACCESS_INFORMATION_TYPE
  #FWP_UNICODE_STRING_TYPE
  #FWP_BYTE_ARRAY6_TYPE
  #FWP_SINGLE_DATA_TYPE_MAX = $FF
  #FWP_V4_ADDR_MASK
  #FWP_V6_ADDR_MASK
  #FWP_RANGE_TYPE
  #FWP_DATA_TYPE_MAX
EndEnumeration

Enumeration FWP_MATCH_TYPE
  #FWP_MATCH_EQUAL
  #FWP_MATCH_GREATER
  #FWP_MATCH_LESS
  #FWP_MATCH_GREATER_OR_EQUAL
  #FWP_MATCH_LESS_OR_EQUAL
  #FWP_MATCH_RANGE
  #FWP_MATCH_FLAGS_ALL_SET
  #FWP_MATCH_FLAGS_ANY_SET
  #FWP_MATCH_FLAGS_NONE_SET
  #FWP_MATCH_EQUAL_CASE_INSENSITIVE
  #FWP_MATCH_NOT_EQUAL
  #FWP_MATCH_TYPE_MAX
EndEnumeration

Structure FWPM_DISPLAY_DATA0
  name.s
  description.s
EndStructure

Structure FWP_BYTE_BLOB
  size.l
  *Data
EndStructure

Structure FWPM_SUBLAYER0
  subLayerKey.GUID
  displayData.FWPM_DISPLAY_DATA0
  flags.w
  providerKey.GUID
  providerData.FWP_BYTE_BLOB
  weight.w
EndStructure

Structure FWP_V4_ADDR_AND_MASK
  addr.l
  mask.l
EndStructure

Structure FWP_CONDITION_VALUE0
  type.l ;FWP_DATA_TYPE
  StructureUnion
    ;...
    v4AddrMask.FWP_V4_ADDR_AND_MASK
    ;...
  EndStructureUnion
EndStructure

Structure FWPM_FILTER_CONDITION0
  fieldKey.GUID
  matchType.l ;FWP_MATCH_TYPE
  conditionValue.FWP_CONDITION_VALUE0
EndStructure

Structure FWP_VALUE0
  type.l ;FWP_DATA_TYPE
  StructureUnion
    ;...
  EndStructureUnion
EndStructure

Structure FWPM_ACTION0
  type.l
  StructureUnion
    filterType.GUID
    calloutKey.GUID
  EndStructureUnion
EndStructure

Structure FWPM_FILTER0
  filterKey.GUID
  displayData.FWPM_DISPLAY_DATA0
  flags.l
  providerKey.GUID
  providerData.FWP_BYTE_BLOB
  layerKey.GUID
  subLayerKey.GUID
  weight.FWP_VALUE0
  numFilterConditions.l
  filterCondition.FWPM_FILTER_CONDITION0
  action.FWPM_ACTION0
  StructureUnion
    rawContext.LARGE_INTEGER
    providerContextKey.GUID
  EndStructureUnion
  reserved.GUID
  filterId.LARGE_INTEGER
  effectiveWeight.FWP_VALUE0
EndStructure

Prototype protoFwpmEngineOpen0(serverName, authnService, authIdentity, session, engineHandle)
Global FwpmEngineOpen0.protoFwpmEngineOpen0

Prototype protoFwpmSubLayerAdd0(engineHandle, subLayer, sd)
Global FwpmSubLayerAdd0.protoFwpmSubLayerAdd0

Prototype protoFwpmSubLayerDeleteByKey0(engineHandle, key)
Global FwpmSubLayerDeleteByKey0.protoFwpmSubLayerDeleteByKey0

Prototype protoFwpmEngineClose0(engineHandle)
Global FwpmEngineClose0.protoFwpmEngineClose0

Prototype protoFwpmFilterAdd0(engineHandle, filter, sd, id)
Global FwpmFilterAdd0.protoFwpmFilterAdd0

Prototype protoFwpmFilterDeleteById0(engineHandle, id)
Global FwpmFilterDeleteById0.protoFwpmFilterDeleteById0

Global fwpmSubLayer.FWPM_SUBLAYER0
Global fwpmFilter.FWPM_FILTER0

Procedure CreateDeleteInterface(fwpuclnt, engineHandle, bCreate.b)
  Result = #Null

  If bCreate
    #RPC_C_AUTHN_WINNT = 10
    FwpmEngineOpen0 = GetFunction(fwpuclnt, "FwpmEngineOpen0")
    FwpmEngineOpen0(#Null, #RPC_C_AUTHN_WINNT, #Null, #Null, @engineHandle)
    Result = engineHandle
  Else
    FwpmEngineClose0 = GetFunction(fwpuclnt, "FwpmEngineClose0")
    FwpmEngineClose0(engineHandle)
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure BindUnbindInterface(fwpuclnt, engineHandle, bBind.b)
  Result = #Null

  If bBind
    guidSubLayer.GUID

    If UuidCreate_(guidSubLayer) = #NO_ERROR
      CopyMemory(guidSubLayer, fwpmSubLayer\subLayerKey, SizeOf(GUID))
      fwpmSubLayer\displayData\name = "FireWALL"
      fwpmSubLayer\displayData\description = "FireWALL"
      fwpmSubLayer\flags = 0
      fwpmSubLayer\weight = $100
      FwpmSubLayerAdd0 = GetFunction(fwpuclnt, "FwpmSubLayerAdd0")
      Result = FwpmSubLayerAdd0(engineHandle, @fwpmSubLayer, #Null)
    EndIf
  Else
    FwpmSubLayerDeleteByKey0 = GetFunction(fwpuclnt, "FwpmSubLayerDeleteByKey0")
    Result = FwpmSubLayerDeleteByKey0(engineHandle, @fwpmSubLayer)
    ZeroMemory_(fwpmSubLayer\subLayerKey, SizeOf(GUID))
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure AddRemoveFilter(fwpuclnt, engineHandle, bAdd.b)
  If bAdd
    #SUBNET_MASK = $FFFFFFFF
    #FWP_SINGLE_DATA_TYPE_MAX = $FF
    #FWP_V4_ADDR_MASK = #FWP_SINGLE_DATA_TYPE_MAX + 1
    #FWP_EMPTY = $0
    #FWP_ACTION_BLOCK = $1
    addrMask.FWP_V4_ADDR_AND_MASK
    addrMask\addr = $C0A80A0A ;192.168.10.10
    addrMask\mask = #SUBNET_MASK
    fwpmCondition.FWPM_FILTER_CONDITION0
;    fwpmCondition\fieldKey = FWPM_CONDITION_IP_REMOTE_ADDRESS
    fwpmCondition\matchType = #FWP_MATCH_EQUAL
    fwpmCondition\conditionValue\type = #FWP_V4_ADDR_MASK
    fwpmCondition\conditionValue\v4AddrMask = addrMask
    fwpmFilter\displayData\name = "FireWALL"
    fwpmFilter\subLayerKey = fwpmSubLayer\subLayerKey
;    fwpmFilter\layerKey = FWPM_LAYER_INBOUND_TRANSPORT_V4
    fwpmFilter\weight\type = #FWP_EMPTY
    fwpmFilter\numFilterConditions = 1
    fwpmFilter\filterCondition = fwpmCondition
    fwpmFilter\action\type = #FWP_ACTION_BLOCK
    FwpmFilterAdd0 = GetFunction(fwpuclnt, "FwpmFilterAdd0")
    Result = FwpmFilterAdd0(engineHandle, @fwpmFilter, #Null, @id)
    Debug Right(Hex(Result), 8)
  Else
    FwpmFilterDeleteById0(engineHandle, id)
    id = 0
  EndIf
EndProcedure
fwpuclnt = OpenLibrary(#PB_Any, "fwpuclnt.dll")

If IsLibrary(fwpuclnt)
  engineHandle = CreateDeleteInterface(fwpuclnt, #Null, #True)

  If engineHandle
    Debug BindUnbindInterface(fwpuclnt, engineHandle, #True)
    ;...
    Debug BindUnbindInterface(fwpuclnt, engineHandle, #False)
  EndIf
  CreateDeleteInterface(fwpuclnt, engineHandle, #False)
  CloseLibrary(fwpuclnt)
EndIf
Last edited by JHPJHP on Thu Oct 03, 2013 10:24 pm, 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 »

Amazing JHPJHP! Lot further than I had. Much appreciations! Thanks JHPJHP.

I make any progress I'll post back. Lots to learn about WFP :shock:
ʽʽ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 »

Found this... "If you need to do basic filtering without packet modification or packet inspection, you can get by with implementing a UserMode service or application. If you need to inspect the packets or modify the content, then a callout driver is necessary." :evil:
ʽʽ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 »

It seems that this method can be used to script a makeshift firewall... Not a lot of documentation - good you found out now.

If you were to continue - the following is helpful:
GUID's: ftp://78292.dyn.ufanet.ru/Delphi/XXX/Di ... de/fwpmu.h
Error Codes: http://msdn.microsoft.com/en-us/library ... p/bb540652

Example using the GUID's (replaces the Procedure in the previous post):

Code: Select all

Procedure AddRemoveFilter(fwpuclnt, engineHandle, bAdd.b)
  If bAdd
    #SUBNET_MASK = $FFFFFFFF
    #FWP_EMPTY = $0
    #FWP_ACTION_BLOCK = $1
    fieldKey.GUID
    fieldKey\Data1 = $B235AE9A
    fieldKey\Data2 = $1D64
    fieldKey\Data3 = $49B8
    fieldKey\Data4[0] = $A4
    fieldKey\Data4[1] = $4C
    fieldKey\Data4[2] = $5F
    fieldKey\Data4[3] = $F3
    fieldKey\Data4[4] = $D9
    fieldKey\Data4[5] = $09
    fieldKey\Data4[6] = $50
    fieldKey\Data4[7] = $45
    layerKey.GUID
    layerKey\Data1 = $5926DFC8
    layerKey\Data2 = $E3CF
    layerKey\Data3 = $4426
    layerKey\Data4[0] = $A2
    layerKey\Data4[1] = $83
    layerKey\Data4[2] = $DC
    layerKey\Data4[3] = $39
    layerKey\Data4[4] = $3F
    layerKey\Data4[5] = $5D
    layerKey\Data4[6] = $0F
    layerKey\Data4[7] = $9D
    addrMask.FWP_V4_ADDR_AND_MASK
    addrMask\addr = $C0A80A0A ;192.168.10.10
    addrMask\mask = #SUBNET_MASK
    fwpmCondition.FWPM_FILTER_CONDITION0
    fwpmCondition\fieldKey = fieldKey ;FWPM_CONDITION_IP_REMOTE_ADDRESS
    fwpmCondition\matchType = #FWP_MATCH_EQUAL
    fwpmCondition\conditionValue\type = #FWP_V4_ADDR_MASK
    fwpmCondition\conditionValue\v4AddrMask = addrMask
    fwpmFilter\displayData\name = "FireWALL"
    fwpmFilter\subLayerKey = fwpmSubLayer\subLayerKey
    fwpmFilter\layerKey = layerKey ;FWPM_LAYER_INBOUND_TRANSPORT_V4
    fwpmFilter\weight\type = #FWP_EMPTY
    fwpmFilter\numFilterConditions = 1
    fwpmFilter\filterCondition = fwpmCondition
    fwpmFilter\action\type = #FWP_ACTION_BLOCK
    FwpmFilterAdd0 = GetFunction(fwpuclnt, "FwpmFilterAdd0")
    Result = FwpmFilterAdd0(engineHandle, @fwpmFilter, #Null, @id)
    Debug Right(Hex(Result), 8)
  Else
    FwpmFilterDeleteById0(engineHandle, id)
    id = 0
  EndIf
EndProcedure

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 »

LOL! Yea... I went to a lot of places on the web. :D

The following you've giving is very helpful, thanks.
ʽʽ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 »

Hi JHPJHP.

We could have some more fun I think.

Yesterday I kept coming to WinDiverthttp://reqrypt.org/windivert.html. I didn't bother giving it a second thought while I thought packet monitoring could be done with WFP in user-mode.

“Windows Packet Divert (WinDivert) is a user-mode packet capture-and-divert package for Windows Vista, Windows 2008, Windows 7, Windows 8.

WinDivert allows user-mode applications to capture/modify/drop network packets sent to/from the Windows network stack. In summary, WinDivert can:

...
...
...”

:P
ʽʽ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 »

Looks promising...

I read the documentation, and put together a very small example - it doesn't do anything, but it does start the process. :)

Two folders (depending on your configuration):
- amd64: Debug the included file: WinDivert.pb (PureBasic 64bit)
- x86: Debug the included file: WinDivert.pb (PureBasic 32bit)

I will be away for most of the weekend, but I'll check the forum periodically, returning Monday.
Last edited by JHPJHP on Thu Oct 03, 2013 10:25 pm, 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 »

You seem to know your stuff :D

Thanks for the small example, it was actually educational.

I appreciate your dedication on this. If I figure I got way over my head on something, I'll poster. You be sure to enjoy your weekend. :mrgreen:
ʽʽ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 »

Thanks, should be a great weekend - enjoy yours as well. Had some extra time - see the following:

I don't have all the bugs worked out, but it's a start...

If you run it in Debug Mode, and then open a Webpage - you should see the beginning of a dissected packet, or at least a template for one - not sure if the lack of data has to do with the Structure setup?

NB*: I also updated the link in the previous post to include the following script.

Code: Select all

Structure DIVERT_ADDRESS
  IfIdx.l
  SubIfIdx.l
  Direction.a
EndStructure

Structure DIVERT_IPHDR
  HdrLength.a[4]
  Version.a[4]
  TOS.a
  Length.c
  Id.c
  FragOff0.c
  TTL.a
  Protocol.a
  Checksum.c
  SrcAddr.l
  DstAddr.l
EndStructure

Structure DIVERT_ICMPHDR
  Type.a
  Code.a
  Checksum.c
  Body.l
EndStructure

Structure DIVERT_TCPHDR
  SrcPort.c
  DstPort.c
  SeqNum.l
  AckNum.l
  Reserved1.c[4]
  HdrLength.c[4]
  Fin.c[1]
  Syn.c[1]
  Rst.c[1]
  Psh.c[1]
  Ack.c[1]
  Urg.c[1]
  Reserved2.c[2]
  Window.c
  Checksum.c
  UrgPtr.c
EndStructure

Structure DIVERT_UDPHDR
  SrcPort.c
  DstPort.c
  Length.c
  Checksum.c
EndStructure

Prototype protoDivertOpen(filter.s, layer, priority.c, 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
  #PRIORITY_DEFAULT = 0
  #DIVERT_FLAG_SNIFF = 1
  DivertOpen = GetFunction(WinDivert, "DivertOpen")
  hDivert = DivertOpen("outbound && ip && tcp.DstPort == 80 && tcp.PayloadLength > 0", #DIVERT_LAYER_NETWORK, #PRIORITY_DEFAULT, #DIVERT_FLAG_SNIFF)

  If hDivert > 0
    Debug "---------------"
    Debug "Success: ( handle ) " + Str(hDivert)
    Debug "---------------"
    #DIVERT_PARAM_QUEUE_LEN = 0
    #DIVERT_PARAM_QUEUE_TIME = 1
    DivertSetParam = GetFunction(WinDivert, "DivertSetParam")
    DivertSetParam(hDivert, #DIVERT_PARAM_QUEUE_LEN, 8192)
    DivertSetParam(hDivert, #DIVERT_PARAM_QUEUE_TIME, 1024)
    *pPacket = AllocateMemory(8192)
    *ppData = AllocateMemory(8192)
    pAddr.DIVERT_ADDRESS
    DivertRecv = GetFunction(WinDivert, "DivertRecv")
    DivertRecv(hDivert, *pPacket, 8192, @pAddr, @recvLen)
    Debug pAddr\IfIdx
    Debug pAddr\SubIfIdx
    Debug pAddr\Direction
    Debug recvLen
    Debug "---------------"
    Debug TestForError()
    Debug "---------------"
    ppIpHdr.DIVERT_IPHDR
    ppIcmpHdr.DIVERT_ICMPHDR
    ppTcpHdr.DIVERT_TCPHDR
    ppUdpHdr.DIVERT_UDPHDR
    DivertHelperParsePacket = GetFunction(WinDivert, "DivertHelperParsePacket")
    DivertHelperParsePacket(*pPacket, recvLen, @ppIpHdr, #Null, @ppIcmpHdr, #Null, @ppTcpHdr, @ppUdpHdr, *ppData, @pDataLen)
    Debug ppIpHdr\SrcAddr
    Debug ppIpHdr\DstAddr
    Debug "---------------"
    Debug ppIcmpHdr\Type
    Debug ppIcmpHdr\Code
    Debug "---------------"
    Debug ppTcpHdr\SrcPort
    Debug ppTcpHdr\DstPort
    Debug "---------------"
    Debug ppUdpHdr\SrcPort
    Debug ppUdpHdr\DstPort
    Debug "---------------"
    Debug PeekS(*ppData, -1)
    Debug pDataLen
    Debug "---------------"
    Debug TestForError()
    Debug "---------------"
    FreeMemory(*ppData)
    FreeMemory(*pPacket)
    DivertClose = GetFunction(WinDivert, "DivertClose")
    DivertClose(hDivert)
  Else
    Debug TestForError()
  EndIf
  CloseLibrary(WinDivert)
EndIf
Last edited by JHPJHP on Sun Sep 22, 2013 5:05 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 »

It reads something but on the x64 system I'm running, the port information isn't read correctly. The destination port that is specified for the event trigger is 80, however I'm getting some other gibberish when reading the dest port information.

With your example, the ICMP and UDP packet information wouldn't be returned with anything since the filter is applied to outgoing www-http traffic (with destination port 80tcp).

However the IP header information like the source and destination IP addresses should be stored and available, but I can't figure out how to retrieve it. Probably align issue and wrong types problem.
ʽʽ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 »

That's what I was thinking, either Structure Alignment, Structure data-types, or both?

The ICMP and UDP are there for additional tests, just change the DivertOpen Procedure filter to "true" to capture all packet types...

*pPacket = AllocateMemory(8192)
... is correct and set to the max but,
*ppData = AllocateMemory(8192)
... I couldnt find enough documentation - and made a guess, for all I know it's a String or UNICODE_STRING (structure)?

I also guessed on the Structures with the Array values - my interpertation from the documentation. :mrgreen:

Maybe you will have better luck - and you were right - this is fun! :D

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 »

No go yet. I can't seem to read properly from the structures, or have the information stored correctly. :?
ʽʽ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 »

Same on 32bit Windows. 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 »

I got in touch with the programmer who created WinDivert, and he gave me some additional information concerning Error Codes, and the DivertHelperParsePacket() function, to at least get over some of the basic issues we were having.

Looking up C Structures on the net - I believe :4 :2 :1 represent bit lengths, and I don't think PureBasic supports bit values in Structures, but we might be able to use Shift Operators (<< >>) on the returned values?

This is what I have so far (link in original post has been updated as well):

Code: Select all

Structure DIVERT_ADDRESS
  IfIdx.l
  SubIfIdx.l
  Direction.a
EndStructure

Structure DIVERT_IPHDR
  HdrLength.a
  Version.a
  TOS.a
  Length.u
  Id.u
  FragOff0.u
  TTL.a
  Protocol.a
  Checksum.u
  SrcAddr.l
  DstAddr.l
EndStructure

Structure DIVERT_ICMPHDR
  Type.a
  Code.a
  Checksum.u
  Body.l
EndStructure

Structure DIVERT_TCPHDR
  SrcPort.u
  DstPort.u
  SeqNum.l
  AckNum.l
  Reserved1.u
  HdrLength.u
  Fin.u
  Syn.u
  Rst.u
  Psh.u
  Ack.u
  Urg.u
  Reserved2.u
  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, 8192, @pAddr, @recvLen)
      Debug "---------------"
      Debug "DivertRecv"
      Debug "---------------"
      Debug "pAddr\IfIdx: " + Str(pAddr\IfIdx)
      Debug "pAddr\SubIfIdx: " + Str(pAddr\SubIfIdx)
      Debug "pAddr\Direction: " + Str(pAddr\Direction)
      ppIpHdr.DIVERT_IPHDR
      ppIcmpHdr.DIVERT_ICMPHDR
      ppTcpHdr.DIVERT_TCPHDR
      ppUdpHdr.DIVERT_UDPHDR
      DivertHelperParsePacket = GetFunction(WinDivert, "DivertHelperParsePacket")
      DivertHelperParsePacket(*pPacket, recvLen, @ppIpHdr, #Null, @ppIcmpHdr, #Null, @ppTcpHdr, @ppUdpHdr, @ppData, @pDataLen)
      Debug "---------------"
      Debug "DivertHelperParsePacket"
      Debug "---------------"
      Debug "ppIpHdr\HdrLength: " + Str(ppIpHdr\HdrLength)
      Debug "ppIpHdr\Version: " + Str(ppIpHdr\Version)
      Debug "ppIpHdr\TOS: " + Str(ppIpHdr\TOS)
      Debug "ppIpHdr\Length: " + Str(ppIpHdr\Length)
      Debug "ppIpHdr\Id: " + Str(ppIpHdr\Id)
      Debug "ppIpHdr\FragOff0: " + Str(ppIpHdr\FragOff0)
      Debug "ppIpHdr\TTL: " + Str(ppIpHdr\TTL)
      Debug "ppIpHdr\Protocol: " + Str(ppIpHdr\Protocol)
      Debug "ppIpHdr\Checksum: " + Str(ppIpHdr\Checksum)
      Debug "ppIpHdr\SrcAddr: " + Str(ppIpHdr\SrcAddr)
      Debug "ppIpHdr\DstAddr: " + Str(ppIpHdr\DstAddr)
      Debug "---------------"
      Debug "ppIcmpHdr\Type: " + Str(ppIcmpHdr\Type)
      Debug "ppIcmpHdr\Code: " + Str(ppIcmpHdr\Code)
      Debug "---------------"
      Debug "ppTcpHdr\SrcPort: " + Str(ppTcpHdr\SrcPort)
      Debug "ppTcpHdr\DstPort: " + Str(ppTcpHdr\DstPort)
      Debug "---------------"
      Debug "ppUdpHdr\SrcPort: " + Str(ppUdpHdr\SrcPort)
      Debug "ppUdpHdr\DstPort: " + Str(ppUdpHdr\DstPort)
      Debug "---------------"
      Debug "*ppData"
      Debug "---------------"
      Debug PeekS(ppData, pDataLen)
      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
Last edited by JHPJHP on Sun Sep 22, 2013 5:06 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.
Post Reply