最近在学习wfp驱动相关资料,在看微软的样例时,发现使用命令停止驱动和卸载驱动函数,为什么停止驱动会走进driverunload中。那停止服务和卸载驱动差别是什么
第二点是关于wfp做关于流量监控,假如应用在驱动启动之后,是不是就监测不到了,看代码实现,是在eatablish层中将pid进行绑定,实现的流量监控,那么是不是可以说,假如这一层的数据已经过了,是无法进行流量监控的。
“Devil组”引证GPT后的撰写:
小魔女参考了bing和GPT部分内容调写:
停止驱动和卸载驱动函数的区别是,停止驱动函数是指停止驱动程序的执行,而卸载驱动函数则是指从系统中完全移除驱动程序,它会调用DriverUnload函数来完成卸载操作。
WFP的流量监控需要在驱动启动之后,在Establish层中将进程ID进行绑定,才能实现流量监控。如果数据已经过了Establish层,就无法进行流量监控了,因为此时已经没有机会将进程ID绑定到流量上。
回答不易,记得采纳呀。
该回答引用ChatGPT
关于第一个问题,当停止驱动时,Windows内核会调用DriverUnload函数以清理驱动程序使用的任何资源。这包括驱动程序创建的设备对象,IRP,内存等等。因此,停止服务和卸载驱动程序之间的主要区别在于,停止服务是暂时停止驱动程序的运行,而卸载驱动程序会彻底删除驱动程序并释放与其关联的所有资源。
关于第二个问题,WFP(Windows Filtering Platform)确实是在网络栈的较低层实现的,它可以在包进入和离开网络栈的不同阶段进行拦截和处理。当应用程序启动驱动程序后,WFP可以继续监视和拦截进出网络栈的流量,但是在一些特殊情况下,例如使用某些加密和隧道协议的流量,WFP可能无法读取和识别数据包的内容。此外,如果网络流量已经到达了与WFP不相关的网络栈层,例如已经由其他驱动程序或过滤器处理,WFP将无法监视该流量。
参考GPT和自己的思路:
关于第一个问题:
在Windows驱动程序中,DriverUnload函数是用来卸载驱动程序的。当操作系统需要卸载驱动程序时,会调用该函数。而停止服务通常是指停止服务进程,而不是卸载驱动程序。如果你的驱动程序提供了服务,那么你需要实现一个服务控制管理函数来处理这些服务请求。在这个函数中,你可以决定是暂停还是停止服务。
当你卸载驱动程序时,操作系统会调用DriverUnload函数,因为它是卸载驱动程序的标准方法。当你停止服务时,操作系统并不会调用DriverUnload函数,因为这并不涉及到卸载驱动程序。相反,你需要实现一个服务控制管理函数来处理这些服务请求。
关于第二个问题:
WFP(Windows Filtering Platform)是一个用于网络数据包过滤的框架,它提供了一种用于监视、过滤和修改网络数据包的机制。如果你在驱动程序启动之后开始监测网络流量,那么你只能监测到从那个时刻开始的流量。如果数据在驱动程序之前已经通过了,则你将无法监测到它们。这是因为WFP仅能监测到经过它的数据包。
在WFP中,你可以使用FWPS_LAYER_STREAM_V4和FWPS_LAYER_STREAM_V6层来监测TCP和UDP流量。当一个进程发送或接收TCP或UDP数据包时,WFP会在FWPS_LAYER_STREAM_V4或FWPS_LAYER_STREAM_V6层上注册一个回调函数。在这个回调函数中,你可以捕获、检查和修改网络数据包。在这个回调函数中,你可以检查流的PID并将它们与应用程序进行关联。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,WDF驱动是Windows Driver Foundation的简称,它是一种为Windows驱动程序提供抽象化的框架,它把驱动程序的复杂性隐藏在后面,使得驱动程序开发者更加容易编写稳定、可靠的驱动程序。
QFP驱动是Qualcomm Frame Protocol的简称,它是用于Qualcomm处理器的一种驱动,主要用于与设备通信,包括Camera、Audio、Sensor等。
关于驱动程序的停止和卸载,停止驱动是指暂停驱动的运行,不再接收请求;卸载驱动是指将驱动程序的所有文件、注册表和其他资源从Windows系统中删除,这将导致所有对该驱动程序的请求失败。当我们执行停止驱动的操作时,WDF框架会调用DriverUnload
函数,它会在驱动程序被卸载之前执行一些清理工作。但是,卸载驱动时,DriverUnload
函数是最后被调用的,因为在卸载驱动时,操作系统已经释放了驱动所占用的所有资源,因此执行DriverUnload
函数的操作将无法完成。
关于WFP的流量监控,WFP是Windows过滤平台的简称,它是一种Windows网络安全技术,可以用于实现流量过滤、访问控制、入侵检测等功能。WFP在网络堆栈的不同层中插入了一个或多个过滤器,以便检查和修改流量。当应用程序启动后,WFP就可以开始对其数据流量进行监控和拦截了。
WFP的流量监控主要涉及到以下几个步骤:
创建一个过滤器:使用FwpmFilterAdd0
函数创建一个过滤器,该过滤器可以指定待监控的端口、协议等。
注册回调函数:使用FwpsCalloutRegister0
函数注册回调函数,该回调函数将被WFP框架检查每个网络数据包时调用。
将回调函数绑定到协议层:使用FwpsFilterAdd0
函数将回调函数绑定到协议层,以便每个协议层都能够监控和拦截其数据流量。
下面是WFP流量监控的示例代码:
#include <ntddk.h>
#include <wdf.h>
#include <fwpsk.h>
#include <fwpmk.h>
// 定义回调函数
const FWPS_CALLOUT0 Callout = {
NULL, // calloutKey
0, // flags
NULL, // providerContext
NULL // reserved
};
// 回调函数实现
void DataRecvCallback(
UINT16 layerId,
UINT32 calloutId,
const void* packet,
const FWP_PACKET0* packetInfo,
void* context,
UINT64* verdict
) {
// 在这里对数据包进行监控和拦截
}
// WDF驱动入口函数
void DriverEntry(
IN OUT PDRIVER_OBJECT DriverObj,
IN PUNICODE_STRING RegistryPath
) {
// 创建一个过滤器
FWPM_FILTER0 Filter = { 0 };
FWPM_FILTER_CONDITION0 FilterCondition = { 0 };
GUID ProviderGuid = { 0 };
RtlZeroMemory(&Filter, sizeof(FWPM_FILTER0));
Filter.providerKey = &ProviderGuid;
Filter.displayData.name = L"Sample Filter";
Filter.displayData.description = L"Sample filter to monitor and intercept network traffic";
Filter.action.type = FWP_ACTION_CALLOUT_TERMINATING;
Filter.action.calloutKey = (UINT64)&Callout;
Filter.action.filterType = FWP_FILTER_TYPE_TRANSPORT;
FilterCondition.fieldKey = FWPM_CONDITION_IP_LOCAL_PORT;
FilterCondition.matchType = FWP_MATCH_EQUAL;
FilterCondition.conditionValue.type = FWP_UINT16;
FilterCondition.conditionValue.uint16 = 80;
Filter.filterCondition = &FilterCondition;
Filter.numFilterConditions = 1;
// 使用FwpmFilterAdd0函数添加过滤器
FwpmFilterAdd0(g_EngineHandle, &Filter, NULL, NULL);
// 注册回调函数
FwpsCalloutRegister0(
L"Sample Callout",
(FWPS_CALLOUT_CLASSIFY_FN0)DataRecvCallback,
NULL,
&Callout.calloutKey
);
// 将回调函数绑定到协议层,这里绑定到TCP层
FWPM_CALLOUT CalloutRegistration = { 0 };
FWPM_DISPLAY_DATA DisplayData = { 0 };
GUID CalloutGuid = { 0 };
RtlZeroMemory(&CalloutRegistration, sizeof(FWPM_CALLOUT));
RtlZeroMemory(&DisplayData, sizeof(FWPM_DISPLAY_DATA));
RtlCopyMemory(&CalloutRegistration.calloutKey, &Callout.calloutKey, sizeof(UINT64));
CalloutRegistration.displayData.name = L"Sample Callout";
CalloutRegistration.displayData.description = L"Sample callout for monitoring and intercepting network traffic";
CalloutRegistration.applicableLayer = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
CalloutRegistration.flags = 0;
CalloutRegistration.calloutClassifyFn = (FWPS_CALLOUT_CLASSIFY_FN0)DataRecvCallback;
FwpmCalloutAdd0(g_EngineHandle, &CalloutRegistration, NULL, &CalloutGuid);
FwpmFilterAdd0(g_EngineHandle, &Filter, NULL, NULL);
DbgPrint("WFP sample driver loaded successfully\n");
}
// 注销WDF驱动函数
void DriverUnload(
IN PDRIVER_OBJECT DriverObj
) {
// 删除过滤器和回调函数
FwpmFilterDeleteByKey0(g_EngineHandle, &Filter.providerKey, 0);
FwpsCalloutUnregisterByKey0(L"Sample Callout", &Callout.calloutKey);
FwpmCalloutDeleteByKey0(g_EngineHandle, &Callout.calloutKey);
DbgPrint("WFP sample driver unloaded successfully\n");
}
希望以上代码示例可以对你有所帮助。
如果我的回答解决了您的问题,请采纳!
参考chatGPT的回答内容,关于第一点,停止驱动和卸载驱动是两个不同的操作。停止驱动是指停止驱动程序运行,而不是将驱动程序从操作系统中卸载。停止驱动的操作通常是由服务控制管理器或其他应用程序触发的,以便在系统运行时停止或重新启动驱动程序。而卸载驱动则是将驱动程序从操作系统中移除,这通常是由用户或管理员手动执行的操作。
当停止驱动时,Windows操作系统会通知驱动程序调用其DriverUnload函数。DriverUnload函数是一个可选的函数,驱动程序可以在其中释放资源并执行清理操作。因此,当停止驱动时,驱动程序会执行DriverUnload函数来进行清理操作。
关于第二点,如果流量已经通过了WFP的过滤层,那么WFP就无法监测到该流量。在WFP中,可以通过在Alepht层注册回调函数来监测网络流量。在注册回调函数时,可以指定要监测的网络层,例如IP层或TCP层。如果流量经过了指定的网络层,那么WFP就会调用注册的回调函数来处理该流量。因此,如果在启动驱动程序之后,WFP注册的回调函数无法处理特定网络层的流量,那么WFP就无法监测到该流量。
该回答引用GPTᴼᴾᴱᴺᴬᴵ
关于WDF驱动和WFP驱动的问题:
停止驱动和卸载驱动的差别:
停止驱动是将驱动暂停或者卸载之前执行一些操作,比如清理内存等。而卸载驱动是将驱动完全从系统中移除。在驱动卸载的过程中,会执行DriverUnload函数来释放驱动使用的资源。
关于WFP做流量监控:
WFP(Windows Filtering Platform)提供了对网络数据包的深度过滤和修改能力,所以可以用来实现网络流量的监控。在WFP中,可以使用WFP层级提供的API来绑定进程或线程,从而实现流量监控。具体来说,可以在流量的Eatablish层中将PID与WFP的过滤条件绑定起来,这样就可以监控特定进程或线程的流量。但是,如果流量已经通过了这一层,那么就无法进行流量监控了。所以,要确保绑定的层级能够涵盖所有需要监控的流量。
停止驱动和卸载驱动是不同的概念,因为停止驱动只是暂时性地禁止驱动程序的执行,而不会从系统中删除驱动程序。而卸载驱动是从系统中完全删除驱动程序。
当停止驱动时,系统会调用DriverUnload函数,这是因为驱动已经被卸载了,所以需要执行清理操作。而停止服务不需要执行这个清理操作。
关于WFP做关于流量监控方面,通常情况下在驱动启动后就已经开始监控了。WFP可以在不同层进行数据包过滤和处理,例如在网络层、传输层或应用层。在实现流量监控时,可以在eatablish层中通过绑定PID来实现对应用程序的流量监控。所以在驱动启动时,已经对数据包进行了过滤和处理操作,因此可以实现流量监控。