PDA

View Full Version : [Orange Box] A few questions regarding Ollydbg and the OB Engine



The Acid
05-21-2010, 01:03 PM
Im currently playing with the OB engine (as some of you might have noticed in the Delphi section) and I am stuck at a few things.

1. How would I obtain the offset for GetBaseCombatWeapon and PunchAngle using Ollydbg, where do I look?

2. How do I convert a Vector to QAngle so I can use SetViewAngles to aim at it? (I want to aim at a hitbox, and I currently only have the vector).

3. The pBaseEntity->EyePosition() seems to be broken, currently I am using the position of the head hitbox instead, does it really matter?

4. People seem to stay at 1 hp a second after they are dead and the IsAlive flag isen't updated - so I draw ESP on dead people for a second or so, how can I check if they are really dead?

Thanks :)

v3n0m4
05-21-2010, 01:55 PM
1. search for m_hActiveWeapon
2. look at some public src the the solution is inside (calculate angles thing)
3. m_vecOrigin + m_vecViewOffset // nah dont matter just slower
4. search for m_lifeState

Casual_Hacker
05-21-2010, 01:55 PM
1) Networked vars.

2) AngleVectors or VectorAngles, alternatively just do the math yourself.

3) Networked vars. No, shots aren't fired from your headhitbox, but from a fixed offset from your absorigin.

4) IsAlive() or read it from the CTFPlayerResource entity.


Preposted :(

rolandsh
05-21-2010, 02:20 PM
v3n0m4 , when i search for m_hActiveWeapon in CSS, it says nothing found ??

The Acid
05-21-2010, 02:25 PM
1. search for m_hActiveWeapon
Thanks.


2) AngleVectors or VectorAngles, alternatively just do the math yourself.
Ahh, I see.


3) Networked vars. No, shots aren't fired from your headhitbox, but from a fixed offset from your absorigin.
From which var would I obtain the fixed offset? and how would I apply it?


4) IsAlive() or read it from the CTFPlayerResource entity.
The IsAlive() function returns alive a second after the player is dead (while dying), so it draws esp for just a second too long. (In the CSS beta)

D3D8
05-21-2010, 02:30 PM
The IsAlive() function returns alive a second after the player is dead (while dying), so it draws esp for just a second too long. (In the CSS beta)

as posted above search for m_lifeState don't use IsAlive

syntroniks
05-21-2010, 03:54 PM
Is it life state now because deadflag doesn't work? I relied on deadflag a lot. That was definitely a favorite.

Remember the hActiveWeapon is an EHANDLE, not a pointer. There is a method that llows you to convert it to one though.

I use Xeno123/C_H's networked var dumper for all offsets.

The Acid
05-21-2010, 04:15 PM
Well, I found the following offset for ActiveWeapon = 0xCD0 and this for LifeState = 0x8B, don't know if I am using it wrong, but none of the following things work:

int *LifeState = (int*) ((DWORD)pBaseEntity + (DWORD)0x8B);

if (*LifeState == LIFE_ALIVE)
Something;

or


C_BaseCombatWeapon* GetBaseCombatActiveWeapon(C_BaseEntity* pBaseEnt)
{
C_BaseCombatWeapon* Result = NULL;
__asm
{
MOV EAX, pBaseEnt;
MOV EDI, EAX;
MOV EAX, DWORD PTR DS :[EDI];
MOV ECX, EDI;
CALL DWORD PTR DS :[EAX+0xCD0]
mov Result, EAX;
}
return Result;
}

Not sure on how to use the offsets, if not as above :rolleyes:

syntroniks
05-21-2010, 08:03 PM
int weaponIndex = reinterpret_cast<GenDT_TFPlayer*>(pBasePlayer)->hActiveWeapon()->GetEntryIndex();
C_BaseCombatWeapon* pBaseEntity = (C_BaseCombatWeapon*)g_pInterfaces->m_pClientEntList->GetClientEntity(weaponIndex);
C++ of course, but you see that the handle has a method called GetEntryIndex.

In Delphi you may have to rewrite that function (It uses the entitylist IIRC). That spits out the weapon's ent index. Use that to get a pointer to the weapon.

Casual_Hacker
05-22-2010, 06:10 AM
for m_lifeState, try char instead of int.
And yes, the game uses EHANDLEs for references to other entities.

You could just use the sdk, but meh, this works fine for me and I don't have to convert it manually:
EHANDLE is otherwise defined in \game\shared\predictioncopy.h

// I like this EHANDLE better
class IClientEntityList;
class IClientEntity;
namespace vars { extern IClientEntityList* pEntityList; }; // My pointer to IClientEntityList, gets initialized on startup.
template< class T > class Handle
{
public:
inline unsigned int entryindex() { return m_index&ENT_ENTRY_MASK; }
inline T* get() { return vars::pEntityList->GetClientEntity( entryindex() ); }
inline T* operator-> () { return get(); }
inline operator T* () { return get(); }
private:
unsigned int m_index;
};
typedef Handle<IClientEntity> EHANDLE;

The Acid
05-22-2010, 06:50 AM
int weaponIndex = reinterpret_cast<GenDT_TFPlayer*>(pBasePlayer)->hActiveWeapon()->GetEntryIndex();
C_BaseCombatWeapon* pBaseEntity = (C_BaseCombatWeapon*)g_pInterfaces->m_pClientEntList->GetClientEntity(weaponIndex);
C++ of course, but you see that the handle has a method called GetEntryIndex.

