2023-06-06 00:23:08 +03:00
|
|
|
#include <windows.h>
|
|
|
|
|
|
|
|
|
|
#include <ntdll.h>
|
|
|
|
|
#include <ace.h>
|
|
|
|
|
#include <game.h>
|
2023-07-28 01:51:04 +03:00
|
|
|
#include <core.h>
|
2023-06-06 00:23:08 +03:00
|
|
|
#include <utils.h>
|
2023-08-04 15:35:29 +03:00
|
|
|
#include <msg.h>
|
2023-08-04 22:17:31 +03:00
|
|
|
#include <tx.h>
|
2023-06-06 00:23:08 +03:00
|
|
|
|
2023-06-21 14:25:22 +03:00
|
|
|
#include <main.h>
|
|
|
|
|
|
|
|
|
|
HMODULE this_module;
|
|
|
|
|
size_t unload_ctr = 0;
|
|
|
|
|
|
|
|
|
|
void unload_ctr_inc() {
|
|
|
|
|
unload_ctr++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void unload_ctr_dec() {
|
|
|
|
|
unload_ctr--;
|
|
|
|
|
if (unload_ctr == 0) {
|
|
|
|
|
void *pFreeLibrary = GetProcAddress(GetModuleHandleA("kernel32.dll"), "FreeLibrary");
|
|
|
|
|
CreateThread(NULL, 0, pFreeLibrary, this_module, 0, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-04 15:35:29 +03:00
|
|
|
void request_restart() {
|
2023-08-05 12:15:08 +03:00
|
|
|
wchar_t restartFlagFile[MAX_PATH];
|
|
|
|
|
GetTempPathW(MAX_PATH, restartFlagFile);
|
|
|
|
|
wcscat(restartFlagFile, L"jadeite\\restart_flag");
|
2023-08-04 15:35:29 +03:00
|
|
|
|
2023-08-05 12:15:08 +03:00
|
|
|
HANDLE hRestartFlag = CreateFileW(restartFlagFile, FILE_WRITE_ACCESS, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
2023-08-04 15:35:29 +03:00
|
|
|
CloseHandle(hRestartFlag);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-04 23:22:26 +03:00
|
|
|
static void _run_game(struct game_data *game, wchar_t *txFile) {
|
2023-08-04 22:17:31 +03:00
|
|
|
// Create fake ACE driver files
|
|
|
|
|
ace_fake_driver_files();
|
|
|
|
|
|
|
|
|
|
// Load both ACE modules
|
|
|
|
|
HMODULE baseModule = ace_load_base_module(game);
|
|
|
|
|
ace_load_driver_module();
|
|
|
|
|
|
|
|
|
|
// ...magic
|
2023-08-04 23:22:26 +03:00
|
|
|
core_setup_patcher(game, baseModule, txFile);
|
2023-08-04 22:17:31 +03:00
|
|
|
|
|
|
|
|
// Load the UnityPlayer module and invoke the callback
|
|
|
|
|
HMODULE unityModule = LoadLibraryA("UnityPlayer.dll");
|
|
|
|
|
INVOKE_CALLBACK(game->unityplayer_callback, unityModule);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-04 23:22:26 +03:00
|
|
|
static void _run_tx(struct game_data *game, wchar_t *txFile) {
|
2023-08-04 22:55:10 +03:00
|
|
|
// ...more magic
|
|
|
|
|
size_t tableSize;
|
2023-08-05 12:15:08 +03:00
|
|
|
void *table = core_perform_tx(game, &tableSize);
|
2023-08-04 22:17:31 +03:00
|
|
|
|
2023-08-04 22:55:10 +03:00
|
|
|
// Save to file
|
2023-08-10 01:15:53 +03:00
|
|
|
utils_create_parent_dirs(txFile);
|
2023-08-04 23:22:26 +03:00
|
|
|
utils_save_to_file(txFile, table, tableSize);
|
2023-08-04 22:17:31 +03:00
|
|
|
|
2023-08-04 22:55:10 +03:00
|
|
|
// Cleanup
|
|
|
|
|
free(table);
|
|
|
|
|
|
|
|
|
|
// The file should now exist: restart and launch the game
|
2023-08-04 22:17:31 +03:00
|
|
|
request_restart();
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-06 00:23:08 +03:00
|
|
|
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) {
|
|
|
|
|
// Only listen to attach
|
|
|
|
|
if (reason != DLL_PROCESS_ATTACH) {
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-21 14:25:22 +03:00
|
|
|
this_module = instance;
|
|
|
|
|
|
2023-06-06 00:23:08 +03:00
|
|
|
// Dynamically link functions from ntdll
|
|
|
|
|
ntdll_link();
|
|
|
|
|
|
|
|
|
|
// Detect which game the user is trying to run
|
|
|
|
|
struct game_data game;
|
|
|
|
|
game_detect(&game);
|
|
|
|
|
|
2023-08-04 22:17:31 +03:00
|
|
|
// Get required table file path
|
2023-08-04 23:22:26 +03:00
|
|
|
wchar_t txFile[MAX_PATH];
|
|
|
|
|
tx_table_file(&game, txFile);
|
2023-06-06 00:23:08 +03:00
|
|
|
|
2023-08-04 23:22:26 +03:00
|
|
|
if (utils_path_exists(txFile)) {
|
|
|
|
|
_run_game(&game, txFile);
|
2023-08-04 22:17:31 +03:00
|
|
|
} else {
|
2023-08-04 23:22:26 +03:00
|
|
|
_run_tx(&game, txFile);
|
2023-08-04 22:17:31 +03:00
|
|
|
}
|
2023-06-08 15:27:51 +03:00
|
|
|
|
2023-06-06 00:23:08 +03:00
|
|
|
return TRUE;
|
|
|
|
|
}
|