I've been modifying the 'inspect' WFP example (bundled with the WinDDK) with the aim of being able to parse the payload of all incoming TCP packets (from a specified IP address) for certain strings. (I've already modified 'inspect' such that only TCP packets are caught by the filter)
So far my modifications have been on the 'TLInspectTransportClassify' classifyFn, as shown below. My aim is to have access to the payload of each TCP packet that is caught.
FWPS_STREAM_CALLOUT_IO_PACKET* ioPacket = (FWPS_STREAM_CALLOUT_IO_PACKET*)layerData;
FWPS_STREAM_DATA* streamData;
SIZE_T streamLength;
BYTE* stream = NULL;
SIZE_T bytesCopied = 0;
[...]
if(ioPacket == NULL) {
DbgPrint("ioPacket == NULL\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
streamData = ioPacket->streamData;
if(!streamData) { // why is this always NULL? shouldn't our payload be here?
DbgPrint("streamData == NULL: no data\n");
classifyOut->actionType = FWP_ACTION_PERMIT;
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
goto Exit;
}
DbgPrint("tcp packet has some data\n");
streamLength = streamData->dataLength;
stream = ExAllocatePoolWithTag(NonPagedPool,
streamLength,
'yftN');
if (!stream)
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(stream,streamLength);
FwpsCopyStreamDataToBuffer0(
streamData,
stream,
streamLength,
&bytesCopied);
// should now have our tcp payload in 'stream' buffer(?)
DbgPrint("reached parsing code\n");
[...]
From my understanding, after declaring ioPacket as above, ioPacket->streamData should contain the packet's payload. However, ioPacket->streamData is ALWAYS NULL for me. How do I get the packet's payload? Am I doing something wrong.
Thanks in advance.
'TLInspectTransportClassify' is on TRANSPORT_LAYER where layerData should be casted into NET_BUFFER_LIST.
FWPS_STREAM_CALLOUT_IO_PACKET is for FWPM_LAYER_STREAM_V4/FWPM_LAYER_STREAM_V6
See MSDN classifyFn0. http://msdn.microsoft.com/en-us/library/ff544890(VS.85).aspx
Management Filtering Layer Identifiers http://msdn.microsoft.com/en-us/library/ff557101(VS.85).aspx