5.用户APC执行过程

本文详细介绍了用户APC(异步过程调用)在系统调用、中断或异常返回用户空间前的执行过程,涉及线程堆栈操作、KiServiceExit和KiDeliverApc函数的作用,以及KinitializeUserApc和KiUserApcDispatcher的功能。用户APC执行需要经过内核到用户空间的切换,包括寄存器、栈顶等运行环境的保存与恢复,涉及复杂堆栈操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

执行用户APC时的堆栈操作

处理用户APC要比内核APC复杂的多,因为,用户APC函数要在用户空间执行的,这里涉及到大量换栈的操作:

当线程从用户层进入内核层时,要保留原来的运行环境,比如各种寄存 囚器,栈的位置等等(_Trap_Frame),然后切换成内核的堆栈,如果正常返回, 您恢复堆栈环境即可。

但如果有用户APC要执行的话,就意味着线程要提前返回到用户空间去,执行,而且返回的位置不是线程进入内核时的位置,而是返回到其他的位置,每处理一个用户APC都会涉及到:
内核->用户空间->再回到内核空间

堆栈的操作比较复杂,如果不了解堆栈的操作细节不可能理解用户APC是如何执行!

KiDeliverApc函数分析
无论是内核APC还是用户APC首先执行的都是这个函数

  1. 判断用户APC链表是否为空
  2. 判断第一个参数是为1
  3. 判断ApcState.UserApcPending是否为1
  4. 将ApcState.UserApcPending设置为0
  5. 链表操作将当前APC从用户队列中拆除
  6. 调用函数(KAPC.KernelRoutine)释放KAPC结构体内存空间
  7. 调用KilnitializeUserApc函数

在这里插入图片描述
取完内核APC后取用户APC,然后判断你用户APC是不是空的,不为空就跳转。

在这里插入图片描述

KilnitializeUserApc函数分析:备份CONTEXT

线程进0环时,原来的运行环境(寄存器栈顶等)保存到Trap_Frame结构体中,如果要提前返回3环去处理用户APC,就必须要修改Trap _Frame结构体:

比如:进0环时的位置存储在EIP中,现在要提前返回,而且返回的并不,是原来的位置,那就意味着必须要修改EIP为新的返回位置。还有堆栈ESP也要修改为处理APC需要的堆栈。那原来的值怎么办呢?处理完APC后该如何返

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值