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