[原创]X86内核笔记

1.API初识

API(应用程序编程接口)是微软为开发者提供的一套函数接口,可以用于与系统进行交互、实现一些复杂的功能等。

我们日常在3环写的API如:ReadMemory、CloseHandle、OpenProcess等。其真正的功能实现全部在驱动层,3环中我们使用的只是一个门票,用于通知驱动层我们要实现的功能。而这些API函数从3环的校验代码进入到0环的功能代码的步骤,就称为系统调用。

一些常见的动态链接库如下:

1
2
3
4
Kernel32.dll : 最核心的功能模块,如内存管理,进程线程相关函数等。
User32.dll : 用户界面相关的函数。
GDI32.dll : 图形设备接口,用于绘制和显示文本等。
Ntdll.dll : 大多数API都会通过这个dll进入0环。

2.了解系统调用好处

于防来说,了解系统调用可以更好的了解程序流程。对于一些恶意样本,攻击者会将API调用改为直接进入0环的方式,这样对于一些3环的监控工具则无法监控该样本的行为,一些3环的APIHOOK也将失效。同样的,IDA一类的反汇编工具也无法直接查看样本使用了哪些API函数。

于攻来说,了解系统调用可以让你真正知道API函数执行的本质,无论是自实现系统调用、驱动层HOOK或是以服务号调用API,都可以让你的攻击手段很难被安全从业者察觉、分析。而HOOK住驱动层的功能函数,也可以达到另类的驱动通信效果。

由于现在的系统带有PG保护,使得系统调用这个技术点无法被直接利用,现已作为基础知识慢慢的与其他技术相融合。

3.ReadProcessMemory实战分析(3环)

在MSDN上搜索该函数,发现其所属模块为kernel32.dll,但是当你去追kernel32里的流程,你会发现最终都是执行了一个return 0。这是历史遗留问题,所以不能盲目相信MSDN。

KernelBase->ntdll

在WIN7镜像中,随便找个程序拖到OD里,Ctrl+G定位至ReadProcessMemory函数。发现该函数已经隶属于KernelBase模块了。且其内部没有什么有用的代码,只调用了ntdll的NtReadVirtualMemory函数。该函数是KernelBase的导入函数。

使用IDA打开ntdll,在导出函数选项卡中搜索NtReadVirtualMemory。

跟过去看一下该函数的实现。发现函数内部仅调用了[7FFE0300]处的函数,同时为eax赋值。

总结

至此,3环绝大部分告一段落。可以发现ReadProcessMemory函数的3环执行流程就是跳来跳去,然后执行一个call [7FFE0300]。接下来我们需要探求7FFE0300里面存的是什么。

4.实战分析-3环进入0环

_KUSER_SHARED_DATA

在继续分析之前,我们需要补充一个知识点:_KUSER_SHARED_DATA。这是一个3环与0环共享的结构体。

在3环,它的地址为7ffe0000,具备只读权限。在0环,它的地址为ffdf0000,具备读写权限。这两个地址指向同一个物理页,只是访问权限不同。该结构会在操作系统启动时由操作系统自己填充。

结构体信息如下:

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
//0x5f0 bytes (sizeof)
struct _KUSER_SHARED_DATA
{
    ULONG TickCountLowDeprecated;                                           //0x0
    ULONG TickCountMultiplier;                                              //0x4
    volatile struct _KSYSTEM_TIME InterruptTime;                            //0x8
    volatile struct _KSYSTEM_TIME SystemTime;                               //0x14
    volatile struct _KSYSTEM_TIME TimeZoneBias;                             //0x20
    USHORT ImageNumberLow;                                                  //0x2c
    USHORT ImageNumberHigh;                                                 //0x2e
    WCHAR NtSystemRoot[260];                                                //0x30
    ULONG MaxStackTraceDepth;                                               //0x238
    ULONG CryptoExponent;                                                   //0x23c
    ULONG TimeZoneId;                                                       //0x240
    ULONG LargePageMinimum;                                                 //0x244
    ULONG Reserved2[7];                                                     //0x248
    enum _NT_PRODUCT_TYPE NtProductType;                                    //0x264
    UCHAR ProductTypeIsValid;                                               //0x268
    ULONG NtMajorVersion;                                                   //0x26c
    ULONG NtMinorVersion;                                                   //0x270
    UCHAR ProcessorFeatures[64];                                            //0x274
    ULONG Reserved1;                                                        //0x2b4
    ULONG Reserved3;                                                        //0x2b8
    volatile ULONG TimeSlip;                                                //0x2bc
    enum _ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;            //0x2c0
    ULONG AltArchitecturePad[1];                                            //0x2c4
    union _LARGE_INTEGER SystemExpirationDate;                              //0x2c8
    ULONG SuiteMask;                                                        //0x2d0
    UCHAR KdDebuggerEnabled;                                                //0x2d4
    UCHAR NXSupportPolicy;                                                  //0x2d5
    volatile ULONG ActiveConsoleId;                                         //0x2d8
    volatile ULONG DismountCount;                                           //0x2dc
    ULONG ComPlusPackage;                                                   //0x2e0
    ULONG LastSystemRITEventTickCount;                                      //0x2e4
    ULONG NumberOfPhysicalPages;                                            //0x2e8
    UCHAR SafeBootMode;                                                     //0x2ec
    union
    {
        UCHAR TscQpcData;                                                   //0x2ed
        struct
        {
            UCHAR TscQpcEnabled:1;                                          //0x2ed
            UCHAR TscQpcSpareFlag:1;                                        //0x2ed
            UCHAR TscQpcShift:6;                                            //0x2ed
        };
    };
    UCHAR TscQpcPad[2];                                                     //0x2ee
    union
    {
        ULONG SharedDataFlags;                                              //0x2f0
        struct
        {
            ULONG DbgErrorPortPresent:1;                                    //0x2f0
            ULONG DbgElevationEnabled:1;                                    //0x2f0
            ULONG DbgVirtEnabled:1;                                         //0x2f0
            ULONG DbgInstallerDetectEnabled:1;                              //0x2f0
            ULONG DbgSystemDllRelocated:1;                                  //0x2f0
            ULONG DbgDynProcessorEnabled:1;                                 //0x2f0
            ULONG DbgSEHValidationEnabled:1;                                //0x2f0
            ULONG SpareBits:25;                                             //0x2f0
        };
    };
    ULONG DataFlagsPad[1];                                                  //0x2f4
    ULONGLONG TestRetInstruction;                                           //0x2f8
    ULONG SystemCall;                                                       //0x300
    ULONG SystemCallReturn;                                                 //0x304
    ULONGLONG SystemCallPad[3];                                             //0x308
    union
    {
        volatile struct _KSYSTEM_TIME TickCount;                            //0x320
        volatile ULONGLONG TickCountQuad;                                   //0x320
        ULONG ReservedTickCountOverlay[3];                                  //0x320
    };
    ULONG TickCountPad[1];                                                  //0x32c
    ULONG Cookie;                                                           //0x330
    ULONG CookiePad[1];                                                     //0x334
    LONGLONG ConsoleSessionForegroundProcessId;                             //0x338
    ULONG Wow64SharedInformation[16];                                       //0x340
    USHORT UserModeGlobalLogger[16];                                        //0x380
    ULONG ImageFileExecutionOptions;                                        //0x3a0
    ULONG LangGenerationCount;                                              //0x3a4
    ULONGLONG Reserved5;                                                    //0x3a8
    volatile ULONGLONG InterruptTimeBias;                                   //0x3b0
    volatile ULONGLONG TscQpcBias;                                          //0x3b8
    volatile ULONG ActiveProcessorCount;                                    //0x3c0
    volatile USHORT ActiveGroupCount;                                       //0x3c4
    USHORT Reserved4;                                                       //0x3c6
    volatile ULONG AitSamplingValue;                                        //0x3c8
    volatile ULONG AppCompatFlag;                                           //0x3cc
    ULONGLONG SystemDllNativeRelocation;                                    //0x3d0
    ULONG SystemDllWowRelocation;                                           //0x3d8
    ULONG XStatePad[1];                                                     //0x3dc
    struct _XSTATE_CONFIGURATION XState;                                    //0x3e0
};

