代码之家  ›  专栏  ›  技术社区  ›  nothrow

如何枚举进程的句柄?

  •  24
  • nothrow  · 技术社区  · 16 年前

    有没有什么方法可以在Windows中用给定的PID枚举进程,并获取所有打开的句柄(锁定的文件等)的列表?

    编辑:我不在乎语言。如果它在.NET中,我会很高兴,如果在WinAPI(C)中,它不会受到伤害。如果在其他方面,我想我可以重写它:—)

    4 回复  |  直到 6 年前
        1
  •  26
  •   aJ.    16 年前

    我咕噜了一声发现了这个 article . 本文给出了一个链接 download source code :

    我在ntsysteminfotest.cpp(下载的源代码)中尝试了这个方法,它运行得非常好。

    void ListHandles( DWORD processID, LPCTSTR lpFilter )
    

    代码有以下声明:

    // Written by Zoltan Csizmadia, zoltan_csizmadia@yahoo.com
    // For companies(Austin,TX): If you would like to get my resume, send an email.
    //
    // The source is free, but if you want to use it, mention my name and e-mail address
    //
    //////////////////////////////////////////////////////////////////////////////////////
    //
    

    希望这对你有帮助。

        2
  •  6
  •   Zac Thompson    16 年前

    命令行' Handle '来自SysInternals的工具可以这样做,如果您只需要一个工具的话。不过,如果您正在寻找代码解决方案,这对您没有帮助。

        3
  •  4
  •   1800 INFORMATION    16 年前

    Here is an example 使用 ZwQueryProcessInformation 来自DDK。DDK现在被称为“WDK”,可与msdn一起使用。如果你没有,显然,你也可以从 here .

    我没试过,只是在谷歌上搜索了你的问题。

    #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;
    }
    
        4
  •  3
  •   Max    6 年前

    下面是SysInternals论坛的一个好答案: HOWTO: Enumerate handles