How I made an Among Us hack (and how you can secure your own game)

Published on 30 August 2020 - Tags: cybersecurity

Edit 2020/10/05: I received emails saying the game has been obfuscated, meaning this process now involves a lot more hassle.

The Steam library is relatively saturated with ~700-900 releases a month. Many of those releases are multiplayer games that don’t bother to take precautions to mitigate the threat of cheaters. I can’t blame low-budget indie developers, but considering the amount of money some studios make, it’s surprising to have 0 hours invested in anti-cheat functionality. Out of curiosity, I recently decided to develop a game hack from start to finish to see how hard it is and whether it’s worth the effort to secure your game.

Executable programs are made up of memory. Some of that is read-only executable memory used to store machine code. Some of it is used to store variables, object instances, and other editable data. The rest of it is garbage.

Reverse engineering

When making hacks, the first step is to reverse engineer the game itself. The closer you can get to the original source code, the more efficiently you can find useful memory addresses to manipulate.

Since Among Us is developed with Unity, I decided to use Il2CppDumper to extract the DLL files from the game assembly DLL. I then used dnSpy to look through the classes for anything interesting.

dnSpy

There were a few things that caught my eye. For instance, a single function can be edited to remove the kill cooldown. Another function can be used to complete your tasks. There’s even a class member that tells you if a player is an impostor.

I used Cheat Engine to verify the memory addresses. I wrote a small Lua script that tells me who the impostors are. It worked. I then began to work on the cheat client.

Memory manipulation

My plan was to inject a DLL that would do all the memory manipulation. DLLs have the same address space as their host process, so pointer assignment is convenient. Instead of having to perform Win32 API calls to read an address, you can just define a pointer bool *is_impostor = 0x12345;. C++ was the obvious choice of language as it’s low-level enough to do pointer manipulation and Win32 API calls and high-level enough to be easy to code.

The memory manipulation part was relatively simple. I just needed to replace some functions with my own and read some memory addresses. For reading memory addresses, pointers were sufficient. To redirect functions, I used Detours. Because the game was written in C# and used cdecl, replacing functions was as easy as giving the Detours library the addresses of the original and replacement functions. I used SigScan to keep track of functions’ memory addresses.

Front-end development

I then had to make the GUI. I considered writing it natively in C++ and adding it to the DLL as that would simplify the project, but I gave up that idea after realizing the complexity of the Win32 API. Instead, I chose to write a .NET executable in C# that would inject and communicate with the DLL. C# made making a GUI straightforward. However, the hardest part in the project was getting the DLL and executable to communicate. After a lot of fiddling around with client-server communication, I accomplished this using named pipes.

named pipe

Conclusion

It’s scary how simple it is to make cheats for games like Among Us. If I reuse my existing code, it would take a few hours to make a comparable tool for other games. Competitors and hackers may decide to distribute such a hack, ruining your game within days. This is a risk that should be avoided if at all possible.

There are 3 main methods to prevent cheaters from ruining your game:

  1. Implement as much server-side functionality as possible. The client doesn’t need to know if another player is an impostor (unless they are also an impostor). Additionally, the server can verify that the kill cooldown is being respected by the client. This is the most effective method whenever possible as it is very difficult to circumvent.

  2. Obfuscate your game assembly. If you use Unity, there are plugins that do this. This doesn’t make it impossible to hack your game, but it does slow the cheaters down.

  3. Include a report feature. This method is the most costly and reliable.

All in all, it’s suggested that you take at least some steps to secure your game, as cheating can greatly ruin its enjoyment and profitability.

The source code is available here for the GUI and here for the DLL.