Added Dynamic Hooking to BinTools (bug 2616 r=dvander,DS)
This commit is contained in:
parent
3bdc8583e5
commit
f641aa92f5
@ -29,9 +29,54 @@
|
|||||||
* Version: $Id$
|
* Version: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "CallMaker.h"
|
#include "CallMaker.h"
|
||||||
#include "CallWrapper.h"
|
#include "jit_compile.h"
|
||||||
#include "jit_call.h"
|
#include "extension.h"
|
||||||
|
|
||||||
|
/* SourceMod <==> SourceHook type conversion functions */
|
||||||
|
|
||||||
|
SourceHook::ProtoInfo::CallConvention GetSHCallConvention(SourceMod::CallConvention cv)
|
||||||
|
{
|
||||||
|
if (cv < SourceMod::CallConv_ThisCall || cv > SourceMod::CallConv_Cdecl)
|
||||||
|
{
|
||||||
|
return SourceHook::ProtoInfo::CallConv_Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (SourceHook::ProtoInfo::CallConvention)(cv + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceMod::CallConvention GetSMCallConvention(SourceHook::ProtoInfo::CallConvention cv)
|
||||||
|
{
|
||||||
|
assert(cv >= SourceHook::ProtoInfo::CallConv_ThisCall || cv <= SourceHook::ProtoInfo::CallConv_Cdecl);
|
||||||
|
|
||||||
|
return (SourceMod::CallConvention)(cv - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceHook::PassInfo::PassType GetSHPassType(SourceMod::PassType type)
|
||||||
|
{
|
||||||
|
if (type < SourceMod::PassType_Basic || type > SourceMod::PassType_Object)
|
||||||
|
{
|
||||||
|
return SourceHook::PassInfo::PassType_Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (SourceHook::PassInfo::PassType)(type + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceMod::PassType GetSMPassType(int type)
|
||||||
|
{
|
||||||
|
/* SourceMod doesn't provide an Unknown type so we it must be an error */
|
||||||
|
assert(type >= SourceHook::PassInfo::PassType_Basic && type <= SourceHook::PassInfo::PassType_Object);
|
||||||
|
|
||||||
|
return (SourceMod::PassType)(type - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetSMPassInfo(SourceMod::PassInfo *out, const SourceHook::PassInfo *in)
|
||||||
|
{
|
||||||
|
out->size = in->size;
|
||||||
|
out->flags = in->flags;
|
||||||
|
out->type = GetSMPassType(in->type);
|
||||||
|
}
|
||||||
|
|
||||||
ICallWrapper *CallMaker::CreateCall(void *address,
|
ICallWrapper *CallMaker::CreateCall(void *address,
|
||||||
CallConvention cv,
|
CallConvention cv,
|
||||||
@ -39,12 +84,26 @@ ICallWrapper *CallMaker::CreateCall(void *address,
|
|||||||
const PassInfo paramInfo[],
|
const PassInfo paramInfo[],
|
||||||
unsigned int numParams)
|
unsigned int numParams)
|
||||||
{
|
{
|
||||||
CallWrapper *pWrapper = new CallWrapper(cv, paramInfo, retInfo, numParams);
|
SourceHook::CProtoInfoBuilder protoInfo(GetSHCallConvention(cv));
|
||||||
pWrapper->m_Addrs[ADDR_CALLEE] = address;
|
|
||||||
|
|
||||||
JIT_Compile(pWrapper, FuncAddr_Direct);
|
for (unsigned int i=0; i<numParams; i++)
|
||||||
|
{
|
||||||
|
protoInfo.AddParam(paramInfo[i].size, GetSHPassType(paramInfo[i].type), paramInfo[i].flags,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return pWrapper;
|
if (retInfo)
|
||||||
|
{
|
||||||
|
protoInfo.SetReturnType(retInfo->size, GetSHPassType(retInfo->type), retInfo->flags,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
protoInfo.SetReturnType(0, SourceHook::PassInfo::PassType_Unknown, 0,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_CallMaker2.CreateCall(address, &(*protoInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
|
ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
|
||||||
@ -54,12 +113,73 @@ ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
|
|||||||
const PassInfo paramInfo[],
|
const PassInfo paramInfo[],
|
||||||
unsigned int numParams)
|
unsigned int numParams)
|
||||||
{
|
{
|
||||||
CallWrapper *pWrapper = new CallWrapper(CallConv_ThisCall, paramInfo, retInfo, numParams);
|
SourceHook::MemFuncInfo info;
|
||||||
pWrapper->m_VtInfo.thisOffs = thisOffs;
|
info.isVirtual = true;
|
||||||
pWrapper->m_VtInfo.vtblIdx = vtblIdx;
|
info.vtblindex = vtblIdx;
|
||||||
pWrapper->m_VtInfo.vtblOffs = vtblOffs;
|
info.vtbloffs = vtblOffs;
|
||||||
|
info.thisptroffs = thisOffs;
|
||||||
|
|
||||||
JIT_Compile(pWrapper, FuncAddr_VTable);
|
SourceHook::CProtoInfoBuilder protoInfo(SourceHook::ProtoInfo::CallConv_ThisCall);
|
||||||
|
|
||||||
|
for (unsigned int i=0; i<numParams; i++)
|
||||||
|
{
|
||||||
|
protoInfo.AddParam(paramInfo[i].size, GetSHPassType(paramInfo[i].type), paramInfo[i].flags,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retInfo)
|
||||||
|
{
|
||||||
|
protoInfo.SetReturnType(retInfo->size, GetSHPassType(retInfo->type), retInfo->flags,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
protoInfo.SetReturnType(0, SourceHook::PassInfo::PassType_Unknown, 0,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return g_CallMaker2.CreateVirtualCall(&(*protoInfo), &info);
|
||||||
|
}
|
||||||
|
|
||||||
|
ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo)
|
||||||
|
{
|
||||||
|
CallWrapper *pWrapper = new CallWrapper(protoInfo);
|
||||||
|
pWrapper->SetCalleeAddr(address);
|
||||||
|
|
||||||
|
void *addr = JIT_CallCompile(pWrapper, FuncAddr_Direct);
|
||||||
|
pWrapper->SetCodeBaseAddr(addr);
|
||||||
|
|
||||||
return pWrapper;
|
return pWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
|
||||||
|
const SourceHook::MemFuncInfo *info)
|
||||||
|
{
|
||||||
|
CallWrapper *pWrapper = new CallWrapper(protoInfo);
|
||||||
|
pWrapper->SetMemFuncInfo(info);
|
||||||
|
|
||||||
|
void *addr = JIT_CallCompile(pWrapper, FuncAddr_VTable);
|
||||||
|
pWrapper->SetCodeBaseAddr(addr);
|
||||||
|
|
||||||
|
return pWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined HOOKING_ENABLED
|
||||||
|
IHookWrapper *CallMaker2::CreateVirtualHook(SourceHook::ISourceHook *pSH,
|
||||||
|
const SourceHook::ProtoInfo *protoInfo,
|
||||||
|
const SourceHook::MemFuncInfo *info,
|
||||||
|
VIRTUAL_HOOK_PROTO f)
|
||||||
|
{
|
||||||
|
HookWrapper *pWrapper = new HookWrapper(pSH, protoInfo, const_cast<SourceHook::MemFuncInfo *>(info), (void *)f);
|
||||||
|
|
||||||
|
void *addr = JIT_HookCompile(pWrapper);
|
||||||
|
pWrapper->SetHookWrpAddr(addr);
|
||||||
|
|
||||||
|
ICallWrapper *callWrap = CreateVirtualCall(protoInfo, info);
|
||||||
|
pWrapper->SetCallWrapperAddr(callWrap);
|
||||||
|
|
||||||
|
return pWrapper;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@ -32,16 +32,12 @@
|
|||||||
#ifndef _INCLUDE_SOURCEMOD_CALLMAKER_H_
|
#ifndef _INCLUDE_SOURCEMOD_CALLMAKER_H_
|
||||||
#define _INCLUDE_SOURCEMOD_CALLMAKER_H_
|
#define _INCLUDE_SOURCEMOD_CALLMAKER_H_
|
||||||
|
|
||||||
#include <IBinTools.h>
|
|
||||||
|
#include "CallWrapper.h"
|
||||||
|
#include "HookWrapper.h"
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
|
||||||
enum FuncAddrMethod
|
|
||||||
{
|
|
||||||
FuncAddr_Direct,
|
|
||||||
FuncAddr_VTable
|
|
||||||
};
|
|
||||||
|
|
||||||
class CallMaker : public IBinTools
|
class CallMaker : public IBinTools
|
||||||
{
|
{
|
||||||
public: //IBinTools
|
public: //IBinTools
|
||||||
@ -58,4 +54,32 @@ public: //IBinTools
|
|||||||
unsigned int numParams);
|
unsigned int numParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CallMaker2
|
||||||
|
#if defined HOOKING_ENABLED
|
||||||
|
: public IBinTools2
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
public: //IBinTools2
|
||||||
|
virtual ICallWrapper *CreateCall(void *address,
|
||||||
|
const SourceHook::ProtoInfo *protoInfo);
|
||||||
|
virtual ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
|
||||||
|
const SourceHook::MemFuncInfo *info);
|
||||||
|
#if defined HOOKING_ENABLED
|
||||||
|
virtual IHookWrapper *CreateVirtualHook(SourceHook::ISourceHook *pSH,
|
||||||
|
const SourceHook::ProtoInfo *protoInfo,
|
||||||
|
const SourceHook::MemFuncInfo *info,
|
||||||
|
VIRTUAL_HOOK_PROTO f);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
extern CallMaker2 g_CallMaker2;
|
||||||
|
|
||||||
|
SourceHook::ProtoInfo::CallConvention GetSHCallConvention(SourceMod::CallConvention cv);
|
||||||
|
SourceMod::CallConvention GetSMCallConvention(SourceHook::ProtoInfo::CallConvention cv);
|
||||||
|
SourceHook::PassInfo::PassType GetSHPassType(SourceMod::PassType type);
|
||||||
|
SourceMod::PassType GetSMPassType(int type);
|
||||||
|
void GetSMPassInfo(SourceMod::PassInfo *out, const SourceHook::PassInfo *in);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_CALLMAKER_H_
|
#endif //_INCLUDE_SOURCEMOD_CALLMAKER_H_
|
||||||
|
@ -31,40 +31,46 @@
|
|||||||
|
|
||||||
#include "extension.h"
|
#include "extension.h"
|
||||||
#include "CallWrapper.h"
|
#include "CallWrapper.h"
|
||||||
|
#include "CallMaker.h"
|
||||||
|
|
||||||
CallWrapper::CallWrapper(CallConvention cv, const PassInfo *paramInfo, const PassInfo *retInfo, unsigned int numParams)
|
CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo)
|
||||||
{
|
{
|
||||||
m_Cv = cv;
|
m_AddrCodeBase = NULL;
|
||||||
|
m_AddrCallee = NULL;
|
||||||
|
|
||||||
if (numParams)
|
unsigned int argnum = protoInfo->numOfParams;
|
||||||
|
|
||||||
|
m_Info = *protoInfo;
|
||||||
|
m_Info.paramsPassInfo = new SourceHook::PassInfo[argnum + 1];
|
||||||
|
memcpy((void *)m_Info.paramsPassInfo, protoInfo->paramsPassInfo, sizeof(SourceHook::PassInfo) * (argnum+1));
|
||||||
|
|
||||||
|
if (argnum)
|
||||||
{
|
{
|
||||||
m_Params = new PassEncode[numParams];
|
m_Params = new PassEncode[argnum];
|
||||||
for (size_t i=0; i<numParams; i++)
|
for (size_t i=0; i<argnum; i++)
|
||||||
{
|
{
|
||||||
m_Params[i].info = paramInfo[i];
|
GetSMPassInfo(&(m_Params[i].info), &(m_Info.paramsPassInfo[i+1]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_Params = NULL;
|
m_Params = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retInfo)
|
if (m_Info.retPassInfo.size != 0)
|
||||||
{
|
{
|
||||||
m_RetParam = new PassInfo;
|
m_RetParam = new PassInfo;
|
||||||
*m_RetParam = *retInfo;
|
GetSMPassInfo(m_RetParam, &(m_Info.retPassInfo));
|
||||||
} else {
|
} else {
|
||||||
m_RetParam = NULL;
|
m_RetParam = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_NumParams = numParams;
|
|
||||||
|
|
||||||
/* Calculate virtual stack offsets for each parameter */
|
/* Calculate virtual stack offsets for each parameter */
|
||||||
size_t offs = 0;
|
size_t offs = 0;
|
||||||
|
|
||||||
if (cv == CallConv_ThisCall)
|
if (m_Info.convention == SourceHook::ProtoInfo::CallConv_ThisCall)
|
||||||
{
|
{
|
||||||
offs += sizeof(void *);
|
offs += sizeof(void *);
|
||||||
}
|
}
|
||||||
for (size_t i=0; i<numParams; i++)
|
for (size_t i=0; i<argnum; i++)
|
||||||
{
|
{
|
||||||
m_Params[i].offset = offs;
|
m_Params[i].offset = offs;
|
||||||
offs += m_Params[i].info.size;
|
offs += m_Params[i].info.size;
|
||||||
@ -75,22 +81,34 @@ CallWrapper::~CallWrapper()
|
|||||||
{
|
{
|
||||||
delete [] m_Params;
|
delete [] m_Params;
|
||||||
delete m_RetParam;
|
delete m_RetParam;
|
||||||
g_SPEngine->FreePageMemory(m_Addrs[ADDR_CODEBASE]);
|
delete [] m_Info.paramsPassInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallWrapper::Destroy()
|
void CallWrapper::Destroy()
|
||||||
{
|
{
|
||||||
|
if (m_AddrCodeBase != NULL)
|
||||||
|
{
|
||||||
|
g_SPEngine->FreePageMemory(m_AddrCodeBase);
|
||||||
|
m_AddrCodeBase = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CallConvention CallWrapper::GetCallConvention()
|
CallConvention CallWrapper::GetCallConvention()
|
||||||
{
|
{
|
||||||
return m_Cv;
|
/* Need to convert to a SourceMod convention for bcompat */
|
||||||
|
return GetSMCallConvention((SourceHook::ProtoInfo::CallConvention)m_Info.convention);
|
||||||
}
|
}
|
||||||
|
|
||||||
const PassEncode *CallWrapper::GetParamInfo(unsigned int num)
|
const PassEncode *CallWrapper::GetParamInfo(unsigned int num)
|
||||||
{
|
{
|
||||||
return (num+1 > m_NumParams) ? NULL : &m_Params[num];
|
if (num + 1 > GetParamCount() || num < 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &m_Params[num];
|
||||||
}
|
}
|
||||||
|
|
||||||
const PassInfo *CallWrapper::GetReturnInfo()
|
const PassInfo *CallWrapper::GetReturnInfo()
|
||||||
@ -100,12 +118,69 @@ const PassInfo *CallWrapper::GetReturnInfo()
|
|||||||
|
|
||||||
unsigned int CallWrapper::GetParamCount()
|
unsigned int CallWrapper::GetParamCount()
|
||||||
{
|
{
|
||||||
return m_NumParams;
|
return m_Info.numOfParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallWrapper::Execute(void *vParamStack, void *retBuffer)
|
void CallWrapper::Execute(void *vParamStack, void *retBuffer)
|
||||||
{
|
{
|
||||||
typedef void (*CALL_EXECUTE)(void *, void *);
|
typedef void (*CALL_EXECUTE)(void *, void *);
|
||||||
CALL_EXECUTE fn = (CALL_EXECUTE)m_Addrs[ADDR_CODEBASE];
|
CALL_EXECUTE fn = (CALL_EXECUTE)GetCodeBaseAddr();
|
||||||
fn(vParamStack, retBuffer);
|
fn(vParamStack, retBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CallWrapper::SetMemFuncInfo(const SourceHook::MemFuncInfo *funcInfo)
|
||||||
|
{
|
||||||
|
m_FuncInfo = *funcInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceHook::MemFuncInfo *CallWrapper::GetMemFuncInfo()
|
||||||
|
{
|
||||||
|
return &m_FuncInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CallWrapper::SetCalleeAddr(void *addr)
|
||||||
|
{
|
||||||
|
m_AddrCallee = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CallWrapper::SetCodeBaseAddr(void *addr)
|
||||||
|
{
|
||||||
|
m_AddrCodeBase = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *CallWrapper::GetCalleeAddr()
|
||||||
|
{
|
||||||
|
return m_AddrCallee;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *CallWrapper::GetCodeBaseAddr()
|
||||||
|
{
|
||||||
|
return m_AddrCodeBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SourceHook::PassInfo *CallWrapper::GetSHReturnInfo()
|
||||||
|
{
|
||||||
|
return &(m_Info.retPassInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceHook::ProtoInfo::CallConvention CallWrapper::GetSHCallConvention()
|
||||||
|
{
|
||||||
|
return (SourceHook::ProtoInfo::CallConvention)m_Info.convention;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SourceHook::PassInfo * CallWrapper::GetSHParamInfo(unsigned int num)
|
||||||
|
{
|
||||||
|
if (num + 1 > GetParamCount() || num < 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &(m_Info.paramsPassInfo[num+1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CallWrapper::GetParamOffset(unsigned int num)
|
||||||
|
{
|
||||||
|
assert(num <= GetParamCount() && num > 0);
|
||||||
|
|
||||||
|
return m_Params[num].offset;
|
||||||
|
}
|
||||||
|
@ -29,27 +29,24 @@
|
|||||||
* Version: $Id$
|
* Version: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _INCLUDE_SOURCEMOD_CCALLWRAPPER_H_
|
#ifndef _INCLUDE_SOURCEMOD_CALLWRAPPER_H_
|
||||||
#define _INCLUDE_SOURCEMOD_CCALLWRAPPER_H_
|
#define _INCLUDE_SOURCEMOD_CALLWRAPPER_H_
|
||||||
|
|
||||||
#include <IBinTools.h>
|
#include <IBinTools.h>
|
||||||
|
#include <sourcehook_pibuilder.h>
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
|
||||||
#define ADDR_CALLEE 0
|
enum FuncAddrMethod
|
||||||
#define ADDR_CODEBASE 1
|
|
||||||
|
|
||||||
struct VtableInfo
|
|
||||||
{
|
{
|
||||||
unsigned int vtblIdx;
|
FuncAddr_Direct,
|
||||||
unsigned int vtblOffs;
|
FuncAddr_VTable
|
||||||
unsigned int thisOffs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CallWrapper : public ICallWrapper
|
class CallWrapper : public ICallWrapper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CallWrapper(CallConvention cv, const PassInfo *paramInfo, const PassInfo *retInfo, unsigned int numParams);
|
CallWrapper(const SourceHook::ProtoInfo *protoInfo);
|
||||||
~CallWrapper();
|
~CallWrapper();
|
||||||
public: //ICallWrapper
|
public: //ICallWrapper
|
||||||
CallConvention GetCallConvention();
|
CallConvention GetCallConvention();
|
||||||
@ -58,15 +55,25 @@ public: //ICallWrapper
|
|||||||
unsigned int GetParamCount();
|
unsigned int GetParamCount();
|
||||||
void Execute(void *vParamStack, void *retBuffer);
|
void Execute(void *vParamStack, void *retBuffer);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
const SourceHook::PassInfo *GetSHReturnInfo();
|
||||||
|
SourceHook::ProtoInfo::CallConvention GetSHCallConvention();
|
||||||
|
const SourceHook::PassInfo *GetSHParamInfo(unsigned int num);
|
||||||
|
unsigned int GetParamOffset(unsigned int num);
|
||||||
public:
|
public:
|
||||||
inline void deleteThis() { delete this; }
|
void SetCalleeAddr(void *addr);
|
||||||
void *m_Addrs[4];
|
void SetCodeBaseAddr(void *addr);
|
||||||
VtableInfo m_VtInfo;
|
void *GetCalleeAddr();
|
||||||
|
void *GetCodeBaseAddr();
|
||||||
|
|
||||||
|
void SetMemFuncInfo(const SourceHook::MemFuncInfo *funcInfo);
|
||||||
|
SourceHook::MemFuncInfo *GetMemFuncInfo();
|
||||||
private:
|
private:
|
||||||
CallConvention m_Cv;
|
|
||||||
PassEncode *m_Params;
|
PassEncode *m_Params;
|
||||||
|
SourceHook::ProtoInfo m_Info;
|
||||||
PassInfo *m_RetParam;
|
PassInfo *m_RetParam;
|
||||||
unsigned int m_NumParams;
|
void *m_AddrCallee;
|
||||||
|
void *m_AddrCodeBase;
|
||||||
|
SourceHook::MemFuncInfo m_FuncInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_CCALLWRAPPER_H_
|
#endif //_INCLUDE_SOURCEMOD_CALLWRAPPER_H_
|
||||||
|
243
extensions/bintools/HookWrapper.cpp
Normal file
243
extensions/bintools/HookWrapper.cpp
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* =============================================================================
|
||||||
|
* SourceMod BinTools Extension
|
||||||
|
* Copyright (C) 2004-2008 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: CallMaker.h 1964 2008-03-27 04:54:56Z damagedsoul $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined HOOKING_ENABLED
|
||||||
|
|
||||||
|
#include "HookWrapper.h"
|
||||||
|
#include "jit_compile.h"
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
* HookWrapper Implementation *
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
HookWrapper::HookWrapper(SourceHook::ISourceHook *pSH,
|
||||||
|
const SourceHook::ProtoInfo *proto,
|
||||||
|
SourceHook::MemFuncInfo *memfunc,
|
||||||
|
void *addr) : m_ParamOffs(NULL), m_ParamSize(0), m_RetSize(0)
|
||||||
|
{
|
||||||
|
unsigned int argnum = proto->numOfParams;
|
||||||
|
|
||||||
|
m_pSH = pSH;
|
||||||
|
m_ProtoInfo = *proto;
|
||||||
|
m_ProtoInfo.paramsPassInfo = new SourceHook::PassInfo[argnum + 1];
|
||||||
|
memcpy((void *)m_ProtoInfo.paramsPassInfo, proto->paramsPassInfo, sizeof(SourceHook::PassInfo) * (argnum+1));
|
||||||
|
m_MemFuncInfo = *memfunc;
|
||||||
|
m_FuncAddr = addr;
|
||||||
|
m_HookWrapper = NULL;
|
||||||
|
|
||||||
|
/* If the function has parameters calculate the parameter buffer size and offsets */
|
||||||
|
if (argnum > 0)
|
||||||
|
{
|
||||||
|
const SourceHook::PassInfo *info = m_ProtoInfo.paramsPassInfo;
|
||||||
|
m_ParamOffs = new unsigned int[argnum];
|
||||||
|
m_ParamOffs[0] = 0;
|
||||||
|
|
||||||
|
for (unsigned int i=1; i<=argnum; i++)
|
||||||
|
{
|
||||||
|
/* The stack should be at least aligned to a 4 byte boundary
|
||||||
|
* and byref params have the size of pointers
|
||||||
|
*/
|
||||||
|
if (((info[i].type == SourceHook::PassInfo::PassType_Basic) &&
|
||||||
|
(info[i].flags & SourceHook::PassInfo::PassFlag_ByVal) &&
|
||||||
|
(info[i].size < sizeof(void *))) ||
|
||||||
|
(info[i].flags & SourceHook::PassInfo::PassFlag_ByRef))
|
||||||
|
{
|
||||||
|
m_ParamSize += sizeof(void *);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ParamSize += info[i].size;
|
||||||
|
}
|
||||||
|
|
||||||
|
//:TODO: fix this!
|
||||||
|
if (i < argnum)
|
||||||
|
{
|
||||||
|
m_ParamOffs[i] = m_ParamSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally calculate the retval size if any */
|
||||||
|
size_t retsize = m_ProtoInfo.retPassInfo.size;
|
||||||
|
if (retsize != 0)
|
||||||
|
{
|
||||||
|
if (m_ProtoInfo.retPassInfo.flags & SourceHook::PassInfo::PassFlag_ByRef)
|
||||||
|
{
|
||||||
|
m_RetSize = sizeof(void *);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_RetSize = (retsize < sizeof(void *)) ? sizeof(void *) : retsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISMDelegate *HookWrapper::CreateDelegate(void *data)
|
||||||
|
{
|
||||||
|
SMDelegate *pDeleg = new SMDelegate(data);
|
||||||
|
pDeleg->PatchVtable(m_HookWrapper);
|
||||||
|
|
||||||
|
return pDeleg;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int HookWrapper::GetParamCount()
|
||||||
|
{
|
||||||
|
return m_ProtoInfo.numOfParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int HookWrapper::GetParamOffset(unsigned int argnum, unsigned int *size)
|
||||||
|
{
|
||||||
|
assert(m_ParamOffs && argnum < (unsigned int)m_ProtoInfo.numOfParams);
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
{
|
||||||
|
*size = m_ProtoInfo.paramsPassInfo[argnum+1].size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_ParamOffs[argnum];
|
||||||
|
}
|
||||||
|
|
||||||
|
void HookWrapper::PerformRecall(void *params, void *retval)
|
||||||
|
{
|
||||||
|
/* Notify SourceHook of the upcoming recall */
|
||||||
|
SH_GLOB_SHPTR->DoRecall();
|
||||||
|
|
||||||
|
/* Add thisptr into params buffer */
|
||||||
|
unsigned char *newparams = new unsigned char[sizeof(void *) + m_ParamSize];
|
||||||
|
*(void **)newparams = META_IFACEPTR(void);
|
||||||
|
memcpy(newparams + sizeof(void *), params, m_ParamSize);
|
||||||
|
|
||||||
|
/* Execute the call */
|
||||||
|
m_CallWrapper->Execute(newparams, retval);
|
||||||
|
|
||||||
|
SET_META_RESULT(MRES_SUPERCEDE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HookWrapper::Destroy()
|
||||||
|
{
|
||||||
|
if (m_HookWrapper != NULL)
|
||||||
|
{
|
||||||
|
JIT_FreeHook(m_HookWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_CallWrapper != NULL)
|
||||||
|
{
|
||||||
|
m_CallWrapper->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int HookWrapper::GetParamSize()
|
||||||
|
{
|
||||||
|
return m_ParamSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceHook::ProtoInfo * HookWrapper::GetProtoInfo()
|
||||||
|
{
|
||||||
|
return &m_ProtoInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int HookWrapper::GetRetSize()
|
||||||
|
{
|
||||||
|
return m_RetSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * HookWrapper::GetHandlerAddr()
|
||||||
|
{
|
||||||
|
return m_FuncAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HookWrapper::SetCallWrapperAddr( ICallWrapper *wrap )
|
||||||
|
{
|
||||||
|
m_CallWrapper = wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HookWrapper::SetHookWrpAddr( void *addr )
|
||||||
|
{
|
||||||
|
m_HookWrapper = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HookWrapper::~HookWrapper()
|
||||||
|
{
|
||||||
|
delete [] m_ProtoInfo.paramsPassInfo;
|
||||||
|
delete [] m_ParamOffs;
|
||||||
|
}
|
||||||
|
/*****************************
|
||||||
|
* SMDelegate Implementation *
|
||||||
|
*****************************/
|
||||||
|
|
||||||
|
SMDelegate::SMDelegate(void *data)
|
||||||
|
{
|
||||||
|
m_Data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMDelegate::IsEqual(ISHDelegate *pOtherDeleg)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMDelegate::DeleteThis()
|
||||||
|
{
|
||||||
|
/* Remove our allocated vtable */
|
||||||
|
delete [] *reinterpret_cast<void ***>(this);
|
||||||
|
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMDelegate::Call()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void *SMDelegate::GetUserData()
|
||||||
|
{
|
||||||
|
return m_Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This duplicates the vtable (so each instance has a unique table) and patches SMDelgate::Call to point to our allocated function
|
||||||
|
*/
|
||||||
|
void SMDelegate::PatchVtable(void *addr)
|
||||||
|
{
|
||||||
|
void **new_vtptr = new void *[4];
|
||||||
|
void **cur_vtptr = *reinterpret_cast<void ***>(this);
|
||||||
|
memcpy(new_vtptr, cur_vtptr, sizeof(void *)*4);
|
||||||
|
|
||||||
|
*reinterpret_cast<void ***>(this) = new_vtptr;
|
||||||
|
|
||||||
|
void *cur_vfnptr = reinterpret_cast<void *>(new_vtptr + VTABLE_PATCH_OFFS);
|
||||||
|
|
||||||
|
*reinterpret_cast<void **>(cur_vfnptr) = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
97
extensions/bintools/HookWrapper.h
Normal file
97
extensions/bintools/HookWrapper.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* =============================================================================
|
||||||
|
* SourceMod BinTools Extension
|
||||||
|
* Copyright (C) 2004-2008 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: CallMaker.h 1964 2008-03-27 04:54:56Z damagedsoul $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_SOURCEMOD_HOOKWRAPPER_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_HOOKWRAPPER_H_
|
||||||
|
|
||||||
|
#if defined HOOKING_ENABLED
|
||||||
|
|
||||||
|
#include "smsdk_ext.h"
|
||||||
|
#include "sourcehook.h"
|
||||||
|
#include "IBinTools.h"
|
||||||
|
|
||||||
|
#define VTABLE_PATCH_OFFS 2
|
||||||
|
|
||||||
|
using namespace SourceMod;
|
||||||
|
|
||||||
|
class HookWrapper : public IHookWrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HookWrapper(SourceHook::ISourceHook *pSH,
|
||||||
|
const SourceHook::ProtoInfo *proto,
|
||||||
|
SourceHook::MemFuncInfo *memfunc,
|
||||||
|
void *addr
|
||||||
|
);
|
||||||
|
~HookWrapper();
|
||||||
|
public: //IHookWrapper
|
||||||
|
ISMDelegate *CreateDelegate(void *data);
|
||||||
|
unsigned int GetParamCount();
|
||||||
|
unsigned int GetParamOffset(unsigned int argnum, unsigned int *size);
|
||||||
|
void PerformRecall(void *params, void *retval);
|
||||||
|
void Destroy();
|
||||||
|
public:
|
||||||
|
unsigned int GetParamSize();
|
||||||
|
unsigned int GetRetSize();
|
||||||
|
SourceHook::ProtoInfo *GetProtoInfo();
|
||||||
|
void *GetHandlerAddr();
|
||||||
|
void SetHookWrpAddr(void *addr);
|
||||||
|
void SetCallWrapperAddr(ICallWrapper *wrap);
|
||||||
|
private:
|
||||||
|
void *m_FuncAddr;
|
||||||
|
void *m_HookWrapper;
|
||||||
|
SourceHook::ISourceHook *m_pSH;
|
||||||
|
unsigned int *m_ParamOffs;
|
||||||
|
unsigned int m_ParamSize;
|
||||||
|
unsigned int m_RetSize;
|
||||||
|
SourceHook::MemFuncInfo m_MemFuncInfo;
|
||||||
|
SourceHook::ProtoInfo m_ProtoInfo;
|
||||||
|
ICallWrapper *m_CallWrapper;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SMDelegate : public ISMDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SMDelegate(void *data);
|
||||||
|
public: //SourceHook::ISHDelegate
|
||||||
|
bool IsEqual(ISHDelegate *pOtherDeleg);
|
||||||
|
void DeleteThis();
|
||||||
|
void Call();
|
||||||
|
public: //ISMDelegate
|
||||||
|
void *GetUserData();
|
||||||
|
public:
|
||||||
|
void PatchVtable(void *addr);
|
||||||
|
private:
|
||||||
|
void *m_Data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SOURCEMOD_HOOKWRAPPER_H_
|
@ -14,10 +14,7 @@ MMSOURCE17 = ../../../mmsource-1.7
|
|||||||
|
|
||||||
PROJECT = bintools
|
PROJECT = bintools
|
||||||
|
|
||||||
#Uncomment for Metamod: Source enabled extension
|
OBJECTS = sdk/smsdk_ext.cpp extension.cpp jit_call.cpp CallWrapper.cpp CallMaker.cpp HookWrapper.cpp jit_hook.cpp
|
||||||
#USEMETA = true
|
|
||||||
|
|
||||||
OBJECTS = sdk/smsdk_ext.cpp extension.cpp jit_call.cpp CallWrapper.cpp CallMaker.cpp
|
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
||||||
@ -49,6 +46,8 @@ ifeq "$(ENGINE)" "orangebox"
|
|||||||
INCLUDE += -I$(HL2SDK)/public/game/server
|
INCLUDE += -I$(HL2SDK)/public/game/server
|
||||||
SRCDS = $(SRCDS_BASE)/orangebox
|
SRCDS = $(SRCDS_BASE)/orangebox
|
||||||
override ENGSET = true
|
override ENGSET = true
|
||||||
|
USEMETA = true
|
||||||
|
CFLAGS += -DHOOKING_ENABLED
|
||||||
endif
|
endif
|
||||||
ifeq "$(ENGINE)" "left4dead"
|
ifeq "$(ENGINE)" "left4dead"
|
||||||
HL2SDK = $(HL2SDK_L4D)
|
HL2SDK = $(HL2SDK_L4D)
|
||||||
@ -59,6 +58,8 @@ ifeq "$(ENGINE)" "left4dead"
|
|||||||
INCLUDE += -I$(HL2SDK)/public/game/server
|
INCLUDE += -I$(HL2SDK)/public/game/server
|
||||||
SRCDS = $(SRCDS_BASE)/l4d
|
SRCDS = $(SRCDS_BASE)/l4d
|
||||||
override ENGSET = true
|
override ENGSET = true
|
||||||
|
USEMETA = true
|
||||||
|
CFLAGS += -DHOOKING_ENABLED
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "$(USEMETA)" "true"
|
ifeq "$(USEMETA)" "true"
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
BinTools g_BinTools; /**< Global singleton for extension's main interface */
|
BinTools g_BinTools; /**< Global singleton for extension's main interface */
|
||||||
CallMaker g_CallMaker;
|
CallMaker g_CallMaker;
|
||||||
|
CallMaker2 g_CallMaker2;
|
||||||
ISourcePawnEngine *g_SPEngine;
|
ISourcePawnEngine *g_SPEngine;
|
||||||
|
|
||||||
SMEXT_LINK(&g_BinTools);
|
SMEXT_LINK(&g_BinTools);
|
||||||
@ -47,6 +48,9 @@ bool BinTools::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
|||||||
{
|
{
|
||||||
g_SPEngine = g_pSM->GetScriptingEngine();
|
g_SPEngine = g_pSM->GetScriptingEngine();
|
||||||
g_pShareSys->AddInterface(myself, &g_CallMaker);
|
g_pShareSys->AddInterface(myself, &g_CallMaker);
|
||||||
|
#if defined METAMOD_PLAPI_VERSION
|
||||||
|
g_pShareSys->AddInterface(myself, &g_CallMaker2);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -33,38 +33,12 @@
|
|||||||
#include "extension.h"
|
#include "extension.h"
|
||||||
#include <jit_helpers.h>
|
#include <jit_helpers.h>
|
||||||
#include <x86_macros.h>
|
#include <x86_macros.h>
|
||||||
#include "jit_call.h"
|
#include "jit_compile.h"
|
||||||
|
|
||||||
jit_uint32_t g_StackUsage = 0;
|
jit_uint32_t g_StackUsage = 0;
|
||||||
jit_uint32_t g_StackAlign = 0;
|
jit_uint32_t g_StackAlign = 0;
|
||||||
jit_uint32_t g_RegDecoder = 0;
|
jit_uint32_t g_RegDecoder = 0;
|
||||||
|
|
||||||
/********************
|
|
||||||
* Assembly Helpers *
|
|
||||||
********************/
|
|
||||||
|
|
||||||
inline jit_uint8_t _DecodeRegister3(jit_uint32_t val)
|
|
||||||
{
|
|
||||||
switch (val % 3)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
return REG_EAX;
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
return REG_EDX;
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
return REG_ECX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Should never happen */
|
|
||||||
return 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************
|
/********************
|
||||||
* Assembly Opcodes *
|
* Assembly Opcodes *
|
||||||
********************/
|
********************/
|
||||||
@ -137,25 +111,25 @@ inline void Write_Function_Epilogue(JitWriter *jit, bool is_void, bool has_param
|
|||||||
IA32_Return(jit);
|
IA32_Return(jit);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Write_PushPOD(JitWriter *jit, const PassEncode *pEnc)
|
inline void Write_PushPOD(JitWriter *jit, const SourceHook::PassInfo *info, unsigned int offset)
|
||||||
{
|
{
|
||||||
jit_uint8_t reg = _DecodeRegister3(g_RegDecoder++);
|
jit_uint8_t reg = _DecodeRegister3(g_RegDecoder++);
|
||||||
|
|
||||||
if (pEnc->info.flags & PASSFLAG_BYVAL)
|
if (info->flags & PASSFLAG_BYVAL)
|
||||||
{
|
{
|
||||||
switch (pEnc->info.size)
|
switch (info->size)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
//movzx reg, BYTE PTR [ebx+<offset>]
|
//movzx reg, BYTE PTR [ebx+<offset>]
|
||||||
//push reg
|
//push reg
|
||||||
if (pEnc->offset < SCHAR_MAX)
|
if (offset < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Movzx_Reg32_Rm8_Disp8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
|
IA32_Movzx_Reg32_Rm8_Disp8(jit, reg, REG_EBX, (jit_int8_t)offset);
|
||||||
} else if (!pEnc->offset) {
|
} else if (!offset) {
|
||||||
IA32_Movzx_Reg32_Rm8(jit, reg, REG_EBX, MOD_MEM_REG);
|
IA32_Movzx_Reg32_Rm8(jit, reg, REG_EBX, MOD_MEM_REG);
|
||||||
} else {
|
} else {
|
||||||
IA32_Movzx_Reg32_Rm8_Disp32(jit, reg, REG_EBX, pEnc->offset);
|
IA32_Movzx_Reg32_Rm8_Disp32(jit, reg, REG_EBX, offset);
|
||||||
}
|
}
|
||||||
IA32_Push_Reg(jit, reg);
|
IA32_Push_Reg(jit, reg);
|
||||||
|
|
||||||
@ -167,13 +141,13 @@ inline void Write_PushPOD(JitWriter *jit, const PassEncode *pEnc)
|
|||||||
//movzx reg, WORD PTR [ebx+<offset>]
|
//movzx reg, WORD PTR [ebx+<offset>]
|
||||||
//push reg
|
//push reg
|
||||||
jit->write_ubyte(IA32_16BIT_PREFIX);
|
jit->write_ubyte(IA32_16BIT_PREFIX);
|
||||||
if (pEnc->offset < SCHAR_MAX)
|
if (offset < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Movzx_Reg32_Rm16_Disp8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
|
IA32_Movzx_Reg32_Rm16_Disp8(jit, reg, REG_EBX, (jit_int8_t)offset);
|
||||||
} else if (!pEnc->offset) {
|
} else if (!offset) {
|
||||||
IA32_Movzx_Reg32_Rm16(jit, reg, REG_EBX, MOD_MEM_REG);
|
IA32_Movzx_Reg32_Rm16(jit, reg, REG_EBX, MOD_MEM_REG);
|
||||||
} else {
|
} else {
|
||||||
IA32_Movzx_Reg32_Rm16_Disp32(jit, reg, REG_EBX, pEnc->offset);
|
IA32_Movzx_Reg32_Rm16_Disp32(jit, reg, REG_EBX, offset);
|
||||||
}
|
}
|
||||||
IA32_Push_Reg(jit, reg);
|
IA32_Push_Reg(jit, reg);
|
||||||
|
|
||||||
@ -184,13 +158,13 @@ inline void Write_PushPOD(JitWriter *jit, const PassEncode *pEnc)
|
|||||||
{
|
{
|
||||||
//mov reg, DWORD PTR [ebx+<offset>]
|
//mov reg, DWORD PTR [ebx+<offset>]
|
||||||
//push reg
|
//push reg
|
||||||
if (pEnc->offset < SCHAR_MAX)
|
if (offset < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
|
IA32_Mov_Reg_Rm_Disp8(jit, reg, REG_EBX, (jit_int8_t)offset);
|
||||||
} else if (!pEnc->offset) {
|
} else if (!offset) {
|
||||||
IA32_Mov_Reg_Rm(jit, reg, REG_EBX, MOD_MEM_REG);
|
IA32_Mov_Reg_Rm(jit, reg, REG_EBX, MOD_MEM_REG);
|
||||||
} else {
|
} else {
|
||||||
IA32_Mov_Reg_Rm_Disp32(jit, reg, REG_EBX, pEnc->offset);
|
IA32_Mov_Reg_Rm_Disp32(jit, reg, REG_EBX, offset);
|
||||||
}
|
}
|
||||||
IA32_Push_Reg(jit, reg);
|
IA32_Push_Reg(jit, reg);
|
||||||
|
|
||||||
@ -205,19 +179,19 @@ inline void Write_PushPOD(JitWriter *jit, const PassEncode *pEnc)
|
|||||||
//push reg2
|
//push reg2
|
||||||
jit_uint8_t reg2 = _DecodeRegister3(g_RegDecoder++);
|
jit_uint8_t reg2 = _DecodeRegister3(g_RegDecoder++);
|
||||||
|
|
||||||
if (pEnc->offset+4 < SCHAR_MAX)
|
if (offset+4 < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, reg, REG_EBX, (jit_int8_t)(pEnc->offset+4));
|
IA32_Mov_Reg_Rm_Disp8(jit, reg, REG_EBX, (jit_int8_t)(offset+4));
|
||||||
} else {
|
} else {
|
||||||
IA32_Mov_Reg_Rm_Disp32(jit, reg, REG_EBX, pEnc->offset+4);
|
IA32_Mov_Reg_Rm_Disp32(jit, reg, REG_EBX, offset+4);
|
||||||
}
|
}
|
||||||
if (pEnc->offset < SCHAR_MAX)
|
if (offset < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Mov_Reg_Rm_Disp8(jit, reg2, REG_EBX, (jit_int8_t)pEnc->offset);
|
IA32_Mov_Reg_Rm_Disp8(jit, reg2, REG_EBX, (jit_int8_t)offset);
|
||||||
} else if (!pEnc->offset) {
|
} else if (!offset) {
|
||||||
IA32_Mov_Reg_Rm(jit, reg2, REG_EBX, MOD_MEM_REG);
|
IA32_Mov_Reg_Rm(jit, reg2, REG_EBX, MOD_MEM_REG);
|
||||||
} else {
|
} else {
|
||||||
IA32_Mov_Reg_Rm_Disp32(jit, reg2, REG_EBX, pEnc->offset);
|
IA32_Mov_Reg_Rm_Disp32(jit, reg2, REG_EBX, offset);
|
||||||
}
|
}
|
||||||
IA32_Push_Reg(jit, reg);
|
IA32_Push_Reg(jit, reg);
|
||||||
IA32_Push_Reg(jit, reg2);
|
IA32_Push_Reg(jit, reg2);
|
||||||
@ -226,20 +200,20 @@ inline void Write_PushPOD(JitWriter *jit, const PassEncode *pEnc)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (pEnc->info.flags & PASSFLAG_BYREF) {
|
} else if (info->flags & PASSFLAG_BYREF) {
|
||||||
//lea reg, [ebx+<offset>]
|
//lea reg, [ebx+<offset>]
|
||||||
//push reg
|
//push reg
|
||||||
if (!pEnc->offset)
|
if (!offset)
|
||||||
{
|
{
|
||||||
IA32_Push_Reg(jit, REG_EBX);
|
IA32_Push_Reg(jit, REG_EBX);
|
||||||
g_StackUsage += 4;
|
g_StackUsage += 4;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pEnc->offset < SCHAR_MAX)
|
if (offset < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
|
IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)offset);
|
||||||
} else {
|
} else {
|
||||||
IA32_Lea_DispRegImm32(jit, reg, REG_EBX, pEnc->offset);
|
IA32_Lea_DispRegImm32(jit, reg, REG_EBX, offset);
|
||||||
}
|
}
|
||||||
IA32_Push_Reg(jit, reg);
|
IA32_Push_Reg(jit, reg);
|
||||||
|
|
||||||
@ -247,24 +221,24 @@ inline void Write_PushPOD(JitWriter *jit, const PassEncode *pEnc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Write_PushFloat(JitWriter *jit, const PassEncode *pEnc)
|
inline void Write_PushFloat(JitWriter *jit, const SourceHook::PassInfo *info, unsigned int offset)
|
||||||
{
|
{
|
||||||
if (pEnc->info.flags & PASSFLAG_BYVAL)
|
if (info->flags & PASSFLAG_BYVAL)
|
||||||
{
|
{
|
||||||
switch (pEnc->info.size)
|
switch (info->size)
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
//fld DWORD PTR [ebx+<offset>]
|
//fld DWORD PTR [ebx+<offset>]
|
||||||
//push reg
|
//push reg
|
||||||
//fstp DWORD PTR [esp]
|
//fstp DWORD PTR [esp]
|
||||||
if (pEnc->offset < SCHAR_MAX)
|
if (offset < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Fld_Mem32_Disp8(jit, REG_EBX, (jit_int8_t)pEnc->offset);
|
IA32_Fld_Mem32_Disp8(jit, REG_EBX, (jit_int8_t)offset);
|
||||||
} else if (!pEnc->offset) {
|
} else if (!offset) {
|
||||||
IA32_Fld_Mem32(jit, REG_EBX);
|
IA32_Fld_Mem32(jit, REG_EBX);
|
||||||
} else {
|
} else {
|
||||||
IA32_Fld_Mem32_Disp32(jit, REG_EBX, pEnc->offset);
|
IA32_Fld_Mem32_Disp32(jit, REG_EBX, offset);
|
||||||
}
|
}
|
||||||
IA32_Push_Reg(jit, _DecodeRegister3(g_RegDecoder++));
|
IA32_Push_Reg(jit, _DecodeRegister3(g_RegDecoder++));
|
||||||
IA32_Fstp_Mem32_ESP(jit);
|
IA32_Fstp_Mem32_ESP(jit);
|
||||||
@ -276,13 +250,13 @@ inline void Write_PushFloat(JitWriter *jit, const PassEncode *pEnc)
|
|||||||
//fld QWORD PTR [ebx+<offset>]
|
//fld QWORD PTR [ebx+<offset>]
|
||||||
//sub esp, 8
|
//sub esp, 8
|
||||||
//fstp QWORD PTR [esp]
|
//fstp QWORD PTR [esp]
|
||||||
if (pEnc->offset < SCHAR_MAX)
|
if (offset < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Fld_Mem64_Disp8(jit, REG_EBX, (jit_int8_t)pEnc->offset);
|
IA32_Fld_Mem64_Disp8(jit, REG_EBX, (jit_int8_t)offset);
|
||||||
} else if (!pEnc->offset) {
|
} else if (!offset) {
|
||||||
IA32_Fld_Mem64(jit, REG_EBX);
|
IA32_Fld_Mem64(jit, REG_EBX);
|
||||||
} else {
|
} else {
|
||||||
IA32_Fld_Mem64_Disp32(jit, REG_EBX, pEnc->offset);
|
IA32_Fld_Mem64_Disp32(jit, REG_EBX, offset);
|
||||||
}
|
}
|
||||||
IA32_Sub_Rm_Imm8(jit, REG_ESP, 8, MOD_REG);
|
IA32_Sub_Rm_Imm8(jit, REG_ESP, 8, MOD_REG);
|
||||||
IA32_Fstp_Mem64_ESP(jit);
|
IA32_Fstp_Mem64_ESP(jit);
|
||||||
@ -290,10 +264,10 @@ inline void Write_PushFloat(JitWriter *jit, const PassEncode *pEnc)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (pEnc->info.flags & PASSFLAG_BYREF) {
|
} else if (info->flags & PASSFLAG_BYREF) {
|
||||||
//lea reg, [ebx+<offset>]
|
//lea reg, [ebx+<offset>]
|
||||||
//push reg
|
//push reg
|
||||||
if (!pEnc->offset)
|
if (!offset)
|
||||||
{
|
{
|
||||||
IA32_Push_Reg(jit, REG_EBX);
|
IA32_Push_Reg(jit, REG_EBX);
|
||||||
g_StackUsage += 4;
|
g_StackUsage += 4;
|
||||||
@ -301,11 +275,11 @@ inline void Write_PushFloat(JitWriter *jit, const PassEncode *pEnc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
jit_uint8_t reg = _DecodeRegister3(g_RegDecoder++);
|
jit_uint8_t reg = _DecodeRegister3(g_RegDecoder++);
|
||||||
if (pEnc->offset < SCHAR_MAX)
|
if (offset < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
|
IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)offset);
|
||||||
} else {
|
} else {
|
||||||
IA32_Lea_DispRegImm32(jit, reg, REG_EBX, pEnc->offset);
|
IA32_Lea_DispRegImm32(jit, reg, REG_EBX, offset);
|
||||||
}
|
}
|
||||||
IA32_Push_Reg(jit, reg);
|
IA32_Push_Reg(jit, reg);
|
||||||
|
|
||||||
@ -313,18 +287,18 @@ inline void Write_PushFloat(JitWriter *jit, const PassEncode *pEnc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Write_PushObject(JitWriter *jit, const PassEncode *pEnc)
|
inline void Write_PushObject(JitWriter *jit, const SourceHook::PassInfo *info, unsigned int offset)
|
||||||
{
|
{
|
||||||
if (pEnc->info.flags & PASSFLAG_BYVAL)
|
if (info->flags & PASSFLAG_BYVAL)
|
||||||
{
|
{
|
||||||
#ifdef PLATFORM_POSIX
|
#ifdef PLATFORM_POSIX
|
||||||
if (pEnc->info.flags & PASSFLAG_ODTOR)
|
if (info->flags & PASSFLAG_ODTOR)
|
||||||
{
|
{
|
||||||
goto push_byref;
|
goto push_byref;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
jit_uint32_t dwords = pEnc->info.size >> 2;
|
jit_uint32_t dwords = info->size >> 2;
|
||||||
jit_uint32_t bytes = pEnc->info.size & 0x3;
|
jit_uint32_t bytes = info->size & 0x3;
|
||||||
|
|
||||||
//sub esp, <size>
|
//sub esp, <size>
|
||||||
//cld
|
//cld
|
||||||
@ -340,23 +314,23 @@ inline void Write_PushObject(JitWriter *jit, const PassEncode *pEnc)
|
|||||||
// rep movsb
|
// rep movsb
|
||||||
//pop esi
|
//pop esi
|
||||||
//pop edi
|
//pop edi
|
||||||
if (pEnc->info.size < SCHAR_MAX)
|
if (info->size < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Sub_Rm_Imm8(jit, REG_ESP, (jit_int8_t)pEnc->info.size, MOD_REG);
|
IA32_Sub_Rm_Imm8(jit, REG_ESP, (jit_int8_t)info->size, MOD_REG);
|
||||||
} else {
|
} else {
|
||||||
IA32_Sub_Rm_Imm32(jit, REG_ESP, pEnc->info.size, MOD_REG);
|
IA32_Sub_Rm_Imm32(jit, REG_ESP, info->size, MOD_REG);
|
||||||
}
|
}
|
||||||
IA32_Cld(jit);
|
IA32_Cld(jit);
|
||||||
IA32_Push_Reg(jit, REG_EDI);
|
IA32_Push_Reg(jit, REG_EDI);
|
||||||
IA32_Push_Reg(jit, REG_ESI);
|
IA32_Push_Reg(jit, REG_ESI);
|
||||||
IA32_Lea_Reg_DispRegMultImm8(jit, REG_EDI, REG_NOIDX, REG_ESP, NOSCALE, 8);
|
IA32_Lea_Reg_DispRegMultImm8(jit, REG_EDI, REG_NOIDX, REG_ESP, NOSCALE, 8);
|
||||||
if (pEnc->offset < SCHAR_MAX)
|
if (offset < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Lea_DispRegImm8(jit, REG_ESI, REG_EBX, (jit_int8_t)pEnc->offset);
|
IA32_Lea_DispRegImm8(jit, REG_ESI, REG_EBX, (jit_int8_t)offset);
|
||||||
} else if (!pEnc->offset) {
|
} else if (!offset) {
|
||||||
IA32_Mov_Reg_Rm(jit, REG_ESI, REG_EBX, MOD_REG);
|
IA32_Mov_Reg_Rm(jit, REG_ESI, REG_EBX, MOD_REG);
|
||||||
} else {
|
} else {
|
||||||
IA32_Lea_DispRegImm32(jit, REG_ESI, REG_EBX, pEnc->offset);
|
IA32_Lea_DispRegImm32(jit, REG_ESI, REG_EBX, offset);
|
||||||
}
|
}
|
||||||
if (dwords)
|
if (dwords)
|
||||||
{
|
{
|
||||||
@ -373,12 +347,12 @@ inline void Write_PushObject(JitWriter *jit, const PassEncode *pEnc)
|
|||||||
IA32_Pop_Reg(jit, REG_ESI);
|
IA32_Pop_Reg(jit, REG_ESI);
|
||||||
IA32_Pop_Reg(jit, REG_EDI);
|
IA32_Pop_Reg(jit, REG_EDI);
|
||||||
|
|
||||||
g_StackUsage += pEnc->info.size;
|
g_StackUsage += info->size;
|
||||||
} else if (pEnc->info.flags & PASSFLAG_BYREF) {
|
} else if (info->flags & PASSFLAG_BYREF) {
|
||||||
#ifdef PLATFORM_POSIX
|
#ifdef PLATFORM_POSIX
|
||||||
push_byref:
|
push_byref:
|
||||||
#endif
|
#endif
|
||||||
if (!pEnc->offset)
|
if (!offset)
|
||||||
{
|
{
|
||||||
IA32_Push_Reg(jit, REG_EBX);
|
IA32_Push_Reg(jit, REG_EBX);
|
||||||
g_StackUsage += 4;
|
g_StackUsage += 4;
|
||||||
@ -388,11 +362,11 @@ push_byref:
|
|||||||
//lea reg, [ebx+<offset>]
|
//lea reg, [ebx+<offset>]
|
||||||
//push reg
|
//push reg
|
||||||
jit_uint8_t reg = _DecodeRegister3(g_RegDecoder++);
|
jit_uint8_t reg = _DecodeRegister3(g_RegDecoder++);
|
||||||
if (pEnc->offset < SCHAR_MAX)
|
if (offset < SCHAR_MAX)
|
||||||
{
|
{
|
||||||
IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
|
IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)offset);
|
||||||
} else {
|
} else {
|
||||||
IA32_Lea_DispRegImm32(jit, reg, REG_EBX, pEnc->offset);
|
IA32_Lea_DispRegImm32(jit, reg, REG_EBX, offset);
|
||||||
}
|
}
|
||||||
IA32_Push_Reg(jit, reg);
|
IA32_Push_Reg(jit, reg);
|
||||||
|
|
||||||
@ -429,15 +403,16 @@ inline void Write_CallFunction(JitWriter *jit, FuncAddrMethod method, CallWrappe
|
|||||||
{
|
{
|
||||||
//call <addr>
|
//call <addr>
|
||||||
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||||
IA32_Write_Jump32_Abs(jit, call, pWrapper->m_Addrs[ADDR_CALLEE]);
|
IA32_Write_Jump32_Abs(jit, call, pWrapper->GetCalleeAddr());
|
||||||
} else if (method == FuncAddr_VTable) {
|
} else if (method == FuncAddr_VTable) {
|
||||||
//*(this + thisOffs + vtblOffs)[vtblIdx]
|
//*(this + thisOffs + vtblOffs)[vtblIdx]
|
||||||
//mov edx, [ebx]
|
//mov edx, [ebx]
|
||||||
//mov eax, [edx+<thisOffs>+<vtblOffs>]
|
//mov eax, [edx+<thisOffs>+<vtblOffs>]
|
||||||
//mov edx, [eax+<vtblIdx>*4]
|
//mov edx, [eax+<vtblIdx>*4]
|
||||||
//call edx
|
//call edx
|
||||||
jit_uint32_t total_offs = pWrapper->m_VtInfo.thisOffs + pWrapper->m_VtInfo.vtblOffs;
|
SourceHook::MemFuncInfo *funcInfo = pWrapper->GetMemFuncInfo();
|
||||||
jit_uint32_t vfunc_pos = pWrapper->m_VtInfo.vtblIdx * 4;
|
jit_uint32_t total_offs = funcInfo->thisptroffs + funcInfo->vtbloffs;
|
||||||
|
jit_uint32_t vfunc_pos = funcInfo->vtblindex * 4;
|
||||||
|
|
||||||
IA32_Mov_Reg_Rm(jit, REG_EDX, REG_EBX, MOD_MEM_REG);
|
IA32_Mov_Reg_Rm(jit, REG_EDX, REG_EBX, MOD_MEM_REG);
|
||||||
if (total_offs < SCHAR_MAX)
|
if (total_offs < SCHAR_MAX)
|
||||||
@ -529,7 +504,7 @@ inline void Write_MovRet2Buf(JitWriter *jit, const PassInfo *pRet)
|
|||||||
* Assembly Compiler Function *
|
* Assembly Compiler Function *
|
||||||
******************************/
|
******************************/
|
||||||
|
|
||||||
void JIT_Compile(CallWrapper *pWrapper, FuncAddrMethod method)
|
void *JIT_CallCompile(CallWrapper *pWrapper, FuncAddrMethod method)
|
||||||
{
|
{
|
||||||
JitWriter writer;
|
JitWriter writer;
|
||||||
JitWriter *jit = &writer;
|
JitWriter *jit = &writer;
|
||||||
@ -553,22 +528,25 @@ jit_rewind:
|
|||||||
/* Write parameter push code */
|
/* Write parameter push code */
|
||||||
for (jit_int32_t i=ParamCount-1; i>=0; i--)
|
for (jit_int32_t i=ParamCount-1; i>=0; i--)
|
||||||
{
|
{
|
||||||
const PassEncode *pEnc = pWrapper->GetParamInfo(i);
|
unsigned int offset = pWrapper->GetParamOffset(i);
|
||||||
switch (pEnc->info.type)
|
const SourceHook::PassInfo *info = pWrapper->GetSHParamInfo(i);
|
||||||
|
assert(info != NULL);
|
||||||
|
|
||||||
|
switch (info->type)
|
||||||
{
|
{
|
||||||
case PassType_Basic:
|
case SourceHook::PassInfo::PassType_Basic:
|
||||||
{
|
{
|
||||||
Write_PushPOD(jit, pEnc);
|
Write_PushPOD(jit, info, offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PassType_Float:
|
case SourceHook::PassInfo::PassType_Float:
|
||||||
{
|
{
|
||||||
Write_PushFloat(jit, pEnc);
|
Write_PushFloat(jit, info, offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PassType_Object:
|
case SourceHook::PassInfo::PassType_Object:
|
||||||
{
|
{
|
||||||
Write_PushObject(jit, pEnc);
|
Write_PushObject(jit, info, offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -640,7 +618,7 @@ skip_retbuffer:
|
|||||||
writer.outbase = (jitcode_t)g_SPEngine->AllocatePageMemory(CodeSize);
|
writer.outbase = (jitcode_t)g_SPEngine->AllocatePageMemory(CodeSize);
|
||||||
g_SPEngine->SetReadWrite(writer.outbase);
|
g_SPEngine->SetReadWrite(writer.outbase);
|
||||||
writer.outptr = writer.outbase;
|
writer.outptr = writer.outbase;
|
||||||
pWrapper->m_Addrs[ADDR_CODEBASE] = writer.outbase;
|
pWrapper->SetCodeBaseAddr(writer.outbase);
|
||||||
g_StackAlign = (g_StackUsage) ? ((g_StackUsage & 0xFFFFFFF0) + 16) - g_StackUsage : 0;
|
g_StackAlign = (g_StackUsage) ? ((g_StackUsage & 0xFFFFFFF0) + 16) - g_StackUsage : 0;
|
||||||
g_StackUsage = 0;
|
g_StackUsage = 0;
|
||||||
g_RegDecoder = 0;
|
g_RegDecoder = 0;
|
||||||
@ -648,4 +626,5 @@ skip_retbuffer:
|
|||||||
goto jit_rewind;
|
goto jit_rewind;
|
||||||
}
|
}
|
||||||
g_SPEngine->SetReadExecute(writer.outbase);
|
g_SPEngine->SetReadExecute(writer.outbase);
|
||||||
|
return writer.outbase;
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,47 @@
|
|||||||
* Version: $Id$
|
* Version: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _INCLUDE_SOURCEMOD_JIT_CALL_H_
|
#ifndef _INCLUDE_SOURCEMOD_JIT_COMPILE_H_
|
||||||
#define _INCLUDE_SOURCEMOD_JIT_CALL_H_
|
#define _INCLUDE_SOURCEMOD_JIT_COMPILE_H_
|
||||||
|
|
||||||
#include "CallMaker.h"
|
#include <jit_helpers.h>
|
||||||
|
#include <x86_macros.h>
|
||||||
#include "CallWrapper.h"
|
#include "CallWrapper.h"
|
||||||
|
#include "HookWrapper.h"
|
||||||
|
|
||||||
void JIT_Compile(CallWrapper *pWrapper, FuncAddrMethod method);
|
void *JIT_CallCompile(CallWrapper *pWrapper, FuncAddrMethod method);
|
||||||
|
#if defined HOOKING_ENABLED
|
||||||
|
void *JIT_HookCompile(HookWrapper *pWrapper);
|
||||||
|
void JIT_FreeHook(void *addr);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_JIT_CALL_H_
|
/********************
|
||||||
|
* Assembly Helpers *
|
||||||
|
********************/
|
||||||
|
|
||||||
|
inline jit_uint8_t _DecodeRegister3(jit_uint32_t val)
|
||||||
|
{
|
||||||
|
switch (val % 3)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
return REG_EAX;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
return REG_EDX;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
return REG_ECX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should never happen */
|
||||||
|
assert(false);
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern jit_uint32_t g_RegDecoder;
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SOURCEMOD_JIT_COMPILE_H_
|
430
extensions/bintools/jit_hook.cpp
Normal file
430
extensions/bintools/jit_hook.cpp
Normal file
@ -0,0 +1,430 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* =============================================================================
|
||||||
|
* SourceMod BinTools Extension
|
||||||
|
* Copyright (C) 2004-2008 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: CallMaker.h 1964 2008-03-27 04:54:56Z damagedsoul $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined HOOKING_ENABLED
|
||||||
|
|
||||||
|
#include "jit_compile.h"
|
||||||
|
#include "sm_platform.h"
|
||||||
|
#include "extension.h"
|
||||||
|
|
||||||
|
/********************
|
||||||
|
* Assembly Opcodes *
|
||||||
|
********************/
|
||||||
|
|
||||||
|
inline void Write_Function_Prologue(JitWriter *jit, bool RetInMemory)
|
||||||
|
{
|
||||||
|
//push ebp
|
||||||
|
//push ebx
|
||||||
|
//mov ebp, esp
|
||||||
|
IA32_Push_Reg(jit, REG_EBP);
|
||||||
|
IA32_Push_Reg(jit, REG_EBX);
|
||||||
|
IA32_Mov_Reg_Rm(jit, REG_EBP, REG_ESP, MOD_REG);
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
//mov ebx, ecx
|
||||||
|
IA32_Mov_Reg_Rm(jit, REG_EBX, REG_ECX, MOD_REG);
|
||||||
|
#elif defined PLATFORM_LINUX
|
||||||
|
//mov ebx, [ebp+12+(RetInMemory)?4:0]
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, REG_EBX, REG_EBP, 12+((RetInMemory)?4:0));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write_Function_Epilogue(JitWriter *jit, unsigned short size)
|
||||||
|
{
|
||||||
|
//mov esp, ebp
|
||||||
|
//pop ebx
|
||||||
|
//pop ebp
|
||||||
|
//ret <value>
|
||||||
|
IA32_Mov_Reg_Rm(jit, REG_ESP, REG_EBP, MOD_REG);
|
||||||
|
IA32_Pop_Reg(jit, REG_EBX);
|
||||||
|
IA32_Pop_Reg(jit, REG_EBP);
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
IA32_Return(jit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IA32_Return_Popstack(jit, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write_Stack_Alloc(JitWriter *jit, jit_uint32_t size)
|
||||||
|
{
|
||||||
|
//sub esp, <value>
|
||||||
|
if (size <= SCHAR_MAX)
|
||||||
|
{
|
||||||
|
IA32_Sub_Rm_Imm8(jit, REG_ESP, (jit_int8_t)size, MOD_REG);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IA32_Sub_Rm_Imm32(jit, REG_ESP, size, MOD_REG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write_Copy_Params(JitWriter *jit, bool RetInMemory, jit_uint32_t retsize, jit_uint32_t paramsize)
|
||||||
|
{
|
||||||
|
//:TODO: inline this memcpy!! - For small numbers of params mov's (with clever reg allocation?) would be faster
|
||||||
|
|
||||||
|
//cld
|
||||||
|
//push edi
|
||||||
|
//push esi
|
||||||
|
//lea edi, [ebp-<retsize>-<paramsize>]
|
||||||
|
//lea esi, [ebp+12+(RetInMemory)?4:0]
|
||||||
|
//if dwords
|
||||||
|
// mov ecx, <dwords>
|
||||||
|
// rep movsd
|
||||||
|
//if bytes
|
||||||
|
// mov ecx, <bytes>
|
||||||
|
// rep movsb
|
||||||
|
//pop esi
|
||||||
|
//pop edi
|
||||||
|
|
||||||
|
jit_int32_t offs;
|
||||||
|
jit_uint32_t dwords = paramsize >> 2;
|
||||||
|
jit_uint32_t bytes = paramsize & 0x3;
|
||||||
|
|
||||||
|
IA32_Cld(jit);
|
||||||
|
IA32_Push_Reg(jit, REG_EDI);
|
||||||
|
IA32_Push_Reg(jit, REG_ESI);
|
||||||
|
offs = -(jit_int32_t)retsize - paramsize;
|
||||||
|
|
||||||
|
if (offs > SCHAR_MIN)
|
||||||
|
{
|
||||||
|
IA32_Lea_DispRegImm8(jit, REG_EDI, REG_EBP, (jit_int8_t)offs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IA32_Lea_DispRegImm32(jit, REG_EDI, REG_EBP, offs);
|
||||||
|
}
|
||||||
|
offs = 12 + ((RetInMemory) ? sizeof(void *) : 0);
|
||||||
|
|
||||||
|
#if defined PLATFORM_LINUX
|
||||||
|
offs += 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (offs < SCHAR_MAX)
|
||||||
|
{
|
||||||
|
IA32_Lea_DispRegImm8(jit, REG_ESI, REG_EBP, (jit_int8_t)offs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IA32_Lea_DispRegImm32(jit, REG_ESI, REG_EBP, offs);
|
||||||
|
}
|
||||||
|
if (dwords)
|
||||||
|
{
|
||||||
|
IA32_Mov_Reg_Imm32(jit, REG_ECX, dwords);
|
||||||
|
IA32_Rep(jit);
|
||||||
|
IA32_Movsd(jit);
|
||||||
|
}
|
||||||
|
if (bytes)
|
||||||
|
{
|
||||||
|
IA32_Mov_Reg_Imm32(jit, REG_ECX, bytes);
|
||||||
|
IA32_Rep(jit);
|
||||||
|
IA32_Movsb(jit);
|
||||||
|
}
|
||||||
|
IA32_Pop_Reg(jit, REG_ESI);
|
||||||
|
IA32_Pop_Reg(jit, REG_EDI);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write_Push_Params(JitWriter *jit,
|
||||||
|
bool isretvoid,
|
||||||
|
bool isvoid,
|
||||||
|
jit_uint32_t retsize,
|
||||||
|
jit_uint32_t paramsize,
|
||||||
|
HookWrapper *pWrapper)
|
||||||
|
{
|
||||||
|
//and esp, 0xFFFFFFF0
|
||||||
|
IA32_And_Rm_Imm8(jit, REG_ESP, MOD_REG, -16);
|
||||||
|
|
||||||
|
//if retvoid
|
||||||
|
// push 0
|
||||||
|
//else
|
||||||
|
// lea reg, [ebp-<retsize>]
|
||||||
|
// push reg
|
||||||
|
if (isretvoid)
|
||||||
|
{
|
||||||
|
IA32_Push_Imm8(jit, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jit_int32_t offs = -(jit_int32_t)retsize;
|
||||||
|
if (offs >= SCHAR_MIN)
|
||||||
|
{
|
||||||
|
IA32_Lea_DispRegImm8(jit, REG_EAX, REG_EBP, (jit_int8_t)offs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IA32_Lea_DispRegImm32(jit, REG_EAX, REG_EBP, offs);
|
||||||
|
}
|
||||||
|
IA32_Push_Reg(jit, REG_EAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if void
|
||||||
|
// push 0
|
||||||
|
//else
|
||||||
|
// lea reg, [ebp-<retsize>-<paramsize>]
|
||||||
|
// push reg
|
||||||
|
if (isvoid)
|
||||||
|
{
|
||||||
|
IA32_Push_Imm8(jit, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jit_int32_t offs = -(jit_int32_t)retsize - paramsize;
|
||||||
|
if (offs > SCHAR_MIN)
|
||||||
|
{
|
||||||
|
IA32_Lea_DispRegImm8(jit, REG_EDX, REG_EBP, (jit_int8_t)offs);
|
||||||
|
} else {
|
||||||
|
IA32_Lea_DispRegImm32(jit, REG_EDX, REG_EBP, offs);
|
||||||
|
}
|
||||||
|
IA32_Push_Reg(jit, REG_EDX);
|
||||||
|
}
|
||||||
|
|
||||||
|
//push eax (thisptr)
|
||||||
|
//IA32_Push_Reg(jit, REG_ECX);
|
||||||
|
|
||||||
|
//push ebx
|
||||||
|
IA32_Push_Reg(jit, REG_EBX);
|
||||||
|
|
||||||
|
//push <pWrapper>
|
||||||
|
IA32_Push_Imm32(jit, (jit_int32_t)pWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write_Call_Handler(JitWriter *jit, void *addr)
|
||||||
|
{
|
||||||
|
//call <addr>
|
||||||
|
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||||
|
IA32_Write_Jump32_Abs(jit, call, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write_Copy_RetVal(JitWriter *jit, SourceHook::PassInfo *pRetInfo)
|
||||||
|
{
|
||||||
|
/* If the return value is a reference the size will probably be >sizeof(void *)
|
||||||
|
* for objects, we need to fix that so we can actually return the reference.
|
||||||
|
*/
|
||||||
|
size_t size = pRetInfo->size;
|
||||||
|
if (pRetInfo->flags & PASSFLAG_BYREF)
|
||||||
|
{
|
||||||
|
size = sizeof(void *);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRetInfo->type == SourceHook::PassInfo::PassType_Float &&
|
||||||
|
pRetInfo->flags & SourceHook::PassInfo::PassFlag_ByVal)
|
||||||
|
{
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
//fld DWORD PTR [ebp-4]
|
||||||
|
IA32_Fld_Mem32_Disp8(jit, REG_EBP, -4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
//fld QWORD PTR [ebp-8]
|
||||||
|
IA32_Fld_Mem64_Disp8(jit, REG_EBP, -8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pRetInfo->type == SourceHook::PassInfo::PassType_Object &&
|
||||||
|
pRetInfo->flags & SourceHook::PassInfo::PassFlag_ByVal)
|
||||||
|
{
|
||||||
|
//cld
|
||||||
|
//push edi
|
||||||
|
//push esi
|
||||||
|
//mov edi, [ebp+12]
|
||||||
|
//lea esi, [ebp-<retsize>]
|
||||||
|
//if dwords
|
||||||
|
// mov ecx, <dwords>
|
||||||
|
// rep movsd
|
||||||
|
//if bytes
|
||||||
|
// mov ecx, <bytes>
|
||||||
|
// rep movsb
|
||||||
|
//pop esi
|
||||||
|
//pop edi
|
||||||
|
|
||||||
|
jit_int32_t offs;
|
||||||
|
jit_uint32_t dwords = size >> 2;
|
||||||
|
jit_uint32_t bytes = size & 0x3;
|
||||||
|
|
||||||
|
IA32_Cld(jit);
|
||||||
|
IA32_Push_Reg(jit, REG_EDI);
|
||||||
|
IA32_Push_Reg(jit, REG_ESI);
|
||||||
|
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, REG_EDI, REG_EBP, 12);
|
||||||
|
|
||||||
|
offs = -(jit_int32_t)pRetInfo->size;
|
||||||
|
if (offs >= SCHAR_MIN)
|
||||||
|
{
|
||||||
|
IA32_Lea_DispRegImm8(jit, REG_ESI, REG_EBP, (jit_int8_t)offs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IA32_Lea_DispRegImm32(jit, REG_ESI, REG_EBP, offs);
|
||||||
|
}
|
||||||
|
IA32_Mov_Reg_Rm(jit, REG_EAX, REG_EDI, MOD_REG);
|
||||||
|
|
||||||
|
if (dwords)
|
||||||
|
{
|
||||||
|
IA32_Mov_Reg_Imm32(jit, REG_ECX, dwords);
|
||||||
|
IA32_Rep(jit);
|
||||||
|
IA32_Movsd(jit);
|
||||||
|
}
|
||||||
|
if (bytes)
|
||||||
|
{
|
||||||
|
IA32_Mov_Reg_Imm32(jit, REG_ECX, bytes);
|
||||||
|
IA32_Rep(jit);
|
||||||
|
IA32_Movsb(jit);
|
||||||
|
}
|
||||||
|
IA32_Pop_Reg(jit, REG_ESI);
|
||||||
|
IA32_Pop_Reg(jit, REG_EDI);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
//mov al, BYTE PTR [ebp-4]
|
||||||
|
IA32_Mov_Reg8_Rm8_Disp8(jit, REG_EAX, REG_EBP, -4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
//mov ax, WORD PTR [ebp-4]
|
||||||
|
jit->write_ubyte(IA32_16BIT_PREFIX);
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, -4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
//mov eax, DWORD PTR [ebp-4]
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, -4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
//mov eax, DWORD PTR [ebp-8]
|
||||||
|
//mov edx, DWORD PTR [ebp-4]
|
||||||
|
//:TODO: this is broken due to SH
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, -8);
|
||||||
|
IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EBP, -4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
* Assembly Compiler Function *
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
void *JIT_HookCompile(HookWrapper *pWrapper)
|
||||||
|
{
|
||||||
|
JitWriter writer;
|
||||||
|
JitWriter *jit = &writer;
|
||||||
|
|
||||||
|
jit_uint32_t CodeSize = 0;
|
||||||
|
jit_uint32_t ParamSize = pWrapper->GetParamSize();
|
||||||
|
jit_uint32_t RetSize = pWrapper->GetRetSize();
|
||||||
|
|
||||||
|
/* Local variable size allocated in the stack for the param and retval buffers */
|
||||||
|
jit_uint32_t LocalVarSize = ParamSize + RetSize;
|
||||||
|
|
||||||
|
/* Check if the return value is returned in memory */
|
||||||
|
bool RetInMemory = false;
|
||||||
|
SourceHook::PassInfo *pRetInfo = &pWrapper->GetProtoInfo()->retPassInfo;
|
||||||
|
if ((pRetInfo->type == SourceHook::PassInfo::PassType_Object) &&
|
||||||
|
(pRetInfo->flags & SourceHook::PassInfo::PassFlag_ByVal))
|
||||||
|
{
|
||||||
|
RetInMemory = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.outbase = NULL;
|
||||||
|
writer.outptr = NULL;
|
||||||
|
|
||||||
|
jit_rewind:
|
||||||
|
/* Write the function prologue */
|
||||||
|
Write_Function_Prologue(jit, RetInMemory);
|
||||||
|
|
||||||
|
/* Allocate the local variables into the stack */
|
||||||
|
if (LocalVarSize)
|
||||||
|
{
|
||||||
|
Write_Stack_Alloc(jit, LocalVarSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy all the parameters into the buffer */
|
||||||
|
if (ParamSize)
|
||||||
|
{
|
||||||
|
Write_Copy_Params(jit, RetInMemory, RetSize, ParamSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Push the parameters into the handler */
|
||||||
|
Write_Push_Params(jit, !RetSize, !ParamSize, RetSize, ParamSize, pWrapper);
|
||||||
|
|
||||||
|
/* Call the handler function */
|
||||||
|
Write_Call_Handler(jit, pWrapper->GetHandlerAddr());
|
||||||
|
|
||||||
|
/* Copy back the return value into eax or the hidden return buffer */
|
||||||
|
if (RetSize)
|
||||||
|
{
|
||||||
|
Write_Copy_RetVal(jit, pRetInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the function epilogue */
|
||||||
|
Write_Function_Epilogue(jit,
|
||||||
|
#if defined PLATFORM_WINDOWS
|
||||||
|
ParamSize + ((RetInMemory) ? sizeof(void *) : 0)
|
||||||
|
#elif defined PLATFORM_LINUX
|
||||||
|
(RetInMemory) ? sizeof(void *) : 0
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
if (writer.outbase == NULL)
|
||||||
|
{
|
||||||
|
CodeSize = writer.get_outputpos();
|
||||||
|
writer.outbase = (jitcode_t)g_SPEngine->AllocatePageMemory(CodeSize);
|
||||||
|
g_SPEngine->SetReadWrite(writer.outbase);
|
||||||
|
writer.outptr = writer.outbase;
|
||||||
|
g_RegDecoder = 0;
|
||||||
|
goto jit_rewind;
|
||||||
|
}
|
||||||
|
g_SPEngine->SetReadExecute(writer.outbase);
|
||||||
|
|
||||||
|
return writer.outbase;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JIT_FreeHook(void *addr)
|
||||||
|
{
|
||||||
|
g_SPEngine->FreePageMemory(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -5,14 +5,32 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bintools", "bintools.vcproj
|
|||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug - Episode 1|Win32 = Debug - Episode 1|Win32
|
||||||
Release|Win32 = Release|Win32
|
Debug - Left 4 Dead|Win32 = Debug - Left 4 Dead|Win32
|
||||||
|
Debug - Old Metamod|Win32 = Debug - Old Metamod|Win32
|
||||||
|
Debug - Orange Box|Win32 = Debug - Orange Box|Win32
|
||||||
|
Release - Episode 1|Win32 = Release - Episode 1|Win32
|
||||||
|
Release - Left 4 Dead|Win32 = Release - Left 4 Dead|Win32
|
||||||
|
Release - Old Metamod|Win32 = Release - Old Metamod|Win32
|
||||||
|
Release - Orange Box|Win32 = Release - Orange Box|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug|Win32.ActiveCfg = Debug|Win32
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Episode 1|Win32.ActiveCfg = Debug - Episode 1|Win32
|
||||||
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug|Win32.Build.0 = Debug|Win32
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Episode 1|Win32.Build.0 = Debug - Episode 1|Win32
|
||||||
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release|Win32.ActiveCfg = Release|Win32
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Left 4 Dead|Win32.ActiveCfg = Debug - Left 4 Dead|Win32
|
||||||
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release|Win32.Build.0 = Release|Win32
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Left 4 Dead|Win32.Build.0 = Debug - Left 4 Dead|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Old Metamod|Win32.ActiveCfg = Debug - Old Metamod|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Old Metamod|Win32.Build.0 = Debug - Old Metamod|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Episode 1|Win32.ActiveCfg = Release - Episode 1|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Episode 1|Win32.Build.0 = Release - Episode 1|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Left 4 Dead|Win32.ActiveCfg = Release - Left 4 Dead|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Left 4 Dead|Win32.Build.0 = Release - Left 4 Dead|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Old Metamod|Win32.ActiveCfg = Release - Old Metamod|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Old Metamod|Win32.Build.0 = Release - Old Metamod|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32
|
||||||
|
{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
</ToolFiles>
|
</ToolFiles>
|
||||||
<Configurations>
|
<Configurations>
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="Debug|Win32"
|
Name="Debug - Orange Box|Win32"
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
ConfigurationType="2"
|
ConfigurationType="2"
|
||||||
@ -40,9 +40,10 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\extensions;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\sourcepawn"
|
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;"$(MMSOURCE17)\core";"$(MMSOURCE17)\core\sourcehook";"$(HL2SDKOB)\public";"$(HL2SDKOB)\public\tier0";"$(HL2SDKOB)\public\tier1""
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD"
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;ORANGEBOX_BUILD;HOOKING_ENABLED;SOURCE_ENGINE=3"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
@ -64,6 +65,7 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies=""$(HL2SDKOB)\lib\public\tier0.lib" "$(HL2SDKOB)\lib\public\tier1.lib" "$(HL2SDKOB)\lib\public\vstdlib.lib" "$(HL2SDKOB)\lib\public\mathlib.lib""
|
||||||
OutputFile="$(OutDir)\bintools.ext.dll"
|
OutputFile="$(OutDir)\bintools.ext.dll"
|
||||||
LinkIncremental="2"
|
LinkIncremental="2"
|
||||||
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMT"
|
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMT"
|
||||||
@ -96,7 +98,7 @@
|
|||||||
/>
|
/>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="Release|Win32"
|
Name="Release - Orange Box|Win32"
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
ConfigurationType="2"
|
ConfigurationType="2"
|
||||||
@ -120,9 +122,10 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/MP /D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\extensions;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\sourcepawn"
|
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;"$(MMSOURCE17)\core";"$(MMSOURCE17)\core\sourcehook";"$(HL2SDKOB)\public";"$(HL2SDKOB)\public\tier0";"$(HL2SDKOB)\public\tier1""
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD"
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;SOURCE_ENGINE=3"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableEnhancedInstructionSet="1"
|
EnableEnhancedInstructionSet="1"
|
||||||
RuntimeTypeInfo="false"
|
RuntimeTypeInfo="false"
|
||||||
@ -142,6 +145,472 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies=""$(HL2SDKOB)\lib\public\tier0.lib" "$(HL2SDKOB)\lib\public\tier1.lib" "$(HL2SDKOB)\lib\public\vstdlib.lib" "$(HL2SDKOB)\lib\public\mathlib.lib""
|
||||||
|
OutputFile="$(OutDir)\bintools.ext.dll"
|
||||||
|
LinkIncremental="1"
|
||||||
|
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMTD"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
RandomizedBaseAddress="1"
|
||||||
|
DataExecutionPrevention="0"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug - Left 4 Dead|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
|
||||||
|
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;"$(MMSOURCE17)\core";"$(MMSOURCE17)\core\sourcehook";"$(HL2SDKL4D)\public";"$(HL2SDKL4D)\public\tier0";"$(HL2SDKL4D)\public\tier1""
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;HOOKING_ENABLED;SOURCE_ENGINE=4"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
EnableEnhancedInstructionSet="1"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies=""$(HL2SDKL4D)\lib\public\tier0.lib" "$(HL2SDKL4D)\lib\public\tier1.lib" "$(HL2SDKL4D)\lib\public\vstdlib.lib" "$(HL2SDKL4D)\lib\public\mathlib.lib""
|
||||||
|
OutputFile="$(OutDir)\bintools.ext.dll"
|
||||||
|
LinkIncremental="2"
|
||||||
|
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMT"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug - Old Metamod|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
|
||||||
|
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;"$(MMSOURCE17)\core\sourcehook";"$(HL2SDK)\public";"$(HL2SDK)\public\tier0";"$(HL2SDK)\public\tier1""
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;SOURCE_ENGINE=2"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
EnableEnhancedInstructionSet="1"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies=""$(HL2SDK)\lib\public\tier0.lib" "$(HL2SDK)\lib\public\tier1.lib" "$(HL2SDK)\lib\public\vstdlib.lib" "$(HL2SDK)\lib\public\mathlib.lib""
|
||||||
|
OutputFile="$(OutDir)\bintools.ext.dll"
|
||||||
|
LinkIncremental="2"
|
||||||
|
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMT"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug - Episode 1|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
|
||||||
|
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;"$(MMSOURCE17)\core";"$(MMSOURCE17)\core\sourcehook";"$(HL2SDK)\public";"$(HL2SDK)\public\tier0";"$(HL2SDK)\public\tier1""
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;HOOKING_ENABLED;SOURCE_ENGINE=2"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="1"
|
||||||
|
EnableEnhancedInstructionSet="1"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies=""$(HL2SDK)\lib\public\tier0.lib" "$(HL2SDK)\lib\public\tier1.lib" "$(HL2SDK)\lib\public\vstdlib.lib" "$(HL2SDK)\lib\public\mathlib.lib""
|
||||||
|
OutputFile="$(OutDir)\bintools.ext.dll"
|
||||||
|
LinkIncremental="2"
|
||||||
|
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMT"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release - Left 4 Dead|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
|
||||||
|
FavorSizeOrSpeed="1"
|
||||||
|
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;"$(MMSOURCE17)\core";"$(MMSOURCE17)\core\sourcehook";"$(HL2SDKL4D)\public";"$(HL2SDKL4D)\public\tier0";"$(HL2SDKL4D)\public\tier1""
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;HOOKING_ENABLED;SOURCE_ENGINE=4"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableEnhancedInstructionSet="1"
|
||||||
|
RuntimeTypeInfo="false"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="false"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies=""$(HL2SDKL4D)\lib\public\tier0.lib" "$(HL2SDKL4D)\lib\public\tier1.lib" "$(HL2SDKL4D)\lib\public\vstdlib.lib" "$(HL2SDKL4D)\lib\public\mathlib.lib""
|
||||||
|
OutputFile="$(OutDir)\bintools.ext.dll"
|
||||||
|
LinkIncremental="1"
|
||||||
|
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMTD"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
RandomizedBaseAddress="1"
|
||||||
|
DataExecutionPrevention="0"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release - Old Metamod|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
|
||||||
|
FavorSizeOrSpeed="1"
|
||||||
|
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;"$(MMSOURCE17)\core\sourcehook";"$(HL2SDK)\public";"$(HL2SDK)\public\tier0";"$(HL2SDK)\public\tier1""
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;SOURCE_ENGINE=2"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableEnhancedInstructionSet="1"
|
||||||
|
RuntimeTypeInfo="false"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="false"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies=""$(HL2SDK)\lib\public\tier0.lib" "$(HL2SDK)\lib\public\tier1.lib" "$(HL2SDK)\lib\public\vstdlib.lib" "$(HL2SDK)\lib\public\mathlib.lib""
|
||||||
|
OutputFile="$(OutDir)\bintools.ext.dll"
|
||||||
|
LinkIncremental="1"
|
||||||
|
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMTD"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
RandomizedBaseAddress="1"
|
||||||
|
DataExecutionPrevention="0"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release - Episode 1|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
|
||||||
|
FavorSizeOrSpeed="1"
|
||||||
|
AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;"$(MMSOURCE17)\core";"$(MMSOURCE17)\core\sourcehook";"$(HL2SDK)\public";"$(HL2SDK)\public\tier0";"$(HL2SDK)\public\tier1""
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;HOOKING_ENABLED;SOURCE_ENGINE=2"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableEnhancedInstructionSet="1"
|
||||||
|
RuntimeTypeInfo="false"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="false"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies=""$(HL2SDK)\lib\public\tier0.lib" "$(HL2SDK)\lib\public\tier1.lib" "$(HL2SDK)\lib\public\vstdlib.lib" "$(HL2SDK)\lib\public\mathlib.lib""
|
||||||
OutputFile="$(OutDir)\bintools.ext.dll"
|
OutputFile="$(OutDir)\bintools.ext.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMTD"
|
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMTD"
|
||||||
@ -227,7 +696,11 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\jit_call.h"
|
RelativePath="..\HookWrapper.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\jit_compile.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
@ -244,10 +717,18 @@
|
|||||||
RelativePath="..\CallWrapper.cpp"
|
RelativePath="..\CallWrapper.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\HookWrapper.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\jit_call.cpp"
|
RelativePath="..\jit_call.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\jit_hook.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
|
@ -57,7 +57,9 @@
|
|||||||
* @brief Sets whether or not this plugin required Metamod.
|
* @brief Sets whether or not this plugin required Metamod.
|
||||||
* NOTE: Uncomment to enable, comment to disable.
|
* NOTE: Uncomment to enable, comment to disable.
|
||||||
*/
|
*/
|
||||||
//#define SMEXT_CONF_METAMOD
|
#if defined HOOKING_ENABLED
|
||||||
|
#define SMEXT_CONF_METAMOD
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Enable interfaces you want to use here by uncommenting lines */
|
/** Enable interfaces you want to use here by uncommenting lines */
|
||||||
//#define SMEXT_ENABLE_FORWARDSYS
|
//#define SMEXT_ENABLE_FORWARDSYS
|
||||||
@ -65,5 +67,17 @@
|
|||||||
//#define SMEXT_ENABLE_PLAYERHELPERS
|
//#define SMEXT_ENABLE_PLAYERHELPERS
|
||||||
//#define SMEXT_ENABLE_DBMANAGER
|
//#define SMEXT_ENABLE_DBMANAGER
|
||||||
//#define SMEXT_ENABLE_GAMECONF
|
//#define SMEXT_ENABLE_GAMECONF
|
||||||
|
//#define SMEXT_ENABLE_MEMUTILS
|
||||||
|
//#define SMEXT_ENABLE_GAMEHELPERS
|
||||||
|
//#define SMEXT_ENABLE_TIMERSYS
|
||||||
|
//#define SMEXT_ENABLE_THREADER
|
||||||
|
//#define SMEXT_ENABLE_LIBSYS
|
||||||
|
//#define SMEXT_ENABLE_MENUS
|
||||||
|
//#define SMEXT_ENABLE_ADTFACTORY
|
||||||
|
//#define SMEXT_ENABLE_PLUGINSYS
|
||||||
|
//#define SMEXT_ENABLE_ADMINSYS
|
||||||
|
//#define SMEXT_ENABLE_TEXTPARSERS
|
||||||
|
//#define SMEXT_ENABLE_USERMSGS
|
||||||
|
//#define SMEXT_ENABLE_TRANSLATOR
|
||||||
|
|
||||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
|
||||||
|
@ -97,6 +97,24 @@ IUserMessages *usermsgs = NULL;
|
|||||||
#if defined SMEXT_ENABLE_TRANSLATOR
|
#if defined SMEXT_ENABLE_TRANSLATOR
|
||||||
ITranslator *translator = NULL;
|
ITranslator *translator = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_PLUGINSYS
|
||||||
|
SourceMod::IPluginManager *plsys;
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_MENUS
|
||||||
|
IMenuManager *menus = NULL;
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_ADMINSYS
|
||||||
|
IAdminSystem *adminsys = NULL;
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_TEXTPARSERS
|
||||||
|
ITextParsers *textparsers = NULL;
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_USERMSGS
|
||||||
|
IUserMessages *usermsgs = NULL;
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_TRANSLATOR
|
||||||
|
ITranslator *translator = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Exports the main interface */
|
/** Exports the main interface */
|
||||||
PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI()
|
PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI()
|
||||||
@ -182,6 +200,24 @@ bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error,
|
|||||||
#if defined SMEXT_ENABLE_USERMSGS
|
#if defined SMEXT_ENABLE_USERMSGS
|
||||||
SM_GET_IFACE(USERMSGS, usermsgs);
|
SM_GET_IFACE(USERMSGS, usermsgs);
|
||||||
#endif
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_TRANSLATOR
|
||||||
|
SM_GET_IFACE(TRANSLATOR, translator);
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_PLUGINSYS
|
||||||
|
SM_GET_IFACE(PLUGINSYSTEM, plsys);
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_MENUS
|
||||||
|
SM_GET_IFACE(MENUMANAGER, menus);
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_ADMINSYS
|
||||||
|
SM_GET_IFACE(ADMINSYS, adminsys);
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_TEXTPARSERS
|
||||||
|
SM_GET_IFACE(TEXTPARSERS, textparsers);
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_USERMSGS
|
||||||
|
SM_GET_IFACE(USERMSGS, usermsgs);
|
||||||
|
#endif
|
||||||
#if defined SMEXT_ENABLE_TRANSLATOR
|
#if defined SMEXT_ENABLE_TRANSLATOR
|
||||||
SM_GET_IFACE(TRANSLATOR, translator);
|
SM_GET_IFACE(TRANSLATOR, translator);
|
||||||
#endif
|
#endif
|
||||||
|
@ -73,6 +73,24 @@
|
|||||||
#if defined SMEXT_ENABLE_LIBSYS
|
#if defined SMEXT_ENABLE_LIBSYS
|
||||||
#include <ILibrarySys.h>
|
#include <ILibrarySys.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_PLUGINSYS
|
||||||
|
#include <IPluginSys.h>
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_MENUS
|
||||||
|
#include <IMenuManager.h>
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_ADMINSYS
|
||||||
|
#include <IAdminSystem.h>
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_TEXTPARSERS
|
||||||
|
#include <ITextParsers.h>
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_USERMSGS
|
||||||
|
#include <IUserMessages.h>
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_TRANSLATOR
|
||||||
|
#include <ITranslator.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined SMEXT_CONF_METAMOD
|
#if defined SMEXT_CONF_METAMOD
|
||||||
#include <ISmmPlugin.h>
|
#include <ISmmPlugin.h>
|
||||||
@ -256,6 +274,21 @@ extern IThreader *threader;
|
|||||||
#if defined SMEXT_ENABLE_LIBSYS
|
#if defined SMEXT_ENABLE_LIBSYS
|
||||||
extern ILibrarySys *libsys;
|
extern ILibrarySys *libsys;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_PLUGINSYS
|
||||||
|
extern SourceMod::IPluginManager *plsys;
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_MENUS
|
||||||
|
extern IMenuManager *menus;
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_ADMINSYS
|
||||||
|
extern IAdminSystem *adminsys;
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_USERMSGS
|
||||||
|
extern IUserMessages *usermsgs;
|
||||||
|
#endif
|
||||||
|
#if defined SMEXT_ENABLE_TRANSLATOR
|
||||||
|
extern ITranslator *translator;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined SMEXT_CONF_METAMOD
|
#if defined SMEXT_CONF_METAMOD
|
||||||
PLUGIN_GLOBALVARS();
|
PLUGIN_GLOBALVARS();
|
||||||
|
@ -34,8 +34,16 @@
|
|||||||
|
|
||||||
#include <IShareSys.h>
|
#include <IShareSys.h>
|
||||||
|
|
||||||
|
|
||||||
#define SMINTERFACE_BINTOOLS_NAME "IBinTools"
|
#define SMINTERFACE_BINTOOLS_NAME "IBinTools"
|
||||||
#define SMINTERFACE_BINTOOLS_VERSION 2
|
#define SMINTERFACE_BINTOOLS_VERSION 3
|
||||||
|
|
||||||
|
#if defined HOOKING_ENABLED
|
||||||
|
#include <sourcehook_pibuilder.h>
|
||||||
|
|
||||||
|
#define SMINTERFACE_BINTOOLS2_NAME "IBinTools2"
|
||||||
|
#define SMINTERFACE_BINTOOLS2_VERSION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function calling encoding utilities
|
* @brief Function calling encoding utilities
|
||||||
@ -135,8 +143,109 @@ namespace SourceMod
|
|||||||
* @brief Destroys all resources used by this object.
|
* @brief Destroys all resources used by this object.
|
||||||
*/
|
*/
|
||||||
virtual void Destroy() =0;
|
virtual void Destroy() =0;
|
||||||
|
|
||||||
|
#if defined HOOKING_ENABLED
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the Return type info.
|
||||||
|
*
|
||||||
|
* @return A PassInfo pointer.
|
||||||
|
*/
|
||||||
|
virtual const SourceHook::PassInfo *GetSHReturnInfo() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the calling convention.
|
||||||
|
*
|
||||||
|
* @return CallConvention value.
|
||||||
|
*/
|
||||||
|
virtual SourceHook::ProtoInfo::CallConvention GetSHCallConvention() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns parameter info.
|
||||||
|
*
|
||||||
|
* @param num Parameter number to get (starting from 0).
|
||||||
|
* @return A PassInfo pointer.
|
||||||
|
*/
|
||||||
|
virtual const SourceHook::PassInfo *GetSHParamInfo(unsigned int num) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the offset of a given param.
|
||||||
|
*
|
||||||
|
* @param num Parameter number to get (starting from 0).
|
||||||
|
* @return Parameter offset.
|
||||||
|
*/
|
||||||
|
virtual unsigned int GetParamOffset(unsigned int num) =0;
|
||||||
|
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined HOOKING_ENABLED
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delegate object that intermediates between SourceHook and the callback function.
|
||||||
|
*/
|
||||||
|
class ISMDelegate : public SourceHook::ISHDelegate
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Internally used callback function - Do not call!
|
||||||
|
*/
|
||||||
|
virtual void Call() =0; /**< Do not call */
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the User data buffer.
|
||||||
|
*
|
||||||
|
* @return User data pointer.
|
||||||
|
*/
|
||||||
|
virtual void *GetUserData() =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wrapper around a virtual hook.
|
||||||
|
*/
|
||||||
|
class IHookWrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Creates a hook delegate to pass to SourceHook.
|
||||||
|
*
|
||||||
|
* @param data User data pointer.
|
||||||
|
* @return A new ISMDelegate for the hook.
|
||||||
|
*/
|
||||||
|
virtual ISMDelegate *CreateDelegate(void *data) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the number of params in the hooked function.
|
||||||
|
*
|
||||||
|
* @return Number of params.
|
||||||
|
*/
|
||||||
|
virtual unsigned int GetParamCount() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the offset of a given param.
|
||||||
|
*
|
||||||
|
* @param argnum Parameter number from 0 to GetParamCount-1.
|
||||||
|
* @param size Optional buffer to store the size of the param.
|
||||||
|
* @return Parameter offset or -1 on error.
|
||||||
|
*/
|
||||||
|
virtual unsigned int GetParamOffset(unsigned int argnum, unsigned int *size) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initiates a recall on the function.
|
||||||
|
*
|
||||||
|
* @param params Parameter buffer.
|
||||||
|
* @param retval Buffer to store the return value in.
|
||||||
|
*/
|
||||||
|
virtual void PerformRecall(void *params, void *retval) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destroys this HookWrapper.
|
||||||
|
*/
|
||||||
|
virtual void Destroy() =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Binary tools interface.
|
* @brief Binary tools interface.
|
||||||
*/
|
*/
|
||||||
@ -196,6 +305,82 @@ namespace SourceMod
|
|||||||
const PassInfo paramInfo[],
|
const PassInfo paramInfo[],
|
||||||
unsigned int numParams) =0;
|
unsigned int numParams) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined HOOKING_ENABLED
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Binary tools interface.
|
||||||
|
*/
|
||||||
|
class IBinTools2 : public SMInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual const char *GetInterfaceName()
|
||||||
|
{
|
||||||
|
return SMINTERFACE_BINTOOLS2_NAME;
|
||||||
|
}
|
||||||
|
virtual unsigned int GetInterfaceVersion()
|
||||||
|
{
|
||||||
|
return SMINTERFACE_BINTOOLS2_VERSION;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a call decoder.
|
||||||
|
*
|
||||||
|
* Note: CallConv_ThisCall requires an implicit first parameter
|
||||||
|
* of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *). However,
|
||||||
|
* this should only be given to the Execute() function, and never
|
||||||
|
* listed in the paramInfo array.
|
||||||
|
*
|
||||||
|
* @param address Address to use as a call.
|
||||||
|
* @param protoInfo Parameter type information.
|
||||||
|
* @return A new ICallWrapper function.
|
||||||
|
*/
|
||||||
|
virtual ICallWrapper *CreateCall(void *address,
|
||||||
|
const SourceHook::ProtoInfo *protoInfo) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a vtable call decoder.
|
||||||
|
*
|
||||||
|
* Note: CallConv_ThisCall requires an implicit first parameter
|
||||||
|
* of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *). However,
|
||||||
|
* this should only be given to the Execute() function, and never
|
||||||
|
* listed in the paramInfo array.
|
||||||
|
*
|
||||||
|
* @param protoInfo Parameter type information.
|
||||||
|
* @param info Function offset information.
|
||||||
|
* @return A new ICallWrapper function.
|
||||||
|
*/
|
||||||
|
virtual ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
|
||||||
|
const SourceHook::MemFuncInfo *info) =0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function pointer for Virtual Hooks.
|
||||||
|
*
|
||||||
|
* @param wrapper Call wrapper for this hook.
|
||||||
|
* @param deleg Delegate for this call.
|
||||||
|
* @param params Array of parameters.
|
||||||
|
* @param ret Storage buffer for the return value.
|
||||||
|
*/
|
||||||
|
typedef void (*VIRTUAL_HOOK_PROTO)(IHookWrapper *wrapper, ISMDelegate *deleg, void *params, void *ret);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a hook on a virtual function.
|
||||||
|
*
|
||||||
|
* @param pSH Global SourceHook pointer.
|
||||||
|
* @param protoInfo Parameter type information.
|
||||||
|
* @param info Function offset information.
|
||||||
|
* @param f Callback function pointer.
|
||||||
|
*/
|
||||||
|
virtual IHookWrapper *CreateVirtualHook(SourceHook::ISourceHook *pSH,
|
||||||
|
const SourceHook::ProtoInfo *protoInfo,
|
||||||
|
const SourceHook::MemFuncInfo *info,
|
||||||
|
VIRTUAL_HOOK_PROTO f) =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //_INCLUDE_SMEXT_BINTOOLS_H_
|
#endif //_INCLUDE_SMEXT_BINTOOLS_H_
|
||||||
|
@ -202,12 +202,37 @@ namespace builder
|
|||||||
libraries.Add(lib);
|
libraries.Add(lib);
|
||||||
|
|
||||||
lib = new Library();
|
lib = new Library();
|
||||||
lib.package_path = "addons/sourcemod/extensions";
|
lib.package_path = "addons/sourcemod/extensions/auto.1.ep1";
|
||||||
lib.source_path = "extensions/bintools";
|
lib.source_path = "extensions/bintools";
|
||||||
lib.binary_name = "bintools.ext";
|
lib.binary_name = "bintools.ext";
|
||||||
lib.vcproj_name = "bintools";
|
lib.vcproj_name = "bintools";
|
||||||
|
lib.build_mode = BuildMode.BuildMode_OldMetamod;
|
||||||
libraries.Add(lib);
|
libraries.Add(lib);
|
||||||
|
|
||||||
|
lib = new Library();
|
||||||
|
lib.package_path = "addons/sourcemod/extensions/auto.2.ep1";
|
||||||
|
lib.source_path = "extensions/bintools";
|
||||||
|
lib.binary_name = "bintools.ext";
|
||||||
|
lib.vcproj_name = "bintools";
|
||||||
|
lib.build_mode = BuildMode.BuildMode_Episode1;
|
||||||
|
libraries.Add(lib);
|
||||||
|
|
||||||
|
lib = new Library();
|
||||||
|
lib.package_path = "addons/sourcemod/extensions/auto.2.ep2";
|
||||||
|
lib.source_path = "extensions/bintools";
|
||||||
|
lib.binary_name = "bintools.ext";
|
||||||
|
lib.vcproj_name = "bintools";
|
||||||
|
lib.build_mode = BuildMode.BuildMode_Episode2;
|
||||||
|
libraries.Add(lib);
|
||||||
|
|
||||||
|
lib = new Library();
|
||||||
|
lib.package_path = "addons/sourcemod/extensions/auto.2.l4d";
|
||||||
|
lib.source_path = "extensions/bintools";
|
||||||
|
lib.binary_name = "bintools.ext";
|
||||||
|
lib.vcproj_name = "bintools";
|
||||||
|
lib.build_mode = BuildMode.BuildMode_Left4Dead;
|
||||||
|
libraries.Add(lib);
|
||||||
|
|
||||||
lib = new Library();
|
lib = new Library();
|
||||||
lib.package_path = "addons/sourcemod/extensions";
|
lib.package_path = "addons/sourcemod/extensions";
|
||||||
lib.source_path = "extensions/mysql";
|
lib.source_path = "extensions/mysql";
|
||||||
|
Loading…
Reference in New Issue
Block a user