Skip to content

Commit 43f8357

Browse files
committed
GWToolbox now inject dll
1 parent 1073e32 commit 43f8357

File tree

5 files changed

+132
-7
lines changed

5 files changed

+132
-7
lines changed

GWToolbox/Inject.cpp

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ bool InjectWindow::AskInjectProcess(Process *target_process)
1515
}
1616

1717
if (processes.empty()) {
18-
MessageBoxW(0, L"Error: Guild Wars not running", L"GWToolbox++", MB_ICONERROR);
18+
// MessageBoxW(0, L"Error: Guild Wars not running", L"GWToolbox++", MB_ICONERROR);
1919
return false;
2020
}
2121

@@ -232,3 +232,109 @@ void InjectWindow::OnEvent(HWND hwnd, LONG control_id, LONG notification_code)
232232
SetEvent(m_event);
233233
}
234234
}
235+
236+
static LPVOID GetLoadLibrary()
237+
{
238+
HMODULE Kernel32 = GetModuleHandleW(L"Kernel32.dll");
239+
if (Kernel32 == NULL)
240+
{
241+
fprintf(stderr, "GetModuleHandleW failed (%lu)\n", GetLastError());
242+
return NULL;
243+
}
244+
245+
LPVOID pLoadLibraryW = GetProcAddress(Kernel32, "LoadLibraryW");
246+
if (pLoadLibraryW == NULL)
247+
{
248+
fprintf(stderr, "GetProcAddress failed (%lu)\n", GetLastError());
249+
return NULL;
250+
}
251+
252+
return pLoadLibraryW;
253+
}
254+
255+
bool InjectRemoteThread(Process& process, LPCWSTR ImagePath, LPDWORD lpExitCode)
256+
{
257+
*lpExitCode = 0;
258+
259+
HANDLE ProcessHandle = process.GetHandle();
260+
if (ProcessHandle == NULL)
261+
{
262+
fprintf(stderr, "Can't inject a dll in a process which is not open\n");
263+
return FALSE;
264+
}
265+
266+
LPVOID pLoadLibraryW = GetLoadLibrary();
267+
if (pLoadLibraryW == NULL)
268+
return FALSE;
269+
270+
size_t ImagePathLength = wcslen(ImagePath);
271+
size_t ImagePathSize = (ImagePathLength * 2) + 2;
272+
273+
LPVOID ImagePathAddress = VirtualAllocEx(
274+
ProcessHandle,
275+
NULL,
276+
ImagePathSize,
277+
MEM_COMMIT | MEM_RESERVE,
278+
PAGE_READWRITE);
279+
280+
if (ImagePathAddress == NULL)
281+
{
282+
fprintf(stderr, "VirtualAllocEx failed (%lu)\n", GetLastError());
283+
return FALSE;
284+
}
285+
286+
SIZE_T BytesWritten;
287+
BOOL Success = WriteProcessMemory(
288+
ProcessHandle,
289+
ImagePathAddress,
290+
ImagePath,
291+
ImagePathSize,
292+
&BytesWritten);
293+
294+
if (!Success || (ImagePathSize != BytesWritten))
295+
{
296+
fprintf(stderr, "WriteProcessMemory failed (%lu)\n", GetLastError());
297+
VirtualFreeEx(ProcessHandle, ImagePathAddress, 0, MEM_RELEASE);
298+
return FALSE;
299+
}
300+
301+
DWORD ThreadId;
302+
HANDLE hThread = CreateRemoteThreadEx(
303+
ProcessHandle,
304+
NULL,
305+
0,
306+
reinterpret_cast<LPTHREAD_START_ROUTINE>(pLoadLibraryW),
307+
ImagePathAddress,
308+
0,
309+
NULL,
310+
&ThreadId);
311+
312+
if (hThread == NULL)
313+
{
314+
fprintf(stderr, "CreateRemoteThreadEx failed (%lu)\n", GetLastError());
315+
return FALSE;
316+
}
317+
318+
DWORD Reason = WaitForSingleObject(hThread, INFINITE);
319+
if (Reason != WAIT_OBJECT_0)
320+
{
321+
fprintf(stderr, "WaitForSingleObject failed {reason: %lu, error: %lu}\n", Reason, GetLastError());
322+
CloseHandle(hThread);
323+
return FALSE;
324+
}
325+
326+
VirtualFreeEx(ProcessHandle, ImagePathAddress, 0, MEM_RELEASE);
327+
328+
DWORD ExitCode;
329+
Success = GetExitCodeThread(hThread, &ExitCode);
330+
CloseHandle(hThread);
331+
332+
if (Success == FALSE)
333+
{
334+
fprintf(stderr, "GetExitCodeThread failed (%lu)\n", GetLastError());
335+
return FALSE;
336+
}
337+
338+
*lpExitCode = ExitCode;
339+
return TRUE;
340+
}

