View Single Post
jim_yang
Veteran Member
Join Date: Aug 2006
Old 08-02-2009 , 22:59   Re: some questions ( CString, CVector, Ham )
Reply With Quote #4

Hamsandwish hooks the virtual functions(vfuncs) of a class, to explain clearly, I'll give an example.
Here is the Class Hierachy:
Code:
CBaseEntity
    CBaseDelay
        CBaseToggle
            CBaseItem
            CBaseMonster
                CBaseCycler
                CBasePlayer
                CBaseGroup
You can see that CBaseEntity is the base class of all other entity classes.
Here is part of vfuncs from CBasePlayer class
Code:
0    CBasePlayer::Spawn(void)
1    CBasePlayer::Precache(void)
2    CBaseEntity::Restart(void)
3    CBaseMonster::KeyValue(KeyValueData_s *)
4    CBasePlayer::Save(CSave &)
5    CBasePlayer::Restore(CRestore &)
6    CBasePlayer::ObjectCaps(void)
7    CBaseEntity::Activate(void)
8    CBaseEntity::SetObjectCollisionBox(void)
9    CBasePlayer::Classify(void)
10   CBaseEntity::DeathNotice(entvars_s *)
11   CBasePlayer::TraceAttack(entvars_s *,float,Vector,TraceResult *,int)
12   CBasePlayer::TakeDamage(entvars_s *,entvars_s *,float,int)
You can see that some functions from CBasePlayer override the original function from CBaseEntity
Code:
RegisterHam(Ham_TakeDamage, "player", "my_hook_func", 0 or 1) //pre or post
To hook the function CBasePlayer::TakeDamage, ham first spawn an entity with given classname, because different classes have different TakeDamage function, so we should specify which class we want to hook.
Virtual table(vtbl) stores in each object of a class, it stores the virtual function's address(pointer). When an obj call its virtual function, it will look up the vtbl to find its real address in memory.
Code:
CBasePlayer *pPlayer;
pPlayer->Spawn();
Numver 0 - 12 above is the index of these vfuncs in vtbl. You can find these numbers in hamdata.ini from configs folder
Ham does the followings to hook CBasePlayer::TakeDamage function:
(1)spawn a "player" entity
(2)get its vtbl address
(3)get its vtbl index from hamdata(actually this have been done when ham init)
(4)get the vfunc address
(5)generate a trampoline function
(6)changed the original vfunc address in vtbl to the trampoline function address(hooking started)
about the trampoline function, it looks like this:
Code:
Tramp()
{
    //prehook
    return_value = my_hook_func(original parameters)
    if(return_value == HAM_SUPERSEDE)
        return
    
    //call the original function
    this->TakeDamage(modified parameters from our prehook function)
    
    //posthook
    my_hook_func()
}
I'm not good at explaining things because of my poor English, so I didn't explain the c++ part, such as class, hierachy, virtual function..., you can find these in any c++ book.
===================
if you want to use ARRAYSIZE, use the hlsdk version
__________________
Project : CSDM all in one - 99%
<team balancer#no round end#entity remover#quake sounds#fake full#maps management menu#players punishment menu#no team flash#colored flashbang#grenade trails#HE effect#spawn protection#weapon arena#weapon upgrade#auto join#no weapon drop#one name>
jim_yang is offline