windows 句柄和句柄表

本文详细介绍了Windows系统中句柄的内部实现原理,包括句柄的结构、句柄表的组织方式及其层级结构,以及如何从句柄解析出对应的内核对象等关键信息。

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

句柄

    Windows支持的句柄是一个索引,指向该句柄所在进程的句柄表中的一个表项。例如,在C运行库中,文件操作使用句柄来表示,每当应用程序创建或打开一个文件时,只要此创建或打开操作成功,则C运行库返回一个句柄。以后应用程序对文件的读写操作都使用此句柄来标示该文件。
    handle是一个32位的数,其中2~10位表示0级表的索引,11~20位表示1级表的索引,21~30位表示2级表的索引。
    struct {
       ULONG_PTR   TagBits2:2
       ULONG_PTR   LowIndex:HANDLE_LOW_BITS (2~10)
       ULONG_PTR   MidIndex:HANDLE_HIGH_BITS (11~20)
       ULONG_PTR   HighIndex:HANDLE_HIGH_BITS (21~30)
       ULONG_PTR   KernelFlag:1
    }; 

句柄表

    句柄表是一个多层结构。
    struct _HANDLE_TABLE{
        ULONG_PTR TableCode;
        ...
    }
    TableCode域是一个指针,指向句柄表的最高层表项页面,它的低2位的值代表了当前句柄表的层数。也就是说,如果TableCode的最低2位为0,说明句柄表只有一层;如果TableCode的最低2位为1,则说明句柄表有两层;如果TableCode的最低2位为2,则说明句柄表有三层。

句柄表项

    struct _HANDLE_TABLE_ENTRY{
        PVOID Object;
        ...
    }
    Object指针指向句柄所代表的的内核对象,它的最低3位有特别含义:第0位OBJ_PROTECT_CLOSE,表示调用者是否允许关闭该句柄;第1位OBJ_INHERIT指示该进程所创建的子进程是否可以继承该句柄,即是否将该句柄项拷贝到它们的句柄表中;第2位OBJ_AUDIT_OBJECT_CLOSE,指示关闭该对象时是否产生一个审计事件。

将一个句柄解析成相应的内核对象

    首先,一个有效的句柄有4中可能:
    -1,代表当前进程
    -2,代表当前线程
    负值,其绝对值为内核句柄表中的索引,即system进程的句柄表
    正值,当前进程的句柄表中的索引

    下面代码根据TableCode和Handle获得object。
    /* Get the table code */
    TableBase = HandleTable->TableCode;

    /* Extract the table level and actual table base */
    TableLevel = (ULONG)(TableBase & 3);
    TableBase &= ~3;

    PointerArray = (PVOID*)TableBase;
    HandleArray = (PHANDLE_TABLE_ENTRY)TableBase;

    /* Check what level we're running at */
    switch (TableLevel)
      {
      case 2:
         /* Get the mid level pointer array */
          PointerArray = PointerArray[Handle.HighIndex];

         /* Fall through */
      case 1:

         /* Get the handle array */
          HandleArray = PointerArray[Handle.MidIndex];

         /* Fall through */
      case 0:

         /* Get the entry using the low index */
          Entry = &HandleArray[Handle.LowIndex];

         /* All done */
          break;
      default:
          ASSERT(FALSE);
          Entry = NULL;
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值