├── DLLHiding.sln
├── DLLHiding
├── DLLHiding.vcxproj
├── DLLHiding.vcxproj.filters
├── Process.cpp
├── Process.h
└── Source.cpp
└── README.md
/DLLHiding.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.30501.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLLHiding", "DLLHiding\DLLHiding.vcxproj", "{3D2441D4-80A6-4E28-A0C8-33939699DD1C}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Debug|x64 = Debug|x64
12 | Release|Win32 = Release|Win32
13 | Release|x64 = Release|x64
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {3D2441D4-80A6-4E28-A0C8-33939699DD1C}.Debug|Win32.ActiveCfg = Debug|Win32
17 | {3D2441D4-80A6-4E28-A0C8-33939699DD1C}.Debug|Win32.Build.0 = Debug|Win32
18 | {3D2441D4-80A6-4E28-A0C8-33939699DD1C}.Debug|x64.ActiveCfg = Debug|x64
19 | {3D2441D4-80A6-4E28-A0C8-33939699DD1C}.Debug|x64.Build.0 = Debug|x64
20 | {3D2441D4-80A6-4E28-A0C8-33939699DD1C}.Release|Win32.ActiveCfg = Release|Win32
21 | {3D2441D4-80A6-4E28-A0C8-33939699DD1C}.Release|Win32.Build.0 = Release|Win32
22 | {3D2441D4-80A6-4E28-A0C8-33939699DD1C}.Release|x64.ActiveCfg = Release|x64
23 | {3D2441D4-80A6-4E28-A0C8-33939699DD1C}.Release|x64.Build.0 = Release|x64
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/DLLHiding/DLLHiding.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Debug
10 | x64
11 |
12 |
13 | Release
14 | Win32
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {3D2441D4-80A6-4E28-A0C8-33939699DD1C}
23 | Win32Proj
24 | DLLHiding
25 |
26 |
27 |
28 | Application
29 | true
30 | v120
31 | Unicode
32 |
33 |
34 | Application
35 | true
36 | v120
37 | Unicode
38 |
39 |
40 | Application
41 | false
42 | v120
43 | true
44 | Unicode
45 |
46 |
47 | Application
48 | false
49 | v120
50 | true
51 | Unicode
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | true
71 |
72 |
73 | true
74 |
75 |
76 | false
77 |
78 |
79 | false
80 |
81 |
82 |
83 |
84 |
85 | Level3
86 | Disabled
87 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
88 |
89 |
90 | Console
91 | true
92 |
93 |
94 |
95 |
96 |
97 |
98 | Level3
99 | Disabled
100 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
101 |
102 |
103 | Console
104 | true
105 |
106 |
107 |
108 |
109 | Level3
110 |
111 |
112 | MaxSpeed
113 | true
114 | true
115 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
116 |
117 |
118 | Console
119 | true
120 | true
121 | true
122 |
123 |
124 |
125 |
126 | Level3
127 |
128 |
129 | MaxSpeed
130 | true
131 | true
132 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
133 |
134 |
135 | Console
136 | true
137 | true
138 | true
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/DLLHiding/DLLHiding.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 |
26 |
27 | Header Files
28 |
29 |
30 |
--------------------------------------------------------------------------------
/DLLHiding/Process.cpp:
--------------------------------------------------------------------------------
1 | #include "Process.h"
2 | #include
3 |
4 | Process::Process(std::string Proc, std::wstring DLLName) {
5 | Pinfo = GetProcessInfo(Proc);
6 | Sleep(1000);
7 |
8 | //Remove the from the 3 linked lists
9 | DLLInLoadStatus = RemoveDLL(Pinfo.Process_ID, DLLName, 0);
10 | DLLInMemStatus = RemoveDLL(Pinfo.Process_ID, DLLName, 1);
11 | DLLInInInitializationStatus = RemoveDLL(Pinfo.Process_ID, DLLName, 2);
12 | }
13 |
14 | Process::~Process(){
15 |
16 | }
17 |
18 | #pragma optimize("", off)
19 | //Get the Process Information
20 | Process::Process_INFO Process::GetProcessInfo(std::string & PN){
21 | PVOID buffer = NULL;
22 | PSYSTEM_PROCESS_INFO inf = NULL;
23 | LPWSTR ProcNAME;
24 |
25 | //convert CHAR to WCHAR
26 | /*int nChars = MultiByteToWideChar(CP_ACP, 0, PN, -1, NULL, 0);
27 | LPWSTR P1 = new WCHAR[nChars]; //Release this at some point
28 | MultiByteToWideChar(CP_ACP, 0, PN, -1, (LPWSTR)P1, nChars);
29 | //delete[] P1;
30 | */
31 |
32 | ULONG buffer_size = 512 * 512;
33 |
34 | NTSTATUS Status = STATUS_INFO_LENGTH_MISMATCH;
35 | _ntQSI fpQSI = (_ntQSI)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtQuerySystemInformation");
36 |
37 |
38 | buffer = VirtualAlloc(NULL, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
39 |
40 | if (buffer == NULL){
41 | return Pinfo;
42 | }
43 |
44 | Status = fpQSI((SYSTEM_INFORMATION_CLASS)All_SYS::SystemExtendedProcessInformation, buffer, buffer_size, NULL);
45 |
46 | //if buffer is too small double size
47 | if (Status == STATUS_INFO_LENGTH_MISMATCH) {
48 | VirtualFree(buffer, NULL, MEM_RELEASE);
49 | buffer_size *= 2;
50 | }
51 |
52 | else if (!NT_SUCCESS(Status)) {
53 | VirtualFree(buffer, NULL, MEM_RELEASE);
54 | return Pinfo;
55 | }
56 |
57 | else{
58 | inf = (PSYSTEM_PROCESS_INFO)buffer;
59 |
60 | while (inf) {
61 | ProcNAME = inf->ImageName.Buffer;
62 |
63 | if (inf->ImageName.Buffer != nullptr){
64 |
65 | //List of all the process id on the current system
66 | if (inf->UniqueProcessId > 0){
67 | //System_PID_List.push_back(inf->UniqueProcessId);
68 | }
69 |
70 | //WinAPI - Converts a Wide Char to multibyte
71 | int nLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)ProcNAME, -1, NULL, NULL, NULL, NULL);
72 | LPSTR P1 = new CHAR[nLen];
73 | WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)ProcNAME, -1, P1, nLen, NULL, NULL);
74 | std::string ProcessName(P1);
75 | delete[] P1;
76 | //std::cout << P1 << std::endl;
77 | //if (strcmp(PN, ProcessName) == 0){
78 | if (PN.compare(ProcessName) == 0){
79 | Pinfo.Process_ID = (DWORD)inf->UniqueProcessId;
80 |
81 | Pinfo.Process_Name = ProcessName;
82 | CHAR szTemp[MAX_PATH] = { 0 };
83 | sprintf(szTemp, "%I64d", (inf->CreateTime).QuadPart);
84 | Pinfo.Create_Time = szTemp;
85 | Pinfo.ThreadCount = inf->NumberOfThreads;
86 | Pinfo.HandleCount = inf->HandleCount;
87 |
88 | /*FILETIME ft;
89 | SYSTEMTIME st;
90 | GetSystemTime(&st);
91 | SystemTimeToFileTime(&st, &ft);
92 | LARGE_INTEGER CT = inf->CreateTime;
93 | CHAR szTemp[MAX_PATH] = { 0 };
94 | CHAR szTemp1[MAX_PATH] = { 0 };
95 | sprintf(szTemp, "%I64d", CT.QuadPart);
96 | sprintf(szTemp1, "%I64d", ft);
97 | std::cout << szTemp << std::endl;
98 | std::cout << szTemp1 << std::endl;*/
99 | //std::cout << PID << std::endl;
100 | //delete[] P1;
101 |
102 | //return Pinfo;
103 | }
104 | //delete[] P1;
105 |
106 |
107 | /*//Testing stuff
108 | if (wcscmp(P1, ProcNAME) == 0){
109 | PID = (DWORD)inf->UniqueProcessId;
110 | delete[] P1;
111 | std::cout << PID << std::endl;
112 | return PID;
113 | }*/
114 |
115 | }
116 |
117 | if (!inf->NextEntryOffset)
118 | break;
119 |
120 | inf = (PSYSTEM_PROCESS_INFO)((LPBYTE)inf + inf->NextEntryOffset);
121 | }
122 |
123 | if (buffer) VirtualFree(buffer, NULL, MEM_RELEASE);
124 | }
125 |
126 | return Pinfo;
127 | }
128 |
129 | All_SYS::PLDR_DATA_TABLE_ENTRY Process::GetNextNode(PCHAR nNode, int Offset){
130 | #ifdef _WIN64
131 | nNode -= sizeof(LIST_ENTRY64) * Offset;
132 | #else
133 | nNode -= sizeof(LIST_ENTRY) * Offset;
134 | #endif
135 | return (All_SYS::PLDR_DATA_TABLE_ENTRY)nNode;
136 | }
137 |
138 | //Remove Modules From PBI
139 | //ListType = 0 - InLoadOrderModuleList
140 | //ListType = 1 - InMemoryOrderModuleList
141 | //ListType = 2 - InInitializationOrderModuleList
142 | BOOL Process::RemoveDLL(DWORD PID, std::wstring DLLtoRemove, int ListType){
143 | pNtQueryInformationProcess NtQIP;
144 | NTSTATUS status;
145 | std::wstring BaseDllName;
146 | std::wstring FullDllName;
147 |
148 | //Check ListType in range
149 | if (ListType > 2 || ListType < 0){
150 | return FALSE;
151 | }
152 |
153 | PROCESS_BASIC_INFORMATION PBI = { 0 };
154 | HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
155 | NtQIP = (pNtQueryInformationProcess)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtQueryInformationProcess");
156 | status = NT_SUCCESS(NtQIP(ProcessHandle, ProcessBasicInformation, &PBI, sizeof(PROCESS_BASIC_INFORMATION), NULL));
157 |
158 | if (status){
159 | All_SYS::PEB_LDR_DATA LdrData;
160 | All_SYS::LDR_DATA_TABLE_ENTRY LdrModule;
161 | All_SYS::PPEB_LDR_DATA pLdrData = nullptr;
162 | PBYTE address = nullptr;
163 |
164 | PBYTE LdrDataOffset = (PBYTE)(PBI.PebBaseAddress) + offsetof(struct All_SYS::_PEB, LoaderData);
165 | ReadProcessMemory(ProcessHandle, LdrDataOffset, &pLdrData, sizeof(All_SYS::PPEB_LDR_DATA), NULL);
166 | ReadProcessMemory(ProcessHandle, pLdrData, &LdrData, sizeof(All_SYS::PEB_LDR_DATA), NULL);
167 |
168 | if (ListType == 0)
169 | address = (PBYTE)LdrData.InLoadOrderModuleList.Flink;
170 | else if (ListType == 1)
171 | address = (PBYTE)LdrData.InMemoryOrderModuleList.Flink;
172 | else if (ListType == 2)
173 | address = (PBYTE)LdrData.InInitializationOrderModuleList.Flink;
174 |
175 | #ifdef _WIN64
176 | address -= sizeof(LIST_ENTRY64)*ListType;
177 | #else
178 | address -= sizeof(LIST_ENTRY)*ListType;
179 | #endif
180 |
181 | All_SYS::PLDR_DATA_TABLE_ENTRY Head = (All_SYS::PLDR_DATA_TABLE_ENTRY)address;
182 | All_SYS::PLDR_DATA_TABLE_ENTRY Node = Head;
183 |
184 | All_SYS::LDR_DATA_TABLE_ENTRY prevNodeModule;
185 | All_SYS::PLDR_DATA_TABLE_ENTRY ptrNode;
186 |
187 | do
188 | {
189 | BOOL status1 = ReadProcessMemory(ProcessHandle, Node, &LdrModule, sizeof(All_SYS::LDR_DATA_TABLE_ENTRY), NULL);
190 | if (status1)
191 | {
192 | if (LdrModule.BaseAddress == 0)
193 | break;
194 |
195 | BaseDllName = std::wstring(LdrModule.BaseDllName.Length / sizeof(WCHAR), 0);
196 | FullDllName = std::wstring(LdrModule.FullDllName.Length / sizeof(WCHAR), 0);
197 | ReadProcessMemory(ProcessHandle, LdrModule.BaseDllName.Buffer, &BaseDllName[0], LdrModule.BaseDllName.Length, NULL);
198 | ReadProcessMemory(ProcessHandle, LdrModule.FullDllName.Buffer, &FullDllName[0], LdrModule.FullDllName.Length, NULL);
199 |
200 | //Null terminate the string
201 | BaseDllName.push_back('\0');
202 | FullDllName.push_back('\0');
203 |
204 | //std::wcout << BaseDllName << std::endl;
205 | }
206 |
207 | #ifdef _WIN64
208 | PLIST_ENTRY64 ptrPrevNodeFlick;
209 | PLIST_ENTRY64 ptrCurNodeBlink;
210 | #else
211 | PLIST_ENTRY ptrPrevNodeFlick;
212 | PLIST_ENTRY ptrCurNodeBlink;
213 | #endif
214 |
215 | All_SYS::PLDR_DATA_TABLE_ENTRY NextNode;
216 | if (BaseDllName.compare(DLLtoRemove) == 0){
217 | #ifdef _WIN64
218 | if (ListType == 0){
219 | //Flick link pointer
220 | ptrPrevNodeFlick = (PLIST_ENTRY64) LdrModule.InLoadOrderModuleList.Flink;
221 | //Blink link pointer
222 | ptrCurNodeBlink = (PLIST_ENTRY64) LdrModule.InLoadOrderModuleList.Blink;
223 | //Prev Node's Flick = Current Node's Flick
224 | prevNodeModule.InLoadOrderModuleList.Flink = (ULONGLONG) ptrPrevNodeFlick;
225 | // Next Node's Blink = Current Node's Blink
226 | NextNode = GetNextNode((PCHAR)LdrModule.InLoadOrderModuleList.Flink, ListType);
227 | //Read the Memory of external proces
228 | ReadProcessMemory(ProcessHandle, NextNode, &LdrModule, sizeof(All_SYS::LDR_DATA_TABLE_ENTRY), NULL);
229 | //Next Node's Blink = Current Node's Blink
230 | LdrModule.InLoadOrderModuleList.Blink = (ULONGLONG) ptrCurNodeBlink;
231 | }
232 | if (ListType == 1){
233 | ptrPrevNodeFlick = (PLIST_ENTRY64) LdrModule.InMemoryOrderModuleList.Flink;
234 | ptrCurNodeBlink = (PLIST_ENTRY64) LdrModule.InMemoryOrderModuleList.Blink;
235 | prevNodeModule.InMemoryOrderModuleList.Flink = (ULONGLONG)ptrPrevNodeFlick;
236 | NextNode = GetNextNode((PCHAR)LdrModule.InMemoryOrderModuleList.Flink, ListType);
237 | ReadProcessMemory(ProcessHandle, NextNode, &LdrModule, sizeof(All_SYS::LDR_DATA_TABLE_ENTRY), NULL);
238 | LdrModule.InMemoryOrderModuleList.Blink = (ULONGLONG)ptrCurNodeBlink;
239 | }
240 | if (ListType == 2){
241 | ptrPrevNodeFlick = (PLIST_ENTRY64)LdrModule.InInitializationOrderModuleList.Flink;
242 | ptrCurNodeBlink = (PLIST_ENTRY64)LdrModule.InInitializationOrderModuleList.Blink;
243 | prevNodeModule.InInitializationOrderModuleList.Flink = (ULONGLONG)ptrPrevNodeFlick;
244 | NextNode = GetNextNode((PCHAR)LdrModule.InInitializationOrderModuleList.Flink, ListType);
245 | ReadProcessMemory(ProcessHandle, NextNode, &LdrModule, sizeof(All_SYS::LDR_DATA_TABLE_ENTRY), NULL);
246 | LdrModule.InInitializationOrderModuleList.Blink = (ULONGLONG) ptrCurNodeBlink;
247 | }
248 | #else
249 | if (ListType == 0){
250 | //Flick link pointer
251 | ptrPrevNodeFlick = LdrModule.InLoadOrderModuleList.Flink;
252 | //Blink link pointer
253 | ptrCurNodeBlink = LdrModule.InLoadOrderModuleList.Blink;
254 | //Prev Node's Flick = Current Node's Flick
255 | prevNodeModule.InLoadOrderModuleList.Flink = ptrPrevNodeFlick;
256 | // Next Node's Blink = Current Node's Blink
257 | NextNode = GetNextNode((PCHAR)LdrModule.InLoadOrderModuleList.Flink, ListType);
258 | //Read the Memory of external proces
259 | ReadProcessMemory(ProcessHandle, NextNode, &LdrModule, sizeof(All_SYS::LDR_DATA_TABLE_ENTRY), NULL);
260 | //Next Node's Blink = Current Node's Blink
261 | LdrModule.InLoadOrderModuleList.Blink = ptrCurNodeBlink;
262 | }
263 | if (ListType == 1){
264 | ptrPrevNodeFlick = LdrModule.InMemoryOrderModuleList.Flink;
265 | ptrCurNodeBlink = LdrModule.InMemoryOrderModuleList.Blink;
266 | prevNodeModule.InMemoryOrderModuleList.Flink = ptrPrevNodeFlick;
267 | NextNode = GetNextNode((PCHAR)LdrModule.InMemoryOrderModuleList.Flink, ListType);
268 | ReadProcessMemory(ProcessHandle, NextNode, &LdrModule, sizeof(All_SYS::LDR_DATA_TABLE_ENTRY), NULL);
269 | LdrModule.InMemoryOrderModuleList.Blink = ptrCurNodeBlink;
270 | }
271 | if (ListType == 2){
272 | ptrPrevNodeFlick = LdrModule.InInitializationOrderModuleList.Flink;
273 | ptrCurNodeBlink = LdrModule.InInitializationOrderModuleList.Blink;
274 | prevNodeModule.InInitializationOrderModuleList.Flink = ptrPrevNodeFlick;
275 | NextNode = GetNextNode((PCHAR)LdrModule.InInitializationOrderModuleList.Flink, ListType);
276 | ReadProcessMemory(ProcessHandle, NextNode, &LdrModule, sizeof(All_SYS::LDR_DATA_TABLE_ENTRY), NULL);
277 | LdrModule.InInitializationOrderModuleList.Blink = ptrCurNodeBlink;
278 | }
279 | #endif
280 |
281 | //Write LDR Modules to memory
282 | WriteProcessMemory(ProcessHandle, ptrNode, &prevNodeModule, sizeof(All_SYS::LDR_DATA_TABLE_ENTRY), NULL);
283 | WriteProcessMemory(ProcessHandle, NextNode, &LdrModule, sizeof(All_SYS::LDR_DATA_TABLE_ENTRY), NULL);
284 |
285 | //DLL module removed - close handle and return
286 | CloseHandle(ProcessHandle);
287 | return TRUE;
288 | //
289 |
290 | }
291 |
292 | prevNodeModule = LdrModule;
293 | ptrNode = Node;
294 |
295 | if (ListType == 0)
296 | Node = GetNextNode((PCHAR)LdrModule.InLoadOrderModuleList.Flink, ListType);
297 | else if (ListType == 1)
298 | Node = GetNextNode((PCHAR)LdrModule.InMemoryOrderModuleList.Flink, ListType);
299 | else if (ListType == 2)
300 | Node = GetNextNode((PCHAR)LdrModule.InInitializationOrderModuleList.Flink, ListType);
301 |
302 | } while (Head != Node);
303 | }
304 | CloseHandle(ProcessHandle);
305 | return FALSE;
306 | }
307 |
308 | //List Modules From PBI
309 | //ListType = 0 - InLoadOrderModuleList
310 | //ListType = 1 - InMemoryOrderModuleList
311 | //ListType = 2 - InInitializationOrderModuleList
312 | //Order = 0 - Flick through list (Forward Order)
313 | //Order = 1 - Blink through list (Backwards Order)
314 | void Process::ListModules(DWORD PID, int ListType, int Order){
315 | pNtQueryInformationProcess NtQIP;
316 | NTSTATUS status;
317 | std::wstring BaseDllName;
318 | std::wstring FullDllName;
319 |
320 | //Check ListType in range
321 | if (ListType > 2 || ListType < 0){
322 | return;
323 | }
324 | if (Order > 1 || Order < 0){
325 | return;
326 | }
327 |
328 | PROCESS_BASIC_INFORMATION PBI = { 0 };
329 | HANDLE ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
330 | NtQIP = (pNtQueryInformationProcess)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtQueryInformationProcess");
331 | status = NT_SUCCESS(NtQIP(ProcessHandle, ProcessBasicInformation, &PBI, sizeof(PROCESS_BASIC_INFORMATION), NULL));
332 |
333 | if (status){
334 | All_SYS::PEB_LDR_DATA LdrData;
335 | All_SYS::LDR_DATA_TABLE_ENTRY LdrModule;
336 | All_SYS::PPEB_LDR_DATA pLdrData = nullptr;
337 | PBYTE address = nullptr;
338 |
339 | PBYTE LdrDataOffset = (PBYTE)(PBI.PebBaseAddress) + offsetof(struct All_SYS::_PEB, LoaderData);
340 | ReadProcessMemory(ProcessHandle, LdrDataOffset, &pLdrData, sizeof(All_SYS::PPEB_LDR_DATA), NULL);
341 | ReadProcessMemory(ProcessHandle, pLdrData, &LdrData, sizeof(All_SYS::PEB_LDR_DATA), NULL);
342 |
343 | if (Order == 0){
344 | if (ListType == 0)
345 | address = (PBYTE)LdrData.InLoadOrderModuleList.Flink;
346 | else if (ListType == 1)
347 | address = (PBYTE)LdrData.InMemoryOrderModuleList.Flink;
348 | else if (ListType == 2)
349 | address = (PBYTE)LdrData.InInitializationOrderModuleList.Flink;
350 | }
351 | else{
352 | if (ListType == 0)
353 | address = (PBYTE)LdrData.InLoadOrderModuleList.Blink;
354 | else if (ListType == 1)
355 | address = (PBYTE)LdrData.InMemoryOrderModuleList.Blink;
356 | else if (ListType == 2)
357 | address = (PBYTE)LdrData.InInitializationOrderModuleList.Blink;
358 | }
359 |
360 | #ifdef _WIN64
361 | address -= sizeof(LIST_ENTRY64)*ListType;
362 | #else
363 | address -= sizeof(LIST_ENTRY)*ListType;
364 | #endif
365 |
366 | All_SYS::PLDR_DATA_TABLE_ENTRY Head = (All_SYS::PLDR_DATA_TABLE_ENTRY)address;
367 | All_SYS::PLDR_DATA_TABLE_ENTRY Node = Head;
368 |
369 | do
370 | {
371 | BOOL status1 = ReadProcessMemory(ProcessHandle, Node, &LdrModule, sizeof(All_SYS::LDR_DATA_TABLE_ENTRY), NULL);
372 | if (status1)
373 | {
374 | if (LdrModule.BaseAddress == 0)
375 | break;
376 |
377 | BaseDllName = std::wstring(LdrModule.BaseDllName.Length / sizeof(WCHAR), 0);
378 | FullDllName = std::wstring(LdrModule.FullDllName.Length / sizeof(WCHAR), 0);
379 | ReadProcessMemory(ProcessHandle, LdrModule.BaseDllName.Buffer, &BaseDllName[0], LdrModule.BaseDllName.Length, NULL);
380 | ReadProcessMemory(ProcessHandle, LdrModule.FullDllName.Buffer, &FullDllName[0], LdrModule.FullDllName.Length, NULL);
381 |
382 | BaseDllName.push_back('\0');
383 | FullDllName.push_back('\0');
384 |
385 | std::wcout << BaseDllName << std::endl;
386 | }
387 |
388 | if (Order == 0){
389 | if (ListType == 0)
390 | Node = GetNextNode((PCHAR)LdrModule.InLoadOrderModuleList.Flink, ListType);
391 | else if (ListType == 1)
392 | Node = GetNextNode((PCHAR)LdrModule.InMemoryOrderModuleList.Flink, ListType);
393 | else if (ListType == 2)
394 | Node = GetNextNode((PCHAR)LdrModule.InInitializationOrderModuleList.Flink, ListType);
395 | }
396 | else{
397 | if (ListType == 0)
398 | Node = GetNextNode((PCHAR)LdrModule.InLoadOrderModuleList.Blink, ListType);
399 | else if (ListType == 1)
400 | Node = GetNextNode((PCHAR)LdrModule.InMemoryOrderModuleList.Blink, ListType);
401 | else if (ListType == 2)
402 | Node = GetNextNode((PCHAR)LdrModule.InInitializationOrderModuleList.Blink, ListType);
403 | }
404 |
405 | } while (Head != Node);
406 | }
407 |
408 | CloseHandle(ProcessHandle);
409 | }
410 | #pragma optimize("", on)
--------------------------------------------------------------------------------
/DLLHiding/Process.h:
--------------------------------------------------------------------------------
1 | #ifndef __Process_H__
2 | #define __Process_H__
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
10 |
11 | namespace All_SYS{
12 | typedef enum _SYSTEM_INFORMATION_CLASS
13 | {
14 | SystemBasicInformation = 0x0000,
15 | SystemProcessorInformation = 0x0001,
16 | SystemPerformanceInformation = 0x0002,
17 | SystemTimeOfDayInformation = 0x0003,
18 | SystemPathInformation = 0x0004,
19 | SystemProcessInformation = 0x0005,
20 | SystemCallCountInformation = 0x0006,
21 | SystemDeviceInformation = 0x0007,
22 | SystemProcessorPerformanceInformation = 0x0008,
23 | SystemFlagsInformation = 0x0009,
24 | SystemCallTimeInformation = 0x000A,
25 | SystemModuleInformation = 0x000B,
26 | SystemLocksInformation = 0x000C,
27 | SystemStackTraceInformation = 0x000D,
28 | SystemPagedPoolInformation = 0x000E,
29 | SystemNonPagedPoolInformation = 0x000F,
30 | SystemHandleInformation = 0x0010,
31 | SystemObjectInformation = 0x0011,
32 | SystemPageFileInformation = 0x0012,
33 | SystemVdmInstemulInformation = 0x0013,
34 | SystemVdmBopInformation = 0x0014,
35 | SystemFileCacheInformation = 0x0015,
36 | SystemPoolTagInformation = 0x0016,
37 | SystemInterruptInformation = 0x0017,
38 | SystemDpcBehaviorInformation = 0x0018,
39 | SystemFullMemoryInformation = 0x0019,
40 | SystemLoadGdiDriverInformation = 0x001A,
41 | SystemUnloadGdiDriverInformation = 0x001B,
42 | SystemTimeAdjustmentInformation = 0x001C,
43 | SystemSummaryMemoryInformation = 0x001D,
44 | SystemMirrorMemoryInformation = 0x001E,
45 | SystemPerformanceTraceInformation = 0x001F,
46 | SystemCrashDumpInformation = 0x0020,
47 | SystemExceptionInformation = 0x0021,
48 | SystemCrashDumpStateInformation = 0x0022,
49 | SystemKernelDebuggerInformation = 0x0023,
50 | SystemContextSwitchInformation = 0x0024,
51 | SystemRegistryQuotaInformation = 0x0025,
52 | SystemExtendServiceTableInformation = 0x0026,
53 | SystemPrioritySeperation = 0x0027,
54 | SystemVerifierAddDriverInformation = 0x0028,
55 | SystemVerifierRemoveDriverInformation = 0x0029,
56 | SystemProcessorIdleInformation = 0x002A,
57 | SystemLegacyDriverInformation = 0x002B,
58 | SystemCurrentTimeZoneInformation = 0x002C,
59 | SystemLookasideInformation = 0x002D,
60 | SystemTimeSlipNotification = 0x002E,
61 | SystemSessionCreate = 0x002F,
62 | SystemSessionDetach = 0x0030,
63 | SystemSessionInformation = 0x0031,
64 | SystemRangeStartInformation = 0x0032,
65 | SystemVerifierInformation = 0x0033,
66 | SystemVerifierThunkExtend = 0x0034,
67 | SystemSessionProcessInformation = 0x0035,
68 | SystemLoadGdiDriverInSystemSpace = 0x0036,
69 | SystemNumaProcessorMap = 0x0037,
70 | SystemPrefetcherInformation = 0x0038,
71 | SystemExtendedProcessInformation = 0x0039,
72 | SystemRecommendedSharedDataAlignment = 0x003A,
73 | SystemComPlusPackage = 0x003B,
74 | SystemNumaAvailableMemory = 0x003C,
75 | SystemProcessorPowerInformation = 0x003D,
76 | SystemEmulationBasicInformation = 0x003E,
77 | SystemEmulationProcessorInformation = 0x003F,
78 | SystemExtendedHandleInformation = 0x0040,
79 | SystemLostDelayedWriteInformation = 0x0041,
80 | SystemBigPoolInformation = 0x0042,
81 | SystemSessionPoolTagInformation = 0x0043,
82 | SystemSessionMappedViewInformation = 0x0044,
83 | SystemHotpatchInformation = 0x0045,
84 | SystemObjectSecurityMode = 0x0046,
85 | SystemWatchdogTimerHandler = 0x0047,
86 | SystemWatchdogTimerInformation = 0x0048,
87 | SystemLogicalProcessorInformation = 0x0049,
88 | SystemWow64SharedInformationObsolete = 0x004A,
89 | SystemRegisterFirmwareTableInformationHandler = 0x004B,
90 | SystemFirmwareTableInformation = 0x004C,
91 | SystemModuleInformationEx = 0x004D,
92 | SystemVerifierTriageInformation = 0x004E,
93 | SystemSuperfetchInformation = 0x004F,
94 | SystemMemoryListInformation = 0x0050,
95 | SystemFileCacheInformationEx = 0x0051,
96 | SystemThreadPriorityClientIdInformation = 0x0052,
97 | SystemProcessorIdleCycleTimeInformation = 0x0053,
98 | SystemVerifierCancellationInformation = 0x0054,
99 | SystemProcessorPowerInformationEx = 0x0055,
100 | SystemRefTraceInformation = 0x0056,
101 | SystemSpecialPoolInformation = 0x0057,
102 | SystemProcessIdInformation = 0x0058,
103 | SystemErrorPortInformation = 0x0059,
104 | SystemBootEnvironmentInformation = 0x005A,
105 | SystemHypervisorInformation = 0x005B,
106 | SystemVerifierInformationEx = 0x005C,
107 | SystemTimeZoneInformation = 0x005D,
108 | SystemImageFileExecutionOptionsInformation = 0x005E,
109 | SystemCoverageInformation = 0x005F,
110 | SystemPrefetchPatchInformation = 0x0060,
111 | SystemVerifierFaultsInformation = 0x0061,
112 | SystemSystemPartitionInformation = 0x0062,
113 | SystemSystemDiskInformation = 0x0063,
114 | SystemProcessorPerformanceDistribution = 0x0064,
115 | SystemNumaProximityNodeInformation = 0x0065,
116 | SystemDynamicTimeZoneInformation = 0x0066,
117 | SystemCodeIntegrityInformation = 0x0067,
118 | SystemProcessorMicrocodeUpdateInformation = 0x0068,
119 | SystemProcessorBrandString = 0x0069,
120 | SystemVirtualAddressInformation = 0x006A,
121 | SystemLogicalProcessorAndGroupInformation = 0x006B,
122 | SystemProcessorCycleTimeInformation = 0x006C,
123 | SystemStoreInformation = 0x006D,
124 | SystemRegistryAppendString = 0x006E,
125 | SystemAitSamplingValue = 0x006F,
126 | SystemVhdBootInformation = 0x0070,
127 | SystemCpuQuotaInformation = 0x0071,
128 | SystemNativeBasicInformation = 0x0072,
129 | SystemErrorPortTimeouts = 0x0073,
130 | SystemLowPriorityIoInformation = 0x0074,
131 | SystemBootEntropyInformation = 0x0075,
132 | SystemVerifierCountersInformation = 0x0076,
133 | SystemPagedPoolInformationEx = 0x0077,
134 | SystemSystemPtesInformationEx = 0x0078,
135 | SystemNodeDistanceInformation = 0x0079,
136 | SystemAcpiAuditInformation = 0x007A,
137 | SystemBasicPerformanceInformation = 0x007B,
138 | SystemQueryPerformanceCounterInformation = 0x007C,
139 | SystemSessionBigPoolInformation = 0x007D,
140 | SystemBootGraphicsInformation = 0x007E,
141 | SystemScrubPhysicalMemoryInformation = 0x007F,
142 | SystemBadPageInformation = 0x0080,
143 | SystemProcessorProfileControlArea = 0x0081,
144 | SystemCombinePhysicalMemoryInformation = 0x0082,
145 | SystemEntropyInterruptTimingInformation = 0x0083,
146 | SystemConsoleInformation = 0x0084,
147 | SystemPlatformBinaryInformation = 0x0085,
148 | SystemThrottleNotificationInformation = 0x0086,
149 | SystemHypervisorProcessorCountInformation = 0x0087,
150 | SystemDeviceDataInformation = 0x0088,
151 | SystemDeviceDataEnumerationInformation = 0x0089,
152 | SystemMemoryTopologyInformation = 0x008A,
153 | SystemMemoryChannelInformation = 0x008B,
154 | SystemBootLogoInformation = 0x008C,
155 | SystemProcessorPerformanceInformationEx = 0x008D,
156 | SystemSpare0 = 0x008E,
157 | SystemSecureBootPolicyInformation = 0x008F,
158 | SystemPageFileInformationEx = 0x0090,
159 | SystemSecureBootInformation = 0x0091,
160 | SystemEntropyInterruptTimingRawInformation = 0x0092,
161 | SystemPortableWorkspaceEfiLauncherInformation = 0x0093,
162 | SystemFullProcessInformation = 0x0094,
163 | MaxSystemInfoClass = 0x0095
164 | } SYSTEM_INFORMATION_CLASS;
165 |
166 | #ifdef _WIN64
167 | //redefine the struct in windows interal header to include undocumented values
168 | typedef struct _PEB_LDR_DATA {
169 | ULONG Length;
170 | UCHAR Initialized;
171 | ULONG64 SsHandle;
172 | LIST_ENTRY64 InLoadOrderModuleList;
173 | LIST_ENTRY64 InMemoryOrderModuleList;
174 | LIST_ENTRY64 InInitializationOrderModuleList;
175 | PVOID64 EntryInProgress;
176 | UCHAR ShutdownInProgress;
177 | PVOID64 ShutdownThreadId;
178 | } PEB_LDR_DATA, *PPEB_LDR_DATA;
179 |
180 | typedef struct _PEB{
181 | UCHAR InheritedAddressSpace;
182 | UCHAR ReadImageFileExecOptions;
183 | UCHAR BeingDebugged;
184 | BYTE Reserved0;
185 | ULONG Reserved1;
186 | ULONG64 Reserved3;
187 | ULONG64 ImageBaseAddress;
188 | ULONG64 LoaderData;
189 | ULONG64 ProcessParameters;
190 | }PEB, *PPEB;
191 |
192 | /** A structure that holds information about a single module loaded by a process **/
193 | /** LIST_ENTRY is a link list pointing to the prev/next Module loaded **/
194 | typedef struct _LDR_DATA_TABLE_ENTRY
195 | {
196 | LIST_ENTRY64 InLoadOrderModuleList;
197 | LIST_ENTRY64 InMemoryOrderModuleList;
198 | LIST_ENTRY64 InInitializationOrderModuleList;
199 | ULONG64 BaseAddress;
200 | ULONG64 EntryPoint;
201 | ULONG SizeOfImage; //bytes
202 | UNICODE_STRING FullDllName;
203 | UNICODE_STRING BaseDllName;
204 | ULONG Flags;
205 | USHORT LoadCount;
206 | } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
207 |
208 | #else
209 | //redefine the struct in windows interal header to include undocumented values
210 | typedef struct _PEB_LDR_DATA {
211 | DWORD Length;
212 | UCHAR Initialized;
213 | PVOID SsHandle;
214 | LIST_ENTRY InLoadOrderModuleList;
215 | LIST_ENTRY InMemoryOrderModuleList;
216 | LIST_ENTRY InInitializationOrderModuleList;
217 | PVOID EntryInProgress;
218 | UCHAR ShutdownInProgress;
219 | PVOID ShutdownThreadId;
220 | } PEB_LDR_DATA, *PPEB_LDR_DATA;
221 |
222 | typedef struct _PEB{
223 | UCHAR InheritedAddressSpace;
224 | UCHAR ReadImageFileExecOptions;
225 | UCHAR BeingDebugged;
226 | BYTE Reserved2[9];
227 | PPEB_LDR_DATA LoaderData;
228 | PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
229 | BYTE Reserved3[448];
230 | ULONG SessionId;
231 | }PEB, *PPEB;
232 |
233 | /** A structure that holds information about a single module loaded by a process **/
234 | /** LIST_ENTRY is a link list pointing to the prev/next Module loaded **/
235 | typedef struct _LDR_DATA_TABLE_ENTRY
236 | {
237 | LIST_ENTRY InLoadOrderModuleList;
238 | LIST_ENTRY InMemoryOrderModuleList;
239 | LIST_ENTRY InInitializationOrderModuleList;
240 | PVOID BaseAddress;
241 | PVOID EntryPoint;
242 | ULONG SizeOfImage;
243 | UNICODE_STRING FullDllName;
244 | UNICODE_STRING BaseDllName;
245 | ULONG Flags;
246 | USHORT LoadCount;
247 | USHORT TlsIndex;
248 | LIST_ENTRY HashTableEntry;
249 | union
250 | {
251 | LIST_ENTRY HashLinks;
252 | struct
253 | {
254 | PVOID SectionPointer;
255 | ULONG CheckSum;
256 | };
257 | };
258 | union
259 | {
260 | ULONG TimeDateStamp;
261 | PVOID LoadedImports;
262 | };
263 | _ACTIVATION_CONTEXT * EntryPointActivationContext;
264 | PVOID PatchInformation;
265 | LIST_ENTRY ForwarderLinks;
266 | LIST_ENTRY ServiceTagLinks;
267 | LIST_ENTRY StaticLinks;
268 | PVOID ContextInformation;
269 | DWORD OriginalBase;
270 | LARGE_INTEGER LoadTime;
271 | } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
272 | #endif
273 | }
274 |
275 | typedef struct _SYSTEM_PROCESS_INFO
276 | {
277 | ULONG NextEntryOffset;
278 | ULONG NumberOfThreads;
279 | LARGE_INTEGER SpareLi1;
280 | LARGE_INTEGER SpareLi2;
281 | LARGE_INTEGER SpareLi3;
282 | LARGE_INTEGER CreateTime;
283 | LARGE_INTEGER UserTime;
284 | LARGE_INTEGER KernelTime;
285 | UNICODE_STRING ImageName;
286 | ULONG BasePriority;
287 | #ifdef _WIN64
288 | ULONG pad1;
289 | ULONG UniqueProcessId;
290 | ULONG pad2;
291 | ULONG InheritedFromUniqueProcessId;
292 | ULONG pad3, pad4, pad5;
293 | #else
294 | ULONG UniqueProcessId;
295 | ULONG InheritedFromUniqueProcessId;
296 | #endif
297 | ULONG HandleCount;
298 | ULONG SessionId;
299 | PVOID PageDirectoryBase;
300 | ULONG VirtualMemoryCounters;
301 | SIZE_T PrivatePageCount;
302 | IO_COUNTERS IoCounters;
303 | PVOID Reserved[1];
304 | }SYSTEM_PROCESS_INFO, *PSYSTEM_PROCESS_INFO;
305 |
306 | typedef NTSTATUS(NTAPI *_ntQSI)(
307 | IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
308 | IN OUT PVOID SystemInformation,
309 | IN ULONG SystemInformationLength,
310 | OUT PULONG ReturnLength OPTIONAL
311 | );
312 |
313 | typedef NTSTATUS(NTAPI * pNtQueryInformationProcess)
314 | (
315 | HANDLE,
316 | PROCESSINFOCLASS,
317 | PVOID,
318 | ULONG,
319 | PULONG
320 | );
321 |
322 | class Process{
323 | private:
324 | All_SYS::PLDR_DATA_TABLE_ENTRY GetNextNode(PCHAR nNode, int Offset);
325 | All_SYS::PLDR_DATA_TABLE_ENTRY GetPrevNode(PCHAR nNode, int Offset);
326 | BOOL RemoveDLL(DWORD PID, std::wstring DLLtoRemove, int ListType);
327 |
328 | public:
329 | BOOL DLLInLoadStatus = FALSE;
330 | BOOL DLLInMemStatus = FALSE;
331 | BOOL DLLInInInitializationStatus = FALSE;
332 |
333 | Process(std::string Proc, std::wstring DLLName);
334 | ~Process();
335 |
336 | struct Process_INFO{
337 | DWORD Process_ID = 0;
338 | std::string Process_Name = "";
339 | std::string Create_Time = "";
340 | ULONG HandleCount = 0;
341 | ULONG ModuleCount = 0;
342 | ULONG ThreadCount = 0;
343 | }Pinfo;
344 |
345 | Process_INFO GetProcessInfo(std::string & PN);
346 |
347 | void ListModules(DWORD PID, int ListType, int Order);
348 | };
349 |
350 | #endif
--------------------------------------------------------------------------------
/DLLHiding/Source.cpp:
--------------------------------------------------------------------------------
1 | #include "Process.h"
2 | #include
3 |
4 | inline const char * const BoolToString(const bool b)
5 | {
6 | return b ? "TRUE" : "FALSE";
7 | }
8 |
9 | //convert string to wstring
10 | std::wstring s2ws(const std::string & s)
11 | {
12 | int len;
13 | int slength = (int)s.length() + 1;
14 | len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
15 | std::wstring r(len, L'\0');
16 | MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, &r[0], len);
17 | return r;
18 | }
19 |
20 | int main(int argc, char* argv[]) {
21 | std::cout << "-----DLL Hider v1.0-----\n" << std::endl;
22 | if (argc > 3 || argc <= 2){
23 | std::cout << "Invalid arguments!" << std::endl;
24 | std::cout << "DllHiding.exe " << std::endl;
25 | std::cout << "example: " << "DllHiding.exe firefox.exe d3d9.dll" << std::endl;
26 | return 0;
27 | }
28 |
29 | std::string strNameProcess = argv[1];
30 | std::string strDLLName = argv[2];
31 | std::wstring wstrDLLName = s2ws(strDLLName);
32 |
33 | Process * A = new Process(strNameProcess, wstrDLLName);
34 |
35 | std::cout << "Process Name: " << strNameProcess << " " << "DLL Name: " << strDLLName << std::endl;
36 | std::cout << "\n" << "Status:" << std::endl;
37 | std::cout << "\t" << "InLoadOrderModuleList: " << BoolToString(A->DLLInLoadStatus) << std::endl;
38 | std::cout << "\t" << "InMemoryOrderModuleList: " << BoolToString(A->DLLInMemStatus) << std::endl;
39 | std::cout << "\t" << "InInitializationOrderModuleList: " << BoolToString(A->DLLInInInitializationStatus) << std::endl;
40 |
41 | //Print InLoadOrderModuleList in forward order
42 | //A->ListModules(A->Pinfo.Process_ID, 0, 0);
43 |
44 | delete A;
45 |
46 | return 0;
47 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DLLHiding
2 | Hiding x32/x64 Modules using PEB
3 |
4 | ##Summary
5 | A simple command-line application to Hide DLLs in any Windows Process. Works on both x32 and x64 Processes.
6 |
7 | It should work on all platforms from Windows XP to Windows 8. Currently only tested on Windows 7.
8 |
9 | Every Process maintains internal set of loaded Modules/DLLs in the form of three linked lists within the PE Block.
10 | - Load Order List
11 | - Memory Order List
12 | - Initialization Order List
13 |
14 | ##Commands
15 | To run in console:
16 | - DLLHiding32.exe "Process Name" "DLL Name"
17 | - DLLHiding64.exe "Process Name" "DLL Name"
18 |
19 | ##Limitations
20 | Should effectively hide modules from all user mode applications. Application with Kernel Mode Access can enumerate the hidden modules such applications include Process Explorer as the Kernel Object remains unchanged. Additionally user mode applications can enumerate the memory of an application using NtQueryVirtualMemory() and find the modules.
21 |
22 | See: https://github.com/SLAUC91/DLLFinder
23 |
24 | ##Motivation
25 | I could not find any source code or support for x64 processes to test some internal software solutions so I developed this application.
26 |
--------------------------------------------------------------------------------