#include<ntifs.h>
LIST_ENTRY g_Head = { 0 };
KSPIN_LOCK g_SpinLock;
typedef struct _ProcessSnapeNode
{
LIST_ENTRY ListEntry;
ULONG PID;
}ProcessSnapeNode, *PProcessSnapeNode;
VOID PrintAllNode()
{
if (IsListEmpty(&g_Head))
{
DbgPrint("链表已经为空了!\n");
}
KIRQL OldIrql;
KeAcquireSpinLock(&g_SpinLock, &OldIrql);
PLIST_ENTRY pTmpList = g_Head.Flink;
while (pTmpList != &g_Head)
{
ProcessSnapeNode* pProc = CONTAINING_RECORD(pTmpList, ProcessSnapeNode, ListEntry);
DbgPrint("[Print All]Node:%llx PID:%d\n", pProc, pProc->PID);
pTmpList = pTmpList->Flink;
}
KeReleaseSpinLock(&g_SpinLock, OldIrql);
}
VOID DeleteProcByID(ULONG TargetPID)
{
if (IsListEmpty(&g_Head))
{
DbgPrint("链表已经为空了!\n");
}
// 枷锁
KIRQL OldIrql;
KeAcquireSpinLock(&g_SpinLock, &OldIrql);
PLIST_ENTRY pTmpList = g_Head.Flink;
while (pTmpList != &g_Head)
{
// 发现目标节点,从列表中删除
ProcessSnapeNode* pProc = CONTAINING_RECORD(pTmpList, ProcessSnapeNode, ListEntry);
if (pProc->PID == TargetPID)
{
DbgPrint("[Delete] Node:%llx PID:%d\n", pProc, pProc->PID);
RemoveEntryList(pTmpList);
pTmpList = pTmpList->Flink;
ExFreePool(pProc);
continue;
}
pTmpList = pTmpList->Flink;
}
KeReleaseSpinLock(&g_SpinLock, OldIrql);
}
VOID DeleteAll()
{
// 遍历,清空所有List节点
KIRQL OldIrql;
KeAcquireSpinLock(&g_SpinLock, &OldIrql);
while (!IsListEmpty(&g_Head))
{
// 删除末尾的节点,返回删除结构中的ListEntry位置
PLIST_ENTRY pEntry = RemoveTailList(&g_Head);
ProcessSnapeNode* pProc = CONTAINING_RECORD(pEntry, ProcessSnapeNode, ListEntry);
DbgPrint("[Delete ALL]Node:%llx PID:%d\n", pProc, pProc->PID);
ExFreePool(pProc);
}
KeReleaseSpinLock(&g_SpinLock, OldIrql);
}
void PcreateProcessNotifyRoutine(HANDLE ParentId,HANDLE ProcessId,BOOLEAN Create)
{
if (Create)
{
ProcessSnapeNode* ProcNode = (PProcessSnapeNode)ExAllocatePoolWithTag(NonPagedPool, sizeof(ProcessSnapeNode), 'tag1');
ProcNode->PID = ProcessId;
DbgPrint("[Insert] Node:%llx PID=%d\n", ProcNode, ProcessId);
ExInterlockedInsertHeadList(&g_Head, &ProcNode->ListEntry, &g_SpinLock);
}
else
{
DeleteProcByID(ProcessId);
PrintAllNode();
}
}
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
PsSetCreateProcessNotifyRoutine(PcreateProcessNotifyRoutine, TRUE);
DeleteAll();
DbgPrint("Driver Unload!\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
KdBreakPoint();
DbgPrint("[%p]Driver Entry! Driver ResistryPath:%ws\n", DriverObject, RegistryPath->Buffer);
DriverObject->DriverUnload = DriverUnload;
// InitList
InitializeListHead(&g_Head);
KeInitializeSpinLock(&g_SpinLock);
// 创建进程通知
PsSetCreateProcessNotifyRoutine(PcreateProcessNotifyRoutine, FALSE);
return STATUS_SUCCESS;
}
使用LIST_ENTRY维护一个进程链:插入、删除、遍历
于 2020-10-14 00:12:32 首次发布