From f1e206fde65652937bcadddf9b7e51808d5d1ff3 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Sun, 1 Jun 2014 19:00:37 +0200 Subject: [PATCH] Cstrike: Refactor code to seperate detours for readability/maintainability + Fix OSX symbols. --- dlls/cstrike/cstrike/CstrikeDatas.h | 35 ++++++----- dlls/cstrike/cstrike/CstrikeHacks.cpp | 90 +++++++++++---------------- dlls/cstrike/cstrike/CstrikeUtils.cpp | 60 ++++++++++++++++++ dlls/cstrike/cstrike/CstrikeUtils.h | 1 + 4 files changed, 116 insertions(+), 70 deletions(-) diff --git a/dlls/cstrike/cstrike/CstrikeDatas.h b/dlls/cstrike/cstrike/CstrikeDatas.h index c7813928..168ce307 100644 --- a/dlls/cstrike/cstrike/CstrikeDatas.h +++ b/dlls/cstrike/cstrike/CstrikeDatas.h @@ -145,14 +145,16 @@ #define OFFSET_HOSTAGEID 516 + EXTRAOFFSET // +29 #endif -#if defined __linux__ +#if defined(__linux__) #define CS_DETOURCOPYBYTES_CLIENTCOMMAND 6 - #define CS_SYM_USEBOTARGS "UseBotArgs" - #define CS_SYM_BOTARGS "BotArgs" -#elif defined __APPLE__ + #define CS_IDENT_USEBOTARGS "UseBotArgs" + #define CS_IDENT_BOTARGS "BotArgs" + #define CS_IDENT_HIDDEN_STATE false +#elif defined(__APPLE__) #define CS_DETOURCOPYBYTES_CLIENTCOMMAND 5 - #define CS_SYM_USEBOTARGS "UseBotArgs" - #define CS_SYM_BOTARGS "BotArgs" + #define CS_IDENT_USEBOTARGS "UseBotArgs" + #define CS_IDENT_BOTARGS "BotArgs" + #define CS_IDENT_HIDDEN_STATE true #else #define CS_DETOURCOPYBYTES_CLIENTCOMMAND 6 #define CS_CLICMD_OFFS_USEBOTARGS 2 @@ -163,17 +165,20 @@ * CS_OnBuy forward */ #if defined(__linux__) - #define CS_SYM_CANBUYTHIS "_Z10CanBuyThisP11CBasePlayeri" - #define CS_SYM_BUYITEM "_Z7BuyItemP11CBasePlayeri" - #define CS_SYM_BUYGUNAMMO "_Z10BuyGunAmmoR11CBasePlayerR15CBasePlayerItemb" + #define CS_IDENT_CANBUYTHIS "_Z10CanBuyThisP11CBasePlayeri" + #define CS_IDENT_BUYITEM "_Z7BuyItemP11CBasePlayeri" + #define CS_IDENT_BUYGUNAMMO "_Z10BuyGunAmmoR11CBasePlayerR15CBasePlayerItemb" + #define CS_IDENT_HIDDEN_STATE false #elif defined(__APPLE__) - #define CS_SYM_CANBUYTHIS "__Z10CanBuyThisP11CBasePlayeri" - #define CS_SYM_BUYITEM "__Z7BuyItemP11CBasePlayeri" - #define CS_SYM_BUYGUNAMMO "__Z10BuyGunAmmoR11CBasePlayerR15CBasePlayerItemb" + #define CS_IDENT_CANBUYTHIS "_Z10CanBuyThisP11CBasePlayeri" + #define CS_IDENT_BUYITEM "_Z7BuyItemP11CBasePlayeri" + #define CS_IDENT_BUYGUNAMMO "_Z10BuyGunAmmoR11CBasePlayerR15CBasePlayerItemb" + #define CS_IDENT_HIDDEN_STATE true #elif defined(WIN32) - #define CS_SIG_CANBUYTHIS "\x53\x8B\x2A\x2A\x2A\x2A\x2A\x56\x8B\x2A\x2A\x2A\x57" - #define CS_SIG_BUYITEM "\x53\x56\x8B\x2A\x2A\x2A\xBB\x2A\x2A\x2A\x2A\x57\x53" - #define CS_SIG_BUYGUNAMMO "\x56\x57\x8B\x2A\x2A\x2A\x6A\x2A\x8B\x2A\xE8\x2A\x2A\x2A\x2A\x84\x2A\x0F" + #define CS_IDENT_CANBUYTHIS "\\x53\\x8B\\x2A\\x2A\\x2A\\x2A\\x2A\\x56\\x8B\\x2A\\x2A\\x2A\\x57" + #define CS_IDENT_BUYITEM "\\x53\\x56\\x8B\\x2A\\x2A\\x2A\\xBB\\x2A\\x2A\\x2A\\x2A\\x57\\x53" + #define CS_IDENT_BUYGUNAMMO "\\x56\\x57\\x8B\\x2A\\x2A\\x2A\\x6A\\x2A\\x8B\\x2A\\xE8\\x2A\\x2A\\x2A\\x2A\\x84\\x2A\\x0F" + #define CS_IDENT_HIDDEN_STATE false #endif #define CSI_P228 CSW_P228 diff --git a/dlls/cstrike/cstrike/CstrikeHacks.cpp b/dlls/cstrike/cstrike/CstrikeHacks.cpp index 70eadc23..0794a239 100644 --- a/dlls/cstrike/cstrike/CstrikeHacks.cpp +++ b/dlls/cstrike/cstrike/CstrikeHacks.cpp @@ -32,14 +32,10 @@ */ #include "CstrikeDatas.h" #include "CstrikeUtils.h" -#include #include "CDetour/detours.h" -#if defined(__APPLE__) - #include -#endif - -void CtrlDetours(bool set); +void CtrlDetours_ClientCommand(bool set); +void CtrlDetours_BuyCommands(bool set); int g_CSCliCmdFwd = -1; int g_CSBuyCmdFwd = -1; @@ -55,12 +51,18 @@ CDetour *g_BuyGunAmmoDetour = NULL; void InitializeHacks() { - CtrlDetours(true); +#if defined AMD64 + #error UNSUPPORTED +#endif + + CtrlDetours_ClientCommand(true); + CtrlDetours_BuyCommands(true); } void ShutdownHacks() { - CtrlDetours(false); + CtrlDetours_ClientCommand(false); + CtrlDetours_BuyCommands(false); } @@ -136,68 +138,47 @@ DETOUR_DECL_STATIC3(BuyGunAmmo, bool, void*, pvPlayer, void*, pvWeapon, bool, bB } -void CtrlDetours(bool set) +void CtrlDetours_ClientCommand(bool set) { -#if defined AMD64 - #error UNSUPPORTED -#endif - if (set) { - char libName[256]; - uintptr_t base; - void *target = (void *)MDLL_ClientCommand; - - if (!g_MemUtils.GetLibraryOfAddress(target, libName, sizeof(libName), &base)) - { - return; - } - - void *canBuyThisAddress = NULL; - void *buyItemAddress = NULL; - void *buyGunAmmoAddress = NULL; #if defined(WIN32) - canBuyThisAddress = g_MemUtils.DecodeAndFindPattern(target, CS_SIG_CANBUYTHIS); - buyItemAddress = g_MemUtils.DecodeAndFindPattern(target, CS_SIG_BUYITEM); - buyGunAmmoAddress = g_MemUtils.DecodeAndFindPattern(target, CS_SIG_BUYGUNAMMO); - g_UseBotArgs = *(int **)((unsigned char *)target + CS_CLICMD_OFFS_USEBOTARGS); g_BotArgs = (const char **)*(const char **)((unsigned char *)target + CS_CLICMD_OFFS_BOTARGS); #elif defined(__linux__) || defined(__APPLE__) - Dl_info info; - void *handle = NULL; - - if (dladdr(target, &info) == 0) || (handle = dlopen(info.dli_fname, RTLD_NOW)) == NULL) - { - return; - } - - canBuyThisAddress = g_MemUtils.ResolveSymbol(handle, CS_SYM_CANBUYTHIS); - buyItemAddress = g_MemUtils.ResolveSymbol(handle, CS_SYM_BUYITEM); - buyGunAmmoAddress = g_MemUtils.ResolveSymbol(handle, CS_SYM_BUYGUNAMMO); - - g_UseBotArgs = (int *)g_MemUtils.ResolveSymbol(handle, CS_SYM_USEBOTARGS); - g_BotArgs = (const char **)g_MemUtils.ResolveSymbol(handle, CS_SYM_BOTARGS); - - dlclose(handle); + g_UseBotArgs = (int *)UTIL_FindAddressFromEntry(CS_IDENT_USEBOTARGS, CS_IDENT_HIDDEN_STATE); + g_BotArgs = (const char **)UTIL_FindAddressFromEntry(CS_IDENT_BOTARGS, CS_IDENT_HIDDEN_STATE); #endif - g_ClientCommandDetour = DETOUR_CREATE_STATIC_FIXED(C_ClientCommand, target); - g_CanBuyThisDetour = DETOUR_CREATE_STATIC_FIXED(CanBuyThis, canBuyThisAddress); - g_BuyItemDetour = DETOUR_CREATE_STATIC_FIXED(BuyItem, buyItemAddress); - g_BuyGunAmmoDetour = DETOUR_CREATE_STATIC_FIXED(BuyGunAmmo, buyGunAmmoAddress); - + g_ClientCommandDetour = DETOUR_CREATE_STATIC_FIXED(C_ClientCommand, target); + if (g_ClientCommandDetour != NULL) g_ClientCommandDetour->EnableDetour(); else - { - MF_Log("No Client Commands detours could be initialized - Disabled Client Command forward."); - } + MF_Log("No Client Commands detour could be initialized - Disabled Client Command forward."); + } + else + { + g_ClientCommandDetour->Destroy(); + } +} + +void CtrlDetours_BuyCommands(bool set) +{ + if (set) + { + void *canBuyThisAddress = UTIL_FindAddressFromEntry(CS_IDENT_CANBUYTHIS, CS_IDENT_HIDDEN_STATE); + void *buyItemAddress = UTIL_FindAddressFromEntry(CS_IDENT_BUYITEM, CS_IDENT_HIDDEN_STATE); + void *buyGunAmmoAddress = UTIL_FindAddressFromEntry(CS_IDENT_BUYGUNAMMO, CS_IDENT_HIDDEN_STATE); + + g_CanBuyThisDetour = DETOUR_CREATE_STATIC_FIXED(CanBuyThis, canBuyThisAddress); + g_BuyItemDetour = DETOUR_CREATE_STATIC_FIXED(BuyItem, buyItemAddress); + g_BuyGunAmmoDetour = DETOUR_CREATE_STATIC_FIXED(BuyGunAmmo, buyGunAmmoAddress); if (g_CanBuyThisDetour != NULL && g_BuyItemDetour != NULL && g_BuyGunAmmoDetour != NULL) { @@ -212,9 +193,8 @@ void CtrlDetours(bool set) } else { - g_CanBuyThisDetour->Destroy(); g_BuyItemDetour->Destroy(); g_BuyGunAmmoDetour->Destroy(); g_ClientCommandDetour->Destroy(); } -} +} \ No newline at end of file diff --git a/dlls/cstrike/cstrike/CstrikeUtils.cpp b/dlls/cstrike/cstrike/CstrikeUtils.cpp index 3f8de77f..70218fe4 100644 --- a/dlls/cstrike/cstrike/CstrikeUtils.cpp +++ b/dlls/cstrike/cstrike/CstrikeUtils.cpp @@ -31,6 +31,7 @@ * version. */ #include "amxxmodule.h" +#include "MemoryUtils.h" bool UTIL_IsPlayer(AMX* amx, edict_t* pPlayer) { @@ -59,4 +60,63 @@ void UTIL_TextMsg_Generic(edict_t* pPlayer, const char* message) #define HUD_PRINTRADIO 5 However both 1 and 2 seems to go to console with Steam CS. */ +} + +void *UTIL_FindAddressFromEntry(const char *entry, bool isHidden, const char *library) +{ + void *addressInBase = NULL; + void *finalAddress; + + if (strcmp(library, "mod") == 0) + { + addressInBase = (void *)MDLL_Spawn; + } + else if (strcmp(library, "engine") == 0) + { + addressInBase = (void *)gpGlobals; + } + + finalAddress = NULL; + + if (*entry != '\\') + { +#if defined(WIN32) + + MEMORY_BASIC_INFORMATION mem; + + if (VirtualQuery(addressInBase, &mem, sizeof(mem))) + { + finalAddress = g_MemUtils.ResolveSymbol(mem.AllocationBase, entry); + } + +#elif defined(__linux__) || defined(__APPLE__) + + Dl_info info; + void *handle = NULL; + + if (dladdr(addressInBase, &info) != 0) + { + void *handle = dlopen(info.dli_fname, RTLD_NOW); + if (handle) + { + if (isHidden) + { + finalAddress = g_MemUtils.ResolveSymbol(handle, entry); + } + else + { + finalAddress = dlsym(handle, entry); + } + + dlclose(handle); + } + } +#endif + } + else + { + finalAddress = g_MemUtils.DecodeAndFindPattern(addressInBase, entry); + } + + return finalAddress != NULL ? finalAddress : NULL; } \ No newline at end of file diff --git a/dlls/cstrike/cstrike/CstrikeUtils.h b/dlls/cstrike/cstrike/CstrikeUtils.h index 6e60842b..443454ea 100644 --- a/dlls/cstrike/cstrike/CstrikeUtils.h +++ b/dlls/cstrike/cstrike/CstrikeUtils.h @@ -35,6 +35,7 @@ bool UTIL_IsPlayer(AMX* amx, edict_t* pPlayer); void UTIL_TextMsg_Generic(edict_t* pPlayer, const char* message); +void *UTIL_FindAddressFromEntry(const char *entry, bool isHidden = false, const char *library = "mod"); #define GETINFOKEYBUFFER (*g_engfuncs.pfnGetInfoKeyBuffer) #define SETCLIENTKEYVALUE (*g_engfuncs.pfnSetClientKeyValue)