4.内核APC执行过程

APC函数的执行与插入并不是同一个线程:

在A线程中向B线程插入一个APC,插入的动作是在A线程中完成的,但什么时候执行则由B线程决定!,所以叫“异步过程调用"

内核APC函数与用户APC函数的执行时间和执行方式也有区别,我们本节课主要学习内核APC的执行过程。



执行点1:线程切换

SwapContext		//判断是否有内核APC

KiSwapThread

KiDelicerApc		//执行内核APC函数

在SwapContext快结束的时候做了一个判断,判断的结果存到EAX中,然后返回。
4.内核APC执行过程

一直到这里才开始处理
4.内核APC执行过程
4.内核APC执行过程



执行点2:系统调用、中断或者异常(_KiServiceExit)

当要执行用户APC之前,先要执行内核APC。

4.内核APC执行过程

KiDeliverApc函数执行流程

  1. 判断第一个链表是否为空
  2. 判断KTHREAD.ApcState.KernelApclnProgress是否为1
  3. 判断是否禁用内核APC(KTHREAD.KernelApcDisable是否为1).
  4. 将当前KAPC结构体从链表中摘除
  5. 执行KAPC.KernelRoutine指定的函数释放KAPC结构体占用的空间
  6. 将KTHREAD.ApcState.KernelApclnProgress设置为1标识正在执行内核APC
  7. 执行真正的内核APC函数(KAPC.NormalRoutine)
  8. 执行完毕将KernelApcInProgress改为0

4.内核APC执行过程

如果链表不为空,把4个要用的放到局部变量里
4.内核APC执行过程

如果NormalRoutine不为空就跳到这(不知道NormalRoutine是什么的去看《3.APC的挂入过程》)
4.内核APC执行过程

9.下一个循环又跳回来
4.内核APC执行过程



总结:

  1. 内核APC在线程切换的时候就会执行,这也就意味着,只要插入内核APC·很快就会执行。
  2. 在执行用户APC之前会先执行内核APC
  3. 内核APC在内核空间执行,不需要换栈,一个循环全部执行完毕。