《逆向工程实战》 习题

首先是一个逆向

练习解答

此部分为书中的练习题解答,不保证正确。(实际上可能错误很多

作者给出的编程题目尽量做了,放在了 Github 上,仅供参考。

如有师傅指正或者交流可以联系我,联系方式见 About。

1.3

1.3

[EBP+8] 和 [EBP+C] 的类型可以从 mov 指令的另一个操作数中看出,第一行目的操作数是 edi,所以 [EBP+8] 是 DWORD;第八行目的操作数是 AL,[EBP+C] 是 byte。

第1、2行,从栈上读取参数存入 EDI,并在 EDX 中备份。第三行清空 EAX,第四行将 ECX 设为 -1。

第五行 Scasb 为 Scan String Byte,将 AL(此处为0) 与 EDI 所指的字符串逐字节比较,每次比较后递增 EDI,并递减 ECX。repne 为 Repeat Not Equal,在不相等时重复。在 ECX 不为 0 且 EF 不为 0 时会重复执行后面的指令。在这里,就是查看 EDI 所指向的缓冲区的第一个字节是否为 0,如果是,退出循环,否则查看下一个字节。

第六行和第七行,由于 ECX 最初被设置为 -1,因此将 ECX 加 2 取负数后即为 repne 语句的执行次数,即在 EDI 所指向的缓冲区中第一次查找到 0 之前的字节数(去除结尾 0 之后的字符串长度)。

第八行读取栈上的参数存入 AL,第九行把在 EDX 中备份的 EDI 恢复。

第十行 rep 将执行 ECX 次,stosb 为 Store String Byte,将 AL 存入 EDI 所指的缓冲区,并递增 EDI,递减 ECX。因此本条将用 AL 填充 EDI 所指的缓冲区 0 之前的部分。

第十一行将备份的 EDI 作为返回值。

整个代码段的作用是用某个 BYTE 填充缓冲区中 0 之前的部分。例如缓冲区内容为abc\0def,使用 2填充后结果为222\0def

1,4

1.4

(1)call $+5, pop eax,$+5 是距离当前指令 5 字节的地址,而 call $+5 本身占 5 字节,所以这条指令没有改变执行流,但是将下一条指令的地址(EIP,指向 pop eax 这条指令)压栈了,此时 pop eax,就读到了EIP 的值。x86 不允许直接操作 EIP。

(2)push 0xaabbccdd, ret,或者call 0xaabbccdd

(3)addme

addme

如果不 pop ebp,执行 ret 相当于 pop eip,会将 ebp 指向的内容作为代码执行,一般会崩溃。

(4)环境: gcc 11.3.0,WSL(kali)

a.c:

1
2
3
4
5
6
7
long long lladd(int a,int b){
return a+b;
}

int main(){
lladd(1,2);
}

编译为 32 位,输出汇编文件,由于是 WSL,汇编是 AT&T 的:

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
$ gcc -S -m32 -o a.s a.c
$ cat a.s

.file "a.c"
.text
.globl lladd
.type lladd, @function
lladd:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
call __x86.get_pc_thunk.ax
addl $_GLOBAL_OFFSET_TABLE_, %eax
movl 8(%ebp), %edx
movl 12(%ebp), %eax
addl %edx, %eax
cltd
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size lladd, .-lladd
.globl main
.type main, @function
main:
.LFB1:
.cfi_startproc
leal 4(%esp), %ecx
.cfi_def_cfa 1, 0
andl $-8, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
.cfi_escape 0x10,0x5,0x2,0x75,0
pushl %ecx
.cfi_escape 0xf,0x3,0x75,0x7c,0x6
subl $4, %esp
call __x86.get_pc_thunk.ax
addl $_GLOBAL_OFFSET_TABLE_, %eax
pushl $2
pushl $1
call lladd
addl $8, %esp
movl $0, %eax
movl -4(%ebp), %ecx
.cfi_def_cfa 1, 0
leave
.cfi_restore 5
leal -4(%ecx), %esp
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE1:
.size main, .-main
.section .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
.globl __x86.get_pc_thunk.ax
.hidden __x86.get_pc_thunk.ax
.type __x86.get_pc_thunk.ax, @function
__x86.get_pc_thunk.ax:
.LFB2:
.cfi_startproc
movl (%esp), %eax
ret
.cfi_endproc
.LFE2:
.ident "GCC: (Debian 11.3.0-3) 11.3.0"
.section .note.GNU-stack,"",@progbits

主要看 lladd 函数,内容用 Intel 汇编应该是这样:

1
2
3
4
5
6
7
push	ebp
mov ebp,esp
mov edx, [ebp+8]
mov eax, [ebp+12]
cdq
pop ebp
ret

cdq 是将 EAX 扩展成 QWORD,高 32 位存储在 EDX。EDX 的内容使用 EAX 的符号位填充,当 EAX 为负数时,EDX 为 0xffffffff,EAX 为正数时,EDX 为 0。所以这里的结论就是使用 long long 类型作为返回值时,结果会保存在 EDX:EAX 中(高 32 位存在 EDX,低 32 位存在 EAX)。

1.7

1.7-1

1.7-2

1

1.6节内容

1.6内容

用到的文档:

栈布局:

栈布局

2

反编译:

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
typedef struct _IDTR {
DWORD base,
WORD limit
} IDTR;

typedef struct tagPROCESSENTRY32 {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
ULONG_PTR th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID;
LONG pcPriClassBase;
DWORD dwFlags;
CHAR szExeFile[MAX_PATH];
} PROCESSENTRY32;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){

IDTR idt;
HANDLE hSnapshot;
PROCESSENTRY32 pe;

__sidt(&idt);

if(idt.base > 0x8003f400 && idt.base < 0x80047400){
return 0;
}

memset(&pe, 0, sizeof(pe));

hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hSnapshot == INVALID_HANDLE_VALUE) return FALSE;
pe.dwSize = 128h;

if(Process32First(hSnapshot ,&pe) == 0){
return FALSE;
}
if(stricmp(pe.szExeFile, 0x10007c50) != 0){
while(Process32Next(hSnapshot , &pe) != 0){
if(stricmp(pe.szExeFile, 0x10007c50) == 0)
break;
}
}
if(pe.th32ProcessId - pe.th32ParentProcessId == 0)
{
return FALSE;
}
if(fdwReason == DLL_PROCESS_ATTACH){
CreateThread(0,0,100d32d0h,0,0,0);
return TRUE;
}
return FALSE;
}

3

这种情况是编译器所作的名称修饰(修饰名 | Microsoft Docs),文档中描述的比较清晰,具体到 DllMain,由于采用了 STDCALL,所以需要前导下划线;参数列表中包含 12 字节的参数,所以@12

4

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
.386	
.model flat,c
public tttt,strlen1,strchr1
.code
tttt PROC ;test

mov eax,10
ret

tttt ENDP

strlen1 proc
push ebp
mov ebp,esp
mov edi, [ebp+8]
xor eax,eax
mov ecx,0ffffffffh
repne scasb
add ecx,2
neg ecx
mov eax,ecx
mov esp,ebp
pop ebp
ret
strlen1 endp

strchr1 proc
push ebp
mov ebp,esp
mov edi,[ebp+8]
mov eax,[ebp+12]
mov ecx,0ffffffffh
repne scasb
add ecx,2
neg ecx
dec edi
mov eax,edi
mov esp,ebp
pop ebp
ret
strchr1 endp

memcpy1 proc
push ebp
mov ebp,esp
mov ecx, [ebp+16]
mov esi, [ebp+12]
mov edi, [ebp+8]
push edi
memcpyloop:
lodsb
stosb
dec ecx
jnz memcpyloop
pop eax
mov esp,ebp
pop ebp
ret
memcpy1 endp

memset1 proc
push ebp
mov ebp,esp
mov ecx,[ebp+16]
mov eax,[ebp+12]
mov edi,[ebp+8]
push edi
rep stosb
pop eax
mov esp,ebp
pop ebp
ret
memset1 endp

strcmp1 proc
push ebp
mov ebp,esp
xor edx,edx
mov edi,[ebp+12]
mov esi,[ebp+8]
strcmploop:
cmpsb
ja strcmpa
jb strcmpb
mov dl, [esi]
cmp edx,0
je strcmpe
inc esi
inc edi
jmp strcmploop
strcmpe:
mov eax,0
mov esp,ebp
pop ebp
ret
strcmpb:
mov eax,-1
mov esp,ebp
pop ebp
ret
strcmpa:
mov eax,1
mov esp,ebp
pop ebp
ret
strcmp1 endp

strset1 proc
push ebp
mov ebp,esp
xor edx,edx
mov eax,[ebp+12]
mov edi,[ebp+8]
push edi
strsetloop:
mov dl,[edi]
cmp edx,0
jz strsetf
stosb
jmp strsetloop
strsetf:
pop eax
mov esp,ebp
pop ebp
ret
strset1 endp

END

测试程序:

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
#include "pureasm.h"
#include <stdio.h>

int main()
{
int c = tttt(1, 2);
char str1[100] = "String 1, length: 20";
char buffer[100] = { 0 };

// size_t strlen(const char *str)
size_t len = 0;
printf("strlen(str1) is %d\n", strlen1(str1));

// char *strchr(const char *str, int c)
printf("strchr(str1, '1') is %s\n", strchr1(str1, '1'));

// void *memcpy(void *dest, const void *src, size_t n)
printf("memcpy(buffer, str1, 10) is %s\n", memcpy1(buffer, str1, 10));

// void *memset(void *str, int c, size_t n)
printf("memset(buffer, 97, 5) is %s\n", memset1(buffer, 97, 5));

// int strcmp(const char *str1, const char *str2)
printf("strcmp(str1,\"String 1, length: 20\") is %d\n", strcmp1(str1, "String 1, length: 20"));
printf("strcmp(str1,buffer) is %d\n", strcmp1(str1, buffer));

// char *strset(char *str, char c);
printf("strset(str1,'C') is %s", strset1(str1, 'C'));

return 0;
}

5

无特殊说明,环境均为 Windows 7 SP1 x86,内核版本 7601 MP。

此部分有完善空间,可配合相应机制仔细研究。

KeInitializeDpc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
nt!KeInitializeDpc:
828f0d25 8bff mov edi,edi
828f0d27 55 push ebp
828f0d28 8bec mov ebp,esp
828f0d2a 8b4508 mov eax,dword ptr [ebp+8]
828f0d2d 33c9 xor ecx,ecx
828f0d2f 83601c00 and dword ptr [eax+1Ch],0
828f0d33 c60013 mov byte ptr [eax],13h
828f0d36 c6400101 mov byte ptr [eax+1],1
828f0d3a 66894802 mov word ptr [eax+2],cx
828f0d3e 8b4d0c mov ecx,dword ptr [ebp+0Ch]
828f0d41 89480c mov dword ptr [eax+0Ch],ecx
828f0d44 8b4d10 mov ecx,dword ptr [ebp+10h]
828f0d47 894810 mov dword ptr [eax+10h],ecx
828f0d4a 5d pop ebp
828f0d4b c20c00 ret 0Ch

文档:KeInitializeDpc function (wdm.h) - Windows drivers | Microsoft Docs,函数原型:

1
2
3
4
5
void KeInitializeDpc(
[out] __drv_aliasesMem PRKDPC Dpc,
[in] PKDEFERRED_ROUTINE DeferredRoutine,
[in, optional] __drv_aliasesMem PVOID DeferredContext
);

KDPC 结构

1
2
3
4
5
6
7
8
9
10
ntdll!_KDPC
+0x000 Type : UChar
+0x001 Importance : UChar
+0x002 Number : Uint2B
+0x004 DpcListEntry : _LIST_ENTRY
+0x00c DeferredRoutine : Ptr32 void
+0x010 DeferredContext : Ptr32 Void
+0x014 SystemArgument1 : Ptr32 Void
+0x018 SystemArgument2 : Ptr32 Void
+0x01c DpcData : Ptr32 Void

反编译:

1
2
3
4
5
6
7
8
9
10
void __cdecl KeInitializeDpc(PKDPC Dpc, 
PKDERFERED_ROUTINE DeferredRoutine,
PVOID DeferredContext){
Dpc->DpcData = 0;
Dpc->Type = 13h;
Dpc->Importance = 1;
Dpc->Number = 0;
Dpc->DeferredRoutine = DeferredRoutine;
Dpc->DeferredContext = DeferredContext;
}
KeInitializeApc
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
nt!KeInitializeApc:
828ffdf3 8bff mov edi,edi
828ffdf5 55 push ebp
828ffdf6 8bec mov ebp,esp
828ffdf8 8b4508 mov eax,dword ptr [ebp+8]
828ffdfb 8b5510 mov edx,dword ptr [ebp+10h]
828ffdfe 8b4d0c mov ecx,dword ptr [ebp+0Ch]
828ffe01 c60012 mov byte ptr [eax],12h
828ffe04 c6400230 mov byte ptr [eax+2],30h
828ffe08 83fa02 cmp edx,2
828ffe0b 7506 jne nt!KeInitializeApc+0x20 (828ffe13) Branch

nt!KeInitializeApc+0x1a:
828ffe0d 8a9134010000 mov dl,byte ptr [ecx+134h]

nt!KeInitializeApc+0x20:
828ffe13 894808 mov dword ptr [eax+8],ecx
828ffe16 8b4d14 mov ecx,dword ptr [ebp+14h]
828ffe19 894814 mov dword ptr [eax+14h],ecx
828ffe1c 8b4d18 mov ecx,dword ptr [ebp+18h]
828ffe1f 88502c mov byte ptr [eax+2Ch],dl
828ffe22 894818 mov dword ptr [eax+18h],ecx
828ffe25 8b4d1c mov ecx,dword ptr [ebp+1Ch]
828ffe28 33d2 xor edx,edx
828ffe2a 89481c mov dword ptr [eax+1Ch],ecx
828ffe2d 3bca cmp ecx,edx
828ffe2f 740e je nt!KeInitializeApc+0x4c (828ffe3f) Branch

nt!KeInitializeApc+0x3e:
828ffe31 8a4d20 mov cl,byte ptr [ebp+20h]
828ffe34 88482d mov byte ptr [eax+2Dh],cl
828ffe37 8b4d24 mov ecx,dword ptr [ebp+24h]
828ffe3a 894820 mov dword ptr [eax+20h],ecx
828ffe3d eb06 jmp nt!KeInitializeApc+0x52 (828ffe45) Branch

nt!KeInitializeApc+0x4c:
828ffe3f 88502d mov byte ptr [eax+2Dh],dl
828ffe42 895020 mov dword ptr [eax+20h],edx

nt!KeInitializeApc+0x52:
828ffe45 88502e mov byte ptr [eax+2Eh],dl
828ffe48 5d pop ebp
828ffe49 c22000 ret 20h

没找到官方的文档,参考KeInitializeApc (codewarrior.cn),函数原型:

1
2
3
4
5
6
7
8
9
10
11
VOID
KeInitializeApc(
IN PRKAPC Apc,
IN PRKTHREAD Thread,
IN KAPC_ENVIRONMENT Environment,
IN PKKERNEL_ROUTINE KernelRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,
IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL,
IN KPROCESSOR_MODE ApcMode OPTIONAL,
IN PVOID NormalContext OPTIONAL
);

APC 结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ntdll!_KAPC
+0x000 Type : UChar
+0x001 SpareByte0 : UChar
+0x002 Size : UChar
+0x003 SpareByte1 : UChar
+0x004 SpareLong0 : Uint4B
+0x008 Thread : Ptr32 _KTHREAD
+0x00c ApcListEntry : _LIST_ENTRY
+0x014 KernelRoutine : Ptr32 void
+0x018 RundownRoutine : Ptr32 void
+0x01c NormalRoutine : Ptr32 void
+0x020 NormalContext : Ptr32 Void
+0x024 SystemArgument1 : Ptr32 Void
+0x028 SystemArgument2 : Ptr32 Void
+0x02c ApcStateIndex : Char
+0x02d ApcMode : Char
+0x02e Inserted : UChar

KTHREAD 结构:

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
kd> dt _KTHREAD
ntdll!_KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 CycleTime : Uint8B
+0x018 HighCycleTime : Uint4B
+0x020 QuantumTarget : Uint8B
+0x028 InitialStack : Ptr32 Void
+0x02c StackLimit : Ptr32 Void
+0x030 KernelStack : Ptr32 Void
+0x034 ThreadLock : Uint4B
+0x038 WaitRegister : _KWAIT_STATUS_REGISTER
+0x039 Running : UChar
+0x03a Alerted : [2] UChar
+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
+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
+0x040 ApcState : _KAPC_STATE
+0x040 ApcStateFill : [23] UChar
+0x057 Priority : Char
+0x058 NextProcessor : Uint4B
+0x05c DeferredProcessor : Uint4B
+0x060 ApcQueueLock : Uint4B
+0x064 ContextSwitches : Uint4B
+0x068 State : UChar
+0x069 NpxState : Char
+0x06a WaitIrql : UChar
+0x06b WaitMode : Char
+0x06c WaitStatus : Int4B
+0x070 WaitBlockList : Ptr32 _KWAIT_BLOCK
+0x074 WaitListEntry : _LIST_ENTRY
+0x074 SwapListEntry : _SINGLE_LIST_ENTRY
+0x07c Queue : Ptr32 _KQUEUE
+0x080 WaitTime : Uint4B
+0x084 KernelApcDisable : Int2B
+0x086 SpecialApcDisable : Int2B
+0x084 CombinedApcDisable : Uint4B
+0x088 Teb : Ptr32 Void
+0x090 Timer : _KTIMER
+0x0b8 AutoAlignment : Pos 0, 1 Bit
+0x0b8 DisableBoost : Pos 1, 1 Bit
+0x0b8 EtwStackTraceApc1Inserted : Pos 2, 1 Bit
+0x0b8 EtwStackTraceApc2Inserted : Pos 3, 1 Bit
+0x0b8 CalloutActive : Pos 4, 1 Bit
+0x0b8 ApcQueueable : Pos 5, 1 Bit
+0x0b8 EnableStackSwap : Pos 6, 1 Bit
+0x0b8 GuiThread : Pos 7, 1 Bit
+0x0b8 UmsPerformingSyscall : Pos 8, 1 Bit
+0x0b8 VdmSafe : Pos 9, 1 Bit
+0x0b8 UmsDispatched : Pos 10, 1 Bit
+0x0b8 ReservedFlags : Pos 11, 21 Bits
+0x0b8 ThreadFlags : Int4B
+0x0bc ServiceTable : Ptr32 Void
+0x0c0 WaitBlock : [4] _KWAIT_BLOCK
+0x120 QueueListEntry : _LIST_ENTRY
+0x128 TrapFrame : Ptr32 _KTRAP_FRAME
+0x12c FirstArgument : Ptr32 Void
+0x130 CallbackStack : Ptr32 Void
+0x130 CallbackDepth : Uint4B
+0x134 ApcStateIndex : UChar
+0x135 BasePriority : Char
+0x136 PriorityDecrement : Char
+0x136 ForegroundBoost : Pos 0, 4 Bits
+0x136 UnusualBoost : Pos 4, 4 Bits
+0x137 Preempted : UChar
+0x138 AdjustReason : UChar
+0x139 AdjustIncrement : Char
+0x13a PreviousMode : Char
+0x13b Saturation : Char
+0x13c SystemCallNumber : Uint4B
+0x140 FreezeCount : Uint4B
+0x144 UserAffinity : _GROUP_AFFINITY
+0x150 Process : Ptr32 _KPROCESS
+0x154 Affinity : _GROUP_AFFINITY
+0x160 IdealProcessor : Uint4B
+0x164 UserIdealProcessor : Uint4B
+0x168 ApcStatePointer : [2] Ptr32 _KAPC_STATE
+0x170 SavedApcState : _KAPC_STATE
+0x170 SavedApcStateFill : [23] UChar
+0x187 WaitReason : UChar
+0x188 SuspendCount : Char
+0x189 Spare1 : Char
+0x18a OtherPlatformFill : UChar
+0x18c Win32Thread : Ptr32 Void
+0x190 StackBase : Ptr32 Void
+0x194 SuspendApc : _KAPC
+0x194 SuspendApcFill0 : [1] UChar
+0x195 ResourceIndex : UChar
+0x194 SuspendApcFill1 : [3] UChar
+0x197 QuantumReset : UChar
+0x194 SuspendApcFill2 : [4] UChar
+0x198 KernelTime : Uint4B
+0x194 SuspendApcFill3 : [36] UChar
+0x1b8 WaitPrcb : Ptr32 _KPRCB
+0x194 SuspendApcFill4 : [40] UChar
+0x1bc LegoData : Ptr32 Void
+0x194 SuspendApcFill5 : [47] UChar
+0x1c3 LargeStack : UChar
+0x1c4 UserTime : Uint4B
+0x1c8 SuspendSemaphore : _KSEMAPHORE
+0x1c8 SuspendSemaphorefill : [20] UChar
+0x1dc SListFaultCount : Uint4B
+0x1e0 ThreadListEntry : _LIST_ENTRY
+0x1e8 MutantListHead : _LIST_ENTRY
+0x1f0 SListFaultAddress : Ptr32 Void
+0x1f4 ThreadCounters : Ptr32 _KTHREAD_COUNTERS
+0x1f8 XStateSave : Ptr32 _XSTATE_SAVE

反编译:

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
VOID __cdecl
KeInitializeApc(
IN PRKAPC Apc,
IN PRKTHREAD Thread,
IN KAPC_ENVIRONMENT Environment,
IN PKKERNEL_ROUTINE KernelRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,
IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL,
IN KPROCESSOR_MODE ApcMode OPTIONAL,
IN PVOID NormalContext OPTIONAL
){
KAPC_ENVIRONMENT Env = Environment; // edx
Byte ApcStateIndex; // dl
PRKTHREAD Th = Thread; // ecx
Apc->Type = 12h;
Apc->Size = 30;
if(Env == 2){
ApcStateIndex = Thread->ApcStateIndex;
}
Apc->Thread = Th;
Apc->KernelRoutine = KernelRoutine;
Apc->RundownRoutine = RundownRoutine;
Apc->ApcStateIndex = ApcStateIndex;
Apc->NormalRoutine = NormalRoutine;
if(NormalRoutine != 0){
Apc->ApcMode = ApcMode;
Apc->NormalContext = NormalContext;
}
else{
Apc->ApcMode = 0;
Apc->NormalContext = 0;
}
Apc->Inserted = 0;
}
ObFastDereferenceObject
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
nt!ObFastDereferenceObject:
828d0a2c 8bff mov edi,edi
828d0a2e 55 push ebp
828d0a2f 8bec mov ebp,esp
828d0a31 51 push ecx
828d0a32 8b0a mov ecx,dword ptr [edx]
828d0a34 56 push esi
828d0a35 57 push edi
828d0a36 8bc1 mov eax,ecx
828d0a38 eb13 jmp nt!ObFastDereferenceObject+0x21 (828d0a4d) Branch

nt!ObFastDereferenceObject+0xe:
828d0a3a 8d4101 lea eax,[ecx+1]
828d0a3d 8bf0 mov esi,eax
828d0a3f 8bfa mov edi,edx
828d0a41 8bc1 mov eax,ecx
828d0a43 f00fb137 lock cmpxchg dword ptr [edi],esi
828d0a47 3bc1 cmp eax,ecx
828d0a49 7412 je nt!ObFastDereferenceObject+0x31 (828d0a5d) Branch

nt!ObFastDereferenceObject+0x1f:
828d0a4b 8bc8 mov ecx,eax

nt!ObFastDereferenceObject+0x21:
828d0a4d 334508 xor eax,dword ptr [ebp+8]
828d0a50 83f807 cmp eax,7
828d0a53 72e5 jb nt!ObFastDereferenceObject+0xe (828d0a3a) Branch

nt!ObFastDereferenceObject+0x29:
828d0a55 8b4d08 mov ecx,dword ptr [ebp+8]
828d0a58 e86672ffff call nt!ObfDereferenceObject (828c7cc3)

nt!ObFastDereferenceObject+0x31:
828d0a5d 5f pop edi
828d0a5e 5e pop esi
828d0a5f 59 pop ecx
828d0a60 5d pop ebp
828d0a61 c20400 ret 4

反编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
VOID FASTCALL ObFastDereferenceObject (IN PEX_FAST_REF FastRef, IN PVOID Object){
PEX_FAST_REF Ref = FastRef; // edx
DWORD v1 = *Ref; // ecx
DWORD v2 = v1; // eax
DWORD v3; // esi
do {
v2 = v2^Object;
if(v2 >= 7) {
break;
}
v2 = *(v1 + 1);
v3 = v2;
v2 = v1;
if(v2 == *Object){ Object = v3; }
else { v2 = *Object; }
if(v1 == v2){ return; }
else{ v1 = v2 }
} while(True);
ObfDereferenceObject(Object);
}
KeInitializeQueue
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
nt!KeInitializeQueue:
8290487b 8bff mov edi,edi
8290487d 55 push ebp
8290487e 8bec mov ebp,esp
82904880 8b4508 mov eax,dword ptr [ebp+8]
82904883 c60004 mov byte ptr [eax],4
82904886 c640020a mov byte ptr [eax+2],0Ah
8290488a 33d2 xor edx,edx
8290488c 885001 mov byte ptr [eax+1],dl
8290488f 895004 mov dword ptr [eax+4],edx
82904892 8d4808 lea ecx,[eax+8]
82904895 894904 mov dword ptr [ecx+4],ecx
82904898 8909 mov dword ptr [ecx],ecx
8290489a 8d4810 lea ecx,[eax+10h]
8290489d 894904 mov dword ptr [ecx+4],ecx
829048a0 8909 mov dword ptr [ecx],ecx
829048a2 8d4820 lea ecx,[eax+20h]
829048a5 894904 mov dword ptr [ecx+4],ecx
829048a8 8909 mov dword ptr [ecx],ecx
829048aa 8b4d0c mov ecx,dword ptr [ebp+0Ch]
829048ad 895018 mov dword ptr [eax+18h],edx
829048b0 3bca cmp ecx,edx
829048b2 7506 jne nt!KeInitializeQueue+0x3f (829048ba) Branch

nt!KeInitializeQueue+0x39:
829048b4 8b0d6c999b82 mov ecx,dword ptr [nt!KeNumberProcessors (829b996c)]

nt!KeInitializeQueue+0x3f:
829048ba 89481c mov dword ptr [eax+1Ch],ecx
829048bd 5d pop ebp
829048be c20800 ret 8

文档:KeInitializeQueue function (ntifs.h) - Windows drivers | Microsoft Docs,函数原型:

1
2
3
4
void KeInitializeQueue(
[out] PRKQUEUE Queue,
[in] ULONG Count
);

第一个参数是指向 KQUEUE 的指针,KQUEUE 结构:

1
2
3
4
5
6
ntdll!_KQUEUE
+0x000 Header : _DISPATCHER_HEADER
+0x010 EntryListHead : _LIST_ENTRY
+0x018 CurrentCount : Uint4B
+0x01c MaximumCount : Uint4B
+0x020 ThreadListHead : _LIST_ENTRY

其中 _DISPATCHER_HEADER结构:

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
ntdll!_DISPATCHER_HEADER
+0x000 Type : UChar
+0x001 TimerControlFlags : UChar
+0x001 Absolute : Pos 0, 1 Bit
+0x001 Coalescable : Pos 1, 1 Bit
+0x001 KeepShifting : Pos 2, 1 Bit
+0x001 EncodedTolerableDelay : Pos 3, 5 Bits
+0x001 Abandoned : UChar
+0x001 Signalling : UChar
+0x002 ThreadControlFlags : UChar
+0x002 CpuThrottled : Pos 0, 1 Bit
+0x002 CycleProfiling : Pos 1, 1 Bit
+0x002 CounterProfiling : Pos 2, 1 Bit
+0x002 Reserved : Pos 3, 5 Bits
+0x002 Hand : UChar
+0x002 Size : UChar
+0x003 TimerMiscFlags : UChar
+0x003 Index : Pos 0, 1 Bit
+0x003 Processor : Pos 1, 5 Bits
+0x003 Inserted : Pos 6, 1 Bit
+0x003 Expired : Pos 7, 1 Bit
+0x003 DebugActive : UChar
+0x003 ActiveDR7 : Pos 0, 1 Bit
+0x003 Instrumented : Pos 1, 1 Bit
+0x003 Reserved2 : Pos 2, 4 Bits
+0x003 UmsScheduled : Pos 6, 1 Bit
+0x003 UmsPrimary : Pos 7, 1 Bit
+0x003 DpcActive : UChar
+0x000 Lock : Int4B
+0x004 SignalState : Int4B
+0x008 WaitListHead : _LIST_ENTRY

_LIST_ENTRY:

1
2
3
ntdll!_LIST_ENTRY
+0x000 Flink : Ptr32 _LIST_ENTRY
+0x004 Blink : Ptr32 _LIST_ENTRY

反编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void __cdecl KeInitializeQueue(PRKQUEUE Queue, ULONG Count){
Queue->Header.Type = 4;
Queue->Header.ThreadControlFlags = 0ah;
Queue->Header.TimerControlFlags = 0;
Queue->Header.SignalState = 0;

_LIST_ENTRY* head = &(Queue->Header.WaitListHead);
head->Blink = head;
head->Flink = head;

_LIST_ENTRY* head2 = &(Queue->ThreadListHead);
head2->Blink = head2
head2->Flink = head2;

Queue->CurrentCount = 0;
if(Count == 0){
Queue->MaximumCount = KeNumberProcessors;
}
else{
Queue->MaximumCount = Count;
}
};
KxWaitForLockChainValid –

我使用的 Win7 SP1 x86 中没有找到这个函数,待续。

1

KeReadyThread
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
nt!KeReadyThread:
828f11fc 8bff mov edi,edi
828f11fe 56 push esi
828f11ff 8bf0 mov esi,eax
828f1201 8b4650 mov eax,dword ptr [esi+50h]
828f1204 8b4874 mov ecx,dword ptr [eax+74h]
828f1207 f6c107 test cl,7
828f120a 7409 je nt!KeReadyThread+0x19 (828f1215) Branch

nt!KeReadyThread+0x10:
828f120c e84751f8ff call nt!KiInSwapSingleProcess (82876358)
828f1211 84c0 test al,al
828f1213 7505 jne nt!KeReadyThread+0x1e (828f121a) Branch

nt!KeReadyThread+0x19:
828f1215 e868ec0000 call nt!KiFastReadyThread (828ffe82)

nt!KeReadyThread+0x1e:
828f121a 5e pop esi
828f121b c3 ret

非官方文档:KeReadyThread (codewarrior.cn),函数原型:

1
2
3
4
VOID
KeReadyThread(
IN PKTHREAD Thread
);

第一个参数是指向 KTHREAD 的指针,结构在KeInitializeAPC中已给出。反编译:

1
2
3
4
5
6
7
8
```





##### KiInitializeTSS

nt!KiInitializeTSS:
82851359 8bff mov edi,edi
8285135b 55 push ebp
8285135c 8bec mov ebp,esp
8285135e 8b4508 mov eax,dword ptr [ebp+8]
82851361 b9ac200000 mov ecx,20ACh
82851366 66894866 mov word ptr [eax+66h],cx
8285136a 33c9 xor ecx,ecx
8285136c 6a10 push 10h
8285136e 66894864 mov word ptr [eax+64h],cx
82851372 66894860 mov word ptr [eax+60h],cx
82851376 59 pop ecx
82851377 66894808 mov word ptr [eax+8],cx
8285137b 5d pop ebp
8285137c c20400 ret 4

1
2
3

非官方文档:[KiInitializeTSS (codewarrior.cn)](https://www.codewarrior.cn/ntdoc/winnt/ke/i386/KiInitializeTSS.htm),函数原型:

VOID
KiInitializeTSS(
IN PKTSS Tss
);

1
2
3

KTSS 结构:

ntdll!_KTSS
+0x000 Backlink : Uint2B
+0x002 Reserved0 : Uint2B
+0x004 Esp0 : Uint4B
+0x008 Ss0 : Uint2B
+0x00a Reserved1 : Uint2B
+0x00c NotUsed1 : [4] Uint4B
+0x01c CR3 : Uint4B
+0x020 Eip : Uint4B
+0x024 EFlags : Uint4B
+0x028 Eax : Uint4B
+0x02c Ecx : Uint4B
+0x030 Edx : Uint4B
+0x034 Ebx : Uint4B
+0x038 Esp : Uint4B
+0x03c Ebp : Uint4B
+0x040 Esi : Uint4B
+0x044 Edi : Uint4B
+0x048 Es : Uint2B
+0x04a Reserved2 : Uint2B
+0x04c Cs : Uint2B
+0x04e Reserved3 : Uint2B
+0x050 Ss : Uint2B
+0x052 Reserved4 : Uint2B
+0x054 Ds : Uint2B
+0x056 Reserved5 : Uint2B
+0x058 Fs : Uint2B
+0x05a Reserved6 : Uint2B
+0x05c Gs : Uint2B
+0x05e Reserved7 : Uint2B
+0x060 LDT : Uint2B
+0x062 Reserved8 : Uint2B
+0x064 Flags : Uint2B
+0x066 IoMapBase : Uint2B
+0x068 IoMaps : [1] _KiIoAccessMap
+0x208c IntDirectionMap : [32] UChar

1
2
3

反编译:

VOID __cdecl KiInitializeTSS(PKTSS Tss){
Tss->ToMapBase = 20ACh;
Tss->Flags = 0;
Tss->LDT = 0;
Tss->Ss0 = 10h;
}

1
2
3
4
5
6
7
8
9
10
11
12
13

##### RtlValidateUnicodeString --

待续





#### 6

感谢万能的网友,书中给出的 Sample H 的 SHA1 值为 cb3b2403e1d777c250210d4ed4567cb527cab0f4,这个样本(我)找不到。有网页:[Malware Samples For Educative Purposes (grsecurity.net)](https://grsecurity.net/malware_research/),提供了本书中样本的合集,但其中 Sample H 的 SHA1 不同,并且这个 Sample H 并没有书中所说的``sub_13846``等等函数。查到一篇博客:[Practical Reverse Engineering Solutions – Page 35 (Part III) - my go at exercises 6 on page 35 (bin.re)](https://bin.re/blog/practical-reverse-engineering-solutions-page-35-part-iii/),其中提到了书中对于 Sample H 给出的函数偏移始终比该 Sample H 大出 4 字节,因此实际指的是``sub_13842``。

.text:00013842 ; =============== S U B R O U T I N E =======================================
.text:00013842
.text:00013842
.text:00013842 sub_13842 proc near ; CODE XREF: sub_1386E+2E8↓p
.text:00013842 ; sub_13BE2+84↓p …
.text:00013842 mov eax, [ecx+60h]
.text:00013845 push esi
.text:00013846 mov esi, [edx+8]
.text:00013849 dec byte ptr [ecx+23h]
.text:0001384C sub eax, 24h ; ‘$’
.text:0001384F mov [ecx+60h], eax
.text:00013852 mov [eax+14h], edx
.text:00013855 movzx eax, byte ptr [eax]
.text:00013858 push ecx
.text:00013859 push edx
.text:0001385A call dword ptr [esi+eax*4+38h]
.text:0001385E pop esi
.text:0001385F retn
.text:0001385F sub_13842 endp

1
2
3

首先该函数采用的是 fastcall 约定,读了 ecxedx,没有读取通过栈传递的参数,因此该函数应该有两个参数。读取的方式都是基地址+偏移的方式,因此 ecxedx 应该是两个结构体的指针。函数原型:

ret_type __fastcall sub_13842(pStruct1 pst1, pStruct2 pst2);

1
2
3

接下来逐行来看,反编译一下

mov eax,[ecx+60h]
var_type_1 v1 = pst1->off_60h;

push esi // 保存 esi

mov esi, [edx+8]
var_type_2 v2 = pst2->off_8h;

dec byte ptr [ecx+23h]
pst1->off_23h–; // off_23h 占 1 字节

sub eax,24h
v1 = (byte*)v1 - 24h;

mov [ecx+60h], eax
pst1->off_60h = v1;

mov [eax+14h],edx
v1->off_14h = pst2;

movzx eax, byte ptr [eax]
int v3 = (byte)v1

push ecx
push edx
call dword ptr [esi+eax4+38h]
(v2 + v1
4 + 38h)(pst1,pst2)

pop esi
retn

1
2
3

尝试还原一下数据类型

Struct1:
unknown
+0x23 v3 Byte
unknown
+0x60 v1 pStruct3

Struct2:
unknown
+0x8 pStruct4

Struct3:
unknown
+0x14 pStruct2

Struct4:
unknown
+0x38 pfnArray Array(function)

1
2
3
4
5
6
7

书中要求看完第三章后回头看这个数据类型。

#### 7

同样是上面的网友给出了这个函数[practical-reverse-engineering/code.asm at master · baderj/practical-reverse-engineering (github.com)](https://github.com/baderj/practical-reverse-engineering/blob/master/chapter_1/page_35/exercise_7/code.asm)

mov     eax, [esp+4]
push    ebx
push    esi
mov     esi, [eax+3Ch]
add     esi, eax
movzx   eax, word ptr [esi+14h]
xor     ebx, ebx
cmp     [esi+6], bx
push    edi
lea     edi, [eax+esi+18h]
jbe     short loc_0_10BEB

loc_0_10BCE:
push [esp+0Ch+8]
push edi
call ds:dword_0_169A4
test eax, eax
pop ecx
pop ecx
jz short loc_0_10BF3
movzx eax, word ptr [esi+6]
add edi, 28h
inc ebx
cmp ebx, eax
jb short loc_0_10BCE

loc_0_10BEB:
xor eax, eax

loc_0_10BED:
pop edi
pop esi
pop ebx
retn 8

loc_0_10BF3:
mov eax, edi
jmp short loc_0_10BED

1
2

反编译:

ret_type sub_10BB6(arg_type_1 arg_1){
var_type_1 v1 = arg_1->off_3Ch;
v1 += arg_1;
int i = 0; // ebx
var_type_2 v2 = v1->off_14h;
var_type_3 v3 = (type *)(v1 + v2 + 18h);
if(v1->off_6 >= 0){
return 0;
}
do{
if( dword_0_169a4(v3, arg_n) == 0){// esp+0ch+8
return v3;
}
v3 += 28h;
i++;
}while( i < v1->off_6 );
}

1
2
3
4
5
6
7
8
9
10
11

差不多是这样。作者提示了这个函数是在搜索 PE 结构里的某些内容。首先粗略观察一下函数的开头,``arg_1``是某个结构体的指针,而``v1``也就是``arg_1->off_3Ch``应该是一个偏移量,因为稍后它又和``arg_1``相加了。

接下来去 PE 结构里看看,哪个结构体偏移``3Ch``的地方保存着一个偏移量,第一眼看到的就是``IMAGE_DOS_HEADER``,它偏移``3Ch``的成员是``e_lfanew``,即``IMAGE_NT_HEADERS``的偏移,比较符合逻辑。那么先假设``arg_type_1````pIMAGE_DOS_HEADER``S。在此基础上,``v2``是 DWORD 类型的``SizeOfOptionalHeader````v3````pIMAGE_NT_HEADERS + SizeOfOptionalHeader + 18h``,其中 ``18h``正是``OptionalHeader``相对于``IMAGE_NT_HEADERS``的偏移,所以 ``v3``实际指向了第一个``IMAGE_SECTION_HEADER``。而``v1->off_6``指向的正是``NumberOfSections``,也就是``IMAGE_SECTION_HEADER``的个数。而出现在循环体里的常量``28h``是一个``IMAGE_SECTION_HEADER``的大小。由此看来,这个假设应该是成立的。

综合来看,该函数接受一个``pIMAGE_DOS_HEADER``,在对应的 PE 文件的``IMAGE_SECTION_HEADER``数组中查找符合某条件(取决于``dowrd_0_169a4``函数)的某个``IMAGE_SECTION_HEADER``,如果查找到会返回该 Section Header 的指针,否则返回 0。

#### 8

根据上面提到的地址不同的问题,找到函数``sub_1172E``

.text:0001172E ; =============== S U B R O U T I N E =======================================
.text:0001172E
.text:0001172E
.text:0001172E sub_1172E proc near ; CODE XREF: sub_11798+115↓p
.text:0001172E ; sub_11798+157↓p
.text:0001172E
.text:0001172E arg_0 = dword ptr 4
.text:0001172E
.text:0001172E push esi
.text:0001172F mov esi, [esp+4+arg_0]
.text:00011733 dec esi
.text:00011734 jz short loc_1175F
.text:00011736 dec esi
.text:00011737 jz short loc_11755
.text:00011739 dec esi
.text:0001173A jz short loc_1174B
.text:0001173C sub esi, 9
.text:0001173F jnz short loc_1176B
.text:00011741 mov esi, [eax+8]
.text:00011744 shr esi, 1
.text:00011746 add eax, 0Ch
.text:00011749 jmp short loc_11767
.text:0001174B ; —————————————————————————
.text:0001174B
.text:0001174B loc_1174B: ; CODE XREF: sub_1172E+C↑j
.text:0001174B mov esi, [eax+3Ch]
.text:0001174E shr esi, 1
.text:00011750 add eax, 5Eh ; ‘^’
.text:00011753 jmp short loc_11767
.text:00011755 ; —————————————————————————
.text:00011755
.text:00011755 loc_11755: ; CODE XREF: sub_1172E+9↑j
.text:00011755 mov esi, [eax+3Ch]
.text:00011758 shr esi, 1
.text:0001175A add eax, 44h ; ‘D’
.text:0001175D jmp short loc_11767
.text:0001175F ; —————————————————————————
.text:0001175F
.text:0001175F loc_1175F: ; CODE XREF: sub_1172E+6↑j
.text:0001175F mov esi, [eax+3Ch]
.text:00011762 shr esi, 1
.text:00011764 add eax, 40h ; ‘@’
.text:00011767
.text:00011767 loc_11767: ; CODE XREF: sub_1172E+1B↑j
.text:00011767 ; sub_1172E+25↑j …
.text:00011767 mov [ecx], esi
.text:00011769 mov [edx], eax
.text:0001176B
.text:0001176B loc_1176B: ; CODE XREF: sub_1172E+11↑j
.text:0001176B pop esi
.text:0001176C retn 4
.text:0001176C sub_1172E endp

1
2
3

每次 ``dec esi``,等于 0 后跳转到一个位置,执行完成后最终又回到同一个位置(``loc_11767``),是一个 switch case 的结构。

ret_type sub_1172E(arg_type_1 arg_1, arg_type_2 arg_2, arg_type 3 arg_3, arg_type_4 arg_4) {// arg_1 eax
// arg_2 ecx
// arg_3 edx
// arg_4 stack
var_type_1 v1 = arg_4; // esi
switch(v1){
case 1:
v1 = arg_1->off_3Ch;
v1 >> 1;
arg_1 += 48h;
break;
case 2:
v1 = arg_1->off_3Ch;
v1 >> 1;
arg_1 += 44h;
break;
case 3:
v1 = arg_1->off_3Ch;
v1 >> 1;
arg_1 += 5eh
break;
case 12:
v1 = arg_1->off_8;
v1 >> 1;
arg_1 += 0Ch;
break;
default:
return arg_1;
}
*arg_2 = v1;
*arg_3 = arg_1;
return arg_1;
}

1
2
3

#### 9

.text:1000CEA0 ; =============== S U B R O U T I N E =======================================
.text:1000CEA0
.text:1000CEA0 ; Attributes: bp-based frame
.text:1000CEA0
.text:1000CEA0 sub_1000CEA0 proc near ; CODE XREF: sub_10007A4B+1D7↑p
.text:1000CEA0 ; sub_1000AD4D+3A↑p …
.text:1000CEA0
.text:1000CEA0 arg_0 = dword ptr 8
.text:1000CEA0 arg_4 = byte ptr 0Ch
.text:1000CEA0
.text:1000CEA0 push ebp
.text:1000CEA1 mov ebp, esp
.text:1000CEA3 push edi
.text:1000CEA4 mov edi, [ebp+arg_0]
.text:1000CEA7 xor eax, eax
.text:1000CEA9 or ecx, 0FFFFFFFFh
.text:1000CEAC repne scasb
.text:1000CEAE add ecx, 1
.text:1000CEB1 neg ecx
.text:1000CEB3 sub edi, 1
.text:1000CEB6 mov al, [ebp+arg_4]
.text:1000CEB9 std
.text:1000CEBA repne scasb
.text:1000CEBC add edi, 1
.text:1000CEBF cmp [edi], al
.text:1000CEC1 jz short loc_1000CEC7
.text:1000CEC3 xor eax, eax
.text:1000CEC5 jmp short loc_1000CEC9
.text:1000CEC7 ; —————————————————————————
.text:1000CEC7
.text:1000CEC7 loc_1000CEC7: ; CODE XREF: sub_1000CEA0+21↑j
.text:1000CEC7 mov eax, edi
.text:1000CEC9
.text:1000CEC9 loc_1000CEC9: ; CODE XREF: sub_1000CEA0+25↑j
.text:1000CEC9 cld
.text:1000CECA pop edi
.text:1000CECB leave
.text:1000CECC retn
.text:1000CECC sub_1000CEA0 endp

1
2
3

反编译

ret_type sub_1000CEA0( char* arg_0, char arg_4 ){

char* v1 = arg_0; // edi
dword v2 = sizeof(arg_0) // ecx
v1 += v2;
char v3 = arg_4;
do{
    v2--;
    if(*v2 == v3){
        return v2;
    }
} while( v2>=0 )
return 0;

}

1
2
3
4
5
6
7

#### 12

从 BeaEngine 的 [Releases](https://github.com/BeaEngine/beaengine/releases)中下载 5.3.0 版本,首先尝试编译其中的例子(examples.pdf),选择其中 ``How to decode a limited block of bytes`` 给出的源代码进行编译。

源代码(disasm.c),buffer 中的字节取自 notepad 中的一段机器码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include “beaengine-5.3.0\headers\BeaEngine.h”
void DisassembleCode(char *start_offset, int size)
{
DISASM infos;
int len;
char *end_offset = (char )start_offset + size;
(void)memset(&infos, 0, sizeof(DISASM));
infos.EIP = (UInt64)start_offset;
while (!infos.Error)
{
infos.SecurityBlock = (int)end_offset - infos.EIP;
if (infos.SecurityBlock <= 0)
break;
len = Disasm(&infos);
switch (infos.Error)
{
case OUT_OF_BLOCK:
(void)printf(“disasm engine is not allowed to read more memory \n”);
break;
case UNKNOWN_OPCODE:
(void)printf(“%s\n”, &infos.CompleteInstr);
infos.EIP += 1;
infos.Error = 0;
break;
default:
(void)printf(“%s\n”, &infos.CompleteInstr);
infos.EIP += len;
}
};
return;
}
int main(void)
{
/
1 byte is missing at the end of this buffer */
char *buffer = “\x48\x83\xc4\x38\xc3\xcc\xcc”;
DisassembleCode(buffer, strlen(buffer));
return 0;
}

1
2
3

编译:

gcc .\disasm.c .\beaengine-5.3.0\dll_x64\BeaEngine.lib

1
2
3

``dll_x64``目录下的 Beaengine.dll 放到与可执行文件同一目录,运行结果:

.\a.exe
add rsp, 38h
ret
int3
int3

1
2
3

与 Windbg 比对可知反汇编成功:

00007ffcdf4008b3 4883c438 add rsp,38h 00007ffcdf4008b7 c3 ret
00007ffcdf4008b8 cc int 3 00007ffcdf4008b9 cc int 3

1
2
3
4
5
6
7
8
9
10
11

在 ``disasm.c ``上进行修改,获取 EntryPoint



### 1.9

![1.9](practical-reverse-engineering/image-20220809141148013.png)

#### 1

mov rax, [rip]
// 或者
call $+5
pop rax

1
2
3
4
5
6
7
8
9
10
11
12
13

### 3.2.3

如无特殊说明,使用的环境为 Win 8.1 x64。

(我真服了,作者留的题也太多了吧

#### 1

> 在Windows 8 x64上,下面这些内核函数中内联的 InitalizeListHead 至少出现了一次。指出这些例程中 InitializeListHead 在何处内联。

根据书中描述,InitiallizeListHead 将 Flink 和 Blink 指向自身,对应代码如下:

VOID InitializeListHead(PLIST_ENTRY ListHead){
ListHead->Flink = ListHead->Blink = ListHead
}

1
2
3

对应汇编形如:

// x86
lea eax, [esi+2Ch]
mov [eax+4], eax
mov [eax], eax

// x64
lea r11, [rbx+48h]
mov [r11+8], r11
mov [r11], r11

1
2
3

- CcAllocateInitializeMbcb

nt!CcAllocateInitializeMbcb:
fffff8015217edd8 4053 push rbx fffff8015217edda 4883ec20 sub rsp,20h
fffff8015217edde bac0000000 mov edx,0C0h fffff8015217ede3 b900020000 mov ecx,200h
fffff8015217ede8 41b843634d62 mov r8d,624D6343h fffff8015217edee e8cd161900 call nt!ExAllocatePoolWithTag (fffff801523104c0) fffff8015217edf3 488bd8 mov rbx,rax
fffff8015217edf6 4885c0 test rax,rax fffff8015217edf9 7454 je nt!CcAllocateInitializeMbcb+0x77 (fffff801`5217ee4f) Branch

nt!CcAllocateInitializeMbcb+0x23:
fffff8015217edfb 33d2 xor edx,edx fffff8015217edfd 41b8c0000000 mov r8d,0C0h
fffff8015217ee03 488bc8 mov rcx,rax fffff8015217ee06 e8b5dc0500 call nt!memset (fffff801521dcac0) fffff8015217ee0b b8fb020000 mov eax,2FBh
fffff8015217ee10 488d4b30 lea rcx,[rbx+30h] fffff8015217ee14 668903 mov word ptr [rbx],ax
fffff8015217ee17 488d4310 lea rax,[rbx+10h] fffff8015217ee1b 48894008 mov qword ptr [rax+8],rax
fffff8015217ee1f 488900 mov qword ptr [rax],rax fffff8015217ee22 488901 mov qword ptr [rcx],rax
fffff8015217ee25 48894108 mov qword ptr [rcx+8],rax fffff8015217ee29 483900 cmp qword ptr [rax],rax
fffff8015217ee2c 7523 jne nt!CcAllocateInitializeMbcb+0x79 (fffff8015217ee51) Branch

nt!CcAllocateInitializeMbcb+0x56:

1
2
3
4
5

