我想枚举一个进程(自己写的应用程序)中的所有句柄,包括线程,资源,文件等等。有什么好方法吗?
传说中的NtQuerySystemInformation可以吗。

解决方案 »

  1.   

    NtQuerySystemInformation价格便宜量又足,我们一直用它
      

  2.   


    BOOL   CALLBACK   EnumWindowsProc(                     HWND   hwnd, 
        LPARAM   lParam 
        ) 

    DWORD   PID=(DWORD)lParam; 
    DWORD   tempPID; 
    GetWindowThreadProcessId(hwnd,&tempPID); 
    if(PID==tempPID) 

      // hwnd是这个进程的窗口

     return false;       } 
          EnumWindows(     
    WNDENUMPROC       EnumWindowsProc,   //       pointer       to       callback       function     
    (LPARAM)       dwProcessId     //       application-defined       value     
    );
      

  3.   


    //#pragma pack(1)
    typedef struct _PROC_HANDLE_INFO

    ULONG ProcessId; //0  进程的标识ID 
    UCHAR ObjectTypeNumber; //4  对象类型 
    UCHAR Flags; //5  0x01 = PROTECT_FROM_CLOSE,0x02 = INHERIT 
    USHORT Handle; //6  对象句柄的数值 
    PVOID Object; //8  对象句柄所指的内核对象地址 
    DWORD GrantedAccess; //C  创建句柄时所准许的对象的访问权 
    }PROC_HANDLE_INFO, * PPROC_HANDLE_INFO;DWORD GetProcHandle(DWORD pid, PROC_HANDLE_INFO StructHandle[], DWORD dwStructStcCount)
    {
    BYTE *mbuf = NULL;
    DWORD re,nedsize,Count;
    DWORD i,nedCount = 0,j;
    Fun4 QuerySysInfo;
    PPROC_HANDLE_INFO pHandleInfo;
    QuerySysInfo = (Fun4)::GetProcAddress(::LoadLibraryA("NTDLL.DLL"),"NtQuerySystemInformation");
    if(QuerySysInfo == NULL)
    {
            Msg("取NtQuerySystemInformation 函数失败! Code:%08X", ::GetLastError());
    return 0;
    }
    nedsize = 16*1024;
    re = STATUS_INFO_LENGTH_MISMATCH;
    while(STATUS_INFO_LENGTH_MISMATCH == re)
    {
    nedsize *= 2;
    if(mbuf) free(mbuf);
            mbuf = (BYTE *)malloc(nedsize);
            re = QuerySysInfo(SystemHandleInformation,(DWORD)mbuf,nedsize,(DWORD)&nedsize);
    if(nedsize > 20*1024*1024 || (re != STATUS_INFO_LENGTH_MISMATCH && re != 0))
    {
    free(mbuf);
    Msg("NtQuerySystemInformation 函数调用失败! re:%08X nedsize:%d",re,nedsize);
    return 0;
    }
    }
    Count = *(DWORD *)mbuf;
    pHandleInfo = (PPROC_HANDLE_INFO)(mbuf + sizeof(DWORD));
    if(StructHandle == NULL || dwStructStcCount == 0) //得到Handle总数目
    {
    if(pid == 0) //所有进程的
    {
    nedCount = Count;
    }
    else //指定进程的
    {
    for(i=0,nedCount=0; i<Count; i++)
    {
    if(pHandleInfo[i].ProcessId == pid) nedCount++;
    }
    }
    free(mbuf);
    return nedCount;
    }
    if(pid == 0) //复制所有进程的
    {
    if(dwStructStcCount > Count) dwStructStcCount = Count;
    memcpy(StructHandle, pHandleInfo, dwStructStcCount*sizeof(PPROC_HANDLE_INFO));
    free(mbuf);
    return dwStructStcCount;
    }
    for(i=0,j=0;i<Count;i++) //复制指定进程的
    {
    if(pHandleInfo[i].ProcessId == pid)
    {
    memcpy(&StructHandle[j], &pHandleInfo[i], sizeof(PROC_HANDLE_INFO));
    j++;
    }
    }
    free(mbuf);
    return j;
    }
      

  4.   

    样例代码,需要DDK:#include "ntdll.h"
    #include <stdlib.h>
    #include <stdio.h>
    #include "ntddk.h"#define DUPLICATE_SAME_ATTRIBUTES   0x00000004#pragma comment(lib,"ntdll.lib")BOOL EnablePrivilege(PCSTR name)
    {
        TOKEN_PRIVILEGES priv = {1, {0, 0, SE_PRIVILEGE_ENABLED}};
        LookupPrivilegeValue(0, name, &priv.Privileges[0].Luid);    HANDLE hToken;
        OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);    AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof priv, 0, 0);
        BOOL rv = GetLastError() == ERROR_SUCCESS;    CloseHandle(hToken);
        return rv;
    }int main(int argc, char *argv[])
    {
        if (argc == 1) return 0;    ULONG pid = strtoul(argv[1], 0, 0);    EnablePrivilege(SE_DEBUG_NAME);    HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid);    ULONG n = 0x1000;
        PULONG p = new ULONG[n];    while (NT::ZwQuerySystemInformation(NT::SystemHandleInformation, p, n * sizeof *p, 0)
               == STATUS_INFO_LENGTH_MISMATCH)        delete [] p, p = new ULONG[n *= 2];    NT::PSYSTEM_HANDLE_INFORMATION h = NT::PSYSTEM_HANDLE_INFORMATION(p + 1);    for (ULONG i = 0; i < *p; i++) {        if (h[i].ProcessId == pid) {
                HANDLE hObject;            if (NT::ZwDuplicateObject(hProcess, HANDLE(h[i].Handle), NtCurrentProcess(), &hObject,
                                          0, 0, DUPLICATE_SAME_ATTRIBUTES)
                    != STATUS_SUCCESS) continue;            NT::OBJECT_BASIC_INFORMATION obi;            NT::ZwQueryObject(hObject, NT::ObjectBasicInformation, &obi, sizeof obi, &n);            printf("%p %04hx %6lx %2x %3lx %3ld %4ld ", 
                       h[i].Object, h[i].Handle, h[i].GrantedAccess,
                       int(h[i].Flags), obi.Attributes,
                       obi.HandleCount - 1, obi.PointerCount - 2);            n = obi.TypeInformationLength + 2;            NT::POBJECT_TYPE_INFORMATION oti = NT::POBJECT_TYPE_INFORMATION(new CHAR[n]);            NT::ZwQueryObject(hObject, NT::ObjectTypeInformation, oti, n, &n);            printf("%-14.*ws ", oti[0].Name.Length / 2, oti[0].Name.Buffer);            n = obi.NameInformationLength == 0 
                    ? MAX_PATH * sizeof (WCHAR) : obi.NameInformationLength;            NT::POBJECT_NAME_INFORMATION oni = NT::POBJECT_NAME_INFORMATION(new CHAR[n]);            NTSTATUS rv = NT::ZwQueryObject(hObject, NT::ObjectNameInformation, oni, n, &n);
                if (NT_SUCCESS(rv))
                    printf("%.*ws", oni[0].Name.Length / 2, oni[0].Name.Buffer);            printf("\n");            CloseHandle(hObject);
            }
        }
        delete [] p;    CloseHandle(hProcess);    return 0;
    }