Raised This Month: $32 Target: $400
 8% 

DHooks (Dynamic Hooks - Dev Preview)


Post New Thread Reply   
 
Thread Tools Display Modes
Dr!fter
The Salt Boss
Join Date: Mar 2007
Old 11-23-2017 , 19:38   Re: DHooks (Dynamic Hooks - Dev Preview)
Reply With Quote #581

If its empty its probably empty, idk. if you can read other data fine on linux it probably works correctly.
Dr!fter is offline
Invisible Man
Junior Member
Join Date: Nov 2017
Location: Persia
Old 12-13-2017 , 12:30   Re: DHooks (Dynamic Hooks - Dev Preview)
Reply With Quote #582

Hi
Is there any way for making this work on cs:s v34?
Help pleaSE!
Invisible Man is offline
Mitchell
~lick~
Join Date: Mar 2010
Old 12-13-2017 , 12:51   Re: DHooks (Dynamic Hooks - Dev Preview)
Reply With Quote #583

Quote:
Originally Posted by Invisible Man View Post
Hi
Is there any way for making this work on cs:s v34?
Help pleaSE!
This should already support the latest version of CS:S.
If you're not using the latest version of CS:S maybe it's time to connect to steam and update to the latest version?
Mitchell is offline
shavit
AlliedModders Donor
Join Date: Dec 2011
Location: Israel
Old 12-14-2017 , 00:37   Re: DHooks (Dynamic Hooks - Dev Preview)
Reply With Quote #584

Quote:
Originally Posted by Invisible Man View Post
Hi
Is there any way for making this work on cs:s v34?
Help pleaSE!
Heck, SourceMod itself doesn't support v34. It's missing interfaces, many features used in current SM and more importantly - lots of code isn't even compatible. Same goes for gamedata.
I myself tried v34 CS:S to see what the hype is about, but it ended up being a buggy, unoptimized mess that has nothing but Russian servers with some version of SM from 7 years ago and lots of cheaters.
Just get it on Steam when Christmas sales happen. It'll be dirt cheap.
__________________
retired
shavit is offline
Dr!fter
The Salt Boss
Join Date: Mar 2007
Old 02-15-2018 , 11:50   Re: DHooks (Dynamic Hooks - Dev Preview)
Reply With Quote #585

Updated, Fixed a possible crash with certain params and added support for setting callbacks on hook rather than only on create.
Dr!fter is offline
janpepu
AlliedModders Donor
Join Date: Sep 2007
Location: france
Old 03-05-2018 , 13:04   Re: DHooks (Dynamic Hooks - Dev Preview)
Reply With Quote #586

hi
SourceMod Version: 1.7.3-dev+5253
dhooks-2.2.0-hg126-linux

[SM] Extension dhooks.ext.so failed to load: Could not find interface: IGameHelpers

Must upgrade sm ?

Last edited by janpepu; 03-05-2018 at 13:08.
janpepu is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 03-05-2018 , 14:31   Re: DHooks (Dynamic Hooks - Dev Preview)
Reply With Quote #587

Quote:
Originally Posted by janpepu View Post
hi
SourceMod Version: 1.7.3-dev+5253
dhooks-2.2.0-hg126-linux

[SM] Extension dhooks.ext.so failed to load: Could not find interface: IGameHelpers

Must upgrade sm ?
Yes.
__________________
asherkin is offline
HelpMePlease
Junior Member
Join Date: Mar 2018
Old 03-30-2018 , 20:13   Re: DHooks (Dynamic Hooks - Dev Preview)
Reply With Quote #588

Quote:
Originally Posted by Dr!fter View Post
Updated, Fixed a possible crash with certain params and added support for setting callbacks on hook rather than only on create.
Send a link in which we can download the updated plugin!
The latest version from 01.30.2018 - this does not prevent crash.

Linux.
SourceMod 1.9

Thank you very much.

