KiFindReadyThread分析 - 查找下一个就绪线程
Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html
KiFindReadyThread分析 - 查找下一个就绪线程
1. KiReadySummary 全局变量
2.KiFindReadyThread 函数分析
3.KiFindReadyThread 逆向分析
1. KiReadySummary 全局变量
之前我们介绍过,其存在32个就绪链表,0-31序号,在Windows操作系统中,其存在一个全局变量KiReadySummary,32位,如果哪个存在就绪链表,其该位被置1。
这样,我们直接检测其KiReadySummary全局变量是否为0就判断是否存在就绪链表,这个你应该明确的。
其从低位到高位优先级依次升高,因此需要找从左边数第一个为1的位数,该位作为位数从KiDispatchReadListHead数组中寻找。
2.KiFindReadyThread 函数分析
该函数在KiSwapThread中出现过,当KPCR中无法找到下一个就绪线程,则调用该函数从就绪链表中查找对应的就绪线程。
该函数虽然不长,但其算法还是稍微有点复杂,大量的移位运算,下面我们来详细分析一下。
该函数做了三件事:
① 解析KiReadySummary,找到从左起第一个为1的位数;
② 用该位获取从KiDispatchReadListHead中的第一个_KTHREAD线程,将其从链表中摘除;
③ 如果摘除后该链表为空,则找到相应的KiReadySummary位将其置0。
其中第一步的算法分析起来是非常棘手的。
1)解析KiReadySummary的算法
KiReadySummary一共32位【0~31】,要找到从左边数第一个为1的。
在Windows内核中存在位图(数组),其可以找到8位中的这样的数,因此,该函数的算法是首先采用二分查找该范围,然后调用该数组确定小范围,在加上大范围即可。
二分效果如下:
3.KiFindReadyThread 逆向分析
该函数做了三件事:
① 解析KiReadySummary,找到从左起第一个为1的位数;
② 用该位获取从KiDispatchReadListHead中的第一个_KTHREAD线程,将其从链表中摘除;
③ 如果摘除后该链表为空,则找到相应的KiReadySummary位将其置0。
其都给用序号标注了,其算法部分前面介绍过,分析起来可能有点麻烦,但也应该很好理解。