Thanks, that method works, but I still can't get lifestate to work, tried char and everything.
Also, where should I look for the PunchAngle? :D

Casual_Hacker
05-22-2010, 06:57 AM
I suppose you could check their solid state.


inline bool IsSolid( SolidType_t solidType, int nSolidFlags )
{
return (solidType != SOLID_NONE) && ((nSolidFlags & FSOLID_NOT_SOLID) == 0);
}
in \public\const.h

m_nSolidType and m_usSolidFlags are networked vars.

m_vecPunchAngle is also a networked var.

I suggest you make a networked var dumper, because some of the offsets aren't absolute, but relative from their container struct. Hard work, but it will pay off, trust me :p

The Acid
05-22-2010, 07:31 AM
I suppose you could check their solid state.


inline bool IsSolid( SolidType_t solidType, int nSolidFlags )
{
return (solidType != SOLID_NONE) && ((nSolidFlags & FSOLID_NOT_SOLID) == 0);
}
in \public\const.h

m_nSolidType and m_usSolidFlags are networked vars.

m_vecPunchAngle is also a networked var.

I suggest you make a networked var dumper, because some of the offsets aren't absolute, but relative from their container struct. Hard work, but it will pay off, trust me :p
I will try the solid check.

m_vecPunchAngle is a vector, and I need the PunchAngle in QAngle.
I tried using VectorAngles, but for some reason it messes up - not sure if I am supposed to use it like this:

QAngle PunchAngle()
{
/* Using netvar dump header (CSS OB) - Thanks to Xeno123 and Casual_Hacker */
Vector *vecPunchAngle = reinterpret_cast<GenDT_CSPlayer*>(MyBaseEnt())->localdata()->Local()->vecPunchAngle();

QAngle PunchAngle;
VectorAngles(*vecPunchAngle, PunchAngle);

return PunchAngle;
}

Thanks :)

Casual_Hacker
05-22-2010, 07:55 AM
QAngle PunchAngle( vecPunchAngle->x, vecPunchAngle->y, vecPunchAngle->z );
Don't ask me why Valve did it like this :/

The Acid
05-22-2010, 09:08 AM
Thanks, works great :D

Last question:
I am using the following function to obtain the position of a hitbox, this works great for ESP and such, but how do I convert the Vector to QAngle (Should I do like above?) so I can use SetViewAngles to aim at it.

// From Zeus TF2 Base by Xeno123
bool GetHitboxPosition(int hitbox, Vector& origin, int index, QAngle& angles)
{
if(hitbox < 0 || hitbox >= 20)
return false;

matrix3x4_t pmatrix[MAXSTUDIOBONES];

IClientEntity* ClientEntity = g_pClientEntList->GetClientEntity(index);
if (!ClientEntity)
return false;

if (ClientEntity->IsDormant())
return false;

const model_t* model = ClientEntity->GetModel();
if(!model)
return false;

studiohdr_t *pStudioHdr = g_pModelInfo->GetStudiomodel(model);
if (!pStudioHdr)
return false;

if(!ClientEntity->SetupBones(pmatrix, 128, BONE_USED_BY_HITBOX, g_pGlobals->curtime))
return false;

mstudiohitboxset_t *set = pStudioHdr->pHitboxSet(0);
if (!set)
return false;

mstudiobbox_t* pBox = NULL;
pBox = pStudioHdr->pHitbox(hitbox, NULL);
Vector min, max;
MatrixAngles(pmatrix[pBox->bone], angles, origin);

VectorTransform(pBox->bbmin, pmatrix[pBox->bone], min);
VectorTransform(pBox->bbmax, pmatrix[pBox->bone], max);
origin = (min + max) * 0.5f;

return true;
}

Thanks for all your help :)

syntroniks
05-22-2010, 09:17 AM
Setviewangles takes absolute viewangles. The math behind it is rectangular to spherical coordinates.

Explanation (http://mathforum.org/dr.math/faq/formulas/faq.spherical.html)
Use the second set of equations that give you pitch and yaw. Rho is used for phi.

The X Y and Z is the vector distance between your eyes (or wherever you shoot from) and your target (IIRC)

C_H, thanks for the cool idea on building a template handle class.

The Acid
05-22-2010, 12:44 PM
Alright, got most if it working (thanks people!), except the IsAlive check.
I even tried checking IsSolid with the flags, but that didn't change things - the problem still remains: The player "is alive" for like half a second after theý die and LifeState never returns LIFE_ALIVE on anything.

Tried the following:

// Returns alive for a while too long (like half a second) also tried with IsSolid + IsAlive.
pBaseEntity->IsAlive()

// This works exactly like pBaseEntity->IsAlive(), it returns alive for a while too long.
if (!*reinterpret_cast<GenDT_CSPlayer*>(pBaseEntity)->pl()->deadflag())
return true;

// This doesn't work, never returns LIFE_ALIVE.
int *LifeState = reinterpret_cast<GenDT_BasePlayer*>(pBaseEnt)->lifeState();
return (*LifeState == LIFE_ALIVE);

I could always check if the entity has 1 hp but that would be a crappy solution as it would stop drawing people with 1 hp.

D3D8
05-22-2010, 01:17 PM
it is a char not an int, you did find the correct offset however.



bool cPlayer::isAlive(CBaseEntity *pBaseEntity)
{
char lifeState = *(char*)((DWORD)pBaseEntity + (DWORD)0x08B);
return(lifeState == 0);
}

The Acid
05-22-2010, 03:15 PM
Thanks, all working great now :)

