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>
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;
}
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"
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;
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");
}
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"
That will be it for now(tired), I'll write up some stuff about hooking CInput and using CUserCMD for fun stuff like spinbots :)