diff --git a/public/CDetour/detourhelpers.h b/public/CDetour/detourhelpers.h deleted file mode 100644 index 9c9bd2de4..000000000 --- a/public/CDetour/detourhelpers.h +++ /dev/null @@ -1,147 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id: detourhelpers.h 248 2008-08-27 00:56:22Z pred $ - */ - -#ifndef _INCLUDE_SOURCEMOD_DETOURHELPERS_H_ -#define _INCLUDE_SOURCEMOD_DETOURHELPERS_H_ - -#if defined PLATFORM_POSIX -#include -#define PAGE_EXECUTE_READWRITE PROT_READ|PROT_WRITE|PROT_EXEC -#endif - -#include -#include -#include -#include - -struct patch_t -{ - patch_t() - { - patch[0] = 0; - bytes = 0; - } - unsigned char patch[20]; - size_t bytes; -}; - -inline void ProtectMemory(void *addr, int length, int prot) -{ - char error[256]; -#if defined PLATFORM_POSIX - long pageSize = sysconf(_SC_PAGESIZE); - void *startPage = ke::AlignedBase(addr, pageSize); - void *endPage = ke::AlignedBase((void *)((intptr_t)addr + length), pageSize); - if (mprotect(startPage, ((intptr_t)endPage - (intptr_t)startPage) + pageSize, prot) == -1) { - ke::FormatSystemError(error, sizeof(error)); - fprintf(stderr, "mprotect: %s\n", error); - } -#elif defined PLATFORM_WINDOWS - DWORD old_prot; - if (!VirtualProtect(addr, length, prot, &old_prot)) { - ke::FormatSystemError(error, sizeof(error)); - fprintf(stderr, "VirtualProtect: %s\n", error); - } -#endif -} - -inline void SetMemPatchable(void *address, size_t size) -{ - ProtectMemory(address, (int)size, PAGE_EXECUTE_READWRITE); -} - -inline void PatchRelJump32(unsigned char *target, void *callback) -{ - SetMemPatchable(target, 5); - - // jmp <32-bit displacement> - target[0] = IA32_JMP_IMM32; - *(int32_t *)(&target[1]) = int32_t((unsigned char *)callback - (target + 5)); -} - -inline void PatchAbsJump64(unsigned char *target, void *callback) -{ - int i = 0; - SetMemPatchable(target, 14); - - // push ; allocates 64-bit stack space on x64 - // mov [rsp+4], ; unnecessary if upper bits are 0 - // ret ; jump to address on stack - target[i++] = IA32_PUSH_IMM32; - *(int32_t *)(&target[i]) = int32_t(int64_t(callback)); - i += 4; - if ((int64_t(callback) >> 32) != 0) - { - target[i++] = IA32_MOV_RM_IMM32; - target[i++] = ia32_modrm(MOD_DISP8, 0, kREG_SIB); - target[i++] = ia32_sib(NOSCALE, kREG_NOIDX, kREG_ESP); - target[i++] = 0x04; - *(int32_t *)(&target[i]) = (int64_t(callback) >> 32); - i += 4; - } - target[i] = IA32_RET; -} - -inline void DoGatePatch(unsigned char *target, void *callback) -{ -#if defined(_WIN64) || defined(__x86_64__) - int64_t diff = int64_t(callback) - (int64_t(target) + 5); - int32_t upperBits = (diff >> 32); - if (upperBits == 0 || upperBits == -1) - PatchRelJump32(target, callback); - else - PatchAbsJump64(target, callback); -#else - PatchRelJump32(target, callback); -#endif -} - -inline void ApplyPatch(void *address, int offset, const patch_t *patch, patch_t *restore) -{ - unsigned char *addr = (unsigned char *)address + offset; - SetMemPatchable(addr, patch->bytes); - - if (restore) - { - for (size_t i=0; ibytes; i++) - { - restore->patch[i] = addr[i]; - } - restore->bytes = patch->bytes; - } - - for (size_t i=0; ibytes; i++) - { - addr[i] = patch->patch[i]; - } -} - -#endif //_INCLUDE_SOURCEMOD_DETOURHELPERS_H_ diff --git a/public/CDetour/detours.cpp b/public/CDetour/detours.cpp deleted file mode 100644 index 0fe27c721..000000000 --- a/public/CDetour/detours.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include "detours.h" -#include - -ISourcePawnEngine *CDetourManager::spengine = NULL; -IGameConfig *CDetourManager::gameconf = NULL; - -void CDetourManager::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf) -{ - CDetourManager::spengine = spengine; - CDetourManager::gameconf = gameconf; -} - -CDetour *CDetourManager::CreateDetour(void *callbackfunction, void **trampoline, const char *signame) -{ - void* pAddress; - if (!gameconf->GetMemSig(signame, &pAddress)) - { - g_pSM->LogError(myself, "Signature for %s not found in gamedata", signame); - return NULL; - } - - if (!pAddress) - { - g_pSM->LogError(myself, "Sigscan for %s failed", signame); - return NULL; - } - - return CreateDetour(callbackfunction, trampoline, pAddress); -} - -CDetour *CDetourManager::CreateDetour(void *callbackFunction, void **trampoline, void *pAddress) -{ - CDetour* detour = new CDetour(callbackFunction, trampoline, pAddress); - - auto result = safetyhook::InlineHook::create(pAddress, callbackFunction, safetyhook::InlineHook::Flags::StartDisabled); - if(result) - { - detour->m_hook = std::move(result.value()); - *trampoline = detour->m_hook.original(); - } - else - { - auto err = result.error(); - switch(err.type) - { - case safetyhook::InlineHook::Error::BAD_ALLOCATION: - if(err.allocator_error == safetyhook::Allocator::Error::BAD_VIRTUAL_ALLOC) - { - g_pSM->LogError(myself, "BAD_VIRTUAL_ALLOC hook %p", pAddress); - } - else if(err.allocator_error == safetyhook::Allocator::Error::NO_MEMORY_IN_RANGE) - { - g_pSM->LogError(myself, "NO_MEMORY_IN_RANGE hook %p", pAddress); - } - else - { - g_pSM->LogError(myself, "BAD_ALLOCATION hook %p errnum %i", pAddress, err.allocator_error); - } - break; - case safetyhook::InlineHook::Error::FAILED_TO_DECODE_INSTRUCTION: - g_pSM->LogError(myself, "FAILED_TO_DECODE_INSTRUCTION hook %p ip %p", pAddress, err.ip); - break; - case safetyhook::InlineHook::Error::SHORT_JUMP_IN_TRAMPOLINE: - g_pSM->LogError(myself, "SHORT_JUMP_IN_TRAMPOLINE hook %p ip %p", pAddress, err.ip); - break; - case safetyhook::InlineHook::Error::IP_RELATIVE_INSTRUCTION_OUT_OF_RANGE: - g_pSM->LogError(myself, "IP_RELATIVE_INSTRUCTION_OUT_OF_RANGE hook %p ip %p", pAddress, err.ip); - break; - case safetyhook::InlineHook::Error::UNSUPPORTED_INSTRUCTION_IN_TRAMPOLINE: - g_pSM->LogError(myself, "UNSUPPORTED_INSTRUCTION_IN_TRAMPOLINE hook %p ip %p", pAddress, err.ip); - break; - case safetyhook::InlineHook::Error::FAILED_TO_UNPROTECT: - g_pSM->LogError(myself, "FAILED_TO_UNPROTECT hook %p ip %p", pAddress, err.ip); - break; - case safetyhook::InlineHook::Error::NOT_ENOUGH_SPACE: - g_pSM->LogError(myself, "NOT_ENOUGH_SPACE hook %p ip %p", pAddress, err.ip); - break; - default: - g_pSM->LogError(myself, "Unknown error %i hook %p ip %p", err.type, pAddress, err.ip); - break; - } - - delete detour; - return NULL; - } - - return detour; -} - -CDetour::CDetour(void* callbackFunction, void **trampoline, void *pAddress) -{ -} - -bool CDetour::IsEnabled() -{ - return m_hook.enabled(); -} - -void CDetour::EnableDetour() -{ - m_hook.enable(); -} - -void CDetour::DisableDetour() -{ - m_hook.disable(); -} - -void CDetour::Destroy() -{ - delete this; -} \ No newline at end of file diff --git a/public/CDetour/detours.h b/public/CDetour/detours.h deleted file mode 100644 index 43e16e245..000000000 --- a/public/CDetour/detours.h +++ /dev/null @@ -1,273 +0,0 @@ -/** -* vim: set ts=4 : -* ============================================================================= -* SourceMod -* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved. -* ============================================================================= -* -* This program is free software; you can redistribute it and/or modify it under -* the terms of the GNU General Public License, version 3.0, as published by the -* Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -* details. -* -* You should have received a copy of the GNU General Public License along with -* this program. If not, see . -* -* As a special exception, AlliedModders LLC gives you permission to link the -* code of this program (as well as its derivative works) to "Half-Life 2," the -* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software -* by the Valve Corporation. You must obey the GNU General Public License in -* all respects for all other code used. Additionally, AlliedModders LLC grants -* this exception to all derivative works. AlliedModders LLC defines further -* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), -* or . -* -* Version: $Id: detours.h 257 2008-09-23 03:12:13Z pred $ -*/ - -#ifndef _INCLUDE_SOURCEMOD_DETOURS_H_ -#define _INCLUDE_SOURCEMOD_DETOURS_H_ - -#include "safetyhook.hpp" -#include - -#define DETOUR_MEMBER_CALL(name) (this->*name##_Actual) -#define DETOUR_STATIC_CALL(name) (name##_Actual) - -#define DETOUR_DECL_STATIC0(name, ret) \ -ret (*name##_Actual)(void) = NULL; \ -ret name(void) - -#define DETOUR_DECL_STATIC1(name, ret, p1type, p1name) \ -ret (*name##_Actual)(p1type) = NULL; \ -ret name(p1type p1name) - -#define DETOUR_DECL_STATIC2(name, ret, p1type, p1name, p2type, p2name) \ -ret (*name##_Actual)(p1type, p2type) = NULL; \ -ret name(p1type p1name, p2type p2name) - -#define DETOUR_DECL_STATIC3(name, ret, p1type, p1name, p2type, p2name, p3type, p3name) \ -ret (*name##_Actual)(p1type, p2type, p3type) = NULL; \ -ret name(p1type p1name, p2type p2name, p3type p3name) - -#define DETOUR_DECL_STATIC4(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name) \ -ret (*name##_Actual)(p1type, p2type, p3type, p4type) = NULL; \ -ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name) - -#define DETOUR_DECL_STATIC5(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name) \ -ret (*name##_Actual)(p1type, p2type, p3type, p4type, p5type) = NULL; \ -ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name) - -#define DETOUR_DECL_STATIC6(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name) \ -ret (*name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type) = NULL; \ -ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name) - -#define DETOUR_DECL_STATIC7(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name, p7type, p7name) \ -ret (*name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type) = NULL; \ -ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name) - -#define DETOUR_DECL_STATIC8(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name, p7type, p7name, p8type, p8name) \ -ret (*name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type, p8type) = NULL; \ -ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name, p8type p8name) - -#define DETOUR_DECL_MEMBER0(name, ret) \ -class name##Class \ -{ \ -public: \ - ret name(); \ - static ret (name##Class::* name##_Actual)(void); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(void) = NULL; \ -ret name##Class::name() - -#define DETOUR_DECL_MEMBER1(name, ret, p1type, p1name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name); \ - static ret (name##Class::* name##_Actual)(p1type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type) = NULL; \ -ret name##Class::name(p1type p1name) - -#define DETOUR_DECL_MEMBER2(name, ret, p1type, p1name, p2type, p2name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name) - -#define DETOUR_DECL_MEMBER3(name, ret, p1type, p1name, p2type, p2name, p3type, p3name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name, p3type p3name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type, p3type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name, p3type p3name) - -#define DETOUR_DECL_MEMBER4(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name) - -#define DETOUR_DECL_MEMBER5(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type, p5type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type, p5type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name) - -#define DETOUR_DECL_MEMBER6(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name) - -#define DETOUR_DECL_MEMBER7(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name, p7type, p7name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name) - -#define DETOUR_DECL_MEMBER8(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name, p7type, p7name, p8type, p8name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name, p8type p8name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type, p8type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type, p7type, p8type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name, p7type p7name, p8type p8name) - - -#define GET_MEMBER_CALLBACK(name) (void *)GetCodeAddress(&name##Class::name) -#define GET_MEMBER_TRAMPOLINE(name) (void **)(&name##Class::name##_Actual) - -#define GET_STATIC_CALLBACK(name) (void *)&name -#define GET_STATIC_TRAMPOLINE(name) (void **)&name##_Actual - -#define DETOUR_CREATE_MEMBER(name, gamedata) CDetourManager::CreateDetour(GET_MEMBER_CALLBACK(name), GET_MEMBER_TRAMPOLINE(name), gamedata); -#define DETOUR_CREATE_STATIC(name, gamedata) CDetourManager::CreateDetour(GET_STATIC_CALLBACK(name), GET_STATIC_TRAMPOLINE(name), gamedata); - - -class GenericClass {}; -typedef void (GenericClass::*VoidFunc)(); - -inline void *GetCodeAddr(VoidFunc mfp) -{ - return *(void **)&mfp; -} - -/** - * Converts a member function pointer to a void pointer. - * This relies on the assumption that the code address lies at mfp+0 - * This is the case for both g++ and later MSVC versions on non virtual functions but may be different for other compilers - * Based on research by Don Clugston : http://www.codeproject.com/cpp/FastDelegate.asp - */ -#define GetCodeAddress(mfp) GetCodeAddr(reinterpret_cast(mfp)) - -class CDetourManager; - -class CDetour -{ -public: - - bool IsEnabled(); - - /** - * These would be somewhat self-explanatory I hope - */ - void EnableDetour(); - void DisableDetour(); - - void Destroy(); - - friend class CDetourManager; - -protected: - CDetour(void*callbackfunction, void **trampoline, void *pAddress); -private: - SafetyHookInline m_hook{}; -}; - -class CDetourManager -{ -public: - - static void Init(ISourcePawnEngine *spengine, IGameConfig *gameconf); - - /** - * Creates a new detour - * - * @param callbackfunction Void pointer to your detour callback function. - * @param trampoline Address of the trampoline pointer - * @param signame Section name containing a signature to fetch from the gamedata file. - * @return A new CDetour pointer to control your detour. - * - * Example: - * - * CBaseServer::ConnectClient(netadr_s &, int, int, int, char const*, char const*, char const*, int) - * - * Define a new class with the required function and a member function pointer to the same type: - * - * class CBaseServerDetour - * { - * public: - * bool ConnectClient(void *netaddr_s, int, int, int, char const*, char const*, char const*, int); - * static bool (CBaseServerDetour::* ConnectClient_Actual)(void *netaddr_s, int, int, int, char const*, char const*, char const*, int); - * } - * - * void *callbackfunc = GetCodeAddress(&CBaseServerDetour::ConnectClient); - * void **trampoline = (void **)(&CBaseServerDetour::ConnectClient_Actual); - * - * Creation: - * CDetourManager::CreateDetour(callbackfunc, trampoline, "ConnectClient"); - * - * Usage: - * - * CBaseServerDetour::ConnectClient(void *netaddr_s, int, int, int, char const*, char const*, char const*, int) - * { - * //pre hook code - * bool result = (this->*ConnectClient_Actual)(netaddr_s, rest of params); - * //post hook code - * return result; - * } - * - * Note we changed the netadr_s reference into a void* to avoid needing to define the type - */ - static CDetour *CreateDetour(void *callbackFunction, void **trampoline, const char *signame); - static CDetour *CreateDetour(void *callbackFunction, void **trampoline, void *pAddress); - - friend class CDetour; - -private: - static ISourcePawnEngine *spengine; - static IGameConfig *gameconf; -}; - -#endif // _INCLUDE_SOURCEMOD_DETOURS_H_ \ No newline at end of file