Update for b3570 (#130)
Some checks are pending
Nightly Build / Check Recent Commit (push) Successful in 34s
Nightly Build / Build Nightly (push) Waiting to run
Nightly Build / Recreate Release (push) Blocked by required conditions

* Update for b3570

* fix pointers

* updated globals

* fix(pointers): fix update language

* Update gtav-classes.cmake

* fix(anticheat): fix anticheat bypass

---------

Co-authored-by: Mr-X-GTA <110748953+Mr-X-GTA@users.noreply.github.com>
This commit is contained in:
Alcina Dimitrescu
2025-06-22 20:00:26 +03:00
committed by GitHub
parent 24ae18cad2
commit 39fef35eeb
14 changed files with 198 additions and 89 deletions

View File

@ -3,7 +3,7 @@ include(FetchContent)
FetchContent_Declare(
gtav_classes
GIT_REPOSITORY https://github.com/Mr-X-GTA/GTAV-Classes-1.git
GIT_TAG 03bc35cc7e61eb74919ad51c217f6b4bf5502088
GIT_TAG 921b1a2089777d073d8eb4c92cc8dde76113c0d8
GIT_PROGRESS TRUE
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View File

@ -1,6 +1,6 @@
{
"game": {
"online": "1.70",
"build": "3411"
"online": "1.71",
"build": "3570"
}
}

View File

@ -19,24 +19,8 @@
namespace big
{
void bypass_battleye()
{
if (g.spoofing.spoof_game_data_hash)
return;
constexpr std::array<std::uint32_t, 16> valid_hashes = {4022154788, 988, 3512952254, 472, 0, 0, 3308328917, 0, 0, 1731098795, 2256610353, 18616, 1540917665, 307143837, 1629784955, 2012170620};
if (auto hashes = *g_pointers->m_gta.m_game_data_hash)
{
for (int i = 0; i < valid_hashes.size(); i++)
hashes->m_data[i] = valid_hashes[i];
}
}
void backend::loop()
{
bypass_battleye();
for (auto& command : g_bool_commands)
command->refresh();
@ -50,8 +34,6 @@ namespace big
while (g_running)
{
bypass_battleye();
looped::system_self_globals();
looped::system_update_pointers();
looped::system_update_desync_kick();

View File

@ -4,101 +4,101 @@
namespace big::scr_globals
{
static inline const script_global gsbd(2648914);
static inline const script_global gsbd_kicking(1877384);
static inline const script_global gsbd_fm_events(1916957);
static inline const script_global gsbd(2648929);
static inline const script_global gsbd_kicking(1876908);
static inline const script_global gsbd_fm_events(1918241);
static inline const script_global globalplayer_bd(2657991);
static inline const script_global gpbd_fm_3(1887549);
static inline const script_global gpbd_fm_1(1845221);
static inline const script_global interiors(1943917);
static inline const script_global globalplayer_bd(2658016);
static inline const script_global gpbd_fm_3(1888737);
static inline const script_global gpbd_fm_1(1845225);
static inline const script_global interiors(1945923);
static inline const script_global launcher_global(2699419);
static inline const script_global launcher_global(2699544);
// creator globals usually remain the same after updates
static inline const script_global terminate_creator(1574607); // NETWORK::NETWORK_BAIL(1, 0, 0); fm_*_creator
static inline const script_global switch_struct(1574633);
static inline const script_global switch_struct(1574634);
static inline const script_global mission_creator_radar_follows_camera(2621443);
static inline const script_global mission_creator_exited(1574530);
static inline const script_global transition_state(1575012);
static inline const script_global sctv_spectator(2697978); // pausemenu_multiplayer function 0xE49C42EC
static inline const script_global transition_state(1575014);
static inline const script_global sctv_spectator(2698102); // pausemenu_multiplayer function 0xE49C42EC
static inline const script_global vehicle_global(1586536);
static inline const script_global vehicle_global(1586540);
static inline const script_global freemode_properties(2672939);
static inline const script_global freemode_global(2739811);
static inline const script_global freemode_properties(2672964);
static inline const script_global freemode_global(2740054);
static inline const script_global spawn_global(2696456);
static inline const script_global spawn_global(2696579);
static inline const script_global transaction_overlimit(4538089);
static inline const script_global transaction_overlimit(4538671);
static inline const script_global stats(2359296);
static inline const script_global session(1574589);
static inline const script_global session2(1575036);
static inline const script_global session3(33088);
static inline const script_global session4(1574942);
static inline const script_global session5(1575011);
static inline const script_global session6(2696374); // freemode -> if (NETWORK::NETWORK_IS_GAME_IN_PROGRESS() && !NETWORK::NETWORK_IS_ACTIVITY_SESSION())
static inline const script_global session2(1575038);
static inline const script_global session3(33282);
static inline const script_global session4(1574943);
static inline const script_global session5(1575013);
static inline const script_global session6(2696496); // freemode -> if (NETWORK::NETWORK_IS_GAME_IN_PROGRESS() && !NETWORK::NETWORK_IS_ACTIVITY_SESSION())
static inline const script_global interaction_menu_access(2711020); // am_pi_menu -> if (NETWORK::NETWORK_IS_SIGNED_ONLINE()) first global after that
static inline const script_global interaction_menu_access(2711261); // am_pi_menu -> if (NETWORK::NETWORK_IS_SIGNED_ONLINE()) first global after that
static inline const script_global disable_wasted_sound(2708030); // freemode -> AUDIO::PLAY_SOUND_FRONTEND(-1, "Wasted", "POWER_PLAY_General_Soundset", true);
static inline const script_global disable_wasted_sound(2708261); // freemode -> AUDIO::PLAY_SOUND_FRONTEND(-1, "Wasted", "POWER_PLAY_General_Soundset", true);
static inline const script_global passive(1574582); // if (((!PED::IS_PED_IN_ANY_VEHICLE(PLAYER::GET_PLAYER_PED(bVar1), false) || Global_
static inline const script_global property_garage(1938043);
static inline const script_global property_names(1312333);
static inline const script_global property_garage(1940049);
static inline const script_global property_names(1312335);
static inline const script_global reset_clothing(104243); // freemode 75, &iLocal_.*, 2\);
static inline const script_global reset_clothing(104448); // freemode 75, &iLocal_.*, 2\);
static inline const script_global gun_van(1950373); // return -29.532f, 6435.136f, 31.162f;
static inline const script_global gun_van(1952452); // return -29.532f, 6435.136f, 31.162f;
static inline const script_global disable_phone(21049);
static inline const script_global disable_phone(21205);
static inline const script_global should_reset_fm_weapons(1578039);
static inline const script_global should_reset_fm_weapons(1578044);
}
namespace big::scr_locals
{
namespace am_hunt_the_beast
{
constexpr static auto broadcast_idx = 622; // (bParam0) != 0;
constexpr static auto player_broadcast_idx = 2606; // if (NETWORK::PARTICIPANT_ID_TO_INT() != -1)
constexpr static auto broadcast_idx = 624; // (bParam0) != 0;
constexpr static auto player_broadcast_idx = 2608; // if (NETWORK::PARTICIPANT_ID_TO_INT() != -1)
}
namespace am_criminal_damage
{
constexpr static auto broadcast_idx = 117; // /* Tunable: CRIMINAL_DAMAGE_DISABLE_SHARE_CASH */)
constexpr static auto score_idx = 112; // AUDIO::PLAY_SOUND_FRONTEND(-1, "Criminal_Damage_High_Value", "GTAO_FM_Events_Soundset", false);
constexpr static auto broadcast_idx = 119; // /* Tunable: CRIMINAL_DAMAGE_DISABLE_SHARE_CASH */)
constexpr static auto score_idx = 114; // AUDIO::PLAY_SOUND_FRONTEND(-1, "Criminal_Damage_High_Value", "GTAO_FM_Events_Soundset", false);
}
namespace am_cp_collection
{
constexpr static auto broadcast_idx = 822; // bVar1 = NETWORK::NETWORK_GET_PLAYER_INDEX(PLAYER::INT_TO_PARTICIPANTINDEX(iVar0));
constexpr static auto player_broadcast_idx = 3463; // bVar1 = NETWORK::NETWORK_GET_PLAYER_INDEX(PLAYER::INT_TO_PARTICIPANTINDEX(iVar0));
constexpr static auto broadcast_idx = 824; // bVar1 = NETWORK::NETWORK_GET_PLAYER_INDEX(PLAYER::INT_TO_PARTICIPANTINDEX(iVar0));
constexpr static auto player_broadcast_idx = 3465; // bVar1 = NETWORK::NETWORK_GET_PLAYER_INDEX(PLAYER::INT_TO_PARTICIPANTINDEX(iVar0));
}
namespace am_king_of_the_castle
{
constexpr static auto broadcast_idx = 100; // KING_OF_THE_CASTLE_EVENT_TIME_LIMIT
constexpr static auto broadcast_idx = 102; // KING_OF_THE_CASTLE_EVENT_TIME_LIMIT
}
namespace fmmc_launcher
{
constexpr static auto broadcast_idx = 12721; // if (NETWORK::NETWORK_IS_PLAYER_ACTIVE(PLAYER::INT_TO_PLAYERINDEX(Global_
constexpr static auto broadcast_idx = 12827; // if (NETWORK::NETWORK_IS_PLAYER_ACTIVE(PLAYER::INT_TO_PLAYERINDEX(Global_
}
namespace fm_mission_controller
{
constexpr static auto mission_controller_wanted_state_flags = 60851; // if (PLAYER::GET_PLAYER_WANTED_LEVEL(bLocal_
constexpr static auto mission_controller_wanted_state_flags = 60892; // if (PLAYER::GET_PLAYER_WANTED_LEVEL(bLocal_
}
namespace freemode
{
// first uLocal_ in this function call
// func_\d+\((&.Local_\d+(, )?){9}\);
inline static script_local mobile(19253);
inline static script_local mobile(19361);
}
}

View File

@ -174,7 +174,7 @@ namespace big::functions
using handle_chat_message = void (*)(void* chat_data, void*, rage::rlGamerHandle* handle, const char* text, bool is_team);
using update_language = void (*)(bool);
using update_language = void (*)(bool, bool);
using get_host_array_handler_by_index = rage::netArrayHandlerBase* (*)(CGameScriptHandlerNetComponent* component, int index);

View File

@ -3,6 +3,7 @@
#include "gta/enums.hpp"
#include <memory/handle.hpp>
#include <security/ObfVar.hpp>
class CCommunications;
class FriendRegistry;
@ -23,6 +24,7 @@ class CPedFactory;
class GtaThread;
class GameDataHash;
class InputMethodEditor;
class CAnticheatContext;
namespace rage
{
@ -411,6 +413,11 @@ namespace big
PVOID m_add_skeleton_extension;
int* m_skeleton_extension_count;
rage::Obf32** m_anticheat_initialized_hash;
PVOID m_get_anticheat_initialized_hash;
PVOID m_get_anticheat_initialized_hash_2;
CAnticheatContext** m_anticheat_context;
};
#pragma pack(pop)
static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned");

View File

@ -159,6 +159,9 @@ namespace big
detour_hook_helper::add<hooks::add_skeleton_extension>("ASE", g_pointers->m_gta.m_add_skeleton_extension);
detour_hook_helper::add<hooks::get_anticheat_initialized_hash>("GAIH", g_pointers->m_gta.m_get_anticheat_initialized_hash);
detour_hook_helper::add<hooks::get_anticheat_initialized_hash_2>("GAIH2", g_pointers->m_gta.m_get_anticheat_initialized_hash_2);
g_hooking = this;
}

View File

@ -214,6 +214,9 @@ namespace big
static uint32_t network_can_access_multiplayer(uint32_t a1, uint64_t* a2);
static void* add_skeleton_extension(rage::fwEntity* entity);
static std::uint32_t get_anticheat_initialized_hash();
static std::uint32_t get_anticheat_initialized_hash_2(void* ac_var, std::uint32_t seed);
};
class minhook_keepalive

View File

@ -126,6 +126,8 @@ namespace big
LOG(INFO) << "METRIC: " << metric_name << "; DATA: " << yim_serializer.get_string();
}
return true;
if (g.debug.block_all_metrics) [[unlikely]]
return true;
else

View File

@ -0,0 +1,49 @@
#include "hooking/hooking.hpp"
#include "pointers.hpp"
struct CAnticheatContext
{
rage::Obf32 m_LastScanTime;
rage::Obf32 m_ScanInterval;
void* m_ScanData;
rage::Obf32 m_ScanDataSize;
rage::Obf32 m_ScanDataSize2;
rage::Obf32 m_GameBuild;
std::uint64_t qword58;
std::uint32_t dword60;
char gap64[2572];
std::uint32_t dwordA70;
std::uint64_t qwordA78;
std::uint32_t dwordA80;
char gapA84[3];
char byteA87[9];
bool m_DebugBattlEyeEnabled;
bool m_BattlEyeEnabled; // 0xA91
bool m_IsDebugMode;
volatile __int32 m_CurrentScanIndex;
std::uint64_t qwordA98;
};
static_assert(sizeof(CAnticheatContext) == 0xAA0);
namespace big
{
std::uint32_t hooks::get_anticheat_initialized_hash()
{
return 0x124EA49D;
}
std::uint32_t hooks::get_anticheat_initialized_hash_2(void* ac_var, std::uint32_t seed)
{
auto orig = (*g_pointers->m_gta.m_anticheat_context) ? (*g_pointers->m_gta.m_anticheat_context)->m_BattlEyeEnabled : false;
if (*g_pointers->m_gta.m_anticheat_context)
(*g_pointers->m_gta.m_anticheat_context)->m_BattlEyeEnabled = true; // integ checks will boot us out if we set this outside this function
auto ret = g_hooking->get_original<get_anticheat_initialized_hash_2>()(ac_var, seed);
if (*g_pointers->m_gta.m_anticheat_context)
(*g_pointers->m_gta.m_anticheat_context)->m_BattlEyeEnabled = orig;
return ret;
}
}

View File

@ -66,11 +66,13 @@ namespace big
}
}
#if 0
if (gta_util::get_net_object_ids()->is_object_id_usable(object_id))
{
LOGF(stream::net_sync, WARNING, "{} sent us an object create request with an object ID that is in our usable object ID list. Somebody lied to us...", src->get_name());
gta_util::get_net_object_ids()->remove_object_id(object_id);
}
#endif
auto plyr = g_player_service->get_by_id(src->m_player_id);

