转载:https://blog.csdn.net/zhuhuibeishadiao/article/details/51292608
需要注意的是:在R3使用ZwQueryObject很容易锁死,需要放到线程中,如果线程超过500ms就说明卡死了 就只能放弃这个句柄了
这个句柄外面是一个FileObject类型,但真实是一个信号类型
还有在R3中枚举 有一个句柄我们是没有权限操作了 就是EtwRegistration类型的
如果非要解决这个问题,可以参考国外的一个开源进程管理器
ProcessHack
我的操作是判断是不是EtwRegistration类型,只要是就都放弃
枚举句柄还是R0好啊~
至于用途:我知道的有
1.删除正在使用中的文件
2.对某些程序实现多开
代码:
main.cpp
-
-
-
-
-
typedef LONG NTSTATUS;
-
-
-
-
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 ",lpHandles->NumberOfHandles);
-
for(i = 0; i < lpHandles->NumberOfHandles; i++)
-
{
-
if(pid != lpHandles->Handles[i].ProcessId)
-
{
-
//printf("%d ",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 ---HandleName:Device\NamePapi ",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 ",TypeInfo->TypeName,lpHandles->Handles[i].ObjectTypeNumber,lpHandles->Handles[i].Flags,lpHandles->Handles[i].Handle,lpHandles->Handles[i].Object);
-
wprintf(L"HandleName:%wZ ",ObjName->Name);
-
printf(" RedeferCount:%d ",lpHandleBasic->ReferenceCount);
-
-
}else
-
{
-
errorCode = GetLastError();
-
if(errorCode == 0x32)//不支持读写的句柄 Etw
-
{
-
printf("ObjectTypeIndex:0x27---HandleAttributes:000000---Handle:0x%x---Object:%p ",lpHandles->Handles[i].Handle,lpHandles->Handles[i].Object);
-
Count++;
-
}
-
}
-
}
-
-
//释放申请的空间
-
free(lpHandles);
-
free(ObjName);
-
free(TypeInfo);
-
free(lpHandleBasic);
-
CloseHandle(hProcess);
-
-
printf("Pid:%d----HandleCount:%d ",pid,Count);
-
return TRUE;
-
}
-
-
-
void main()
-
{
-
ThreadEnumHandleByZwQuerySystemInformation(2292);
-
getchar();
-
}
关于ZwDuplicateObject的妙用可以参考我的另一篇文章,在复制的时候就可以关闭对方的句柄
http://blog.csdn.net/zhuhuibeishadiao/article/details/51046595