Raised This Month: $65 Target: $400
 16% 

Solved Crash on DHook detouring (dhooks.ext.dll + 0xc3e0)


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Addie
Junior Member
Join Date: Nov 2018
Old 11-09-2018 , 04:24   Crash on DHook detouring (dhooks.ext.dll + 0xc3e0)
Reply With Quote #1

I'm trying to get the address to a function from its caller function, to set up a detour for it. It looks like this:

CNMRiH_GameRules::CleanAndResetMap(void) + E4 == call CEventQueue::Clear(void)

Both are non-virtual so I'm using DHooks with Experimental Dynamic Detours. I set up my gamedata to look like this:

PHP Code:
"Games"
{
    
"nmrih"
    
{
        
"Addresses"
        
{
            
"CEventQueue::Clear"
            
{
                
"windows"
                
{
                    
"signature" "CNMRiH_GameRules::CleanAndResetMap"        //Tells it to use this signature which is in the signatures block        
                    
"read" "228"        //Tells it to read 228 bytes and get the pointer for what is here    
                
}
                
//"linux"{}
            
}
        }
        
        
"Signatures"
        
{
            
/* Used solely to get the offset for CEventQueue::Clear */
            
"CNMRiH_GameRules::CleanAndResetMap"
            
{
                
"library" "server"
                "windows" "\x55\x8B\xEC\xA1****\x83\xEC\x24\x83\x78\x30\x00\x56\x57"
                "linux" "@_ZN16CNMRiH_GameRules16CleanAndResetMapEv"
            
}
        }    
    }

And this is my script:

PHP Code:
#include <sdktools>
#include <dhooks>

#define DHOOK_PRE false
#define DHOOK_POST true

Handle hClear;

public 
void OnPluginStart()
{
    
Handle hGameData LoadGameConfigFile("EQC.games");
    if(!
hGameData)
        
SetFailState("Couldn't find EQC.games gamedata.");
    
    
// Setup detour on CEventQueue::Clear
    
hClear DHookCreateDetour(Address_NullCallConv_THISCALLReturnType_VoidThisPointer_Address);
    if (!
hClear)
        
SetFailState("Failed to set up detour for CEventQueue::Clear");
    
    
// Load the address of the function from EQC's address gamedata file.
    
if (!DHookSetFromConf(hClearhGameDataSDKConf_Address"CEventQueue::Clear"))
        
SetFailState("Failed to load CEventQueue::Clear address from gamedata");
    
    
// Add a pre hook on the function.
    
if (!DHookEnableDetour(hClearDHOOK_PREDetour_OnEventQueueClear))
        
SetFailState("Failed to detour CEventQueue::Clear");
    
    
PrintToServer("CEventQueue::Clear detoured!");
}

public 
MRESReturn Detour_OnEventQueueClear(Address pThisHandle hReturnHandle hParams)
{
    
PrintToServer("CEventQueue::Clear called");
    
//Do stuff
    
return MRES_Ignored;

However, it seems to crash the server the moment I start it.

https://crash.limetech.org/sselqyxocfdi
https://crash.limetech.org/zltfxqe7oabw

Am I doing something wrong here? The signature is confirmed valid
Thanks

Last edited by Addie; 11-09-2018 at 23:14.
Addie is offline
Benoist3012
Veteran Member
Join Date: Mar 2014
Location: CWave::ForceFinish()
Old 11-09-2018 , 05:27   Re: Crash on DHook detouring (dhooks.ext.dll + 0xc3e0)
Reply With Quote #2

PHP Code:
"Games"
{
    
"nmrih"
    
{
        
"Addresses"
        
{
            
"CEventQueue::Clear"
            
{
                
"windows"
                
{
                    
"signature" "CNMRiH_GameRules::CleanAndResetMap"        //Tells it to use this signature which is in the signatures block        
                    
"read" "228"        //Tells it to read 228 bytes and get the pointer for what is here    
                
}
                
//"linux"{}
                
"read" "0"
            
}
        }
        
        
"Signatures"
        
{
            
/* Used solely to get the offset for CEventQueue::Clear */
            
"CNMRiH_GameRules::CleanAndResetMap"
            
{
                
"library" "server"
                "windows" "\x55\x8B\xEC\xA1****\x83\xEC\x24\x83\x78\x30\x00\x56\x57"
                "linux" "@_ZN16CNMRiH_GameRules16CleanAndResetMapEv"
            
}
        }    
    }

Add "read" "0" this shall fix your issue.
https://wiki.alliedmods.net/SDKTools...ddress_lookups

Edit:
Location in sourcemod code where this is done https://github.com/alliedmodders/sou...pp#L1031#L1047
__________________

Last edited by Benoist3012; 11-09-2018 at 05:44.
Benoist3012 is offline
Addie
Junior Member
Join Date: Nov 2018
Old 11-09-2018 , 06:40   Re: Crash on DHook detouring (dhooks.ext.dll + 0xc3e0)
Reply With Quote #3

Thank you, I've fixed that together with a wrong offset calculation (now 244 instead of 228)

Unfortunately, it's still crashing, now on sourcemod.logic.dll!CGameConfig::GetAddress instead:
https://crash.limetech.org/hhvmep4pdgdl

I'm not sure what's up with that. The offset is definitely correct this time:



PHP Code:
"CEventQueue::Clear"
{
    
"windows"
    
{
        
"signature" "CNMRiH_GameRules::CleanAndResetMap"    
        "read" "244"
    
}
    
//"linux"{}
    
"read" "0"

(page also added "offset" "4" so I tried with that as well)

Last edited by Addie; 11-09-2018 at 06:46.
Addie is offline
hmmmmm
Senior Member
Join Date: Mar 2017
Location: ...
Old 11-09-2018 , 18:08   Re: Crash on DHook detouring (dhooks.ext.dll + 0xc3e0)
Reply With Quote #4

Any chance you can send the IDB?
hmmmmm is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 11-09-2018 , 18:54   Re: Crash on DHook detouring (dhooks.ext.dll + 0xc3e0)
Reply With Quote #5

"Read" isn't for offsets, it's for indirections.

Last edited by Fyren; 11-10-2018 at 01:02. Reason: see later reply
Fyren is offline
Addie
Junior Member
Join Date: Nov 2018
Old 11-09-2018 , 20:46   Re: Crash on DHook detouring
Reply With Quote #6

Quote:
Originally Posted by hmmmmm View Post
Any chance you can send the IDB?
It created an i64 file instead, does that work?
https://www.dropbox.com/s/ls4l9puj2j...erver.i64?dl=0

Quote:
Originally Posted by Fyren View Post
"Read" isn't for offsets, it's for indirections.
Alright bear with me, I'm still pretty new to this; If the offset doesn't go there, where should I specify it?

Thanks for the hints so far
Addie is offline
Addie
Junior Member
Join Date: Nov 2018
Old 11-09-2018 , 23:13   Re: Crash on DHook detouring (dhooks.ext.dll + 0xc3e0)
Reply With Quote #7

Marking as solved as I managed to get my hands on a unique signature for the target function (thanks Ryan!) This approach is no longer needed.

Last edited by Addie; 11-09-2018 at 23:13.
Addie is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 11-10-2018 , 01:17   Re: Crash on DHook detouring (dhooks.ext.dll + 0xc3e0)
Reply With Quote #8

I was wrong in my earlier reply. A read or offset entry are equivalent.

Though you found an alternate solution, in case someone happens to want the info:

If you have a signature for a function, and 0xF4 bytes into that function is a call instruction, then addressOf(sig) + 0xF4 does not hold the target of the call. First, there's an 0xE8 for call's opcode, then a relative offset for the target. It's relative to the next instruction.

So, the offset is at addressOf(sig) + 0xF5. You'd have to get what's at that address (you could use a "read" "0" like Benoist said) and add it to addressOf(sig) + 0xF4 + 0x5. The 0x5 is because the call instruction is 5 bytes long, so that's the address of the next instruction.
Fyren is offline
hmmmmm
Senior Member
Join Date: Mar 2017
Location: ...
Old 11-10-2018 , 06:35   Re: Crash on DHook detouring
Reply With Quote #9

Glad you solved it

Quote:
Originally Posted by Addie View Post
It created an i64 file instead, does that work?
For reference an i64 is just an IDB created by x64 version of IDA for x64 binaries.
hmmmmm is offline
Addie
Junior Member
Join Date: Nov 2018
Old 11-10-2018 , 11:33   Re: Crash on DHook detouring (dhooks.ext.dll + 0xc3e0)
Reply With Quote #10

Quote:
Originally Posted by Fyren View Post
I was wrong in my earlier reply. A read or offset entry are equivalent.

Though you found an alternate solution, in case someone happens to want the info:

If you have a signature for a function, and 0xF4 bytes into that function is a call instruction, then addressOf(sig) + 0xF4 does not hold the target of the call. First, there's an 0xE8 for call's opcode, then a relative offset for the target. It's relative to the next instruction.

So, the offset is at addressOf(sig) + 0xF5. You'd have to get what's at that address (you could use a "read" "0" like Benoist said) and add it to addressOf(sig) + 0xF4 + 0x5. The 0x5 is because the call instruction is 5 bytes long, so that's the address of the next instruction.
Thanks for clearing that up, I'll keep it in mind for future use
Addie 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 14:44.


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