1. 程式人生 > >Ring3句柄表的枚舉

Ring3句柄表的枚舉

msdn max trace lin ins buffer same rar release

由於windows並沒有給出枚舉所有句柄所用到的API,要獲得句柄,我們必須使用未公開的Native API才可以,使用如下函數:
NTSTATUS WINAPI NtQuerySystemInformation(
  _In_      SYSTEM_INFORMATION_CLASS SystemInformationClass,
  _Inout_   PVOID                    SystemInformation,
  _In_      ULONG                    SystemInformationLength,
  _Out_opt_ PULONG                   ReturnLength
);
枚舉的關鍵是使用NtQuerySystemInformation,註意它的第一項,是我們查詢枚舉信息所想要做的class集合,如下,我們在這裏使用的是 SystemHandleInformation(16),這很重要,

typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemBasicInformation,
    SystemProcessorInformation,             
    SystemPerformanceInformation,
    SystemTimeOfDayInformation,
    SystemPathInformation,
    SystemProcessInformation,
    SystemCallCountInformation,
    SystemDeviceInformation,
    SystemProcessorPerformanceInformation,
    SystemFlagsInformation,
    SystemCallTimeInformation,
    SystemModuleInformation,
    SystemLocksInformation,
    SystemStackTraceInformation,
    SystemPagedPoolInformation,
    SystemNonPagedPoolInformation,
    SystemHandleInformation,
    SystemObjectInformation,
    SystemPageFileInformation,
    SystemVdmInstemulInformation,
    SystemVdmBopInformation,
    SystemFileCacheInformation,
    SystemPoolTagInformation,
    SystemInterruptInformation,
    SystemDpcBehaviorInformation,
    SystemFullMemoryInformation,
    SystemLoadGdiDriverInformation,
    SystemUnloadGdiDriverInformation,
    SystemTimeAdjustmentInformation,
    SystemSummaryMemoryInformation,
    SystemMirrorMemoryInformation,
    SystemPerformanceTraceInformation,
    SystemObsolete0,
    SystemExceptionInformation,
    SystemCrashDumpStateInformation,
    SystemKernelDebuggerInformation,
    SystemContextSwitchInformation,
    SystemRegistryQuotaInformation,
    SystemExtendServiceTableInformation,
    SystemPrioritySeperation,
    SystemVerifierAddDriverInformation,
    SystemVerifierRemoveDriverInformation,
    SystemProcessorIdleInformation,
    SystemLegacyDriverInformation,
    SystemCurrentTimeZoneInformation,
    SystemLookasideInformation,
    SystemTimeSlipNotification,
    SystemSessionCreate,
    SystemSessionDetach,
    SystemSessionInformation,
    SystemRangeStartInformation,
    SystemVerifierInformation,
    SystemVerifierThunkExtend,
    SystemSessionProcessInformation,
    SystemLoadGdiDriverInSystemSpace,
    SystemNumaProcessorMap,
    SystemPrefetcherInformation,
    SystemExtendedProcessInformation,
    SystemRecommendedSharedDataAlignment,
    SystemComPlusPackage,
    SystemNumaAvailableMemory,
    SystemProcessorPowerInformation,
    SystemEmulationBasicInformation,
    SystemEmulationProcessorInformation,
    SystemExtendedHandleInformation,
    SystemLostDelayedWriteInformation,
    SystemBigPoolInformation,
    SystemSessionPoolTagInformation,
    SystemSessionMappedViewInformation,
    SystemHotpatchInformation,
    SystemObjectSecurityMode,
    SystemWatchdogTimerHandler,
    SystemWatchdogTimerInformation,
    SystemLogicalProcessorInformation,
    SystemWow64SharedInformation,
    SystemRegisterFirmwareTableInformationHandler,
    SystemFirmwareTableInformation,
    SystemModuleInformationEx,
    SystemVerifierTriageInformation,
    SystemSuperfetchInformation,
    SystemMemoryListInformation,
    SystemFileCacheInformationEx,
    MaxSystemInfoClass  // MaxSystemInfoClass should always be the last enum
} SYSTEM_INFORMATION_CLASS;
技術分享圖片 第17項(枚舉值16)的SystemHandleInformation,這就是我們想要的東西,通過這個值傳入NtQuerySystemInformation 然後我們利用ObjectTypeInformation ObjectNameInformation(下面是他們的結構體) 去枚舉對象類型和對象名字,這樣我們得到這三項做信息查詢枚舉,做小MFC可以知道句柄和對應的對象類型,對象名字,是一個很簡答的查閱工具

typedef enum OBJECT_INFORMATION_CLASS
{
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectTypesInformation,
ObjectHandleFlagInformation,
ObjectSessionInformation,
MaxObjectInfoClass
}OBJECT_INFORMATION_CLASS;

當然我們這裏為了在MFC顯示要有自己的數據結構去得到這些值,然後壓棧,顯示等,這是我的結構體:

