Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 42 additions & 34 deletions src/extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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<const char*>(pPatch->pPatch));

#ifdef _WIN32
HMODULE pBinary = LoadLibrary(pPatch->pLibrary);
Expand Down Expand Up @@ -908,42 +910,34 @@ 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);
}
}

uintptr_t ofs = 0;
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);

Expand Down Expand Up @@ -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<const char*>(pPatch->pPatch));

SrcdsPatch::Restore *pRestore = pPatch->pRestore;
while(pRestore)
Expand Down Expand Up @@ -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<unsigned char *>(E8Addr) != 0xE8)
return 0x00;

uint32_t offset = *reinterpret_cast<int32_t *>(E8Addr + 1);
return E8Addr + 5 + offset;
}