在``fffff801`5217ee10``处即``nt!CcAllocateInitializeMbcb+0x39``处开始,初始化了两个双向链表``[rbx+30h]``和``[rbx+10h]``。

- CmpInitcallbacks


kd> uf CmpInitcallbacks
nt!InitializeSListHead:
fffff8015214c42c 4883ec28 sub rsp,28h fffff8015214c430 f6c10f test cl,0Fh
fffff8015214c433 750e jne nt!InitializeSListHead+0x17 (fffff8015214c443) Branch

nt!InitializeSListHead+0x9:
fffff8015214c435 33c0 xor eax,eax fffff8015214c437 488901 mov qword ptr [rcx],rax
fffff8015214c43a 48894108 mov qword ptr [rcx+8],rax fffff8015214c43e 4883c428 add rsp,28h
fffff8015214c442 c3 ret

1
2
3
4
5

``nt!InitializeSListHead+0x9`` 处将``[rcx]``初始化为 NULL

- ExCreatecallback

nt!ExCreateCallback+0x146: fffff801524165c2 c70143616c6c mov dword ptr [rcx],6C6C6143h
fffff801524165c8 44887120 mov byte ptr [rcx+20h],r14b fffff801524165cc 488d4110 lea rax,[rcx+10h]
fffff801524165d0 48894008 mov qword ptr [rax+8],rax fffff801524165d4 488900 mov qword ptr [rax],rax
1
2
3
4
5
6
7
8
9
10
11

- ExpInitSystemPhase0

- ExpInitSystemPhase1

- ExpTimerInitialization

- InitBootProcessor

- IoCreateDevice


nt!IoCreateDevice+0x385:
fffff801524e3ad1 488b442450 mov rax,qword ptr [rsp+50h] fffff801524e3ad6 4883c050 add rax,50h
fffff801524e3ada 48894008 mov qword ptr [rax+8],rax fffff801524e3ade 488900 mov qword ptr [rax],rax
1
2
3

- IoInitializeIrp


nt!IoInitializeIrp+0x41:
fffff8015215b121 b806000000 mov eax,6 fffff8015215b126 668903 mov word ptr [rbx],ax
fffff8015215b129 8d4701 lea eax,[rdi+1] fffff8015215b12c 884343 mov byte ptr [rbx+43h],al
fffff8015215b12f 65488b042588010000 mov rax,qword ptr gs:[188h] fffff8015215b138 8a8842020000 mov cl,byte ptr [rax+242h]
fffff8015215b13e 488d4320 lea rax,[rbx+20h] fffff8015215b142 884b46 mov byte ptr [rbx+46h],cl
nt!IoInitializeIrp+0x65:
fffff8015215b145 48894008 mov qword ptr [rax+8],rax fffff8015215b149 488900 mov qword ptr [rax],rax
1
2
3

- KeInitializeMutex


nt!KiInitializeMutant+0x3f:
fffff801520a5c87 488b7c2448 mov rdi,qword ptr [rsp+48h] fffff801520a5c8c 488d4308 lea rax,[rbx+8]
fffff801520a5c90 48894008 mov qword ptr [rax+8],rax fffff801520a5c94 488900 mov qword ptr [rax],rax
1
2
3

- KeInitializeProcess


nt!KeInitializeProcess+0x1c:
fffff801524d2b70 c64102b2 mov byte ptr [rcx+2],0B2h fffff801524d2b74 488d4108 lea rax,[rcx+8]
fffff801524d2b78 48894008 mov qword ptr [rax+8],rax fffff801524d2b7c 488900 mov qword ptr [rax],rax
1
2
3

- KeInitializeTimerEx


nt!KeInitializeTimerEx:
fffff801520cb494 4533c0 xor r8d,r8d fffff801520cb497 488d4108 lea rax,[rcx+8]
fffff801520cb49b 80c208 add dl,8 fffff801520cb49e 4c8901 mov qword ptr [rcx],r8
fffff801520cb4a1 8811 mov byte ptr [rcx],dl fffff801520cb4a3 48894008 mov qword ptr [rax+8],rax
fffff801520cb4a7 488900 mov qword ptr [rax],rax
1
2
3

- KeInitializeTimerTable

nt!KeInitializeTimerTable+0x77: fffff801
525769b3 668983b2500000 mov word ptr [rbx+50B2h],ax
fffff801525769ba 488d8308300000 lea rax,[rbx+3008h] fffff801525769c1 488360f800 and qword ptr [rax-8],0
fffff801525769c6 48894008 mov qword ptr [rax+8],rax fffff801525769ca 488900 mov qword ptr [rax],rax
1
2
3

- KiInitializeProcessor


nt!KiInitializeProcessor+0x104:
fffff801523efeb0 4903c1 add rax,r9 fffff801523efeb3 488bcb mov rcx,rbx
fffff801523efeb6 48897c2420 mov qword ptr [rsp+20h],rdi fffff801523efebb 49f7f1 div rax,r9
fffff801523efebe 493bc6 cmp rax,r14 fffff801523efec1 490f47c6 cmova rax,r14
fffff801523efec5 898668500000 mov dword ptr [rsi+5068h],eax fffff801523efecb 89866c500000 mov dword ptr [rsi+506Ch],eax
1
2
3

- KiInitializeThread ?


nt!KiInitializeThread+0xeb:
fffff8023fddf2fb 488b0576d3feff mov rax,qword ptr [nt!KiInitialProcess+0x478 (fffff8023fdcc678)]
fffff8023fddf302 488d8b00040000 lea rcx,[rbx+400h] fffff8023fddf309 488911 mov qword ptr [rcx],rdx
fffff8023fddf30c 48894108 mov qword ptr [rcx+8],rax
1
2
3
4
5

- MiInitializeLoadedModuleList

- MiInitializePrefetchHead

nt!MiInitializePrefetchHead: fffff802
3fba2ba0 488d4108 lea rax,[rcx+8]
fffff8023fba2ba4 48894008 mov qword ptr [rax+8],rax fffff8023fba2ba8 488900 mov qword ptr [rax],rax
fffff8023fba2bab 488d4118 lea rax,[rcx+18h] fffff8023fba2baf 48894008 mov qword ptr [rax+8],rax
fffff8023fba2bb3 488900 mov qword ptr [rax],raxnt!MiInitializePrefetchHead: fffff8023fba2ba0 488d4108 lea rax,[rcx+8]
fffff8023fba2ba4 48894008 mov qword ptr [rax+8],rax fffff8023fba2ba8 488900 mov qword ptr [rax],rax
fffff8023fba2bab 488d4118 lea rax,[rcx+18h] fffff8023fba2baf 48894008 mov qword ptr [rax+8],rax
fffff8023fba2bb3 488900 mov qword ptr [rax],rax fffff8023fba2bbe 488900 mov qword ptr [rax],rax
1
2
3
4
5

三处

- PspAllocateProcess


nt!PspAllocateProcess+0x1d9:
fffff801524d1335 498d8508060000 lea rax,[r13+608h] fffff801524d133c 48894008 mov qword ptr [rax+8],rax
fffff801524d1340 488900 mov qword ptr [rax],rax fffff801524d1343 4d89b5d8020000 mov qword ptr [r13+2D8h],r14
fffff801524d134a 4d89b5c8020000 mov qword ptr [r13+2C8h],r14 fffff801524d1351 498d8570040000 lea rax,[r13+470h]
fffff801524d1358 48894008 mov qword ptr [rax+8],rax fffff801524d135c 488900 mov qword ptr [rax],rax
1
2
3
4
5

两处

- PspAllocateThread


nt!PspAllocateThread+0x21e:
fffff801524c5256 498d8e30060000 lea rcx,[r14+630h] fffff801524c525d 448bc3 mov r8d,ebx
fffff801524c5260 33d2 xor edx,edx fffff801524c5262 e8410cc9ff call nt!KeInitializeSemaphore (fffff80152155ea8) fffff801524c5267 498d86d8050000 lea rax,[r14+5D8h]
fffff801524c526e 48894008 mov qword ptr [rax+8],rax fffff801524c5272 488900 mov qword ptr [rax],rax
fffff801524c5275 498d86f8060000 lea rax,[r14+6F8h] nt!PspAllocateThread+0x244: fffff801524c527c 48894008 mov qword ptr [rax+8],rax
fffff801524c5280 488900 mov qword ptr [rax],rax fffff801524c5283 498d8608070000 lea rax,[r14+708h]
fffff801524c528a 48894008 mov qword ptr [rax+8],rax fffff801524c528e 488900 mov qword ptr [rax],rax
fffff801524c5291 4989be18070000 mov qword ptr [r14+718h],rdi fffff801524c5298 498d8658060000 lea rax,[r14+658h]
fffff801524c529f 48894008 mov qword ptr [rax+8],rax nt!PspAllocateThread+0x26b: fffff801524c52a3 488900 mov qword ptr [rax],rax
fffff801524c52a6 4989be20070000 mov qword ptr [r14+720h],rdi fffff801524c52ad 4989be08060000 mov qword ptr [r14+608h],rdi
fffff801524c52b4 498d8610060000 lea rax,[r14+610h] fffff801524c52bb 48894008 mov qword ptr [rax+8],rax
fffff801`524c52bf 488900 mov qword ptr [rax],rax
1
2
3
4
5
6


#### 2

> 在下面函数中重复前一个练习,指出 InsertHeadList 在何处内联。


VOID InsertHeadList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry){
PLIST_ENTRY Flink;
Flink = ListHead->Flink;
Entry->Flink = Flink
Entry->Blink = ListHead;
Flink->Blink = Entry;
ListHead->Flink = Entry;
return;
}

1
2
3

对应汇编:

// x86
mov edx, [ebx]
mov [ecx], edx
mov [ecx+4], ebx
mov [edx+4], ecx
mov [ebx], ecx

// x64
mov rcx, [rdi]
mov [rax+8], rdi
mov [rax], rcx
mov [rcx+8], rax
mov [rdi], rax

1
2
3
4
5

观察 C 代码,可以看到 EntryFlinkBlink 都被修改,将存储 Entry 的寄存器记为 ``entry``,则(x64 中)``[entry]````[entry+8]``都将被修改,分别被修改为为``flink````listhead``;而 ListHead->FlinkFlink->Blink 都会被修改为 Entry,即``[listhead]````[flink+8]``都被修改为``entry``

- CcSetVacbInFreeList

nt!CcSetVacbInFreeList:
fffff8015210bc30 4883ec28 sub rsp,28h fffff8015210bc34 ff0d1e332100 dec dword ptr [nt!CcNumberOfMappedVacbs (fffff8015231ef58)] fffff8015210bc3a 4c8bc1 mov r8,rcx
fffff8015210bc3d 84d2 test dl,dl fffff8015210bc3f 0f85cf7e0f00 jne nt! ?? ::FNODOBFM::string'+0x23664 (fffff80152203b14)
fffff8015210bc45 488d4110 lea rax,[rcx+10h] fffff8015210bc49 488b0dd0962400 mov rcx,qword ptr [nt!CcVacbFreeList (fffff80152355320)] fffff8015210bc50 488d15c9962400 lea rdx,[nt!CcVacbFreeList (fffff80152355320)] 1: kd> u nt!CcSetVacbInFreeList+0x27: fffff8015210bc57 488908 mov qword ptr [rax],rcx
fffff8015210bc5a 48895008 mov qword ptr [rax+8],rdx fffff8015210bc5e 48395108 cmp qword ptr [rcx+8],rdx

1
2
3
4
5
6
7
8
9



- CmpDoSort

- ExBurnMemory

- ExFreePoolWithTag - win8


nt!ExFreePoolWithTag+0xf9f:
fffff8023fceafae 4883c114 add rcx,14h fffff8023fceafb2 48c1e104 shl rcx,4
fffff8023fceafb6 4903cc add rcx,r12 fffff8023fceafb9 488b01 mov rax,qword ptr [rcx]
fffff8023fceafbc 48894b08 mov qword ptr [rbx+8],rcx fffff8023fceafc0 488903 mov qword ptr [rbx],rax
fffff8023fceafc3 48394808 cmp qword ptr [rax+8],rcx fffff8023fceafc7 7564 jne nt!ExFreePoolWithTag+0x101e (fffff8023fceb02d) kd> nt!ExFreePoolWithTag+0xfba: fffff8023fceafc9 48895808 mov qword ptr [rax+8],rbx
fffff8023fceafcd 488919 mov qword ptr [rcx],rbx
1
2
3
4
5



- IoPageRead - win8

nt!IoPageRead+0x1a0: fffff802
3fae91f0 f0480fba2b00 lock bts qword ptr [rbx],0
fffff8023fae91f6 0f8233010000 jb nt!IoPageRead+0x2df (fffff8023fae932f)
fffff8023fae91fc 498b06 mov rax,qword ptr [r14] fffff8023fae91ff 4c897608 mov qword ptr [rsi+8],r14
fffff8023fae9203 488906 mov qword ptr [rsi],rax fffff8023fae9206 4c397008 cmp qword ptr [rax+8],r14
fffff8023fae920a 0f8526111600 jne nt! ?? ::FNODOBFM::string’+0xa17a (fffff8023fc4a336) fffff8023fae9210 48897008 mov qword ptr [rax+8],rsi
fffff8023fae9214 498936 mov qword ptr [r14],rsi
1
2
3

- IovpCallDriver1

nt!IovpCallDriver1+0x440: fffff802
400c4ac0 488b54d070 mov rdx,qword ptr [rax+rdx*8+70h]
fffff802400c4ac5 488d4710 lea rax,[rdi+10h] fffff802400c4ac9 48895728 mov qword ptr [rdi+28h],rdx
fffff802400c4acd 0fba77041e btr dword ptr [rdi+4],1Eh fffff802400c4ad2 4c8b00 mov r8,qword ptr [rax]
fffff802400c4ad5 498d5720 lea rdx,[r15+20h] fffff802400c4ad9 4c8902 mov qword ptr [rdx],r8
fffff802400c4adc 48894208 mov qword ptr [rdx+8],rax fffff802400c4ae0 49394008 cmp qword ptr [r8+8],rax
fffff802400c4ae4 7407 je nt!IovpCallDriver1+0x46d (fffff802400c4aed)
fffff802400c4ae6 b903000000 mov ecx,3 fffff802400c4aeb cd29 int 29h
fffff802400c4aed 49895008 mov qword ptr [r8+8],rdx fffff802400c4af1 488910 mov qword ptr [rax],rdx
1
2
3
4
5



- KeInitThread- win8


nt!KeInitThread+0x15b:
fffff8023fdd92bb 4c33d8 xor r11,rax fffff8023fdd92be 4c895b30 mov qword ptr [rbx+30h],r11
fffff8023fdd92c2 488d87d0010000 lea rax,[rdi+1D0h] fffff8023fdd92c9 c7401001020201 mov dword ptr [rax+10h],1020201h
fffff8023fdd92d0 ba01000000 mov edx,1 fffff8023fdd92d5 4883c308 add rbx,8
fffff8023fdd92d9 488b0b mov rcx,qword ptr [rbx] fffff8023fdd92dc 488908 mov qword ptr [rax],rcx
fffff8023fdd92df 48895808 mov qword ptr [rax+8],rbx fffff8023fdd92e3 48395908 cmp qword ptr [rcx+8],rbx
fffff8023fdd92e7 0f856f230100 jne nt! ?? ::OKHAJAOM::string’+0x20a (fffff8023fdeb65c) fffff8023fdd92ed 48894108 mov qword ptr [rcx+8],rax
fffff8023fdd92f1 488903 mov qword ptr [rbx],rax
1
2
3
4
5



- KiInsertQueueApc - win8

nt!KiInsertQueueApc+0x47: fffff802
3fb4bce7 4803c8 add rcx,rax
fffff8023fb4bcea 488b4108 mov rax,qword ptr [rcx+8] fffff8023fb4bcee 483bc1 cmp rax,rcx
fffff8023fb4bcf1 0f850a030000 jne nt!KiInsertQueueApc+0x360 (fffff8023fb4c001)
fffff8023fb4bcf7 4c8b00 mov r8,qword ptr [rax] fffff8023fb4bcfa 488d4a10 lea rcx,[rdx+10h]
fffff8023fb4bcfe 4c8901 mov qword ptr [rcx],r8 fffff8023fb4bd01 48894108 mov qword ptr [rcx+8],rax
fffff8023fb4bd05 49394008 cmp qword ptr [r8+8],rax fffff8023fb4bd09 0f85fb4e1000 jne nt! ?? ::FNODOBFM::string'+0x145d0 (fffff8023fc50c0a)
fffff8023fb4bd0f 49894808 mov qword ptr [r8+8],rcx fffff8023fb4bd13 488908 mov qword ptr [rax],rcx

nt!KiInsertQueueApc+0x292:
fffff8023fb4bf34 488b01 mov rax,qword ptr [rcx] fffff8023fb4bf37 49894808 mov qword ptr [r8+8],rcx
fffff8023fb4bf3b 498900 mov qword ptr [r8],rax fffff8023fb4bf3e 48394808 cmp qword ptr [rax+8],rcx
fffff8023fb4bf42 0f85b44c1000 jne nt! ?? ::FNODOBFM::string’+0x145c2 (fffff8023fc50bfc) fffff8023fb4bf48 4c894008 mov qword ptr [rax+8],r8
fffff8023fb4bf4c 4c8901 mov qword ptr [rcx],r8

1
2
3
4
5

两处

- KeInsertQueueDpc- win8

nt!KeInsertQueueDpc+0x252: fffff8023fb1e1d3 4489942480000000 mov dword ptr [rsp+80h],r10d
fffff8023fb1e1db e93afeffff jmp nt!KeInsertQueueDpc+0x9a (fffff8023fb1e01a)
fffff8023fb1e1e0 cc int 3 fffff8023fb1e1e1 b102 mov cl,2
fffff8023fb1e1e3 ff15e7a12a00 call qword ptr [nt!_imp_HalRequestSoftwareInterrupt (fffff8023fdc83d0)]
fffff8023fb1e1e9 e961ffffff jmp nt!KeInsertQueueDpc+0x1cf (fffff8023fb1e14f)
fffff8023fb1e1ee 488b0f mov rcx,qword ptr [rdi] fffff8023fb1e1f1 48897808 mov qword ptr [rax+8],rdi
fffff8023fb1e1f5 488908 mov qword ptr [rax],rcx fffff8023fb1e1f8 48397908 cmp qword ptr [rcx+8],rdi
fffff8023fb1e1fc 0f8511191300 jne nt! ?? ::FNODOBFM::string’+0x12087 (fffff8023fc4fb13) fffff8023fb1e202 48894108 mov qword ptr [rcx+8],rax
fffff8023fb1e206 488907 mov qword ptr [rdi],rax
1
2
3

- KiQueueReadyThread - win8

nt!KiQueueReadyThread+0x97: fffff802
3fb35367 4881c3d8000000 add rbx,0D8h
fffff8023fb3536e 48c1e104 shl rcx,4 fffff8023fb35372 8983dc000000 mov dword ptr [rbx+0DCh],eax
fffff8023fb35378 4803cf add rcx,rdi fffff8023fb3537b 4084ed test bpl,bpl
fffff8023fb3537e 7444 je nt!KiQueueReadyThread+0xf4 (fffff8023fb353c4)
fffff8023fb35380 488b01 mov rax,qword ptr [rcx] fffff8023fb35383 48894b08 mov qword ptr [rbx+8],rcx
fffff8023fb35387 488903 mov qword ptr [rbx],rax fffff8023fb3538a 48394808 cmp qword ptr [rax+8],rcx
fffff8023fb3538e 0f8597c31100 jne nt! ?? ::FNODOBFM::string’+0x15448 (fffff8023fc5172b) fffff8023fb35394 48895808 mov qword ptr [rax+8],rbx
fffff8023fb35398 488919 mov qword ptr [rcx],rbx
1
2
3

- MiInsertInSystemSpace - win8

nt!MiInsertInSystemSpace+0x201: fffff802
3faa999d 498b03 mov rax,qword ptr [r11]
fffff8023faa99a0 4d895e08 mov qword ptr [r14+8],r11 fffff8023faa99a4 498906 mov qword ptr [r14],rax
fffff8023faa99a7 4c395808 cmp qword ptr [rax+8],r11 fffff8023faa99ab 0f85f59a1100 jne nt! ?? ::FNODOBFM::string'+0x19f67 (fffff8023fbc34a6)
fffff8023faa99b1 4c897008 mov qword ptr [rax+8],r14 fffff8023faa99b5 4d8933 mov qword ptr [r11],r14
1
2
3

- MiUpdateWsle - win8


nt!MiUpdateWsle+0x279:
fffff8023fb3d409 488b4708 mov rax,qword ptr [rdi+8] fffff8023fb3d40d 48397908 cmp qword ptr [rcx+8],rdi
fffff8023fb3d411 0f85854ff6ff jne nt! ?? ::FNODOBFM::string’+0x1d562 (fffff8023faa239c) fffff8023fb3d417 483938 cmp qword ptr [rax],rdi
fffff8023fb3d41a 0f857c4ff6ff jne nt! ?? ::FNODOBFM::string’+0x1d562 (fffff8023faa239c) fffff8023fb3d420 488908 mov qword ptr [rax],rcx
fffff8023fb3d423 48894108 mov qword ptr [rcx+8],rax fffff8023fb3d427 488b05f2942000 mov rax,qword ptr [nt!MmWorkingSetExpansionHead (fffff8023fd46920)] fffff8023fb3d42e 488d0deb942000 lea rcx,[nt!MmWorkingSetExpansionHead (fffff8023fd46920)] fffff8023fb3d435 488907 mov qword ptr [rdi],rax
fffff8023fb3d438 48894f08 mov qword ptr [rdi+8],rcx fffff8023fb3d43c 48394808 cmp qword ptr [rax+8],rcx
fffff8023fb3d440 0f854f4ff6ff jne nt! ?? ::FNODOBFM::string’+0x1d55b (fffff8023faa2395) fffff8023fb3d446 48897808 mov qword ptr [rax+8],rdi
fffff8023fb3d44a 48893dcf942000 mov qword ptr [nt!MmWorkingSetExpansionHead (fffff8023fd46920)],rdi
1
2
3
4
5



- ObpInsertCallbackByAltitude - win8


nt!ObpInsertCallbackByAltitude+0x40:
fffff8023ff67380 f0480fba2b00 lock bts qword ptr [rbx],0 fffff8023ff67386 0f8210761100 jb nt! ?? ::NNGAKEGL::string'+0x3a8da (fffff8024007e99c)
fffff8023ff6738c 4981c6c8000000 add r14,0C8h fffff8023ff67393 498b3e mov rdi,qword ptr [r14]
fffff8023ff67396 493bfe cmp rdi,r14 fffff8023ff67399 0f8593000000 jne nt!ObpInsertCallbackByAltitude+0xf2 (fffff8023ff67432) fffff8023ff6739f 488b4708 mov rax,qword ptr [rdi+8]
fffff8023ff673a3 488b08 mov rcx,qword ptr [rax] kd> nt!ObpInsertCallbackByAltitude+0x66: fffff8023ff673a6 48894608 mov qword ptr [rsi+8],rax
fffff8023ff673aa 48890e mov qword ptr [rsi],rcx fffff8023ff673ad 48394108 cmp qword ptr [rcx+8],rax
fffff8023ff673b1 0f8522761100 jne nt! ?? ::NNGAKEGL::string’+0x3a917 (fffff8024007e9d9) fffff8023ff673b7 48897108 mov qword ptr [rcx+8],rsi
fffff802`3ff673bb 488930 mov qword ptr [rax],rsi
1
2
3
4
5

#### 3

> 在下面函数中重复前面练习,指出 InsertTailList 在何处内联。


VOID InsertTailList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry){
PLIST_ENTRY Blink;
Blink = ListHead->Blink;
Entry->Flink = ListHead;
Entry->Blink = Blink;
Blink->Flink = Entry;
ListHead->Blink = Entry;
return;
}

1
2
3

对应汇编:

// x86
mov ecx, [ebx+4]
mov [eax], ebx
mov [eax+4], ecx
mov [ecx], eax
mov [ebx+4], eax

// x64
mov rcx, [rdi+8]
mov [rax], rdi
mov [rax+8], rcx
mov [rcx], rax
mov [rdi+8], rax

1
2
3
4
5



- AlpcpCreateClientPort - win8

nt!AlpcpCreateClientPort+0x18f:
fffff8023fe7850f 4c8b65e0 mov r12,qword ptr [rbp-20h] fffff8023fe78513 4981c448010000 add r12,148h
fffff8023fe7851a f0490fba2c2400 lock bts qword ptr [r12],0 fffff8023fe78521 0f82a6020000 jb nt!AlpcpCreateClientPort+0x44d (fffff8023fe787cd) fffff8023fe78527 488b4610 mov rax,qword ptr [rsi+10h]
fffff8023fe7852b 488b4f10 mov rcx,qword ptr [rdi+10h] fffff8023fe7852f 488b5020 mov rdx,qword ptr [rax+20h]
fffff8023fe78533 4883c018 add rax,18h fffff8023fe78537 4883c118 add rcx,18h
fffff8023fe7853b 48895108 mov qword ptr [rcx+8],rdx fffff8023fe7853f 488901 mov qword ptr [rcx],rax
fffff8023fe78542 483902 cmp qword ptr [rdx],rax fffff8023fe78545 0f852cb51f00 jne nt! ?? ::NNGAKEGL::string'+0x2c1f9 (fffff80240073a77)
fffff8023fe7854b 48890a mov qword ptr [rdx],rcx fffff8023fe7854e 48894808 mov qword ptr [rax+8],rcx

1
2
3

- AlpcpCreateSection - win8


nt!AlpcpCreateSection+0x161:
fffff8023fe906a1 4981c738010000 add r15,138h fffff8023fe906a8 498b4708 mov rax,qword ptr [r15+8]
fffff8023fe906ac 4c893e mov qword ptr [rsi],r15 fffff8023fe906af 48894608 mov qword ptr [rsi+8],rax
fffff8023fe906b3 4c3938 cmp qword ptr [rax],r15 fffff8023fe906b6 0f852d76f7ff jne nt! ?? ::NNGAKEGL::string'+0x2f5bf (fffff8023fe07ce9)
fffff8023fe906bc 488930 mov qword ptr [rax],rsi fffff8023fe906bf 49897708 mov qword ptr [r15+8],rsi
1
2
3

- AlpcpCreateView - win8


nt!AlpcpCreateView+0x1ec:
fffff8023fe847ec f0490fba2c2400 lock bts qword ptr [r12],0 fffff8023fe847f3 0f825d010000 jb nt!AlpcpCreateView+0x354 (fffff8023fe84956) fffff8023fe847f9 4881c538010000 add rbp,138h
fffff8023fe84800 488b4508 mov rax,qword ptr [rbp+8] fffff8023fe84804 49892f mov qword ptr [r15],rbp
fffff8023fe84807 49894708 mov qword ptr [r15+8],rax fffff8023fe8480b 483928 cmp qword ptr [rax],rbp
fffff8023fe8480e 0f8503171f00 jne nt! ?? ::NNGAKEGL::string’+0x2f497 (fffff80240075f17) fffff8023fe84814 4c8938 mov qword ptr [rax],r15
fffff8023fe84817 4c897d08 mov qword ptr [rbp+8],r15
1
2
3
4
5



- AuthzBasepAddSecurityAttributeToLists - win8

nt!AuthzBasepAddSecurityAttributeToLists+0x17: fffff802
3ff4106b 4d8b4808 mov r9,qword ptr [r8+8]
fffff8023ff4106f 4c8900 mov qword ptr [rax],r8 fffff8023ff41072 4c894808 mov qword ptr [rax+8],r9
fffff8023ff41076 4d3901 cmp qword ptr [r9],r8 fffff8023ff41079 7407 je nt!AuthzBasepAddSecurityAttributeToLists+0x2e (fffff8023ff41082) fffff8023ff4107b b903000000 mov ecx,3
fffff8023ff41080 cd29 int 29h fffff8023ff41082 498901 mov qword ptr [r9],rax
fffff802`3ff41085 49894008 mov qword ptr [r8+8],rax

