Skip to content

Commit

Permalink
Warn if Metamod is detected. Auto disable it for cstrike.
Browse files Browse the repository at this point in the history
  • Loading branch information
khanghugo committed Feb 21, 2024
1 parent a0cc469 commit 5a5e059
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 13 deletions.
111 changes: 98 additions & 13 deletions BunnymodXT/modules/HwDLL.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "../stdafx.hpp"

#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <cerrno>
#include <GL/gl.h>
#include "../sptlib-wrapper.hpp"
Expand Down Expand Up @@ -346,6 +347,11 @@ extern "C" qboolean __cdecl CL_ReadDemoMessage_OLD()
{
return HwDLL::HOOKED_CL_ReadDemoMessage_OLD();
}

extern "C" void __cdecl LoadThisDll(char *szDllFilename)
{
return HwDLL::HOOKED_LoadThisDll_Linux(szDllFilename);
}
#endif

void HwDLL::Hook(const std::wstring& moduleName, void* moduleHandle, void* moduleBase, size_t moduleLength, bool needToIntercept)
Expand Down Expand Up @@ -472,6 +478,7 @@ void HwDLL::Hook(const std::wstring& moduleName, void* moduleHandle, void* modul
MemUtils::MarkAsExecutable(ORIG_ValidStuffText);
MemUtils::MarkAsExecutable(ORIG_CL_ReadDemoMessage_OLD);
MemUtils::MarkAsExecutable(ORIG_NLoadBlobFileClient);
MemUtils::MarkAsExecutable(ORIG_LoadThisDll);
}

MemUtils::Intercept(moduleName,
Expand Down Expand Up @@ -536,7 +543,8 @@ void HwDLL::Hook(const std::wstring& moduleName, void* moduleHandle, void* modul
ORIG_ReleaseEntityDlls, HOOKED_ReleaseEntityDlls,
ORIG_ValidStuffText, HOOKED_ValidStuffText,
ORIG_CL_ReadDemoMessage_OLD, HOOKED_CL_ReadDemoMessage_OLD,
ORIG_Host_Shutdown, HOOKED_Host_Shutdown);
ORIG_Host_Shutdown, HOOKED_Host_Shutdown,
ORIG_LoadThisDll, HOOKED_LoadThisDll);
}

#ifdef _WIN32
Expand Down Expand Up @@ -630,7 +638,8 @@ void HwDLL::Unhook()
ORIG_ReleaseEntityDlls,
ORIG_ValidStuffText,
ORIG_CL_ReadDemoMessage_OLD,
ORIG_Host_Shutdown);
ORIG_Host_Shutdown,
ORIG_LoadThisDll);
}

for (auto cvar : CVars::allCVars)
Expand Down Expand Up @@ -733,6 +742,8 @@ void HwDLL::Clear()
ORIG_ReleaseEntityDlls = nullptr;
ORIG_ValidStuffText = nullptr;
ORIG_CL_ReadDemoMessage_OLD = nullptr;
ORIG_LoadThisDll = nullptr;
ORIG_LoadThisDll_Linux = nullptr;

ClientDLL::GetInstance().pEngfuncs = nullptr;
ServerDLL::GetInstance().pEngfuncs = nullptr;
Expand Down Expand Up @@ -1322,6 +1333,14 @@ void HwDLL::FindStuff()
EngineDevMsg("[hw dll] Found g_sv_delta at %p.\n", g_sv_delta);
else
EngineDevWarning("[hw dll] Could not find g_sv_delta.\n");

ORIG_LoadThisDll_Linux = reinterpret_cast<_LoadThisDll_Linux>(MemUtils::GetSymbolAddress(m_Handle, "LoadThisDll"));
if (ORIG_LoadThisDll_Linux)
EngineDevMsg("[hw dll] Found LoadThisDll at %p.\n", ORIG_LoadThisDll_Linux);
else {
EngineDevWarning("[hw dll] Could not find LoadThisDll.\n");
EngineWarning("[hw dll] AmxModX might crash with BunnymodXT.\n");
}
}
else
{
Expand Down Expand Up @@ -1469,25 +1488,24 @@ void HwDLL::FindStuff()
}
});

