2009-04-09 12 views
21

¿Hay alguna forma de enumerar el proceso con un PID dado en Windows, y obtener una lista de todos sus identificadores abiertos (archivos bloqueados, etc.)?¿Cómo se enumeran los identificadores del proceso?

EDIT: No me importa el lenguaje. Si está en .NET, me alegra que, si está en WinApi (C), no duela. Si está en otra cosa, creo que puedo reescribirlo :-)

Respuesta

23

Hice un google profundo y encontré esto article. Este artículo dio un enlace a download source code:

Probé el método en NtSystemInfoTest.cpp (código fuente descargado) y funcionó magníficamente.

void ListHandles(DWORD processID, LPCTSTR lpFilter) 

El código siguiente ha declamador:

// 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 
// 
////////////////////////////////////////////////////////////////////////////////////// 
// 

espero que esto le ayuda.

+0

¡Excelente! Es exactamente lo que necesitaba (y no pude googlear). Gracias. :-) – nothrow

4

Here is an example usando ZwQueryProcessInformation desde el DDK. El DDK ahora se conoce como el "WDK" y está disponible con MSDN. Si no tiene MSDN, al parecer, también puede obtenerlo en here.

No lo he intentado, simplemente busqué en Google su pregunta.

#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; 
} 
+0

Bueno, busqué en Google también, pero no ha podido descargar DDK para Vista :-(Así que pensé, que hay una cierta otra solución (ProcessExplorer de sysinternals no enlaza ntdll en absoluto) – nothrow

+0

ProcessExplorer no enlaza estáticamente a ntdll pero lo cargará en tiempo de ejecución. Lo puede encontrar con un depende –

+0

¿Cómo funciona esta solución colgando si está haciendo ZwQueryObject (.. ObjectNameInformation ..) en un pipe con open con SYNC_READ? – mrduclaw

5

El 'Handle' herramienta de línea de comandos de Sysinternals hace esto, si lo que desea es una herramienta. Sin embargo, esto no te ayudará si estás buscando una solución de código.

Cuestiones relacionadas