Casual_Hacker
05-22-2010, 03:29 PM
C_H, thanks for the cool idea on building a template handle class.

Uhm, the SDK is templated as well, but it uses a C_BaseEntity instead, I didn't invent anyting :p
I just made it use my own IClientEntityList pointer so I don't have to go manually get the entity pointer all the time.

The Acid
05-22-2010, 04:26 PM
Another quick question: What would be the best method of doing nospread in the OB engine? Is it still done with m_flAccuracy and m_bWeaponBit? Because I couldn't find those in the networked vars.

D3D8
05-22-2010, 09:51 PM
spread is still the same method as before, activeweapon + accuracy, new offsets are needed of course...... not too much information can be posted this is a good chance for shit pay2cheat sites to die off

The Acid
05-23-2010, 03:41 AM
I was just wondering on where to search for m_flAccuracy since it doesn't seem to be a networked var :)
Also, I was thinking about hooking FX_FireBullets to get the spread, but it isen't a vtable function (as far as I know), so I am not sure on how VAC would react on a detour of the function.

TheCore
05-23-2010, 04:57 AM
There is a nice function that returns the weaponspread. Look in the parameters of FX_Firebullets!

And people, why dont you just use IGameResources for ESP alive checks and all that shit? ;D

The Acid
05-23-2010, 05:02 AM
How should I hook FX_FireBullets? I am assuming that a simple jump detour in client.dll would cause VAC to spread mayhem and destruction? Since it ain't a virtual function I can't use a VMT hook :(

copymark
05-23-2010, 06:38 AM
DetourFunction is still not detected



template <typename _FunktionsPrototyp> void HookFunction(_FunktionsPrototyp &Pointer, DWORD dwOriginal, _FunktionsPrototyp Ziel, const char *pszName, bool bLog = true)
{
try
{
Pointer = (_FunktionsPrototyp)DetourFunction((PBYTE)dwOriginal,(PBYTE)Ziel);
if (bLog)
m_pConLog->Write(true,FOREGROUND_GREEN | FOREGROUND_INTENSITY,"[HOOKED (DETOURED)]:\n\t%s: [0x%x]",pszName,dwOriginal);
}
catch (...)
{ \
m_pConLog->Error("Failed to hook %s: [0x%x]",pszName,dwOriginal);
}
}



this address probably doesnt work on OrangeBox
just search it again (how far i can remember, it was easy)


DWORD dwFX_FireBulletsAddress = m_pMemTools->findPattern((DWORD)GetModuleHandle("client.dll"),0x2f1000,(PBYTE)"\x8B\x44\x24\x04\x8B\x0D\x00\x00\x00\x00\x81\xEC\x00\x00\x00\x00\x53\x 55\x56\x57\x50\xE8\x00\x00\x00\x00\x8B\xF0\x85\xF6\x74\x29\x8B\x16\x8B \xCE\xFF\x92\x00\x00\x00\x00\x84\xC0\x74\x1B\x6A\x00\x68\x00\x00\x00\x 00\x68\x00\x00\x00\x00\x6A\x00\x56\xE8\x00\x00\x00\x00","xxxxxx????xx????xxxxxx????xxxxxxxxxxxx????xxxxxxx????x????xxxx????");
HookFunction<void (__cdecl *)(int,const Vector&,const QAngle&,int,int,int,float)>(g_pHooks->m_pFX_FireBullets,dwFX_FireBulletsAddress,FX_FireBullets,"FX_FireBullets");

The Acid
05-23-2010, 07:14 AM
I just thought that when using DetourFunc you would change the CRC of client.dll and be banned :D
Should I use something like http://forum.gamedeception.net/threads/10649-DetourXS ?

Here is the updated sig for CSS Beta, probaly works in all OB games:

dwFindPattern((DWORD)hClient, 0x577000, (PBYTE)"\x8B\x44\x24\x04\x8B\x0D\x00\x00\x00\x00\x81\xEC\x00\x00\x00\x00\x53\x 55\x56\x57\x50","xxxxxx????xx????xxxxx");

EDIT:
Why is this crashing? :O

typedef void(*FX_FireBullets_def)(int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles, int iWeaponID, int iMode, int iSeed, float flSpread);
FX_FireBullets_def FX_FireBullets_o;

void hk_FX_FireBullets(int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles, int iWeaponID, int iMode, int iSeed, float flSpread)
{
add_log("flSpread: %f", flSpread); //Returns 0.008000 for USP

// The crash is here, it prints the spread correctly but when calling the original function it crashes.
FX_FireBullets_o(iPlayerIndex, vOrigin, vAngles, iWeaponID, iMode, iSeed, flSpread);
};

void Hook(void)
{
DWORD dwFX_FireBulletsAddress = dwFindPattern((DWORD)GetModuleHandle("client.dll") ,0x577000, (PBYTE)"SIGHERE","MASKHERE");

// Using DetourXS by Sinner
FX_FireBullets_o = *(FX_FireBullets_def)DetourCreate((PBYTE)(dwFX_FireBulletsAddress + 0x4), (PBYTE)hk_FX_FireBullets, DETOUR_TYPE_JMP, 6);
}

Im not sure how that can be VAC2 proof? A jump detour would change the crc of the client.dll, right?

kolbybrooks
05-23-2010, 09:14 AM
Detours aren't scanned for on FX_FireBullets

The Acid
05-23-2010, 09:22 AM
I thought they checked the crc of the .code section? Wouldn't placing a detour on FX_FireBullets change the crc?
Any suggestion on the crash above?

Thanks

syntroniks
05-23-2010, 10:44 AM
Acid, what you're saying makes sense to me, but I'd trust kolby. I just feel dirty using that kind of detour :-p

The Acid
05-23-2010, 10:47 AM
How would I hook the function using a clean method then (Not changing the CRC of the .code section) :D?
Also, it still crashes when calling the original function, can't seem to figure out why hehe.

The orig function returns an address in MSS32.DLL? Thats not how it is supposed to be, right? That is probaly why it crashes :D

copymark
05-23-2010, 01:34 PM
you have to use pushad and popad:



void __cdecl FX_FireBullets(int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles, int iWeaponID, int iMode, int iSeed, float flSpread)
{
__asm pushad;
g_pNoSpread->SetSpread(flSpread);
__asm popad;
g_pHooks->m_pFX_FireBullets(iPlayerIndex,vOrigin,vAngles,iWeaponID,iMode,iSeed,f lSpread);
}

also you should note that this function is a __cdecl call. __stdcall wont work

The Acid
05-23-2010, 02:30 PM
Thanks for your help copymark, I still crash however, maybe you can see whats wrong.

typedef void(*FX_FireBullets_def)(int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles, int iWeaponID, int iMode, int iSeed, float flSpread);
FX_FireBullets_def FX_FireBullets_o;

float flFX_FireBulletsSpread;

void __cdecl hk_FX_FireBullets(int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles, int iWeaponID, int iMode, int iSeed, float flSpread)
{
__asm pushad;

add_log("flSpread: %f", flSpread);
flFX_FireBulletsSpread = flSpread;

__asm popad;

// Call the original fire bullets - this crashes.
FX_FireBullets_o(iPlayerIndex, vOrigin, vAngles, iWeaponID, iMode, iSeed, flSpread);
};

void Hook(void)
{
DWORD dwFX_FireBulletsAddress = dwFindPattern((DWORD)GetModuleHandle("client.dll") ,0x577000, (PBYTE)"SIG","MASK");

// Using DetourXS by Sinner - http://forum.gamedeception.net/threads/10649-DetourXS
// Also, still not convinced that this is VAC2 proof :D
FX_FireBullets_o = (FX_FireBullets_def)DetourCreate((PBYTE)(dwFX_FireBulletsAddress + 0x4), (PBYTE)hk_FX_FireBullets, DETOUR_TYPE_CLC_JNC);

add_log("dwFX_FireBulletsAddress: [0x%.8X]", dwFX_FireBulletsAddress);
add_log("FX_FireBullets_o: [0x%.8X]", FX_FireBullets_o);
}

Returns the following with USP, it crashes when shooting.

[21:25:35] dwFX_FireBulletsAddress: [0x127DB7A0]
[21:25:35] FX_FireBullets_o: [0x232F91F8] <--- I think this is wrong, which module should FX_FireBullets reside in?
[21:25:51] flSpread: 0.080000

Thanks alot for your help.

copymark
05-23-2010, 03:15 PM
mmhh actually it should work^^

DetourCreate bY Sinner uses VirtualProtect, so its detected anyways ( i think^^ )
Maybe it just can not handle this function (it was always tricky to hook)

And why + 0x4, normally you can sigscan for a function directly^^

Maybe you have to call the original function with assember. (some functions like PaintTraverse need this)

i cant test it myself, because css-beta is still downloading^^

The Acid
05-23-2010, 03:39 PM
So what should I use for detours to not get banned :D?

Oh your right, it is a sig for the function directly, so it crashes because of the + 0x4, nicely spotted :D (Also, push and popad is not required for it to work)
Also, there is still spread on the first shot, then it goes nospread, (I am applying it in CreateMove), is this because FX_FireBullets is called after a shot :O?

D3D8
05-23-2010, 04:41 PM
hooking firebullets is not an accurate way of doing spread removal, that is the only problem.

The Acid
05-23-2010, 05:25 PM
Alright, its way better than without, so even if its not an accurate way, its a way :D
Anyways, is there a way to detour the function, so it doesn't modify the .code secton (Im pretty sure that it does)?

I am using this method for VMT hooking (Thanks P47R!CK) since I used it in the original Source engine and it still works great.
http://forum.gamedeception.net/threads/10200-vtable-class?p=76695#post76695

So the question is pretty much, which method of detouring should be used to avoid changing anything VAC2 might scan? :O

copymark
05-23-2010, 05:56 PM
// File: detours.h
// Module: detours.lib
//
// Detours for binary functions. Version 1.5 (Build 46)
//
// Copyright 1995-2001, Microsoft Corporation
//

then use DetourFunction
i am not banned since nov. 09

The Acid
05-23-2010, 06:17 PM
I just thought that MSDetours changed the .code section and that VAC would ban for it.
Well, I will just use the same method you use, you haven't been banned, so shouldn't be a problem.

This is my final code and it works:

typedef void (*FX_FireBullets_def)(int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles, int iWeaponID, int iMode, int iSeed, float flSpread);
FX_FireBullets_def FX_FireBullets_o;

float flFX_FireBulletsSpread;

void __cdecl hk_FX_FireBullets(int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles, int iWeaponID, int iMode, int iSeed, float flSpread)
{
flFX_FireBulletsSpread = flSpread;
FX_FireBullets_o(iPlayerIndex, vOrigin, vAngles, iWeaponID, iMode, iSeed, flSpread);
};

void Initialize(void)
{
DWORD dwFX_FireBulletsAddress = dwFindPattern((DWORD)GetModuleHandle("client.dll"), 0x577000, (PBYTE)"SIG", "MASK");
FX_FireBullets_o = (FX_FireBullets_def)DetourFunction((PBYTE)dwFX_FireBulletsAddress, (PBYTE)hk_FX_FireBullets);
}

Thanks.

learn_more
05-23-2010, 08:04 PM
just noticed your trampoline (FX_FireBullets_def) doesnt have a calling convention set,
this time it works because the original function is __cdecl and msvc defaults to that, but it might break,
for stuff like this u should always specify the calling convention ;)