nt!AuthzBasepAddSecurityAttributeToLists+0x48:
fffff8023ff4109c 488d4108 lea rax,[rcx+8] fffff8023ff410a0 4c8b4008 mov r8,qword ptr [rax+8]
fffff8023ff410a4 488902 mov qword ptr [rdx],rax fffff8023ff410a7 4c894208 mov qword ptr [rdx+8],r8
fffff8023ff410ab 493900 cmp qword ptr [r8],rax fffff8023ff410ae 7407 je nt!AuthzBasepAddSecurityAttributeToLists+0x63 (fffff8023ff410b7) fffff8023ff410b0 b903000000 mov ecx,3
fffff8023ff410b5 cd29 int 29h fffff8023ff410b7 498910 mov qword ptr [r8],rdx
fffff8023ff410ba 48895008 mov qword ptr [rax+8],rdx

1
2
3
4
5

两处

- CcFlushCachePriv - win8

nt!CcFlushCachePriv+0xb36: fffff8023fb6f0c8 483901 cmp qword ptr [rcx],rax
fffff8023fb6f0cb 757c jne nt!CcFlushCachePriv+0xbb7 (fffff8023fb6f149)
fffff8023fb6f0cd 488911 mov qword ptr [rcx],rdx fffff8023fb6f0d0 48894a08 mov qword ptr [rdx+8],rcx
fffff8023fb6f0d4 488b158d3a1f00 mov rdx,qword ptr [nt!CcDirtySharedCacheMapWithLogHandleList+0x8 (fffff8023fd62b68)]
fffff8023fb6f0db 488d0d7e3a1f00 lea rcx,[nt!CcDirtySharedCacheMapWithLogHandleList (fffff8023fd62b60)]
fffff8023fb6f0e2 48895008 mov qword ptr [rax+8],rdx fffff8023fb6f0e6 488908 mov qword ptr [rax],rcx
fffff8023fb6f0e9 48390a cmp qword ptr [rdx],rcx fffff8023fb6f0ec 7554 jne nt!CcFlushCachePriv+0xbb0 (fffff8023fb6f142) fffff8023fb6f0ee 488902 mov qword ptr [rdx],rax
fffff8023fb6f0f1 488905703a1f00 mov qword ptr [nt!CcDirtySharedCacheMapWithLogHandleList+0x8 (fffff8023fd62b68)],rax
1
2
3
4
5
6
7



- CcInitializeCacheManager

- CcInsertVacbArray - win8


fffff8023fa84bcd 4c8d05ecde2d00 lea r8,[nt!CcVacbFreeList (fffff8023fd62ac0)]
kd>
nt!CcInsertVacbArray+0x60:
fffff8023fa84bd4 4c8d0df5de2d00 lea r9,[nt!CcVacbFreeHighPriorityList (fffff8023fd62ad0)]
fffff8023fa84bdb 488378f000 cmp qword ptr [rax-10h],0 fffff8023fa84be0 7536 jne nt!CcInsertVacbArray+0xa4 (fffff8023fa84c18) fffff8023fa84be2 488b0ddfde2d00 mov rcx,qword ptr [nt!CcVacbFreeList+0x8 (fffff8023fd62ac8)] fffff8023fa84be9 4c8900 mov qword ptr [rax],r8
fffff8023fa84bec 48894808 mov qword ptr [rax+8],rcx fffff8023fa84bf0 4c3901 cmp qword ptr [rcx],r8
fffff8023fa84bf3 7548 jne nt!CcInsertVacbArray+0xc9 (fffff8023fa84c3d)
kd>
nt!CcInsertVacbArray+0x81:
fffff8023fa84bf5 488901 mov qword ptr [rcx],rax fffff8023fa84bf8 ff059ade2d00 inc dword ptr [nt!CcNumberOfFreeVacbs (fffff8023fd62a98)] fffff8023fa84bfe 488905c3de2d00 mov qword ptr [nt!CcVacbFreeList+0x8 (fffff8023fd62ac8)],rax
1
2
3
4
5



- CcSetFileSizesEx

nt!CcSetFileSizesEx+0x34a: fffff802
3fb50f7c 0f851f2f0f00 jne nt! ?? ::FNODOBFM::string'+0x2876 (fffff8023fc43ea1)
fffff8023fb50f82 483930 cmp qword ptr [rax],rsi fffff8023fb50f85 0f85162f0f00 jne nt! ?? ::FNODOBFM::string'+0x2876 (fffff8023fc43ea1)
fffff8023fb50f8b 488908 mov qword ptr [rax],rcx fffff8023fb50f8e 48894108 mov qword ptr [rcx+8],rax
fffff8023fb50f92 488b050f1c2100 mov rax,qword ptr [nt!CcLazyWriterCursor+0x8 (fffff8023fd62ba8)]
fffff8023fb50f99 48894608 mov qword ptr [rsi+8],rax fffff8023fb50f9d 4c892e mov qword ptr [rsi],r13
fffff8023fb50fa0 4c3928 cmp qword ptr [rax],r13 fffff8023fb50fa3 0f85f12e0f00 jne nt! ?? ::FNODOBFM::string'+0x286f (fffff8023fc43e9a)
fffff8023fb50fa9 488930 mov qword ptr [rax],rsi fffff8023fb50fac 33d2 xor edx,edx
fffff8023fb50fae 410fb6c8 movzx ecx,r8b fffff8023fb50fb2 488935ef1b2100 mov qword ptr [nt!CcLazyWriterCursor+0x8 (fffff8023fd62ba8)],rsi
1
2
3
4
5



- CmRenameKey -win8

nt!CmRenameKey+0x3d6: fffff802
3ffab0ca 0f84da080000 je nt!CmRenameKey+0xcb6 (fffff8023ffab9aa) fffff8023ffab0d0 488b4748 mov rax,qword ptr [rdi+48h]
fffff8023ffab0d4 498d4c2420 lea rcx,[r12+20h] fffff8023ffab0d9 4805c8000000 add rax,0C8h
fffff8023ffab0df 488b5008 mov rdx,qword ptr [rax+8] fffff8023ffab0e3 488901 mov qword ptr [rcx],rax
fffff8023ffab0e6 48895108 mov qword ptr [rcx+8],rdx fffff8023ffab0ea 483902 cmp qword ptr [rdx],rax
nt!CmRenameKey+0x3f9:
fffff8023ffab0ed 7407 je nt!CmRenameKey+0x402 (fffff8023ffab0f6)
fffff8023ffab0ef b903000000 mov ecx,3 fffff8023ffab0f4 cd29 int 29h
fffff8023ffab0f6 48890a mov qword ptr [rdx],rcx fffff8023ffab0f9 48894808 mov qword ptr [rax+8],rcx

nt!CmRenameKey+0x4d5:
fffff8023ffab1c9 e84e3eafff call nt!KiCheckForKernelApcDelivery (fffff8023fa9f01c)
fffff8023ffab1ce 488b45c7 mov rax,qword ptr [rbp-39h] fffff8023ffab1d2 4989442438 mov qword ptr [r12+38h],rax
fffff8023ffab1d7 498b4e08 mov rcx,qword ptr [r14+8] fffff8023ffab1db 498d4720 lea rax,[r15+20h]
fffff8023ffab1df 4c8930 mov qword ptr [rax],r14 fffff8023ffab1e2 48894808 mov qword ptr [rax+8],rcx
fffff8023ffab1e6 4c3931 cmp qword ptr [rcx],r14 nt!CmRenameKey+0x4f5: fffff8023ffab1e9 7407 je nt!CmRenameKey+0x4fe (fffff8023ffab1f2) fffff8023ffab1eb b903000000 mov ecx,3
fffff8023ffab1f0 cd29 int 29h fffff8023ffab1f2 488901 mov qword ptr [rcx],rax
fffff8023ffab1f5 488bcf mov rcx,rdi fffff8023ffab1f8 49894608 mov qword ptr [r14+8],rax

nt!CmRenameKey+0x548:
fffff8023ffab23c 488b4308 mov rax,qword ptr [rbx+8] fffff8023ffab240 49891f mov qword ptr [r15],rbx
fffff8023ffab243 49894708 mov qword ptr [r15+8],rax fffff8023ffab247 483918 cmp qword ptr [rax],rbx
fffff8023ffab24a 7407 je nt!CmRenameKey+0x55f (fffff8023ffab253)
fffff8023ffab24c b903000000 mov ecx,3 fffff8023ffab251 cd29 int 29h
fffff8023ffab253 4c8938 mov qword ptr [rax],r15 nt!CmRenameKey+0x562: fffff8023ffab256 4c897b08 mov qword ptr [rbx+8],r15

1
2
3
4
5

三处

- ExAllocatePoolWithTag- win8


nt!ExAllocatePoolWithTag+0x9a2:
fffff8023fceb9de 4883c114 add rcx,14h fffff8023fceb9e2 48c1e104 shl rcx,4
fffff8023fceb9e6 4803cd add rcx,rbp fffff8023fceb9e9 488b4108 mov rax,qword ptr [rcx+8]
fffff8023fceb9ed 48890e mov qword ptr [rsi],rcx fffff8023fceb9f0 48894608 mov qword ptr [rsi+8],rax
fffff8023fceb9f4 483908 cmp qword ptr [rax],rcx fffff8023fceb9f7 0f85c40b0000 jne nt!ExFreePool+0x47a (fffff8023fcec5c1) nt!ExAllocatePoolWithTag+0x9c1: fffff8023fceb9fd 83bc24e800000000 cmp dword ptr [rsp+0E8h],0
fffff8023fceba05 488930 mov qword ptr [rax],rsi fffff8023fceba08 48897108 mov qword ptr [rcx+8],rsi
1
2
3

- ExFreePoolWithTag - win8


nt!ExFreePoolWithTag+0xdc2:
fffff8023fceadd1 488b4208 mov rax,qword ptr [rdx+8] fffff8023fceadd5 488911 mov qword ptr [rcx],rdx
fffff8023fceadd8 48894108 mov qword ptr [rcx+8],rax fffff8023fceaddc 483910 cmp qword ptr [rax],rdx
fffff8023fceaddf 0f853e1c0000 jne nt!ExFreePool+0x945 (fffff8023fceca23)
fffff8023fceade5 488b7db7 mov rdi,qword ptr [rbp-49h] fffff8023fceade9 488908 mov qword ptr [rax],rcx
fffff8023fceadec 48894a08 mov qword ptr [rdx+8],rcx
1
2
3

- ExQueueWorkItem - win8

fffff802
3fb2f815 488b4b20 mov rcx,qword ptr [rbx+20h]
kd>
nt!ExQueueWorkItem+0x2b9:
fffff8023fb2f819 488d4318 lea rax,[rbx+18h] fffff8023fb2f81d 48894f08 mov qword ptr [rdi+8],rcx
fffff8023fb2f821 488907 mov qword ptr [rdi],rax fffff8023fb2f824 483901 cmp qword ptr [rcx],rax
fffff8023fb2f827 0f85c7a81400 jne nt! ?? ::FNODOBFM::string’+0x4d031 (fffff8023fc7a0f4) fffff8023fb2f82d 488939 mov qword ptr [rcx],rdi
fffff8023fb2f830 48897808 mov qword ptr [rax+8],rdi
1
2
3
4
5



- ExRegisterCallback

nt!ExRegisterCallback+0x8b: fffff802
3fbc4707 0f8265420b00 jb nt! ?? ::FNODOBFM::string'+0x4b076 (fffff8023fc78972)
fffff8023fbc470d 807e2000 cmp byte ptr [rsi+20h],0 fffff8023fbc4711 745e je nt!ExRegisterCallback+0xf5 (fffff8023fbc4771) fffff8023fbc4713 488d4610 lea rax,[rsi+10h]
fffff8023fbc4717 40b501 mov bpl,1 fffff8023fbc471a 488b4808 mov rcx,qword ptr [rax+8]
fffff8023fbc471e 488903 mov qword ptr [rbx],rax fffff8023fbc4721 48894b08 mov qword ptr [rbx+8],rcx
nt!ExRegisterCallback+0xa9:
fffff8023fbc4725 483901 cmp qword ptr [rcx],rax fffff8023fbc4728 7552 jne nt!ExRegisterCallback+0x100 (fffff8023fbc477c) fffff8023fbc472a 488919 mov qword ptr [rcx],rbx
fffff8023fbc472d 48895808 mov qword ptr [rax+8],rbx
1
2
3
4
5



- ExpSetTimer

nt!ExpSetTimer+0x3db: fffff802
3fae32eb 4c8b4208 mov r8,qword ptr [rdx+8]
fffff8023fae32ef 488910 mov qword ptr [rax],rdx fffff8023fae32f2 4c894008 mov qword ptr [rax+8],r8
fffff8023fae32f6 493910 cmp qword ptr [r8],rdx fffff8023fae32f9 0f850b7a1900 jne nt! ?? ::FNODOBFM::string'+0x4dca0 (fffff8023fc7ad0a)
fffff8023fae32ff 498900 mov qword ptr [r8],rax fffff8023fae3302 48894208 mov qword ptr [rdx+8],rax

1
2
3
4
5



- IoSetIoCompletionEx2 - win8

nt!IoSetIoCompletionEx2+0xd6:
fffff8023fadb5e6 488d4318 lea rax,[rbx+18h] fffff8023fadb5ea 41f6c702 test r15b,2
fffff8023fadb5ee 0f8564f61600 jne nt! ?? ::FNODOBFM::string’+0xb068 (fffff8023fc4ac58) fffff8023fadb5f4 488b4808 mov rcx,qword ptr [rax+8]
fffff8023fadb5f8 488907 mov qword ptr [rdi],rax fffff8023fadb5fb 48894f08 mov qword ptr [rdi+8],rcx
fffff8023fadb5ff 483901 cmp qword ptr [rcx],rax fffff8023fadb602 0f8573f61600 jne nt! ?? ::FNODOBFM::string'+0xb08f (fffff8023fc4ac7b)
kd>
nt!IoSetIoCompletionEx2+0xf8:
fffff8023fadb608 488939 mov qword ptr [rcx],rdi fffff8023fadb60b 48897808 mov qword ptr [rax+8],rdi

nt!IoSetIoCompletionEx2+0x42d:
fffff8023fadb932 72e1 jb nt!IoSetIoCompletionEx2+0x410 (fffff8023fadb915)
fffff8023fadb934 488b8c24b0000000 mov rcx,qword ptr [rsp+0B0h] fffff8023fadb93c e991fcffff jmp nt!IoSetIoCompletionEx2+0xc2 (fffff8023fadb5d2) fffff8023fadb941 ff4304 inc dword ptr [rbx+4]
fffff8023fadb944 488d4318 lea rax,[rbx+18h] fffff8023fadb948 41f6c402 test r12b,2
fffff8023fadb94c 0f85e3f41600 jne nt! ?? ::FNODOBFM::string’+0xb25d (fffff8023fc4ae35) fffff8023fadb952 488b4808 mov rcx,qword ptr [rax+8]
nt!IoSetIoCompletionEx2+0x451:
fffff8023fadb956 488907 mov qword ptr [rdi],rax fffff8023fadb959 48894f08 mov qword ptr [rdi+8],rcx
fffff8023fadb95d 483901 cmp qword ptr [rcx],rax fffff8023fadb960 0f85f2f41600 jne nt! ?? ::FNODOBFM::string'+0xb284 (fffff8023fc4ae58)
fffff8023fadb966 488939 mov qword ptr [rcx],rdi fffff8023fadb969 48897808 mov qword ptr [rax+8],rdi

1
2
3
4
5

两处

- KeInsertQueueDpc


nt!KeInsertQueueDpc+0x103:
fffff8023fb1e083 488b4f08 mov rcx,qword ptr [rdi+8] fffff8023fb1e087 488938 mov qword ptr [rax],rdi
fffff8023fb1e08a 48894808 mov qword ptr [rax+8],rcx fffff8023fb1e08e 483939 cmp qword ptr [rcx],rdi
fffff8023fb1e091 0f85831a1300 jne nt! ?? ::FNODOBFM::string’+0x1208e (fffff8023fc4fb1a) fffff8023fb1e097 488901 mov qword ptr [rcx],rax
fffff8023fb1e09a 48894708 mov qword ptr [rdi+8],rax
1
2
3
4
5



- KeStartThread - win8

nt!KeStartThread+0x23c: fffff802
3fadbfa8 0f82302a0c00 jb nt! ?? ::FNODOBFM::string'+0xe095 (fffff8023fb9e9de)
fffff8023fadbfae 488b4e08 mov rcx,qword ptr [rsi+8] fffff8023fadbfb2 488d87f8020000 lea rax,[rdi+2F8h]
fffff8023fadbfb9 488930 mov qword ptr [rax],rsi fffff8023fadbfbc 48894808 mov qword ptr [rax+8],rcx
fffff8023fadbfc0 483931 cmp qword ptr [rcx],rsi fffff8023fadbfc3 0f854c2a0c00 jne nt! ?? ::FNODOBFM::string'+0xe0cc (fffff8023fb9ea15)
fffff8023fadbfc9 488901 mov qword ptr [rcx],rax nt!KeStartThread+0x260: fffff8023fadbfcc 48894608 mov qword ptr [rsi+8],rax

nt!KeStartThread+0x341:
fffff8023fadc0ad 488d8338020000 lea rax,[rbx+238h] fffff8023fadc0b4 488d15c51b2700 lea rdx,[nt!KiProcessListHead (fffff8023fd4dc80)] fffff8023fadc0bb 488910 mov qword ptr [rax],rdx
fffff8023fadc0be 48894808 mov qword ptr [rax+8],rcx fffff8023fadc0c2 483911 cmp qword ptr [rcx],rdx
fffff8023fadc0c5 0f85ee280c00 jne nt! ?? ::FNODOBFM::string’+0xe070 (fffff8023fb9e9b9) fffff8023fadc0cb 488901 mov qword ptr [rcx],rax
fffff8023fadc0ce 44853daf5f2f00 test dword ptr [nt!PerfGlobalGroupMask+0x4 (fffff8023fdd2084)],r15d
nt!KeStartThread+0x369:
fffff8023fadc0d5 488905ac1b2700 mov qword ptr [nt!KiProcessListHead+0x8 (fffff8023fd4dc88)],rax

1
2
3
4
5



- KiAddThreadToScbQueue- win8


nt!KiAddThreadToScbQueue+0x49:
fffff8023fba0331 4883c206 add rdx,6 fffff8023fba0335 48c1e204 shl rdx,4
fffff8023fba0339 4803d3 add rdx,rbx fffff8023fba033c 488b4208 mov rax,qword ptr [rdx+8]
fffff8023fba0340 488911 mov qword ptr [rcx],rdx fffff8023fba0343 48894108 mov qword ptr [rcx+8],rax
fffff8023fba0347 483910 cmp qword ptr [rax],rdx fffff8023fba034a 0f85f02a0b00 jne nt! ?? ::FNODOBFM::string'+0x1741c (fffff8023fc52e40)
nt!KiAddThreadToScbQueue+0x68:
fffff8023fba0350 488908 mov qword ptr [rax],rcx fffff8023fba0353 48894a08 mov qword ptr [rdx+8],rcx
1
2
3
4
5



- KiInsertQueueApc - win8