typedef
struct _USER_DATA_
{
HANDLE HandleValue;
uint32_t GrantedAccess = 0;//要求
uint32_t Flags = 0;
ULONG64 ObjectValue;

std::wstring ObjectTypeName;//類型
std::wstring ObjectName;//對象名字
SECTION_INFORMATION SectionInfo;
}USER_DATA, *PUSER_DATA;

接下來是枚舉的代碼過程:其中有註釋

if ((ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID)) == NULL)
{
return Status;
}
if (__NtQuerySystemInformation==NULL||__NtDuplicateObject==NULL||__NtQueryObject==NULL||__NtQuerySection==NULL)
{
goto Exit;
}

BufferData = (uint8_t*)VirtualAlloc(NULL, BufferLength, MEM_COMMIT/*物理頁屬性*/, PAGE_READWRITE);
if (BufferData = NULL)
{
goto Exit;
}

Status = __NtQuerySystemInformation(SystemHandleInformation, BufferData, BufferLength, &ReturnLength);
//得到系統信息
while (Status == STATUS_INFO_LENGTH_MISMATCH)
{
BufferLength *= 2;
VirtualFree(BufferData, 0, MEM_RELEASE);
BufferData = (uint8_t*)VirtualAlloc(NULL, BufferLength, MEM_COMMIT, PAGE_READWRITE);
Status = __NtQuerySystemInformation(SystemHandleInformation, BufferData, BufferLength, &ReturnLength);
}
//列表獲得句柄
SE_SYSTEM_EHT_INFORMATION_T* SystemEHTInfo = (SE_SYSTEM_EHT_INFORMATION_T*)BufferData;//模板定義記筆記
for (ULONG i = 0; i < SystemEHTInfo->ItemCount; i++)
{
if (SystemEHTInfo->Items[i].ProcessID != ProcessID)
{
continue;
}
//拷貝
Status = __NtDuplicateObject(ProcessHandle, reinterpret_cast<HANDLE>(SystemEHTInfo->Items[i].HandleValue/*獲得句柄所以 這樣*/),
GetCurrentProcess()/*給到當前*/, &DuplicatedHandle, 0, 0, DUPLICATE_SAME_ACCESS);//拷貝
if (!NT_SUCCESS(Status))
{
continue;
}
//還是結構體模板
//對象信息獲得
ObjectTypeInfo = (OBJECT_TYPE_INFORMATION_T*)malloc(0x1000);
Status = __NtQueryObject(DuplicatedHandle, ObjectTypeInformation, ObjectTypeInfo, 0x1000, &ReturnLength);
if (!NT_SUCCESS(Status))
{
CloseHandle(DuplicateHandle);
continue;
}
ObjectNameInfo = malloc(0x1000);
Status = __NtQueryObject(DuplicatedHandle, ObjectNameInformation, ObjectNameInfo, 0x1000, &ReturnLength);
if (!NT_SUCCESS(Status))
{
if (Status==STATUS_INFO_LENGTH_MISMATCH)
{
ObjectNameInfo = realloc(ObjectNameInfo, ReturnLength);
Status = __NtQueryObject(DuplicatedHandle, ObjectNameInformation, ObjectNameInfo, ReturnLength/*這兒有點意思*/, &ReturnLength);
if (!NT_SUCCESS(Status))
{
goto Exit;
}
}
else
{
goto Exit;
}
}

ObjectName = *(_UNICODE_STRING_T<WCHAR*>*)ObjectNameInfo;
//賦值到用戶上
v1.HandleValue = reinterpret_cast<HANDLE>(SystemEHTInfo->Items[i].HandleValue);
v1.GrantedAccess = SystemEHTInfo->Items[i].GrantedAccess;
v1.Flags = SystemEHTInfo->Items[i].Flags;
v1.ObjectValue = SystemEHTInfo->Items[i].ObjectValue;
//類型狀態賦值
if (ObjectTypeInfo->ObjectTypeName.BufferLength)
v1.ObjectTypeName = (wchar_t*)ObjectTypeInfo->ObjectTypeName.BufferData;
if (ObjectName.BufferLength)
v1.ObjectName = ObjectName.BufferData;
if (_wcsicmp(v1.ObjectTypeName.c_str(), L"Section") == 0)
{
SECTION_BASIC_INFORMATION_T SectionBasicInfo = { 0 };
//結構提函數
Status = __NtQuerySection(DuplicatedHandle, SectionBasicInformation, &SectionBasicInfo,
(ULONG)sizeof(SectionBasicInfo), NULL);
if (NT_SUCCESS(Status))
{

v1.SectionInfo.SectionSize = SectionBasicInfo.SectionSize/*T*/.QuadPart;
v1.SectionInfo.SectionAttributes = SectionBasicInfo.Attributes;
}
}
ProcessHandleInfo.push_back(v1);

Ring3句柄表的枚舉