From d7655f0389fe5a88f4dd2794b923db9e94836c80 Mon Sep 17 00:00:00 2001 From: praydog Date: Wed, 4 Oct 2023 00:57:17 -0700 Subject: [PATCH] IntegrityCheckBypass (RE4): Fix for JP version again (#912) --- src/mods/IntegrityCheckBypass.cpp | 41 ++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/mods/IntegrityCheckBypass.cpp b/src/mods/IntegrityCheckBypass.cpp index 0d4fce722..f0d48fdc9 100644 --- a/src/mods/IntegrityCheckBypass.cpp +++ b/src/mods/IntegrityCheckBypass.cpp @@ -439,14 +439,47 @@ void IntegrityCheckBypass::immediate_patch_re4() { // so we have to use the unique instruction is a reference point to scan from. const auto short_jmp_before = utility::scan_reverse(*unique_instruction, 0x100, "75 ? 50 F7 D0"); - if (!short_jmp_before) { - spdlog::error("[IntegrityCheckBypass]: Could not find short_jmp_before!"); + if (short_jmp_before) { + static auto patch = Patch::create(*short_jmp_before, { 0xEB }, true); + spdlog::info("[IntegrityCheckBypass]: Patched conditional_jmp!"); return; } - static auto patch = Patch::create(*short_jmp_before, { 0xEB }, true); - spdlog::info("[IntegrityCheckBypass]: Patched conditional_jmp!"); + // If we've gotten to this point, we are trying the scorched earth method of trying to obtain the function "start" + // for this giant obfuscated blob. We will get the instructions behind the unique_instruction we found by doing that, + // and look for the nearest branch instruction to patch. + spdlog::error("[IntegrityCheckBypass]: Could not find short_jmp_before, trying fallback."); + // Get the preceding instructions. If this doesn't work we'll need to scan for a common instruction anchor to scan forward from... + auto previous_instructions = utility::get_disassembly_behind(*unique_instruction); + + if (previous_instructions.empty()) { + spdlog::error("[IntegrityCheckBypass]: Could not find previous_instructions!"); + return; + } + + // Reverse the order of the instructions. + std::reverse(previous_instructions.begin(), previous_instructions.end()); + + spdlog::info("[IntegrityCheckBypass]: Found {} previous instructions.", previous_instructions.size()); + spdlog::info("[IntegrityCheckBypass]: Walking previous instructions..."); + + for (auto& insn : previous_instructions) { + if (insn.instrux.BranchInfo.IsBranch) { + spdlog::info("[IntegrityCheckBypass]: Found branch instruction, patching..."); + + if (insn.instrux.BranchInfo.IsFar) { + static auto patch = Patch::create(insn.addr, { 0xE9 }, true); + } else { + static auto patch = Patch::create(insn.addr, { 0xEB }, true); + } + + spdlog::info("[IntegrityCheckBypass]: Patched conditional_jmp"); + return; + } + } + + spdlog::error("[IntegrityCheckBypass]: Could not find branch instruction to patch!"); return; }