Skip to content

Commit

Permalink
Merge pull request #1197 from praydog/mhwilds-wip
Browse files Browse the repository at this point in the history
Fixes for Monster Hunter Wilds
  • Loading branch information
praydog authored Feb 28, 2025
2 parents 3d533b6 + 44b3116 commit 2d9f833
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 4 deletions.
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

0 comments on commit 2d9f833

Please sign in to comment.