nt!KiInsertQueueApc+0x47:
fffff8023fb4bce7 4803c8 add rcx,rax fffff8023fb4bcea 488b4108 mov rax,qword ptr [rcx+8]
fffff8023fb4bcee 483bc1 cmp rax,rcx fffff8023fb4bcf1 0f850a030000 jne nt!KiInsertQueueApc+0x360 (fffff8023fb4c001) fffff8023fb4bcf7 4c8b00 mov r8,qword ptr [rax]
fffff8023fb4bcfa 488d4a10 lea rcx,[rdx+10h] fffff8023fb4bcfe 4c8901 mov qword ptr [rcx],r8
fffff8023fb4bd01 48894108 mov qword ptr [rcx+8],rax nt!KiInsertQueueApc+0x65: fffff8023fb4bd05 49394008 cmp qword ptr [r8+8],rax
fffff8023fb4bd09 0f85fb4e1000 jne nt! ?? ::FNODOBFM::string’+0x145d0 (fffff8023fc50c0a) fffff8023fb4bd0f 49894808 mov qword ptr [r8+8],rcx
fffff802`3fb4bd13 488908 mov qword ptr [rax],rcx

nt!KiInsertQueueApc+0x1cd:
fffff8023fb4be6d 4c8d4210 lea r8,[rdx+10h] fffff8023fb4be71 490fbec1 movsx rax,r9b
fffff8023fb4be75 48c1e004 shl rax,4 fffff8023fb4be79 4803c8 add rcx,rax
fffff8023fb4be7c 488b4108 mov rax,qword ptr [rcx+8] fffff8023fb4be80 498908 mov qword ptr [r8],rcx
fffff8023fb4be83 49894008 mov qword ptr [r8+8],rax fffff8023fb4be87 483908 cmp qword ptr [rax],rcx
nt!KiInsertQueueApc+0x1ea:
fffff8023fb4be8a 0f85734d1000 jne nt! ?? ::FNODOBFM::string’+0x145c9 (fffff8023fc50c03) fffff8023fb4be90 4c8900 mov qword ptr [rax],r8
fffff8023fb4be93 4c894108 mov qword ptr [rcx+8],r8

1
2
3
4
5

两处

- KiQueueReadyThread - win8

nt!KiQueueReadyThread+0xf3: fffff8023fb353c3 c3 ret
fffff8023fb353c4 488b4108 mov rax,qword ptr [rcx+8] fffff8023fb353c8 48890b mov qword ptr [rbx],rcx
fffff8023fb353cb 48894308 mov qword ptr [rbx+8],rax fffff8023fb353cf 483908 cmp qword ptr [rax],rcx
fffff8023fb353d2 0f855ac31100 jne nt! ?? ::FNODOBFM::string’+0x1544f (fffff8023fc51732) fffff8023fb353d8 488918 mov qword ptr [rax],rbx
fffff8023fb353db 48895908 mov qword ptr [rcx+8],rbx
1
2
3
4
5



- MiInsertNewProcess - win8

nt!MiInsertNewProcess+0x4a: fffff802
3fad10fa 488bd1 mov rdx,rcx
fffff8023fad10fd 498710 xchg rdx,qword ptr [r8] fffff8023fad1100 4885d2 test rdx,rdx
fffff8023fad1103 0f85c0000000 jne nt!MiInsertNewProcess+0x119 (fffff8023fad11c9)
fffff8023fad1109 488b0d08612700 mov rcx,qword ptr [nt!MmProcessList+0x8 (fffff8023fd47218)]
fffff8023fad1110 488d8778050000 lea rax,[rdi+578h] fffff8023fad1117 488d15f2602700 lea rdx,[nt!MmProcessList (fffff8023fd47210)] fffff8023fad111e 488910 mov qword ptr [rax],rdx
nt!MiInsertNewProcess+0x71:
fffff8023fad1121 48894808 mov qword ptr [rax+8],rcx fffff8023fad1125 483911 cmp qword ptr [rcx],rdx
fffff8023fad1128 0f8558451800 jne nt! ?? ::FNODOBFM::string’+0x1ad34 (fffff8023fc55686) fffff8023fad112e 488901 mov qword ptr [rcx],rax
fffff8023fad1131 488905e0602700 mov qword ptr [nt!MmProcessList+0x8 (fffff8023fd47218)],rax

nt!MiInsertNewProcess+0x91:
fffff8023fad1141 488d8730030000 lea rax,[rdi+330h] fffff8023fad1148 488b5108 mov rdx,qword ptr [rcx+8]
fffff8023fad114c 488908 mov qword ptr [rax],rcx fffff8023fad114f 48895008 mov qword ptr [rax+8],rdx
fffff8023fad1153 48390a cmp qword ptr [rdx],rcx fffff8023fad1156 0f8531451800 jne nt! ?? ::FNODOBFM::string'+0x1ad3b (fffff8023fc5568d)
fffff8023fad115c 488902 mov qword ptr [rdx],rax fffff8023fad115f 48894108 mov qword ptr [rcx+8],rax

1
2
3
4
5

两处

- PnpRequestDeviceAction - win8


nt!PnpRequestDeviceAction+0xad:
fffff8023fb81ff1 f0480fba2f00 lock bts qword ptr [rdi],0 fffff8023fb81ff7 0f82d1a60c00 jb nt! ?? ::FNODOBFM::string'+0xcefe (fffff8023fc4c6ce)
fffff8023fb81ffd 488b0504d71c00 mov rax,qword ptr [nt!PnpEnumerationRequestList+0x8 (fffff8023fd4f708)]
fffff8023fb82004 488d0df5d61c00 lea rcx,[nt!PnpEnumerationRequestList (fffff8023fd4f700)]
fffff8023fb8200b 48894608 mov qword ptr [rsi+8],rax fffff8023fb8200f 48890e mov qword ptr [rsi],rcx
fffff8023fb82012 483908 cmp qword ptr [rax],rcx fffff8023fb82015 0f85c1a60c00 jne nt! ?? ::FNODOBFM::string'+0xcf0c (fffff8023fc4c6dc)
nt!PnpRequestDeviceAction+0xd7:
fffff8023fb8201b 488930 mov qword ptr [rax],rsi fffff8023fb8201e 488935e3d61c00 mov qword ptr [nt!PnpEnumerationRequestList+0x8 (fffff8023fd4f708)],rsi
1
2
3
4
5



- PspInsertProcess - win8

nt!PspInsertProcess+0xa0: fffff802
3fe8ec9c 0f82e7010000 jb nt!PspInsertProcess+0x28d (fffff8023fe8ee89) fffff8023fe8eca2 488b0d6f3fe8ff mov rcx,qword ptr [nt!PsActiveProcessHead+0x8 (fffff8023fd12c18)] fffff8023fe8eca9 488d87e8020000 lea rax,[rdi+2E8h]
fffff8023fe8ecb0 488d15593fe8ff lea rdx,[nt!PsActiveProcessHead (fffff8023fd12c10)]
fffff8023fe8ecb7 488910 mov qword ptr [rax],rdx fffff8023fe8ecba 48894808 mov qword ptr [rax+8],rcx
fffff8023fe8ecbe 483911 cmp qword ptr [rcx],rdx fffff8023fe8ecc1 0f85cfa81f00 jne nt! ?? ::NNGAKEGL::string'+0x46b22 (fffff80240089596)
nt!PspInsertProcess+0xcb:
fffff8023fe8ecc7 488901 mov qword ptr [rcx],rax fffff8023fe8ecca 488905473fe8ff mov qword ptr [nt!PsActiveProcessHead+0x8 (fffff8023fd12c18)],rax
1
2
3
4
5



- PspInsertThread - win8

nt!PspInsertThread+0x243: fffff802
3feab2b3 83cb01 or ebx,1
fffff8023feab2b6 895c2450 mov dword ptr [rsp+50h],ebx fffff8023feab2ba 498db630060000 lea rsi,[r14+630h]
fffff8023feab2c1 f0480fba2e00 lock bts qword ptr [rsi],0 fffff8023feab2c7 0f824416f6ff jb nt! ?? ::NNGAKEGL::string'+0x46149 (fffff8023fe0c911)
fffff8023feab2cd 498d8f00040000 lea rcx,[r15+400h] fffff8023feab2d4 498d8670040000 lea rax,[r14+470h]
fffff8023feab2db 488b5008 mov rdx,qword ptr [rax+8] nt!PspInsertThread+0x26f: fffff8023feab2df 488901 mov qword ptr [rcx],rax
fffff8023feab2e2 48895108 mov qword ptr [rcx+8],rdx fffff8023feab2e6 483902 cmp qword ptr [rdx],rax
fffff8023feab2e9 0f853016f6ff jne nt! ?? ::NNGAKEGL::string’+0x46157 (fffff8023fe0c91f) fffff8023feab2ef 48890a mov qword ptr [rdx],rcx
fffff802`3feab2f2 48894808 mov qword ptr [rax+8],rcx
1
2
3
4
5

#### 小总结1

InsertHeadList 和 InsertTailList 的汇编结构非常类似,相同点如下:



mov [rcx], rax
mov [rcx+8], rdx
; 修改 entry 的 Flink 和 Blink

cmp
jne
; 判断,不相等则跳转,在后面的练习中提到

mov [rax+8], rcx
mov [rdx], rax
; 比照修改 entry 时链表中项的排列顺序,修改影响到的指针
; InsertHeadList 插入头部,就需要修改 ListHead->Flink 和 Flink->Blink
; InsertTailList 插入尾部,则需要修改 ListHead->Blink 和 Blink->Flink
; 而这部分在汇编上的体现是一样的,因为都在修改 entry 的 Flink 和 Blink 时决定了

1
2
3

所以区分 InsertHeadList 和 InertTailList 的方式只有第一步:

mov rax, [rdx]
; 如果时这样,那么 rax 就是 ListHead->Flink, rdx 是 LiskHead
; 后面加上上一部分的汇编,则是 InsertHeadList

mov rdx, [rax+8]
; 这样则 rbx 是 ListHead->Blink,rax 是 ListHead
; 加上上一部分则是 InsertTailList

1
2
3
4
5
6
7
8
9

另外 ListHead 并不会总是保存在寄存器中,可能出现直接引用内存的情况。



#### 4

> 在下面函数中重复前面练习,指出 RemoveHeadList 在何处内联。

BOOLEAN IsListEmpty(PLIST_ENTRY ListHead){
return (BOOLEAN)(ListHead->Flink == ListHead);
}

1
2
3

对应汇编:

// x86
mov eax,[esi]
cmp eax, esi

/ x64
mov rax, [rbx]
cmp rax, rbx

1
2
3



PLIST_ENTRY RemoveHeadList(PLIST_ENTRY ListHead){
PLIST_ENTRY Flink;
PLIST_ENTRY Entry;
Entry = ListHead->Flink;
Flink = Entry->Flink;
ListHead->Flink = Flink;
Flink->Blink = ListHead;
return Entry;
}

1
2
3

对应汇编:

// x86
mov eax, [esi]
mov ecx, [eax]
mov [esi], ecx
mov [ecx+4], esi

// x64
mov rax, [rbx]
mov rcx, [rax]
mov [rbx], rcx
mov [rcx+8], rbx

1
2
3
4
5

此处开始,练习在 win8 x64 下进行

- AlpcpFlushResourcesPort

nt!AlpcpFlushResourcesPort+0x29:
fffff8023fe86da9 0f82a9fc1e00 jb nt! ?? ::NNGAKEGL::string’+0x30412 (fffff80240076a58) fffff8023fe86daf 4883cbff or rbx,0FFFFFFFFFFFFFFFFh
fffff8023fe86db3 498b36 mov rsi,qword ptr [r14] fffff8023fe86db6 493bf6 cmp rsi,r14
fffff8023fe86db9 7524 jne nt!AlpcpFlushResourcesPort+0x5f (fffff8023fe86ddf)

nt!AlpcpFlushResourcesPort+0x49:
fffff8023fe86dc9 488b5c2430 mov rbx,qword ptr [rsp+30h] fffff8023fe86dce 488b742438 mov rsi,qword ptr [rsp+38h]
fffff8023fe86dd3 488b7c2440 mov rdi,qword ptr [rsp+40h] fffff8023fe86dd8 4883c420 add rsp,20h
fffff8023fe86ddc 415e pop r14 fffff8023fe86dde c3 ret
fffff8023fe86ddf 488b06 mov rax,qword ptr [rsi] fffff8023fe86de2 4c397608 cmp qword ptr [rsi+8],r14
nt!AlpcpFlushResourcesPort+0x66:
fffff8023fe86de6 0f857afc1e00 jne nt! ?? ::NNGAKEGL::string’+0x30420 (fffff80240076a66) fffff8023fe86dec 48397008 cmp qword ptr [rax+8],rsi
fffff8023fe86df0 0f8570fc1e00 jne nt! ?? ::NNGAKEGL::string’+0x30420 (fffff80240076a66) fffff8023fe86df6 498906 mov qword ptr [r14],rax
fffff8023fe86df9 4c897008 mov qword ptr [rax+8],r14

1
2
3
4
5



- CcDeleteMbcb

nt!CcDeleteMbcb+0x12d: fffff8023fb7c525 440f22c0 mov cr8,rax
fffff8023fb7c529 4c8d7e10 lea r15,[rsi+10h] fffff8023fb7c52d 498b3f mov rdi,qword ptr [r15]
fffff8023fb7c530 493bff cmp rdi,r15 fffff8023fb7c533 746d je nt!CcDeleteMbcb+0x1aa (fffff8023fb7c5a2) fffff8023fb7c535 488b0f mov rcx,qword ptr [rdi]
fffff8023fb7c538 488b4708 mov rax,qword ptr [rdi+8] fffff8023fb7c53c 48397908 cmp qword ptr [rcx+8],rdi
nt!CcDeleteMbcb+0x148:
fffff8023fb7c540 0f851e010000 jne nt!CcDeleteMbcb+0x26c (fffff8023fb7c664)
fffff8023fb7c546 483938 cmp qword ptr [rax],rdi fffff8023fb7c549 0f8515010000 jne nt!CcDeleteMbcb+0x26c (fffff8023fb7c664)
1
2
3
4
5



- CcGetVacbMiss

nt!CcGetVacbMiss+0x2a4: fffff802
3fb4d8f4 5e pop rsi
fffff8023fb4d8f5 5d pop rbp fffff8023fb4d8f6 c3 ret
fffff8023fb4d8f7 488b02 mov rax,qword ptr [rdx] fffff8023fb4d8fa 488d4dd8 lea rcx,[rbp-28h]
fffff8023fb4d8fe 48394a08 cmp qword ptr [rdx+8],rcx fffff8023fb4d902 0f8525900f00 jne nt! ?? ::FNODOBFM::string'+0x5dc7 (fffff8023fc4692d)
fffff8023fb4d908 48395008 cmp qword ptr [rax+8],rdx nt!CcGetVacbMiss+0x2bc: fffff8023fb4d90c 0f851b900f00 jne nt! ?? ::FNODOBFM::string'+0x5dc7 (fffff8023fc4692d)
fffff8023fb4d912 488945d8 mov qword ptr [rbp-28h],rax fffff8023fb4d916 488d4dd8 lea rcx,[rbp-28h]
fffff8023fb4d91a 48894808 mov qword ptr [rax+8],rcx
1
2
3
4
5



- CmpLazyCommitWorker

nt!CmpLazyCommitWorker+0x118: fffff802
3ffae81c 65488b1c2588010000 mov rbx,qword ptr gs:[188h]
fffff8023ffae825 f0410fba3600 lock btr dword ptr [r14],0 fffff8023ffae82b 7208 jb nt!CmpLazyCommitWorker+0x131 (fffff8023ffae835) fffff8023ffae82d 498bce mov rcx,r14
fffff8023ffae830 e85375b3ff call nt!ExpAcquireFastMutexContended (fffff8023fae5d88)
fffff8023ffae835 48891d0c2edbff mov qword ptr [nt!CmpTransactionListLock+0x8 (fffff8023fd61648)],rbx
fffff8023ffae83c 488b1d5d2edbff mov rbx,qword ptr [nt!CmpLazyCommitListHead (fffff8023fd616a0)]
fffff8023ffae843 488b03 mov rax,qword ptr [rbx] nt!CmpLazyCommitWorker+0x142: fffff8023ffae846 4c397b08 cmp qword ptr [rbx+8],r15
fffff8023ffae84a 0f850c030000 jne nt!CmpLazyCommitWorker+0x458 (fffff8023ffaeb5c)
fffff8023ffae850 48395808 cmp qword ptr [rax+8],rbx fffff8023ffae854 0f8502030000 jne nt!CmpLazyCommitWorker+0x458 (fffff8023ffaeb5c) fffff8023ffae85a 4889053f2edbff mov qword ptr [nt!CmpLazyCommitListHead (fffff8023fd616a0)],rax fffff8023ffae861 4c897808 mov qword ptr [rax+8],r15

nt!CmpLazyCommitWorker+0x2a2:
fffff8023ffae9a6 e8dd73b3ff call nt!ExpAcquireFastMutexContended (fffff8023fae5d88)
fffff8023ffae9ab 48891d962cdbff mov qword ptr [nt!CmpTransactionListLock+0x8 (fffff8023fd61648)],rbx
fffff8023ffae9b2 488b45f0 mov rax,qword ptr [rbp-10h] fffff8023ffae9b6 488d55f0 lea rdx,[rbp-10h]
fffff8023ffae9ba 488b08 mov rcx,qword ptr [rax] fffff8023ffae9bd 48395008 cmp qword ptr [rax+8],rdx
fffff8023ffae9c1 0f858e010000 jne nt!CmpLazyCommitWorker+0x451 (fffff8023ffaeb55)
fffff8023ffae9c7 48394108 cmp qword ptr [rcx+8],rax nt!CmpLazyCommitWorker+0x2c7: fffff8023ffae9cb 0f8584010000 jne nt!CmpLazyCommitWorker+0x451 (fffff8023ffaeb55) fffff8023ffae9d1 48894df0 mov qword ptr [rbp-10h],rcx
fffff8023ffae9d5 488d55f0 lea rdx,[rbp-10h] fffff8023ffae9d9 48895108 mov qword ptr [rcx+8],rdx

1
2
3
4
5

两处

- ExAllocatePoolWithTag


nt!ExAllocatePoolWithTag+0x421:
fffff8023fceb459 488d542440 lea rdx,[rsp+40h] fffff8023fceb45e 49875500 xchg rdx,qword ptr [r13]
fffff8023fceb462 4885d2 test rdx,rdx fffff8023fceb465 0f85b3030000 jne nt!ExAllocatePoolWithTag+0x7e4 (fffff8023fceb81e) fffff8023fceb46b 48391b cmp qword ptr [rbx],rbx
fffff8023fceb46e 0f8433060000 je nt!ExAllocatePoolWithTag+0xa6b (fffff8023fcebaa7)
fffff8023fceb474 4c8b03 mov r8,qword ptr [rbx] fffff8023fceb477 498b00 mov rax,qword ptr [r8]
kd>
nt!ExAllocatePoolWithTag+0x442:
fffff8023fceb47a 4c8b4808 mov r9,qword ptr [rax+8] fffff8023fceb47e 4d3bc8 cmp r9,r8
fffff8023fceb481 0f8594100000 jne nt!ExFreePool+0x3d3 (fffff8023fcec51b)
fffff8023fceb487 498b4008 mov rax,qword ptr [r8+8] fffff8023fceb48b 4c3900 cmp qword ptr [rax],r8
fffff8023fceb48e 0f8587100000 jne nt!ExFreePool+0x3d3 (fffff8023fcec51b)
fffff8023fceb494 498b00 mov rax,qword ptr [r8] fffff8023fceb497 49395808 cmp qword ptr [r8+8],rbx
nt!ExAllocatePoolWithTag+0x463:
fffff8023fceb49b 0f8573100000 jne nt!ExFreePool+0x3cc (fffff8023fcec514)
fffff8023fceb4a1 4c394008 cmp qword ptr [rax+8],r8 fffff8023fceb4a5 0f8569100000 jne nt!ExFreePool+0x3cc (fffff8023fcec514) fffff8023fceb4ab 448ba424d0000000 mov r12d,dword ptr [rsp+0D0h]
fffff8023fceb4b3 488903 mov qword ptr [rbx],rax fffff8023fceb4b6 48895808 mov qword ptr [rax+8],rbx
1
2
3
4
5



- FsRtlNotifyCompleteIrpList


nt!FsRtlNotifyCompleteIrpList+0x20:
fffff8023fe3bbd0 66214158 and word ptr [rcx+58h],ax fffff8023fe3bbd4 83617c00 and dword ptr [rcx+7Ch],0
fffff8023fe3bbd8 8bf2 mov esi,edx fffff8023fe3bbda 488bf9 mov rdi,rcx
fffff8023fe3bbdd 488d5940 lea rbx,[rcx+40h] fffff8023fe3bbe1 488b03 mov rax,qword ptr [rbx]
fffff8023fe3bbe4 488b0b mov rcx,qword ptr [rbx] fffff8023fe3bbe7 488b10 mov rdx,qword ptr [rax]
nt!FsRtlNotifyCompleteIrpList+0x3a:
fffff8023fe3bbea 4881e9a8000000 sub rcx,0A8h fffff8023fe3bbf1 48395808 cmp qword ptr [rax+8],rbx
fffff8023fe3bbf5 754b jne nt!FsRtlNotifyCompleteIrpList+0x92 (fffff8023fe3bc42)
fffff8023fe3bbf7 48394208 cmp qword ptr [rdx+8],rax fffff8023fe3bbfb 7545 jne nt!FsRtlNotifyCompleteIrpList+0x92 (fffff8023fe3bc42) fffff8023fe3bbfd 488913 mov qword ptr [rbx],rdx
fffff8023fe3bc00 48895a08 mov qword ptr [rdx+8],rbx
1
2
3
4
5
6
7



- IopInitializeBootDrivers

- KiProcessDisconnectList

nt!KiProcessDisconnectList: fffff802
3fbf3fb0 fff3 push rbx
fffff8023fbf3fb2 4883ec20 sub rsp,20h fffff8023fbf3fb6 488bd9 mov rbx,rcx
fffff8023fbf3fb9 488b03 mov rax,qword ptr [rbx] fffff8023fbf3fbc 483bc3 cmp rax,rbx
fffff8023fbf3fbf 7435 je nt!KiProcessDisconnectList+0x46 (fffff8023fbf3ff6)
fffff8023fbf3fc1 488b08 mov rcx,qword ptr [rax] fffff8023fbf3fc4 48395808 cmp qword ptr [rax+8],rbx
nt!KiProcessDisconnectList+0x18:
fffff8023fbf3fc8 7525 jne nt!KiProcessDisconnectList+0x3f (fffff8023fbf3fef)
fffff8023fbf3fca 48394108 cmp qword ptr [rcx+8],rax fffff8023fbf3fce 751f jne nt!KiProcessDisconnectList+0x3f (fffff8023fbf3fef) fffff8023fbf3fd0 48890b mov qword ptr [rbx],rcx
fffff8023fbf3fd3 48895908 mov qword ptr [rcx+8],rbx
1
2
3
4
5



- PnpDeviceCompletionQueueGetCompletedRequest

nt!PnpDeviceCompletionQueueGetCompletedRequest+0x49: fffff802
3fbc45f9 488b1d78df1800 mov rbx,qword ptr [nt!PnpDeviceCompletionQueue+0x18 (fffff8023fd52578)] fffff8023fbc4600 488d0d71df1800 lea rcx,[nt!PnpDeviceCompletionQueue+0x18 (fffff8023fd52578)] fffff8023fbc4607 488b03 mov rax,qword ptr [rbx]
fffff8023fbc460a 48394b08 cmp qword ptr [rbx+8],rcx fffff8023fbc460e 755c jne nt!PnpDeviceCompletionQueueGetCompletedRequest+0xbc (fffff8023fbc466c) fffff8023fbc4610 48395808 cmp qword ptr [rax+8],rbx
fffff8023fbc4614 7556 jne nt!PnpDeviceCompletionQueueGetCompletedRequest+0xbc (fffff8023fbc466c)
fffff8023fbc4616 4889055bdf1800 mov qword ptr [nt!PnpDeviceCompletionQueue+0x18 (fffff8023fd52578)],rax
nt!PnpDeviceCompletionQueueGetCompletedRequest+0x6d:
fffff8023fbc461d 48894808 mov qword ptr [rax+8],rcx
1
2
3
4
5
6
7



- RtlDestroyAtomTable

- RtlEmptyAtomTable

nt!RtlEmptyAtomTable+0x64: fffff802
40006834 488bcf mov rcx,rdi
fffff80240006837 498906 mov qword ptr [r14],rax fffff8024000683a 4c892b mov qword ptr [rbx],r13
fffff8024000683d e8e6cae9ff call nt!RtlpFreeHandleForAtom (fffff8023fea3328)
fffff80240006842 488d7310 lea rsi,[rbx+10h] fffff80240006846 483936 cmp qword ptr [rsi],rsi
fffff80240006849 7428 je nt!RtlEmptyAtomTable+0xa3 (fffff80240006873)
fffff8024000684b 488b0e mov rcx,qword ptr [rsi] nt!RtlEmptyAtomTable+0x7e: fffff8024000684e 488b01 mov rax,qword ptr [rcx]
fffff80240006851 48397108 cmp qword ptr [rcx+8],rsi fffff80240006855 0f85a1000000 jne nt!RtlEmptyAtomTable+0x12c (fffff802400068fc) fffff8024000685b 48394808 cmp qword ptr [rax+8],rcx
fffff8024000685f 0f8597000000 jne nt!RtlEmptyAtomTable+0x12c (fffff802400068fc)
fffff80240006865 488906 mov qword ptr [rsi],rax fffff80240006868 48897008 mov qword ptr [rax+8],rsi
1
2
3
4
5



- RtlpFreeAllAtom


nt!RtlpFreeAllAtom+0x7b:
fffff8023fad5a7b 488b0b mov rcx,qword ptr [rbx] fffff8023fad5a7e 488b01 mov rax,qword ptr [rcx]
fffff8023fad5a81 48395908 cmp qword ptr [rcx+8],rbx fffff8023fad5a85 7514 jne nt!RtlpFreeAllAtom+0x9b (fffff8023fad5a9b) fffff8023fad5a87 48394808 cmp qword ptr [rax+8],rcx
fffff8023fad5a8b 750e jne nt!RtlpFreeAllAtom+0x9b (fffff8023fad5a9b)
fffff8023fad5a8d 488903 mov qword ptr [rbx],rax fffff8023fad5a90 48895808 mov qword ptr [rax+8],rbx
1
2
3
4
5
6
7



#### 5

> 在下面函数中重复前面练习,指出 RemoveTaillList 在何处内联。


PLIST_ENTRY RemoveTailList(PLIST_ENTRY ListHead){
PLIST_ENTRY Blink;
PLISTENTRY Entry;
Entry = ListHead->Blink
Blink = Entry->Blink;
ListHead->Blink = Blink;
Blink->Flink = ListHead;
return Entry;
}

1
2
3

对应汇编:

// x86
mov ebx, [edi+4]
mov eax, [ebx+4]
mov [edi+4], eax
mov [eax], edi

// x64
mov rsi, [rdi+8]
mov rax, [rsi+8]
mov [rdi+8], rax
mov [rax], rdi

1
2
3
4
5
6
7
8
9



- BootApplicationPersistentDataProcess

- CmpCallCallBacks

- CmpDelayCloseWorker

nt!CmpDelayCloseWorker+0xc7:
fffff8023fe55847 0fb6c3 movzx eax,bl fffff8023fe5584a 890500c0f0ff mov dword ptr [nt!CmpDelayedCloseTableLock+0x30 (fffff8023fd61850)],eax fffff8023fe55850 443b052993e9ff cmp r8d,dword ptr [nt!CmpDelayedCloseSize (fffff8023fceeb80)] fffff8023fe55857 0f8689000000 jbe nt!CmpDelayCloseWorker+0x166 (fffff8023fe558e6) fffff8023fe5585d 488b0504c0f0ff mov rax,qword ptr [nt!CmpDelayedLRUListHead+0x8 (fffff8023fd61868)] fffff8023fe55864 488b4808 mov rcx,qword ptr [rax+8]
fffff8023fe55868 4c8d8828ffffff lea r9,[rax-0D8h] fffff8023fe5586f 483910 cmp qword ptr [rax],rdx
nt!CmpDelayCloseWorker+0xf2:
fffff8023fe55872 0f8543052000 jne nt! ?? ::NNGAKEGL::string’+0x9b81 (fffff80240055dbb) fffff8023fe55878 483901 cmp qword ptr [rcx],rax
fffff8023fe5587b 0f853a052000 jne nt! ?? ::NNGAKEGL::string’+0x9b81 (fffff80240055dbb) fffff8023fe55881 48890de0bff0ff mov qword ptr [nt!CmpDelayedLRUListHead+0x8 (fffff8023fd61868)],rcx fffff8023fe55888 488911 mov qword ptr [rcx],rdx

1
2
3
4
5



- ObpCallPostOperationCallbacks


