diff --git a/BigBaseV2/src/main.cpp b/BigBaseV2/src/main.cpp index f146afc0..2bd3df14 100644 --- a/BigBaseV2/src/main.cpp +++ b/BigBaseV2/src/main.cpp @@ -9,6 +9,7 @@ #include "script_mgr.hpp" #include "thread_pool.hpp" +#include "native_hooks/native_hooks.hpp" #include "services/globals_service.hpp" #include "services/mobile_service.hpp" #include "services/vehicle_service.hpp" @@ -55,20 +56,26 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID) g_hooking->enable(); LOG(INFO) << "Hooking enabled."; - LOG(INFO) << "Registering service instances..."; auto globals_service_instace = std::make_unique(); auto mobile_service_instance = std::make_unique(); auto vehicle_service_instance = std::make_unique(); + LOG(INFO) << "Registered service instances..."; + + auto native_hooks_instance = std::make_unique(); + LOG(INFO) << "Dynamic native hooker initialized."; while (g_running) { std::this_thread::sleep_for(500ms); } - LOG(INFO) << "Serviceses uninitialized."; + native_hooks_instance.reset(); + LOG(INFO) << "Dynamic native hooker uninitialized."; + vehicle_service_instance.reset(); mobile_service_instance.reset(); globals_service_instace.reset(); + LOG(INFO) << "Serviceses uninitialized."; // Make sure that all threads created don't have any blocking loops // otherwise make sure that they have stopped executing diff --git a/BigBaseV2/src/native_hooks/carmod_shop.hpp b/BigBaseV2/src/native_hooks/carmod_shop.hpp new file mode 100644 index 00000000..31bac06b --- /dev/null +++ b/BigBaseV2/src/native_hooks/carmod_shop.hpp @@ -0,0 +1,37 @@ +#pragma once +#include "native_hooks.hpp" +#include "natives.hpp" + +namespace big +{ + namespace carmod_shop + { + inline void SET_ENTITY_COORDS(rage::scrNativeCallContext* src) + { + if (!g.vehicle.ls_customs) + { + ENTITY::SET_ENTITY_COORDS( + src->get_arg(0), + src->get_arg(1), + src->get_arg(2), + src->get_arg(3), + src->get_arg(4), + src->get_arg(5), + src->get_arg(6), + src->get_arg(7) + ); + } + } + + inline void SET_ENTITY_HEADING(rage::scrNativeCallContext* src) + { + if (!g.vehicle.ls_customs) + { + ENTITY::SET_ENTITY_HEADING( + src->get_arg(0), + src->get_arg(1) + ); + } + } + } +} \ No newline at end of file diff --git a/BigBaseV2/src/native_hooks/freemode.hpp b/BigBaseV2/src/native_hooks/freemode.hpp new file mode 100644 index 00000000..89810cb4 --- /dev/null +++ b/BigBaseV2/src/native_hooks/freemode.hpp @@ -0,0 +1,15 @@ +#pragma once + +namespace big +{ + namespace freemode + { + inline void NETWORK_CAN_BAIL(rage::scrNativeCallContext* src) + { + LOG(INFO) << "NATIVE_HOOK => NETWORK_CAN_BAIL : TRIGGERED"; + + src->set_return_value(false); + } + } + +} \ No newline at end of file diff --git a/BigBaseV2/src/native_hooks/native_hooks.hpp b/BigBaseV2/src/native_hooks/native_hooks.hpp index baa48f96..1fd15017 100644 --- a/BigBaseV2/src/native_hooks/native_hooks.hpp +++ b/BigBaseV2/src/native_hooks/native_hooks.hpp @@ -1,16 +1,84 @@ #pragma once -#include "natives.hpp" +#include "gta/joaat.hpp" +#include "gta/script_thread.hpp" +#include "native_hooks/carmod_shop.hpp" +#include "native_hooks/freemode.hpp" +#include "script_hook.hpp" -namespace big::native_hook +namespace big { - inline void NETWORK_CAN_BAIL(rage::scrNativeCallContext* src); - inline void STAT_SET_INT(rage::scrNativeCallContext* src); - inline void TRIGGER_SCRIPT_EVENT(rage::scrNativeCallContext* src); + class native_hooks; + inline native_hooks* g_native_hooks{}; - static std::unordered_map natives_replace = + class native_hooks final { - { 0x580CE4438479CC61, &NETWORK_CAN_BAIL }, - { 0xB3271D7AB655B441, &STAT_SET_INT }, - { 0x5AE99C571D5BBE5D, &TRIGGER_SCRIPT_EVENT } + typedef std::pair native_detour; + + std::map> m_native_registrations; + + std::map> m_script_hooks; + + public: + native_hooks() + { + this->add_native_detour(RAGE_JOAAT("carmod_shop"), 0x06843DA7060A026B, carmod_shop::SET_ENTITY_COORDS); + this->add_native_detour(RAGE_JOAAT("carmod_shop"), 0x8E2530AA8ADA980E, carmod_shop::SET_ENTITY_HEADING); + this->add_native_detour(RAGE_JOAAT("freemode"), 0x580CE4438479CC61, freemode::NETWORK_CAN_BAIL); + + g_native_hooks = this; + } + ~native_hooks() + { + g_native_hooks = nullptr; + } + + void add_native_detour(rage::joaat_t script_hash, rage::scrNativeHash hash, rage::scrNativeHandler detour) + { + if (auto it = m_native_registrations.find(script_hash); it != m_native_registrations.end()) + return it->second.push_back({ hash, detour }); + + m_native_registrations.emplace(script_hash, std::vector({ { hash, detour } })); + } + + bool check_for_thread(GtaThread* gta_thread) + { + std::unordered_map native_replacements; + rage::joaat_t script_hash = gta_thread->m_script_hash; + + std::map>::iterator pair = m_native_registrations.find(script_hash); + if (pair == m_native_registrations.end()) + return false; + + for (native_detour native_hook_reg : pair->second) + native_replacements.insert(native_hook_reg); + + if (native_replacements.size()) + { + if (m_script_hooks.find(gta_thread->m_script_hash) != m_script_hooks.end()) + { + // this should never happen but if it does we catch it + LOG(INFO) << "Dynamic native script hook still active for script, cleaning up..."; + + m_script_hooks.erase(gta_thread->m_script_hash); + } + + m_script_hooks.emplace( + gta_thread->m_script_hash, + std::make_unique(gta_thread->m_script_hash, native_replacements) + ); + + return true; + } + return false; + } + + void do_cleanup_for_thread(GtaThread* gta_thread) + { + if (m_script_hooks.erase(gta_thread->m_script_hash)) + { + LOG(INFO) << gta_thread->m_name << " script terminated, cleaning up native hooks"; + } + } + }; } \ No newline at end of file diff --git a/BigBaseV2/src/native_hooks/network_can_bail.cpp b/BigBaseV2/src/native_hooks/network_can_bail.cpp index 8e406355..9b00530d 100644 --- a/BigBaseV2/src/native_hooks/network_can_bail.cpp +++ b/BigBaseV2/src/native_hooks/network_can_bail.cpp @@ -1,8 +1,8 @@ #include "native_hooks.hpp" -namespace big::native_hook +namespace big { - void NETWORK_CAN_BAIL(rage::scrNativeCallContext* src) + inline void NETWORK_CAN_BAIL(rage::scrNativeCallContext* src) { LOG(INFO) << "NATIVE_HOOK => NETWORK_CAN_BAIL : TRIGGERED"; diff --git a/BigBaseV2/src/native_hooks/stat_set_int.cpp b/BigBaseV2/src/native_hooks/stat_set_int.cpp deleted file mode 100644 index 14af0663..00000000 --- a/BigBaseV2/src/native_hooks/stat_set_int.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "native_hooks.hpp" -#include "gta/joaat.hpp" - -namespace big::native_hook -{ - void STAT_SET_INT(rage::scrNativeCallContext* src) - { - Hash stat_hash = src->get_arg(0); - int value = src->get_arg(1); - BOOL save = src->get_arg(2); - - switch (stat_hash) - { - case RAGE_JOAAT("MPPLY_GAME_EXPLOITS"): - case RAGE_JOAAT("MPPLY_VC_HATE"): - case RAGE_JOAAT("MPPLY_EXPLOITS"): - case RAGE_JOAAT("MPPLY_TC_ANNOYINGME"): - case RAGE_JOAAT("MPPLY_TC_HATE"): - src->set_return_value(true); - - break; - default: - src->set_return_value(STATS::STAT_SET_INT(stat_hash, value, save)); - - break; - } - } -} \ No newline at end of file diff --git a/BigBaseV2/src/native_hooks/trigger_script_event.cpp b/BigBaseV2/src/native_hooks/trigger_script_event.cpp deleted file mode 100644 index c3a215e3..00000000 --- a/BigBaseV2/src/native_hooks/trigger_script_event.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "native_hooks.hpp" -#include "pointers.hpp" - -namespace big::native_hook -{ - void TRIGGER_SCRIPT_EVENT(rage::scrNativeCallContext* src) - { - int event_group = src->get_arg(0); - Any* event_data = src->get_arg(1); - int event_size = src->get_arg(3); - int player_bits = src->get_arg(4); - - if (event_group) - { - Hash event_hash = event_data[0]; - - LOG(INFO) << "Event hash: " << event_hash; - for (size_t i = 1; i < std::min(event_size, 200); i++) - LOG(INFO) << "Arg[#" << i << "] : " << event_data[i]; - } - - SCRIPT::TRIGGER_SCRIPT_EVENT(event_group, event_data, event_size, player_bits); - } -} \ No newline at end of file