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

[DHooks] IGameMovement Help (unexposed interfaces)


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
ici
Member
Join Date: Jan 2014
Old 01-28-2018 , 19:36   [DHooks] IGameMovement Help (unexposed interfaces)
Reply With Quote #1

Hi guys,

I've been playing around with DHooks lately.

I'm trying to reach IGameMovement / CGameMovement / CCSGameMovement and hook a couple virtual functions there. I've tried to do it on my own but I'm now at a stage where I'm kinda stuck. Here's what I've done so far:

I looked at the source code from both 2007 and 2013 and found this (src: igamemovement.h):
#define INTERFACENAME_GAMEMOVEMENT "GameMovement001"

In fact the interface name has remained the same over the years: (src: latest css linux srv binary)


I retrieved the offsets following Drifter's tutorial:
Code:
// Auto reconstructed from vtable block @ 0x008825A0
// from "server_srv.so", by ida_vtables.idc
0	CCSGameMovement::~CCSGameMovement()
1	CCSGameMovement::~CCSGameMovement()
2	CCSGameMovement::ProcessMovement(CBasePlayer *,CMoveData *)
3	CGameMovement::StartTrackPredictionErrors(CBasePlayer *)
4	CGameMovement::FinishTrackPredictionErrors(CBasePlayer *)
5	CGameMovement::DiffPrint(char const*,...)
6	CGameMovement::GetPlayerMins(bool)const
7	CGameMovement::GetPlayerMaxs(bool)const
8	CGameMovement::GetPlayerViewOffset(bool)const
9	CGameMovement::TracePlayerBBox(Vector const&,Vector const&,unsigned int,int,CGameTrace &)
10	CCSGameMovement::TryTouchGround(Vector const&,Vector const&,Vector const&,Vector const&,unsigned int,int,CGameTrace &)
11	CCSGameMovement::PlayerSolidMask(bool)
12	CCSGameMovement::PlayerMove(void)
13	CGameMovement::CalcRoll(QAngle const&,Vector const&,float,float)
14	CCSGameMovement::DecayPunchAngle(void)
15	CGameMovement::CheckWaterJump(void)
16	CGameMovement::WaterMove(void)
17	CGameMovement::AirAccelerate(Vector &,float,float)
18	CCSGameMovement::AirMove(void)
19	CGameMovement::GetAirSpeedCap(void)
20	CCSGameMovement::CanAccelerate(void)
21	CGameMovement::Accelerate(Vector &,float,float)
22	CCSGameMovement::WalkMove(void)
23	CGameMovement::FullWalkMove(void)
24	CCSGameMovement::OnJump(float)
25	CCSGameMovement::OnLand(float)
26	CGameMovement::OnTryPlayerMoveCollision(CGameTrace &)
27	CGameMovement::GetPlayerMins(void)const
28	CGameMovement::GetPlayerMaxs(void)const
29	CGameMovement::GetCheckInterval(CGameMovement::IntervalType_t)
30	CCSGameMovement::CheckJumpButton(void)
31	CGameMovement::FullTossMove(void)
32	CGameMovement::FullLadderMove(void)
33	CGameMovement::TryPlayerMove(Vector *,CGameTrace *)
34	CCSGameMovement::LadderMove(void)
35	CCSGameMovement::OnLadder(CGameTrace &)
36	CCSGameMovement::LadderDistance(void)const
37	CCSGameMovement::LadderMask(void)const
38	CCSGameMovement::ClimbSpeed(void)const
39	CCSGameMovement::LadderLateralMultiplier(void)const
40	CGameMovement::CheckStuck(void)
41	CGameMovement::CheckWater(void)
42	CGameMovement::CategorizePosition(void)
43	CCSGameMovement::CheckParameters(void)
44	CCSGameMovement::ReduceTimers(void)
45	CGameMovement::CheckFalling(void)
46	CGameMovement::PlayerRoughLandingEffects(float)
47	CCSGameMovement::Duck(void)
48	CCSGameMovement::HandleDuckingSpeedCrop(void)
49	CCSGameMovement::FinishUnDuck(void)
50	CCSGameMovement::FinishDuck(void)
51	CCSGameMovement::CanUnduck(void)
52	CGameMovement::TestPlayerPosition(Vector const&,int,CGameTrace &)
53	CGameMovement::SetGroundEntity(CGameTrace *)
54	CGameMovement::StepMove(Vector &,CGameTrace &)
55	CGameMovement::GameHasLadders(void)const
56	CCSGameMovement::PreventBunnyJumping(void)
I looked at this example and used it as a reference, wrote the script and provided the gamedata:
PHP Code:
/* Headers */
#include <sourcemod>
#include <sdktools>
#include <dhooks>

