Difference between revisions of "Virtual Offsets (Source Mods)"

From AlliedModders Wiki
Jump to: navigation, search
m (Hidden: Source: err)
(Swap out Berni's offset dumper for Asherkin's)
 
(17 intermediate revisions by 10 users not shown)
Line 6: Line 6:
  
 
== Offset Lists ==
 
== Offset Lists ==
 +
==== Automated Offsets ====
 +
You can get updated offsets from the following tool. It automatically updates the offsets when an update is pushed by Valve for the 6 games it supports, and you may input your own *.so file to obtain offsets for other games.
 +
* [https://asherkin.github.io/vtable VTable Dumper (by Asherkin)]
 
==== Counter-Strike: Source ====
 
==== Counter-Strike: Source ====
* [[CCSPlayer offset list (SourceMM)|CCSPlayer]]
+
* [[CCSPlayer Offset List (Counter-Strike: Source)|CCSPlayer]]
* [[CBaseCombatWeapon CSS offset list (SourceMM)|CBaseCombatWeapon]]
+
* [[CBaseCombatWeapon Offset List (Counter-Strike: Source)|CBaseCombatWeapon]]
 +
* [[CCSGameRules Offset List (Counter-Strike: Source) | CCSGameRules]]
 +
* [[CBaseGrenade Offset List (Counter-Strike: Source) | CBaseGrenade]]
 +
* [[CDEagle Offset List (Counter-Strike: Source) | CDEagle]]
  
 
==== Day of Defeat: Source ====
 
==== Day of Defeat: Source ====
* [[CDODPlayer offset list (SourceMM)|CDODPlayer]]
+
* [[CDODPlayer Offset List (Day of Defeat: Source)|CDODPlayer]]
  
 
==== Dystopia ====
 
==== Dystopia ====
* [[Dystopia CDYSPlayer offset list (SourceMM)|CDYSPlayer]]
+
* [[CDYSPlayer Offset List (Dystopia)|CDYSPlayer]]
  
==== Empires ====
+
==== Empires v2.12 ====
* [[Empires CSDKPlayer offset list (SourceMM)|CSDKPlayer]]
+
* [[CSDKPlayer Offset List (Empires)|CSDKPlayer]]
  
 
==== Fortress Forever ====
 
==== Fortress Forever ====
* [[FortressForever CFFPlayer offset list|CFFPlayer]]
+
* [[CFFPlayer Offset List (Fortress Forever)|CFFPlayer]]
  
 
==== Half-Life 2: Capture the Flag ====
 
==== Half-Life 2: Capture the Flag ====
* [[HL2CTF CHL2_Player offset list (SourceMM)|CHL2_Player]]
+
* [[CHL2_Player Offset List (Half-Life 2: Capture the Flag)|CHL2_Player]]
  
 
==== Half-Life 2: Deathmatch ====
 
==== Half-Life 2: Deathmatch ====
* [[CHL2MP_Player offset list (SourceMM)|CHL2MP_Player]]
+
* [[CHL2MP_Player Offset List (Half-Life 2: Deathmatch)|CHL2MP_Player]]
  
 
==== Hidden: Source ====
 
==== Hidden: Source ====
* [[CSDKPlayer offset list (Hidden:Source)|CSDKPlayer]]
+
* [[CSDKPlayer Offset List (Hidden: Source)|CSDKPlayer]]
  
 
==== Insurgency ====
 
==== Insurgency ====
* [[Insurgency CINSPlayer offset list (SourceMM)|CINSPlayer]]
+
* [[CINSPlayer Offset List (Insurgency)|CINSPlayer]]
 +
 
 +
==== Left 4 Dead ====
 +
* [[CTerrorPlayer Offset List (Left 4 Dead)|CTerrorPlayer]]
 +
 
 +
==== Left 4 Dead 2 ====
 +
* [[CTerrorPlayer Offset List (Left 4 Dead 2)|CTerrorPlayer]]
 +
 
 +
==== Obsidian Conflict ====
 +
* [[CHL2MP_Player Offset List (Obsidian Conflict)|CHL2MP_Player]]
  
 
==== Pirates, Vikings, and Knights II ====
 
==== Pirates, Vikings, and Knights II ====
* [[PVK II CPVK2Player offset list (SourceMM)|CPVK2Player]]
+
* [[CPVK2Player Offset List (Pirates, Vikings, and Knights II)|CPVK2Player]]
  
 
==== The Ship ====
 
==== The Ship ====
* [[The Ship CShipPlayer offset list (SourceMM)|CShipPlayer]]
+
* [[CShipPlayer Offset List (The Ship)|CShipPlayer]]
  
 
==== SourceForts ====
 
==== SourceForts ====
* [[SourceForts CHL2MP Player offset list (SourceMM)|CHL2MP_Player]]
+
* [[CHL2MP_Player Offset List (SourceForts)|CHL2MP_Player]]
  
 
==== Synergy ====
 
==== Synergy ====
* [[Synergy Player offset list]]
+
* [[CHL2MP_Player Offset List (Synergy)|CHL2MP_Player]]
 +
 
 +
==== Synergy SteamWorks (Synergy Orange Box Edition)====
 +
* [[CHL2MP_Player Offset List (SynergyOB)|CHL2MP_Player]]
  
 
==== Team Fortress 2 ====
 
==== Team Fortress 2 ====
* [[Team Fortress 2 CTFPlayer offset list (SourceMM)|CTFPlayer]]
+
* [[CTFPlayer Offset List (Team Fortress 2)|CTFPlayer]]
  
 
==== Zombie Master ====
 
==== Zombie Master ====
* [[Zombie Master Player offset list]]
+
* [[CHL2MP_Player Offset List (Zombie Master)|CHL2MP_Player]]
  
 
==== Zombie Panic: Source ====
 
==== Zombie Panic: Source ====
* [[ZPS CHL2MP Player offset list (SourceMM)|CHL2MP_Player]]
+
* [[CHL2MP_Player Offset List (Zombie Panic: Source)|CHL2MP_Player]]
 +
 
 +
==== GoldenEye: Source ====
 +
* [[CGEPlayer Offset List (GoldenEye: Source)|CGEPlayer]]
  
 
== How to use the examples ==
 
== How to use the examples ==

Latest revision as of 17:00, 2 October 2016

Calling virtual functions

I got this method from Mani, who I believe got it from Pavol Marko. Thank you!

I hope to expand on an actual explanation when I have the time (and understand it better). Hopefully, someone can expand on this, but for now I'll just post the examples and a list of the CCSPlayer virtual function table offsets.

Offset Lists

Automated Offsets

You can get updated offsets from the following tool. It automatically updates the offsets when an update is pushed by Valve for the 6 games it supports, and you may input your own *.so file to obtain offsets for other games.

Counter-Strike: Source

Day of Defeat: Source

Dystopia

Empires v2.12

Fortress Forever

Half-Life 2: Capture the Flag

Half-Life 2: Deathmatch

Hidden: Source

Insurgency

Left 4 Dead

Left 4 Dead 2

Obsidian Conflict

Pirates, Vikings, and Knights II

The Ship

SourceForts

Synergy

Synergy SteamWorks (Synergy Orange Box Edition)

Team Fortress 2

Zombie Master

Zombie Panic: Source

GoldenEye: Source

How to use the examples

Basically, this lets you call any virtual function by knowing it's offset. A table is created for each class that lists the address of the function for each virtual function. This method takes advantage of that to call those addresses.

Look at the examples below and edit to match the function you want to call: Use the offset for the function you want to call in this line. (CCSPlayer_offset_list_(SourceMM))

void *func = vtable[m_Off_GiveNamedItem];

Change this line to match your return type and parameters:

union {CBaseEntity *(VfuncEmptyClass::*mfpnew)(const char *, int );

Call the original function with your parameters (change the return type to match the function you're calling):

return (CBaseEntity *) (reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)(ItemName, iSubType);

You'll need to add an empty class for the union. Something like this:

class VfuncEmptyClass {};

Examples

These examples are for CSS. Mani has created a set of macros to make this easier. If you ask nicely, maybe he'll give them to you or let you post them here.

datamap_t *VFuncs::GetDataDescMap(CBaseEntity *pThisPtr)
{
	void **this_ptr = *(void ***)&pThisPtr;
	void **vtable = *(void ***)pThisPtr;
	void *func = vtable[m_Off_GetDataDescMap]; 
 
	union {datamap_t *(VfuncEmptyClass::*mfpnew)();
#ifndef __linux__
        void *addr;	} u; 	u.addr = func;
#else /* GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 */
			struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;
#endif
 
	return (datamap_t *) (reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)();
 
}
 
void VFuncs::SetModel(CBaseEntity *pThisPtr, const char *ModelName)
{
	void **this_ptr = *(void ***)&pThisPtr;
	void **vtable = *(void ***)pThisPtr;
	void *func = vtable[m_Off_SetModel]; 
 
	union {void (VfuncEmptyClass::*mfpnew)(const char *);
	#ifndef __linux__
			void *addr;	} u; 	u.addr = func;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;
	#endif
 
	(void) (reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)(ModelName);
 
}
 
void VFuncs::Teleport(CBaseEntity *pThisPtr, const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity)
{
	void **this_ptr = *(void ***)&pThisPtr;
	void **vtable = *(void ***)pThisPtr;
	void *func = vtable[m_Off_Teleport]; 
 
	union {void (VfuncEmptyClass::*mfpnew)(const Vector *, const QAngle *, const Vector *);
	#ifndef __linux__
			void *addr;	} u; 	u.addr = func;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;
	#endif
 
	(void) (reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)(newPosition, newAngles, newVelocity);
 
}
 
Vector VFuncs::EyePosition( CBaseEntity *pThisPtr )
{
	void **this_ptr = *(void ***)&pThisPtr;
	void **vtable = *(void ***)pThisPtr;
	void *func = vtable[m_Off_EyePosition]; 
 
	union {Vector (VfuncEmptyClass::*mfpnew)( void );
	#ifndef __linux__
			void *addr;	} u; 	u.addr = func;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;
	#endif
 
	return (Vector) (reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)( );
 
}
 
QAngle &VFuncs::EyeAngles( CBaseEntity *pThisPtr )
{
	void **this_ptr = *(void ***)&pThisPtr;
	void **vtable = *(void ***)pThisPtr;
	void *func = vtable[m_Off_EyeAngles]; 
 
	union {QAngle& (VfuncEmptyClass::*mfpnew)( void );
	#ifndef __linux__
			void *addr;	} u; 	u.addr = func;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;
	#endif
 
	return (QAngle&) (reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)( );
 
}
 
 
void VFuncs::Ignite(CBaseEntity *pThisPtr, float flFlameLifetime, bool bNPCOnly, float flSize, bool bCalledByLevelDesigner)
{
	void **this_ptr = *(void ***)&pThisPtr;
	void **vtable = *(void ***)pThisPtr;
	void *func = vtable[m_Off_Ignite]; 
 
	union {void (VfuncEmptyClass::*mfpnew)(float , bool , float , bool );
	#ifndef __linux__
			void *addr;	} u; 	u.addr = func;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;
	#endif
 
	(void) (reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)(flFlameLifetime, bNPCOnly, flSize, bCalledByLevelDesigner);
 
}
 
CBaseEntity *VFuncs::GiveNamedItem(CBaseEntity *pThisPtr, const char *ItemName, int iSubType)
{
	void **this_ptr = *(void ***)&pThisPtr;
	void **vtable = *(void ***)pThisPtr;
	void *func = vtable[m_Off_GiveNamedItem]; 
 
	union {CBaseEntity *(VfuncEmptyClass::*mfpnew)(const char *, int );
	#ifndef __linux__
			void *addr;	} u; 	u.addr = func;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;
	#endif
 
	return (CBaseEntity *) (reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)(ItemName, iSubType);
}
 
void VFuncs::CommitSuicide(CBaseEntity *pThisPtr)
{
	void **this_ptr = *(void ***)&pThisPtr;
	void **vtable = *(void ***)pThisPtr;
	void *func = vtable[m_Off_CommitSuicide]; 
 
	union {CBaseEntity *(VfuncEmptyClass::*mfpnew)( void );
	#ifndef __linux__
			void *addr;	} u; 	u.addr = func;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;
	#endif
 
	(reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)();
}