nt!ObpCallPostOperationCallbacks+0x1d:
fffff8023fff597d 7464 je nt!ObpCallPostOperationCallbacks+0x83 (fffff8023fff59e3)
fffff8023fff597f 488b7708 mov rsi,qword ptr [rdi+8] fffff8023fff5983 488b4608 mov rax,qword ptr [rsi+8]
fffff8023fff5987 48393e cmp qword ptr [rsi],rdi fffff8023fff598a 7550 jne nt!ObpCallPostOperationCallbacks+0x7c (fffff8023fff59dc) fffff8023fff598c 483930 cmp qword ptr [rax],rsi
fffff8023fff598f 754b jne nt!ObpCallPostOperationCallbacks+0x7c (fffff8023fff59dc)
fffff8023fff5991 48894708 mov qword ptr [rdi+8],rax nt!ObpCallPostOperationCallbacks+0x35: fffff8023fff5995 488938 mov qword ptr [rax],rdi
1
2
3
4
5



- RaspAddCacheEntry,这里怀疑是作者写错了,函数汇编很短,只有一个 InsertHeadList


nt!RaspAddCacheEntry:
fffff802400df280 488b01 mov rax,qword ptr [rcx] fffff802400df283 48894a08 mov qword ptr [rdx+8],rcx
fffff802400df287 488902 mov qword ptr [rdx],rax fffff802400df28a 48394808 cmp qword ptr [rax+8],rcx
fffff802400df28e 7513 jne nt!RaspAddCacheEntry+0x23 (fffff802400df2a3)
fffff802400df290 48895008 mov qword ptr [rax+8],rdx fffff802400df294 488911 mov qword ptr [rcx],rdx
1
2
3
4
5

#### 小总结2

RemoveHeadList 和 RemoveTailList 都只接受一个 ListHead 参数,因此需要获取需要 Remove 的那个 entry 和它后面(RemoveHeadList)或者前面(removeTailList)的一项来方便后续操作,因此会获取两次 Flink 或者 Blink,特征如下:


; RemoveHeadList
mov rax, [rcx]
mov rdx, [rax]

; 或者 RemoveTailList
mov rax, [rcx+8]
mov rdx, [rax+8]

; 以下是共通的,与小总结1一样
cmp
jne
cmp
jne

; 将 ListHead 与 Flink 或者 Blink 连接到一起
; 省略

1
2
3
4
5
6
7
8
9



#### 6

> 在下面函数中重复前面练习,指出 RemoveEntryList 在何处内联。



BOOLEAN RemoveEntryList(PLIST_ENTRY Entry){
PLIST_ENTRY Blink;
PLIST_ENTRY Flink;
Flink = Entry->Flink;
Blink = Entry->Blink;
Blink->Flink = Flink;
Flink->Blink = Blink;
return (BOOLEAN)(Flink == Blink);
}

1
2
3

对应汇编:

// x86
mov edx, [ecx]
mov eax, [ecx+4]
mov [eax], edx
mov [edx+4], eax

// x64
mov rdx, [rcx]
mov rax, [rcx+8]
mov [rax], rdx
mov [rdx+8], rax

1
2
3



#define CONTAINING_RECORD(address, type, field) ((type )(
(PCHAR)(address) -
(ULONG_PTR)(&((type
) 0)->field)))

1
2
3
4
5



- AlpcSectionDeleteProcedure

nt!AlpcSectionDeleteProcedure+0x68:
fffff8023fe84a88 0f828e32f8ff jb nt! ?? ::NNGAKEGL::string’+0x2f67a (fffff8023fe07d1c) fffff8023fe84a8e 488b07 mov rax,qword ptr [rdi]
fffff8023fe84a91 483bc7 cmp rax,rdi fffff8023fe84a94 0f8599000000 jne nt!AlpcSectionDeleteProcedure+0x113 (fffff8023fe84b33) ... nt!AlpcSectionDeleteProcedure+0xf8: fffff8023fe84b18 415f pop r15
fffff8023fe84b1a 415e pop r14 fffff8023fe84b1c 5f pop rdi
fffff8023fe84b1d c3 ret fffff8023fe84b1e 488b5618 mov rdx,qword ptr [rsi+18h]
fffff8023fe84b22 4c8bc6 mov r8,rsi fffff8023fe84b25 e806020000 call nt!AlpcDeleteBlobByHandle (fffff8023fe84d30) fffff8023fe84b2a 4c897e10 mov qword ptr [rsi+10h],r15
nt!AlpcSectionDeleteProcedure+0x10e:
fffff8023fe84b2e e918ffffff jmp nt!AlpcSectionDeleteProcedure+0x2b (fffff8023fe84a4b)
fffff8023fe84b33 488b4f08 mov rcx,qword ptr [rdi+8] fffff8023fe84b37 48397808 cmp qword ptr [rax+8],rdi
fffff8023fe84b3b 7522 jne nt!AlpcSectionDeleteProcedure+0x13f (fffff8023fe84b5f)
fffff8023fe84b3d 483939 cmp qword ptr [rcx],rdi fffff8023fe84b40 751d jne nt!AlpcSectionDeleteProcedure+0x13f (fffff8023fe84b5f) fffff8023fe84b42 488901 mov qword ptr [rcx],rax
fffff8023fe84b45 48894808 mov qword ptr [rax+8],rcx

1
2
3
4
5



- AlpcpDeletePort

nt!AlpcpDeletePort+0xf1: fffff8023fe871c9 48878f98010000 xchg rcx,qword ptr [rdi+198h]
fffff8023fe871d0 4885c9 test rcx,rcx fffff8023fe871d3 0f851d010000 jne nt!AlpcpDeletePort+0x21e (fffff8023fe872f6) fffff8023fe871d9 483937 cmp qword ptr [rdi],rsi
fffff8023fe871dc 7443 je nt!AlpcpDeletePort+0x149 (fffff8023fe87221)
fffff8023fe871de f0480fba2dc801ecff00 lock bts qword ptr [nt!AlpcpPortListLock (fffff8023fd473b0)],0
fffff8023fe871e8 0f821c010000 jb nt!AlpcpDeletePort+0x232 (fffff8023fe8730a)
fffff8023fe871ee 488b17 mov rdx,qword ptr [rdi] nt!AlpcpDeletePort+0x119: fffff8023fe871f1 488b4708 mov rax,qword ptr [rdi+8]
fffff8023fe871f5 48397a08 cmp qword ptr [rdx+8],rdi fffff8023fe871f9 0f85e5f21e00 jne nt! ?? ::NNGAKEGL::string'+0x2fe4e (fffff802400764e4)
fffff8023fe871ff 483938 cmp qword ptr [rax],rdi fffff8023fe87202 0f85dcf21e00 jne nt! ?? ::NNGAKEGL::string'+0x2fe4e (fffff802400764e4)
fffff8023fe87208 488910 mov qword ptr [rax],rdx fffff8023fe8720b 48894208 mov qword ptr [rdx+8],rax

; 看过头了,第二个不是这个函数的,就留在这里吧
nt!AlpcConnectionDestroyProcedure+0x3a:
fffff8023fe873d6 f0480fba2e00 lock bts qword ptr [rsi],0 fffff8023fe873dc 0f82b4000000 jb nt!AlpcConnectionDestroyProcedure+0xfa (fffff8023fe87496) fffff8023fe873e2 488d4718 lea rax,[rdi+18h]
fffff8023fe873e6 488b10 mov rdx,qword ptr [rax] fffff8023fe873e9 488b4808 mov rcx,qword ptr [rax+8]
fffff8023fe873ed 48394208 cmp qword ptr [rdx+8],rax fffff8023fe873f1 0f85b6000000 jne nt!AlpcConnectionDestroyProcedure+0x111 (fffff8023fe874ad) fffff8023fe873f7 483901 cmp qword ptr [rcx],rax
nt!AlpcConnectionDestroyProcedure+0x5e:
fffff8023fe873fa 0f85ad000000 jne nt!AlpcConnectionDestroyProcedure+0x111 (fffff8023fe874ad)
fffff8023fe87400 4883cbff or rbx,0FFFFFFFFFFFFFFFFh fffff8023fe87404 488911 mov qword ptr [rcx],rdx
fffff8023fe87407 48894a08 mov qword ptr [rdx+8],rcx

1
2
3
4
5



- AlpcpUnregisterCompletionListDatabase

nt!AlpcpUnregisterCompletionListDatabase: fffff8023fe0c67c fff3 push rbx
fffff8023fe0c67e 4883ec20 sub rsp,20h fffff8023fe0c682 f0480fba2d34adf3ff00 lock bts qword ptr [nt!AlpcpCompletionListDatabase (fffff8023fd473c0)],0 fffff8023fe0c68c 488bd9 mov rbx,rcx
fffff8023fe0c68f 723a jb nt!AlpcpUnregisterCompletionListDatabase+0x4f (fffff8023fe0c6cb)
fffff8023fe0c691 488b13 mov rdx,qword ptr [rbx] fffff8023fe0c694 488b4308 mov rax,qword ptr [rbx+8]
fffff8023fe0c698 48395a08 cmp qword ptr [rdx+8],rbx nt!AlpcpUnregisterCompletionListDatabase+0x20: fffff8023fe0c69c 753b jne nt!AlpcpUnregisterCompletionListDatabase+0x5d (fffff8023fe0c6d9) fffff8023fe0c69e 483918 cmp qword ptr [rax],rbx
fffff8023fe0c6a1 7536 jne nt!AlpcpUnregisterCompletionListDatabase+0x5d (fffff8023fe0c6d9)
fffff8023fe0c6a3 488910 mov qword ptr [rax],rdx fffff8023fe0c6a6 48894208 mov qword ptr [rdx+8],rax
1
2
3
4
5



- AuthzBasepRemoveSecurityAttributeFromLists


nt!AuthzBasepRemoveSecurityAttributeFromLists+0x17:
fffff8023ff410e7 4c8b08 mov r9,qword ptr [rax] fffff8023ff410ea 4c8b4008 mov r8,qword ptr [rax+8]
fffff8023ff410ee 49394108 cmp qword ptr [r9+8],rax fffff8023ff410f2 754b jne nt!AuthzBasepRemoveSecurityAttributeFromLists+0x6f (fffff8023ff4113f) fffff8023ff410f4 493900 cmp qword ptr [r8],rax
fffff8023ff410f7 7546 jne nt!AuthzBasepRemoveSecurityAttributeFromLists+0x6f (fffff8023ff4113f)
fffff8023ff410f9 4d8908 mov qword ptr [r8],r9 fffff8023ff410fc 4d894108 mov qword ptr [r9+8],r8

nt!AuthzBasepRemoveSecurityAttributeFromLists+0x47:
fffff8023ff41117 7425 je nt!AuthzBasepRemoveSecurityAttributeFromLists+0x6e (fffff8023ff4113e)
fffff8023ff41119 4c8b02 mov r8,qword ptr [rdx] fffff8023ff4111c 488b4208 mov rax,qword ptr [rdx+8]
fffff8023ff41120 49395008 cmp qword ptr [r8+8],rdx fffff8023ff41124 7520 jne nt!AuthzBasepRemoveSecurityAttributeFromLists+0x76 (fffff8023ff41146) fffff8023ff41126 483910 cmp qword ptr [rax],rdx
fffff8023ff41129 751b jne nt!AuthzBasepRemoveSecurityAttributeFromLists+0x76 (fffff8023ff41146)
fffff8023ff4112b 4c8900 mov qword ptr [rax],r8 kd> nt!AuthzBasepRemoveSecurityAttributeFromLists+0x5e: fffff8023ff4112e 49894008 mov qword ptr [r8+8],rax

1
2
3
4
5
6
7

两处

- CcDeleteBcbs

- CcFindNextWorkQueueEntry


nt!CcFindNextWorkQueueEntry+0x16:
fffff8023fb6944a 744d je nt!CcFindNextWorkQueueEntry+0x65 (fffff8023fb69499)
fffff8023fb6944c 3c02 cmp al,2 fffff8023fb6944e 7537 jne nt!CcFindNextWorkQueueEntry+0x53 (fffff8023fb69487) fffff8023fb69450 488b4210 mov rax,qword ptr [rdx+10h]
fffff8023fb69454 4c8990f0010000 mov qword ptr [rax+1F0h],r10 fffff8023fb6945b 488b0a mov rcx,qword ptr [rdx]
fffff8023fb6945e 488b4208 mov rax,qword ptr [rdx+8] fffff8023fb69462 48395108 cmp qword ptr [rcx+8],rdx
nt!CcFindNextWorkQueueEntry+0x32:
fffff8023fb69466 0f8540ae0d00 jne nt! ?? ::FNODOBFM::string’+0x323a (fffff8023fc442ac) fffff8023fb6946c 483910 cmp qword ptr [rax],rdx
fffff8023fb6946f 0f8537ae0d00 jne nt! ?? ::FNODOBFM::string’+0x323a (fffff8023fc442ac) fffff8023fb69475 488908 mov qword ptr [rax],rcx
fffff8023fb69478 48894108 mov qword ptr [rcx+8],rax
1
2
3
4
5



- CcLazyWriteScan

nt!CcLazyWriteScan+0x55c: fffff802
3fb68b70 0f84cf000000 je nt!CcLazyWriteScan+0x631 (fffff8023fb68c45) fffff8023fb68b76 488b0d23a01f00 mov rcx,qword ptr [nt!CcLazyWriterCursor (fffff8023fd62ba0)] fffff8023fb68b7d 488b0524a01f00 mov rax,qword ptr [nt!CcLazyWriterCursor+0x8 (fffff8023fd62ba8)] fffff8023fb68b84 48397908 cmp qword ptr [rcx+8],rdi
fffff8023fb68b88 0f85cabb0d00 jne nt! ?? ::FNODOBFM::string’+0x36e4 (fffff8023fc44758) fffff8023fb68b8e 483938 cmp qword ptr [rax],rdi
fffff8023fb68b91 0f85c1bb0d00 jne nt! ?? ::FNODOBFM::string’+0x36e4 (fffff8023fc44758) fffff8023fb68b97 488908 mov qword ptr [rax],rcx
nt!CcLazyWriteScan+0x586:
fffff802`3fb68b9a 48894108 mov qword ptr [rcx+8],rax

nt!CcLazyWriteScan+0x66c:
fffff8023fb68c80 b905000000 mov ecx,5 fffff8023fb68c85 44883db4a01f00 mov byte ptr [nt!LazyWriter+0x80 (fffff8023fd62d40)],r15b fffff8023fb68c8c e843b2ffff call nt!KeReleaseQueuedSpinLock (fffff8023fb63ed4) fffff8023fb68c91 e9d1fbffff jmp nt!CcLazyWriteScan+0x253 (fffff8023fb68867) fffff8023fb68c96 488b0d039f1f00 mov rcx,qword ptr [nt!CcLazyWriterCursor (fffff8023fd62ba0)] fffff8023fb68c9d 488b05049f1f00 mov rax,qword ptr [nt!CcLazyWriterCursor+0x8 (fffff8023fd62ba8)] fffff8023fb68ca4 48397908 cmp qword ptr [rcx+8],rdi
fffff8023fb68ca8 0f85d4ba0d00 jne nt! ?? ::FNODOBFM::string’+0x370e (fffff8023fc44782) nt!CcLazyWriteScan+0x69a: fffff8023fb68cae 483938 cmp qword ptr [rax],rdi
fffff8023fb68cb1 0f85cbba0d00 jne nt! ?? ::FNODOBFM::string’+0x370e (fffff8023fc44782) fffff8023fb68cb7 488908 mov qword ptr [rax],rcx
fffff802`3fb68cba 48894108 mov qword ptr [rcx+8],rax

nt!CcLazyWriteScan+0x7a1:
fffff8023fb68db5 294150 sub dword ptr [rcx+50h],eax fffff8023fb68db8 ebe6 jmp nt!CcLazyWriteScan+0x78c (fffff8023fb68da0) fffff8023fb68dba 488b08 mov rcx,qword ptr [rax]
fffff8023fb68dbd 4c394008 cmp qword ptr [rax+8],r8 fffff8023fb68dc1 756c jne nt!CcLazyWriteScan+0x81b (fffff8023fb68e2f) fffff8023fb68dc3 48394108 cmp qword ptr [rcx+8],rax
fffff8023fb68dc7 7566 jne nt!CcLazyWriteScan+0x81b (fffff8023fb68e2f)
fffff8023fb68dc9 48890da09e1f00 mov qword ptr [nt!CcPostTickWorkQueue (fffff8023fd62c70)],rcx
nt!CcLazyWriteScan+0x7bc:
fffff802`3fb68dd0 4c894108 mov qword ptr [rcx+8],r8

nt!CcLazyWriteScan+0x7d8:
fffff8023fb68dec 488901 mov qword ptr [rcx],rax fffff8023fb68def 488945d7 mov qword ptr [rbp-29h],rax
fffff8023fb68df3 e9d1f8ffff jmp nt!CcLazyWriteScan+0xb5 (fffff8023fb686c9)
fffff8023fb68df8 488b01 mov rax,qword ptr [rcx] fffff8023fb68dfb 488d55cf lea rdx,[rbp-31h]
fffff8023fb68dff 48395108 cmp qword ptr [rcx+8],rdx fffff8023fb68e03 7531 jne nt!CcLazyWriteScan+0x822 (fffff8023fb68e36) fffff8023fb68e05 48394808 cmp qword ptr [rax+8],rcx
nt!CcLazyWriteScan+0x7f5:
fffff8023fb68e09 752b jne nt!CcLazyWriteScan+0x822 (fffff8023fb68e36)
fffff8023fb68e0b 488d55cf lea rdx,[rbp-31h] fffff8023fb68e0f 488945cf mov qword ptr [rbp-31h],rax
fffff8023fb68e13 48895008 mov qword ptr [rax+8],rdx

1
2
3
4
5

三处

- CcSetFileSizesEx

nt!CcSetFileSizesEx+0x324: fffff8023fb50f56 0fbae119 bt ecx,19h
fffff8023fb50f5a 0f82ec2e0f00 jb nt! ?? ::FNODOBFM::string’+0x2815 (fffff8023fc43e4c) fffff8023fb50f60 0fbae118 bt ecx,18h
fffff8023fb50f64 0f82e22e0f00 jb nt! ?? ::FNODOBFM::string’+0x2815 (fffff8023fc43e4c) fffff8023fb50f6a 4881c688000000 add rsi,88h
fffff8023fb50f71 488b0e mov rcx,qword ptr [rsi] fffff8023fb50f74 488b4608 mov rax,qword ptr [rsi+8]
fffff8023fb50f78 48397108 cmp qword ptr [rcx+8],rsi nt!CcSetFileSizesEx+0x34a: fffff8023fb50f7c 0f851f2f0f00 jne nt! ?? ::FNODOBFM::string'+0x2876 (fffff8023fc43ea1)
fffff8023fb50f82 483930 cmp qword ptr [rax],rsi fffff8023fb50f85 0f85162f0f00 jne nt! ?? ::FNODOBFM::string'+0x2876 (fffff8023fc43ea1)
fffff8023fb50f8b 488908 mov qword ptr [rax],rcx fffff8023fb50f8e 48894108 mov qword ptr [rcx+8],rax

nt!CcSetFileSizesEx+0x45f:
fffff8023fb51092 0f82562c0f00 jb nt! ?? ::FNODOBFM::string’+0x2693 (fffff8023fc43cee) fffff8023fb51098 0fbae018 bt eax,18h
fffff8023fb5109c 0f824c2c0f00 jb nt! ?? ::FNODOBFM::string’+0x2693 (fffff8023fc43cee) fffff8023fb510a2 4881c688000000 add rsi,88h
fffff8023fb510a9 488b0e mov rcx,qword ptr [rsi] fffff8023fb510ac 488b4608 mov rax,qword ptr [rsi+8]
fffff8023fb510b0 48397108 cmp qword ptr [rcx+8],rsi fffff8023fb510b4 7554 jne nt!CcSetFileSizesEx+0x4d7 (fffff8023fb5110a) nt!CcSetFileSizesEx+0x483: fffff8023fb510b6 483930 cmp qword ptr [rax],rsi
fffff8023fb510b9 754f jne nt!CcSetFileSizesEx+0x4d7 (fffff8023fb5110a)
fffff8023fb510bb 488908 mov qword ptr [rax],rcx fffff8023fb510be 48894108 mov qword ptr [rcx+8],rax

1
2
3
4
5

两处

- CmShutdownSystem


nt!CmShutdownSystem+0x2b0:
fffff8023ffa96b8 488b0e mov rcx,qword ptr [rsi] fffff8023ffa96bb 488b4608 mov rax,qword ptr [rsi+8]
fffff8023ffa96bf 48397108 cmp qword ptr [rcx+8],rsi fffff8023ffa96c3 0f8511020000 jne nt!CmShutdownSystem+0x4d2 (fffff8023ffa98da) fffff8023ffa96c9 483930 cmp qword ptr [rax],rsi
fffff8023ffa96cc 0f8508020000 jne nt!CmShutdownSystem+0x4d2 (fffff8023ffa98da)
fffff8023ffa96d2 488908 mov qword ptr [rax],rcx fffff8023ffa96d5 48894108 mov qword ptr [rcx+8],rax
1
2
3
4
5



- CmUnRegisterCallback


nt!CmUnRegisterCallback+0x14a:
fffff8023ff86aee 44899c24d0000000 mov dword ptr [rsp+0D0h],r11d fffff8023ff86af6 4439a424d0000000 cmp dword ptr [rsp+0D0h],r12d
fffff8023ff86afe 75c9 jne nt!CmUnRegisterCallback+0x125 (fffff8023ff86ac9)
fffff8023ff86b00 65488b042588010000 mov rax,qword ptr gs:[188h] fffff8023ff86b09 664401a8e4010000 add word ptr [rax+1E4h],r13w
fffff8023ff86b11 f0490fba2f00 lock bts qword ptr [r15],0 fffff8023ff86b17 0f8237fcffff jb nt! ?? ::NNGAKEGL::string'+0x5966 (fffff8023ff86754)
fffff8023ff86b1d 488b0f mov rcx,qword ptr [rdi] nt!CmUnRegisterCallback+0x17c: fffff8023ff86b20 488b4708 mov rax,qword ptr [rdi+8]
fffff8023ff86b24 48397908 cmp qword ptr [rcx+8],rdi fffff8023ff86b28 0f856afcffff jne nt! ?? ::NNGAKEGL::string'+0x59aa (fffff8023ff86798)
fffff8023ff86b2e 483938 cmp qword ptr [rax],rdi fffff8023ff86b31 0f8561fcffff jne nt! ?? ::NNGAKEGL::string'+0x59aa (fffff8023ff86798)
fffff8023ff86b37 488908 mov qword ptr [rax],rcx fffff8023ff86b3a 48894108 mov qword ptr [rcx+8],rax
1
2
3
4
5



- CmpCallCallBacks


nt!CmUnRegisterCallback+0x346:
fffff8023ff86cea 488b0f mov rcx,qword ptr [rdi] fffff8023ff86ced 488b4708 mov rax,qword ptr [rdi+8]
fffff8023ff86cf1 48397908 cmp qword ptr [rcx+8],rdi fffff8023ff86cf5 7578 jne nt!CmUnRegisterCallback+0x3cb (fffff8023ff86d6f) fffff8023ff86cf7 483938 cmp qword ptr [rax],rdi
fffff8023ff86cfa 7573 jne nt!CmUnRegisterCallback+0x3cb (fffff8023ff86d6f)
fffff8023ff86cfc 488908 mov qword ptr [rax],rcx fffff8023ff86cff 48894108 mov qword ptr [rcx+8],rax
1
2
3
4
5



- CmpPostApc


nt!CmpPostApc+0x114:
fffff8023fe2fcb8 488b10 mov rdx,qword ptr [rax] fffff8023fe2fcbb 488b4808 mov rcx,qword ptr [rax+8]
fffff8023fe2fcbf 48394208 cmp qword ptr [rdx+8],rax fffff8023fe2fcc3 7570 jne nt!CmpPostApc+0x191 (fffff8023fe2fd35) fffff8023fe2fcc5 483901 cmp qword ptr [rcx],rax
fffff8023fe2fcc8 756b jne nt!CmpPostApc+0x191 (fffff8023fe2fd35)
fffff8023fe2fcca 488911 mov qword ptr [rcx],rdx fffff8023fe2fccd 48894a08 mov qword ptr [rdx+8],rcx

nt!CmpPostApc+0x148:
fffff8023fe2fcec c3 ret fffff8023fe2fced 488b09 mov rcx,qword ptr [rcx]
fffff8023fe2fcf0 4883e920 sub rcx,20h fffff8023fe2fcf4 488d4120 lea rax,[rcx+20h]
fffff8023fe2fcf8 4c8b00 mov r8,qword ptr [rax] fffff8023fe2fcfb 488b5008 mov rdx,qword ptr [rax+8]
fffff8023fe2fcff 49394008 cmp qword ptr [r8+8],rax fffff8023fe2fd03 753e jne nt!CmpPostApc+0x19f (fffff8023fe2fd43) kd> nt!CmpPostApc+0x161: fffff8023fe2fd05 483902 cmp qword ptr [rdx],rax
fffff8023fe2fd08 7539 jne nt!CmpPostApc+0x19f (fffff8023fe2fd43)
fffff8023fe2fd0a 4c8902 mov qword ptr [rdx],r8 fffff8023fe2fd0d 49895008 mov qword ptr [r8+8],rdx
fffff8023fe2fd11 488d5110 lea rdx,[rcx+10h] fffff8023fe2fd15 4c8b02 mov r8,qword ptr [rdx]
fffff8023fe2fd18 488b4208 mov rax,qword ptr [rdx+8] fffff8023fe2fd1c 49395008 cmp qword ptr [r8+8],rdx
nt!CmpPostApc+0x17c:
fffff8023fe2fd20 751a jne nt!CmpPostApc+0x198 (fffff8023fe2fd3c)
fffff8023fe2fd22 483910 cmp qword ptr [rax],rdx fffff8023fe2fd25 7515 jne nt!CmpPostApc+0x198 (fffff8023fe2fd3c) fffff8023fe2fd27 4c8900 mov qword ptr [rax],r8
fffff8023fe2fd2a 49894008 mov qword ptr [r8+8],rax

1
2
3
4
5

三处,第二段包含连续的两处

- ExFreePoolWithTag

nt!ExFreePoolWithTag+0x9ad: fffff8023fcea9bc 0f8559040000 jne nt!ExFreePoolWithTag+0xe0c (fffff8023fceae1b) fffff8023fcea9c2 3c01 cmp al,1
fffff8023fcea9c4 7426 je nt!ExFreePoolWithTag+0x9dd (fffff8023fcea9ec)
fffff8023fcea9c6 4d8b4610 mov r8,qword ptr [r14+10h] fffff8023fcea9ca 498b5618 mov rdx,qword ptr [r14+18h]
fffff8023fcea9ce 498d4610 lea rax,[r14+10h] fffff8023fcea9d2 49394008 cmp qword ptr [r8+8],rax
fffff8023fcea9d6 0f85f8040000 jne nt!ExFreePoolWithTag+0xec5 (fffff8023fceaed4)
nt!ExFreePoolWithTag+0x9cd:
fffff8023fcea9dc 483902 cmp qword ptr [rdx],rax fffff8023fcea9df 0f85ef040000 jne nt!ExFreePoolWithTag+0xec5 (fffff8023fceaed4) fffff8023fcea9e5 4c8902 mov qword ptr [rdx],r8
fffff8023fcea9e8 49895008 mov qword ptr [r8+8],rdx
1
2
3
4
5



- ExQueueWorkItem

nt!ExQueueWorkItem+0x13a: fffff802
3fb2f69a 0f8465010000 je nt!ExQueueWorkItem+0x2a5 (fffff8023fb2f805) fffff8023fb2f6a0 488b7310 mov rsi,qword ptr [rbx+10h]
fffff8023fb2f6a4 488bd6 mov rdx,rsi fffff8023fb2f6a7 488b7608 mov rsi,qword ptr [rsi+8]
fffff8023fb2f6ab 4c8b02 mov r8,qword ptr [rdx] fffff8023fb2f6ae 49395008 cmp qword ptr [r8+8],rdx
fffff8023fb2f6b2 0f8524030000 jne nt!ExQueueWorkItem+0x487 (fffff8023fb2f9dc)
fffff8023fb2f6b8 483916 cmp qword ptr [rsi],rdx nt!ExQueueWorkItem+0x15b: fffff8023fb2f6bb 0f851b030000 jne nt!ExQueueWorkItem+0x487 (fffff8023fb2f9dc) fffff8023fb2f6c1 4c8906 mov qword ptr [rsi],r8
fffff8023fb2f6c4 49897008 mov qword ptr [r8+8],rsi
1
2
3
4
5



- ExTimerRundown

nt!ExTimerRundown+0x13d: fffff802
3fadad61 488b10 mov rdx,qword ptr [rax]
fffff8023fadad64 488b4808 mov rcx,qword ptr [rax+8] fffff8023fadad68 48394208 cmp qword ptr [rdx+8],rax
fffff8023fadad6c 0f8595041a00 jne nt! ?? ::FNODOBFM::string’+0x4e227 (fffff8023fc7b207) fffff8023fadad72 483901 cmp qword ptr [rcx],rax
fffff8023fadad75 0f858c041a00 jne nt! ?? ::FNODOBFM::string’+0x4e227 (fffff8023fc7b207) fffff8023fadad7b 488911 mov qword ptr [rcx],rdx
fffff8023fadad7e 48894a08 mov qword ptr [rdx+8],rcx
1
2
3
4
5



- ExpDeleteTImer

nt!ExpDeleteTimer+0x9c: fffff802
3faca6d8 440f20c5 mov rbp,cr8
fffff8023faca6dc 450f22c4 mov cr8,r12 fffff8023faca6e0 f7059a79300000002100 test dword ptr [nt!PerfGlobalGroupMask+0x4 (fffff8023fdd2084)],210000h fffff8023faca6ea 0f85000a1b00 jne nt! ?? ::FNODOBFM::string'+0x4e0a2 (fffff8023fc7b0f0)
fffff8023faca6f0 f0480fba2b00 lock bts qword ptr [rbx],0 fffff8023faca6f6 0f82020a1b00 jb nt! ?? ::FNODOBFM::string'+0x4e0b0 (fffff8023fc7b0fe)
fffff8023faca6fc 488b0f mov rcx,qword ptr [rdi] fffff8023faca6ff 488b4708 mov rax,qword ptr [rdi+8]
nt!ExpDeleteTimer+0xc7:
fffff8023faca703 48397908 cmp qword ptr [rcx+8],rdi fffff8023faca707 0f85120a1b00 jne nt! ?? ::FNODOBFM::string'+0x4e0d1 (fffff8023fc7b11f)
fffff8023faca70d 483938 cmp qword ptr [rax],rdi fffff8023faca710 0f85090a1b00 jne nt! ?? ::FNODOBFM::string'+0x4e0d1 (fffff8023fc7b11f)
fffff8023faca716 488908 mov qword ptr [rax],rcx fffff8023faca719 48894108 mov qword ptr [rcx+8],rax

nt!ExpDeleteTimer+0x11d:
fffff8023faca759 f0480fba2dbd0a240000 lock bts qword ptr [nt!ExpWakeTimerLock (fffff8023fd0b220)],0
fffff8023faca763 7266 jb nt!ExpDeleteTimer+0x18f (fffff8023faca7cb)
fffff8023faca765 498b16 mov rdx,qword ptr [r14] fffff8023faca768 498b4608 mov rax,qword ptr [r14+8]
fffff8023faca76c 4c397208 cmp qword ptr [rdx+8],r14 fffff8023faca770 7567 jne nt!ExpDeleteTimer+0x19d (fffff8023faca7d9) fffff8023faca772 4c3930 cmp qword ptr [rax],r14
fffff8023faca775 7562 jne nt!ExpDeleteTimer+0x19d (fffff8023faca7d9)
nt!ExpDeleteTimer+0x13b:
fffff8023faca777 488910 mov qword ptr [rax],rdx fffff8023faca77a 48894208 mov qword ptr [rdx+8],rax

1
2
3
4
5
6
7
8
9
10
11



- ExpSetTimer

- IoDeleteDevice

- IoUnregisterFsRegistrationChange

- IopfCompleteRequest


nt!IopfCompleteRequest+0x348:
fffff8023fb2e058 0f82650f0000 jb nt!IopfCompleteRequest+0x12c3 (fffff8023fb2efc3)
fffff8023fb2e05e 0fb64311 movzx eax,byte ptr [rbx+11h] fffff8023fb2e062 3c02 cmp al,2
fffff8023fb2e064 7521 jne nt!IopfCompleteRequest+0x377 (fffff8023fb2e087)
fffff8023fb2e066 488b0b mov rcx,qword ptr [rbx] fffff8023fb2e069 488b4308 mov rax,qword ptr [rbx+8]
fffff8023fb2e06d 48395908 cmp qword ptr [rcx+8],rbx fffff8023fb2e071 0f851e100000 jne nt!IopfCompleteRequest+0x1399 (fffff8023fb2f095) nt!IopfCompleteRequest+0x367: fffff8023fb2e077 483918 cmp qword ptr [rax],rbx
fffff8023fb2e07a 0f8515100000 jne nt!IopfCompleteRequest+0x1399 (fffff8023fb2f095)
fffff8023fb2e080 488908 mov qword ptr [rax],rcx fffff8023fb2e083 48894108 mov qword ptr [rcx+8],rax

nt!IopfCompleteRequest+0x758:
fffff8023fb2e468 483bc7 cmp rax,rdi fffff8023fb2e46b 0f848b030000 je nt!IopfCompleteRequest+0xaea (fffff8023fb2e7fc) fffff8023fb2e471 4c8b4710 mov r8,qword ptr [rdi+10h]
fffff8023fb2e475 498b10 mov rdx,qword ptr [r8] fffff8023fb2e478 498b4808 mov rcx,qword ptr [r8+8]
fffff8023fb2e47c 4d8be0 mov r12,r8 fffff8023fb2e47f 48894dd7 mov qword ptr [rbp-29h],rcx
fffff8023fb2e483 4c394208 cmp qword ptr [rdx+8],r8 nt!IopfCompleteRequest+0x777: fffff8023fb2e487 0f859f070000 jne nt!IopfCompleteRequest+0xf35 (fffff8023fb2ec2c) fffff8023fb2e48d 4c3901 cmp qword ptr [rcx],r8
fffff8023fb2e490 0f8596070000 jne nt!IopfCompleteRequest+0xf35 (fffff8023fb2ec2c)
fffff8023fb2e496 488911 mov qword ptr [rcx],rdx fffff8023fb2e499 4532f6 xor r14b,r14b
fffff802`3fb2e49c 48894a08 mov qword ptr [rdx+8],rcx

