仅在现代 Windows NT 系统上,我能否在运行时确定句柄是指套接字句柄还是对象句柄?
On modern Windows NT systems only, can I determine at runtime whether a handle refers to a socket or an object handle?
我完全知道,在过去 Windows 套接字仅作为第三方用户模式 DLL 实现,套接字和对象句柄是不相关的。然而,在现代 Windows NT 系统上,套接字是完整的内核对象,尽管也有一些用户模式状态。
遗憾的是,该特定查询没有单个 API。您必须直接访问 NT 对象管理器并在其已知句柄列表中找到所需的句柄,然后您可以检索句柄的对象类型(以及其他内容)。
Pushing the Limits of Windows: Handles
WinObj: The ultimate Object Manager namespace viewer
更新:我忘了NtQueryObject()。您可以查询 HANDLE
的 ObjectTypeInformation
class,其中 returns 一个 PUBLIC_OBJECT_TYPE_INFORMATION
结构:
typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION {
UNICODE_STRING TypeName;
ULONG Reserved [22]; // reserved for internal use
} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;
例如:
std::wstring GetHandleTypeName(HANDLE hHandle)
{
typedef NTSTATUS (NTAPI *NtQueryObjectPtr)(
HANDLE Handle,
OBJECT_INFORMATION_CLASS ObjectInformationClass,
PVOID ObjectInformation,
ULONG ObjectInformationLength,
PULONG ReturnLength);
HMODULE hMod = LoadLibrary(_T("NtDll.dll"));
NtQueryObjectPtr QueryObj = (NtQueryObjectPtr) ::GetProcAddress(hMod, "NtQueryObject");
ASSERT(QueryObj);
ULONG OutSize = 0;
NTSTATUS NtStatus = QueryObj(hHandle, ObjectTypeInformation, NULL, 0, &OutSize);
std::vector<BYTE> buffer(OutSize);
PPUBLIC_OBJECT_TYPE_INFORMATION TypeInfo = (PPUBLIC_OBJECT_TYPE_INFORMATION) &buffer[0];
ULONG InSize = OutSize;
NtStatus = QueryObj(hHandle, ObjectTypeInformation, TypeInfo, InSize, &OutSize);
return std::wstring(TypeInfo->TypeName.Buffer, TypeInfo->TypeName.Length);
}
std::wstring cs = GetHandleTypeName((HANDLE)TheDesiredSocket);
MessageBoxW(cs.c_str());
有关将 NtQueryObject()
与套接字一起使用的更多信息,请参阅这些内容:
C++ Get Handle of Open Sockets of a Program
我完全知道,在过去 Windows 套接字仅作为第三方用户模式 DLL 实现,套接字和对象句柄是不相关的。然而,在现代 Windows NT 系统上,套接字是完整的内核对象,尽管也有一些用户模式状态。
遗憾的是,该特定查询没有单个 API。您必须直接访问 NT 对象管理器并在其已知句柄列表中找到所需的句柄,然后您可以检索句柄的对象类型(以及其他内容)。
Pushing the Limits of Windows: Handles
WinObj: The ultimate Object Manager namespace viewer
更新:我忘了NtQueryObject()。您可以查询 HANDLE
的 ObjectTypeInformation
class,其中 returns 一个 PUBLIC_OBJECT_TYPE_INFORMATION
结构:
typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION {
UNICODE_STRING TypeName;
ULONG Reserved [22]; // reserved for internal use
} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;
例如:
std::wstring GetHandleTypeName(HANDLE hHandle)
{
typedef NTSTATUS (NTAPI *NtQueryObjectPtr)(
HANDLE Handle,
OBJECT_INFORMATION_CLASS ObjectInformationClass,
PVOID ObjectInformation,
ULONG ObjectInformationLength,
PULONG ReturnLength);
HMODULE hMod = LoadLibrary(_T("NtDll.dll"));
NtQueryObjectPtr QueryObj = (NtQueryObjectPtr) ::GetProcAddress(hMod, "NtQueryObject");
ASSERT(QueryObj);
ULONG OutSize = 0;
NTSTATUS NtStatus = QueryObj(hHandle, ObjectTypeInformation, NULL, 0, &OutSize);
std::vector<BYTE> buffer(OutSize);
PPUBLIC_OBJECT_TYPE_INFORMATION TypeInfo = (PPUBLIC_OBJECT_TYPE_INFORMATION) &buffer[0];
ULONG InSize = OutSize;
NtStatus = QueryObj(hHandle, ObjectTypeInformation, TypeInfo, InSize, &OutSize);
return std::wstring(TypeInfo->TypeName.Buffer, TypeInfo->TypeName.Length);
}
std::wstring cs = GetHandleTypeName((HANDLE)TheDesiredSocket);
MessageBoxW(cs.c_str());
有关将 NtQueryObject()
与套接字一起使用的更多信息,请参阅这些内容:
C++ Get Handle of Open Sockets of a Program