Files
reverse-engineering-anything/src/native/metadata/readBinaryContainer.ts
T
morluto c19c2d6723 fix(native): separate container facts from Go metadata admission
Move ELF, PE and Mach-O container parsing into a shared native owner. Go alone selects and validates Go build-info sections, so unrelated malformed Go metadata no longer blocks Rust dependency or IL2CPP inspection. Remove the superseded Go-specific container representation and migrate all consumers. Adapted from draft PR #5510 without asserting human PR readiness.

Validation: 51 compiled CLI/MCP acceptance tests across Rust, Go and IL2CPP; 186 shared-reader tests; full check:ci passed. Three public synthetic-file probes reproduce the baseline Rust refusal and validate the fixed SDK-advertised MCP output, artifact digests and unchanged bytes. The exact zero-address nonallocated ELF case now succeeds for Rust while Go still reports invalid_format. No target execution or real compiler-artifact qualification was performed; no performance improvement is claimed.

Closes #3398
2026-10-21 11:58:15 +08:00

49 lines
1.9 KiB
TypeScript

import {
BinaryFormatFailure,
type BinaryContainer,
} from "./BinaryContainer.js";
import {
classifyFatContainerIdentity,
readFatContainerHeader,
} from "../../domain/apple/machoContainer.js";
import { readElfImage } from "./ElfImage.js";
import { readPeImage } from "./PeImage.js";
import { readMachoImage } from "./MachoImage.js";
/** Identify an ELF, PE, or thin Mach-O image and its named file sections. */
export const readBinaryContainer = (bytes: Buffer): BinaryContainer => {
if (bytes.subarray(0, 4).equals(Buffer.from([0x7f, 0x45, 0x4c, 0x46])))
return readElfImage(bytes);
if (bytes.subarray(0, 2).equals(Buffer.from("MZ"))) return readPeImage(bytes);
if (bytes.length >= 4) {
const magic = bytes.readUInt32BE();
if ([0xcafebabe, 0xcafebabf, 0xbebafeca, 0xbfbafeca].includes(magic)) {
const fatHeader = readFatContainerHeader(bytes, bytes.length);
if (fatHeader.state === "malformed")
throw new BinaryFormatFailure("malformed", fatHeader.reason);
const identity =
fatHeader.state === "parsed"
? classifyFatContainerIdentity(fatHeader, (offset) => {
if (offset >= bytes.length) return undefined;
if (offset + 4 > bytes.length) return null;
return bytes.readUInt32BE(offset);
})
: undefined;
// An invalid FAT-shaped table is not proof of a Mach-O container: JVM
// constant-pool bytes can share both the magic and a known CPU value.
const confirmedFatMachO = identity?.state === "mach-o";
if (confirmedFatMachO)
throw new BinaryFormatFailure(
"unsupported",
"Universal/fat Mach-O containers require selecting a thin slice",
);
}
if ([0xfeedface, 0xfeedfacf, 0xcefaedfe, 0xcffaedfe].includes(magic))
return readMachoImage(bytes);
}
throw new BinaryFormatFailure(
"unsupported",
"Only ELF, PE, and thin Mach-O native images are supported",
);
};