闲来无事,随手写了一个在驱动程序中遍历系统中运行的进程信息代码,欢迎大家交流指导(zhxunCC)。代码在win11上跑了几次,可正常运行。
#include <ntddk.h>
#include <wdm.h>
#include <ntstrsafe.h>
// 1. 声明SYSTEM_INFORMATION_CLASS枚举
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemProcessInformation = 5
} SYSTEM_INFORMATION_CLASS;
// 2. 声明NtQuerySystemInformation函数原型
extern "C" NTSTATUS NTAPI NtQuerySystemInformation(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_Out_writes_bytes_to_opt_(SystemInformationLength, *ReturnLength) PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
);
// 3. 进程信息结构体(需与内核实际结构一致)
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER WorkingSetPrivateSize;
ULONG HardFaultCount;
ULONG Reserved1;
ULONGLONG CycleTime;
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
ULONG BasePriority;
HANDLE ProcessId;
HANDLE ParentProcessId;
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
// 4. 日志写入函数
NTSTATUS WriteProcessLog(PSYSTEM_PROCESS_INFORMATION pEntry) {
NTSTATUS status;
HANDLE fileHandle = NULL;
IO_STATUS_BLOCK ioStatusBlock;
UNICODE_STRING fileName;
OBJECT_ATTRIBUTES objAttr;
// 初始化文件路径
RtlInitUnicodeString(&fileName, L"\\??\\C:\\ProcessLog.txt");
InitializeObjectAttributes(
&objAttr,
&fileName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL
);
// 打开或创建日志文件(追加模式)
status = ZwCreateFile(
&fileHandle,
FILE_APPEND_DATA,
&objAttr,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
if (!NT_SUCCESS(status)) {
KdPrint(("ZwCreateFile failed: 0x%X\n", status));
return status;
}
// 准备进程名称缓冲区
WCHAR nameBuffer[256] = { 0 };
USHORT copySize = min(pEntry->ImageName.Length, sizeof(nameBuffer) - sizeof(WCHAR));
if (copySize > 0) {
RtlCopyMemory(nameBuffer, pEntry->ImageName.Buffer, copySize);
nameBuffer[copySize / sizeof(WCHAR)] = L'\0';
}
// 格式化日志内容
WCHAR logBuffer[512];
status = RtlStringCbPrintfW(
logBuffer,
sizeof(logBuffer),
L"PID: 0x%p\tParent PID: 0x%p\tName: %s\r\n",
pEntry->ProcessId,
pEntry->ParentProcessId,
nameBuffer
);
if (NT_SUCCESS(status)) {
size_t logLength;
RtlStringCbLengthW(logBuffer, sizeof(logBuffer), &logLength);
// 写入文件
status = ZwWriteFile(
fileHandle,
NULL,
NULL,
NULL,
&ioStatusBlock,
logBuffer,
(ULONG)logLength,
NULL,
NULL
);
if (!NT_SUCCESS(status)) {
KdPrint(("ZwWriteFile failed: 0x%X\n", status));
}
}
// 清理资源
if (fileHandle) {
ZwClose(fileHandle);
}
return status;
}
// 5. 驱动入口函数
extern "C"
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
UNREFERENCED_PARAMETER(DriverObject);
UNREFERENCED_PARAMETER(RegistryPath);
NTSTATUS status;
ULONG returnLength = 0;
PVOID processInfo = NULL;
// 第一次调用获取所需内存大小
status = NtQuerySystemInformation(
SystemProcessInformation,
NULL,
0,
&returnLength
);
if (status != STATUS_INFO_LENGTH_MISMATCH) {
KdPrint(("First NtQuerySystemInformation failed: 0x%X\n", status));
return status;
}
// 分配非分页内存
processInfo = ExAllocatePool2(
POOL_FLAG_NON_PAGED,
returnLength,
'TAG1'
);
if (!processInfo) {
KdPrint(("Memory allocation failed\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
// 第二次调用获取进程信息
status = NtQuerySystemInformation(
SystemProcessInformation,
processInfo,
returnLength,
&returnLength
);
if (!NT_SUCCESS(status)) {
KdPrint(("Second NtQuerySystemInformation failed: 0x%X\n", status));
ExFreePool(processInfo);
return status;
}
// 遍历进程列表
PSYSTEM_PROCESS_INFORMATION pEntry = (PSYSTEM_PROCESS_INFORMATION)processInfo;
do {
KdPrint(("Processing PID: 0x%p\n", pEntry->ProcessId));
// 写入日志文件
NTSTATUS writeStatus = WriteProcessLog(pEntry);
if (!NT_SUCCESS(writeStatus)) {
KdPrint(("Write log failed for PID 0x%p: 0x%X\n",
pEntry->ProcessId, writeStatus));
}
// 移动到下一个条目
if (pEntry->NextEntryOffset == 0) break;
pEntry = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)pEntry + pEntry->NextEntryOffset);
} while (TRUE);
// 清理资源
if (processInfo) {
ExFreePool(processInfo);
}
KdPrint(("DriverEntry completed successfully\n"));
return STATUS_SUCCESS;
}



3549

被折叠的 条评论
为什么被折叠?



