mirror of
https://github.com/YimMenu/YimMenuV2.git
synced 2026-10-11 17:58:10 +08:00
feat: add experimental standalone bypass
This commit is contained in:
1 parent
b13352897e
commit
1bfdf2d8f4
11 files changed
+183
-2
No files matched your search
@@ -0,0 +1,53 @@
|
||||
#include "AnticheatBypass.hpp"
|
||||
#include "core/backend/ScriptMgr.hpp"
|
||||
#include "core/memory/ModuleMgr.hpp"
|
||||
#include "core/util/Joaat.hpp"
|
||||
#include "game/pointers/Pointers.hpp"
|
||||
#include "game/backend/NativeHooks.hpp"
|
||||
#include "game/gta/Natives.hpp"
|
||||
|
||||
namespace YimMenu
|
||||
{
|
||||
static bool CheckForFSL()
|
||||
{
|
||||
int num_versions = 0;
|
||||
for (auto& module : ModuleMgr.GetModules())
|
||||
if (module.first == "version.dll"_J)
|
||||
num_versions++;
|
||||
|
||||
return num_versions > 1;
|
||||
}
|
||||
|
||||
static void TransactionHook(rage::scrNativeCallContext* ctx)
|
||||
{
|
||||
if (ctx->GetArg<int>(3) == -50712147)
|
||||
{
|
||||
LOG(WARNING) << "NET_GAMESERVER_BEGIN_SERVICE: blocked shop_controller report";
|
||||
return ctx->SetReturnValue(FALSE);
|
||||
}
|
||||
return ctx->SetReturnValue(NETSHOPPING::NET_GAMESERVER_BEGIN_SERVICE(ctx->GetArg<int*>(0), ctx->GetArg<Hash>(1), ctx->GetArg<Hash>(2), ctx->GetArg<Hash>(3), ctx->GetArg<int>(4), ctx->GetArg<int>(5)));
|
||||
}
|
||||
|
||||
void AnticheatBypass::RunScriptImpl()
|
||||
{
|
||||
NativeHooks::AddHook("shop_controller"_J, NativeIndex::NET_GAMESERVER_BEGIN_SERVICE, &TransactionHook);
|
||||
|
||||
m_IsFSLLoaded = CheckForFSL();
|
||||
|
||||
LOG(INFO) << (m_IsFSLLoaded ? "FSL is loaded" : "FSL is NOT loaded");
|
||||
|
||||
if (!m_IsFSLLoaded)
|
||||
Pointers.BattlEyeStatusUpdatePatch->Apply();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!m_IsFSLLoaded)
|
||||
{
|
||||
*Pointers.BERestartStatus = 0;
|
||||
*Pointers.NeedsBERestart = false;
|
||||
*Pointers.IsBEBanned = false;
|
||||
}
|
||||
ScriptMgr::Yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
namespace YimMenu
|
||||
{
|
||||
class AnticheatBypass
|
||||
{
|
||||
private:
|
||||
static AnticheatBypass& GetInstance()
|
||||
{
|
||||
static AnticheatBypass instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void RunScriptImpl();
|
||||
|
||||
bool m_IsFSLLoaded = false;
|
||||
|
||||
public:
|
||||
static void RunScript()
|
||||
{
|
||||
GetInstance().RunScriptImpl();
|
||||
}
|
||||
|
||||
static bool IsFSLLoaded()
|
||||
{
|
||||
return GetInstance().m_IsFSLLoaded;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "core/hooking/DetourHook.hpp"
|
||||
#include "game/hooks/Hooks.hpp"
|
||||
|
||||
namespace YimMenu::Hooks
|
||||
{
|
||||
bool Anticheat::PrepareMetricForSending(rage::JsonSerializer* ser, void* a2, void* a3, rage::rlMetric* metric)
|
||||
{
|
||||
return false; // don't send any telemetry
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ namespace rage
|
||||
class scrProgram;
|
||||
class netObject;
|
||||
class datBitBuffer;
|
||||
class JsonSerializer;
|
||||
class rlMetric;
|
||||
}
|
||||
|
||||
namespace YimMenu
|
||||
@@ -31,6 +33,7 @@ namespace YimMenu::Hooks
|
||||
namespace Anticheat
|
||||
{
|
||||
extern void QueueDependency(__int64 a1);
|
||||
extern bool PrepareMetricForSending(rage::JsonSerializer* ser, void* a2, void* a3, rage::rlMetric* metric);
|
||||
}
|
||||
|
||||
namespace Info
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "core/hooking/DetourHook.hpp"
|
||||
#include "game/backend/AnticheatBypass.hpp"
|
||||
#include "game/backend/Players.hpp"
|
||||
#include "game/frontend/ChatDisplay.hpp"
|
||||
#include "game/hooks/Hooks.hpp"
|
||||
#include "game/gta/Packet.hpp"
|
||||
#include "types/network/netEvent.hpp"
|
||||
#include "types/network/netMessage.hpp"
|
||||
#include "types/rage/datBitBuffer.hpp"
|
||||
@@ -43,7 +45,7 @@ namespace YimMenu::Hooks
|
||||
buffer.ReadString(msg, sizeof(msg)); // we don't need the rest
|
||||
ChatDisplay::Show(player.GetName(), msg, ImGui::Colors::LightBlue);
|
||||
}
|
||||
break;
|
||||
return; // the game doesn't handle that anyway
|
||||
}
|
||||
case rage::netMessage::Type::PackedEvents:
|
||||
{
|
||||
@@ -88,6 +90,59 @@ namespace YimMenu::Hooks
|
||||
|
||||
break;
|
||||
}
|
||||
case rage::netMessage::Type::KickPlayer:
|
||||
{
|
||||
if (!AnticheatBypass::IsFSLLoaded())
|
||||
return;
|
||||
break;
|
||||
}
|
||||
case rage::netMessage::Type::BattlEyeCmd:
|
||||
{
|
||||
if (!AnticheatBypass::IsFSLLoaded())
|
||||
{
|
||||
char data[1028]{};
|
||||
int size = buffer.Read<int>(11);
|
||||
bool from_client = buffer.Read<bool>(1);
|
||||
buffer.Seek(4, true); // normalize before we read
|
||||
buffer.ReadArrayBytes(&data, size);
|
||||
|
||||
if (from_client)
|
||||
break;
|
||||
|
||||
Packet reply;
|
||||
char reply_buf[1028]{};
|
||||
int reply_sz = 0;
|
||||
|
||||
auto op = data[0];
|
||||
|
||||
if (op == 0)
|
||||
{
|
||||
char payload[] = {0x0, 0x5};
|
||||
reply_sz = sizeof(payload);
|
||||
memcpy(reply_buf, payload, reply_sz);
|
||||
}
|
||||
else if (op == 2 || op == 4)
|
||||
{
|
||||
char payload[] = {op, data[1]};
|
||||
reply_sz = sizeof(payload);
|
||||
memcpy(reply_buf, payload, reply_sz);
|
||||
}
|
||||
else if (op == 9)
|
||||
{
|
||||
reply_sz = size;
|
||||
memcpy(reply_buf, data, reply_sz);
|
||||
}
|
||||
|
||||
reply.WriteMessageHeader(rage::netMessage::Type::BattlEyeCmd);
|
||||
reply.GetBuffer().Write<int>(reply_sz, 11);
|
||||
reply.GetBuffer().Write<bool>(true, 1);
|
||||
reply.GetBuffer().Seek(4, false);
|
||||
reply.GetBuffer().WriteArrayBytes(reply_buf, reply_sz);
|
||||
reply.Send(fr_evt->m_MsgId);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -207,6 +207,23 @@ namespace YimMenu
|
||||
ScriptVM = ptr.Sub(0x24).As<PVOID>();
|
||||
});
|
||||
|
||||
constexpr auto prepareMetricForSendingPtrn = Pattern<"48 89 F9 FF 50 20 48 8D 15">("PrepareMetricForSending");
|
||||
scanner.Add(prepareMetricForSendingPtrn, [this](PointerCalculator ptr) {
|
||||
PrepareMetricForSending = ptr.Sub(0x26).As<PVOID>();
|
||||
});
|
||||
|
||||
constexpr auto beDataPtrn = Pattern<"48 C7 05 ? ? ? ? 00 00 00 00 E8 ? ? ? ? 48 89 C1 E8 ? ? ? ? E8 ? ? ? ? BD 0A 00 00 00">("BEData");
|
||||
scanner.Add(beDataPtrn, [this](PointerCalculator ptr) {
|
||||
BERestartStatus = ptr.Add(3).Rip().Add(8).Add(4).As<int*>();
|
||||
NeedsBERestart = ptr.Add(3).Rip().Add(8).Add(4).Add(8).As<bool*>();
|
||||
IsBEBanned = ptr.Add(3).Rip().Add(8).Add(4).Add(8).Add(4).As<bool*>();
|
||||
});
|
||||
|
||||
constexpr auto battlEyeStatusUpdatePatchPtrn = Pattern<"80 B9 92 0A 00 00 01">("BattlEyeStatusUpdatePatch");
|
||||
scanner.Add(battlEyeStatusUpdatePatchPtrn, [this](PointerCalculator ptr) {
|
||||
BattlEyeStatusUpdatePatch = BytePatches::Add(ptr.Sub(0x26).As<std::uint8_t*>(), 0xC3);
|
||||
});
|
||||
|
||||
if (!scanner.Scan())
|
||||
{
|
||||
LOG(FATAL) << "Some patterns could not be found, unloading.";
|
||||
|
||||
@@ -84,6 +84,11 @@ namespace YimMenu
|
||||
PVOID QueueDependency;
|
||||
PVOID SigScanMemory;
|
||||
PVOID ScriptVM;
|
||||
PVOID PrepareMetricForSending;
|
||||
int* BERestartStatus;
|
||||
bool* NeedsBERestart;
|
||||
bool* IsBEBanned;
|
||||
BytePatch BattlEyeStatusUpdatePatch;
|
||||
};
|
||||
|
||||
struct Pointers : PointerData
|
||||
|
||||
Reference in new issue
Block a user