/* Compiler options */
#pragma newdecls required // Use the new syntax
#pragma semicolon 1 // Let me know if I miss a semicolon

/* Preprocessor directives */
#define PLUGIN_VERSION "1.0.0"

/* Global variables */
// CCSGameMovement::ProcessMovement(CBasePlayer *,CMoveData *)
Handle g_hProcessMovement;

public 
void OnPluginStart()
{
    
Handle gameconf LoadGameConfigFile("gamemove.games");
    
    if ( 
gameconf == null )
        
SetFailState("Why you no has gamedata?");
    
    
StartPrepSDKCall(SDKCall_Static);
    if ( !
PrepSDKCall_SetFromConf(gameconfSDKConf_Signature"CreateInterface") )
    {
        
SetFailState("Failed to get CreateInterface");
        
delete gameconf;
    }
    
    
PrepSDKCall_AddParameter(SDKType_StringSDKPass_Pointer);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_PointerVDECODE_FLAG_ALLOWNULL);
    
PrepSDKCall_SetReturnInfo(SDKType_PlainOldDataSDKPass_Plain);
    
    
char iface[32];
    if ( !
GameConfGetKeyValue(gameconf"IGameMovement"ifacesizeof(iface)) )
    {
        
SetFailState("Failed to get interface name");
        
delete gameconf;
    }
    
    
Handle call EndPrepSDKCall();
    
Address addr SDKCall(calliface0);
    
delete call;
    
    if ( !
addr )
    {
        
SetFailState("Failed to get IGameMovement ptr");
    }
    
    
int offset GameConfGetOffset(gameconf"ProcessMovement");
    if (
offset == -1)
        
SetFailState("Couldn't find offset for ProcessMovement");
    
    
g_hProcessMovement DHookCreate(offsetHookType_RawReturnType_VoidThisPointer_IgnoreHook_ProcessMovement);
    
DHookAddParam(g_hProcessMovementHookParamType_CBaseEntity);
    
DHookAddParam(g_hProcessMovementHookParamType_ObjectPtr);
    
DHookRaw(g_hProcessMovementfalseaddr);
    
    
delete gameconf;
}

