WFP Note 20170304
先说需求,我想知道指定ProcessID 和ProcessPath ,并且能得出对应的进程进出的数据。这样就需要建立两个CallOuts驱动,一个Established v4层,另一个Stream v4层,第一个是用来获取进程ID和进程Path,还有数据包包头信息(ip,prot,direction)。第二个是用来获取数据包(数据包实际数据大小,数据包内部具体信息)首先建立
先说需求,我想知道指定ProcessID 和ProcessPath ,并且能得出对应的进程进出的数据。
这样就需要建立两个CallOuts驱动,一个Established v4层,另一个Stream v4层,第一个是用来获取进程ID和进程Path,
还有数据包包头信息(ip,prot,direction)。第二个是用来获取数据包(数据包实际数据大小,数据包内部具体信息)
首先建立了一个数据结构FLOW_DATA,用来存储Estabished Layer的数据。
因为肯定有很多条Estabished layer信息,所以建立list entry链表连起来。
typedef struct _FLOW_DATA
{
LIST_ENTRY listEntry;
UINT64 flowHandle;
UINT64 flowContext;
UINT64 calloutId;
ULONG localAddressV4;
USHORT localPort;
USHORT ipProto;
ULONG remoteAddressV4;
USHORT remotePort;
WCHAR* processPath;
UINT64 processID;
BOOLEAN deleting;
} FLOW_DATA;
要将进程与传输数据Connect上,先看一个函数:
NTSTATUS NTAPI
FwpsFlowAssociateContext0(
IN UINT64 flowId,
IN UINT16 layerId,
IN UINT32 calloutId,
IN UINT64 flowContext
);
flowId: inMetaValues->flowHandle(Established Layer的Classify函数中)
layerId: 要连接的Layer(例如:FWPS_LAYER_STREAM_V4)
calloutId: Stream layer的CallOut ID
flowContext: 这个也就是建立的FLOW_DATA对象,用来存储Established layer所读出来的信息(进程ID,进程路径,ip...)
因为我要做一个WFP进程监控驱动,所以就需要FwpsFlowAssociateContext函数来建立Established layer和Stream Layer的Association,
所以用FLOW_DATA数据
最后copy写的Established layer的Calssify函数,供参考:
VOID NTAPI Established_ClassifyFn_V4(
IN const FWPS_INCOMING_VALUES *inFixedValues,IN const FWPS_INCOMING_METADATA_VALUES *inMetaValues,
IN OUT VOID *layerData,IN OPTIONAL const void *classifyContext,IN const FWPS_FILTER1 *filter,IN UINT64 flowContext,
OUT FWPS_CLASSIFY_OUT *classifyOut)
{
KdPrint(("Wfp_Established_ClassifyFn_V4\n"));
//存储基本包头信息
WORD wDirection = 0;
WORD wRemotePort = 0;
WORD wSrcPort = 0;
WORD wProtocol = 0;
ULONG ulSrcIPAddress = 0;
ULONG ulRemoteIPAddress = 0;
UINT64 proID;
FWP_BYTE_BLOB *proPath = NULL;
ULONG Length = 0;
FLOW_DATA *FlowContext = NULL;
NTSTATUS Status = STATUS_SUCCESS;
FlowContext = ExAllocatePoolWithTag(NonPagedPool,sizeof(FLOW_DATA),'FC');
do{
if (!FWPS_IS_METADATA_FIELD_PRESENT(inMetaValues, FWPS_METADATA_FIELD_PROCESS_PATH)){
Status = STATUS_NOT_FOUND;
break;
}
if (!(classifyOut->rights & FWPS_RIGHT_ACTION_WRITE))
return;
//获得进程路径
proPath = inMetaValues->processPath;
FlowContext->processPath = ExAllocatePoolWithTag(NonPagedPool,proPath->size,'pp');
memcpy(FlowContext->processPath, proPath->data, proPath->size);
//获得进程ID
proID = inMetaValues->processId;
FlowContext->processID = proID;
//wDirection表示数据包的方向,取值为 //FWP_DIRECTION_INBOUND/FWP_DIRECTION_OUTBOUND
wDirection = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_DIRECTION].value.int8;
//wSrcPort表示本地端口
FlowContext->localPort = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_LOCAL_PORT].value.uint16;
//wRemotePort表示远端端口
FlowContext->remotePort = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_PORT].value.uint16;
//ulSrcIPAddress 表示源IP
FlowContext->localAddressV4 = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_LOCAL_ADDRESS].value.uint32;
//ulRemoteIPAddress 表示远端IP
FlowContext->remoteAddressV4= inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_REMOTE_ADDRESS].value.uint32;
//wProtocol表示网络协议,可以取值是IPPROTO_ICMP/IPPROTO_UDP/IPPROTO_TCP
wProtocol = inFixedValues->incomingValue[FWPS_FIELD_ALE_FLOW_ESTABLISHED_V4_IP_PROTOCOL].value.uint8;
if (wDirection == FWP_DIRECTION_INBOUND){
KdPrint(("---IN BOUND\n"));
}
else if (wDirection == FWP_DIRECTION_OUTBOUND){
KdPrint(("---OUT BOUND\n"));
}
KdPrint(("ProcessID: %d\n", FlowContext->processID));
KdPrint(("Process Path: %ws\n",FlowContext->processPath));
KdPrint(("--SrcProt: %d\n",FlowContext->localPort));
KdPrint(("--RemoteProt: %d\n",FlowContext->remotePort));
UINT8 * srcIp = (UINT8 *)&(FlowContext->localAddressV4);
KdPrint(("--SrcIp: %d,%d,%d,%d\n", srcIp[3],srcIp[2],srcIp[1],srcIp[0]));
UINT8 * remIp = (UINT8 *)&(FlowContext->remoteAddressV4);
KdPrint(("--RemoteIP: %d,%d,%d,%d\n",remIp[3],remIp[2],remIp[1],remIp[0]));
//Establish layer Connect Stream layer
UINT64 FlowHandle = inMetaValues->flowHandle;
FlowContext->flowHandle = inMetaValues->flowHandle;
Status = FwpsFlowAssociateContext(FlowHandle,FWPS_LAYER_STREAM_V4,g_uFwpsDataCallOutId,(UINT64)FlowContext);
if (!NT_SUCCESS(Status))
classifyOut->actionType = FWP_ACTION_CONTINUE;
//默认"允许"(PERMIT)
classifyOut->actionType = FWP_ACTION_PERMIT;
//clear FWPS_RIGHT_ACTION_WRITE Tag
if (filter->flags & FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT)
classifyOut->rights &= ~FWPS_RIGHT_ACTION_WRITE;
return;
}
参考文章:
http://bbs.pediy.com/thread-173871.htm
http://bbs.pediy.com/thread-212152.htm

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)