2009-04-09 5 views
21

Windows에서 주어진 PID로 프로세스를 열거하고 열린 모든 핸들 (잠긴 파일 등)의 목록을 얻는 방법이 있습니까?프로세스 '핸들을 열거하는 방법?

편집 : 언어에 대해서는 신경 쓰지 않습니다. 그것이 .NET에 있다면, WinApi (C)에 있다면 다행이 아닐 테니 다행입니다. 다른 것, 나는 그것을 다시 쓸 수 있다고 생각한다 :-)

답변

23

나는 굉장히 인터넷 검색을 수행했으며 article을 발견했습니다. 이 기사는 download source code에 대한 링크를 제공 했음 :

NtSystemInfoTest.cpp (다운로드 된 소스 코드)의 메소드를 사용해 보았는데 멋지게 작동했습니다. 이 코드는 declaimer 다음있다

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

나는이 당신을 도움이되기를 바랍니다.

+0

멋지다! 정확히 내가 필요로하는 (그리고 Google을 할 수 없었다). 감사합니다. :-) – nothrow

4

Here is an example DDK에서 ZwQueryProcessInformation을 사용한다. DDK는 현재 "WDK"로 알려져 있으며 MSDN에서 사용할 수 있습니다. MSDN이 없다면 here에서 얻을 수도 있습니다.

나는 그것을 시도하지 않았다, 나는 다만 당신의 질문을 googled.

#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

글쎄, 나도 그것을 인터넷 검색,하지만 그래서 몇 가지가 있다고 생각 :-(나는 Vista 용 DDK를 다운로드 할 수 없습니다 다른 해결책 (sysinternals의 ProcessExplorer가 전혀 ntdll 링크가 아님) – nothrow

+0

ProcessExplorer가 ntdll에 정적으로 링크하지 않지만 런타임에로드합니다. –

+0

어떻게하면이 솔루션을 사용할 수 있습니까? SYNC_READ로 열린 파이프에서 ZwQueryObject (.. ObjectNameInformation ..)를 수행 하시겠습니까? – mrduclaw

5

당신은 단지 도구를 원하는 경우 시스 인 터널에서 명령 줄 'Handle'도구이를 수행합니다. 비록 당신이 코드 솔루션을 찾고 있다면 이것은 도움이되지 않습니다.

관련 문제