} 0匕口仏^^^^1^161&1^6是与系统进程相关的句柄,用于存放内核模式下的所有句柄,这 类句柄只允许运行在&1^0级下的代码访问。句柄的属性设置可调^^^ 11^乜&112601^6(^41让让的68宏实现,即设置宏参数人丨让让说^^^一础财^1一_01£即可0 图2给出186系统上每个单一句柄表节点的大致结构,占2个32^^^括对象结构的内核模 式地址以及标识开放资源权限的访问掩码等。化仏标识即标记当前句柄是否正在使用; 1汕虹^31^6若被设置,则标记为给定的对象可被父^^^^6^^程继承;第三个标识则 用于标记句柄关闭时是否生成审计日志。这几个域都十分重^除了化仏标识会在进程调用 CloseHandle时清除Lockflag外,其它两个标识^^用)以被用户控制。详细信息读者可参考” MSDN, SetHandleInformation Function, http://msdn. microsoft. com/en-us/lihy5fVnisr^4635%28v=vs. 85%29. aspx. ” ^ffi*^HANDLE_TABLE_ENTRYft<I^M^4^T : kd> dt _HANDLE_TABLE_ENTRY nt!_HANDLE_TABLE_ENTRY +0x000 Object : Ptr32 Void //指向句柄所代表的对象 +0x000 0bAttributes : Uint4B +0x000 InfoTable : Ptr32 _HANDLE_TABLE_ENTRY_INF0 +0x000 Value : Uint4B +0x004 GrantedAccess : Uint4B //记录了该句柄的访问掩码 +0x004 GrantedAccessIndex : Uint2B +0x006 CreatorBackTraceIndex : Uint2B +0x004 NextFreeTab 1 eEntry : Int4B //空闲时表示下一个空闲句柄索 引 31 0 Access Mask rp 句柄分配 Microsoft并没有提供接口文档可直接操作内部句柄结构,如句柄表。句柄的分配完全 由对象管理器负责,并不向第三方町1^(^8程序开发人员公开。如图3所示,用户模式下的句 柄操作只能借助特定对象类型的服务函数GnNtCreateFile, NtCreateJobObject)或者 财010%等,而内核模块下则可使用类似力"仍~游导出函数,但仍然无法直接使用底层的句 柄分配函数。为了了解上层八?1函数请求句柄对象时,系统内部是如何实现资源分配的,下 面将深入调查未导出的对象管理器相关函数。 User mode -publicAPI interface CreateFile | CreateJobObject | CloseHandle Image 3. Windows Kernel object manipulation interface layers >1 mode — private Object Manager interface (handle management) ObpCreateHandle O b pAI locateO bj ect ObpCloseHandle 任一进程在创建对象时,系统都要为此对象分配一个句柄,即在进程的句柄表中创建一 个新句柄。就句柄分配而言,1^!03卩&6&1611&1^16函数主要用来初始化两个局部变量 PHAM)LE_TABLEfDHANDLE_TABLE_ENTRY.然后在__ @&用£1&6&丨61131^16创建一个句柄 ^^Entry,并初始化此表项,部分实现如下: NTSTATUS ObpCreateHandle ( IN 0B_0PEN_REAS0N OpenReason, IN PVOID Object, IN POBJECT_TYPE ExpectedObjectType OPTIONAL, IN PACCESS_STATE AccessState, IN ULONG ObjectPointerBias OPTIONAL, IN ULONG Attributes, IN P0BP_L00KUP_C0NTEXT LookupContext, IN KPR0CESS0R_M0DE AccessMode, OUT PVOID *ReferencedNewObject OPTIONAL, OUT PHANDLE Handle) PVOID ObjectTable; HANDLE_TABLE_ENTRY ObjectTableEntry; HANDLE NewHandle; /*获取对象头及类型并检测类型是否匹配*/ (…) /*检验是否为内核句柄*/ if (Attributes & OBJ_KERNEL_HANDLE){ ObjectTable = ObpKernelHandleTable; (•••) //判断此进程是否为系统进程 else{ ObjectTable = PsGetCurrentProcess () ->ObjectTable; //获取当前句柄表 } /*初始化01^6(^了&1^6£1^^. Object and ObjectTableEntry. GrantedAccess*/ /*调用ExCreateHandle之前需要调用ObpIncrementHandleCount ()函数增加句柄计 数,*/ /*确保对象安全性有效*/ NewHandle = ExCreateHandle( ObjectTable, &ObjectTableEntry ); (…) 函数的具体实现代码读者可参考 http://doxygen. reactos. org/d4/df6/obhandle_8c_a202d5 72ea4dc48c5dd053923c01e867a. html.函数故!£10^&161^1^16实际上封装了真正的句 柄分配函数即1^!£1口41100&丨6服1^161&1)16£1^17,系统通过 £叉口人11003纟6此1^161&616£01^实现句柄的分配,然后将此1^16了&616£1^^结构体各参 数赋值给新创建的£故[7.函数£10^&〖61^1^16的实现代码如下: HANDLE NTAPI ExCreateHandle (IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry ) { EXHANDLE Handle; PHANDLE_TABLE_ENTRY NewEntry; PAGED_CODE(); /* Start with a clean handle */ Handle. GenericHandleOverlay = NULL; /*分配一个新句柄表项*/ |