diff --git a/game_payload/src/hsr.c b/game_payload/src/hsr.c index cd07056..4e399d8 100644 --- a/game_payload/src/hsr.c +++ b/game_payload/src/hsr.c @@ -1,5 +1,9 @@ #include #include +#include + +#include +#include #include @@ -20,24 +24,52 @@ const struct crc_id_pair HSR_REGIONS[] = { { 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) { if (utils_env_enabled("SRFIX_DISABLE")) { msg_info_a("Shared resources fix disabled. The game may not work"); return; } - - // Disable shared resources - // Temporarily hardcoded offset - // v1.1.0, same for os and cn - unsigned char *srAddr = ((unsigned char*)unityModule) + 0x16430; + // Remove dependency on shared resources by patching WriteTextureStatisticUserData + + wtsud_patch_addr = ((char*)unityModule) + 0x16430; 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) { @@ -66,5 +98,6 @@ void hsr_fill_data(struct game_data *buf) { buf->tp6_section_name = HSR_TP6_SECTION_NAME; buf->tvm_section_name = HSR_TVM_SECTION_NAME; + unload_ctr_inc(); buf->unityplayer_callback = &_unityplayer_callback; }