天天看点

时钟中断 (线程切换)—— 逆向分析 KeUpdateRunTime/KiDispatchInterrupt

简介

系统时钟可以实现的线程的切换。

Windows

系列操作系统的时钟间隔:10 - 20 毫秒,采用

0x30

中断号。

在系统时钟下,线程的执行流程:

  1. 当一个新的线程开始执行时,初始化程序会在

    _KTHREAD.Quantum

    赋初始值,该值的大小由

    _KPROCESS.ThreadQuantum

    决定。
  2. 线程在执行过程中,系统就会调用

    KeUpdateRunTime

    来记录时间片的使用情况。
  3. KiDispatchInterrupt

    完成对线程的调度

    (1)当该线程的时间片耗尽并让出处理机时,通过调用

    KiQuantumEnd

    函数实现对该线程重新分配时间片,切换到新的就绪线程,并将旧线程重新添加到就绪链表中,完成线程切换。

    (2)若时间片没有耗尽,将会调用

    SwapContext

    完成线程切换。

KeUpdateRunTime

每次时钟中断会调用

KeUpdateRunTime

函数,该函数每次将当前线程

Quantum

减少3个单位,如果减到0,则将

KPCR.PrcbData.QuantumEnd

的值设置为非0。

.text:0046A1B8                 sub     [ebx+_KTHREAD.Quantum], 3 ; 时间片 -3
.text:0046A1BC                 jg      short loc_46A1D7
.text:0046A1BE                 cmp     ebx, [eax+_KPCR.PrcbData.IdleThread]
.text:0046A1C4                 jz      short loc_46A1D7
.text:0046A1C6                 mov     [eax+_KPCR.PrcbData.QuantumEnd], esp
           

一个线程初始状态有6个时间片,每次中断会把当前线程时间片减3,这意味着一个线程要经过两次时钟中断时间片才会用完。

KiDispatchInterrupt

内核

API

函数

KiDispatchInterrupt

实现的线程的调度。

该函数的逻辑流程图如下:

时钟中断 (线程切换)—— 逆向分析 KeUpdateRunTime/KiDispatchInterrupt

KiQuantumEnd

内核

API

函数

KiQuantumEnd

,用于实现重新设置时间片耗尽的线程的时间片、并找到下一个要运行的线程。

该函数的关键代码如下:

时钟中断 (线程切换)—— 逆向分析 KeUpdateRunTime/KiDispatchInterrupt

KiReadyThread

内核

API

函数

KiReadyThread

实现将旧线程的

_ETHREAD

ECX

传参)添加到就绪链表中。

该函数的关键代码如下:

时钟中断 (线程切换)—— 逆向分析 KeUpdateRunTime/KiDispatchInterrupt

继续阅读