v3n0m4
05-26-2010, 01:33 PM
Alright, got most if it working (thanks people!), except the IsAlive check.
I even tried checking IsSolid with the flags, but that didn't change things - the problem still remains: The player "is alive" for like half a second after theý die and LifeState never returns LIFE_ALIVE on anything.

Tried the following:

// Returns alive for a while too long (like half a second) also tried with IsSolid + IsAlive.
pBaseEntity->IsAlive()

// This works exactly like pBaseEntity->IsAlive(), it returns alive for a while too long.
if (!*reinterpret_cast<GenDT_CSPlayer*>(pBaseEntity)->pl()->deadflag())
return true;

// This doesn't work, never returns LIFE_ALIVE.
int *LifeState = reinterpret_cast<GenDT_BasePlayer*>(pBaseEnt)->lifeState();
return (*LifeState == LIFE_ALIVE);

I could always check if the entity has 1 hp but that would be a crappy solution as it would stop drawing people with 1 hp.

& LIFE_ALIVE not
== LIFE_ALIVE

example:



bool entity_info::is_alive(void)
{
if( (base_entity()) )
{
if ( hl2_offsets::m_lifeState )
{
if ( m_pExport->_memory->GetClass_int(base_entity(),hl2_offsets::m_lifeState) & LIFE_ALIVE )
{
return !(Gethealth() == 0);
}
if ( m_pExport->_memory->GetClass_int(base_entity(),hl2_offsets::m_lifeState) & LIFE_DEAD )
{
return false;
}
if ( m_pExport->_memory->GetClass_int(base_entity(),hl2_offsets::m_lifeState) & LIFE_DYING )
{
return false;
}
}
}
return (Gethealth() >= 1||Gethealth() == -1);
// (valve_games_interfaces::is_half_life_2_2007_engine()) ? (Gethealth() >= 2||Gethealth() == -1) : (Gethealth() >= 1||Gethealth() == -1);
}

