fix(ghidra): clarify function annotation selectors

This commit is contained in:
morluto committed 2026-11-02 02:17:10 +08:00
1 parent ce9095d727
commit 2a17f77b1c
6 files changed
+30 -4

No files matched your search

+3 -1
View File
@@ -1137,7 +1137,9 @@ handle-based path admission. See [Windows Ghidra P0](windows-ghidra-p0.md) and
[issue #527](https://github.com/morluto/rea/issues/527).
On Linux and macOS, `annotate_native_function` atomically edits a function name
and entry comments in the ephemeral database, returning refreshed analysis
without changing executable bytes. Annotation text must contain no NUL or
without changing executable bytes. A Ghidra address inside a function selects
the containing function; the name and comments are changed at its entry, not
at the selected instruction. Annotation text must contain no NUL or
unpaired Unicode surrogate; a rejection identifies the field and UTF-16 index
and leaves every annotation unchanged. CRLF, supplementary Unicode characters,
and combining characters are preserved. Windows P0 remains read-only. Ghidra has no
+8
View File
@@ -29,6 +29,14 @@ export async function verifyGhidraBoundaries(
) {
const options = { timeout: 180000 };
const catalog = await client.listTools();
const annotation = catalog.tools.find(
(tool) => tool.name === "annotate_native_function",
);
assert.match(
annotation?.description ?? "",
/interior address.*containing function.*function entry.*procedure_address/u,
"The annotation catalog must explain where an interior selector edits",
);
const ajv = new Ajv({ strict: false });
addFormats(ajv);
const validators = new Map();
@@ -156,6 +156,15 @@ export async function verifyGhidraEntryAliases({
alias.address,
"Explicit interior addresses keep their existing containment semantics",
);
const interiorEdit = await call("annotate_native_function", {
procedure: interior.address,
comment: "Selected by interior address",
});
assert.equal(interiorEdit.annotations.address, alias.address);
assert.equal(
interiorEdit.annotations.comment,
"Selected by interior address",
);
const edited = await call("annotate_native_function", {
procedure: alias.value,
comment: "Selected by imported entry alias",
+3 -1
View File
@@ -469,7 +469,9 @@ const registerAnnotationCommand = (
path: localPathStringSchema.describe("Local executable path"),
procedure: z
.string()
.describe("Exact function entry address or unique name"),
.describe(
"Function name or address; Ghidra resolves interior addresses to the containing function and edits its entry",
),
}),
options: z.object({
name: z.string().min(1).optional().describe("Analyst function name"),
+1 -1
View File
@@ -50,7 +50,7 @@ const official = <
export const OFFICIAL_TOOL_CONTRACTS = [
official(
"annotate_native_function",
"Atomically update one function name and/or entry comments, read them back, and return a refreshed complete function dossier. Ghidra changes its ephemeral session analysis database only; original executable bytes remain unchanged. Empty comment text clears that comment. Edits remain available to subsequent MCP calls until close; CLI returns the updated dossier before discarding its session. Invalid edits roll back the entire operation. Windows P0 and providers without this capability are unsupported.",
"Atomically update one function name and/or entry comments, read them back, and return a refreshed complete function dossier. Ghidra resolves an interior address to its containing function and applies edits at the function entry, not at the selected instruction; use procedure_address first to find that entry. Ghidra changes its ephemeral session analysis database only; original executable bytes remain unchanged. Empty comment text clears that comment. Edits remain available to subsequent MCP calls until close; CLI returns the updated dossier before discarding its session. Invalid edits roll back the entire operation. Windows P0 and providers without this capability are unsupported.",
nativeFunctionAnnotationsInputSchema,
),
official(
@@ -4,7 +4,12 @@ import { functionDossierSchema } from "../native/functionDossier.js";
/** One explicit function's analyst-authored metadata changes. */
export const nativeFunctionAnnotationsInputSchema = z
.strictObject({
procedure: z.string().min(1),
procedure: z
.string()
.min(1)
.describe(
"Function name or address selecting a function; edits apply at its entry.",
),
name: z.string().min(1).optional(),
comment: z
.string()