我是靠谱客的博主 勤劳电脑,最近开发中收集的这篇文章主要介绍KeWaitForSingleObject简析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

这个函数在进行同步操作时经常会用到,它内部的工作流程是什么样的呢?让我来试着分析分析吧. (以反编译的汇编代码片段为材料)

NTSTATUS KeWaitForSingleObject(
IN PVOID
Object,//分发器对象(dispatcher object),像(event,mutex,semaphore,thread or timer)
IN KWAIT_REASON
WaitReason,
IN KPROCESSOR_MODE
WaitMode,
IN BOOLEAN
Alertable,
IN PLARGE_INTEGER
Timeout OPTIONAL
);

The KeWaitForSingleObject routine puts the current thread into a wait state until the given dispatcher object is set to a signaled state or (optionally) until the wait times out.–(from ddk)
KeWaitForSingleObject例程将当前线程(ethread里包含几个以Wait开头的字段,有WaitIrql,WaitMode,WaitStatus)置为等待状态,直到提供的分发器对象被设置为已处理状态,或者第五个参数给出的时间Timeout走完。

8408ad4c 8b4518
mov
eax,dword ptr [ebp+18h];第五个参数
8408ad4f 53
push
ebx
8408ad50 56
push
esi
8408ad51 648b3524010000
mov
esi,dword ptr fs:[124h];--@1
8408ad58 0fba763c03
btr
dword ptr [esi+3Ch],3
8408ad5d 57
push
edi
8408ad5e 0f92c3
setb
bl
8408ad61 8944242c
mov
dword ptr [esp+2Ch],eax
8408ad65 8dbec0000000
lea
edi,[esi+0C0h];--@2
8408ad6b 84db
test
bl,bl
8408ad6d 7509
jne
nt!KeWaitForSingleObject+0x3c (8408ad78)

btr和setb指令???在@1处,fs寄存器总是指向kpcr(processor control region 处理器控制区),在偏移为0x120处是该结构的最后一个成员PrcbData,其类型为_kprcb;在结构_kprcb的0x0x4处是成员CurrentThread。在ethread结构的0x3c处成员MicsFlags记录了一些重要的状态信息(其实在kthread结构里)如下:


+0x03c KernelStackResident : Pos 0, 1 Bit
+0x03c ReadyTransition
: Pos 1, 1 Bit
+0x03c ProcessReadyQueue : Pos 2, 1 Bit
+0x03c WaitNext
: Pos 3, 1 Bit
+0x03c SystemAffinityActive : Pos 4, 1 Bit
+0x03c Alertable
: Pos 5, 1 Bit;是否可以'叫醒'
+0x03c GdiFlushActive
: Pos 6, 1 Bit
+0x03c UserStackWalkActive : Pos 7, 1 Bit
+0x03c ApcInterruptRequest : Pos 8, 1 Bit;Apc 中断请求
+0x03c ForceDeferSchedule : Pos 9, 1 Bit
+0x03c QuantumEndMigrate : Pos 10, 1 Bit
+0x03c UmsDirectedSwitchEnable : Pos 11, 1 Bit
+0x03c TimerActive
: Pos 12, 1 Bit;是否使用计时器
+0x03c SystemThread
: Pos 13, 1 Bit;是不是系统线程
+0x03c Reserved
: Pos 14, 18 Bits
+0x03c MiscFlags
: Int4B

接下来确定Irql是DpcLevel,为什么是这个级别呢?因为延迟过程调用(Dpc)和线程分发器运行于同一级别,并且在这个函数里发生了线程的切换需要线程分发器的帮助。(不确定,我没实验证实)

8408ad6f ff157c510184
call
dword ptr [nt!_imp__KeRaiseIrqlToDpcLevel (8401517c)]
8408ad75 88466a
mov
byte ptr [esi+6Ah],al;WaitIrql=al
8408ad8d
and
dword ptr [esi+3Ch],0FFFFFFDFh;set Alretable to 0
8408ad
cmp
byte ptr [ebp+14h],0
8408ad
mov
cl,byte ptr [ebp+10h]
8408ad98
mov
eax,dword ptr [esi+3Ch]
8408ad9b
mov
byte ptr [esi+38h],0;WaitRegister->Flags=0
8408ad9f
mov
byte ptr [esi+6Bh],cl;WaitMode=第3个参数
8408ada2
je
nt!KeWaitForSingleObject+0x6e (8408adaa)
接着又是各种检查(痛苦)。
8408adf5
cmp
byte ptr [esi+55h],dl;ApcStateFill[15]
8408adf8 je
nt!KeWaitForSingleObject+0xf3 (8408ae2f)
UCHR ApcStateFill[23] 表示的意义不了解。 对这个字符数组进行了大量操作。
8b4c2414
mov
ecx,dword ptr [esp+14h]
c6466805
mov
byte ptr [esi+68h],5;State=5
33c0
xor
eax,eax
f02101
lock and dword ptr [ecx],eax
8a450c
mov
al,byte ptr [ebp+0Ch];WaitReason
888687010000
mov
byte ptr [esi+187h],al
a180351484
mov
eax,dword ptr [nt!KeTickCount (84143580)]
898680000000
mov
dword ptr [esi+80h],eax
8b4518
mov
eax,dword ptr [ebp+18h];WaitTime
3bc2
cmp
eax,edx
0f84fc000000
je
nt!KeWaitForSingleObject+0x258 (8408af94)

到这里大概是所有反编译代码的1/6,后面的hold不住了,就简单的说一下吧。同步对象有事件,信号量,互斥体,计时器等,但在KeWaitForSingleObject 单独有一个参数 Timeout 表示一段时间,实际上在它的内部有大片的代码是和时间,计时器(Timer)有关,可见Timer的地位比较特殊。当等待的条件不满足时,当前线程就会处于等待状态,由KicommitThreadWait去完成此操作;当某个时候条件满足,KiExitThreadWait将会被调用使线程的状态恢复重新运行。根据不同的同步对象实际检查等待条件是否满足时处理也不一样。

最后

以上就是勤劳电脑为你收集整理的KeWaitForSingleObject简析的全部内容,希望文章能够帮你解决KeWaitForSingleObject简析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部