Skip to content

Commit

Permalink
Add IntegrityCheckBypass (fixes interaction/cutscenes breaking in ful…
Browse files Browse the repository at this point in the history
…l version of RE3)
  • Loading branch information
praydog committed Apr 3, 2020
1 parent 95dcc20 commit 9bd9187
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ set(MODS_SRC
FirstPerson.cpp
FreeCam.hpp
FreeCam.cpp
IntegrityCheckBypass.hpp
IntegrityCheckBypass.cpp
ManualFlashlight.hpp
ManualFlashlight.cpp
ObjectExplorer.hpp
Expand Down
46 changes: 46 additions & 0 deletions src/IntegrityCheckBypass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "utility/Scan.hpp"

#include "IntegrityCheckBypass.hpp"

struct IntegrityCheckPattern {
std::string pat{};
uint32_t offset{};
};

std::optional<std::string> IntegrityCheckBypass::on_initialize() {
// Patterns for assigning or accessing of the integrity check boolean
std::vector<IntegrityCheckPattern> possible_patterns{
/*
cmp qword ptr [rax+18h], 0
cmovz ecx, r15d
mov cs:bypass_integrity_checks, cl*/
// Referenced above "steam_api64.dll"
{"48 ? ? 18 00 41 ? ? ? 88 0D ? ? ? ?", 11},
{"48 ? ? 18 00 0F ? ? 88 0D ? ? ? ? 49 ? ? ? 48", 10},
};

for (auto& possible_pattern : possible_patterns) {
auto integrity_check_ref = utility::scan(g_framework->get_module().as<HMODULE>(), possible_pattern.pat);

if (!integrity_check_ref) {
continue;
}

m_bypass_integrity_checks = (bool*)utility::calculate_absolute(*integrity_check_ref + possible_pattern.offset);
}

// These may be removed, so don't fail altogether
/*if (m_bypass_integrity_checks == nullptr) {
return "Failed to find IntegrityCheckBypass pattern";
}*/

spdlog::info("[{:s}]: bypass_integrity_checks: {:x}", get_name().data(), (uintptr_t)m_bypass_integrity_checks);

return Mod::on_initialize();
}

void IntegrityCheckBypass::on_frame() {
if (m_bypass_integrity_checks != nullptr) {
*m_bypass_integrity_checks = true;
}
}
18 changes: 18 additions & 0 deletions src/IntegrityCheckBypass.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include "Mod.hpp"

// Always on for RE3
// Because we use hooks that modify the integrity of the executable
// And RE3 has unfortunately decided to implement an integrity check on the executable code of the process
class IntegrityCheckBypass : public Mod {
public:
std::string_view get_name() const override { return "IntegrityCheckBypass"; };
std::optional<std::string> on_initialize() override;

void on_frame() override;

private:
// This is what the game uses to bypass its integrity checks altogether or something
bool* m_bypass_integrity_checks{ nullptr };
};
5 changes: 5 additions & 0 deletions src/Mods.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <spdlog/spdlog.h>

#include "IntegrityCheckBypass.hpp"
#include "PositionHooks.hpp"
#include "FirstPerson.hpp"
#include "DeveloperTools.hpp"
Expand All @@ -10,6 +11,10 @@

Mods::Mods()
{
#ifdef RE3
m_mods.emplace_back(std::make_unique<IntegrityCheckBypass>());
#endif

m_mods.emplace_back(std::make_unique<PositionHooks>());
m_mods.emplace_back(std::make_unique<FirstPerson>());
m_mods.emplace_back(std::make_unique<ManualFlashlight>());
Expand Down

0 comments on commit 9bd9187

Please sign in to comment.