码迷,mamicode.com
首页 > 其他好文 > 详细

APC

时间:2020-03-30 19:14:42      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:image   alt   因此   退出   init   get   context   ima   mamicode   

Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html

APC

5. 用户APC执行过程

  1) 用户APC函数的执行时机

  当程序在零环执行完成返回三环时,其调用_KiServiceExit,此时其调用_KiDeliverApc来检查是否有派发的APC函数,然后执行。

  技术图片

  2) 用户APC执行流程

  当发现有用户APC要执行时,其处于零环,要执行必须返回三环。

  执行流程为:零环->三环(执行用户APC)->零环->三环(正常退出)。

  之前我们在系统调用这中提到过如何从三环进到零环,其三环现场保存在_KTRAP_FRAME(_ETHREAD+0x124)这个结构体中。

  此时回去肯定不能从_KTRPA_FRAME中返回三环。

  3)构建_CONTEXT结构体返回三环

  返回三环时根据_KTRAP_FRAME.Eip来返回三环,因此我们想要处理用户APC,其必须修改KTrapFrame.EIP。

  1> KiDiverApc函数中调用KiInitalUserApc来初始化用户APC环境

    技术图片

   2> KiInitalUserApc函数中调用KiContextFromKframes将TrapFrame转换为CONTEXT结构体

    这一步的目的是为了备份原来的TrapFrame,因为返回三环必然修改TrapFrame,因此将旧的转换为CONTEXT预先放到三环的堆栈。

    技术图片

  3> KiInitalUserApc函数中将_APC_RECORD和_CONTEXT保存到三环的堆栈中

    虽然此时处于零环,但是可以从TrapFrame.esp来获取三环的堆栈地址,然后将两者保存进去。

    因为APC执行完之后还必须从三环进入零环,此时直接在堆栈进行操作进行复原即可。

    1* 获取esp并计算提升堆栈大小

      技术图片

    2* 将 _Context 写入三环地址

      技术图片

      3* 将ApcRecord写入三环地址

      技术图片

       4* 保存之后三环的堆栈空间

      技术图片

  4> KiInitalUserApc函数中修改TrapFrame为返回三环做准备

    其修改很多TrapFrame的值,但对于我们最重要的就是回到三环后的落脚点。

    其回到KeUserApcDispatch来执行用户的APC函数,至于函数地址,ApcRecord.NormalContext存放的是真正的APC函数。

    技术图片

  4)总结

  理解上面过程,此时,我们就可以通过KiServiceExit函数利用KTrapFrame来返回用户层,其返回的就是KiInitalizeUserApc函数,然后执行用户APC。

  当用户APC执行完成之后,返回零环,此时就是Context。我们直接在三环把Context再转换为KtrapFrame,这之后就很好理解了。

APC

标签:image   alt   因此   退出   init   get   context   ima   mamicode   

原文地址:https://www.cnblogs.com/onetrainee/p/12600409.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!