Files
reverse-engineering-anything/src/domain/native/nativeInspection.ts
T
morluto d4415444c4 fix(native): retain processor, hidden-slice and property type facts
Separate AMDGPU processors from feature-qualified note identities. Read Apple hidden ARM64 table rows once and preserve visibility through artifact, dylib and fuse consumers. Keep Objective-C++ template commas within type attributes and incomplete metadata unknown.

Validated provider/parser and production property regressions, Electron CLI/MCP consumers, and native Apple lipo -hideARM64 output through the production slice reader and public artifact inspection. LLVM execution remains unverified.

Fixes #6806

Fixes #6799

Fixes #6801
2026-10-24 01:00:14 +08:00

211 lines
6.6 KiB
TypeScript

import { z } from "zod";
import { bundleResourceRootSchema } from "../apple/bundleResourceRoot.js";
import { jsonValueSchema } from "../jsonValue.js";
const hexAddress = z.string().regex(/^0x[a-fA-F0-9]+$/u);
const coverage = <Schema extends z.ZodType>(item: Schema) =>
z.object({
items: z.array(item),
total: z.int().min(0).nullable(),
exhaustive: z.boolean(),
limitations: z.array(z.string()),
});
const nativeCommandInvocationSchema = z.object({
tool: z.string().min(1),
command: z.array(z.string()),
tool_version: z.string().nullable(),
version_reason: z.string().nullable(),
executable_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
exit: z.object({
code: z.int().nullable(),
signal: z.string().nullable(),
}),
stdout_bytes: z.int().min(0),
stderr_bytes: z.int().min(0),
});
const architectureSchema = z.object({
name: z.string(),
hidden: z.boolean().exactOptional(),
cpu_type: z.string().nullable(),
cpu_subtype: z.string().nullable(),
file_offset: z
.int()
.min(0)
.nullable()
.describe("Offset from the start of the input Mach-O container."),
size: z.int().min(0).nullable(),
alignment: z.int().min(0).nullable(),
});
const permissionSchema = z.object({
read: z.boolean().nullable(),
write: z.boolean().nullable(),
execute: z.boolean().nullable(),
raw: z.string().nullable(),
});
const sectionSchema = z.object({
segment: z.string(),
name: z.string(),
address: hexAddress.nullable(),
size: z.int().min(0).nullable(),
file_offset: z
.int()
.min(0)
.nullable()
.describe("Offset from the start of the selected Mach-O slice."),
alignment: z.int().min(0).nullable(),
flags: z.array(z.string()),
});
const segmentSchema = z.object({
name: z.string(),
vm_address: hexAddress.nullable(),
vm_size: z.int().min(0).nullable(),
file_offset: z
.int()
.min(0)
.nullable()
.describe("Offset from the start of the selected Mach-O slice."),
file_size: z.int().min(0).nullable(),
maximum_permissions: permissionSchema,
initial_permissions: permissionSchema,
sections: coverage(sectionSchema),
});
const symbolSchema = z.object({
name: z.string(),
address: hexAddress.nullable(),
weak: z.boolean().nullable(),
reexport: z.boolean().nullable(),
source: z.string().nullable(),
});
const importSymbolSchema = z.object({
/** Resolved symbol identity; null when the textual row has multiple parses. */
name: z.string().nullable(),
/** Exact import text retained when a chained suffix makes identity ambiguous. */
raw_name: z.string().nullable().default(null),
name_status: z.enum(["exact", "ambiguous"]).nullable().default(null),
/** Addend is unknown when only the ambiguous text expression is available. */
addend: hexAddress.nullable().default(null),
address: hexAddress.nullable(),
weak: z.boolean().nullable(),
reexport: z.boolean().nullable(),
source: z.string().nullable(),
});
const dependencySchema = z.object({
path: z.string(),
kind: z.string(),
current_version: z.string().nullable(),
compatibility_version: z.string().nullable(),
});
const loadCommandSchema = z.object({
index: z.int().min(0),
kind: z.string(),
fields: z.record(z.string(), z.union([z.string(), z.number(), z.null()])),
});
const buildMetadataSchema = z.object({
platform: z.string().nullable(),
minimum_os: z.string().nullable(),
sdk: z.string().nullable(),
tools: z.array(z.object({ name: z.string(), version: z.string() })),
});
export const inspectMachoSchema = z.object({
format: z.enum(["mach-o", "mach-o-universal"]),
/** Exact lipo slice selected for inspection and its offset in the input container. */
selected_architecture: z.object({
name: z
.string()
.nullable()
.describe(
"Exact architecture name selected from lipo output; null when selection is unknown.",
),
container_file_offset: z
.int()
.min(0)
.nullable()
.describe(
"Offset of the selected slice from the start of the input Mach-O container; null when unknown.",
),
}),
endian: z.enum(["little", "big"]).nullable(),
word_size: z.union([z.literal(32), z.literal(64)]).nullable(),
file_type: z.string().nullable(),
flags: z.array(z.string()),
uuid: z.string().nullable(),
entrypoints: coverage(
z.object({
file_offset: z
.int()
.min(0)
.describe(
"LC_MAIN entry offset from the start of the selected Mach-O slice.",
),
}),
),
architectures: coverage(architectureSchema),
build_metadata: coverage(buildMetadataSchema),
load_commands: coverage(loadCommandSchema),
dependencies: coverage(dependencySchema),
imports: coverage(importSymbolSchema),
exports: coverage(symbolSchema),
segments: coverage(segmentSchema),
provenance: z.array(nativeCommandInvocationSchema),
limitations: z.array(z.string()),
});
export const inspectSignatureSchema = z.object({
signed: z.boolean(),
identifier: z.string().nullable(),
team_identifier: z.string().nullable(),
format: z.string().nullable(),
cdhashes: z.array(z.string()),
hash_algorithms: z.array(z.string()),
authorities: z.array(z.string()),
designated_requirement: z.string().nullable(),
entitlements: jsonValueSchema.nullable(),
timestamp: z.string().nullable(),
hardened_runtime: z.boolean().nullable(),
provenance: z.array(nativeCommandInvocationSchema),
limitations: z.array(z.string()),
});
export const inspectPlistSchema = z.object({
format: z.enum(["xml", "binary", "json", "unknown"]),
value: jsonValueSchema,
bundle: z.object({
identifier: z.string().nullable(),
executable: z.string().nullable(),
name: z.string().nullable(),
version: z.string().nullable(),
short_version: z.string().nullable(),
}),
source_path: z.string(),
resource_root: bundleResourceRootSchema.optional(),
provenance: z.array(nativeCommandInvocationSchema),
limitations: z.array(z.string()),
});
export const listArchitecturesSchema = z.object({
architectures: coverage(architectureSchema),
provenance: z.array(nativeCommandInvocationSchema),
limitations: z.array(z.string()),
});
export const demangleSwiftSchema = z.object({
symbols: z.array(
z.object({
input: z.string(),
output: z.string(),
status: z.enum(["demangled", "unchanged", "invalid"]),
}),
),
provenance: z.array(nativeCommandInvocationSchema),
limitations: z.array(z.string()),
});
export type NativeCommandInvocation = z.infer<
typeof nativeCommandInvocationSchema
>;
export type InspectMacho = z.infer<typeof inspectMachoSchema>;
export type InspectSignature = z.infer<typeof inspectSignatureSchema>;