Files
Hi3-Patcher/docs/ace.md
T
2026-10-31 23:35:41 +01:00

1.8 KiB

ACE patch (Windows, clients ≤ 8.9)

Builds a patched BH3.exe from a capture of the clean client's initialized state. Only BH3.exe is written, without a backup. 9.0+ clients use HoYoKProtect instead.

Discovery (ace/discovery.rs)

Read-only; all checks must pass:

File Required layout
BH3.exe 7 sections all named .ace*, 4 KiB section alignment, no TLS directory, entry calls the BH3Base.dll ordinal-1 import
BH3_Data/sharedassets0.assets ChannelConfig resolves to a known region
UnityPlayer.dll exports UnityMain; three writable decoder globals found via a .text code pattern
BH3_Data/Native/UserAssembly.dll exports il2cpp_get_api_table; executable .tvm0 section with a virtual tail larger than its raw size

Capture (ace/capture.rs, ace/process.rs)

After confirmation, launches the client (Windows directly; Linux via umu-run + Proton) and reads its memory read-only — no injection or protection tampering. Once the state is stable for 2 s (120 s timeout), it captures the .tvm0 section, the three decoder states and the committed private executable allocations.

Normalize and rebuild (ace/runtime.rs, ace/generate.rs)

runtime.rs checks the captured .tvm0 against the original after PE relocations, resolves FF 25 jump slots against the captured allocations, and emits a position-independent blob and two thunk tables. generate.rs appends .bh3code (the bootstrap.bin stub, patched with the discovered RVAs/sizes per bootstrap.json) and .bh3imp (imports, decoder states and the runtime blob), then repoints the entry point.

A HI3AUTO1 receipt with SHA-256 hashes of the patched image, UnityPlayer.dll and UserAssembly.dll is appended; a repeat run that validates it is a no-op. Written via util::replace::verified.