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。

  其都给用序号标注了,其算法部分前面介绍过,分析起来可能有点麻烦,但也应该很好理解。

   

 

posted @ 2020-04-22 15:07  OneTrainee  阅读(783)  评论(0编辑  收藏  举报