"Low-level programming is good for the programmer's soul." - John Carmack
I love video games. I remember when my dad brought home a Commadore 64, but I was still too young to use it without his help. From there, our first console was a Nintendo Entertainment System. But things really got serious when we got our first PC. Some of my fondest memories in gaming come from games that ran on MS-DOS. Of course we had Doom, which was fantastic. But I especially loved this "1001 Games" CD. Plenty of the games were trash, and some didn't run on our hardware, but there was a seemingly infinite amount of entertainment to be had. Eventually my mind was blown by titles like Quake, Warcraft, Diablo, and Ultima Online, all of which incredibly innovative multiplayer experiences.
Cheaters have existed for as long as games have. Anybody that has played a multiplayer game has likely been exposed to a hacker taking some form or another. These hackers, and the tools they used, had always seemed to me like an enigmatic underbelly of the internet. There's nothing worse than getting wrecked by a cheater in a competitive match. But disdain wasn't the only emotion those experiences evoked. They also made me curious. How did these cheats work? Who was building them? I had experimented with Diablo trainers and the like when I was younger, but the knowledge to learn how to create something like that was far beyond my capabilities.
Having made a career of Web Development, with about 5 years of programming experience under my belt, I decided to take another crack at it. After some initial research, I started poking around on some forums, and I was blown away by just how sophisticated some of these techniques truly are, and I gained a new respect for these hackers. So much of what they were talking about was still way over my head. There was some seriously low level computer science concepts involved. Abstraction is a powerful thing - I was amazed at how far I had gotten in my career without truly understanding some of the fundamental concepts that formed the foundation of every piece of software I built. It's easy to take for granted just how good our high level programming languages are, and how impressive modern compilers have become.
I found some great resources - the x86 Assembly Wikibook helped me understand the basics of CPU architecture, and the journey your source code takes before it's executed by your CPU. The x86 Disassembly Wikibook is a great crash course in disassembly and reverse engineering. Ownedcore has some fantastic discussions about concepts such as DLL injection, assembly injection, interoperability, function detouring, and interacting with the Windows API. Learncpp has deep and thorough explanations of how pointers and memory management work (admittedly, I've read the book twice and my C++ still stinks, but some fundamental knowledge helps a lot with reverse engineering).
After many late nights, and plenty of borrowed code from all over the web, I had built a fully functional World of Warcraft bot capable of fighting monsters for hours on end without any human interaction. Having made it this far, it's astonishing how much there is to learn. Many of these concepts were totally foreign to me coming from a background in Web Development, and I've barely scratched the surface. But the process has been extremely gratifying, and I believe without a doubt that it has made me a better developer. Thinking about how to make a bot behave more like a human was also an interesting glimpse into the world of AI.
I had started and stopped this intellectual journey a number of times before I found a project that kept my interest for long enough to make any significant progress. Without a formal education in computer science, the task was incredibly daunting. So my goal is to try to distill some of the lessons I've learned over the past year, hopefully making the journey a little easier for anybody else that feels the same way.
DISCLAIMER: I have serious ethical concerns about cheating in gaming. Especially with the blossoming world of eSports and competitive gaming, using hacks in games is guaranteed to ruin the experience for other players. That being said, I think there's a difference between a bot in World of Warcraft who runs around fighting with the AI, and an aim bot in Counter-Strike that instantly destroys other players. I chose World of Warcraft not only because it's a game I loved when I was younger, but also because it's fairly (not completely) harmless to other players. I made a conscious effort to design the bot in such a way that it won't damage the experience of other players on the server. I also tested the bot exclusively on a free, private server not run by Blizzard. Ultimately my motivation was curiosity, not to "get ahead" in the game, and I think that's an important distinction. Unfortunately, cheating in gaming isn't going anywhere. The bright side is that while the techniques discussed in this article can most certainly be used to create hacks, the same concepts can be used to inform the design of anticheat software, so I think it's information worth sharing.
Before taking a look under the hood of the WoW bot, we'll first examine a rudamentary game engine I wrote in C++ called BloogsQuest that we'll use as a contrived example to explore some fundamental concepts that are important to understand before diving fully into bot development.
I also want to mention that the code snippets found here will be truncated, and will most certainly deviate from best practices in software development. This is less a step-by-step tutorial in bot development, and more an exploration of the high level concepts involved. Some prerequisite knowledge of C# and C++ are necessary, including understanding pointers, but I'll do my best to explain things as they come up.