From 2f9b1f444d032fc06790208d114ffe6967695b0a Mon Sep 17 00:00:00 2001 From: aixxe Date: Tue, 20 Dec 2016 20:20:39 +0000 Subject: [PATCH] Add main source file and placeholder hooks. Signed-off-by: aixxe --- CMakeLists.txt | 11 +++ src/Basehook.cpp | 113 +++++++++++++++++++++++++++ src/Basehook.h | 14 ++++ src/Hooks/CreateMove.cpp | 21 +++++ src/Hooks/DrawModelExecute.cpp | 11 +++ src/Hooks/FrameStageNotify.cpp | 11 +++ src/Hooks/Hooks.h | 29 +++++++ src/Hooks/PaintTraverse.cpp | 11 +++ src/Hooks/PumpWindowsMessageLoop.cpp | 11 +++ src/Hooks/SetKeyCodeState.cpp | 14 ++++ src/Hooks/SetMouseCodeState.cpp | 14 ++++ src/Hooks/ShowPixels.cpp | 44 +++++++++++ 12 files changed, 304 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 src/Basehook.cpp create mode 100644 src/Basehook.h create mode 100644 src/Hooks/CreateMove.cpp create mode 100644 src/Hooks/DrawModelExecute.cpp create mode 100644 src/Hooks/FrameStageNotify.cpp create mode 100644 src/Hooks/Hooks.h create mode 100644 src/Hooks/PaintTraverse.cpp create mode 100644 src/Hooks/PumpWindowsMessageLoop.cpp create mode 100644 src/Hooks/SetKeyCodeState.cpp create mode 100644 src/Hooks/SetMouseCodeState.cpp create mode 100644 src/Hooks/ShowPixels.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c9ca975 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 2.8) +project(cstrike-basehook) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++14 -I./include -m32 -Wall -Wextra -Wpedantic") +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++ -m32 -lSDL2") + +file(GLOB_RECURSE SOURCE_FILES src/*.cpp include/*.cpp) + +add_library(cstrike-basehook SHARED ${SOURCE_FILES}) + +target_link_libraries(cstrike-basehook) diff --git a/src/Basehook.cpp b/src/Basehook.cpp new file mode 100644 index 0000000..d5b7628 --- /dev/null +++ b/src/Basehook.cpp @@ -0,0 +1,113 @@ +/* + + cstrike-basehook-linux -- Internal base for Counter-Strike: Source. + Copyright (C) 2016, aixxe. (www.aixxe.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cstrike-basehook-linux. If not, see . + +*/ + +#include "Basehook.h" +#include "Hooks/Hooks.h" + +ICvar* cvar = nullptr; +IPanel* panel = nullptr; +ISurface* matsurface = nullptr; +IVModelInfoClient* modelinfo = nullptr; +ILauncherMgr* launchermgr = nullptr; +IInputSystem* inputsystem = nullptr; +IInputInternal* inputinternal = nullptr; +IVEngineClient* engine = nullptr; +IVModelRender* modelrender = nullptr; +IVDebugOverlay* debugoverlay = nullptr; +IBaseClientDLL* clientdll = nullptr; +IMaterialSystem* matsystem = nullptr; +IClientEntityList* entitylist = nullptr; +IGameEventManager2* gameevents = nullptr; + +CInput* input = nullptr; +CGlobalVarsBase* globalvars = nullptr; + +CRC32_ProcessBufferFn CRC32_ProcessBuffer = NULL; + +NetVars netvars; + +std::unique_ptr sdl_hook; +std::unique_ptr panel_hook; +std::unique_ptr clientdll_hook; +std::unique_ptr modelrender_hook; +std::unique_ptr inputinternal_hook; + +extern "C" void __attribute__((constructor)) css_basehook_open() { + // Get class pointers from game libraries using partial interface versions. + cvar = GetInterface("bin/libvstdlib.so", "VEngineCvar0"); + panel = GetInterface("bin/vgui2.so", "VGUI_Panel0"); + matsurface = GetInterface("bin/vguimatsurface.so", "VGUI_Surface0"); + modelinfo = GetInterface("bin/engine.so", "VModelInfoClient0"); + inputsystem = GetInterface("bin/inputsystem.so", "InputSystemVersion0"); + inputinternal = GetInterface("bin/vgui2.so", "VGUI_InputInternal0"); + engine = GetInterface("bin/engine.so", "VEngineClient0"); + modelrender = GetInterface("bin/engine.so", "VEngineModel0"); + debugoverlay = GetInterface("bin/engine.so", "VDebugOverlay0"); + clientdll = GetInterface("bin/client.so", "VClient0"); + matsystem = GetInterface("bin/materialsystem.so", "VMaterialSystem0"); + entitylist = GetInterface("bin/client.so", "VClientEntityList0"); + gameevents = GetInterface("bin/engine.so", "GAMEEVENTSMANAGER002"); + + // Scan for the 'CRC32_ProcessBuffer' function. + CRC32_ProcessBuffer = reinterpret_cast( + FindPattern("bin/client.so", "\x55\x89\xE5\x57\x56\x53\x83\xEC\x08\x8B\x4D\x10", "xxxxxxxxxxxx") + ); + + // Hook 'FrameStageNotify' and 'CreateMove' from IBaseClientDLL. + clientdll_hook = std::make_unique(clientdll); + clientdll_hook->HookFunction(reinterpret_cast(Hooks::CreateMove), 21); + clientdll_hook->HookFunction(reinterpret_cast(Hooks::FrameStageNotify), 35); + + // Hook 'PaintTraverse' from IPanel. + panel_hook = std::make_unique(panel); + panel_hook->HookFunction(reinterpret_cast(Hooks::PaintTraverse), 42); + + // Hook 'DrawModelExecute' from IVModelRender. + modelrender_hook = std::make_unique(modelrender); + modelrender_hook->HookFunction(reinterpret_cast(Hooks::DrawModelExecute), 19); + + // Hook 'PumpWindowsMessageLoop' and 'ShowPixels' from ILauncherMgr. + launchermgr = **reinterpret_cast( + FindPattern("bin/launcher.so", "\x24\x8B\x1D\x00\x00\x00\x00", "xxx????") + 3 + ); + + sdl_hook = std::make_unique(launchermgr); + sdl_hook->HookFunction(reinterpret_cast(Hooks::PumpWindowsMessageLoop), 15); + sdl_hook->HookFunction(reinterpret_cast(Hooks::ShowPixels), 29); + + // Hook 'SetKeyCodeState' and 'SetMouseCodeState' from IInputInternal. + inputinternal_hook = std::make_unique(inputinternal); + inputinternal_hook->HookFunction(reinterpret_cast(Hooks::SetKeyCodeState), 83); + inputinternal_hook->HookFunction(reinterpret_cast(Hooks::SetMouseCodeState), 84); + + // Get a pointer to CInput from 'IN_ActivateMouse' in IBaseClientDLL. + input = **reinterpret_cast( + clientdll_hook->GetOriginalFunction(14) + 1 + ); + + // Get a pointer to CGlobalVarsBase from 'HUDUpdate' in IBaseClientDLL. + globalvars = **reinterpret_cast( + clientdll_hook->GetOriginalFunction(11) + 8 + ); +} + +extern "C" void __attribute__((destructor)) css_basehook_close() { + cvar->ConsoleColorPrintf(Color(255, 150, 150), "Unloaded from game successfully.\n"); +} \ No newline at end of file diff --git a/src/Basehook.h b/src/Basehook.h new file mode 100644 index 0000000..1a8aa8a --- /dev/null +++ b/src/Basehook.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +#include +#include + +#include "Utilities/Linker.h" +#include "Utilities/FindPattern.h" +#include "Utilities/Interfaces.h" +#include "Utilities/NetVars.h" + +extern NetVars netvars; \ No newline at end of file diff --git a/src/Hooks/CreateMove.cpp b/src/Hooks/CreateMove.cpp new file mode 100644 index 0000000..1ba6d2c --- /dev/null +++ b/src/Hooks/CreateMove.cpp @@ -0,0 +1,21 @@ +#include "Hooks.h" + +typedef void (*CreateMove_t) (IBaseClientDLL*, int, float, bool); + +void Hooks::CreateMove(IBaseClientDLL* thisptr, int sequence, float frametime, bool active) { + // Get the original function and store it statically. + static CreateMove_t oCreateMove = clientdll_hook->GetOriginalFunction(21); + + // Call original 'IBaseClientDLL::CreateMove'. + oCreateMove(thisptr, sequence, frametime, active); + + // Get the current user command. + CUserCmd* cmd = input->GetUserCmd(sequence); + + if (cmd->buttons & IN_JUMP) { + cmd->buttons |= IN_ATTACK; + } + + // Re-calculate the command checksum after making changes. + input->VerifyUserCmd(cmd, sequence); +} \ No newline at end of file diff --git a/src/Hooks/DrawModelExecute.cpp b/src/Hooks/DrawModelExecute.cpp new file mode 100644 index 0000000..6ee884d --- /dev/null +++ b/src/Hooks/DrawModelExecute.cpp @@ -0,0 +1,11 @@ +#include "Hooks.h" + +typedef void (*DrawModelExecute_t) (IVModelRender*, DrawModelState_t const&, ModelRenderInfo_t const&, matrix3x4_t*); + +void Hooks::DrawModelExecute(IVModelRender* thisptr, DrawModelState_t const& drawmodelstate, ModelRenderInfo_t const& modelrenderinfo, matrix3x4_t* bonetoworld) { + // Get the original function and store it statically. + static DrawModelExecute_t oDrawModelExecute = modelrender_hook->GetOriginalFunction(19); + + // Call original 'IVModelRender::DrawModelExecute'. + oDrawModelExecute(thisptr, drawmodelstate, modelrenderinfo, bonetoworld); +} \ No newline at end of file diff --git a/src/Hooks/FrameStageNotify.cpp b/src/Hooks/FrameStageNotify.cpp new file mode 100644 index 0000000..d20aa00 --- /dev/null +++ b/src/Hooks/FrameStageNotify.cpp @@ -0,0 +1,11 @@ +#include "Hooks.h" + +typedef void (*FrameStageNotify_t) (IBaseClientDLL*, ClientFrameStage_t); + +void Hooks::FrameStageNotify(IBaseClientDLL* thisptr, ClientFrameStage_t stage) { + // Get the original function and store it statically. + static FrameStageNotify_t oFrameStageNotify = clientdll_hook->GetOriginalFunction(35); + + // Call original 'IBaseClientDLL::FrameStageNotify'. + oFrameStageNotify(thisptr, stage); +} \ No newline at end of file diff --git a/src/Hooks/Hooks.h b/src/Hooks/Hooks.h new file mode 100644 index 0000000..dc7ebbc --- /dev/null +++ b/src/Hooks/Hooks.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../Basehook.h" + +namespace Hooks { + // IBaseClientDLL + void CreateMove(IBaseClientDLL*, int, float, bool); + void FrameStageNotify(IBaseClientDLL*, ClientFrameStage_t); + + // IPanel + void PaintTraverse(IPanel*, VPANEL, bool, bool); + + // IVModelRender + void DrawModelExecute(IVModelRender*, DrawModelState_t const&, ModelRenderInfo_t const&, matrix3x4_t*); + + // ILauncherMgr + void PumpWindowsMessageLoop(ILauncherMgr*); + void ShowPixels(ILauncherMgr*, CShowPixelsParams*); + + // IInputInternal + void SetKeyCodeState(IInputInternal*, KeyCode, bool); + void SetMouseCodeState(IInputInternal*, MouseCode, MouseCodeState_t); +} + +extern std::unique_ptr sdl_hook; +extern std::unique_ptr panel_hook; +extern std::unique_ptr clientdll_hook; +extern std::unique_ptr modelrender_hook; +extern std::unique_ptr inputinternal_hook; \ No newline at end of file diff --git a/src/Hooks/PaintTraverse.cpp b/src/Hooks/PaintTraverse.cpp new file mode 100644 index 0000000..9eca49a --- /dev/null +++ b/src/Hooks/PaintTraverse.cpp @@ -0,0 +1,11 @@ +#include "Hooks.h" + +typedef void (*PaintTraverse_t) (IPanel*, VPANEL, bool, bool); + +void Hooks::PaintTraverse(IPanel* thisptr, VPANEL vpanel, bool force_repaint, bool allow_force) { + // Get the original function and store it statically. + static PaintTraverse_t oPaintTraverse = panel_hook->GetOriginalFunction(42); + + // Call original 'IPanel::PaintTraverse'. + oPaintTraverse(thisptr, vpanel, force_repaint, allow_force); +} \ No newline at end of file diff --git a/src/Hooks/PumpWindowsMessageLoop.cpp b/src/Hooks/PumpWindowsMessageLoop.cpp new file mode 100644 index 0000000..ad723aa --- /dev/null +++ b/src/Hooks/PumpWindowsMessageLoop.cpp @@ -0,0 +1,11 @@ +#include "Hooks.h" + +typedef void (*PumpWindowsMessageLoop_t) (ILauncherMgr*); + +void Hooks::PumpWindowsMessageLoop(ILauncherMgr* thisptr) { + // Get the original function and store it statically. + static PumpWindowsMessageLoop_t oPumpWindowsMessageLoop = sdl_hook->GetOriginalFunction(15); + + // Call original 'ILauncherMgr::PumpWindowsMessageLoop'. + oPumpWindowsMessageLoop(thisptr); +} \ No newline at end of file diff --git a/src/Hooks/SetKeyCodeState.cpp b/src/Hooks/SetKeyCodeState.cpp new file mode 100644 index 0000000..0b32be3 --- /dev/null +++ b/src/Hooks/SetKeyCodeState.cpp @@ -0,0 +1,14 @@ +#include "Hooks.h" + +typedef void (*SetKeyCodeState_t) (IInputInternal*, KeyCode, bool); + +void Hooks::SetKeyCodeState(IInputInternal* thisptr, KeyCode code, bool pressed) { + // Get the original function and store it statically. + static SetKeyCodeState_t oSetKeyCodeState = inputinternal_hook->GetOriginalFunction(83); + + // Print to console every time a key is pressed or released. + cvar->ConsoleColorPrintf(Color(150, 150, 255, 255), "IInputInternal::SetKeyCodeState - code: %i, pressed: %i\n", code, pressed); + + // Call original 'IInputInternal::SetKeyCodeState'. + oSetKeyCodeState(thisptr, code, pressed); +} \ No newline at end of file diff --git a/src/Hooks/SetMouseCodeState.cpp b/src/Hooks/SetMouseCodeState.cpp new file mode 100644 index 0000000..bc2db9e --- /dev/null +++ b/src/Hooks/SetMouseCodeState.cpp @@ -0,0 +1,14 @@ +#include "Hooks.h" + +typedef void (*SetMouseCodeState_t) (IInputInternal*, MouseCode, MouseCodeState_t); + +void Hooks::SetMouseCodeState(IInputInternal* thisptr, MouseCode code, MouseCodeState_t state) { + // Get the original function and store it statically. + static SetMouseCodeState_t oSetMouseCodeState = inputinternal_hook->GetOriginalFunction(84); + + // Print to console every time a mouse button is clicked, double-clicked or released. + cvar->ConsoleColorPrintf(Color(150, 150, 255, 255), "IInputInternal::SetMouseCodeState - code: %i, state: %i\n", code, state); + + // Call original 'IInputInternal::SetMouseCodeState'. + oSetMouseCodeState(thisptr, code, state); +} \ No newline at end of file diff --git a/src/Hooks/ShowPixels.cpp b/src/Hooks/ShowPixels.cpp new file mode 100644 index 0000000..f73042e --- /dev/null +++ b/src/Hooks/ShowPixels.cpp @@ -0,0 +1,44 @@ +#include "Hooks.h" + +#include +#include + +typedef void (*ShowPixels_t) (ILauncherMgr*, CShowPixelsParams*); + +void Hooks::ShowPixels(ILauncherMgr* thisptr, CShowPixelsParams* params) { + // Get the original function and store it statically. + static ShowPixels_t oShowPixels = sdl_hook->GetOriginalFunction(29); + + if (!params->m_noBlit) + return oShowPixels(thisptr, params); + + // Also store the game window, original and user contexts statically. + static SDL_Window* window = reinterpret_cast(launchermgr->GetWindowRef()); + + static PseudoGLContextPtr original_context = launchermgr->GetMainContext(); + static PseudoGLContextPtr user_context = nullptr; + + // Set up our context on first execution. + if (!user_context) { + user_context = launchermgr->CreateExtraContext(); + ImGui_ImplSdl_Init(window); + } + + // Switch to our context. + launchermgr->MakeContextCurrent(user_context); + + // Start ImGui rendering. + ImGui_ImplSdl_NewFrame(window); + + // Draw some test stuff. + ImGui::Text("Hello, world!"); + + // Finish ImGui rendering. + ImGui::Render(); + + // Switch back to the game context. + launchermgr->MakeContextCurrent(original_context); + + // Call original 'ILauncherMgr::ShowPixels'. + oShowPixels(thisptr, params); +} \ No newline at end of file