其中偏移0x300处的成员为SystemCall,该成员指明了当发生系统调用时,3环进入0环走哪个函数,该成员就存储对应函数的地址

由于现在的处理器均支持快速调用(sysenter指令),而旧处理器不支持,所以此处存储的函数地址有两种情况。后文仅演示快速调用。(中断门(0x2E)进0环已经在历史的长河中被替代了,有兴趣的可以了解下。)

为了查看7FFE0300的值,我们需要借助windbg动态调试。

在windbg中输入 !process 0 0遍历所有进程,随便附加其中一个即可。

输入 dt _KUSER_SHARED_DATA 7FFE0000查看该结构体的成员信息。可以发现偏移0x300处存储的值为0x77a470b0。

使用命令 u 77a470b0 查看该地址的函数。可以看到windbg帮我们识别出来是ntdll模块中的KiFastSystemCall函数。回到IDA中,定位至该函数,观察函数执行流程。

KiFastSystemCall

可以发现该函数只有两行代码:mov edx,esp sysenter。 sysenter将会进入0环。

sysenter指令

在保护模式章节中,我们知道3环进0环必备的几个条件:

  • 权限发生切换时,需要新的CS
  • 与CS保持权限一致,也需要新的SS
  • 0环的堆栈:ESP
  • 0环代码从哪执行:EIP

在旧CPU中,使用中断门(0x2E)进行系统调用,需要查询TSS来获取这几个寄存器的值。内存查询是很慢的。

而sysenter指令将会直接从MSR寄存器中读取并写入至CS、SS、EIP、ESP中,速度很快,因此称为快速调用。

MSR寄存器

MSR寄存器很大,存了很多的数据。

在偏移0x174处,存储着系统调用时0环的CS。

在偏移0x175处,存储着系统调用时0环的ESP。

在偏移0x176处,存储着系统调用时0环的EIP。

SS的值通过CS+8得到(具体原因参考保护模式章节,CS与SS的段描述符是相邻的)。

通过指令RDMSR/WRMSR可以对MSR寄存器进行读写。

在windbg中查看CS ESP EIP的值:

在windbg中输入命令 u 83e420c0查看这个函数

可以得知当我们在3环调用sysenter指令时,将会执行内核模块(ntoskrnl、ntkrnlpa)中的KiFastCallEntry函数

总结

当发生系统调用时,若CPU支持快速调用,则走KiFastSystemCall函数,内部执行sysenter指令。并在0环执行KiFastCallEntry函数。同时携带了edx(3环堆栈)、eax(系统调用号)

5.前置知识-内核结构体

以下结构体均在内核空间,3环无法直接访问

TrapFrame

在进入0环时,该结构体用于保存3环寄存器。由windows进行维护。

结构体成员:

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
//0x8c bytes (sizeof)
struct _KTRAP_FRAME
{
    ULONG DbgEbp;                                                           //0x0
    ULONG DbgEip;                                                           //0x4
    ULONG DbgArgMark;                                                       //0x8
    ULONG DbgArgPointer;                                                    //0xc
    USHORT TempSegCs;                                                       //0x10
    UCHAR Logging;                                                          //0x12
    UCHAR Reserved;                                                         //0x13
    ULONG TempEsp;                                                          //0x14
    ULONG Dr0;                                                              //0x18
    ULONG Dr1;                                                              //0x1c
    ULONG Dr2;                                                              //0x20
    ULONG Dr3;                                                              //0x24
    ULONG Dr6;                                                              //0x28
    ULONG Dr7;                                                              //0x2c
    ULONG SegGs;                                                            //0x30
    ULONG SegEs;                                                            //0x34
    ULONG SegDs;                                                            //0x38
    ULONG Edx;                                                              //0x3c
    ULONG Ecx;                                                              //0x40
    ULONG Eax;                                                              //0x44
    ULONG PreviousPreviousMode;                                             //0x48
    struct _EXCEPTION_REGISTRATION_RECORD* ExceptionList;                   //0x4c
    ULONG SegFs;                                                            //0x50
    ULONG Edi;                                                              //0x54
    ULONG Esi;                                                              //0x58
    ULONG Ebx;                                                              //0x5c
    ULONG Ebp;                                                              //0x60
    ULONG ErrCode;                                                          //0x64
    ULONG Eip;                                                              //0x68
    ULONG SegCs;                                                            //0x6c
    ULONG EFlags;                                                           //0x70
    ULONG HardwareEsp;                                                      //0x74
    ULONG HardwareSegSs;                                                    //0x78
    ULONG V86Es;                                                            //0x7c
    ULONG V86Ds;                                                            //0x80
    ULONG V86Fs;                                                            //0x84
    ULONG V86Gs;                                                            //0x88
};

KPCR

在3环时,FS指向TEB结构。在0环时,FS指向KPCR结构。该结构体用于描述对应的CPU的状态。(一核对应一个KPCR)

windbg中输入 dd KeNumberProcessor 查看核数

windbg中输入 dd KiProcessorBlock LXXX 查看每个核的KPCR结构地址。

