From 857d2363dc5df0973b66f087070277a408a54dd7 Mon Sep 17 00:00:00 2001 From: xen Date: Sat, 22 Feb 2025 21:31:25 +0200 Subject: [PATCH] Use a different method for custom sim loop Also nuke all sigs and csgo/windows code --- extension.cpp | 311 ++++------------------------------- gamedata/PhysHooks.games.txt | 71 +------- smsdk_config.h | 2 +- 3 files changed, 35 insertions(+), 349 deletions(-) diff --git a/extension.cpp b/extension.cpp index 89e77f4..31218c5 100644 --- a/extension.cpp +++ b/extension.cpp @@ -52,50 +52,6 @@ public: virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity ) = 0; }; -struct SrcdsPatch -{ - const char *pSignature; - const unsigned char *pPatchSignature; - const char *pPatchPattern; - const unsigned char *pPatch; - - unsigned char *pOriginal; - uintptr_t pAddress; - uintptr_t pPatchAddress; - bool engine; -} gs_Patches[] = { - // Hook: Replace call inside Physics_RunThinkFunctions -#if SOURCE_ENGINE == SE_CSS && defined PLATFORM_LINUX - { - "Physics_RunThinkFunctions", - (unsigned char *)"\x8B\x14\x9E\x85\xD2\x74\x00\xA1\x00\x00\x00\x00\x83\xEC\x00\xF3\x0F\x10\x55\x00\xF3\x0F\x11\x50\x00\xFF", - "xxxxxx?x????xx?xxxx?xxxx?x", - NULL, - 0, 0, 0, false - } -#elif SOURCE_ENGINE == SE_CSGO && defined PLATFORM_LINUX - { - "Physics_RunThinkFunctions", - (unsigned char *)"\xA1\x5C\xD8\x42\x01\x89\x78\x10\x8B\x04\x9E\x89\x04\x24\xE8\xAD\xFC\xFF\xFF\x83\xC3\x01\x3B\x5D\xD4\x75\xE5", - "x????xxxxxxxxxx????xxxxxxxx", - NULL, - 0, 0, 0, false - } -#elif SOURCE_ENGINE == SE_CSGO && defined PLATFORM_WINDOWS - { - "Physics_RunThinkFunctions", - (unsigned char *)"\x8B\xF0\x0F\x1F\x84\x00\x00\x00\x00\x00\x8B\x0D\xD0\x52\xA3\x10\xF3\x0F\x10\x45\xFC\xF3\x0F\x11\x41\x10\x8B\x0C\xBB\xE8\x18\xFE\xFF\xFF\x47\x3B\xFE\x7C\xE3\x8B\x75\xF4", - "xxxxxxxxxxxx????xxxxxxxxxxxxxx????xxxxxxxx", - NULL, - 0, 0, 0, false - } -#else -#error "Unsupported platform" -#endif -}; - -uintptr_t FindPattern(uintptr_t BaseAddr, const unsigned char *pData, const char *pPattern, size_t MaxSize, bool Reverse=false); - /** * @file extension.cpp * @brief Implement extension code here. @@ -109,6 +65,7 @@ CGlobalVars *gpGlobals = NULL; IGameConfig *g_pGameConf = NULL; CDetour *g_pDetour_RunThinkFunctions = NULL; +CDetour *g_pDetour_SimThink_ListCopy = NULL; IForward *g_pOnRunThinkFunctions = NULL; IForward *g_pOnPrePlayerThinkFunctions = NULL; @@ -145,16 +102,11 @@ DETOUR_DECL_STATIC1(DETOUR_RunThinkFunctions, void, bool, simulating) } } -#if defined PLATFORM_LINUX void (*g_pPhysics_SimulateEntity)(CBaseEntity *pEntity) = NULL; -#elif defined PLATFORM_WINDOWS -void (__fastcall *g_pPhysics_SimulateEntity)(CBaseEntity *pEntity) = NULL; -#endif void Physics_SimulateEntity_CustomLoop(CBaseEntity **ppList, int Count, float Startime) { - CUtlVectorFixed apPlayers; - int iPlayers = 0; + CUtlVectorFixed apPlayers; // Remove players from list and put into apPlayers for(int i = 0; i < Count; i++) @@ -170,22 +122,16 @@ void Physics_SimulateEntity_CustomLoop(CBaseEntity **ppList, int Count, float St int Entity = gamehelpers->IndexOfEdict(pEdict); if(Entity >= 1 && Entity <= g_iMaxPlayers) { - apPlayers[iPlayers++] = pEntity; + apPlayers.AddToTail(pEntity); ppList[i] = NULL; } } // Shuffle players array - for(int i = iPlayers - 1; i > 0; i--) - { - int j = rand() % (i + 1); - CBaseEntity *pTmp = apPlayers[j]; - apPlayers[j] = apPlayers[i]; - apPlayers[i] = pTmp; - } + apPlayers.Shuffle(); // Simulate players first - for(int i = 0; i < iPlayers; i++) + FOR_EACH_VEC(apPlayers, i) { gpGlobals->curtime = Startime; g_pPhysics_SimulateEntity(apPlayers[i]); @@ -210,6 +156,13 @@ void Physics_SimulateEntity_CustomLoop(CBaseEntity **ppList, int Count, float St } } +DETOUR_DECL_STATIC2(DETOUR_SimThink_ListCopy, int, CBaseEntity **, ppList, int, listMax) +{ + int count = DETOUR_STATIC_CALL(DETOUR_SimThink_ListCopy)(ppList, listMax); + Physics_SimulateEntity_CustomLoop(ppList, count, gpGlobals->curtime); + return 0; +} + int g_TriggerEntityMoved; int *g_pBlockTriggerTouchPlayers = NULL; int *g_pBlockTriggerMoved = NULL; @@ -385,8 +338,16 @@ bool PhysHooks::SDK_OnLoad(char *error, size_t maxlength, bool late) g_pDetour_RunThinkFunctions->EnableDetour(); + g_pDetour_SimThink_ListCopy = DETOUR_CREATE_STATIC(DETOUR_SimThink_ListCopy, "SimThink_ListCopy"); + if (g_pDetour_SimThink_ListCopy == NULL) + { + snprintf(error, maxlength, "Could not create detour for SimThink_ListCopy"); + SDK_OnUnload(); + return false; + } + + g_pDetour_SimThink_ListCopy->EnableDetour(); -#if defined PLATFORM_LINUX // Find VTable for CTriggerMoved uintptr_t pCTriggerMoved; if(!g_pGameConf->GetMemSig("CTriggerMoved", (void **)(&pCTriggerMoved)) || !pCTriggerMoved) @@ -405,67 +366,10 @@ bool PhysHooks::SDK_OnLoad(char *error, size_t maxlength, bool late) return false; } -#if SOURCE_ENGINE == SE_CSS // First function in VTable g_CTriggerMoved = (CTriggerMoved *)(pCTriggerMoved + 8); g_CTouchLinks = (CTouchLinks *)(pCTouchLinks + 8); -#elif SOURCE_ENGINE == SE_CSGO - // On Linux CSGO we can only find the typeinfo name '_ZTS' for the vtable - uintptr_t pCTriggerMoved_ZTS = pCTriggerMoved; - uintptr_t pCTouchLinks_ZTS = pCTouchLinks; - - // This leads us to the first item in the typeinfo '_ZTI' if we search for a reference of '_ZTS' addr in reverse - uintptr_t pCTriggerMoved_ZTI = FindPattern(pCTriggerMoved_ZTS, (unsigned char *)&pCTriggerMoved_ZTS, "xxxx", 0x100, true); - uintptr_t pCTouchLinks_ZTI = FindPattern(pCTouchLinks_ZTS, (unsigned char *)&pCTouchLinks_ZTS, "xxxx", 0x100, true); - if(!pCTriggerMoved_ZTI || !pCTouchLinks_ZTI) - { - snprintf(error, maxlength, "Failed to FindPattern CTriggerMoved_ZTS or CTouchLinks_ZTI.\n"); - SDK_OnUnload(); - return false; - } - - // The actual '_ZTI' is at -4 from the element we found inside it - pCTriggerMoved_ZTI -= 4; - pCTouchLinks_ZTI -= 4; - - // Now we can search for a reference of '_ZTI' in reverse, it'll be the first item of our vtable / '_ZTV' - pCTriggerMoved = FindPattern(pCTriggerMoved_ZTI, (unsigned char *)&pCTriggerMoved_ZTI, "xxxx", 0x100, true); - pCTouchLinks = FindPattern(pCTouchLinks_ZTI, (unsigned char *)&pCTouchLinks_ZTI, "xxxx", 0x100, true); - if(!pCTriggerMoved || !pCTouchLinks) - { - snprintf(error, maxlength, "Failed to FindPattern CTriggerMoved_ZTV or CTouchLinks_ZTI.\n"); - SDK_OnUnload(); - return false; - } - - // First function in VTable - g_CTriggerMoved = (CTriggerMoved *)(pCTriggerMoved + 4); - g_CTouchLinks = (CTouchLinks *)(pCTouchLinks + 4); -#else -#error "Unsupported platform" -#endif - -#elif defined PLATFORM_WINDOWS - // Find VTable for CTriggerMoved - if(!g_pGameConf->GetAddress("CTriggerMoved", (void **)(&g_CTriggerMoved)) || !g_CTriggerMoved) - { - snprintf(error, maxlength, "Failed to find CTriggerMoved.\n"); - SDK_OnUnload(); - return false; - } - - // Find VTable for CTouchLinks - if(!g_pGameConf->GetAddress("CTouchLinks", (void **)(&g_CTouchLinks)) || !g_CTouchLinks) - { - snprintf(error, maxlength, "Failed to find CTouchLinks.\n"); - SDK_OnUnload(); - return false; - } -#else -#error "Unsupported platform" -#endif - g_SH_TriggerMoved = SH_ADD_DVPHOOK(CTriggerMoved, EnumElement, g_CTriggerMoved, SH_STATIC(TriggerMoved_EnumElement), false); g_SH_TouchLinks = SH_ADD_DVPHOOK(CTouchLinks, EnumElement, g_CTouchLinks, SH_STATIC(TouchLinks_EnumElement), false); @@ -479,121 +383,9 @@ bool PhysHooks::SDK_OnLoad(char *error, size_t maxlength, bool late) return false; } - /* Hook: Replace call inside Physics_RunThinkFunctions */ - uintptr_t pAddress; - if(!g_pGameConf->GetMemSig(gs_Patches[0].pSignature, (void **)&pAddress) || !pAddress) - { - snprintf(error, maxlength, "Failed to find Physics_RunThinkFunctions address.\n"); - SDK_OnUnload(); - return false; - } - - uintptr_t pPatchAddress = FindPattern(pAddress, gs_Patches[0].pPatchSignature, gs_Patches[0].pPatchPattern, 1024); - if(!pPatchAddress) - { - snprintf(error, maxlength, "Could not find patch signature for symbol: %s", gs_Patches[0].pSignature); - SDK_OnUnload(); - return false; - } - -#if SOURCE_ENGINE == SE_CSS && defined PLATFORM_LINUX - // sub esp, 4 ; allocate room on stack for starttime - // movss [esp], xmm2 ; startime - // push eax ; count - // push esi ; **list - // call NULL ; <- our func here - // add esp, 12 ; fix up stack - // jmp +24 ; jump over useless instructions - //"\x8B\x14\x9E\x85\xD2\x74\x00\xA1\x00\x00\x00\x00\x83\xEC\x00\xF3\x0F\x10\x55\x00\xF3\x0F\x11\x50\x00\xFF" - static unsigned char aPatch[] = "\x83\xEC\x04\xF3\x0F\x11\x14\x24\x50\x56\xE8\x00\x00\x00\x00\x83\xC4\x0C\xEB\x18\x90\x90\x90\x90\x90\x90"; - gs_Patches[0].pPatch = aPatch; - - // put our function address into the relative call instruction - // relative call: new PC = PC + imm1 - // call is at + 10 after pPatchAddress - // PC will be past our call instruction so + 5 - *(uintptr_t *)&aPatch[11] = (uintptr_t)Physics_SimulateEntity_CustomLoop - (pPatchAddress + 10 + 5); -#elif SOURCE_ENGINE == SE_CSGO && defined PLATFORM_LINUX - // mov [esp+8], edi ; startime - // mov [esp+4], eax ; count - // mov [esp], esi ; **list - // call NULL ; <- our func here - // jmp +9 ; jump over useless instructions - static unsigned char aPatch[] = "\x89\x7C\x24\x08\x89\x44\x24\x04\x89\x34\x24\xE8\x00\x00\x00\x00\xEB\x09\x90\x90\x90\x90\x90\x90\x90\x90\x90"; - gs_Patches[0].pPatch = aPatch; - - // put our function address into the relative call instruction - // relative call: new PC = PC + imm1 - // call is at + 11 after pPatchAddress - // PC will be past our call instruction so + 5 - *(uintptr_t *)&aPatch[12] = (uintptr_t)Physics_SimulateEntity_CustomLoop - (pPatchAddress + 11 + 5); -#elif SOURCE_ENGINE == SE_CSGO && defined PLATFORM_WINDOWS - // sub esp, 4 ; allocate room on stack for startime - // movss xmm0, [ebp-4] ; startime from stack into FP register - // movss DWORD PTR [esp], xmm0 ; startime - // push eax ; count - // push ebx ; **list - // call NULL ; <- our func here - // add esp, 12 ; fix up stack - // jmp +17 ; jump over useless instructions - static unsigned char aPatch[] = "\x83\xEC\x04\xF3\x0F\x10\x45\xFC\xF3\x0F\x11\x04\x24\x50\x53\xE8\x00\x00\x00\x00\x83\xC4\x0C\xEB\x11\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"; - gs_Patches[0].pPatch = aPatch; - - // put our function address into the relative call instruction - // relative call: new PC = PC + imm1 - // call is at + 15 after pPatchAddress - // PC will be past our call instruction so + 5 - *(uintptr_t *)&aPatch[16] = (uintptr_t)Physics_SimulateEntity_CustomLoop - (pPatchAddress + 15 + 5); -#else -#error "Unsupported platform" -#endif - - bool bSuccess = true; - - // TODO: Fix this cursed patch - /* - // Apply all patches - for(size_t i = 0; i < sizeof(gs_Patches) / sizeof(*gs_Patches); i++) - { - struct SrcdsPatch *pPatch = &gs_Patches[i]; - int PatchLen = strlen(pPatch->pPatchPattern); - - if(!g_pGameConf->GetMemSig(pPatch->pSignature, (void **)&pPatch->pAddress) || !pPatch->pAddress) - { - g_pSM->LogError(myself, "Could not find symbol: %s", pPatch->pSignature); - bSuccess = false; - continue; - } - - pPatch->pPatchAddress = FindPattern(pPatch->pAddress, pPatch->pPatchSignature, pPatch->pPatchPattern, 1024); - if(!pPatch->pPatchAddress) - { - g_pSM->LogError(myself, "Could not find patch signature for symbol: %s", pPatch->pSignature); - bSuccess = false; - continue; - } - - pPatch->pOriginal = (unsigned char *)malloc(PatchLen * sizeof(unsigned char)); - - SourceHook::SetMemAccess((void *)pPatch->pPatchAddress, PatchLen, SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); - for(int j = 0; j < PatchLen; j++) - { - pPatch->pOriginal[j] = *(unsigned char *)(pPatch->pPatchAddress + j); - *(unsigned char *)(pPatch->pPatchAddress + j) = pPatch->pPatch[j]; - } - SourceHook::SetMemAccess((void *)pPatch->pPatchAddress, PatchLen, SH_MEM_READ|SH_MEM_EXEC); - } - */ - - if (!bSuccess) - { - SDK_OnUnload(); - return false; - } - g_pOnRunThinkFunctions = forwards->CreateForward("OnRunThinkFunctions", ET_Ignore, 1, NULL, Param_Cell); g_pOnPrePlayerThinkFunctions = forwards->CreateForward("OnPrePlayerThinkFunctions", ET_Ignore, 0, NULL); - g_pOnPostPlayerThinkFunctions = forwards->CreateForward("OnPostPlayerThinkFunctions", ET_Ignore, 0, NULL); // NOTE: This relies on the cursed patch above + g_pOnPostPlayerThinkFunctions = forwards->CreateForward("OnPostPlayerThinkFunctions", ET_Ignore, 0, NULL); g_pOnRunThinkFunctionsPost = forwards->CreateForward("OnRunThinkFunctionsPost", ET_Ignore, 1, NULL, Param_Cell); return true; @@ -622,6 +414,12 @@ void PhysHooks::SDK_OnUnload() g_pDetour_RunThinkFunctions = NULL; } + if (g_pDetour_SimThink_ListCopy != NULL) + { + g_pDetour_SimThink_ListCopy->Destroy(); + g_pDetour_SimThink_ListCopy = NULL; + } + if(g_pOnRunThinkFunctions != NULL) { forwards->ReleaseForward(g_pOnRunThinkFunctions); @@ -656,26 +454,6 @@ void PhysHooks::SDK_OnUnload() SH_REMOVE_HOOK(IVEngineServer, SolidMoved, engine, SH_STATIC(SolidMoved), false); gameconfs->CloseGameConfigFile(g_pGameConf); - - // Revert all applied patches - for(size_t i = 0; i < sizeof(gs_Patches) / sizeof(*gs_Patches); i++) - { - struct SrcdsPatch *pPatch = &gs_Patches[i]; - int PatchLen = strlen(pPatch->pPatchPattern); - - if(!pPatch->pOriginal) - continue; - - SourceHook::SetMemAccess((void *)pPatch->pPatchAddress, PatchLen, SH_MEM_READ|SH_MEM_WRITE|SH_MEM_EXEC); - for(int j = 0; j < PatchLen; j++) - { - *(unsigned char *)(pPatch->pPatchAddress + j) = pPatch->pOriginal[j]; - } - SourceHook::SetMemAccess((void *)pPatch->pPatchAddress, PatchLen, SH_MEM_READ|SH_MEM_EXEC); - - free(pPatch->pOriginal); - pPatch->pOriginal = NULL; - } } bool PhysHooks::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late) @@ -684,36 +462,3 @@ bool PhysHooks::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, boo gpGlobals = ismm->GetCGlobals(); return true; } - -uintptr_t FindPattern(uintptr_t BaseAddr, const unsigned char *pData, const char *pPattern, size_t MaxSize, bool Reverse) -{ - unsigned char *pMemory; - uintptr_t PatternLen = strlen(pPattern); - - pMemory = reinterpret_cast(BaseAddr); - - if(!Reverse) - for(uintptr_t i = 0; i < MaxSize; i++) - { - uintptr_t Matches = 0; - while(*(pMemory + i + Matches) == pData[Matches] || pPattern[Matches] != 'x') - { - Matches++; - if(Matches == PatternLen) - return (uintptr_t)(pMemory + i); - } - } - else - for(uintptr_t i = 0; i < MaxSize; i++) - { - uintptr_t Matches = 0; - while(*(pMemory - i + Matches) == pData[Matches] || pPattern[Matches] != 'x') - { - Matches++; - if(Matches == PatternLen) - return (uintptr_t)(pMemory - i); - } - } - - return 0x00; -} diff --git a/gamedata/PhysHooks.games.txt b/gamedata/PhysHooks.games.txt index 01edc39..6d9d115 100644 --- a/gamedata/PhysHooks.games.txt +++ b/gamedata/PhysHooks.games.txt @@ -9,6 +9,12 @@ "library" "server" "linux" "@_Z25Physics_RunThinkFunctionsb" } + + "SimThink_ListCopy" + { + "library" "server" + "linux" "@_Z17SimThink_ListCopyPP11CBaseEntityi" + } "Physics_SimulateEntity" { @@ -29,69 +35,4 @@ } } } - - "csgo" - { - "Signatures" - { - "Physics_RunThinkFunctions" - { - "library" "server" - "linux" "\x55\x89\xE5\x57\x56\x53\x83\xEC\x4C\xA1\x2A\x2A\x2A\x2A\x0F\xB6\x5D\x08" - "windows" "\x55\x8B\xEC\x83\xEC\x0C\x53\x56\x8B\x35\x2A\x2A\x2A\x2A\x8A\xD9" - } - - "Physics_SimulateEntity" - { - "library" "server" - "linux" "\x55\x89\xE5\x57\x56\xBE\x2A\x2A\x2A\x2A\x53\x83\xEC\x4C\xA1\x2A\x2A\x2A\x2A" - "windows" "\x56\x8B\xF1\x83\x7E\x1C\x00\x74\x2A\x80\xBE\x4B\x02\x00\x00\x00" - } - - "CTriggerMoved" - { - "library" "engine" - "linux" "13CTriggerMoved" - } - - "CTouchLinks" - { - "library" "engine" - "linux" "11CTouchLinks" - } - - "SV_TriggerMoved" - { - "library" "engine" - "windows" "\x55\x8B\xEC\x83\xEC\x34\xA1\x2A\x2A\x2A\x2A\x53\x56\x8B\xF1\xC7\x45\xCC\x2A\x2A\x2A\x2A\x8B\x08\x8A\xDA\xC7\x45\xE8\x00\x00\x00\x00\xC7\x45\xEC\x08\x00\x00\x00\xC7\x45\xF0\x08\x00\x00\x00\x8B\x01\x6A\x20\xFF\x50\x04\x56\x8D\x4D\xCC\x89\x45\xE8\xC7\x45\xF4\x00\x00\x00\x00\x89\x45\xF8\x88\x5D\xFC\xE8\x2A\x2A\x2A\x2A\x33\xF6" - } - - "SV_SolidMoved" - { - "library" "engine" - "windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\xEC\x18\x56\x8B\xF1\x6A\x20\xC7\x06\x2A\x2A\x2A\x2A\xC7\x46\x50\x00\x00\x00\x00\xC7\x46\x6C\x00\x00\x00\x00\xC7\x46\x70\x08\x00\x00\x00\xC7\x46\x74\x08\x00\x00\x00\x8B\x08\x8B\x01\xFF\x50\x04\x8B\x4D\x08\x89\x46\x6C\xC7\x46\x78\x00\x00\x00\x00\x89\x46\x7C\x89\x4E\x60\xF6\x01\x04" - } - } - - "Addresses" - { - "CTriggerMoved" - { - "windows" - { - "signature" "SV_TriggerMoved" - "read" "18" - } - } - - "CTouchLinks" - { - "windows" - { - "signature" "SV_SolidMoved" - "read" "18" - } - } - } - } } diff --git a/smsdk_config.h b/smsdk_config.h index db4697a..bba74bd 100644 --- a/smsdk_config.h +++ b/smsdk_config.h @@ -40,7 +40,7 @@ /* Basic information exposed publicly */ #define SMEXT_CONF_NAME "PhysHooks" #define SMEXT_CONF_DESCRIPTION "Hooks, forwards and natives for LagCompensation, etc." -#define SMEXT_CONF_VERSION "1.0" +#define SMEXT_CONF_VERSION "1.1" #define SMEXT_CONF_AUTHOR "BotoX" #define SMEXT_CONF_URL "" #define SMEXT_CONF_LOGTAG "PhysHooks"