Skip to content

Commit 457ff12

Browse files
committed
Fix custom PAK loadding
1 parent aee94ca commit 457ff12

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/mods/IntegrityCheckBypass.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <unordered_set>
22
#include <iomanip>
3+
#include <regex>
34

45
#include "utility/Module.hpp"
56
#include "utility/Scan.hpp"
@@ -230,6 +231,8 @@ std::optional<std::string> IntegrityCheckBypass::on_initialize() {
230231
}
231232
#endif
232233

234+
s_patch_count_checked = false;
235+
233236
spdlog::info("Done.");
234237

235238
return Mod::on_initialize();
@@ -634,6 +637,25 @@ void IntegrityCheckBypass::init_anti_debug_watcher() {
634637
});
635638
}
636639

640+
void IntegrityCheckBypass::pak_load_check_function(safetyhook::Context& context) {
641+
const auto return_address = *reinterpret_cast<uintptr_t*>(context.rsp);
642+
auto pak_name_wstr = reinterpret_cast<const wchar_t*>(context.rdx);
643+
644+
spdlog::info("[IntegrityCheckBypass]: pak_load_check_function called from: 0x{:X}", return_address);
645+
spdlog::info("[IntegrityCheckBypass]: Pak name: {}", utility::narrow(pak_name_wstr));
646+
}
647+
648+
void IntegrityCheckBypass::patch_version_hook(safetyhook::Context& context) {
649+
// THEY STORE PATCH VERSION INSIDE SOMEWHERE NOW! And only load until that patch version then dont load no more paks
650+
spdlog::info("[IntegrityCheckBypass]: patch_version_hook called!");
651+
// Print rax
652+
spdlog::info("[IntegrityCheckBypass]: Patch version: {}. Game wont load past this patch version", context.rax);
653+
654+
// I WILL OVERWRITE THIS RAX. FUCK YOU
655+
// Scan for amount of paks. Get exe directory. To be honest set this to 9999 is okay, but i feel like it might take a long time
656+
context.rax = std::max<int>(scan_patch_files_count(), context.rax);
657+
}
658+
637659
// This allows unencrypted paks to load.
638660
void IntegrityCheckBypass::sha3_rsa_code_midhook(safetyhook::Context& context) {
639661
spdlog::info("[IntegrityCheckBypass]: sha3_code_midhook called!");
@@ -771,6 +793,20 @@ void IntegrityCheckBypass::restore_unencrypted_paks() {
771793

772794
spdlog::info("[IntegrityCheckBypass]: Created sha3_rsa_code_midhook!");
773795

796+
const auto pak_load_check_start = utility::scan(game, "41 57 41 56 41 55 41 54 56 57 55 53 48 81 EC 18 01 00 00 48 89 CE 48 8B 05 43 43 BB 09 48 31 E0");
797+
798+
if (pak_load_check_start) {
799+
spdlog::info("[IntegrityCheckBypass]: Found pak_load_check_function @ 0x{:X}, hook!", (uintptr_t)*pak_load_check_start);
800+
s_pak_load_check_function_hook = safetyhook::create_mid((void*)*pak_load_check_start, &IntegrityCheckBypass::pak_load_check_function);
801+
}
802+
803+
const auto patch_version_start = utility::scan(game, "48 89 44 24 30 48 85 FF 0F 84 28 01 00 00 66 83 3F 72 0F 85 1E 01 00 00 66 BA 72 00 B8 02 00 00 00 48 8D 0D 3A A7 BB 03 66 85 D2 74");
804+
805+
if (patch_version_start) {
806+
spdlog::info("[IntegrityCheckBypass]: Created patch_version_hook to 0x{:X}, hook!", (uintptr_t)*patch_version_start);
807+
s_patch_version_hook = safetyhook::create_mid((void*)*patch_version_start, &IntegrityCheckBypass::patch_version_hook);
808+
}
809+
774810
auto previous_instructions = utility::get_disassembly_behind(*s_sha3_code_end);
775811
auto previous_instructions_start = utility::get_disassembly_behind(*sha3_code_start);
776812

@@ -826,6 +862,60 @@ void IntegrityCheckBypass::restore_unencrypted_paks() {
826862
}
827863
}
828864

865+
int IntegrityCheckBypass::scan_patch_files_count() {
866+
if (s_patch_count_checked) {
867+
return s_patch_count;
868+
}
869+
870+
spdlog::info("[IntegrityCheckBypass]: Scanning for patch files...");
871+
872+
// Get executable directory
873+
const auto exe_module = utility::get_executable();
874+
const auto exe_path = utility::get_module_pathw(exe_module);
875+
876+
if (!exe_path) {
877+
spdlog::error("[IntegrityCheckBypass]: Could not get executable path!");
878+
return -1;
879+
}
880+
881+
const auto exe_dir = std::filesystem::path(*exe_path).parent_path();
882+
883+
spdlog::info("[IntegrityCheckBypass]: Scanning directory: {}", utility::narrow(exe_dir.wstring()));
884+
885+
// Scan for matching files: re_chunk_000.pak.sub_000.pak.patch_0.pak
886+
// Capture the patch number to find the highest one
887+
std::regex pattern(R"(re_chunk_\d+\.pak\.sub_\d+\.pak\.patch_(\d+)\.pak)");
888+
std::smatch match;
889+
int highest_patch_num = -1;
890+
891+
for (const auto& entry : std::filesystem::directory_iterator(exe_dir)) {
892+
if (entry.is_regular_file()) {
893+
const auto filename = entry.path().filename().string();
894+
if (std::regex_match(filename, match, pattern)) {
895+
try {
896+
const int patch_num = std::stoi(match[1].str());
897+
highest_patch_num = std::max(highest_patch_num, patch_num);
898+
spdlog::info("[IntegrityCheckBypass]: Found patch file: {} (patch_{})", filename, patch_num);
899+
} catch (const std::exception& e) {
900+
spdlog::warn("[IntegrityCheckBypass]: Failed to parse patch number from {}: {}", filename, e.what());
901+
}
902+
}
903+
}
904+
}
905+
906+
if (highest_patch_num >= 0) {
907+
spdlog::info("[IntegrityCheckBypass]: Highest patch number found: {}", highest_patch_num);
908+
} else {
909+
spdlog::warn("[IntegrityCheckBypass]: No valid patch files found!");
910+
highest_patch_num = 0;
911+
}
912+
913+
s_patch_count_checked = true;
914+
s_patch_count = highest_patch_num;
915+
916+
return highest_patch_num;
917+
}
918+
829919
void IntegrityCheckBypass::immediate_patch_dd2() {
830920
// Just like RE4, this deals with the scans that are done every frame on the game's memory.
831921
// The scans are still performed, but the crash will be avoided.

src/mods/IntegrityCheckBypass.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,17 @@ class IntegrityCheckBypass : public Mod {
4545
static inline uint32_t s_last_non_zero_corruption{ 8 }; // What I've seen it default to
4646

4747
static void sha3_rsa_code_midhook(safetyhook::Context& context);
48+
static void pak_load_check_function(safetyhook::Context& context);
49+
static void patch_version_hook(safetyhook::Context& context);
50+
static int scan_patch_files_count();
4851
static void restore_unencrypted_paks();
4952
static inline safetyhook::MidHook s_sha3_rsa_code_midhook;
53+
static inline safetyhook::MidHook s_pak_load_check_function_hook;
54+
static inline safetyhook::MidHook s_patch_version_hook;
5055
static inline std::optional<uintptr_t> s_sha3_code_end{};
5156
static inline int32_t s_sha3_reg_index{-1};
57+
static inline int s_patch_count;
58+
static inline bool s_patch_count_checked;
5259

5360
static void anti_debug_watcher();
5461
static void init_anti_debug_watcher();

0 commit comments

Comments
 (0)