lørdag den 16. juni 2012

CSGO: Chickens

 Shooting chickens is loads of fun in CSGO so I decided to code some stuff for it;
Chickens have 28 hitboxes:

enum EChickenHitboxes
{
 HITBOX_CHICKEN_PELVIS,
 HITBOX_CHICKEN_LEFTKNEE,
 HITBOX_CHICKEN_LEFTANKLE,
 HITBOX_CHICKEN_LEFTBACKTOE,
 HITBOX_CHICKEN_LEFTTOE,
 HITBOX_CHICKEN_RIGHTKNEE,
 HITBOX_CHICKEN_RIGHTANKLE,
 HITBOX_CHICKEN_RIGHTBACKTOE,
 HITBOX_CHICKEN_RIGHTTOE,
 HITBOX_CHICKEN_TAIL,
 HITBOX_CHICKEN_TAIL1,
 HITBOX_CHICKEN_TAIL2,
 HITBOX_CHICKEN_CLAVICAL, // gg misspell valve?
 HITBOX_CHICKEN_RIGHTBREAST,
 HITBOX_CHICKEN_RIGHTSHOULDER,
 HITBOX_CHICKEN_RIGHTELBOW,
 HITBOX_CHICKEN_RIGHTWRIST,
 HITBOX_CHICKEN_RIGHTTIP,
 HITBOX_CHICKEN_LEFTBREAST,
 HITBOX_CHICKEN_LEFTSHOULDER,
 HITBOX_CHICKEN_LEFTELBOW,
 HITBOX_CHICKEN_LEFTWRIST,
 HITBOX_CHICKEN_LEFTTIP,
 HITBOX_CHICKEN_NECK1,
 HITBOX_CHICKEN_NECK2,
 HITBOX_CHICKEN_NECK3,
 HITBOX_CHICKEN_HEAD,
 HITBOX_CHICKEN_WOBBLER
};

The chickens all have the clientclass CDynamicProp, and you can check wether it's a chicken or not by checking model name; Ex:
 bool CEntity::IsChicken( void )
{
 const model_t *model = GetModel();

 if ( !model )
 {
  LOG_ERROR( "model_t was 0" );
  return false;
 }


 studiohdr_t *studioHeader = g_InterfaceManager->ModelInfo()->GetVTable<IVModelInfo>()->GetStudiomodel( model );

 if ( !studioHeader )
 {
  LOG_ERROR( "studiohdr_t was 0" );
  return false;
 }


 return strstr( studioHeader->name, "chicken" );
}
  The pelvis hitbox is very big, almost like a bounding box tbh. and the height of the chickens hull is ~23;

A video of the result:

torsdag den 14. juni 2012

Networked Variables in the Source engine

I needed a way to hook networked props/get offsets simply in the source engine, so I implemented ghetto's/altimor's recursive solution in my netvars class.

 netvars.h:
#pragma once


#include "main.h"


class CNetworkedVariableManager
{
public:

    // stores all tables, and all props inside those
    CNetworkedVariableManager( void );


    // calls GetProp wrapper to get the absolute offset of the prop
    int GetOffset( const char *tableName, const char *propName );


    // calls GetProp wrapper to get prop and sets the proxy of the prop
    bool HookProp( const char *tableName, const char *propName, RecvVarProxyFn function );


private:

    // wrapper so we can use recursion without too much performance loss
    int GetProp( const char *tableName, const char *propName, RecvProp **prop = 0 );


    // uses recursion to return a the relative offset to the given prop and sets the prop param
    int GetProp( RecvTable *recvTable, const char *propName, RecvProp **prop = 0 );


    RecvTable *GetTable( const char *tableName );


    std::vector<RecvTable*>    m_tables;
};


extern CNetworkedVariableManager *g_NetworkedVariableManager; 


netvars.cpp:
#include "main.h"


CNetworkedVariableManager *g_NetworkedVariableManager = 0;


CNetworkedVariableManager::CNetworkedVariableManager( void )
{
    m_tables.clear();


    ClientClass *clientClass = g_InterfaceManager->Client()->GetOriginalMethod<GetAllClasses_t>( INDEX_GETALLCLASSES )( g_InterfaceManager->Client()->thisptr() );

    if ( !clientClass )
    {
        LOG_ERROR( "ClientClass was not found" );
        return;
    }


    while ( clientClass )
    {
        RecvTable *recvTable = clientClass->m_pRecvTable;


        m_tables.push_back( recvTable );


        clientClass = clientClass->m_pNext;
    }
}


