java. Brian D.

About me

I’m Brian, also known as java, an experienced software engineer from Ireland with a passion for C#, C++, reverse engineering, and cybersecurity, focused on building scalable, high-performance tools and applications.

Projects

Note: Most of these repositories have been made private due to exclusivity or because they were created as part of commissioned work.

XOR Packet Verification in GOW (Gears of War)

8 Aug 2025 · written by java

In this post, I'll talk about the process of discovering a critical vulnerability in Gears of War, rooted in its native UObject system and multiplayer synchronization layer.

The aim was to explore UE3 (Unreal Engine 3) internals, specifically UObject behavior, vtable layouts, and how replicated state is handled across the network. Along the way, I uncovered a flawed XOR-based packet verification routine that could be bypassed with trivial effort.

As always, no binaries were redistributed. All research was performed in a legal, offline sandboxed environment for educational purposes only.

What is Gears of War?

Gears of War is a third-person shooter developed by TC (The Coalition) & Epic Games, built on Unreal Engine 3. Its multiplayer networking relies heavily on UE3’s replication framework, which serializes and transmits actor state between clients and servers.

First thought

I began by acquiring a clean runtime memory dump of the game. This was done after the game had fully initialized to ensure all code sections were in their decompressed, executable form. The dump included .text, .rdata, and .data segments to capture both logic and constant data tables.

For analysis, I loaded the dump using the PowerPC (PPC) processor module, supplemented with UE3-specific type libraries for UObject and FName parsing. I also created a small tool for dynamic memory introspection to extract GObjects and GNames arrays, confirming that no obfuscation or ASLR was in place, rare for a game of this era.

From there, I targeted UObject::ProcessEvent, the core virtual function responsible for dispatching native and UScript calls. Using a known UE3 signature (48 89 5C 24 10 48 89 74 24 18), I mapped out the base UObject structure:

class UObject {
    void* vtable;
    int ObjectFlags;
    int InternalIndex;
    UClass* Class;
    FName Name;
    UObject* Outer;
};

With this in place, I traced function calls into multiplayer replication code paths, focusing on AGameReplicationInfo::PostNetReceive, which processes incoming state updates from the network.

Things seems to be getting strange?

While stepping through the packet processing flow, I found a function I labeled verify_packet_integrity. Its role was to check incoming packet payloads before applying replicated state changes. The implementation was a simple XOR checksum:

bool verify_packet_integrity(uint8_t *data, int length, uint8_t key) {
      uint8_t checksum = 0;
      for (int i = 0; i < length; i++) {
          checksum ^= data[i];
      }
      return (checksum == key);
}

The problem? The key was derived from a combination of the player’s UID and system tick count, both predictable or capturable locally. Once the key was known, any packet could be forged to pass integrity checks, since the XOR checksum space is only 256 possible values.

Disassembly

To validate the weakness, I redirected all multiplayer traffic through a custom packet inspection proxy, enabling real-time capture and modification of replication data. By intercepting a legitimate packet, stripping its checksum byte, recalculating it offline using the static XOR key, and reinjecting it, I was able to bypass the integrity mechanism entirely. The server accepted the modified packet without any errors.

This opened the door to several exploit vectors: injecting forged packets to trigger server-side events without an authenticated session, replaying captured packets to repeat one-time actions, and modifying replicated actor properties in real time without triggering anti-cheat detection.

The anti-cheat system in place operated purely in user-mode, relying on memory CRC checks and basic pointer validation. I disabled it by NOPing the ValidateHooks() call inside UPlayer::CheckForTamper(). There was no kernel-level enforcement, no hardware binding, and no substantial runtime protection.

image

Decompiled logic showing the XOR-based packet verification. The predictable key derivation renders the integrity check trivially forgeable.

Mitigation would require replacing the static XOR validation with a robust cryptographic integrity check, ideally leveraging a session-specific key negotiated during handshake. Incorporating replay protection via nonces or sequence numbers would further prevent the reuse of captured packets.

Never trust client-supplied data without rigorous, server-side validation.

What now?

This issue was responsibly disclosed to The Coalition (TC) in accordance with their security reporting guidelines and was addressed quickly and transparently.

Disclaimer: This research was conducted on a legally acquired copy of Gears of War in an isolated, offline environment. No online services or multiplayer servers were accessed. This post is shared for academic and educational purposes only.