v3n0m4
05-26-2010, 01:47 PM
Thanks for your help copymark, I still crash however, maybe you can see whats wrong.

typedef void(*FX_FireBullets_def)(int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles, int iWeaponID, int iMode, int iSeed, float flSpread);
FX_FireBullets_def FX_FireBullets_o;

float flFX_FireBulletsSpread;

void __cdecl hk_FX_FireBullets(int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles, int iWeaponID, int iMode, int iSeed, float flSpread)
{
__asm pushad;

add_log("flSpread: %f", flSpread);
flFX_FireBulletsSpread = flSpread;

__asm popad;

// Call the original fire bullets - this crashes.
FX_FireBullets_o(iPlayerIndex, vOrigin, vAngles, iWeaponID, iMode, iSeed, flSpread);
};

void Hook(void)
{
DWORD dwFX_FireBulletsAddress = dwFindPattern((DWORD)GetModuleHandle("client.dll") ,0x577000, (PBYTE)"SIG","MASK");

// Using DetourXS by Sinner - http://forum.gamedeception.net/threads/10649-DetourXS
// Also, still not convinced that this is VAC2 proof :D
FX_FireBullets_o = (FX_FireBullets_def)DetourCreate((PBYTE)(dwFX_FireBulletsAddress + 0x4), (PBYTE)hk_FX_FireBullets, DETOUR_TYPE_CLC_JNC);

add_log("dwFX_FireBulletsAddress: [0x%.8X]", dwFX_FireBulletsAddress);
add_log("FX_FireBullets_o: [0x%.8X]", FX_FireBullets_o);
}

Returns the following with USP, it crashes when shooting.

[21:25:35] dwFX_FireBulletsAddress: [0x127DB7A0]
[21:25:35] FX_FireBullets_o: [0x232F91F8] <--- I think this is wrong, which module should FX_FireBullets reside in?
[21:25:51] flSpread: 0.080000

Thanks alot for your help.

as for this,
since i release stuff publically on my side (secret place nah just kidding)
here you go for the missing "SIG","MASK" that seem to be a secret,
all you need is to credit j1gs4w if you use them since he is who searched.



games_mod that = m_pExport->nActualGameMod;

