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();
9294bool module_has_rwx_section (HMODULE mod);
9395bool core_modules_signed ();
9496bool hypervisor_present ();
97+ void snapshot_prologues ();
98+ bool prologues_ok ();
9599std::string seed;
96100void cleanUpSeedData (const std::string& seed);
97101std::string signature;
@@ -103,11 +107,16 @@ std::atomic<bool> LoggedIn(false);
103107std::atomic<long long > last_integrity_check{ 0 };
104108std::atomic<int > integrity_fail_streak{ 0 };
105109std::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
107115void 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+
19922026void 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