[GUIDE]Hooking the source engine.

Researching, Proof of Concepts, Hacking, Console Modding and Hacking and more. No game hacking / modding here.
Post Reply
TeamRetox
Allie
Allie
Posts: 222
Joined: Sat Jun 06, 2009 3:48 pm

[GUIDE]Hooking the source engine.

Post by TeamRetox »

Hai guys, I'll be teaching you how to make a source engine hook(CS: Source, National Bloodsports, Hidden: Source)
The game I'll be using for this tutorial is Hidden: Source
The same can be applied to the orange box, altho orange box games have some extra protections on stuff like CUserCMD.

Installing the Source SDK
Go to the Tools tab in steam and right click -> install 'Source SDK' if you don't already have it.

Installing the code
Launch the source SDK and make sure you've set up the engine version matches the game you're going to code for.
Now that you've set up the correct engine version click 'Create a Mod' and click 'Source code only'.
Install it into an empty folder so it is easily accesible.
After it's finished copying you can close the SDK.
Finally open up the Game_HL2-2005.sln in Visual Studio 2005.

Setting up the project
Since we'll be coding for the client only, we won't need the server part of the SDK, so delete the server folder from the project.
We won't be using the .cpp files either since we will write our own, so remove all of them from the project(Yes, I know its alot of work :P)
Open up the project's settings, go to the Custom Build Steps under the submenu Configuration Properties and clear out the 3 properties.
Don't close the settings just yet, first go to the Linker tab and replace output dir with $(OutDir)/MyLeetVIPHax.dll.
Under the C/C++ submenu, turn off precompiled headers.

Note: You can delete the headers from the project aslong as you make sure they aren't removed from your harddrive. I removed these to make things easier to manage.

Lets get started!
Create main.cpp and SDK.h.
SDK.h will contain all the header's we're going to use, main.cpp will the file where we do our hooking.
Open up SDK.h and add the following code:

Code: Select all

#pragma once
#include <windows.h>
And open up main.cpp and add the following:

Code: Select all

#include "SDK.h"

void MainThread(void)
{
	HMODULE hClient = NULL;
	// Wait for the process to load its client.dll, which we'll use for fun.
	while(hClient == NULL)
	{
		hClient = GetModuleHandle("client.dll");
		Sleep(100);
	}
}

BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
{
	if( dwReason == DLL_PROCESS_ATTACH )
	{
		CreateThread( NULL, NULL, (LPTHREAD_START_ROUTINE)MainThread, NULL, NULL, NULL);
	}
	return TRUE;
}
Now this in itself doesn't do a whole lot, besides waiting for your target to load up client.dll.

Doing some usefull stuff
Since the above doesn't do a whole lot of usefull stuff, lets do something usefull like writing to the game's console =D

Normally if you would do this from scratch you'd have to open up your target game and search for console related strings.
You'd find a CreateInterface call in 'gameui.dll' with a "GameConsole003", which is the interface version the game is requesting.
The CreateInterface call returns a pointer to a class, and if you check out that pointer you'll see a vtable with 7 functions.
By watching calls you can then figure out which does what, and by looking at the disassembly you could see how many arguments the function takes etc.

Now, here's the console class(create a new file called IGameConsole.h):

Code: Select all

#pragma once
class IGameConsole : public IBaseInterface
{
public:
    virtual void Show() = 0;
    virtual void Init() = 0;
    virtual void Hide() = 0;
    virtual void Clear() = 0;
    virtual bool IsShown() = 0;

    // ???
    virtual void UnknownA() = 0;
    virtual void UnknownB() = 0;
};

#define GAMECONSOLE_INTERFACE_VERSION "GameConsole003"
The class IGameConsole is an extention of IBaseInterface, which is located in interface.h

Now, we haven't hooked the console yet, we'll need the following code to do that.
Place this at the top:

Code: Select all

IGameConsole *g_pIGameConsole=NULL;
And place this in MainThread:

Code: Select all

	CreateInterfaceFn ConCreateInterface = (CreateInterfaceFn)GetProcAddress(GetModuleHandle("gameui.dll"), "CreateInterface");
	g_pIGameConsole = (IGameConsole *)ConCreateInterface(GAMECONSOLE_INTERFACE_VERSION, NULL);
	if (g_pIGameConsole == NULL) return;
	if (g_pIGameConsole->IsConsoleShown() == false)
	{
		g_pIGameConsole->Show();
		ConMsg(0, "Our hook has been loaded :D\n");
	}
To use CreateInterface we'll have to include interface.h and to use our console class, we'll have to include IGameConsole.h.
We'll also need to include tier0/dbg.h, because we used ConMsg.

Here's the new SDK.h

Code: Select all

#pragma once

#include <windows.h>
#include "tier0/dbg.h"
#undef CreateThread
#include "interface.h"

#include "IGameConsole.h"
Notice the #undef CreateThread? We'll need to do that because tier0/dbg.h makes some weird defines that conflict with what we want to do ;(

That will be it for now(tired), I'll write up some stuff about hooking CInput and using CUserCMD for fun stuff like spinbots :)
Post Reply