public 
MRESReturn Hook_ProcessMovement(Handle hParams)
{
    
int client DHookGetParam(hParams1);
    
    
PrintToChatAll("%N ProcessMovement"client);
    
    return 
MRES_Ignored;

Gamedata: (src: gamemove.games.txt)
Code:
"Games"
{
	"cstrike"
	{
		"Keys"
		{
			"IGameMovement"		"GameMovement001"
		}
		"Signatures"
		{
			"CreateInterface"
			{
				"library"		"engine"
				"windows"		"@CreateInterface"
				"linux"			"@CreateInterface"
			}
		}
		"Offsets"
		{
			// CCSGameMovement::ProcessMovement(CBasePlayer *,CMoveData *)
			// virtual void	ProcessMovement( CBasePlayer *pPlayer, CMoveData *pMove );
			"ProcessMovement"
			{
				"windows"		"1"
				"linux"			"2"
			}
			
			// CGameMovement::AirAccelerate(Vector &,float,float)
			// virtual void	AirAccelerate( Vector& wishdir, float wishspeed, float accel );
			"AirAccelerate"
			{
				"windows"		"16"
				"linux"			"17"
			}
			
			// CCSGameMovement::AirMove(void)
			// virtual void	AirMove( void );
			"AirMove"
			{
				"windows"		"17"
				"linux"			"18"
			}
			
			// CCSGameMovement::OnJump(float)
			// virtual void	OnJump( float fImpulse );
			"OnJump"
			{
				"windows"		"23"
				"linux"			"24"
			}
			
			// CCSGameMovement::OnLand(float)
			// virtual void	OnLand( float fVelocity );
			"OnLand"
			{
				"windows"		"24"
				"linux"			"25"
			}
		}
	}
}

Found out I could use @CreateInterface for Windows too instead of supplying a signature. Does anybody know why this is the case? Is that just an alias that SM converts to a unique byte pattern under the hood?


So far so good, the script compiles. However, I get a runtime error:
Code:
L 01/28/2018 - 16:29:20: [SM] Exception reported: Failed to get IGameMovement ptr
L 01/28/2018 - 16:29:20: [SM] Blaming: gamemove.smx
L 01/28/2018 - 16:29:20: [SM] Call stack trace:
L 01/28/2018 - 16:29:20: [SM]   [0] SetFailState
L 01/28/2018 - 16:29:20: [SM]   [1] Line 48, C:\dev\sourcepawn\gamemove\gamemove.sp::OnPluginStart
L 01/28/2018 - 16:29:20: [SM] Unable to load plugin "gamemove.smx": Error detected in plugin startup (see error logs)
Ok, so before I did all of this - wrote the script, gathered the offsets and so on, I found this post on DHooks' official thread:

Quoting psychonic: https://forums.alliedmods.net/showpo...&postcount=453
Quote:
Originally Posted by psychonic View Post
The IGameMovement pointer isn't exposed as an interface. You'd need to use custom gamedata for it, using Address gamedata with "@g_pGameMovement" (?) symbol for OS's where symbols are available (usually Linux and Mac) and a byte signature with offset and a read to get it on others (Windows).
I was going through the source code earlier on and accidently found this (src: ccsgamemovement.cpp):


I assumed I could actually access it, because it said it's exposed. I thought maybe Valve had updated it or psychonic was wrong. It turns out psychonic wasn't wrong. The interface is not exposed, but why? What do these lines of code actually do then? I mean, I can see the #define generates this sorta function but I don't understand much about how and why it's used:


What I don't understand is how psychonic found out the interface is not exposed. What is actually meant by an "exposed interface"? Is there a list of all interfaces that are exposed? How do I know if an interface is exposed?

If somebody could guide me in the right direction, provide an article/post or something I could read, I'd be grateful. I'm trying to learn here. Psychonic has somewhat provided me with the steps I need to undertake, but I feel stuck because I don't know what he means by all of that he's written. I mean, I've found peace-maker's post explaining what "read" is for but I still don't understand how to use it.

I've done a little bit of sigscanning before - generating sigs for outdated extensions pmuch. Those sigs were for functions though. "@g_pGameMovement" - isn't that a member ptr variable? When I use the sig generator script inside IDA, it tells me I have to be inside a function. So yeah, that's why I'm stuck, I don't know what to do. If someone could break it down for me, I'd really appreciate it. I also believe it will be beneficial to other people interested in using DHooks and cpp/asm in general.

Thank you

P.S.
I'm still waiting for Drifter's 2nd tutorial!

P.P.S
I know that's a lot of info to digest. I'm sorry for the wall of text. I'll colour all my questions in red.

Last edited by ici; 01-28-2018 at 19:46.
ici is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 01-29-2018 , 00:53   Re: [DHooks] IGameMovement Help (unexposed interfaces)
Reply With Quote #2

Quote:
Originally Posted by ici View Post
Found out I could use @CreateInterface for Windows too instead of supplying a signature. Does anybody know why this is the case? Is that just an alias that SM converts to a unique byte pattern under the hood?
If a signature starts with an @, it's a symbol. A function in a DLL that's intended to be used by others will not be stripped so that it can be easily called. CreateInterface is one such function.

Quote:
The interface is not exposed, but why? What do these lines of code actually do then? I mean, I can see the #define generates this sorta function but I don't understand much about how and why it's used.

What I don't understand is how psychonic found out the interface is not exposed. What is actually meant by an "exposed interface"? Is there a list of all interfaces that are exposed? How do I know if an interface is exposed?
Valve chooses what they want to hand out. In that sense, if it's not in the SDK under public/, it isn't "exposed." You could use a different meaning for "exposed" where it means "reasonably accessible."

The lines in your image do create a global variable and add it to the list of interfaces in the DLL.

That said, it looks like IGameMovement is part of the server but you're calling CreateInterface on the engine. I tried doing the call manually in gdb on CSGO and it returned a pointer. I'd guess it should work in any game. I didn't try doing it through a plugin.

Quote:
"@g_pGameMovement" - isn't that a member ptr variable? When I use the sig generator script inside IDA, it tells me I have to be inside a function.
If you see just "@g_pGameMovement" in gamedata, you only know it's a symbol in a binary. It's a pretty easy guess that it's a global variable that's a pointer to something based on the name. A "member pointer variable" sounds like maybe you mean "a member of a class that's a pointer" or "a pointer to a member of a class" which are both wrong.

If you're looking up a function, you can use a signature made up of the instructions for that function. A global variable is just going to be sitting off in space somewhere, probably with other globals around it. There's nothing to directly search for. You instead will have to find somewhere it's used in a function, then write some code/gamedata to pull out the address from the code that uses it.

The function in one of your images does use it, but you probably can't make a unique signature out of it, so you'd have to find it elsewhere. If CreateInterface on the server works, you won't need to do that, though.

Last edited by Fyren; 01-29-2018 at 00:55. Reason: rephrase something
Fyren is offline
backwards
AlliedModders Donor
Join Date: Feb 2014
Location: USA
Old 01-29-2018 , 01:16   Re: [DHooks] IGameMovement Help (unexposed interfaces)
Reply With Quote #3

You need to call CreateInterface in server.dll instead of engine to get the exposed interface for game movement. I'm surprised you're going this far inside a source mod plugin, most people at this point would switch to a c++ plugin project. Also process movement was at vmt[0] and not vmt[1] last i checked in csgo about 6 months ago. (I'm not sure if offset 1 is equal to 0 in this case)
__________________
I highly recommend joining the SourceMod Discord Server for real time support.
backwards is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 01-29-2018 , 05:27   Re: [DHooks] IGameMovement Help (unexposed interfaces)
Reply With Quote #4

I recently hooked ProcessMovement and offset I got was 1 (right after destructor) for windows. I also did it with DHooks to test out some stuff, so you might find the code and/or the gamedata useful: https://forums.alliedmods.net/showpo...61&postcount=8

But if you're doing a big project you should probably be doing this in an extension instead. I don't think sourcemod plugins are built for this type of thing, and it can get really messy.

Last edited by hmmmmm; 01-29-2018 at 05:32.
hmmmmm is offline
ici
Member
Join Date: Jan 2014
Old 01-30-2018 , 17:12   Re: [DHooks] IGameMovement Help (unexposed interfaces)
Reply With Quote #5

Thanks a lot for the help boys

It worked after I changed the library from engine to server.

Quote:
If you see just "@g_pGameMovement" in gamedata, you only know it's a symbol in a binary. It's a pretty easy guess that it's a global variable that's a pointer to something based on the name. A "member pointer variable" sounds like maybe you mean "a member of a class that's a pointer" or "a pointer to a member of a class" which are both wrong.
Yeah, a global ptr var is what I meant there, my bad. Confused the prefix, thought it was m_

Anyway, I got ProcessMovement to work. However, the callbacks for AirMove & AirAccelerate don't seem to get called using the offsets I've set above. I've tried increasing and decreasing the offsets to see if any work. The server crashed when I did that. I've tried changing the hooks from pre to post - still no luck. Does any of you know what the problem could be? Here's the script as it is right now:

PHP Code:
/* Headers */
#include <sourcemod>
#include <sdktools>
#include <dhooks>

/* Compiler options */
#pragma newdecls required // Use the new syntax
#pragma semicolon 1 // Let me know if I miss a semicolon

/* Preprocessor directives */
#define PLUGIN_VERSION "1.0.0"

/* Global variables */

// CCSGameMovement::ProcessMovement(CBasePlayer *,CMoveData *)
Handle g_hProcessMovement;

// CGameMovement::AirAccelerate(Vector &,float,float)
Handle g_hAirAccelerate;

// CCSGameMovement::AirMove(void)
Handle g_hAirMove;

// CCSGameMovement::OnJump(float)
Handle g_hOnJump;

public 
void OnPluginStart()
{
    
Handle gameconf LoadGameConfigFile("gamemove.games");
    
    if ( 
gameconf == null )
        
SetFailState("Why you no has gamedata?");
    
    
StartPrepSDKCall(SDKCall_Static);
    if ( !
PrepSDKCall_SetFromConf(gameconfSDKConf_Signature"CreateInterface") )
    {
        
SetFailState("Failed to get CreateInterface");
        
delete gameconf;
    }
    
    
PrepSDKCall_AddParameter(SDKType_StringSDKPass_Pointer);
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_PointerVDECODE_FLAG_ALLOWNULL);
    
PrepSDKCall_SetReturnInfo(SDKType_PlainOldDataSDKPass_Plain);
    
    
char iface[32];
    if ( !
GameConfGetKeyValue(gameconf"IGameMovement"ifacesizeof(iface)) )
    {
        
SetFailState("Failed to get interface name");
        
delete gameconf;
    }
    
    
Handle call EndPrepSDKCall();
    
Address addr SDKCall(calliface0);
    
delete call;
    
    if ( !
addr )
    {
        
SetFailState("Failed to get IGameMovement ptr");
    }
    
    
int offset GameConfGetOffset(gameconf"ProcessMovement");
    if (
offset == -1)
        
SetFailState("Couldn't find offset for ProcessMovement");
    
    
g_hProcessMovement DHookCreate(offsetHookType_RawReturnType_VoidThisPointer_IgnoreHook_ProcessMovement);
    
DHookAddParam(g_hProcessMovementHookParamType_CBaseEntity);
    
DHookAddParam(g_hProcessMovementHookParamType_ObjectPtr);
    
DHookRaw(g_hProcessMovementfalseaddr);
    
    
offset GameConfGetOffset(gameconf"AirAccelerate");
    if (
offset == -1)
        
SetFailState("Couldn't find offset for AirAccelerate");
    
    
g_hAirAccelerate DHookCreate(offsetHookType_RawReturnType_VoidThisPointer_IgnoreHook_AirAccelerate);
    
DHookAddParam(g_hAirAccelerateHookParamType_Object3DHookPass_ByRef); // Vector& wishdir
    
DHookAddParam(g_hAirAccelerateHookParamType_Float); // float wishspeed
    
DHookAddParam(g_hAirAccelerateHookParamType_Float); // float accel
    
DHookRaw(g_hAirAcceleratefalseaddr);
    
    
offset GameConfGetOffset(gameconf"AirMove");
    if (
offset == -1)
        
SetFailState("Couldn't find offset for AirMove");
    
    
g_hAirMove DHookCreate(offsetHookType_RawReturnType_VoidThisPointer_IgnoreHook_AirMove);
    
DHookRaw(g_hAirMovefalseaddr);
    
    
offset GameConfGetOffset(gameconf"OnJump");
    if (
offset == -1)
        
SetFailState("Couldn't find offset for OnJump");
    
    
g_hOnJump DHookCreate(offsetHookType_RawReturnType_VoidThisPointer_IgnoreHook_OnJump);
    
DHookAddParam(g_hOnJumpHookParamType_Float); // float fImpulse
    //DHookRaw(g_hOnJump, false, addr);
    
    
delete gameconf;
}

public 
MRESReturn Hook_OnJump(Handle hParams)
{
    
PrintToChatAll("OnJump");
    
    return 
MRES_Ignored;
}

public 
MRESReturn Hook_AirMove(Handle hParams)
{
    
PrintToChatAll("AirMove");
    
    return 
MRES_Ignored;
}

public 
MRESReturn Hook_AirAccelerate(Handle hParams)
{
    
PrintToChatAll("AirAccelerate");
    
    return 
MRES_Ignored;
}

public 
MRESReturn Hook_ProcessMovement(Handle hParams)
{
    
int client DHookGetParam(hParams1);
    
    
// m_bFirstRunOfFunctions & m_bGameCodeMovedPlayer bit field
    //int m_bFirstRunOfFunctions = DHookGetParamObjectPtrVar(hParams, 2, 0, ObjectValueType_Int); // or Bool
    //int m_nPlayerHandle = DHookGetParamObjectPtrVar(hParams, 2, 4, ObjectValueType_Ehandle);
    //int m_nImpulseCommand = DHookGetParamObjectPtrVar(hParams, 2, 8, ObjectValueType_Int);
    
    //float m_vecViewAngles[3];
    //DHookGetParamObjectPtrVarVector(hParams, 2, 12, ObjectValueType_Vector, m_vecViewAngles);
    //float m_vecAbsViewAngles[3];
    //DHookGetParamObjectPtrVarVector(hParams, 2, 24, ObjectValueType_Vector, m_vecAbsViewAngles);
    
    //int m_nButtons = DHookGetParamObjectPtrVar(hParams, 2, 36, ObjectValueType_Int);
    //int m_nOldButtons = DHookGetParamObjectPtrVar(hParams, 2, 40, ObjectValueType_Int);
    //float m_flForwardMove = DHookGetParamObjectPtrVar(hParams, 2, 44, ObjectValueType_Float);
    //float m_flSideMove = DHookGetParamObjectPtrVar(hParams, 2, 48, ObjectValueType_Float);
    //float m_flUpMove = DHookGetParamObjectPtrVar(hParams, 2, 52, ObjectValueType_Float);
    //float m_flMaxSpeed = DHookGetParamObjectPtrVar(hParams, 2, 56, ObjectValueType_Float);
    //float m_flClientMaxSpeed = DHookGetParamObjectPtrVar(hParams, 2, 60, ObjectValueType_Float);
    
    //float m_vecVelocity[3];
    //DHookGetParamObjectPtrVarVector(hParams, 2, 64, ObjectValueType_Vector, m_vecVelocity);
    //float m_vecAngles[3];
    //DHookGetParamObjectPtrVarVector(hParams, 2, 76, ObjectValueType_Vector, m_vecAngles);
    //float m_vecOldAngles[3];
    //DHookGetParamObjectPtrVarVector(hParams, 2, 88, ObjectValueType_Vector, m_vecAngles);
    
    //float m_outStepHeight = DHookGetParamObjectPtrVar(hParams, 2, 100, ObjectValueType_Float);
    
    //float m_outWishVel[3];
    //DHookGetParamObjectPtrVarVector(hParams, 2, 104, ObjectValueType_Vector, m_outWishVel);
    //float m_outJumpVel[3];
    //DHookGetParamObjectPtrVarVector(hParams, 2, 116, ObjectValueType_Vector, m_outJumpVel);
    //float m_vecConstraintCenter[3];
    //DHookGetParamObjectPtrVarVector(hParams, 2, 128, ObjectValueType_Vector, m_vecConstraintCenter);
    
    //float m_flConstraintRadius = DHookGetParamObjectPtrVar(hParams, 2, 140, ObjectValueType_Float);
    //float m_flConstraintWidth = DHookGetParamObjectPtrVar(hParams, 2, 144, ObjectValueType_Float);
    //float m_flConstraintSpeedFactor = DHookGetParamObjectPtrVar(hParams, 2, 148, ObjectValueType_Float);
    
    
float m_vecAbsOrigin[3];
    
DHookGetParamObjectPtrVarVector(hParams2152ObjectValueType_Vectorm_vecAbsOrigin);
    
    
PrintHintText(client"ProcessMovement\n \n"
        
//... "m_bFirstRunOfFunctions: %d\n"
        //... "m_nPlayerHandle: %d\n"
        //... "m_nImpulseCommand: %d\n"
        //... "m_vecViewAngles: %.1f %.1f %.1f\n"
        //... "m_vecAbsViewAngles: %.1f %.1f %.1f\n"
        //... "m_nButtons: %d\n"
        //... "m_nOldButtons: %d\n"
        //... "m_flForwardMove: %.2f\n"
        //... "m_flSideMove: %.2f\n"
        //... "m_flUpMove: %.2f\n"
        //... "m_flMaxSpeed: %.2f\n"
        //... "m_flClientMaxSpeed: %.2f\n"
        //... "m_vecVelocity: %.1f %.1f %.1f\n"
        //... "m_vecAngles: %.1f %.1f %.1f\n"
        //... "m_vecOldAngles: %.1f %.1f %.1f\n"
        //... "m_outStepHeight: %.2f\n"
        //... "m_outWishVel: %.1f %.1f %.1f\n"
        //... "m_outJumpVel: %.1f %.1f %.1f\n"
        //... "m_vecConstraintCenter: %.1f %.1f %.1f\n"
        //... "m_flConstraintRadius: %.2f\n"
        //... "m_flConstraintWidth: %.2f\n"
        //... "m_flConstraintSpeedFactor: %.2f\n"
        
... "m_vecAbsOrigin: %.1f %.1f %.1f\n",
        
        
//m_bFirstRunOfFunctions,
        //m_nPlayerHandle,
        //m_nImpulseCommand,
        //m_vecViewAngles[0], m_vecViewAngles[1], m_vecViewAngles[2],
        //m_vecAbsViewAngles[0], m_vecAbsViewAngles[1], m_vecAbsViewAngles[2],
        //m_nButtons,
        //m_nOldButtons,
        //m_flForwardMove,
        //m_flSideMove,
        //m_flUpMove,
        //m_flMaxSpeed,
        //m_flClientMaxSpeed,
        //m_vecVelocity[0], m_vecVelocity[1], m_vecVelocity[2]
        //m_vecAngles[0], m_vecAngles[1], m_vecAngles[2],
        //m_vecOldAngles[0], m_vecOldAngles[1], m_vecOldAngles[2],
        //m_outStepHeight,
        //m_outWishVel[0], m_outWishVel[1], m_outWishVel[2],
        //m_outJumpVel[0], m_outJumpVel[1], m_outJumpVel[2],
        //m_vecConstraintCenter[0], m_vecConstraintCenter[1], m_vecConstraintCenter[2],
        //m_flConstraintRadius,
        //m_flConstraintWidth,
        //m_flConstraintSpeedFactor,
        
m_vecAbsOrigin[0], m_vecAbsOrigin[1], m_vecAbsOrigin[2]
        );
        
    return 
MRES_Ignored;

Also, OnJump seems to crash the server for whatever reason too. That's why I've commented it out. Any ideas why this one doesn't work as well?

Quote:
If you're looking up a function, you can use a signature made up of the instructions for that function. A global variable is just going to be sitting off in space somewhere, probably with other globals around it. There's nothing to directly search for. You instead will have to find somewhere it's used in a function, then write some code/gamedata to pull out the address from the code that uses it.
I had a look at hmmmmm's example code and I think I understand the concept better now. I have a question. Suppose you have the following function and you're trying to access g_pGameMovement:

Code:
void foo(int param)
{
	doSomething(param);
	int temp;
	g_pGameMovement = nullptr; // how many bytes should you offset away from foo?
}
How do you know how many bytes to offset away from foo in order to reach g_pGameMovement? I assume you'd have to know how cpp works internally and how it lays out data in memory. Are there any rules one needs to follow? Perhaps find the correct "read" value by trial and error? hmmmmm, how did you find out you had to offset 9 bytes away from CPhysicsPushedEntities::SpeculativelyCheckPus h for ex.?

Quote:
I'm surprised you're going this far inside a source mod plugin, most people at this point would switch to a c++ plugin project.
Quote:
But if you're doing a big project you should probably be doing this in an extension instead. I don't think sourcemod plugins are built for this type of thing, and it can get really messy.
I'm not working on anything huge in particular. I'm curious about how certain things work under the hood. I also don't feel very confident I could write extensions. I might look up the tutorials and try something out in the future, though.

Once again, thanks a lot for the replies!
ici is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 01-30-2018 , 23:33   Re: [DHooks] IGameMovement Help (unexposed interfaces)
Reply With Quote #6

Quote:
Originally Posted by ici View Post
How do you know how many bytes to offset away from foo in order to reach g_pGameMovement? I assume you'd have to know how cpp works internally and how it lays out data in memory. Are there any rules one needs to follow? Perhaps find the correct "read" value by trial and error? hmmmmm, how did you find out you had to offset 9 bytes away from CPhysicsPushedEntities::SpeculativelyCheckPus h for ex.?
You would look at the actual assembly code in the binary and count. There's an option in IDA somewhere to show the opcodes.
Fyren is offline
backwards
AlliedModders Donor
Join Date: Feb 2014
Location: USA
Old 01-31-2018 , 00:00   Re: [DHooks] IGameMovement Help (unexposed interfaces)
Reply With Quote #7

They have plugins and python scripts that automatically find the shortest unique signature for the selected position of your cursor in IDA and it retrieves the offset to that position from the unique signature as well with a code mask ready for signature scanning functions.
__________________
I highly recommend joining the SourceMod Discord Server for real time support.
backwards is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 01-31-2018 , 01:13   Re: [DHooks] IGameMovement Help (unexposed interfaces)
Reply With Quote #8

Like Fyren said, you turn on the opcodes (options->general->no. of opcode bytes) and count. One thing to keep in mind is that pointers are like ints and are 4 bytes long. With that in mind when you look at this, which is where the windows signature leads to, you want to get to the last 4 bytes which would be g_pGameMovement. So you count from the top to the last 4 bytes and you get 9.

Last edited by hmmmmm; 01-31-2018 at 01:14.
hmmmmm is offline
psychonic

BAFFLED
Join Date: May 2008
Old 01-31-2018 , 07:57   Re: [DHooks] IGameMovement Help (unexposed interfaces)
Reply With Quote #9

Quote:
Originally Posted by 1337norway View Post
They have plugins and python scripts that automatically find the shortest unique signature for the selected position of your cursor in IDA.
Not a plugin nor a python script, but we do have an idc script for it.
https://github.com/alliedmodders/sou...ts/makesig.idc
psychonic is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 01-31-2018 , 08:35   Re: [DHooks] IGameMovement Help (unexposed interfaces)
Reply With Quote #10

Quote:
Originally Posted by psychonic View Post
Not a plugin nor a python script, but we do have an idc script for it.
https://github.com/alliedmodders/sou...ts/makesig.idc
I think he meant other scripts that also generate sigs but don't automatically seek beginning of function like makesig.idc does.
hmmmmm is offline
Reply



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 19:11.


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