feat(NativeHooking): Added dynamic script native hooking
This commit is contained in:
@ -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<globals_service>();
|
||||
auto mobile_service_instance = std::make_unique<mobile_service>();
|
||||
auto vehicle_service_instance = std::make_unique<vehicle_service>();
|
||||
LOG(INFO) << "Registered service instances...";
|
||||
|
||||
auto native_hooks_instance = std::make_unique<native_hooks>();
|
||||
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
|
||||
|
37
BigBaseV2/src/native_hooks/carmod_shop.hpp
Normal file
37
BigBaseV2/src/native_hooks/carmod_shop.hpp
Normal file
@ -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<Entity>(0),
|
||||
src->get_arg<float>(1),
|
||||
src->get_arg<float>(2),
|
||||
src->get_arg<float>(3),
|
||||
src->get_arg<BOOL>(4),
|
||||
src->get_arg<BOOL>(5),
|
||||
src->get_arg<BOOL>(6),
|
||||
src->get_arg<BOOL>(7)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
inline void SET_ENTITY_HEADING(rage::scrNativeCallContext* src)
|
||||
{
|
||||
if (!g.vehicle.ls_customs)
|
||||
{
|
||||
ENTITY::SET_ENTITY_HEADING(
|
||||
src->get_arg<Entity>(0),
|
||||
src->get_arg<float>(1)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
BigBaseV2/src/native_hooks/freemode.hpp
Normal file
15
BigBaseV2/src/native_hooks/freemode.hpp
Normal file
@ -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<BOOL>(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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<rage::scrNativeHash, rage::scrNativeHandler> natives_replace =
|
||||
class native_hooks final
|
||||
{
|
||||
{ 0x580CE4438479CC61, &NETWORK_CAN_BAIL },
|
||||
{ 0xB3271D7AB655B441, &STAT_SET_INT },
|
||||
{ 0x5AE99C571D5BBE5D, &TRIGGER_SCRIPT_EVENT }
|
||||
typedef std::pair<rage::scrNativeHash, rage::scrNativeHandler> native_detour;
|
||||
|
||||
std::map<rage::joaat_t, std::vector<native_detour>> m_native_registrations;
|
||||
|
||||
std::map<rage::joaat_t, std::unique_ptr<script_hook>> 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<native_detour>({ { hash, detour } }));
|
||||
}
|
||||
|
||||
bool check_for_thread(GtaThread* gta_thread)
|
||||
{
|
||||
std::unordered_map<rage::scrNativeHash, rage::scrNativeHandler> native_replacements;
|
||||
rage::joaat_t script_hash = gta_thread->m_script_hash;
|
||||
|
||||
std::map<rage::joaat_t, std::vector<native_detour>>::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<script_hook>(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";
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
@ -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";
|
||||
|
||||
|
@ -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<Hash>(0);
|
||||
int value = src->get_arg<int>(1);
|
||||
BOOL save = src->get_arg<BOOL>(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<BOOL>(true);
|
||||
|
||||
break;
|
||||
default:
|
||||
src->set_return_value<BOOL>(STATS::STAT_SET_INT(stat_hash, value, save));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<int>(0);
|
||||
Any* event_data = src->get_arg<Any*>(1);
|
||||
int event_size = src->get_arg<int>(3);
|
||||
int player_bits = src->get_arg<int>(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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user