zoukankan      html  css  js  c++  java
  • 枚举任意进程内核对象句柄的方法

    原理:

    调用ntdll的一个导出函数ZwQuerySystemInformation可以获取一些重要信息,函数定义如下:

    1 NTSTATUS WINAPI ZwQuerySystemInformation(
    2   _In_       SYSTEM_INFORMATION_CLASS SystemInformationClass,
    3   _Inout_    PVOID SystemInformation,
    4   _In_       ULONG SystemInformationLength,
    5   _Out_opt_  PULONG ReturnLength
    6 );

    不过msdn上说该函数在win8下已经不能使用了,用到的时候再说。

     重点关注该函数的第一个参数SYSTEM_INFORMATION_CLASS是一个结构体,具体定义如下:

    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;

    16号SystemHandleInformation即可获得系统句柄信息。

    获取所以进程句柄后并不能直接操作这些句柄,因为每个进程的句柄都是独立存在的,所以需要调用DuplicateHandle将需要的进程句柄Dump到当前进程然后再进行操作,

    BOOL WINAPI DuplicateHandle(
      _In_   HANDLE hSourceProcessHandle,
      _In_   HANDLE hSourceHandle,
      _In_   HANDLE hTargetProcessHandle,
      _Out_  LPHANDLE lpTargetHandle,
      _In_   DWORD dwDesiredAccess,
      _In_   BOOL bInheritHandle,
      _In_   DWORD dwOptions
    );

    得到的lpTargetHandle保存着目标进程的句柄。然后调用NtQueryObject可以获取句柄的类型(mutex、File、Section等),以及句柄名称等等。

    NTSTATUS NtQueryObject(
      _In_opt_   HANDLE Handle,
      _In_       OBJECT_INFORMATION_CLASS ObjectInformationClass,
      _Out_opt_  PVOID ObjectInformation,
      _In_       ULONG ObjectInformationLength,
      _Out_opt_  PULONG ReturnLength
    );

    说了一大堆了,开始写代码吧,由于这里需要很多结构信息,因此我写了一个头文件来定义这些结构:

    objEnum.h:
     1 #include "ntsecapi.h"
     2 #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
     3 typedef NTSTATUS (WINAPI *ZWQUERYSYSTEMINFORMATION)(DWORD, PVOID, DWORD, PDWORD);
     4 typedef enum _OBJECT_INFORMATION_CLASS {
     5      ObjectBasicInformation,
     6           ObjectNameInformation,
     7           ObjectTypeInformation,
     8           ObjectAllInformation,
     9           ObjectDataInformation,
    10 } OBJECT_INFORMATION_CLASS;
    11 typedef NTSTATUS (NTAPI *NTQUERYOBJECT)(
    12      HANDLE Handle,
    13      OBJECT_INFORMATION_CLASS ObjectInformationClass,
    14      PVOID ObjectInformation,
    15      ULONG ObjectInformationLength,
    16      PULONG ReturnLength
    17      );
    18 typedef struct _OBJECT_NAME_INFORMATION {
    19      UNICODE_STRING Name;
    20 } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
    21 typedef struct _SYSTEM_HANDLE_INFORMATION
    22 {
    23      ULONG ProcessId;
    24      UCHAR ObjectTypeNumber;
    25      UCHAR Flags;
    26      USHORT Handle;
    27      PVOID Object;
    28      ACCESS_MASK GrantedAccess;
    29 }SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
    30 
    31 typedef struct _SYSTEM_HANDLE_INFORMATION_EX
    32 {
    33      ULONG NumberOfHandles;
    34      SYSTEM_HANDLE_INFORMATION Information[1];
    35 }SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
    36 #define SystemHandleInformation 0x10  // 16

    然后是两个函数:

    1、GetSystemProcessHandeleInfo()可以获取当前系统的所有内核对象句柄信息并返回。

     1 LPVOID GetSystemProcessHandleInfo()
     2 {
     3      ULONG cbBuffer = 0x4000;
     4      LPVOID pBuffer = NULL;
     5      NTSTATUS sts;
     6      do
     7      {
     8           pBuffer = malloc(cbBuffer);
     9           if(pBuffer == NULL)
    10           {
    11                cout<<"error alloc memory:"<<GetLastError()<<endl;
    12                return NULL;
    13           }
    14           memset(pBuffer,0,cbBuffer);
    15          
    16           sts = ZwQuerySystemInformation(SystemHandleInformation, pBuffer, cbBuffer, NULL);
    17           if(sts == STATUS_INFO_LENGTH_MISMATCH)
    18           {
    19                free(pBuffer);
    20                pBuffer = NULL;
    21                cbBuffer = cbBuffer +0x4000; // 初始分配的空间不足+4000h
    22           }
    23      }while(sts == STATUS_INFO_LENGTH_MISMATCH);
    24      return pBuffer;
    25 }
     2.EnumObjInfo()获取从返回的内核对象句柄信息中取出指定pid,指定句柄类型的内核对象,并打印:
    void EnumObjInfo(LPVOID pBuffer,DWORD pid)
     {
          char szType[128] = {0};
          char szName[512] = {0};
          DWORD dwFlags = 0;
          POBJECT_NAME_INFORMATION pNameInfo;
          POBJECT_NAME_INFORMATION pNameType;
          PSYSTEM_HANDLE_INFORMATION_EX pInfo = (PSYSTEM_HANDLE_INFORMATION_EX)pBuffer;
          ULONG OldPID = 0;
          for(DWORD i = 0; i < pInfo->NumberOfHandles; i++)
          {
               if(OldPID != pInfo->Information[i].ProcessId)
               {
                   if(pInfo->Information[i].ProcessId==pid)
                    {
                        
                         HANDLE newHandle;
                         DuplicateHandle(OpenProcess(PROCESS_ALL_ACCESS,FALSE,pInfo->Information[i].ProcessId),(HANDLE)pInfo->Information[i].Handle,GetCurrentProcess(),&newHandle,DUPLICATE_SAME_ACCESS,FALSE,DUPLICATE_SAME_ACCESS);
                         NTSTATUS status1=NtQueryObject(newHandle, ObjectNameInformation, szName, 512, &dwFlags);
                         NTSTATUS status2=NtQueryObject(newHandle, ObjectTypeInformation, szType, 128, &dwFlags);
                         if(strcmp(szName,"")&&strcmp(szType,"")&&status1!=0xc0000008&&status2!=0xc0000008)
                         {
                              pNameInfo = (POBJECT_NAME_INFORMATION)szName; 
    pNameType = (POBJECT_NAME_INFORMATION)szType; printf("%wZ ",pNameType); printf("%wZ ",pNameInfo); } } } }
  • 相关阅读:
    net.sf.fmj.media.cdp.civil.CaptureDevicePlugger addCaptureDevices解决方法
    SVN快速入门教程
    Struts 2详细工作流程
    未能加载.NET基类问题
    图片上传的例子
    一个.NET发邮件的简单例子
    一种巧妙的删除程序自己的方法
    oracle的问题
    javascript 中对Trim()的实现
    SQL Server 不存在或访问被拒绝的问题
  • 原文地址:https://www.cnblogs.com/Lamboy/p/3307012.html
Copyright © 2011-2022 走看看