Protection improvements (#3146)

This commit is contained in:
Mr-X-GTA 2024-05-19 20:26:44 +02:00 committed by GitHub
parent 84d76f2038
commit ee92caa889
20 changed files with 290 additions and 145 deletions

View File

@ -2,6 +2,7 @@
#include "core/scr_globals.hpp"
#include "gta_util.hpp"
#include "natives.hpp"
#include "util/math.hpp"
#include <network/CCommunications.hpp>
#include <network/Network.hpp>
@ -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;

View File

@ -211,5 +211,5 @@ namespace big::functions
using can_create_vehicle = bool (*)();
using get_unk_weapon = void* (*) (CPed*);
using get_searchlight = void* (*) (CPed*);
}

View File

@ -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,

View File

@ -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;
};

View File

@ -65,7 +65,6 @@ namespace big
detour_hook_helper::add<hooks::get_network_event_data>("GNED", g_pointers->m_gta.m_get_network_event_data);
detour_hook_helper::add<hooks::write_player_gamer_data_node>("WPGDN", g_pointers->m_gta.m_write_player_gamer_data_node);
detour_hook_helper::add<hooks::invalid_mods_crash_detour>("IMCD", g_pointers->m_gta.m_invalid_mods_crash_detour);
detour_hook_helper::add<hooks::invalid_decal>("IDC", g_pointers->m_gta.m_invalid_decal_crash);
detour_hook_helper::add<hooks::task_parachute_object>("TPO", g_pointers->m_gta.m_task_parachute_object);
detour_hook_helper::add<hooks::task_ambient_clips>("TAC", g_pointers->m_gta.m_task_ambient_clips);
@ -125,6 +124,7 @@ namespace big
detour_hook_helper::add<hooks::netfilter_handle_message>("NHM", g_pointers->m_gta.m_netfilter_handle_message);
detour_hook_helper::add<hooks::log_error_message_box>("E0MBH", g_pointers->m_gta.m_error_message_box);
detour_hook_helper::add<hooks::log_error_message_box_2>("E0MBH2", g_pointers->m_gta.m_error_message_box_2);
detour_hook_helper::add<hooks::send_non_physical_player_data>("SNPPD", g_pointers->m_gta.m_send_non_physical_player_data);

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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<hooks::invalid_mods_crash_detour>()(a1, a2, a3, a4);
}
}

View File

@ -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);

View File

@ -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<bool>(1);
std::int16_t entity_net_id;
rage::fvector3 position;
if (is_entity)
{
entity_net_id = buffer.Read<uint16_t>(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<bool>(1);
uint32_t ref_hash = has_ref ? buffer.Read<uint32_t>(32) : 0;
uint32_t sound_hash = buffer.Read<uint32_t>(32);
uint8_t sound_id = buffer.Read<uint8_t>(8);
bool has_script_hash = buffer.Read<bool>(1);
uint32_t script_hash = has_script_hash ? buffer.Read<uint32_t>(32) : 0;
static const std::unordered_set<uint32_t> 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<uint32_t> 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<GlobalPlayerBD*>()->Entries[plyr->id()].OrbitalBitset.IsSet(eOrbitalBitset::kOrbitalCannonActive))
return true;
static const std::unordered_set<uint32_t> 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<bool>(1);
std::int16_t entity_net_id;
rage::fvector3 position;
uint32_t ref_hash;
if (is_entity)
entity_net_id = buffer->Read<std::int16_t>(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<bool>(1);
if (has_ref)
ref_hash = buffer->Read<uint32_t>(32);
uint32_t sound_hash = buffer->Read<uint32_t>(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<int16_t>(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<int16_t>(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<int16_t>(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<received_event>()(event_manager, source_player, target_player, event_id, event_index, event_handled_bitset, buffer_size, buffer);

View File

@ -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<hooks::searchlight_crash>()(a1, ped);

View File

@ -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<const std::exception*>(m_exception_info->ExceptionRecord->ExceptionInformation[1])->what() << '\n';
}
}

View File

@ -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<uintptr_t>(base))
{
const auto dos_header = reinterpret_cast<IMAGE_DOS_HEADER*>(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;
};

View File

@ -545,15 +545,6 @@ namespace big
g_pointers->m_gta.m_fipackfile_mount = ptr.add(0x47).rip().as<functions::fipackfile_mount>();
}
},
// 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<PVOID>();
}
},
// 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<PVOID>();
ptr = ptr.add(1).rip();
g_pointers->m_gta.m_error_message_box = ptr.add(7).rip().as<PVOID>();
g_pointers->m_gta.m_error_message_box_2 = ptr.as<PVOID>();
}
},
// 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<PVOID>();
g_pointers->m_gta.m_get_unk_weapon = ptr.add(0x28).rip().as<functions::get_unk_weapon>();
g_pointers->m_gta.m_get_searchlight = ptr.add(0x28).rip().as<functions::get_searchlight>();
}
},
// 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<GenericPool**>();
g_pointers->m_gta.m_vehicle_allocator = ptr.add(3).rip().as<GenericPool**>();
}
},
// Write Physical Script Game State Data Node

View File

@ -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;

View File

@ -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 <entities/CDynamicEntity.hpp>
#include <random>
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<int> 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<int> 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);
}

View File

@ -2,6 +2,8 @@
#include "pointers.hpp"
#include "natives.hpp"
#include <random>
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<int> 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<int> dist{min_value, max_value};
return dist(gen);
}
}

View File

@ -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<uint32_t> 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<uint32_t> 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<uint32_t> 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<uint32_t> 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);
}
}

View File

@ -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())

View File

@ -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]);