由于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句柄表的枚举的更多相关文章

  1. Win8下枚举任意进程的句柄表。。。(VB6 Code)

    添加一个Command1.一个List1,代码: Private Type PROCESS_HANDLE_TABLE_ENTRY_INFO HandleValue As Long HandleCoun ...

  2. 驱动开发:内核枚举PspCidTable句柄表

    在上一篇文章<驱动开发:内核枚举DpcTimer定时器>中我们通过枚举特征码的方式找到了DPC定时器基址并输出了内核中存在的定时器列表,本章将学习如何通过特征码定位的方式寻找Windows ...

  3. EPROCESS 进程/线程优先级 句柄表 GDT LDT 页表 《寒江独钓》内核学习笔记(2)

    在学习笔记(1)中,我们学习了IRP的数据结构的相关知识,接下来我们继续来学习内核中很重要的另一批数据结构: EPROCESS/KPROCESS/PEB.把它们放到一起是因为这三个数据结构及其外延和w ...

  4. 【旧文章搬运】Windows句柄表分配算法分析(一)

    原文发表于百度空间,2009-03-30========================================================================== 阅读提示: ...

  5. Windbg调试(关于句柄表的获取,32位)

    今天利用Windbg(x86)进行了获得句柄表的调试,从中获益良多,对调试步骤和按键又一次进行了熟悉,对于句柄表页的概念更是得到了进一步的清晰认识.windbg调试和句柄表不熟悉的朋友可以借鉴我的调试 ...

  6. win32进程概念之句柄表,以及内核对象.

    句柄表跟内核对象 一丶什么是句柄表什么是内核对象. 1.句柄表的生成 我们知道.我们使用CreateProcess 的时候会返回一个进程句柄.以及线程句柄. 其实在调用CreateProcess的时候 ...

  7. Windows进程的内核对象句柄表

    当一个进程被初始化时,系统要为它分配一个句柄表.该句柄表只用于内核对象 ,不用于用户对象或GDI对象. 创建内核对象 当进程初次被初始化时,它的句柄表是空的.然后,当进程中的线程调用创建内核对象的函数 ...

  8. 扫描系统句柄表(WIN7 x86)(附录源码)

    PspCidTable存放着系统中所有的进程和线程对象,其索引也就是进程ID(PID)或线程ID(TID).先通过它来看看windbg里的HANDLE_TABLE结构: 可以看到地址 0x83f41b ...

  9. 【旧文章搬运】Windows句柄表分配算法分析(实验部分)

    原文发表于百度空间,2009-03-31========================================================================== 理论结合实 ...

随机推荐

  1. SpringMvc开发步骤

    1.导入基本jar包 2.在Web.xml中配置DispatcherServlet <!-- 配置 DispatcherServlet --> <servlet> <se ...

  2. form注册表单圆角 demo

    form注册表单圆角 <BODY> <div class="form"> <ul class="list"> <li& ...

  3. 深入研究ES6 Generators

    ES6 Generators系列: ES6 Generators基本概念 深入研究ES6 Generators ES6 Generators的异步应用 ES6 Generators并发 如果你还不知道 ...

  4. Server Tomcat v7.0 Server at localhost failed to start.

    1:这里记录一下这个错误,反正百度一大推,但是很长很长,我感觉这个问题肯定是servlet引起的,因为我遇到的总是如此: 2:我的问题如下所示: <servlet> <servlet ...

  5. Windows数据库编程接口简介

    数据库是计算机中一种专门管理数据资源的系统,目前几乎所有软件都需要与数据库打交道(包括操作系统,比如Windows上的注册表其实也是一种数据库),有些软件更是以数据库为核心因此掌握数据库系统的使用方法 ...

  6. 解决api、WebService跨域问题

    webapi接口在ajax调用的很多情况下都会出现跨域问题,同样的WebService如果想用ajax调用,也需要接口跨域问题,解决方案如下: 1.IIS配置 打开IIS选择发布后的webapi或者是 ...

  7. 大数据分析中Redis怎么做到220万ops

    大数据时代,海量数据分析就像吃饭一样,成为了我们每天的工作.为了更好的为公司提供运营决策,各种抖机灵甚至异想天开的想法都会紧跟着接踵而来!业务多变,决定了必须每天修改系统,重新跑数据,这就要求极高的海 ...

  8. js监听文本框值变化事件,就oninput & onpropertychange & onkeyup & onchange的区别

    在Web前端项目中实时监听文本框的值变化是非常常见的功能,通常最简单最容易想到的是onkeyup和onchange事件,但是在使用onkeyup来监听键盘事件的时候,监听不到鼠标右键的粘贴.复制的操作 ...

  9. 工作整理: python报表系统常见错误整理

    1.一般收不到邮件是因为配置文件邮箱写错 2.如果报表数据不对,看数据插入的时候是否再次写入产生冲突 3.如果收不到报表某些组别的excel查看组别名称是否匹配正确,是否匹配成功,不成功无法发送

  10. gitignore文件的作用

    早上上传文件的时候,发现有一些密钥不需要增加到版本库中,但是由于每次git status都会提示Untracked files ...并且这些文件并不需要一直提示,会占用相应的需要跟踪的文件位置,导致 ...