nt!IopfCompleteRequest+0x80c:
fffff8023fb2e51c 4885c0 test rax,rax fffff8023fb2e51f 7433 je nt!IopfCompleteRequest+0x844 (fffff8023fb2e554) fffff8023fb2e521 488d86d8000000 lea rax,[rsi+0D8h]
fffff8023fb2e528 488b10 mov rdx,qword ptr [rax] fffff8023fb2e52b 488b4808 mov rcx,qword ptr [rax+8]
fffff8023fb2e52f 48394208 cmp qword ptr [rdx+8],rax fffff8023fb2e533 0f858c080000 jne nt!IopfCompleteRequest+0x10cd (fffff8023fb2edc5) fffff8023fb2e539 483901 cmp qword ptr [rcx],rax
nt!IopfCompleteRequest+0x82c:
fffff8023fb2e53c 0f8583080000 jne nt!IopfCompleteRequest+0x10cd (fffff8023fb2edc5)
fffff8023fb2e542 488911 mov qword ptr [rcx],rdx fffff8023fb2e545 48894a08 mov qword ptr [rdx+8],rcx

1
2
3
4
5

三处

- KeDeregisterBugCheckCallback


nt!KeDeregisterBugCheckCallback+0x4c:
fffff8023fbf0ee0 e80b57efff call nt!KxWaitForSpinLockAndAcquire (fffff8023fae65f0)
fffff8023fbf0ee5 4032ff xor dil,dil fffff8023fbf0ee8 807b3801 cmp byte ptr [rbx+38h],1
fffff8023fbf0eec 7520 jne nt!KeDeregisterBugCheckCallback+0x7a (fffff8023fbf0f0e)
fffff8023fbf0eee 488b0b mov rcx,qword ptr [rbx] fffff8023fbf0ef1 488b4308 mov rax,qword ptr [rbx+8]
fffff8023fbf0ef5 40887b38 mov byte ptr [rbx+38h],dil fffff8023fbf0ef9 48395908 cmp qword ptr [rcx+8],rbx
nt!KeDeregisterBugCheckCallback+0x69:
fffff8023fbf0efd 752e jne nt!KeDeregisterBugCheckCallback+0x99 (fffff8023fbf0f2d)
fffff8023fbf0eff 483918 cmp qword ptr [rax],rbx fffff8023fbf0f02 7529 jne nt!KeDeregisterBugCheckCallback+0x99 (fffff8023fbf0f2d) fffff8023fbf0f04 488908 mov qword ptr [rax],rcx
fffff8023fbf0f07 40b701 mov dil,1 fffff8023fbf0f0a 48894108 mov qword ptr [rcx+8],rax
1
2
3
4
5



- KeDeregisterObjectNotification


nt!KeDeregisterObjectNotification+0x39:
fffff8023fad4c49 8a4711 mov al,byte ptr [rdi+11h] fffff8023fad4c4c 413ac7 cmp al,r15b
fffff8023fad4c4f 7520 jne nt!KeDeregisterObjectNotification+0x61 (fffff8023fad4c71)
fffff8023fad4c51 488b0f mov rcx,qword ptr [rdi] fffff8023fad4c54 488b4708 mov rax,qword ptr [rdi+8]
fffff8023fad4c58 48397908 cmp qword ptr [rcx+8],rdi fffff8023fad4c5c 7545 jne nt!KeDeregisterObjectNotification+0x93 (fffff8023fad4ca3) fffff8023fad4c5e 483938 cmp qword ptr [rax],rdi
nt!KeDeregisterObjectNotification+0x51:
fffff8023fad4c61 7540 jne nt!KeDeregisterObjectNotification+0x93 (fffff8023fad4ca3)
fffff8023fad4c63 488908 mov qword ptr [rax],rcx fffff8023fad4c66 48894108 mov qword ptr [rcx+8],rax
1
2
3
4
5



- KeRegisterObjectNotification


nt!KeRegisterObjectNotification+0x119:
fffff8023fae3815 483bc7 cmp rax,rdi fffff8023fae3818 750a jne nt!KeRegisterObjectNotification+0x128 (fffff8023fae3824) fffff8023fae381a 4180bf830200000f cmp byte ptr [r15+283h],0Fh
fffff8023fae3822 7470 je nt!KeRegisterObjectNotification+0x198 (fffff8023fae3894)
fffff8023fae3824 4c8b7710 mov r14,qword ptr [rdi+10h] fffff8023fae3828 498bd6 mov rdx,r14
fffff8023fae382b 4d8b7608 mov r14,qword ptr [r14+8] fffff8023fae382f 4c8b02 mov r8,qword ptr [rdx]
nt!KeRegisterObjectNotification+0x136:
fffff8023fae3832 49395008 cmp qword ptr [r8+8],rdx fffff8023fae3836 0f85d4000000 jne nt!KeRegisterObjectNotification+0x214 (fffff8023fae3910) fffff8023fae383c 493916 cmp qword ptr [r14],rdx
fffff8023fae383f 0f85cb000000 jne nt!KeRegisterObjectNotification+0x214 (fffff8023fae3910)
fffff8023fae3845 4d8906 mov qword ptr [r14],r8 fffff8023fae3848 4d897008 mov qword ptr [r8+8],r14
1
2
3
4
5



- KeRemoveQueueApc


nt!KeRemoveQueueApc+0x63:
fffff8023fad62a3 5f pop rdi fffff8023fad62a4 c3 ret
fffff8023fad62a5 480fbe4650 movsx rax,byte ptr [rsi+50h] fffff8023fad62aa c6465200 mov byte ptr [rsi+52h],0
fffff8023fad62ae 4c8d4e10 lea r9,[rsi+10h] fffff8023fad62b2 498b09 mov rcx,qword ptr [r9]
fffff8023fad62b5 4c8b84c748020000 mov r8,qword ptr [rdi+rax*8+248h] fffff8023fad62bd 498b4108 mov rax,qword ptr [r9+8]
kd>
nt!KeRemoveQueueApc+0x81:
fffff8023fad62c1 4c394908 cmp qword ptr [rcx+8],r9 fffff8023fad62c5 7529 jne nt!KeRemoveQueueApc+0xb0 (fffff8023fad62f0) fffff8023fad62c7 4c3908 cmp qword ptr [rax],r9
fffff8023fad62ca 7524 jne nt!KeRemoveQueueApc+0xb0 (fffff8023fad62f0)
fffff8023fad62cc 488908 mov qword ptr [rax],rcx fffff8023fad62cf 48894108 mov qword ptr [rcx+8],rax
1
2
3
4
5
6
7



- KeRemoveQueueDpc

- KiCancelTimer


nt!KiCancelTimer+0xbf:
fffff8023fb2280f f0480fba2e00 lock bts qword ptr [rsi],0 fffff8023fb22815 0f820f010000 jb nt!KiCancelTimer+0x1e0 (fffff8023fb2292a) fffff8023fb2281b 0fb64303 movzx eax,byte ptr [rbx+3]
fffff8023fb2281f 84c0 test al,al fffff8023fb22821 0f88b5000000 js nt!KiCancelTimer+0x18c (fffff8023fb228dc) fffff8023fb22827 488b4b20 mov rcx,qword ptr [rbx+20h]
fffff8023fb2282b 488b4328 mov rax,qword ptr [rbx+28h] fffff8023fb2282f 488d5320 lea rdx,[rbx+20h]
nt!KiCancelTimer+0xe3:
fffff8023fb22833 4d8d4710 lea r8,[r15+10h] fffff8023fb22837 4d8bcf mov r9,r15
fffff8023fb2283a 49c1e005 shl r8,5 fffff8023fb2283e 48395108 cmp qword ptr [rcx+8],rdx
fffff8023fb22842 0f858d000000 jne nt!KiCancelTimer+0x185 (fffff8023fb228d5)
fffff8023fb22848 483910 cmp qword ptr [rax],rdx fffff8023fb2284b 0f8584000000 jne nt!KiCancelTimer+0x185 (fffff8023fb228d5) fffff8023fb22851 488908 mov qword ptr [rax],rcx
nt!KiCancelTimer+0x104:
fffff8023fb22854 48894108 mov qword ptr [rcx+8],rax
1
2
3
4
5



- KeTerminateThread

nt!KeTerminateThread+0x93: fffff802
3fada337 4c8da3f8020000 lea r12,[rbx+2F8h]
fffff8023fada33e 49390424 cmp qword ptr [r12],rax fffff8023fada342 0f841b010000 je nt!KeTerminateThread+0x1bf (fffff8023fada463) fffff8023fada348 8bf7 mov esi,edi
fffff8023fada34a f0410fba2f07 lock bts dword ptr [r15],7 fffff8023fada350 0f82d7adfaff jb nt! ?? ::FNODOBFM::string'+0xd7d3 (fffff8023fa8512d)
fffff8023fada356 498b0c24 mov rcx,qword ptr [r12] fffff8023fada35a 498b442408 mov rax,qword ptr [r12+8]
nt!KeTerminateThread+0xbb:
fffff8023fada35f 4c396108 cmp qword ptr [rcx+8],r12 fffff8023fada363 0f853c020000 jne nt!KeTerminateThread+0x301 (fffff8023fada5a5) fffff8023fada369 4c3920 cmp qword ptr [rax],r12
fffff8023fada36c 0f8533020000 jne nt!KeTerminateThread+0x301 (fffff8023fada5a5)
fffff8023fada372 488908 mov qword ptr [rax],rcx fffff8023fada375 41bc7fffffff mov r12d,0FFFFFF7Fh
fffff802`3fada37b 48894108 mov qword ptr [rcx+8],rax

nt!KeTerminateThread+0x1f2:
fffff8023fada496 498d8738020000 lea rax,[r15+238h] fffff8023fada49d 488b10 mov rdx,qword ptr [rax]
fffff8023fada4a0 488b4808 mov rcx,qword ptr [rax+8] fffff8023fada4a4 48394208 cmp qword ptr [rdx+8],rax
fffff8023fada4a8 0f8578acfaff jne nt! ?? ::FNODOBFM::string’+0xd7cc (fffff8023fa85126) fffff8023fada4ae 483901 cmp qword ptr [rcx],rax
fffff8023fada4b1 0f856facfaff jne nt! ?? ::FNODOBFM::string’+0xd7cc (fffff8023fa85126) fffff8023fada4b7 488911 mov qword ptr [rcx],rdx
nt!KeTerminateThread+0x216:
fffff8023fada4ba 48894a08 mov qword ptr [rdx+8],rcx

1
2
3
4
5



- KiDeliverApc

nt!KiDeliverApc+0x10c: fffff8023fb58e3c 7556 jne nt!KiDeliverApc+0x164 (fffff8023fb58e94) fffff8023fb58e3e 488b0a mov rcx,qword ptr [rdx]
fffff8023fb58e41 488b4208 mov rax,qword ptr [rdx+8] fffff8023fb58e45 48395108 cmp qword ptr [rcx+8],rdx
fffff8023fb58e49 0f854a020000 jne nt!KiDeliverApc+0x36e (fffff8023fb59099)
fffff8023fb58e4f 483910 cmp qword ptr [rax],rdx fffff8023fb58e52 0f8541020000 jne nt!KiDeliverApc+0x36e (fffff8023fb59099) fffff8023fb58e58 488908 mov qword ptr [rax],rcx
nt!KiDeliverApc+0x12b:
fffff802`3fb58e5b 48894108 mov qword ptr [rcx+8],rax

nt!KiDeliverApc+0x171:
fffff8023fb58ea1 6683bbe401000000 cmp word ptr [rbx+1E4h],0 fffff8023fb58ea9 0f8586010000 jne nt!KiDeliverApc+0x303 (fffff8023fb59035) fffff8023fb58eaf 488b0a mov rcx,qword ptr [rdx]
fffff8023fb58eb2 488b4208 mov rax,qword ptr [rdx+8] fffff8023fb58eb6 48395108 cmp qword ptr [rcx+8],rdx
fffff8023fb58eba 0f85cb010000 jne nt!KiDeliverApc+0x360 (fffff8023fb5908b)
fffff8023fb58ec0 483910 cmp qword ptr [rax],rdx fffff8023fb58ec3 0f85c2010000 jne nt!KiDeliverApc+0x360 (fffff8023fb5908b) nt!KiDeliverApc+0x199: fffff8023fb58ec9 488908 mov qword ptr [rax],rcx
fffff802`3fb58ecc 48894108 mov qword ptr [rcx+8],rax

nt!KiDeliverApc+0x266:
fffff8023fb58f98 488b4128 mov rax,qword ptr [rcx+28h] fffff8023fb58f9c 488945f0 mov qword ptr [rbp-10h],rax
fffff8023fb58fa0 488b4130 mov rax,qword ptr [rcx+30h] fffff8023fb58fa4 488945e8 mov qword ptr [rbp-18h],rax
fffff8023fb58fa8 488b4138 mov rax,qword ptr [rcx+38h] fffff8023fb58fac 48894550 mov qword ptr [rbp+50h],rax
fffff8023fb58fb0 488b11 mov rdx,qword ptr [rcx] fffff8023fb58fb3 488b4108 mov rax,qword ptr [rcx+8]
nt!KiDeliverApc+0x285:
fffff8023fb58fb7 48394a08 cmp qword ptr [rdx+8],rcx fffff8023fb58fbb 0f85d1000000 jne nt!KiDeliverApc+0x367 (fffff8023fb59092) fffff8023fb58fc1 483908 cmp qword ptr [rax],rcx
fffff8023fb58fc4 0f85c8000000 jne nt!KiDeliverApc+0x367 (fffff8023fb59092)
fffff8023fb58fca 488910 mov qword ptr [rax],rdx fffff8023fb58fcd 48894208 mov qword ptr [rdx+8],rax

1
2
3
4
5



- KiExecuteAllDpcs


nt!KiExecuteAllDpcs+0xa9:
fffff8023faed3a9 83f801 cmp eax,1 fffff8023faed3ac 7f15 jg nt!KiExecuteAllDpcs+0xc3 (fffff8023faed3c3) fffff8023faed3ae 66f04321946fdc2d0000 lock and word ptr [r15+r13*2+2DDCh],dx
fffff8023faed3b8 8b4318 mov eax,dword ptr [rbx+18h] fffff8023faed3bb 85c0 test eax,eax
fffff8023faed3bd 0f84d619fbff je nt! ?? ::FNODOBFM::string’+0x14ab8 (fffff8023fa9ed99) fffff8023faed3c3 488b11 mov rdx,qword ptr [rcx]
fffff8023faed3c6 488b4108 mov rax,qword ptr [rcx+8] nt!KiExecuteAllDpcs+0xca: fffff8023faed3ca 48394a08 cmp qword ptr [rdx+8],rcx
fffff8023faed3ce 0f85d9020000 jne nt!KiExecuteAllDpcs+0x3ad (fffff8023faed6ad)
fffff8023faed3d4 483908 cmp qword ptr [rax],rcx fffff8023faed3d7 0f85d0020000 jne nt!KiExecuteAllDpcs+0x3ad (fffff8023faed6ad) fffff8023faed3dd 488910 mov qword ptr [rax],rdx
fffff8023faed3e0 48894208 mov qword ptr [rdx+8],rax
1
2
3
4
5
6
7



- KiExpireTimerTable

- KiFindReadyThread

nt!KiFindReadyThread+0x5e: fffff802
3fa9f32e 488b8760060000 mov rax,qword ptr [rdi+660h]
fffff8023fa9f335 49858238020000 test qword ptr [r10+238h],rax fffff8023fa9f33c 744f je nt!KiFindReadyThread+0xbd (fffff8023fa9f38d) fffff8023fa9f33e 4c8b01 mov r8,qword ptr [rcx]
fffff8023fa9f341 488b5108 mov rdx,qword ptr [rcx+8] fffff8023fa9f345 49394808 cmp qword ptr [r8+8],rcx
fffff8023fa9f349 7568 jne nt!KiFindReadyThread+0xe3 (fffff8023fa9f3b3)
fffff8023fa9f34b 48390a cmp qword ptr [rdx],rcx nt!KiFindReadyThread+0x7e: fffff8023fa9f34e 7563 jne nt!KiFindReadyThread+0xe3 (fffff8023fa9f3b3) fffff8023fa9f350 4c8902 mov qword ptr [rdx],r8
fffff8023fa9f353 49895008 mov qword ptr [r8+8],rdx
1
2
3
4
5
6
7
8
9



- KiFlushQueueApc

- KiInsertTimerTable

- KiProcessExpiredTimerList

nt!KiProcessExpiredTimerList+0x338: fffff802
3fb239d8 7521 jne nt!KiProcessExpiredTimerList+0x35b (fffff8023fb239fb) fffff8023fb239da 488b0b mov rcx,qword ptr [rbx]
fffff8023fb239dd 488b4308 mov rax,qword ptr [rbx+8] fffff8023fb239e1 48395908 cmp qword ptr [rcx+8],rbx
fffff8023fb239e5 0f85c3010000 jne nt!KiProcessExpiredTimerList+0x50e (fffff8023fb23bae)
fffff8023fb239eb 483918 cmp qword ptr [rax],rbx fffff8023fb239ee 0f85ba010000 jne nt!KiProcessExpiredTimerList+0x50e (fffff8023fb23bae) fffff8023fb239f4 488908 mov qword ptr [rax],rcx
nt!KiProcessExpiredTimerList+0x357:
fffff802`3fb239f7 48894108 mov qword ptr [rcx+8],rax

