Difference between revisions of "Virtual Offsets (Source Mods)"
m (→Hidden: Source: err) |
m (→Offset Lists: Updated offset links to new page titles) |
||
Line 7: | Line 7: | ||
== Offset Lists == | == Offset Lists == | ||
==== Counter-Strike: Source ==== | ==== Counter-Strike: Source ==== | ||
− | * [[CCSPlayer | + | * [[CCSPlayer Offset List (Counter-Strike: Source)|CCSPlayer]] |
− | * [[CBaseCombatWeapon | + | * [[CBaseCombatWeapon Offset List (Counter-Strike: Source)|CBaseCombatWeapon]] |
==== Day of Defeat: Source ==== | ==== Day of Defeat: Source ==== | ||
− | * [[CDODPlayer | + | * [[CDODPlayer Offset List (Day of Defeat: Source)|CDODPlayer]] |
==== Dystopia ==== | ==== Dystopia ==== | ||
− | * [[ | + | * [[CDYSPlayer Offset List (Dystopia)|CDYSPlayer]] |
==== Empires ==== | ==== Empires ==== | ||
− | * [[ | + | * [[CSDKPlayer Offset List (Empires)|CSDKPlayer]] |
==== Fortress Forever ==== | ==== Fortress Forever ==== | ||
− | * [[ | + | * [[CFFPlayer Offset List (Fortress Forever)|CFFPlayer]] |
==== Half-Life 2: Capture the Flag ==== | ==== Half-Life 2: Capture the Flag ==== | ||
− | * [[ | + | * [[CHL2_Player Offset List (Half-Life 2: Capture the Flag)|CHL2_Player]] |
==== Half-Life 2: Deathmatch ==== | ==== Half-Life 2: Deathmatch ==== | ||
− | * [[CHL2MP_Player | + | * [[CHL2MP_Player Offset List (Half-Life 2: Deathmatch)|CHL2MP_Player]] |
==== Hidden: Source ==== | ==== Hidden: Source ==== | ||
− | * [[CSDKPlayer | + | * [[CSDKPlayer Offset List (Hidden: Source)|CSDKPlayer]] |
==== Insurgency ==== | ==== Insurgency ==== | ||
− | * [[ | + | * [[CINSPlayer Offset List (Insurgency)|CINSPlayer]] |
==== Pirates, Vikings, and Knights II ==== | ==== Pirates, Vikings, and Knights II ==== | ||
− | * [[ | + | * [[CPVK2Player Offset List (Pirates, Vikings, and Knights II)|CPVK2Player]] |
==== The Ship ==== | ==== The Ship ==== | ||
− | * [[The Ship | + | * [[CShipPlayer Offset List (The Ship)|CShipPlayer]] |
==== SourceForts ==== | ==== SourceForts ==== | ||
− | * [[SourceForts | + | * [[CHL2MP_Player Offset List (SourceForts)|CHL2MP_Player]] |
==== Synergy ==== | ==== Synergy ==== | ||
− | * [[Synergy | + | * [[CHL2MP_Player Offset List (Synergy)|CHL2MP_Player]] |
==== Team Fortress 2 ==== | ==== Team Fortress 2 ==== | ||
− | * [[Team Fortress 2 | + | * [[CTFPlayer Offset List (Team Fortress 2)|CTFPlayer]] |
==== Zombie Master ==== | ==== Zombie Master ==== | ||
− | * [[Zombie Master | + | * [[CHL2MP_Player Offset List (Zombie Master)|CHL2MP_Player]] |
==== Zombie Panic: Source ==== | ==== Zombie Panic: Source ==== | ||
− | * [[ | + | * [[CHL2MP_Player Offset List (Zombie Panic: Source)|CHL2MP_Player]] |
== How to use the examples == | == How to use the examples == |
Revision as of 08:54, 23 April 2008
Contents
- 1 Calling virtual functions
- 2 Offset Lists
- 2.1 Counter-Strike: Source
- 2.2 Day of Defeat: Source
- 2.3 Dystopia
- 2.4 Empires
- 2.5 Fortress Forever
- 2.6 Half-Life 2: Capture the Flag
- 2.7 Half-Life 2: Deathmatch
- 2.8 Hidden: Source
- 2.9 Insurgency
- 2.10 Pirates, Vikings, and Knights II
- 2.11 The Ship
- 2.12 SourceForts
- 2.13 Synergy
- 2.14 Team Fortress 2
- 2.15 Zombie Master
- 2.16 Zombie Panic: Source
- 3 How to use the examples
- 4 Examples
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
Counter-Strike: Source
Day of Defeat: Source
Dystopia
Empires
Fortress Forever
Half-Life 2: Capture the Flag
Half-Life 2: Deathmatch
Hidden: Source
Insurgency
Pirates, Vikings, and Knights II
The Ship
SourceForts
Synergy
Team Fortress 2
Zombie Master
Zombie Panic: 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)(); }