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 <tupoy-ya@users.noreply.github.com>
This commit is contained in:
tupoy-ya
2026-01-03 23:34:11 +05:00
committed by GitHub
parent c4849db275
commit dbfd43639d
9 changed files with 123 additions and 3 deletions
+1
View File
@@ -40,6 +40,7 @@ namespace YimMenu
BaseHook::Add<Hooks::Spoofing::WriteSyncTree>(new DetourHook("WriteSyncTree", Pointers.WriteSyncTree, Hooks::Spoofing::WriteSyncTree));
BaseHook::Add<Hooks::Network::GetPoolType>(new DetourHook("GetPoolType", Pointers.GetPoolType, Hooks::Network::GetPoolType));
BaseHook::Add<Hooks::Network::GetDLCHash>(new DetourHook("GetDLCHash", Pointers.GetDLCHash, Hooks::Network::GetDLCHash));
BaseHook::Add<Hooks::Matchmaking::MatchmakingAdvertise>(new DetourHook("MatchmakingAdvertise", Pointers.MatchmakingAdvertise, Hooks::Matchmaking::MatchmakingAdvertise));
BaseHook::Add<Hooks::Matchmaking::MatchmakingSessionDetailSendResponse>(new DetourHook("MatchmakingSessionDetailSendResponse", Pointers.MatchmakingSessionDetailSendResponse, Hooks::Matchmaking::MatchmakingSessionDetailSendResponse));
-1
View File
@@ -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 (*)();
+100
View File
@@ -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<Hooks::Network::GetDLCHash, DetourHook<decltype(&Hooks::Network::GetDLCHash)>>()->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<std::uint32_t, 16> origHashes;
virtual void OnEnable() override
{
NativeHooks::AddHook(NativeHooks::ALL_SCRIPTS, NativeIndex::GET_EVER_HAD_BAD_PACK_ORDER, &PackOrderHook);
constexpr std::array<std::uint32_t, 16> 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<Network::GetDLCHash, DetourHook<decltype(&Network::GetDLCHash)>>()->Original()(manager, seed);
}
}
@@ -58,6 +58,8 @@ namespace YimMenu::Submenus
}
}));
misc->AddItem(std::make_shared<CommandItem>("dumpdatahash"_J));
return misc;
}
}
+2 -1
View File
@@ -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<BoolCommandItem>("spoofmmregion"_J, "Spoof Region"));
spoofMMRegion->AddItem(std::make_shared<ConditionalItem>("spoofmmregion"_J, std::make_shared<ListCommandItem>("mmregion"_J, "##mmregion")));
matchmakingGroup->AddItem(std::make_shared<ConditionalItem>("cheaterpool"_J, spoofMMRegion, true));
matchmakingGroup->AddItem(std::make_shared<BoolCommandItem>("spoofdatahash"_J));
spoofing->AddItem(matchmakingGroup);
auto matchmakingSrvGroup = std::make_shared<Group>("Matchmaking (Server)");
+1
View File
@@ -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();
}
+12
View File
@@ -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<PVOID*>()[1];
});
constexpr auto gameDataHashPtrn = Pattern<"48 8D 3D ? ? ? ? 69 C9">("GameDataHash");
scanner.Add(gameDataHashPtrn, [this](PointerCalculator ptr) {
GameDataHash = ptr.Add(3).Rip().As<CGameDataHash*>();
});
constexpr auto getDLCHashPtrn = Pattern<"31 D2 E8 ? ? ? ? 3B 84">("GetDLCHash&DLCManager");
scanner.Add(getDLCHashPtrn, [this](PointerCalculator ptr) {
DLCManager = ptr.Sub(4).Rip().As<void**>();
GetDLCHash = ptr.Add(3).Rip().As<PVOID>();
});
constexpr auto assistedAimShouldReleaseEntityPtrn = Pattern<"80 7F 28 04 75 6A">("AssistedAimShouldReleaseEntity");
scanner.Add(assistedAimShouldReleaseEntityPtrn, [this](PointerCalculator ptr) {
AssistedAimShouldReleaseEntity = ptr.Sub(0xF).As<PVOID>();
+4
View File
@@ -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;
+1 -1
View File
@@ -10,4 +10,4 @@ public:
std::array<rage::Obf32, 16> m_Data;
};
static_assert(sizeof(CGameDataHash) == 0x104);
#pragma pack(pop)
#pragma pack(pop)