From e494127fcb929898039b33313e12013f230196ff Mon Sep 17 00:00:00 2001 From: Benoist <14257866+Kenzzer@users.noreply.github.com> Date: Mon, 7 Apr 2025 19:39:13 +0200 Subject: [PATCH] Remove RejectConnection detour + unused signature (#45) * Remove RejectConnection detour + unused signature * Readd rejectconnection signature * Remove offset redefinition * Remove unused variable --------- Co-authored-by: Kenzzer --- connect.games.txt | 9 -- extension/extension.cpp | 225 ++++++++++++++++------------------------ 2 files changed, 92 insertions(+), 142 deletions(-) diff --git a/connect.games.txt b/connect.games.txt index c7cce07..21359ba 100644 --- a/connect.games.txt +++ b/connect.games.txt @@ -93,15 +93,6 @@ "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x6C\x24\x2A\x48\x89\x74\x24\x2A\x57\x48\x81\xEC\x50\x05\x00\x00" } - "CBaseClient__SetSteamID" - { - "library" "engine" - "linux" "@_ZN11CBaseClient10SetSteamIDERK8CSteamID" - "linux64" "@_ZN11CBaseClient10SetSteamIDERK8CSteamID" - "windows" "\x55\x8B\xEC\x56\x8B\xF1\x57\x8B\x7D\x08\x8D\x4E\x04" - "windows64" "\x48\x89\x5C\x24\x2A\x57\x48\x83\xEC\x20\x48\x8B\x02\x48\x8B\xD9\x48\x89\x41" - } - "CBaseServer__CheckMasterServerRequestRestart" { "library" "engine" diff --git a/extension/extension.cpp b/extension/extension.cpp index 64621fb..70bd423 100644 --- a/extension/extension.cpp +++ b/extension/extension.cpp @@ -30,12 +30,9 @@ SMEXT_LINK(&g_connect); ConVar connectVersion("connect_version", SMEXT_CONF_VERSION, FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY, SMEXT_CONF_DESCRIPTION " Version"); IGameConfig *g_pGameConf = NULL; - IForward *g_pConnectForward = NULL; class IClient; -class CBaseClient; - class CBaseServer; typedef enum EAuthProtocol @@ -81,11 +78,12 @@ const char *CSteamID::Render() const return szSteamID; } +class ISteamGameServer; class CSteam3Server { public: void *m_pSteamClient; - void *m_pSteamGameServer; + ISteamGameServer* m_pSteamGameServer; void *m_pSteamGameServerUtils; void *m_pSteamGameServerNetworking; void *m_pSteamGameServerStats; @@ -95,26 +93,70 @@ public: void *m_pSteamApps; } *g_pSteam3Server; -CBaseServer *g_pBaseServer = NULL; - typedef CSteam3Server *(*Steam3ServerFunc)(); -#if !defined(WIN32) || defined(WIN64) -typedef void (*RejectConnectionFunc)(CBaseServer *, const netadr_t &address, int iClientChallenge, const char *pchReason); -#else -typedef void (__fastcall *RejectConnectionFunc)(CBaseServer *, void *, const netadr_t &address, int iClientChallenge, const char *pchReason); -#endif +class FEmptyClass {}; +template +union MFPHack { +private: + void* addr; +public: + MFPHack(void* addr) + { + this->addr = addr; + } -#if !defined(WIN32) || defined(WIN64) -typedef void (*SetSteamIDFunc)(CBaseClient *, const CSteamID &steamID); -#else -typedef void (__fastcall *SetSteamIDFunc)(CBaseClient *, void *, const CSteamID &steamID); + template + MFPHack(RetType (randomclass::*mfp)(Args...)) + { + union + { + RetType (randomclass::*ptr)(Args...); + struct + { + void* addr; +#ifdef __linux__ + intptr_t adjustor; #endif + } details; + } u; + u.ptr = mfp; + this->addr = u.details.addr; + } + + void SetAddress(void* addr) + { + this->addr = addr; + } + + void* GetAddress() + { + return this->addr; + } + + RetType operator()(classcall* ptrThis, Args... args) + { + union + { + RetType (FEmptyClass::*ptr)(Args...); + struct + { + void* addr; +#ifdef __linux__ + intptr_t adjustor; +#endif + } details; + } u; + + u.details.addr = addr; +#ifdef __linux__ + u.details.adjustor = 0; +#endif + return (((FEmptyClass*)ptrThis)->*u.ptr)(args...); + } +}; CDetour* detourCBaseServer__ConnectClient = nullptr; -CDetour* detourCBaseServer__RejectConnection = nullptr; - -bool g_bEndAuthSessionOnRejectConnection = false; bool g_bSuppressBeginAuthSession = false; CSteamID g_lastClientSteamID; const void* g_lastAuthTicket; @@ -122,9 +164,10 @@ int g_lastcbAuthTicket; char passwordBuffer[255]; -Steam3ServerFunc g_pSteam3ServerFunc = NULL; -RejectConnectionFunc g_pRejectConnectionFunc = NULL; -SetSteamIDFunc g_pSetSteamIDFunc = NULL; +Steam3ServerFunc g_pSteam3ServerFunc = nullptr; +MFPHack g_pRejectConnectionFunc(nullptr); +MFPHack g_pBeginAuthSession(nullptr); +MFPHack g_pEndAuthSession(nullptr); CSteam3Server *Steam3Server() { @@ -134,38 +177,7 @@ CSteam3Server *Steam3Server() return g_pSteam3ServerFunc(); } -void RejectConnection(const netadr_t &address, int iClientChallenge, const char *pchReason) -{ - if (!g_pRejectConnectionFunc || !g_pBaseServer) - return; - -#if !defined(WIN32) || defined(WIN64) - g_pRejectConnectionFunc(g_pBaseServer, address, iClientChallenge, pchReason); -#else - g_pRejectConnectionFunc(g_pBaseServer, NULL, address, iClientChallenge, pchReason); -#endif -} - -void SetSteamID(CBaseClient *pClient, const CSteamID &steamID) -{ - if (!pClient || !g_pSetSteamIDFunc) - return; - -#if !defined(WIN32) || defined(WIN64) - g_pSetSteamIDFunc(pClient, steamID); -#else - g_pSetSteamIDFunc(pClient, NULL, steamID); -#endif -} - -class VFuncEmptyClass{}; - -int g_nBeginAuthSessionOffset = 0; -int g_nEndAuthSessionOffset = 0; - SH_DECL_MANUALHOOK3(MHook_BeginAuthSession, 0, 0, 0, EBeginAuthSessionResult, const void *, int, CSteamID); -int g_nHookIdBeginAuthSession = -1; - EBeginAuthSessionResult Hook_BeginAuthSession(const void *pAuthTicket, int cbAuthTicket, CSteamID steamID) { if (!g_bSuppressBeginAuthSession) @@ -186,38 +198,6 @@ EBeginAuthSessionResult Hook_BeginAuthSession(const void *pAuthTicket, int cbAut RETURN_META_VALUE(MRES_IGNORED, k_EBeginAuthSessionResultDuplicateRequest); } -EBeginAuthSessionResult BeginAuthSession(const void *pAuthTicket, int cbAuthTicket, CSteamID steamID) -{ - if (g_nBeginAuthSessionOffset == 0) - return k_EBeginAuthSessionResultInvalidTicket; - - void *func = (*(void ***)g_pSteam3Server->m_pSteamGameServer)[g_nBeginAuthSessionOffset]; - - union { - EBeginAuthSessionResult (VFuncEmptyClass::*mfpnew)(const void *, int, CSteamID); - mfpDetails mfp; - } u; - u.mfp.Init(func); - - return (EBeginAuthSessionResult)(reinterpret_cast(g_pSteam3Server->m_pSteamGameServer)->*u.mfpnew)(pAuthTicket, cbAuthTicket, steamID); -} - -void EndAuthSession(CSteamID steamID) -{ - if (g_nEndAuthSessionOffset == 0) - return; - - void *func = (*(void ***)g_pSteam3Server->m_pSteamGameServer)[g_nEndAuthSessionOffset]; - - union { - void (VFuncEmptyClass::*mfpnew)(CSteamID); - mfpDetails mfp; - } u; - u.mfp.Init(func); - - return (void)(reinterpret_cast(g_pSteam3Server->m_pSteamGameServer)->*u.mfpnew)(steamID); -} - DETOUR_DECL_MEMBER9(CBaseServer__ConnectClient, IClient*, netadr_t&, address, int, nProtocol, int, iChallenge, int, iClientChallenge, int, nAuthProtocol, const char *, pchName, const char *, pchPassword, const char *, pCookie, int, cbCookie) { if (nAuthProtocol != k_EAuthProtocolSteam) @@ -226,14 +206,14 @@ DETOUR_DECL_MEMBER9(CBaseServer__ConnectClient, IClient*, netadr_t&, address, in return DETOUR_MEMBER_CALL(CBaseServer__ConnectClient)(address, nProtocol, iChallenge, iClientChallenge, nAuthProtocol, pchName, pchPassword, pCookie, cbCookie); } - g_pBaseServer = (CBaseServer *)this; - if (pCookie == NULL || (size_t)cbCookie < sizeof(uint64)) { - RejectConnection(address, iClientChallenge, "#GameUI_ServerRejectInvalidSteamCertLen"); + g_pRejectConnectionFunc((CBaseServer*)this, address, iClientChallenge, "#GameUI_ServerRejectInvalidSteamCertLen"); return NULL; } + auto steamGameServer = Steam3Server()->m_pSteamGameServer; + char ipString[30]; V_snprintf(ipString, sizeof(ipString), "%u.%u.%u.%u", address.ip[0], address.ip[1], address.ip[2], address.ip[3]); V_strncpy(passwordBuffer, pchPassword, 255); @@ -242,16 +222,15 @@ DETOUR_DECL_MEMBER9(CBaseServer__ConnectClient, IClient*, netadr_t&, address, in void *pvTicket = (void *)((intptr_t)pCookie + sizeof(uint64)); int cbTicket = cbCookie - sizeof(uint64); - g_bEndAuthSessionOnRejectConnection = true; g_lastClientSteamID = CSteamID(ullSteamID); g_lastcbAuthTicket = cbTicket; g_lastAuthTicket = pvTicket; // Validate steam ticket - EBeginAuthSessionResult result = BeginAuthSession(pvTicket, cbTicket, g_lastClientSteamID); + EBeginAuthSessionResult result = g_pBeginAuthSession(steamGameServer, pvTicket, cbTicket, g_lastClientSteamID); if (result != k_EBeginAuthSessionResultOK) { - RejectConnection(address, iClientChallenge, "#GameUI_ServerRejectSteam"); + g_pRejectConnectionFunc((CBaseServer*)this, address, iClientChallenge, "#GameUI_ServerRejectSteam"); return NULL; } @@ -268,7 +247,8 @@ DETOUR_DECL_MEMBER9(CBaseServer__ConnectClient, IClient*, netadr_t&, address, in if (retVal == 0) { - RejectConnection(address, iClientChallenge, rejectReason); + g_pEndAuthSession(steamGameServer, g_lastClientSteamID); + g_pRejectConnectionFunc((CBaseServer*)this, address, iClientChallenge, rejectReason); return NULL; } @@ -277,18 +257,11 @@ DETOUR_DECL_MEMBER9(CBaseServer__ConnectClient, IClient*, netadr_t&, address, in g_bSuppressBeginAuthSession = true; auto client = DETOUR_MEMBER_CALL(CBaseServer__ConnectClient)(address, nProtocol, iChallenge, iClientChallenge, nAuthProtocol, pchName, pchPassword, pCookie, cbCookie); g_bSuppressBeginAuthSession = false; - return client; -} - -DETOUR_DECL_MEMBER3(CBaseServer__RejectConnection, void, netadr_t &, address, int, iClientChallenge, const char *, pchReason) -{ - if (g_bEndAuthSessionOnRejectConnection) + if (client == nullptr) { - EndAuthSession(g_lastClientSteamID); - g_bEndAuthSessionOnRejectConnection = false; + g_pEndAuthSession(steamGameServer, g_lastClientSteamID); } - - return DETOUR_MEMBER_CALL(CBaseServer__RejectConnection)(address, iClientChallenge, pchReason); + return client; } bool Connect::SDK_OnLoad(char *error, size_t maxlen, bool late) @@ -303,17 +276,13 @@ bool Connect::SDK_OnLoad(char *error, size_t maxlen, bool late) return false; } - if (!g_pGameConf->GetMemSig("CBaseServer__RejectConnection", (void **)(&g_pRejectConnectionFunc)) || !g_pRejectConnectionFunc) + void* addr; + if (!g_pGameConf->GetMemSig("CBaseServer__RejectConnection", &addr) || addr == nullptr) { snprintf(error, maxlen, "Failed to find CBaseServer__RejectConnection function.\n"); return false; } - - if (!g_pGameConf->GetMemSig("CBaseClient__SetSteamID", (void **)(&g_pSetSteamIDFunc)) || !g_pSetSteamIDFunc) - { - snprintf(error, maxlen, "Failed to find CBaseClient__SetSteamID function.\n"); - return false; - } + g_pRejectConnectionFunc.SetAddress(addr); #ifndef WIN32 if (!g_pGameConf->GetMemSig("Steam3Server", (void **)(&g_pSteam3ServerFunc)) || !g_pSteam3ServerFunc) @@ -338,9 +307,7 @@ bool Connect::SDK_OnLoad(char *error, size_t maxlen, bool late) //META_CONPRINTF("CheckMasterServerRequestRestart: %p\n", address); address = (void *)((intptr_t)address + steam3ServerFuncOffset); - int32_t offset = (*(int32_t *)address); // Get offset (yes, int32 even on 64-bit) - - g_pSteam3ServerFunc = (Steam3ServerFunc)((intptr_t)address + offset + sizeof(int32_t)); + g_pSteam3ServerFunc = (Steam3ServerFunc)((intptr_t)address + *((int32_t *)address) + sizeof(int32_t)); //META_CONPRINTF("Steam3Server: %p\n", g_pSteam3ServerFunc); #endif @@ -364,25 +331,31 @@ bool Connect::SDK_OnLoad(char *error, size_t maxlen, bool late) META_CONPRINTF("ISteamNetworking: %p\n", g_pSteam3Server->m_pSteamGameServerNetworking); META_CONPRINTF("ISteamGameServerStats: %p\n", g_pSteam3Server->m_pSteamGameServerStats); */ + void** vtable = *((void***)g_pSteam3Server->m_pSteamGameServer); - if (!g_pGameConf->GetOffset("ISteamGameServer__BeginAuthSession", &g_nBeginAuthSessionOffset) || g_nBeginAuthSessionOffset == 0) + int offset = 0; + if (!g_pGameConf->GetOffset("ISteamGameServer__BeginAuthSession", &offset) || offset == 0) { snprintf(error, maxlen, "Failed to find ISteamGameServer__BeginAuthSession offset.\n"); return false; } - SH_MANUALHOOK_RECONFIGURE(MHook_BeginAuthSession, g_nBeginAuthSessionOffset, 0, 0); + g_pBeginAuthSession.SetAddress(vtable[offset]); + + offset = 0; + if (!g_pGameConf->GetOffset("ISteamGameServer__EndAuthSession", &offset) || offset == 0) + { + snprintf(error, maxlen, "Failed to find ISteamGameServer__EndAuthSession offset.\n"); + return false; + } + g_pEndAuthSession.SetAddress(vtable[offset]); + + SH_MANUALHOOK_RECONFIGURE(MHook_BeginAuthSession, offset, 0, 0); if (SH_ADD_MANUALHOOK(MHook_BeginAuthSession, g_pSteam3Server->m_pSteamGameServer, SH_STATIC(Hook_BeginAuthSession), true) == 0) { snprintf(error, maxlen, "Failed to setup ISteamGameServer__BeginAuthSession hook.\n"); return false; } - if (!g_pGameConf->GetOffset("ISteamGameServer__EndAuthSession", &g_nEndAuthSessionOffset) || g_nEndAuthSessionOffset == 0) - { - snprintf(error, maxlen, "Failed to find ISteamGameServer__EndAuthSession offset.\n"); - return false; - } - CDetourManager::Init(g_pSM->GetScriptingEngine(), g_pGameConf); detourCBaseServer__ConnectClient = DETOUR_CREATE_MEMBER(CBaseServer__ConnectClient, "CBaseServer__ConnectClient"); @@ -393,14 +366,6 @@ bool Connect::SDK_OnLoad(char *error, size_t maxlen, bool late) } detourCBaseServer__ConnectClient->EnableDetour(); - detourCBaseServer__RejectConnection = DETOUR_CREATE_MEMBER(CBaseServer__RejectConnection, "CBaseServer__RejectConnection"); - if (detourCBaseServer__RejectConnection == nullptr) - { - snprintf(error, maxlen, "Failed to create CBaseServer__RejectConnection detour.\n"); - return false; - } - detourCBaseServer__RejectConnection->EnableDetour(); - g_pConnectForward = g_pForwards->CreateForward("OnClientPreConnectEx", ET_LowEvent, 5, NULL, Param_String, Param_String, Param_String, Param_String, Param_String); return true; @@ -430,12 +395,6 @@ bool Connect::SDK_OnMetamodUnload(char *error, size_t maxlen) delete detourCBaseServer__ConnectClient; } - if (detourCBaseServer__RejectConnection) - { - detourCBaseServer__RejectConnection->DisableDetour(); - delete detourCBaseServer__RejectConnection; - } - return true; }