2009-04-09 19 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

まあ、私もそれをGoogleで検索、しかし、だから私はいくつか存在することが、思った:-(私はVista用DDKをダウンロードすることができませんでしたそれ以外の場合は解決策(sysinternalsのProcessExplorerは全くリンクできません) – nothrow

+0

ProcessExplorerはntdllに静的にリンクしませんが、実行時にロードされます。 –

+0

このソリューションを回避するにはどうすればよいですか? SYNC_READでオープンされたパイプ上でZwQueryObject(.. ObjectNameInformation ..)を実行していますか? – mrduclaw

5

あなただけのツールをしたい場合はSysinternalsのコマンドライン「Handle」ツールは、これを行います。あなたがコードソリューションを探しているなら、これはあなたを助けません。

3

そして、ここでは、Sysinternalsのフォーラムから良い答えのようになります。 HOWTO: Enumerate handles

関連する問題