00001 /** 00002 * vim: set ts=4 : 00003 * ============================================================================= 00004 * SourceMod BinTools Extension 00005 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. 00006 * ============================================================================= 00007 * 00008 * This program is free software; you can redistribute it and/or modify it under 00009 * the terms of the GNU General Public License, version 3.0, as published by the 00010 * Free Software Foundation. 00011 * 00012 * This program is distributed in the hope that it will be useful, but WITHOUT 00013 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00014 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00015 * details. 00016 * 00017 * You should have received a copy of the GNU General Public License along with 00018 * this program. If not, see <http://www.gnu.org/licenses/>. 00019 * 00020 * As a special exception, AlliedModders LLC gives you permission to link the 00021 * code of this program (as well as its derivative works) to "Half-Life 2," the 00022 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software 00023 * by the Valve Corporation. You must obey the GNU General Public License in 00024 * all respects for all other code used. Additionally, AlliedModders LLC grants 00025 * this exception to all derivative works. AlliedModders LLC defines further 00026 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), 00027 * or <http://www.sourcemod.net/license.php>. 00028 * 00029 * Version: $Id$ 00030 */ 00031 00032 #ifndef _INCLUDE_SMEXT_BINTOOLS_H_ 00033 #define _INCLUDE_SMEXT_BINTOOLS_H_ 00034 00035 #include <IShareSys.h> 00036 00037 00038 #define SMINTERFACE_BINTOOLS_NAME "IBinTools" 00039 #define SMINTERFACE_BINTOOLS_VERSION 3 00040 00041 #if defined METAMOD_PLAPI_VERSION 00042 #ifndef HOOKING_ENABLED 00043 #define HOOKING_ENABLED 00044 #endif 00045 #endif 00046 00047 #if defined HOOKING_ENABLED 00048 #include <sourcehook_pibuilder.h> 00049 00050 #define SMINTERFACE_BINTOOLS2_NAME "IBinTools2" 00051 #define SMINTERFACE_BINTOOLS2_VERSION 1 00052 #endif 00053 00054 /** 00055 * @brief Function calling encoding utilities 00056 * @file IBinTools.h 00057 */ 00058 00059 namespace SourceMod 00060 { 00061 /** 00062 * @brief Supported calling conventions 00063 */ 00064 enum CallConvention 00065 { 00066 CallConv_ThisCall, /**< This call (object pointer required) */ 00067 CallConv_Cdecl, /**< Standard C call */ 00068 }; 00069 00070 /** 00071 * @brief Describes how a parameter should be passed 00072 */ 00073 enum PassType 00074 { 00075 PassType_Basic, /**< Plain old register data (pointers, integers) */ 00076 PassType_Float, /**< Floating point data */ 00077 PassType_Object, /**< Object or structure */ 00078 }; 00079 00080 #define PASSFLAG_BYVAL (1<<0) /**< Passing by value */ 00081 #define PASSFLAG_BYREF (1<<1) /**< Passing by reference */ 00082 #define PASSFLAG_ODTOR (1<<2) /**< Object has a destructor */ 00083 #define PASSFLAG_OCTOR (1<<3) /**< Object has a constructor */ 00084 #define PASSFLAG_OASSIGNOP (1<<4) /**< Object has an assignment operator */ 00085 00086 /** 00087 * @brief Parameter passing information 00088 */ 00089 struct PassInfo 00090 { 00091 PassType type; /**< PassType value */ 00092 unsigned int flags; /**< Pass/return flags */ 00093 size_t size; /**< Size of the data being passed */ 00094 }; 00095 00096 /** 00097 * @brief Parameter encoding information 00098 */ 00099 struct PassEncode 00100 { 00101 PassInfo info; /**< Parameter information */ 00102 size_t offset; /**< Offset into the virtual stack */ 00103 }; 00104 00105 /** 00106 * @brief Wraps a C/C++ call. 00107 */ 00108 class ICallWrapper 00109 { 00110 public: 00111 /** 00112 * @brief Returns the calling convention. 00113 * 00114 * @return CallConvention value. 00115 */ 00116 virtual CallConvention GetCallConvention() =0; 00117 00118 /** 00119 * @brief Returns parameter info. 00120 * 00121 * @param num Parameter number to get (starting from 0). 00122 * @return A PassInfo pointer. 00123 */ 00124 virtual const PassEncode *GetParamInfo(unsigned int num) =0; 00125 00126 /** 00127 * @brief Returns return type info. 00128 * 00129 * @return A PassInfo pointer. 00130 */ 00131 virtual const PassInfo *GetReturnInfo() =0; 00132 00133 /** 00134 * @brief Returns the number of parameters. 00135 * 00136 * @return Number of parameters. 00137 */ 00138 virtual unsigned int GetParamCount() =0; 00139 00140 /** 00141 * @brief Execute the contained function. 00142 * 00143 * @param vParamStack A blob of memory containing stack data. 00144 * @param retBuffer Buffer to store return value. 00145 */ 00146 virtual void Execute(void *vParamStack, void *retBuffer) =0; 00147 00148 /** 00149 * @brief Destroys all resources used by this object. 00150 */ 00151 virtual void Destroy() =0; 00152 00153 #if defined HOOKING_ENABLED 00154 00155 /** 00156 * @brief Gets the Return type info. 00157 * 00158 * @return A PassInfo pointer. 00159 */ 00160 virtual const SourceHook::PassInfo *GetSHReturnInfo() =0; 00161 00162 /** 00163 * @brief Returns the calling convention. 00164 * 00165 * @return CallConvention value. 00166 */ 00167 virtual SourceHook::ProtoInfo::CallConvention GetSHCallConvention() =0; 00168 00169 /** 00170 * @brief Returns parameter info. 00171 * 00172 * @param num Parameter number to get (starting from 0). 00173 * @return A PassInfo pointer. 00174 */ 00175 virtual const SourceHook::PassInfo *GetSHParamInfo(unsigned int num) =0; 00176 00177 /** 00178 * @brief Returns the offset of a given param. 00179 * 00180 * @param num Parameter number to get (starting from 0). 00181 * @return Parameter offset. 00182 */ 00183 virtual unsigned int GetParamOffset(unsigned int num) =0; 00184 00185 #endif 00186 }; 00187 00188 #if defined HOOKING_ENABLED 00189 00190 /** 00191 * @brief Delegate object that intermediates between SourceHook and the callback function. 00192 */ 00193 class ISMDelegate : public SourceHook::ISHDelegate 00194 { 00195 private: 00196 /** 00197 * @brief Internally used callback function - Do not call! 00198 */ 00199 virtual void Call() =0; /**< Do not call */ 00200 public: 00201 /** 00202 * @brief Retrieves the User data buffer. 00203 * 00204 * @return User data pointer. 00205 */ 00206 virtual void *GetUserData() =0; 00207 }; 00208 00209 /** 00210 * @brief Wrapper around a virtual hook. 00211 */ 00212 class IHookWrapper 00213 { 00214 public: 00215 /** 00216 * @brief Creates a hook delegate to pass to SourceHook. 00217 * 00218 * @param data User data pointer. 00219 * @return A new ISMDelegate for the hook. 00220 */ 00221 virtual ISMDelegate *CreateDelegate(void *data) =0; 00222 00223 /** 00224 * @brief Gets the number of params in the hooked function. 00225 * 00226 * @return Number of params. 00227 */ 00228 virtual unsigned int GetParamCount() =0; 00229 00230 /** 00231 * @brief Returns the offset of a given param. 00232 * 00233 * @param argnum Parameter number from 0 to GetParamCount-1. 00234 * @param size Optional buffer to store the size of the param. 00235 * @return Parameter offset or -1 on error. 00236 */ 00237 virtual unsigned int GetParamOffset(unsigned int argnum, unsigned int *size) =0; 00238 00239 /** 00240 * @brief Initiates a recall on the function. 00241 * 00242 * @param params Parameter buffer. 00243 * @param retval Buffer to store the return value in. 00244 */ 00245 virtual void PerformRecall(void *params, void *retval) =0; 00246 00247 /** 00248 * @brief Destroys this HookWrapper. 00249 */ 00250 virtual void Destroy() =0; 00251 }; 00252 00253 #endif 00254 00255 /** 00256 * @brief Binary tools interface. 00257 */ 00258 class IBinTools : public SMInterface 00259 { 00260 public: 00261 virtual const char *GetInterfaceName() 00262 { 00263 return SMINTERFACE_BINTOOLS_NAME; 00264 } 00265 virtual unsigned int GetInterfaceVersion() 00266 { 00267 return SMINTERFACE_BINTOOLS_VERSION; 00268 } 00269 public: 00270 /** 00271 * @brief Creates a call decoder. 00272 * 00273 * Note: CallConv_ThisCall requires an implicit first parameter 00274 * of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *). However, 00275 * this should only be given to the Execute() function, and never 00276 * listed in the paramInfo array. 00277 * 00278 * @param address Address to use as a call. 00279 * @param cv Calling convention. 00280 * @param retInfo Return type information, or NULL for void. 00281 * @param paramInfo Array of parameters. 00282 * @param numParams Number of parameters in the array. 00283 * @return A new ICallWrapper function. 00284 */ 00285 virtual ICallWrapper *CreateCall(void *address, 00286 CallConvention cv, 00287 const PassInfo *retInfo, 00288 const PassInfo paramInfo[], 00289 unsigned int numParams) =0; 00290 00291 /** 00292 * @brief Creates a vtable call decoder. 00293 * 00294 * Note: CallConv_ThisCall requires an implicit first parameter 00295 * of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *). However, 00296 * this should only be given to the Execute() function, and never 00297 * listed in the paramInfo array. 00298 * 00299 * @param vtblIdx Index into the virtual table. 00300 * @param vtblOffs Offset of the virtual table. 00301 * @param thisOffs Offset of the this pointer of the virtual table. 00302 * @param retInfo Return type information, or NULL for void. 00303 * @param paramInfo Array of parameters. 00304 * @param numParams Number of parameters in the array. 00305 * @return A new ICallWrapper function. 00306 */ 00307 virtual ICallWrapper *CreateVCall(unsigned int vtblIdx, 00308 unsigned int vtblOffs, 00309 unsigned int thisOffs, 00310 const PassInfo *retInfo, 00311 const PassInfo paramInfo[], 00312 unsigned int numParams) =0; 00313 }; 00314 00315 #if defined HOOKING_ENABLED 00316 00317 /** 00318 * @brief Binary tools interface. 00319 */ 00320 class IBinTools2 : public SMInterface 00321 { 00322 public: 00323 virtual const char *GetInterfaceName() 00324 { 00325 return SMINTERFACE_BINTOOLS2_NAME; 00326 } 00327 virtual unsigned int GetInterfaceVersion() 00328 { 00329 return SMINTERFACE_BINTOOLS2_VERSION; 00330 } 00331 public: 00332 00333 /** 00334 * @brief Creates a call decoder. 00335 * 00336 * Note: CallConv_ThisCall requires an implicit first parameter 00337 * of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *). However, 00338 * this should only be given to the Execute() function, and never 00339 * listed in the paramInfo array. 00340 * 00341 * @param address Address to use as a call. 00342 * @param protoInfo Parameter type information. 00343 * @return A new ICallWrapper function. 00344 */ 00345 virtual ICallWrapper *CreateCall(void *address, 00346 const SourceHook::ProtoInfo *protoInfo) =0; 00347 00348 /** 00349 * @brief Creates a vtable call decoder. 00350 * 00351 * Note: CallConv_ThisCall requires an implicit first parameter 00352 * of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *). However, 00353 * this should only be given to the Execute() function, and never 00354 * listed in the paramInfo array. 00355 * 00356 * @param protoInfo Parameter type information. 00357 * @param info Function offset information. 00358 * @return A new ICallWrapper function. 00359 */ 00360 virtual ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo, 00361 const SourceHook::MemFuncInfo *info) =0; 00362 00363 00364 /** 00365 * @brief Callback function pointer for Virtual Hooks. 00366 * 00367 * @param wrapper Call wrapper for this hook. 00368 * @param deleg Delegate for this call. 00369 * @param params Array of parameters. 00370 * @param ret Storage buffer for the return value. 00371 */ 00372 typedef void (*VIRTUAL_HOOK_PROTO)(IHookWrapper *wrapper, ISMDelegate *deleg, void *params, void *ret); 00373 00374 /** 00375 * @brief Creates a hook on a virtual function. 00376 * 00377 * @param pSH Global SourceHook pointer. 00378 * @param protoInfo Parameter type information. 00379 * @param info Function offset information. 00380 * @param f Callback function pointer. 00381 */ 00382 virtual IHookWrapper *CreateVirtualHook(SourceHook::ISourceHook *pSH, 00383 const SourceHook::ProtoInfo *protoInfo, 00384 const SourceHook::MemFuncInfo *info, 00385 VIRTUAL_HOOK_PROTO f) =0; 00386 }; 00387 00388 #endif 00389 00390 } 00391 00392 #endif //_INCLUDE_SMEXT_BINTOOLS_H_
1.7.1