From ee92caa88933244013f84b807240b8f50f98e6c2 Mon Sep 17 00:00:00 2001 From: Mr-X-GTA <110748953+Mr-X-GTA@users.noreply.github.com> Date: Sun, 19 May 2024 20:26:44 +0200 Subject: [PATCH] Protection improvements (#3146) --- src/backend/looped/system/spoofing.cpp | 3 +- src/function_types.hpp | 2 +- src/gta/enums.hpp | 1 - src/gta_pointers.hpp | 6 +- src/hooking/hooking.cpp | 2 +- src/hooking/hooking.hpp | 2 +- src/hooks/misc/log_message_error_box.cpp | 5 + .../protections/invalid_mods_crash_detour.cpp | 11 - .../protections/received_clone_create.cpp | 19 +- src/hooks/protections/received_event.cpp | 194 +++++++++++++++--- src/hooks/protections/searchlight_crash.cpp | 2 +- src/logger/stack_trace.cpp | 36 +++- src/logger/stack_trace.hpp | 4 +- src/pointers.cpp | 23 +-- src/services/players/player.hpp | 1 + src/util/fuzzer.hpp | 64 ++---- src/util/math.hpp | 22 ++ src/util/protection.cpp | 30 ++- src/util/sync_trees.hpp | 3 - src/widgets/imgui_hotkey.hpp | 5 + 20 files changed, 290 insertions(+), 145 deletions(-) delete mode 100644 src/hooks/protections/invalid_mods_crash_detour.cpp diff --git a/src/backend/looped/system/spoofing.cpp b/src/backend/looped/system/spoofing.cpp index ab2e0f84..8a3a95d0 100644 --- a/src/backend/looped/system/spoofing.cpp +++ b/src/backend/looped/system/spoofing.cpp @@ -2,6 +2,7 @@ #include "core/scr_globals.hpp" #include "gta_util.hpp" #include "natives.hpp" +#include "util/math.hpp" #include #include @@ -18,7 +19,7 @@ namespace big uint64_t host_token; g_pointers->m_gta.m_generate_uuid(&host_token); - host_token = g.session.force_session_host ? (rand() % 10000) : host_token; + host_token = g.session.force_session_host ? math::rand(10000) : host_token; *g_pointers->m_gta.m_host_token = host_token; diff --git a/src/function_types.hpp b/src/function_types.hpp index 5d392e6d..2e5ee3cf 100644 --- a/src/function_types.hpp +++ b/src/function_types.hpp @@ -211,5 +211,5 @@ namespace big::functions using can_create_vehicle = bool (*)(); - using get_unk_weapon = void* (*) (CPed*); + using get_searchlight = void* (*) (CPed*); } diff --git a/src/gta/enums.hpp b/src/gta/enums.hpp index b2b30ba9..e11ca33b 100644 --- a/src/gta/enums.hpp +++ b/src/gta/enums.hpp @@ -485,7 +485,6 @@ enum class eNetworkEvents : uint16_t REQUEST_DETACHMENT_EVENT, KICK_VOTES_EVENT, GIVE_PICKUP_REWARDS_EVENT, - NETWORK_CRC_HASH_CHECK_EVENT, BLOW_UP_VEHICLE_EVENT, NETWORK_SPECIAL_FIRE_EQUIPPED_WEAPON, NETWORK_RESPONDED_TO_THREAT_EVENT, diff --git a/src/gta_pointers.hpp b/src/gta_pointers.hpp index e464011e..7721011d 100644 --- a/src/gta_pointers.hpp +++ b/src/gta_pointers.hpp @@ -187,7 +187,6 @@ namespace big functions::fipackfile_unmount m_fipackfile_unmount; functions::fipackfile_close_archive m_fipackfile_close_archive; - PVOID m_invalid_mods_crash_detour; PVOID m_invalid_decal_crash; PVOID m_task_parachute_object; PVOID m_task_ambient_clips; @@ -305,6 +304,7 @@ namespace big functions::get_host_array_handler_by_index m_get_host_array_handler_by_index; PVOID m_error_message_box; + PVOID m_error_message_box_2; functions::get_title_caption_error_message_box m_get_title_caption_error_message_box; @@ -373,9 +373,9 @@ namespace big PVOID m_format_int; PVOID m_searchlight_crash; - functions::get_unk_weapon m_get_unk_weapon; + functions::get_searchlight m_get_searchlight; - GenericPool** m_clone_create_pool; // this is not a normal pool + GenericPool** m_vehicle_allocator; // this is not a normal pool PVOID m_write_physical_script_game_state_data_node; }; diff --git a/src/hooking/hooking.cpp b/src/hooking/hooking.cpp index acc0835d..01231919 100644 --- a/src/hooking/hooking.cpp +++ b/src/hooking/hooking.cpp @@ -65,7 +65,6 @@ namespace big detour_hook_helper::add("GNED", g_pointers->m_gta.m_get_network_event_data); detour_hook_helper::add("WPGDN", g_pointers->m_gta.m_write_player_gamer_data_node); - detour_hook_helper::add("IMCD", g_pointers->m_gta.m_invalid_mods_crash_detour); detour_hook_helper::add("IDC", g_pointers->m_gta.m_invalid_decal_crash); detour_hook_helper::add("TPO", g_pointers->m_gta.m_task_parachute_object); detour_hook_helper::add("TAC", g_pointers->m_gta.m_task_ambient_clips); @@ -125,6 +124,7 @@ namespace big detour_hook_helper::add("NHM", g_pointers->m_gta.m_netfilter_handle_message); detour_hook_helper::add("E0MBH", g_pointers->m_gta.m_error_message_box); + detour_hook_helper::add("E0MBH2", g_pointers->m_gta.m_error_message_box_2); detour_hook_helper::add("SNPPD", g_pointers->m_gta.m_send_non_physical_player_data); diff --git a/src/hooking/hooking.hpp b/src/hooking/hooking.hpp index 66004e05..f694c908 100644 --- a/src/hooking/hooking.hpp +++ b/src/hooking/hooking.hpp @@ -104,7 +104,6 @@ namespace big static void write_player_gamer_data_node(rage::netObject* player, CPlayerGamerDataNode* node); static void write_player_game_state_data_node(rage::netObject* player, CPlayerGameStateDataNode* node); - static void invalid_mods_crash_detour(int64_t a1, int64_t a2, int a3, char a4); static void invalid_decal(uintptr_t a1, int a2); static int task_parachute_object(uint64_t _this, int a2, int a3); static int task_ambient_clips(uint64_t _this, int a2, int a3); @@ -164,6 +163,7 @@ namespace big static int netfilter_handle_message(__int64 filter, char* message, int flags); static void log_error_message_box(rage::joaat_t joaated_error_code, bool a2); + static void log_error_message_box_2(rage::joaat_t joaated_error_code); static bool send_non_physical_player_data(CNetGamePlayer* player, __int64 message, int flags, void* a4, CNetGamePlayer* a5); diff --git a/src/hooks/misc/log_message_error_box.cpp b/src/hooks/misc/log_message_error_box.cpp index 9cefc260..cb9bbf25 100644 --- a/src/hooks/misc/log_message_error_box.cpp +++ b/src/hooks/misc/log_message_error_box.cpp @@ -38,4 +38,9 @@ namespace big log_stack_trace(); } + + void hooks::log_error_message_box_2(rage::joaat_t joaated_error_code) + { + log_error_message_box(joaated_error_code, false); + } } diff --git a/src/hooks/protections/invalid_mods_crash_detour.cpp b/src/hooks/protections/invalid_mods_crash_detour.cpp deleted file mode 100644 index 0c76f8f1..00000000 --- a/src/hooks/protections/invalid_mods_crash_detour.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "hooking/hooking.hpp" - -namespace big -{ - void hooks::invalid_mods_crash_detour(int64_t a1, int64_t a2, int a3, char a4) - { - if (!*(int64_t*)(a1 + 0xD8)) [[unlikely]] - return; - g_hooking->get_original()(a1, a2, a3, a4); - } -} \ No newline at end of file diff --git a/src/hooks/protections/received_clone_create.cpp b/src/hooks/protections/received_clone_create.cpp index 30427fa9..b93971db 100644 --- a/src/hooks/protections/received_clone_create.cpp +++ b/src/hooks/protections/received_clone_create.cpp @@ -13,11 +13,22 @@ namespace big return; } - if (*g_pointers->m_gta.m_clone_create_pool && (*g_pointers->m_gta.m_clone_create_pool)->m_size < 2) + switch (object_type) { - // We don't have enough memory to handle this - g_notification_service.push_warning("Protections", "Low net object pool size"); - return; + case eNetObjType::NET_OBJ_TYPE_AUTOMOBILE: + case eNetObjType::NET_OBJ_TYPE_BIKE: + case eNetObjType::NET_OBJ_TYPE_BOAT: + case eNetObjType::NET_OBJ_TYPE_HELI: + case eNetObjType::NET_OBJ_TYPE_PLANE: + case eNetObjType::NET_OBJ_TYPE_SUBMARINE: + case eNetObjType::NET_OBJ_TYPE_TRAILER: + case eNetObjType::NET_OBJ_TYPE_TRAIN: + if ((*g_pointers->m_gta.m_vehicle_allocator)->m_size < 10) [[unlikely]] + { + // We don't have enough memory to handle this + g_notification_service.push_warning("Protections", "Low vehicle allocator size"); + return; + } } auto plyr = g_player_service->get_by_id(src->m_player_id); diff --git a/src/hooks/protections/received_event.cpp b/src/hooks/protections/received_event.cpp index aae1c867..c2ffd72f 100644 --- a/src/hooks/protections/received_event.cpp +++ b/src/hooks/protections/received_event.cpp @@ -38,6 +38,21 @@ namespace big return false; } + + inline bool is_local_vehicle(int16_t net_id) + { + return g_local_player && g_local_player->m_vehicle && g_local_player->m_vehicle->m_net_object + && g_local_player->m_vehicle->m_driver == g_local_player && g_local_player->m_vehicle->m_net_object->m_object_id == net_id; + } + + inline bool is_in_vehicle(CPed* ped) + { + for (int i = 0; i < 15; i++) + if (g_local_player->m_vehicle->m_passengers[i] == ped) + return true; + + return false; + } // Returns true if bad event bool scan_weapon_damage_event(rage::netEventMgr* event_manager, CNetGamePlayer* player, CNetGamePlayer* target_player, int event_index, int event_handled_bitset, rage::datBitBuffer* buffer) @@ -376,6 +391,96 @@ namespace big // clang-format on } + bool scan_play_sound_event(player_ptr plyr, rage::datBitBuffer& buffer) + { + bool is_entity = buffer.Read(1); + std::int16_t entity_net_id; + rage::fvector3 position; + + if (is_entity) + { + entity_net_id = buffer.Read(13); + } + else + { + position.x = buffer.ReadSignedFloat(19, 1337.0f); + position.y = buffer.ReadSignedFloat(19, 1337.0f); + position.z = buffer.ReadFloat(19, 1337.0f); + } + + bool has_ref = buffer.Read(1); + uint32_t ref_hash = has_ref ? buffer.Read(32) : 0; + uint32_t sound_hash = buffer.Read(32); + uint8_t sound_id = buffer.Read(8); + + bool has_script_hash = buffer.Read(1); + uint32_t script_hash = has_script_hash ? buffer.Read(32) : 0; + + static const std::unordered_set blocked_ref_hashes = {"Arena_Vehicle_Mod_Shop_Sounds"_J, "CELEBRATION_SOUNDSET"_J, "DLC_AW_Arena_Office_Planning_Wall_Sounds"_J, "DLC_AW_Arena_Spin_Wheel_Game_Frontend_Sounds"_J, "DLC_Biker_SYG_Sounds"_J, "DLC_BTL_SECURITY_VANS_RADAR_PING_SOUNDS"_J, "DLC_BTL_Target_Pursuit_Sounds"_J, "DLC_GR_Bunker_Door_Sounds"_J, "DLC_GR_CS2_Sounds"_J, "DLC_IO_Warehouse_Mod_Garage_Sounds"_J, "DLC_MPSUM2_HSW_Up_Sounds"_J, "DLC_sum20_Business_Battle_AC_Sounds"_J, "DLC_TG_Running_Back_Sounds"_J, "dlc_vw_table_games_frontend_sounds"_J, "dlc_xm_facility_entry_exit_sounds"_J, "Frontend"_J, "GTAO_Boss_Goons_FM_Soundset"_J, "GTAO_Exec_SecuroServ_Computer_Sounds"_J, "GTAO_Exec_SecuroServ_Warehouse_PC_Sounds"_J, "GTAO_Script_Doors_Faded_Screen_Sounds"_J, "GTAO_SMG_Hangar_Computer_Sounds"_J, "HUD_AMMO_SHOP_SOUNDSET"_J, "HUD_FRONTEND_CUSTOM_SOUNDSET"_J, "HUD_FRONTEND_DEFAULT_SOUNDSET"_J, "HUD_FRONTEND_MP_SOUNDSET"_J, "HUD_FRONTEND_MP_COLLECTABLE_SOUNDS"_J, "HUD_FRONTEND_TATTOO_SHOP_SOUNDSET"_J, "HUD_FRONTEND_CLOTHESSHOP_SOUNDSET"_J, "HUD_FRONTEND_STANDARD_PICKUPS_NPC_SOUNDSET"_J, "HUD_FRONTEND_VEHICLE_PICKUPS_NPC_SOUNDSET"_J, "HUD_FRONTEND_WEAPONS_PICKUPS_NPC_SOUNDSET"_J, "HUD_FREEMODE_SOUNDSET"_J, "HUD_MINI_GAME_SOUNDSET"_J, "HUD_AWARDS"_J, "JA16_Super_Mod_Garage_Sounds"_J, "Low2_Super_Mod_Garage_Sounds"_J, "MissionFailedSounds"_J, "MP_CCTV_SOUNDSET"_J, "MP_LOBBY_SOUNDS"_J, "MP_MISSION_COUNTDOWN_SOUNDSET"_J, "Phone_SoundSet_Default"_J, "Phone_SoundSet_Glasses_Cam"_J, "Phone_SoundSet_Prologue"_J, "Phone_SoundSet_Franklin"_J, "Phone_SoundSet_Michael"_J, "Phone_SoundSet_Trevor"_J, "PLAYER_SWITCH_CUSTOM_SOUNDSET"_J, "RESPAWN_ONLINE_SOUNDSET"_J, "TATTOOIST_SOUNDS"_J, "WastedSounds"_J, "WEB_NAVIGATION_SOUNDS_PHONE"_J}; + static const std::unordered_set blocked_sound_hashes = {"Remote_Ring"_J, "COP_HELI_CAM_ZOOM"_J, "Object_Dropped_Remote"_J}; + if (blocked_ref_hashes.contains(ref_hash) || blocked_sound_hashes.contains(sound_hash)) + return true; + + switch (sound_hash) + { + case "DLC_XM_Explosions_Orbital_Cannon"_J: + { + if (is_entity) + return true; + + if (!scr_globals::globalplayer_bd.as()->Entries[plyr->id()].OrbitalBitset.IsSet(eOrbitalBitset::kOrbitalCannonActive)) + return true; + + static const std::unordered_set valid_script_hashes = {"am_mp_defunct_base"_J, "am_mp_orbital_cannon"_J, "fm_mission_controller_2020"_J, "fm_mission_controller"_J}; + if (!valid_script_hashes.contains(script_hash)) + return true; + + break; + } + } + + switch (ref_hash) + { + case "GTAO_Biker_Modes_Soundset"_J: + case "DLC_Biker_Sell_Postman_Sounds"_J: + { + if (is_entity) + return true; + + if (script_hash != "gb_biker_contraband_sell"_J) + return true; + + break; + } + case "DLC_AW_General_Sounds"_J: + { + if (sound_hash != "Airhorn_Blast_Long"_J) + return true; + + if (script_hash != "gb_casino_heist"_J) + return true; + + if (!gta_util::find_script_thread("gb_casino_heist"_J)) + return true; + + break; + } + case "GTAO_FM_Events_Soundset"_J: + { + if (!is_entity) + return true; + + if (sound_hash != "Explosion_Countdown"_J) + return true; + + break; + } + } + + buffer.Seek(0); + return false; + } + void hooks::received_event(rage::netEventMgr* event_manager, CNetGamePlayer* source_player, CNetGamePlayer* target_player, uint16_t event_id, int event_index, int event_handled_bitset, int buffer_size, rage::datBitBuffer* buffer) { if (event_id > 91u) [[unlikely]] @@ -521,9 +626,7 @@ namespace big // player sending this event is a modder case eNetworkEvents::REPORT_MYSELF_EVENT: { - if (auto plyr = g_player_service->get_by_id(source_player->m_player_id)) - session::add_infraction(plyr, Infraction::TRIGGERED_ANTICHEAT); - + session::add_infraction(plyr, Infraction::TRIGGERED_ANTICHEAT); g.reactions.game_anti_cheat_modder_detection.process(plyr); break; } @@ -539,11 +642,11 @@ namespace big || personal_vehicle == veh //Or we're in our personal vehicle. || self::spawned_vehicles.contains(net_id)) // Or it's a vehicle we spawned. { - auto plyr = g_player_service->get_by_id(source_player->m_player_id); // Let trusted friends and players request control (e.g., they want to hook us to their tow-truck or something) if (plyr && (plyr->is_trusted || (g.session.trust_friends && plyr->is_friend()))) { - return; + buffer->Seek(0); + break; } if (g_local_player->m_vehicle->m_driver != source_player->m_player_info->m_ped) //This will block hackers who are not in the car but still want control. @@ -697,39 +800,20 @@ namespace big { if (plyr->m_play_sound_rate_limit.exceeded_last_process()) { - notify::crash_blocked(source_player, "sound spam"); + //notify::crash_blocked(source_player, "sound spam"); --- false positives } g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); return; } - bool is_entity = buffer->Read(1); - std::int16_t entity_net_id; - rage::fvector3 position; - uint32_t ref_hash; - - if (is_entity) - entity_net_id = buffer->Read(13); - else - { - position.x = buffer->ReadSignedFloat(19, 1337.0f); - position.y = buffer->ReadSignedFloat(19, 1337.0f); - position.z = buffer->ReadFloat(19, 1337.0f); - } - - bool has_ref = buffer->Read(1); - if (has_ref) - ref_hash = buffer->Read(32); - - uint32_t sound_hash = buffer->Read(32); - - if (sound_hash == "Remote_Ring"_J && plyr) + if (plyr && scan_play_sound_event(plyr, *buffer)) { g.reactions.sound_spam.process(plyr); + + g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); return; } - buffer->Seek(0); break; } case eNetworkEvents::EXPLOSION_EVENT: @@ -751,7 +835,59 @@ namespace big } break; } - default: break; + case eNetworkEvents::ACTIVATE_VEHICLE_SPECIAL_ABILITY_EVENT: + { + int16_t net_id = buffer->Read(13); + + if (is_local_vehicle(net_id)) + { + g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); + return; + } + + buffer->Seek(0); + break; + } + case eNetworkEvents::DOOR_BREAK_EVENT: + { + int16_t net_id = buffer->Read(13); + + if (is_local_vehicle(net_id)) + { + g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); + return; + } + + buffer->Seek(0); + break; + } + case eNetworkEvents::CHANGE_RADIO_STATION_EVENT: + { + int16_t net_id = buffer->Read(13); + + if (is_local_vehicle(net_id)) + { + if (!is_in_vehicle(plyr->get_ped())) + { + g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); + return; + } + + if (plyr->m_radio_station_change_rate_limit.process()) + { + g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); + return; + } + } + else + { + g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); + return; + } + + buffer->Seek(0); + break; + } } return g_hooking->get_original()(event_manager, source_player, target_player, event_id, event_index, event_handled_bitset, buffer_size, buffer); diff --git a/src/hooks/protections/searchlight_crash.cpp b/src/hooks/protections/searchlight_crash.cpp index 30f2128c..cb3d746e 100644 --- a/src/hooks/protections/searchlight_crash.cpp +++ b/src/hooks/protections/searchlight_crash.cpp @@ -5,7 +5,7 @@ namespace big { void hooks::searchlight_crash(void* a1, CPed* ped) { - if (!ped || !g_pointers->m_gta.m_get_unk_weapon(ped)) [[unlikely]] + if (!ped || !g_pointers->m_gta.m_get_searchlight(ped)) [[unlikely]] return; return g_hooking->get_original()(a1, ped); diff --git a/src/logger/stack_trace.cpp b/src/logger/stack_trace.cpp index 50c7729d..40f0833d 100644 --- a/src/logger/stack_trace.cpp +++ b/src/logger/stack_trace.cpp @@ -31,6 +31,9 @@ namespace big m_exception_info = exception_info; + m_dump.str(""); + m_dump.clear(); + m_dump << exception_code_to_string(exception_info->ExceptionRecord->ExceptionCode) << '\n'; if (g.in_script_vm) @@ -77,7 +80,7 @@ namespace big { auto mod_info = module_info(table_entry->FullDllName.Buffer, table_entry->DllBase); - m_dump << mod_info.m_path.filename().string() << " Base Address: " << HEX_TO_UPPER(mod_info.m_base) + m_dump << mod_info.m_name << " Base Address: " << HEX_TO_UPPER(mod_info.m_base) << " Size: " << mod_info.m_size << '\n'; m_modules.emplace_back(std::move(mod_info)); @@ -128,29 +131,39 @@ namespace big for (size_t i = 0; i < m_frame_pointers.size() && m_frame_pointers[i]; ++i) { - const auto addr = m_frame_pointers[i]; + const auto addr = m_frame_pointers[i]; + const auto module_info = get_module_by_address(addr); m_dump << "\n[" << i << "]\t"; if (SymFromAddr(GetCurrentProcess(), addr, &displacement64, symbol)) { if (SymGetLineFromAddr64(GetCurrentProcess(), addr, &displacement, &line)) { - m_dump << line.FileName << " L: " << line.LineNumber << " " << std::string_view(symbol->Name, symbol->NameLen); + m_dump << line.FileName << " L: " << line.LineNumber << ' ' << std::string_view(symbol->Name, symbol->NameLen); continue; } - const auto module_info = get_module_by_address(addr); + + if (module_info) + { + m_dump << module_info->m_name << ' ' << std::string_view(symbol->Name, symbol->NameLen); - if (module_info->m_base == (uint64_t)GetModuleHandle(0)) - m_dump << module_info->m_path.filename().string() << " " << std::string_view(symbol->Name, symbol->NameLen) << " (" - << module_info->m_path.filename().string() << "+" << HEX_TO_UPPER(addr - module_info->m_base) << ")"; - else - m_dump << module_info->m_path.filename().string() << " " << std::string_view(symbol->Name, symbol->NameLen); + continue; + } + + m_dump << HEX_TO_UPPER(addr) << ' ' << std::string_view(symbol->Name, symbol->NameLen); continue; } - const auto module_info = get_module_by_address(addr); - m_dump << module_info->m_path.filename().string() << "+" << HEX_TO_UPPER(addr - module_info->m_base) << " " << HEX_TO_UPPER(addr); + + if (module_info) + { + m_dump << module_info->m_name << '+' << HEX_TO_UPPER(addr - module_info->m_base) << ' ' << HEX_TO_UPPER(addr); + + continue; + } + + m_dump << HEX_TO_UPPER(addr); } } @@ -167,6 +180,7 @@ namespace big if (m_exception_info->ExceptionRecord->ExceptionCode == msvc_exception_code) { m_dump + << '\n' << reinterpret_cast(m_exception_info->ExceptionRecord->ExceptionInformation[1])->what() << '\n'; } } diff --git a/src/logger/stack_trace.hpp b/src/logger/stack_trace.hpp index 862d6726..b469ea80 100644 --- a/src/logger/stack_trace.hpp +++ b/src/logger/stack_trace.hpp @@ -20,7 +20,7 @@ namespace big struct module_info { module_info(std::filesystem::path path, void* base) : - m_path(path), + m_name(path.filename().string()), m_base(reinterpret_cast(base)) { const auto dos_header = reinterpret_cast(base); @@ -29,7 +29,7 @@ namespace big m_size = nt_header->OptionalHeader.SizeOfCode; } - std::filesystem::path m_path; + std::string m_name; uintptr_t m_base; size_t m_size; }; diff --git a/src/pointers.cpp b/src/pointers.cpp index e5018c10..a7a317cd 100644 --- a/src/pointers.cpp +++ b/src/pointers.cpp @@ -545,15 +545,6 @@ namespace big g_pointers->m_gta.m_fipackfile_mount = ptr.add(0x47).rip().as(); } }, - // Invalid Mods Crash Detour - { - "IMCD", - "E8 ? ? ? ? 40 88 7C 24 ? 49 89 9C 24", - [](memory::handle ptr) - { - g_pointers->m_gta.m_invalid_mods_crash_detour = ptr.add(1).rip().as(); - } - }, // Send Chat Ptr { "SCP", @@ -1612,10 +1603,12 @@ namespace big // ERROR message box { "E0MB", - "E8 ? ? ? ? CC FF 15", + "E8 ? ? ? ? 33 F6 EB 0F", [](memory::handle ptr) { - g_pointers->m_gta.m_error_message_box = ptr.add(1).rip().as(); + ptr = ptr.add(1).rip(); + g_pointers->m_gta.m_error_message_box = ptr.add(7).rip().as(); + g_pointers->m_gta.m_error_message_box_2 = ptr.as(); } }, // Get title caption for ERROR message box @@ -1772,16 +1765,16 @@ namespace big [](memory::handle ptr) { g_pointers->m_gta.m_searchlight_crash = ptr.sub(0x1E).as(); - g_pointers->m_gta.m_get_unk_weapon = ptr.add(0x28).rip().as(); + g_pointers->m_gta.m_get_searchlight = ptr.add(0x28).rip().as(); } }, - // Clone Create Pool + // Vehicle Allocator { - "CCP", + "VA", "48 8B 0D ? ? ? ? 45 33 C9 BA ? ? ? ? 41", [](memory::handle ptr) { - g_pointers->m_gta.m_clone_create_pool = ptr.add(3).rip().as(); + g_pointers->m_gta.m_vehicle_allocator = ptr.add(3).rip().as(); } }, // Write Physical Script Game State Data Node diff --git a/src/services/players/player.hpp b/src/services/players/player.hpp index 16018b76..206513a2 100644 --- a/src/services/players/player.hpp +++ b/src/services/players/player.hpp @@ -70,6 +70,7 @@ namespace big rate_limiter m_play_sound_rate_limit_tse{5s, 2}; rate_limiter m_invites_rate_limit{10s, 2}; rate_limiter m_radio_request_rate_limit{5s, 2}; + rate_limiter m_radio_station_change_rate_limit{1s, 3}; bool block_radio_requests = false; diff --git a/src/util/fuzzer.hpp b/src/util/fuzzer.hpp index 560587fc..820873e5 100644 --- a/src/util/fuzzer.hpp +++ b/src/util/fuzzer.hpp @@ -1,36 +1,14 @@ #pragma once #include "pointers.hpp" #include "sync_trees.hpp" +#include "util/math.hpp" #include "util/model_info.hpp" #include "util/pools.hpp" #include -#include namespace big::fuzzer { - // helpers - - // [0, max_value) - inline int rand(int max_value) - { - std::random_device seed; - std::mt19937 gen{seed()}; - std::uniform_int_distribution dist{0, max_value - 1}; - - return dist(gen); - } - - // [min_value, max_value] - inline int rand(int min_value, int max_value) - { - std::random_device seed; - std::mt19937 gen{seed()}; - std::uniform_int_distribution dist{min_value, max_value}; - - return dist(gen); - } - inline bool is_fuzzer_enabled() { return g.debug.fuzzer.active && g.debug.fuzzer.enabled && g.debug.fuzzer.thread_id == GetCurrentThreadId(); @@ -86,7 +64,7 @@ namespace big::fuzzer else if (info && (info->m_model_type == eModelType::Ped || info->m_model_type == eModelType::OnlineOnlyPed)) std::erase(models, "player_zero"_J); - return models[rand(models.size())]; + return models[math::rand(models.size())]; } inline rage::joaat_t get_crash_model(rage::joaat_t original) @@ -100,7 +78,7 @@ namespace big::fuzzer else if (info && info->m_model_type == eModelType::Vehicle) return "arbitergt"_J; else - return rand(2) ? "urbanweeds01"_J : "slod_human"_J; + return math::rand(2) ? "urbanweeds01"_J : "slod_human"_J; } inline std::int16_t get_first_ped_id() @@ -147,18 +125,18 @@ namespace big::fuzzer return -1; if (is_object_model(entity->m_model_info->m_hash)) - return rand(2) ? get_first_ped_id() : get_first_veh_id(); + return math::rand(2) ? get_first_ped_id() : get_first_veh_id(); else if (entity->m_model_info->m_model_type == eModelType::Ped || entity->m_model_info->m_model_type == eModelType::OnlineOnlyPed) - return rand(2) ? get_first_obj_id() : get_first_veh_id(); + return math::rand(2) ? get_first_obj_id() : get_first_veh_id(); else if (entity->m_model_info->m_model_type == eModelType::Vehicle) - return rand(2) ? get_first_obj_id() : get_first_ped_id(); + return math::rand(2) ? get_first_obj_id() : get_first_ped_id(); - return rand(2) ? get_first_ped_id() : get_first_veh_id(); + return math::rand(2) ? get_first_ped_id() : get_first_veh_id(); } inline rage::fvector3 get_fuzz_vector() { - if (rand(2) == 0) + if (math::rand(2) == 0) { return {10800.0f, 10800.0f, 10.0f}; // host crash coords } @@ -233,7 +211,7 @@ namespace big::fuzzer if (!is_fuzzer_enabled()) return net_id; - int option = rand(0, 3); + int option = math::rand(0, 3); switch (option) { @@ -269,7 +247,7 @@ namespace big::fuzzer if (hash == 0 || is_model_hash(hash)) { - int option = rand(0, 4); + int option = math::rand(0, 4); switch (option) { @@ -282,8 +260,8 @@ namespace big::fuzzer } else { - if (rand(4)) - hash = rand(0, UINT_MAX); // not much we can do here + if (math::rand(4)) + hash = math::rand(0, UINT_MAX); // not much we can do here } return hash; @@ -294,7 +272,7 @@ namespace big::fuzzer if (!is_fuzzer_enabled()) return value; - if (rand(4) == 0) + if (math::rand(4) == 0) return value; // flip bools else return true; // set to true @@ -311,7 +289,7 @@ namespace big::fuzzer return fuzz_potential_hash(bits); else { - if (rand(5 - (count == 1)) == 0) + if (math::rand(5 - (count == 1)) == 0) { if (count == 1) { @@ -319,8 +297,8 @@ namespace big::fuzzer } else { - if (rand(2) == 0) - return rand(((int)pow(2, count))); // random + if (math::rand(2) == 0) + return math::rand(((int)pow(2, count))); // random else return ((int)pow(2, count)) - 1; // max possible value } @@ -334,7 +312,7 @@ namespace big::fuzzer { auto n = fuzz_bits(bits, count - 1); - if (rand(5) == 0) + if (math::rand(5) == 0) n = -n; return n; @@ -348,7 +326,7 @@ namespace big::fuzzer // well not much to do here I suppose for (int i = 0; i < size; i++) - *(char*)((__int64)data + i) = rand(0, 255); + *(char*)((__int64)data + i) = math::rand(0, 255); } inline float fuzz_float(float orig, int size, float divisor, bool _signed) @@ -358,9 +336,9 @@ namespace big::fuzzer if (!is_fuzzer_enabled()) return orig; - if (rand(3) == 0) + if (math::rand(3) == 0) { - int option = rand(0, 2); + int option = math::rand(0, 2); switch (option) { case 0: return truncate_func(9999.9f, size, divisor); @@ -376,7 +354,7 @@ namespace big::fuzzer { auto truncate_func = _signed_z ? &truncate_vector_signed_z : &truncate_vector; - if (rand(3) == 0) + if (math::rand(3) == 0) { return truncate_func(get_fuzz_vector(), size, divisor); } diff --git a/src/util/math.hpp b/src/util/math.hpp index 749eabc2..ce7f49eb 100644 --- a/src/util/math.hpp +++ b/src/util/math.hpp @@ -2,6 +2,8 @@ #include "pointers.hpp" #include "natives.hpp" +#include + namespace big::math { inline float deg_to_rad(float deg) @@ -63,4 +65,24 @@ namespace big::math SHAPETEST::GET_SHAPE_TEST_RESULT(ray, &hit, &end_coords, &surface_normal, &hit_entity); return end_coords; } + + // [0, max_value) + inline int rand(int max_value) + { + static std::random_device seed; + static std::mt19937 gen{seed()}; + std::uniform_int_distribution dist{0, max_value - 1}; + + return dist(gen); + } + + // [min_value, max_value] + inline int rand(int min_value, int max_value) + { + static std::random_device seed; + static std::mt19937 gen{seed()}; + std::uniform_int_distribution dist{min_value, max_value}; + + return dist(gen); + } } diff --git a/src/util/protection.cpp b/src/util/protection.cpp index b420ce51..575495f6 100644 --- a/src/util/protection.cpp +++ b/src/util/protection.cpp @@ -4,42 +4,39 @@ namespace big::protection { - constexpr auto crash_objects = {"proc_drygrasses01"_J, "proc_drygrasses01b"_J, "proc_brittlebush_01"_J, "proc_forest_ivy_01"_J, "proc_grassdandelion01"_J, "proc_grasses01b"_J, "proc_grassfronds01"_J, "proc_grassplantmix_01"_J, "proc_indian_pbrush_01"_J, "proc_leafybush_01"_J, "proc_lizardtail_01"_J, "proc_lupins_01"_J, "proc_meadowmix_01"_J, "proc_meadowpoppy_01"_J, "proc_desert_sage_01"_J, "prop_saplin_001_b"_J, "prop_dummy_01"_J, "prop_dummy_car"_J, "prop_dummy_light"_J, "prop_dummy_plane"_J, "prop_distantcar_night"_J, "prop_distantcar_day"_J, "hei_bh1_08_details4_em_night"_J, "dt1_18_sq_night_slod"_J, "ss1_12_night_slod"_J, "hash_b334b5e2_qyquzxq_collision"_J, "h4_prop_bush_bgnvla_med_01"_J, "h4_prop_bush_bgnvla_lrg_01"_J, "h4_prop_bush_buddleia_low_01"_J, "h4_prop_bush_ear_aa"_J, "h4_prop_bush_ear_ab"_J, "h4_prop_bush_fern_low_01"_J, "h4_prop_bush_fern_tall_cc"_J, "h4_prop_bush_mang_ad"_J, "h4_prop_bush_mang_low_aa"_J, "h4_prop_bush_mang_low_ab"_J, "h4_prop_bush_seagrape_low_01"_J, "prop_h4_ground_cover"_J, "h4_prop_weed_groundcover_01"_J, "h4_prop_grass_med_01"_J, "h4_prop_grass_tropical_lush_01"_J, "h4_prop_grass_wiregrass_01"_J, "h4_prop_weed_01_plant"_J, "h4_prop_weed_01_row"_J, "urbanweeds02_l1"_J, "proc_forest_grass01"_J, "prop_small_bushyba"_J, "v_res_d_dildo_a"_J, "v_res_d_dildo_b"_J, "v_res_d_dildo_c"_J, "v_res_d_dildo_d"_J, "v_res_d_dildo_e"_J, "v_res_d_dildo_f"_J, "v_res_skateboard"_J, "prop_battery_01"_J, "prop_barbell_01"_J, "prop_barbell_02"_J, "prop_bandsaw_01"_J, "prop_bbq_3"_J, "v_med_curtainsnewcloth2"_J, "bh1_07_flagpoles"_J, "hash_058a7eb5_deihiws_collision"_J, "proc_dry_plants_01"_J, "proc_leafyplant_01"_J, "proc_grassplantmix_02"_J, "proc_dryplantsgrass_01"_J, "proc_dryplantsgrass_02"_J, "proc_grasses01"_J, "prop_dryweed_002_a"_J, "prop_fernba"_J, "prop_weed_001_aa"_J, "urbangrnfrnds_01"_J, "urbanweeds01"_J, "prop_dandy_b"_J, "v_proc2_temp"_J, "prop_fernbb"_J, "proc_drygrassfronds01"_J, "prop_log_ae"_J, "prop_grass_da"_J, "prop_fragtest_cnst_04"_J}; + static const std::unordered_set crash_objects = {"proc_drygrasses01"_J, "proc_drygrasses01b"_J, "proc_brittlebush_01"_J, "proc_forest_ivy_01"_J, "proc_grassdandelion01"_J, "proc_grasses01b"_J, "proc_grassfronds01"_J, "proc_grassplantmix_01"_J, "proc_indian_pbrush_01"_J, "proc_leafybush_01"_J, "proc_lizardtail_01"_J, "proc_lupins_01"_J, "proc_meadowmix_01"_J, "proc_meadowpoppy_01"_J, "proc_desert_sage_01"_J, "prop_saplin_001_b"_J, "prop_dummy_01"_J, "prop_dummy_car"_J, "prop_dummy_light"_J, "prop_dummy_plane"_J, "prop_distantcar_night"_J, "prop_distantcar_day"_J, "hei_bh1_08_details4_em_night"_J, "dt1_18_sq_night_slod"_J, "ss1_12_night_slod"_J, "hash_b334b5e2_qyquzxq_collision"_J, "h4_prop_bush_bgnvla_med_01"_J, "h4_prop_bush_bgnvla_lrg_01"_J, "h4_prop_bush_buddleia_low_01"_J, "h4_prop_bush_ear_aa"_J, "h4_prop_bush_ear_ab"_J, "h4_prop_bush_fern_low_01"_J, "h4_prop_bush_fern_tall_cc"_J, "h4_prop_bush_mang_ad"_J, "h4_prop_bush_mang_low_aa"_J, "h4_prop_bush_mang_low_ab"_J, "h4_prop_bush_seagrape_low_01"_J, "prop_h4_ground_cover"_J, "h4_prop_weed_groundcover_01"_J, "h4_prop_grass_med_01"_J, "h4_prop_grass_tropical_lush_01"_J, "h4_prop_grass_wiregrass_01"_J, "h4_prop_weed_01_plant"_J, "h4_prop_weed_01_row"_J, "urbanweeds02_l1"_J, "proc_forest_grass01"_J, "prop_small_bushyba"_J, "v_res_d_dildo_a"_J, "v_res_d_dildo_b"_J, "v_res_d_dildo_c"_J, "v_res_d_dildo_d"_J, "v_res_d_dildo_e"_J, "v_res_d_dildo_f"_J, "v_res_skateboard"_J, "prop_battery_01"_J, "prop_barbell_01"_J, "prop_barbell_02"_J, "prop_bandsaw_01"_J, "prop_bbq_3"_J, "v_med_curtainsnewcloth2"_J, "bh1_07_flagpoles"_J, "hash_058a7eb5_deihiws_collision"_J, "proc_dry_plants_01"_J, "proc_leafyplant_01"_J, "proc_grassplantmix_02"_J, "proc_dryplantsgrass_01"_J, "proc_dryplantsgrass_02"_J, "proc_grasses01"_J, "prop_dryweed_002_a"_J, "prop_fernba"_J, "prop_weed_001_aa"_J, "urbangrnfrnds_01"_J, "urbanweeds01"_J, "prop_dandy_b"_J, "v_proc2_temp"_J, "prop_fernbb"_J, "proc_drygrassfronds01"_J, "prop_log_ae"_J, "prop_grass_da"_J, "prop_fragtest_cnst_04"_J, "prop_thindesertfiller_aa"_J}; bool is_crash_object(rage::joaat_t model) { + if (crash_objects.contains(model)) + return true; if (!model_info::get_model(model)) return false; if (!model_info::is_model_of_type(model, eModelType::Object, eModelType::Time, eModelType::Weapon, eModelType::Destructable, eModelType::WorldObject, eModelType::Sprinkler, eModelType::Unk65, eModelType::Plant, eModelType::LOD, eModelType::Unk132, eModelType::Building)) - return true; - for (auto iterator : crash_objects) - if (iterator == model) - return true; + return true; return false; } - constexpr auto crash_peds = {"slod_human"_J, "slod_small_quadped"_J, "slod_large_quadped"_J}; + static const std::unordered_set crash_peds = {"slod_human"_J, "slod_small_quadped"_J, "slod_large_quadped"_J}; bool is_crash_ped(rage::joaat_t model) { - for (auto iterator : crash_peds) - if (iterator == model) - return true; + if (crash_peds.contains(model)) + return true; if (!model_info::is_model_of_type(model, eModelType::Ped, eModelType::OnlineOnlyPed)) return true; return false; } - constexpr auto crash_vehicles = {"arbitergt"_J, "astron2"_J, "cyclone2"_J, "ignus2"_J, "s95"_J}; + static const std::unordered_set crash_vehicles = {"arbitergt"_J, "astron2"_J, "cyclone2"_J, "ignus2"_J, "s95"_J}; bool is_crash_vehicle(rage::joaat_t model) { - for (auto iterator : crash_vehicles) - if (iterator == model) - return true; + if (crash_vehicles.contains(model)) + return true; if (!model_info::is_model_of_type(model, eModelType::Vehicle, eModelType::Unk133)) return true; return false; } - constexpr auto valid_player_models = { + static const std::unordered_set valid_player_models = { "mp_m_freemode_01"_J, "mp_f_freemode_01"_J, "u_m_m_filmdirector"_J, @@ -80,9 +77,6 @@ namespace big::protection }; bool is_valid_player_model(rage::joaat_t model) { - for (auto iterator : valid_player_models) - if (iterator == model) - return true; - return false; + return valid_player_models.contains(model); } } diff --git a/src/util/sync_trees.hpp b/src/util/sync_trees.hpp index b89cb57f..1e1d5f27 100644 --- a/src/util/sync_trees.hpp +++ b/src/util/sync_trees.hpp @@ -534,9 +534,6 @@ namespace big { for (int i = (int)eNetObjType::NET_OBJ_TYPE_AUTOMOBILE; i <= (int)eNetObjType::NET_OBJ_TYPE_TRAIN; i++) { - if (i == (int)eNetObjType::NET_OBJ_TYPE_TRAILER) - continue; - rage::netSyncTree* tree = g_pointers->m_gta.m_get_sync_tree_for_type(*g_pointers->m_gta.m_network_object_mgr, i); if (tree->m_child_node_count != finder.sync_trees_node_array_index_to_node_id[i].size()) diff --git a/src/widgets/imgui_hotkey.hpp b/src/widgets/imgui_hotkey.hpp index c57b366b..ad902aa8 100644 --- a/src/widgets/imgui_hotkey.hpp +++ b/src/widgets/imgui_hotkey.hpp @@ -115,6 +115,11 @@ namespace ImGui true, style.FrameRounding); + if (*k < 0 || *k > VK_RMENU) + { + *k = 0; + } + if (*k != 0 && g.ActiveId != id) { strcpy_s(buf_display, key_names[*k]);