windows进程句柄表

本文介绍了Windows操作系统中进程的句柄表,包括句柄的概念、好处,以及如何通过调试工具Windbg查找进程的句柄表。句柄是访问资源的高效、封装的方式,句柄表则用于管理这些句柄,存在于_EPROCESS结构中的ObjectTable字段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.介绍

1.什么是句柄

句柄windows应用程序用来表示资源的一个符号,几乎所有的资源对于应用程序来说都表示为一个句柄。比如文件,用CreateFile打开一个文件,成功则会得到一个句柄,其实就是一个32位无符号整数。“当一个进程根据名称来创建或者打开一个对象时,他收到一个句柄,然后通过此举并来访问该对象。”(深入解析windows操作系统,P135)。这里HANDLE类型的作用已经很清楚了。C语言fopen函数打开文件时候,会返回一个FILE类型指针,其实这东西就可以认为也是个句柄。

2.HANDLE有什么好处呢?

a.效率:“使用句柄访问对象要比使用名字访问对象快的多,因为对象管理器可以跳过名称查找过程,直接找到目标对象。”(深入解析windows操作系统,P135)。这个问题属于对象管理器范畴,不细说了。

b.封装:句柄是系统资源的一个间接指针,使得用户模式应用程序不用直接和系统数据结构打交道。windows应用程序看来,文件,进程,线程等资源统统都是一个句柄。开发者只需要获得这个句柄,然后将句柄作为参数来做有关调用。

下面这段代码就是很好的例子:

	vector<wstring> vecProcessNames;
	PROCESSENTRY32 pe32;
	HANDLE hTool;

	pe32.dwSize = sizeof(PROCESSENTRY32);
	hTool = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); //获得句柄
	if(hTool==INVALID_HANDLE_VALUE)
	{
		MessageBox(NULL, _T("获得Toolhelp32Snapshot句柄失败"), _T("错误"), MB_OK);
		return 1;
	}

	if(Process32First(hTool, &pe32) == TRUE) //第一个参数就是获得的句柄
	{
		while(Process32Next(hTool,&pe32))
		{
			vecProcessNames.push_back(pe32.szExeFile);
		}
	}

	CloseHandle(hTool);//关闭句柄

c.统一的资源接口:如上所说,文件,进程,线程,内存段等资源都以HANDLE出现。

d.安全性:对喜爱能够管理器可以完全监视应用程序访问的资源。

3.什么是句柄表

句柄表是windows对象管理器用来管理句柄的结构,每个进程都包含一个执行体进程结构块(_EPROCESS),而该结构中的的ObjectTable字段就是句柄表的指针。

通过windbg内核调试器找到一个进程的句柄表地址:

1.找到指定程序的process id。这里我自己写了一个程序,打开一个文件,显示当前文件句柄和当前进程号。2928 = 0xb7

2.windbg内核调试器连接到虚拟机,这个不说了,去网上赵windbg的用法吧。

3.使用!process 0xb70 7命令,获得该进程相关信息。第一个参数0xb70就是process id。

这张图中,我们可以得到很多信息:

EPROCESS结构地址:0x884a65d0

ObjectTable指针:0x949b1cc0

4.使用dt _EPROCESS 0x884a65d0即可查看到当前进程的EPROCESS结构

这里也可以看到,了ObjectTable指针是0x949b1cc0。我的调试机器是win7 32位旗舰版,ObjectTable在EPROCESS中的偏移是0xf4。别的系统可能不同。


二.句柄表结构

1._HANDLE_TABLE结构

WRK 1.2中该结构定义为:

typedef struct _HANDLE_TABLE {

    //
    //  A pointer to the top level handle table tree node.
    //	一个指向顶层句柄表树节点的指针(句柄表是一个树结构,分三层)
    ULONG_PTR TableCode;

    //
    //  The process who is being charged quota for this handle table and a
    //  unique process id to use in our callbacks
    //	所属进程的EPROCESS结构,和所属进程的id
    struct _EPROCESS *QuotaProcess;
    HANDLE UniqueProcessId;


    //
    // These locks are used for table expansion and preventing the A-B-A problem
    // on handle allocate.
    // 这些锁
#define HANDLE_TABLE_LOCKS 4
    EX_PUSH_LOCK HandleTableLock[HANDLE_TABLE_LOCKS];

    //
    //  The list of global handle tables.  This field is protected by a global
    //  lock.
    // 
    LIST_ENTRY HandleTableList;

    //
    // Define a field to block on if a handle is found locked.
    //
    EX_PUSH_LOCK HandleContentionEvent;

    //
    // Debug info. Only allocated if we are debugging handles
    //
    PHANDLE_TRACE_DEBUG_INFO DebugInfo;

    //
    //  The number of pages for additional info.
    //  This counter is used to improve the performance
    //  in ExGetHandleInfo
    //
    LONG ExtraInfoPages;

    //
    //  This is a singly linked list of free table entries.  We don't actually
    //  use pointers, but have each store the index of the next free entry
    //  in the list.  The list is managed as a lifo list.  We also keep track
    //  of the next index that we have to allocate pool to hold.
    //
    ULONG FirstFree;

    //
    // We free handles to this list when handle debugging is on or if we see
    // that a thread has this handles bucket lock held. The allows us to delay reuse
    // of handles to get a better chance of catching offenders
    //
    ULONG LastFree;

    //
    // This is the next handle index needing a pool allocation. Its also used as a bound
    // for good handles.
    //
    ULONG NextHandleNeedingPool;

    //
    //  The number of handle table entries in use.
    //
    LONG HandleCount;

    //
    // Define a flags field
    //
    union {
        ULONG Flags;

        //
        // For optimization we reuse handle values quickly. This can be a problem for
        // some usages of handles and makes debugging a little harder. If this
        // bit is set then we always use FIFO handle allocation.
        //
        BOOLEAN StrictFIFO : 1;
    };

} HANDLE_TABLE, *PHANDLE_TABLE;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值