Introduction
Reverse engineering is the process of analyzing a compiled program to understand its inner workings without having the original source code. In the context of video games, reverse engineers often use specialized tools (such as IDA Pro, Ghidra, or x64dbg) to disassemble or decompile game binaries, revealing functions and logic hidden inside. This practice is common in the modding and security community, whether to create mods, cheats, or to discover vulnerabilities.
One especially dangerous type of vulnerability is a Remote Code Execution (RCE). An RCE allows an attacker to execute arbitrary code on another player's machine simply by exploiting the game's network communication. In a multiplayer game, this means a malicious player could potentially run any program or command on your PC just by being in the same lobby — a worst-case scenario for security.
In recent years, Call of Duty: Modern Warfare 2 (2009) for PC has gained notoriety for containing a known RCE vulnerability that went unpatched for a long time. This blog post explores that vulnerability from a reverse engineering perspective: how it works, how it was discovered, and how it can be patched.
This document is provided for educational purposes only. Its objective is to inform gamers and aspiring cybersecurity researchers about the mechanisms behind such vulnerabilities and the strategies available for remediation. Unauthorized execution of malicious code on another person's computer is illegal. The hope is that by enhancing understanding of these exploits, both the industry and its users can collaborate to ensure that legacy games remain safe and enjoyable.
The MW2 RCE Vulnerability: Overview and Discovery
Call of Duty: Modern Warfare 2 (MW2) still has an active player base even many years after its 2009 release. Unfortunately, for a long time it also had a serious RCE flaw lurking in its multiplayer code. The issue was ultimately traced to the game's handling of compressed network data — specifically a function related to Huffman compression, a method used to compress/decompress messages in the Quake engine lineage that Call of Duty is built upon.
Back in late 2017, security researcher Maurice Heumann (known online as momo5502) detailed this vulnerability. He explained that users playing a Call of Duty match "could cause a buffer overflow on the host's system inside a stack allocated buffer within the game's network handling. In consequence, this allows full remote code execution!"
In simpler terms, by sending a specially crafted network packet to an MW2 player who is hosting a match, an attacker could overflow a buffer in the game and inject their own code to be executed on the host's PC. The community widely warned that "someone who uses RCE exploits on MW2 can infect anybody in the lobby with malware... and steal passwords, log keystrokes, access your files."
Eventually, this vulnerability was assigned CVE-2018-10718, and Activision released a patch in late April 2018 to fix it. Despite the patch, not all players updated their games, and similar vulnerabilities persisted in other older Call of Duty titles for years.
Breaking Down the Vulnerability: Huffman Compression Overflow
The offending bug in MW2 occurs during the processing of network packets, specifically in a function known as SV_ExecuteClientMessage.
This function is part of the server-side logic (which in peer-to-peer games like MW2 means the host player's client acts as the "server" for that match).
SV_ExecuteClientMessage is responsible for reading and handling messages sent from a connected client.
Inside SV_ExecuteClientMessage, the game allocates a fixed-size buffer on the stack to hold decompressed data.
The vulnerability lies in the fact that the game did not properly validate the size of the incoming compressed data before decompressing
it into that fixed buffer. The length of the compressed data is not checked to be smaller than the
allocated buffer on the stack before the call to MSG_ReadBitsCompress.
The result is a classic buffer overflow — data spills past the buffer's boundary and overwrites adjacent memory on the stack, including the function's return address. Once an attacker can overwrite a return address on the stack, they can redirect execution to their own code.
Here's a simplified pseudocode version of the vulnerable function:
void SV_ExecuteClientMessage(client_t *cl, msg_t *msg) {
char decompressedData[1024]; // fixed-size stack buffer
int compLen = MSG_ReadShort(msg); // attacker-controlled length
// No bounds check! If compLen > 1024, this overflows decompressedData.
MSG_ReadBitsCompress(msg->data + msg->readcount, compLen, decompressedData, sizeof(decompressedData));
// continue processing using decompressedData ...
}
An attacker can craft a packet with a large compLen value such that decompression overwrites memory beyond
decompressedData's boundary — including the saved return address on the stack — redirecting execution to their shellcode.
Reverse Engineering the RCE: Tools and Methodology
A combination of static analysis and dynamic analysis was used to find and understand this bug.
- IDA Pro / Ghidra: to disassemble
iw4mp.exeand locate functions related to network message handling. Community-maintained function lists helped identifySV_ExecuteClientMessageandMSG_ReadBitsCompressin the binary. - x64dbg: to set breakpoints and watch how the game processes incoming data at runtime.
- WinDivert: a packet capture/filter driver for Windows. By intercepting network traffic at the OS level, you can inject crafted packets without modifying the game binary — avoiding anti-cheat detection.
- Wireshark: to capture and analyze MW2's custom UDP protocol (inherited from the Quake engine) and understand where in the packet the length field lives.
Once MSG_ReadBitsCompress was located in the binary via these tools, seeing it called inside SV_ExecuteClientMessage
with an attacker-controlled length and no preceding bounds check was the "aha" moment.
Technical Details: Disassembly Snippets
Here is a representative IDA assembly excerpt for the vulnerable code path:
.text:00612345 movzx eax, byte ptr [esi] ; read message type byte
.text:00612348 cmp eax, 5Ah ; check message type
.text:0061234B jne NOT_COMPRESSED
.text:00612351 movzx ecx, word ptr [esi+1] ; ECX = compSize (attacker-controlled)
.text:00612355 add esi, 3
.text:00612358 lea edx, [ebp-400h] ; EDX = dest buffer (1024 bytes on stack)
.text:0061235E push 400h ; push dest buffer size
.text:00612363 push edx ; push dest buffer pointer
.text:00612364 push ecx ; push compSize (no bounds check!)
.text:00612365 push esi ; push compressed data pointer
.text:00612366 call MSG_ReadBitsCompress ; OVERFLOW if compSize >= 0x400 The correct fix is one added comparison before the call:
cmp compLen, 0x400 ; is compLen >= 1024?
jge handle_overflow ; if so, drop the packet The vulnerable version before April 2018 was simply missing that cmp/jge pair.
Exploit in Action: What Could Attackers Do?
When successfully exploited, this vulnerability gives the attacker the same privileges as the game process. Examples include:
- Injecting and executing malware or ransomware.
- Stealing sensitive information from the victim's PC.
- Manipulating the game session with unauthorized commands.
- In anecdotal reports, attackers opened inappropriate websites on victims' computers as harassment via the exploit.
Patching the Vulnerability
The best solution is to update to the latest official version on Steam. For those on older installs, two approaches were common:
Manual Binary Patch
With the vulnerable call located in IDA, one can either NOP it out entirely or redirect to a code cave with an added bounds check:
cmp ecx, 400h ; compare compSize with buffer size
jge skip_decompress
call MSG_ReadBitsCompress
skip_decompress: Community DLL Fixes
The community shared DLL fixes that patch the game in memory at runtime — no permanent binary modification required.
Inject the anti-RCE DLL into iw4mp.exe after launch; it hooks the vulnerable function and adds the missing validation.
Third-Party Clients
- IW4x — a community client for MW2 with patched exploits including this Huffman overflow (fixed in
r4773). - Plutonium — covers older CoD titles (MW3, BO1, BO2, WaW) with similar security hardening baked in.
Responsible Disclosure
When Maurice Heumann documented this vulnerability, he published a proof of concept aimed at the security community rather than weaponizing it. This led to a CVE assignment and an official patch. Best practices when you find a similar flaw:
- Notify the vendor through their security channels before going public.
- Do not use the exploit on real players except in controlled testing with consent.
- Wait to disclose technical details until a fix is available or a reasonable disclosure window has passed.
- When disclosing, include an educational write-up and necessary disclaimers.
The MW2 case also illustrates what happens when vulnerabilities linger: in early 2023, self-spreading worms in older CoD games exploiting similar flaws forced Activision to finally patch Black Ops 3 — eight years after the vulnerability was introduced.
Conclusion
A simple oversight — a missing length check on a network packet — opened the door for arbitrary code execution in one of the most-played shooters of its era. Through disassemblers and network analysis tools, researchers uncovered the bug and documented its impact, ultimately leading to patches both official and community-driven.
If you're a developer maintaining any networked game or application: audit your network code carefully, especially anywhere data is copied or decompressed. Always validate input lengths against your buffer sizes. The cost of that one comparison is nothing compared to the alternative.
Sources
- Heumann, Maurice. "Game Hacking reinvented? — A COD Exploit" — Personal blog detailing the discovery (Dec 2017).
- CVE-2018-10718 — Stack buffer overflow in MW2 via crafted packets, fixed April 2018.
- momo5502 on GitHub — COD Exploits repository with proof of concept and README.
- Plutonium Project Documentation — Notes on improved security in community clients.
- AlterWare (IW4x) — Security notice confirming RCE fixes in the IW4x community client.