// calls GetProp wrapper to get the absolute offset of the prop
int CNetworkedVariableManager::GetOffset( const char *tableName, const char *propName )
{
    int offset = GetProp( tableName, propName );

    if ( !offset )
    {
        LOG_ERROR( "Failed to find offset for prop: %s from table: %s", propName, tableName );
        return 0;
    }


    return offset;
}


// calls GetProp wrapper to get prop and sets the proxy of the prop
bool CNetworkedVariableManager::HookProp( const char *tableName, const char *propName, RecvVarProxyFn function )
{
    RecvProp *recvProp = 0;
    GetProp( tableName, propName, &recvProp );


    if ( !recvProp )
    {
        LOG_ERROR( "Failed to hook prop: %s from table: %s", propName, tableName );
        return false;
    }


    recvProp->m_ProxyFn = function;

    return true;
}


// wrapper so we can use recursion without too much performance loss
int CNetworkedVariableManager::GetProp( const char *tableName, const char *propName, RecvProp **prop )
{
    RecvTable *recvTable = GetTable( tableName );

    if ( !recvTable )
    {
        LOG_ERROR( "Failed to find table: %s", tableName );
        return 0;
    }


    int offset = GetProp( recvTable, propName, prop );

    if ( !offset )
    {
        LOG_ERROR( "Failed to find prop: %s from table: %s", propName, tableName );
        return 0;
    }


    return offset;
}


// uses recursion to return a the relative offset to the given prop and sets the prop param
int CNetworkedVariableManager::GetProp( RecvTable *recvTable, const char *propName, RecvProp **prop )
{
    int extraOffset = 0;

    for ( int i = 0; i < recvTable->m_nProps; ++i )
    {
        RecvProp *recvProp = &recvTable->m_pProps[i];


        RecvTable *child = recvProp->m_pDataTable;

        if ( child
            && ( child->m_nProps > 0 ) )
        {
            int tmp = GetProp( child, propName, prop );

            if ( tmp )
            {
                extraOffset += ( recvProp->m_Offset + tmp );
            }
        }


        if ( stricmp( recvProp->m_pVarName, propName ) )
        {
            continue;
        }


        if ( prop )
        {
            *prop = recvProp;
        }

        return ( recvProp->m_Offset + extraOffset );
    }

    return extraOffset;
}


RecvTable *CNetworkedVariableManager::GetTable( const char *tableName )
{
    if ( m_tables.empty() )
    {
        LOG_ERROR( "Failed to find table: %s (m_tables is empty)", tableName );
        return 0;
    }


    for each ( RecvTable *table in m_tables )
    {
        if ( !table )
        {
            continue;
        }


        if ( stricmp( table->m_pNetTableName, tableName ) == 0 )
        {
            return table;
        }
    }

    return 0;
}

example usages:
// we need to construct this manually
g_NetworkedVariableManager = new CNetworkedVariableManager();

// hook netvar proxy
g_NetworkedVariableManager->HookProp( "DT_CSPlayer", "m_angEyeAngles[0]", CSPlayer_EyeAnglesX );
Vector CPlayer::GetViewOffset( void )
{
 static int offset = g_NetworkedVariableManager->GetOffset( "DT_BasePlayer", "m_vecViewOffset[0]" );
 return *Member<Vector*>( this, offset );
}

lørdag den 9. juni 2012

CTraceFilterSkipTwoEntities

