This post has been superseded by “Hacking Videogames For Fun

Introduction

I wanted to learn C++, how computers work and reverse engineering. What comes to mind when combining these skills? For me the first thing that came to mind was game hacking. So where do I begin? I don’t know, but looking into it, LiveOverflow came into mind with his pwnadventure. From one of the episodes we were introduced to guided hacking. I then looked into it and found their playlist Start Here Beginner’s Guide to Game Hacking. So I started watching.

Before Guided Hacking even started showing how games are hacked he introduced us to how computers worked. I have previous experience in this topic from both university and my own research. Guided Hacking started with an introduction in how a computers memory works and how important the memory is for everything a computer does. Next he gives an introduction to different way games are cheated. Memory editing (editing values in memory), Assembly editing (rewrite the game’s code), hex editing (edit save-files and other on-disk resources) and packet editing (send modified information to the servers).

Hacking process

Find thing to exploit/hack -> Try to exploit/hack -> See if it worked

After looking trough his introduction on how to hack games I needed to learn C++. Off to learncpp.com I go! I have prior experience to programming before from python, java, assembly, bash, lua etc. learning basic C++ didn’t take long, but how C++ handled memory and pointers was new to me. And the windows.h header was another beast to tame. I headed off to my first challenge. I figured that making a cheat for Counter-Strike: Global Offensive was a good place to start since CS:GO is a game that has been done to death when it comes to making game cheats.

What are offsets?

Before attempting making a cheat for CS:GO I tried making one for a game called The Legend of Zelda: The Wind Waker. The game was emulated using the Dolphin Emulator. I found the address rupies in the game by using cheat engine scanning memory. Much like how I used to cheat in flash games in browsers as a kid. I successfully was able to create infinite rupies for the game writing this script:

#include <iostream>
#include <Windows.h>

int maxCash = 5000;
int addressCash = 0x803B4C0C; //address for rupies

int main()
{
  HWND hwnd = FindWindowA(NULL, "Dolphin 5.0 | JIT64 DC | Direct3D 12 (experimental) | HLE | FPS: 30 - VPS: 60 - 100%");
  if (hwnd == NULL)
  {
    std::cout << "Cannot find window!" << std::endl;
    Sleep(2000);
    exit(-1);
  }
  else
  {
    DWORD procID;
    GetWindowThreadProcessId(hwnd, &procID);
    HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
    if (procID == NULL)
    {
      std::cout << "Cannot obtain process ID!" << std::endl;
      Sleep(2000);
      exit(-1);
    }
    else
    {
      while (true)
      {
        WriteProcessMemory(handle, (LPVOID)ad_Cash, &maxCash, sizeof(maxCash), 0);
        Sleep(1000);
      }
    }
  }
  return 0;
}

Issue using this is that I’m using the address in memory where the rupies are stored. This address will be different every time I reboot the game. I need a way to find the address(es) where the rupies are stored from wherever in memory it is… Another issue is that for the rupies value to change it also needs an update of some sort e.g., spending or getting a rupie. So how do we solve our first issue? Entering offsets and pointers! We can find the rupies address from the games base address e.g., game.exe+0x3ACA0 where 0x3ACA0 would be the offset.

Playing with cheat engine

A year went by with me not doing anything related to this. I was very buzzy with school and was having a hard time doing extra courses. I’m not a very good student and will mostly focus on what interest me at the time. Anyways this section is dedicated to me learning about cheat engine. I believe many of us remember doing simple hacks for flash games getting unlimited X or doing Y.

At the time of writing this I have successfully made some cheats for CS:GO and I’m a little bit more familiar with how everything works. I can see why CS:GO has been cheated to death since it’s so easy to do! The VAC anticheat is also a joke according to the guided hacking forums. I haven’t learned about anticheats or how they are defeated yet, so to me they don’t exists.

Cheat engine is actually mega powerfull and is a huge part of game hacking. I really suggest learning how to use it and it has a fun tutorial

(you will find the tutorial in Help -> Cheat Engine Tutorial *).

CheatEngineTutorialExampleImg

Ok cool! Now we know a little about cheat engine, now how do we get these magic offsets? Easy! We just apply what we learned from the tutorial and then follow GuidedHackings guide on how to find offsets. The TL;DR of it tho is that you wanna find pointers to what you wanna find because everything is created dynamically. What we then need is a static address which will always be relative to a module e.g., client.exe + 0xD882BC will lead you to your player structure which contains your player vars. We can find these static addresses by using cheat engine searching for pointers. I’m not gonna go deep in on how to find these as the video in the link above is gonna explain this a lot better than I can ever type.

Writing CS:GO hacks!

So here we are. Lets make some cheats! First we get our offsets. At this point I wanted to write so code badly! I got all the offsets using a tool called hazedumper. I also picked up some headers from guidedhacking called MemMan which I picked up from their website somewhere. MemMan is very nice because it simplify the WriteProcessMemory();, ReadProcessMemory(); and the process of getting handles. e.g., instead of: WriteProcessMemory(handle, (LPVOID)ad_Cash, &maxCash, sizeof(maxCash), 0); I can simply do MemMan.writeMem(address, maxCash);

First I wanted to write a bunny hop script. To make this script, we first need to get a handle to the process. It’s nice to store all these vales in a class or a struct since these values will be used over and over. We also need a need to get the right module. Using MemMan we can get the process like this:

#include <iostream>
#include <Windows.h>
#include "MemMan.h"

MemMan memClass;

struct vars
{
  uintptr_t process;
  uintptr_t gameModule;
}vars;

int main()
{
  vars.process = memClass.getProcess(L"csgo.exe");
  vars.gameModule = memClass.getModule(vars.process, L"client.dll");
  return 0;
}

