jadeite/game_payload/src/hsr.c

98 lines
2.7 KiB
C
Raw Normal View History

2023-06-08 15:36:22 +00:00
#include <utils.h>
2023-06-08 18:44:42 +00:00
#include <msg.h>
#include <main.h>
2023-06-08 15:36:22 +00:00
#include <game.h>
2023-08-03 21:19:02 +00:00
const char *HSR_BASE_MODULE_NAME = "StarRailBase.dll";
const char *HSR_ASSEMBLY_NAME = "GameAssembly.dll";
2023-08-04 19:17:31 +00:00
const char *HSR_TXS_SECTION_NAME = ".ace";
2023-06-08 15:36:22 +00:00
const char *HSR_TVM_SECTION_NAME = ".tvm0";
2023-08-04 20:00:42 +00:00
enum hsr_region {
HSR_INVALID,
HSR_OS,
HSR_CN
2023-06-08 15:36:22 +00:00
};
2023-08-04 20:00:42 +00:00
struct crc_region_pair {
uint32_t crc;
enum hsr_region id;
};
2023-06-08 15:36:22 +00:00
2023-08-04 20:00:42 +00:00
const struct crc_region_pair HSR_REGIONS[] = {
{ 0x9eb3084e, HSR_OS }, // os v1.2.0
{ 0x14be07e9, HSR_CN } // cn v1.2.0
2023-06-08 15:36:22 +00:00
};
#define JUMP_SIZE (6 + sizeof(void*))
// Temporarily hardcoded offset
2023-07-17 11:39:12 +00:00
// v1.2.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();
}
2023-06-08 17:13:21 +00:00
static void _unityplayer_callback(HMODULE unityModule) {
2023-06-08 19:33:37 +00:00
if (utils_env_enabled("SRFIX_DISABLE")) {
msg_info_a("Shared resources fix disabled. The game may not work");
return;
}
2023-06-08 17:13:21 +00:00
// Remove dependency on shared resources by patching WriteTextureStatisticUserData
unload_ctr_inc();
2023-06-21 13:24:16 +00:00
wtsud_patch_addr = ((char*)unityModule) + WTSUD_PATCH_OFFSET;
2023-06-08 17:13:21 +00:00
DWORD oldProtect;
VirtualProtect(wtsud_patch_addr, JUMP_SIZE, PAGE_EXECUTE_READWRITE, &oldProtect);
// Save original bytes
memcpy(wtsud_original_bytes, wtsud_patch_addr, JUMP_SIZE);
// Write jump
const char JUMP_INST[] = { 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 }; // jmp [$ + 6]
memcpy(wtsud_patch_addr, JUMP_INST, sizeof(JUMP_INST));
2023-06-08 17:13:21 +00:00
// Write destination address
void *destAddr = &_wtsud_stub;
memcpy(wtsud_patch_addr + sizeof(JUMP_INST), &destAddr, sizeof(destAddr));
2023-06-08 17:13:21 +00:00
VirtualProtect(wtsud_patch_addr, JUMP_SIZE, oldProtect, &oldProtect);
2023-06-08 17:13:21 +00:00
}
2023-06-08 15:36:22 +00:00
void hsr_fill_data(struct game_data *buf) {
uint32_t crc = utils_file_crc32c(L"UnityPlayer.dll");
2023-06-08 15:36:22 +00:00
2023-08-04 20:00:42 +00:00
enum hsr_region id = HSR_INVALID;
for (size_t i = 0; i < sizeof(HSR_REGIONS) / sizeof(struct crc_region_pair); i++) {
2023-06-08 15:36:22 +00:00
if (HSR_REGIONS[i].crc == crc) {
id = HSR_REGIONS[i].id;
}
}
2023-08-04 20:00:42 +00:00
if (id == HSR_INVALID) {
msg_err_a("Invalid UnityPlayer.dll checksum: %x", crc);
2023-06-08 15:36:22 +00:00
}
2023-08-03 21:19:02 +00:00
buf->base_module_name = HSR_BASE_MODULE_NAME;
buf->assembly_name = HSR_ASSEMBLY_NAME;
2023-08-04 19:17:31 +00:00
buf->txs_section_name = HSR_TXS_SECTION_NAME;
2023-06-08 15:36:22 +00:00
buf->tvm_section_name = HSR_TVM_SECTION_NAME;
2023-06-08 17:13:21 +00:00
buf->unityplayer_callback = &_unityplayer_callback;
2023-06-08 15:36:22 +00:00
}