5 Commits

Author SHA1 Message Date
6209157cf2 v1.1.4 2023-06-21 15:42:19 +03:00
f26bcbd0fc HOTFIX: fix module unloading with SRFIX_DISABLE 2023-06-21 15:41:46 +03:00
14c90f7137 v1.1.3 2023-06-21 14:52:38 +03:00
8f96ec4eec Unpatch WriteTextureStatisticUserData after execution 2023-06-21 14:47:46 +03:00
5421487212 Counter-based unloading logic 2023-06-21 14:25:22 +03:00
6 changed files with 68 additions and 12 deletions

View File

@ -0,0 +1,4 @@
#pragma once
void unload_ctr_inc();
void unload_ctr_dec();

View File

@ -4,4 +4,4 @@
#include <game.h> #include <game.h>
void tp6_setup_patcher(struct game_data *game, HMODULE thisModule, HMODULE baseModule); void tp6_setup_patcher(struct game_data *game, HMODULE baseModule);

View File

@ -1,5 +1,9 @@
#include <utils.h> #include <utils.h>
#include <msg.h> #include <msg.h>
#include <main.h>
#include <crc32.h>
#include <pe.h>
#include <game.h> #include <game.h>
@ -20,24 +24,53 @@ const struct crc_id_pair HSR_REGIONS[] = {
{ 0x3e644d26, GAME_HSR_CN } // cn v1.1.0 { 0x3e644d26, GAME_HSR_CN } // cn v1.1.0
}; };
#define JUMP_SIZE (6 + sizeof(void*))
// Temporarily hardcoded offset
// v1.1.0, same for os and cn
#define WTSUD_PATCH_OFFSET 0x16430
char wtsud_original_bytes[JUMP_SIZE];
char *wtsud_patch_addr;
static void _wtsud_stub() {
// Recover original bytes
DWORD oldProtect;
VirtualProtect(wtsud_patch_addr, JUMP_SIZE, PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy(wtsud_patch_addr, wtsud_original_bytes, JUMP_SIZE);
VirtualProtect(wtsud_patch_addr, JUMP_SIZE, oldProtect, &oldProtect);
unload_ctr_dec();
}
static void _unityplayer_callback(HMODULE unityModule) { static void _unityplayer_callback(HMODULE unityModule) {
if (utils_env_enabled("SRFIX_DISABLE")) { if (utils_env_enabled("SRFIX_DISABLE")) {
msg_info_a("Shared resources fix disabled. The game may not work"); msg_info_a("Shared resources fix disabled. The game may not work");
return; return;
} }
// Disable shared resources
// Temporarily hardcoded offset // Remove dependency on shared resources by patching WriteTextureStatisticUserData
// v1.1.0, same for os and cn unload_ctr_inc();
unsigned char *srAddr = ((unsigned char*)unityModule) + 0x16430;
wtsud_patch_addr = ((char*)unityModule) + 0x16430;
DWORD oldProtect; DWORD oldProtect;
VirtualProtect(srAddr, 1, PAGE_EXECUTE_READWRITE, &oldProtect); VirtualProtect(wtsud_patch_addr, JUMP_SIZE, PAGE_EXECUTE_READWRITE, &oldProtect);
*srAddr = 0xC3; // ret // Save original bytes
memcpy(wtsud_original_bytes, wtsud_patch_addr, JUMP_SIZE);
VirtualProtect(srAddr, 1, oldProtect, &oldProtect); // Write jump
const char JUMP_INST[] = { 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 }; // jmp [$ + 6]
memcpy(wtsud_patch_addr, JUMP_INST, sizeof(JUMP_INST));
// Write destination address
void *destAddr = &_wtsud_stub;
memcpy(wtsud_patch_addr + sizeof(JUMP_INST), &destAddr, sizeof(destAddr));
VirtualProtect(wtsud_patch_addr, JUMP_SIZE, oldProtect, &oldProtect);
} }
void hsr_fill_data(struct game_data *buf) { void hsr_fill_data(struct game_data *buf) {

View File

@ -6,12 +6,31 @@
#include <tp6.h> #include <tp6.h>
#include <utils.h> #include <utils.h>
#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);
}
}
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) {
// Only listen to attach // Only listen to attach
if (reason != DLL_PROCESS_ATTACH) { if (reason != DLL_PROCESS_ATTACH) {
return TRUE; return TRUE;
} }
this_module = instance;
// Dynamically link functions from ntdll // Dynamically link functions from ntdll
ntdll_link(); ntdll_link();
@ -27,7 +46,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) {
ace_load_driver_module(); ace_load_driver_module();
// ...magic // ...magic
tp6_setup_patcher(&game, instance, baseModule); tp6_setup_patcher(&game, baseModule);
// Load the UnityPlayer module and invoke the callback // Load the UnityPlayer module and invoke the callback
HMODULE unityModule = LoadLibraryA("UnityPlayer.dll"); HMODULE unityModule = LoadLibraryA("UnityPlayer.dll");

View File

@ -1,4 +1,4 @@
project('jadeite', 'c', version: '1.1.2') project('jadeite', 'c', version: '1.1.4')
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,6 +1,6 @@
{ {
"jadeite": { "jadeite": {
"version": "1.1.2" "version": "1.1.4"
}, },
"games": { "games": {
"hi3rd": { "hi3rd": {