reverse-engineering

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Reverse engineering for mods

面向 mod 的逆向工程

Rule zero: read the real thing, don't guess. Decompiled code, the actual data, a live memory view or a GPU capture is the spec. Write what you learn into
MODLOG.md
(names, IDs, offsets, formats) as you go.
Keep all decompiled output and extracted assets outside the mod repo (e.g.
~/<game>-decomp/
) and never publish them. Offline/single-player only. Never attach debuggers or scanners to games with anti-cheat (see
skills/mod-any-game/references/safety.md
).
规则零:**阅读真实内容,不要猜测。**反编译代码、实际数据、实时内存视图或 GPU capture 才是规范。分析过程中,将发现的名称、ID、offset 和格式等信息写入
MODLOG.md
。
务必将所有反编译输出和提取的资源放在 mod repo 之外,且绝不发布它们。仅限离线/单人游戏。绝不要对带 anti-cheat 的游戏 attach debugger 或 scanner(参见
skills/mod-any-game/references/safety.md
)。

Pick the tool by what the code is (
um scan
tells you)

根据代码类型选择工具(
um scan
会告诉你)

Managed .NET (XNA/FNA, Unity Mono, most indie C#)
  • dotnet tool install -g ilspycmd
    , then
    ilspycmd -p -o ~/<game>-decomp <Game>.exe
    (or
    Assembly-CSharp.dll
    ). This gives a full C# project you can grep.
  • dnSpyEx: step through with a debugger, set breakpoints, edit methods.
  • MCP: ILSpy-MCP / dnspy-mcp let an agent query types and methods directly.
Unity IL2CPP
  • Cpp2IL (or Il2CppDumper) on
    GameAssembly.dll
    +
    global-metadata.dat
    gives types, fields, method signatures and addresses, plus dummy DLLs for ILSpy.
  • Method bodies are native: load
    GameAssembly.dll
    in Ghidra/IDA and apply the generated script to name functions.
  • Live: UnityExplorer, or
    il2cpp-frida-mcp
    .
Java (Minecraft, Slay the Spire...) Vineflower / CFR / Recaf. For Minecraft, use Loom
genSources
with Mojang mappings.
Native C/C++ (custom engines, Unreal game code, console recomps)
  • Ghidra (free) or IDA, driven through MCP so the agent can decompile, rename, retype and follow cross-references:
    • Ghidra: GhidraMCP (LaurieWired), pyghidra-mcp (headless, with a run-script tool; code-capable tools beat hundreds of tiny ones), ReVa.
    • IDA: the official Hex-Rays IDA MCP (IDA 9.4+ Pro/Home; "code mode" runs IDAPython), or ida-pro-mcp.
    • Binary Ninja and radare2 have MCP servers too.
  • Workflow:
    1. Strings, then cross-references, then the function.
    2. Name and type everything you understand. Renames accumulate into a readable program.
    3. Confirm dynamically (below) before building on a guess. Agents can confidently misidentify things.
  • Unreal: dump the reflection data first (UE4SS dumper or Dumper-7); it names most gameplay classes and properties for free.
Dynamic / live
  • Cheat Engine: value scans → "find out what writes to this address" → struct → owner. CheatEngine MCP servers exist.
  • x64dbg: breakpoints and tracing (x64dbg-mcp; bind it to 127.0.0.1, since some default to 0.0.0.0).
  • Frida (frida-mcp, frida-game-hacking-mcp): hook functions from JavaScript, log arguments.
  • ReClass.NET rebuilds structs from live memory.
Graphics
  • RenderDoc (renderdoc-mcp) captures a frame and shows every draw, the render targets, the constant buffers (view/projection matrices) and the depth buffer.
  • That's how you find where to inject geometry or effects (mashup-mods), and which texture holds a sprite atlas.
托管 .NET(XNA/FNA、Unity Mono、大多数 indie C#)
  • dotnet tool install -g ilspycmd
    ,然后运行
    ilspycmd -p -o ~/<game>-decomp <Game>.exe
    (或
    Assembly-CSharp.dll
    )。这样会生成一个可用 grep 搜索的完整 C# project。
  • dnSpyEx:使用 debugger 单步执行、设置 breakpoint 和编辑 method。
  • MCP:ILSpy-MCP / dnspy-mcp 可让 Agent 直接查询 type 和 method。
Unity IL2CPP
  • 对
    GameAssembly.dll
    和
    global-metadata.dat
    运行 Cpp2IL(或 Il2CppDumper),即可获得 type、field、method signature 和 address,以及供 ILSpy 使用的 dummy DLL。
  • Method body 是原生代码:在 Ghidra/IDA 中加载
    GameAssembly.dll
    ,并应用生成的 script 为 function 命名。
  • 实时分析:UnityExplorer,或
    il2cpp-frida-mcp
    。
Java(Minecraft、Slay the Spire 等) Vineflower / CFR / Recaf。对于 Minecraft,使用带 Mojang mapping 的 Loom
genSources
。
原生 C/C++(自定义引擎、Unreal 游戏代码、主机重制版)
  • Ghidra(免费版)或 IDA,通过 MCP 驱动,让 Agent 能够 decompile、rename、重新设定类型并跟踪 cross-reference:
    • Ghidra:GhidraMCP(LaurieWired)、pyghidra-mcp(无头模式,带 run-script 工具;可执行代码操作的工具优于数百个功能单一的小工具)、ReVa。
    • IDA:官方 Hex-Rays IDA MCP(IDA 9.4+ Pro/Home;“code mode”可运行 IDAPython),或 ida-pro-mcp。
    • Binary Ninja 和 radare2 也有 MCP server。
  • 工作流:
    1. 先找 string,再找 cross-reference,最后定位 function。
    2. 为所有已理解的内容命名并设定类型。重命名会逐步沉淀为可读的程序。
    3. 在基于猜测继续构建之前,先进行动态确认(见下文)。Agent 可能会非常自信地误判事物。
  • Unreal:首先转储 reflection data(UE4SS dumper 或 Dumper-7);它可以自动命名大多数 gameplay class 和 property。
动态 / 实时
  • Cheat Engine:value scan →“找出谁写入此地址”→ struct → owner。已有 CheatEngine MCP server。
  • x64dbg:breakpoint 和 tracing(x64dbg-mcp;将其绑定到 127.0.0.1,因为有些默认绑定到 0.0.0.0)。
  • Frida(frida-mcp、frida-game-hacking-mcp):从 JavaScript hook function,并记录 argument。
  • ReClass.NET 根据实时内存重建 struct。
图形
  • RenderDoc(renderdoc-mcp)捕获一帧,并显示每次 draw、render target、constant buffer(view/projection matrix)和 depth buffer。
  • 借助它可以确定应在何处注入 geometry 或 effect(mashup-mods),以及哪个 texture 包含 sprite atlas。

Data files and asset formats

数据文件与资源格式

Use the community tool first:
  • Unity: UABEA, AssetRipper
  • Unreal: FModel, UAssetGUI
  • Bethesda: xEdit, BSArch
  • GameMaker: UndertaleModTool
  • Genie: genieutils
  • Source: VRF, Crowbar
  • FromSoft: WitchyBND, Smithbox
  • Godot: GDRE Tools
For an undocumented format:
  1. Collect several stock files. Compare sizes, and hex-dump the headers (
    xxd | head
    ). Look for magic numbers, counts, offsets and tables of fixed-size records.
  2. Form a hypothesis for the header, then the frame/record layout, then the compression. Check it by parsing every stock file without errors.
  3. Write a reader that decodes to something viewable (PNGs, JSON) and look at it.
  4. Write the writer, and prove it with a round trip: decode → encode → decode, compared against the original. The AoE2 SLD sprite writer was accepted only when it round-tripped the stock knight at 0.9/255 mean error (
    examples/aoe2-de-civ/sld.py
    ).
  5. Only then write new files. Test them in game with one asset before batch-converting.
优先使用社区工具:
  • Unity:UABEA、AssetRipper
  • Unreal:FModel、UAssetGUI
  • Bethesda:xEdit、BSArch
  • GameMaker:UndertaleModTool
  • Genie:genieutils
  • Source:VRF、Crowbar
  • FromSoft:WitchyBND、Smithbox
  • Godot:GDRE Tools
对于没有文档说明的格式:
  1. 收集多个游戏原始文件。比较文件大小,并对 header 执行 hex dump(
    xxd | head
    )。查找 magic number、count、offset 和定长 record table。
  2. 先对 header 提出假设,再对 frame/record layout 提假设,最后考虑 compression。通过解析每个原始文件且不报错来验证。
  3. 编写 reader,将内容解码为可查看的形式(PNG、JSON),并实际查看结果。
  4. 编写 writer,并通过 round trip 证明其正确性:decode → encode → decode,并与原文件比较。AoE2 SLD sprite writer 只有在对原始 knight 素材进行 round trip 后,mean error 达到 0.9/255 时才被认可(
    examples/aoe2-de-civ/sld.py
    )。
  5. 完成上述步骤后再编写新文件。在批量转换前,先在游戏中用一个 asset 进行测试。

Make it an oracle

将其打造为 oracle

  • Engine logic you port (for a simulator, a trainer, a reimplementation): record real traces from the game (positions, velocities per tick) and replay them against your port. In the Terraria Eye of Cthulhu work, the Eye's velocity matched 99.9% once the port used the action applied on frame t+1. Float32 constants mattered too (
    0.2f
    ≠
    0.2
    ). A leftover mismatch was traced to a hidden buff (Happy!, x1.21 move speed). Replays find what reading the code misses.
  • For long RE runs:
    • a journal file;
    • small verified steps;
    • cap attempts per problem (about 3 identical failures, then change approach);
    • commit every confirmed fact.
  • 你移植的 Engine logic(用于 simulator、trainer 或 reimplementation):从 game 中记录真实 trace(每个 tick 的 position、velocity),并用其对移植版本进行 replay。在 Terraria 的 Eye of Cthulhu 工作中,只有当移植版本采用 frame t+1 上应用的 action 后,Eye 的 velocity 才达到 99.9% 的匹配度。Float32 常量也很关键(
    0.2f
    ≠
    0.2
    )。剩余 mismatch 被追溯到一个隐藏 buff(Happy!,移动速度 x1.21)。Replay 能找出仅阅读代码时遗漏的内容。
  • 对于长时间的 RE 过程:
    • 维护 journal 文件;
    • 采用小步且经验证的流程;
    • 限制每个问题的尝试次数(同一问题约失败 3 次后更换方法);
    • 将每个已确认的事实提交到版本库。