From f338479c5c1e56cc2bac97988b514b6f32d9e604 Mon Sep 17 00:00:00 2001 From: maybegreat48 <96936658+maybegreat48@users.noreply.github.com> Date: Thu, 8 Dec 2022 12:23:57 +0000 Subject: [PATCH] RID Spoofing Improvements (#666) * Fix stability issues with handler hook * Better RID spoofing --- src/backend/backend.cpp | 2 +- src/backend/looped/looped.hpp | 2 +- .../{force_session_host.cpp => spoofing.cpp} | 12 +++++++- src/core/globals.hpp | 4 +++ src/hooking.cpp | 4 ++- src/hooking.hpp | 5 ++++ src/hooks/protections/receive_net_message.cpp | 25 ++++++++++++++++ src/hooks/script/script_handler.cpp | 19 +----------- .../spoofing/read_bitbuffer_gamer_handle.cpp | 14 +++++++++ src/hooks/spoofing/send_net_info_to_lobby.cpp | 14 +++------ .../spoofing/write_bitbuffer_gamer_handle.cpp | 23 +++++++++++++++ src/native_hooks/all_scripts.hpp | 29 +++++++++++++++++++ src/native_hooks/native_hooks.cpp | 2 ++ src/pointers.cpp | 18 ++++++++---- src/pointers.hpp | 6 ++-- 15 files changed, 139 insertions(+), 40 deletions(-) rename src/backend/looped/system/{force_session_host.cpp => spoofing.cpp} (70%) create mode 100644 src/hooks/spoofing/read_bitbuffer_gamer_handle.cpp create mode 100644 src/hooks/spoofing/write_bitbuffer_gamer_handle.cpp diff --git a/src/backend/backend.cpp b/src/backend/backend.cpp index cc3346a4..f176107c 100644 --- a/src/backend/backend.cpp +++ b/src/backend/backend.cpp @@ -18,7 +18,7 @@ namespace big looped::system_self_globals(); looped::system_update_pointers(); looped::system_desync_kick_protection(); - looped::system_force_session_host(); + looped::system_spoofing(); looped::system_mission_creator(); looped::system_auto_tp(); diff --git a/src/backend/looped/looped.hpp b/src/backend/looped/looped.hpp index 322c9ccb..a6282ae1 100644 --- a/src/backend/looped/looped.hpp +++ b/src/backend/looped/looped.hpp @@ -45,7 +45,7 @@ namespace big static void system_self_globals(); static void system_update_pointers(); static void system_desync_kick_protection(); - static void system_force_session_host(); + static void system_spoofing(); static void system_mission_creator(); static void system_auto_tp(); diff --git a/src/backend/looped/system/force_session_host.cpp b/src/backend/looped/system/spoofing.cpp similarity index 70% rename from src/backend/looped/system/force_session_host.cpp rename to src/backend/looped/system/spoofing.cpp index 8abc97c8..283001fd 100644 --- a/src/backend/looped/system/force_session_host.cpp +++ b/src/backend/looped/system/spoofing.cpp @@ -6,7 +6,7 @@ namespace big { static bool bLastForceHost = false; - void looped::system_force_session_host() + void looped::system_spoofing() { if (bLastForceHost != g->session.force_session_host && gta_util::get_network()->m_game_session_state == 0) { @@ -29,5 +29,15 @@ namespace big bLastForceHost = g->session.force_session_host; } + + if (g->spoofing.rockstar_id != g->spoofing.applied_spoof_rockstar_id && gta_util::get_network()->m_game_session_state == 0) + { + g->spoofing.applied_spoof_rockstar_id = g->spoofing.spoof_rockstar_id; + } + + if (g->spoofing.spoof_rockstar_id != g->spoofing.should_spoof_rockstar_id && gta_util::get_network()->m_game_session_state == 0) + { + g->spoofing.should_spoof_rockstar_id = g->spoofing.spoof_rockstar_id; + } } } diff --git a/src/core/globals.hpp b/src/core/globals.hpp index 5d71d832..caaeabbe 100644 --- a/src/core/globals.hpp +++ b/src/core/globals.hpp @@ -307,6 +307,10 @@ namespace big int session_language = 0; bool spoof_session_player_count = false; int session_player_count = 25; + + // don't save + bool should_spoof_rockstar_id = false; + uint64_t applied_spoof_rockstar_id = 0; }; struct tunables { diff --git a/src/hooking.cpp b/src/hooking.cpp index 93b49b36..fafaa11e 100644 --- a/src/hooking.cpp +++ b/src/hooking.cpp @@ -93,7 +93,9 @@ namespace big detour_hook_helper::add("STOPVT", g_pointers->m_serialize_take_off_ped_variation_task); detour_hook_helper::add("CSH", g_pointers->m_create_script_handler); - detour_hook_helper::add("SSAN", g_pointers->m_set_script_as_networked); + + detour_hook_helper::add("WBGH", g_pointers->m_write_bitbuffer_gamer_handle); + detour_hook_helper::add("RBGH", g_pointers->m_read_bitbuffer_gamer_handle); g_hooking = this; } diff --git a/src/hooking.hpp b/src/hooking.hpp index cc39aaaa..7bb8733c 100644 --- a/src/hooking.hpp +++ b/src/hooking.hpp @@ -31,7 +31,9 @@ namespace rage class netArrayHandlerBase; class CEventNetwork; class CSyncDataBase; + class rlGamerHandle; class netConnectionManager; + class datBitBuffer; namespace netConnection { @@ -128,6 +130,9 @@ namespace big static bool script_handler_is_networked(CGameScriptHandler* this_); static bool script_handler_dtor(CGameScriptHandler* this_, bool free_memory); static void set_script_as_networked(void*, rage::scrThread* thread, int instance_id); + + static bool write_bitbuffer_gamer_handle(rage::datBitBuffer* buffer, rage::rlGamerHandle* handle); + static bool read_bitbuffer_gamer_handle(rage::datBitBuffer* buffer, rage::rlGamerHandle* handle); }; class minhook_keepalive diff --git a/src/hooks/protections/receive_net_message.cpp b/src/hooks/protections/receive_net_message.cpp index 6b8dcc48..c6654a6b 100644 --- a/src/hooks/protections/receive_net_message.cpp +++ b/src/hooks/protections/receive_net_message.cpp @@ -37,6 +37,18 @@ namespace big hnd.unk_0009 = buf.Read(8); } + static void script_id_deserialize(CGameScriptId& id, rage::datBitBuffer& buffer) + { + id.m_hash = buffer.Read(32); + id.m_timestamp = buffer.Read(32); + + if (buffer.Read(1)) + id.m_position_hash = buffer.Read(32); + + if (buffer.Read(1)) + id.m_instance_id = buffer.Read(8); + } + bool hooks::receive_net_message(void* netConnectionManager, void* a2, rage::netConnection::InFrame* frame) { if (frame->get_event_type() == rage::netConnection::InFrame::EventType::FrameReceived) @@ -115,11 +127,13 @@ namespace big } } } + if (player && pl && player->id() != pl->id() && count == 1 && frame->m_msg_id == -1) { g_notification_service->push_error("Warning!", std::format("{} breakup kicked {}!", player->get_name(), pl->get_name())); session::add_infraction(player, Infraction::BREAKUP_KICK_DETECTED); } + break; } case rage::eNetMessage::MsgLostConnectionToHost: @@ -192,6 +206,17 @@ namespace big g_notification_service->push("Join Blocker", std::format("Trying to prevent {} from joining...", player->get_name())); return true; } + break; + } + case rage::eNetMessage::MsgScriptHostRequest: + { + CGameScriptId script; + script_id_deserialize(script, buffer); + + if (script.m_hash == RAGE_JOAAT("freemode") && g->session.force_script_host) + return true; + + break; } } } diff --git a/src/hooks/script/script_handler.cpp b/src/hooks/script/script_handler.cpp index 1b8e7c9d..2cc26435 100644 --- a/src/hooks/script/script_handler.cpp +++ b/src/hooks/script/script_handler.cpp @@ -1,7 +1,6 @@ #include "hooking.hpp" #include "gta/script_handler.hpp" -bool spoof_networked_status = true; namespace big { void hooking::hook_script_handler(CGameScriptHandler* handler) @@ -29,10 +28,7 @@ namespace big bool hooks::script_handler_is_networked(CGameScriptHandler* _this) { - if (spoof_networked_status) - return true; - - return false; + return true; } bool hooks::script_handler_dtor(CGameScriptHandler* _this, bool free_memory) @@ -56,17 +52,4 @@ namespace big return false; } } - - void hooks::set_script_as_networked(void* mgr, rage::scrThread* thread, int instance_id) - { - if (instance_id >= 0x100) - { - LOG(INFO) << "Blocked a crash"; - return; - } - - spoof_networked_status = false; - g_hooking->get_original()(mgr, thread, instance_id); - spoof_networked_status = true; - } }; diff --git a/src/hooks/spoofing/read_bitbuffer_gamer_handle.cpp b/src/hooks/spoofing/read_bitbuffer_gamer_handle.cpp new file mode 100644 index 00000000..b6b7115f --- /dev/null +++ b/src/hooks/spoofing/read_bitbuffer_gamer_handle.cpp @@ -0,0 +1,14 @@ +#include "hooking.hpp" +#include "network/Network.hpp" +#include "pointers.hpp" + +namespace big +{ + bool hooks::read_bitbuffer_gamer_handle(rage::datBitBuffer* buffer, rage::rlGamerHandle* handle) + { + bool result = g_hooking->get_original()(buffer, handle); + if (g->spoofing.should_spoof_rockstar_id && handle->m_rockstar_id == g->spoofing.applied_spoof_rockstar_id) + handle->m_rockstar_id = g_pointers->m_profile_gamer_info->m_gamer_handle_2.m_rockstar_id; + return result; + } +} \ No newline at end of file diff --git a/src/hooks/spoofing/send_net_info_to_lobby.cpp b/src/hooks/spoofing/send_net_info_to_lobby.cpp index be7ad051..f9de9668 100644 --- a/src/hooks/spoofing/send_net_info_to_lobby.cpp +++ b/src/hooks/spoofing/send_net_info_to_lobby.cpp @@ -30,10 +30,10 @@ namespace big player->m_external_ip.m_field4 = g->spoofing.ip_address[3]; } - if (g->spoofing.spoof_rockstar_id) + if (g->spoofing.should_spoof_rockstar_id) { - player->m_gamer_handle.m_rockstar_id = g->spoofing.rockstar_id; - player->m_gamer_handle_2.m_rockstar_id = g->spoofing.rockstar_id; + player->m_gamer_handle.m_rockstar_id = g->spoofing.applied_spoof_rockstar_id; + player->m_gamer_handle_2.m_rockstar_id = g->spoofing.applied_spoof_rockstar_id; } if (g->notifications.send_net_info_to_lobby.log) @@ -56,12 +56,6 @@ namespace big } } - const auto result = g_hooking->get_original()(player, a2, a3, a4); - - // restore player name to prevent detection of spoofed name - if (is_local_player && g->spoofing.spoof_username) - memcpy(player->m_name, g_local_player->m_player_info->m_net_player_data.m_name, sizeof(player->m_name)); - - return result; + return g_hooking->get_original()(player, a2, a3, a4); } } diff --git a/src/hooks/spoofing/write_bitbuffer_gamer_handle.cpp b/src/hooks/spoofing/write_bitbuffer_gamer_handle.cpp new file mode 100644 index 00000000..f8a76cf9 --- /dev/null +++ b/src/hooks/spoofing/write_bitbuffer_gamer_handle.cpp @@ -0,0 +1,23 @@ +#include "hooking.hpp" +#include "network/Network.hpp" +#include "pointers.hpp" + +namespace big +{ + bool hooks::write_bitbuffer_gamer_handle(rage::datBitBuffer* buffer, rage::rlGamerHandle* handle) + { + bool restore = false; + + if (g->spoofing.should_spoof_rockstar_id && handle->m_rockstar_id == g_pointers->m_profile_gamer_info->m_gamer_handle_2.m_rockstar_id) + { + handle->m_rockstar_id = g->spoofing.applied_spoof_rockstar_id; + restore = true; + } + + bool result = g_hooking->get_original()(buffer, handle); + + if (restore) + handle->m_rockstar_id = g_pointers->m_profile_gamer_info->m_gamer_handle_2.m_rockstar_id; + return result; + } +} \ No newline at end of file diff --git a/src/native_hooks/all_scripts.hpp b/src/native_hooks/all_scripts.hpp index 06027a31..44b3dc03 100644 --- a/src/native_hooks/all_scripts.hpp +++ b/src/native_hooks/all_scripts.hpp @@ -4,6 +4,7 @@ #include "core/scr_globals.hpp" #include "fiber_pool.hpp" #include "util/scripts.hpp" +#include "hooking.hpp" namespace big { @@ -35,5 +36,33 @@ namespace big *scr_globals::gsbd.as() = 4; src->set_return_value(TRUE); } + + void NETWORK_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT(rage::scrNativeCallContext* src) + { + if (rage::scrThread::get() && rage::scrThread::get()->m_handler) + { + if (auto hook = g_hooking->m_handler_hooks[(CGameScriptHandler*)rage::scrThread::get()->m_handler].get()) + { + hook->disable(); + g_hooking->m_handler_hooks.erase((CGameScriptHandler*)rage::scrThread::get()->m_handler); + } + } + + NETWORK::NETWORK_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT(src->get_arg(0), src->get_arg(1), src->get_arg(2)); + } + + void NETWORK_TRY_TO_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT(rage::scrNativeCallContext* src) + { + if (rage::scrThread::get() && rage::scrThread::get()->m_handler) + { + if (auto hook = g_hooking->m_handler_hooks[(CGameScriptHandler*)rage::scrThread::get()->m_handler].get()) + { + hook->disable(); + g_hooking->m_handler_hooks.erase((CGameScriptHandler*)rage::scrThread::get()->m_handler); + } + } + + src->set_return_value(NETWORK::NETWORK_TRY_TO_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT(src->get_arg(0), src->get_arg(1), src->get_arg(2))); + } } } \ No newline at end of file diff --git a/src/native_hooks/native_hooks.cpp b/src/native_hooks/native_hooks.cpp index 913b628b..88d5c2ac 100644 --- a/src/native_hooks/native_hooks.cpp +++ b/src/native_hooks/native_hooks.cpp @@ -105,6 +105,8 @@ namespace big { add_native_detour(0x812595A0644CE1DE, all_scripts::IS_DLC_PRESENT); add_native_detour(0x5D10B3795F3FC886, all_scripts::NETWORK_HAS_RECEIVED_HOST_BROADCAST_DATA); + add_native_detour(0x1CA59E306ECB80A5, all_scripts::NETWORK_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT); + add_native_detour(0xD1110739EEADB592, all_scripts::NETWORK_TRY_TO_SET_THIS_SCRIPT_IS_NETWORK_SCRIPT); add_native_detour(RAGE_JOAAT("carmod_shop"), 0x06843DA7060A026B, carmod_shop::SET_ENTITY_COORDS); add_native_detour(RAGE_JOAAT("carmod_shop"), 0x8E2530AA8ADA980E, carmod_shop::SET_ENTITY_HEADING); add_native_detour(RAGE_JOAAT("carmod_shop"), 0x34E710FF01247C5A, carmod_shop::SET_VEHICLE_LIGHTS); diff --git a/src/pointers.cpp b/src/pointers.cpp index da13efb9..1a4f2a45 100644 --- a/src/pointers.cpp +++ b/src/pointers.cpp @@ -647,18 +647,24 @@ namespace big m_create_script_handler = *(ptr.add(3).rip().as() + 8); }); - // Set Script As Networked - main_batch.add("SSAN", "48 89 5C 24 10 55 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 70 FD", [this](memory::handle ptr) - { - m_set_script_as_networked = ptr.as(); - }); - // Creator Warp Cheat Triggered Patch main_batch.add("CW", "74 44 E8 ? ? ? ? 80 65 2B F8 48 8D 0D ? ? ? ? 48 89 4D 17 48 89 7D 1F 89 7D 27 C7 45", [](memory::handle ptr) { memory::byte_patch::make(ptr.as(), 0xEB)->apply(); }); + // Write Bitbuffer Gamer Handle + main_batch.add("WBGH", "4C 8B DC 49 89 5B 08 57 48 83 EC 30 48 8B F9", [this](memory::handle ptr) + { + m_write_bitbuffer_gamer_handle = ptr.as(); + }); + + // Read Bitbuffer Gamer Handle + main_batch.add("RBGH", "48 8B C4 48 89 58 10 48 89 68 18 48 89 70 20 57 48 83 EC 30 C6", [this](memory::handle ptr) + { + m_read_bitbuffer_gamer_handle = ptr.as(); + }); + auto mem_region = memory::module("GTA5.exe"); main_batch.run(mem_region); diff --git a/src/pointers.hpp b/src/pointers.hpp index 4ad11371..b8c27ac4 100644 --- a/src/pointers.hpp +++ b/src/pointers.hpp @@ -200,8 +200,10 @@ namespace big PVOID m_serialize_take_off_ped_variation_task; - PVOID m_create_script_handler{}; - PVOID m_set_script_as_networked{}; + PVOID m_create_script_handler; + + PVOID m_write_bitbuffer_gamer_handle; + PVOID m_read_bitbuffer_gamer_handle; }; inline pointers* g_pointers{};