Как перечислить дескрипторы процесса?

Есть ли способ перечислить процесс с заданным PID в Windows и получить список всех его открытых дескрипторов (заблокированных файлов и т. д.)?

РЕДАКТИРОВАТЬ: Меня не волнует язык. Если на .NET, то буду рад, если на WinApi(C), то не помешает. Если в чем-то другом, думаю, можно переписать :-)


person nothrow    schedule 09.04.2009    source источник


Ответы (3)


Я глубоко погуглил и нашел эту статью. В этой статье дана ссылка на скачать исходный код:

Я попробовал метод в NtSystemInfoTest.cpp (скачал исходный код), и он отлично сработал.

void ListHandles( DWORD processID, LPCTSTR lpFilter )

Код имеет следующий декламер:

// Written by Zoltan Csizmadia, [email protected]
// 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
//
//////////////////////////////////////////////////////////////////////////////////////
//

Я надеюсь, это поможет вам.

person aJ.    schedule 15.04.2009
comment
Превосходно! Это именно то, что мне было нужно (и я не смог погуглить). Спасибо. :-) - person nothrow; 15.04.2009
comment
К сожалению, хотя это работает, все же требуется вызов NtQuerySystemInformation, который возвращает все дескрипторы, которые затем необходимо повторять и фильтровать по требуемому PID. Я не знаю способа запросить у ОС дескрипторы только для одного процесса. - person Bartek Banachewicz; 05.12.2018

Инструмент командной строки 'Handle от Sysinternals делает это, если вам просто нужен инструмент. Однако это не поможет вам, если вы ищете решение для кода.

person Zac Thompson    schedule 13.04.2009

Вот пример использования ZwQueryProcessInformation из DDK. DDK теперь известен как «WDK» и доступен в MSDN. Если у вас нет MSDN, очевидно, вы также можете получить его по адресу здесь.

Я не пробовал, я просто гуглил ваш вопрос.

#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;
}
person 1800 INFORMATION    schedule 09.04.2009
comment
Ну, я тоже погуглил, но не смог скачать DDK для Vista :-( Вот я и подумал, что есть какое-то другое решение (ProcessExplorer от sysinternals вообще не связывает ntdll) - person nothrow; 09.04.2009
comment
ProcessExplorer не связывается статически с ntdll, но загружает его во время выполнения. Вы можете найти его с зависимостями. - person Shay Erlichmen; 11.04.2009
comment
Как вы обходитесь с зависанием этого решения, если вы выполняете ZwQueryObject(.. ObjectNameInformation..) в канале, открытом с помощью SYNC_READ? - person mrduclaw; 25.08.2010
comment
@nothrow — каждый процесс неявно связан с ntdll, это часть загрузчика Windows. Это обсуждается в книге Марка Руссиновича «Внутреннее устройство Windows», см. главу 3 «Загрузчик изображений». - person antiduh; 10.11.2018