看流星社区

 找回密码
 注册账号
查看: 1862|回复: 0

R3 x64枚举进程句柄

[复制链接]

该用户从未签到

发表于 2017-6-1 13:32:49 | 显示全部楼层 |阅读模式
需要注意的是:在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.ProcessId)
          {      
                //printf("%d\n",lpHandles->Handles.ProcessId);
                        continue;
          }
  
          if(DuplicateHandle(hProcess,(HANDLE)lpHandles->Handles.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---HandleNameevice\\NamePapi\n",lpHandles->Handles.ObjectTypeNumber,lpHandles->Handles.Flags,lpHandles->Handles.Handle,lpHandles->Handles.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.Handle);
                }
                */
                printf("ObjceTypeName:%wZ---ObjectTypeIndex:%d---HandleAttributes:%x---Handle:0x%x---Object:%p\n",TypeInfo->TypeName,lpHandles->Handles.ObjectTypeNumber,lpHandles->Handles.Flags,lpHandles->Handles.Handle,lpHandles->Handles.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.Handle,lpHandles->Handles.Object);
                          Count++;
                  }
          }
  }
  
  //释放申请的空间
  free(lpHandles);
  free(ObjName);
  free(TypeInfo);
  free(lpHandleBasic);
  CloseHandle(hProcess);
  
  printf(&quotid:%d----HandleCount:%d\n",pid,Count);
  return TRUE;
}


void main()
{
        ThreadEnumHandleByZwQuerySystemInformation(2292);
        getchar();
}[/code]




关于ZwDuplicateObject的妙用可以参考我的另一篇文章,在复制的时候就可以关闭对方的句柄
51046595
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 11:09

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表