// The idea of Dynamic Attach on Windows is to inject a thread into remote JVM // that calls JVM_EnqueueOperation() function exported by HotSpot DLL static int inject_thread(int pid, char* pipeName, int argc, char** argv) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) { if (!enable_debug_privileges()) { print_error("Not enough privileges", GetLastError()); return 0; } hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); } if (hProcess == NULL) { print_error("Could not open process", GetLastError()); return 0; } LPTHREAD_START_ROUTINE code = allocate_code(hProcess); LPVOID data = code != NULL ? allocate_data(hProcess, pipeName, argc, argv) : NULL; if (data == NULL) { print_error("Could not allocate memory in target process", GetLastError()); CloseHandle(hProcess); return 0; } int success = 1; HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, code, data, 0, NULL); if (hThread == NULL) { print_error("Could not create remote thread", GetLastError()); success = 0; } else { printf("Connected to remote process\n"); WaitForSingleObject(hThread, INFINITE); DWORD exitCode; GetExitCodeThread(hThread, &exitCode); if (exitCode != 0) { print_error("Attach is not supported by the target process", exitCode); success = 0; } CloseHandle(hThread); } VirtualFreeEx(hProcess, code, 0, MEM_RELEASE); VirtualFreeEx(hProcess, data, 0, MEM_RELEASE); CloseHandle(hProcess); return success; }
DllInjector::DllInjector(std::string dll_path) : dll_path(dll_path) { enable_debug_privileges(); }
int main() { enable_debug_privileges(); if (file_exists(EVERQUEST_CLIENT) == 0) { MessageBox ( NULL, EVERQUEST_CLIENT " not found!\n" APPLICATION_NAME " files must be inside the game folder!", "Error", MB_OK | MB_ICONERROR ); return 1; } if (file_exists(APPLICATION_DLL_NAME) == 0) { MessageBox ( NULL, APPLICATION_DLL_NAME " not found!\n" APPLICATION_NAME " files must be inside the game folder!", "Error", MB_OK | MB_ICONERROR ); return 1; } HWND everquest_window = FindWindow(NULL, EVERQUEST_TITLE); if (everquest_window == NULL) { MessageBox ( NULL, EVERQUEST_TITLE " window not found!\nPlease start " EVERQUEST_CLIENT " first!", "Error", MB_OK | MB_ICONERROR ); return 1; } DWORD processes[1024]; DWORD needed; if (!EnumProcesses(processes, sizeof(processes), &needed)) { return 1; } DWORD num_processes = needed / sizeof(DWORD); unsigned int i; for (i = 0; i < num_processes; i++) { if (processes[i] != 0) { HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processes[i]); if (process_handle != NULL) { HMODULE module; DWORD needed_ex; if (EnumProcessModules(process_handle, &module, sizeof(module), &needed_ex)) { char process_name[MAX_PATH] = {0}; GetModuleBaseName(process_handle, module, process_name, sizeof(process_name)); if (strcmp(process_name, EVERQUEST_CLIENT) == 0) { char dll_path_name[MAX_PATH] = {0}; GetFullPathName(APPLICATION_DLL_NAME, MAX_PATH, dll_path_name, NULL); LPVOID remote_memory = VirtualAllocEx(process_handle, NULL, strlen(dll_path_name), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(process_handle, remote_memory, dll_path_name, strlen(dll_path_name), NULL); HANDLE remote_thread = CreateRemoteThread(process_handle, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA"), remote_memory, 0, NULL); WaitForSingleObject(remote_thread, INFINITE); VirtualFreeEx(process_handle, remote_memory, strlen(dll_path_name), MEM_RELEASE); CloseHandle(remote_thread); } } } CloseHandle(process_handle); } } /* DWORD process_id; GetWindowThreadProcessId(everquest_window, &process_id); HANDLE process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id); char dll_path_name[MAX_PATH] = {0}; GetFullPathName(APPLICATION_DLL_NAME, MAX_PATH, dll_path_name, NULL); LPVOID remote_memory = VirtualAllocEx(process_handle, NULL, strlen(dll_path_name), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(process_handle, remote_memory, dll_path_name, strlen(dll_path_name), NULL); HANDLE remote_thread = CreateRemoteThread(process_handle, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA"), remote_memory, 0, NULL); WaitForSingleObject(remote_thread, INFINITE); VirtualFreeEx(process_handle, remote_memory, strlen(dll_path_name), MEM_RELEASE); CloseHandle(remote_thread); CloseHandle(process_handle); */ return EXIT_SUCCESS; }