mirror of
https://github.com/morluto/rea
synced 2026-10-25 22:08:11 -04:00
53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
import type { Evidence } from "../evidence.js";
|
|
import type { FunctionDossier } from "../hopperValues.js";
|
|
import { digestCanonicalValue } from "../canonicalDigest.js";
|
|
import { normalizeCfg } from "../functionComparisonNormalization.js";
|
|
import { hasStableNativeSymbol } from "./nativeSymbol.js";
|
|
import { assessFunctionCallCoverage } from "../functionCallCoverage.js";
|
|
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
|
|
/** An observed structural signature proposes candidates; it never proves identity. */
|
|
export const functionStructuralCandidate = (
|
|
evidence: Evidence,
|
|
dossier: FunctionDossier,
|
|
): string | null => {
|
|
if (
|
|
evidence.subject?.architecture == null ||
|
|
dossier.facet_availability?.cfg?.available !== true ||
|
|
dossier.facet_availability?.callees?.available !== true ||
|
|
dossier.facet_availability?.strings_names?.available !== true ||
|
|
dossier.unresolved_calls === undefined ||
|
|
assessFunctionCallCoverage(evidence.relationship_coverage, dossier).blockers
|
|
.length > 0 ||
|
|
(dossier.swift_string_literal_omissions?.length ?? 0) > 0 ||
|
|
evidence.analysis_profile === null
|
|
)
|
|
return null;
|
|
const cfg = normalizeCfg(dossier.basic_blocks);
|
|
if (
|
|
cfg === null ||
|
|
cfg.length === 0 ||
|
|
dossier.callees.some(
|
|
(callee) => !hasStableNativeSymbol(callee.name, callee.symbol),
|
|
)
|
|
)
|
|
return null;
|
|
const calls = dossier.callees
|
|
.map((callee) => callee.name)
|
|
.sort(compareUnicodeCodePoints);
|
|
const strings = [
|
|
...dossier.referenced_strings.map((value) => value.value),
|
|
...(dossier.swift_string_literals ?? []).map((value) => value.value),
|
|
].sort(compareUnicodeCodePoints);
|
|
// Empty leaf functions otherwise produce huge uninformative CFG-only buckets.
|
|
if (calls.length === 0 && strings.length === 0) return null;
|
|
return digestCanonicalValue({
|
|
algorithm: "observed-cfg-calls-strings-v1",
|
|
profile: evidence.analysis_profile.digest,
|
|
architecture: evidence.subject.architecture,
|
|
cfg,
|
|
calls,
|
|
strings,
|
|
});
|
|
};
|