8 Commits

Author SHA1 Message Date
e29b27bfd1 v1.0.1 2023-06-07 21:00:17 +03:00
bcbc679a21 Optimized build 2023-06-07 20:57:56 +03:00
435f1b0355 Allow launching the injector from a different directory 2023-06-07 20:09:02 +03:00
f965bb79a3 Merge hi3.h into game.h 2023-06-06 21:14:21 +03:00
a79ebdc0c8 Remove redundant "assembly_name_lwr" field from "struct game_data" 2023-06-06 20:52:48 +03:00
0dea9e7625 Show a messagebox if the game failed to start 2023-06-06 20:36:00 +03:00
c1cfed6216 Move envvar names into injshared.h 2023-06-06 20:23:15 +03:00
ab0668d3a9 Fix typo in readme 2023-06-06 20:21:06 +03:00
11 changed files with 36 additions and 27 deletions

View File

@ -4,7 +4,7 @@
This project is in the proof-of-concept stage. Currently, only **3rd glb v6.6.0** is supported. It may be possilbe to completely remove the region and version-specific data in the future. Refer to the source code in `game_payload/src` for details. This project is in the proof-of-concept stage. Currently, only **3rd glb v6.6.0** is supported. It may be possilbe to completely remove the region and version-specific data in the future. Refer to the source code in `game_payload/src` for details.
### Information ### Information
The anticheat the games use is fundamentally incompatible with Wine in multiple ways. This tool launches the game without it (`inject/launcher_payload`) and imitates it's behaviour (`game_payload`). The anticheat the games use is fundamentally incompatible with Wine in multiple ways. This tool launches the game without it (`injector/launcher_payload`) and imitates it's behaviour (`game_payload`).
Does not work on Windows. Does not work on Windows.

View File

