From dbfd43639d8a988bb7e0d611621e52f2e74e29b7 Mon Sep 17 00:00:00 2001 From: tupoy-ya <72797377+tupoy-ya@users.noreply.github.com> Date: Sat, 3 Jan 2026 23:34:11 +0500 Subject: [PATCH] feat: Data hash spoofing. (#364) * feat: Add data hash spoofing. feat: LogCurrentSessionInfo To be deleted. * chore: Remove logcurrentsessioninfo. * chore(PackOrderHook): Move to SpoofDataHash. * chore: Update getDLCHashPtrn to support new version. * chore: Update to 889.15. I hope this is correct... * chore: Remove unused include. * chore: Update data hash to latest. --------- Co-authored-by: tupoy-ya --- src/core/hooking/Hooking.cpp | 1 + src/game/backend/AnticheatBypass.cpp | 1 - src/game/features/network/SpoofDataHash.cpp | 100 ++++++++++++++++++++ src/game/frontend/submenus/Debug/Misc.cpp | 2 + src/game/frontend/submenus/Network.cpp | 3 +- src/game/hooks/Hooks.hpp | 1 + src/game/pointers/Pointers.cpp | 12 +++ src/game/pointers/Pointers.hpp | 4 + src/types/game_files/CGameDataHash.hpp | 2 +- 9 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 src/game/features/network/SpoofDataHash.cpp diff --git a/src/core/hooking/Hooking.cpp b/src/core/hooking/Hooking.cpp index 3108e64..64cb358 100644 --- a/src/core/hooking/Hooking.cpp +++ b/src/core/hooking/Hooking.cpp @@ -40,6 +40,7 @@ namespace YimMenu BaseHook::Add(new DetourHook("WriteSyncTree", Pointers.WriteSyncTree, Hooks::Spoofing::WriteSyncTree)); BaseHook::Add(new DetourHook("GetPoolType", Pointers.GetPoolType, Hooks::Network::GetPoolType)); + BaseHook::Add(new DetourHook("GetDLCHash", Pointers.GetDLCHash, Hooks::Network::GetDLCHash)); BaseHook::Add(new DetourHook("MatchmakingAdvertise", Pointers.MatchmakingAdvertise, Hooks::Matchmaking::MatchmakingAdvertise)); BaseHook::Add(new DetourHook("MatchmakingSessionDetailSendResponse", Pointers.MatchmakingSessionDetailSendResponse, Hooks::Matchmaking::MatchmakingSessionDetailSendResponse)); diff --git a/src/game/backend/AnticheatBypass.cpp b/src/game/backend/AnticheatBypass.cpp index c3fa2e9..77b536f 100644 --- a/src/game/backend/AnticheatBypass.cpp +++ b/src/game/backend/AnticheatBypass.cpp @@ -7,7 +7,6 @@ #include "game/gta/Natives.hpp" #include "types/rage/gameSkeleton.hpp" #include "types/anticheat/CAnticheatContext.hpp" -#include "types/game_files/CGameDataHash.hpp" using FnGetVersion = int (*)(); using FnLocalSaves = bool (*)(); diff --git a/src/game/features/network/SpoofDataHash.cpp b/src/game/features/network/SpoofDataHash.cpp new file mode 100644 index 0000000..1398d0c --- /dev/null +++ b/src/game/features/network/SpoofDataHash.cpp @@ -0,0 +1,100 @@ +#include "core/commands/BoolCommand.hpp" +#include "core/hooking/DetourHook.hpp" +#include "game/backend/NativeHooks.hpp" +#include "game/gta/Natives.hpp" +#include "game/hooks/Hooks.hpp" +#include "game/pointers/Pointers.hpp" +#include "types/game_files/CGameDataHash.hpp" + +namespace YimMenu::Features +{ + class DumpDataHash : public Command + { + using Command::Command; + + virtual void OnCall() override + { + auto log = LOG(VERBOSE); + log << "DLC Hash: " + << BaseHook::Get>()->Original()( + *Pointers.DLCManager, + 0) + << "\n"; + if (auto hashes = Pointers.GameDataHash) + { + log << "validHashes = {" << "\n"; + for (int i = 0; i < hashes->m_Data.size(); i++) + log << hashes->m_Data[i].getData() << ", // " << i << "\n"; + log << "};"; + } + } + }; + static DumpDataHash _DumpDataHash{"dumpdatahash", "Dump Data Hash", "Dumps the current data hash into the console"}; + + static void PackOrderHook(rage::scrNativeCallContext* ctx); + class SpoofDataHash : public BoolCommand + { + using BoolCommand::BoolCommand; + + std::array origHashes; + + virtual void OnEnable() override + { + NativeHooks::AddHook(NativeHooks::ALL_SCRIPTS, NativeIndex::GET_EVER_HAD_BAD_PACK_ORDER, &PackOrderHook); + + constexpr std::array validHashes = { + 1222354255, // 0 + 1017, // 1 + 2008403316, // 2 + 472, // 3 + 0, // 4 + 0, // 5 + 1061472380, // 6 + 0, // 7 + 0, // 8 + 1731098795, // 9 + 234493012, // 10 + 19919, // 11 + 4002619495, // 12 + 307143837, // 13 + 2941593772, // 14 + 200299391, // 15 + }; + if (auto hashes = Pointers.GameDataHash) + { + for (int i = 0; i < hashes->m_Data.size(); i++) + origHashes[i] = hashes->m_Data[i]; + + for (int i = 0; i < validHashes.size(); i++) + hashes->m_Data[i] = validHashes[i]; + } + } + + virtual void OnDisable() override + { + if (auto hashes = Pointers.GameDataHash) + { + for (int i = 0; i < origHashes.size(); i++) + hashes->m_Data[i] = origHashes[i]; + } + } + }; + + static SpoofDataHash _SpoofDataHash{"spoofdatahash", "Spoof Data Hash", "Allows you to join players with rpf mods (or a half installed game)."}; + + static void PackOrderHook(rage::scrNativeCallContext* ctx) + { + return ctx->SetReturnValue(FALSE); + } +} + +namespace YimMenu::Hooks +{ + uint32_t Network::GetDLCHash(void* manager, uint32_t seed) + { + if (YimMenu::Features::_SpoofDataHash.GetState()) + return 2784221708; + + return BaseHook::Get>()->Original()(manager, seed); + } +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Debug/Misc.cpp b/src/game/frontend/submenus/Debug/Misc.cpp index 2437498..85bad25 100644 --- a/src/game/frontend/submenus/Debug/Misc.cpp +++ b/src/game/frontend/submenus/Debug/Misc.cpp @@ -58,6 +58,8 @@ namespace YimMenu::Submenus } })); + misc->AddItem(std::make_shared("dumpdatahash"_J)); + return misc; } } \ No newline at end of file diff --git a/src/game/frontend/submenus/Network.cpp b/src/game/frontend/submenus/Network.cpp index 1435dad..57ff38b 100644 --- a/src/game/frontend/submenus/Network.cpp +++ b/src/game/frontend/submenus/Network.cpp @@ -3,8 +3,8 @@ #include "core/frontend/Notifications.hpp" #include "game/frontend/items/Items.hpp" #include "game/frontend/submenus/Network/SavedPlayers.hpp" -#include "game/gta/Network.hpp" #include "game/frontend/submenus/Network/RandomEvents.hpp" +#include "game/gta/Network.hpp" namespace YimMenu::Submenus { @@ -111,6 +111,7 @@ namespace YimMenu::Submenus spoofMMRegion->AddItem(std::make_shared("spoofmmregion"_J, "Spoof Region")); spoofMMRegion->AddItem(std::make_shared("spoofmmregion"_J, std::make_shared("mmregion"_J, "##mmregion"))); matchmakingGroup->AddItem(std::make_shared("cheaterpool"_J, spoofMMRegion, true)); + matchmakingGroup->AddItem(std::make_shared("spoofdatahash"_J)); spoofing->AddItem(matchmakingGroup); auto matchmakingSrvGroup = std::make_shared("Matchmaking (Server)"); diff --git a/src/game/hooks/Hooks.hpp b/src/game/hooks/Hooks.hpp index 2c4ffee..2fe72e7 100644 --- a/src/game/hooks/Hooks.hpp +++ b/src/game/hooks/Hooks.hpp @@ -87,6 +87,7 @@ namespace YimMenu::Hooks extern void ReceiveNetMessage(void* a1, rage::netConnectionManager* mgr, rage::netEvent* event); extern void ReceiveNetGameEvent(Player player, uint16_t event_id, uint32_t event_index, uint32_t event_handled_bits, rage::datBitBuffer& buffer); extern bool HandleScriptedGameEvent(Player player, CScriptedGameEvent& event); + extern uint32_t GetDLCHash(void* manager, uint32_t seed); extern int GetPoolType(); } diff --git a/src/game/pointers/Pointers.cpp b/src/game/pointers/Pointers.cpp index 8cd6f8b..0578c88 100644 --- a/src/game/pointers/Pointers.cpp +++ b/src/game/pointers/Pointers.cpp @@ -4,6 +4,7 @@ #include "core/memory/ModuleMgr.hpp" #include "core/memory/PatternScanner.hpp" #include "core/util/Joaat.hpp" +#include "types/network/rlSessionInfo.hpp" #include "types/rage/atArray.hpp" namespace YimMenu @@ -389,6 +390,17 @@ namespace YimMenu BattlEyeServerProcessPlayerJoin = ptr.Sub(4).Rip().As()[1]; }); + constexpr auto gameDataHashPtrn = Pattern<"48 8D 3D ? ? ? ? 69 C9">("GameDataHash"); + scanner.Add(gameDataHashPtrn, [this](PointerCalculator ptr) { + GameDataHash = ptr.Add(3).Rip().As(); + }); + + constexpr auto getDLCHashPtrn = Pattern<"31 D2 E8 ? ? ? ? 3B 84">("GetDLCHash&DLCManager"); + scanner.Add(getDLCHashPtrn, [this](PointerCalculator ptr) { + DLCManager = ptr.Sub(4).Rip().As(); + GetDLCHash = ptr.Add(3).Rip().As(); + }); + constexpr auto assistedAimShouldReleaseEntityPtrn = Pattern<"80 7F 28 04 75 6A">("AssistedAimShouldReleaseEntity"); scanner.Add(assistedAimShouldReleaseEntityPtrn, [this](PointerCalculator ptr) { AssistedAimShouldReleaseEntity = ptr.Sub(0xF).As(); diff --git a/src/game/pointers/Pointers.hpp b/src/game/pointers/Pointers.hpp index 79e96a0..08cd357 100644 --- a/src/game/pointers/Pointers.hpp +++ b/src/game/pointers/Pointers.hpp @@ -42,6 +42,7 @@ class PoolEncryption; class CStatsMgr; class CNetShopTransaction; class CNetworkSession; +class CGameDataHash; class CStatsMpCharacterMappingData; class CAnticheatContext; @@ -154,6 +155,9 @@ namespace YimMenu CStatsMpCharacterMappingData* StatsMpCharacterMappingData; int* HasGTAPlus; PVOID BattlEyeServerProcessPlayerJoin; + CGameDataHash* GameDataHash; + void** DLCManager; + PVOID GetDLCHash; PVOID AssistedAimShouldReleaseEntity; Functions::AssistedAimFindNewTarget AssistedAimFindNewTarget; rage::gameSkeleton* GameSkeleton; diff --git a/src/types/game_files/CGameDataHash.hpp b/src/types/game_files/CGameDataHash.hpp index 9d10050..580acae 100644 --- a/src/types/game_files/CGameDataHash.hpp +++ b/src/types/game_files/CGameDataHash.hpp @@ -10,4 +10,4 @@ public: std::array m_Data; }; static_assert(sizeof(CGameDataHash) == 0x104); -#pragma pack(pop) \ No newline at end of file +#pragma pack(pop)