2023-06-05 21:23:08 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2023-06-25 09:32:19 +00:00
|
|
|
#include <inject.h>
|
2023-06-26 09:53:07 +00:00
|
|
|
#include <envs.h>
|
2023-06-05 21:23:08 +00:00
|
|
|
|
2023-06-25 09:32:19 +00:00
|
|
|
#include <launcher_p.h>
|
2023-06-05 21:23:08 +00:00
|
|
|
|
2023-07-03 11:04:04 +00:00
|
|
|
const wchar_t *LAUNCHER_INJECT_DLL = L"launcher_payload.dll";
|
|
|
|
const wchar_t *GAME_INJECT_DLL = L"game_payload.dll";
|
2023-06-05 21:23:08 +00:00
|
|
|
|
2023-06-11 15:04:24 +00:00
|
|
|
#define SHIFT(argc, argv) argc--, argv++
|
|
|
|
|
2023-07-03 11:04:04 +00:00
|
|
|
int wmain(int argc, wchar_t **argv) {
|
2023-06-05 21:23:08 +00:00
|
|
|
// Read arguments
|
2023-07-03 11:04:04 +00:00
|
|
|
wchar_t *gamePath = NULL;
|
|
|
|
wchar_t *launcherPath = NULL;
|
2023-06-05 21:23:08 +00:00
|
|
|
|
2023-06-11 15:04:24 +00:00
|
|
|
// Skip executable
|
|
|
|
SHIFT(argc, argv);
|
|
|
|
|
2023-06-05 21:23:08 +00:00
|
|
|
switch (argc) {
|
2023-06-11 15:04:24 +00:00
|
|
|
case 0:
|
2023-07-03 11:04:04 +00:00
|
|
|
wprintf(L"Usage: wine jadeite.exe [game path] <launcher path>\n");
|
2023-06-05 21:23:08 +00:00
|
|
|
return 0;
|
2023-06-11 15:04:24 +00:00
|
|
|
case 1:
|
|
|
|
gamePath = argv[0];
|
|
|
|
SHIFT(argc, argv);
|
|
|
|
|
2023-07-03 11:04:04 +00:00
|
|
|
launcherPath = L"--";
|
2023-06-11 15:04:24 +00:00
|
|
|
|
2023-06-05 21:23:08 +00:00
|
|
|
break;
|
|
|
|
default:
|
2023-06-11 15:04:24 +00:00
|
|
|
gamePath = argv[0];
|
|
|
|
SHIFT(argc, argv);
|
|
|
|
|
|
|
|
launcherPath = argv[0];
|
|
|
|
SHIFT(argc, argv);
|
|
|
|
|
|
|
|
break;
|
2023-06-05 21:23:08 +00:00
|
|
|
}
|
|
|
|
|
2023-06-11 15:04:24 +00:00
|
|
|
// Default launcher path
|
2023-07-03 11:04:04 +00:00
|
|
|
if (wcscmp(launcherPath, L"--") == 0) {
|
|
|
|
wprintf(L"No launcher process specified! Using explorer.exe\n");
|
|
|
|
launcherPath = L"C:\\Windows\\explorer.exe";
|
2023-06-11 15:04:24 +00:00
|
|
|
}
|
|
|
|
|
2023-06-07 17:09:02 +00:00
|
|
|
// cd into the injector directory
|
2023-07-03 11:04:04 +00:00
|
|
|
wchar_t injectorPath[MAX_PATH];
|
|
|
|
GetModuleFileNameW(GetModuleHandleW(NULL), injectorPath, MAX_PATH);
|
2023-06-07 17:09:02 +00:00
|
|
|
|
2023-07-03 11:04:04 +00:00
|
|
|
*(wcsrchr(injectorPath, L'\\')) = L'\0';
|
2023-06-07 17:09:02 +00:00
|
|
|
|
2023-07-03 11:04:04 +00:00
|
|
|
SetCurrentDirectoryW(injectorPath);
|
2023-06-07 17:09:02 +00:00
|
|
|
|
2023-06-05 21:23:08 +00:00
|
|
|
// Compute absolute paths
|
2023-07-03 11:04:04 +00:00
|
|
|
wchar_t gameExePath[MAX_PATH];
|
|
|
|
GetFullPathNameW(gamePath, MAX_PATH, gameExePath, NULL);
|
2023-06-05 21:23:08 +00:00
|
|
|
|
2023-07-03 11:04:04 +00:00
|
|
|
wchar_t gamePayloadPath[MAX_PATH];
|
|
|
|
GetFullPathNameW(GAME_INJECT_DLL, MAX_PATH, gamePayloadPath, NULL);
|
2023-06-05 21:23:08 +00:00
|
|
|
|
2023-07-03 11:04:04 +00:00
|
|
|
wchar_t launcherPayloadPath[MAX_PATH];
|
|
|
|
GetFullPathNameW(LAUNCHER_INJECT_DLL, MAX_PATH, launcherPayloadPath, NULL);
|
2023-06-05 21:23:08 +00:00
|
|
|
|
2023-06-11 15:04:24 +00:00
|
|
|
// Construct commandline for the game process
|
2023-07-03 11:04:04 +00:00
|
|
|
wchar_t cmdline[8192];
|
|
|
|
wsprintfW(cmdline, L"\"%ls\"", gameExePath);
|
2023-06-11 15:04:24 +00:00
|
|
|
|
|
|
|
while (argc) {
|
2023-07-03 11:04:04 +00:00
|
|
|
wchar_t arg[8192];
|
|
|
|
wsprintfW(arg, L" \"%ls\"", argv[0]);
|
|
|
|
wcscat(cmdline, arg);
|
2023-06-11 15:04:24 +00:00
|
|
|
|
|
|
|
SHIFT(argc, argv);
|
|
|
|
}
|
2023-06-05 21:23:08 +00:00
|
|
|
|
|
|
|
// Set envvars
|
2023-07-03 11:04:04 +00:00
|
|
|
SetEnvironmentVariableW(ENV_EXE_PATH, gameExePath);
|
|
|
|
SetEnvironmentVariableW(ENV_DLL_PATH, gamePayloadPath);
|
|
|
|
SetEnvironmentVariableW(ENV_PROC_CMD, cmdline);
|
2023-06-05 21:23:08 +00:00
|
|
|
|
|
|
|
// Start the launcher
|
2023-07-03 11:04:04 +00:00
|
|
|
wprintf(L"Starting '%ls' via '%ls'\n", gameExePath, launcherPath);
|
2023-06-11 15:04:24 +00:00
|
|
|
|
2023-07-03 11:04:04 +00:00
|
|
|
STARTUPINFOW si;
|
2023-06-05 21:23:08 +00:00
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
|
|
|
|
|
|
PROCESS_INFORMATION pi;
|
|
|
|
si.cb = sizeof(si);
|
|
|
|
ZeroMemory(&pi, sizeof(pi));
|
|
|
|
|
2023-07-03 11:04:04 +00:00
|
|
|
if (!CreateProcessW(
|
2023-06-05 21:23:08 +00:00
|
|
|
launcherPath,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
FALSE,
|
|
|
|
CREATE_SUSPENDED,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&si,
|
|
|
|
&pi
|
|
|
|
)) {
|
2023-07-03 11:04:04 +00:00
|
|
|
fwprintf(stderr, L"Could not start process! (%ld)\n", GetLastError());
|
2023-06-05 21:23:08 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2023-07-03 11:04:04 +00:00
|
|
|
wprintf(L"Started launcher process (%ld)\n", pi.dwProcessId);
|
2023-06-05 21:23:08 +00:00
|
|
|
|
|
|
|
// Inject
|
2023-06-25 09:32:19 +00:00
|
|
|
void *payloadStart = &_binary_launcher_p_o_p_launcher_p_bin_start;
|
|
|
|
size_t payloadSize = (size_t)&_binary_launcher_p_o_p_launcher_p_bin_size; // yes this is valid
|
2023-06-05 21:23:08 +00:00
|
|
|
inject(pi.hProcess, payloadStart, payloadSize, launcherPayloadPath);
|
|
|
|
|
|
|
|
// Resume the process
|
|
|
|
ResumeThread(pi.hThread);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|