if ( !m_bInitialized )
{
if ( that == GAME_DOD_SOURCE )
{
dwFX_FireBulletsAddress = m_pExport->_memory->dwFindPattern2(
GetModuleHandle( "client.dll" ),
(BYTE*)"\x8B\x0D\x00\x00\x00\x00\x81\xEC\x00\x00\x00\x00\x55\x8B\xAC\x24\x00\x 00\x00\x00\x56\x57\x55",
"xx????xx????xxxx????xxx" );
}
if ( that == GAME_TEAM_FORTRESS_2 )
{
dwFX_FireBulletsAddress = m_pExport->_memory->dwFindPattern2(
GetModuleHandle( "client.dll" ),
(BYTE*)"\x81\xEC\x00\x00\x00\x00\x56\x57\x8B\xBC\x24\x00\x00\x00\x00\x57",
"xx????xxxxx????x" );
}
if ( that == GAME_COUNTER_STRIKE_SOURCE )
{
dwFX_FireBulletsAddress = m_pExport->_memory->dwFindPattern2(
GetModuleHandle( "client.dll" ),
(BYTE*)"\x8B\x44\x24\x04\x8B\x0D\x00\x00\x00\x00\x81\xEC\x00\x00\x00\x00\x53\x 55\x56\x57\x50",
"xxxxxx????xx????xxxxx" );
}
if ( that == GAME_COUNTER_STRIKE_SOURCE_BETA )
{
dwFX_FireBulletsAddress = m_pExport->_memory->dwFindPattern2(
GetModuleHandle( "client.dll" ),
(BYTE*)"\x8B\x44\x24\x04\x8B\x0D\x00\x00\x00\x00\x81\xEC\x00\x00\x00\x00\x53\x 55\x56\x57\x50 ",
"xxxxxx????xx????xxxxx" );
}
if ( that == GAME_HALF_LIFE_2_NEOTOKIO )
{
dwFX_FireBulletsAddress = m_pExport->_memory->dwFindPattern2(
GetModuleHandle( "client.dll" ),
(BYTE*)"\x8B\x0D\x00\x00\x00\x00\x81\xEC\x00\x00\x00\x00\x53\x55\x8B\xAC\x24\x 00\x00\x00\x00\x56\x57\x55",
"xx????xx????xxxxx????xxx" );
}
m_pExport->add_logA( "dwFX_FireBulletsAddress: [0x%X]", dwFX_FireBulletsAddress );

if ( dwFX_FireBulletsAddress )
{
// protect a bunch cuz ms detour,
// just be sure these zone cant be seen
if ( m_pExport->_memory->_protect((void*)dwFX_FireBulletsAddress,100) )
{
FX_FireBullets = (FX_FireBullets_org)DetourFunction(
(PBYTE)dwFX_FireBulletsAddress,
(PBYTE)new_FX_FireBullets);

m_pExport->_memory->_protect((void*)FX_FireBullets,100);
m_pExport->_memory->_protect((void*)new_FX_FireBullets,100);
m_pExport->add_logA( "FX_FireBullets: [0x%X]", FX_FireBullets );
}
}
m_bInitialized = true;
}



& then



DWORD dwFX_FireBulletsAddress = 0;

typedef void(__cdecl*FX_FireBullets_org)(int,const Vector &,const QAngle &,int,int,int,float);
static FX_FireBullets_org FX_FireBullets = 0;
static void __cdecl new_FX_FireBullets( int iPlayerIndex,
const Vector &vOrigin,
const QAngle &vAngles,
int iWeaponID,
int iMode,
int iSeed,
float flSpread )
{
(*FX_FireBullets)(iPlayerIndex,vOrigin,vAngles,iWeaponID,iMode,iSeed,f lSpread);

if ( m_pEntList
&& m_pNospread
&& valve_games_interfaces::m_pEngine )
{
if(!mi)mi = m_pEntList->get_local();

if( mi && mi->is_alive() && (iPlayerIndex == mi->entity_index) )
{
m_pNospread->seed = iSeed;
m_pNospread->spread = flSpread;

// m_pExport->add_logA("iWeaponID %i, iSeed %i, flSpread: %f",iWeaponID,iSeed,flSpread);

if ( m_pCvars->aim_norecoil->GetInt() == 2 )
{
valve_games_interfaces::m_pEngine->SetViewAngles((QAngle&const)vAngles);
}
}
}
};

no pushad popad needed and no crash :/

The Acid
05-26-2010, 03:53 PM
I posted the sig and the mask on page 2, I just used Ollydbg + Sigmaker 0.3 :)
Just wrote SIG and MASK so it wouldn't go on 2 lines :D

Here is the updated sig for CSS Beta, probaly works in all OB games:

dwFindPattern((DWORD)hClient, 0x577000, (PBYTE)"\x8B\x44\x24\x04\x8B\x0D\x00\x00\x00\x00\x81\xEC\x00\x00\x00\x00\x53\x 55\x56\x57\x50","xxxxxx????xx????xxxxx");

Also I ended up using a breakpoint, then hooking GetThreadContext via detour and return false information.

freax
06-30-2010, 07:40 PM
Hey.
Sorry to push such an "old" thread, just want to clarify some things:

1. FX_FireBullets is called AFTER the actual CreateMove update is called. It means, the value flSpread is outdated. It isn't accurate (it is useless actually), there are much better functions (look forums).

2. To check for a clean way if an entity index is a valid player or if he is alive, you should use IGameResources (stolen this from Xeno if I remember correctly, look in this forums too) - the signature works for the new CS:S and all other valve games I've tested aswell (TF2, DoD:S):
typedef IGameResources* (*GetGameResources_t)();
IGameResources*pGameResources = ((GetGameResources_t)pTools->ScanSignature((unsigned long)pInject->m_hClient, 0x2680C6, (unsigned char*)"\xA1\x00\x00\x00\x00\x85\xC0\x74\x06\x05", "x????xxxxx"))();
Some other nice functions are contained in this interface, like GetHealth, ... see yourself:
virtual const char *GetTeamName( int index ) = 0;
virtual int GetTeamScore( int index ) = 0;
virtual const Color& GetTeamColor( int index ) = 0;

