example-memp-loader

memp loader (medge multiplayer loader) is a DLL written in Rust that loads the Mirror’s Edge multiplayer mod into the game at startup.

Inspiration

Why a loader was needed: what wasn’t working about getting the mod into the game the usual way.

How it works

The loader gets into the game through phantom DLL hijacking. Mirror’s Edge tries to load AgPerfMon.dll, a DLL that isn’t actually present on the system. Because nothing satisfies that name, a DLL placed in the search order under it gets loaded instead, so this project builds itself as AgPerfMon.dll and the game loads it without being asked to.

Once loaded, it pulls in the multiplayer mod DLL and then unloads itself from the game, leaving only the mod behind.

I wrote up the technique in more detail in Chasing Ghosts: Phantom DLLs in Mirror’s Edge.

Building

The build targets 32-bit x86 Windows, which .cargo/config.toml sets by default:

rustup install stable-i686-pc-windows-msvc
rustup target add i686-pc-windows-msvc
cargo build

The result lands at target/i686-pc-windows-msvc/debug/AgPerfMon.dll, which is then copied into a directory on the DLL search order.

Variants

Two other branches explore different versions of the same idea:

  • without-dependencies: the same code with no external dependencies
  • find-mp-dll-by-modules: locates the multiplayer mod DLL relative to the loader DLL

Challenges

The hard parts: finding a DLL name the game would load, getting Rust to emit a 32-bit DLL Windows would accept, or unloading cleanly without taking the game down.

What I learned

What this taught you about Windows’ DLL search order, or about Rust at the FFI boundary.

What’s next

Features or fixes you have in mind.