【问题标题】:Trying To Print Out All The Names Of The Processes And Their PID In Kernel Mode尝试在内核模式下打印出所有进程的名称及其 PID
【发布时间】:2021-09-15 15:53:26
【问题描述】:

我正在尝试打印所有进程的名称及其 PID。 但是当我打印 PID 时,它不会打印出来。

它确实打印了所有其他的东西,其他一切都在工作。

我认为问题在于我正在尝试将fileName 转换为wchar_t*

有人可以帮帮我吗?

int getPIDByName(wchar_t* name) {
    PEPROCESS ep;
    if (::PsLookupProcessByProcessId(::PsGetCurrentProcessId(), &ep) == STATUS_INVALID_PARAMETER) {
        ObDereferenceObject(ep);
        DbgPrint("Can't get EPROCESS");
        return STATUS_INVALID_PARAMETER;
    }

    PUNICODE_STRING Path = NULL;
    ::SeLocateProcessImageName(ep, &Path);
    PLIST_ENTRY Process_List_Entry = ((LIST_ENTRY*)((LPBYTE)ep + 0x448));
    PLIST_ENTRY List_Entry = Process_List_Entry->Flink;
    LPBYTE pUpi;
    DbgPrint("Starting with buffer path: %wZ", Path);
    while (Path->Buffer == NULL) {
        DbgPrint("The buffer is null so going forward to next process: %wZ", Path);
        pUpi = ((LPBYTE)List_Entry) - 0x448;
        ep = ((PEPROCESS)pUpi);
        ::SeLocateProcessImageName(ep, &Path);
        List_Entry = List_Entry->Flink;
    }

    DbgPrint("1.The path is: %wZ", Path);
    while (wcsstr(Path->Buffer, name) == NULL && Process_List_Entry != List_Entry->Flink) {
        pUpi = ((LPBYTE)List_Entry) - 0x448;
        ep = ((PEPROCESS)pUpi);
        ::SeLocateProcessImageName(ep, &Path);
        DbgPrint("2. The path is: %wZ", (const wchar_t*)Path);
        List_Entry = List_Entry->Flink;
    }
    if (Process_List_Entry == List_Entry->Flink) {
        DbgPrint("%wZ isn't running quiting!", name);
        return STATUS_SUCCESS;
    }
    pUpi = ((LPBYTE)List_Entry->Blink) - 0x448 + 0x440;
    int UniqueProcessId = *((int*)pUpi); //Notepad PID
    DbgPrint("The PID of %ls is %d\n", name, UniqueProcessId);
    return UniqueProcessId;
}


NTSTATUS PrintPID() {
    PEPROCESS EP;
    if (::PsLookupProcessByProcessId(::PsGetCurrentProcessId(), &EP) == STATUS_INVALID_PARAMETER) {
        ObDereferenceObject(EP);
        DbgPrint("Can't get EPROCESS");
        return STATUS_INVALID_PARAMETER;
    }
    UCHAR* fileName = { 0 };
    UCHAR* processFileName;

    LIST_ENTRY list_entry = *((LIST_ENTRY*)((LPBYTE)EP + 0x448));
    processFileName = ((UCHAR*)(LPBYTE)list_entry.Flink - 0x448 + 0x5a8);
    DbgPrint("%s", processFileName);
    list_entry = *list_entry.Flink;

    while (fileName != processFileName) {
        fileName = ((UCHAR*)(LPBYTE)list_entry.Flink - 0x448 + 0x5a8);
        if (fileName[0] == 'N' || fileName[0] == 'n') {
            DbgPrint("Test");
            DbgPrint("The PID is %d\n" , getPIDByName((wchar_t*)fileName));
        }
        list_entry = *list_entry.Flink;
    }
    return STATUS_SUCCESS;
}

【问题讨论】:

  • 你为什么使用这些低级 API,而不是像 CreateToolhelp32Snapshot()+Process32(First|Next)() 或至少 EnumProcesses()+OpenProcess()+QueryFullProcessImageName() 这样的高级 API?
  • “当我打印 PID 时,它不打印”是什么意思?你没有输出?您得到输出但不包含以“PID”开头的行?你得到那条线但没有号码?你得到了那行,它包含一个数字,但这个数字不是你所期望的?
  • 我正在使用较低级别的 API,因为我想练习。 “当我打印 PID 时,它不打印”意味着我得到了那行但没有数字。
  • 我不知道这些奇怪的魔法常量是怎么回事:0x448 + 0x5a8,但是fileName 实际上是用 UTF-16LE 格式化的吗?否则,转换为 wchar_t* 会产生不好的结果。

标签: c++ windows winapi kernel


【解决方案1】:

您可以使用 ZwQuerySystemInformation 来获取所有进程的列表。从该列表中,您可以获得所有名称和进程 ID。

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 2018-04-10
  • 2021-08-10
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-03
  • 1970-01-01
  • 2013-03-10
相关资源
最近更新 更多