转载:https://blog.csdn.net/zhuhuibeishadiao/article/details/51292608

需要注意的是:在R3使用ZwQueryObject很容易锁死,需要放到线程中,如果线程超过500ms就说明卡死了 就只能放弃这个句柄了

这个句柄外面是一个FileObject类型,但真实是一个信号类型

还有在R3中枚举 有一个句柄我们是没有权限操作了 就是EtwRegistration类型的

如果非要解决这个问题,可以参考国外的一个开源进程管理器

ProcessHack

我的操作是判断是不是EtwRegistration类型,只要是就都放弃

枚举句柄还是R0好啊~

至于用途:我知道的有

1.删除正在使用中的文件

2.对某些程序实现多开

代码:

main.cpp

  1.  
    #include <Windows.h>
  2.  
    #include <stdio.h>
  3.  
    #include <process.h>
  4.  
     
  5.  
    typedef LONG NTSTATUS;
  6.  
    #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
  7.  
     
  8.  
     
  9.  
    typedef enum _SYSTEM_INFORMATION_CLASS {
  10.  
    SystemBasicInformation, // 0 Y N
  11.  
    SystemProcessorInformation, // 1 Y N
  12.  
    SystemPerformanceInformation, // 2 Y N
  13.  
    SystemTimeOfDayInformation, // 3 Y N
  14.  
    SystemNotImplemented1, // 4 Y N
  15.  
    SystemProcessesAndThreadsInformation, // 5 Y N
  16.  
    SystemCallCounts, // 6 Y N
  17.  
    SystemConfigurationInformation, // 7 Y N
  18.  
    SystemProcessorTimes, // 8 Y N
  19.  
    SystemGlobalFlag, // 9 Y Y
  20.  
    SystemNotImplemented2, // 10 Y N
  21.  
    SystemModuleInformation, // 11 Y N
  22.  
    SystemLockInformation, // 12 Y N
  23.  
    SystemNotImplemented3, // 13 Y N
  24.  
    SystemNotImplemented4, // 14 Y N
  25.  
    SystemNotImplemented5, // 15 Y N
  26.  
    SystemHandleInformation, // 16 Y N
  27.  
    SystemObjectInformation, // 17 Y N
  28.  
    SystemPagefileInformation, // 18 Y N
  29.  
    SystemInstructionEmulationCounts, // 19 Y N
  30.  
    SystemInvalidInfoClass1, // 20
  31.  
    SystemCacheInformation, // 21 Y Y
  32.  
    SystemPoolTagInformation, // 22 Y N
  33.  
    SystemProcessorStatistics, // 23 Y N
  34.  
    SystemDpcInformation, // 24 Y Y
  35.  
    SystemNotImplemented6, // 25 Y N
  36.  
    SystemLoadImage, // 26 N Y
  37.  
    SystemUnloadImage, // 27 N Y
  38.  
    SystemTimeAdjustment, // 28 Y Y
  39.  
    SystemNotImplemented7, // 29 Y N
  40.  
    SystemNotImplemented8, // 30 Y N
  41.  
    SystemNotImplemented9, // 31 Y N
  42.  
    SystemCrashDumpInformation, // 32 Y N
  43.  
    SystemExceptionInformation, // 33 Y N
  44.  
    SystemCrashDumpStateInformation, // 34 Y Y/N
  45.  
    SystemKernelDebuggerInformation, // 35 Y N
  46.  
    SystemContextSwitchInformation, // 36 Y N
  47.  
    SystemRegistryQuotaInformation, // 37 Y Y
  48.  
    SystemLoadAndCallImage, // 38 N Y
  49.  
    SystemPrioritySeparation, // 39 N Y
  50.  
    SystemNotImplemented10, // 40 Y N
  51.  
    SystemNotImplemented11, // 41 Y N
  52.  
    SystemInvalidInfoClass2, // 42
  53.  
    SystemInvalidInfoClass3, // 43
  54.  
    SystemTimeZoneInformation, // 44 Y N
  55.  
    SystemLookasideInformation, // 45 Y N
  56.  
    SystemSetTimeSlipEvent, // 46 N Y
  57.  
    SystemCreateSession, // 47 N Y
  58.  
    SystemDeleteSession, // 48 N Y
  59.  
    SystemInvalidInfoClass4, // 49
  60.  
    SystemRangeStartInformation, // 50 Y N
  61.  
    SystemVerifierInformation, // 51 Y Y
  62.  
    SystemAddVerifier, // 52 N Y
  63.  
    SystemSessionProcessesInformation // 53 Y N
  64.  
    } SYSTEM_INFORMATION_CLASS;
  65.  
     
  66.  
    typedef struct
  67.  
    {
  68.  
    USHORT Length;
  69.  
    USHORT MaxLen;
  70.  
    USHORT *Buffer;
  71.  
    }UNICODE_STRING, *PUNICODE_STRING;
  72.  
     
  73.  
    typedef enum _OBJECT_INFORMATION_CLASS {
  74.  
    ObjectBasicInformation,
  75.  
    ObjectNameInformation,
  76.  
    ObjectTypeInformation,
  77.  
    ObjectAllInformation,
  78.  
    ObjectDataInformation
  79.  
    } OBJECT_INFORMATION_CLASS;
  80.  
     
  81.  
    typedef struct _OBJECT_NAME_INFORMATION {
  82.  
    UNICODE_STRING Name;
  83.  
    } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
  84.  
     
  85.  
     
  86.  
     
  87.  
    typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO{
  88.  
    ULONG ProcessId;
  89.  
    UCHAR ObjectTypeNumber;
  90.  
    UCHAR Flags;
  91.  
    USHORT Handle;
  92.  
    PVOID Object;
  93.  
    ACCESS_MASK GrantedAccess;
  94.  
    } SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
  95.  
     
  96.  
    typedef struct _SYSTEM_HANDLE_INFORMATIONS {
  97.  
    ULONG NumberOfHandles;
  98.  
    SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
  99.  
    } SYSTEM_HANDLE_INFORMATIONS, *PSYSTEM_HANDLE_INFORMATIONS;
  100.  
     
  101.  
    typedef struct _OBJECT_BASIC_INFORMATION {
  102.  
    ULONG Attributes;
  103.  
    ACCESS_MASK DesiredAccess;
  104.  
    ULONG HandleCount;
  105.  
    ULONG ReferenceCount;
  106.  
    ULONG PagedPoolUsage;
  107.  
    ULONG NonPagedPoolUsage;
  108.  
    ULONG Reserved[3];
  109.  
    ULONG NameInformationLength;
  110.  
    ULONG TypeInformationLength;
  111.  
    ULONG SecurityDescriptorLength;
  112.  
    LARGE_INTEGER CreationTime;
  113.  
    } OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
  114.  
     
  115.  
    typedef enum _PROCESSINFOCLASS
  116.  
    {
  117.  
    ProcessBasicInformation = 0, // 0, q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
  118.  
    ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
  119.  
    ProcessIoCounters, // q: IO_COUNTERS
  120.  
    ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX
  121.  
    ProcessTimes, // q: KERNEL_USER_TIMES
  122.  
    ProcessBasePriority, // s: KPRIORITY
  123.  
    ProcessRaisePriority, // s: ULONG
  124.  
    ProcessDebugPort, // q: HANDLE
  125.  
    ProcessExceptionPort, // s: HANDLE
  126.  
    ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
  127.  
    ProcessLdtInformation, // 10
  128.  
    ProcessLdtSize,
  129.  
    ProcessDefaultHardErrorMode, // qs: ULONG
  130.  
    ProcessIoPortHandlers, // (kernel-mode only)
  131.  
    ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
  132.  
    ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
  133.  
    ProcessUserModeIOPL,
  134.  
    ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
  135.  
    ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
  136.  
    ProcessWx86Information,
  137.  
    ProcessHandleCount, // 20, q: ULONG, PROCESS_HANDLE_INFORMATION
  138.  
    ProcessAffinityMask, // s: KAFFINITY
  139.  
    ProcessPriorityBoost, // qs: ULONG
  140.  
    ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
  141.  
    ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
  142.  
    ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
  143.  
    ProcessWow64Information, // q: ULONG_PTR
  144.  
    ProcessImageFileName, // q: UNICODE_STRING
  145.  
    ProcessLUIDDeviceMapsEnabled, // q: ULONG
  146.  
    ProcessBreakOnTermination, // qs: ULONG
  147.  
    ProcessDebugObjectHandle, // 30, q: HANDLE
  148.  
    ProcessDebugFlags, // qs: ULONG
  149.  
    ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
  150.  
    ProcessIoPriority, // qs: ULONG
  151.  
    ProcessExecuteFlags, // qs: ULONG
  152.  
    ProcessResourceManagement,
  153.  
    ProcessCookie, // q: ULONG
  154.  
    ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
  155.  
    ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION
  156.  
    ProcessPagePriority, // q: ULONG
  157.  
    ProcessInstrumentationCallback, // 40
  158.  
    ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
  159.  
    ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
  160.  
    ProcessImageFileNameWin32, // q: UNICODE_STRING
  161.  
    ProcessImageFileMapping, // q: HANDLE (input)
  162.  
    ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
  163.  
    ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
  164.  
    ProcessGroupInformation, // q: USHORT[]
  165.  
    ProcessTokenVirtualizationEnabled, // s: ULONG
  166.  
    ProcessConsoleHostProcess, // q: ULONG_PTR
  167.  
    ProcessWindowInformation, // 50, q: PROCESS_WINDOW_INFORMATION
  168.  
    ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
  169.  
    ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
  170.  
    ProcessDynamicFunctionTableInformation,
  171.  
    ProcessHandleCheckingMode,
  172.  
    ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
  173.  
    ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
  174.  
    MaxProcessInfoClass
  175.  
    }PROCESSINFOCLASS;
  176.  
     
  177.  
    typedef struct _OBJECT_TYPE_INFORMATION
  178.  
    {
  179.  
    UNICODE_STRING TypeName;
  180.  
    ULONG TotalNumberOfObjects;
  181.  
    ULONG TotalNumberOfHandles;
  182.  
    ULONG TotalPagedPoolUsage;
  183.  
    ULONG TotalNonPagedPoolUsage;
  184.  
    ULONG TotalNamePoolUsage;
  185.  
    ULONG TotalHandleTableUsage;
  186.  
    ULONG HighWaterNumberOfObjects;
  187.  
    ULONG HighWaterNumberOfHandles;
  188.  
    ULONG HighWaterPagedPoolUsage;
  189.  
    ULONG HighWaterNonPagedPoolUsage;
  190.  
    ULONG HighWaterNamePoolUsage;
  191.  
    ULONG HighWaterHandleTableUsage;
  192.  
    ULONG InvalidAttributes;
  193.  
    GENERIC_MAPPING GenericMapping;
  194.  
    ULONG ValidAccessMask;
  195.  
    BOOLEAN SecurityRequired;
  196.  
    BOOLEAN MaintainHandleCount;
  197.  
    ULONG PoolType;
  198.  
    ULONG DefaultPagedPoolCharge;
  199.  
    ULONG DefaultNonPagedPoolCharge;
  200.  
    } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
  201.  
     
  202.  
    typedef NTSTATUS
  203.  
    (NTAPI *ZWQUERYSYSTEMINFORMATION)(
  204.  
    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
  205.  
    OUT PVOID SystemInformation,
  206.  
    IN ULONG SystemInformationLength,
  207.  
    OUT PULONG ReturnLength OPTIONAL
  208.  
    );
  209.  
    typedef NTSTATUS
  210.  
    (WINAPI *ZWQUERYOBJECT)(
  211.  
    IN HANDLE OPTIONAL,
  212.  
    IN OBJECT_INFORMATION_CLASS,
  213.  
    OUT PVOID OPTIONAL,
  214.  
    IN ULONG,
  215.  
    OUT PULONG OPTIONAL);
  216.  
     
  217.  
    //这个没有用到 不过留着 后面会用到的
  218.  
    typedef NTSTATUS
  219.  
    (WINAPI *ZWQUERYINFORMATIONPROCESS)(
  220.  
    HANDLE ProcessHandle,
  221.  
    PROCESSINFOCLASS ProcessInformationClass,
  222.  
    PVOID ProcessInformation,
  223.  
    ULONG ProcessInformationLength,
  224.  
    PULONG ReturnLength);
  225.  
     
  226.  
    typedef long (*RTLADJUSTPRIVILEGE)(ULONG,ULONG,ULONG,PVOID);
  227.  
    RTLADJUSTPRIVILEGE RtlAdjustPrivilege;
  228.  
     
  229.  
    //g_
  230.  
    HANDLE g_Event = 0,hTest = 0;
  231.  
    POBJECT_NAME_INFORMATION ObjName;
  232.  
    BOOL g_ZwFaild = FALSE;
  233.  
    ZWQUERYOBJECT ZwQueryObject;
  234.  
    ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;
  235.  
     
  236.  
    UINT WINAPI ZwThreadProc(PVOID lpParma)
  237.  
    {
  238.  
    NTSTATUS ntStatus = ZwQueryObject(hTest, ObjectNameInformation, ObjName, 0x512, NULL);//可能锁死
  239.  
    if(!NT_SUCCESS(ntStatus))
  240.  
    {
  241.  
    g_ZwFaild = TRUE;
  242.  
    }
  243.  
    SetEvent(g_Event);
  244.  
    return 0;
  245.  
    }
  246.  
     
  247.  
     
  248.  
    BOOL ThreadEnumHandleByZwQuerySystemInformation(DWORD pid)
  249.  
    {
  250.  
    ULONG i;
  251.  
    ULONG ulSize;
  252.  
    ULONG* pHandleInfor;
  253.  
    NTSTATUS ntStatus;
  254.  
    HMODULE hHanlde;
  255.  
    PSYSTEM_HANDLE_INFORMATIONS lpHandles;
  256.  
    POBJECT_BASIC_INFORMATION lpHandleBasic;
  257.  
    HANDLE hProcess = 0,hThread = 0;
  258.  
    ULONG errorCode = 0;
  259.  
    ULONG Count = 0;
  260.  
    POBJECT_TYPE_INFORMATION TypeInfo;
  261.  
    UINT dwThread = 0;
  262.  
    //初始化变量
  263.  
    ulSize = 0x4000;
  264.  
    pHandleInfor = NULL;
  265.  
    ZwQueryObject = NULL;
  266.  
    ZwQuerySystemInformation = NULL;
  267.  
     
  268.  
    hTest = 0;
  269.  
    //由于ZwQueryObject和ZwQuerySystemInformation是未导出的函数,需要动态加载Ntdll,dll,然后通过函数GetProcAddress
  270.  
    //得到它们的函数地址,由于这个dll一般的进程都会在创建的时候加载,所以省略加载,直接获取其模块地址
  271.  
    hHanlde = GetModuleHandle(L"ntdll.dll");
  272.  
    if(NULL == hHanlde)
  273.  
    {
  274.  
    //加载Ntdll.dll失败
  275.  
    return FALSE;
  276.  
    }
  277.  
     
  278.  
    //获取ZwQuerySystemInformation函数地址
  279.  
    ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hHanlde, "ZwQuerySystemInformation");
  280.  
    if(NULL == ZwQuerySystemInformation)
  281.  
    {
  282.  
    //获取ZwQuerySystemInformation函数地址失败
  283.  
    return FALSE;
  284.  
    }
  285.  
     
  286.  
    //获取ZwQueryObject函数地址
  287.  
    ZwQueryObject = (ZWQUERYOBJECT)GetProcAddress(hHanlde, "ZwQueryObject");
  288.  
    if(NULL == ZwQueryObject)
  289.  
    {
  290.  
    //获取ZwQueryObject函数地址失败
  291.  
    return FALSE;
  292.  
    }
  293.  
     
  294.  
    //打开进程 复制句柄时用到
  295.  
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
  296.  
    PROCESS_DUP_HANDLE, FALSE, pid);
  297.  
     
  298.  
    if(hProcess == NULL)
  299.  
    {
  300.  
    return FALSE;
  301.  
    }
  302.  
    //获取系统所有句柄信息
  303.  
    do
  304.  
    {
  305.  
    //申请内存
  306.  
    pHandleInfor = (ULONG*)malloc(ulSize);
  307.  
    if(NULL == pHandleInfor)
  308.  
    {
  309.  
    //申请内存失败
  310.  
    CloseHandle(hProcess);
  311.  
    return FALSE;
  312.  
    }
  313.  
     
  314.  
    ntStatus = ZwQuerySystemInformation( SystemHandleInformation, pHandleInfor, ulSize, NULL);
  315.  
    if(!NT_SUCCESS(ntStatus))
  316.  
    {
  317.  
    //空间不足继续申请。
  318.  
    free(pHandleInfor);
  319.  
    ulSize = ulSize * 2;
  320.  
    //为防止ZwQuerySystemInformation一直失败,程序陷入死循环,当申请的空间超过64M时则返回失败
  321.  
    if(ulSize > 0x4000000)
  322.  
    {
  323.  
    CloseHandle(hProcess);
  324.  
    return FALSE;
  325.  
    }
  326.  
    }
  327.  
    }while(!NT_SUCCESS(ntStatus));
  328.  
    //转换数据结构类型
  329.  
    lpHandles = (PSYSTEM_HANDLE_INFORMATIONS)pHandleInfor;
  330.  
    if(NULL == lpHandles)
  331.  
    {
  332.  
    CloseHandle(hProcess);
  333.  
    return FALSE;
  334.  
    }
  335.  
    //申请空间,用于存储对象的名字信息和对象类型名字
  336.  
    ObjName = (POBJECT_NAME_INFORMATION)malloc(0x512);
  337.  
    TypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x512);
  338.  
    lpHandleBasic = (POBJECT_BASIC_INFORMATION)malloc(sizeof(OBJECT_BASIC_INFORMATION));
  339.  
    //开始搜索获取的句柄信息,并对句柄对应的对象名进行比较,如果与要求关闭的名字相同,则关闭此句柄
  340.  
    //printf("%d\n",lpHandles->NumberOfHandles);
  341.  
    for(i = 0; i < lpHandles->NumberOfHandles; i++)
  342.  
    {
  343.  
    if(pid != lpHandles->Handles[i].ProcessId)
  344.  
    {
  345.  
    //printf("%d\n",lpHandles->Handles[i].ProcessId);
  346.  
    continue;
  347.  
    }
  348.  
     
  349.  
    if(DuplicateHandle(hProcess,(HANDLE)lpHandles->Handles[i].Handle,GetCurrentProcess(),&hTest,0,FALSE,DUPLICATE_SAME_ACCESS))
  350.  
    {
  351.  
    Count++;
  352.  
    //获取这个对象的类型名
  353.  
    ntStatus = ZwQueryObject(hTest,ObjectTypeInformation,TypeInfo,0x512,NULL);
  354.  
    if(!NT_SUCCESS(ntStatus))
  355.  
    {
  356.  
    //查询失败
  357.  
    continue;
  358.  
    }
  359.  
    ntStatus = ZwQueryObject(hTest,ObjectBasicInformation,lpHandleBasic,sizeof(OBJECT_BASIC_INFORMATION),NULL);
  360.  
    if(!NT_SUCCESS(ntStatus))
  361.  
    {
  362.  
    //查询失败
  363.  
    continue;
  364.  
    }
  365.  
    //获取这个对象的名字信息
  366.  
    _beginthreadex(NULL,0,ZwThreadProc,NULL,0,&dwThread);
  367.  
    DWORD dwSatu = WaitForSingleObject(g_Event,500);
  368.  
    if(dwSatu == WAIT_TIMEOUT){
  369.  
    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);
  370.  
    hThread = OpenThread(THREAD_TERMINATE,FALSE,dwThread);
  371.  
    if(!TerminateThread(hThread,0)){
  372.  
    CloseHandle(hThread);
  373.  
    ExitProcess(0);
  374.  
    }
  375.  
    CloseHandle(hThread);
  376.  
    continue;
  377.  
     
  378.  
    }
  379.  
    if(g_ZwFaild)
  380.  
    {
  381.  
    g_ZwFaild = FALSE;
  382.  
    continue;
  383.  
    }
  384.  
    /*
  385.  
    //将unicode 字串转换为 ansi字串
  386.  
    WideCharToMultiByte(CP_ACP, 0, ObjName->Name.Buffer, -1, pName, 200, NULL, NULL);
  387.  
    if( 0 == strcmp(pName, pObjectName))
  388.  
    {
  389.  
    //找到对应名字的对象,将其关闭
  390.  
    CloseHandle((HANDLE)Handles->Information[i].Handle);
  391.  
    }
  392.  
    */
  393.  
    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);
  394.  
    wprintf(L"HandleName:%wZ\n",ObjName->Name);
  395.  
    printf("\nRedeferCount:%d\n",lpHandleBasic->ReferenceCount);
  396.  
     
  397.  
    }else
  398.  
    {
  399.  
    errorCode = GetLastError();
  400.  
    if(errorCode == 0x32)//不支持读写的句柄 Etw
  401.  
    {
  402.  
    printf("ObjectTypeIndex:0x27---HandleAttributes:000000---Handle:0x%x---Object:%p\n",lpHandles->Handles[i].Handle,lpHandles->Handles[i].Object);
  403.  
    Count++;
  404.  
    }
  405.  
    }
  406.  
    }
  407.  
     
  408.  
    //释放申请的空间
  409.  
    free(lpHandles);
  410.  
    free(ObjName);
  411.  
    free(TypeInfo);
  412.  
    free(lpHandleBasic);
  413.  
    CloseHandle(hProcess);
  414.  
     
  415.  
    printf("Pid:%d----HandleCount:%d\n",pid,Count);
  416.  
    return TRUE;
  417.  
    }
  418.  
     
  419.  
     
  420.  
    void main()
  421.  
    {
  422.  
    ThreadEnumHandleByZwQuerySystemInformation(2292);
  423.  
    getchar();
  424.  
    }

关于ZwDuplicateObject的妙用可以参考我的另一篇文章,在复制的时候就可以关闭对方的句柄

http://blog.csdn.net/zhuhuibeishadiao/article/details/51046595

05-17 19:39