Add main source file and placeholder hooks.

Signed-off-by: aixxe <me@aixxe.net>
This commit is contained in:
aixxe 2016-12-20 20:20:39 +00:00
parent 27eb1e65e2
commit 2f9b1f444d
12 changed files with 304 additions and 0 deletions

11
CMakeLists.txt Normal file
View File

@ -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)

113
src/Basehook.cpp Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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<VMTHook> sdl_hook;
std::unique_ptr<VMTHook> panel_hook;
std::unique_ptr<VMTHook> clientdll_hook;
std::unique_ptr<VMTHook> modelrender_hook;
std::unique_ptr<VMTHook> inputinternal_hook;
extern "C" void __attribute__((constructor)) css_basehook_open() {
// Get class pointers from game libraries using partial interface versions.
cvar = GetInterface<ICvar>("bin/libvstdlib.so", "VEngineCvar0");
panel = GetInterface<IPanel>("bin/vgui2.so", "VGUI_Panel0");
matsurface = GetInterface<ISurface>("bin/vguimatsurface.so", "VGUI_Surface0");
modelinfo = GetInterface<IVModelInfoClient>("bin/engine.so", "VModelInfoClient0");
inputsystem = GetInterface<IInputSystem>("bin/inputsystem.so", "InputSystemVersion0");
inputinternal = GetInterface<IInputInternal>("bin/vgui2.so", "VGUI_InputInternal0");
engine = GetInterface<IVEngineClient>("bin/engine.so", "VEngineClient0");
modelrender = GetInterface<IVModelRender>("bin/engine.so", "VEngineModel0");
debugoverlay = GetInterface<IVDebugOverlay>("bin/engine.so", "VDebugOverlay0");
clientdll = GetInterface<IBaseClientDLL>("bin/client.so", "VClient0");
matsystem = GetInterface<IMaterialSystem>("bin/materialsystem.so", "VMaterialSystem0");
entitylist = GetInterface<IClientEntityList>("bin/client.so", "VClientEntityList0");
gameevents = GetInterface<IGameEventManager2>("bin/engine.so", "GAMEEVENTSMANAGER002");
// Scan for the 'CRC32_ProcessBuffer' function.
CRC32_ProcessBuffer = reinterpret_cast<CRC32_ProcessBufferFn>(
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<VMTHook>(clientdll);
clientdll_hook->HookFunction(reinterpret_cast<void*>(Hooks::CreateMove), 21);
clientdll_hook->HookFunction(reinterpret_cast<void*>(Hooks::FrameStageNotify), 35);
// Hook 'PaintTraverse' from IPanel.
panel_hook = std::make_unique<VMTHook>(panel);
panel_hook->HookFunction(reinterpret_cast<void*>(Hooks::PaintTraverse), 42);
// Hook 'DrawModelExecute' from IVModelRender.
modelrender_hook = std::make_unique<VMTHook>(modelrender);
modelrender_hook->HookFunction(reinterpret_cast<void*>(Hooks::DrawModelExecute), 19);
// Hook 'PumpWindowsMessageLoop' and 'ShowPixels' from ILauncherMgr.
launchermgr = **reinterpret_cast<ILauncherMgr***>(
FindPattern("bin/launcher.so", "\x24\x8B\x1D\x00\x00\x00\x00", "xxx????") + 3
);
sdl_hook = std::make_unique<VMTHook>(launchermgr);
sdl_hook->HookFunction(reinterpret_cast<void*>(Hooks::PumpWindowsMessageLoop), 15);
sdl_hook->HookFunction(reinterpret_cast<void*>(Hooks::ShowPixels), 29);
// Hook 'SetKeyCodeState' and 'SetMouseCodeState' from IInputInternal.
inputinternal_hook = std::make_unique<VMTHook>(inputinternal);
inputinternal_hook->HookFunction(reinterpret_cast<void*>(Hooks::SetKeyCodeState), 83);
inputinternal_hook->HookFunction(reinterpret_cast<void*>(Hooks::SetMouseCodeState), 84);
// Get a pointer to CInput from 'IN_ActivateMouse' in IBaseClientDLL.
input = **reinterpret_cast<CInput***>(
clientdll_hook->GetOriginalFunction<uintptr_t>(14) + 1
);
// Get a pointer to CGlobalVarsBase from 'HUDUpdate' in IBaseClientDLL.
globalvars = **reinterpret_cast<CGlobalVarsBase***>(
clientdll_hook->GetOriginalFunction<uintptr_t>(11) + 8
);
}
extern "C" void __attribute__((destructor)) css_basehook_close() {
cvar->ConsoleColorPrintf(Color(255, 150, 150), "Unloaded from game successfully.\n");
}

14
src/Basehook.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <cstrike/cstrike.h>
#include <vmthook/vmthook.h>
#include "Utilities/Linker.h"
#include "Utilities/FindPattern.h"
#include "Utilities/Interfaces.h"
#include "Utilities/NetVars.h"
extern NetVars netvars;

21
src/Hooks/CreateMove.cpp Normal file
View File

@ -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<CreateMove_t>(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);
}

View File

@ -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<DrawModelExecute_t>(19);
// Call original 'IVModelRender::DrawModelExecute'.
oDrawModelExecute(thisptr, drawmodelstate, modelrenderinfo, bonetoworld);
}

View File

@ -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<FrameStageNotify_t>(35);
// Call original 'IBaseClientDLL::FrameStageNotify'.
oFrameStageNotify(thisptr, stage);
}

29
src/Hooks/Hooks.h Normal file
View File

@ -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<VMTHook> sdl_hook;
extern std::unique_ptr<VMTHook> panel_hook;
extern std::unique_ptr<VMTHook> clientdll_hook;
extern std::unique_ptr<VMTHook> modelrender_hook;
extern std::unique_ptr<VMTHook> inputinternal_hook;

View File

@ -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<PaintTraverse_t>(42);
// Call original 'IPanel::PaintTraverse'.
oPaintTraverse(thisptr, vpanel, force_repaint, allow_force);
}

View File

@ -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<PumpWindowsMessageLoop_t>(15);
// Call original 'ILauncherMgr::PumpWindowsMessageLoop'.
oPumpWindowsMessageLoop(thisptr);
}

View File

@ -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<SetKeyCodeState_t>(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);
}

View File

@ -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<SetMouseCodeState_t>(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);
}

44
src/Hooks/ShowPixels.cpp Normal file
View File

@ -0,0 +1,44 @@
#include "Hooks.h"
#include <imgui/imgui.h>
#include <imgui/imgui_impl_sdl.h>
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<ShowPixels_t>(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<SDL_Window*>(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);
}