├── .gitattributes ├── .gitignore ├── BruteforceProcessId ├── BruteforceProcessId.vcxproj ├── BruteforceProcessId.vcxproj.filters └── src │ └── BruteforceProcessId.cpp ├── CsrssProcessHandleEnumeration ├── CsrssProcessHandleEnumeration.vcxproj └── src │ └── CrsssProcessHandleEnumeration.cpp ├── DirectNtSystemCalls ├── DirectNtSystemCalls.vcxproj ├── DirectNtSystemCalls.vcxproj.filters └── src │ └── DirectNtSystemCalls.cpp ├── HiddenProcessDetection.sln ├── README.md ├── useful.cpp └── useful.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /BruteforceProcessId/BruteforceProcessId.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {7F6DDAEC-EBB4-4A0F-987D-56D74B1201DE} 15 | Win32Proj 16 | BruteforceProcessId 17 | 18 | 19 | 20 | Application 21 | true 22 | Unicode 23 | 24 | 25 | Application 26 | false 27 | true 28 | Unicode 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | true 42 | 43 | 44 | false 45 | 46 | 47 | 48 | 49 | 50 | Level3 51 | Disabled 52 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 53 | 54 | 55 | Console 56 | true 57 | 58 | 59 | 60 | 61 | Level3 62 | 63 | 64 | MaxSpeed 65 | true 66 | true 67 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 68 | 69 | 70 | Console 71 | true 72 | true 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /BruteforceProcessId/BruteforceProcessId.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;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | 22 | 23 | Header Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /BruteforceProcessId/src/BruteforceProcessId.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "./../../useful.h" 4 | 5 | bool BruteforceProcessIds() 6 | { 7 | HANDLE hProcess = NULL; 8 | DWORD dwExitCode = 0; 9 | ULONG ulHiddenProcesses = 0, ulScannedProccesses = 0; 10 | 11 | for ( DWORD dwProcessId = 0; dwProcessId < 0x83B8; dwProcessId += 4) 12 | { 13 | if ( dwProcessId == 0 || dwProcessId == 4 ) 14 | continue; 15 | 16 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId); 17 | if ( hProcess == NULL ) 18 | { 19 | if ( GetLastError() != ERROR_INVALID_PARAMETER ) 20 | { 21 | // If the error code is other than 22 | // ERROR_INVALID_PARAMETER that means this 23 | // process exists but we are not able to open. 24 | 25 | //check if this process is already discovered 26 | //using standard API functions. 27 | if( !ProcessExist(dwProcessId) ) 28 | { 29 | printf("Hidden process found pid=%d\n", dwProcessId); 30 | ulHiddenProcesses++; 31 | } 32 | 33 | } 34 | continue; 35 | } 36 | 37 | ulScannedProccesses++; 38 | 39 | dwExitCode = 0; 40 | GetExitCodeProcess( hProcess, &dwExitCode ); 41 | 42 | // check if this is active process... 43 | // only active process will return error 44 | // code as ERROR_NO_MORE_ITEMS 45 | if( dwExitCode == ERROR_NO_MORE_ITEMS ) 46 | { 47 | // 48 | // check if this process is already discovered 49 | // process should not exist 50 | // 51 | if( !ProcessExist(dwProcessId) ) 52 | { 53 | printf("Hidden process found pid=%d\n", dwProcessId); 54 | ulHiddenProcesses++; 55 | } 56 | } 57 | 58 | CloseHandle(hProcess); 59 | } 60 | 61 | return ulHiddenProcesses > 0 ? true : false; 62 | } 63 | 64 | int main(int argc, char* argv[]) 65 | { 66 | printf( "This method was first used by BlackLight and it turned out to be very effective yet simple." 67 | "Here, it enumerates through process id from 0 to 0x41DC and then check if that process exist by calling OpenProcess function." 68 | "Then this list of discovered processes are compared with normal process list got using standard enumeration functions (such as Process32First, EnumProcesses functions).\n"); 69 | 70 | SetDebugPrivileges(); 71 | BruteforceProcessIds(); 72 | 73 | return 0; 74 | } -------------------------------------------------------------------------------- /CsrssProcessHandleEnumeration/CsrssProcessHandleEnumeration.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {C77BABDF-E200-4D7B-8E10-D66ED7D73C56} 15 | Win32Proj 16 | CsrssProcessHandleEnumeration 17 | 18 | 19 | 20 | Application 21 | true 22 | Unicode 23 | 24 | 25 | Application 26 | false 27 | true 28 | Unicode 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | true 42 | 43 | 44 | false 45 | 46 | 47 | 48 | 49 | 50 | Level3 51 | Disabled 52 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 53 | 54 | 55 | Console 56 | true 57 | 58 | 59 | 60 | 61 | Level3 62 | 63 | 64 | MaxSpeed 65 | true 66 | true 67 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 68 | 69 | 70 | Console 71 | true 72 | true 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /CsrssProcessHandleEnumeration/src/CrsssProcessHandleEnumeration.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "./../../useful.h" 4 | 5 | NTQUERYSYSTEMINFORMATION NtQuerySystemInformation; 6 | 7 | // 8 | // Csrss contains a list of all running processes. 9 | // We get this list of running processes and compare it with the normal windows API from tlhelp32 (Process32First and Process32Next) 10 | // 11 | 12 | bool CsrssProcessHandleEnumeration() 13 | { 14 | NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation"); 15 | if ( NtQuerySystemInformation == NULL ) 16 | return false; 17 | 18 | LPBYTE pBufHandleTable = NULL; 19 | DWORD dwHandleTableSize = 0x100000; 20 | SYSTEM_HANDLE_INFORMATION* pHandleInformation = NULL; 21 | ULONG ulHiddenProcesses = 0, ulScannedProccesses = 0; 22 | 23 | pBufHandleTable = new BYTE[ dwHandleTableSize ]; 24 | 25 | NtQuerySystemInformation(SystemHandleInformation, (PDWORD)pBufHandleTable, dwHandleTableSize, NULL); 26 | pHandleInformation = (SYSTEM_HANDLE_INFORMATION*)pBufHandleTable; 27 | 28 | for(ULONG i = 0; i< pHandleInformation->HandleCount; i++) 29 | { 30 | DWORD dwProcessId = pHandleInformation->Handles[i].ProcessId; 31 | 32 | if(pHandleInformation->Handles[i].ObjectTypeNumber == HANDLE_TYPE_PROCESS) 33 | { 34 | if ( IsCSRSSProcess(dwProcessId) ) 35 | { 36 | // printf( "type: %08x, handle: %08x\n", pHandleInformation->Handles[i].ObjectTypeNumber, pHandleInformation->Handles[i].Handle); 37 | 38 | // 39 | // ok current process is csrss, now duplicate all process id's and look with normal windows API if process is found 40 | // 41 | HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId); 42 | if ( hProcess != NULL ) 43 | { 44 | HANDLE hTarget = NULL; 45 | if ( DuplicateHandle(hProcess, (HANDLE)pHandleInformation->Handles[i].Handle, GetCurrentProcess(), &hTarget, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, 0) ) 46 | { 47 | DWORD dwTargetId = GetProcessId(hTarget); 48 | if ( dwTargetId != (DWORD)-1 ) 49 | { 50 | ulScannedProccesses++; 51 | 52 | // 53 | // let's see if process is hidden for normal windows API 54 | // 55 | if ( !ProcessExist(dwTargetId) ) 56 | { 57 | printf( "Found hidden process %u\n", dwTargetId ); 58 | ulHiddenProcesses++; 59 | } 60 | } 61 | CloseHandle(hTarget); 62 | } 63 | CloseHandle(hProcess); 64 | } 65 | } 66 | } 67 | } 68 | 69 | delete[] pBufHandleTable; 70 | 71 | return ulHiddenProcesses > 0 ? true : false; 72 | } 73 | 74 | int main(int argc, char* argv[]) 75 | { 76 | printf( "Any windows process when run will have lot of open handles related to process, thread, named objects, file, port, registry, etc. that can be used to detect hidden process." 77 | "One can use the native API function. The effective way to enumerate handles is to use NtQuerySystemInformation with first parameter as SystemHandleInformation." 78 | "It lists the handles from all running processes in the system. For each enumerated handle, it provides information such as handle, handle type and process id of the owning process." 79 | "Hence, by enumerating through all the handles and then using the associated process id, one can detect all possible hidden processes that are not revealed through standard API functions.\n" ); 80 | 81 | 82 | SetDebugPrivileges(); 83 | CsrssProcessHandleEnumeration(); 84 | 85 | return 0; 86 | } 87 | 88 | -------------------------------------------------------------------------------- /DirectNtSystemCalls/DirectNtSystemCalls.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {B93264FE-9214-4DA9-9F2D-558EF5D09260} 15 | Win32Proj 16 | DirectNtSystemCalls 17 | 18 | 19 | 20 | Application 21 | true 22 | Unicode 23 | 24 | 25 | Application 26 | false 27 | true 28 | Unicode 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | true 42 | 43 | 44 | false 45 | 46 | 47 | 48 | 49 | 50 | Level3 51 | Disabled 52 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 53 | 54 | 55 | Console 56 | true 57 | 58 | 59 | 60 | 61 | Level3 62 | 63 | 64 | MaxSpeed 65 | true 66 | true 67 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 68 | 69 | 70 | Console 71 | true 72 | true 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /DirectNtSystemCalls/DirectNtSystemCalls.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;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | 22 | 23 | Header Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /DirectNtSystemCalls/src/DirectNtSystemCalls.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "./../../useful.h" 5 | 6 | DWORD g_dwMajorVersion = 0; 7 | DWORD g_dwMinorVersion = 0; 8 | 9 | #define SystemProcessInformation 5 10 | 11 | __declspec(naked) NTSTATUS __stdcall DirectNTQuerySystemInformation(ULONG SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength) 12 | { 13 | if( g_dwMajorVersion == 5 ) 14 | { 15 | if (g_dwMinorVersion == 0) 16 | { 17 | //For Windows 2000 18 | __asm 19 | { 20 | mov eax, 0x97 21 | lea edx, dword ptr ss:[esp+4] 22 | int 0x2E 23 | ret 0x10 24 | } 25 | } 26 | else if (g_dwMinorVersion == 1) 27 | { 28 | // Windows XP 29 | __asm 30 | { 31 | mov eax, 0xAD 32 | call SystemCall_XP 33 | ret 0x10 34 | 35 | SystemCall_XP: 36 | mov edx, esp 37 | _emit 0x0f 38 | _emit 0x34 //sysenter opcodes... 39 | } 40 | } 41 | } 42 | 43 | //For Windows Vista & Longhorn 44 | else if (g_dwMajorVersion == 6) 45 | { 46 | if (g_dwMinorVersion == 0) 47 | { 48 | __asm 49 | { 50 | mov eax, 0xF8 51 | call SystemCall_VISTA 52 | ret 0x10 53 | 54 | SystemCall_VISTA: 55 | mov edx, esp 56 | _emit 0x0f 57 | _emit 0x34 //sysenter opcodes... 58 | } 59 | } 60 | else if (g_dwMinorVersion == 1) 61 | { 62 | // Windows 7 63 | __asm 64 | { 65 | mov eax, 0x105 66 | call SystemCall_WIN7 67 | ret 0x10 68 | 69 | SystemCall_WIN7: 70 | mov edx, esp 71 | _emit 0x0f 72 | _emit 0x34 //sysenter opcodes... 73 | } 74 | } 75 | else if (g_dwMinorVersion == 2) 76 | { 77 | // 78 | // Windows 8 Wow64 only, you guys need to implement this for every type of windows, like windows 8 x64 and windows 8 wow64 79 | // http://www.ffri.jp/assets/files/research/research_papers/psj10-murakami_EN.pdf 80 | // 81 | 82 | __asm 83 | { 84 | mov eax, 0x34 85 | xor ecx, ecx 86 | lea edx, [esp+4] 87 | call dword ptr fs:[0x0c0] 88 | ret 0x10 89 | } 90 | 91 | } 92 | } 93 | 94 | // 95 | // clean stack up 96 | // 97 | __asm 98 | { 99 | ret 0x10 100 | } 101 | } 102 | 103 | bool CheckProcessesWithDirectSystemCall() 104 | { 105 | OSVERSIONINFO os = { 0 }; 106 | ULONG ulReturnLength = 0; 107 | LPBYTE pProcessList = NULL; 108 | SYSTEM_PROCESS_INFORMATION* pCurrentElement = NULL; 109 | wchar_t szProcessName[ 0x100 ] = { 0 }; 110 | ULONG ulHiddenProcesses = 0, ulScannedProccesses = 0; 111 | 112 | os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 113 | if (!GetVersionEx(&os)) 114 | { 115 | return false; 116 | } 117 | 118 | g_dwMajorVersion = os.dwMajorVersion; 119 | g_dwMinorVersion = os.dwMinorVersion; 120 | 121 | DirectNTQuerySystemInformation(SystemProcessInformation, NULL, 0, &ulReturnLength); 122 | 123 | if ( ulReturnLength <= 0) 124 | { 125 | return false; 126 | } 127 | 128 | pProcessList = new BYTE[ ulReturnLength ]; 129 | 130 | if ( pProcessList ) 131 | { 132 | DirectNTQuerySystemInformation(SystemProcessInformation, pProcessList, ulReturnLength, &ulReturnLength); 133 | if ( ulReturnLength > 0 ) 134 | { 135 | pCurrentElement = (SYSTEM_PROCESS_INFORMATION*)pProcessList; 136 | while (TRUE) 137 | { 138 | ulScannedProccesses++; 139 | 140 | // 141 | // todo: make one snapshot before and compare them both here (right now we are always creating a snapshot... and if a process closes right now we might think its hidden) 142 | // 143 | if ( !ProcessExist((DWORD)pCurrentElement->UniqueProcessId) ) 144 | { 145 | printf( "Found hidden process (or not running anymore): process id=%u\n", pCurrentElement->UniqueProcessId); 146 | ulHiddenProcesses++; 147 | } 148 | 149 | pCurrentElement = (SYSTEM_PROCESS_INFORMATION*)((BYTE*)pCurrentElement + pCurrentElement->NextEntryOffset); 150 | 151 | if ( pCurrentElement->NextEntryOffset == 0 ) 152 | break; 153 | } 154 | } 155 | } 156 | 157 | delete[] pProcessList; 158 | 159 | printf( "Done. Scanned %u processes.\n", ulScannedProccesses); 160 | 161 | return ulHiddenProcesses > 0 ? true : false; 162 | } 163 | 164 | int main(int argc, char* argv[]) 165 | { 166 | printf( "This is very effective method to detect any hidden userland rootkit processes." 167 | "One of the lesser-known methods of enumerating the processes is to use NtQuerySystemInformation function by passing first parameter as SystemProcessesAndThreadsInformation." 168 | "The drawback of this method is that it can be easily circumvented by hooking the NtQuerySystemInformation function and then by tampering with the results.\n"); 169 | 170 | SetDebugPrivileges(); 171 | CheckProcessesWithDirectSystemCall(); 172 | 173 | return 0; 174 | } -------------------------------------------------------------------------------- /HiddenProcessDetection.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BruteforceProcessId", "BruteforceProcessId\BruteforceProcessId.vcxproj", "{7F6DDAEC-EBB4-4A0F-987D-56D74B1201DE}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectNtSystemCalls", "DirectNtSystemCalls\DirectNtSystemCalls.vcxproj", "{B93264FE-9214-4DA9-9F2D-558EF5D09260}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CsrssProcessHandleEnumeration", "CsrssProcessHandleEnumeration\CsrssProcessHandleEnumeration.vcxproj", "{C77BABDF-E200-4D7B-8E10-D66ED7D73C56}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Win32 = Debug|Win32 13 | Release|Win32 = Release|Win32 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {7F6DDAEC-EBB4-4A0F-987D-56D74B1201DE}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {7F6DDAEC-EBB4-4A0F-987D-56D74B1201DE}.Debug|Win32.Build.0 = Debug|Win32 18 | {7F6DDAEC-EBB4-4A0F-987D-56D74B1201DE}.Release|Win32.ActiveCfg = Release|Win32 19 | {7F6DDAEC-EBB4-4A0F-987D-56D74B1201DE}.Release|Win32.Build.0 = Release|Win32 20 | {B93264FE-9214-4DA9-9F2D-558EF5D09260}.Debug|Win32.ActiveCfg = Debug|Win32 21 | {B93264FE-9214-4DA9-9F2D-558EF5D09260}.Debug|Win32.Build.0 = Debug|Win32 22 | {B93264FE-9214-4DA9-9F2D-558EF5D09260}.Release|Win32.ActiveCfg = Release|Win32 23 | {B93264FE-9214-4DA9-9F2D-558EF5D09260}.Release|Win32.Build.0 = Release|Win32 24 | {C77BABDF-E200-4D7B-8E10-D66ED7D73C56}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {C77BABDF-E200-4D7B-8E10-D66ED7D73C56}.Debug|Win32.Build.0 = Debug|Win32 26 | {C77BABDF-E200-4D7B-8E10-D66ED7D73C56}.Release|Win32.ActiveCfg = Release|Win32 27 | {C77BABDF-E200-4D7B-8E10-D66ED7D73C56}.Release|Win32.Build.0 = Release|Win32 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | EndGlobal 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | HiddenProcessDetection 2 | ====================== 3 | 4 | Examples for detection of hidden processes on windows. 5 | Examples are based on http://www.rootkitanalytics.com/userland/Hidden-Process-Detection.php 6 | 7 | -------------------------------------------------------------------------------- /useful.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "useful.h" 5 | 6 | /* 7 | * Sets debug privileges to current process. 8 | */ 9 | bool SetDebugPrivileges() 10 | { 11 | HANDLE hToken; 12 | LUID LuidValue; 13 | TOKEN_PRIVILEGES tp; 14 | bool fResult = false; 15 | 16 | if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 17 | { 18 | if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &LuidValue)) 19 | { 20 | tp.PrivilegeCount = 1; 21 | tp.Privileges[0].Luid = LuidValue; 22 | tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 23 | if (AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL)) 24 | { 25 | fResult = true; 26 | } 27 | } 28 | CloseHandle(hToken); 29 | } 30 | 31 | return fResult; 32 | } 33 | 34 | 35 | /* 36 | * Returns true if Process ID is found. 37 | */ 38 | bool GetProcessName(DWORD dwProcessId, wchar_t* szProcessName, size_t nMaxProcessName) 39 | { 40 | bool fResult = false; 41 | HANDLE hSnapshot = NULL; 42 | PROCESSENTRY32 pe32 = { 0 }; 43 | 44 | hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0 ); 45 | if ( hSnapshot != INVALID_HANDLE_VALUE ) 46 | { 47 | pe32.dwSize = sizeof(PROCESSENTRY32); 48 | if (Process32First(hSnapshot, &pe32)) 49 | { 50 | do 51 | { 52 | if ( pe32.th32ProcessID == dwProcessId) 53 | { 54 | memset(szProcessName, 0, nMaxProcessName); 55 | wcsncpy_s(szProcessName, nMaxProcessName, pe32.szExeFile, __min(nMaxProcessName, wcslen(pe32.szExeFile))); 56 | fResult = true; 57 | break; 58 | } 59 | } while (Process32Next(hSnapshot, &pe32)); 60 | } 61 | CloseHandle(hSnapshot); 62 | } 63 | 64 | 65 | return fResult; 66 | } 67 | 68 | /* 69 | * Returns true if process id has been found. 70 | */ 71 | bool ProcessExist(DWORD dwProcessId) 72 | { 73 | bool fResult = false; 74 | HANDLE hSnapshot = NULL; 75 | PROCESSENTRY32 pe32 = { 0 }; 76 | 77 | hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0 ); 78 | if ( hSnapshot != INVALID_HANDLE_VALUE ) 79 | { 80 | pe32.dwSize = sizeof(PROCESSENTRY32); 81 | if (Process32First(hSnapshot, &pe32)) 82 | { 83 | do 84 | { 85 | if ( pe32.th32ProcessID == dwProcessId) 86 | { 87 | // 88 | // process found, abort 89 | // 90 | fResult = true; 91 | break; 92 | } 93 | } while (Process32Next(hSnapshot, &pe32)); 94 | } 95 | CloseHandle(hSnapshot); 96 | } 97 | 98 | return fResult; 99 | } 100 | 101 | 102 | /* 103 | * Returns true if process name is csrss.exe 104 | */ 105 | bool IsCSRSSProcess(DWORD dwProcessId) 106 | { 107 | wchar_t szName[ 0x100 ]= { 0 }; 108 | 109 | if (GetProcessName(dwProcessId, szName, sizeof(szName)/sizeof(szName[0]))) 110 | { 111 | if (_wcsicmp(L"csrss.exe", szName) == 0 ) 112 | return true; 113 | } 114 | return false; 115 | } 116 | 117 | -------------------------------------------------------------------------------- /useful.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | /* The following structure is actually called SYSTEM_HANDLE_TABLE_ENTRY_INFO, but SYSTEM_HANDLE is shorter. */ 5 | typedef struct _SYSTEM_HANDLE 6 | { 7 | ULONG ProcessId; 8 | BYTE ObjectTypeNumber; 9 | BYTE Flags; 10 | USHORT Handle; 11 | PVOID Object; 12 | ACCESS_MASK GrantedAccess; 13 | } SYSTEM_HANDLE, *PSYSTEM_HANDLE; 14 | 15 | typedef struct _SYSTEM_HANDLE_INFORMATION 16 | { 17 | ULONG HandleCount; /* Or NumberOfHandles if you prefer. */ 18 | SYSTEM_HANDLE Handles[1]; 19 | } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; 20 | 21 | 22 | #define SystemProcessInformation 5 23 | #define SystemHandleInformation 16 24 | 25 | // For XP & 2K3 : HANDLE_TYPE_PROCESS = 0x5 26 | // For Vista & Longhorn : HANDLE_TYPE_PROCESS = 0x6 27 | // Windows 8: HANDLE_TYPE_PROCESS = 0x7 28 | #define HANDLE_TYPE_PROCESS 7 29 | 30 | 31 | typedef DWORD (CALLBACK* NTQUERYSYSTEMINFORMATION)( DWORD , PDWORD , DWORD , PVOID ); 32 | 33 | 34 | bool SetDebugPrivileges(); 35 | bool ProcessExist(DWORD dwProcessId); 36 | bool GetProcessName(DWORD dwProcessId, wchar_t* szProcessName, size_t nMaxProcessName); 37 | bool IsCSRSSProcess(DWORD dwProcessId); 38 | --------------------------------------------------------------------------------