Introduction
In this post, I will try something different, both as a way of writing the posts and also today’s post is not so much about what we do during this post as to what we learn from it and opening up new ways of thinking.
New Tool
First off, I want to mention that for some time (some might have noticed) I tried different ways of introducing code snippets due to WordPress’s oh so intuitive way of handling code sections. Well, this week I found an interesting tool which I didn’t even know I had already installed, and that is Xamarin Workbooks.
Basically, the selling point (it’s free) for using this tool is the ability to create documentation that also contains runnable code snippets, in that sense, it’s quite good at experimenting and prototyping (even though I still prefer LinqPad as my experimenting and prototyping platform) as well as having sections of documentation around the code for your team to read and play with (yey, no more copy-paste examples in test solutions to prove it).
So from this point of view, I personally think it’s a great addition to any teams' arsenal, especially when it’s about coding standards or API documentation.
The second point which is why I’m using it, is that the files are saved as a Markdown file with a special header, so for me, this is a major bonus for bloggers since you can type in your content and explanations and still have the code embedded, especially for testing a particular code snippet before releasing it in front of the whole world. On this thought, though I have to mention that it doesn’t support everything Markdown has to offer (like tables) but maybe in the future, who knows. At any rate after saving your workbook, you can then open it in your favorite text editor and copy and paste everything below the custom header and do the necessary tweaks for your content (hey, at least it gets most of the job done, right? :D).
And now back to our usual program.
CAUTION: I DO NOT ENDORSE CHEATING OR HACKING OF ANYONE’s SOFTWARE TO DO HARM OR FOR PERSONAL GAIN, THIS IS JUST A LEARNING EXERCISE. PLEASE USE THIS KNOWLEDGE ONLY TO IMPROVE YOURSELF AND YOUR UNDERSTANDING OF HOW SYSTEMS WORK.
Games as a Service?
In this topic, I wanted to share my findings with you. If you ever played a game, maybe you have encountered the term of trainer which is a small program that you launch alongside the game it was designed for then starts cheating in the game, but how do they do it?
In comes CheatEngine.
What is CheatEngine?
Word of warning beforehand, Cheat Engine requires some basic understanding of low-level implementations in software like the sizes of integers and floats, but also of what pointers are and what they do.
CheatEngine is a tool that does just as the name implies, it helps people cheat, but it does it by connecting to a running process and finding out (through trial and error) which variables hold the values you are looking for, be it gold, health, mana or whatever else is part of the game. A small disclaimer here is if you download it from the official site, due to some optional add-ware present in the installer, your anti-virus/malware will catch it then quarantine or delete it, though if you make an exception for it and run the installer, the add-ware is just a checkbox.
Great but how and why do we use it? Well to answer why we use it first, the reason is that it’s quite a mature tool from my point of view and has a lot of neat features to help you out, as for why, well to read and manipulate the memory of course.
Though this is not a tutorial on how to use CheatEngine, it does quite a good job with a big forum and community and also an embedded tutorial about how to use it. Suffice to say, that we need to read certain aspects of the memory and manipulate it somehow.
Ok, What Now?
Well, I’ve been playing with cheat engine for some time and it always fascinated me how with a little elbow grease and perseverance, you can unravel the black box mystery of a game and start seeing its underlining structures in memory, and also find some interesting ways of fighting against cheaters and hackers (got to understand how they do it so you can prevent it).
This just shows that no matter how you obfuscate your code, once it is in memory, it’s fair game for anyone to dissect.
Now for the interesting part, not only can we manipulate memory, we can also change the behavior of certain mechanisms by the use of Assembly Injection, through which you can introduce your own code written in Assembler into a running process and make it do things it shouldn’t.
Oh Great, Assembler? Really?
Yes I know, it’s not really my cup of tea either, but it’s always good to know how something works. But fear not, from this point, we’re jumping right straight into our friend, the high-level language C#. Let’s say for example, you don’t want to be all god like in a game but maybe just tweak it a bit, and that tweak might require a level of logic and complexity far beyond what we can do in a simple Assembler injection. Well fortunately for us, we can use C# to read and write into another process.
For this, we need a few things as follows:
- Since .NET is sandboxed, we can’t just tap into another process so easily, the trainer we would write would have to run in Administrator Mode.
- For reading the memory, we need to add this line in our code:
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[Out] byte[] lpBuffer,
int dwSize,
out int lpNumberOfBytesRead
);
- For writing to the memory of a process, we need to add this line:
[DllImport("kernel32.dll", SetLastError = true)]
extern bool WriteProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
byte[] lpBuffer,
uint nSize,
out UIntPtr lpNumberOfBytesWritten
);
What these lines do is that they allow us to use the low-level functions of Windows to access the processes. Let’s look at an example of how to use it:
Process process = Process.GetProcessesByName("notepad").Single();
int size = sizeof(int);
byte[] buffer = new byte[size];
int bytesReadWritten;
IntPtr addressToManipulate = new IntPtr(0x010129D4);
ReadProcessMemory(process.Handle, addressToManipulate, buffer, size, bytesReadWritten);
if (size != bytesReadWritten) throw new Exception();
int valueFromAddress = BitConverter.ToInt32(buffer, 0);
valueFromAddress = valueFromAddress + 500;
buffer = BitConverter.GetBytes(valueFromAddress);
WriteProcessMemory(process.Handle, addressToManipulate, buffer, size, bytesReadWritten);
if (size != bytesReadWritten) throw new Exception();
So you can see, with these lines, we can read parts of the memory and write to them (if they are writable), the reason CheatEngine
was brought up is that it helps in finding those addresses we want to read or manipulate, also since most programs, especially managed ones like Java and .NET make heavy use memory allocation, this is also a way to read pointers, the reason pointers are brought up is because of the way memory allocation works, we may not know where a variable resides in memory every time, but we can follow its references and find it, here is an example of how that would look:
var offset1 = process.ReadInt32(IntPtr.Add(process.MainModule.BaseAddress, 0x010129D4));
var offset2 = process.ReadInt32(offset1);
var offset3 = process.ReadInt32(offset2);
var offset4 = process.ReadInt32(offset3 + 0x5a4);
var playerDataAddress = process.ReadInt32(offset4 + 0x18);
Here, we would have a static address that serves as the reference start for a chain of pointers ending up at the start of the playerData
structure.
Conclusion
With what we’ve seen so far, the goal wasn’t how to cheat at games, the goal of this post was to show you what happens behind the scenes.
Here are a few good things you could do with this:
- Imagine you’re working for testing automation, by using this technique, you might be able to test your products even after they have been compiled though instead of manipulating game data, we would be manipulating input data and output data.
- We could help gather telemetry during the testing phase of our product without introducing a lot of boilerplate code, in fact turning another application or process into a service out of which you can read.
- I have seen in other games, find ways of deterring and impeding cheaters in games.
Please note that as stated before, this knowledge is only presented here to teach and learn about how systems work in general, games were just a common example.
I hope you enjoyed this little adventure as much as I did.
Thank you for reading.
CodeProject