Skip to content

Scan the x86-64 slice of universal Mach-O game assemblies - #289

Open
Ketlark wants to merge 1 commit into
BepInEx:masterfrom
Ketlark:macho-universal-xref
Open

Ketlark wants to merge 1 commit into
BepInEx:masterfrom
Ketlark:macho-universal-xref

Conversation

@Ketlark

@Ketlark Ketlark commented Oct 5, 2026

Copy link
Copy Markdown

Pass16ScanMethodRefs maps GameAssemblyPath and adds each method's file offset to the start of the mapping. In a universal (fat) Mach-O those offsets are relative to the x86-64 image, which starts at a slice offset, not at the start of the file. Xref scanning therefore decodes unrelated bytes and fails in XrefScannerLowLevel.ExtractTargetAddress with ArgumentOutOfRangeException. macOS Unity games ship such a universal GameAssembly.dylib (x86_64 + arm64).

The fix adds MachOUniversalBinary.TryGetSlice, which parses fat/fat64 headers big-endian. When the file is universal, the scan is offset to the x86-64 slice and bounded by its size. Thin binaries are unaffected.

Validation (generator harness against the Dofus 3.6.10.11 Cpp2IL output):

Build universal GameAssembly thin x86_64 GameAssembly
master ArgumentOutOfRangeException OK, 174 assemblies
fix OK, 174 assemblies OK, 174 assemblies
  • The three successful runs produce identical file name/size listings.
  • The solution builds.
  • dotnet format --verify-no-changes is clean on the changed files. The only pre-existing whitespace finding is in ReferenceCreator.cs, which this change does not touch.
  • Full in-game check: MelonLoader generation with this generator completes on Dofus, and mods load.

Pass16ScanMethodRefs maps GameAssemblyPath and adds each method's file offset
to the start of the mapping. Those offsets are relative to the x86-64 image,
which in a universal (fat) Mach-O binary starts at a slice offset rather than
at the start of the file, so xref scanning decoded unrelated bytes and failed
with ArgumentOutOfRangeException in XrefScannerLowLevel.ExtractTargetAddress.
macOS Unity games ship such a universal GameAssembly.dylib (x86_64 + arm64).

Locate the x86-64 slice when the file is universal and scan within it. Thin
binaries are unaffected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant