mirror of
https://github.com/alliedmodders/sourcemod.git
synced 2025-12-07 02:18:35 +00:00
Add x64 Windows support to DHooks (#2154)
* Add x64 Windows support * undo changes of hook.cpp * undo changes of hook.h * undo changes of extension.cpp * undo changes of listeners.cpp * undo changes of signatures.cpp * fix dhooks on x86 * Fix-up dhooks buildscript --------- Co-authored-by: Kenzzer <kenzzer@users.noreply.github.com>
This commit is contained in:
parent
4e6d66b721
commit
4e15a92984
@ -4,8 +4,11 @@ import os
|
|||||||
for cxx in builder.targets:
|
for cxx in builder.targets:
|
||||||
binary = SM.ExtLibrary(builder, cxx, 'dhooks.ext')
|
binary = SM.ExtLibrary(builder, cxx, 'dhooks.ext')
|
||||||
|
|
||||||
# Only x86 on Linux and Windows is supported.
|
# mac isn't supported
|
||||||
if binary.compiler.target.platform == 'mac' or binary.compiler.target.arch != 'x86':
|
if binary.compiler.target.platform == 'mac':
|
||||||
|
continue
|
||||||
|
# Presently only x86_64 on Windows is supported
|
||||||
|
if binary.compiler.target.arch == 'x86_64' and binary.compiler.target.platform != 'windows':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
binary.compiler.defines += [
|
binary.compiler.defines += [
|
||||||
@ -21,10 +24,8 @@ for cxx in builder.targets:
|
|||||||
os.path.join(SM.mms_root, 'core', 'sourcehook'),
|
os.path.join(SM.mms_root, 'core', 'sourcehook'),
|
||||||
os.path.join(builder.sourcePath, 'extensions', 'dhooks'),
|
os.path.join(builder.sourcePath, 'extensions', 'dhooks'),
|
||||||
os.path.join(builder.sourcePath, 'public', 'jit'),
|
os.path.join(builder.sourcePath, 'public', 'jit'),
|
||||||
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
|
|
||||||
os.path.join(builder.sourcePath, 'sourcepawn', 'include'),
|
os.path.join(builder.sourcePath, 'sourcepawn', 'include'),
|
||||||
os.path.join(builder.sourcePath, 'sourcepawn', 'vm'),
|
os.path.join(builder.sourcePath, 'sourcepawn', 'vm'),
|
||||||
os.path.join(builder.sourcePath, 'sourcepawn', 'vm', 'x86'),
|
|
||||||
os.path.join(builder.sourcePath, 'extensions', 'dhooks', 'DynamicHooks'),
|
os.path.join(builder.sourcePath, 'extensions', 'dhooks', 'DynamicHooks'),
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -48,22 +49,34 @@ for cxx in builder.targets:
|
|||||||
'libudis86/syn-intel.c',
|
'libudis86/syn-intel.c',
|
||||||
'libudis86/syn.c',
|
'libudis86/syn.c',
|
||||||
'libudis86/udis86.c',
|
'libudis86/udis86.c',
|
||||||
'../../sourcepawn/vm/x86/assembler-x86.cpp',
|
# Dynamic Hooks
|
||||||
|
os.path.join('DynamicHooks', 'registers.cpp')
|
||||||
]
|
]
|
||||||
|
|
||||||
# DynamicHooks
|
if binary.compiler.target.arch == 'x86':
|
||||||
binary.sources += [
|
binary.sources += ['../../sourcepawn/vm/x86/assembler-x86.cpp']
|
||||||
os.path.join('DynamicHooks', 'hook.cpp'),
|
binary.compiler.cxxincludes += [
|
||||||
os.path.join('DynamicHooks', 'manager.cpp'),
|
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
|
||||||
os.path.join('DynamicHooks', 'registers.cpp'),
|
os.path.join(builder.sourcePath, 'sourcepawn', 'vm', 'x86')
|
||||||
os.path.join('DynamicHooks', 'conventions', 'x86MsCdecl.cpp'),
|
]
|
||||||
os.path.join('DynamicHooks', 'conventions', 'x86MsStdcall.cpp'),
|
# DynamicHooks
|
||||||
os.path.join('DynamicHooks', 'conventions', 'x86MsFastcall.cpp'),
|
binary.sources += [
|
||||||
]
|
os.path.join('DynamicHooks', 'hook.cpp'),
|
||||||
|
os.path.join('DynamicHooks', 'manager.cpp'),
|
||||||
|
os.path.join('DynamicHooks', 'conventions', 'x86MsCdecl.cpp'),
|
||||||
|
os.path.join('DynamicHooks', 'conventions', 'x86MsStdcall.cpp'),
|
||||||
|
os.path.join('DynamicHooks', 'conventions', 'x86MsFastcall.cpp'),
|
||||||
|
]
|
||||||
|
|
||||||
if binary.compiler.target.platform == 'windows':
|
if binary.compiler.target.platform == 'windows':
|
||||||
binary.sources += [os.path.join('DynamicHooks', 'conventions', 'x86MsThiscall.cpp')]
|
binary.sources += [os.path.join('DynamicHooks', 'conventions', 'x86MsThiscall.cpp')]
|
||||||
else:
|
else:
|
||||||
binary.sources += [os.path.join('DynamicHooks', 'conventions', 'x86GccThiscall.cpp')]
|
binary.sources += [os.path.join('DynamicHooks', 'conventions', 'x86GccThiscall.cpp')]
|
||||||
|
|
||||||
|
# Dynamic detour is only supported on x86
|
||||||
|
binary.compiler.defines += ['DHOOKS_DYNAMIC_DETOUR']
|
||||||
|
|
||||||
|
elif binary.compiler.target.arch == 'x86_64':
|
||||||
|
binary.compiler.defines += ['PLATFORM_X64']
|
||||||
|
|
||||||
SM.extensions += [builder.Add(binary)]
|
SM.extensions += [builder.Add(binary)]
|
||||||
|
|||||||
@ -111,7 +111,7 @@ The data type you would like to get the size of.
|
|||||||
@param <alignment>:
|
@param <alignment>:
|
||||||
The alignment that should be used.
|
The alignment that should be used.
|
||||||
*/
|
*/
|
||||||
inline int GetDataTypeSize(DataTypeSized_t type, int iAlignment=4)
|
inline size_t GetDataTypeSize(DataTypeSized_t type, int iAlignment=4)
|
||||||
{
|
{
|
||||||
switch(type.type)
|
switch(type.type)
|
||||||
{
|
{
|
||||||
@ -257,9 +257,9 @@ public:
|
|||||||
int size = GetArgStackSize() + GetArgRegisterSize();
|
int size = GetArgStackSize() + GetArgRegisterSize();
|
||||||
std::unique_ptr<uint8_t[]> pSavedCallArguments = std::make_unique<uint8_t[]>(size);
|
std::unique_ptr<uint8_t[]> pSavedCallArguments = std::make_unique<uint8_t[]>(size);
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
for (size_t i = 0; i < m_vecArgTypes.size(); i++) {
|
for (unsigned int i = 0; i < m_vecArgTypes.size(); i++) {
|
||||||
DataTypeSized_t &type = m_vecArgTypes[i];
|
DataTypeSized_t &type = m_vecArgTypes[i];
|
||||||
memcpy((void *)((unsigned long)pSavedCallArguments.get() + offset), GetArgumentPtr(i, pRegisters), type.size);
|
memcpy((void *)((uintptr_t)pSavedCallArguments.get() + offset), GetArgumentPtr(i, pRegisters), type.size);
|
||||||
offset += type.size;
|
offset += type.size;
|
||||||
}
|
}
|
||||||
m_pSavedCallArguments.push_back(std::move(pSavedCallArguments));
|
m_pSavedCallArguments.push_back(std::move(pSavedCallArguments));
|
||||||
@ -271,7 +271,7 @@ public:
|
|||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
for (size_t i = 0; i < m_vecArgTypes.size(); i++) {
|
for (size_t i = 0; i < m_vecArgTypes.size(); i++) {
|
||||||
DataTypeSized_t &type = m_vecArgTypes[i];
|
DataTypeSized_t &type = m_vecArgTypes[i];
|
||||||
memcpy(GetArgumentPtr(i, pRegisters), (void *)((unsigned long)pSavedCallArguments + offset), type.size);
|
memcpy(GetArgumentPtr((unsigned int)i, pRegisters), (void *)((uintptr_t)pSavedCallArguments + offset), type.size);
|
||||||
offset += type.size;
|
offset += type.size;
|
||||||
}
|
}
|
||||||
m_pSavedCallArguments.pop_back();
|
m_pSavedCallArguments.pop_back();
|
||||||
|
|||||||
@ -116,7 +116,7 @@ CRegisters::CRegisters(std::vector<Register_t> registers)
|
|||||||
// >> 64-bit General purpose registers
|
// >> 64-bit General purpose registers
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// 64-bit mode only
|
// 64-bit mode only
|
||||||
/*
|
#ifdef PLATFORM_X64
|
||||||
m_rax = CreateRegister(registers, RAX, 8);
|
m_rax = CreateRegister(registers, RAX, 8);
|
||||||
m_rcx = CreateRegister(registers, RCX, 8);
|
m_rcx = CreateRegister(registers, RCX, 8);
|
||||||
m_rdx = CreateRegister(registers, RDX, 8);
|
m_rdx = CreateRegister(registers, RDX, 8);
|
||||||
@ -125,10 +125,7 @@ CRegisters::CRegisters(std::vector<Register_t> registers)
|
|||||||
m_rbp = CreateRegister(registers, RBP, 8);
|
m_rbp = CreateRegister(registers, RBP, 8);
|
||||||
m_rsi = CreateRegister(registers, RSI, 8);
|
m_rsi = CreateRegister(registers, RSI, 8);
|
||||||
m_rdi = CreateRegister(registers, RDI, 8);
|
m_rdi = CreateRegister(registers, RDI, 8);
|
||||||
*/
|
|
||||||
|
|
||||||
// 64-bit mode only
|
|
||||||
/*
|
|
||||||
m_r8 = CreateRegister(registers, R8, 8);
|
m_r8 = CreateRegister(registers, R8, 8);
|
||||||
m_r9 = CreateRegister(registers, R9, 8);
|
m_r9 = CreateRegister(registers, R9, 8);
|
||||||
m_r10 = CreateRegister(registers, R10, 8);
|
m_r10 = CreateRegister(registers, R10, 8);
|
||||||
@ -137,7 +134,7 @@ CRegisters::CRegisters(std::vector<Register_t> registers)
|
|||||||
m_r13 = CreateRegister(registers, R13, 8);
|
m_r13 = CreateRegister(registers, R13, 8);
|
||||||
m_r14 = CreateRegister(registers, R14, 8);
|
m_r14 = CreateRegister(registers, R14, 8);
|
||||||
m_r15 = CreateRegister(registers, R15, 8);
|
m_r15 = CreateRegister(registers, R15, 8);
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// >> 64-bit MM (MMX) registers
|
// >> 64-bit MM (MMX) registers
|
||||||
@ -165,7 +162,7 @@ CRegisters::CRegisters(std::vector<Register_t> registers)
|
|||||||
m_xmm7 = CreateRegister(registers, XMM7, 16, 16);
|
m_xmm7 = CreateRegister(registers, XMM7, 16, 16);
|
||||||
|
|
||||||
// 64-bit mode only
|
// 64-bit mode only
|
||||||
/*
|
#ifdef PLATFORM_X64
|
||||||
m_xmm8 = CreateRegister(registers, XMM8, 16);
|
m_xmm8 = CreateRegister(registers, XMM8, 16);
|
||||||
m_xmm9 = CreateRegister(registers, XMM9, 16);
|
m_xmm9 = CreateRegister(registers, XMM9, 16);
|
||||||
m_xmm10 = CreateRegister(registers, XMM10, 16);
|
m_xmm10 = CreateRegister(registers, XMM10, 16);
|
||||||
@ -174,7 +171,7 @@ CRegisters::CRegisters(std::vector<Register_t> registers)
|
|||||||
m_xmm13 = CreateRegister(registers, XMM13, 16);
|
m_xmm13 = CreateRegister(registers, XMM13, 16);
|
||||||
m_xmm14 = CreateRegister(registers, XMM14, 16);
|
m_xmm14 = CreateRegister(registers, XMM14, 16);
|
||||||
m_xmm15 = CreateRegister(registers, XMM15, 16);
|
m_xmm15 = CreateRegister(registers, XMM15, 16);
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// >> 16-bit Segment registers
|
// >> 16-bit Segment registers
|
||||||
@ -282,7 +279,7 @@ CRegisters::~CRegisters()
|
|||||||
// >> 64-bit General purpose registers
|
// >> 64-bit General purpose registers
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// 64-bit mode only
|
// 64-bit mode only
|
||||||
/*
|
#ifdef PLATFORM_X64
|
||||||
DeleteRegister(m_rax);
|
DeleteRegister(m_rax);
|
||||||
DeleteRegister(m_rcx);
|
DeleteRegister(m_rcx);
|
||||||
DeleteRegister(m_rdx);
|
DeleteRegister(m_rdx);
|
||||||
@ -291,10 +288,8 @@ CRegisters::~CRegisters()
|
|||||||
DeleteRegister(m_rbp);
|
DeleteRegister(m_rbp);
|
||||||
DeleteRegister(m_rsi);
|
DeleteRegister(m_rsi);
|
||||||
DeleteRegister(m_rdi);
|
DeleteRegister(m_rdi);
|
||||||
*/
|
|
||||||
|
|
||||||
// 64-bit mode only
|
// 64-bit mode only
|
||||||
/*
|
|
||||||
DeleteRegister(m_r8);
|
DeleteRegister(m_r8);
|
||||||
DeleteRegister(m_r9);
|
DeleteRegister(m_r9);
|
||||||
DeleteRegister(m_r10);
|
DeleteRegister(m_r10);
|
||||||
@ -303,7 +298,7 @@ CRegisters::~CRegisters()
|
|||||||
DeleteRegister(m_r13);
|
DeleteRegister(m_r13);
|
||||||
DeleteRegister(m_r14);
|
DeleteRegister(m_r14);
|
||||||
DeleteRegister(m_r15);
|
DeleteRegister(m_r15);
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// >> 64-bit MM (MMX) registers
|
// >> 64-bit MM (MMX) registers
|
||||||
@ -330,7 +325,7 @@ CRegisters::~CRegisters()
|
|||||||
DeleteRegister(m_xmm7);
|
DeleteRegister(m_xmm7);
|
||||||
|
|
||||||
// 64-bit mode only
|
// 64-bit mode only
|
||||||
/*
|
#ifdef PLATFORM_X64
|
||||||
DeleteRegister(m_xmm8);
|
DeleteRegister(m_xmm8);
|
||||||
DeleteRegister(m_xmm9);
|
DeleteRegister(m_xmm9);
|
||||||
DeleteRegister(m_xmm10);
|
DeleteRegister(m_xmm10);
|
||||||
@ -339,7 +334,7 @@ CRegisters::~CRegisters()
|
|||||||
DeleteRegister(m_xmm13);
|
DeleteRegister(m_xmm13);
|
||||||
DeleteRegister(m_xmm14);
|
DeleteRegister(m_xmm14);
|
||||||
DeleteRegister(m_xmm15);
|
DeleteRegister(m_xmm15);
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// >> 2-bit Segment registers
|
// >> 2-bit Segment registers
|
||||||
|
|||||||
@ -132,8 +132,7 @@ enum Register_t
|
|||||||
// ========================================================================
|
// ========================================================================
|
||||||
// >> 64-bit General purpose registers
|
// >> 64-bit General purpose registers
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// 64-bit mode only
|
#ifdef PLATFORM_X64
|
||||||
/*
|
|
||||||
RAX,
|
RAX,
|
||||||
RCX,
|
RCX,
|
||||||
RDX,
|
RDX,
|
||||||
@ -142,10 +141,7 @@ enum Register_t
|
|||||||
RBP,
|
RBP,
|
||||||
RSI,
|
RSI,
|
||||||
RDI,
|
RDI,
|
||||||
*/
|
|
||||||
|
|
||||||
// 64-bit mode only
|
|
||||||
/*
|
|
||||||
R8,
|
R8,
|
||||||
R9,
|
R9,
|
||||||
R10,
|
R10,
|
||||||
@ -154,7 +150,7 @@ enum Register_t
|
|||||||
R13,
|
R13,
|
||||||
R14,
|
R14,
|
||||||
R15,
|
R15,
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// >> 64-bit MM (MMX) registers
|
// >> 64-bit MM (MMX) registers
|
||||||
@ -181,7 +177,7 @@ enum Register_t
|
|||||||
XMM7,
|
XMM7,
|
||||||
|
|
||||||
// 64-bit mode only
|
// 64-bit mode only
|
||||||
/*
|
#ifdef PLATFORM_X64
|
||||||
XMM8,
|
XMM8,
|
||||||
XMM9,
|
XMM9,
|
||||||
XMM10,
|
XMM10,
|
||||||
@ -190,7 +186,7 @@ enum Register_t
|
|||||||
XMM13,
|
XMM13,
|
||||||
XMM14,
|
XMM14,
|
||||||
XMM15,
|
XMM15,
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// >> 16-bit Segment registers
|
// >> 16-bit Segment registers
|
||||||
@ -377,7 +373,7 @@ public:
|
|||||||
// >> 64-bit General purpose registers
|
// >> 64-bit General purpose registers
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// 64-bit mode only
|
// 64-bit mode only
|
||||||
/*
|
#ifdef PLATFORM_X64
|
||||||
CRegister* m_rax;
|
CRegister* m_rax;
|
||||||
CRegister* m_rcx;
|
CRegister* m_rcx;
|
||||||
CRegister* m_rdx;
|
CRegister* m_rdx;
|
||||||
@ -386,10 +382,7 @@ public:
|
|||||||
CRegister* m_rbp;
|
CRegister* m_rbp;
|
||||||
CRegister* m_rsi;
|
CRegister* m_rsi;
|
||||||
CRegister* m_rdi;
|
CRegister* m_rdi;
|
||||||
*/
|
|
||||||
|
|
||||||
// 64-bit mode only
|
|
||||||
/*
|
|
||||||
CRegister* m_r8;
|
CRegister* m_r8;
|
||||||
CRegister* m_r9;
|
CRegister* m_r9;
|
||||||
CRegister* m_r10;
|
CRegister* m_r10;
|
||||||
@ -398,7 +391,7 @@ public:
|
|||||||
CRegister* m_r13;
|
CRegister* m_r13;
|
||||||
CRegister* m_r14;
|
CRegister* m_r14;
|
||||||
CRegister* m_r15;
|
CRegister* m_r15;
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// >> 64-bit MM (MMX) registers
|
// >> 64-bit MM (MMX) registers
|
||||||
@ -425,7 +418,7 @@ public:
|
|||||||
CRegister* m_xmm7;
|
CRegister* m_xmm7;
|
||||||
|
|
||||||
// 64-bit mode only
|
// 64-bit mode only
|
||||||
/*
|
#ifdef PLATFORM_X64
|
||||||
CRegister* m_xmm8;
|
CRegister* m_xmm8;
|
||||||
CRegister* m_xmm9;
|
CRegister* m_xmm9;
|
||||||
CRegister* m_xmm10;
|
CRegister* m_xmm10;
|
||||||
@ -434,7 +427,7 @@ public:
|
|||||||
CRegister* m_xmm13;
|
CRegister* m_xmm13;
|
||||||
CRegister* m_xmm14;
|
CRegister* m_xmm14;
|
||||||
CRegister* m_xmm15;
|
CRegister* m_xmm15;
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
// >> 16-bit Segment registers
|
// >> 16-bit Segment registers
|
||||||
|
|||||||
@ -63,15 +63,18 @@ DetourMap g_pPostDetours;
|
|||||||
|
|
||||||
void UnhookFunction(HookType_t hookType, CHook *pDetour)
|
void UnhookFunction(HookType_t hookType, CHook *pDetour)
|
||||||
{
|
{
|
||||||
|
#if defined( DHOOKS_DYNAMIC_DETOUR )
|
||||||
CHookManager *pDetourManager = GetHookManager();
|
CHookManager *pDetourManager = GetHookManager();
|
||||||
pDetour->RemoveCallback(hookType, (HookHandlerFn *)(void *)&HandleDetour);
|
pDetour->RemoveCallback(hookType, (HookHandlerFn *)(void *)&HandleDetour);
|
||||||
// Only disable the detour if there are no more listeners.
|
// Only disable the detour if there are no more listeners.
|
||||||
if (!pDetour->AreCallbacksRegistered())
|
if (!pDetour->AreCallbacksRegistered())
|
||||||
pDetourManager->UnhookFunction(pDetour->m_pFunc);
|
pDetourManager->UnhookFunction(pDetour->m_pFunc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddDetourPluginHook(HookType_t hookType, CHook *pDetour, HookSetup *setup, IPluginFunction *pCallback)
|
bool AddDetourPluginHook(HookType_t hookType, CHook *pDetour, HookSetup *setup, IPluginFunction *pCallback)
|
||||||
{
|
{
|
||||||
|
#if defined( DHOOKS_DYNAMIC_DETOUR )
|
||||||
DetourMap *map;
|
DetourMap *map;
|
||||||
if (hookType == HOOKTYPE_PRE)
|
if (hookType == HOOKTYPE_PRE)
|
||||||
map = &g_pPreDetours;
|
map = &g_pPreDetours;
|
||||||
@ -102,10 +105,14 @@ bool AddDetourPluginHook(HookType_t hookType, CHook *pDetour, HookSetup *setup,
|
|||||||
wrappers->push_back(pWrapper);
|
wrappers->push_back(pWrapper);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RemoveDetourPluginHook(HookType_t hookType, CHook *pDetour, IPluginFunction *pCallback)
|
bool RemoveDetourPluginHook(HookType_t hookType, CHook *pDetour, IPluginFunction *pCallback)
|
||||||
{
|
{
|
||||||
|
#if defined( DHOOKS_DYNAMIC_DETOUR )
|
||||||
DetourMap *map;
|
DetourMap *map;
|
||||||
if (hookType == HOOKTYPE_PRE)
|
if (hookType == HOOKTYPE_PRE)
|
||||||
map = &g_pPreDetours;
|
map = &g_pPreDetours;
|
||||||
@ -139,10 +146,14 @@ bool RemoveDetourPluginHook(HookType_t hookType, CHook *pDetour, IPluginFunction
|
|||||||
}
|
}
|
||||||
|
|
||||||
return bRemoved;
|
return bRemoved;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveAllCallbacksForContext(HookType_t hookType, DetourMap *map, IPluginContext *pContext)
|
void RemoveAllCallbacksForContext(HookType_t hookType, DetourMap *map, IPluginContext *pContext)
|
||||||
{
|
{
|
||||||
|
#if defined( DHOOKS_DYNAMIC_DETOUR )
|
||||||
PluginCallbackList *wrappers;
|
PluginCallbackList *wrappers;
|
||||||
CDynamicHooksSourcePawn *pWrapper;
|
CDynamicHooksSourcePawn *pWrapper;
|
||||||
DetourMap::iterator it = map->iter();
|
DetourMap::iterator it = map->iter();
|
||||||
@ -170,16 +181,20 @@ void RemoveAllCallbacksForContext(HookType_t hookType, DetourMap *map, IPluginCo
|
|||||||
it.erase();
|
it.erase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveAllCallbacksForContext(IPluginContext *pContext)
|
void RemoveAllCallbacksForContext(IPluginContext *pContext)
|
||||||
{
|
{
|
||||||
|
#if defined( DHOOKS_DYNAMIC_DETOUR )
|
||||||
RemoveAllCallbacksForContext(HOOKTYPE_PRE, &g_pPreDetours, pContext);
|
RemoveAllCallbacksForContext(HOOKTYPE_PRE, &g_pPreDetours, pContext);
|
||||||
RemoveAllCallbacksForContext(HOOKTYPE_POST, &g_pPostDetours, pContext);
|
RemoveAllCallbacksForContext(HOOKTYPE_POST, &g_pPostDetours, pContext);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanupDetours(HookType_t hookType, DetourMap *map)
|
void CleanupDetours(HookType_t hookType, DetourMap *map)
|
||||||
{
|
{
|
||||||
|
#if defined( DHOOKS_DYNAMIC_DETOUR )
|
||||||
PluginCallbackList *wrappers;
|
PluginCallbackList *wrappers;
|
||||||
CDynamicHooksSourcePawn *pWrapper;
|
CDynamicHooksSourcePawn *pWrapper;
|
||||||
DetourMap::iterator it = map->iter();
|
DetourMap::iterator it = map->iter();
|
||||||
@ -199,14 +214,18 @@ void CleanupDetours(HookType_t hookType, DetourMap *map)
|
|||||||
UnhookFunction(hookType, it->key);
|
UnhookFunction(hookType, it->key);
|
||||||
}
|
}
|
||||||
map->clear();
|
map->clear();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CleanupDetours()
|
void CleanupDetours()
|
||||||
{
|
{
|
||||||
|
#if defined( DHOOKS_DYNAMIC_DETOUR )
|
||||||
CleanupDetours(HOOKTYPE_PRE, &g_pPreDetours);
|
CleanupDetours(HOOKTYPE_PRE, &g_pPreDetours);
|
||||||
CleanupDetours(HOOKTYPE_POST, &g_pPostDetours);
|
CleanupDetours(HOOKTYPE_POST, &g_pPostDetours);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined( DHOOKS_DYNAMIC_DETOUR )
|
||||||
ICallingConvention *ConstructCallingConvention(HookSetup *setup)
|
ICallingConvention *ConstructCallingConvention(HookSetup *setup)
|
||||||
{
|
{
|
||||||
// Convert function parameter types into DynamicHooks structures.
|
// Convert function parameter types into DynamicHooks structures.
|
||||||
@ -249,6 +268,7 @@ ICallingConvention *ConstructCallingConvention(HookSetup *setup)
|
|||||||
|
|
||||||
return pCallConv;
|
return pCallConv;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Some arguments might be optimized to be passed in registers instead of the stack.
|
// Some arguments might be optimized to be passed in registers instead of the stack.
|
||||||
bool UpdateRegisterArgumentSizes(CHook* pDetour, HookSetup *setup)
|
bool UpdateRegisterArgumentSizes(CHook* pDetour, HookSetup *setup)
|
||||||
|
|||||||
@ -62,7 +62,9 @@ public:
|
|||||||
CallingConvention callConv;
|
CallingConvention callConv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined( DHOOKS_DYNAMIC_DETOUR )
|
||||||
ICallingConvention *ConstructCallingConvention(HookSetup *setup);
|
ICallingConvention *ConstructCallingConvention(HookSetup *setup);
|
||||||
|
#endif
|
||||||
bool UpdateRegisterArgumentSizes(CHook* pDetour, HookSetup *setup);
|
bool UpdateRegisterArgumentSizes(CHook* pDetour, HookSetup *setup);
|
||||||
ReturnAction_t HandleDetour(HookType_t hookType, CHook* pDetour);
|
ReturnAction_t HandleDetour(HookType_t hookType, CHook* pDetour);
|
||||||
bool AddDetourPluginHook(HookType_t hookType, CHook *pDetour, HookSetup *setup, IPluginFunction *pCallback);
|
bool AddDetourPluginHook(HookType_t hookType, CHook *pDetour, HookSetup *setup, IPluginFunction *pCallback);
|
||||||
|
|||||||
@ -338,6 +338,7 @@ cell_t Native_AddParam(IPluginContext *pContext, const cell_t *params)
|
|||||||
// native bool:DHookEnableDetour(Handle:setup, bool:post, DHookCallback:callback);
|
// native bool:DHookEnableDetour(Handle:setup, bool:post, DHookCallback:callback);
|
||||||
cell_t Native_EnableDetour(IPluginContext *pContext, const cell_t *params)
|
cell_t Native_EnableDetour(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
|
#if defined( DHOOKS_DYNAMIC_DETOUR )
|
||||||
HookSetup *setup;
|
HookSetup *setup;
|
||||||
|
|
||||||
if (!GetHandleIfValidOrError(g_HookSetupHandle, (void **)&setup, pContext, params[1]))
|
if (!GetHandleIfValidOrError(g_HookSetupHandle, (void **)&setup, pContext, params[1]))
|
||||||
@ -377,11 +378,15 @@ cell_t Native_EnableDetour(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
// Add the plugin callback to the map.
|
// Add the plugin callback to the map.
|
||||||
return AddDetourPluginHook(hookType, pDetour, setup, callback);
|
return AddDetourPluginHook(hookType, pDetour, setup, callback);
|
||||||
|
#else
|
||||||
|
return pContext->ThrowNativeError("Dynamic detours are not enabled for this mod!");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// native bool:DHookDisableDetour(Handle:setup, bool:post, DHookCallback:callback);
|
// native bool:DHookDisableDetour(Handle:setup, bool:post, DHookCallback:callback);
|
||||||
cell_t Native_DisableDetour(IPluginContext *pContext, const cell_t *params)
|
cell_t Native_DisableDetour(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
|
#if defined( DHOOKS_DYNAMIC_DETOUR )
|
||||||
HookSetup *setup;
|
HookSetup *setup;
|
||||||
|
|
||||||
if (!GetHandleIfValidOrError(g_HookSetupHandle, (void **)&setup, pContext, params[1]))
|
if (!GetHandleIfValidOrError(g_HookSetupHandle, (void **)&setup, pContext, params[1]))
|
||||||
@ -414,6 +419,9 @@ cell_t Native_DisableDetour(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
// Remove the callback from the hook.
|
// Remove the callback from the hook.
|
||||||
return RemoveDetourPluginHook(hookType, pDetour, callback);
|
return RemoveDetourPluginHook(hookType, pDetour, callback);
|
||||||
|
#else
|
||||||
|
return pContext->ThrowNativeError("Dynamic detours are not enabled for this mod!");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
cell_t HookEntityImpl(IPluginContext *pContext, const cell_t *params, uint32_t callbackIndex, uint32_t removalcbIndex)
|
cell_t HookEntityImpl(IPluginContext *pContext, const cell_t *params, uint32_t callbackIndex, uint32_t removalcbIndex)
|
||||||
|
|||||||
@ -62,7 +62,11 @@ size_t GetStackParamOffset(HookParamsStruct *paramStruct, unsigned int index)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef PLATFORM_X64
|
||||||
|
offset += 8;
|
||||||
|
#else
|
||||||
offset += paramStruct->dg->params[i].size;
|
offset += paramStruct->dg->params[i].size;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
@ -77,7 +81,9 @@ size_t GetRegisterParamOffset(HookParamsStruct *paramStruct, unsigned int index)
|
|||||||
for (int i = paramStruct->dg->params.size() - 1; i >= 0; i--)
|
for (int i = paramStruct->dg->params.size() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (paramStruct->dg->params[i].custom_register == None)
|
if (paramStruct->dg->params[i].custom_register == None)
|
||||||
|
{
|
||||||
stackSize += paramStruct->dg->params[i].size;
|
stackSize += paramStruct->dg->params[i].size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t offset = stackSize;
|
size_t offset = stackSize;
|
||||||
|
|||||||
@ -200,8 +200,8 @@ SDKVector CallVFunction<SDKVector>(DHooksCallback *dg, HookParamsStruct *paramSt
|
|||||||
{
|
{
|
||||||
size_t offset = GetParamOffset(paramStruct, i);
|
size_t offset = GetParamOffset(paramStruct, i);
|
||||||
|
|
||||||
void *orgAddr = *(void **)((intptr_t)paramStruct->orgParams + offset);
|
void *orgAddr = (void **)((intptr_t)paramStruct->orgParams + offset);
|
||||||
void *newAddr = *(void **)((intptr_t)paramStruct->newParams + offset);
|
void *newAddr = (void **)((intptr_t)paramStruct->newParams + offset);
|
||||||
|
|
||||||
switch (dg->params.at(i).type)
|
switch (dg->params.at(i).type)
|
||||||
{
|
{
|
||||||
@ -291,8 +291,8 @@ string_t CallVFunction<string_t>(DHooksCallback *dg, HookParamsStruct *paramStru
|
|||||||
{
|
{
|
||||||
size_t offset = GetParamOffset(paramStruct, i);
|
size_t offset = GetParamOffset(paramStruct, i);
|
||||||
|
|
||||||
void *orgAddr = *(void **)((intptr_t)paramStruct->orgParams + offset);
|
void *orgAddr = (void **)((intptr_t)paramStruct->orgParams + offset);
|
||||||
void *newAddr = *(void **)((intptr_t)paramStruct->newParams + offset);
|
void *newAddr = (void **)((intptr_t)paramStruct->newParams + offset);
|
||||||
|
|
||||||
switch (dg->params.at(i).type)
|
switch (dg->params.at(i).type)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -32,7 +32,11 @@
|
|||||||
#include "vhook.h"
|
#include "vhook.h"
|
||||||
#include "vfunc_call.h"
|
#include "vfunc_call.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#ifdef PLATFORM_X64
|
||||||
|
#include "sh_asm_x86_64.h"
|
||||||
|
#else
|
||||||
#include <macro-assembler-x86.h>
|
#include <macro-assembler-x86.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
SourceHook::IHookManagerAutoGen *g_pHookManager = NULL;
|
SourceHook::IHookManagerAutoGen *g_pHookManager = NULL;
|
||||||
|
|
||||||
@ -47,9 +51,111 @@ using namespace sp;
|
|||||||
#define OBJECT_OFFSET (sizeof(void *)*2)
|
#define OBJECT_OFFSET (sizeof(void *)*2)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifdef PLATFORM_X64
|
||||||
void *GenerateThunk(ReturnType type)
|
using namespace SourceHook::Asm;
|
||||||
|
SourceHook::CPageAlloc GenBuffer::ms_Allocator(16);
|
||||||
|
|
||||||
|
void test_func(void* rcx, void* rdx, SDKVector* r8, bool r9)
|
||||||
{
|
{
|
||||||
|
//g_pSM->LogMessage(myself, "rcx(%p) - rdx(%p) - r8(%p) - r9(%p)", rcx, rdx, r8, r9);
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceHook::Asm::x64JitWriter* GenerateThunk(HookSetup* hook)
|
||||||
|
{
|
||||||
|
auto masm = new x64JitWriter();
|
||||||
|
auto type = hook->returnType;
|
||||||
|
|
||||||
|
/*if (type == ReturnType_Vector)
|
||||||
|
{
|
||||||
|
masm->push(rcx);
|
||||||
|
masm->push(rdx);
|
||||||
|
masm->push(r8);
|
||||||
|
masm->push(r9);
|
||||||
|
masm->sub(rsp, 40);
|
||||||
|
masm->mov(rax, (uintptr_t)test_func);
|
||||||
|
masm->call(rax);
|
||||||
|
masm->add(rsp, 40);
|
||||||
|
masm->pop(r9);
|
||||||
|
masm->pop(r8);
|
||||||
|
masm->pop(rdx);
|
||||||
|
masm->pop(rcx);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// We're going to transform rbp into our stack
|
||||||
|
masm->push(rbp);
|
||||||
|
|
||||||
|
// Copy all the arguments into the stack
|
||||||
|
// 8 bytes per parameter + 8 bytes for potential return value
|
||||||
|
int32_t fakeStackSize = ke::Align((int32_t)hook->params.size() * 8 + 8, 16) + 8; // Add another +8 bytes to realign on 16 bytes, due to 'push rbp' earlier
|
||||||
|
int32_t parameterOffset = fakeStackSize + 8 /* push rbp */ + 8 /* return address */ + 32 /* shadow space */;
|
||||||
|
masm->sub(rsp, fakeStackSize);
|
||||||
|
masm->mov(rbp, rsp);
|
||||||
|
|
||||||
|
static x86_64_Reg arg_reg[] = { rcx, rdx, r8, r9 };
|
||||||
|
static x86_64_FloatReg arg_reg_float[] = { xmm0, xmm1, xmm2, xmm3 };
|
||||||
|
|
||||||
|
int stack_index = 0;
|
||||||
|
int fake_stack_index = 0;
|
||||||
|
int reg_index = 1; // Account |this| right away
|
||||||
|
if (type == ReturnType_Vector) { // Special return types occupy another register
|
||||||
|
masm->mov(rbp(8 * fake_stack_index), rdx); // Store return ptr at the bottom of the stack
|
||||||
|
reg_index++;
|
||||||
|
fake_stack_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < hook->params.size(); i++, fake_stack_index++) {
|
||||||
|
if (reg_index < 4) {
|
||||||
|
if (hook->params[i].type == HookParamType_Float && hook->params[i].flags == PASSFLAG_BYVAL) {
|
||||||
|
masm->movsd(rbp(8 * fake_stack_index), arg_reg_float[reg_index]);
|
||||||
|
} else {
|
||||||
|
masm->mov(rax, arg_reg[reg_index]);
|
||||||
|
masm->mov(rbp(8 * fake_stack_index), rax);
|
||||||
|
}
|
||||||
|
reg_index++;
|
||||||
|
} else {
|
||||||
|
masm->mov(rax, rbp(parameterOffset + 8 * stack_index));
|
||||||
|
masm->mov(rbp(8 * fake_stack_index), rax);
|
||||||
|
stack_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//masm->mov(rbp(8 * 2), 0x7777777777777777);
|
||||||
|
//masm->mov(rbp(8 * 1), 0xDEADBEEFDEADBEEF);
|
||||||
|
|
||||||
|
// Setup 2nd parameter (our fake stack)
|
||||||
|
masm->mov(rdx, rbp);
|
||||||
|
|
||||||
|
if (type == ReturnType_Float)
|
||||||
|
{
|
||||||
|
masm->mov(rax, (uintptr_t)Callback_float);
|
||||||
|
}
|
||||||
|
else if (type == ReturnType_Vector)
|
||||||
|
{
|
||||||
|
masm->mov(rax, (uintptr_t)Callback_vector);
|
||||||
|
}
|
||||||
|
/*else if (type == ReturnType_String)
|
||||||
|
{
|
||||||
|
masm->mov(rax, (uintptr_t)Callback_stringt);
|
||||||
|
}*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
masm->mov(rax, (uintptr_t)Callback);
|
||||||
|
}
|
||||||
|
masm->sub(rsp, 40);
|
||||||
|
masm->call(rax);
|
||||||
|
masm->add(rsp, 40);
|
||||||
|
|
||||||
|
masm->add(rsp, fakeStackSize);
|
||||||
|
masm->pop(rbp);
|
||||||
|
masm->retn();
|
||||||
|
|
||||||
|
masm->SetRE();
|
||||||
|
return masm;
|
||||||
|
}
|
||||||
|
#elif !defined( WIN32 )
|
||||||
|
void *GenerateThunk(HookSetup* hook)
|
||||||
|
{
|
||||||
|
auto type = hook->returnType;
|
||||||
sp::MacroAssembler masm;
|
sp::MacroAssembler masm;
|
||||||
static const size_t kStackNeeded = (2) * 4; // 2 args max
|
static const size_t kStackNeeded = (2) * 4; // 2 args max
|
||||||
static const size_t kReserve = ke::Align(kStackNeeded + 8, 16) - 8;
|
static const size_t kReserve = ke::Align(kStackNeeded + 8, 16) - 8;
|
||||||
@ -97,8 +203,9 @@ void *GenerateThunk(ReturnType type)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// HUGE THANKS TO BAILOPAN (dvander)!
|
// HUGE THANKS TO BAILOPAN (dvander)!
|
||||||
void *GenerateThunk(ReturnType type)
|
void *GenerateThunk(HookSetup* hook)
|
||||||
{
|
{
|
||||||
|
auto type = hook->returnType;
|
||||||
sp::MacroAssembler masm;
|
sp::MacroAssembler masm;
|
||||||
static const size_t kStackNeeded = (3 + 1) * 4; // 3 args max, 1 locals max
|
static const size_t kStackNeeded = (3 + 1) * 4; // 3 args max, 1 locals max
|
||||||
static const size_t kReserve = ke::Align(kStackNeeded + 8, 16) - 8;
|
static const size_t kReserve = ke::Align(kStackNeeded + 8, 16) - 8;
|
||||||
@ -138,7 +245,7 @@ void *GenerateThunk(ReturnType type)
|
|||||||
|
|
||||||
DHooksManager::DHooksManager(HookSetup *setup, void *iface, IPluginFunction *remove_callback, IPluginFunction *plugincb, bool post)
|
DHooksManager::DHooksManager(HookSetup *setup, void *iface, IPluginFunction *remove_callback, IPluginFunction *plugincb, bool post)
|
||||||
{
|
{
|
||||||
this->callback = MakeHandler(setup->returnType);
|
this->callback = MakeHandler(setup);
|
||||||
this->hookid = 0;
|
this->hookid = 0;
|
||||||
this->remove_callback = remove_callback;
|
this->remove_callback = remove_callback;
|
||||||
this->callback->offset = setup->offset;
|
this->callback->offset = setup->offset;
|
||||||
@ -232,11 +339,11 @@ SourceHook::PassInfo::PassType GetParamTypePassType(HookParamType type)
|
|||||||
size_t GetStackArgsSize(DHooksCallback *dg)
|
size_t GetStackArgsSize(DHooksCallback *dg)
|
||||||
{
|
{
|
||||||
size_t res = GetParamsSize(dg);
|
size_t res = GetParamsSize(dg);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if(dg->returnType == ReturnType_Vector)//Account for result vector ptr.
|
if(dg->returnType == ReturnType_Vector)//Account for result vector ptr.
|
||||||
#else
|
#else
|
||||||
if(dg->returnType == ReturnType_Vector || dg->returnType == ReturnType_String)
|
if(dg->returnType == ReturnType_Vector || dg->returnType == ReturnType_String)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
res += OBJECT_OFFSET;
|
res += OBJECT_OFFSET;
|
||||||
}
|
}
|
||||||
@ -272,11 +379,11 @@ HookParamsStruct *GetParamStruct(DHooksCallback *dg, void **argStack, size_t arg
|
|||||||
{
|
{
|
||||||
HookParamsStruct *params = new HookParamsStruct();
|
HookParamsStruct *params = new HookParamsStruct();
|
||||||
params->dg = dg;
|
params->dg = dg;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if(dg->returnType != ReturnType_Vector)
|
if(dg->returnType != ReturnType_Vector)
|
||||||
#else
|
#else
|
||||||
if(dg->returnType != ReturnType_Vector && dg->returnType != ReturnType_String)
|
if(dg->returnType != ReturnType_Vector && dg->returnType != ReturnType_String)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
params->orgParams = (void **)malloc(argStackSize);
|
params->orgParams = (void **)malloc(argStackSize);
|
||||||
memcpy(params->orgParams, argStack, argStackSize);
|
memcpy(params->orgParams, argStack, argStackSize);
|
||||||
@ -284,7 +391,7 @@ HookParamsStruct *GetParamStruct(DHooksCallback *dg, void **argStack, size_t arg
|
|||||||
else //Offset result ptr
|
else //Offset result ptr
|
||||||
{
|
{
|
||||||
params->orgParams = (void **)malloc(argStackSize-OBJECT_OFFSET);
|
params->orgParams = (void **)malloc(argStackSize-OBJECT_OFFSET);
|
||||||
memcpy(params->orgParams, argStack+OBJECT_OFFSET, argStackSize-OBJECT_OFFSET);
|
memcpy(params->orgParams, (void*)((uintptr_t)argStack + OBJECT_OFFSET), argStackSize - OBJECT_OFFSET);
|
||||||
}
|
}
|
||||||
size_t paramsSize = GetParamsSize(dg);
|
size_t paramsSize = GetParamsSize(dg);
|
||||||
|
|
||||||
@ -388,11 +495,14 @@ cell_t GetThisPtr(void *iface, ThisPointerType type)
|
|||||||
return -1;
|
return -1;
|
||||||
return gamehelpers->EntityToBCompatRef((CBaseEntity *)iface);
|
return gamehelpers->EntityToBCompatRef((CBaseEntity *)iface);
|
||||||
}
|
}
|
||||||
|
#ifdef PLATFORM_X64
|
||||||
|
return g_pSM->ToPseudoAddress(iface);
|
||||||
|
#else
|
||||||
return (cell_t)iface;
|
return (cell_t)iface;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined( WIN32 ) && !defined( PLATFORM_X64 )
|
||||||
void *Callback(DHooksCallback *dg, void **argStack, size_t *argsizep)
|
void *Callback(DHooksCallback *dg, void **argStack, size_t *argsizep)
|
||||||
#else
|
#else
|
||||||
void *Callback(DHooksCallback *dg, void **argStack)
|
void *Callback(DHooksCallback *dg, void **argStack)
|
||||||
@ -403,11 +513,12 @@ void *Callback(DHooksCallback *dg, void **argStack)
|
|||||||
Handle_t rHndl;
|
Handle_t rHndl;
|
||||||
Handle_t pHndl;
|
Handle_t pHndl;
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined( WIN32 ) && !defined( PLATFORM_X64 )
|
||||||
*argsizep = GetStackArgsSize(dg);
|
*argsizep = GetStackArgsSize(dg);
|
||||||
#else
|
#else
|
||||||
size_t argsize = GetStackArgsSize(dg);
|
size_t argsize = GetStackArgsSize(dg);
|
||||||
#endif
|
#endif
|
||||||
|
//g_pSM->LogMessage(myself, "[DEFAULT]DHooksCallback(%p) argStack(%p) - argsize(%d)", dg, argStack, argsize);
|
||||||
|
|
||||||
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
|
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
|
||||||
{
|
{
|
||||||
@ -430,15 +541,15 @@ void *Callback(DHooksCallback *dg, void **argStack)
|
|||||||
dg->plugin_callback->PushCell(rHndl);
|
dg->plugin_callback->PushCell(rHndl);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined( WIN32 ) && !defined( PLATFORM_X64 )
|
||||||
if(*argsizep > 0)
|
if(*argsizep > 0)
|
||||||
{
|
{
|
||||||
paramStruct = GetParamStruct(dg, argStack, *argsizep);
|
paramStruct = GetParamStruct(dg, argStack, *argsizep);
|
||||||
#else
|
#else
|
||||||
if(argsize > 0)
|
if(argsize > 0)
|
||||||
{
|
{
|
||||||
paramStruct = GetParamStruct(dg, argStack, argsize);
|
paramStruct = GetParamStruct(dg, argStack, argsize);
|
||||||
#endif
|
#endif
|
||||||
pHndl = handlesys->CreateHandle(g_HookParamsHandle, paramStruct, dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity(), NULL);
|
pHndl = handlesys->CreateHandle(g_HookParamsHandle, paramStruct, dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity(), NULL);
|
||||||
if(!pHndl)
|
if(!pHndl)
|
||||||
{
|
{
|
||||||
@ -575,7 +686,7 @@ void *Callback(DHooksCallback *dg, void **argStack)
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#ifdef WIN32
|
#if defined( WIN32 ) && !defined( PLATFORM_X64 )
|
||||||
float Callback_float(DHooksCallback *dg, void **argStack, size_t *argsizep)
|
float Callback_float(DHooksCallback *dg, void **argStack, size_t *argsizep)
|
||||||
#else
|
#else
|
||||||
float Callback_float(DHooksCallback *dg, void **argStack)
|
float Callback_float(DHooksCallback *dg, void **argStack)
|
||||||
@ -586,11 +697,12 @@ float Callback_float(DHooksCallback *dg, void **argStack)
|
|||||||
Handle_t rHndl;
|
Handle_t rHndl;
|
||||||
Handle_t pHndl;
|
Handle_t pHndl;
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined( WIN32 ) && !defined( PLATFORM_X64 )
|
||||||
*argsizep = GetStackArgsSize(dg);
|
*argsizep = GetStackArgsSize(dg);
|
||||||
#else
|
#else
|
||||||
size_t argsize = GetStackArgsSize(dg);
|
size_t argsize = GetStackArgsSize(dg);
|
||||||
#endif
|
#endif
|
||||||
|
//g_pSM->LogMessage(myself, "[FLOAT]DHooksCallback(%p) argStack(%p) - argsize(%d)", dg, argStack, argsize);
|
||||||
|
|
||||||
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
|
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
|
||||||
{
|
{
|
||||||
@ -612,7 +724,7 @@ float Callback_float(DHooksCallback *dg, void **argStack)
|
|||||||
}
|
}
|
||||||
dg->plugin_callback->PushCell(rHndl);
|
dg->plugin_callback->PushCell(rHndl);
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined( WIN32 ) && !defined( PLATFORM_X64 )
|
||||||
if(*argsizep > 0)
|
if(*argsizep > 0)
|
||||||
{
|
{
|
||||||
paramStruct = GetParamStruct(dg, argStack, *argsizep);
|
paramStruct = GetParamStruct(dg, argStack, *argsizep);
|
||||||
@ -729,24 +841,25 @@ float Callback_float(DHooksCallback *dg, void **argStack)
|
|||||||
}
|
}
|
||||||
return *(float *)ret;
|
return *(float *)ret;
|
||||||
}
|
}
|
||||||
#ifdef WIN32
|
#if defined( WIN32 ) && !defined( PLATFORM_X64 )
|
||||||
SDKVector *Callback_vector(DHooksCallback *dg, void **argStack, size_t *argsizep)
|
SDKVector *Callback_vector(DHooksCallback *dg, void **argStack, size_t *argsizep)
|
||||||
#else
|
#else
|
||||||
SDKVector *Callback_vector(DHooksCallback *dg, void **argStack)
|
SDKVector *Callback_vector(DHooksCallback *dg, void **argStack)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
SDKVector *vec_result = (SDKVector *)argStack[0]; // Save the result
|
SDKVector *vec_result = (SDKVector *)argStack[0];
|
||||||
|
|
||||||
HookReturnStruct *returnStruct = NULL;
|
HookReturnStruct *returnStruct = NULL;
|
||||||
HookParamsStruct *paramStruct = NULL;
|
HookParamsStruct *paramStruct = NULL;
|
||||||
Handle_t rHndl;
|
Handle_t rHndl;
|
||||||
Handle_t pHndl;
|
Handle_t pHndl;
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined( WIN32 ) && !defined( PLATFORM_X64 )
|
||||||
*argsizep = GetStackArgsSize(dg);
|
*argsizep = GetStackArgsSize(dg);
|
||||||
#else
|
#else
|
||||||
size_t argsize = GetStackArgsSize(dg);
|
size_t argsize = GetStackArgsSize(dg);
|
||||||
#endif
|
#endif
|
||||||
|
//g_pSM->LogMessage(myself, "[VECTOR]DHooksCallback(%p) argStack(%p) - argsize(%d) - params count %d", dg, argStack, argsize, dg->params.size());
|
||||||
|
|
||||||
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
|
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
|
||||||
{
|
{
|
||||||
@ -768,7 +881,7 @@ SDKVector *Callback_vector(DHooksCallback *dg, void **argStack)
|
|||||||
}
|
}
|
||||||
dg->plugin_callback->PushCell(rHndl);
|
dg->plugin_callback->PushCell(rHndl);
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined( WIN32 ) && !defined( PLATFORM_X64 )
|
||||||
if(*argsizep > 0)
|
if(*argsizep > 0)
|
||||||
{
|
{
|
||||||
paramStruct = GetParamStruct(dg, argStack, *argsizep);
|
paramStruct = GetParamStruct(dg, argStack, *argsizep);
|
||||||
|
|||||||
@ -39,6 +39,10 @@
|
|||||||
#include <registers.h>
|
#include <registers.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef PLATFORM_X64
|
||||||
|
#include "sh_asm_x86_64.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
enum CallingConvention
|
enum CallingConvention
|
||||||
{
|
{
|
||||||
CallConv_CDECL,
|
CallConv_CDECL,
|
||||||
@ -163,11 +167,20 @@ public:
|
|||||||
class DHooksCallback : public SourceHook::ISHDelegate, public DHooksInfo
|
class DHooksCallback : public SourceHook::ISHDelegate, public DHooksInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
DHooksCallback()
|
||||||
|
{
|
||||||
|
//g_pSM->LogMessage(myself, "DHooksCallback(%p)", this);
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool IsEqual(ISHDelegate *pOtherDeleg){return false;};
|
virtual bool IsEqual(ISHDelegate *pOtherDeleg){return false;};
|
||||||
virtual void DeleteThis()
|
virtual void DeleteThis()
|
||||||
{
|
{
|
||||||
*(void ***)this = this->oldvtable;
|
*(void ***)this = this->oldvtable;
|
||||||
|
#ifdef PLATFORM_X64
|
||||||
|
delete callThunk;
|
||||||
|
#else
|
||||||
g_pSM->GetScriptingEngine()->FreePageMemory(this->newvtable[2]);
|
g_pSM->GetScriptingEngine()->FreePageMemory(this->newvtable[2]);
|
||||||
|
#endif
|
||||||
delete this->newvtable;
|
delete this->newvtable;
|
||||||
delete this;
|
delete this;
|
||||||
};
|
};
|
||||||
@ -175,9 +188,12 @@ public:
|
|||||||
public:
|
public:
|
||||||
void **newvtable;
|
void **newvtable;
|
||||||
void **oldvtable;
|
void **oldvtable;
|
||||||
|
#ifdef PLATFORM_X64
|
||||||
|
SourceHook::Asm::x64JitWriter* callThunk;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined( WIN32 ) && !defined( PLATFORM_X64 )
|
||||||
void *Callback(DHooksCallback *dg, void **stack, size_t *argsizep);
|
void *Callback(DHooksCallback *dg, void **stack, size_t *argsizep);
|
||||||
float Callback_float(DHooksCallback *dg, void **stack, size_t *argsizep);
|
float Callback_float(DHooksCallback *dg, void **stack, size_t *argsizep);
|
||||||
SDKVector *Callback_vector(DHooksCallback *dg, void **stack, size_t *argsizep);
|
SDKVector *Callback_vector(DHooksCallback *dg, void **stack, size_t *argsizep);
|
||||||
@ -192,20 +208,6 @@ bool SetupHookManager(ISmmAPI *ismm);
|
|||||||
void CleanupHooks(IPluginContext *pContext = NULL);
|
void CleanupHooks(IPluginContext *pContext = NULL);
|
||||||
size_t GetParamTypeSize(HookParamType type);
|
size_t GetParamTypeSize(HookParamType type);
|
||||||
SourceHook::PassInfo::PassType GetParamTypePassType(HookParamType type);
|
SourceHook::PassInfo::PassType GetParamTypePassType(HookParamType type);
|
||||||
void *GenerateThunk(ReturnType type);
|
|
||||||
|
|
||||||
static DHooksCallback *MakeHandler(ReturnType type)
|
|
||||||
{
|
|
||||||
DHooksCallback *dg = new DHooksCallback();
|
|
||||||
dg->returnType = type;
|
|
||||||
dg->oldvtable = *(void ***)dg;
|
|
||||||
dg->newvtable = new void *[3];
|
|
||||||
dg->newvtable[0] = dg->oldvtable[0];
|
|
||||||
dg->newvtable[1] = dg->oldvtable[1];
|
|
||||||
dg->newvtable[2] = GenerateThunk(type);
|
|
||||||
*(void ***)dg = dg->newvtable;
|
|
||||||
return dg;
|
|
||||||
}
|
|
||||||
|
|
||||||
class HookParamsStruct
|
class HookParamsStruct
|
||||||
{
|
{
|
||||||
@ -276,6 +278,37 @@ public:
|
|||||||
HookMethod hookMethod;
|
HookMethod hookMethod;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef PLATFORM_X64
|
||||||
|
SourceHook::Asm::x64JitWriter* GenerateThunk(HookSetup* type);
|
||||||
|
static DHooksCallback *MakeHandler(HookSetup* hook)
|
||||||
|
{
|
||||||
|
DHooksCallback *dg = new DHooksCallback();
|
||||||
|
dg->returnType = hook->returnType;
|
||||||
|
dg->oldvtable = *(void ***)dg;
|
||||||
|
dg->newvtable = new void *[3];
|
||||||
|
dg->newvtable[0] = dg->oldvtable[0];
|
||||||
|
dg->newvtable[1] = dg->oldvtable[1];
|
||||||
|
dg->callThunk = GenerateThunk(hook);
|
||||||
|
dg->newvtable[2] = dg->callThunk->GetData();
|
||||||
|
*(void ***)dg = dg->newvtable;
|
||||||
|
return dg;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void *GenerateThunk(HookSetup* type);
|
||||||
|
static DHooksCallback *MakeHandler(HookSetup* hook)
|
||||||
|
{
|
||||||
|
DHooksCallback *dg = new DHooksCallback();
|
||||||
|
dg->returnType = hook->returnType;
|
||||||
|
dg->oldvtable = *(void ***)dg;
|
||||||
|
dg->newvtable = new void *[3];
|
||||||
|
dg->newvtable[0] = dg->oldvtable[0];
|
||||||
|
dg->newvtable[1] = dg->oldvtable[1];
|
||||||
|
dg->newvtable[2] = GenerateThunk(hook);
|
||||||
|
*(void ***)dg = dg->newvtable;
|
||||||
|
return dg;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
class DHooksManager
|
class DHooksManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user