Merge pull request #97 from nullifiedcat/minor-changes

multiplatform offset support + faster hooks
This commit is contained in:
nullifiedcat 2017-05-04 16:57:45 +03:00 committed by GitHub
commit c43e3dfb5d
11 changed files with 273 additions and 246 deletions

View File

@ -27,6 +27,7 @@
#include <unordered_map>
#include <algorithm>
#include "aftercheaders.h"
#include "offsets.hpp"
#include "drawing.h"
#include "resource.hpp"
#include "entitycache.h"

View File

@ -127,49 +127,39 @@ void hack::Initialize() {
InitNetVars();
g_pLocalPlayer = new LocalPlayer();
g_pPlayerResource = new TFPlayerResource();
hooks::hkPanel = new hooks::VMTHook();
hooks::hkPanel->Init(g_IPanel, 0);
//hooks::hkPanel->HookMethod((void*)&hack::Hk_PaintTraverse, hooks::offPaintTraverse);
hooks::hkPanel->HookMethod((void*)PaintTraverse_hook, hooks::offPaintTraverse);
hooks::hkPanel->Apply();
hooks::hkClientMode = new hooks::VMTHook();
/*
* TIME FOR HOOKING! wow
*/
hooks::panel.Set(g_IPanel);
hooks::panel.HookMethod((void*)PaintTraverse_hook, offsets::PaintTraverse());
hooks::panel.Apply();
uintptr_t* clientMode = 0;
// Bad way to get clientmode.
// FIXME [MP]?
while(!(clientMode = **(uintptr_t***)((uintptr_t)((*(void***)g_IBaseClient)[10]) + 1))) {
sleep(1);
}
//hooks::hkMatSurface = new hooks::VMTHook();
//hooks::hkMatSurface->Init((void*)matsurface, 0);
//hooks::hkMatSurface->HookMethod((void*)test_handleevent, 1);
hooks::hkClientMode->Init((void*)clientMode, 0);
//hooks::hkClientMode->HookMethod((void*)&hack::Hk_CreateMove, hooks::offCreateMove);
hooks::hkClientMode->HookMethod((void*)CreateMove_hook, hooks::offCreateMove);
hooks::hkClientMode->HookMethod((void*)OverrideView_hook, hooks::offOverrideView);
hooks::hkClientMode->HookMethod((void*)LevelInit_hook, hooks::offLevelInit);
hooks::hkClientMode->HookMethod((void*)LevelShutdown_hook, hooks::offLevelShutdown);
hooks::hkClientMode->Apply();
hooks::hkStudioRender = new hooks::VMTHook();
hooks::hkStudioRender->Init((void*)g_IStudioRender, 0);
hooks::hkStudioRender->HookMethod((void*)BeginFrame_hook, hooks::offBeginFrame);
hooks::hkStudioRender->Apply();
hooks::hkClient = new hooks::VMTHook();
hooks::hkClient->Init((void*)g_IBaseClient, 0);
hooks::hkClient->HookMethod((void*)FrameStageNotify_hook, hooks::offFrameStageNotify);
hooks::hkClient->HookMethod((void*)DispatchUserMessage_hook, hooks::offFrameStageNotify + 1);
hooks::hkClient->HookMethod((void*)IN_KeyEvent_hook, hooks::offKeyEvent);
hooks::hkClient->Apply();
hooks::hkInput = new hooks::VMTHook();
hooks::hkInput->Init((void*)g_IInput, 0);
hooks::hkInput->HookMethod((void*)GetUserCmd_hook, hooks::offGetUserCmd);
hooks::hkInput->Apply();
//logging::Info("Before hacking: %s", g_ISteamFriends->GetPersonaName());
hooks::hkIVModelRender = new hooks::VMTHook();
hooks::hkIVModelRender->Init(g_IVModelRender, 0);
hooks::hkIVModelRender->HookMethod((void*)DrawModelExecute_hook, hooks::offDrawModelExecute);
hooks::hkIVModelRender->Apply();
hooks::hkSteamFriends = new hooks::VMTHook();
hooks::hkSteamFriends->Init(g_ISteamFriends, 0);
hooks::hkSteamFriends->HookMethod((void*)GetFriendPersonaName_hook, hooks::offGetFriendPersonaName);
hooks::hkSteamFriends->Apply();
hooks::clientmode.Set((void*)clientMode);
hooks::clientmode.HookMethod((void*)CreateMove_hook, offsets::CreateMove());
hooks::clientmode.HookMethod((void*)OverrideView_hook, offsets::OverrideView());
hooks::clientmode.HookMethod((void*)LevelInit_hook, offsets::LevelInit());
hooks::clientmode.HookMethod((void*)LevelShutdown_hook, offsets::LevelShutdown());
hooks::clientmode.Apply();
hooks::client.Set(g_IBaseClient);
hooks::client.HookMethod((void*)FrameStageNotify_hook, offsets::FrameStageNotify());
hooks::client.HookMethod((void*)DispatchUserMessage_hook, offsets::DispatchUserMessage());
hooks::client.HookMethod((void*)IN_KeyEvent_hook, offsets::IN_KeyEvent());
hooks::client.Apply();
hooks::input.Set(g_IInput);
hooks::input.HookMethod((void*)GetUserCmd_hook, offsets::GetUserCmd());
hooks::input.Apply();
hooks::modelrender.Set(g_IVModelRender);
hooks::modelrender.HookMethod((void*)DrawModelExecute_hook, offsets::DrawModelExecute());
hooks::modelrender.Apply();
hooks::steamfriends.Set(g_ISteamFriends);
hooks::steamfriends.HookMethod((void*)GetFriendPersonaName_hook, offsets::GetFriendPersonaName());
hooks::steamfriends.Apply();
//logging::Info("After hacking: %s", g_ISteamFriends->GetPersonaName());
// Sadly, it doesn't work as expected :(
/*hooks::hkBaseClientState = new hooks::VMTHook();
@ -181,6 +171,8 @@ void hack::Initialize() {
//hooks::hkBaseClientState8->HookMethod((void*)ProcessSetConVar_hook, hooks::offProcessSetConVar);
//hooks::hkBaseClientState8->HookMethod((void*)ProcessGetCvarValue_hook, hooks::offProcessGetCvarValue);
//hooks::hkBaseClientState8->Apply();
// FIXME [MP]
if (TF2) g_GlowObjectManager = *reinterpret_cast<CGlowObjectManager**>(gSignatures.GetClientSignature("C1 E0 05 03 05") + 5);
InitStrings();
hacks::shared::killsay::Init();
@ -211,18 +203,6 @@ void hack::Shutdown() {
if (hack::shutdown) return;
hack::shutdown = true;
playerlist::Save();
logging::Info("Killing hooks..");
if (hooks::hkPanel) hooks::hkPanel->Kill();
if (hooks::hkClientMode) hooks::hkClientMode->Kill();
if (hooks::hkClient) hooks::hkClient->Kill();
if (hooks::hkMatSurface) hooks::hkMatSurface->Kill();
if (hooks::hkNetChannel) hooks::hkNetChannel->Kill();
if (hooks::hkStudioRender) hooks::hkStudioRender->Kill();
if (hooks::hkInput) hooks::hkInput->Kill();
if (hooks::hkIVModelRender) hooks::hkIVModelRender->Kill();
if (hooks::hkBaseClientState) hooks::hkBaseClientState->Kill();
if (hooks::hkBaseClientState8) hooks::hkBaseClientState8->Kill();
//if (hooks::hkCTFPlayer) hooks::hkCTFPlayer->Kill();
logging::Info("Unregistering convars..");
ConVar_Unregister();
logging::Info("Shutting down killsay...");

View File

@ -112,16 +112,15 @@ static int last_number = 0;
void CreateMove() {
static bool flswitch = false;
// TODO FIXME HOOKING WITHOUT UNHOOKING = 100% SEGV ON UNINJECT.
// TODO FIXME this should be moved out of here
IClientEntity* localplayer = g_IEntityList->GetClientEntity(g_IEngine->GetLocalPlayer());
if (TF && render_zoomed && localplayer) {
void** vtable = *(void***)(localplayer);
if (vtable[hooks::offShouldDraw] != C_TFPlayer__ShouldDraw_hook) {
C_TFPlayer__ShouldDraw_original = vtable[hooks::offShouldDraw];
if (vtable[offsets::ShouldDraw()] != C_TFPlayer__ShouldDraw_hook) {
C_TFPlayer__ShouldDraw_original = vtable[offsets::ShouldDraw()];
void* page = (void*)((uintptr_t)vtable &~ 0xFFF);
mprotect(page, 0xFFF, PROT_READ | PROT_WRITE | PROT_EXEC);
vtable[hooks::offShouldDraw] = (void*)C_TFPlayer__ShouldDraw_hook;
vtable[offsets::ShouldDraw()] = (void*)C_TFPlayer__ShouldDraw_hook;
mprotect(page, 0xFFF, PROT_READ | PROT_EXEC);
}
}

View File

@ -10,78 +10,78 @@
#include "logging.h"
#include <stdlib.h>
#include <string.h>
unsigned int hooks::offCreateMove = 22;
unsigned int hooks::offPaintTraverse = 42;
unsigned int hooks::offOverrideView = 17;
unsigned int hooks::offFrameStageNotify = 35;
unsigned int hooks::offCanPacket = 57;
unsigned int hooks::offSendNetMsg = 41;
unsigned int hooks::offShutdown = 37;
unsigned int hooks::offKeyEvent = 20;
unsigned int hooks::offHandleInputEvent = 78;
unsigned int hooks::offLevelInit = 23;
unsigned int hooks::offLevelShutdown = 24;
unsigned int hooks::offBeginFrame = 5;
namespace hooks {
// This thing had been copypasted from somewhere, maybe from F1Public.
bool hooks::IsHooked(void* inst) {
return hooks::GetVMT(inst, 0)[-2] == (void*)VMTHook::GUARD;
}
unsigned int hooks::CountMethods(void** vmt) {
unsigned CountMethods(method_table_t table) {
unsigned int i = -1;
do ++i; while (vmt[i]);
do ++i; while (table[i]);
return i;
}
void**& hooks::GetVMT(void* inst, unsigned int offset) {
return *reinterpret_cast<void***>((char*)inst + offset);
table_ref_t GetVMT(ptr_t inst, uint32_t offset) {
return *reinterpret_cast<table_ptr_t>((uint32_t)inst + offset);
}
void hooks::VMTHook::Init(void* inst, unsigned int offset) {
vmt = &GetVMT(inst, offset);
oldvmt = *vmt;
unsigned int cnt = CountMethods(oldvmt);
void **arr = array = (void**)malloc((cnt + 4) * sizeof(void*));
arr[0] = this;
arr[1] = (void* )GUARD;
(arr + 3)[cnt] = 0;
unsigned int i = -1;
do arr[i + 3] = oldvmt[i]; while (++i < cnt);
bool IsHooked(ptr_t inst, uint32_t offset) {
return GetVMT(inst, offset)[-1] == (method_t)GUARD;
}
void hooks::VMTHook::Kill() {
if (vmt)
*vmt = oldvmt;
vmt = 0;
free(array);
array = 0;
VMTHook::VMTHook() {
static_assert(ptr_size == 4, "Pointer size must be DWORD.");
};
VMTHook::~VMTHook() {
Release();
}
void hooks::VMTHook::HookMethod(void* func, unsigned int idx) {
array[idx + 3] = func;
void VMTHook::Set(ptr_t inst, uint32_t offset) {
Release();
vtable_ptr = &GetVMT(inst, offset);
vtable_original = *vtable_ptr;
int mc = CountMethods(vtable_original);
vtable_hooked = static_cast<method_table_t>(calloc(mc + 3, sizeof(ptr_t)));
memcpy(&vtable_hooked[2], vtable_original, sizeof(ptr_t) * mc);
vtable_hooked[0] = this;
vtable_hooked[1] = (void*)GUARD;
}
void* hooks::VMTHook::GetMethod(unsigned int idx) const {
return oldvmt[idx];
void VMTHook::Release() {
if (vtable_ptr) {
if ((*vtable_ptr)[-1] == (method_t)GUARD) {
*vtable_ptr = vtable_original;
}
free(vtable_hooked);
vtable_ptr = nullptr;
vtable_hooked = nullptr;
vtable_original = nullptr;
}
}
void hooks::VMTHook::Apply() {
*vmt = array + 3;
void* VMTHook::GetMethod(uint32_t idx) const {
return vtable_original[idx];
}
//hooks::VMTHook* hooks::hkCTFPlayer = nullptr;
hooks::VMTHook* hooks::hkInput = nullptr;
hooks::VMTHook* hooks::hkSteamFriends = nullptr;
hooks::VMTHook* hooks::hkBaseClientState = nullptr;
hooks::VMTHook* hooks::hkBaseClientState8 = nullptr;
hooks::VMTHook* hooks::hkClientMode = 0;
hooks::VMTHook* hooks::hkPanel = 0;
hooks::VMTHook* hooks::hkClient = 0;
hooks::VMTHook* hooks::hkNetChannel = 0;
hooks::VMTHook* hooks::hkClientDLL = 0;
hooks::VMTHook* hooks::hkMatSurface = 0;
hooks::VMTHook* hooks::hkStudioRender = 0;
hooks::VMTHook* hooks::hkIVModelRender = nullptr;
void VMTHook::HookMethod(ptr_t func, uint32_t idx) {
vtable_hooked[2 + idx] = func;
}
void VMTHook::Apply() {
*vtable_ptr = &vtable_hooked[2];
}
VMTHook input {};
VMTHook steamfriends {};
VMTHook baseclientstate {};
VMTHook baseclientstate8 {};
VMTHook clientmode {};
VMTHook panel {};
VMTHook client {};
VMTHook netchannel {};
VMTHook clientdll {};
VMTHook matsurface {};
VMTHook studiorender {};
VMTHook modelrender {};
}

View File

@ -8,62 +8,56 @@
#ifndef HOOKS_H_
#define HOOKS_H_
namespace hooks {
// Parts of copypasted code
// Credits: Casual_Hacker
unsigned int CountMethods(void** vmt);
void**& GetVMT(void* inst, unsigned int offset);
bool IsHooked(void* inst);
#include <stdint.h>
#include <stddef.h>
namespace hooks {
typedef void* ptr_t;
typedef void* method_t;
typedef method_t* method_table_t;
typedef method_table_t* table_ptr_t;
typedef method_table_t& table_ref_t;
constexpr size_t ptr_size = sizeof(ptr_t);
unsigned CountMethods(method_table_t table);
table_ref_t GetVMT(ptr_t inst, uint32_t offset = 0);
bool IsHooked(ptr_t inst, uint32_t offset = 0);
constexpr uint32_t GUARD = 0xD34DC477;
class VMTHook {
public:
enum { GUARD = 0xD34DC477 };
void Init(void* inst, unsigned int offset);
void Kill();
void HookMethod(void* func, unsigned int idx);
void* GetMethod(unsigned int idx) const;
VMTHook();
~VMTHook();
void Set(ptr_t inst, uint32_t offset = 0);
void Release();
void HookMethod(ptr_t func, uint32_t idx);
void* GetMethod(uint32_t idx) const;
void Apply();
protected:
void ***vmt;
void **oldvmt;
void **array;
public:
ptr_t object { nullptr };
table_ptr_t vtable_ptr { nullptr };
method_table_t vtable_original { nullptr };
method_table_t vtable_hooked { nullptr };
};
//extern VMTHook* hkCTFPlayer;
extern VMTHook* hkPanel;
extern VMTHook* hkClientMode;
extern VMTHook* hkClient;
extern VMTHook* hkNetChannel;
extern VMTHook* hkClientDLL;
extern VMTHook* hkMatSurface;
extern VMTHook* hkStudioRender;
extern VMTHook* hkInput;
extern VMTHook* hkIVModelRender;
extern VMTHook* hkBaseClientState;
extern VMTHook* hkBaseClientState8;
extern VMTHook* hkSteamFriends;
constexpr unsigned int offGetUserCmd = 8;
constexpr unsigned int offShouldDraw = 136;
constexpr unsigned int offDrawModelExecute = 19;
constexpr unsigned int offGetClientName = 44;
constexpr unsigned int offProcessSetConVar = 4;
constexpr unsigned int offProcessGetCvarValue = 29;
constexpr unsigned int offGetFriendPersonaName = 7;
extern unsigned int offHandleInputEvent;
extern unsigned int offPaintTraverse;
extern unsigned int offCreateMove;
extern unsigned int offOverrideView;
extern unsigned int offFrameStageNotify;
extern unsigned int offCanPacket;
extern unsigned int offSendNetMsg;
extern unsigned int offShutdown;
extern unsigned int offKeyEvent;
extern unsigned int offLevelInit;
extern unsigned int offLevelShutdown;
extern unsigned int offBeginFrame;
extern VMTHook panel;
extern VMTHook clientmode;
extern VMTHook client;
extern VMTHook netchannel;
extern VMTHook clientdll;
extern VMTHook matsurface;
extern VMTHook studiorender;
extern VMTHook input;
extern VMTHook modelrender;
extern VMTHook baseclientstate;
extern VMTHook baseclientstate8;
extern VMTHook steamfriends;
}

View File

@ -1,14 +0,0 @@
/*
* BeginFrame.cpp
*
* Created on: Feb 10, 2017
* Author: nullifiedcat
*/
#include "hookedmethods.h"
#include "../common.h"
#include "../sdk.h"
void BeginFrame_hook(IStudioRender* _this) {
((BeginFrame_t*)hooks::hkStudioRender->GetMethod(hooks::offBeginFrame))(_this);
}

View File

@ -12,6 +12,7 @@
#include "../common.h"
#include "hookedmethods.h"
// FIXME remove this temporary code already!
float AngleDiff( float destAngle, float srcAngle )
{
float delta;
@ -28,7 +29,7 @@ float AngleDiff( float destAngle, float srcAngle )
delta += 360;
}
return delta;
}//TODO temporary
}
#include "../profiler.h"
@ -70,7 +71,9 @@ bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) {
if (TF2C && CE_GOOD(LOCAL_W) && minigun_jump && LOCAL_W->m_iClassID == g_pClassID->CTFMinigun) {
CE_INT(LOCAL_W, netvar.iWeaponState) = 0;
}
bool ret = ((CreateMove_t*)hooks::hkClientMode->GetMethod(hooks::offCreateMove))(thisptr, inputSample, cmd);
static CreateMove_t original_method = (CreateMove_t)hooks::clientmode.GetMethod(offsets::CreateMove());
bool ret = original_method(thisptr, inputSample, cmd);
PROF_SECTION(CreateMove);
@ -90,13 +93,12 @@ bool CreateMove_hook(void* thisptr, float inputSample, CUserCmd* cmd) {
// PROF_BEGIN();
INetChannel* ch = (INetChannel*)g_IEngine->GetNetChannelInfo();
if (ch && !hooks::IsHooked((void*)((uintptr_t)ch))) {
hooks::hkNetChannel = new hooks::VMTHook();
hooks::hkNetChannel->Init(ch, 0);
hooks::hkNetChannel->HookMethod((void*)CanPacket_hook, hooks::offCanPacket);
hooks::hkNetChannel->HookMethod((void*)SendNetMsg_hook, hooks::offSendNetMsg);
hooks::hkNetChannel->HookMethod((void*)Shutdown_hook, hooks::offShutdown);
hooks::hkNetChannel->Apply();
if (ch && !hooks::IsHooked((void*)ch)) {
hooks::netchannel.Set(ch);
hooks::netchannel.HookMethod((void*)CanPacket_hook, offsets::CanPacket());
hooks::netchannel.HookMethod((void*)SendNetMsg_hook, offsets::SendNetMsg());
hooks::netchannel.HookMethod((void*)Shutdown_hook, offsets::Shutdown());
hooks::netchannel.Apply();
}
//logging::Info("canpacket: %i", ch->CanPacket());
//if (!cmd) return ret;

View File

@ -26,7 +26,8 @@ void** pure_addr = nullptr;
CatEnum software_cursor_enum({"KEEP", "ALWAYS", "NEVER", "MENU ON", "MENU OFF"});
CatVar software_cursor_mode(software_cursor_enum, "software_cursor_mode", "1", "Software cursor", "Try to change this and see what works best for you");
void PaintTraverse_hook(void* p, unsigned int vp, bool fr, bool ar) {
void PaintTraverse_hook(void* _this, unsigned int vp, bool fr, bool ar) {
static const PaintTraverse_t original = (PaintTraverse_t)hooks::panel.GetMethod(offsets::PaintTraverse());
#if DEBUG_SEGV == true
if (!segvcatch::handler_fpe || !segvcatch::handler_segv) {
if (!segvcatch::handler_fpe) segvcatch::init_segv();
@ -83,7 +84,7 @@ void PaintTraverse_hook(void* p, unsigned int vp, bool fr, bool ar) {
}
}
if (call_default) SAFE_CALL(((PaintTraverse_t*)hooks::hkPanel->GetMethod(hooks::offPaintTraverse))(p, vp, fr, ar));
if (call_default) SAFE_CALL(original(_this, vp, fr, ar));
// To avoid threading problems.
PROF_SECTION(PaintTraverse);

View File

@ -10,36 +10,32 @@
#include "../common.h"
typedef bool(CreateMove_t)(void*, float, CUserCmd*);
typedef void(PaintTraverse_t)(void*, unsigned int, bool, bool);
typedef bool(CanPacket_t)(void*);
typedef int(IN_KeyEvent_t)(void*, int, int, const char*);
typedef bool(SendNetMsg_t)(void*, INetMessage&, bool, bool);
typedef void(Shutdown_t)(void*, const char*);
typedef void(OverrideView_t)(void*, CViewSetup*);
typedef bool(DispatchUserMessage_t)(void*, int, bf_read&);
typedef void(FrameStageNotify_t)(void*, int);
typedef void(LevelInit_t)(void*, const char*);
typedef void(LevelShutdown_t)(void*);
typedef void(BeginFrame_t)(IStudioRender*);
typedef bool(*CreateMove_t)(void*, float, CUserCmd*);
typedef void(*PaintTraverse_t)(void*, unsigned int, bool, bool);
typedef bool(*CanPacket_t)(void*);
typedef int(*IN_KeyEvent_t)(void*, int, int, const char*);
typedef bool(*SendNetMsg_t)(void*, INetMessage&, bool, bool);
typedef void(*Shutdown_t)(void*, const char*);
typedef void(*OverrideView_t)(void*, CViewSetup*);
typedef bool(*DispatchUserMessage_t)(void*, int, bf_read&);
typedef void(*FrameStageNotify_t)(void*, int);
typedef void(*LevelInit_t)(void*, const char*);
typedef void(*LevelShutdown_t)(void*);
typedef void(*BeginFrame_t)(IStudioRender*);
typedef bool(*CanInspect_t)(IClientEntity*);
typedef void(*DrawModelExecute_t)(IVModelRender*, const DrawModelState_t&, const ModelRenderInfo_t&, matrix3x4_t*);
typedef CUserCmd*(GetUserCmd_t)(IInput*, int);
typedef const char*(GetClientName_t)(CBaseClientState*);
typedef bool(ProcessSetConVar_t)(CBaseClientState*, NET_SetConVar*);
typedef bool(ProcessGetCvarValue_t)(CBaseClientState*, SVC_GetCvarValue*);
typedef CUserCmd*(*GetUserCmd_t)(IInput*, int);
typedef const char*(*GetClientName_t)(CBaseClientState*);
typedef bool(*ProcessSetConVar_t)(CBaseClientState*, NET_SetConVar*);
typedef bool(*ProcessGetCvarValue_t)(CBaseClientState*, SVC_GetCvarValue*);
const char* GetClientName_hook(CBaseClientState* _this);
bool ProcessSetConVar_hook(CBaseClientState* _this, NET_SetConVar* msg);
bool ProcessGetCvarValue_hook(CBaseClientState* _this, SVC_GetCvarValue* msg);
//typedef void(*CInput__CreateMove_t)(void*, int, float, bool);
//void CInput__CreateMove_hook(void*, int sequence_number, float input_sample_frametime, bool active);
bool CanInspect_hook(IClientEntity*);
const unsigned int offCanInspect = 512;
typedef const char*(GetFriendPersonaName_t)(ISteamFriends*, CSteamID);
typedef const char*(*GetFriendPersonaName_t)(ISteamFriends*, CSteamID);
const char* GetFriendPersonaName_hook(ISteamFriends* _this, CSteamID steamID);
void BeginFrame_hook(IStudioRender*);
CUserCmd* GetUserCmd_hook(IInput*, int);
void DrawModelExecute_hook(IVModelRender* _this, const DrawModelState_t& state, const ModelRenderInfo_t& info, matrix3x4_t* matrix);

View File

@ -12,6 +12,7 @@
static CatVar no_invisibility(CV_SWITCH, "no_invis", "0", "Remove Invisibility", "Useful with chams!");
// This hook isn't used yet!
int C_TFPlayer__DrawModel_hook(IClientEntity* _this, int flags) {
float old_invis = *(float*)((uintptr_t)_this + 79u);
if (no_invisibility) {
@ -27,17 +28,9 @@ static CatVar no_arms(CV_SWITCH, "no_arms", "0", "No Arms", "Removes arms from f
static CatVar no_hats(CV_SWITCH, "no_hats", "0", "No Hats", "Removes non-stock hats");
void DrawModelExecute_hook(IVModelRender* _this, const DrawModelState_t& state, const ModelRenderInfo_t& info, matrix3x4_t* matrix) {
/*IClientUnknown* unknown = info.pRenderable->GetIClientUnknown();
if (unknown) {
IClientEntity* entity = unknown->GetIClientEntity();
if (entity && entity->entindex() != -1) {
if (entity->GetClientClass()->m_ClassID == g_pClassID->C_Player) {
//CMatRenderContextPtr ptr();
}
}
}*/
static const DrawModelExecute_t original = (DrawModelExecute_t)hooks::modelrender.GetMethod(offsets::DrawModelExecute());
if (!cathook || !(no_arms || no_hats || (clean_screenshots && g_IEngine->IsTakingScreenshot()))) {
((DrawModelExecute_t)(hooks::hkIVModelRender->GetMethod(hooks::offDrawModelExecute)))(_this, state, info, matrix);
original(_this, state, info, matrix);
return;
}
@ -63,18 +56,20 @@ void DrawModelExecute_hook(IVModelRender* _this, const DrawModelState_t& state,
}
}
((DrawModelExecute_t)(hooks::hkIVModelRender->GetMethod(hooks::offDrawModelExecute)))(_this, state, info, matrix);
original(_this, state, info, matrix);
}
bool CanPacket_hook(void* thisptr) {
bool CanPacket_hook(void* _this) {
const CanPacket_t original = (CanPacket_t)hooks::netchannel.GetMethod(offsets::CanPacket());
SEGV_BEGIN;
return send_packets && ((CanPacket_t*)hooks::hkNetChannel->GetMethod(hooks::offCanPacket))(thisptr);
return send_packets && original(_this);
SEGV_END;
return false;
}
CUserCmd* GetUserCmd_hook(IInput* thisptr, int sequence_number) {
CUserCmd* def = ((GetUserCmd_t*)(hooks::hkInput->GetMethod(hooks::offGetUserCmd)))(thisptr, sequence_number);
CUserCmd* GetUserCmd_hook(IInput* _this, int sequence_number) {
static const GetUserCmd_t original = (GetUserCmd_t)hooks::input.GetMethod(offsets::GetUserCmd());
CUserCmd* def = original(_this, sequence_number);
if (def && command_number_mod.find(def->command_number) != command_number_mod.end()) {
logging::Info("Replacing command %i with %i", def->command_number, command_number_mod[def->command_number]);
int oldcmd = def->command_number;
@ -85,12 +80,13 @@ CUserCmd* GetUserCmd_hook(IInput* thisptr, int sequence_number) {
return def;
}
int IN_KeyEvent_hook(void* thisptr, int eventcode, int keynum, const char* pszCurrentBinding) {
int IN_KeyEvent_hook(void* _this, int eventcode, int keynum, const char* pszCurrentBinding) {
static const IN_KeyEvent_t original = (IN_KeyEvent_t)hooks::client.GetMethod(offsets::IN_KeyEvent());
SEGV_BEGIN;
if (g_pGUI->ConsumesKey((ButtonCode_t)keynum) && g_pGUI->Visible()) {
return 0;
}
return ((IN_KeyEvent_t*)hooks::hkClient->GetMethod(hooks::offKeyEvent))(thisptr, eventcode, keynum, pszCurrentBinding);
return original(_this, eventcode, keynum, pszCurrentBinding);
SEGV_END;
return 0;
}
@ -112,7 +108,9 @@ static CatVar newlines_msg(CV_INT, "chat_newlines", "0", "Prefix newlines", "Add
// TODO name \\n = \n
//static CatVar queue_messages(CV_SWITCH, "chat_queue", "0", "Queue messages", "Use this if you want to use spam/killsay and still be able to chat normally (without having your msgs eaten by valve cooldown)");
bool SendNetMsg_hook(void* thisptr, INetMessage& msg, bool bForceReliable = false, bool bVoice = false) {
bool SendNetMsg_hook(void* _this, INetMessage& msg, bool bForceReliable = false, bool bVoice = false) {
// This is a INetChannel hook - it SHOULDN'T be static because netchannel changes.
const SendNetMsg_t original = (SendNetMsg_t)hooks::netchannel.GetMethod(offsets::SendNetMsg());
SEGV_BEGIN;
// net_StringCmd
if (msg.GetType() == 4 && (newlines_msg)) {
@ -128,7 +126,7 @@ bool SendNetMsg_hook(void* thisptr, INetMessage& msg, bool bForceReliable = fals
str = str.substr(16, str.length() - 17);
//if (queue_messages && !chat_stack::CanSend()) {
NET_StringCmd stringcmd(str.c_str());
return ((SendNetMsg_t*)hooks::hkNetChannel->GetMethod(hooks::offSendNetMsg))(thisptr, stringcmd, bForceReliable, bVoice);
return original(_this, stringcmd, bForceReliable, bVoice);
//}
}
}
@ -145,19 +143,21 @@ bool SendNetMsg_hook(void* thisptr, INetMessage& msg, bool bForceReliable = fals
}
logging::Info("%i bytes => %s", buffer.GetNumBytesWritten(), bytes.c_str());
}
return ((SendNetMsg_t*)hooks::hkNetChannel->GetMethod(hooks::offSendNetMsg))(thisptr, msg, bForceReliable, bVoice);
return original(_this, msg, bForceReliable, bVoice);
SEGV_END;
return false;
}
CatVar disconnect_reason(CV_STRING, "disconnect_reason", "", "Disconnect reason", "A custom disconnect reason");
void Shutdown_hook(void* thisptr, const char* reason) {
void Shutdown_hook(void* _this, const char* reason) {
// This is a INetChannel hook - it SHOULDN'T be static because netchannel changes.
const Shutdown_t original = (Shutdown_t)hooks::netchannel.GetMethod(offsets::Shutdown());
SEGV_BEGIN;
if (cathook && (disconnect_reason.convar_parent->m_StringLength > 3) && strstr(reason, "user")) {
((Shutdown_t*)hooks::hkNetChannel->GetMethod(hooks::offShutdown))(thisptr, disconnect_reason.GetString());
original(_this, disconnect_reason.GetString());
} else {
((Shutdown_t*)hooks::hkNetChannel->GetMethod(hooks::offShutdown))(thisptr, reason);
original(_this, reason);
}
SEGV_END;
}
@ -167,13 +167,15 @@ static CatVar glow_alpha(CV_FLOAT, "glow_old_alpha", "1", "Alpha", "Glow Transpa
static CatVar resolver(CV_SWITCH, "resolver", "0", "Resolve angles");
const char* GetFriendPersonaName_hook(ISteamFriends* _this, CSteamID steamID) {
static const GetFriendPersonaName_t original = (GetFriendPersonaName_t)hooks::steamfriends.GetMethod(offsets::GetFriendPersonaName());
if ((force_name.convar->m_StringLength > 2) && steamID == g_ISteamUser->GetSteamID()) {
return force_name.GetString();
}
return ((GetFriendPersonaName_t*)(hooks::hkSteamFriends->GetMethod(hooks::offGetFriendPersonaName)))(_this, steamID);
return original(_this, steamID);
}
void FrameStageNotify_hook(void* thisptr, int stage) {
void FrameStageNotify_hook(void* _this, int stage) {
static const FrameStageNotify_t original = (FrameStageNotify_t)hooks::client.GetMethod(offsets::FrameStageNotify());
SEGV_BEGIN;
if (!g_IEngine->IsInGame()) g_Settings.bInvalid = true;
// TODO hack FSN hook
@ -255,16 +257,17 @@ void FrameStageNotify_hook(void* thisptr, int stage) {
}
}
}
SAFE_CALL(((FrameStageNotify_t*)hooks::hkClient->GetMethod(hooks::offFrameStageNotify))(thisptr, stage));
SAFE_CALL(original(_this, stage));
SEGV_END;
}
CatVar override_fov_zoomed(CV_FLOAT, "fov_zoomed", "0", "FOV override (zoomed)", "Overrides FOV with this value when zoomed in (default FOV when zoomed is 20)");
CatVar override_fov(CV_FLOAT, "fov", "0", "FOV override", "Overrides FOV with this value");
void OverrideView_hook(void* thisptr, CViewSetup* setup) {
void OverrideView_hook(void* _this, CViewSetup* setup) {
static const OverrideView_t original = (OverrideView_t)hooks::clientmode.GetMethod(offsets::OverrideView());
SEGV_BEGIN;
((OverrideView_t*)hooks::hkClientMode->GetMethod(hooks::offOverrideView))(thisptr, setup);
original(_this, setup);
if (!cathook) return;
bool zoomed = g_pLocalPlayer->bZoomed;
if (zoomed && override_fov_zoomed) {
@ -280,7 +283,8 @@ void OverrideView_hook(void* thisptr, CViewSetup* setup) {
static CatVar clean_chat(CV_SWITCH, "clean_chat", "0", "Clean chat", "Removes newlines from chat");
static CatVar dispatch_log(CV_SWITCH, "debug_log_usermessages", "0", "Log dispatched user messages");
bool DispatchUserMessage_hook(void* thisptr, int type, bf_read& buf) {
bool DispatchUserMessage_hook(void* _this, int type, bf_read& buf) {
static const DispatchUserMessage_t original = (DispatchUserMessage_t)hooks::client.GetMethod(offsets::DispatchUserMessage());
SEGV_BEGIN;
if (clean_chat) {
if (type == 4) {
@ -301,31 +305,29 @@ bool DispatchUserMessage_hook(void* thisptr, int type, bf_read& buf) {
if (dispatch_log) {
logging::Info("D> %i", type);
}
//if (type != net_Tick) logging::Info("Got message: %s", type);
return ((DispatchUserMessage_t*)hooks::hkClient->GetMethod(hooks::offFrameStageNotify + 1))(thisptr, type, buf);
SEGV_END; return false;
return original(_this, type, buf);
SEGV_END;
return false;
}
void LevelInit_hook(void* thisptr, const char* newmap) {
void LevelInit_hook(void* _this, const char* newmap) {
static const LevelInit_t original = (LevelInit_t)hooks::clientmode.GetMethod(offsets::LevelInit());
playerlist::Save();
((LevelInit_t*) hooks::hkClientMode->GetMethod(hooks::offLevelInit))(thisptr, newmap);
g_IEngine->ClientCmd_Unrestricted("exec cat_matchexec");
hacks::shared::aimbot::Reset();
// LEVEL_SHUTDOWN(FollowBot);
//if (TF) LEVEL_INIT(SpyAlert);
chat_stack::Reset();
hacks::shared::spam::Reset();
original(_this, newmap);
}
bool CanInspect_hook(IClientEntity*) { return true; }
void LevelShutdown_hook(void* thisptr) {
void LevelShutdown_hook(void* _this) {
static const LevelShutdown_t original = (LevelShutdown_t)hooks::clientmode.GetMethod(offsets::LevelShutdown());
need_name_change = true;
playerlist::Save();
((LevelShutdown_t*) hooks::hkClientMode->GetMethod(hooks::offLevelShutdown))(thisptr);
g_Settings.bInvalid = true;
hacks::shared::aimbot::Reset();
chat_stack::Reset();
hacks::shared::spam::Reset();
original(_this);
}

66
src/offsets.hpp Normal file
View File

@ -0,0 +1,66 @@
/*
* offsets.hpp
*
* Created on: May 4, 2017
* Author: nullifiedcat
*/
#ifndef OFFSETS_HPP_
#define OFFSETS_HPP_
#include <stdint.h>
#include <exception>
enum class platform {
PLATFORM_LINUX,
PLATFORM_WINDOWS,
PLATFORM_OSX,
PLATFORM_UNSUPPORTED
};
#ifdef LINUX
constexpr platform PLATFORM = platform::PLATFORM_LINUX;
#else
constexpr platform PLATFORM = platform::PLATFORM_UNSUPPORTED;
#endif
struct offsets {
static constexpr uint32_t PlatformOffset(uint32_t offset_linux, uint32_t offset_windows, uint32_t offset_osx) {
uint32_t result = -1;
switch (PLATFORM) {
case platform::PLATFORM_LINUX:
result = offset_linux; break;
case platform::PLATFORM_WINDOWS:
result = offset_windows; break;
case platform::PLATFORM_OSX:
result = offset_osx; break;
}
if (result == -1) {
throw std::logic_error("No offset defined for this platform!");
}
return result;
}
static constexpr uint32_t GetUserCmd() { return PlatformOffset(8, -1, -1); }
static constexpr uint32_t ShouldDraw() { return PlatformOffset(136, -1, -1); }
static constexpr uint32_t DrawModelExecute() { return PlatformOffset(19, -1, -1); }
static constexpr uint32_t GetClientName() { return PlatformOffset(44, -1, -1); }
static constexpr uint32_t ProcessSetConVar() { return PlatformOffset(4, -1, -1); }
static constexpr uint32_t ProcessGetCvarValue() { return PlatformOffset(29, -1, -1); }
static constexpr uint32_t GetFriendPersonaName() { return PlatformOffset(7, -1, -1); }
static constexpr uint32_t CreateMove() { return PlatformOffset(22, -1, -1); }
static constexpr uint32_t PaintTraverse() { return PlatformOffset(42, -1, -1); }
static constexpr uint32_t OverrideView() { return PlatformOffset(17, -1, -1); }
static constexpr uint32_t FrameStageNotify() { return PlatformOffset(35, -1, -1); }
static constexpr uint32_t DispatchUserMessage() { return PlatformOffset(36, -1, -1); }
static constexpr uint32_t CanPacket() { return PlatformOffset(57, -1, -1); }
static constexpr uint32_t SendNetMsg() { return PlatformOffset(41, -1, -1); }
static constexpr uint32_t Shutdown() { return PlatformOffset(37, -1, -1); }
static constexpr uint32_t IN_KeyEvent() { return PlatformOffset(20, -1, -1); }
static constexpr uint32_t HandleInputEvent() { return PlatformOffset(78, -1, -1); }
static constexpr uint32_t LevelInit() { return PlatformOffset(23, -1, -1); }
static constexpr uint32_t LevelShutdown() { return PlatformOffset(24, -1, -1); }
static constexpr uint32_t BeginFrame() { return PlatformOffset(5, -1, -1); }
};
#endif /* OFFSETS_HPP_ */