CDetour safetyhook (#2162)
* Add safetyhook, remove libudis86 Co-authored-by: bottiger1 <55270538+bottiger1@users.noreply.github.com> * Add modified CDetour Co-authored-by: bottiger1 <55270538+bottiger1@users.noreply.github.com> * Add CDetour [Safetyhook] to build script * Re-enable loader/core/corelogic, and fix new C++20 error * Reenable all extensions (except dhooks) * Make cstrike compile against new CDetour * Remove unused variable in sdktools output? * Make sdktools compile against new cdetour * Downgrade to C++17 * remove auto * fix compilation on linux * Re-enable dhooks * Re-authorise old compilers * Fix invalid downgrade of std::optional * readd libudis86 for dhooks only --------- Co-authored-by: Kenzzer <kenzzer@users.noreply.github.com> Co-authored-by: bottiger1 <55270538+bottiger1@users.noreply.github.com>
This commit is contained in:
parent
e3734803f0
commit
e07c120cab
@ -520,6 +520,16 @@ class SMConfig(object):
|
||||
|
||||
return binary
|
||||
|
||||
def AddCDetour(self, binary):
|
||||
public_path = os.path.join(builder.sourcePath, 'public')
|
||||
binary.sources += [
|
||||
os.path.join(public_path, 'CDetour', 'detours.cpp'),
|
||||
os.path.join(public_path, 'safetyhook', 'safetyhook.cpp'),
|
||||
os.path.join(public_path, 'safetyhook', 'Zydis.c')
|
||||
]
|
||||
binary.compiler.cxxincludes += [ os.path.join(public_path, 'safetyhook') ]
|
||||
binary.compiler.includes += [ os.path.join(public_path, 'safetyhook') ]
|
||||
|
||||
def HL2Library(self, context, compiler, name, sdk):
|
||||
binary = self.Library(context, compiler, name)
|
||||
self.ConfigureForExtension(context, binary.compiler)
|
||||
|
@ -395,11 +395,6 @@ void CExtension::AddDependency(const IfaceInfo *pInfo)
|
||||
}
|
||||
}
|
||||
|
||||
bool operator ==(const IfaceInfo &i1, const IfaceInfo &i2)
|
||||
{
|
||||
return (i1.iface == i2.iface) && (i1.owner == i2.owner);
|
||||
}
|
||||
|
||||
void CExtension::AddChildDependent(CExtension *pOther, SMInterface *iface)
|
||||
{
|
||||
IfaceInfo info;
|
||||
|
@ -59,7 +59,7 @@ namespace SourceMod
|
||||
|
||||
struct IfaceInfo
|
||||
{
|
||||
bool operator ==(const IfaceInfo &info)
|
||||
bool operator ==(const IfaceInfo &info) const
|
||||
{
|
||||
return (info.iface == iface && info.owner == owner);
|
||||
}
|
||||
|
@ -9,15 +9,7 @@ project.sources += [
|
||||
'timeleft.cpp',
|
||||
'forwards.cpp',
|
||||
'util_cstrike.cpp',
|
||||
'../../public/smsdk_ext.cpp',
|
||||
'../../public/CDetour/detours.cpp',
|
||||
'../../public/asm/asm.c',
|
||||
'../../public/libudis86/decode.c',
|
||||
'../../public/libudis86/itab.c',
|
||||
'../../public/libudis86/syn-att.c',
|
||||
'../../public/libudis86/syn-intel.c',
|
||||
'../../public/libudis86/syn.c',
|
||||
'../../public/libudis86/udis86.c',
|
||||
'../../public/smsdk_ext.cpp'
|
||||
]
|
||||
|
||||
for sdk_name in ['css', 'csgo']:
|
||||
@ -34,6 +26,8 @@ for sdk_name in ['css', 'csgo']:
|
||||
|
||||
cxx.defines += ['HAVE_STRING_H']
|
||||
binary = SM.HL2ExtConfig(project, builder, cxx, 'game.cstrike.ext.' + sdk['extension'], sdk)
|
||||
SM.AddCDetour(binary)
|
||||
|
||||
if sdk_name == 'csgo':
|
||||
compiler = binary.compiler
|
||||
compiler.cxxincludes += [os.path.join(sdk['path'], 'public', 'steam')]
|
||||
|
@ -19,6 +19,7 @@ for cxx in builder.targets:
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(SM.mms_root, 'core'),
|
||||
os.path.join(SM.mms_root, 'core', 'sourcehook'),
|
||||
os.path.join(builder.sourcePath, 'extensions', 'dhooks'),
|
||||
os.path.join(builder.sourcePath, 'public', 'jit'),
|
||||
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
|
||||
os.path.join(builder.sourcePath, 'sourcepawn', 'include'),
|
||||
@ -27,6 +28,10 @@ for cxx in builder.targets:
|
||||
os.path.join(builder.sourcePath, 'extensions', 'dhooks', 'DynamicHooks'),
|
||||
]
|
||||
|
||||
binary.compiler.includes += [
|
||||
os.path.join(builder.sourcePath, 'extensions', 'dhooks')
|
||||
]
|
||||
|
||||
binary.sources += [
|
||||
'extension.cpp',
|
||||
'listeners.cpp',
|
||||
@ -36,13 +41,13 @@ for cxx in builder.targets:
|
||||
'util.cpp',
|
||||
'dynhooks_sourcepawn.cpp',
|
||||
'../../public/smsdk_ext.cpp',
|
||||
'../../public/asm/asm.c',
|
||||
'../../public/libudis86/decode.c',
|
||||
'../../public/libudis86/itab.c',
|
||||
'../../public/libudis86/syn-att.c',
|
||||
'../../public/libudis86/syn-intel.c',
|
||||
'../../public/libudis86/syn.c',
|
||||
'../../public/libudis86/udis86.c',
|
||||
'asm/asm.c',
|
||||
'libudis86/decode.c',
|
||||
'libudis86/itab.c',
|
||||
'libudis86/syn-att.c',
|
||||
'libudis86/syn-intel.c',
|
||||
'libudis86/syn.c',
|
||||
'libudis86/udis86.c',
|
||||
'../../sourcepawn/vm/x86/assembler-x86.cpp',
|
||||
]
|
||||
|
||||
|
@ -24,15 +24,7 @@ project.sources += [
|
||||
'hooks.cpp',
|
||||
'gamerulesnatives.cpp',
|
||||
'vstringtable.cpp',
|
||||
'../../public/smsdk_ext.cpp',
|
||||
'../../public/CDetour/detours.cpp',
|
||||
'../../public/asm/asm.c',
|
||||
'../../public/libudis86/decode.c',
|
||||
'../../public/libudis86/itab.c',
|
||||
'../../public/libudis86/syn-att.c',
|
||||
'../../public/libudis86/syn-intel.c',
|
||||
'../../public/libudis86/syn.c',
|
||||
'../../public/libudis86/udis86.c',
|
||||
'../../public/smsdk_ext.cpp'
|
||||
]
|
||||
|
||||
for sdk_name in SM.sdks:
|
||||
@ -45,18 +37,20 @@ for sdk_name in SM.sdks:
|
||||
continue
|
||||
|
||||
binary = SM.HL2ExtConfig(project, builder, cxx, 'sdktools.ext.' + sdk['extension'], sdk)
|
||||
SM.AddCDetour(binary)
|
||||
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(builder.sourcePath, 'public', 'jit'),
|
||||
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
|
||||
]
|
||||
|
||||
if sdk['name'] in ('episode1', 'darkm'):
|
||||
binary.compiler.cxxincludes += [os.path.join(builder.options.hl2sdk_root, sdk['path'], 'game_shared')]
|
||||
binary.compiler.cxxincludes += [os.path.join(builder.options.hl2sdk_root, sdk['path'], 'dlls')]
|
||||
binary.compiler.cxxincludes += [os.path.join(sdk['path'], 'game_shared')]
|
||||
binary.compiler.cxxincludes += [os.path.join(sdk['path'], 'dlls')]
|
||||
else:
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(builder.options.hl2sdk_root, sdk['path'], 'game', 'shared'),
|
||||
os.path.join(builder.options.hl2sdk_root, sdk['path'], 'game', 'server'),
|
||||
os.path.join(sdk['path'], 'game', 'shared'),
|
||||
os.path.join(sdk['path'], 'game', 'server'),
|
||||
]
|
||||
|
||||
#binary.sources += [os.path.join(builder.options.hl2sdk_root, sdk['path'], 'game', 'server', 'variant_t.cpp')]
|
||||
|
@ -128,7 +128,6 @@ private:
|
||||
|
||||
int HookCount;
|
||||
|
||||
patch_t info_restore;
|
||||
void *info_address;
|
||||
void *info_callback;
|
||||
};
|
||||
|
@ -8,6 +8,7 @@ if 'tf2' in SM.sdks:
|
||||
if not cxx.target.arch in sdk['platforms'][cxx.target.platform]:
|
||||
continue
|
||||
binary = SM.HL2Library(builder, cxx, 'game.tf2.ext.' + sdk['extension'], sdk)
|
||||
SM.AddCDetour(binary)
|
||||
binary.sources += [
|
||||
'extension.cpp',
|
||||
'natives.cpp',
|
||||
@ -18,15 +19,7 @@ if 'tf2' in SM.sdks:
|
||||
'teleporter.cpp',
|
||||
'gameplayrules.cpp',
|
||||
'conditions.cpp',
|
||||
'../../public/smsdk_ext.cpp',
|
||||
'../../public/CDetour/detours.cpp',
|
||||
'../../public/asm/asm.c',
|
||||
'../../public/libudis86/decode.c',
|
||||
'../../public/libudis86/itab.c',
|
||||
'../../public/libudis86/syn-att.c',
|
||||
'../../public/libudis86/syn-intel.c',
|
||||
'../../public/libudis86/syn.c',
|
||||
'../../public/libudis86/udis86.c',
|
||||
'../../public/smsdk_ext.cpp'
|
||||
]
|
||||
binary.compiler.defines += ['HAVE_STRING_H']
|
||||
SM.extensions += [builder.Add(binary)]
|
||||
|
@ -1,92 +1,9 @@
|
||||
/**
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id: detours.cpp 248 2008-08-27 00:56:22Z pred $
|
||||
*/
|
||||
|
||||
#include "detours.h"
|
||||
#include <asm/asm.h>
|
||||
#include <cstdio>
|
||||
|
||||
ISourcePawnEngine *CDetourManager::spengine = NULL;
|
||||
IGameConfig *CDetourManager::gameconf = NULL;
|
||||
|
||||
// Push 64-bit value onto the stack using two instructions.
|
||||
//
|
||||
// Pushing 0xF00DF00DF00DF00D:
|
||||
// push 0xF00DF00D
|
||||
// mov [rsp+4], 0xF00DF00D
|
||||
static inline void X64_Push_Imm64(JitWriter *jit, jit_int64_t val)
|
||||
{
|
||||
jit->write_ubyte(IA32_PUSH_IMM32);
|
||||
jit->write_int32(jit_int32_t(val));
|
||||
if ((val >> 32) != 0)
|
||||
IA32_Mov_ESP_Disp8_Imm32(jit, 4, (val >> 32));
|
||||
}
|
||||
|
||||
// Jump to absolute 64-bit address using multiple instructions.
|
||||
//
|
||||
// Jumping to address 0xF00DF00DF00DF00D:
|
||||
// push 0xF00DF00D
|
||||
// mov [rsp+4], 0xF00DF00D
|
||||
// ret
|
||||
static inline void X64_Jump_Abs(JitWriter *jit, void *dest)
|
||||
{
|
||||
X64_Push_Imm64(jit, jit_int64_t(dest));
|
||||
IA32_Return(jit);
|
||||
}
|
||||
|
||||
static inline void RelativeJump32(JitWriter *jit, void *target)
|
||||
{
|
||||
jitoffs_t call = IA32_Jump_Imm32(jit, 0);
|
||||
IA32_Write_Jump32_Abs(jit, call, target);
|
||||
}
|
||||
|
||||
#if defined(_WIN64) || defined(__x86_64__)
|
||||
static inline bool IsShortJump(JitWriter *jit, void *target)
|
||||
{
|
||||
int64_t diff = int64_t(target) - (int64_t(jit->outbase) + jit->get_outputpos() + OP_JMP_SIZE);
|
||||
int32_t upperBits = (diff >> 32);
|
||||
return upperBits == 0 || upperBits == -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void AbsJump(JitWriter *jit, void *target)
|
||||
{
|
||||
#if defined(_WIN64) || defined(__x86_64__)
|
||||
if (IsShortJump(jit, target))
|
||||
RelativeJump32(jit, target);
|
||||
else
|
||||
X64_Jump_Abs(jit, target);
|
||||
#else
|
||||
RelativeJump32(jit, target);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CDetourManager::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf)
|
||||
{
|
||||
CDetourManager::spengine = spengine;
|
||||
@ -95,196 +12,101 @@ void CDetourManager::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf)
|
||||
|
||||
CDetour *CDetourManager::CreateDetour(void *callbackfunction, void **trampoline, const char *signame)
|
||||
{
|
||||
CDetour *detour = new CDetour(callbackfunction, trampoline, signame);
|
||||
if (detour)
|
||||
void* pAddress;
|
||||
if (!gameconf->GetMemSig(signame, &pAddress))
|
||||
{
|
||||
if (!detour->Init(spengine, gameconf))
|
||||
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<void*>();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto err = result.error();
|
||||
switch(err.type)
|
||||
{
|
||||
delete detour;
|
||||
return NULL;
|
||||
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;
|
||||
}
|
||||
|
||||
return detour;
|
||||
|
||||
delete detour;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return detour;
|
||||
}
|
||||
|
||||
CDetour *CDetourManager::CreateDetour(void *callbackfunction, void **trampoline, void *pAddress)
|
||||
CDetour::CDetour(void* callbackFunction, void **trampoline, void *pAddress)
|
||||
{
|
||||
CDetour *detour = new CDetour(callbackfunction, trampoline, pAddress);
|
||||
if (detour)
|
||||
{
|
||||
if (!detour->Init(spengine, gameconf))
|
||||
{
|
||||
delete detour;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return detour;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CDetour::CDetour(void *callbackfunction, void **trampoline, const char *signame)
|
||||
{
|
||||
enabled = false;
|
||||
detoured = false;
|
||||
detour_address = NULL;
|
||||
detour_trampoline = NULL;
|
||||
this->signame = signame;
|
||||
this->detour_callback = callbackfunction;
|
||||
spengine = NULL;
|
||||
gameconf = NULL;
|
||||
this->trampoline = trampoline;
|
||||
}
|
||||
|
||||
CDetour::CDetour(void*callbackfunction, void **trampoline, void *pAddress)
|
||||
{
|
||||
enabled = false;
|
||||
detoured = false;
|
||||
detour_address = pAddress;
|
||||
detour_trampoline = NULL;
|
||||
this->signame = NULL;
|
||||
this->detour_callback = callbackfunction;
|
||||
spengine = NULL;
|
||||
gameconf = NULL;
|
||||
this->trampoline = trampoline;
|
||||
}
|
||||
|
||||
bool CDetour::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf)
|
||||
{
|
||||
this->spengine = spengine;
|
||||
this->gameconf = gameconf;
|
||||
|
||||
if (!CreateDetour())
|
||||
{
|
||||
enabled = false;
|
||||
return enabled;
|
||||
}
|
||||
|
||||
enabled = true;
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void CDetour::Destroy()
|
||||
{
|
||||
DeleteDetour();
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool CDetour::IsEnabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
bool CDetour::CreateDetour()
|
||||
{
|
||||
if (signame)
|
||||
{
|
||||
if (!gameconf->GetMemSig(signame, &detour_address))
|
||||
{
|
||||
g_pSM->LogError(myself, "Signature for %s not found in gamedata", signame);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!detour_address)
|
||||
{
|
||||
g_pSM->LogError(myself, "Sigscan for %s failed", signame);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!detour_address)
|
||||
{
|
||||
g_pSM->LogError(myself, "Invalid function address passed for detour");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(_WIN64) || defined(__x86_64__)
|
||||
int shortBytes = copy_bytes((unsigned char *)detour_address, NULL, OP_JMP_SIZE);
|
||||
detour_restore.bytes = copy_bytes((unsigned char *)detour_address, NULL, X64_ABS_SIZE);
|
||||
#else
|
||||
detour_restore.bytes = copy_bytes((unsigned char *)detour_address, NULL, OP_JMP_SIZE);
|
||||
#endif
|
||||
|
||||
JitWriter wr;
|
||||
JitWriter *jit = ≀
|
||||
jit_uint32_t CodeSize = 0;
|
||||
|
||||
wr.outbase = NULL;
|
||||
wr.outptr = NULL;
|
||||
|
||||
jit_rewind:
|
||||
|
||||
/* Patch old bytes in */
|
||||
if (wr.outbase != NULL)
|
||||
{
|
||||
#if defined(_WIN64) || defined(__x86_64__)
|
||||
wr.outptr += shortBytes;
|
||||
bool isShort = IsShortJump(jit, detour_address);
|
||||
wr.outptr -= shortBytes;
|
||||
if (isShort)
|
||||
detour_restore.bytes = shortBytes;
|
||||
#endif
|
||||
/* Save restore bits */
|
||||
memcpy(detour_restore.patch, detour_address, detour_restore.bytes);
|
||||
|
||||
copy_bytes((unsigned char *)detour_address, (unsigned char*)wr.outptr, detour_restore.bytes);
|
||||
}
|
||||
wr.outptr += detour_restore.bytes;
|
||||
|
||||
/* Return to the original function */
|
||||
AbsJump(jit, (unsigned char *)detour_address + detour_restore.bytes);
|
||||
|
||||
if (wr.outbase == NULL)
|
||||
{
|
||||
CodeSize = wr.get_outputpos();
|
||||
wr.outbase = (jitcode_t)spengine->AllocatePageMemory(CodeSize);
|
||||
spengine->SetReadWrite(wr.outbase);
|
||||
wr.outptr = wr.outbase;
|
||||
detour_trampoline = wr.outbase;
|
||||
goto jit_rewind;
|
||||
}
|
||||
|
||||
spengine->SetReadExecute(wr.outbase);
|
||||
|
||||
*trampoline = detour_trampoline;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDetour::DeleteDetour()
|
||||
{
|
||||
if (detoured)
|
||||
{
|
||||
DisableDetour();
|
||||
}
|
||||
|
||||
if (detour_trampoline)
|
||||
{
|
||||
/* Free the allocated trampoline memory */
|
||||
spengine->FreePageMemory(detour_trampoline);
|
||||
detour_trampoline = NULL;
|
||||
}
|
||||
return m_hook.enabled();
|
||||
}
|
||||
|
||||
void CDetour::EnableDetour()
|
||||
{
|
||||
if (!detoured)
|
||||
{
|
||||
DoGatePatch((unsigned char *)detour_address, detour_callback);
|
||||
detoured = true;
|
||||
}
|
||||
m_hook.enable();
|
||||
}
|
||||
|
||||
void CDetour::DisableDetour()
|
||||
{
|
||||
if (detoured)
|
||||
{
|
||||
/* Remove the patch */
|
||||
ApplyPatch(detour_address, 0, &detour_restore, NULL);
|
||||
detoured = false;
|
||||
}
|
||||
m_hook.disable();
|
||||
}
|
||||
|
||||
void CDetour::Destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
@ -32,18 +32,8 @@
|
||||
#ifndef _INCLUDE_SOURCEMOD_DETOURS_H_
|
||||
#define _INCLUDE_SOURCEMOD_DETOURS_H_
|
||||
|
||||
#include "extension.h"
|
||||
#include <jit/jit_helpers.h>
|
||||
#include <jit/x86/x86_macros.h>
|
||||
#include "detourhelpers.h"
|
||||
|
||||
/**
|
||||
* CDetours class for SourceMod Extensions by pRED*
|
||||
* detourhelpers.h entirely stolen from CSS:DM and were written by BAILOPAN (I assume).
|
||||
* asm.h/c from devmaster.net (thanks cybermind) edited by pRED* to handle gcc -fPIC thunks correctly
|
||||
* Concept by Nephyrin Zey (http://www.doublezen.net/) and Windows Detour Library (http://research.microsoft.com/sn/detours/)
|
||||
* Member function pointer ideas by Don Clugston (http://www.codeproject.com/cpp/FastDelegate.asp)
|
||||
*/
|
||||
#include "../safetyhook/safetyhook.hpp"
|
||||
#include <smsdk_ext.h>
|
||||
|
||||
#define DETOUR_MEMBER_CALL(name) (this->*name##_Actual)
|
||||
#define DETOUR_STATIC_CALL(name) (name##_Actual)
|
||||
@ -220,32 +210,9 @@ public:
|
||||
friend class CDetourManager;
|
||||
|
||||
protected:
|
||||
CDetour(void *callbackfunction, void **trampoline, const char *signame);
|
||||
CDetour(void*callbackfunction, void **trampoline, void *pAddress);
|
||||
|
||||
bool Init(ISourcePawnEngine *spengine, IGameConfig *gameconf);
|
||||
private:
|
||||
|
||||
/* These create/delete the allocated memory */
|
||||
bool CreateDetour();
|
||||
void DeleteDetour();
|
||||
|
||||
bool enabled;
|
||||
bool detoured;
|
||||
|
||||
patch_t detour_restore;
|
||||
/* Address of the detoured function */
|
||||
void *detour_address;
|
||||
/* Address of the allocated trampoline function */
|
||||
void *detour_trampoline;
|
||||
/* Address of the callback handler */
|
||||
void *detour_callback;
|
||||
/* The function pointer used to call our trampoline */
|
||||
void **trampoline;
|
||||
|
||||
const char *signame;
|
||||
ISourcePawnEngine *spengine;
|
||||
IGameConfig *gameconf;
|
||||
SafetyHookInline m_hook{};
|
||||
};
|
||||
|
||||
class CDetourManager
|
||||
@ -293,10 +260,9 @@ public:
|
||||
*
|
||||
* 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);
|
||||
static CDetour *CreateDetour(void *callbackFunction, void **trampoline, const char *signame);
|
||||
static CDetour *CreateDetour(void *callbackFunction, void **trampoline, void *pAddress);
|
||||
|
||||
friend class CBlocker;
|
||||
friend class CDetour;
|
||||
|
||||
private:
|
||||
@ -304,4 +270,4 @@ private:
|
||||
static IGameConfig *gameconf;
|
||||
};
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_DETOURS_H_
|
||||
#endif // _INCLUDE_SOURCEMOD_DETOURS_H_
|
54198
public/safetyhook/Zydis.c
Normal file
54198
public/safetyhook/Zydis.c
Normal file
File diff suppressed because one or more lines are too long
11885
public/safetyhook/Zydis.h
Normal file
11885
public/safetyhook/Zydis.h
Normal file
File diff suppressed because it is too large
Load Diff
2444
public/safetyhook/expected.hpp
Normal file
2444
public/safetyhook/expected.hpp
Normal file
File diff suppressed because it is too large
Load Diff
1731
public/safetyhook/safetyhook.cpp
Normal file
1731
public/safetyhook/safetyhook.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1153
public/safetyhook/safetyhook.hpp
Normal file
1153
public/safetyhook/safetyhook.hpp
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user