Skip to content

Commit 6463238

Browse files
author
bytecode77
committed
Helper.exe -> Helper.dll
1 parent a1bd694 commit 6463238

File tree

20 files changed

+409
-549
lines changed

20 files changed

+409
-549
lines changed

Helper/Helper.c

Lines changed: 92 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -3,70 +3,20 @@
33
#include "r77win.h"
44
#include "r77config.h"
55
#include "r77process.h"
6-
#include <stdio.h>
76
#include <Shlwapi.h>
87
#include <tlhelp32.h>
98
#include <Psapi.h>
109

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)
1211
{
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;
6613
}
6714

68-
int ProcessList()
15+
BOOL GetProcessList(PPROCESS_LIST_ENTRY entries, LPDWORD count)
6916
{
17+
BOOL result = FALSE;
18+
*count = 0;
19+
7020
// Get r77 configuration to determine which processes are hidden by ID.
7121
PR77_CONFIG r77Config = LoadR77Config();
7222

@@ -77,144 +27,119 @@ int ProcessList()
7727

7828
PR77_PROCESS r77Processes = NEW_ARRAY(R77_PROCESS, 1000);
7929
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))
9231
{
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)
10834
{
109-
platform = is64Bit ? 64 : 32;
110-
}
35+
PROCESSENTRY32W processEntry;
36+
processEntry.dwSize = sizeof(PROCESSENTRY32W);
11137

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))
12539
{
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);
13385
}
134-
}
13586

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+
}
15290
}
15391

154-
CloseHandle(snapshot);
92+
DeleteR77Config(r77Config);
93+
FREE(r77Processes);
15594

156-
return 0;
95+
return result;
15796
}
158-
int CreateConfig()
97+
BOOL CreateConfigSystem()
15998
{
16099
HKEY key;
161100
if (InstallR77Config(&key))
162101
{
163102
RegCloseKey(key);
164-
return 0;
103+
return TRUE;
165104
}
166105
else
167106
{
168-
return 1;
107+
return FALSE;
169108
}
170109
}
171-
int Inject(DWORD processId, LPCWSTR dllPath)
110+
BOOL Inject(DWORD processId, LPBYTE dll, DWORD dllSize)
172111
{
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;
179117

180-
if (processId == -1)
118+
LPDWORD processes = NEW_ARRAY(DWORD, 10000);
119+
DWORD processCount = 0;
120+
if (EnumProcesses(processes, sizeof(DWORD) * 10000, &processCount))
181121
{
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);
188123

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++)
197125
{
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);
199129
}
130+
131+
result = TRUE;
200132
}
201-
else
202-
{
203-
// Inject specific process
204-
return InjectDll(processId, dll, dllSize, FALSE) ? 0 : 1;
205-
}
133+
134+
FREE(processes);
135+
return result;
206136
}
207-
int Detach(DWORD processId)
137+
BOOL Detach(DWORD processId)
208138
{
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;
220145
}

0 commit comments

Comments
 (0)