Raised This Month: $13 Target: $400
 3% 

Solved Call a function by the pointer from FunctionTable


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
kadet.89
Veteran Member
Join Date: Nov 2012
Old 03-27-2020 , 10:47   Call a function by the pointer from FunctionTable
Reply With Quote #1

I have these functions from datamaps:

DEFINE_THINKFUNC( Detonate )

Code:
CBaseCSGrenadeProjectile - hegrenade_projectile
- InitializeSpawnFromWorld (Offset 0) (Input)(0 Bytes) - InitializeSpawnFromWorld
- CBaseCSGrenadeProjectileDangerSoundThink (Offset 0) (FunctionTable)(0 Bytes)
- m_hThrower (Offset 1292) (Save)(4 Bytes)
- m_bIsLive (Offset 1265) (Save)(1 Bytes)
- m_DmgRadius (Offset 1268) (Save)(4 Bytes)
- CBaseGrenadeSmoke (Offset 0) (FunctionTable)(0 Bytes)
- CBaseGrenadeExplodeTouch (Offset 0) (FunctionTable)(0 Bytes)
- CBaseGrenadeDetonateUse (Offset 0) (FunctionTable)(0 Bytes)
- CBaseGrenadePreDetonate (Offset 0) (FunctionTable)(0 Bytes)
- CBaseGrenadeDetonate (Offset 0) (FunctionTable)(0 Bytes)
I get a void* from CBaseGrenadeDetonate (and it's not nullptr), is there a way to call the function using the pointer?
PHP Code:
DEFINE_THINKFUNCDetonate ),
virtual void Detonatevoid ); 
I tried to do it like this, but it crashes the server:
PHP Code:
typedef void (*Detonate_pointer)();

voidpointer = ...

((
Detonate_pointer)pointer ())(); 
PHP Code:
voidpointer = ...
CBaseEntityptr = ...
reinterpret_castvoid(*)(CBaseEntity*) > (pointer ) (ptr ); 

UPD:
I got inputfunc_t field value from typedescription_t of the "CBaseGrenadeDetonate", I gues that should be the correct funcion pointer, but have no idea ho I can call it

Last edited by kadet.89; 03-27-2020 at 18:39.
kadet.89 is offline
Send a message via Skype™ to kadet.89
kadet.89
Veteran Member
Join Date: Nov 2012
Old 03-27-2020 , 18:37   Re: Call a function by the pointer from FunctionTable
Reply With Quote #2

Here is my solution:

PHP Code:
#define EXTRACT_VOID_FUNCTIONPTR(x)        (*(void **)(&(x)))

void *UTIL_FunctionFromNamedatamap_t *pMap, const char *pName )
{
    while ( 
pMap )
    {
        for ( 
int i 0pMap->dataNumFieldsi++ )
        {
            
Assertsizeof(pMap->dataDesc[i].inputFunc) == sizeof(void *) );

            if ( 
pMap->dataDesc[i].flags FTYPEDESC_FUNCTIONTABLE )
            {
                if ( 
FStrEqpNamepMap->dataDesc[i].fieldName ) )
                {
                    return 
EXTRACT_VOID_FUNCTIONPTR(pMap->dataDesc[i].inputFunc);
                }
            }
        }
        
pMap pMap->baseMap;
    }

    
Msg"Failed to find function %s\n"pName );

    return 
NULL;
}

typedef void (CBaseEntity::*VALVE_BASEPTR)(void);
typedef void (CBaseEntity::*VALVE_ENTITYFUNCPTR)(CBaseEntity *pOther);

VALVE_BASEPTR CBaseGrenade::func_Detonate nullptr;
VALVE_ENTITYFUNCPTR CBaseGrenade::func_ExplodeTouch nullptr;

void CBaseGrenade::detonate()
{
    if(
func_Detonate != nullptr)
        return;

    
void *ptr UTIL_FunctionFromNameGetDataDescMap_Real(), "CBaseGrenadeDetonate");
    if(!
ptr)
        return;

    
memcpy(&func_Detonate, &ptrsizeof(void *));
    (
getBaseEntity()->*func_Detonate)(); //getBaseEntity() returns CBaseEntity*

For GetDataDescMap_Real use standard offset from core.games "GetDataDescMap"
It seams to be the only way to detonate grenades without delays and dealing with signatures.

Last edited by kadet.89; 03-27-2020 at 18:40.
kadet.89 is offline
Send a message via Skype™ to kadet.89
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 08:50.


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