NtQuerySystemInformation 未获取某些进程

问题描述 投票:0回答:1

我一直在使用

NtQuerySystemInformation
中的
winternl.h
函数来查找系统中的一些互斥体。我正在使用以下结构来通过该函数检索信息。

#pragma pack(1)
typedef struct __SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
    DWORD   UniqueProcessId;
    UCHAR   ObjectTypeIndex;
    UCHAR   HandleAttributes;
    USHORT  HandleValue;
    PVOID   Object;
    ULONG   GrantedAccess;
}   SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
#pragma pack()

#pragma pack(1)
typedef struct __SYSTEM_HANDLE_INFORMATION
{
    ULONG                           NumberOfHandles;
    SYSTEM_HANDLE_TABLE_ENTRY_INFO  Handles[1];
}   SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
#pragma pack()

这是检索和过滤互斥体的代码。

Comman::Comman()
{
    PSYSTEM_HANDLE_INFORMATION pshi;
    NTSTATUS ret;
    ULONG ulRequired;

    pshi = (PSYSTEM_HANDLE_INFORMATION)VirtualAlloc(NULL, SYSTEM_HANDLE_INFORMATION_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    ret = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)0x10, pshi, SYSTEM_HANDLE_INFORMATION_SIZE, &ulRequired);

    if (pshi && !NT_SUCCESS(ret))
    {
        VirtualFree(pshi, 0, MEM_RELEASE);
        pshi = (PSYSTEM_HANDLE_INFORMATION)VirtualAlloc(NULL, ulRequired + 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        ret = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)0x10, pshi, ulRequired + 4096, &ulRequired);

        if (!NT_SUCCESS(ret))
            throw ret;
    }

    InitializeMutexVector(pshi);
}

//...

void Comman::InitializeMutexVector(PSYSTEM_HANDLE_INFORMATION pshi)
{
    int i;
    PUBLIC_OBJECT_TYPE_INFORMATION oti;
    PPUBLIC_OBJECT_TYPE_INFORMATION poti;
    NTSTATUS ret;
    ULONG required;

    for (i = 0, required = 0, poti = NULL; i < pshi->NumberOfHandles; i++, required = 0, poti = NULL)
    {
        ret = NtQueryObject((PVOID)pshi->Handles[i].HandleValue, ObjectTypeInformation, &oti, sizeof(oti), &required);
        if (ret == 0xC0000004)
        {
            poti = (PPUBLIC_OBJECT_TYPE_INFORMATION)VirtualAlloc(NULL, required + 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
            ret = NtQueryObject((PVOID)pshi->Handles[i].HandleValue, ObjectTypeInformation, poti, required + 1024, &required);
            if (poti)
                oti = *poti;
        }
        if (DEBUG && NT_SUCCESS(ret) && poti)
            std::wcout << pshi->Handles[i].UniqueProcessId << ", " << oti.TypeName.Buffer << '\n';
        if (NT_SUCCESS(ret) && poti && !wcscmp(L"Mutant", oti.TypeName.Buffer))
            mutexes.push_back(pshi->Handles[i]);
        if (poti)
            VirtualFree(poti, 0, MEM_RELEASE);
    }
}

我将结果打印为“PID,object_type_name”的格式,并制作了一个

.csv
文件,并用Microsoft Excel打开它。不幸的是,当我运行一个创建两个互斥体并故意导致死锁的测试程序时,
NtQuerySystemInformation
函数没有从测试程序中获取任何资源。

我在下面附上了测试程序的代码,供可能需要的人使用。

#include <Windows.h>
#include <stdio.h>

HANDLE R1, R2, sync;

DWORD WINAPI ThreadProc(LPVOID param)
{
    wprintf(L"[THRD] Acquiring R2.\n");
    WaitForSingleObject(R2, INFINITE);

    Sleep(2000);

    wprintf(L"[THRD] Acquiring R1.\n");
    WaitForSingleObject(R1, INFINITE);
}

int wmain(void)
{
    HANDLE hThread;
    DWORD dwThreadID;

    wprintf(L"PID: %d\n", GetCurrentProcessId());

    R1 = CreateMutexW(NULL, FALSE, L"name");
    R2 = CreateMutexW(NULL, FALSE, L"name2");
    if (!R1 || !R2)
    {
        wprintf(L"Mutex creation has failed.\n");
        return -1;
    }

    hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, &dwThreadID);
    if (!hThread)
    {
        wprintf(L"Thread creation has failed.\n");
        return -1;
    }

    wprintf(L"[MAIN] Acquiring R1.\n");
    WaitForSingleObject(R1, INFINITE);

    Sleep(1000);

    wprintf(L"[MAIN] Acquiring R2.\n");
    WaitForSingleObject(R2, INFINITE);

    wprintf(L"[MAIN] Releasing R1.\n");
    ReleaseMutex(R1);

    return 0;
}