Last edited by HelpMePlease; 03-30-2018 at 20:17.
HelpMePlease is offline
Peace-Maker
SourceMod Plugin Approver
Join Date: Aug 2008
Location: Germany
Old 04-21-2018 , 05:58   Re: DHooks (Dynamic Hooks - Dev Preview)
Reply With Quote #589

DHooks is now included with SourceMod 1.11.6820. Previous versions are unsupported.


Please use SourceMod's issue tracker on GitHub for any new issues.



Experimental dynamic detour support

I've been fiddling with extending DHooks to not only support hooking of virtual functions, but non-virtual functions as well. The dynamic detour support in this version is based on Ayuto's DynamicHooks library. Huge thank you for that nice piece of engineering!

This build adds support for detouring any functions through SourcePawn.

Detours in plugins
Setting up detours in a plugin is very similar to current virtual hooks. Instead of DHookCreate you'd use DHookCreateDetour. This time you'll pass the address to the function you want to detour instead of the vtable offset though and specify the calling convention the function uses.
Instead of hooking single entities you'll just enable the detour globally (DHookEnableDetour). Your detour is disabled automatically on plugin unload.

Natives
Spoiler


Examples
Replicate PTaH's detour on IClient::ExecuteStringCommand: (why is this a detour instead of a vtable hook again?)
Spoiler


In the above example you'll notice the use of the new
DHookSetFromConf native to simplify hook setup similar to how SDKCalls in SDKTools are created.

Instead of
PHP Code:
Handle hGameData LoadGameConfigFile("sdktools.games");
if(
hGameData == null)
    
SetFailState("Failed to load sdktools gamedata.");

int iOffset GameConfGetOffset(hGameData"Teleport");
delete hGameData;
if(
iOffset == -1)
    
SetFailState("Failed to find Teleport offset in gamedata");

g_hTeleport DHookCreate(iOffsetHookType_EntityReturnType_VoidThisPointer_CBaseEntityDHooks_OnTeleport);
if(
g_hTeleport == null)
    
SetFailState("Failed to setup hook for Teleport"); 
you can grab the offset and pass it to the hook in one go:

PHP Code:
Handle hGameData LoadGameConfigFile("sdktools.games");
if(
hGameData == null)
   
SetFailState("Failed to load sdktools gamedata.");
        
g_hTeleport DHookCreate(0HookType_EntityReturnType_VoidThisPointer_CBaseEntityDHooks_OnTeleport);
if(
g_hTeleport == null)
    
SetFailState("Failed to setup hook for Teleport");

if (!
DHookSetFromConf(g_hTeleporthGameDataSDKConf_Virtual"Teleport"))
        
SetFailState("Failed to load Teleport offset from gamedata");
delete hGameData
This allows you to use the "Signatures" section in gamedata directly without the need to wrap it in an "Address" for use with the GameConfGetAddress native for detours.


Detouring member functions
Member functions usually need a pointer to the instance of their class to access the right member variables and stuff. On Windows there's a special calling convention thiscall which specifies that the this-pointer should be passed in the ecx register. On linux the this-pointer is passed as an implicit first argument on the stack before all the other arguments using the cdecl calling convention.
To save you from having to configure the hook differently on linux and windows the thiscall calling convention actually means "cdecl with implicit first |this| argument" on linux. So you don't have to add another parameter yourself when detouring on linux, but can just use CallConv_THISCALL and use the this-pointer just like you would with virtual hooks (e.g. passing ThisPointer_Address to DHookCreateDetour and choosing the right callback prototype including the Address pThis parameter).


Accessing parameter values in post-hooks
Some compiler optimizations can cause the memory locations of the arguments to be reused and overwritten in the function if the compiler comes to the conclusion that the argument isn't needed anymore (mostly used on Windows). This can cause problems in post-hooks, because the real argument values aren't available anymore and you find "garbage" values instead of the expected arguments. Some pointer types can even cause a crash when DHooks tries to dereference them and the value doesn't point to valid memory anymore. If you experience problems like this, the current workaround would be to save the arguments in a pre-hook and use them in the post-hook instead of calling DHooksGetParam*.
Parameter values are saved before calling the original function and restored before the post callback since detours15.



