AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Coding MM:S Plugins & SM Extensions (https://forums.alliedmods.net/forumdisplay.php?f=75)
-   -   Solved Detour the same function twice (https://forums.alliedmods.net/showthread.php?t=321317)

kadet.89 02-04-2020 15:09

Detour the same function twice
 
I have 2 extensions with detours for CreateEntityByName function:
PHP Code:

DETOUR_DECL_STATIC3(CreateEntityByNameDetourCBaseEntity *, const char *, classNameintiForceEdictIndexboolflag)
{
    return 
DETOUR_STATIC_CALL(CreateEntityByNameDetour)(classNameiForceEdictIndexflag);
}

detourPtr DETOUR_CREATE_STATIC(CreateEntityByNameDetour"CreateEntityByName"); 

The problem is that only one of the extensions can hook the function successfully - the first one. For the second one detourPtr is always nullptr.

Apparentelly the signature changes and I can't know a new one. Is there a way to bypass the limitation?

Fyren 02-05-2020 16:55

Re: Detour the same function twice
 
Detouring involves rewriting the instructions at the beginning of a function so it runs the detour instead. CDetour doesn't have a singleton/global manager to deal with two detours at the same spot, so you'll have to deal with it yourself with only one detour.

asherkin 02-05-2020 19:17

Re: Detour the same function twice
 
You can wildcard the first 8 (I think) bytes of the signature (but make sure it still matches what you expect) to account for the patched bytes from the previous detour.

kadet.89 02-06-2020 05:14

Re: Detour the same function twice
 
Quote:

Originally Posted by asherkin (Post 2682870)
You can wildcard the first 8 (I think) bytes of the signature (but make sure it still matches what you expect) to account for the patched bytes from the previous detour.

That's an interesting idea. Not sure though that it will always work properly. Correct me If I' wrong with my understanding. Lets assume the function signature is ABC, where A is to be replaced by a jump.
When the first extension is loaded the signature looks this way XBC
When the second extension is loaded, the signature looks YBC. When the function is called, the chain looks this way:

Y -> 2nd extension detour -> X - > 1st extension detour -> A -> back to the original function.

Now if the 1-st extension is unloaded, YBC is changed to ABC.
When the second extension is unloaded, ABC becomes XBC, which is not the original state and will likely lead to SIGFAULT/SIGSEGV

Loading: ABC->XBC->YBC
Unloading: YBC->ABC->XBC

Am I right?
How is it handled in virtual function hooking? the same virtual function can be hooked/unhooked many times without such problems.

Silvers 02-06-2020 07:03

Re: Detour the same function twice
 
Have done this several times. Only need to wildcard first 6 bytes. Suggest wildcard both signatures so load order isn't a factor. Unloading you raise a good point, but who really unloads extensions anyway?

Maybe alloc some memory to maintain a list of different detours and point to that. If any of the first 6 bytes don't match the original expected bytes then we have a ptr to list. Check the list for bytes which indicate a detour and have it call each one as required. Then you can safely remove the detoured addresses from the list. Something like that, don't know how possible, just an idea.

asherkin 02-06-2020 08:40

Re: Detour the same function twice
 
Quote:

Originally Posted by kadet.89 (Post 2682900)
Am I right?

Yes.

Quote:

Originally Posted by kadet.89 (Post 2682900)
How is it handled in virtual function hooking? the same virtual function can be hooked/unhooked many times without such problems.

That is the primary reason for Metamod:Source existing - it has a centralised list of all virtual function hooks done using SourceHook and can manage the inter-dependencies between plugins.

kadet.89 02-06-2020 10:13

Re: Detour the same function twice
 
Is there a way to have shared memory between several extensions?
The only solution that comes on my mind is a separate extension with shared detour handling, a bit ugly solution...

asherkin 02-06-2020 11:42

Re: Detour the same function twice
 
It belongs as part of MM:S, there's just never been a decent library for it (or really a need, detouring was fairly uncommon until quite recently) - Ayuto's DynamicHooks looks like it probably is library for it these days. Drifter has had a few attempts at adding it in the past.

kadet.89 02-08-2020 03:05

Re: Detour the same function twice
 
My current solution, in case somebody faces the same problem.
I created an extension which handles all detours that I need, redirect the function calls through virtual functions to the original functions. In all the other extensions I get the detour manager extension interface and hook the virtual functions.


All times are GMT -4. The time now is 05:33.

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