提前感谢您,如果需要,我将非常乐意提供更多资源。

c windows winapi
1个回答
0
投票
  • #pragma pack(1)
    - 这不能出现在结构声明中。
  • 使用
    SystemExtendedHandleInformation
    代替
    SystemHandleInformation
  • 始终在循环中进行查询并检查
    STATUS_INFO_LENGTH_MISMATCH
  • 不查询所有句柄。仅查询突变类型。
  • HandleValue
    是在另一个进程的上下文中,您首先需要 在查询之前将其复制到您的流程中

void DumpMutexs()
{
    if (HANDLE hMutant = CreateMutexExW(0, 0, 0, 0))
    {
        union {
            PVOID buf;
            PBYTE pb;
            POBJECT_NAME_INFORMATION poni;
        };

        ULONG cb = 0x10000;
        NTSTATUS status;

        enum { cbNameInfo = 0x10000 };
        do 
        {
            status = STATUS_NO_MEMORY;

            if (buf = LocalAlloc(LMEM_FIXED, cbNameInfo + (cb += 0x1000)))
            {
                SYSTEM_HANDLE_INFORMATION_EX* phei = (SYSTEM_HANDLE_INFORMATION_EX*)(pb + cbNameInfo);

                if (0 <= (status = NtQuerySystemInformation(SystemExtendedHandleInformation, phei, cb, &cb)))
                {
                    if (ULONG_PTR NumberOfHandles = phei->NumberOfHandles)
                    {

                        PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles = phei->Handles;
                        ULONG dwProcessId = GetCurrentProcessId();
                        do 
                        {
                            if (Handles->UniqueProcessId == dwProcessId &&
                                Handles->HandleValue == (ULONG_PTR)hMutant)
                            {
                                USHORT ObjectTypeIndex = Handles->ObjectTypeIndex;
                                NumberOfHandles = phei->NumberOfHandles;
                                Handles = phei->Handles;

                                HANDLE hProcess = 0;
                                ULONG_PTR UniqueProcessId = 0;

                                do 
                                {
                                    if (ObjectTypeIndex == Handles->ObjectTypeIndex)
                                    {
                                        if (Handles->UniqueProcessId != UniqueProcessId)
                                        {
                                            UniqueProcessId = Handles->UniqueProcessId;

                                            if (hProcess)
                                            {
                                                NtClose(hProcess);
                                                hProcess = 0;
                                            }

                                            hProcess = dwProcessId == UniqueProcessId ? 0 :
                                                OpenProcess(PROCESS_DUP_HANDLE, FALSE, (ULONG)UniqueProcessId);
                                        }

                                        if (hProcess)
                                        {
                                            HANDLE hMutex;
                                            if (DuplicateHandle(hProcess, (HANDLE)Handles->HandleValue, 
                                                NtCurrentProcess(), &hMutex, 0, 0, DUPLICATE_SAME_ACCESS))
                                            {
                                                if (0 <= NtQueryObject(hMutex, ObjectNameInformation, poni, cbNameInfo, &cb))
                                                {
                                                    if (poni->Name.Length)
                                                    {
                                                        DbgPrint("%p:%p %wZ\n", UniqueProcessId, Handles->HandleValue, &poni->Name);
                                                    }
                                                }
                                                else
                                                {
                                                    __nop();
                                                }
                                                
                                                NtClose(hMutex);
                                            }
                                            else
                                            {
                                                DbgPrint("dup(%p)=%x\n", Handles->HandleValue, RtlGetLastNtStatus());
                                            }
                                        }
                                    }
                                } while (Handles++, --NumberOfHandles);

                                if (hProcess)
                                {
                                    NtClose(hProcess);
                                    hProcess = 0;
                                }

                                break;
                            }
                        } while (Handles++, --NumberOfHandles);
                    }
                }

                LocalFree(buf);
            }

        } while (STATUS_INFO_LENGTH_MISMATCH == status);

        NtClose(hMutant);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.