结构体成员:

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
//0x3748 bytes (sizeof)
struct _KPCR
{
    union
    {
        struct _NT_TIB NtTib;                                               //0x0
        struct
        {
            struct _EXCEPTION_REGISTRATION_RECORD* Used_ExceptionList;      //0x0
            VOID* Used_StackBase;                                           //0x4
            VOID* Spare2;                                                   //0x8
            VOID* TssCopy;                                                  //0xc
            ULONG ContextSwitches;                                          //0x10
            ULONG SetMemberCopy;                                            //0x14
            VOID* Used_Self;                                                //0x18
        };
    };
    struct _KPCR* SelfPcr;                                                  //0x1c
    struct _KPRCB* Prcb;                                                    //0x20
    UCHAR Irql;                                                             //0x24
    ULONG IRR;                                                              //0x28
    ULONG IrrActive;                                                        //0x2c
    ULONG IDR;                                                              //0x30
    VOID* KdVersionBlock;                                                   //0x34
    struct _KIDTENTRY* IDT;                                                 //0x38
    struct _KGDTENTRY* GDT;                                                 //0x3c
    struct _KTSS* TSS;                                                      //0x40
    USHORT MajorVersion;                                                    //0x44
    USHORT MinorVersion;                                                    //0x46
    ULONG SetMember;                                                        //0x48
    ULONG StallScaleFactor;                                                 //0x4c
    UCHAR SpareUnused;                                                      //0x50
    UCHAR Number;                                                           //0x51
    UCHAR Spare0;                                                           //0x52
    UCHAR SecondLevelCacheAssociativity;                                    //0x53
    ULONG VdmAlert;                                                         //0x54
    ULONG KernelReserved[14];                                               //0x58
    ULONG SecondLevelCacheSize;                                             //0x90
    ULONG HalReserved[16];                                                  //0x94
    ULONG InterruptMode;                                                    //0xd4
    UCHAR Spare1;                                                           //0xd8
    ULONG KernelReserved2[17];                                              //0xdc
    struct _KPRCB PrcbData;                                                 //0x120
};

KPRCB

