98 lines
2.7 KiB
C
98 lines
2.7 KiB
C
#include <utils.h>
|
|
#include <msg.h>
|
|
#include <main.h>
|
|
|
|
#include <game.h>
|
|
|
|
const char *HSR_BASE_MODULE_NAME = "StarRailBase.dll";
|
|
const char *HSR_ASSEMBLY_PATH = "GameAssembly.dll";
|
|
const char *HSR_TXS_SECTION_NAME = ".ace";
|
|
const char *HSR_TVM_SECTION_NAME = ".tvm0";
|
|
|
|
enum hsr_region {
|
|
HSR_INVALID,
|
|
HSR_OS,
|
|
HSR_CN
|
|
};
|
|
|
|
struct crc_region_pair {
|
|
uint32_t crc;
|
|
enum hsr_region id;
|
|
};
|
|
|
|
const struct crc_region_pair HSR_REGIONS[] = {
|
|
{ 0x9eb3084e, HSR_OS }, // os v1.2.0
|
|
{ 0x14be07e9, HSR_CN } // cn v1.2.0
|
|
};
|
|
|
|
#define JUMP_SIZE (6 + sizeof(void*))
|
|
|
|
// Temporarily hardcoded offset
|
|
// 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();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
// Remove dependency on shared resources by patching WriteTextureStatisticUserData
|
|
unload_ctr_inc();
|
|
|
|
wtsud_patch_addr = ((char*)unityModule) + WTSUD_PATCH_OFFSET;
|
|
|
|
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));
|
|
|
|
// 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) {
|
|
uint32_t crc = utils_file_crc32c(L"UnityPlayer.dll");
|
|
|
|
enum hsr_region id = HSR_INVALID;
|
|
for (size_t i = 0; i < sizeof(HSR_REGIONS) / sizeof(struct crc_region_pair); i++) {
|
|
if (HSR_REGIONS[i].crc == crc) {
|
|
id = HSR_REGIONS[i].id;
|
|
}
|
|
}
|
|
|
|
if (id == HSR_INVALID) {
|
|
msg_err_a("Invalid UnityPlayer.dll checksum: %x", crc);
|
|
}
|
|
|
|
buf->base_module_name = HSR_BASE_MODULE_NAME;
|
|
buf->assembly_path = HSR_ASSEMBLY_PATH;
|
|
buf->txs_section_name = HSR_TXS_SECTION_NAME;
|
|
buf->tvm_section_name = HSR_TVM_SECTION_NAME;
|
|
|
|
buf->unityplayer_callback = &_unityplayer_callback;
|
|
}
|