Files
rea/src/cli/coreNativeCommands.ts
T
Matt Van Horn 9dde3fd6a4 fix(cli): advertise required CLI selector choices (#6759)
* fix(artifacts): retain caller selection and applicable publication recovery

* fix(artifacts): retain DMG producer failures and bound integrity recovery claims

* fix(apk): classify malformed supported Zip64 records as input failures

* fix(browser): compare script and tool facts without metadata identity churn

* fix(environment): retain path segments counters and parent diagnostics

* fix(discovery): retain Frida optional provider failure dispatch

* test(native): share Swift context in vtable fixture admission

* fix(native): narrow capability refusal before retaining its reason

* fix(javascript): retain private receiver and iterative disposal effects

* fix(native): preserve negative Mach-O admission identity

* fix(javascript): bind Next page admission to source context

* fix: preserve process filesystem scope and admission failures

* fix(evidence): reject runtime locations for managed static facts

* fix(hopper): bind ordinary executable opens to selected bytes

* fix(browser): admit legacy capture uncertainty at retained input boundaries

* fix(unknowns): distinguish rejected creation from committed mutation delivery

* fix(evidence): preserve authentication failures and diagnose prior commitments

* fix(cli): preserve explicit Evidence record pairing in bundle comparison

* fix(artifacts): publish addressable inspection sources through both adapters

* docs(evidence): define authentication and committed delivery recovery

* fix(javascript): own reference roles and invocation result identities

* fix(hopper): pass private X authority cookie through stdin

* fix(ghidra): preserve catalog and metadata admission failures

* fix(jeb): retain selected inputs and completed primary replies

* fix(native): preserve literal environment map members

* test: retain direct hash cleanup retainer contract

* test: distinguish corrected port normalization commitment

* fix: recheck attached worker policy after final artifacts

* fix(javascript): share iteration and equality invocation facts

* fix(artifacts): preserve typed resource limit diagnoses

* fix(javascript): preserve semantic query identity and source coverage

* docs(readme): align translated setup and analysis facts

* fix(cli): reject surplus positional arguments before execution

* fix(kuna): retain setting-specific doctor recovery

* fix(setup): preserve semantic configuration refusal during uninstall

* fix(setup): retain publication operation failures and recovery facts

* fix(setup): distinguish Hopper inspection and archive staging failures

* docs(managed): distinguish oracle conformance from host verification

* docs(skill): keep one setup prerequisite policy

* fix(firmware): preserve admission and extraction coverage outcomes

* fix(contracts): preserve safe defaults and client literal guidance

* fix(javascript): retain worker storage and projection failures

* fix(evidence): preserve valid output paths near filesystem pathname limits

* fix(cli): accept named native API selectors beginning with a dash

* fix(artifacts): retain DMG carrier observations when child traversal is unavailable

* fix(artifacts): retain dylib enumeration readers through failed cleanup

* fix(browser): resolve empty storage-world origins from exact frame evidence

* fix(browser): retain unknown popup storage initialization coverage

* test(reconstruction): isolate derived surface ownership in fixtures

* test(filesystem): probe actual permission denial before host assertions

* test(managed): assert large issue retention without full-array diffs

* fix(javascript): preserve source facts across graph projections

* fix(javascript): preserve copied values and export publication lifetimes

* fix(javascript): preserve per-field publication and provenance coverage

* fix(javascript): retain initialized class self binding at body reads

* fix(artifacts): retain permission omissions through JavaScript lookups

* test(graph): narrow summary owner and complete PE fixture facts

* test(javascript): supply source graph to native handoff checks

* fix(sourcemaps): bind cleanup status to remaining codec owners

* fix(browser): retain excluded source-map declaration coverage

* test(javascript): preserve exact empty property keys in declarations

* fix(browser): keep code absence unknown without worker inventory

* fix(browser): preserve WebMCP optional fields and replay coverage gaps

* fix(browser): publish executable examples with truthful capture coverage

* fix(browser): preserve observed document invalidation and scope recovery

* fix(native): share exact-name xref ambiguity resolution

* fix(hopper): own bookmark API capability checks

* fix(native): preserve procedure selector coordinate intent

* test(discovery): select the declared GDB console contract

* fix(ghidra): bind session refusal to retained cleanup owner

* fix(apple): retain selected dylib identity after path removal

* fix(apple): preserve asset failures and authored resource coverage

* fix(apple): retain binary UID identity through archive projection

* fix: retain completed historical replies through finalization

* fix: retain unresolved browser secret declarations as input errors

* test(browser): resolve network fixture secrets through typed input contract

* fix(environment): distinguish destination refusal and write access failures

* fix(artifacts): preserve exact ZIP and DMG caller cancellation reasons

* fix(artifacts): require regular source-map target occurrences

* fix(reference): separate local filesystem diagnostics from graph commitments

* fix(setup): retain proven PATH aliases in installed registrations

* test(package): join owned updater after registry fixture failure

* fix(javascript): preserve recovery acquisition and cancellation failures

* fix(session): retain cleanup blockers and snapshot request identity

* fix(evidence): preserve format-owned JSON recovery diagnostics

* test(evidence): cover BOM recovery across bundle commands

* fix(tracing): retain caller reasons at traversal checkpoints

* fix(inventory): require released cleanup before capability fallback

* fix(hopper): drain retained publishers after current close failure

* fix(native): preserve unknown Swift extension contexts

* fix(apple): qualify unexamined nib content coverage

* fix(frida): preserve session refusal and close execution effects

* fix(rizin): retain cancellation and recover cleanup correlation

* fix: retain Electron file admission facts across adapters

* fix: preserve selected Electron display authorization

* fix(javascript): retain unavailable HTML reference scopes

* fix(javascript): preserve capture timing and detached receiver authority

* fix(ida): preserve producer failure and caller abort outcomes

* fix(cli): retain nested facts in Markdown tables

* fix(cli): present argument guidance without validator cause dumps

* docs(setup): define optional native update verification limits

* docs(clients): distinguish discovery and schema recovery boundaries

* docs(setup): explain npm workspace launcher failures

* fix(verification): bind Copilot schema profile to observed inputs

* fix(javascript): scope Next package admission by container identity

* fix(apple): align asset allowance and category fixture types

* fix(protocols): honor runtime queue and Frida identity types

* test: parse Electron listing Evidence before comparison

* fix(evidence): omit absent format recovery metadata

* fix(contracts): validate historical source examples as exact JSON values

* fix(javascript): consume per-field CommonJS publication facts

* fix(gdb): correlate raw-output completion and retain read-only TTY proof

* fix(native): retain completed LLDB facts across output-close cancellation

* fix(hopper): retain failed private-display probe cleanup authority

* style(lifecycle): format traversal and fallback edits

* fix(apple): own ordered nib collections and registry parentage

* fix(process): attribute trace omissions without changing shared successors

* fix(cli): share builtin argument ownership with MCP routing

* fix(cli): count emitted documents and normalize token windows

* fix(inspector): retain captures through authorization cleanup failures

* fix(artifacts): retain declared ASAR companion occurrence facts

* fix(javascript): separate endpoint syntax correspondence from target identity

* fix: distinguish native process exit from sampling failure

* fix(javascript): retain selected-root access and filesystem failure facts

* fix(browser): retain truthful cleanup facts and document request ownership

* fix(native): share exact Objective-C class symbol interpretation

* fix(go): retain completed artifact facts through finalization

* fix(native): preserve seed analysis failures in value traces

* fix(native): classify observed dSYM inspection refusal

* test(apple): assert observed collection edge contract

* fix(javascript): retain primary interruption through worker cleanup

* fix(cutter): retain completion-read failures during cleanup retry

* fix(cli): validate output windows and finish pending writes

* fix(mcp): require absolute JavaScript application inputs

* fix(capabilities): report missing navigation targets

* fix(cli): support system Bash completion registration

* fix(cli): retain narrowed token-count format handling

* test(ida): preserve exact optional resource method shape

* test(javascript): retain valid unknown endpoint coverage shape

* fix(ghidra): try keg JDKs after failed PATH launchers

* fix(browser): retain capacity refusal through terminal progress

* fix(reference): require exact optional JSON diagnostics at the source schema

* fix(apple): retain reader outcomes and cleanup ownership

* fix(elf): qualify exports without dynamic symbol declarations

* fix(mips): retain unexamined RELR declaration coverage

* fix(metadata): preserve canonical PowerPC subject identity

* fix(native): preserve LLDB discovery failure classifications

* fix(native): report absent launch process before cleanup classification

* fix(rizin): preserve primary outcomes across final cleanup

* fix(browser): preserve admission failures and retain policy transport cleanup

* fix(objdump): preserve input issues and provider launch failures

* test(apple): attribute omitted edges to their node capacity limit

* chore(metadata): synchronize packaged skill version

* fix(cli): consume canonical output validation state

* fix(views): preserve owning layout field diagnostics

* test(pyinstaller): distinguish path and metadata allowance failures

* fix(native): compose the selected command cause once

* fix(setup): require HTTPS throughout Hopper download redirects

* fix(ghidra): narrow fallback probe failures before projection

* fix(native): require observed symbol origin for named identity

* fix(javascript): retain unavailable source processing scopes

* fix(cli): share declared output-error redaction

* docs(windows): explain MCP registration launcher limits

* fix(session): preserve binding commitments during restoration

* fix(environment): retain primary facts through server cleanup failure

* fix(pe): distinguish unsupported overlapping header layouts

* fix(cli): keep positional admission placeholders omittable

* test(cli): expose JavaScript progress workflow failure output

* test(browser): match retained subframe limitations structurally

* fix(javascript): preserve capture and property-key effect ownership

* fix(ghidra): attribute import policy conflicts to settings

* fix(native): validate Mach-O command framing before admission

* docs(mcp): state plist inspection session prerequisite

* fix(electron): separate script frame admission from declared source labels

* test(environment): read asynchronous owner observations through contracts

* test(javascript): distinguish resolver URLs from existing module targets

* fix(ghidra): retain neutral recovery for observed SIGKILL

* fix(hopper): preserve unknown relationship completeness

* docs(native): clarify Darwin runtime breakpoint names

* fix(browser): preserve unknown script ownership through reconciliation

* fix(electron): keep optional provenance fields within JSON evidence values

* fix(native): retain Mach-O architecture discriminant narrowing

* test: give oversized registration groups semantic owners

* test: group boundary registration by observed behavior

* fix: normalize retained terminal observations with sampled identities

* fix: identify missing Electron lineage ownership markers

* fix(ida): retain registration constraints and identity refusal guidance

* fix(kuna): retain published exports through staging cleanup failures

* fix(nativeaot): charge only examined candidate table entries

* docs: clarify batch decompilation retention limits

* fix(javascript): distinguish deferred bootstrap installer writes

* fix(native)!: preserve UI scalar facts and selection failures

BREAKING CHANGE: Accessibility node value can also be a JSON number or boolean. Strings and null retain their prior meaning.

* fix(javascript): retain activation order for captured scope exits

* test(pyinstaller): use an absolute drive path for refusal coverage

* fix(javascript): preserve route selection owners and uncertainty

* fix(javascript): prove native URL constructor paths

* refactor(tests): separate fixtures and registration groups

* test(native): distinguish qualified symbol identity controls

* fix(ida): preserve busy details across timeout attribution

* fix(cli): unify builtin and global completion scope

* test(ghidra): group exit-signal evidence controls

* fix: retain narrowed terminal observation values

* fix(cli): bind completion input to public registry type

* fix(flutter): qualify unsupported unified snapshot profiles

* test(native): bind origin comparison to containing entries

* fix(cli): remove completion markers on system Bash

* test(ida): preserve physical workspace traversal controls

* fix(native): retain unknown UI executable identity

* fix(native): unify LLDB discovery preparation failures

* fix(evidence): preserve primary semantics during pending cleanup

* fix(evidence): retain owner finalization reports across cleanup envelopes

* test(browser): inspect provenance in owned graph observations

* test(flutter): assert canonical unsupported profile error code

* fix(javascript): capture primitive return values at evaluation

* fix(mcp): own cancellation and raw input throughout startup

* test(ghidra): construct exact import policy targets

* fix(gdb): preserve configured executable launch recovery

* test(ghidra): own fixed import target fixtures

* docs(readme): align localized guide link occurrences

* test(evidence): retain structured input issues through cleanup owners

* test(mcp): await observed EOF before releasing startup

* fix(electron): retain bounded source frame claims

* fix(elf): validate declared file extents before provider admission

* fix(elf): align metadata and admission fixture error types

* test(wasm): place parsed interface comparison at provider boundary

* test(ida): place capability composition at provider boundary

* test(browser): place PNG contract execution at provider boundary

* perf(test): share SDK catalog compilation across deferred clients

* fix(cli): trim repeated selector discovery guidance

* revert(test): remove unproven SDK compiler sharing

This reverts commit 56eca648d. The equivalent completed two-client measurement increased elapsed and CPU time, so compiler sharing has not established a benefit.

* refactor(managed): retain decoded metadata token facts

* test(managed): scope cleanup failures to snapshot reads

* test(cli): bound selector rejection cases by command

* test(mips): distinguish damaged ELF admission from partial ABI evidence

* test(reconstruction): declare authored function symbol identity

* test(rizin): register terminal admission at provider boundary

* test(process): align root admission fixture with observer allocation ownership

* test(mips): project inspected ABI facts without undefined overrides

* refactor(browser): remove obsolete web script reconciliation

* refactor(javascript): remove obsolete in-process projection runner

* refactor(managed): retain TypeDef row ownership through projections

* test(process): assert canonical admission failure through cleanup envelopes

* fix(managed): select types from retained definition records

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-24 06:19:39 +08:00

446 lines
14 KiB
TypeScript

import { nativeDispatchMetadataInputSchema } from "../domain/native/objcSwiftMetadata.js";
import { z } from "incur";
import {
addressOrProcedureGuidance,
equalSelectorGuidance,
resolveCliAnalysisSelector,
} from "./analysisSelector.js";
import type { DirectAnalysis } from "../composition/directAnalysis.js";
import { CLI_COMMANDS } from "../cliCommandNames.js";
import { logCliCommand } from "../cliLogging.js";
import type { Logger } from "pino";
import {
directAnalysisOptionsFromCli,
nativeOpenOptionFields,
snapshotSelectionOption,
} from "./options.js";
import type { CliInstance } from "./types.js";
/** Register native load-image, memory, and annotation CLI commands. */
export const registerCoreNativeCommands = (
cli: CliInstance,
logger: Logger,
runDirectAnalysis: DirectAnalysis["runDirectAnalysis"],
): void => {
registerAnnotationCommand(cli, logger, runDirectAnalysis);
cli.command(CLI_COMMANDS.searchBytes, {
description: "Find masked byte patterns in initialized provider memory",
args: z.object({
path: z.string().describe("Local executable path"),
pattern: z.string().describe("Hexadecimal byte pairs with ?? wildcards"),
}),
options: z.object({
mask: z.string().optional().describe("Equal-length hexadecimal bit mask"),
start: z.string().optional().describe("Inclusive start address"),
end: z.string().optional().describe("Inclusive end address"),
cursor: z
.string()
.optional()
.describe("Continuation from the same query's next_cursor"),
limit: z
.number()
.int()
.min(1)
.max(1000)
.default(100)
.describe("Maximum matches on this page"),
...nativeOpenOptionFields,
}),
run: ({ args, options }) =>
logCliCommand(logger, CLI_COMMANDS.searchBytes, () =>
runDirectAnalysis(
args.path,
"search_bytes",
{
pattern: args.pattern,
limit: options.limit,
...(options.mask === undefined ? {} : { mask: options.mask }),
...(options.start === undefined ? {} : { start: options.start }),
...(options.end === undefined ? {} : { end: options.end }),
...(options.cursor === undefined ? {} : { cursor: options.cursor }),
},
directAnalysisOptionsFromCli(logger, options),
),
),
});
cli.command(CLI_COMMANDS.inspectNativeLoadImage, {
description:
"Verify loaded native bytes, source mappings, relocations and entry",
args: z.object({ path: z.string().describe("Local executable path") }),
options: z.object({
...nativeOpenOptionFields,
}),
run: ({ args, options }) =>
logCliCommand(logger, CLI_COMMANDS.inspectNativeLoadImage, () =>
runDirectAnalysis(
args.path,
"inspect_native_load_image",
{},
directAnalysisOptionsFromCli(logger, options),
),
),
});
cli.command(CLI_COMMANDS.readBytes, {
description: "Read exact provider memory bytes at one analysis address",
args: z.object({
path: z.string().describe("Local executable path"),
address: z.string().describe("Exact provider memory address"),
}),
options: z.object({
length: z
.number()
.int()
.min(1)
.default(256)
.describe("Requested byte count"),
...nativeOpenOptionFields,
}),
run: ({ args, options }) =>
logCliCommand(logger, CLI_COMMANDS.readBytes, () =>
runDirectAnalysis(
args.path,
"read_bytes",
{ address: args.address, length: options.length },
directAnalysisOptionsFromCli(logger, options),
),
),
});
cli.command(CLI_COMMANDS.addressToFileOffset, {
description: "Resolve an analysis address to its original file byte offset",
args: z.object({
path: z.string().describe("Local executable path"),
address: z.string().describe("Exact provider memory address"),
}),
options: z.object({
...nativeOpenOptionFields,
}),
run: ({ args, options }) =>
logCliCommand(logger, CLI_COMMANDS.addressToFileOffset, () =>
runDirectAnalysis(
args.path,
"address_to_file_offset",
{ address: args.address },
directAnalysisOptionsFromCli(logger, options),
),
),
});
cli.command(CLI_COMMANDS.traceNativeValues, {
description: "Trace bounded native def-use and call dependencies",
args: z.object({
path: z.string().describe("Local native executable or app path"),
procedure: z
.string()
.describe("Explicit native procedure symbol or address"),
}),
options: z.object({
maxDepth: z
.number()
.int()
.min(0)
.max(16)
.default(3)
.describe("Maximum call traversal depth"),
maxFunctions: z
.number()
.int()
.min(1)
.max(64)
.default(16)
.describe("Maximum function decompilations"),
maxCallSites: z
.number()
.int()
.min(1)
.max(4096)
.default(256)
.describe("Maximum static call-site resolutions"),
maxNodes: z
.number()
.int()
.min(1)
.max(20000)
.default(5000)
.describe("Maximum retained graph nodes"),
maxEdges: z
.number()
.int()
.min(1)
.max(40000)
.default(10000)
.describe("Maximum retained graph edges"),
offset: z
.number()
.int()
.min(0)
.default(0)
.describe("First graph node index"),
limit: z
.number()
.int()
.min(1)
.max(5000)
.default(1000)
.describe("Maximum nodes on this page"),
...nativeOpenOptionFields,
}),
run: ({ args, options }) =>
logCliCommand(logger, CLI_COMMANDS.traceNativeValues, () =>
runDirectAnalysis(
args.path,
"trace_native_values",
{
procedure: args.procedure,
max_depth: options.maxDepth,
max_functions: options.maxFunctions,
max_call_sites: options.maxCallSites,
max_nodes: options.maxNodes,
max_edges: options.maxEdges,
offset: options.offset,
limit: options.limit,
},
directAnalysisOptionsFromCli(logger, options),
),
),
});
cli.command(CLI_COMMANDS.inspectNativeDataType, {
description: "Inspect one recovered database type or typed data object",
args: z.object({
path: z.string().describe("Local native executable or app path"),
}),
options: z.object({
type: z.string().optional().describe("Exact database type category path"),
address: z.string().optional().describe("Exact native address"),
...nativeOpenOptionFields,
}),
run: ({ args, options }) =>
logCliCommand(logger, CLI_COMMANDS.inspectNativeDataType, () =>
runDirectAnalysis(
args.path,
"inspect_native_data_type",
{
...(options.type === undefined ? {} : { type: options.type }),
...(options.address === undefined
? {}
: { address: options.address }),
},
directAnalysisOptionsFromCli(logger, options),
),
),
});
for (const [command, operation] of [
[CLI_COMMANDS.inspectNativeInstruction, "inspect_native_instruction"],
[CLI_COMMANDS.resolveNativeCallTargets, "resolve_native_call_targets"],
] as const) {
cli.command(command, {
description:
operation === "inspect_native_instruction"
? "Inspect one native instruction with decoded operand facts"
: "Resolve one static native call site",
args: z.object({
path: z.string().describe("Local native executable or app path"),
address: z.string().describe("Exact native address"),
}),
options: z.object({
...nativeOpenOptionFields,
}),
run: ({ args, options }) =>
logCliCommand(logger, command, () =>
runDirectAnalysis(
args.path,
operation,
{ address: args.address },
directAnalysisOptionsFromCli(logger, options),
),
),
});
}
registerNativeApiCommand(cli, logger, runDirectAnalysis);
registerNativeUiActionCommand(cli, logger, runDirectAnalysis);
registerNativeDispatchMetadataCommand(cli, logger, runDirectAnalysis);
};
const registerNativeDispatchMetadataCommand = (
cli: CliInstance,
logger: Logger,
runDirectAnalysis: DirectAnalysis["runDirectAnalysis"],
): void => {
cli.command(CLI_COMMANDS.inspectNativeDispatchMetadata, {
description: "Inspect typed Objective-C and Swift dispatch metadata",
args: z.object({
path: z.string().describe("Target path used to bind the result evidence"),
}),
options: z.object({
maxRecords: nativeDispatchMetadataInputSchema.shape.max_records.describe(
"Maximum symbol records to inspect",
),
maxInputBytes: nativeDispatchMetadataInputSchema.shape.max_input_bytes,
snapshot: snapshotSelectionOption.describe(
"Load or update the local analysis snapshot",
),
...nativeOpenOptionFields,
}),
run: async ({ args, options }) =>
logCliCommand(logger, "inspect-native-dispatch-metadata", () =>
runDirectAnalysis(
args.path,
"inspect_native_dispatch_metadata",
{
max_records: options.maxRecords,
...(options.maxInputBytes === undefined
? {}
: { max_input_bytes: options.maxInputBytes }),
},
directAnalysisOptionsFromCli(logger, options),
),
),
});
};
const registerNativeUiActionCommand = (
cli: CliInstance,
logger: Logger,
runDirectAnalysis: DirectAnalysis["runDirectAnalysis"],
): void => {
cli.command(CLI_COMMANDS.traceNativeUiAction, {
description:
"Trace a compiled UI action selector to its native handler and direct callees",
args: z.object({
path: z.string().describe("Target path used to bind the result evidence"),
action: z
.string()
.min(1)
.describe(
"A unique compiled UI action selector or interface object ID",
),
}),
options: z.object({
maxDepth: z
.number()
.int()
.min(0)
.max(32)
.default(8)
.describe("Maximum relationship depth"),
maxNodes: z
.number()
.int()
.min(1)
.max(2_000)
.default(250)
.describe("Maximum returned graph nodes"),
maxEdges: z
.number()
.int()
.min(1)
.max(5_000)
.default(500)
.describe("Maximum returned graph edges"),
...nativeOpenOptionFields,
}),
run: async ({ args, options }) =>
logCliCommand(logger, "trace-native-ui-action", () =>
runDirectAnalysis(
args.path,
"trace_native_ui_action",
{
action: args.action,
max_depth: options.maxDepth,
max_nodes: options.maxNodes,
max_edges: options.maxEdges,
},
directAnalysisOptionsFromCli(logger, options),
),
),
});
};
const registerNativeApiCommand = (
cli: CliInstance,
logger: Logger,
runDirectAnalysis: DirectAnalysis["runDirectAnalysis"],
): void => {
cli.command(CLI_COMMANDS.inspectNativeApi, {
description: `Reconstruct one native function API boundary with evidence. ${addressOrProcedureGuidance} ${equalSelectorGuidance}`,
args: z.object({
path: z.string().describe("App or program path"),
address: z
.string()
.optional()
.describe(`Procedure name or address. ${addressOrProcedureGuidance}`),
}),
options: z.object({
procedure: z
.string()
.optional()
.describe(
`Procedure selector; use this option for symbols beginning with a dash. ${addressOrProcedureGuidance}`,
),
snapshot: snapshotSelectionOption,
...nativeOpenOptionFields,
}),
run: ({ args, options }) =>
logCliCommand(logger, "inspect-native-api", () =>
runDirectAnalysis(
args.path,
"inspect_native_api",
{
procedure: resolveCliAnalysisSelector(
args.address,
options.procedure,
"procedure",
"inspect_native_api",
),
},
directAnalysisOptionsFromCli(logger, options),
),
),
});
};
const registerAnnotationCommand = (
cli: CliInstance,
logger: Logger,
runDirectAnalysis: DirectAnalysis["runDirectAnalysis"],
): void => {
cli.command(CLI_COMMANDS.annotateNativeFunction, {
description: "Edit function annotations and return refreshed analysis",
args: z.object({
path: z.string().describe("Local executable path"),
procedure: z
.string()
.describe("Exact function entry address or unique name"),
}),
options: z.object({
name: z.string().min(1).optional().describe("Analyst function name"),
comment: z
.string()
.optional()
.describe("Regular entry comment; empty text clears it"),
"inline-comment": z
.string()
.optional()
.describe("Inline entry comment; empty text clears it"),
...nativeOpenOptionFields,
}),
run: ({ args, options }) =>
logCliCommand(logger, CLI_COMMANDS.annotateNativeFunction, () =>
runDirectAnalysis(
args.path,
"annotate_native_function",
{
procedure: args.procedure,
...(options.name === undefined ? {} : { name: options.name }),
...(options.comment === undefined
? {}
: { comment: options.comment }),
...(options["inline-comment"] === undefined
? {}
: { inline_comment: options["inline-comment"] }),
},
directAnalysisOptionsFromCli(logger, options),
),
),
});
};