Windows驱动程序中遍历系统中运行的进程信息完整代码

闲来无事,随手写了一个在驱动程序中遍历系统中运行的进程信息代码,欢迎大家交流指导(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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

danxuezx

如果对你有用是我的快乐

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值