windows 句柄和句柄表

来源:互联网 发布:专业作曲软件 编辑:程序博客网 时间:2024/05/29 16:15

句柄

    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;   }