首页
社区
课程
招聘
[原创]QueueUserAPC执行成功条件-逆向总结
发表于: 2022-4-29 14:12 24076

[原创]QueueUserAPC执行成功条件-逆向总结

2022-4-29 14:12
24076

 使用Win32 API QueueUserAPC做注入时总是遇到明明插入成功了,但就是得不到执行的情况。为了得到原因,在Win7 x86 PAE模式下跟踪了一下QueueUserAPC的整个处理过程(初始化->插入->执行),详细分析过程我会用附件的形式给出,下面是得到的一些结论,有错误欢迎指出,一起交流。

 在系统调用、中断、异常等操作发生后,会从r3进入内核来处理,在内核处理完准备返回r3时,会调用这个函数,在函数内部会做出一些判断来决定是否要交付用户态APC,判断条件就是当前线程的ApcState.UserApcPending,这个域为1时,表示有要处理的用户态APC存在,才会继续调用KiDeliverApc,这一点很关键。

 这个函数进去第一件事就是判断当前线程的SpecialApcDisable域是否为1,这个域相当于一个总开关,置1表示,内核和用户态APC都不能交付,函数直接返回。如果为0,判断内核APC队列是否有内容,没有就去交付用户APC,如果有内核APC,一个循环全部交付完,但在交付内核APC过程中,一旦检查发现KernelApcDiable域为1,KiDeliverApc函数直接返回,不会向下处理用户APC了。这里可以得出结论,用户态APC必须在内核APC交付完才有机会交付。但通过QueueUserAPC插入的APC是不存在内核APC的,直接相当于内核APC交付完了。
而内核APC交付完,会开始交付用户APC,这里需要注意一下,使用QueueUserApc插入的APC,真正的回调函数是保存在NormalContext里,而NormalRoutine只是保存了一个r3执行时候的派发入口(ntdll.dll中的8号导出函数),而要执行回调函数,需要从内核返回到r3由派发函数统一派发。Windows这里采用的是劫持TrapFrame实现的回r3。

从上面的执行过程分析得出,要想让由QueueUserApc插入的用户态APC交付成功,需要满足以下条件:

第三点暂时不用考虑,一般都是0,但UserApcPending什么时候才能是1以及队列什么时候被插入APC?这就需要去分析QueueUserApc的初始化和插入过程了。

 这个函数是系统调用进来先执行的内核函数,函数内部首先判断目标线程是否是系统线程,即CrossThreadFlags.SystemThread位是否为1,如果为1函数直接返回,为0才分配KAPC结构内存并初始化。

 这个函数中判断插入的目标线程的ThreadFlags.ApcQueue位,如果这个位为0,不插入队列,直接返回。不为1,继续调用KiInsertQueueApc。

 将APC插入ApcList[1]队列。这个函里面有个点,因为调用QueueUserApc环境固定为0(始终插入原始环境),也就是KAPC.ApcStateIndex始终为0,而这个函数里会把当前线程的ApcStateIndex与KAPC.ApcStateIndex做对比,因为线程在挂靠的时候ApcStateIndex为1,这样就说明无法插入一个正在挂靠的线程。接下来会去判断目标线程是不是当前线程,如果是当前线程并且是用户态APC,函数也返回了。前面条件都满足了,会判断目标线程是否处于可以被唤醒的等待状态,如果不是,函数在这里也返回了。如果是,将目标线程唤醒(从等待链表->延时就绪链表),唤醒成功后将UserApcPending置1。到这里,条件全部满足。

从检查顺序排列,要想QueueUserApc执行成功,目标线程需要满足以下条件:

  • CurrentThread.ApcState.UserApcPending值为1
  • ApcList[1]队列不为空
  • CurrentThread.SpecialApcDisable值为0

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 5
支持
分享
最新回复 (7)
雪    币: 9024
活跃值: (6245)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
感谢大佬分享
2022-4-30 13:12
0
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢大佬分享
2022-5-5 08:43
0
雪    币: 300
活跃值: (2477)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
mark
2022-5-5 09:19
0
雪    币: 698
活跃值: (4564)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
2022-5-5 09:52
0
雪    币: 436
活跃值: (2668)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
KeTestAlertThread
2022-8-31 11:56
0
雪    币: 3738
活跃值: (3872)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
感谢分享,分析得很详细!
2022-8-31 14:11
0
雪    币: 1810
活跃值: (4020)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
感谢分享
2022-9-23 10:24
0
游客
登录 | 注册 方可回帖
返回
//