获取文件句柄的基本信息
有时候我们想得到文件句柄的一些信息, 比如这个句柄的引用计数, 属性等等的. 我就写了下面的函数.
声明的头文件:
typedef LONG NTSTATUS;
typedef struct _OBJECT_BASIC_INFORMATION
{
ULONG Attributes;
ACCESS_MASK GrantedAccess;
ULONG HandleCount;
ULONG PointerCount;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG Reserved[3];
ULONG NameInfoSize;
ULONG TypeInfoSize;
ULONG SecurityDescriptorSize;
LARGE_INTEGER CreationTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
NTSTATUS WINAPI _GetHandleInformation
(
HANDLE ProcessHandle,
HANDLE Handle,
POBJECT_BASIC_INFORMATION BasicInformation
);
以下是实现文件:
#include <windows.h>
#include <tchar.h>
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define __out_bcount_opt(x)
#define __in
#define __in_opt
#define __out_opt
typedef enum _OBJECT_INFORMATION_CLASS
{
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectTypesInformation,
ObjectHandleFlagInformation,
ObjectSessionInformation,
MaxObjectInfoClass,
} OBJECT_INFORMATION_CLASS;
typedef NTSTATUS (WINAPI * PFN_NtQueryObject)
(
__in HANDLE Handle,
__in OBJECT_INFORMATION_CLASS ObjectInformationClass,
__out_bcount_opt(ObjectInformationLength) PVOID ObjectInformation,
__in ULONG ObjectInformationLength,
__out_opt PULONG ReturnLength
);
typedef NTSTATUS (WINAPI * PFN_NtClose) ( __in HANDLE Handle );
typedef NTSTATUS (WINAPI * PFN_NtDuplicateObject)
(
__in HANDLE SourceProcessHandle,
__in HANDLE SourceHandle,
__in_opt HANDLE TargetProcessHandle,
__out_opt PHANDLE TargetHandle,
__in ACCESS_MASK DesiredAccess,
__in ULONG HandleAttributes,
__in ULONG Options
);
#define NtCurrentProcess() ( (HANDLE) -1 )
#define NtCurrentThread() ( (HANDLE) -2 )
NTSTATUS WINAPI _GetHandleInformation
(
__in HANDLE ProcessHandle,
__in HANDLE Handle,
__out_opt POBJECT_BASIC_INFORMATION BasicInformation
)
{
HMODULE hNtDll = NULL;
BOOL bDup = FALSE;
NTSTATUS status;
HANDLE dupHandle = NULL;
PFN_NtDuplicateObject pfn_NtDuplicateObject = NULL;
PFN_NtQueryObject pfn_NtQueryObject = NULL;
PFN_NtClose pfn_NtClose = NULL;
if (Handle == NULL || Handle == NtCurrentProcess() ||
Handle == NtCurrentThread())
{
return STATUS_INVALID_HANDLE;
}
hNtDll = GetModuleHandle(_T("ntdll.dll"));
if (NULL == hNtDll) {
return STATUS_INVALID_HANDLE;
}
pfn_NtDuplicateObject = (PFN_NtDuplicateObject)
GetProcAddress(hNtDll, "NtDuplicateObject");
pfn_NtQueryObject = (PFN_NtQueryObject)
GetProcAddress(hNtDll, "NtQueryObject");
pfn_NtClose = (PFN_NtClose) GetProcAddress(hNtDll, "NtClose");
if (NULL == pfn_NtQueryObject) {
return STATUS_INVALID_HANDLE;
}
// Duplicate the handle if we're not using KPH.
// However, we obviously don't need to duplicate it
// if the handle is in the current process.
if (ProcessHandle != NtCurrentProcess())
{
status = pfn_NtDuplicateObject(ProcessHandle, Handle,
NtCurrentProcess(), &dupHandle, 0, 0, 0);
if (!NT_SUCCESS(status))
return status;
bDup = TRUE;
}
else
{
dupHandle = Handle;
}
// Get basic information.
if (BasicInformation)
{
status = pfn_NtQueryObject(
dupHandle,
ObjectBasicInformation,
BasicInformation,
sizeof(OBJECT_BASIC_INFORMATION),
NULL
);
if (NT_SUCCESS(status))
{
// The object was referenced in NtQueryObject and
// a handle was opened to the object. We need to
// subtract 1 from the pointer count, then subtract
// 1 from both counts.
BasicInformation->PointerCount -= 1;
if (bDup)
{
BasicInformation->HandleCount -= 1;
BasicInformation->PointerCount -= 1;
}
}
}
if (bDup) {
pfn_NtClose(dupHandle);
}
return status;
}

近期评论