Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6209157cf2 | |||
| f26bcbd0fc | |||
| 14c90f7137 | |||
| 8f96ec4eec | |||
| 5421487212 |
4
game_payload/include/main.h
Normal file
4
game_payload/include/main.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void unload_ctr_inc();
|
||||||
|
void unload_ctr_dec();
|
||||||
@ -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);
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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");
|
||||||
|
|||||||
@ -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')
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"jadeite": {
|
"jadeite": {
|
||||||
"version": "1.1.2"
|
"version": "1.1.4"
|
||||||
},
|
},
|
||||||
"games": {
|
"games": {
|
||||||
"hi3rd": {
|
"hi3rd": {
|
||||||
|
|||||||
Reference in New Issue
Block a user