nt!KiProcessExpiredTimerList+0x3f3:
fffff8023fb23a93 488b7320 mov rsi,qword ptr [rbx+20h] fffff8023fb23a97 4533e4 xor r12d,r12d
fffff8023fb23a9a f00fba2e07 lock bts dword ptr [rsi],7 fffff8023fb23a9f 0f823d010000 jb nt!KiProcessExpiredTimerList+0x550 (fffff8023fb23be2) fffff8023fb23aa5 0fb64311 movzx eax,byte ptr [rbx+11h]
fffff8023fb23aa9 3c02 cmp al,2 fffff8023fb23aab 7525 jne nt!KiProcessExpiredTimerList+0x432 (fffff8023fb23ad2) fffff8023fb23aad 488b0b mov rcx,qword ptr [rbx]
nt!KiProcessExpiredTimerList+0x410:
fffff8023fb23ab0 488b4308 mov rax,qword ptr [rbx+8] fffff8023fb23ab4 48395908 cmp qword ptr [rcx+8],rbx
fffff8023fb23ab8 0f854c010000 jne nt!KiProcessExpiredTimerList+0x578 (fffff8023fb23c0a)
fffff8023fb23abe 483918 cmp qword ptr [rax],rbx fffff8023fb23ac1 0f8543010000 jne nt!KiProcessExpiredTimerList+0x578 (fffff8023fb23c0a) fffff8023fb23ac7 488908 mov qword ptr [rax],rcx
fffff8023fb23aca 48894108 mov qword ptr [rcx+8],rax

1
2
3
4
5



- MiDeleteVIrtualAddresses

nt!MiDeleteVirtualAddresses+0x8f6: fffff8023fb3bde6 0f85f3030000 jne nt!MiDeleteVirtualAddresses+0xcf4 (fffff8023fb3c1df) fffff8023fb3bdec 803d42a1200000 cmp byte ptr [nt!MiWsData+0x35 (fffff8023fd45f35)],0 fffff8023fb3bdf3 0f859a030000 jne nt!MiDeleteVirtualAddresses+0xca8 (fffff8023fb3c193) fffff8023fb3bdf9 49833c2400 cmp qword ptr [r12],0
fffff8023fb3bdfe 0f848f030000 je nt!MiDeleteVirtualAddresses+0xca8 (fffff8023fb3c193)
fffff8023fb3be04 498b0c24 mov rcx,qword ptr [r12] fffff8023fb3be08 498b442408 mov rax,qword ptr [r12+8]
fffff8023fb3be0d 4c396108 cmp qword ptr [rcx+8],r12 nt!MiDeleteVirtualAddresses+0x921: fffff8023fb3be11 0f85e9bc1200 jne nt! ?? ::FNODOBFM::string'+0x36698 (fffff8023fc67b00)
fffff8023fb3be17 4c3920 cmp qword ptr [rax],r12 fffff8023fb3be1a 0f85e0bc1200 jne nt! ?? ::FNODOBFM::string'+0x36698 (fffff8023fc67b00)
fffff8023fb3be20 488908 mov qword ptr [rax],rcx fffff8023fb3be23 48894108 mov qword ptr [rcx+8],rax
1
2
3
4
5
6
7
8
9
10
11
12
13



- NtNotifyChangeMultipleKeys

- ObRegisterCallbacks

- ObUnRegisterCallbacks

#### 小总结3

RemoveEntryList 需要获取 Entry 的 Flink 和 Blink,而且最后 Flink 和 Blink 会连接到一起,特征:


mov rcx, [r12]
mov rax, [r12+8]

; 同以上小总结
cmp
jne
cmp
jne

; 连接 Flink 和 Blink
mov [rax], rcx
mov [rcx+8], rax

1
2
3
4
5
6
7
8
9

#### 7 --



#### 8

结构是 cmp 然后 jne 到一个位置,Insert 时会出现一次,Remove 时出现两次,这个位置的内容是

mov ecx, 3
int 29h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

除此之外,mov 密集出现且两个操作数中一个是 [reg] 或 [reg+8] 而另一个是 reg 的情况是链表操作的可能性较大。

出现 cmp jne 的原因:

InsertHeadList 中,检查的是 Flink 的 Blink 是否是 ListHead;InsertTailList 检查 Blink 的 Flink 是否是 ListhHead。

RemoveHeadList 中,检查 Entry->Blink 是否是 ListHead 以及 Flink->Blink 是否是 Entry;RemoveTailList 中,检查 Entry->Flink 是否是 ListHead 以及 Blink->Flink 是否是 Entry。

RemoveEntryList 中,检查 Flink->Blink 是否是 Entry 以及 Blink->Flink 是否是 Entry。

观察之后,可以发现检查的是:从与获取相反的方向能否验证获取的结果。以 RemoveHeadList 为例,它通过 ListHead->Flink 获取 Entry,然后通过 Entry->Flink 获取 Flink。所以检查的就是 Flink 的Blink 是否是 Entry 以及 Entry->Blink 是否是 ListHead。正常情况下这些检查应该总是满足的,但是在链表损坏时就可能不满足这样的条件。当链表损坏时,会进行``mov ecx,3``和``int 29h``。

查询发现 int 29h 的描述,[__fastfail](https://learn.microsoft.com/en-us/cpp/intrinsics/fastfail?view=msvc-170)。简单来说,这个函数会终结调用的进程,函数原型如下:

void __fastfail(Unsigned int code);

1
2
3

其中 code 是失败原因。在 x64 中,code 参数由 ecx 传递,因此这个函数在原因为 3 时就会编译为:

mov ecx, 3
int 29h

1
2
3

然后我们查看这个原因 3 是什么,文档中说明了这个原因在 winnt.h 或者 wdm.h 中,查看 wdm.h 可以发现:

#define FAST_FAIL_CORRUPT_LIST_ENTRY 3

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

原因是链表损坏,和我们的推测一致。

#### 9 --

先查文档,[AuxKlibQueryModuleInformation function (aux_klib.h)](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/aux_klib/nf-aux_klib-auxklibquerymoduleinformation),然后发现没这个符号,回头再说。

#### 10 --

KeInsertQueueDpc

KiRetireDpcList

KiExecuteDpc

KiExecuteAllDpcs

### 3.3.1

#### 1

> 阅读某些在线论坛后,你注意到有些人认为 PsCreateSystemThread 会在调用进程的上下文中创建线程,也就是说他们认为如果在 IOCTL 处理程序中调用 PsCreateSystemThread 的话,新线程会运行在请求服务的用户模式应用程序上下文中。写一个在 IOCTL 处理函数中调用 PsCreateSystemThread 的驱动程序来验证这一点。然后,使用非 NULL 的 ProcessHandle,确定其上下文是否有改变。

其实这个问题文档里已经说了。。[PsCreateSystemThread function (wdm.h) - Windows drivers | Microsoft Learn](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-pscreatesystemthread)

不过还是写了一下,内容在 github 仓库里。

在 Windbg 里可以看到输出(KdPrint):

3.3.1(1): DriverEntry
3.3.1(1): Run in the system process
3.3.1(1): Run in the current process
3.3.1(1): Process: FFFFBA0A21A840C0
3.3.1(1): Process: FFFFBA0A2C2F1080

1
2
3
4
5
6
7
8
9
10
11

可能是因为 PsCreateSystemThread 是异步的并且慢于 KdPrint,导致信息没有按顺序输出,不过也可以看出执行的线程属于两个不同的进程,使用``dt _EPROCESS <addr>``查看两个进程的 UniqueProcessId,可以发现第一个进程 PID 是 4,也就是系统进程,而第二个进程是 16d4。查看第二个进程的 PEB,确定确实是我们运行的 client 进程。或者使用``!process <addr>``直接可以看到映像名。

#### 2

> 尽可能多地阅读内核映像调用 PsCreateSystemThread 的部分,确定其中是否有传入 ProcessHandle 参数为非 NULL 值的情况。解释这些例程的目的,对尽可能多的函数重复这个练习。

ProcessHandle 非 NULL 的原因是需要访问创建进程的地址空间,而且是用户地址空间。

在 IDA 里加载 ntoskrnl.exe,然后找到 PsCreateSystemThread,x 一下就可以找到它的交叉引用,使用 IDAPython 可以筛选出调用时 r9 为 0 即 ProcessHandle 为 null 的情况(来自[matteomalvica.com](https://www.matteomalvica.com/blog/2021/02/11/practical-re-win-solutions-ch3-system-threads/)):

ps1 = idc.get_name_ea_simple(“PsCreateSystemThread”)
ps2 = idc.get_name_ea_simple(“PsCreateSystemThreadEx”)

def filterXrf(targetFunction):
for addr in CodeRefsTo(targetFunction, 0):
funcName = get_func_name(addr)
func = ida_funcs.get_func(addr)
funcStart = func.start_ea
funcEnd = func.end_ea
print(“Calling function: %s at 0x%x %s - function start 0x%x “ % (funcName,addr, idc.generate_disasm_line(addr, 0),funcStart))
cur_addr = addr

    while(cur_addr > funcStart):
        cur_asm = idc.generate_disasm_line(cur_addr, 0)
        if "xor     r9d, r9d" in cur_asm:
            break
        if "r9" in cur_asm:
            print("0x%x %s" % (cur_addr, idc.generate_disasm_line(cur_addr, 0)))
            break
        cur_addr = idc.prev_head(cur_addr)

filterXrf(ps1)
filterXrf(ps2)

1
2
3

下条件断点:

bp nt!PsCreateSystemThread “.if @r9 != 0x0 {.printf "Found NON-NULL call to PsCreateSystemThread with Process Handle value of 0x%p \n",r9} .else {gc}”

1
2
3
4
5
6
7
8
9

### 3.3.2

#### 1

> 解释如何确定 ExpWorkerThread 是负责 work item 出队的系统进程。提示:最简单的方法就是写一个驱动程序。

这里编程就是插入一个 WorkItem,在它执行的 Routine 里面查看调用者就可以。可以使用[Stack Trace](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/examining-the-stack-trace),不过我这里就直接触发一个断点(``DbgBreakPoint``),然后用 Windbg k 一下就可以了。调用栈:

5: kd> k

Child-SP RetAddr Call Site

00 ffffda827c0e6ad0 fffff8073de99645 3_3_2_1_Driver!WorkItemRoutine+0xe [C:\Users\admin\source\repos\PraticalReverseEngineering\3.3.2(1)\Driver.cpp @ 78]
01 ffffda827c0e6b00 fffff8073de52b65 nt!IopProcessWorkItem+0x135
02 ffffda827c0e6b70 fffff8073de71d25 nt!ExpWorkerThread+0x105
03 ffffda827c0e6c10 fffff8073e000628 nt!PspSystemThreadStartup+0x55
04 ffffda827c0e6c60 0000000000000000 nt!KiStartSystemThread+0x28

1
2
3
4
5
6
7
8
9
10
11

可以看到 ExpWorkerThread。

#### 2

> 研究 IoAllocateWorkItem、IoInitializeWorkItem、IoQueueWorkItem、IopQueueWorkItemProlog 和 ExQueueWorkItem,解释它们是如何工作的。

先看文档,[System Worker Threads](https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/system-worker-threads),根据文档,使用 Work Item 分为三步:分配空间和初始化一个``IO_WORKITEM``结构(此过程使用 IoAllocateWorkItem 或 IoInitializeWorkItem);指定 callback,将 WorkItem 入队(使用 IoQueueWorkItem);不需要 WorkItem 后进行释放(对应第一步使用 IoFreeWorkItem 或者 IoUninitializeWorkItem)。

- IoAllocateWorkItem,[文档](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-ioinitializeworkitem)

7: kd> uf Ioallocateworkitem
nt!IoAllocateWorkItem:
fffff8073df417a0 4053 push rbx fffff8073df417a2 4883ec20 sub rsp,20h
fffff8073df417a6 488bd9 mov rbx,rcx fffff8073df417a9 ba58000000 mov edx,58h
fffff8073df417ae b900020000 mov ecx,200h fffff8073df417b3 e89860ecff call nt!IopVerifierExAllocatePool (fffff8073de07850) fffff8073df417b8 4885c0 test rax,rax
fffff8073df417bb 7423 je nt!IoAllocateWorkItem+0x40 (fffff8073df417e0) Branch

nt!IoAllocateWorkItem+0x1d:
fffff8073df417bd 4883603800 and qword ptr [rax+38h],0 fffff8073df417c2 488d0d477df5ff lea rcx,[nt!IopProcessWorkItem (fffff8073de99510)] fffff8073df417c9 48895828 mov qword ptr [rax+28h],rbx
fffff8073df417cd c7404001000000 mov dword ptr [rax+40h],1 fffff8073df417d4 48832000 and qword ptr [rax],0
fffff8073df417d8 48894810 mov qword ptr [rax+10h],rcx fffff8073df417dc 48894018 mov qword ptr [rax+18h],rax

nt!IoAllocateWorkItem+0x40:
fffff8073df417e0 4883c420 add rsp,20h fffff8073df417e4 5b pop rbx
fffff8073df417e5 c3 ret

1
2
3

``nt!IopVerifierExAllocatePool`` 检查是否开启了验证(``nt!ViVerifierEnabled``),是则进行验证。随后调用``ExAllocatePoolWithTag``,在我的机器上,第一个参数``POOL_TYPE``200h(``NonPagedPoolNx``),第二个参数 ``NumberOfBytes``58h,(``sizeof(_IO_WORKITEM)``),第三个参数 ``Tag``20206F49h,是``Io<space><space>``。这样就在非分页池中分配了一个 ``_IO_WORKITEM``结构。

nt!_IO_WORKITEM +0x000 WorkItem : _WORK_QUEUE_ITEM +0x000 WorkItem.List ; _LIST_ENTRY ; 0 +0x010 WorkItem.WorkerRoutine; Ptr64 void; IopProcessWorkItem +0x018 WorkItem.Parameter ; Ptr64 void ; WorkItem +0x020 Routine : Ptr64 void +0x028 IoObject : Ptr64 Void ; DeviceObject +0x030 Context : Ptr64 Void ; 0 +0x038 WorkOnBehalfThread : Ptr64 _ETHREAD ; 0 +0x040 Type : Uint4B ; 1 +0x044 ActivityId : _GUID
1
2
3
4
5

随后设置结构中的各个字段,具体如注释。

- IoInitializeWorkItem,[文档](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-ioinitializeworkitem),调用该函数之前需要自己分配一个空间用于存放 WorkItem

nt!IoInitializeWorkItem: fffff807
3df778f0 4883ec38 sub rsp,38h
fffff8073df778f4 0fb701 movzx eax,word ptr [rcx] fffff8073df778f7 41ba03000000 mov r10d,3
fffff8073df778fd 66412bc2 sub ax,r10w fffff8073df77901 458d42fe lea r8d,[r10-2]
fffff8073df77905 66413bc0 cmp ax,r8w fffff8073df77909 0f87af7b1100 ja nt!IoInitializeWorkItem+0x117bce (fffff807`3e08f4be) Branch

nt!IoInitializeWorkItem+0x1f:
fffff8073df7790f 4883623800 and qword ptr [rdx+38h],0 fffff8073df77914 488d05f51bf2ff lea rax,[nt!IopProcessWorkItem (fffff8073de99510)] fffff8073df7791b 44894240 mov dword ptr [rdx+40h],r8d
fffff8073df7791f 48894a28 mov qword ptr [rdx+28h],rcx fffff8073df77923 48832200 and qword ptr [rdx],0
fffff8073df77927 48894210 mov qword ptr [rdx+10h],rax fffff8073df7792b 48895218 mov qword ptr [rdx+18h],rdx
fffff8073df7792f 4883c438 add rsp,38h fffff8073df77933 c3 ret

1
2
3
4
5

有点区别但不大,都是进行一些检查,然后设置 IO_WORKITEM 结构的成员。

- IoQueueWorkItem,[文档](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-ioqueueworkitem),将 WorkItem.Type 设置为 0,Context 存在 r8, QueueType 存在 rbx,然后调用 IopQueueWorkItemProlog。


nt!IoQueueWorkItem:
fffff8073df41950 4053 push rbx fffff8073df41952 4883ec20 sub rsp,20h
fffff8073df41956 83614000 and dword ptr [rcx+40h],0 fffff8073df4195a 418bd8 mov ebx,r8d
fffff8073df4195d 4d8bc1 mov r8,r9 fffff8073df41960 e8f784edff call nt!IopQueueWorkItemProlog (fffff8073de19e5c) fffff8073df41965 8bd3 mov edx,ebx
fffff8073df41967 488bc8 mov rcx,rax nt!IoQueueWorkItem+0x1a: fffff8073df4196a e839000000 call nt!ExQueueWorkItemFromIo (fffff8073df419a8) fffff8073df4196f 4883c420 add rsp,20h
fffff8073df41973 5b pop rbx fffff8073df41974 c3 ret
1
2
3

- IopQueueWorkItemProlog,增加 DeviceObject 的引用计数,把 Context 存到 WorkItem.ContextWorkerRoutine 存到 WorkItem.WorkerRoutine。除此之外就是一些检查。


nt!IopQueueWorkItemProlog:
fffff8073de19e5c 488bc4 mov rax,rsp fffff8073de19e5f 48895810 mov qword ptr [rax+10h],rbx
fffff8073de19e63 48896818 mov qword ptr [rax+18h],rbp fffff8073de19e67 48897020 mov qword ptr [rax+20h],rsi
fffff8073de19e6b 57 push rdi fffff8073de19e6c 4883ec20 sub rsp,20h
fffff8073de19e70 83600800 and dword ptr [rax+8],0 fffff8073de19e74 498bf0 mov rsi,r8
fffff8073de19e77 488bea mov rbp,rdx fffff8073de19e7a 488bd9 mov rbx,rcx
fffff8073de19e7d e896db0700 call nt!IopIsActivityTracingEnabled (fffff8073de97a18)
fffff8073de19e82 84c0 test al,al fffff8073de19e84 0f852c712000 jne nt!IopQueueWorkItemProlog+0x20715a (fffff807`3e020fb6) Branch

nt!IopQueueWorkItemProlog+0x2e:
fffff8073de19e8a 0f57c0 xorps xmm0,xmm0 fffff8073de19e8d 0f114344 movups xmmword ptr [rbx+44h],xmm0

nt!IopQueueWorkItemProlog+0x35:
fffff8073de19e91 658b0425ac320000 mov eax,dword ptr gs:[32ACh] fffff8073de19e99 a901000100 test eax,10001h
fffff8073de19e9e 742f je nt!IopQueueWorkItemProlog+0x73 (fffff8073de19ecf) Branch

nt!IopQueueWorkItemProlog+0x44:
fffff8073de19ea0 488b4b28 mov rcx,qword ptr [rbx+28h] fffff8073de19ea4 ba44666c74 mov edx,746C6644h
fffff8073de19ea9 e8c2f0ffff call nt!ObfReferenceObjectWithTag (fffff8073de18f70)
fffff8073de19eae 48896b20 mov qword ptr [rbx+20h],rbp fffff8073de19eb2 488bc3 mov rax,rbx
fffff8073de19eb5 488b6c2440 mov rbp,qword ptr [rsp+40h] fffff8073de19eba 48897330 mov qword ptr [rbx+30h],rsi
fffff8073de19ebe 488b5c2438 mov rbx,qword ptr [rsp+38h] fffff8073de19ec3 488b742448 mov rsi,qword ptr [rsp+48h]
fffff8073de19ec8 4883c420 add rsp,20h fffff8073de19ecc 5f pop rdi
fffff8073de19ecd c3 ret

1
2
3

- ExQueueWorkItem,[文档](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-exqueueworkitem),与上面函数不同,它不特定于某个 DevcieObject。

nt!ExQueueWorkItem: fffff8073de54130 48895c2408 mov qword ptr [rsp+8],rbx
fffff8073de54135 57 push rdi fffff8073de54136 4883ec30 sub rsp,30h
fffff8073de5413a 4863da movsxd rbx,edx fffff8073de5413d 488bf9 mov rdi,rcx
fffff8073de54140 8bd3 mov edx,ebx fffff8073de54142 e861000000 call nt!ExpValidateWorkItem (fffff8073de541a8) fffff8073de54147 8bcb mov ecx,ebx
nt!ExQueueWorkItem+0x19:
fffff8073de54149 e83a000000 call nt!ExpTypeToPriority (fffff8073de54188)
fffff8073de5414e 4c8b050b86aa00 mov r8,qword ptr [nt!PspSystemPartition (fffff8073e8fc760)]
fffff8073de54155 4183c9ff or r9d,0FFFFFFFFh fffff8073de54159 8364242000 and dword ptr [rsp+20h],0
fffff8073de5415e 488bd7 mov rdx,rdi fffff8073de54161 498b4810 mov rcx,qword ptr [r8+10h]
fffff8073de54165 448bc0 mov r8d,eax fffff8073de54168 e813dfffff call nt!ExpQueueWorkItem (fffff8073de52080) nt!ExQueueWorkItem+0x3d: fffff8073de5416d 84c0 test al,al
fffff8073de5416f 0f845dcb1d00 je nt!ExQueueWorkItem+0x1dcba2 (fffff8073e030cd2)
fffff8073de54175 488b5c2440 mov rbx,qword ptr [rsp+40h] fffff8073de5417a 4883c430 add rsp,30h
fffff8073de5417e 5f pop rdi fffff8073de5417f c3 ret
1
2
3
4
5

可以看到 ExpQueueWorkItem 接受的参数,rcx 是一个系统中的位置,应该是 WorkItem 的队列,rdx 是 WorkItem。据此猜测 ExpQueueWorkItem 将 WorkItem 插入队列。着急下班于是就结束了。

然而第二天,我去验证书上所说的内容,尝试通过 (_ENODE *)Prcb->ParentNote 找到这个队列(PspSystemPartition),发现并找不到。一番查找后,发现了两篇文章([[原创\]win10 1909逆向(win10内存分区浅析)](https://bbs.pediy.com/thread-266152.htm)、[Work Items & System Worker Threads](https://www.matteomalvica.com/blog/2021/03/10/practical-re-win-solutions-ch3-work-items/))都介绍了 SystemPartition,这里就不献丑了。简单来说,从 Windows 10 引入内存分区开始,这个 Queue 就不再保存在 ENODE 中,而是保存在系统分区中。


dx -r0 @$queue = ((nt!_EX_PARTITION*)((nt!_EPARTITION*)&nt!PspSystemPartition)->ExPartition)->WorkQueues[0][1],d


#### 3

> Work item 和系统线程在功能上几乎是相同的,解释为什么 DPC 常将 work item 入队来处理请求,而从不调用 PsCreateSystemThread

work item 相对来说是比较轻量级的,PspCreateSystemThread 开销比较大,不适合在 DPC 的 DISPATCH_LEVEL 调用。

#### 4

> 写一个驱动程序以美剧出系统中所有的 work item,并解释这个过程中你需要克服的难点。

咕咕咕

### 3.3.3 -

#### 1 未完成

> 编写使用内核模式和用户模式 APC 的驱动。

KeIntializeApc 和 KeInsertQueueApc 包含在 ntoskrnl 中,如果使用 C++,需要在这两个函数前指定``extern "C"``。

APC 参考文章:

- [Inside NT's Asynchronous Procedure Call | Dr Dobb's (drdobbs.com)](https://www.drdobbs.com/inside-nts-asynchronous-procedure-call/184416590)

- [小Win,点一份APC(Apc机制详解)(一) | Anhkgg'Lab ](https://anhkgg.com/win-apc-analyze1/)
- [APC Series: User APC Internals · Low Level Pleasure (repnz.github.io)](https://repnz.github.io/posts/apc/kernel-user-apc-api/)

其中 Low Level Pleasure 这篇文章提到了 User APC 也分 Special 和 Normal,具体没有说明。

实现见工程。可以发现,KernelRoutine 总是运行在 APC_LEVEL,而 NormalRoutine(如果有)则运行在 PASSIVE_LEVEL



#### 2

> 编写一个驱动程序以美剧一个进程中所有线程上所有的用户模式和内核模式 APC。提示:执行枚举是要考虑到 IRQL 级别。



### 3.3.4



### x64后门程序
作者

lll

发布于

2022-07-12

更新于

2022-10-16

许可协议