Turning a Temporary DLC Check Fix into a Runtime Patch

posted: August 27, 2026

I wanted to understand how a game was checking for DLC availability and what would happen if the result of that check was changed at runtime.

This was done as a reverse-engineering experiment on a copy of the game I was analyzing. The goal was mainly to understand how managed code, native functions, and return values interact.

## 0x01 - Finding the DLC check

While inspecting the game’s code, I found a call to:

Steamworks.SteamApps.BIsDlcInstalled

The function name was a pretty good indication of what it was responsible for: asking Steam whether a DLC was installed.

The interesting part was that the game appeared to use the returned boolean as part of its local DLC logic.

Conceptually, the flow looked like:

Game

BIsDlcInstalled()

true / false

DLC state

That gave me a useful function to investigate.

## 0x02 - The temporary modification

I first tested the idea by modifying the function at runtime.

The important part was:

mov rax, 1
ret

On x86-64, RAX is used for the return value of a function.

Setting it to 1 and immediately returning therefore makes the function return true.

Conceptually, I changed:

BIsDlcInstalled() → Steam's result

into:

BIsDlcInstalled() → true

This was enough to confirm that the function’s return value was being trusted by the game’s local logic.

## 0x03 - From a temporary fix to a patch

Once I confirmed the behavior, I turned the runtime modification into an actual patch.

The script first locates the function:

Steamworks.SteamApps.BIsDlcInstalled

and compiles it so that it can be modified.

I also kept the original bytes:

40 53 48 83 EC 20 8B D9 33 C9 E8

This allowed the patch to restore the original function when disabled.

The relevant patch was:

DLC_CHECK:

mov rax, 1
ret

So the resulting flow became:

BIsDlcInstalled()

   mov rax, 1

      ret

     true

## 0x04 - Why the byte check matters

The patch uses:

assert(DLC_CHECK, bytes)

before modifying the function.

This checks that the bytes currently present at the target address match the expected original bytes.

That’s useful because blindly overwriting an address can cause problems if the game has changed between versions.

Instead of assuming:

"This address is still the function I expect."

the patch verifies:

"The bytes here still match what I analyzed."

If they don’t match, the patch should fail rather than blindly writing over potentially different code.

## 0x05 - Restoring the original function

The patch also has a disable section:

[DISABLE]

DLC_CHECK:

db bytes

This writes the original bytes back.

The overall process therefore becomes:

Enable

Verify original bytes

Replace function

Function returns true

Disable

Restore original bytes

Original function behavior

This was the part that turned the experiment from a temporary runtime modification into a reusable patch.

## 0x06 - What I learned

The interesting part of this experiment wasn’t the DLC itself. It was seeing how a relatively small native function could influence higher-level game logic.

The game can have complicated systems surrounding DLC, but if a particular decision ultimately depends on a boolean returned from a function, changing that return value can change everything downstream that relies on it.

It also demonstrated the difference between modifying managed code and modifying the native code underneath it.

A managed patch can change the game’s logic directly, while this experiment modified the native function responsible for returning the value.

## 0x07 - Result

The final patch changed the behavior of the targeted function so that calls to it returned true immediately, while retaining the ability to restore the original function.

The experiment gave me a practical example of:

Finding a function

Understanding its return value

Testing a runtime modification

Verifying the result

Turning the modification into a reversible patch

It was a small experiment, but it helped me understand how reverse engineering can go from simply finding something interesting in a decompiler to actually tracing and modifying the behavior of the compiled program.

## 0x08 - Download

I also packaged the patch used for the experiment so I could keep the tested version separate from the rest of my notes.

Patch: BIsDlcInstalled runtime patch Purpose: Reverse-engineering experiment Type: Cheat Engine table/script

Download the patch