Merge pull request #97 from nullifiedcat/minor-changes
multiplatform offset support + faster hooks
This commit is contained in:
commit
c43e3dfb5d
@ -27,6 +27,7 @@
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
#include "aftercheaders.h"
|
||||
#include "offsets.hpp"
|
||||
#include "drawing.h"
|
||||
#include "resource.hpp"
|
||||
#include "entitycache.h"
|
||||
|
82
src/hack.cpp
82
src/hack.cpp
@ -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...");
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
114
src/hooks.cpp
114
src/hooks.cpp
@ -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 {};
|
||||
|
||||
}
|
||||
|
88
src/hooks.h
88
src/hooks.h
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
66
src/offsets.hpp
Normal 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_ */
|
Reference in New Issue
Block a user