Skip to content

Commit f16bfae

Browse files
committed
Add prologue integrity checks
1 parent 6302206 commit f16bfae

1 file changed

Lines changed: 40 additions & 0 deletions

File tree

auth.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
#include <softpub.h>
4747
#include <cwctype>
4848
#include <intrin.h>
49+
#include <array>
50+
#include <cstring>
4951
#include <stdexcept>
5052
#include <string>
5153
#include <array>
@@ -92,6 +94,8 @@ bool user_writable_module_present();
9294
bool module_has_rwx_section(HMODULE mod);
9395
bool core_modules_signed();
9496
bool hypervisor_present();
97+
void snapshot_prologues();
98+
bool prologues_ok();
9599
std::string seed;
96100
void cleanUpSeedData(const std::string& seed);
97101
std::string signature;
@@ -103,11 +107,16 @@ std::atomic<bool> LoggedIn(false);
103107
std::atomic<long long> last_integrity_check{ 0 };
104108
std::atomic<int> integrity_fail_streak{ 0 };
105109
std::atomic<long long> last_module_check{ 0 };
110+
std::atomic<bool> prologues_ready{ false };
111+
std::array<uint8_t, 16> pro_req{};
112+
std::array<uint8_t, 16> pro_verify{};
113+
std::array<uint8_t, 16> pro_checkinit{};
106114

107115
void KeyAuth::api::init()
108116
{
109117
std::thread(runChecks).detach();
110118
std::thread(integrity_watchdog).detach();
119+
snapshot_prologues();
111120
seed = generate_random_number();
112121
std::atexit([]() { cleanUpSeedData(seed); });
113122
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)modify, 0, 0, 0);
@@ -1989,6 +1998,31 @@ bool hypervisor_present()
19891998
return false;
19901999
}
19912000

2001+
void snapshot_prologues()
2002+
{
2003+
if (prologues_ready.load())
2004+
return;
2005+
const auto req_ptr = reinterpret_cast<const uint8_t*>(reinterpret_cast<uintptr_t>(&KeyAuth::api::req));
2006+
const auto verify_ptr = reinterpret_cast<const uint8_t*>(reinterpret_cast<uintptr_t>(&VerifyPayload));
2007+
const auto check_ptr = reinterpret_cast<const uint8_t*>(reinterpret_cast<uintptr_t>(&checkInit));
2008+
std::memcpy(pro_req.data(), req_ptr, pro_req.size());
2009+
std::memcpy(pro_verify.data(), verify_ptr, pro_verify.size());
2010+
std::memcpy(pro_checkinit.data(), check_ptr, pro_checkinit.size());
2011+
prologues_ready.store(true);
2012+
}
2013+
2014+
bool prologues_ok()
2015+
{
2016+
if (!prologues_ready.load())
2017+
return true;
2018+
const auto req_ptr = reinterpret_cast<const uint8_t*>(reinterpret_cast<uintptr_t>(&KeyAuth::api::req));
2019+
const auto verify_ptr = reinterpret_cast<const uint8_t*>(reinterpret_cast<uintptr_t>(&VerifyPayload));
2020+
const auto check_ptr = reinterpret_cast<const uint8_t*>(reinterpret_cast<uintptr_t>(&checkInit));
2021+
return std::memcmp(pro_req.data(), req_ptr, pro_req.size()) == 0 &&
2022+
std::memcmp(pro_verify.data(), verify_ptr, pro_verify.size()) == 0 &&
2023+
std::memcmp(pro_checkinit.data(), check_ptr, pro_checkinit.size()) == 0;
2024+
}
2025+
19922026
void KeyAuth::api::setDebug(bool value) {
19932027
KeyAuth::api::debug = value;
19942028
}
@@ -2379,6 +2413,9 @@ void checkInit() {
23792413
error(XorStr("module path check failed, possible side-load detected."));
23802414
}
23812415
}
2416+
if (!prologues_ok()) {
2417+
error(XorStr("function prologue check failed, possible inline hook detected."));
2418+
}
23822419
integrity_check();
23832420
}
23842421

@@ -2411,6 +2448,9 @@ void integrity_watchdog() {
24112448
error(XorStr("module path check failed, possible side-load detected."));
24122449
}
24132450
}
2451+
if (!prologues_ok()) {
2452+
error(XorStr("function prologue check failed, possible inline hook detected."));
2453+
}
24142454
if (check_section_integrity(XorStr(".text").c_str(), false)) {
24152455
const int streak = integrity_fail_streak.fetch_add(1) + 1;
24162456
if (streak >= 2) {

0 commit comments

Comments
 (0)