rea-agents 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -21
- package/bridge/hopper_bridge.py +156 -14
- package/dist/application/AnalysisProvider.js +12 -1
- package/dist/application/ArtifactExtraction.js +166 -0
- package/dist/application/ArtifactGraphConstruction.js +257 -0
- package/dist/application/ArtifactInventory.js +253 -0
- package/dist/application/BinarySession.js +174 -14
- package/dist/application/CompositeProvider.js +73 -0
- package/dist/application/DirectAnalysis.js +44 -3
- package/dist/application/Doctor.js +35 -6
- package/dist/application/EnhancedTools.js +10 -7
- package/dist/application/EvidenceBundleCommands.js +51 -0
- package/dist/application/EvidenceBundleFiles.js +127 -0
- package/dist/application/EvidenceLedger.js +225 -18
- package/dist/application/FilesystemSnapshot.js +124 -0
- package/dist/application/LinuxHopper.js +186 -0
- package/dist/application/LoopbackReplay.js +195 -37
- package/dist/application/ProcessHarness.js +200 -191
- package/dist/application/ProcessNormalization.js +44 -0
- package/dist/application/ProcessOwnership.js +105 -0
- package/dist/application/ProcessSampling.js +284 -0
- package/dist/application/RealHopperAssertions.js +116 -0
- package/dist/application/ReferenceSourceImport.js +182 -0
- package/dist/application/ReferenceSourceImportEntries.js +122 -0
- package/dist/application/ReferenceSourceImportPolicy.js +73 -0
- package/dist/application/ReferenceSourceImportTypes.js +18 -0
- package/dist/application/ReferenceSourceVcsAdapter.js +34 -0
- package/dist/application/Setup.js +192 -41
- package/dist/application/Uninstall.js +130 -0
- package/dist/application/runtime.js +8 -1
- package/dist/artifacts/ArtifactPaths.js +51 -0
- package/dist/artifacts/ArtifactProvider.js +130 -0
- package/dist/artifacts/ArtifactReader.js +9 -0
- package/dist/artifacts/AsarArtifactReader.js +62 -0
- package/dist/artifacts/DirectoryArtifactReader.js +107 -0
- package/dist/artifacts/MachOSliceArtifactReader.js +66 -0
- package/dist/artifacts/SafeOutputTree.js +199 -0
- package/dist/artifacts/StreamBytes.js +10 -0
- package/dist/artifacts/ZipArtifactReader.js +109 -0
- package/dist/cli.js +229 -21
- package/dist/cliEvidenceCommands.js +68 -0
- package/dist/cliLogging.js +21 -0
- package/dist/config.js +35 -1
- package/dist/contracts/artifactComparisonExample.js +95 -0
- package/dist/contracts/artifactToolContracts.js +84 -0
- package/dist/contracts/enhancedInputs.js +4 -0
- package/dist/contracts/functionComparisonExample.js +57 -0
- package/dist/contracts/investigationExamples.js +118 -0
- package/dist/contracts/nativeToolContracts.js +52 -0
- package/dist/contracts/processCaptureExample.js +25 -0
- package/dist/contracts/toolContractExamples.js +69 -0
- package/dist/contracts/toolContracts.js +99 -36
- package/dist/contracts/toolOutputSchemas.js +156 -82
- package/dist/contracts/unknownContractExamples.js +33 -0
- package/dist/domain/artifactComparison.js +273 -0
- package/dist/domain/artifactGraph.js +194 -0
- package/dist/domain/artifactInventoryEvidence.js +150 -0
- package/dist/domain/binaryTarget.js +55 -0
- package/dist/domain/bundleComparison.js +266 -0
- package/dist/domain/callPath.js +346 -0
- package/dist/domain/changedBehavior.js +294 -0
- package/dist/domain/errors.js +199 -5
- package/dist/domain/evidence.js +41 -10
- package/dist/domain/evidenceBundle.js +187 -6
- package/dist/domain/functionComparison.js +201 -0
- package/dist/domain/functionComparisonNormalization.js +112 -0
- package/dist/domain/functionComparisonResults.js +54 -0
- package/dist/domain/functionComparisonSchemas.js +82 -0
- package/dist/domain/functionDossierEvidence.js +171 -0
- package/dist/domain/hopperValues.js +35 -8
- package/dist/domain/nativeInspection.js +142 -0
- package/dist/domain/processCapture.js +152 -54
- package/dist/domain/processComparison.js +106 -0
- package/dist/domain/reconstructionUnknowns.js +90 -0
- package/dist/domain/reconstructionVerification.js +285 -0
- package/dist/domain/reconstructionVerificationSchemas.js +126 -0
- package/dist/domain/referenceSourceClassification.js +496 -0
- package/dist/domain/referenceSourceGraph.js +376 -0
- package/dist/domain/referenceSourceImportParsing.js +235 -0
- package/dist/domain/referenceSourcePolicy.js +1 -0
- package/dist/domain/residualUnknown.js +239 -0
- package/dist/domain/staticRuntimeCorrelation.js +375 -0
- package/dist/hopper/BridgeLauncher.js +39 -3
- package/dist/hopper/HopperClient.js +14 -5
- package/dist/hopper/HopperProvider.js +57 -22
- package/dist/hopper/protocol.js +13 -2
- package/dist/identity.js +1 -0
- package/dist/main.js +5 -1
- package/dist/native/CommandRunner.js +156 -0
- package/dist/native/NativeMacOSProvider.js +306 -0
- package/dist/native/NativeMachoInspection.js +135 -0
- package/dist/native/parsers/codesign.js +55 -0
- package/dist/native/parsers/demangle.js +26 -0
- package/dist/native/parsers/dyldInfo.js +25 -0
- package/dist/native/parsers/lipo.js +67 -0
- package/dist/native/parsers/otool.js +193 -0
- package/dist/native/parsers/plist.js +23 -0
- package/dist/reference/ReferenceSourceReader.js +73 -0
- package/dist/reference/ReferenceSourceReaderEntries.js +206 -0
- package/dist/reference/ReferenceSourceReaderErrors.js +19 -0
- package/dist/reference/ReferenceSourceReaderFile.js +119 -0
- package/dist/reference/ReferenceSourceReaderPaths.js +23 -0
- package/dist/reference/ReferenceSourceReaderTypes.js +2 -0
- package/dist/reference/ReferenceSourceReaderValidate.js +71 -0
- package/dist/server/createServer.js +31 -5
- package/dist/server/recordDerivedEvidence.js +10 -0
- package/dist/server/registerArtifactComparisonTool.js +62 -0
- package/dist/server/registerArtifactTools.js +6 -0
- package/dist/server/registerBundleComparisonTool.js +47 -0
- package/dist/server/registerEnhancedTools.js +64 -12
- package/dist/server/registerEvidenceTools.js +36 -0
- package/dist/server/registerFunctionComparisonTool.js +68 -0
- package/dist/server/registerInvestigationTools.js +224 -0
- package/dist/server/registerNativeTools.js +6 -0
- package/dist/server/registerOfficialTools.js +47 -14
- package/dist/server/registerProcessComparisonTool.js +106 -0
- package/dist/server/registerSessionTools.js +179 -70
- package/dist/server/sessionEvidence.js +28 -0
- package/dist/server/sessionToolPolicies.js +64 -0
- package/dist/server/toolRegistrationOptions.js +7 -0
- package/dist/server/toolResult.js +8 -5
- package/install.sh +198 -0
- package/package.json +18 -1
- package/scripts/rea.mjs +5 -1
- package/skills/rea-analysis/SKILL.md +77 -2
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import canonicalize from "canonicalize";
|
|
2
|
+
import { enhancedInputSchemas } from "../contracts/enhancedInputs.js";
|
|
3
|
+
import { parseEvidence } from "./evidence.js";
|
|
4
|
+
import { functionDossierSchema } from "./hopperValues.js";
|
|
5
|
+
const MAX_PAGES = 100;
|
|
6
|
+
const MAX_ITEMS = 50_000;
|
|
7
|
+
const MAX_PSEUDOCODE_CHARS = 2_000_000;
|
|
8
|
+
const DOSSIER_COLLECTION_FIELDS = [
|
|
9
|
+
"assembly",
|
|
10
|
+
"comments",
|
|
11
|
+
"callers",
|
|
12
|
+
"callees",
|
|
13
|
+
"incoming_references",
|
|
14
|
+
"outgoing_references",
|
|
15
|
+
"referenced_strings",
|
|
16
|
+
"referenced_names",
|
|
17
|
+
"basic_blocks",
|
|
18
|
+
];
|
|
19
|
+
/** Parse and assemble up to 100 mutually consistent analyze_function pages. */
|
|
20
|
+
export const parseFunctionEvidence = (input) => {
|
|
21
|
+
const values = Array.isArray(input) ? input : [input];
|
|
22
|
+
if (values.length === 0 || values.length > MAX_PAGES)
|
|
23
|
+
throw new TypeError("Function comparison requires 1 to 100 Evidence pages");
|
|
24
|
+
const pages = values.map(parsePage);
|
|
25
|
+
assertPageGroup(pages);
|
|
26
|
+
const first = pages[0];
|
|
27
|
+
if (first === undefined)
|
|
28
|
+
throw new TypeError("Function comparison requires Evidence pages");
|
|
29
|
+
const pseudocode = mergePseudocode(pages);
|
|
30
|
+
const collections = {
|
|
31
|
+
assembly: mergeCollection(pages, "assembly"),
|
|
32
|
+
comments: mergeCollection(pages, "comments"),
|
|
33
|
+
callers: mergeCollection(pages, "callers"),
|
|
34
|
+
callees: mergeCollection(pages, "callees"),
|
|
35
|
+
incoming_references: mergeCollection(pages, "incoming_references"),
|
|
36
|
+
outgoing_references: mergeCollection(pages, "outgoing_references"),
|
|
37
|
+
referenced_strings: mergeCollection(pages, "referenced_strings"),
|
|
38
|
+
referenced_names: mergeCollection(pages, "referenced_names"),
|
|
39
|
+
basic_blocks: mergeCollection(pages, "basic_blocks"),
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
evidence: pages.map(({ evidence }) => evidence),
|
|
43
|
+
procedure: first.dossier.procedure,
|
|
44
|
+
provider: first.evidence.provider,
|
|
45
|
+
subject: first.evidence.subject,
|
|
46
|
+
pseudocode,
|
|
47
|
+
collections,
|
|
48
|
+
instructionScan: first.dossier.instruction_scan,
|
|
49
|
+
limitations: [
|
|
50
|
+
...new Set(pages.flatMap(({ evidence }) => evidence.limitations)),
|
|
51
|
+
].sort((left, right) => left.localeCompare(right)),
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
const parsePage = (input) => {
|
|
55
|
+
const evidence = parseEvidence(input);
|
|
56
|
+
if (evidence.operation !== "analyze_function")
|
|
57
|
+
throw new TypeError("Function comparison requires analyze_function Evidence");
|
|
58
|
+
if (evidence.subject === null)
|
|
59
|
+
throw new TypeError("Function comparison requires artifact-bound Evidence");
|
|
60
|
+
return {
|
|
61
|
+
evidence: { ...evidence, subject: evidence.subject },
|
|
62
|
+
dossier: functionDossierSchema.parse(evidence.normalized_result),
|
|
63
|
+
parameters: enhancedInputSchemas.analyze_function.parse(evidence.parameters),
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
const assertPageGroup = (pages) => {
|
|
67
|
+
const first = pages[0];
|
|
68
|
+
if (first === undefined)
|
|
69
|
+
return;
|
|
70
|
+
const invariant = pageInvariant(first);
|
|
71
|
+
for (const page of pages)
|
|
72
|
+
if (canonicalJson(pageInvariant(page)) !== canonicalJson(invariant))
|
|
73
|
+
throw new TypeError("Function Evidence pages mix subjects, providers, or immutable analysis controls");
|
|
74
|
+
};
|
|
75
|
+
const pageInvariant = (page) => ({
|
|
76
|
+
subject: {
|
|
77
|
+
digest: page.evidence.subject?.digest,
|
|
78
|
+
format: page.evidence.subject?.format,
|
|
79
|
+
architecture: page.evidence.subject?.architecture,
|
|
80
|
+
},
|
|
81
|
+
provider: page.evidence.provider,
|
|
82
|
+
procedure: page.dossier.procedure,
|
|
83
|
+
requested_procedure: page.parameters.procedure,
|
|
84
|
+
include_assembly: page.parameters.include_assembly,
|
|
85
|
+
max_instructions: page.parameters.max_instructions,
|
|
86
|
+
instruction_scan: page.dossier.instruction_scan,
|
|
87
|
+
});
|
|
88
|
+
const mergePseudocode = (pages) => {
|
|
89
|
+
const totals = new Set(pages.map(({ dossier }) => dossier.pseudocode.total_chars));
|
|
90
|
+
if (totals.size !== 1)
|
|
91
|
+
throw new TypeError("Function pseudocode pages disagree on total length");
|
|
92
|
+
const total = pages[0]?.dossier.pseudocode.total_chars ?? 0;
|
|
93
|
+
if (total > MAX_PSEUDOCODE_CHARS)
|
|
94
|
+
throw new TypeError("Function pseudocode exceeds comparison limit");
|
|
95
|
+
const characters = new Map();
|
|
96
|
+
for (const page of pages) {
|
|
97
|
+
const offset = page.parameters.pseudocode_offset;
|
|
98
|
+
for (const [index, character] of [
|
|
99
|
+
...page.dossier.pseudocode.text,
|
|
100
|
+
].entries())
|
|
101
|
+
mergeIndexed(characters, offset + index, character, "pseudocode");
|
|
102
|
+
if (characters.size > MAX_PSEUDOCODE_CHARS)
|
|
103
|
+
throw new TypeError("Function pseudocode exceeds comparison limit");
|
|
104
|
+
}
|
|
105
|
+
const complete = hasCompleteRange(characters, total);
|
|
106
|
+
return {
|
|
107
|
+
text: orderedValues(characters).join(""),
|
|
108
|
+
total,
|
|
109
|
+
complete,
|
|
110
|
+
truncated: !complete,
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
const mergeCollection = (pages, field) => {
|
|
114
|
+
const totals = new Set(pages.map(({ dossier }) => dossier[field].total));
|
|
115
|
+
if (totals.size !== 1)
|
|
116
|
+
throw new TypeError(`Function ${field} pages disagree on total count`);
|
|
117
|
+
const total = pages[0]?.dossier[field].total ?? null;
|
|
118
|
+
if (total !== null && total > MAX_ITEMS)
|
|
119
|
+
throw new TypeError(`Function ${field} exceeds comparison item limit`);
|
|
120
|
+
const items = new Map();
|
|
121
|
+
for (const page of pages) {
|
|
122
|
+
const offset = collectionOffset(page, field);
|
|
123
|
+
for (const [index, item] of page.dossier[field].items.entries())
|
|
124
|
+
mergeIndexed(items, offset + index, item, field);
|
|
125
|
+
if (items.size > MAX_ITEMS)
|
|
126
|
+
throw new TypeError(`Function ${field} exceeds comparison item limit`);
|
|
127
|
+
}
|
|
128
|
+
const scanLimited = field !== "assembly" && pageDependsOnScan(field)
|
|
129
|
+
? pages.some(({ dossier }) => dossier.instruction_scan.truncated)
|
|
130
|
+
: false;
|
|
131
|
+
const unavailable = field === "assembly" &&
|
|
132
|
+
pages.every(({ parameters }) => !parameters.include_assembly);
|
|
133
|
+
const complete = !scanLimited &&
|
|
134
|
+
!unavailable &&
|
|
135
|
+
total !== null &&
|
|
136
|
+
hasCompleteRange(items, total);
|
|
137
|
+
return {
|
|
138
|
+
items: orderedValues(items),
|
|
139
|
+
total,
|
|
140
|
+
complete,
|
|
141
|
+
truncated: scanLimited || (!unavailable && !complete),
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
const collectionOffset = (page, field) => field === "assembly"
|
|
145
|
+
? page.parameters.assembly_offset
|
|
146
|
+
: page.parameters.collection_offset[field];
|
|
147
|
+
const pageDependsOnScan = (field) => field !== "callers" && field !== "callees";
|
|
148
|
+
const mergeIndexed = (output, index, value, field) => {
|
|
149
|
+
const previous = output.get(index);
|
|
150
|
+
if (previous !== undefined &&
|
|
151
|
+
canonicalJson(previous) !== canonicalJson(value))
|
|
152
|
+
throw new TypeError(`Function ${field} pages overlap with conflicting data`);
|
|
153
|
+
output.set(index, value);
|
|
154
|
+
};
|
|
155
|
+
const hasCompleteRange = (values, total) => {
|
|
156
|
+
if (values.size !== total)
|
|
157
|
+
return false;
|
|
158
|
+
for (let index = 0; index < total; index += 1)
|
|
159
|
+
if (!values.has(index))
|
|
160
|
+
return false;
|
|
161
|
+
return true;
|
|
162
|
+
};
|
|
163
|
+
const orderedValues = (values) => [...values.entries()]
|
|
164
|
+
.sort(([left], [right]) => left - right)
|
|
165
|
+
.map(([, value]) => value);
|
|
166
|
+
const canonicalJson = (value) => {
|
|
167
|
+
const encoded = canonicalize(value);
|
|
168
|
+
if (encoded === undefined)
|
|
169
|
+
throw new TypeError("Function Evidence could not be canonicalized");
|
|
170
|
+
return encoded;
|
|
171
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
2
|
+
import { AnalysisOutputError, HopperProtocolError } from "./errors.js";
|
|
3
3
|
import { err, ok } from "./result.js";
|
|
4
4
|
const procedureMapSchema = z.record(z.string(), z.string());
|
|
5
5
|
const addressedNamesSchema = z.array(z.object({ address: z.string(), name: z.string() }));
|
|
@@ -8,11 +8,34 @@ const segmentSchema = z.object({
|
|
|
8
8
|
name: z.string().default(""),
|
|
9
9
|
start: z.string().default(""),
|
|
10
10
|
end: z.string().default(""),
|
|
11
|
+
readable: z.boolean().nullable().default(null),
|
|
12
|
+
writable: z.boolean().nullable().default(null),
|
|
13
|
+
executable: z.boolean().nullable().default(null),
|
|
11
14
|
});
|
|
12
|
-
const addressedPageSchema = z
|
|
15
|
+
const addressedPageSchema = z
|
|
16
|
+
.object({
|
|
13
17
|
items: z.array(z.object({ address: z.string(), value: z.string() })),
|
|
18
|
+
offset: z.number().int().min(0),
|
|
19
|
+
limit: z.number().int().min(1),
|
|
20
|
+
total: z.number().int().min(0),
|
|
14
21
|
next_offset: z.number().int().min(0).nullable(),
|
|
15
22
|
has_more: z.boolean(),
|
|
23
|
+
})
|
|
24
|
+
.superRefine((value, context) => {
|
|
25
|
+
if (value.has_more && value.next_offset === null) {
|
|
26
|
+
context.addIssue({
|
|
27
|
+
code: "custom",
|
|
28
|
+
message: "a page with more results must provide next_offset",
|
|
29
|
+
path: ["next_offset"],
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (!value.has_more && value.next_offset !== null) {
|
|
33
|
+
context.addIssue({
|
|
34
|
+
code: "custom",
|
|
35
|
+
message: "a complete page must not provide next_offset",
|
|
36
|
+
path: ["next_offset"],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
16
39
|
});
|
|
17
40
|
const unavailableSchema = z
|
|
18
41
|
.object({ available: z.literal(false), reason: z.string() })
|
|
@@ -20,6 +43,12 @@ const unavailableSchema = z
|
|
|
20
43
|
const procedureIdentitySchema = z
|
|
21
44
|
.object({ address: z.string(), name: z.string() })
|
|
22
45
|
.strict();
|
|
46
|
+
const localVariableSchema = z
|
|
47
|
+
.object({
|
|
48
|
+
description: z.string(),
|
|
49
|
+
provenance: z.literal("hopper-public-python-api"),
|
|
50
|
+
})
|
|
51
|
+
.strict();
|
|
23
52
|
const boundedSchema = (item) => z
|
|
24
53
|
.object({
|
|
25
54
|
items: z.array(item),
|
|
@@ -61,14 +90,14 @@ const referenceEdgeSchema = z
|
|
|
61
90
|
kind: unavailableSchema,
|
|
62
91
|
})
|
|
63
92
|
.strict();
|
|
64
|
-
const functionDossierSchema = z
|
|
93
|
+
export const functionDossierSchema = z
|
|
65
94
|
.object({
|
|
66
95
|
procedure: z
|
|
67
96
|
.object({
|
|
68
97
|
address: z.string(),
|
|
69
98
|
name: z.string(),
|
|
70
99
|
signature: z.string().nullable(),
|
|
71
|
-
locals: z.array(
|
|
100
|
+
locals: z.array(localVariableSchema),
|
|
72
101
|
})
|
|
73
102
|
.strict(),
|
|
74
103
|
pseudocode: z
|
|
@@ -81,7 +110,7 @@ const functionDossierSchema = z
|
|
|
81
110
|
})
|
|
82
111
|
.strict()
|
|
83
112
|
.superRefine((value, context) => {
|
|
84
|
-
if (value.returned_chars !== value.text.length) {
|
|
113
|
+
if (value.returned_chars !== [...value.text].length) {
|
|
85
114
|
context.addIssue({
|
|
86
115
|
code: "custom",
|
|
87
116
|
message: "returned_chars must equal the text length",
|
|
@@ -146,9 +175,7 @@ export const parseFunctionDossier = (value) => {
|
|
|
146
175
|
const parsed = functionDossierSchema.safeParse(value);
|
|
147
176
|
return parsed.success
|
|
148
177
|
? ok(parsed.data)
|
|
149
|
-
: err(new
|
|
150
|
-
cause: parsed.error,
|
|
151
|
-
}));
|
|
178
|
+
: err(new AnalysisOutputError("analyze_function", "provider output did not match the dossier contract", { cause: parsed.error }));
|
|
152
179
|
};
|
|
153
180
|
/** Parse page entries and continuation metadata returned by list operations. */
|
|
154
181
|
export const parseAddressedPage = (value) => {
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const hexAddress = z.string().regex(/^0x[a-fA-F0-9]+$/u);
|
|
3
|
+
const coverage = (item) => z.object({
|
|
4
|
+
items: z.array(item),
|
|
5
|
+
total: z.number().int().min(0).nullable(),
|
|
6
|
+
exhaustive: z.boolean(),
|
|
7
|
+
limitations: z.array(z.string()),
|
|
8
|
+
});
|
|
9
|
+
const nativeCommandInvocationSchema = z.object({
|
|
10
|
+
tool: z.string().min(1),
|
|
11
|
+
command: z.array(z.string()),
|
|
12
|
+
tool_version: z.string().nullable(),
|
|
13
|
+
version_reason: z.string().nullable(),
|
|
14
|
+
executable_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
|
|
15
|
+
exit: z.object({
|
|
16
|
+
code: z.number().int().nullable(),
|
|
17
|
+
signal: z.string().nullable(),
|
|
18
|
+
}),
|
|
19
|
+
stdout_bytes: z.number().int().min(0),
|
|
20
|
+
stderr_bytes: z.number().int().min(0),
|
|
21
|
+
stdout_truncated: z.boolean(),
|
|
22
|
+
stderr_truncated: z.boolean(),
|
|
23
|
+
});
|
|
24
|
+
const architectureSchema = z.object({
|
|
25
|
+
name: z.string(),
|
|
26
|
+
cpu_type: z.string().nullable(),
|
|
27
|
+
cpu_subtype: z.string().nullable(),
|
|
28
|
+
file_offset: z.number().int().min(0).nullable(),
|
|
29
|
+
size: z.number().int().min(0).nullable(),
|
|
30
|
+
alignment: z.number().int().min(0).nullable(),
|
|
31
|
+
});
|
|
32
|
+
const permissionSchema = z.object({
|
|
33
|
+
read: z.boolean().nullable(),
|
|
34
|
+
write: z.boolean().nullable(),
|
|
35
|
+
execute: z.boolean().nullable(),
|
|
36
|
+
raw: z.string().nullable(),
|
|
37
|
+
});
|
|
38
|
+
const sectionSchema = z.object({
|
|
39
|
+
segment: z.string(),
|
|
40
|
+
name: z.string(),
|
|
41
|
+
address: hexAddress.nullable(),
|
|
42
|
+
size: z.number().int().min(0).nullable(),
|
|
43
|
+
file_offset: z.number().int().min(0).nullable(),
|
|
44
|
+
alignment: z.number().int().min(0).nullable(),
|
|
45
|
+
flags: z.array(z.string()),
|
|
46
|
+
});
|
|
47
|
+
const segmentSchema = z.object({
|
|
48
|
+
name: z.string(),
|
|
49
|
+
vm_address: hexAddress.nullable(),
|
|
50
|
+
vm_size: z.number().int().min(0).nullable(),
|
|
51
|
+
file_offset: z.number().int().min(0).nullable(),
|
|
52
|
+
file_size: z.number().int().min(0).nullable(),
|
|
53
|
+
maximum_permissions: permissionSchema,
|
|
54
|
+
initial_permissions: permissionSchema,
|
|
55
|
+
sections: coverage(sectionSchema),
|
|
56
|
+
});
|
|
57
|
+
const symbolSchema = z.object({
|
|
58
|
+
name: z.string(),
|
|
59
|
+
address: hexAddress.nullable(),
|
|
60
|
+
weak: z.boolean().nullable(),
|
|
61
|
+
reexport: z.boolean().nullable(),
|
|
62
|
+
source: z.string().nullable(),
|
|
63
|
+
});
|
|
64
|
+
const dependencySchema = z.object({
|
|
65
|
+
path: z.string(),
|
|
66
|
+
kind: z.string(),
|
|
67
|
+
current_version: z.string().nullable(),
|
|
68
|
+
compatibility_version: z.string().nullable(),
|
|
69
|
+
});
|
|
70
|
+
const loadCommandSchema = z.object({
|
|
71
|
+
index: z.number().int().min(0),
|
|
72
|
+
kind: z.string(),
|
|
73
|
+
file_offset: z.number().int().min(0).nullable(),
|
|
74
|
+
fields: z.record(z.string(), z.union([z.string(), z.number(), z.null()])),
|
|
75
|
+
});
|
|
76
|
+
const buildMetadataSchema = z.object({
|
|
77
|
+
platform: z.string().nullable(),
|
|
78
|
+
minimum_os: z.string().nullable(),
|
|
79
|
+
sdk: z.string().nullable(),
|
|
80
|
+
tools: z.array(z.object({ name: z.string(), version: z.string() })),
|
|
81
|
+
});
|
|
82
|
+
export const inspectMachoSchema = z.object({
|
|
83
|
+
format: z.literal("mach-o"),
|
|
84
|
+
endian: z.enum(["little", "big"]).nullable(),
|
|
85
|
+
word_size: z.union([z.literal(32), z.literal(64)]).nullable(),
|
|
86
|
+
file_type: z.string().nullable(),
|
|
87
|
+
flags: z.array(z.string()),
|
|
88
|
+
uuid: z.string().nullable(),
|
|
89
|
+
entrypoints: coverage(z.object({ file_offset: z.number().int().min(0) })),
|
|
90
|
+
architectures: coverage(architectureSchema),
|
|
91
|
+
build_metadata: coverage(buildMetadataSchema),
|
|
92
|
+
load_commands: coverage(loadCommandSchema),
|
|
93
|
+
dependencies: coverage(dependencySchema),
|
|
94
|
+
imports: coverage(symbolSchema),
|
|
95
|
+
exports: coverage(symbolSchema),
|
|
96
|
+
segments: coverage(segmentSchema),
|
|
97
|
+
provenance: z.array(nativeCommandInvocationSchema),
|
|
98
|
+
limitations: z.array(z.string()),
|
|
99
|
+
});
|
|
100
|
+
export const inspectSignatureSchema = z.object({
|
|
101
|
+
signed: z.boolean(),
|
|
102
|
+
identifier: z.string().nullable(),
|
|
103
|
+
team_identifier: z.string().nullable(),
|
|
104
|
+
format: z.string().nullable(),
|
|
105
|
+
cdhashes: z.array(z.string()),
|
|
106
|
+
hash_algorithms: z.array(z.string()),
|
|
107
|
+
authorities: z.array(z.string()),
|
|
108
|
+
designated_requirement: z.string().nullable(),
|
|
109
|
+
entitlements: z.unknown().nullable(),
|
|
110
|
+
timestamp: z.string().nullable(),
|
|
111
|
+
hardened_runtime: z.boolean().nullable(),
|
|
112
|
+
provenance: z.array(nativeCommandInvocationSchema),
|
|
113
|
+
limitations: z.array(z.string()),
|
|
114
|
+
});
|
|
115
|
+
export const inspectPlistSchema = z.object({
|
|
116
|
+
format: z.enum(["xml", "binary", "json", "unknown"]),
|
|
117
|
+
value: z.unknown(),
|
|
118
|
+
bundle: z.object({
|
|
119
|
+
identifier: z.string().nullable(),
|
|
120
|
+
executable: z.string().nullable(),
|
|
121
|
+
name: z.string().nullable(),
|
|
122
|
+
version: z.string().nullable(),
|
|
123
|
+
short_version: z.string().nullable(),
|
|
124
|
+
}),
|
|
125
|
+
source_path: z.string(),
|
|
126
|
+
provenance: z.array(nativeCommandInvocationSchema),
|
|
127
|
+
limitations: z.array(z.string()),
|
|
128
|
+
});
|
|
129
|
+
export const listArchitecturesSchema = z.object({
|
|
130
|
+
architectures: coverage(architectureSchema),
|
|
131
|
+
provenance: z.array(nativeCommandInvocationSchema),
|
|
132
|
+
limitations: z.array(z.string()),
|
|
133
|
+
});
|
|
134
|
+
export const demangleSwiftSchema = z.object({
|
|
135
|
+
symbols: z.array(z.object({
|
|
136
|
+
input: z.string(),
|
|
137
|
+
output: z.string(),
|
|
138
|
+
status: z.enum(["demangled", "unchanged", "invalid"]),
|
|
139
|
+
})),
|
|
140
|
+
provenance: z.array(nativeCommandInvocationSchema),
|
|
141
|
+
limitations: z.array(z.string()),
|
|
142
|
+
});
|