结构体成员:

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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
//0x3628 bytes (sizeof)
struct _KPRCB
{
    USHORT MinorVersion;                                                    //0x0
    USHORT MajorVersion;                                                    //0x2
    struct _KTHREAD* CurrentThread;                                         //0x4
    struct _KTHREAD* NextThread;                                            //0x8
    struct _KTHREAD* IdleThread;                                            //0xc
    UCHAR LegacyNumber;                                                     //0x10
    UCHAR NestingLevel;                                                     //0x11
    USHORT BuildType;                                                       //0x12
    CHAR CpuType;                                                           //0x14
    CHAR CpuID;                                                             //0x15
    union
    {
        USHORT CpuStep;                                                     //0x16
        struct
        {
            UCHAR CpuStepping;                                              //0x16
            UCHAR CpuModel;                                                 //0x17
        };
    };
    struct _KPROCESSOR_STATE ProcessorState;                                //0x18
    ULONG KernelReserved[16];                                               //0x338
    ULONG HalReserved[16];                                                  //0x378
    ULONG CFlushSize;                                                       //0x3b8
    UCHAR CoresPerPhysicalProcessor;                                        //0x3bc
    UCHAR LogicalProcessorsPerCore;                                         //0x3bd
    UCHAR PrcbPad0[2];                                                      //0x3be
    ULONG MHz;                                                              //0x3c0
    UCHAR CpuVendor;                                                        //0x3c4
    UCHAR GroupIndex;                                                       //0x3c5
    USHORT Group;                                                           //0x3c6
    ULONG GroupSetMember;                                                   //0x3c8
    ULONG Number;                                                           //0x3cc
    UCHAR PrcbPad1[72];                                                     //0x3d0
    struct _KSPIN_LOCK_QUEUE LockQueue[17];                                 //0x418
    struct _KTHREAD* NpxThread;                                             //0x4a0
    ULONG InterruptCount;                                                   //0x4a4
    ULONG KernelTime;                                                       //0x4a8
    ULONG UserTime;                                                         //0x4ac
    ULONG DpcTime;                                                          //0x4b0
    ULONG DpcTimeCount;                                                     //0x4b4
    ULONG InterruptTime;                                                    //0x4b8
    ULONG AdjustDpcThreshold;                                               //0x4bc
    ULONG PageColor;                                                        //0x4c0
    UCHAR DebuggerSavedIRQL;                                                //0x4c4
    UCHAR NodeColor;                                                        //0x4c5
    UCHAR PrcbPad20[2];                                                     //0x4c6
    ULONG NodeShiftedColor;                                                 //0x4c8
    struct _KNODE* ParentNode;                                              //0x4cc
    ULONG SecondaryColorMask;                                               //0x4d0
    ULONG DpcTimeLimit;                                                     //0x4d4
    ULONG PrcbPad21[2];                                                     //0x4d8
    ULONG CcFastReadNoWait;                                                 //0x4e0
    ULONG CcFastReadWait;                                                   //0x4e4
    ULONG CcFastReadNotPossible;                                            //0x4e8
    ULONG CcCopyReadNoWait;                                                 //0x4ec
    ULONG CcCopyReadWait;                                                   //0x4f0
    ULONG CcCopyReadNoWaitMiss;                                             //0x4f4
    volatile LONG MmSpinLockOrdering;                                       //0x4f8
    volatile LONG IoReadOperationCount;                                     //0x4fc
    volatile LONG IoWriteOperationCount;                                    //0x500
    volatile LONG IoOtherOperationCount;                                    //0x504
    union _LARGE_INTEGER IoReadTransferCount;                               //0x508
    union _LARGE_INTEGER IoWriteTransferCount;                              //0x510
    union _LARGE_INTEGER IoOtherTransferCount;                              //0x518
    ULONG CcFastMdlReadNoWait;                                              //0x520
    ULONG CcFastMdlReadWait;                                                //0x524
    ULONG CcFastMdlReadNotPossible;                                         //0x528
    ULONG CcMapDataNoWait;                                                  //0x52c
    ULONG CcMapDataWait;                                                    //0x530
    ULONG CcPinMappedDataCount;                                             //0x534
    ULONG CcPinReadNoWait;                                                  //0x538
    ULONG CcPinReadWait;                                                    //0x53c
    ULONG CcMdlReadNoWait;                                                  //0x540
    ULONG CcMdlReadWait;                                                    //0x544
    ULONG CcLazyWriteHotSpots;                                              //0x548
    ULONG CcLazyWriteIos;                                                   //0x54c
    ULONG CcLazyWritePages;                                                 //0x550
    ULONG CcDataFlushes;                                                    //0x554
    ULONG CcDataPages;                                                      //0x558
    ULONG CcLostDelayedWrites;                                              //0x55c
    ULONG CcFastReadResourceMiss;                                           //0x560
    ULONG CcCopyReadWaitMiss;                                               //0x564
    ULONG CcFastMdlReadResourceMiss;                                        //0x568
    ULONG CcMapDataNoWaitMiss;                                              //0x56c
    ULONG CcMapDataWaitMiss;                                                //0x570
    ULONG CcPinReadNoWaitMiss;                                              //0x574
    ULONG CcPinReadWaitMiss;                                                //0x578
    ULONG CcMdlReadNoWaitMiss;                                              //0x57c
    ULONG CcMdlReadWaitMiss;                                                //0x580
    ULONG CcReadAheadIos;                                                   //0x584
    ULONG KeAlignmentFixupCount;                                            //0x588
    ULONG KeExceptionDispatchCount;                                         //0x58c
    ULONG KeSystemCalls;                                                    //0x590
    ULONG AvailableTime;                                                    //0x594
    ULONG PrcbPad22[2];                                                     //0x598
    struct _PP_LOOKASIDE_LIST PPLookasideList[16];                          //0x5a0
    struct _GENERAL_LOOKASIDE_POOL PPNPagedLookasideList[32];               //0x620
    struct _GENERAL_LOOKASIDE_POOL PPPagedLookasideList[32];                //0xf20
    volatile ULONG PacketBarrier;                                           //0x1820
    volatile LONG ReverseStall;                                             //0x1824
    VOID* IpiFrame;                                                         //0x1828
    UCHAR PrcbPad3[52];                                                     //0x182c
    VOID* volatile CurrentPacket[3];                                        //0x1860
    volatile ULONG TargetSet;                                               //0x186c
    VOID (* volatileWorkerRoutine)(VOID* arg1, VOID* arg2, VOID* arg3, VOID* arg4); //0x1870
    volatile ULONG IpiFrozen;                                               //0x1874
    UCHAR PrcbPad4[40];                                                     //0x1878
    volatile ULONG RequestSummary;                                          //0x18a0
    struct _KPRCB* volatile SignalDone;                                     //0x18a4
    UCHAR PrcbPad50[56];                                                    //0x18a8
    struct _KDPC_DATA DpcData[2];                                           //0x18e0
    VOID* DpcStack;                                                         //0x1908
    LONG MaximumDpcQueueDepth;                                              //0x190c
    ULONG DpcRequestRate;                                                   //0x1910
    ULONG MinimumDpcRate;                                                   //0x1914
    ULONG DpcLastCount;                                                     //0x1918
    ULONG PrcbLock;                                                         //0x191c
    struct _KGATE DpcGate;                                                  //0x1920
    UCHAR ThreadDpcEnable;                                                  //0x1930
    volatile UCHAR QuantumEnd;                                              //0x1931
    volatile UCHAR DpcRoutineActive;                                        //0x1932
    volatile UCHAR IdleSchedule;                                            //0x1933
    union
    {
        volatile LONG DpcRequestSummary;                                    //0x1934
        SHORT DpcRequestSlot[2];                                            //0x1934
        struct
        {
            SHORT NormalDpcState;                                           //0x1934
            union
            {
                volatile USHORT DpcThreadActive:1;                          //0x1936
                SHORT ThreadDpcState;                                       //0x1936
            };
        };
    };
    volatile ULONG TimerHand;                                               //0x1938
    ULONG LastTick;                                                         //0x193c
    LONG MasterOffset;                                                      //0x1940
    ULONG PrcbPad41[2];                                                     //0x1944
    ULONG PeriodicCount;                                                    //0x194c
    ULONG PeriodicBias;                                                     //0x1950
    ULONGLONG TickOffset;                                                   //0x1958
    struct _KTIMER_TABLE TimerTable;                                        //0x1960
    struct _KDPC CallDpc;                                                   //0x31a0
    LONG ClockKeepAlive;                                                    //0x31c0
    UCHAR ClockCheckSlot;                                                   //0x31c4
    UCHAR ClockPollCycle;                                                   //0x31c5
    UCHAR PrcbPad6[2];                                                      //0x31c6
    LONG DpcWatchdogPeriod;                                                 //0x31c8
    LONG DpcWatchdogCount;                                                  //0x31cc
    LONG ThreadWatchdogPeriod;                                              //0x31d0
    LONG ThreadWatchdogCount;                                               //0x31d4
    volatile LONG KeSpinLockOrdering;                                       //0x31d8
    ULONG PrcbPad70[1];                                                     //0x31dc
    struct _LIST_ENTRY WaitListHead;                                        //0x31e0
    ULONG WaitLock;                                                         //0x31e8
    ULONG ReadySummary;                                                     //0x31ec
    ULONG QueueIndex;                                                       //0x31f0
    struct _SINGLE_LIST_ENTRY DeferredReadyListHead;                        //0x31f4
    ULONGLONG StartCycles;                                                  //0x31f8
    volatile ULONGLONG CycleTime;                                           //0x3200
    volatile ULONG HighCycleTime;                                           //0x3208
    ULONG PrcbPad71;                                                        //0x320c
    ULONGLONG PrcbPad72[2];                                                 //0x3210
    struct _LIST_ENTRY DispatcherReadyListHead[32];                         //0x3220
    VOID* ChainedInterruptList;                                             //0x3320
    LONG LookasideIrpFloat;                                                 //0x3324
    volatile LONG MmPageFaultCount;                                         //0x3328
    volatile LONG MmCopyOnWriteCount;                                       //0x332c
    volatile LONG MmTransitionCount;                                        //0x3330
    volatile LONG MmCacheTransitionCount;                                   //0x3334
    volatile LONG MmDemandZeroCount;                                        //0x3338
    volatile LONG MmPageReadCount;                                          //0x333c
    volatile LONG MmPageReadIoCount;                                        //0x3340
    volatile LONG MmCacheReadCount;                                         //0x3344
    volatile LONG MmCacheIoCount;                                           //0x3348
    volatile LONG MmDirtyPagesWriteCount;                                   //0x334c
    volatile LONG MmDirtyWriteIoCount;                                      //0x3350
    volatile LONG MmMappedPagesWriteCount;                                  //0x3354
    volatile LONG MmMappedWriteIoCount;                                     //0x3358
    volatile ULONG CachedCommit;                                            //0x335c
    volatile ULONG CachedResidentAvailable;                                 //0x3360
    VOID* HyperPte;                                                         //0x3364
    UCHAR PrcbPad8[4];                                                      //0x3368
    UCHAR VendorString[13];                                                 //0x336c
    UCHAR InitialApicId;                                                    //0x3379
    UCHAR LogicalProcessorsPerPhysicalProcessor;                            //0x337a
    UCHAR PrcbPad9[5];                                                      //0x337b
    ULONG FeatureBits;                                                      //0x3380
    union _LARGE_INTEGER UpdateSignature;                                   //0x3388
    volatile ULONGLONG IsrTime;                                             //0x3390
    ULONGLONG RuntimeAccumulation;                                          //0x3398
    struct _PROCESSOR_POWER_STATE PowerState;                               //0x33a0
    struct _KDPC DpcWatchdogDpc;                                            //0x3468
    struct _KTIMER DpcWatchdogTimer;                                        //0x3488
    VOID* WheaInfo;                                                         //0x34b0
    VOID* EtwSupport;                                                       //0x34b4
    union _SLIST_HEADER InterruptObjectPool;                                //0x34b8
    union _SLIST_HEADER HypercallPageList;                                  //0x34c0
    VOID* HypercallPageVirtual;                                             //0x34c8
    VOID* VirtualApicAssist;                                                //0x34cc
    ULONGLONG* StatisticsPage;                                              //0x34d0
    VOID* RateControl;                                                      //0x34d4
    struct _CACHE_DESCRIPTOR Cache[5];                                      //0x34d8
    ULONG CacheCount;                                                       //0x3514
    ULONG CacheProcessorMask[5];                                            //0x3518
    struct _KAFFINITY_EX PackageProcessorSet;                               //0x352c
    ULONG PrcbPad91[1];                                                     //0x3538
    ULONG CoreProcessorSet;                                                 //0x353c
    struct _KDPC TimerExpirationDpc;                                        //0x3540
    ULONG SpinLockAcquireCount;                                             //0x3560
    ULONG SpinLockContentionCount;                                          //0x3564
    ULONG SpinLockSpinCount;                                                //0x3568
    ULONG IpiSendRequestBroadcastCount;                                     //0x356c
    ULONG IpiSendRequestRoutineCount;                                       //0x3570
    ULONG IpiSendSoftwareInterruptCount;                                    //0x3574
    ULONG ExInitializeResourceCount;                                        //0x3578
    ULONG ExReInitializeResourceCount;                                      //0x357c
    ULONG ExDeleteResourceCount;                                            //0x3580
    ULONG ExecutiveResourceAcquiresCount;                                   //0x3584
    ULONG ExecutiveResourceContentionsCount;                                //0x3588
    ULONG ExecutiveResourceReleaseExclusiveCount;                           //0x358c
    ULONG ExecutiveResourceReleaseSharedCount;                              //0x3590
    ULONG ExecutiveResourceConvertsCount;                                   //0x3594
    ULONG ExAcqResExclusiveAttempts;                                        //0x3598
    ULONG ExAcqResExclusiveAcquiresExclusive;                               //0x359c
    ULONG ExAcqResExclusiveAcquiresExclusiveRecursive;                      //0x35a0
    ULONG ExAcqResExclusiveWaits;                                           //0x35a4
    ULONG ExAcqResExclusiveNotAcquires;                                     //0x35a8
    ULONG ExAcqResSharedAttempts;                                           //0x35ac
    ULONG ExAcqResSharedAcquiresExclusive;                                  //0x35b0
    ULONG ExAcqResSharedAcquiresShared;                                     //0x35b4
    ULONG ExAcqResSharedAcquiresSharedRecursive;                            //0x35b8
    ULONG ExAcqResSharedWaits;                                              //0x35bc
    ULONG ExAcqResSharedNotAcquires;                                        //0x35c0
    ULONG ExAcqResSharedStarveExclusiveAttempts;                            //0x35c4
    ULONG ExAcqResSharedStarveExclusiveAcquiresExclusive;                   //0x35c8
    ULONG ExAcqResSharedStarveExclusiveAcquiresShared;                      //0x35cc
    ULONG ExAcqResSharedStarveExclusiveAcquiresSharedRecursive;             //0x35d0
    ULONG ExAcqResSharedStarveExclusiveWaits;                               //0x35d4
    ULONG ExAcqResSharedStarveExclusiveNotAcquires;                         //0x35d8
    ULONG ExAcqResSharedWaitForExclusiveAttempts;                           //0x35dc
    ULONG ExAcqResSharedWaitForExclusiveAcquiresExclusive;                  //0x35e0
    ULONG ExAcqResSharedWaitForExclusiveAcquiresShared;                     //0x35e4
    ULONG ExAcqResSharedWaitForExclusiveAcquiresSharedRecursive;            //0x35e8
    ULONG ExAcqResSharedWaitForExclusiveWaits;                              //0x35ec
    ULONG ExAcqResSharedWaitForExclusiveNotAcquires;                        //0x35f0
    ULONG ExSetResOwnerPointerExclusive;                                    //0x35f4
    ULONG ExSetResOwnerPointerSharedNew;                                    //0x35f8
    ULONG ExSetResOwnerPointerSharedOld;                                    //0x35fc
    ULONG ExTryToAcqExclusiveAttempts;                                      //0x3600
    ULONG ExTryToAcqExclusiveAcquires;                                      //0x3604
    ULONG ExBoostExclusiveOwner;                                            //0x3608
    ULONG ExBoostSharedOwners;                                              //0x360c
    ULONG ExEtwSynchTrackingNotificationsCount;                             //0x3610
    ULONG ExEtwSynchTrackingNotificationsAccountedCount;                    //0x3614
    struct _CONTEXT* Context;                                               //0x3618
    ULONG ContextFlags;                                                     //0x361c
    struct _XSAVE_AREA* ExtendedState;                                      //0x3620
};

