2009-04-09 16 views
21

क्या कोई तरीका है कि विंडोज़ में दिए गए पीआईडी ​​के साथ प्रक्रिया को कैसे समझाएं, और उसके सभी खुले हैंडल (लॉक की गई फाइलें इत्यादि) की सूची प्राप्त करें?प्रक्रिया 'हैंडल की गणना कैसे करें?

संपादित करें: मुझे भाषा के बारे में परवाह नहीं है। यदि यह .NET में है, तो मुझे खुशी होगी, अगर WinApi (सी) में, यह चोट नहीं पहुंचाएगा। अगर किसी और चीज में, मुझे लगता है कि मैं इसे फिर से लिख सकता हूं :-)

उत्तर

23

मैंने गहरी गुगल किया और यह article पाया। इस आलेख ने download source code:

पर एक लिंक दिया, मैंने NtSystemInfoTest.cpp (डाउनलोड स्रोत कोड) में विधि की कोशिश की और यह शानदार काम किया।

void ListHandles(DWORD processID, LPCTSTR lpFilter) 

कोड Declaimer निम्नलिखित है:

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

मुझे आशा है कि यह आप में मदद करता है।

+0

शानदार! यह वही है जो मुझे चाहिए (और Google में असमर्थ नहीं था)। धन्यवाद। :) – nothrow

4

Here is an example डीडीके से ZwQueryProcessInformation का उपयोग कर। डीडीके अब "डब्लूडीके" के रूप में जाना जाता है और एमएसडीएन के साथ उपलब्ध है। यदि आपके पास एमएसडीएन नहीं है, तो आप इसे 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; 
} 
+0

ठीक है, मैं यह भी googled, लेकिन :-(तो मैंने सोचा, कुछ है कि वहाँ मैं Vista के लिए DDK डाउनलोड करने में असमर्थ था अन्य समाधान (sysinternals से ProcessExplorer सभी को ntdll से लिंक नहीं करता है) – nothrow

+0

ProcessExplorer स्थिर रूप से ntdll से लिंक नहीं करता है लेकिन यह इसे रनटाइम पर लोड करेगा। आप इसे एक निर्भर के साथ पा सकते हैं। –

+0

यदि आप हैं तो इस समाधान के आसपास आप कैसे काम करते हैं ZNCQueryObject (.. ObjectNameInformation ..) को एक पाइप पर SYNC_READ के साथ खोला गया है? – mrduclaw

5

कमांड लाइन 'Handle' Sysinternals से उपकरण इस करता है, अगर आप सिर्फ एक उपकरण चाहते हैं। यदि आप कोड समाधान की तलाश में हैं, तो यह आपकी मदद नहीं करेगा।

3

और यहाँ क्या Sysinternals मंच से एक अच्छा जवाब की तरह लग रहा है: HOWTO: Enumerate handles

संबंधित मुद्दे