简介
本项目主要为使用定时器做的示例,可以把DPC理解为是基于CPU核心的一个定时任务,下面通过使用DPC和定时器来演示在DISPATCH_LEVEL
与PASSIVE_LEVEL
分别如何创建定时循环任务。
代码
#include <ntifs.h>
PKDPC kdpc = NULL;
PKDPC kTimer = NULL;
HANDLE hTimer = NULL;
VOID workDpc2(
_In_ struct _KDPC *Dpc,
_In_opt_ PVOID DeferredContext,
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2
)
{
static int count = 0;
DbgPrintEx(77, 0, "[xxxx] %d\r\n", ++count);
KeInitializeTimer(kTimer);
LARGE_INTEGER inTime = { 0 };
inTime.QuadPart = -10000 * 1000;
KeSetTimer(kTimer, inTime, kdpc);
}
VOID workDpc1(
_In_ struct _KDPC *Dpc,
_In_opt_ PVOID DeferredContext,
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2
)
{
static int count = 0;
DbgPrintEx(77, 0, "[xxxx] 2 irql = %d,count=%d ,number = %d\r\n", KeGetCurrentIrql(), ++count,KeGetCurrentProcessorNumber());
//清空DPC内存
//ExFreePool(Dpc);
}
//
VOID apcTimer(
_In_ PVOID TimerContext,
_In_ ULONG TimerLowValue,
_In_ LONG TimerHighValue
)
{
static int count = 0;
DbgPrintEx(77, 0, "[xxxx] 3 irql = %d,count=%d \r\n", KeGetCurrentIrql(), ++count);
}
VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
if (hTimer)
{
ZwCancelTimer(hTimer, NULL);
}
/*
//实验二需要的代码
KeCancelTimer(kTimer);
ExFreePool(kTimer);
ExFreePool(kdpc);
*/
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
LARGE_INTEGER inTime = { 0 };
inTime.QuadPart = -10000 * 10000;
kdpc = ExAllocatePool(NonPagedPool, sizeof(KDPC));
KeInitializeDpc(kdpc, workDpc1, NULL);
/*
//实验一:指定在特定核运行DPC
KeSetTargetProcessorDpc(kdpc, 1);
KeInsertQueueDpc(kdpc, NULL, NULL);
*/
/*
//实验二:使用内核时钟定时器
kTimer = ExAllocatePool(NonPagedPool, sizeof(KTIMER));
//KeInitializeTimer(kTimer);
//KeSetTimer(kTimer, inTime, kdpc);
//使用扩展内核时钟定时器,使用workDpc1即可实现循环功能
KeInitializeTimerEx(kTimer, SynchronizationTimer);
//运行在DISPATCH_LEVEL等级
KeSetTimerEx(kTimer, inTime, 1000, kdpc);
*/
//实验三:使用应用层时钟定时器,运行在PASSIVE_LEVEL等级
NTSTATUS status = ZwCreateTimer(&hTimer, PROCESS_ALL_ACCESS, NULL, SynchronizationTimer);
if (NT_SUCCESS(status))
{
ZwSetTimer(hTimer, &inTime, apcTimer, NULL, FALSE, 1000, NULL);
}
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
参考资料
火哥五期