Ethread

线程结构体,每一个线程都有一个线程结构体,用于描述对应线程的各种属性。

结构体成员:

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
//0x2b8 bytes (sizeof)
struct _ETHREAD
{
    struct _KTHREAD Tcb;                                                    //0x0
    union _LARGE_INTEGER CreateTime;                                        //0x200
    union
    {
        union _LARGE_INTEGER ExitTime;                                      //0x208
        struct _LIST_ENTRY KeyedWaitChain;                                  //0x208
    };
    LONG ExitStatus;                                                        //0x210
    union
    {
        struct _LIST_ENTRY PostBlockList;                                   //0x214
        struct
        {
            VOID* ForwardLinkShadow;                                        //0x214
            VOID* StartAddress;                                             //0x218
        };
    };
    union
    {
        struct _TERMINATION_PORT* TerminationPort;                          //0x21c
        struct _ETHREAD* ReaperLink;                                        //0x21c
        VOID* KeyedWaitValue;                                               //0x21c
    };
    ULONG ActiveTimerListLock;                                              //0x220
    struct _LIST_ENTRY ActiveTimerListHead;                                 //0x224
    struct _CLIENT_ID Cid;                                                  //0x22c
    union
    {
        struct _KSEMAPHORE KeyedWaitSemaphore;                              //0x234
        struct _KSEMAPHORE AlpcWaitSemaphore;                               //0x234
    };
    union _PS_CLIENT_SECURITY_CONTEXT ClientSecurity;                       //0x248
    struct _LIST_ENTRY IrpList;                                             //0x24c
    ULONG TopLevelIrp;                                                      //0x254
    struct _DEVICE_OBJECT* DeviceToVerify;                                  //0x258
    union _PSP_CPU_QUOTA_APC* CpuQuotaApc;                                  //0x25c
    VOID* Win32StartAddress;                                                //0x260
    VOID* LegacyPowerObject;                                                //0x264
    struct _LIST_ENTRY ThreadListEntry;                                     //0x268
    struct _EX_RUNDOWN_REF RundownProtect;                                  //0x270
    struct _EX_PUSH_LOCK ThreadLock;                                        //0x274
    ULONG ReadClusterSize;                                                  //0x278
    volatile LONG MmLockOrdering;                                           //0x27c
    union
    {
        ULONG CrossThreadFlags;                                             //0x280
        struct
        {
            ULONG Terminated:1;                                             //0x280
            ULONG ThreadInserted:1;                                         //0x280
            ULONG HideFromDebugger:1;                                       //0x280
            ULONG ActiveImpersonationInfo:1;                                //0x280
            ULONG Reserved:1;                                               //0x280
            ULONG HardErrorsAreDisabled:1;                                  //0x280
            ULONG BreakOnTermination:1;                                     //0x280
            ULONG SkipCreationMsg:1;                                        //0x280
            ULONG SkipTerminationMsg:1;                                     //0x280
            ULONG CopyTokenOnOpen:1;                                        //0x280
            ULONG ThreadIoPriority:3;                                       //0x280
            ULONG ThreadPagePriority:3;                                     //0x280
            ULONG RundownFail:1;                                            //0x280
            ULONG NeedsWorkingSetAging:1;                                   //0x280
        };
    };
    union
    {
        ULONG SameThreadPassiveFlags;                                       //0x284
        struct
        {
            ULONG ActiveExWorker:1;                                         //0x284
            ULONG ExWorkerCanWaitUser:1;                                    //0x284
            ULONG MemoryMaker:1;                                            //0x284
            ULONG ClonedThread:1;                                           //0x284
            ULONG KeyedEventInUse:1;                                        //0x284
            ULONG RateApcState:2;                                           //0x284
            ULONG SelfTerminate:1;                                          //0x284
        };
    };
    union
    {
        ULONG SameThreadApcFlags;                                           //0x288
        struct
        {
            UCHAR Spare:1;                                                  //0x288
            volatile UCHAR StartAddressInvalid:1;                           //0x288
            UCHAR EtwPageFaultCalloutActive:1;                              //0x288
            UCHAR OwnsProcessWorkingSetExclusive:1;                         //0x288
            UCHAR OwnsProcessWorkingSetShared:1;                            //0x288
            UCHAR OwnsSystemCacheWorkingSetExclusive:1;                     //0x288
            UCHAR OwnsSystemCacheWorkingSetShared:1;                        //0x288
            UCHAR OwnsSessionWorkingSetExclusive:1;                         //0x288
            UCHAR OwnsSessionWorkingSetShared:1;                            //0x289
            UCHAR OwnsProcessAddressSpaceExclusive:1;                       //0x289
            UCHAR OwnsProcessAddressSpaceShared:1;                          //0x289
            UCHAR SuppressSymbolLoad:1;                                     //0x289
            UCHAR Prefetching:1;                                            //0x289
            UCHAR OwnsDynamicMemoryShared:1;                                //0x289
            UCHAR OwnsChangeControlAreaExclusive:1;                         //0x289
            UCHAR OwnsChangeControlAreaShared:1;                            //0x289
            UCHAR OwnsPagedPoolWorkingSetExclusive:1;                       //0x28a
            UCHAR OwnsPagedPoolWorkingSetShared:1;                          //0x28a
            UCHAR OwnsSystemPtesWorkingSetExclusive:1;                      //0x28a
            UCHAR OwnsSystemPtesWorkingSetShared:1;                         //0x28a
            UCHAR TrimTrigger:2;                                            //0x28a
            UCHAR Spare1:2;                                                 //0x28a
            UCHAR PriorityRegionActive;                                     //0x28b
        };
    };
    UCHAR CacheManagerActive;                                               //0x28c
    UCHAR DisablePageFaultClustering;                                       //0x28d
    UCHAR ActiveFaultCount;                                                 //0x28e
    UCHAR LockOrderState;                                                   //0x28f
    ULONG AlpcMessageId;                                                    //0x290
    union
    {
        VOID* AlpcMessage;                                                  //0x294
        ULONG AlpcReceiveAttributeSet;                                      //0x294
    };
    struct _LIST_ENTRY AlpcWaitListEntry;                                   //0x298
    ULONG CacheManagerCount;                                                //0x2a0
    ULONG IoBoostCount;                                                     //0x2a4
    ULONG IrpListLock;                                                      //0x2a8
    VOID* ReservedForSynchTracking;                                         //0x2ac
    struct _SINGLE_LIST_ENTRY CmCallbackListHead;                           //0x2b0
};

Kthread

Ethread的子结构体,里面的成员相对于Ethread更重要。

结构体成员:

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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
//0x200 bytes (sizeof)
struct _KTHREAD
{
    struct _DISPATCHER_HEADER Header;                                       //0x0
    volatile ULONGLONG CycleTime;                                           //0x10
    volatile ULONG HighCycleTime;                                           //0x18
    ULONGLONG QuantumTarget;                                                //0x20
    VOID* InitialStack;                                                     //0x28
    VOID* volatile StackLimit;                                              //0x2c
    VOID* KernelStack;                                                      //0x30
    ULONG ThreadLock;                                                       //0x34
    union _KWAIT_STATUS_REGISTER WaitRegister;                              //0x38
    volatile UCHAR Running;                                                 //0x39
    UCHAR Alerted[2];                                                       //0x3a
    union
    {
        struct
        {
            ULONG KernelStackResident:1;                                    //0x3c
            ULONG ReadyTransition:1;                                        //0x3c
            ULONG ProcessReadyQueue:1;                                      //0x3c
            ULONG WaitNext:1;                                               //0x3c
            ULONG SystemAffinityActive:1;                                   //0x3c
            ULONG Alertable:1;                                              //0x3c
            ULONG GdiFlushActive:1;                                         //0x3c
            ULONG UserStackWalkActive:1;                                    //0x3c
            ULONG ApcInterruptRequest:1;                                    //0x3c
            ULONG ForceDeferSchedule:1;                                     //0x3c
            ULONG QuantumEndMigrate:1;                                      //0x3c
            ULONG UmsDirectedSwitchEnable:1;                                //0x3c
            ULONG TimerActive:1;                                            //0x3c
            ULONG SystemThread:1;                                           //0x3c
            ULONG Reserved:18;                                              //0x3c
        };
        LONG MiscFlags;                                                     //0x3c
    };
    union
    {
        struct _KAPC_STATE ApcState;                                        //0x40
        struct
        {
            UCHAR ApcStateFill[23];                                         //0x40
            CHAR Priority;                                                  //0x57
        };
    };
    volatile ULONG NextProcessor;                                           //0x58
    volatile ULONG DeferredProcessor;                                       //0x5c
    ULONG ApcQueueLock;                                                     //0x60
    ULONG ContextSwitches;                                                  //0x64
    volatile UCHAR State;                                                   //0x68
    CHAR NpxState;                                                          //0x69
    UCHAR WaitIrql;                                                         //0x6a
    CHAR WaitMode;                                                          //0x6b
    volatile LONG WaitStatus;                                               //0x6c
    struct _KWAIT_BLOCK* WaitBlockList;                                     //0x70
    union
    {
        struct _LIST_ENTRY WaitListEntry;                                   //0x74
        struct _SINGLE_LIST_ENTRY SwapListEntry;                            //0x74
    };
    struct _KQUEUE* volatile Queue;                                         //0x7c
    ULONG WaitTime;                                                         //0x80
    union
    {
        struct
        {
            SHORT KernelApcDisable;                                         //0x84
            SHORT SpecialApcDisable;                                        //0x86
        };
        ULONG CombinedApcDisable;                                           //0x84
    };
    VOID* Teb;                                                              //0x88
    struct _KTIMER Timer;                                                   //0x90
    union
    {
        struct
        {
            volatile ULONG AutoAlignment:1;                                 //0xb8
            volatile ULONG DisableBoost:1;                                  //0xb8
            volatile ULONG EtwStackTraceApc1Inserted:1;                     //0xb8
            volatile ULONG EtwStackTraceApc2Inserted:1;                     //0xb8
            volatile ULONG CalloutActive:1;                                 //0xb8
            volatile ULONG ApcQueueable:1;                                  //0xb8
            volatile ULONG EnableStackSwap:1;                               //0xb8
            volatile ULONG GuiThread:1;                                     //0xb8
            volatile ULONG UmsPerformingSyscall:1;                          //0xb8
            volatile ULONG VdmSafe:1;                                       //0xb8
            volatile ULONG UmsDispatched:1;                                 //0xb8
            volatile ULONG ReservedFlags:21;                                //0xb8
        };
        volatile LONG ThreadFlags;                                          //0xb8
    };
    VOID* ServiceTable;                                                     //0xbc
    struct _KWAIT_BLOCK WaitBlock[4];                                       //0xc0
    struct _LIST_ENTRY QueueListEntry;                                      //0x120
    struct _KTRAP_FRAME* TrapFrame;                                         //0x128
    VOID* FirstArgument;                                                    //0x12c
    union
    {
        VOID* CallbackStack;                                                //0x130
        ULONG CallbackDepth;                                                //0x130
    };
    UCHAR ApcStateIndex;                                                    //0x134
    CHAR BasePriority;                                                      //0x135
    union
    {
        CHAR PriorityDecrement;                                             //0x136
        struct
        {
            UCHAR ForegroundBoost:4;                                        //0x136
            UCHAR UnusualBoost:4;                                           //0x136
        };
    };
    UCHAR Preempted;                                                        //0x137
    UCHAR AdjustReason;                                                     //0x138
    CHAR AdjustIncrement;                                                   //0x139
    CHAR PreviousMode;                                                      //0x13a
    CHAR Saturation;                                                        //0x13b
    ULONG SystemCallNumber;                                                 //0x13c
    ULONG FreezeCount;                                                      //0x140
    volatile struct _GROUP_AFFINITY UserAffinity;                           //0x144
    struct _KPROCESS* Process;                                              //0x150
    volatile struct _GROUP_AFFINITY Affinity;                               //0x154
    ULONG IdealProcessor;                                                   //0x160
    ULONG UserIdealProcessor;                                               //0x164
    struct _KAPC_STATE* ApcStatePointer[2];                                 //0x168
    union
    {
        struct _KAPC_STATE SavedApcState;                                   //0x170
        struct
        {
            UCHAR SavedApcStateFill[23];                                    //0x170
            UCHAR WaitReason;                                               //0x187
        };
    };
    CHAR SuspendCount;                                                      //0x188
    CHAR Spare1;                                                            //0x189
    UCHAR OtherPlatformFill;                                                //0x18a
    VOID* volatile Win32Thread;                                             //0x18c
    VOID* StackBase;                                                        //0x190
    union
    {
        struct _KAPC SuspendApc;                                            //0x194
        struct
        {
            UCHAR SuspendApcFill0[1];                                       //0x194
            UCHAR ResourceIndex;                                            //0x195
        };
        struct
        {
            UCHAR SuspendApcFill1[3];                                       //0x194
            UCHAR QuantumReset;                                             //0x197
        };
        struct
        {
            UCHAR SuspendApcFill2[4];                                       //0x194
            ULONG KernelTime;                                               //0x198
        };
        struct
        {
            UCHAR SuspendApcFill3[36];                                      //0x194
            struct _KPRCB* volatile WaitPrcb;                               //0x1b8
        };
        struct
        {
            UCHAR SuspendApcFill4[40];                                      //0x194
            VOID* LegoData;                                                 //0x1bc
        };
        struct
        {
            UCHAR SuspendApcFill5[47];                                      //0x194
            UCHAR LargeStack;                                               //0x1c3
        };
    };
    ULONG UserTime;                                                         //0x1c4
    union
    {
        struct _KSEMAPHORE SuspendSemaphore;                                //0x1c8
        UCHAR SuspendSemaphorefill[20];                                     //0x1c8
    };
    ULONG SListFaultCount;                                                  //0x1dc
    struct _LIST_ENTRY ThreadListEntry;                                     //0x1e0
    struct _LIST_ENTRY MutantListHead;                                      //0x1e8
    VOID* SListFaultAddress;                                                //0x1f0
    struct _KTHREAD_COUNTERS* ThreadCounters;                               //0x1f4
    struct _XSTATE_SAVE* XStateSave;                                        //0x1f8
};