@ -1,9 +1,11 @@
#!/usr/bin/env sh #!/usr/bin/env bash
strip="x86_64-w64-mingw32-strip"
rm -f jadeite.zip rm -f jadeite.zip
rm -rf out rm -rf out
sh setup.sh sh setup.sh --buildtype=release
ninja -C build ninja -C build
mkdir out mkdir out
@ -13,6 +15,8 @@ cp ./build/injector/launcher_payload/launcher_payload.dll ./out
cp ./build/game_payload/game_payload.dll ./out cp ./build/game_payload/game_payload.dll ./out
cp ./LICENSE.txt ./out cp ./LICENSE.txt ./out
$strip ./out/*.{exe,dll}
if [ "x$1" = "xrelease" ]; then if [ "x$1" = "xrelease" ]; then
cd out cd out
zip ../jadeite.zip * zip ../jadeite.zip *

View File

@ -12,9 +12,10 @@ struct game_data {
enum game_id id; // Temporary enum game_id id; // Temporary
const char *name; const char *name;
const char *assembly_path; const char *assembly_path;
const wchar_t *assembly_name_lwr;
const char *tp6_section_name; // Unused for now const char *tp6_section_name; // Unused for now
const char *tvm_section_name; const char *tvm_section_name;
}; };
void game_detect(struct game_data *buf); void game_detect(struct game_data *buf);
void hi3_fill_data(struct game_data *buf);

View File

@ -1,5 +0,0 @@
#pragma once
#include <game.h>
void hi3_fill_data(struct game_data *buf);

View File

@ -1,5 +1,4 @@
#include <err.h> #include <err.h>
#include <hi3.h>
#include <game.h> #include <game.h>

View File

@ -1,11 +1,10 @@
#include <utils.h> #include <utils.h>
#include <err.h> #include <err.h>
#include <hi3.h> #include <game.h>
const char *HI3_NAME = "BH3"; const char *HI3_NAME = "BH3";
const char *HI3_ASSEMBLY_PATH = "BH3_Data/Native/UserAssembly.dll"; const char *HI3_ASSEMBLY_PATH = "BH3_Data/Native/UserAssembly.dll";
const wchar_t *HI3_ASSEMBLY_NAME_LWR = L"userassembly.dll";
const char *HI3_TP6_SECTION_NAME = ".bh3"; const char *HI3_TP6_SECTION_NAME = ".bh3";
const char *HI3_TVM_SECTION_NAME = ".tvm0"; const char *HI3_TVM_SECTION_NAME = ".tvm0";
@ -38,7 +37,6 @@ void hi3_fill_data(struct game_data *buf) {
buf->id = id; buf->id = id;
buf->name = HI3_NAME; buf->name = HI3_NAME;
buf->assembly_path = HI3_ASSEMBLY_PATH; buf->assembly_path = HI3_ASSEMBLY_PATH;
buf->assembly_name_lwr = HI3_ASSEMBLY_NAME_LWR;
buf->tp6_section_name = HI3_TP6_SECTION_NAME; buf->tp6_section_name = HI3_TP6_SECTION_NAME;
buf->tvm_section_name = HI3_TVM_SECTION_NAME; buf->tvm_section_name = HI3_TVM_SECTION_NAME;
} }

View File

@ -1,5 +1,8 @@
#include <windows.h> #include <windows.h>
const char ENV_EXE_PATH[] = "JADEITE_TARGET_EXE_PATH";
const char ENV_DLL_PATH[] = "JADEITE_INJECT_DLL_PATH";
static inline void write_protected_process_memory(HANDLE process, void *address, const void *buf, size_t size) { static inline void write_protected_process_memory(HANDLE process, void *address, const void *buf, size_t size) {
DWORD oldProtect; DWORD oldProtect;
VirtualProtectEx(process, address, size, PAGE_EXECUTE_READWRITE, &oldProtect); VirtualProtectEx(process, address, size, PAGE_EXECUTE_READWRITE, &oldProtect);
@ -22,8 +25,8 @@ static inline void inject(HANDLE process, const void *payload, size_t payloadSiz
// Find the EXE header in the process // Find the EXE header in the process
char exeHeader[1024]; char exeHeader[1024];
IMAGE_DOS_HEADER *dosHeader; IMAGE_DOS_HEADER *dosHeader = NULL;
IMAGE_NT_HEADERS64 *ntHeaders; IMAGE_NT_HEADERS64 *ntHeaders = NULL;
MEMORY_BASIC_INFORMATION memoryInfo; MEMORY_BASIC_INFORMATION memoryInfo;
char *currentAddress = 0x0; char *currentAddress = 0x0;

View File

@ -1,10 +1,9 @@
#include <stdio.h>
#include <injshared.h> #include <injshared.h>
#include <lpayload.h> #include <lpayload.h>
const char EXE_ENV[] = "JADEITE_TARGET_EXE_PATH";
const char INJECT_DLL_ENV[] = "JADEITE_INJECT_DLL_PATH";
static inline void read_env(const char *env, char *dest, size_t size) { static inline void read_env(const char *env, char *dest, size_t size) {
GetEnvironmentVariableA(env, dest, size); GetEnvironmentVariableA(env, dest, size);
SetEnvironmentVariableA(env, ""); SetEnvironmentVariableA(env, "");
@ -18,11 +17,11 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) {
// Get target EXE path // Get target EXE path
char targetExe[MAX_PATH]; char targetExe[MAX_PATH];
read_env(EXE_ENV, targetExe, sizeof(targetExe)); read_env(ENV_EXE_PATH, targetExe, sizeof(targetExe));
// Get the path of the DLL to inject // Get the path of the DLL to inject
char injectDll[MAX_PATH]; char injectDll[MAX_PATH];
read_env(INJECT_DLL_ENV, injectDll, sizeof(injectDll)); read_env(ENV_DLL_PATH, injectDll, sizeof(injectDll));
// Compute the working directory path // Compute the working directory path
char workdir[MAX_PATH]; char workdir[MAX_PATH];
@ -49,6 +48,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) {
&si, &si,
&pi &pi
)) { )) {
char message[64];
sprintf(message, "Failed to start game process: %ld", GetLastError());
MessageBoxA(NULL, message, "Jadeite Launcher Payload", MB_OK | MB_ICONERROR);
exit(1); exit(1);
} }

View File

@ -4,9 +4,6 @@
#include <ipayload.h> #include <ipayload.h>
const char EXE_ENV[] = "JADEITE_TARGET_EXE_PATH";
const char INJECT_DLL_ENV[] = "JADEITE_INJECT_DLL_PATH";
const char LAUNCHER_INJECT_DLL[] = "launcher_payload.dll"; const char LAUNCHER_INJECT_DLL[] = "launcher_payload.dll";
const char GAME_INJECT_DLL[] = "game_payload.dll"; const char GAME_INJECT_DLL[] = "game_payload.dll";
@ -33,6 +30,15 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
// cd into the injector directory
char injectorPath[MAX_PATH];
GetModuleFileNameA(GetModuleHandleA(NULL), injectorPath, sizeof(injectorPath));
char *lastSep = strrchr(injectorPath, '\\');
*lastSep = '\0';
SetCurrentDirectoryA(injectorPath);
// Compute absolute paths // Compute absolute paths
char gameExePath[MAX_PATH]; char gameExePath[MAX_PATH];
GetFullPathNameA(gamePath, sizeof(gameExePath), gameExePath, NULL); GetFullPathNameA(gamePath, sizeof(gameExePath), gameExePath, NULL);
@ -46,8 +52,8 @@ int main(int argc, char **argv) {
printf("Starting \"%s\" via \"%s\"\n", gameExePath, launcherPath); printf("Starting \"%s\" via \"%s\"\n", gameExePath, launcherPath);
// Set envvars // Set envvars
SetEnvironmentVariableA(EXE_ENV, gameExePath); SetEnvironmentVariableA(ENV_EXE_PATH, gameExePath);
SetEnvironmentVariableA(INJECT_DLL_ENV, gamePayloadPath); SetEnvironmentVariableA(ENV_DLL_PATH, gamePayloadPath);
// Start the launcher // Start the launcher
STARTUPINFO si; STARTUPINFO si;

View File

@ -1,4 +1,4 @@
project('jadeite', 'c', version: '1.0.0') project('jadeite', 'c', version: '1.0.1')
nasm = find_program('nasm') nasm = find_program('nasm')
gen_res = find_program('gen_resources.sh') gen_res = find_program('gen_resources.sh')

View File

@ -1,4 +1,4 @@
#!/usr/bin/env sh #!/usr/bin/env sh
rm -rf build rm -rf build
meson setup --cross-file mingw_cross.txt build meson setup --cross-file mingw_cross.txt $* build