View File

@ -37,6 +37,23 @@
namespace big
{
static void nop_game_skeleton_element(rage::game_skeleton_update_element* element)
{
// TODO: small memory leak
// Hey rockstar if you keep up with this I'll make you integrity check everything until you can't anymore, please grow a brain and realize that this is futile
// and kills performance if you're the host
auto vtable = *reinterpret_cast<void***>(element);
if (vtable[1] == g_pointers->m_gta.m_nullsub)
{
return; // already nopped
}
auto new_vtable = new void*[3];
memcpy(new_vtable, vtable, sizeof(void*) * 3);
new_vtable[1] = g_pointers->m_gta.m_nullsub;
*reinterpret_cast<void***>(element) = new_vtable;
}
bool disable_anticheat_skeleton()
{
bool patched = false;
@ -46,7 +63,9 @@ namespace big
{
if (update_node->m_hash != "Common Main"_J)
continue;
rage::game_skeleton_update_group* group = reinterpret_cast<rage::game_skeleton_update_group*>(update_node);
for (rage::game_skeleton_update_base* group_child_node = group->m_head; group_child_node;
group_child_node = group_child_node->m_next)
{
@ -54,21 +73,13 @@ namespace big
if (group_child_node->m_hash != 0xA0F39FB6 && group_child_node->m_hash != "TamperActions"_J)
continue;
patched = true;
//LOG(INFO) << "Patching problematic skeleton update";
reinterpret_cast<rage::game_skeleton_update_element*>(group_child_node)->m_function =
g_pointers->m_gta.m_nullsub;
nop_game_skeleton_element(reinterpret_cast<rage::game_skeleton_update_element*>(group_child_node));
}
break;
}
}
for (rage::skeleton_data& i : g_pointers->m_gta.m_game_skeleton->m_sys_data)
{
if (i.m_hash != 0xA0F39FB6 && i.m_hash != "TamperActions"_J)
continue;
i.m_init_func = reinterpret_cast<uint64_t>(g_pointers->m_gta.m_nullsub);
i.m_shutdown_func = reinterpret_cast<uint64_t>(g_pointers->m_gta.m_nullsub);
}
return patched;
}
@ -178,6 +189,16 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
auto pointers_instance = std::make_unique<pointers>();
LOG(INFO) << "Pointers initialized.";
if (!*g_pointers->m_gta.m_anticheat_initialized_hash)
{
*g_pointers->m_gta.m_anticheat_initialized_hash = new rage::Obf32; // this doesn't get freed so we don't have to use the game allocator
(*g_pointers->m_gta.m_anticheat_initialized_hash)->setData(0x124EA49D);
}
else
{
(*g_pointers->m_gta.m_anticheat_initialized_hash)->setData(0x124EA49D);
}
while (!disable_anticheat_skeleton())
{
LOG(WARNING) << "Failed patching anticheat gameskeleton (injected too early?). Waiting 100ms and trying again";

View File

@ -3,7 +3,7 @@
#include "gta_pointers_layout_info.hpp"
#include "sc_pointers_layout_info.hpp"
#define GTA_VERSION_TARGET "1.70-3521"
#define GTA_VERSION_TARGET "1.71-3570.0"
namespace big
{
@ -558,10 +558,10 @@ namespace big
// Send Chat Message
{
"SCM",
"48 81 EC 80 00 00 00 48 8B E9 48 8B CA 41",
"45 8A F9 4D 8B E0 48 8B EA",
[](memory::handle ptr)
{
g_pointers->m_gta.m_send_chat_message = ptr.sub(21).as<functions::send_chat_message>();
g_pointers->m_gta.m_send_chat_message = ptr.sub(0x2D).as<functions::send_chat_message>();
}
},
// Get Gamer Online State
@ -636,13 +636,13 @@ namespace big
g_pointers->m_gta.m_script_vm = ptr.add(1).rip().as<functions::script_vm>();
}
},
// Handle Join Request
// Handle Join Request (partially obfuscated now, crutches deployed)
{
"HJR",
"48 8B C4 48 89 58 08 4C 89 48 20 4C 89 40 18 48 89 50 10 55 56 57 41 54 41 55 41 56 41 57 48 8D A8 18",
"4C 8B F1 45 33 ED 48 8D 4D",
[](memory::handle ptr)
{
g_pointers->m_gta.m_handle_join_request = ptr.as<PVOID>();
g_pointers->m_gta.m_handle_join_request = ptr.sub(0x2D).as<PVOID>();
}
},
// Write Join Response Data
@ -693,7 +693,7 @@ namespace big
// Serialize Join Request Message 2
{
"SJRM2",
"E8 ? ? ? ? 48 8D 8D C8 01 00 00 8A D8",
"E8 ? ? ? ? 48 8D 8D E0 01 00 00 8A D8",
[](memory::handle ptr)
{
g_pointers->m_gta.m_serialize_join_request_message_2 = ptr.add(1).rip().as<PVOID>();
@ -1160,14 +1160,22 @@ namespace big
g_pointers->m_gta.m_handle_chat_message = ptr.as<functions::handle_chat_message>();
}
},
// Language & Update Language
// Language
{
"L&UL",
"L",
"83 3D ? ? ? ? ? 44 8B C3",
[](memory::handle ptr)
{
g_pointers->m_gta.m_language = ptr.add(2).rip().add(1).as<eGameLanguage*>();
g_pointers->m_gta.m_update_language = ptr.add(0x38).rip().as<functions::update_language>();
}
},
// Update Language
{
"UL",
"84 C0 B1 01",
[](memory::handle ptr)
{
g_pointers->m_gta.m_update_language = ptr.add(0x11).rip().as<functions::update_language>();
}
},
// Get Host Array Handler By Index
@ -1386,7 +1394,7 @@ namespace big
// Blame Explode
{
"BE",
"0F 85 EE 00 00 00 84 C0",
"0F 85 EF 00 00 00 84 C0",
[](memory::handle ptr)
{
g_pointers->m_gta.m_blame_explode = ptr;
@ -1404,7 +1412,7 @@ namespace big
// Is Matchmaking Session Valid
{
"IMSV",
"48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 54 41 55 41 56 41 57 48 83 EC 20 45 0F",
"48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 54 41 55 41 56 41 57 48 83 EC 20 49 83",
[](memory::handle ptr)
{
g_pointers->m_gta.m_is_matchmaking_session_valid = ptr;
@ -1754,7 +1762,7 @@ namespace big
// Session Request Patch
{
"SRP",
"45 38 BE 48 B7 00 00 0F 85 F6 00 00 00",
"45 38 8E 48 B7 00 00 0F 85 43 FE FF FF",
[](memory::handle ptr)
{
g_pointers->m_gta.m_session_request_patch = ptr.add(0x14).as<PVOID>();
@ -1900,10 +1908,10 @@ namespace big
// Network Can Access Multiplayer
{
"NCAM",
"E9 4F 01 00 00 33 D2 8B CB",
"E9 89 01 00 00 48 8B CF E8 13 A3 04 00",
[](memory::handle ptr)
{
g_pointers->m_gta.m_network_can_access_multiplayer = ptr.add(10).rip().as<PVOID>();
g_pointers->m_gta.m_network_can_access_multiplayer = ptr.add(0x23).rip().as<PVOID>();
}
},
// BattlEye Network Bail Patch
@ -1925,6 +1933,34 @@ namespace big
g_pointers->m_gta.m_add_skeleton_extension = ptr.as<PVOID>();
g_pointers->m_gta.m_skeleton_extension_count = ptr.add(0x2C).rip().as<int*>();
}
},
// Anticheat Initialized Hash
{
"AIH",
"48 83 EC 20 48 8B D9 48 8B 0D ? ? ? ? 48 85 C9 0F 84",
[](memory::handle ptr)
{
g_pointers->m_gta.m_anticheat_initialized_hash = ptr.add(10).rip().as<rage::Obf32**>();
g_pointers->m_gta.m_get_anticheat_initialized_hash = ptr.add(24).rip().add(1).rip().as<PVOID>();
}
},
// Anticheat Initialized Hash 2
{
"AIH2",
"89 8B E8 00 00 00 48 8B 0D",
[](memory::handle ptr)
{
g_pointers->m_gta.m_get_anticheat_initialized_hash_2 = ptr.add(14).rip().as<PVOID>();
}
},
// Anticheat Context
{
"AC",
"8B D0 41 54",
[](memory::handle ptr)
{
g_pointers->m_gta.m_anticheat_context = ptr.sub(10).rip().as<CAnticheatContext**>();
}
}
>(); // don't leave a trailing comma at the end
@ -2056,13 +2092,17 @@ namespace big
sc_batch_and_hash.m_batch>(m_sc_pointers_cache, sc_module);
}
else
{
LOG(WARNING) << "socialclub.dll module was not loaded within the time limit.";
}
m_hwnd = FindWindowW(L"grcWindow", nullptr);
if (!m_hwnd)
{
throw std::runtime_error("Failed to find the game's window.");
}
}
pointers::~pointers()
{

View File

@ -36,7 +36,7 @@ namespace big
*g_pointers->m_gta.m_language = id;
g_fiber_pool->queue_job([] {
g_pointers->m_gta.m_update_language(true);
g_pointers->m_gta.m_update_language(true, false);
});
}