查看原文
其他

内核APC调用过程学习笔记

三一米田 看雪学苑 2022-07-01

本文为看雪论坛优秀文章

看雪论坛作者ID:三一米田





主要内容


APC函数的执行与插入并不是同一个线程,具体点说:

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




内核APC函数执行点1:线程切换


    
分析SwapConText线程切换函数、KiSwaoThread函数:





执行点2:当产生系统调用、
中断或者异常时


当产生系统调用、中断或者异常时线程在返回用户空间前都会调用_KiServiceExit函数,在_KiServiceExit会判断是否有要执行的用户APC,如果有则调用KiDeliverApc函数(第一个参数为1)进行处理,没有则直接return。

分析SwapConText函数


发现最终确实是调用了_KiServiceExit函数。

分析_KiServiceExit函数


分析发现,内核执行流程如下:


1) 判断第一个链表是否为空;

2) 判断KTHREAD.ApcState.KernelApcInProgress是否为1(当前APC是否正在执行);

3) 判断是否禁用内核APC(KTHREAD.KernelApcDisable是否为1);

4) 将当前链表的KAPC结构体从链表中摘除(我们是通过链表找到这个KAPC的);

5) 执行KAPC.KernelRoutine指定的函数,释放KAPC结构体占用的空间;

6) 将KTHREAD.ApcState.KernelApcInProgress设置为1 标识正在执行内核APC;

7) 执行真正的内核APC函数(KAPC.NormalRoutine);

8) 执行完毕,将KernelApcInProgress改为0;

9) 循环第1)步。





总结


1) 内核APC在线程切换的时候就会执行,这也就意味着,只要插入内核APC很快就会执行。

2) 在执行用户APC之前会先执行内核APC。

3) 内核APC在内核空间执行,不需要换栈,一个循环全部执行完毕。



- End -



看雪ID:三一米田

https://bbs.pediy.com/user-881392.htm

  *本文由看雪论坛 三一米田 原创,转载请注明来自看雪社区。



推荐文章++++

* CVE-2020-1048、CVE-2020-1337漏洞原理及利用

* Windows不太常见的进程注入学习小记(二)

* 给流行视频软件的JS虚拟机写一个编译器

* 溢 出 大 师

* Windows不太常见的进程注入学习小记(一)







公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com


求分享

求点赞

求在看


“阅读原文”一起来充电吧!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存