View Single Post
TheAvenger
Junior Member
Join Date: May 2012
Old 05-03-2012 , 11:33   Re: The art of signature scanning
Reply With Quote #5

Quote:
Originally Posted by joaquimandrade View Post
Yes its mostly of interest when using windows.

InstallGameRules creates the global CHalfLifeMultiplay object. With it you can:
call and hook its virtual functions with simple direct code just with their offsets in the virtual table
call and hook its non virtual functions with signature scanning and more complicated hooking.
Change its data. For example with this i'm modifing the object field named m_iUnBalancedRounds to make round balancing happen every round.

About the last question you should provide the pointer pvPrivateData since that is a CBasePlayer* in the case of a player and is you are expected to pass it when you call a class member function.

One thing you must be aware is that to call class member functions (classes that are non static and belong to a class) the convention call you must use is thiscall that is much different from windows to linux and therefore will force you to create different code to handle it with some ifdefs.
Interesting! Thanks for all the details about InstallGameRules. Right now I'm trying to document
the CGameRules class by using 'fake' structure pointers which works perfect!

Right now it looks something like this:
PHP Code:
struct CGameRules
{
    
byte fill1[40];
    
long m_fTeamCount;            // Offset: 40
    
byte fill2[4];
    
long m_fRoundCount;            // Offset: 48
    
byte fill3[4];
    
int m_iRoundTimeSecs;            // Offset: 56
    
byte fill4[8];
    
int m_iAccountTerrorist;        // Offset: 68
    
int m_iAccountCT;            // Offset: 72
    
byte fill5[8];
    
int m_iNumSpawnableTerrorist;    // Offset: 84
    
int m_iNumSpawnableCT;        // Offset: 88
    
byte fill6[8];
    
int m_iHostagesRescued;        // Offset: 100
    
byte fill7[4];
    
int m_iRoundWinStatus;        // Offset: 108
    
short m_iNumCTWins;            // Offset: 112
    
short m_iNumTerroristWins;        // Offset: 114
    
bool m_bTargetBombed;        // Offset: 116
    
bool m_bBombDefused;        // Offset: 117
    
bool m_bMapHasBombTarget;    // Offset: 118
    
bool m_bMapHasBombZone;        // Offset: 119
    
byte fill8[1];
    
bool m_bMapHasRescueZone;    // Offset: 121
    
bool m_bMapHasEscapeZone;        // Offset: 122
    
byte fill9[1];
    
byte m_iMapHasVIPSafetyZone;    // Offset: 124
    
byte fill10[36];
    
bool m_bRoundTerminating;        // Offset: 161
    
byte fill11[2];
    
float m_flRequiredEscapeRatio;    // Offset: 164
}; 
There is one question I'd like to ask you though, how do you find these offsets, and especially the name
of the offets (and what they do)? I take it for granted that you haven't come up with these names by yourself?

Currently I'm designing this structure from the file 'CGameOffsets' supplied in Arkshine's plugin "Round Terminator".
This is because I have no idea myself, how to find these offets and _especially_ what they do (the name often describes that).

About the _thiscall convention, it's a breeze for me. Since I'm only programming for linux, it's the GCC calling convention,
which means no push to the ecx registry or anything, just use it as a first argument! Awesome

Perhaps I should tell Arkshine this myself, but you also seem to have a lot of knowledge on the subject. In his CGameOffset
file (supplied in the zip file here), a LOT of different offsets are specified, although I believe one of the offsets is incorrect (or around ~4 of them).

According to the file, the variable (remember I'm talking linux offets here) m_flRequiredEscapeRatio is at offset 164 (and it's
a long, or well a float, but it's still 4 bytes). This means that it takes up space for offsets 164-168 (4 bytes), but the adjacent offset
specified, m_iNumEscapers, is at offset 166, which makes no sense, unless there is some low/upper bit computations behind
the scene (which still makes no sense since its a float), it should be invalid. Which also (might) mean that all the offsets 'below'
this one, is also invalid (i.e m_iHaveEscaped and m_pVIP).

However I would appreciate it a lot if you could briefly explain how to find these member offsets (and their types, and names).

EDIT: After further analyzing, it's pretty obvious m_iNumEscapers is at offset 168, not 166...

EDIT 2: Another question I have is about CBasePlayer*. Let's take CGameRules as an example. It contains the member m_pVIP, which
is a CBasePlayer pointer. If I want to, for example, find out the players name or fetch his entity (edict_t) how would I proceed?

Normally one would just do STRING(m_pVIP->v.netname), but I have no insight/knowledge on how the CBasePlayer structure is?
One way would be too loop all players entites, and check if their pvPrivateData matches the CBasePlayer address, but that isn't efficient...

If I look here at the partial source code (player.cpp) it seems as if pev is a member structure (which obviously is an
edict_t pointer). If that is true, I only need to find the offset of this structure (in CBasePlayer*), but how does one do that?

Last edited by TheAvenger; 05-03-2012 at 11:59.
TheAvenger is offline