DHooks (SourceMod Scripting)

From AlliedModders Wiki
Revision as of 18:32, 12 June 2024 by Mooshua (talk | contribs) (Create basic dhooks page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

DHooks is a hooking and detouring extension for SourceMod plugins. Whereas most existing hook extensions provide a selection of hooks, DHooks allows you to specify the exact hook yourself. DHooks is included with SourceMod starting from 1.12 and newer versions of 1.11.

DynamicHooks

DynamicHooks use SourceHook as a backend, and can only hook virtual tables. To create a DynamicHook, you specify it's virtual offset, hook mode, and return type. You then add each argument individually using the methodmap.

DynamicHooks can hook either a raw thispointer (as an Address), the gamerules object, or an entity index.

//  Create the initial hook configuration.
DynamicHook hook = new DynamicHook(/* offset */ 0, HookType_Raw, ReturnType_Void, ThisPointer_Address);
{
    hook.AddParam(HookParamType_CharPtr);
 
    //  Choose a custom pass type of register
    //  (DHooks will try to automatically detect the register)
    hook.AddParam(HookParamType_CharPtr, -1, DHookPass_ByRef, DHookRegister_XMM6);
}
 
//  Hook an entity by it's entity index
hook.HookEntity(HookMode_Post, /*ent index*/ edict, /* callbacks and more ... */);
 
//  Hook a raw address
hook.HookRaw(HookMode_Post, /*address*/ thisptr, /* callback here.... */);

Gamedata

DHooks parses the Functions block of a gamedata file. You can include an OS name in most places to limit values to a specific OS.

Functions are referenced by name, which must be unique across the install

Dhooks handles names globally, so if two functions have the same name in different gamedata files they will conflict!

   "FunctionName"
   {
       "signature" ""
       "address"   ""
       "offset"    ""

       "callconv" "cdecl/thiscall/stdcall/fastcall"
       "hooktype" "entity/gamerules/raw"

       "return" ""
       "this"   "ignore/entity/address"

       "arguments"
       {
           arg_name
           {
               "type" ""
               "size" ""
               "flags"    "byval/byref/odtor/octor/oassignop/ocopyctor/ounalign"
               "register" "theres a lot"
           }
       }
   }

You can call FromConf on a hook to load the appropriate function from a gamedata file:

//  Must have an offset, no address or signature
DynamicHook.FromConf(gamedata, "FunctionName");
 
//  Must have a signature or address!
DynamicDetour.FromConf(gamedata, "FunctionName");