Now lets make our bunny hop script. First we need the offset to our player structure, the relative offset from out player structure to see what state our player is in (if in the air, on the ground, in water etc.) and we need a way to force a jump. I got all my offsets from hazedumper and will be using those and also save them in a struct for easy access.

struct gameOffsets
{
  uintptr_t lPlayer = 0xD882BC; // offset to player structure
  uintptr_t fJump = 0x5249B34; // offset from client to address storing jump value
  uintptr_t flags = 0x104; // offset from player structure to what state we are in.
}offsets;

struct vars // the saved variables from the offsets
{
  uintptr_t process;
  uintptr_t gameModule;
  BYTE flag;
}vars;

void bunnyHop()
{
  vars.flag = memClass.readMem<BYTE>(vars.localPlayer + offsets.flags);
  if (GetAsyncKeyState(VK_SPACE) && vars.flag & (1 << 0))
  {
    memClass.writeMem<uintptr_t>(vars.gameModule + offsets.fJump, 6);
    Sleep(1);
  }
}

int main()
{
  vars.process = memClass.getProcess(L"csgo.exe");
  vars.gameModule = memClass.getModule(vars.process, L"client.dll");

  while (true)
  {
    bunnyHop();
  }
  return 0;
}

We now have a basic bunny hop script working! We also needs to know what’s going on or else it is just copy-pasted code. When I first wrote this, I was confused about (1 << 0) in flags and why we wrote 6 into fjump… The gist of it is that (1 << 0) means that we are standing on the ground and we are writing 6 in to memory since that will do a jump and reset it back to 4. Why 4? Because 4 i believe is the “base” state and by 5 is spacebar down. In cheat engine, you will see that if you type +jump in the cs:go console you will jump and the address will be set to 5. If you try to jump again after, you can’t since it needs a -jump before you can jump again. Writing 6 into it, forces a jump and resets it back to 4.

I have made some others cheats for the game like a radar-hack, triggerbot, wallhack etc. It’s kinda funny to see how easy and effective these cheats are. For instance the radar hack just loops trough the entities in the game and sets a bool that they are indeed spotted to true. The wallhack I belive isn’t a true wallhack since it uses an in-game “glow” to work.

glowHack

You might be wondering why this is in the game, but it’s actually very useful. In the game as it stands now, it is used to see players trough walls when you are a spectator, like when you are watching a game or when you are dead. I belive a true wallhack would be able to draw the entities for any game. This “glow” is true only to games with a glow function like cs:go. I don’t think this way of doing it is necessarily bad since this idea can apply to many games. Instead of using glow-effects, you can maybe force nameplates to render trough walls etc.

Applying knowledge elsewhere

So for now I have mostly walked in others footsteps. To force myself not to copy code, I decided that I wanted to do another game based on another engine. I decided that I wanted to try to make some cheats for a game called Satisfactory. It’s a game where you are supposed to build factories and make them as efficient as possible.

So what do I wanna hack for this game? The things I wanna be able to do are: god-mode, fly, teleport to begin with. So, for god-mode the first thing I needed was to figure out how I take damage to begin with. Health must be a decent place to start looking. To find the health address I started jumping off cliffs until I found my health address. I knew it was correct since changing it from 30 -> 50 worked.

Health

Jumping off the cliff again while seeing what accesses this address yielded interesting results.

AccessHealth

Viewing these addresses in the disassembler reveals a very fun function.

DisAsmDamage

I tried to replace the function with a bunch of NOPs, this yielded very funny results. Now I no longer took any damage from any sources. Nice! Job done? Not quite. Funny thing is that all damage in the game uses that function… I need to figure out a way to check if it’s me that is taking damage. Looking at the function the first argument it takes is AActor damagedActor. Ok, need to check this argument. Looking at msdn for x64 calling convention, we see that the first argument gets put in the RCX registry.

I put a breakpoint on this function and jumped off the cliff again. breakpointDamagePlayer

Great, now I have some value for the player. I tried to jump a few more times to see if the values looked correct, and I noticed something weird. On one of the jumps I died and the health address was no longer valid. The RCX value also changed. At this point I have no idea what’s going on as this is completely new. Anyways, I also wanted to test for the animals in the game. This was the closest thing…

magesticBeast

Nothing weird going down there. breakpointDamageBeast

Registry values for the tests: DmgFuncRegs

Well so what now? Nothing really. I tried looking into it and looked unreal engine up on GuidedHacking forums. I found a guide on how to hack unreal engine and was warned. Direct quote: Unreal Engine is Object Oriented Programming on steroids. Reversing it without understanding how the engine works will give you brain damage. I do not recommend anyone tries to hack UE games unless they are experienced hackers. You can use native methods to hack Unreal Engine games but we don't recommend it. The best method to hack these games is to dump an SDK using the Feckless SDK generator. Well I don’t know much about dumping SDKs or how to use them. I only know the conventional methods I have been thought, so I’m thinking about changing game. You are almost caught up to speed on where I stand. This article doesn’t give the full picture as I suck at writing and probably missed some parts… But I don’t really care. I wrote this for me.

Purpose

There isn’t really any purpose behind this post. You can view it as a tour, guide, experience, diary, whatever. But it is more for my own learning. I also wanted to have my work documented since undocumented work sucks. Much of the reason why I did writeups.

Credits!

I would like to thank GuidedHacking for teaching game hacking. I believe that this is the greatest source for learning game hacking. You should keep in mind if you ever decide to learn, guidedhacking will guide you, but won’t hold your hand.

Second I would like to thank Ferib for answering pretty much any of my questions on demand. If you are interested in reverse engineering and it’s applications, you can check out his blog.