@@ -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+ }
0 commit comments