// Player data access
virtual bool IsConnected( int index ) = 0;
virtual bool IsAlive( int index ) = 0;
virtual bool IsFakePlayer( int index ) = 0;
virtual bool IsLocalPlayer( int index ) = 0;

virtual const char *GetPlayerName( int index ) = 0;
virtual int GetPlayerScore( int index ) = 0;
virtual int GetPing( int index ) = 0;
// virtual int GetPacketloss( int index ) = 0;
virtual int GetDeaths( int index ) = 0;
virtual int GetFrags( int index ) = 0;
virtual int GetTeam( int index ) = 0;
virtual int GetHealth( int index ) = 0;

3. Here's an updated offsetdump (new CS:S):
m_iAddonBits: 0x1364
m_iPrimaryAddon: 0x1368
m_iSecondaryAddon: 0x136c
m_iThrowGrenadeCounter: 0x1360
m_iPlayerState: 0x1358
m_iAccount: 0x13d8
m_bInBombZone: 0x135d
m_bInBuyZone: 0x135e
m_iClass: 0x13e0
m_ArmorValue: 0x13e4
m_angEyeAngles[0]: 0x13e8
m_angEyeAngles[1]: 0x13ec
m_flStamina: 0x1378
m_bHasDefuser: 0x13f4
m_bNightVisionOn: 0x1384
m_bHasNightVision: 0x1385
m_bInHostageRescueZone: 0x13f5
m_ArmorValue: 0x13e4
m_bIsDefusing: 0x135c
m_bHasHelmet: 0x13dc
m_vecRagdollVelocity: 0x1400
m_flFlashDuration: 0x13a4
m_flFlashMaxAlpha: 0x13a0
m_iProgressBarDuration: 0x1370
m_flProgressBarStartTime: 0x1374
m_hRagdoll: 0x1390
m_cycleLatch: 0x14a8

4. For all those wondering why their "IsInGame" function always return false. IVEngineClient::IsLevelMainMenuBackground() returns true permanently for a reason I currently couldn't locate. Just remove it to get valid results again.

5. Nice Casual_Hacker, some neat ideas :)

Have Phun