Custom calling conventions and LTCG
Some functions can be optimized to expect arguments in random registers instead of the stack. This optimization can save stack operations since the callee just expects the argument to be in the same register the caller already uses to store the value. The caller doesn't have to push the argument on the stack, but can just keep it in the register. You'll often notice this in the CS:GO binaries on windows.

Since the used register can be arbitary and the compiler doesn't have to follow any standardized calling conventions for functions that aren't called externally, the DHookAddParam native received a new parameter to define the register the parameter is passed in.

Spoiler


You can detour CCSGameRules::TerminateRound (like the cstrike extension does) like this:
Spoiler


This works on windows, since the first float parameter is passed in register xmm1 (the this-pointer is passed in ecx by default, so no action needed for that):
PHP Code:
char __userpurge TerminateRound(int a1@<ecx>, float a2@<xmm1>, int *a3
That optimization isn't used in the linux build though, so we'd need a way to define different function signatures per platform. That's why there's a new "Functions" section in gamedata files where you can define all the above including parts only valid on single platforms.

"Functions" in gamedata
You can define function signatures in this new section in gamedata files parsed by DHooks2 now.
Since we don't know which gamedata file is being parsed when looking at the "Functions" section, all functions are cached globally. So the "Functions" section is parsed automatically when loading gamedata files using LoadGameConfigFile (or through an extension) without any additional action needed.

First you create a new subsection preferably named after the function you want to hook/detour.
The section name is used in the new DHookCreateFromConf native.

DHookCreateFromConf native

Spoiler


Required key values
Then you reference an "offset", "signature" or "address" section from the gamedata file who's handle will be passed to DHookCreateFromConf. Depending on if you specify an offset or not you'll setup a virtual hook or a detour.

If you setup a detour set the calling convention in the "callconv" key: cdecl, thiscall, stdcall or fastcall.
If you setup a virtual hook set the hook type in the "hooktype" key: entity, gamerules or raw. This corresponds to the HookType enum in the include.
If you setup a virtual hook or a detour using the thiscall calling convention decide what to do with the this-pointer in the "this" key: ignore, entity, address. This corresponds to the ThisPointerType enum in the include.

Lastly you have to specify the return type of the function in the "return" key. The ReturnType enum values are mapped to the lowercase version of the enum attributes.
  • ReturnType_Void: "void"
  • ReturnType_Int: "int"
  • ReturnType_Bool: "bool"
  • ReturnType_Float: "float"
  • ReturnType_String: "string"
  • ReturnType_StringPtr: "stringptr"
  • ReturnType_CharPtr: "charptr"
  • ReturnType_Vector: "vector"
  • ReturnType_VectorPtr: "vectorptr"
  • ReturnType_CBaseEntity: "cbaseentity"
  • ReturnType_Edict: "edict"

Defining function arguments

If your function has some arguments list them in an "arguments" subsection. Each argument will get its own subsection. The argument section name isn't used anywhere yet, but it might be useful to name the section after the argument it describes ;)

There is only one required key value for an argument just like with DHookAddParam: the "type". The values are derived from the HookParamType enum again just like the ReturnType above by using the latter part in lowercase.
  • HookParamType_Int: "int"
  • HookParamType_Bool: "bool"
  • HookParamType_Float: "float"
  • HookParamType_String: "string"
  • HookParamType_StringPtr: "stringptr"
  • HookParamType_CharPtr: "charptr"
  • HookParamType_VectorPtr: "vectorptr"
  • HookParamType_CBaseEntity: "cbaseentity"
  • HookParamType_ObjectPtr: "objectptr"
  • HookParamType_Edict: "edict"
  • HookParamType_Object: "object"
Optionally you can add the following keys to further specify the argument:
  • "size" - Used for Objects (not Object ptr) to define the size of the object.
  • "flags" - Used to change the pass type. The accepted values map to the PASSFLAG_* defines. You can put multiple flags in one line.
    • PASSFLAG_BYVAL: "byval" (default)
    • PASSFLAG_BYREF: "byref"
    • PASSFLAG_ODTOR: "odtor"
    • PASSFLAG_OCTOR: "octor"
    • PASSFLAG_OASSIGNOP: "oassignop"
    • PASSFLAG_OCOPYCTOR: "ocopyctor"
    • PASSFLAG_OUNALIGN: "ounalign"
  • "register" - The register this argument is passed in instead of the stack.
    • 8-bit General purpose registers: al, cl, dl, bl, ah, ch, dh, bh
    • 16-bit General purpose registers: ax, cx, dx, bx, sp, bp, si, di
    • 32-bit General purpose registers: eax, ecx, edx, ebx, esp, ebp, esi, edi
    • 64-bit MM (MMX) registers: mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7
    • 128-bit XMM registers: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
    • 16-bit Segment registers: cs, ss, ds, es, fs, gs
    • 80-bit FPU registers: st0
Platform specific settings
Every subsection or keyvalue inside the "Functions" section can be enclosed by a "windows", "linux" or "mac" section to make the content only valid if the file is parsed on that platform. For the above TerminateRound detour example, you could specify the first parameter to be passed in the custom register only on windows like:
Code:
"arguments"
{
    "delay"
    {
        "type"  "float"
        "windows"
        {
            "register"  "xmm1"
        }
    }
    "reason"
    {
        "type"    "int"
    }
}
Examples
The TerminateRound detour can be rewritten like this:

function-def.games.txt
Spoiler


terminateround.sp
Spoiler


Game specific settings
You can change settings or add parameters for single games/engines as well. Imagine we'd want to hook CBaseAnimating::Teleport. In most games, the signature is
PHP Code:
void CBaseAnimating::Teleport( const Vector  *newPosition, const QAngle *newAngles, const Vector *newVelocity 
CS:GO added another parameter though
PHP Code:
void  CBaseAnimating::Teleport( const Vector *newPosition, const QAngle  *newAngles, const Vector *newVelocitybool notsolid 

Hardcoding the hook it could look something like this:
Spoiler


You can move that setup into your gamedata file like this:
Spoiler


Later sections in the file add to the already parsed setup.

Credits
Ayuto - DynamicHooks library
BAILOPAN - Help with assembly and converting DynamicHooks to SourcePawn's MacroAssembler
Dr!fter - DHooks!

Source
Old repository

Note: To build yourself, you'll need to update amtl in sourcemod 1.9 to include this PR. SourceMod 1.10+ already includes the change.
Code:
~/sourcemod> cd public/amtl
~/sourcemod/public/amtl>git checkout ad5439b
No Mac or x64 support yet!

Changelog
2.2.0-detours1 - 21.04.2018:
  • Initial release
2.2.0-detours2 - 22.04.2018:
  • Fix overriding function return value (thanks SlidyBat)
2.2.0-detours3 - 20.05.2018:
  • Don't call sourcepawn callbacks when detour function is called from a different thread
  • Fix setting up virtual hooks through "Functions" section in gamedata
2.2.0-detours4 - 06.06.2018:
  • Fix detouring |thiscall| functions with additional parameters on linux (thanks Ryan.)
2.2.0-detours5 - 08.08.2018:
  • Fix adding arguments multiple times when reparsing the "Functions" section (thanks Silvers)
  • Fix not removing all plugin callbacks from detour list on plugin unload
2.2.0-detours6 - 19.09.2018:
  • Fix detouring functions returning a float
2.2.0-detours7 - 21.11.2018:
  • Fix crash on unaligned SSE instructions (thanks Kailo)
  • Fix crash when trying to decode NULL this-pointer
2.2.0-detours8 - 03.08.2019:
  • Add |fastcall| calling convention support
  • Fix changing of charptr and vectorptr returns and parameters (thanks Silvers)
2.2.0-detours9 - 19.08.2019
  • Pull fix for changing vector returns from upstream
2.2.0-detours10 - 21.04.2020
  • Add |this|-ptr save and restore from pre to post hooks on linux
  • Fix parsing of platform specific sections in "Functions" gamedata (thanks vanz)
2.2.0-detours11 - 28.05.2020
  • Fix recursive calls when the ESP register is reused (thanks L'In20Cible Ayuto/DynamicHooks#4)
  • Fix skipping and overriding return values of recursive calls (thanks ldesgoui #3)
2.2.0-detours12 - 29.05.2020
  • Fix typo preventing "odtor" argument flag parsing in gamedata (thanks Alienmario)
2.2.0-detours13 - 30.05.2020
  • Fix parsing of multiple argument flags in gamedata (thanks Alienmario)
2.2.0-detours14 - 09.06.2020
  • Fix regression crash with post-only detours from recursive call fix in detours11 (Thanks Crasher_3637)
  • Include sdktools.inc in include file for DHookSetFromConf native (Thanks ClaudiuHKS #4)
  • Fix crash when trying to call hook removal callback on unloaded plugin (Thanks FortyTwoFortyTwo Drifter321#3)
2.2.0-detours14a - 09.06.2020
  • More regression fixes for post-only detours (thanks Silvers)
2.2.0-detours15 - 17.10.2020
  • Add methodmap API
  • Save all arguments before calling the original function (thanks nosoop)
  • Fix regression when unloading plugins with entity vhooks on mapchange leading to a crash
  • Print nicer error message on wrong callback signature
2.2.0-detours16 - 28.01.2021
  • Fix crash on server shutdown
  • Switch to std::vector and std::string for SourceMod 1.11 / AMTL update compatibility
  • Enable frame pointer on linux for better crash stack traces
  • Include:
    • Fix INVALID_HOOK_ID using incorrect value
    • Avoid reference to GameData methodmap for backwards compatibility
2.2.0-detours17 - 30.06.2021
  • Allow returning NULL for CBaseEntity return types by setting the return value to -1 (thanks arthurdead)
  • Allow specifying object argument size in hexadecimal in gamedata similar to SM 1.11
  • Fix SourceHook context leak when superceding virtual hooked functions (thanks nosoop and BotoX Drifter321#2)
    • This fixes a long standing issue with memory leaks, crashes and lag on map change
  • Fix crash on CentOS7+ / SELinux with "allow_execheap" disabled (thanks vintagepc #22)
  • Fix DHookIsNullParam checking wrong parameter for detour setups with parameters passed in custom registers (thanks GAMMACASE #15)
  • Fix crash due to mismatching new[] + delete[] pair of return value buffer (thanks bottiger)
1.11.6820 - 17.11.2021:
  • DHooks is now included with SourceMod 1.11.6820
  • Added new native "DHookParam.GetAddress" to get the address of a pointer parameter. (Thanks LuqS #24)
  • Fix error reporting on invalid entity (Thanks FortyTwoFortyTwo #25)


Attention: Make sure to download the right file based on the SourceMod version installed on your server. SourceMod 1.10+ had a breaking change in the IBinTools interface and required a recompiled build. Use the *-sm110.zip if you run SourceMod 1.10+.
Attached Files
File Type: zip dhooks-2.2.0-detours17-sm110.zip (619.6 KB, 25446 views)
File Type: zip dhooks-2.2.0-detours17.zip (613.3 KB, 5516 views)
__________________

Last edited by Peace-Maker; 11-17-2021 at 07:39. Reason: Announce merge into SourceMod
Peace-Maker is offline
Oshizu
Veteran Member
Join Date: Nov 2012
Location: Warsaw
Old 05-03-2018 , 15:51   Re: DHooks (Dynamic Hooks - Dev Preview)
Reply With Quote #590

Quote:
Originally Posted by Peace-Maker View Post
[SIZE=5]Experimental dynamic detour support
Woo, that's amazing,
have my bacon

Last edited by Oshizu; 05-03-2018 at 15:52.
Oshizu is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 16:54.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode