├── 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 | --------------------------------------------------------------------------------