[I WON'T GO INTO DETAILS WITH THIS]
This isn't anything special, but since there always seems to be alot of drama going on when there has been an update, I figured I'll post some code here and simple instructions on how to find it. If you will be using Olly, you need the SigMaker plugin, by p47r!ck: Sig Maker 0.4


This tracefilter(CTraceFilterSkipTwoEntities) which is used in peoples tracing code, can be found alot of places, but my preferred location is inside the CSPlayer::FireBullet function, which contains a neat little string which we can follow: "gunshotsplash".
The call to CTraceFilterSkipTwoEntities's constructor is almost at the top of the function and should look something like this(raw copy paste from Olly):

54227F7C   6A 00            PUSH 0
54227F7E   57               PUSH EDI
54227F7F   56               PUSH ESI
54227F80   8D8D 9CFDFFFF    LEA ECX,DWORD PTR SS:[EBP-264]
54227F86   E8 E54BFCFF      CALL client.541ECB70
Just follow that call and make a signature/get the relative offset for it. Please note that this is achievable in IDA aswell, but Olly is my preferred tool.
 
void Aimbot::GetTraceFilterSkipTwoEntities( CSPlayer *first, CSPlayer *second, DWORD* thisptr )
{
 typedef void ( __thiscall *TraceFilterSkipTwoEntities_t )( void *thisptr, const CSPlayer *first, const CSPlayer *second, int group );
 static TraceFilterSkipTwoEntities_t traceFilterskiptwoentities = (TraceFilterSkipTwoEntities_t)memory::FindPattern( GetModuleHandle( "client.dll" ), "\x55\x8B\xEC\x8B\x55\x10\x8B\xC1\x8B\x4D\x08\x89\x48\x04\x8B\x4D\x0C\x89\x50\x08\xC7\x40" );

 if ( !traceFilterskiptwoentities )
 {
  LOG_ERROR( "TraceFilterSkipTwoEntities not found" );
 }


 traceFilterskiptwoentities( thisptr, first, second, 0 );
}
ex. usage: 
DWORD traceFilter[5]; // 20 or 0x14 bytes
GetTraceFilterSkipTwoEntities( m_localPlayer, skipPlayer, traceFilter );
TraceRay( ray, 0x4600400B, (ITraceFilter*)&traceFilter, &traceData );

mandag den 6. februar 2012

Creating materials at runtime in Source engine

An example on a common material used in the source engine can be:

"VertexLitGeneric"
{
    "$baseTexture" "models\props_equipment/Cargo_container03"
    "$Envmap" "env_cubemap"
    "$EnvmapMask" "models\props_equipment\Cargo_container03_ref"
    "$BlendTintByBaseAlpha" "1"
    "$envmapfresnel" "1"
    "$envmapFresnelMinMaxExp" "[0.03 0.03 2]"
}

...a .vmt file(Valve Material Type). So we need a way to create these materials at runtime, dynamically.

After looking through the old SDK, and reading about it on valve wiki it was pretty obvious what needed to be done. Please see below code sample.

#define MAT( _TYPE_ ) "\"" + _TYPE_ + "\"\n{\n\t\"$basetexture\" \"VGUI/white_additive\"\n\t\"$ignorez\" \"1\"\n\t\"$nofog\" \"1\"\n\t\"$halflambert\" \"1\"\n}"
#define MAT_IGNOREZ( _TYPE_ ) "\"" + _TYPE_ + "\"\n{\n\t\"$basetexture\" \"VGUI/white_additive\"\n\t\"$ignorez\" \"0\"\n\t\"$nofog\" \"1\"\n\t\"$halflambert\" \"1\"\n}"

IMaterial* CreateMaterial( bool shouldIgnoreZ )
{
 static int created = 0;

 //this is a pointer to the cvar I use for controlling lighting on the materials,
 //I registered it in the source engines linked list of ConVars,
 //and it's changable through the games console
 static ConVar* shadows = Singleton::Get()->Interfaces()->m_Cvar->FindVar( "cheat_chams_shadows" );

 std::string type = ( shadows->GetFloat() == 0.f ) ? "UnlitGeneric" : "VertexLitGeneric";

 //materialBuffer holds the vmt "script" or what to call it
 char materialBuffer[2048];
 if ( shouldIgnoreZ )
 {
  std::string tmp( MAT( type ) );
  sprintf( materialBuffer, tmp.c_str() );
 }
    else
 {
  std::string tmp( MAT_IGNOREZ( type ) );
  sprintf( materialBuffer, tmp.c_str() );
 }

 //make a unique name for our material
 char materialName[512];
 sprintf( materialName, "custom_material_%i.vmt", created );
    ++created;

 //construct keyvalues based on the material type
 KeyValues* keyValues = new KeyValues( type.c_str() );

 //load vmt "script" into our instance of keyvalues
    keyValues->LoadFromBuffer( materialName, materialBuffer );

 //create the actual material
 IMaterial* createdMaterial = Singleton::Get()->Interfaces()->m_MaterialSystem->CreateMaterial( materialName, keyValues );
    createdMaterial->IncrementReferenceCount();
 
    return createdMaterial;
}

fredag den 27. januar 2012

Adjusting aiming height for players with anti-aim

When playing HvH(Hacks vs. Hacks) in CSS, a feature, known as anti-aim, is often used.
I attached a screenshot of a bot, using anti-aim via the bot_mimic 1 convar:

As you can see on the screenshot, aiming at the center of the head hitbox, is not very effective for getting headshots.

I have attached my solution below with comments explaining the code:

struct Hitbox
{
 Hitbox( void )
 {
  hitbox = -1;
 }


 Hitbox( int newHitBox )
 {
  hitbox = newHitBox;
 }


 int  hitbox;
 Vector points[9];
};


enum
{
 FL_HIGH =  (1<<0),
 FL_LOW =  (1<<1),
 FL_SPECIAL = (1<<2)
};


struct BestPoint
{
 BestPoint( void )
 {
  hitbox = -1;
  point = 0;
  index = -1;
  dmg = -1;
  flags = 0;
 }


 BestPoint( int newHitBox )
 {
  hitbox = newHitBox;
  point = 0;
  index = -1;
  dmg = -1;
  flags = 0;
 }


 Vector point;
 int  index;
 int  dmg;
 int  flags;
 int  hitbox;
};
  
bool Aimbot::GetHitbox( CSPlayer *targetPlayer, Hitbox *box )
{
 matrix3x4_t matrix[MAXSTUDIOBONES];
 if ( !targetPlayer->SetupBones( matrix, MAXSTUDIOBONES, BONE_USED_BY_HITBOX, 0 ) )
 {
  return false;
 }


 studiohdr_t *studioHeader = g_InterfaceManager->ModelInfo()->GetVTable<IVModelInfo>()->GetStudiomodel( targetPlayer->GetModel() );
 if ( !studioHeader )
 {
  return false;
 }


 mstudiohitboxset_t *hitboxSet = studioHeader->pHitboxSet( targetPlayer->GetHitboxSet() );
 mstudiobbox_t *untransformedBox = hitboxSet->pHitbox( box->hitbox );

 
 // center and all the corners of the hitbox hehe
 Vector points[] = { ( ( untransformedBox->bbmin + untransformedBox->bbmax ) * .5f ),
  Vector( untransformedBox->bbmin.x, untransformedBox->bbmin.y, untransformedBox->bbmin.z ),
  Vector( untransformedBox->bbmin.x, untransformedBox->bbmax.y, untransformedBox->bbmin.z ),
  Vector( untransformedBox->bbmax.x, untransformedBox->bbmax.y, untransformedBox->bbmin.z ),
  Vector( untransformedBox->bbmax.x, untransformedBox->bbmin.y, untransformedBox->bbmin.z ),
  Vector( untransformedBox->bbmax.x, untransformedBox->bbmax.y, untransformedBox->bbmax.z ),
  Vector( untransformedBox->bbmin.x, untransformedBox->bbmax.y, untransformedBox->bbmax.z ),
  Vector( untransformedBox->bbmin.x, untransformedBox->bbmin.y, untransformedBox->bbmax.z ),
  Vector( untransformedBox->bbmax.x, untransformedBox->bbmin.y, untransformedBox->bbmax.z ) };


 for ( int index = 0; index <= 8; ++index )
 {
  if ( index != 0 )
  {
   // scale down the hitbox size
   points[index] =  ( ( ( ( points[index] + points[0] ) * .5f ) + points[index] ) * .5f );
  }
  
  // transform the vector
  VectorTransform( points[index], matrix[untransformedBox->bone], box->points[index] );

  //box.points[index] = this->GetExtrapolatedPosition( box.points[index], targetPlayer );
 }

 return true;
}


bool Aimbot::GetBestPoint( CSPlayer *targetPlayer, Hitbox *box, BestPoint *best )
{
 Vector center = box->points[0];

 // if we're checking the head hitbox
 if ( box->hitbox == 12 )
 {
  // aimpoints is already 3/4 of hitbox size
  Vector high = ( ( box->points[3] + box->points[5] ) * .5f );

  // is target looking down?
  float pitch = targetPlayer->GetEyeAngles().x;
  if ( ( pitch > 0.f )
   && ( pitch <= 89.f ) )
  {
   Vector height = ( ( ( high - box->points[0] ) / 3 ) * 4 );
   Vector newhigh = ( box->points[0] + ( height * ( pitch / 89.f ) ) );

   box->points[0] = newhigh;
   best->flags |= FL_HIGH;
  }
  // is target looking up?
  else if ( ( pitch < 292.5f )
   && ( pitch >= 271.f ) )
  {
   // lower the aimpoint
   box->points[0] -= Vector( 0.f, 0.f, 1.f );
   best->flags |= FL_LOW;
  }
 }


 for ( int index = 0; index <= 8; ++index )
 {
  int tmpdmg = GetDamage( box->points[index], targetPlayer );

  if ( ( tmpdmg != -1 )
   && ( best->dmg < tmpdmg )
   && ( ( tmpdmg - best->dmg ) > 1 ) )
  {
   best->dmg = tmpdmg;
   best->point = box->points[index];
   best->index = index;
  }
 }

 return ( best->dmg > 0 );
}
Usage should be quite obvious;
Result:
Happy hacking!

tirsdag den 10. januar 2012

Creating a simple string reversing user defined function(UDF) in C, for MySQL and running on CentOS

For an upcomming project, I need to use user defined functions in MySQL. Therefore I decided to figure out how it works, and what the optimal method of compiling an extention with the desired function, on CentOS would be.

To acquire the includes etc, download and install the MySQL source.

You need to customize the header called mysql_version.h according to your version of MySQL:
#ifndef _mysql_version_h
#define _mysql_version_h
#ifdef _CUSTOMCONFIG_
#include 
#else
#define PROTOCOL_VERSION 5
#define MYSQL_SERVER_VERSION "5.0.77"
#define MYSQL_BASE_VERSION "mysqld-5.0"
#define MYSQL_SERVER_SUFFIX_DEF  ""
#define FRM_VER 0
#define MYSQL_VERSION_ID 0
#define MYSQL_PORT 3306
#define MYSQL_PORT_DEFAULT 3306
#define MYSQL_UNIX_ADDR "/tmp/mysql.sock"
#define MYSQL_CONFIG_NAME "my"
#define MYSQL_COMPILATION_COMMENT ""

#endif /* _CUSTOMCONFIG_ */

#ifndef LICENSE
#define LICENSE GPL
#endif /* LICENSE */

#endif /* _mysql_version_h */

Now you can include mysql.h to your C-file, and start coding your UDF, I've coded a simple function for reversing a string, code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef unsigned long long ulonglong;
typedef long long longlong;
#include <mysql.h>
#include <ctype.h>


my_bool Inverse_init( UDF_INIT* initid, UDF_ARGS* args, char* message );
void Inverse_deinit( UDF_INIT* initid );
char* Inverse( UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error );


my_bool Inverse_init( UDF_INIT* initid, UDF_ARGS* args, char* message )
{
 if ( ( args->arg_count != 1 ) || ( args->arg_type[0] != STRING_RESULT ) )
 {
  strcpy( message, "Wrong argument type" );
  return 1;
 }

 return 0;
}


void Inverse_deinit( UDF_INIT* initid )
{
}


char* Inverse( UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error )
{
 const char* arg = args->args[0];

 (*length) = strlen( arg );

 int i;
 for ( i = (*length); i >= 0; i-- )
 {
  result[(*length) - i - 1] = arg[i];
 }

 return result;
}

 I have not made this code to be compatible with Unicode, but I intend to make a post in the near future, explaining Unicode.

We need to compile this, so let's fire up our CentOS and go the the directory where we saved the C-File(save it in your MySQL source directory somewhere), and compile using the following command:
gcc -shared -o filenamehere.so filenamehere.c -I ../include/

Obviously you want to customize the include directory parameter to lead to the include directory, from the directory where your file is, the include directories is: */mysqlsource/include/

So now that we have the shared object(.so) file, we can go ahead and put it in the following directory: */usr/lib/ 
then restart our mysqld service:
service mysqld restart

You can now load up your SQLyog, and define your newly created function using:
CREATE FUNCTION Inverse RETURNS STRING SONAME 'filenamehere.so'


And now your UDF is ready for use!