Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
scen committed Sep 24, 2012
1 parent 4472c8b commit 678dacd
Show file tree
Hide file tree
Showing 15 changed files with 277 additions and 35 deletions.
68 changes: 68 additions & 0 deletions CSGO_Reversing_Log.md
Expand Up @@ -17,6 +17,14 @@ Mac Bins
* `68 ? ? ? ? 52 FF D0 85 C0 75 0D 68 ? ? ? ? E8 ? ? ? ? 83 C4 04` + `0x1`

* Updating classes
* client.dylib
* `CHLClient`
* After HudText()
* Add `virtual void ShouldDrawDropdownConsole(void) = 0;`
* After connect()
* add `virtual int Disconnect( void) = 0;`
* `CInput`
* added a bunch of joystick functions
* engine.dylib
* `CEngineClient`
* After `Key_BindingForKey()`
Expand Down Expand Up @@ -48,6 +56,66 @@ Reversing
* C_BaseEntity->index
* Offset is 0x64 at the moment

* New CUserCmd crap
* since csgo refuses to work with olly, to get addy of getusercmd in ida, getvfunc(ginput, 8) then find address of it then sub from base address then add to ida's base address (0x1000000)
* http://www.gamedeception.net/threads/18658-L4D2-Verifying-CUserCmd
* GetUserCmd takes 2 args -1, 0
int __thiscall CInput__GetUserCmd(void *this, int nSlot, signed int sequence_number)
{
int v3; // esi@2
int v5; // eax@4

if ( nSlot == -1 )
v3 = (int)((char *)this + 56);
else
v3 = (int)(this + 212 * nSlot + 56);
v5 = *(_DWORD *)(v3 + 172) + 100 * sequence_number % 150;// MULTIPLAYER_BACKUP = 150
return ((*(_DWORD *)(v5 + 4) != sequence_number) - 1) & v5;
}

.text:102480C0 ; int __thiscall CInput__GetUserCmd(void *this, int nSlot, signed int sequence_number)
.text:102480C0 CInput__GetUserCmd proc near ; DATA XREF: .rdata:105F2C74o
.text:102480C0 ; .rdata:1061F4B4o
.text:102480C0
.text:102480C0 nSlot = dword ptr 8
.text:102480C0 sequence_number = dword ptr 0Ch
.text:102480C0
.text:102480C0 push ebp
.text:102480C1 mov ebp, esp
.text:102480C3 mov eax, [ebp+nSlot]
.text:102480C6 push esi
.text:102480C7 cmp eax, 0FFFFFFFFh ; CMP -1
.text:102480CA jnz short loc_102480D1
.text:102480CC lea esi, [ecx+38h]
.text:102480CF jmp short loc_102480DB
.text:102480D1 ; ---------------------------------------------------------------------------
.text:102480D1
.text:102480D1 loc_102480D1: ; CODE XREF: CInput__GetUserCmd+Aj
.text:102480D1 imul eax, 0D4h
.text:102480D7 lea esi, [eax+ecx+38h]
.text:102480DB
.text:102480DB loc_102480DB: ; CODE XREF: CInput__GetUserCmd+Fj
.text:102480DB mov ecx, [ebp+sequence_number]
.text:102480DE mov eax, 1B4E81B5h
.text:102480E3 imul ecx
.text:102480E5 sar edx, 4
.text:102480E8 mov eax, edx
.text:102480EA shr eax, 1Fh
.text:102480ED add edx, eax
.text:102480EF imul edx, 96h ; MULTIPLAYER_BACKUP = 150 decimal
.text:102480F5 mov eax, ecx
.text:102480F7 sub eax, edx
.text:102480F9 imul eax, 64h ; sizeof(CUserCmd) = 100
.text:102480FC add eax, [esi+0ACh]
.text:10248102 xor edx, edx
.text:10248104 cmp [eax+4], ecx
.text:10248107 pop esi
.text:10248108 setnz dl
.text:1024810B dec edx
.text:1024810C and eax, edx
.text:1024810E pop ebp
.text:1024810F retn 8
.text:1024810F CInput__GetUserCmd endp
* WeaponIDS
* In mac bins the functions are called BLah::GetCSWeaponID() they just mov a # into eax
* Make ida script to loop through all functions
Expand Down
74 changes: 71 additions & 3 deletions src/framework/csgo/csgohook.h
Expand Up @@ -22,13 +22,15 @@ namespace ion
const static int CLIENT_CREATEMOVE = 21;
const static int CLIENT_DISPATCHUSERMESSAGE = 36;
const static int PANEL_PAINTTRAVERSE = 41;
const static int MODELRENDER_DRAWMODELEXECUTE = 19;

