diff --git a/src/extension.cpp b/src/extension.cpp index 3070e8a..52d4079 100644 --- a/src/extension.cpp +++ b/src/extension.cpp @@ -180,7 +180,7 @@ typedef bool (*ShouldHitFunc_t)( IHandleEntity *pHandleEntity, int contentsMask uintptr_t FindPattern(uintptr_t BaseAddr, const unsigned char *pData, const char *pPattern, size_t MaxSize); uintptr_t FindFunctionCall(uintptr_t BaseAddr, uintptr_t Function, size_t MaxSize); - +uintptr_t FindFunctionAddressByPattern(uintptr_t StartAddr, size_t MaxSize); /** * @file extension.cpp @@ -760,22 +760,22 @@ bool CSSFixes::SDK_OnLoad(char *error, size_t maxlength, bool late) // 10: fix server lagging resulting from too many ConMsgs due to packet spam { "_ZN8CNetChan19ProcessPacketHeaderEP11netpacket_s", - (unsigned char *)"_Z6ConMsgPKcz", - "xxxxx", + (unsigned char *)"\x8B\x45\x08\x05\xA0\x2A\x2A\x2A\xFF\x75\xC8\x53\x50\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A", // Pattern for first ConMsg call. + "xxxxx???xxxxxx????x????", (unsigned char *)"\x90\x90\x90\x90\x90", "bin/engine_srv.so", 0x7d1, 100, - true, "bin/libtier0_srv.so" + true }, // 11: fix server lagging resulting from too many ConMsgs due to packet spam { "_Z11NET_GetLongiP11netpacket_s", - (unsigned char *)"Msg", - "xxxxx", + (unsigned char *)"\x83\xC4\x0C\x50\xFF\xB6\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A", // Pattern for first Msg call. + "xxxxxx????x????x????", (unsigned char *)"\x90\x90\x90\x90\x90", "bin/engine_srv.so", 0x800, 100, - true, "bin/libtier0_srv.so" + true }, // 13: CTriggerCamera::FollowTarget: Don't early return when the player handle is null { @@ -878,7 +878,9 @@ bool CSSFixes::SDK_OnLoad(char *error, size_t maxlength, bool late) for(size_t i = 0; i < gs_Patches.size(); i++) { struct SrcdsPatch *pPatch = &gs_Patches[i]; - int PatchLen = strlen(pPatch->pPatchPattern); + + // PatchLen has to be the number of opcodes for a function call which is just E8 followed by 4 byes + int PatchLen = !pPatch->functionCall ? strlen(pPatch->pPatchPattern) : strlen(reinterpret_cast(pPatch->pPatch)); #ifdef _WIN32 HMODULE pBinary = LoadLibrary(pPatch->pLibrary); @@ -908,32 +910,17 @@ bool CSSFixes::SDK_OnLoad(char *error, size_t maxlength, bool late) SrcdsPatch::Restore **ppRestore = &pPatch->pRestore; + uintptr_t functionAddress = 0x00; // For patches that NOP function calls. + + // If it's a function call patch, resolve the target function address ONCE before applying patches if(pPatch->functionCall) { -#ifdef _WIN32 - HMODULE pFunctionBinary = LoadLibrary(pPatch->pFunctionLibrary); -#else - void* pFunctionBinary = dlopen(pPatch->pFunctionLibrary, RTLD_NOW); -#endif - if(!pFunctionBinary) + uintptr_t startAddr = FindPattern(pPatch->pAddress, pPatch->pPatchSignature, pPatch->pPatchPattern, pPatch->range); + if(startAddr) { - g_pSM->LogError(myself, "Could not dlopen %s", pPatch->pFunctionLibrary); - bSuccess = false; - continue; - } - - pPatch->pSignatureAddress = (uintptr_t)memutils->ResolveSymbol(pFunctionBinary, (char *)pPatch->pPatchSignature); -#ifdef _WIN32 - FreeLibrary(pFunctionBinary); -#else - dlclose(pFunctionBinary); -#endif - if(!pPatch->pSignatureAddress) - { - g_pSM->LogError(myself, "Could not find patch signature symbol: %s in %s (%p)", - (char *)pPatch->pPatchSignature, pPatch->pFunctionLibrary, pFunctionBinary); - bSuccess = false; - continue; + functionAddress = FindFunctionAddressByPattern(startAddr, strlen(pPatch->pPatchPattern)); + if (functionAddress && g_SvLogs->GetInt()) + g_pSM->LogMessage(myself, "Found patched function address for symbol: %s (%p)", pPatch->pSignature, functionAddress); } } @@ -941,9 +928,16 @@ bool CSSFixes::SDK_OnLoad(char *error, size_t maxlength, bool late) int found; for(found = 0; found < pPatch->occurrences; found++) { - uintptr_t pPatchAddress; + uintptr_t pPatchAddress = 0x00; if(pPatch->functionCall) - pPatchAddress = FindFunctionCall(pPatch->pAddress + ofs, pPatch->pSignatureAddress, pPatch->range - ofs); + { + if(functionAddress) + { + pPatchAddress = FindFunctionCall(pPatch->pAddress + ofs, functionAddress, pPatch->range - ofs); + if (pPatchAddress && g_SvLogs->GetInt()) + g_pSM->LogMessage(myself, "Found occurence (%d) function call for symbol: %s (%p)", found, pPatch->pSignature, pPatchAddress); + } + } else pPatchAddress = FindPattern(pPatch->pAddress + ofs, pPatch->pPatchSignature, pPatch->pPatchPattern, pPatch->range - ofs); @@ -1071,7 +1065,7 @@ void CSSFixes::SDK_OnUnload() for(size_t i = 0; i < gs_Patches.size(); i++) { struct SrcdsPatch *pPatch = &gs_Patches[i]; - int PatchLen = strlen(pPatch->pPatchPattern); + int PatchLen = !pPatch->functionCall ? strlen(pPatch->pPatchPattern) : strlen(reinterpret_cast(pPatch->pPatch)); SrcdsPatch::Restore *pRestore = pPatch->pRestore; while(pRestore) @@ -1146,3 +1140,17 @@ uintptr_t FindFunctionCall(uintptr_t BaseAddr, uintptr_t Function, size_t MaxSiz return 0x00; } + +uintptr_t FindFunctionAddressByPattern(uintptr_t StartAddr, size_t MaxSize) +{ + // Find the E8 opcode so we can calculate the desired function's address. + // The E8 opcode and what follows it (The 4 bytes) have to be at the end of the pattern. + uintptr_t E8Addr = StartAddr + (MaxSize - 5); + + // Just a safety chekc + if (*reinterpret_cast(E8Addr) != 0xE8) + return 0x00; + + uint32_t offset = *reinterpret_cast(E8Addr + 1); + return E8Addr + 5 + offset; +}