mirror of
https://github.com/morluto/rea.git
synced 2026-11-10 16:57:19 +00:00
Link original DEX native declarations to per-ABI function exports and relocated static JNI table candidates through shared CLI/MCP workflows. Preserve global attribution ambiguity, exact provenance, partial coverage and retained Evidence; default MCP delivery to bounded summaries with filtered/batch pages. Use one immutable ELF relocation decoder with streaming IL2CPP materialization, cooperative bounded export/version parsing and bounded JNI state. Reuse validated session inventories without loading target libraries or executing JNI code. Validation: relevant type/lint/build and parser/domain/public CLI/MCP regressions; genuine four-ABI NDK fixtures and independent library/slot oracles; actual JDK/JADX Conscrypt workflows with retained-source removal. Full measurements and limitations are recorded in docs/verification/android-jni-bindings-2026-10-27.md. Closes #6403.
63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
import { z } from "zod";
|
|
|
|
import { digestSchema } from "../digests.js";
|
|
import { jsonObjectSchema, jsonValueSchema } from "../jsonValue.js";
|
|
import { localPathStringSchema } from "../localPath.js";
|
|
import { androidJniPartialFactsSchema } from "./androidJniBindings.js";
|
|
|
|
const operationSchema = z.enum([
|
|
"inspect_android_package",
|
|
"inspect_android_jni_bindings",
|
|
"search_android_classes",
|
|
"inspect_android_class",
|
|
"inspect_android_method",
|
|
"trace_android_references",
|
|
]);
|
|
|
|
/** JSON-safe Android provider facts collected before an analysis failure. */
|
|
export const androidPartialObservationSchema = z
|
|
.strictObject({
|
|
provider_id: z.literal("jadx"),
|
|
operation: operationSchema,
|
|
target: z.strictObject({
|
|
selected_path: localPathStringSchema,
|
|
path: localPathStringSchema,
|
|
sha256: digestSchema,
|
|
format: z.literal("apk"),
|
|
}),
|
|
provider_facts: z.strictObject({
|
|
jar_sha256: digestSchema.nullable(),
|
|
bridge_sha256: digestSchema.nullable(),
|
|
bridge_name: z.string().min(1),
|
|
bridge_version: z.string().min(1),
|
|
server_name: z.string().nullable(),
|
|
server_version: z.string().nullable(),
|
|
engine_version: z.string().min(1).nullable(),
|
|
}),
|
|
calls: z.array(
|
|
z.strictObject({
|
|
operation: z.string().min(1),
|
|
input: jsonObjectSchema,
|
|
response: jsonValueSchema,
|
|
}),
|
|
),
|
|
jni: androidJniPartialFactsSchema.optional(),
|
|
})
|
|
.superRefine((observation, context) => {
|
|
if (
|
|
observation.jni !== undefined &&
|
|
observation.operation !== "inspect_android_jni_bindings"
|
|
)
|
|
context.addIssue({
|
|
code: "custom",
|
|
path: ["jni"],
|
|
message:
|
|
"Parsed JNI facts belong only to inspect_android_jni_bindings observations",
|
|
});
|
|
});
|
|
|
|
/** JSON-safe Android provider facts retained when analysis fails. */
|
|
export type AndroidPartialObservation = z.infer<
|
|
typeof androidPartialObservationSchema
|
|
>;
|