typedef void (__thiscall *CreateMoveFn)(void*,int , float , bool );
typedef CUserCmd* (__thiscall *GetUserCmdFn)(void* thisptr,int sequence_number);
typedef bool (__thiscall* DispatchUserMessageFn)( void* thisptr, int msg_type, bf_read& msg_data );
typedef void (__thiscall *PaintTraverseFn)(void*,VPANEL, bool, bool);
typedef void (__thiscall *AchievementMgrFn)(void*, float frametime);


static bool __fastcall hkDispatchUserMessage(void* thisptr, int edx, int msg_type, bf_read &msg_data )
{
if (msg_type == 5) return 1;
Expand All @@ -39,12 +41,56 @@ namespace ion
return ret;
}

static void __stdcall hkDrawModelExecute( IMatRenderContext * ctx, const DrawModelState_t &state, const ModelRenderInfo_t &pInfo, matrix3x4_t *pCustomBoneToWorld)
{
csgo->modelRenderHk->unhookMethod(MODELRENDER_DRAWMODELEXECUTE);
if (pInfo.pModel)
{
auto name = csgo->gModelInfo->GetModelName(pInfo.pModel);
//log.write(log.VERB, format("%s\n") %name);
//012345678901234567
//models/weapons/t_arms
//models/weapons/ct_arms
if (!strncmp(name + 17, "arms", 4) || !strncmp(name + 18, "arms", 4))
{
//nodraw
}
else
{
csgo->gModelRender->DrawModelExecute(ctx, state, pInfo, pCustomBoneToWorld);
}
}
else
{
csgo->gModelRender->DrawModelExecute(ctx, state, pInfo, pCustomBoneToWorld);
}

csgo->modelRenderHk->hookMethod(&hkDrawModelExecute, MODELRENDER_DRAWMODELEXECUTE);
}

