3
3
#include "r77win.h"
4
4
#include "r77config.h"
5
5
#include "r77process.h"
6
- #include <stdio.h>
7
6
#include <Shlwapi.h>
8
7
#include <tlhelp32.h>
9
8
#include <Psapi.h>
10
9
11
- int CALLBACK WinMain (_In_ HINSTANCE instance , _In_opt_ HINSTANCE previousInstance , _In_ LPSTR commandLine , _In_ int cmdShow )
10
+ BOOL WINAPI DllMain (_In_ HINSTANCE module , _In_ DWORD reason , _In_ LPVOID reserved )
12
11
{
13
- EnabledDebugPrivilege ();
14
-
15
- int argCount ;
16
- LPWSTR * args = CommandLineToArgvW (GetCommandLineW (), & argCount );
17
- if (!args ) return 1 ;
18
-
19
- if (argCount == 1 )
20
- {
21
- MessageBoxW (NULL , L"This is a commandline utility used by TestConsole.exe" , COALESCE_BITNESS (L"Helper32.exe" , L"Helper64.exe" ), MB_ICONASTERISK | MB_OK );
22
- return 1 ;
23
- }
24
- // Helper32|64.exe -config
25
- else if (argCount == 2 && !StrCmpIW (args [1 ], L"-config" ))
26
- {
27
- return CreateConfig ();
28
- }
29
- // Helper32|64.exe -list
30
- else if (argCount == 2 && !StrCmpIW (args [1 ], L"-list" ))
31
- {
32
- return ProcessList ();
33
- }
34
- // All processes: Helper32|64.exe -inject -all "C:\path\to\r77-*.dll"
35
- // Specific PID: Helper32|64.exe -inject 1234 "C:\path\to\r77-*.dll"
36
- else if (argCount == 4 && !StrCmpIW (args [1 ], L"-inject" ))
37
- {
38
- if (!StrCmpIW (args [2 ], L"-all" ))
39
- {
40
- return Inject (-1 , args [3 ]);
41
- }
42
- else
43
- {
44
- DWORD processId = _wtol (args [2 ]);
45
- return processId == 0 ? 1 : Inject (processId , args [3 ]);
46
- }
47
- }
48
- // All processes: Helper32|64.exe -detach -all
49
- // Specific PID: Helper32|64.exe -detach 1234
50
- else if (argCount == 3 && !StrCmpIW (args [1 ], L"-detach" ))
51
- {
52
- if (!StrCmpIW (args [2 ], L"-all" ))
53
- {
54
- return Detach (-1 );
55
- }
56
- else
57
- {
58
- DWORD processId = _wtol (args [2 ]);
59
- return processId == 0 ? 1 : Detach (processId );
60
- }
61
- }
62
- else
63
- {
64
- return 1 ;
65
- }
12
+ return TRUE;
66
13
}
67
14
68
- int ProcessList ( )
15
+ BOOL GetProcessList ( PPROCESS_LIST_ENTRY entries , LPDWORD count )
69
16
{
17
+ BOOL result = FALSE;
18
+ * count = 0 ;
19
+
70
20
// Get r77 configuration to determine which processes are hidden by ID.
71
21
PR77_CONFIG r77Config = LoadR77Config ();
72
22
@@ -77,144 +27,119 @@ int ProcessList()
77
27
78
28
PR77_PROCESS r77Processes = NEW_ARRAY (R77_PROCESS , 1000 );
79
29
DWORD r77ProcessCount = 1000 ;
80
- if (!GetR77Processes (r77Processes , & r77ProcessCount )) r77ProcessCount = 0 ;
81
-
82
- HANDLE snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS , 0 );
83
- if (snapshot == INVALID_HANDLE_VALUE ) return 1 ;
84
-
85
- PROCESSENTRY32W processEntry ;
86
- processEntry .dwSize = sizeof (PROCESSENTRY32W );
87
-
88
- WCHAR fileName [MAX_PATH + 1 ];
89
- WCHAR userName [256 ];
90
-
91
- for (BOOL enumerate = Process32FirstW (snapshot , & processEntry ); enumerate ; enumerate = Process32NextW (snapshot , & processEntry ))
30
+ if (GetR77Processes (r77Processes , & r77ProcessCount ))
92
31
{
93
- // Query following information for each process, using OpenProcess with the least possible DesiredAccess.
94
- fileName [0 ] = L'\0' ;
95
- DWORD platform = -1 ;
96
- DWORD integrityLevel = -1 ;
97
- userName [0 ] = L'\0' ;
98
- DWORD userNameLength = 256 ;
99
- DWORD isInjected = 0 ;
100
- DWORD isR77Service = 0 ;
101
- DWORD isHelper = 0 ;
102
- DWORD isHiddenById = 0 ;
103
-
104
- GetProcessFileName (processEntry .th32ProcessID , TRUE, fileName , MAX_PATH );
105
-
106
- BOOL is64Bit ;
107
- if (Is64BitProcess (processEntry .th32ProcessID , & is64Bit ))
32
+ HANDLE snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS , 0 );
33
+ if (snapshot != INVALID_HANDLE_VALUE )
108
34
{
109
- platform = is64Bit ? 64 : 32 ;
110
- }
35
+ PROCESSENTRY32W processEntry ;
36
+ processEntry . dwSize = sizeof ( PROCESSENTRY32W );
111
37
112
- HANDLE process = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION , FALSE, processEntry .th32ProcessID );
113
- if (process )
114
- {
115
- GetProcessIntegrityLevel (process , & integrityLevel );
116
-
117
- if (!GetProcessUserName (process , userName , & userNameLength )) userName [0 ] = L'\0' ;
118
-
119
- CloseHandle (process );
120
- }
121
-
122
- for (DWORD i = 0 ; i < r77ProcessCount ; i ++ )
123
- {
124
- if (r77Processes [i ].ProcessId == processEntry .th32ProcessID )
38
+ for (BOOL enumerate = Process32FirstW (snapshot , & processEntry ); enumerate ; enumerate = Process32NextW (snapshot , & processEntry ))
125
39
{
126
- // If the process is in the list of r77 processes, its signature will tell what kind of r77 process it is.
127
-
128
- if (r77Processes [i ].Signature == R77_SIGNATURE ) isInjected = 1 ;
129
- else if (r77Processes [i ].Signature == R77_SERVICE_SIGNATURE ) isR77Service = 1 ;
130
- else if (r77Processes [i ].Signature == R77_HELPER_SIGNATURE ) isHelper = 1 ;
131
-
132
- break ;
40
+ PPROCESS_LIST_ENTRY entry = & entries [(* count )++ ];
41
+ entry -> ProcessId = processEntry .th32ProcessID ;
42
+ StrCpyW (entry -> Name , processEntry .szExeFile );
43
+ GetProcessFileName (processEntry .th32ProcessID , TRUE, entry -> FullName , MAX_PATH );
44
+
45
+ BOOL is64Bit ;
46
+ if (Is64BitProcess (processEntry .th32ProcessID , & is64Bit ))
47
+ {
48
+ entry -> Platform = is64Bit ? 64 : 32 ;
49
+ }
50
+ else
51
+ {
52
+ entry -> Platform = -1 ;
53
+ }
54
+
55
+ entry -> IntegrityLevel = -1 ;
56
+ HANDLE process = OpenProcess (PROCESS_QUERY_LIMITED_INFORMATION , FALSE, processEntry .th32ProcessID );
57
+ if (process )
58
+ {
59
+ GetProcessIntegrityLevel (process , & entry -> IntegrityLevel );
60
+
61
+ DWORD userNameLength = 256 ;
62
+ if (!GetProcessUserName (process , entry -> UserName , & userNameLength ))
63
+ {
64
+ entry -> UserName [0 ] = L'\0' ;
65
+ }
66
+
67
+ CloseHandle (process );
68
+ }
69
+
70
+ for (DWORD i = 0 ; i < r77ProcessCount ; i ++ )
71
+ {
72
+ if (r77Processes [i ].ProcessId == processEntry .th32ProcessID )
73
+ {
74
+ // If the process is in the list of r77 processes, its signature will tell what kind of r77 process it is.
75
+
76
+ if (r77Processes [i ].Signature == R77_SIGNATURE ) entry -> IsInjected = TRUE;
77
+ else if (r77Processes [i ].Signature == R77_SERVICE_SIGNATURE ) entry -> IsR77Service = TRUE;
78
+ else if (r77Processes [i ].Signature == R77_HELPER_SIGNATURE ) entry -> IsHelper = TRUE;
79
+
80
+ break ;
81
+ }
82
+ }
83
+
84
+ entry -> IsHiddenById = IntegerListContains (r77Config -> HiddenProcessIds , processEntry .th32ProcessID );
133
85
}
134
- }
135
86
136
- isHiddenById = IntegerListContains (r77Config -> HiddenProcessIds , processEntry .th32ProcessID );
137
-
138
- wprintf
139
- (
140
- L"%ld|%s|%s|%ld|%ld|%s|%ld|%ld|%ld|%ld\n" ,
141
- processEntry .th32ProcessID ,
142
- processEntry .szExeFile ,
143
- fileName ,
144
- platform ,
145
- integrityLevel ,
146
- userName ,
147
- isInjected ,
148
- isR77Service ,
149
- isHelper ,
150
- isHiddenById
151
- );
87
+ CloseHandle (snapshot );
88
+ result = TRUE;
89
+ }
152
90
}
153
91
154
- CloseHandle (snapshot );
92
+ DeleteR77Config (r77Config );
93
+ FREE (r77Processes );
155
94
156
- return 0 ;
95
+ return result ;
157
96
}
158
- int CreateConfig ()
97
+ BOOL CreateConfigSystem ()
159
98
{
160
99
HKEY key ;
161
100
if (InstallR77Config (& key ))
162
101
{
163
102
RegCloseKey (key );
164
- return 0 ;
103
+ return TRUE ;
165
104
}
166
105
else
167
106
{
168
- return 1 ;
107
+ return FALSE ;
169
108
}
170
109
}
171
- int Inject (DWORD processId , LPCWSTR dllPath )
110
+ BOOL Inject (DWORD processId , LPBYTE dll , DWORD dllSize )
172
111
{
173
- // Read r77-x86.dll or r77-x64.dll into memory for reflective DLL injection.
174
- // When r77 is deployed, the DLL does not need to be on the disk; It is injected directly from memory into the remote process.
175
-
176
- LPBYTE dll ;
177
- DWORD dllSize ;
178
- if (!ReadFileContent (dllPath , & dll , & dllSize )) return 1 ;
112
+ return InjectDll (processId , dll , dllSize , FALSE);
113
+ }
114
+ BOOL InjectAll (LPBYTE dll32 , DWORD dll32Size , LPBYTE dll64 , DWORD dll64Size )
115
+ {
116
+ BOOL result = FALSE;
179
117
180
- if (processId == -1 )
118
+ LPDWORD processes = NEW_ARRAY (DWORD , 10000 );
119
+ DWORD processCount = 0 ;
120
+ if (EnumProcesses (processes , sizeof (DWORD ) * 10000 , & processCount ))
181
121
{
182
- // Inject all processes
183
- LPDWORD processes = NEW_ARRAY (DWORD , 10000 );
184
- DWORD processCount = 0 ;
185
- if (EnumProcesses (processes , sizeof (DWORD ) * 10000 , & processCount ))
186
- {
187
- processCount /= sizeof (DWORD );
122
+ processCount /= sizeof (DWORD );
188
123
189
- for (DWORD i = 0 ; i < processCount ; i ++ )
190
- {
191
- InjectDll (processes [i ], dll , dllSize , TRUE);
192
- }
193
-
194
- return 0 ;
195
- }
196
- else
124
+ for (DWORD i = 0 ; i < processCount ; i ++ )
197
125
{
198
- return 1 ;
126
+ // Try both the 32-bit and the 64-bit DLL. Either the first or the second call will succeed.
127
+ InjectDll (processes [i ], dll32 , dll32Size , TRUE);
128
+ InjectDll (processes [i ], dll64 , dll64Size , TRUE);
199
129
}
130
+
131
+ result = TRUE;
200
132
}
201
- else
202
- {
203
- // Inject specific process
204
- return InjectDll (processId , dll , dllSize , FALSE) ? 0 : 1 ;
205
- }
133
+
134
+ FREE (processes );
135
+ return result ;
206
136
}
207
- int Detach (DWORD processId )
137
+ BOOL Detach (DWORD processId )
208
138
{
209
- if (processId == -1 )
210
- {
211
- // Detach from all processes
212
- DetachAllInjectedProcesses ();
213
- return 0 ;
214
- }
215
- else
216
- {
217
- // Detach from specific process
218
- return DetachInjectedProcessById (processId ) ? 0 : 1 ;
219
- }
139
+ return DetachInjectedProcessById (processId );
140
+ }
141
+ BOOL DetachAll ()
142
+ {
143
+ DetachAllInjectedProcesses ();
144
+ return TRUE;
220
145
}
0 commit comments