Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for Monster Hunter Wilds #1197

Merged
merged 4 commits into from
Feb 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(bddisasm)

message(STATUS "Fetching kananlib (8b29e1694dbf4ad4c878ff54bcbcabf280b37168)...")
message(STATUS "Fetching kananlib (d659e3b8312e26ba19329f96b73ba88d1211bfdb)...")
FetchContent_Declare(
kananlib
GIT_REPOSITORY
https://github.com/cursey/kananlib
GIT_TAG
8b29e1694dbf4ad4c878ff54bcbcabf280b37168
d659e3b8312e26ba19329f96b73ba88d1211bfdb
)
FetchContent_MakeAvailable(kananlib)

Expand Down
2 changes: 1 addition & 1 deletion cmake.toml
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ tag = "v1.34.10"

[fetch-content.kananlib]
git = "https://github.com/cursey/kananlib"
tag = "8b29e1694dbf4ad4c878ff54bcbcabf280b37168"
tag = "d659e3b8312e26ba19329f96b73ba88d1211bfdb"

[target.utility]
type = "static"
Expand Down
2 changes: 1 addition & 1 deletion shared/sdk/RETypeDefinition.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct RETypeDefVersion74 {
uint32_t type_crc;
uint64_t default_ctor : 22;
uint64_t member_method : 22;
uint64_t member_field : TYPE_INDEX_BITS;
uint64_t member_field : FIELD_BITS;
uint32_t num_member_prop : 12;
uint32_t member_prop : TYPE_INDEX_BITS;

Expand Down
13 changes: 13 additions & 0 deletions shared/sdk/TDBVer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,48 +53,61 @@ struct RETypeDefinition;

#if defined(MHWILDS)
#define TYPE_INDEX_BITS 19
#define FIELD_BITS 20
using RETypeDefinition_ = sdk::RETypeDefVersion74;
#elif defined(DD2)
#define TYPE_INDEX_BITS 19
#define FIELD_BITS 19
using RETypeDefinition_ = sdk::RETypeDefVersion71; // same thing for now
#elif defined(SF6)
#define TYPE_INDEX_BITS 19
#define FIELD_BITS 19
using RETypeDefinition_ = sdk::RETypeDefVersion71;
#elif defined(RE4)
#define TYPE_INDEX_BITS 19
#define FIELD_BITS 19
using RETypeDefinition_ = sdk::RETypeDefVersion71;
#elif defined(MHRISE)
#ifdef MHRISE_TDB70
// it's version 70 but looks the same for now i guess
#define TYPE_INDEX_BITS 18
#define FIELD_BITS 18
using RETypeDefinition_ = sdk::RETypeDefVersion69;
#else
#define TYPE_INDEX_BITS 19
#define FIELD_BITS 19
using RETypeDefinition_ = sdk::RETypeDefVersion71;
#endif
#elif defined(RE8)
#define TYPE_INDEX_BITS 18
#define FIELD_BITS 18
using RETypeDefinition_ = sdk::RETypeDefVersion69;
#elif defined(DMC5)
#define TYPE_INDEX_BITS 17
#define FIELD_BITS 17
using RETypeDefinition_ = sdk::RETypeDefVersion67;
#elif defined(RE2) || defined(RE3)
#ifdef RE2_TDB66
#define TYPE_INDEX_BITS 16
#define FIELD_BITS 16
using RETypeDefinition_ = sdk::RETypeDefVersion66;
#elif defined(RE3_TDB67)
#define TYPE_INDEX_BITS 17
#define FIELD_BITS 17
using RETypeDefinition_ = sdk::RETypeDefVersion67;
#else
#define TYPE_INDEX_BITS 18
#define FIELD_BITS 18
using RETypeDefinition_ = sdk::RETypeDefVersion69;
#endif
#elif RE7
#ifdef RE7_TDB49
#define TYPE_INDEX_BITS 16
#define FIELD_BITS 16
using RETypeDefinition_ = sdk::RETypeDefVersion49;
#else
#define TYPE_INDEX_BITS 18
#define FIELD_BITS 18
using RETypeDefinition_ = sdk::RETypeDefVersion69;
#endif
#endif
Expand Down
78 changes: 78 additions & 0 deletions src/mods/IntegrityCheckBypass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,19 @@ void IntegrityCheckBypass::immediate_patch_re4() {
spdlog::info("[IntegrityCheckBypass]: Patched conditional_jmp!");
}

void* IntegrityCheckBypass::renderer_create_blas_hook(void* a1, void* a2, void* a3, void* a4, void* a5) {
if (s_corruption_when_zero != nullptr) {
if (*s_corruption_when_zero == 0) {
*s_corruption_when_zero = s_last_non_zero_corruption;
spdlog::info("[IntegrityCheckBypass]: Fixed corruption_when_zero!");
}

s_last_non_zero_corruption = *s_corruption_when_zero;
}

return s_renderer_create_blas_hook->get_original<decltype(renderer_create_blas_hook)>()(a1, a2, a3, a4, a5);
}

void IntegrityCheckBypass::immediate_patch_dd2() {
// Just like RE4, this deals with the scans that are done every frame on the game's memory.
// The scans are still performed, but the crash will be avoided.
Expand All @@ -518,6 +531,71 @@ void IntegrityCheckBypass::immediate_patch_dd2() {
spdlog::info("[IntegrityCheckBypass]: Scanning DD2...");

const auto game = utility::get_executable();

#if TDB_VER >= 74
const auto query_performance_frequency = &QueryPerformanceFrequency;
const auto query_performance_counter = &QueryPerformanceCounter;

if (query_performance_frequency != nullptr && query_performance_counter != nullptr) {
const auto qpf_import = utility::scan_ptr(game, (uintptr_t)query_performance_frequency);
const auto qpc_import = utility::scan_ptr(game, (uintptr_t)query_performance_counter);

if (qpf_import && qpc_import) {
const auto crasher_fn = utility::find_function_with_refs(game, { *qpf_import, *qpc_import });

if (crasher_fn) {
spdlog::info("[IntegrityCheckBypass]: Found crasher_fn!");

// Make function just ret
//static auto patch = Patch::create(*crasher_fn, { 0xC3 }, true);

const auto cmp_jz = utility::find_pattern_in_path((uint8_t*)*crasher_fn, 1000, false, "39 0C 82 74 ?");

if (cmp_jz) {
static auto patch = Patch::create(cmp_jz->addr + 3, { 0xEB }, true);
spdlog::info("[IntegrityCheckBypass]: Patched crasher_fn!");
} else {
spdlog::error("[IntegrityCheckBypass]: Could not find cmp_jz!");
}
} else {
spdlog::error("[IntegrityCheckBypass]: Could not find crasher_fn!");
}
} else {
spdlog::error("[IntegrityCheckBypass]: Could not find QueryPerformanceFrequency/Counter imports!");
}
}

if (const auto create_blas_fn = utility::find_function_from_string_ref(game, "createBLAS"); create_blas_fn.has_value()) {
const auto create_blas_fn_unwind = utility::find_function_start_unwind(*create_blas_fn);

if (create_blas_fn_unwind) {
spdlog::info("[IntegrityCheckBypass]: Found createBLAS!");

// Look for first lea rcx, [mem]
const auto lea_rcx = utility::find_pattern_in_path((uint8_t*)*create_blas_fn_unwind, 1000, false, "48 8D 0D ? ? ? ?");

if (lea_rcx) {
s_corruption_when_zero = (uint32_t*)utility::calculate_absolute(lea_rcx->addr + 3);
spdlog::info("[IntegrityCheckBypass]: Found corruption_when_zero!");
} else {
spdlog::error("[IntegrityCheckBypass]: Could not find lea_rcx!");
}

s_renderer_create_blas_hook = std::make_unique<FunctionHook>(*create_blas_fn, &renderer_create_blas_hook);

if (!s_renderer_create_blas_hook->create()) {
spdlog::error("[IntegrityCheckBypass]: Failed to hook createBLAS!");
} else {
spdlog::info("[IntegrityCheckBypass]: Hooked createBLAS!");
}
} else {
spdlog::error("[IntegrityCheckBypass]: Could not find unwound createBLAS!");
}
} else {
spdlog::error("[IntegrityCheckBypass]: Could not find createBLAS!");
}
#endif

const auto conditional_jmp_block = utility::scan(game, "41 8B ? ? 78 83 ? 07 ? ? 75 ?");

if (conditional_jmp_block) {
Expand Down
5 changes: 5 additions & 0 deletions src/mods/IntegrityCheckBypass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ class IntegrityCheckBypass : public Mod {
}

private:
static void* renderer_create_blas_hook(void* a1, void* a2, void* a3, void* a4, void* a5);
static inline std::unique_ptr<FunctionHook> s_renderer_create_blas_hook{};
static inline uint32_t* s_corruption_when_zero{ nullptr };
static inline uint32_t s_last_non_zero_corruption{ 8 }; // What I've seen it default to

static BOOL WINAPI virtual_protect_impl(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
static BOOL WINAPI virtual_protect_hook(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);

Expand Down
Loading