static void __fastcall hkCreateMove(void* thisptr, int edx, int sequence_number, float input_sample_frametime, bool active )
{
csgo->clientHk->unhookMethod(CLIENT_CREATEMOVE);
csgo->clientHk->getMethod<csgohook::CreateMoveFn>(CLIENT_CREATEMOVE)(thisptr, sequence_number, input_sample_frametime, active);
csgo->clientHk->hookMethod(&hkCreateMove, CLIENT_CREATEMOVE);
lua.call("CreateMove");

if (!entity::me().isAlive()) return;
log.write(log.WARN, format("gInput = 0x%X gClient = 0x%X 0x%X\n") % csgo->gInput% csgo->gClient% getvfunc<const void*>(csgo->gInput, 8) );
return;
CUserCmd* pCmd = csgo->gInput->GetUserCmd(0, sequence_number);

if (!pCmd) return;

for (int i = 1; i < 50; i++) //only have to loop up to max players
{

}

CVerifiedUserCmd* pVerifiedCmd = *(CVerifiedUserCmd**)((DWORD)csgo->gInput + 0xB8);
CVerifiedUserCmd* pVerified = &pVerifiedCmd[ sequence_number % MULTIPLAYER_BACKUP];
memcpy(&pVerified->m_cmd, pCmd, sizeof(CUserCmd));

pVerified->m_crc = CRC32_ProcessSingleBuffer(&pVerified->m_cmd, sizeof(CUserCmd));
}
static void __fastcall hkPaintTraverse(void* thisptr, int edx, VPANEL vguiPanel, bool forceRepaint, bool allowForce)
{
Expand All @@ -66,15 +112,37 @@ namespace ion
entity ent(i);
if (ent == me) continue;

if (ent.getType() == entity::PLAYER)
switch (ent.getType())
{
case entity::PLAYER:
visuals::renderPlayer(ent);
break;
case entity::C4PLANTED:
visuals::renderPlantedC4(ent);
break;
case entity::C4:
visuals::renderC4(ent);
break;
case entity::WEAPON:
visuals::renderWeapon(ent);
break;
default:
break;
if (!ent.isDormant())
{
auto pos = ent.getBonePos(0).toScreen();
if (pos.visible)
{
csgo->render->renderText(render::Center, csgo->tahoma12, point(pos.x, pos.y), color::white(), ent.getClientClassName());
}
}
break;
}
}

}
else
{
csgo->render->renderCornerRect(rect(point(600, 300), size(20, 20)), color::white());
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/framework/csgo/entity.h
Expand Up @@ -27,7 +27,8 @@ namespace ion
UNKNOWN = 0,
PLAYER,
C4,
C4PLANTED
C4PLANTED,
WEAPON
};

enum ETeamID
Expand Down Expand Up @@ -129,12 +130,17 @@ namespace ion
//0123456789
if (name[1] == 'P' && name[4] == 'n' && name[9] == '4') return C4PLANTED;

if (!strncmp(name + 1, "Weapon", 6))
{
return WEAPON;
}

return UNKNOWN;
}

float distanceTo() const
{
return fabs((me().getOrigin() - getOrigin()).Length());
return sqrt(fabs((me().getOrigin() - getOrigin()).Length()));
}

const vector getOrigin() const
Expand Down
5 changes: 4 additions & 1 deletion src/framework/csgo/interfaces.h
Expand Up @@ -30,13 +30,16 @@ namespace ion

module modClient, modEngine;

vmt* clientHk, *inputHk, *panelHk;
vmt* clientHk, *inputHk, *panelHk, *modelRenderHk;
netvar* nvar;
csgorender* render;

//address
DWORD weaponIDAsString;

//materials
IMaterial* mat_tArms;

//fonts
csgofont* tahoma12;
};
Expand Down
10 changes: 8 additions & 2 deletions src/framework/csgo/ioncsgo.h
Expand Up @@ -54,8 +54,10 @@ namespace ion
csgo->gMatSystem = reinterpret_cast<IMaterialSystem*>(appSystemFactory(getInterface("VMaterialSystem0"), NULL));
csgo->gDebugOverlay = reinterpret_cast<IVDebugOverlay*>(fnEngine(getInterface("VDebugOverlay0"), NULL));

//DWORD* clientVmt = *(DWORD**)(csgo->gClient);
//csgo->gInput = (CInput*)**(DWORD**)(clientVmt[14] + 0x2); //InActivateMouse();
DWORD* clientVmt = *(DWORD**)(csgo->gClient);
csgo->gInput = (CInput*)**(DWORD**)(clientVmt[15] + 0x2); //InActivateMouse();

log.write(log.WARN, format("input = 0x%X\n") % csgo->gInput);

//init fonts

Expand All @@ -67,6 +69,10 @@ namespace ion
csgo->nvar = new netvar(csgo->gClient);

csgo->clientHk = new vmt(csgo->gClient);
csgo->clientHk->hookMethod(&csgohook::hkCreateMove, csgohook::CLIENT_CREATEMOVE);

csgo->modelRenderHk = new vmt(csgo->gModelRender);
csgo->modelRenderHk->hookMethod(&csgohook::hkDrawModelExecute, csgohook::MODELRENDER_DRAWMODELEXECUTE);

