Quantcast
Channel: プログラミング
Viewing all articles
Browse latest Browse all 7991

C++&Win API NtQuerySystemInformation関数とSystemExtendedHandleInformation (0x40)でカーネルオブジェクトハンドルの一覧取得 - potisanのプログラミングメモ

$
0
0

公開された非公開関数NtQuerySystemInformationと非公開の定数SystemExtendedHandleInformation (0x40)を使うとカーネルオブジェクトハンドルの一覧を取得できます。固定長構造体のみなので前回投稿と比べれば遥かに扱いが楽です。なお、NtQuerySystemInformationSystemExtendedHandleInformationは非後方互換性が明記された関数と非公開定数の組み合わせです。今後のWindowsアップデート次第では使えなくなる可能性があります。

追記∶C++では一見正常に動作しましたが、C#へ移植したところ範囲外アクセスエラーが発生しました。NtQuerySystemInformationの2〜3回目の呼び出しの間にカーネルオブジェクトが増加したことが要因と思われます。適当なマージンを加えつつ、戻り値がメモリ不足情報(STATUS_INFO_LENGTH_MISMATCH)の場合は処理を繰り返しても良いかもしれません。

#include <bit>#include <vector>#include <ranges>#include <format>#include <iostream>#define STRICT#define NOMINMAX#include <Windows.h>#include <winternl.h>#pragma comment(lib, "ntdll.lib")// 参考// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/query.htmstaticconstauto SystemExtendedHandleInformation = (SYSTEM_INFORMATION_CLASS)0x40;

// 参考// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/handle_table_entry_ex.htm?tx=60&ts=0,313typedefstruct SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
{
    PVOID Object;
    ULONG_PTR UniqueProcessId;
    ULONG_PTR HandleValue;
    ULONG GrantedAccess;
    USHORT CreatorBackTraceIndex;
    USHORT ObjectTypeIndex;
    ULONG HandleAttributes;
    ULONG Reserved;
} *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;

// 参考// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/handle_ex.htm?tx=60typedefstruct SYSTEM_HANDLE_INFORMATION_EX
{
    ULONG_PTR NumberOfHandles;
    ULONG_PTR Reserved;
    SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];
} *PSYSTEM_HANDLE_INFORMATION_EX;

staticstd::vector<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> GetSystemHandleTableEntryInfosEx()
{
    // NtQuerySystemInformationはnullptrと0を渡すと56(64ビット環境)、// サイズ56のバッファーを渡すと実際に必要なサイズを返す。
    DWORD required;
    ::NtQuerySystemInformation(SystemExtendedHandleInformation, nullptr, 0, &required);

    std::vector<BYTE> buffer(required);
    ::NtQuerySystemInformation(SystemExtendedHandleInformation, buffer.data(), required, &required);

    buffer.resize(required);
    if (!NT_SUCCESS(::NtQuerySystemInformation(SystemExtendedHandleInformation, buffer.data(), required, nullptr)))
        throwstd::exception();

    auto pinfos = std::bit_cast<PSYSTEM_HANDLE_INFORMATION_EX>(buffer.data());
    returnstd::vector(pinfos->Handles, pinfos->Handles + pinfos->NumberOfHandles);
}

intwmain()
{
    auto entries = GetSystemHandleTableEntryInfosEx();
    for (constauto& [i, entry] : entries | std::views::take(1000) | std::views::enumerate)
    {
        std::wcout<< std::format(L"{}: {} ({})\n", i, entry.Object, entry.ObjectTypeIndex);
    }
    if (entries.size() > 1000)
        std::wcout<< L"...\n";

    return0;
}

参考


Viewing all articles
Browse latest Browse all 7991

Trending Articles