6.0环KiFastCallEntry(初始化部分)

分析该函数需要时刻对照上文的几个结构体,否则无法理解函数在做什么。

函数内部首先填充DS ES FS寄存器,并切换堆栈。(由于MSR寄存器所有核共享一个,为了防止互相影响,又从各自的TSS中拿了单独的ESP0 )

然后填充TrapFrame结构,该结构存储在0环堆栈中,通过push依次进行成员的填充。

起始位置为HardwareSegSs,V86那四个寄存器是虚拟8086模式用的,所以直接省略了。

继续填充TrapFrame结构体的其余成员。

填充好后将TrapFrame结构的首地址赋值给Kthread中的TrapFrame成员。

7.前置知识-系统服务表

在上文3环分析部分,可以看到ReadPrcMem函数仅调用了sysenter,并没有直接调用内核的某个对应函数。其真正调用的功能函数的地址,将通过查找系统服务表的方式得到。而3环传入的eax则是这个系统服务表的索引,也叫系统调用号。

系统服务表的宏观架构(系统服务表地址存储在Kthread+E0处):

  • ServiceTable:函数地址表地址。每个成员是4字节,指向函数地址。
  • Count:当前的系统服务表共被调用了多少次。(未使用)
  • ServiceLimit:当前的系统服务表里共有多少个函数。
  • ArgumentMent:函数参数个数表,每个成员都是参数的字节数,占1个字节。如对应函数由2个4字节参数,则存8。

3环在调用sysenter之前往eax中存的值决定了要调用哪个函数。

系统调用号仅低13位起作用,结构如下:

下标为12的位(第13位)如果为0,则查第一张系统服务表,为1则查第二张。

低12位(0~11)就是函数地址表和函数参数表的索引。

8.0环KiFastCallEntry(调用部分)

首先拆分系统调用号,找到系统服务表地址,取出索引。

获取函数地址、函数参数个数,复制参数至0环堆栈,并做第一次权限判断(3环堆栈地址判断)。

再次判断3环cs权限,通过后调用最终的功能函数。

9.SSDT

