首页
社区
课程
招聘
线程的Alertable与User APC
发表于: 2016-4-13 11:16 7711

线程的Alertable与User APC

2016-4-13 11:16
7711
    在使用插User APC注入DLL时,经常面临一个问题,那就是线程必须是处于Alertable模式才能注入成功。但一直对这个Alertable的含义不甚清楚,今天总算是把这个梗消化了。刚好论坛有人提到这个问题,索性发出来大家探讨一下。有错误的地方请大神指出,多谢。

    微软对Alertable与APC的执行关系有详细的描述:

    https://msdn.microsoft.com/en-us/library/ms810047.aspx

    其中有一段是这样说的:


    也就是说,正常情况下,用户模式的APC是不会打断用户态程序的执行流的。除非,线程是Alertable——可唤醒的。

So, what is Alertable?

    想象一个应用场景:

    客户端程序每隔5分钟就和服务端进行一次通信,实现“心跳”,最简单的就是使用Sleep(5*60*1000)。那么这样一来,这5分钟内,线程就沉睡了,如果这个时候有比较紧急的网络IO事件发生怎么办呢?线程还在沉睡中,因为5分钟时间还未到,所以无法及时处理这些事件。如何解决这个问题呢?那就是使用SleepEx替换Sleep。这个函数比起Sleep就多了一个参数Alertable,表示该线程是“可唤醒的”,就是说,线程虽然等待时间未到,但如果发生一些事件,线程也会及时去处理。这些事件就是:IO完成例程需要执行或者线程有APC需要交付。

    内核中线程数据结构KTHREAD中的Alertable成员就是表示该线程是不是可唤醒的。这个成员会在什么时候被赋值呢?参见WRK有三个宏会设置该值:

    InitializeDelayExecution()

    InitializeWaitSingle()

    InitializeWaitMultiple()

    这三个宏分别被

    SleepEx()---->KeDelayExecutionThread()

    WaitForSingleObject()---->KeWaitForSingleObject()

    WaitForMultipleObjects()---->KeWaitForMultipleObjects()

    调用。

    当上述调用发生时,线程Alertable被置为TRUE。同时,还会通过宏TestForAlertPending设置KTHREAD的另外一个成员:UserApcPending,当Alertable为TRUE,并且User APC队列不为空,那么该值将被置为TRUE。



 
    当从内核模式返回时,DISPATCH_USER_APC在交付用户模式APC前会判断这个标志,如果为FALSE,则不会交付User APC。

 

    这也就是为什么当线程为Alertale的时候,插入的User APC才会得到执行。回过头来想,我是这样理解的,用户模式的代码执行流程默认是不被用户模式的APC打断的,除非使用Alertable为TRUE明确告诉系统,“我希望被打断”。

 

    还有一个问题:在进程启动时使用驱动进行APC注入DLL的时候,并没有去考虑这个UserApcPending标记,那为什么APC就一定能得到执行呢?

    这是因为,在XP中,进程初始化重要工作LdrInitializeThunk本身就是使用APC进行执行的,所以在PspUserThreadStartup中对UserApcPending设置为了TRUE,这样保证了初始的时候User APC能成功交付。

    即使在Win7中,LdrInitializeThunk不再使用APC进行派遣,LdrInitializeThunk在执行完成后会使用NtTestAlert,同样会设置UserApcPending为TRUE。从而在返回用户模式时,User APC同样能交付。

    但每次交付用户模式的时候,UserApcPending会被重置,所以线程启动之后就不再能保证插APC能得到执行了。除非使用前面说到的那些Alertable为TRUE的等待函数,再次设置了UserApcPending。

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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 163
活跃值: (103)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
2
mark
2016-4-13 11:25
0
雪    币: 99
活跃值: (110)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
mark
2016-4-13 11:48
0
雪    币: 324
活跃值: (60)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
mark
2016-4-13 11:52
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
刚好今天也在研究这个
2016-4-13 21:30
0
雪    币: 573
活跃值: (222)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6

那么问题就在于怎么设置 这个  UserApcPending 了。。。。

我听说过   什么  DKOM  法                                                                       

2017-5-6 05:16
0
雪    币: 2347
活跃值: (58)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
这个可以  分析的很到位
2017-5-7 16:55
0
雪    币: 20
活跃值: (146)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
空白即是正义 这个可以 分析的很到位
我靠,你是不是mengwuji那里的大表哥。。。。
2017-11-23 16:54
0
雪    币: 799
活跃值: (457)
能力值: ( LV12,RANK:280 )
在线值:
发帖
回帖
粉丝
9
sqdwr 我靠,你是不是mengwuji那里的大表哥。。。。
梦织未来吗
2017-11-23 17:40
0
雪    币: 20
活跃值: (146)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
Ox9A82 梦织未来吗[em_38]
又是一个大佬!带不带新人,我会擦桌子扫地。
2017-11-23 18:17
0
雪    币: 799
活跃值: (457)
能力值: ( LV12,RANK:280 )
在线值:
发帖
回帖
粉丝
11
sqdwr 又是一个大佬!带不带新人,我会擦桌子扫地。
萌新瑟瑟发抖
2017-11-23 18:44
0
雪    币: 20
活跃值: (146)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
Ox9A82 萌新瑟瑟发抖[em_51]
别闹别闹!!
2017-11-23 19:24
0
雪    币: 2347
活跃值: (58)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
sqdwr 我靠,你是不是mengwuji那里的大表哥。。。。
萌新瑟瑟发抖
2018-1-19 02:25
0
雪    币: 20
活跃值: (146)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
空白即是正义 萌新瑟瑟发抖
带不带萌新?我会擦桌子扫地。
2018-2-1 17:29
0
雪    币: 419
活跃值: (96)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
mark
2019-1-18 12:13
0
游客
登录 | 注册 方可回帖
返回
//