void* LoadThisDll;
auto fLoadThisDll = FindAsync(
LoadThisDll,
ORIG_LoadThisDll,
patterns::engine::LoadThisDll,
[&](auto pattern) {
switch (pattern - patterns::engine::LoadThisDll.cbegin())
{
default:
case 0: // HL-Steampipe
ServerDLL::GetInstance().pEngfuncs = *reinterpret_cast<enginefuncs_t**>(reinterpret_cast<uintptr_t>(LoadThisDll) + 95);
ppGlobals = *reinterpret_cast<globalvars_t**>(reinterpret_cast<uintptr_t>(LoadThisDll) + 90);
ServerDLL::GetInstance().pEngfuncs = *reinterpret_cast<enginefuncs_t**>(reinterpret_cast<uintptr_t>(ORIG_LoadThisDll) + 95);
ppGlobals = *reinterpret_cast<globalvars_t**>(reinterpret_cast<uintptr_t>(ORIG_LoadThisDll) + 90);
break;
case 1: // HL-4554
ServerDLL::GetInstance().pEngfuncs = *reinterpret_cast<enginefuncs_t**>(reinterpret_cast<uintptr_t>(LoadThisDll) + 91);
ppGlobals = *reinterpret_cast<globalvars_t**>(reinterpret_cast<uintptr_t>(LoadThisDll) + 86);
ServerDLL::GetInstance().pEngfuncs = *reinterpret_cast<enginefuncs_t**>(reinterpret_cast<uintptr_t>(ORIG_LoadThisDll) + 91);
ppGlobals = *reinterpret_cast<globalvars_t**>(reinterpret_cast<uintptr_t>(ORIG_LoadThisDll) + 86);
break;
case 2: // HL-WON-1712
ServerDLL::GetInstance().pEngfuncs = *reinterpret_cast<enginefuncs_t**>(reinterpret_cast<uintptr_t>(LoadThisDll) + 89);
ppGlobals = *reinterpret_cast<globalvars_t**>(reinterpret_cast<uintptr_t>(LoadThisDll) + 84);
ServerDLL::GetInstance().pEngfuncs = *reinterpret_cast<enginefuncs_t**>(reinterpret_cast<uintptr_t>(ORIG_LoadThisDll) + 89);
ppGlobals = *reinterpret_cast<globalvars_t**>(reinterpret_cast<uintptr_t>(ORIG_LoadThisDll) + 84);
break;
case 3: // CoF-5936
ServerDLL::GetInstance().pEngfuncs = *reinterpret_cast<enginefuncs_t**>(reinterpret_cast<uintptr_t>(LoadThisDll) + 118);
Expand Down Expand Up @@ -2076,8 +2094,8 @@ void HwDLL::FindStuff()

{
auto pattern = fLoadThisDll.get();
if (LoadThisDll) {
EngineDevMsg("[hw dll] Found LoadThisDll at %p (using the %s pattern).\n", LoadThisDll, pattern->name());
if (ORIG_LoadThisDll) {
EngineDevMsg("[hw dll] Found LoadThisDll at %p (using the %s pattern).\n", ORIG_LoadThisDll, pattern->name());
EngineDevMsg("[hw dll] Found g_engfuncsExportedToDlls at %p.\n", ServerDLL::GetInstance().pEngfuncs);
EngineDevMsg("[hw dll] Found gGlobalVariables at %p.\n", ppGlobals);
}
Expand Down Expand Up @@ -2419,7 +2437,8 @@ void HwDLL::FindStuff()
GET_FUTURE(ReleaseEntityDlls);
GET_FUTURE(ValidStuffText);
GET_FUTURE(CL_ReadDemoMessage_OLD);
GET_FUTURE(NLoadBlobFileClient)
GET_FUTURE(NLoadBlobFileClient);
GET_FUTURE(LoadThisDll)

if (oldEngine) {
GET_FUTURE(LoadAndDecryptHwDLL);
Expand Down Expand Up @@ -8053,3 +8072,69 @@ HOOK_DEF_0(HwDLL, qboolean, __cdecl, CL_ReadDemoMessage_OLD)

return rv;
}

void SwapMetamodDll(char* current_dll_path, const char* new_dll_path) {
const std::string filename = std::string(current_dll_path);
const auto addons_index = filename.find("addons");
auto new_path = filename.substr(0, addons_index) + new_dll_path;

strcpy(current_dll_path, new_path.c_str());
}

HOOK_DEF_1(HwDLL, void, __fastcall, LoadThisDll, char*, szDllFilename)
{
// error: ‘const std::string’ {aka ‘const class std::__cxx11::basic_string<char>’} has no member named ‘ends_with’
// :smiley:
if (boost::ends_with(szDllFilename, "metamod.dll")) {
auto &cl = ClientDLL::GetInstance();
static bool is_cstrike = cl.DoesGameDirMatch("cstrike");

EngineDevMsg("[hw dll] AmxModX detected.\n");

if (is_cstrike) {
static const char *cs_windows = "dlls/mp.dll";

SwapMetamodDll(szDllFilename, cs_windows);
EngineDevMsg("[hw dll] Current mod is cstrike. AmxModX is disabled.\n");
} else {
EngineWarning("[hw dll] Cannot disable AmdModX for current mod. Edit <mod>/liblist.gam to continue.\n");

if (ORIG_Host_Shutdown)
ORIG_Host_Shutdown();
else
exit(-1);
}

}

ORIG_LoadThisDll(szDllFilename);
}

HOOK_DEF_1(HwDLL, void, __cdecl, LoadThisDll_Linux, char*, szDllFilename)
{
// error: ‘const std::string’ {aka ‘const class std::__cxx11::basic_string<char>’} has no member named ‘ends_with’
// :smiley:
if (boost::ends_with(szDllFilename, "metamod.so")) {
auto &cl = ClientDLL::GetInstance();
static bool is_cstrike = cl.DoesGameDirMatch("cstrike");

EngineDevMsg("[hw dll] AmxModX detected.\n");

if (is_cstrike) {
static const char *cs_linux = "dlls/cs.so";

SwapMetamodDll(szDllFilename, cs_linux);
EngineDevMsg("[hw dll] Current mod is cstrike. AmxModX is disabled.\n");
} else {
EngineWarning("[hw dll] Cannot disable AmdModX for current mod. Edit <mod>/liblist.gam to continue.\n");

if (ORIG_Host_Shutdown)
ORIG_Host_Shutdown();
else
exit(-1);
}

}

ORIG_LoadThisDll_Linux(szDllFilename);
}
2 changes: 2 additions & 0 deletions BunnymodXT/modules/HwDLL.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class HwDLL : public IHookableNameFilterOrdered
HOOK_DECL(void, __cdecl, ReleaseEntityDlls)
HOOK_DECL(qboolean, __cdecl, ValidStuffText, char* buf)
HOOK_DECL(qboolean, __cdecl, CL_ReadDemoMessage_OLD)
HOOK_DECL(void, __fastcall, LoadThisDll, char* szDllFilename)
HOOK_DECL(void, __cdecl, LoadThisDll_Linux, char* szDllFilename)

struct cmdbuf_t
{
Expand Down

0 comments on commit 5a5e059

Please sign in to comment.