上文通过Kthread+BC去得到了系统服务表地址。Windows中提供了一个导出的全局变量SystemServicesDescriptorTable。也叫SSDT。这个全局变量存储了系统服务表的地址,但仅存储了第一张表的地址。

在windbg中输入命令 dd KeServiceDescriptorTable查看该全局变量。可以发现只有一张表(16个字节)。第二张表全部为空。

内核中还有一个全局变量称为SSDT Shadow,该变量未导出,但可以查看所有的系统服务表。

在windbg中输入命令 dd KeServiceDescriptorTableShadow查看该全局变量。可以看到所有的系统服务表。

10.系统调用-返回3环

接近上文call ebx后,首先检查IRQL及线程挂靠相关信息。

然后检查ETW日志是否需要记录。并为Kthread->TrapFrame成员赋值。可用于恢复旧TrapFrame或蓝屏时进行堆栈回溯。

随后判断是否虚拟8086模式和之前的特权级。并相应的执行性能统计。

如果有APC需要处理则处理APC。(仅先前模式为用户模式时才会处理,APC知识后续章节学习。)

恢复异常链表及调试寄存器(如果为调试模式的话)。

进行一万个感觉没卵用的判断

最后恢复各种寄存器,并以iret方式返回3环。

总结:

返回的代码真正有用的就是恢复寄存器的几行,其余全是在做先前模式相关的判断。其中穿插了一个处理APC的逻辑。

当有APC需要处理时,会以另一套流程返回3环,由于目前不具备APC知识,暂不做分析。

整体分析流程皆以 先前模式为用户级别 为前提去分析,可以看到判断还是很多的,甚至考虑了其他非正常cs的情况。

11.SSDT HOOK保护进程

SSDT HOOK代码不算难,个人觉得比Inline HOOK简单的多。

取SSDT

1
2
3
4
5
6
7
8
ULONG GetSSDTBase() {
    PULONG pKthread = 0;
    __asm {
        mov eax,fs:[0x124] //找到Kthread结构指针
        mov pKthread,eax
    }
    return *(PULONG)((PUCHAR)pKthread + 0xBC); //Kthread+BC就是系统服务表位置
}

SetHook

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
VOID SetSsdtHook(ULONG oldFuncAddr,ULONG newFuncAddr) {
    PULONG SsdtBase = (PULONG)GetSSDTBase();
    //0BEh  OpenProcess
    PULONG ServiceTable = (PULONG)SsdtBase[0];
    ULONG ServiceLimit = SsdtBase[2];
    PULONG ArgumentTable = (PULONG)SsdtBase[3];
    //遍历函数表,找到函数在ServiceTable中的位置并替换
    for (ULONG i = 0; i < ServiceLimit; i++)
    {
        if (ServiceTable[i] == oldFuncAddr)
        {
            ServiceTable[i] = newFuncAddr;
        }
    }
}

新函数

1
2
3
4
5
6
7
8
9
10
NTSTATUS NewOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId) {
    if (ClientId->UniqueProcess == 2356 || ClientId->UniqueThread == 2356)
    {
        //保护一下DbgView进程
        DbgPrint("Catch You!\r\n");
        *ProcessHandle = NULL;
        return STATUS_INVALID_PARAMETER;
    }
    return NtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}

Main函数

1
2
3
4
5
NTSTATUS DriverEntry(PDRIVER_OBJECT pObj,PUNICODE_STRING pReg) {
    SetSsdtHook((ULONG)NtOpenProcess, (ULONG)NewOpenProcess);
    pObj->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}

卸载Hook

1
2
3
VOID DriverUnload(PDRIVER_OBJECT pObj) {
    SetSsdtHook(NewOpenProcess,NtOpenProcess);
}

效果

还挺好玩的,简单的保护了DbgView进程。

(0)

相关推荐

  • windows 堆分析

    windows和linux堆管理机制虽然呈现给用户的效果是一样的,大体思路也是差不太多,但是底层实现逻辑大相径庭,很多地方和glibc的ptmalloc差别很大.网上资料零零散散,而且都是通过逆向手段 ...

  • 原创|天文台笔记

    原创|天文台笔记 图/芳姐 文/欢爸 时间/2017-01-16 23:18 [引言]假期第一站:上海天文博物馆,偶遇黄教授... 稚嫩的心灵,不需要自以为是的教化,找个美好的地方,让她自己去感悟.. ...

  • 针灸原创的内核是什么?

    "尽管针灸已经在全世界被普遍运用,但是针灸的原创内核,还并没有真正地得到深刻的理解和精确的应用.因此出现了下面这个问题,许多针灸师都不理解,把时空这个耳熟能详的词汇同针灸连接在一起,成为时空 ...

  • [原创]逆向学习笔记之汇编

    初学逆向,学习滴水的课程整理出的笔记,不足之处敬请各位老师傅指正 十六进制可看作二进制的一种简写形式 数据宽度 计算机中数据有长度限制,超过最高宽度的数据会被丢弃. 1 2 3 4 1.位(bit): ...

  • 文字版 | 朱勉生:针灸原创的内核是什么

    "尽管针灸已经在全世界被普遍运用,但是针灸的原创内核,还并没有真正地得到深刻的理解和精确的应用.因此出现了下面这个问题,许多针灸师都不理解,把时空这个耳熟能详的词汇同针灸连接在一起,成为时空 ...

  • 高中物理必修 电学模块 原创笔记(转发/收藏)

    前言 电学模块笔记,是通过教学实践总结的原创笔记,感谢大家的支持. 1.<电学模块原创笔记>包括:静电场.恒定电流.磁场.电磁感应.交变电流.电磁场和传感器,共7章的内容,涵盖电学模块几乎 ...

  • 人生有时就像一场笑话,曾经求而不得的东西,有一天你发现,它一文不值。#原创#人生笔记 #治愈系

    人生有时就像一场笑话,曾经求而不得的东西,有一天你发现,它一文不值。#原创#人生笔记 #治愈系

  • 2020年灰灰龙的教学笔记原创精华合辑

    您好,我是灰灰龙. 感谢这一年大家对我的支持. 在此整理了2020年的原创精华文章,方便大家查阅. 2020年6月1日~2020年12月31日,合计203篇. 如果喜欢,分享给更多朋友哈. 01  学 ...

  • 全面挑战x86!Arm公布最强服务器内核及首款ArmV9平台

      新智元报道   来源:VB 编辑:LQ [新智元导读]去年9月,Arm公布了两大服务器芯片平台Neoverse V1和N2,但并没有公开性能情况,那么到底性能如何,是否能全面挑战x86?刚刚,Ar ...

  • 全面挑战x86!Arm公布迄今为止性能最高的服务器内核及首款Armv9平台

    射频测试技术周(5月10-14日) 下一代射频芯片.相控阵方案.滤波器.等5场射频专题直播等你参加 Arm 新一代 Neoverse V1和Neoverse N2 听起来并不陌生,因为Arm已于去年9 ...