GWToolbox/Inject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,5 @@ class InjectWindow
4545

4646
int m_selected;
4747
};
48+
49+
bool InjectRemoteThread(Process& process, LPCWSTR ImagePath, LPDWORD lpExitCode);

GWToolbox/Options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void ParseCommandLine(int argc, char *argv[])
3838
options.uninstall = true;
3939
} else if (strcmp(arg, "--reinstall") == 0) {
4040
options.reinstall = true;
41-
} else if (strcmp(arg, "--pid")) {
41+
} else if (strcmp(arg, "--pid") == 0) {
4242
fprintf(stderr, "Process id\n");
4343
if (++i == argc) {
4444
fprintf(stderr, "'--pid' must be followed by a process id\n");

GWToolbox/Process.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ class Process
5050
bool GetModule(ProcessModule *module, const wchar_t *module_name);
5151
bool GetModules(std::vector<ProcessModule>& modules);
5252

53+
HANDLE GetHandle() { return m_hProcess; }
5354
uint32_t GetProcessId();
5455
private:
55-
void *m_hProcess;
56+
HANDLE m_hProcess;
5657
};
5758

5859
bool GetProcesses(std::vector<Process>& processes, const wchar_t *name, DWORD rights = PROCESS_ALL_ACCESS);

GWToolbox/main.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ bool IsRunningAsAdmin()
4242
}
4343

4444
FreeSid(AdministratorsGroup);
45-
return true;
45+
return (IsRunAsAdmin != FALSE);
4646
}
4747

4848
static bool CreateProcessAsAdmin(const wchar_t *path, const wchar_t *args, const wchar_t *workdir)
@@ -146,18 +146,34 @@ int main(int argc, char *argv[])
146146
}
147147
} else {
148148
if (!InjectWindow::AskInjectProcess(&proc)) {
149-
fprintf(stderr, "InjectWindow::AskInjectName failed\n");
150-
return 1;
149+
if (IsRunningAsAdmin()) {
150+
fprintf(stderr, "InjectWindow::AskInjectName failed\n");
151+
return 1;
152+
} else {
153+
wchar_t args[64];
154+
swprintf(args, 64, L"--pid %lu", proc.GetProcessId());
155+
RestartAsAdmin(args);
156+
return 0;
157+
}
151158
}
152159
}
153160

154161
if (!EnableDebugPrivilege() && !IsRunningAsAdmin()) {
155162
wchar_t args[64];
156163
swprintf(args, 64, L"--pid %lu", proc.GetProcessId());
157164
RestartAsAdmin(args);
165+
return 0;
158166
}
159167

160-
// InjectRemoteThread(proc, L"");
168+
DWORD ExitCode;
169+
if (!InjectRemoteThread(proc, L"D:\\GWToolboxpp\\Debug\\GWToolboxdll.dll", &ExitCode)) {
170+
if (!IsRunningAsAdmin()) {
171+
wchar_t args[64];
172+
swprintf(args, 64, L"--pid %lu", proc.GetProcessId());
173+
RestartAsAdmin(args);
174+
return 0;
175+
}
176+
}
161177

162178
return 0;
163179
}

0 commit comments

Comments
 (0)