转载:https://blog.csdn.net/zhuhuibeishadiao/article/details/51292608
需要注意的是:在R3使用ZwQueryObject很容易锁死,需要放到线程中,如果线程超过500ms就说明卡死了 就只能放弃这个句柄了
这个句柄外面是一个FileObject类型,但真实是一个信号类型
还有在R3中枚举 有一个句柄我们是没有权限操作了 就是EtwRegistration类型的
如果非要解决这个问题,可以参考国外的一个开源进程管理器
ProcessHack
我的操作是判断是不是EtwRegistration类型,只要是就都放弃
枚举句柄还是R0好啊~
至于用途:我知道的有
1.删除正在使用中的文件
2.对某些程序实现多开
代码:
main.cpp
- #include <Windows.h>
- #include <stdio.h>
- #include <process.h>
- typedef LONG NTSTATUS;
- #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
- typedef enum _SYSTEM_INFORMATION_CLASS {
- SystemBasicInformation, // 0 Y N
- SystemProcessorInformation, // 1 Y N
- SystemPerformanceInformation, // 2 Y N
- SystemTimeOfDayInformation, // 3 Y N
- SystemNotImplemented1, // 4 Y N
- SystemProcessesAndThreadsInformation, // 5 Y N
- SystemCallCounts, // 6 Y N
- SystemConfigurationInformation, // 7 Y N
- SystemProcessorTimes, // 8 Y N
- SystemGlobalFlag, // 9 Y Y
- SystemNotImplemented2, // 10 Y N
- SystemModuleInformation, // 11 Y N
- SystemLockInformation, // 12 Y N
- SystemNotImplemented3, // 13 Y N
- SystemNotImplemented4, // 14 Y N
- SystemNotImplemented5, // 15 Y N
- SystemHandleInformation, // 16 Y N
- SystemObjectInformation, // 17 Y N
- SystemPagefileInformation, // 18 Y N
- SystemInstructionEmulationCounts, // 19 Y N
- SystemInvalidInfoClass1, // 20
- SystemCacheInformation, // 21 Y Y
- SystemPoolTagInformation, // 22 Y N
- SystemProcessorStatistics, // 23 Y N
- SystemDpcInformation, // 24 Y Y
- SystemNotImplemented6, // 25 Y N
- SystemLoadImage, // 26 N Y
- SystemUnloadImage, // 27 N Y
- SystemTimeAdjustment, // 28 Y Y
- SystemNotImplemented7, // 29 Y N
- SystemNotImplemented8, // 30 Y N
- SystemNotImplemented9, // 31 Y N
- SystemCrashDumpInformation, // 32 Y N
- SystemExceptionInformation, // 33 Y N
- SystemCrashDumpStateInformation, // 34 Y Y/N
- SystemKernelDebuggerInformation, // 35 Y N
- SystemContextSwitchInformation, // 36 Y N
- SystemRegistryQuotaInformation, // 37 Y Y
- SystemLoadAndCallImage, // 38 N Y
- SystemPrioritySeparation, // 39 N Y
- SystemNotImplemented10, // 40 Y N
- SystemNotImplemented11, // 41 Y N
- SystemInvalidInfoClass2, // 42
- SystemInvalidInfoClass3, // 43
- SystemTimeZoneInformation, // 44 Y N
- SystemLookasideInformation, // 45 Y N
- SystemSetTimeSlipEvent, // 46 N Y
- SystemCreateSession, // 47 N Y
- SystemDeleteSession, // 48 N Y
- SystemInvalidInfoClass4, // 49
- SystemRangeStartInformation, // 50 Y N
- SystemVerifierInformation, // 51 Y Y
- SystemAddVerifier, // 52 N Y
- SystemSessionProcessesInformation // 53 Y N
- } SYSTEM_INFORMATION_CLASS;
- typedef struct
- {
- USHORT Length;
- USHORT MaxLen;
- USHORT *Buffer;
- }UNICODE_STRING, *PUNICODE_STRING;
- typedef enum _OBJECT_INFORMATION_CLASS {
- ObjectBasicInformation,
- ObjectNameInformation,
- ObjectTypeInformation,
- ObjectAllInformation,
- ObjectDataInformation
- } OBJECT_INFORMATION_CLASS;
- typedef struct _OBJECT_NAME_INFORMATION {
- UNICODE_STRING Name;
- } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
- typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO{
- ULONG ProcessId;
- UCHAR ObjectTypeNumber;
- UCHAR Flags;
- USHORT Handle;
- PVOID Object;
- ACCESS_MASK GrantedAccess;
- } SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
- typedef struct _SYSTEM_HANDLE_INFORMATIONS {
- ULONG NumberOfHandles;
- SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
- } SYSTEM_HANDLE_INFORMATIONS, *PSYSTEM_HANDLE_INFORMATIONS;
- typedef struct _OBJECT_BASIC_INFORMATION {
- ULONG Attributes;
- ACCESS_MASK DesiredAccess;
- ULONG HandleCount;
- ULONG ReferenceCount;
- ULONG PagedPoolUsage;
- ULONG NonPagedPoolUsage;
- ULONG Reserved[3];
- ULONG NameInformationLength;
- ULONG TypeInformationLength;
- ULONG SecurityDescriptorLength;
- LARGE_INTEGER CreationTime;
- } OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
- typedef enum _PROCESSINFOCLASS
- {
- ProcessBasicInformation = 0, // 0, q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
- ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
- ProcessIoCounters, // q: IO_COUNTERS
- ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX
- ProcessTimes, // q: KERNEL_USER_TIMES
- ProcessBasePriority, // s: KPRIORITY
- ProcessRaisePriority, // s: ULONG
- ProcessDebugPort, // q: HANDLE
- ProcessExceptionPort, // s: HANDLE
- ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
- ProcessLdtInformation, // 10
- ProcessLdtSize,
- ProcessDefaultHardErrorMode, // qs: ULONG
- ProcessIoPortHandlers, // (kernel-mode only)
- ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
- ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
- ProcessUserModeIOPL,
- ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
- ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
- ProcessWx86Information,
- ProcessHandleCount, // 20, q: ULONG, PROCESS_HANDLE_INFORMATION
- ProcessAffinityMask, // s: KAFFINITY
- ProcessPriorityBoost, // qs: ULONG
- ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
- ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
- ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
- ProcessWow64Information, // q: ULONG_PTR
- ProcessImageFileName, // q: UNICODE_STRING
- ProcessLUIDDeviceMapsEnabled, // q: ULONG
- ProcessBreakOnTermination, // qs: ULONG
- ProcessDebugObjectHandle, // 30, q: HANDLE
- ProcessDebugFlags, // qs: ULONG
- ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
- ProcessIoPriority, // qs: ULONG
- ProcessExecuteFlags, // qs: ULONG
- ProcessResourceManagement,
- ProcessCookie, // q: ULONG
- ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
- ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION
- ProcessPagePriority, // q: ULONG
- ProcessInstrumentationCallback, // 40
- ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
- ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
- ProcessImageFileNameWin32, // q: UNICODE_STRING
- ProcessImageFileMapping, // q: HANDLE (input)
- ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
- ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
- ProcessGroupInformation, // q: USHORT[]
- ProcessTokenVirtualizationEnabled, // s: ULONG
- ProcessConsoleHostProcess, // q: ULONG_PTR
- ProcessWindowInformation, // 50, q: PROCESS_WINDOW_INFORMATION
- ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
- ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
- ProcessDynamicFunctionTableInformation,
- ProcessHandleCheckingMode,
- ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
- ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
- MaxProcessInfoClass
- }PROCESSINFOCLASS;
- typedef struct _OBJECT_TYPE_INFORMATION
- {
- UNICODE_STRING TypeName;
- ULONG TotalNumberOfObjects;
- ULONG TotalNumberOfHandles;
- ULONG TotalPagedPoolUsage;
- ULONG TotalNonPagedPoolUsage;
- ULONG TotalNamePoolUsage;
- ULONG TotalHandleTableUsage;
- ULONG HighWaterNumberOfObjects;
- ULONG HighWaterNumberOfHandles;
- ULONG HighWaterPagedPoolUsage;
- ULONG HighWaterNonPagedPoolUsage;
- ULONG HighWaterNamePoolUsage;
- ULONG HighWaterHandleTableUsage;
- ULONG InvalidAttributes;
- GENERIC_MAPPING GenericMapping;
- ULONG ValidAccessMask;
- BOOLEAN SecurityRequired;
- BOOLEAN MaintainHandleCount;
- ULONG PoolType;
- ULONG DefaultPagedPoolCharge;
- ULONG DefaultNonPagedPoolCharge;
- } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
- typedef NTSTATUS
- (NTAPI *ZWQUERYSYSTEMINFORMATION)(
- IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
- OUT PVOID SystemInformation,
- IN ULONG SystemInformationLength,
- OUT PULONG ReturnLength OPTIONAL
- );
- typedef NTSTATUS
- (WINAPI *ZWQUERYOBJECT)(
- IN HANDLE OPTIONAL,
- IN OBJECT_INFORMATION_CLASS,
- OUT PVOID OPTIONAL,
- IN ULONG,
- OUT PULONG OPTIONAL);
- //这个没有用到 不过留着 后面会用到的
- typedef NTSTATUS
- (WINAPI *ZWQUERYINFORMATIONPROCESS)(
- HANDLE ProcessHandle,
- PROCESSINFOCLASS ProcessInformationClass,
- PVOID ProcessInformation,
- ULONG ProcessInformationLength,
- PULONG ReturnLength);
- typedef long (*RTLADJUSTPRIVILEGE)(ULONG,ULONG,ULONG,PVOID);
- RTLADJUSTPRIVILEGE RtlAdjustPrivilege;
- //g_
- HANDLE g_Event = 0,hTest = 0;
- POBJECT_NAME_INFORMATION ObjName;
- BOOL g_ZwFaild = FALSE;
- ZWQUERYOBJECT ZwQueryObject;
- ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;
- UINT WINAPI ZwThreadProc(PVOID lpParma)
- {
- NTSTATUS ntStatus = ZwQueryObject(hTest, ObjectNameInformation, ObjName, 0x512, NULL);//可能锁死
- if(!NT_SUCCESS(ntStatus))
- {
- g_ZwFaild = TRUE;
- }
- SetEvent(g_Event);
- return 0;
- }
- BOOL ThreadEnumHandleByZwQuerySystemInformation(DWORD pid)
- {
- ULONG i;
- ULONG ulSize;
- ULONG* pHandleInfor;
- NTSTATUS ntStatus;
- HMODULE hHanlde;
- PSYSTEM_HANDLE_INFORMATIONS lpHandles;
- POBJECT_BASIC_INFORMATION lpHandleBasic;
- HANDLE hProcess = 0,hThread = 0;
- ULONG errorCode = 0;
- ULONG Count = 0;
- POBJECT_TYPE_INFORMATION TypeInfo;
- UINT dwThread = 0;
- //初始化变量
- ulSize = 0x4000;
- pHandleInfor = NULL;
- ZwQueryObject = NULL;
- ZwQuerySystemInformation = NULL;
- hTest = 0;
- //由于ZwQueryObject和ZwQuerySystemInformation是未导出的函数,需要动态加载Ntdll,dll,然后通过函数GetProcAddress
- //得到它们的函数地址,由于这个dll一般的进程都会在创建的时候加载,所以省略加载,直接获取其模块地址
- hHanlde = GetModuleHandle(L"ntdll.dll");
- if(NULL == hHanlde)
- {
- //加载Ntdll.dll失败
- return FALSE;
- }
- //获取ZwQuerySystemInformation函数地址
- ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hHanlde, "ZwQuerySystemInformation");
- if(NULL == ZwQuerySystemInformation)
- {
- //获取ZwQuerySystemInformation函数地址失败
- return FALSE;
- }
- //获取ZwQueryObject函数地址
- ZwQueryObject = (ZWQUERYOBJECT)GetProcAddress(hHanlde, "ZwQueryObject");
- if(NULL == ZwQueryObject)
- {
- //获取ZwQueryObject函数地址失败
- return FALSE;
- }
- //打开进程 复制句柄时用到
- hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
- PROCESS_DUP_HANDLE, FALSE, pid);
- if(hProcess == NULL)
- {
- return FALSE;
- }
- //获取系统所有句柄信息
- do
- {
- //申请内存
- pHandleInfor = (ULONG*)malloc(ulSize);
- if(NULL == pHandleInfor)
- {
- //申请内存失败
- CloseHandle(hProcess);
- return FALSE;
- }
- ntStatus = ZwQuerySystemInformation( SystemHandleInformation, pHandleInfor, ulSize, NULL);
- if(!NT_SUCCESS(ntStatus))
- {
- //空间不足继续申请。
- free(pHandleInfor);
- ulSize = ulSize * 2;
- //为防止ZwQuerySystemInformation一直失败,程序陷入死循环,当申请的空间超过64M时则返回失败
- if(ulSize > 0x4000000)
- {
- CloseHandle(hProcess);
- return FALSE;
- }
- }
- }while(!NT_SUCCESS(ntStatus));
- //转换数据结构类型
- lpHandles = (PSYSTEM_HANDLE_INFORMATIONS)pHandleInfor;
- if(NULL == lpHandles)
- {
- CloseHandle(hProcess);
- return FALSE;
- }
- //申请空间,用于存储对象的名字信息和对象类型名字
- ObjName = (POBJECT_NAME_INFORMATION)malloc(0x512);
- TypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x512);
- lpHandleBasic = (POBJECT_BASIC_INFORMATION)malloc(sizeof(OBJECT_BASIC_INFORMATION));
- //开始搜索获取的句柄信息,并对句柄对应的对象名进行比较,如果与要求关闭的名字相同,则关闭此句柄
- //printf("%d\n",lpHandles->NumberOfHandles);
- for(i = 0; i < lpHandles->NumberOfHandles; i++)
- {
- if(pid != lpHandles->Handles[i].ProcessId)
- {
- //printf("%d\n",lpHandles->Handles[i].ProcessId);
- continue;
- }
- if(DuplicateHandle(hProcess,(HANDLE)lpHandles->Handles[i].Handle,GetCurrentProcess(),&hTest,0,FALSE,DUPLICATE_SAME_ACCESS))
- {
- Count++;
- //获取这个对象的类型名
- ntStatus = ZwQueryObject(hTest,ObjectTypeInformation,TypeInfo,0x512,NULL);
- if(!NT_SUCCESS(ntStatus))
- {
- //查询失败
- continue;
- }
- ntStatus = ZwQueryObject(hTest,ObjectBasicInformation,lpHandleBasic,sizeof(OBJECT_BASIC_INFORMATION),NULL);
- if(!NT_SUCCESS(ntStatus))
- {
- //查询失败
- continue;
- }
- //获取这个对象的名字信息
- _beginthreadex(NULL,0,ZwThreadProc,NULL,0,&dwThread);
- DWORD dwSatu = WaitForSingleObject(g_Event,500);
- if(dwSatu == WAIT_TIMEOUT){
- printf("ObjceTypeName:FILE---ObjectTypeIndex:%d---HandleAttributes:%x---Handle:0x%x---Object:%p\n---HandleName:Device\\NamePapi\n",lpHandles->Handles[i].ObjectTypeNumber,lpHandles->Handles[i].Flags,lpHandles->Handles[i].Handle,lpHandles->Handles[i].Object);
- hThread = OpenThread(THREAD_TERMINATE,FALSE,dwThread);
- if(!TerminateThread(hThread,0)){
- CloseHandle(hThread);
- ExitProcess(0);
- }
- CloseHandle(hThread);
- continue;
- }
- if(g_ZwFaild)
- {
- g_ZwFaild = FALSE;
- continue;
- }
- /*
- //将unicode 字串转换为 ansi字串
- WideCharToMultiByte(CP_ACP, 0, ObjName->Name.Buffer, -1, pName, 200, NULL, NULL);
- if( 0 == strcmp(pName, pObjectName))
- {
- //找到对应名字的对象,将其关闭
- CloseHandle((HANDLE)Handles->Information[i].Handle);
- }
- */
- printf("ObjceTypeName:%wZ---ObjectTypeIndex:%d---HandleAttributes:%x---Handle:0x%x---Object:%p\n",TypeInfo->TypeName,lpHandles->Handles[i].ObjectTypeNumber,lpHandles->Handles[i].Flags,lpHandles->Handles[i].Handle,lpHandles->Handles[i].Object);
- wprintf(L"HandleName:%wZ\n",ObjName->Name);
- printf("\nRedeferCount:%d\n",lpHandleBasic->ReferenceCount);
- }else
- {
- errorCode = GetLastError();
- if(errorCode == 0x32)//不支持读写的句柄 Etw
- {
- printf("ObjectTypeIndex:0x27---HandleAttributes:000000---Handle:0x%x---Object:%p\n",lpHandles->Handles[i].Handle,lpHandles->Handles[i].Object);
- Count++;
- }
- }
- }
- //释放申请的空间
- free(lpHandles);
- free(ObjName);
- free(TypeInfo);
- free(lpHandleBasic);
- CloseHandle(hProcess);
- printf("Pid:%d----HandleCount:%d\n",pid,Count);
- return TRUE;
- }
- void main()
- {
- ThreadEnumHandleByZwQuerySystemInformation(2292);
- getchar();
- }
关于ZwDuplicateObject的妙用可以参考我的另一篇文章,在复制的时候就可以关闭对方的句柄
http://blog.csdn.net/zhuhuibeishadiao/article/details/51046595