这线程恢复真的是比线程挂起麻烦的多,挂起线程插个apc就结了,线程恢复这块流程和分支非常多,wrk在这块的源码也不全,本次分析的流程和分支仅按照下方测试代码进行,不考虑其它情况;调试的操作系统是WindowsXP,单核
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
nt!KiReadyThread:
mov edi,edi
push ebp
mov ebp,esp
push ecx
push ecx
push ebx
push esi
mov esi,ecx ;esi
=
ecx
=
KTHREAD
=
ReadyThread
lea ecx,[esi
+
128h
] ;ecx
=
PCHAR Preempted
=
&_KTHREAD
-
>Preempted
mov al,byte ptr [ecx] ;al
=
*
Preempted;
mov byte ptr [ecx],
0
;
*
Preempted
=
0
;
mov ecx,dword ptr [nt!KeTickCount (
8055b000
)]
push edi
mov edi,dword ptr [esi
+
44h
] ;esi
=
_KTHREAD
-
>APC_STATE
-
>Process
mov byte ptr [ebp
-
1
],al
movsx eax,byte ptr [esi
+
33h
] ;eax
=
_KTHREAD
-
>Priority
mov dword ptr [esi
+
68h
],ecx ;_KTHREAD
-
>WaitTime
=
KeTickCount
nt!KiReadyThread
+
0x12a
:
cmp
byte ptr [edi
+
65h
],
0
;
if
jne nt!KiReadyThread
+
0x134
;_KPROCESS
-
>State !
=
STANDBY(
0
)
nt!KiReadyThread
+
0x2f
:
cmp
byte ptr [esi
+
12Ah
],
0
;
if
je nt!KiReadyThread
+
0x17d
;_KTHREAD
-
>KernelStackResident
=
=
FALSE
nt!KiReadyThread
+
0x3c
:
movzx ecx,byte ptr [esi
+
1BAh
] ;ecx
=
_KTHREAD
-
>IdealProcessor
mov edi,dword ptr [esi
+
124h
] ;edi
=
_KTHREAD
-
>Affinity
mov byte ptr [esi
+
2Dh
],
3
;_KTHREAD
-
>State
=
ProcessInSwap(
3
)
mov edx,dword ptr nt!KiProcessorBlock (
805633c0
)[ecx
*
4
] ;edx
=
KPRCB
mov ebx,dword ptr [edx
+
4D0h
] ;ebx
=
_KPRCB
-
>MultiThreadProcessorSet
mov edx,dword ptr [esi
+
120h
] ;edx
=
_KTHREAD
-
>SoftAffinity
and
edx,edi ;
if
je nt!KiReadyThread
+
0x66
(
804dd6c2
) ;Affinity
=
=
SoftAffinity
nt!KiReadyThread
+
0x64
:
mov edi,edx ;Affinity
=
SoftAffinity
nt!KiReadyThread
+
0x66
:
mov edx,dword ptr [nt!KiIdleSummary (
8055ae80
)];edx
=
调度链表数组
and
edx,edi ;根据cpu编号找到对应调度链表,edx
=
调度链表
jne nt!KiReadyThread
+
0x1aa
(
804e8755
) ;如果调度链表不为空,跳转
nt!KiReadyThread
+
0x74
:
xor edx,edx ;edx
=
0
inc edx ;edx
=
1
mov ebx,edx ;
shl ebx,cl ;ebx << cpu
test edi,ebx ;edi
=
Affinity & (
1
<< cpu)
je nt!KiReadyThread
+
0x7f
(
8051992b
) ;
if
(! edi & ebx)
nt!KiReadyThread
+
0xb4
:
mov byte ptr [esi
+
12Bh
],cl ;_KTHREAD
-
>NextProcessor
=
ecx
mov ebx,dword ptr nt!KiProcessorBlock (
805633c0
)[ecx
*
4
] ;ebx
=
KPRCB
mov edi,dword ptr [ebx
+
8
] ;edi
=
NextThread
test edi,edi ;
if
jne nt!KiReadyThread
+
0xcc
(
804e6ea0
) ;NextThread !
=
NULL
nt!KiReadyThread
+
0x2d1
:
mov ecx,dword ptr [ebx
+
4
] ;ecx
=
CurrentThread
movsx edi,byte ptr [ecx
+
33h
] ;edi
=
_KTHREAD
-
>Priority
cmp
eax,edi ;
if
jg nt!KiReadyThread
+
0x2dc
;ReadyThread
-
>Priority > CurrentThread
-
>Priority
nt!KiReadyThread
+
0x307
:
mov byte ptr [esi
+
2Dh
],
1
;_KTHREAD
-
>STATE
=
READY(
1
)
add esi,
60h
;esi
=
&_KTHREAD
-
>WaitListEntry
cmp
byte ptr [ebp
-
1
],
0
;
if
_KTHREAD
-
>Preetempt !
=
0
lea ecx,nt!KiDispatcherReadyListHead (
80563da0
)[eax
*
8
] ;ecx
=
调度链表
jne nt!KiReadyThread
+
0x31b
(
804dd641
) ;_KTHREAD
-
>Preetempt !
0
nt!KiReadyThread
+
0x329
: ;将ReadyThread挂入调度链表
mov edi,dword ptr [ecx
+
4
] ;edi
=
调度链表
-
>Blink
mov dword ptr [esi],ecx ;_KTHREAD
-
>WaitListEntry.Flink
=
调度链表
mov dword ptr [esi
+
4
],edi ;_KTHREAD
-
>WaitListEntry.Blink
=
调度链表.Blink
mov dword ptr [edi],esi ;调度链表.Blink.Flink
=
_KTHREAD
-
>WaitListEntry
mov dword ptr [ecx
+
4
],esi ;调度链表.Blink
=
_KTHREAD
-
>WaitListEntry
nt!KiReadyThread
+
0x336
:
mov ecx,eax ;ecx
=
ReadyThread
-
>Priority
shl edx,cl ;edx
=
cpu
or
dword ptr [nt!KiReadySummary (
8055ae88
)],edx
nt!KiReadyThread
+
0x340
:
pop edi
pop esi
pop ebx
leave
ret