freax
07-01-2010, 08:48 AM
Find some interesting usermessage stuff. UpdateRadar looks interesting because it updates ALL players over the map, regardless whether they are renderable or not (the server seems to send this message without any fear, and yes, it's update quite often!). The following properties are supported (at minimum), I think:

player index
player position (vecOrigin so far)
player viewangle
team index
health
Problem is, that I don't know if that are exactly all properties, and in which order they are sent. If we would know that, we could simply hook the UserMessage function, looking for if the current usermessage was UpdateRadar and decode it (read it through bf_read pointer). But I currently only get unusable data out of it (problems listet before).

A list of all availabale usermessages in CSS (OB) - this seems to be the place where they are added to an internal vector or map (found in client.dll):
131B97B0 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B97B6 6A 01 PUSH 1
131B97B8 68 64D83513 PUSH client.1335D864 ; ASCII "Geiger"
131B97BD E8 2E38F8FF CALL client.1313CFF0
131B97C2 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B97C8 6A 01 PUSH 1
131B97CA 68 7C3D3713 PUSH client.13373D7C ; ASCII "Train"
131B97CF E8 1C38F8FF CALL client.1313CFF0
131B97D4 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B97DA 6A FF PUSH -1
131B97DC 68 AC8F3613 PUSH client.13368FAC ; ASCII "HudText"
131B97E1 E8 0A38F8FF CALL client.1313CFF0
131B97E6 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B97EC 6A FF PUSH -1
131B97EE 68 70663913 PUSH client.13396670 ; ASCII "SayText"
131B97F3 E8 F837F8FF CALL client.1313CFF0
131B97F8 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B97FE 6A FF PUSH -1
131B9800 68 64663913 PUSH client.13396664 ; ASCII "SayText2"
131B9805 E8 E637F8FF CALL client.1313CFF0
131B980A 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9810 6A FF PUSH -1
131B9812 68 5C663913 PUSH client.1339665C ; ASCII "TextMsg"
131B9817 E8 D437F8FF CALL client.1313CFF0
131B981C 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9822 6A FF PUSH -1
131B9824 68 988F3613 PUSH client.13368F98 ; ASCII "HudMsg"
131B9829 E8 C237F8FF CALL client.1313CFF0
131B982E 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9834 6A 01 PUSH 1
131B9836 68 20E73513 PUSH client.1335E720 ; ASCII "ResetHUD"
131B983B E8 B037F8FF CALL client.1313CFF0
131B9840 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9846 6A 00 PUSH 0
131B9848 68 A08F3613 PUSH client.13368FA0 ; ASCII "GameTitle"
131B984D E8 9E37F8FF CALL client.1313CFF0
131B9852 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9858 6A FF PUSH -1
131B985A 68 E4E03513 PUSH client.1335E0E4 ; ASCII "ItemPickup"
131B985F E8 8C37F8FF CALL client.1313CFF0
131B9864 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B986A 6A FF PUSH -1
131B986C 68 CC8E3613 PUSH client.13368ECC ; ASCII "ShowMenu"
131B9871 E8 7A37F8FF CALL client.1313CFF0
131B9876 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B987C 6A 0D PUSH 0D
131B987E 68 1C793713 PUSH client.1337791C ; ASCII "Shake"
131B9883 E8 6837F8FF CALL client.1313CFF0
131B9888 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B988E 6A 0A PUSH 0A
131B9890 68 14793713 PUSH client.13377914 ; ASCII "Fade"
131B9895 E8 5637F8FF CALL client.1313CFF0
131B989A 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B98A0 6A FF PUSH -1
131B98A2 68 D4753513 PUSH client.133575D4 ; ASCII "VGUIMenu"
131B98A7 E8 4437F8FF CALL client.1313CFF0
131B98AC 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B98B2 6A 03 PUSH 3
131B98B4 68 CC753513 PUSH client.133575CC ; ASCII "Rumble"
131B98B9 E8 3237F8FF CALL client.1313CFF0
131B98BE 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B98C4 6A FF PUSH -1
131B98C6 68 642E3613 PUSH client.13362E64 ; ASCII "CloseCaption"
131B98CB E8 2037F8FF CALL client.1313CFF0
131B98D0 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B98D6 6A FF PUSH -1
131B98D8 68 14E73513 PUSH client.1335E714 ; ASCII "SendAudio"
131B98DD E8 0E37F8FF CALL client.1313CFF0
131B98E2 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B98E8 6A FF PUSH -1
131B98EA 68 50663913 PUSH client.13396650 ; ASCII "RawAudio"
131B98EF E8 FC36F8FF CALL client.1313CFF0
131B98F4 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B98FA 6A 19 PUSH 19
131B98FC 68 149F3713 PUSH client.13379F14 ; ASCII "VoiceMask"
131B9901 E8 EA36F8FF CALL client.1313CFF0
131B9906 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B990C 6A 00 PUSH 0
131B990E 68 049F3713 PUSH client.13379F04 ; ASCII "RequestState"
131B9913 E8 D836F8FF CALL client.1313CFF0
131B9918 6A FF PUSH -1
131B991A 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9920 68 48663913 PUSH client.13396648 ; ASCII "BarTime"
131B9925 E8 C636F8FF CALL client.1313CFF0
131B992A 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9930 6A FF PUSH -1
131B9932 68 40663913 PUSH client.13396640 ; ASCII "Damage"
131B9937 E8 B436F8FF CALL client.1313CFF0
131B993C 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9942 6A FF PUSH -1
131B9944 68 34663913 PUSH client.13396634 ; ASCII "RadioText"
131B9949 E8 A236F8FF CALL client.1313CFF0
131B994E 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9954 6A FF PUSH -1
131B9956 68 D0463613 PUSH client.133646D0 ; ASCII "HintText"
131B995B E8 9036F8FF CALL client.1313CFF0
131B9960 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9966 6A FF PUSH -1
131B9968 68 C4463613 PUSH client.133646C4 ; ASCII "KeyHintText"
131B996D E8 7E36F8FF CALL client.1313CFF0
131B9972 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9978 6A 02 PUSH 2
131B997A 68 8C023913 PUSH client.1339028C ; ASCII "ReloadEffect"
131B997F E8 6C36F8FF CALL client.1313CFF0
131B9984 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B998A 6A FF PUSH -1
131B998C 68 24663913 PUSH client.13396624 ; ASCII "PlayerAnimEvent"
131B9991 E8 5A36F8FF CALL client.1313CFF0
131B9996 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B999C 6A 02 PUSH 2
131B999E 68 D8E03513 PUSH client.1335E0D8 ; ASCII "AmmoDenied"
131B99A3 E8 4836F8FF CALL client.1313CFF0
131B99A8 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B99AE 6A FF PUSH -1
131B99B0 68 18663913 PUSH client.13396618 ; ASCII "UpdateRadar"
131B99B5 E8 3636F8FF CALL client.1313CFF0
131B99BA 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B99C0 6A FF PUSH -1
131B99C2 68 E4243913 PUSH client.133924E4 ; ASCII "KillCam"
131B99C7 E8 2436F8FF CALL client.1313CFF0
131B99CC 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B99D2 6A FF PUSH -1
131B99D4 68 08663913 PUSH client.13396608 ; ASCII "MarkAchievement"
131B99D9 E8 1236F8FF CALL client.1313CFF0
131B99DE E8 ADC5F0FF CALL client.130C5F90
131B99E3 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B99E9 6A FF PUSH -1
131B99EB 68 202D3913 PUSH client.13392D20 ; ASCII "PlayerStatsUpdate"
131B99F0 E8 FB35F8FF CALL client.1313CFF0
131B99F5 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B99FB 6A FF PUSH -1
131B99FD 68 B4F93213 PUSH client.1332F9B4 ; ASCII "AchievementEvent"
131B9A02 E8 E935F8FF CALL client.1313CFF0
131B9A07 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9A0D 6A FF PUSH -1
131B9A0F 68 48293913 PUSH client.13392948 ; ASCII "MatchEndConditions"
131B9A14 E8 D735F8FF CALL client.1313CFF0
131B9A19 8B0D BC5F4513 MOV ECX,DWORD PTR DS:[13455FBC] ; client.13455FC0
131B9A1F 6A FF PUSH -1
131B9A21 68 0C2D3913 PUSH client.13392D0C ; ASCII "MatchStatsUpdate"
131B9A26 E8 C535F8FF CALL client.1313CFF0

Blah & HF