Skip to content(if available)orjump to list(if available)

Reverse engineering Call of Duty anti-cheat

sas41

Cheating in multiplayer games has become such a huge problem, it has destroyed trust across every major FPS.

I am a long time CS player, but I did briefly play one of the new CoD games, before they went crazy with Nicki Minaj skins and bong-guns.

A person was so convinced I was cheating, they started doing OSINT on me while still in a match, and they found my old UnKnOwNcHeAtS account as some kind of proof that I am cheating (that account was 12 years old by that point).

I abhor cheating, and I have a lot of interest in computer science, so of course I wanted to see how all of it works and did my research during my youth, taking care to never compromise the competitive integrity of the games I played, but if you look around, there is not a single game that I can recommend to people anymore.

Games like Escape From Tarkov are so busted, cheaters are stealing the barrels off people's guns and crashing their game/PC on command.

My beloved counter-strike's premier competitive game mode has a global leaderboard that acts as a cheat advertisement section within the game.

Games like Valorant are a cut above the rest on account of their massively invasive anti-cheat, but are nowhere near as clean as most fans claim, I mean, you could write a cheat for the game using nothing but AHK and reading the color of a pixel.

There is a whole industry of private matchmaking for counter-strike, built solely on the back of their anti-cheat and promises of pro-level play to the top players.

EDIT: I found the screenshot, it was MPGH not UnknownCheats, but yeah, they also had a game ban on their account.

enjoylife

We’re seeing a clear divide where both competitive gamers and hackers are retreating into their own ecosystems, away from public matchmaking. Public matchmaking has simply become too optimized/lucrative to sustain trust or meaningful competition. Private matchmaking and closed communities are thriving, raising the average skill ceiling in competitive. Similarly, hacking communities are evolving with easier forms of payment and distribution. The monetary aspects are huge. But most importantly, both cultures push each away. Your persona of someone who plays with integrity and crosses the competitive and hacker mentality is pretty much gone.

Dalewyn

I disagree that cheating "has become" a huge problem, it was always a huge problem.

I can't remember a single multiplayer game that didn't have cheaters of some form or another. None. Zilch. Zero. It's kind of why I never grew beyond playing MMORPGs, and even that passion ultimately died out.

adiabatichottub

I'm very curious about the jump obfuscation. Maybe somebody who's done more reverse-engineering can answer this for me:

  a) Are unconditional jumps common enough that they couldn't be filtered out with some set of pre-conditions?

  b) It seems like finding the end of a function would be easy, because there's a return.  Is there some way to analyze the stack so that you know where a function is returning to, then look for a call immediately preceding the return address?
Apologies if I'm wrong about how this works, I haven't done much x86 assembly programming.

mahmoudimus

There's some other cool tricks you can do, where you symbolically execute using angr or another emulator such as https://github.com/cea-sec/miasm to be able to use control flow graph unflattening. You can also use Intel's PIN framework to do some interesting analysis. Some helpful articles here:

- https://calwa.re/reversing/obfuscation/binary-deobfuscation-...

- https://www.nccgroup.com/us/research-blog/a-look-at-some-rea...

russdill

Unconditional jumps are very common and everything in x86 assembly is very very messy after optimizations. Many functions do not end in ret.

jychang

How do functions that not end in ret work?

DSMan195276

In addition to what others said, I'd simply point out that all 'ret' does on x86 is pop an address off the top of the stack and jump to it. It's more of a "helper" than a special instruction and it's use is never required as long as you ensure the stack will be kept correct (such as with a tail-call situation).

duskwuff

The return is somewhere before the end of the function, e.g.

  loop:
    do stuff
    if some condition: return
    do more stuff
    goto loop
Alternatively, the function might end with a tail-call to another function, written as an unconditional branch.

jcranmer

There are things like compiling a tail call as JMP func_addr.

to11mtm

My gut (been a while since I've been that low level) is various forms of inlining and/or flow continuation (which is kinda inlining, except when we talk about obfuscation/protection schemes where you might inline but then do fun stuff on the inlined version.)

phire

Yeah, should be easy enough to filter these particular jumps out. It's an obfuscation designed to annoy people using common off-the-shelf tools (especially IDA pro)

Most obfuscations are only trying to annoy people just enough that they move on to other projects.

ackbar03

What are off the shelf tools/methods people use now? Ida was pretty standard goto when I was into RE

mahmoudimus

Not much has changed, except there are more entrants. Binary Ninja, Ghidra, radare (last two being open source). For debugging, there's x64dbg. Some use windbg and gdb (for non windows os), but it still is mostly IDA as king though the others are catching up.

I evaluated entering the space by building something with AI native however, the business case just didn't make sense

shj2105

Where did you learn how to do this? I would love to learn more about understanding half of what this article said but I don’t know how to start.

therein

I got started with Lena151's tutorials back in the day. https://github.com/kosmokato/Lena151

andrewmcwatters

Dang, I'm old. I was going to say hang out in Gamedeception, but apparently it's been gone for years!

greetz to readers of Unknowncheats, cs.rin.ru, etc.

jorvi

Yoo haha Unknowncheats, now there's a blast from the past.

Milworm (milw0rm?) also got me started back in the day.

therein

I used to frequent cs.rin.ru for all things non-steam back when I operated non-steam CSS servers.

UnknownCheats is also absolutely amazing for cheat development. Back when I was writing undetected kernel cheats for my own experimentation purposes, I learned so much there.

andrewmcwatters

I made my lifelong best friends hosting non-Steam servers, and writing the first cracks in Lua to generate fake Steam IDs from IP addresses.

b8

The secret.club is a good resource.

mahmoudimus

I have been doing a bit of reverse engineering on a popular Horde/Alliance based MMO game and it follows almost the exact same steps (including the FNV32 export hashes). It almost seems very similar as I have seen it employ very similar tricks. I wonder if it's packed using the same protection?

roflmuffin

The source 2 engine also uses fnv to hash the schema (basically entity properties)

2c2c2c

would make sense to reuse warden for Activision IP post merge

SheinhardtWigCo

Phenomenal piece of research. Clearly this is not the author's first rodeo :)

andrewmcwatters

Signature scanning is indeed the hot shit.

It's like the most addicting part of reverse engineering to me. Building signature lists, and then writing bindings to scripting languages to call those function pointers.

It's also the foundation of how many third-party mod platforms work, because you need to build a meaningful API to modders that isn't exposed by the first-party.

Cyph0n

No idea what signature scanning is, but found this resource for those curious:

https://www.unknowncheats.me/forum/general-programming-and-r...

c0balt

From my limited experience, it refers to the act of reverse engendering the function (signatures) contained the code of a binary.

A binary, like the underlying code, has commonly used code split into functions that may get called in multiple places. These calls can be analyzed either through static analyzers or by a human, who may analyze context of the callsite to guess what each Arg is supposed to do/be.

For modding, e. G. in a single player game, one might want to find out where the engine adjusts the health points of a player or updates progress.

null

[deleted]