Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GameData.GetMemSig #1345

Merged
merged 1 commit into from
Oct 2, 2020
Merged

Add GameData.GetMemSig #1345

merged 1 commit into from
Oct 2, 2020

Conversation

Scags
Copy link
Contributor

@Scags Scags commented Sep 1, 2020

Adds a method of acquiring a function address via its signature from a GameData handle. I find this most useful with DHook detours, especially the "half-made" ones (detours that use gamedata solely for its signature and not parameters or anything else) that can use this for more streamlined creation.

Would convert something like this

GameData conf = LoadGameConfigFile("tf2.condmgr");
Handle hook = DHookCreateDetour(Address_Null, CallConv_THISCALL, ReturnType_Void, ThisPointer_Address);
DHookSetFromConf(hook, conf, SDKLibrary_Server, "CTFPlayerShared::AddCond");
// ... Etc
delete conf;

to

GameData conf = LoadGameConfigFile("tf2.condmgr");
Address addr = conf.GetMemSig("CTFPlayerShared::AddCond");
Handle hook = DHookCreateDetour(addr, CallConv_THISCALL, ReturnType_Void, ThisPointer_Address);
// ... Etc
delete conf;

The current way of getting addresses like such would require you to stick in a new "Addresses" section that points to the signature you want, then use GameData.GetAddress. Pretty QOL IMO.

Got it to build on both Windows and Linux though I've only tested on Windows.

Here's the test script I used

#include <sdktools>
#include <dhooks>

Handle hHndl;
public void OnPluginStart()
{
	GameData conf = LoadGameConfigFile("tf2.condmgr");
	Address addr = conf.GetMemSig("CTFPlayerShared::AddCond");
	PrintToServer("0x%X", addr);

	if (addr)
	{
		StartPrepSDKCall(SDKCall_Raw);
		PrepSDKCall_SetAddress(addr);
		PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
		PrepSDKCall_AddParameter(SDKType_Float, SDKPass_Plain);
		PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
		hHndl = EndPrepSDKCall();
	}

	Handle hook = DHookCreateDetour(addr, CallConv_THISCALL, ReturnType_Void, ThisPointer_Address);
	DHookAddParam(hook, HookParamType_Int);
	DHookAddParam(hook, HookParamType_Float);
	DHookAddParam(hook, HookParamType_Int);
	DHookEnableDetour(hook, false, OnConditionAdded);

	for (int i = MaxClients; i; --i)
		if (IsClientInGame(i))
			SDKCall(hHndl, GetEntityAddress(i) + view_as< Address >(FindSendPropInfo("CTFPlayer", "m_Shared")), 10, -1.0, 0);

	delete conf;
}

public MRESReturn OnConditionAdded(Address pThis, Handle hParams)
{
	PrintToServer("OnConditionAdded => CALLED:\n0x%X %d %.1f %d", pThis, DHookGetParam(hParams, 1), DHookGetParam(hParams, 2), DHookGetParam(hParams, 3));
}
"CTFPlayerShared::AddCond"	// (ETFCond, float, CBaseEntity*)
{
	"library" 	"server"
	"windows" 	"\x55\x8B\xEC\x83\xEC\x08\x56\x8B\xF1\x8B\x8E\x90\x01\x00\x00\x85\xC9"
	"linux" 	"@_ZN15CTFPlayerShared7AddCondE7ETFCondfP11CBaseEntity"
}

@Wend4r
Copy link
Contributor

Wend4r commented Sep 1, 2020

You can get the function address as follows

in gamegata

"Addresses"
{
	"Address:CTFPlayerShared::AddCond"
	{
		"signature" "CTFPlayerShared::AddCond"
	}
}

in SourcePawn

Address addr = conf.GetAddress("Address:CTFPlayerShared::AddCond");

@Scags
Copy link
Contributor Author

Scags commented Sep 2, 2020

I'm aware. I mentioned it above. Though adding this seems commonsensical. You can get values from every other section in a gamedata file, so why not a signature address? Secondly, this is exposed in the interface which puzzles me as to why it was never added in the first place.

@KyleSanderson KyleSanderson merged commit 589d6df into alliedmodders:master Oct 2, 2020
@KyleSanderson
Copy link
Member

This is as dangerous as the other natives we have, but I can certainly see the use-case. Thank you for the contribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants