轉載: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\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