如何枚举到一个进程中的所有句柄

truelove7283159 2007-11-22 02:15:21
我想枚举一个进程(自己写的应用程序)中的所有句柄,包括线程,资源,文件等等。有什么好方法吗?
传说中的NtQuerySystemInformation可以吗。
...全文
755 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
dyw 2007-11-22
  • 打赏
  • 举报
回复
样例代码,需要DDK:

#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;
}
Yofoo 2007-11-22
  • 打赏
  • 举报
回复

//#pragma pack(1)
typedef struct _PROC_HANDLE_INFO
{
ULONG ProcessId; //0 进程的标识ID
UCHAR ObjectTypeNumber; //4 对象类型
UCHAR Flags; //5 0x01 = PROTECT_FROM_CLOSE,0x02 = INHERIT
USHORT Handle; //6 对象句柄的数值
PVOID Object; //8 对象句柄所指的内核对象地址
DWORD GrantedAccess; //C 创建句柄时所准许的对象的访问权
}PROC_HANDLE_INFO, * PPROC_HANDLE_INFO;

DWORD GetProcHandle(DWORD pid, PROC_HANDLE_INFO StructHandle[], DWORD dwStructStcCount)
{
BYTE *mbuf = NULL;
DWORD re,nedsize,Count;
DWORD i,nedCount = 0,j;
Fun4 QuerySysInfo;
PPROC_HANDLE_INFO pHandleInfo;
QuerySysInfo = (Fun4)::GetProcAddress(::LoadLibraryA("NTDLL.DLL"),"NtQuerySystemInformation");
if(QuerySysInfo == NULL)
{
Msg("取NtQuerySystemInformation 函数失败! Code:%08X", ::GetLastError());
return 0;
}
nedsize = 16*1024;
re = STATUS_INFO_LENGTH_MISMATCH;
while(STATUS_INFO_LENGTH_MISMATCH == re)
{
nedsize *= 2;
if(mbuf) free(mbuf);
mbuf = (BYTE *)malloc(nedsize);
re = QuerySysInfo(SystemHandleInformation,(DWORD)mbuf,nedsize,(DWORD)&nedsize);
if(nedsize > 20*1024*1024 || (re != STATUS_INFO_LENGTH_MISMATCH && re != 0))
{
free(mbuf);
Msg("NtQuerySystemInformation 函数调用失败! re:%08X nedsize:%d",re,nedsize);
return 0;
}
}
Count = *(DWORD *)mbuf;
pHandleInfo = (PPROC_HANDLE_INFO)(mbuf + sizeof(DWORD));
if(StructHandle == NULL || dwStructStcCount == 0) //得到Handle总数目
{
if(pid == 0) //所有进程的
{
nedCount = Count;
}
else //指定进程的
{
for(i=0,nedCount=0; i<Count; i++)
{
if(pHandleInfo[i].ProcessId == pid) nedCount++;
}
}
free(mbuf);
return nedCount;
}
if(pid == 0) //复制所有进程的
{
if(dwStructStcCount > Count) dwStructStcCount = Count;
memcpy(StructHandle, pHandleInfo, dwStructStcCount*sizeof(PPROC_HANDLE_INFO));
free(mbuf);
return dwStructStcCount;
}
for(i=0,j=0;i<Count;i++) //复制指定进程的
{
if(pHandleInfo[i].ProcessId == pid)
{
memcpy(&StructHandle[j], &pHandleInfo[i], sizeof(PROC_HANDLE_INFO));
j++;
}
}
free(mbuf);
return j;
}
yxz_lp 2007-11-22
  • 打赏
  • 举报
回复

BOOL CALLBACK EnumWindowsProc( HWND hwnd,
LPARAM lParam
)
{
DWORD PID=(DWORD)lParam;
DWORD tempPID;
GetWindowThreadProcessId(hwnd,&tempPID);
if(PID==tempPID)
{
// hwnd是这个进程的窗口
}
return false;

}
EnumWindows(
WNDENUMPROC EnumWindowsProc, // pointer to callback function
(LPARAM) dwProcessId // application-defined value
);
WingForce 2007-11-22
  • 打赏
  • 举报
回复
NtQuerySystemInformation价格便宜量又足,我们一直用它

15,467

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