【旧文章搬运】Windows句柄表分配算法分析(一)
原文发表于百度空间,2009-03-30 阅读提示:由于继续使用了chichou同学的CodeHighlighter来修饰代码,造成文章字数过多,故分成三篇,且后两篇内容的顺序稍有调整,阅读时请根据大标题的顺序来~
一、首先来看ExCreateHandleTable(),该函数创建一个HANDLE_TABLE结构; HandleTable = ExpAllocateHandleTable( Process,TRUE );//创建句柄表 InsertTailList( &HandleTableListHead,&HandleTable->HandleTableList );//放入双向链表中 ======================================================= PHANDLE_TABLE ExpAllocateHandleTable ( IN PEPROCESS Process OPTIONAL,IN BOOLEAN DoInit ); 过程分析: 1.申请一块PagedPool作为HANDLE_TABLE,大小为sizeof(HANDLE_TABLE) //设置TableCode为刚申请的一级表,这里其实隐含了句柄表为一级这个事实 HandleTable->TableCode = (ULONG_PTR)HandleTableTable; //下面是对这个刚申请的一级表进行初始化 HandleEntry = &HandleTableTable[0]; //第一个HANDLE_TABLE_ENTRY HandleEntry->NextFreeTableEntry = EX_ADDITIONAL_INFO_SIGNATURE;//-2,作为标志; HandleEntry->Value = 0; //对象值为0,对应于无效句柄NULL // // For duplicate calls we skip building the free list as we rebuild it manually as // we traverse the old table we are duplicating // if (DoInit) { //这个参数在普通调用时为TRUE,仅在复制句柄表时则为False,因为复制时并不需要重新分配句柄 HandleEntry++; //从第二个HANDLE_TABLE_ENTRY开始 // // Now setup the free list. We do this by chaining together the free // entries such that each free entry give the next free index (i.e.,// like a fat chain). The chain is terminated with a 0. Note that // we‘ll skip handle zero because our callers will get that value // confused with null. // for (i = 1; i < LOWLEVEL_COUNT - 1; i += 1) { HandleEntry->Value = 0; //对象值初始化为0 //FreeHandle即自由的,未被使用的句柄 HandleEntry->NextFreeTableEntry = (i+1)*HANDLE_VALUE_INC; //构建FreeHandle列表,在初始化时,每一个HANDLE_TABLE_ENTRY都指向下一个句柄.这里的NextFreeTableEntry的值准确说是下一个FreeHandle,这样构成了一个单向链表一样的结构 HandleEntry++; } //对最后一项作特殊处理 HandleEntry->Value = 0; HandleEntry->NextFreeTableEntry = 0; //最后一项的NextFreeTableEntry为0 HandleTable->FirstFree = HANDLE_VALUE_INC; //把刚初始化完的句柄表的FirstFree设为4,即第一个可用句柄 } HandleTable->NextHandleNeedingPool = LOWLEVEL_COUNT * HANDLE_VALUE_INC; //一级表最大句柄 // // Setup the necessary process information // HandleTable->QuotaProcess = Process; //设置所属的Process HandleTable->UniqueProcessId = PsGetCurrentProcess()->UniqueProcessId; //调置所属Process的ProcessId HandleTable->Flags = 0; ============================================================================================================= 二、申请低级表,即最底层一级的表.每个HANDLE_TABLE的第一个一级表在创建HANDLE_TABLE时就被创建了,ExpAllocateLowLevelTable用于提供在其它时候创建一级表的支持,比如句柄表已经为二级时再申请句柄表时只需要申请创建一个一级表并加入二级表中即可. PHANDLE_TABLE_ENTRY ExpAllocateLowLevelTable ( IN PHANDLE_TABLE HandleTable,IN BOOLEAN DoInit ) /*++ Routine Description: This worker routine allocates a new low level table Note: The caller must have already locked the handle table Arguments: HandleTable - Supplies the handle table being used DoInit - If FALSE the caller (duplicate) doesn‘t need the free list maintained Return Value: Returns - a pointer to a low-level table if allocation is successful otherwise the return value is null. --*/ { ULONG k; PHANDLE_TABLE_ENTRY NewLowLevel = NULL,HandleEntry; ULONG BaseHandle; // // Allocate the pool for lower level // NewLowLevel = ExpAllocateTablePagedPoolNoZero( HandleTable->QuotaProcess,TABLE_PAGE_SIZE );//申请内存,大小为一级表的大小TABLE_PAGE_SIZE if (NewLowLevel == NULL) { return NULL; } // // We stamp with EX_ADDITIONAL_INFO_SIGNATURE to recognize in the future this // is a special information entry // //下面三行代码为初始化,这个同刚创建HANDLE_TABLE时创建第一个一级表时的工作基本相同,不多说 HandleEntry = &NewLowLevel[0]; HandleEntry->NextFreeTableEntry = EX_ADDITIONAL_INFO_SIGNATURE; HandleEntry->Value = 0; // // Initialize the free list within this page if the caller wants this // if (DoInit) { HandleEntry++; // // Now add the new entries to the free list. To do this we // chain the new free entries together. We are guaranteed to // have at least one new buffer. The second buffer we need // to check for. // // We reserve the first entry in the table to the structure with // additional info // // // Do the guaranteed first buffer // //这里是构建FreeHandleList,也是将每一个HANDLE_TABLE_ENTRY的NextFreeTableEntry指向下一个可用句柄. //但是由于这里不是第一个一级表,所以句柄值的计算稍有不同,需要考虑加上前面的部分 BaseHandle = HandleTable->NextHandleNeedingPool + 2 * HANDLE_VALUE_INC; //BaseHandle是当前新分配的句柄表中的最小句柄+4,即未申请本表时的最大Handle(句柄表的最大Handle即HandleTable->NextHandleNeedingPool)再加上8,也就是说跳过了第一个用作无效标记的HANDLE_TABLE_ENTRY(占一个句柄索引), ? 未完待续~ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows – Delphi2010中的CoInternetIsFeatureEnabled
- window 杀固定端口的进程
- windows 安装 jdk 7和8
- Windows使用TensorFlow-GPU导致IPython Notebook 崩溃问题
- 强化经济上至关重要的Windows计算机
- windows-runtime – Metro App FileIO.WriteTextAsync多线程
- Windows Azure Active Directory备份/还原
- 在Windows上使用PHP删除符号链接
- windows-runtime – Windows Phone 8.1中的Image上的Opacit
- tinymce-3 – TypeError:window.tinyMCE.execInstanceComm