csgo->panelHk = new vmt(csgo->gPanel);
csgo->panelHk->hookMethod(&csgohook::hkPaintTraverse, csgohook::PANEL_PAINTTRAVERSE);
Expand Down
8 changes: 8 additions & 0 deletions src/framework/csgo/netvar.h
Expand Up @@ -28,6 +28,13 @@ namespace ion
wep_Clip1 = findOffset(t, "m_iClip1");
wep_Clip2 = findOffset(t, "m_iClip2");

t = findTable("DT_PlantedC4");
c4_Ticking = findOffset(t, "m_bBombTicking");
c4_Blow = findOffset(t, "m_flC4Blow");
c4_TimerLen = findOffset(t, "m_flTimerLength");
c4_DefuseLen = findOffset(t, "m_flDefuseLength");
c4_DefuseCountDown = findOffset(t, "m_flDefuseCountDown");

t = findTable("DT_BaseEntity");
ply_Team = findOffset(t, "m_iTeamNum");

Expand Down Expand Up @@ -151,6 +158,7 @@ namespace ion
DWORD ply_Health, ply_LifeState, ply_Team, ply_Origin, ply_Flags, ply_ActiveWeapon;
DWORD ply_EyePos;
DWORD wep_Owner, wep_Clip1, wep_Clip2;
DWORD c4_Ticking, c4_Blow, c4_TimerLen, c4_DefuseLen, c4_DefuseCountDown;

IBaseClientDLL* client;

Expand Down
3 changes: 3 additions & 0 deletions src/framework/csgo/sdk.h
Expand Up @@ -58,6 +58,9 @@
#include "../../sdk/hl2_csgo/public/vgui/IPanel.h"
#include "../../sdk/hl2_csgo/public/vgui/ISurfaceV30.h"
#include "../../sdk/hl2_csgo/public/vgui/ILocalize.h"

#include "../../sdk/hl2_csgo/public/tier1/checksum_crc.h"

#undef private
#undef protected

Expand Down
70 changes: 66 additions & 4 deletions src/framework/csgo/visuals.h
Expand Up @@ -21,6 +21,61 @@ namespace ion
return healthRed;
}

static void renderC4(entity& ent)
{
auto wep = weapon(ent.baseEnt);
auto holder = wep.getPlayerOwner();
auto bone = holder.isAlive() ? holder.getBonePos(holder.MID_CHEST).toScreen() : wep.getBonePos(0).toScreen();

static color c4(252, 88, 209, 255);

if (bone.visible)
{
auto r = csgo->render;
const static int TextSpace = 3;
r->renderCornerRect(rect(point(bone.x - 8, bone.y - 8), size(16, 16)), c4);
r->renderText(0, csgo->tahoma12, point(bone.x + 8 + TextSpace, bone.y - 8), c4, "C4");
r->renderText(render::RAlign, csgo->tahoma12, point(bone.x - 8 - TextSpace, bone.y - 8), c4, format("%d m") % (int)ent.distanceTo());
}
}

static void renderWeapon(entity& ent)
{
static color weaponCol(214, 181, 90, 255);
auto wep = weapon(ent.baseEnt);
if (wep.getPlayerOwner().isValid()) return;
auto bone = wep.getBonePos(0).toScreen();
if (bone.visible)
{
auto r = csgo->render;
const static int TextSpace = 3;
r->renderCornerRect(rect(point(bone.x - 8, bone.y - 8), size(16, 16)), weaponCol);
r->renderText(0, csgo->tahoma12, point(bone.x + 8 + TextSpace, bone.y - 8), weaponCol, std::string(wep.getNiceName()));
r->renderText(render::RAlign, csgo->tahoma12, point(bone.x - 8 - TextSpace, bone.y - 8), weaponCol, format("%d m") % (int)ent.distanceTo());
}
}

