mirror of
https://github.com/YimMenu/YimMenuV2.git
synced 2026-10-10 03:43:15 +08:00
fix(anticheat): fix anticheat bypass (#843)
This commit is contained in:
@@ -17,6 +17,7 @@ namespace YimMenu
|
||||
BaseHook::Add<Hooks::SwapChain::ResizeBuffers>(new DetourHook("ResizeBuffers", swapchain_vft[Hooks::SwapChain::VMTResizeBuffersIdx], Hooks::SwapChain::ResizeBuffers));
|
||||
|
||||
// BaseHook::Add<Hooks::Anticheat::QueueDependency>(new DetourHook("QueueDependency", Pointers.QueueDependency, Hooks::Anticheat::QueueDependency));
|
||||
BaseHook::Add<Hooks::Anticheat::GameSkeletonUpdate>(new DetourHook("GameSkeletonUpdate", Pointers.GameSkeletonUpdate, Hooks::Anticheat::GameSkeletonUpdate));
|
||||
BaseHook::Add<Hooks::Anticheat::PrepareMetricForSending>(new DetourHook("PrepareMetricForSending", Pointers.PrepareMetricForSending, Hooks::Anticheat::PrepareMetricForSending));
|
||||
BaseHook::Add<Hooks::Anticheat::GetThreadContext>(new DetourHook("GetThreadContext", reinterpret_cast<void*>(GetProcAddress(LoadLibraryA("kernel32.dll"), "GetThreadContext")), Hooks::Anticheat::GetThreadContext));
|
||||
BaseHook::Add<Hooks::Anticheat::HttpStartRequest>(new DetourHook("HttpStartRequest", Pointers.HttpStartRequest, Hooks::Anticheat::HttpStartRequest));
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace YimMenu
|
||||
m_HeapAllocator.Create(m_Device.Get(), m_DescriptorHeap.Get());
|
||||
|
||||
// never returns false, useless to check return
|
||||
ImGui::CreateContext(&GetInstance().m_FontAtlas);
|
||||
ImGui::CreateContext();
|
||||
ImGui_ImplWin32_Init(*Pointers.Hwnd);
|
||||
|
||||
ImGui_ImplDX12_InitInfo init_info = {};
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "game/pointers/Pointers.hpp"
|
||||
#include "game/backend/NativeHooks.hpp"
|
||||
#include "game/gta/Natives.hpp"
|
||||
#include "types/rage/gameSkeleton.hpp"
|
||||
#include "types/anticheat/CAnticheatContext.hpp"
|
||||
|
||||
using FnGetVersion = int (*)();
|
||||
@@ -33,57 +32,6 @@ namespace YimMenu
|
||||
return NativeInvoker::GetNativeHandler(NativeIndex::NET_GAMESERVER_BEGIN_SERVICE)(ctx);
|
||||
}
|
||||
|
||||
static void NopGameSkeletonElement(rage::gameSkeletonUpdateElement* 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] == Pointers.Nullsub)
|
||||
return; // already nopped
|
||||
|
||||
auto new_vtable = new void*[3];
|
||||
memcpy(new_vtable, vtable, sizeof(void*) * 3);
|
||||
new_vtable[1] = Pointers.Nullsub;
|
||||
*reinterpret_cast<void***>(element) = new_vtable;
|
||||
}
|
||||
|
||||
static void DefuseSigscanner()
|
||||
{
|
||||
bool patched = false;
|
||||
for (auto mode = Pointers.GameSkeleton->m_UpdateModes; mode; mode = mode->m_Next)
|
||||
{
|
||||
for (auto update_node = mode->m_Head; update_node; update_node = update_node->m_Next)
|
||||
{
|
||||
if (update_node->m_Hash != "Common Main"_J)
|
||||
continue;
|
||||
|
||||
auto group = reinterpret_cast<rage::gameSkeletonUpdateGroup*>(update_node);
|
||||
|
||||
for (auto group_child_node = group->m_Head; group_child_node; group_child_node = group_child_node->m_Next)
|
||||
{
|
||||
// TamperActions is a leftover from the old AC, but still useful to block anyway
|
||||
if (group_child_node->m_Hash != 0xA0F39FB6 && group_child_node->m_Hash != "TamperActions"_J)
|
||||
continue;
|
||||
patched = true;
|
||||
|
||||
NopGameSkeletonElement(reinterpret_cast<rage::gameSkeletonUpdateElement*>(group_child_node));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (patched)
|
||||
{
|
||||
LOGF(VERBOSE, "DefuseSigscanner: Patched out the sigscanner");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGF(WARNING, "DefuseSigscanner: Failed to patch the sigscanner");
|
||||
}
|
||||
}
|
||||
|
||||
void AnticheatBypass::RunOnStartupImpl()
|
||||
{
|
||||
bool loaded_late = false;
|
||||
@@ -102,8 +50,6 @@ namespace YimMenu
|
||||
|
||||
void AnticheatBypass::RunScriptImpl()
|
||||
{
|
||||
DefuseSigscanner();
|
||||
|
||||
NativeHooks::AddHook("shop_controller"_J, NativeIndex::NET_GAMESERVER_BEGIN_SERVICE, &TransactionHook);
|
||||
|
||||
m_IsFSLLoaded = CheckForFSL();
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "game/gta/invoker/Invoker.hpp"
|
||||
|
||||
#include "types/script/scrProgram.hpp"
|
||||
#include "types/script/scrThread.hpp"
|
||||
|
||||
|
||||
namespace YimMenu
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace YimMenu::Submenus
|
||||
|
||||
static bool ShouldRenderPlayer(std::string_view name, std::string_view search)
|
||||
{
|
||||
if (!search[0])
|
||||
if (search.empty())
|
||||
return true;
|
||||
|
||||
if (name.size() < search.size())
|
||||
|
||||
@@ -65,6 +65,37 @@ namespace YimMenu::Submenus
|
||||
ImGui::SetClipboardText(std::to_string(rid1).c_str());
|
||||
}
|
||||
|
||||
auto& platformAccountId = Players::GetSelected().GetHandle()->m_PlatformAccountId;
|
||||
switch (platformAccountId.m_Platform)
|
||||
{
|
||||
case PlatformAccountId::PLATFORM_XBOX:
|
||||
ImGui::Text("Xbox User ID:");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(std::to_string(platformAccountId.m_XboxUserId).c_str()))
|
||||
{
|
||||
ImGui::SetClipboardText(std::to_string(platformAccountId.m_XboxUserId).c_str());
|
||||
}
|
||||
break;
|
||||
case PlatformAccountId::PLATFORM_STEAM:
|
||||
ImGui::Text("Steam ID:");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(std::to_string(platformAccountId.m_SteamId).c_str()))
|
||||
{
|
||||
ImGui::SetClipboardText(std::to_string(platformAccountId.m_SteamId).c_str());
|
||||
}
|
||||
break;
|
||||
case PlatformAccountId::PLATFORM_EPIC:
|
||||
ImGui::Text("Epic Account ID:");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(platformAccountId.m_EpicAccountId))
|
||||
{
|
||||
ImGui::SetClipboardText(platformAccountId.m_EpicAccountId);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
auto ip = Players::GetSelected().GetExternalAddress();
|
||||
|
||||
@@ -83,14 +114,14 @@ namespace YimMenu::Submenus
|
||||
if (ImGui::Button("View SC Profile"))
|
||||
FiberPool::Push([] {
|
||||
uint64_t handle[13];
|
||||
NETWORK::NETWORK_HANDLE_FROM_PLAYER(Players::GetSelected().GetId(), handle, sizeof(handle));
|
||||
NETWORK::NETWORK_HANDLE_FROM_PLAYER(Players::GetSelected().GetId(), handle, std::size(handle));
|
||||
NETWORK::NETWORK_SHOW_PROFILE_UI(handle);
|
||||
});
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Add Friend"))
|
||||
FiberPool::Push([] {
|
||||
uint64_t handle[13];
|
||||
NETWORK::NETWORK_HANDLE_FROM_PLAYER(Players::GetSelected().GetId(), handle, sizeof(handle));
|
||||
NETWORK::NETWORK_HANDLE_FROM_PLAYER(Players::GetSelected().GetId(), handle, std::size(handle));
|
||||
NETWORK::NETWORK_ADD_FRIEND(handle, "");
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "core/frontend/manager/Category.hpp"
|
||||
#include "game/frontend/items/Items.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace YimMenu
|
||||
{
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "game/hooks/Hooks.hpp"
|
||||
#include "core/util/Joaat.hpp"
|
||||
#include "types/rage/gameSkeleton.hpp"
|
||||
|
||||
namespace YimMenu::Hooks
|
||||
{
|
||||
void Anticheat::GameSkeletonUpdate(rage::gameSkeleton* skeleton, int type)
|
||||
{
|
||||
for (auto mode = skeleton->m_UpdateModes; mode; mode = mode->m_Next)
|
||||
{
|
||||
if (mode->m_Type != type)
|
||||
continue;
|
||||
|
||||
for (auto group = mode->m_Head; group; group = group->m_Next)
|
||||
{
|
||||
if (group->m_Hash != "Common Main"_J)
|
||||
{
|
||||
group->Run();
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto item = static_cast<rage::gameSkeletonUpdateGroup*>(group)->m_Head; item; item = item->m_Next)
|
||||
{
|
||||
if (item->m_Hash != 0xA0F39FB6 && item->m_Hash != "TamperActions"_J)
|
||||
{
|
||||
item->Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ namespace rage
|
||||
class rlSessionDetailMsg;
|
||||
class rlSessionInfo;
|
||||
struct rlTaskStatus;
|
||||
struct gameSkeleton;
|
||||
}
|
||||
|
||||
class MatchmakingAttributes;
|
||||
@@ -44,6 +45,7 @@ namespace YimMenu::Hooks
|
||||
namespace Anticheat
|
||||
{
|
||||
extern void QueueDependency(__int64 a1);
|
||||
extern void GameSkeletonUpdate(rage::gameSkeleton* skeleton, int type);
|
||||
extern bool PrepareMetricForSending(rage::JsonSerializer* ser, void* a2, void* a3, rage::rlMetric* metric);
|
||||
extern BOOL GetThreadContext(HANDLE hThread, LPCONTEXT lpContext);
|
||||
extern void HttpStartRequest(void* request);
|
||||
|
||||
@@ -411,11 +411,6 @@ namespace YimMenu
|
||||
AssistedAimFindNewTarget = ptr.Sub(0x33).As<Functions::AssistedAimFindNewTarget>();
|
||||
});
|
||||
|
||||
constexpr auto gameSkeletonPtrn = Pattern<"0F B6 C0 8D 14 00 83 C2 02">("GameSkeleton");
|
||||
scanner.Add(gameSkeletonPtrn, [this](PointerCalculator ptr) {
|
||||
GameSkeleton = ptr.Add(0x9).Add(3).Rip().As<rage::gameSkeleton*>();
|
||||
});
|
||||
|
||||
constexpr auto anticheatInitializedHashPtrn = Pattern<"89 9E C8 00 00 00 48 8B 0D ? ? ? ? 48 85 C9 74 46">("AnticheatInitializedHash&GetAnticheatInitializedHash");
|
||||
scanner.Add(anticheatInitializedHashPtrn, [this](PointerCalculator ptr) {
|
||||
AnticheatInitializedHash = ptr.Add(9).Rip().As<rage::Obf32**>();
|
||||
@@ -457,6 +452,11 @@ namespace YimMenu
|
||||
MatchmakingSessionDetailSendResponse = addr.Add(0x2F).Rip().As<PVOID>();
|
||||
});
|
||||
|
||||
static constexpr auto gameSkeletonUpdatePtrn = Pattern<"56 48 83 EC 20 48 8B 81 40 01 00 00 48 85 C0">("GameSkeletonUpdate");
|
||||
scanner.Add(gameSkeletonUpdatePtrn, [this](PointerCalculator addr) {
|
||||
GameSkeletonUpdate = addr.As<PVOID>();
|
||||
});
|
||||
|
||||
if (!scanner.Scan())
|
||||
{
|
||||
LOG(FATAL) << "Some patterns could not be found, unloading.";
|
||||
|
||||
@@ -160,7 +160,6 @@ namespace YimMenu
|
||||
PVOID GetDLCHash;
|
||||
PVOID AssistedAimShouldReleaseEntity;
|
||||
Functions::AssistedAimFindNewTarget AssistedAimFindNewTarget;
|
||||
rage::gameSkeleton* GameSkeleton;
|
||||
PVOID Nullsub;
|
||||
rage::Obf32** AnticheatInitializedHash;
|
||||
PVOID GetAnticheatInitializedHash;
|
||||
@@ -171,6 +170,7 @@ namespace YimMenu
|
||||
PVOID MatchmakingUpdate;
|
||||
PVOID MatchmakingUnadvertise;
|
||||
PVOID MatchmakingSessionDetailSendResponse;
|
||||
PVOID GameSkeletonUpdate;
|
||||
};
|
||||
|
||||
struct Pointers : PointerData
|
||||
|
||||
@@ -8,6 +8,7 @@ class CGameDataHash
|
||||
public:
|
||||
bool m_IsJapaneseVersion;
|
||||
std::array<rage::Obf32, 16> m_Data;
|
||||
char m_GameSkeletonHash[0x18]; // Obf64
|
||||
};
|
||||
static_assert(sizeof(CGameDataHash) == 0x104);
|
||||
static_assert(sizeof(CGameDataHash) == 0x11C);
|
||||
#pragma pack(pop)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
struct PlatformAccountId
|
||||
{
|
||||
enum Platform : uint8_t
|
||||
{
|
||||
PLATFORM_INVALID = 0,
|
||||
PLATFORM_XBOX = 1,
|
||||
PLATFORM_STEAM = 10,
|
||||
PLATFORM_EPIC = 15
|
||||
};
|
||||
|
||||
union {
|
||||
uint64_t m_XboxUserId; //0x0000
|
||||
uint64_t m_SteamId;
|
||||
char m_EpicAccountId[32 + 1];
|
||||
char m_Pad[40];
|
||||
};
|
||||
Platform m_Platform; //0x0028
|
||||
};
|
||||
static_assert(sizeof(PlatformAccountId) == 0x30);
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "types/rage/RTTI.hpp"
|
||||
#include "PlatformAccountId.hpp"
|
||||
|
||||
namespace rage
|
||||
{
|
||||
@@ -31,7 +32,8 @@ namespace rage
|
||||
|
||||
int m_AccountId; //0x0008
|
||||
int64_t m_RockstarId; //0x0010
|
||||
char pad_0018[0x38]; //0x0018 voice chat stuff
|
||||
PlatformAccountId m_PlatformAccountId; //0x0018
|
||||
uint32_t unk_0048; //0x0048
|
||||
CNonPhysicalPlayerData* m_NonPhysicalPlayer; //0x0050
|
||||
uint32_t m_MessageId; //0x0058
|
||||
char pad_005C[4]; //0x005C
|
||||
|
||||
Reference in New Issue
Block a user