static void renderPlantedC4(entity& ent)
{
auto bone = ent.getBonePos(0).toScreen();

static color c4planted(252, 88, 209, 255);

if (bone.visible)
{
auto r = csgo->render;
auto base = ent.baseEnt;
const static int TextSpace = 3;
r->renderCornerRect(rect(point(bone.x - 8, bone.y - 8), size(16, 16)), c4planted);
r->renderText(0, csgo->tahoma12, point(bone.x + 8 + TextSpace, bone.y - 8), c4planted, "C4 (Live)");
r->renderText(render::RAlign, csgo->tahoma12, point(bone.x - 8 - TextSpace, bone.y - 8), c4planted, format("%d m") % (int)ent.distanceTo());
r->renderText(render::Center, csgo->tahoma12, point(bone.x, bone.y + 8 + TextSpace), c4planted, format("%.1f s") % ( *makeptr<float>(base, csgo->nvar->c4_Blow) -csgo->gGlobalVars->curtime ));
/* % *makeptr<bool>(base, csgo->nvar->c4_Ticking) % *makeptr<float>(base, csgo->nvar->c4_Blow)
% *makeptr<float>(base, csgo->nvar->c4_TimerLen)
% *makeptr<float>(base, csgo->nvar->c4_DefuseLen)
% *makeptr<float>(base, csgo->nvar->c4_DefuseCountDown));*/
}
}

static void renderPlayer(entity& ent)
{
Expand Down Expand Up @@ -73,22 +128,29 @@ namespace ion
const static int DistanceHP = 2;
const static int HPBarWidth = 5;
const static int DistanceText = 2;
const static int DistanceTextLeft = 3;

float healthPct = (float)ent.getHealth() / 100.0;
r->outlineRectOutline(rect(point(upperBB.x - bbWidth, upperBB.y), size(bbWidth * 2.0f, bbHeight)), col, color::black());
r->fillRect(rect(point(upperBB.x + bbWidth + DistanceHP, upperBB.y), size(HPBarWidth, bbHeight)), color::black());
r->fillRect(rect(point(upperBB.x + bbWidth + DistanceHP + 1, upperBB.y + 1 + ((bbHeight - 2.0f) * (1.0f - healthPct))), size(HPBarWidth - 2, bbHeight * healthPct - 2)), getHealthColor(healthPct));
r->fillRect(rect(point(upperBB.x + bbWidth + DistanceHP + 1, upperBB.y + 1 + ((bbHeight - 2.0f) * (1.0f - healthPct))), size(HPBarWidth - 2, (bbHeight-2.0f) * healthPct )), getHealthColor(healthPct));

int lx = upperBB.x - bbWidth - DistanceTextLeft;
int ly = upperBB.y;

size ls;

//right side
int x = upperBB.x + bbWidth + DistanceHP + HPBarWidth + DistanceText;
int y = upperBB.y;
size s = r->renderText(render::None, csgo->tahoma12, point(x, y), col, ent.getName());
y = y + s.getHeight();
s = r->renderText(render::None, csgo->tahoma12, point(x, y), col, format("%d HP") % ent.getHealth());
y = y + s.getHeight();
s = r->renderText(render::None, csgo->tahoma12, point(x, y), col, format("%.1f m") % (int)sqrt(ent.distanceTo()));
s = r->renderText(render::None, csgo->tahoma12, point(x, y), col, format("%.1f m") % (int)ent.distanceTo());
y = y + s.getHeight();
auto wep = weapon(ent.getActiveWeapon());
auto own = wep.getPlayerOwner();
s = r->renderText(render::None, csgo->tahoma12, point(x, y), col, format("wep: %s owner: 0x%X name=%s") % wep.getNiceName() % own % (!own?"69":entity(own).getName()));
s = r->renderText(render::None, csgo->tahoma12, point(x, y), col, std::string(wep.getNiceName()));

r->renderCornerRect(rect(point(origHead.x - 8, origHead.y - 8), size(16, 16)), col);
}
Expand Down

0 comments on commit 678dacd

Please sign in to comment.