@eyeauras/insight-cli 0.3.1 → 0.4.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/.cli-package-build.json +1 -1
- package/SKILL.md +4 -1
- package/dist/src/analysis-default.d.ts +26 -0
- package/dist/src/analysis-default.js +149 -0
- package/dist/src/analysis-storage.d.ts +39 -20
- package/dist/src/analysis-storage.js +112 -16
- package/dist/src/arguments.js +9 -4
- package/dist/src/cli.js +45 -37
- package/dist/src/code-references.d.ts +48 -0
- package/dist/src/code-references.js +154 -0
- package/dist/src/context-diagnostics.d.ts +25 -0
- package/dist/src/context-diagnostics.js +82 -0
- package/dist/src/contexts.d.ts +13 -1
- package/dist/src/contexts.js +38 -9
- package/dist/src/function-boundaries.d.ts +9 -0
- package/dist/src/function-boundaries.js +68 -0
- package/dist/src/function-entries.d.ts +33 -0
- package/dist/src/function-entries.js +84 -0
- package/dist/src/function-inspection.d.ts +4 -2
- package/dist/src/function-inspection.js +94 -59
- package/dist/src/function-results.d.ts +3 -1
- package/dist/src/function-results.js +9 -3
- package/dist/src/inline-script.d.ts +15 -0
- package/dist/src/inline-script.js +62 -0
- package/dist/src/internal-timing.d.ts +3 -0
- package/dist/src/internal-timing.js +52 -0
- package/dist/src/lifecycle.js +14 -4
- package/dist/src/native-inputs.d.ts +1 -1
- package/dist/src/native-inputs.js +1 -1
- package/dist/src/native-queries.js +1 -1
- package/dist/src/persistent-client.d.ts +30 -0
- package/dist/src/persistent-client.js +125 -0
- package/dist/src/queries.js +4 -1
- package/dist/src/query-policy.js +9 -1
- package/dist/src/research-view.d.ts +6 -0
- package/dist/src/research-view.js +9 -0
- package/dist/src/research.d.ts +38 -0
- package/dist/src/research.js +78 -8
- package/dist/src/string-anchors.d.ts +43 -0
- package/dist/src/string-anchors.js +176 -0
- package/dist/src/sync-policy.js +3 -0
- package/dist/src/timed-backend.d.ts +3 -0
- package/dist/src/timed-backend.js +16 -0
- package/dist/src/transport.d.ts +1 -0
- package/dist/src/transport.js +4 -0
- package/dist/src/workspace.js +5 -2
- package/package.json +12 -1
- package/references/native/InsightAnchorScan.java +135 -0
- package/references/native/InsightCodeReferences.java +129 -0
- package/references/native/InsightFunctionBoundaries.java +56 -0
- package/references/native/InsightInlineExecutor.java +143 -0
- package/references/native/InsightInlineScript.java +14 -0
- package/references/native/InsightPeRanges.java +92 -0
- package/references/native/InsightResearchQueries.java +22 -1
- package/references/native/InsightResearchView.java +69 -0
- package/references/native/InsightStringAnchors.java +49 -0
- package/references/persistent-client.mjs +125 -0
- package/references/persistent.md +50 -0
- package/references/query-semantics.md +12 -0
- package/references/recovery.md +36 -0
- package/references/research.md +87 -0
- package/references/setup.md +1 -1
- package/references/sparse-navigation.md +173 -0
- package/references/storage.md +35 -7
- package/runtime/GhidraMCP-7.0.0.jar +0 -0
- package/runtime/GhidraMCP-NOTICE +5 -0
- package/runtime/provenance.json +17 -3
- package/runtime/research-view.provenance.json +28 -0
- package/runtime/toolbox.json +10 -3
- package/skill-bundle/insight-artifacts/SKILL.md +1 -1
- package/skill-bundle/insight-artifacts/references/recovery.md +36 -0
- package/skill-bundle/insight-artifacts/references/storage.md +35 -7
- package/skill-bundle/insight-binary/SKILL.md +1 -1
- package/skill-bundle/insight-capture/SKILL.md +1 -1
- package/skill-bundle/insight-cli/SKILL.md +4 -1
- package/skill-bundle/insight-cli/references/persistent-client.mjs +125 -0
- package/skill-bundle/insight-cli/references/persistent.md +50 -0
- package/skill-bundle/insight-cli/references/recovery.md +36 -0
- package/skill-bundle/insight-cli/references/setup.md +1 -1
- package/skill-bundle/insight-cli/references/storage.md +35 -7
- package/skill-bundle/insight-die/SKILL.md +1 -1
- package/skill-bundle/insight-dnspy/SKILL.md +1 -1
- package/skill-bundle/insight-dotnet-dump/SKILL.md +1 -1
- package/skill-bundle/insight-dotnet-stack/SKILL.md +1 -1
- package/skill-bundle/insight-dotnet-trace/SKILL.md +1 -1
- package/skill-bundle/insight-frida/SKILL.md +1 -1
- package/skill-bundle/insight-ghidra/SKILL.md +14 -1
- package/skill-bundle/insight-ghidra/references/persistent-client.mjs +125 -0
- package/skill-bundle/insight-ghidra/references/persistent.md +50 -0
- package/skill-bundle/insight-ghidra/references/query-semantics.md +12 -0
- package/skill-bundle/insight-ghidra/references/recovery.md +36 -0
- package/skill-bundle/insight-ghidra/references/research.md +87 -0
- package/skill-bundle/insight-ghidra/references/setup.md +1 -1
- package/skill-bundle/insight-ghidra/references/sparse-navigation.md +173 -0
- package/skill-bundle/insight-ghidra/references/storage.md +35 -7
- package/skill-bundle/insight-ilspy/SKILL.md +1 -1
- package/skill-bundle/insight-interop/SKILL.md +1 -1
- package/skill-bundle/insight-lldb/SKILL.md +1 -1
- package/skill-bundle/insight-llvm/SKILL.md +1 -1
- package/skill-bundle/insight-managed-heap/SKILL.md +1 -1
- package/skill-bundle/insight-managed-metadata/SKILL.md +1 -1
- package/skill-bundle/insight-mitmproxy/SKILL.md +1 -1
- package/skill-bundle/insight-overview/SKILL.md +1 -1
- package/skill-bundle/insight-procmon/SKILL.md +1 -1
- package/skill-bundle/insight-re/SKILL.md +4 -1
- package/skill-bundle/insight-re/references/persistent-client.mjs +125 -0
- package/skill-bundle/insight-re/references/persistent.md +50 -0
- package/skill-bundle/insight-re/references/recovery.md +36 -0
- package/skill-bundle/insight-re/references/storage.md +35 -7
- package/skill-bundle/insight-sevenzip/SKILL.md +1 -1
- package/skill-bundle/insight-strace/SKILL.md +1 -1
- package/skill-bundle/insight-tshark/SKILL.md +1 -1
- package/skill-bundle/insight-windbg/SKILL.md +1 -1
- package/skill-bundle/manifest.json +1 -1
- package/skills/insight-artifacts/SKILL.md +1 -1
- package/skills/insight-artifacts/references/recovery.md +36 -0
- package/skills/insight-artifacts/references/storage.md +35 -7
- package/skills/insight-binary/SKILL.md +1 -1
- package/skills/insight-capture/SKILL.md +1 -1
- package/skills/insight-die/SKILL.md +1 -1
- package/skills/insight-dnspy/SKILL.md +1 -1
- package/skills/insight-dotnet-dump/SKILL.md +1 -1
- package/skills/insight-dotnet-stack/SKILL.md +1 -1
- package/skills/insight-dotnet-trace/SKILL.md +1 -1
- package/skills/insight-frida/SKILL.md +1 -1
- package/skills/insight-ghidra/SKILL.md +14 -1
- package/skills/insight-ghidra/references/persistent-client.mjs +125 -0
- package/skills/insight-ghidra/references/persistent.md +50 -0
- package/skills/insight-ghidra/references/query-semantics.md +12 -0
- package/skills/insight-ghidra/references/recovery.md +36 -0
- package/skills/insight-ghidra/references/research.md +87 -0
- package/skills/insight-ghidra/references/setup.md +1 -1
- package/skills/insight-ghidra/references/sparse-navigation.md +173 -0
- package/skills/insight-ghidra/references/storage.md +35 -7
- package/skills/insight-ilspy/SKILL.md +1 -1
- package/skills/insight-interop/SKILL.md +1 -1
- package/skills/insight-lldb/SKILL.md +1 -1
- package/skills/insight-llvm/SKILL.md +1 -1
- package/skills/insight-managed-heap/SKILL.md +1 -1
- package/skills/insight-managed-metadata/SKILL.md +1 -1
- package/skills/insight-mitmproxy/SKILL.md +1 -1
- package/skills/insight-overview/SKILL.md +1 -1
- package/skills/insight-procmon/SKILL.md +1 -1
- package/skills/insight-re/SKILL.md +4 -1
- package/skills/insight-re/references/persistent-client.mjs +125 -0
- package/skills/insight-re/references/persistent.md +50 -0
- package/skills/insight-re/references/recovery.md +36 -0
- package/skills/insight-re/references/storage.md +35 -7
- package/skills/insight-sevenzip/SKILL.md +1 -1
- package/skills/insight-strace/SKILL.md +1 -1
- package/skills/insight-tshark/SKILL.md +1 -1
- package/skills/insight-windbg/SKILL.md +1 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { StringDecoder } from 'node:string_decoder';
|
|
3
|
+
export class InsightCommandError extends Error {
|
|
4
|
+
rpc;
|
|
5
|
+
constructor(rpc) {
|
|
6
|
+
super(rpc.message);
|
|
7
|
+
this.rpc = rpc;
|
|
8
|
+
this.name = 'InsightCommandError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export class InsightTransportError extends Error {
|
|
12
|
+
dispatched;
|
|
13
|
+
constructor(message, dispatched) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.dispatched = dispatched;
|
|
16
|
+
this.name = 'InsightTransportError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** A thin client of Factory's existing stream, with no reconnect or command replay. */
|
|
20
|
+
export async function connectInsight(options) {
|
|
21
|
+
const child = spawn(options.executable, [...(options.arguments ?? []), '--json-rpc'], { cwd: options.cwd, env: options.env, stdio: ['pipe', 'pipe', 'pipe'], shell: false });
|
|
22
|
+
const maximum = 4 * 1024 ** 2, decoder = new StringDecoder('utf8');
|
|
23
|
+
let buffer = '', bytes = 0, sequence = 0, accepting = true, failed = false, ended = false;
|
|
24
|
+
let closePromise, tail = Promise.resolve();
|
|
25
|
+
const pending = new Map();
|
|
26
|
+
// Drain diagnostics without retaining arbitrary stderr, paths, tokens or unbounded output.
|
|
27
|
+
child.stderr.resume();
|
|
28
|
+
const fail = (message) => {
|
|
29
|
+
if (failed)
|
|
30
|
+
return;
|
|
31
|
+
failed = true;
|
|
32
|
+
accepting = false;
|
|
33
|
+
for (const p of pending.values())
|
|
34
|
+
p.reject(new InsightTransportError(message, true));
|
|
35
|
+
pending.clear();
|
|
36
|
+
child.stdin.destroy();
|
|
37
|
+
child.stdout.destroy();
|
|
38
|
+
};
|
|
39
|
+
child.on('error', () => fail('Persistent CLI process failed.'));
|
|
40
|
+
child.stdout.on('error', () => fail('Persistent CLI output was lost.'));
|
|
41
|
+
child.stderr.on('error', () => fail('Persistent CLI diagnostic stream was lost.'));
|
|
42
|
+
child.stdin.on('error', () => fail('Persistent CLI input was lost; inspect request/status before retrying a changing command.'));
|
|
43
|
+
const exited = new Promise((resolve, reject) => {
|
|
44
|
+
child.once('close', (code, signal) => {
|
|
45
|
+
ended = true;
|
|
46
|
+
if (code !== 0 || signal || pending.size || buffer.trim()) {
|
|
47
|
+
fail('Persistent CLI closed without a complete acknowledged response.');
|
|
48
|
+
reject(new InsightTransportError('Persistent CLI transport ended unexpectedly.', false));
|
|
49
|
+
}
|
|
50
|
+
else if (failed)
|
|
51
|
+
reject(new InsightTransportError('Persistent CLI transport failed.', false));
|
|
52
|
+
else
|
|
53
|
+
resolve();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
void exited.catch(() => { });
|
|
57
|
+
child.stdout.on('data', (chunk) => {
|
|
58
|
+
if (failed)
|
|
59
|
+
return;
|
|
60
|
+
buffer += decoder.write(chunk);
|
|
61
|
+
bytes += chunk.length;
|
|
62
|
+
if (bytes > maximum) {
|
|
63
|
+
fail('Persistent CLI response exceeded the bounded transport limit.');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
for (;;) {
|
|
67
|
+
const newline = buffer.indexOf('\n');
|
|
68
|
+
if (newline < 0)
|
|
69
|
+
break;
|
|
70
|
+
const line = buffer.slice(0, newline);
|
|
71
|
+
buffer = buffer.slice(newline + 1);
|
|
72
|
+
bytes = Buffer.byteLength(buffer);
|
|
73
|
+
if (!line.trim())
|
|
74
|
+
continue;
|
|
75
|
+
try {
|
|
76
|
+
const r = JSON.parse(line);
|
|
77
|
+
if (!r || r.jsonrpc !== '2.0' || typeof r.id !== 'number' || !pending.has(r.id) || Object.hasOwn(r, 'result') === Object.hasOwn(r, 'error'))
|
|
78
|
+
throw Error();
|
|
79
|
+
const p = pending.get(r.id);
|
|
80
|
+
if (Object.hasOwn(r, 'error') && (!r.error || typeof r.error !== 'object' || typeof r.error.code !== 'number' || !Number.isInteger(r.error.code) || typeof r.error.message !== 'string'))
|
|
81
|
+
throw Error();
|
|
82
|
+
pending.delete(r.id);
|
|
83
|
+
if (r.error)
|
|
84
|
+
p.reject(new InsightCommandError(r.error));
|
|
85
|
+
else
|
|
86
|
+
p.resolve(r.result);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
fail('Persistent CLI returned a malformed or uncorrelated response.');
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
await new Promise((resolve, reject) => { child.once('spawn', resolve); child.once('error', () => reject(new InsightTransportError('Could not start persistent CLI.', false))); });
|
|
95
|
+
return {
|
|
96
|
+
execute(argv) {
|
|
97
|
+
if (!Array.isArray(argv) || argv.length > 512 || argv.some(x => typeof x !== 'string' || x.includes('\0')) || Buffer.byteLength(JSON.stringify(argv)) > 1024 ** 2)
|
|
98
|
+
return Promise.reject(new TypeError('argv must be a bounded array of strings without NUL.'));
|
|
99
|
+
if (!accepting || failed || ended)
|
|
100
|
+
return Promise.reject(new InsightTransportError('Persistent CLI connection is closed.', false));
|
|
101
|
+
const args = [...argv];
|
|
102
|
+
const request = tail.then(() => {
|
|
103
|
+
if (failed || ended)
|
|
104
|
+
throw new InsightTransportError('Persistent CLI connection was lost before dispatch.', false);
|
|
105
|
+
const id = ++sequence;
|
|
106
|
+
return new Promise((resolve, reject) => {
|
|
107
|
+
pending.set(id, { resolve, reject });
|
|
108
|
+
try {
|
|
109
|
+
child.stdin.write(JSON.stringify({ jsonrpc: '2.0', id, method: 'cli.execute', params: { argv: args } }) + '\n');
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
fail('Persistent CLI input was lost; inspect request/status before retrying a changing command.');
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
tail = request.catch(() => { });
|
|
117
|
+
return request;
|
|
118
|
+
},
|
|
119
|
+
close() {
|
|
120
|
+
accepting = false;
|
|
121
|
+
return closePromise ??= tail.then(async () => { if (!failed && !ended)
|
|
122
|
+
child.stdin.end(); await exited; });
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Persistent research calls
|
|
2
|
+
|
|
3
|
+
For a sequence of CLI research calls, keep one `insight-cli --json-rpc` frontend alive in the
|
|
4
|
+
agent's long-lived JavaScript runtime. The Factory owner and Ghidra processes have their own
|
|
5
|
+
lifetime; retaining only the owner still makes a new frontend validate its installed build.
|
|
6
|
+
|
|
7
|
+
The package exports a small stdio client, independent of the facade's eager imports:
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import {connectInsight, InsightCommandError, InsightTransportError}
|
|
11
|
+
from '@eyeauras/insight-cli/persistent';
|
|
12
|
+
|
|
13
|
+
const cli = await connectInsight({executable: 'insight-cli', cwd: projectDirectory});
|
|
14
|
+
const result = await cli.execute([
|
|
15
|
+
'ghidra', 'functions', 'inspect', '--session', session, '--target', target,
|
|
16
|
+
'--function', 'main', '--fields', 'entry_point', '--include-call-context', 'false'
|
|
17
|
+
]);
|
|
18
|
+
// Keep cli for subsequent calls in this investigation.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
When package-name resolution is unavailable in the agent host, dynamically import the
|
|
22
|
+
[`persistent-client.mjs`](persistent-client.mjs) beside this reference by its absolute file URL.
|
|
23
|
+
It is generated from the same canonical package module. In a persistent REPL retain `cli` as a
|
|
24
|
+
binding across tool invocations. A new Node process per query does not retain this connection.
|
|
25
|
+
For an explicit installed bin, use `{executable: process.execPath, arguments: [installedBin], cwd}`.
|
|
26
|
+
`env` optionally supplies the child environment. There is no shell or separate profile/config.
|
|
27
|
+
Use existing `--profile` argv flags when selecting a profile explicitly.
|
|
28
|
+
|
|
29
|
+
`execute(argv)` returns the CLI result unchanged, without a JSON-RPC envelope. Calls are queued
|
|
30
|
+
in admission order. Native work can be long: await the original promise through the agent host's
|
|
31
|
+
existing wait facility. This V1 client deliberately has no per-request timeout or automatic
|
|
32
|
+
reconnect/retry. Factory permissions, command validation, IDs and native budgets remain authoritative.
|
|
33
|
+
|
|
34
|
+
* `InsightCommandError.rpc` preserves the JSON-RPC error code, message and data, including typed
|
|
35
|
+
CLI error results. A command failure leaves a healthy connection usable for the next command.
|
|
36
|
+
* `InsightTransportError.dispatched === true` means the request was handed to the stream and its
|
|
37
|
+
acknowledgment is unavailable; it does not prove execution. Changing commands require their
|
|
38
|
+
existing request-ID/status recovery. The client never resends them.
|
|
39
|
+
* `dispatched === false` means this client did not send that request, including queued requests
|
|
40
|
+
after a transport failure. Reconnection is an explicit new connection, not an implicit replay.
|
|
41
|
+
|
|
42
|
+
The client bounds each response line to four MiB, validates IDs and envelopes, and fails the
|
|
43
|
+
connection on malformed, uncorrelated or oversized replies. It drains stderr without retaining
|
|
44
|
+
arbitrary native diagnostics in memory. Read command-level diagnostics from their typed results
|
|
45
|
+
and the existing profile diagnostic locations.
|
|
46
|
+
|
|
47
|
+
Finish owned Ghidra contexts with the normal scoped commands, following the project's shared
|
|
48
|
+
server policy. Then `await cli.close()` drains already admitted requests and ends this stdio
|
|
49
|
+
connection. It does not issue `ipc-server stop`, close another agent's context or stop a server.
|
|
50
|
+
Do not call close while expecting to admit more requests.
|
|
@@ -51,6 +51,18 @@ finding. Narrow the query or raise its budget within the declared bound. Oversiz
|
|
|
51
51
|
also stop a scan rather than silently claiming complete coverage. Returned string values are
|
|
52
52
|
bounded; check truncation fields.
|
|
53
53
|
|
|
54
|
+
`strings list` and `strings search` visit **defined data**, not every possible literal in memory.
|
|
55
|
+
The visited-input budget includes non-string data. Zero matches with an incomplete scan means
|
|
56
|
+
the searched prefix contains no matches; it does not establish absence. Increasing `--offset`
|
|
57
|
+
only skips matching rows from that same scan and cannot reach a later unscanned string. These
|
|
58
|
+
scans have no continuation cursor. Increase `--max-scan` up to 200000 when that covers the
|
|
59
|
+
needed data. A narrower text filter alone does not skip earlier visited data or reach beyond
|
|
60
|
+
that bound; use an explicitly addressed memory search when the needed region is known.
|
|
61
|
+
For undefined ASCII/UTF-16 literals, encode the expected bytes and use
|
|
62
|
+
`analysis search-byte-patterns --pattern <hex> --max-bytes <bytes>`; that separate initialized-
|
|
63
|
+
memory search exposes `--scan-from`/`next_address` continuation. Byte matches still need
|
|
64
|
+
interpretation and do not define string data or prove a stored xref exists.
|
|
65
|
+
|
|
54
66
|
Bounded string/instruction regex search supports literals, escapes, anchors, character classes
|
|
55
67
|
and at most one `.*` wildcard. Branching/nested repetition and unsupported patterns are rejected.
|
|
56
68
|
Use the literal `strings search --contains` convenience when no regex is needed.
|
|
@@ -24,11 +24,47 @@ establishes that the old owned bootstrap worker has ended, then uses an authorit
|
|
|
24
24
|
probe. An absent canonical item permits private preparation; an existing first version requires
|
|
25
25
|
independent readback. The old project, intent and original session/target remain preserved.
|
|
26
26
|
|
|
27
|
+
## Interrupted save or close
|
|
28
|
+
|
|
29
|
+
After restoring profile storage, inspect the selected session and target with
|
|
30
|
+
`sessions status <session> --target <target>`. Retry the original save/close with the
|
|
31
|
+
same `--request-id`. If the original command had no caller ID, use the generated
|
|
32
|
+
`unresolvedRequests[].id` from status. This retrieves the original intent instead of
|
|
33
|
+
creating another close. A verified stopped worker lets close report `state: closed`
|
|
34
|
+
and retain the acknowledged private snapshot and pending changes; it sends no new save,
|
|
35
|
+
open, close or publication. Reopen the same session/target afterward.
|
|
36
|
+
|
|
37
|
+
If release cannot be proved, the command still fails with `coordinator.unknown`
|
|
38
|
+
and gives scoped status/process inspection commands. An authenticated live worker is not
|
|
39
|
+
closed again automatically. Retain its project and journals. After inspecting its retained
|
|
40
|
+
work, an operator may terminate that exact owned headless worker through
|
|
41
|
+
`tools processes kill <process>` with Destructive permission, accepting loss of any
|
|
42
|
+
unacknowledged in-memory work. Do not kill by guessed PID/port or stop the shared server.
|
|
43
|
+
Retrieve the same close request after that worker has ended. An unavailable endpoint or
|
|
44
|
+
changed process receipt is not proof of release; preserve the binding for investigation.
|
|
45
|
+
|
|
27
46
|
If a response was lost, inspect `sessions status <session> --target <target>`. Never infer
|
|
28
47
|
`applied` from a connection failure. A changing command's optional request ID binds one effective
|
|
29
48
|
intent inside the profile. Repeating the same ID/input retrieves its recorded outcome or
|
|
30
49
|
unresolved state; changing input under that ID fails. Without an ID, calls are new intentions.
|
|
31
50
|
|
|
51
|
+
For Java `scripts run-inline`, a versioned native executor records compilation, non-initializing
|
|
52
|
+
class resolution, initialization, construction and framework execution separately. A correlated
|
|
53
|
+
receipt proving `userCode: not_started` and `entrypointInvoked: false` before initialization
|
|
54
|
+
produces `state: rejected` with a terminal failed request. The context remains available and
|
|
55
|
+
its prior saved/pending work is unchanged. The CLI exits nonzero; the error result retains
|
|
56
|
+
bounded compiler/load diagnostics. Repeating that request ID retrieves the same rejection;
|
|
57
|
+
corrected source requires a new ID. Each attempt has isolated source/classes under profile
|
|
58
|
+
analysis storage, with annotation processing disabled and no reuse of older inline classes.
|
|
59
|
+
|
|
60
|
+
Initialization or constructor failure can have effects even when `run()` was never called.
|
|
61
|
+
These failures, framework/runtime failures and missing/malformed/lost acknowledgements remain
|
|
62
|
+
unknown. During framework execution `entrypointInvoked: null` means actual `run()` entry was
|
|
63
|
+
not independently observed. Console text cannot establish non-execution. This is not a sandbox
|
|
64
|
+
for adversarial same-JVM Java, and existing unknown script attempts are not reclassified from
|
|
65
|
+
their exception strings or an unchanged program snapshot. File/Python scripts retain their
|
|
66
|
+
existing conservative recovery semantics.
|
|
67
|
+
|
|
32
68
|
An unknown or partial effect retains its request intent, snapshots and native stage. Open the
|
|
33
69
|
same tuple to reconcile supported outcomes. A committed merge is verified against its recorded
|
|
34
70
|
server version and complete saved buffers through independent read authority; it is never
|
|
@@ -17,6 +17,13 @@ Open input with `insight-cli ghidra open ./client.exe --session new --json`. Sto
|
|
|
17
17
|
`session` and `target` as the explicit scope for every later research call. Names are display
|
|
18
18
|
labels; equal filenames or addresses in different inputs do not select the same object.
|
|
19
19
|
|
|
20
|
+
If the database has missing strings/xrefs, one-byte function bodies or no Listing instructions,
|
|
21
|
+
use [sparse navigation](sparse-navigation.md) before following the metadata-only route below.
|
|
22
|
+
It distinguishes existing entries, undefined code and undefined literals. For raw literals,
|
|
23
|
+
use `strings anchors --text Widget --encodings ascii,utf16le --scan-from START --scan-through END`,
|
|
24
|
+
then explicit batched code references and function inspection. Candidate context remains
|
|
25
|
+
separate from exact match addresses; coverage, decoding, caps and cursor are explained there.
|
|
26
|
+
|
|
20
27
|
Use `ghidra strings search --contains config.json`, then `ghidra xrefs to --address <string>`.
|
|
21
28
|
Reference results include a containing function address when available. Pass that address to
|
|
22
29
|
`ghidra functions get` or `ghidra functions decompile`. Add the same session/target selectors and
|
|
@@ -105,6 +112,19 @@ native, a sanitized diagnostic of at most 500 Unicode characters. Reasons distin
|
|
|
105
112
|
`function_not_found`, `native_function_failure`, `selector_mismatch`, `invalid_native_shape`,
|
|
106
113
|
`missing_signature` and `missing_decompiler_text`. Missing definitions remain failures; reads
|
|
107
114
|
never create functions or run analysis. JSON-RPC `cli.execute` preserves the same error data.
|
|
115
|
+
If executable bytes are known but the function is absent, use the read-only `functions decode`
|
|
116
|
+
command below at the explicit address. A containing function with a one-byte body and missing
|
|
117
|
+
stored xrefs can also indicate sparse metadata. Decode reveals bounded local instruction flow;
|
|
118
|
+
it does not repair function boundaries or establish whole-function callers/callees. Defining
|
|
119
|
+
functions or disassembling the listing requires a separate explicit Update operation.
|
|
120
|
+
For a known existing entry, try compact `functions inspect` first; use
|
|
121
|
+
`functions force-decompile --function <entry>` to refresh stale/failed decompiler output.
|
|
122
|
+
Its result is `value.decompiled`, and its pinned upstream work bound is not guaranteed.
|
|
123
|
+
Successful transient decompilation can coexist with an empty Listing and missing stored xrefs.
|
|
124
|
+
It does not create an absent function or repair its saved body. Avoid repeating it merely to
|
|
125
|
+
populate `functions disassemble`; use bounded `decode` for local instruction corroboration.
|
|
126
|
+
Per-item inspection failures retain the facade recovery message in `error` and the bounded
|
|
127
|
+
native explanation separately in `nativeDiagnostic`; use stable `reason` for classification.
|
|
108
128
|
|
|
109
129
|
The existing `functions inspect` accepts 1–20 distinct names/addresses. Existing `--fields`
|
|
110
130
|
remain valid; unknown fields fail before dispatch. Decompiled text uses per-item
|
|
@@ -129,6 +149,32 @@ host, including through JSON-RPC; it is never silently a client-host path. An ex
|
|
|
129
149
|
is rejected. A filesystem failure can leave a partial new directory without a completed manifest;
|
|
130
150
|
retain it for inspection and choose a fresh directory for another explicit save.
|
|
131
151
|
|
|
152
|
+
For sparse interior addresses, opt in to
|
|
153
|
+
`functions inspect --functions <hex-addresses> --resolve-address containing-or-preceding --max-entry-distance 4096`.
|
|
154
|
+
The distance is required (1–65536 bytes), applies only to fallback and is rejected without the
|
|
155
|
+
mode. Names/address-space prefixes are not accepted in this mode. Exact entries and recorded
|
|
156
|
+
body containment take precedence in valid default-space memory, including non-executable or
|
|
157
|
+
uninitialized blocks. Otherwise the nearest previous known entry is considered only inside
|
|
158
|
+
the same initialized executable memory block as the query.
|
|
159
|
+
No byte search, analysis or function creation is performed.
|
|
160
|
+
|
|
161
|
+
Every resolved row retains `entry_point` and `resolution`, even if `--fields` omits entry metadata
|
|
162
|
+
or the function read fails. Kinds are `exact-entry`, `recorded-containing` and
|
|
163
|
+
`preceding-entry-candidate`. `recordedBodyContainsAddress` is actual stored body membership,
|
|
164
|
+
not semantic proof. `distanceBytes` is zero for exact entries and the positive offset for
|
|
165
|
+
preceding candidates; it is omitted for recorded containment, whose body can precede its entry.
|
|
166
|
+
`status: success` means the selected function was read, not that the query belongs to it.
|
|
167
|
+
|
|
168
|
+
`--functions` preserves original selector spelling as keys, including hexadecimal aliases.
|
|
169
|
+
Selected entries are deduplicated for native reads, but inline text is charged for every
|
|
170
|
+
original row in selector order. Each saved row keeps its mapping; owner-save paths remain
|
|
171
|
+
per-selector. `--function` retains the existing single-row result/error behavior. Policy misses
|
|
172
|
+
are per-item `not_found` with `address_out_of_range`,
|
|
173
|
+
`address_not_in_initialized_executable_block`, `no_preceding_entry`, `entry_outside_block` or
|
|
174
|
+
`entry_distance_exceeded`; these do not claim that code or an unknown function is absent.
|
|
175
|
+
The before/after guard covers both lookup and inspection, and native selector/entry mismatches
|
|
176
|
+
fail. Existing view continuation/text hashes, text windows and result/file bounds still apply.
|
|
177
|
+
|
|
132
178
|
`functions decode --address <address> --max-bytes 64 --max-instructions 16` uses Ghidra pseudo
|
|
133
179
|
instructions without defining listing instructions, functions or xrefs, running analyzers or
|
|
134
180
|
saving state. It requires initialized executable memory and currently supports x86 language
|
|
@@ -139,3 +185,44 @@ computed from instruction bytes, not proof of function membership or stored xref
|
|
|
139
185
|
flow has no invented target. Decoding stops at terminal/unconditional flow, input/instruction
|
|
140
186
|
bounds, undecodable/truncated bytes or unavailable context. Existing `disassemble-bytes` remains
|
|
141
187
|
an Update operation with its original guards.
|
|
188
|
+
|
|
189
|
+
## Navigation and lifecycle diagnostics
|
|
190
|
+
|
|
191
|
+
`analysis navigation` uses the selected session/target and ReadOnly permission. It reports
|
|
192
|
+
`initialAnalysis` (`none` or `requested`) as the original facade import policy, separately from
|
|
193
|
+
the current metadata observations. Prior analysis history is unknown, including saved/imported
|
|
194
|
+
databases. `ready` means the context opened; it does not establish analysis completeness.
|
|
195
|
+
|
|
196
|
+
The diagnostic samples at most 128 functions, instructions, stored references and defined-data
|
|
197
|
+
units per category, in address order, sharing `--max-scan` (default 10000, 1–200000) and a fixed
|
|
198
|
+
five-second native deadline. Each category reports its own completion; top-level `scan` reports
|
|
199
|
+
the visited sum, sample bound, completion and reason. Defined-string counts cover only sampled
|
|
200
|
+
defined data. One-byte bodies together with missing entry instructions in at least 80% of the
|
|
201
|
+
sample yield `sparse-metadata`; this is an explicit heuristic, not proof that a specific analysis
|
|
202
|
+
pass failed. Normal instruction-bearing one-byte leaf functions alone do not trigger it.
|
|
203
|
+
Follow [sparse navigation](sparse-navigation.md): known function entries can use compact inspection
|
|
204
|
+
and cache refresh; executable bytes without an entry use bounded decode, undefined literals use
|
|
205
|
+
byte search and explicit continuation. The diagnostic does
|
|
206
|
+
not run analyzers, define data, repair boundaries, save a snapshot or certify semantic completeness.
|
|
207
|
+
|
|
208
|
+
`diagnostics lifecycle` reads retained start/restore/stop events and the current process receipt
|
|
209
|
+
without starting or probing Ghidra. At most the latest 128 observations are retained. A stopped
|
|
210
|
+
receipt can identify `explicit_close`, `view_replaced`, `mode_changed`, `startup_failed` or
|
|
211
|
+
`owner_dispose`; historical receipts without reasons remain `unknown`. Owner disposal does not
|
|
212
|
+
establish whether Factory exited due to idle, explicit stop, a signal or another cause. A current
|
|
213
|
+
receipt without a matching stop receipt reports `unobserved`, not a claim that the PID is live.
|
|
214
|
+
|
|
215
|
+
Internal correlated timing diagnostics live under profile workspace `diagnostics/timings.jsonl`,
|
|
216
|
+
with one previous segment and an eight-MiB rotation threshold. They contain operation names,
|
|
217
|
+
timestamps, correlation/parent IDs, duration and success/failure, not argv, source, payloads or
|
|
218
|
+
exception text. They are an internal troubleshooting format, not a public trace API. Nested spans
|
|
219
|
+
must not be added to their parents. `facade.command` starts at the handler and ends before Factory
|
|
220
|
+
serializes the response; client startup, IPC and response overhead are not separately measured.
|
|
221
|
+
Tracing is best-effort and cannot change program outcomes. Empty runtime readiness checks still
|
|
222
|
+
avoid creating a research workspace. The Factory idle policy remains unchanged.
|
|
223
|
+
|
|
224
|
+
For sparse PE32+/AMD64 interior addresses, `functions inspect --resolve-address
|
|
225
|
+
containing-or-pe-runtime --max-unwind-bytes 4194304` uses fully validated current mapped runtime
|
|
226
|
+
regions and independent recorded-body facts. Conflicting or missing entries remain partial with
|
|
227
|
+
evidence; incomplete/malformed/unavailable metadata prevents automatic selection. This is not
|
|
228
|
+
semantic function reconstruction; see [sparse navigation](sparse-navigation.md).
|
|
@@ -11,7 +11,7 @@ external executable paths, status/doctor and safe removal. Existing Factory prof
|
|
|
11
11
|
The package contains the verified GhidraMCP 7.0.0 bridge, its Apache-2.0 license/notice and
|
|
12
12
|
artifact provenance. Its pinned functionality catalog is from source
|
|
13
13
|
`57e37a8bf388b1279cff46378f85be1554548f61`, with SHA256
|
|
14
|
-
`
|
|
14
|
+
`f4a9272e911466ed774c8cf73bc1adf1daef6009d895fda57aa0b28522fcdf32`.
|
|
15
15
|
`mcpJar` optionally selects another copy of those exact verified bytes. Runtime startup needs no
|
|
16
16
|
bridge/Factory source checkout or Python MCP bridge. Packaged native helper sources compile
|
|
17
17
|
against the installed Ghidra/JDK.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Navigate a sparse database
|
|
2
|
+
|
|
3
|
+
Function counts and `ready` do not establish decoded bodies, strings or xrefs. A one-byte
|
|
4
|
+
function entry without Listing instructions can still be useful to the decompiler. Choose
|
|
5
|
+
the route from the actual observation before building a script or requesting broad analysis.
|
|
6
|
+
|
|
7
|
+
All examples below need the same `--session S --target T --json`. Replace placeholder
|
|
8
|
+
addresses with observed addresses in that input; symbols and offsets never transfer implicitly.
|
|
9
|
+
Use generated help for exact flags.
|
|
10
|
+
|
|
11
|
+
| Observation | Next command | What it establishes |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
|Empty navigation results / suspicious body sizes|`analysis navigation`|Bounded metadata samples and coverage; no analysis is started|
|
|
14
|
+
|Known function entries, even without Listing|`functions inspect --functions 0xENTRY_A,0xENTRY_B --fields decompiled_code,callees --include-call-context false`|Up to20 compact decompiler observations; inspect each status and truncation|
|
|
15
|
+
|Interior code addresses with sparse saved bodies|`functions inspect --functions 0xCODE_A,0xCODE_B --resolve-address containing-or-preceding --max-entry-distance 4096 --fields entry_point,decompiled_code --include-call-context false`|One guarded lookup+inspection; a preceding entry is explicitly a candidate, not established containment|
|
|
16
|
+
|Stale/failed decompilation at a known entry|`functions force-decompile --function 0xENTRY`|Fresh native decompiler output in `value.decompiled`; no function creation or Listing repair|
|
|
17
|
+
|Known executable bytes, no function entry|`functions decode --address 0xCODE --max-bytes 64 --max-instructions 16`|Bounded local instructions/direct targets, input hash and stop reason; no persistent definitions|
|
|
18
|
+
|Expected literal absent from defined strings|`strings anchors --text SPARSE --encodings ascii,utf16le --scan-from 0xREGION_START --scan-through 0xREGION_END`|Exact raw hits plus separate bounded NUL candidate context, explicit coverage and stateless cursor|
|
|
19
|
+
|
|
20
|
+
## Follow existing entries first
|
|
21
|
+
|
|
22
|
+
Start with a small set of independently known entries: exported symbols, retained project
|
|
23
|
+
evidence for this exact build or direct targets from bounded decode. Check the function selector;
|
|
24
|
+
an interior address is not automatically an entry. Compact inspection avoids unrelated metadata
|
|
25
|
+
and supports mixed outcomes, text paging and owner-host saves. For large output, use
|
|
26
|
+
`--save-owner-directory <new-absolute-directory>` and retain its hash manifest; see
|
|
27
|
+
[research](research.md) for Unicode windows, view guards and native truncation.
|
|
28
|
+
Empty `callees` or xrefs on a sparse database do not prove that the decompiled function
|
|
29
|
+
has no calls. Keep decompiler observations distinct from stored-reference coverage.
|
|
30
|
+
|
|
31
|
+
For known interior addresses, the explicit resolution mode avoids the separate name/prefix
|
|
32
|
+
search. It accepts addresses only and requires the distance bound. Inspect `resolution.kind`
|
|
33
|
+
for every result: `exact-entry`, `recorded-containing`, or `preceding-entry-candidate`.
|
|
34
|
+
Recorded containment is a database fact, not validated source membership. The fallback may
|
|
35
|
+
point into unrelated padding, split code or an incorrect prior function. It is not a repair.
|
|
36
|
+
Exact/recorded containment take precedence; the distance limit applies only to fallback.
|
|
37
|
+
See [research](research.md) for mixed outcomes, original selector keys and shared budgets.
|
|
38
|
+
|
|
39
|
+
Use `force-decompile` when a fresh decompiler pass is needed. It does not accept the inspect
|
|
40
|
+
text-window/save flags; its ordinary query response is capped at1MiB and reports the pinned
|
|
41
|
+
upstream work bound as not guaranteed. Selecting one entry narrows the request but is not a
|
|
42
|
+
hard instruction/CPU bound. A host running-session ID must be awaited, not retried as failure.
|
|
43
|
+
No successful decompile is proof of complete control flow, correct types or valid function bounds.
|
|
44
|
+
|
|
45
|
+
After transient decompilation, `functions disassemble`, instruction search and stored xrefs can
|
|
46
|
+
remain empty. Repeating cache refresh does not populate them. Corroborate an important store,
|
|
47
|
+
branch or call with bounded `decode` at its observed instruction address. Its direct targets are
|
|
48
|
+
local decoded flow, not a complete call graph. Neither route runs the target program.
|
|
49
|
+
|
|
50
|
+
## When entries or literals are absent
|
|
51
|
+
|
|
52
|
+
An absent function stays absent after `force-decompile`. Use bounded decode, retaining its
|
|
53
|
+
stop reason; do not silently create functions to make a read succeed. Decode stops at terminal
|
|
54
|
+
or unconditional flow and has byte/instruction limits; it is not whole-function reconstruction.
|
|
55
|
+
Persistent Listing/entry/body repair is a separate explicit Update operation in the owned
|
|
56
|
+
context, followed by saved readback. Consult `functions create`, `functions disassemble-bytes`
|
|
57
|
+
and their generated help rather than an unbounded all-function reconstruction script.
|
|
58
|
+
|
|
59
|
+
For literal search, prefer `strings anchors` with explicit encodings and both inclusive bounds.
|
|
60
|
+
It searches raw initialized bytes, merges adjacent initialized blocks, and never bridges a hole.
|
|
61
|
+
Read `matchAddress` as the exact target; a nullable candidate `start` is a separate observation.
|
|
62
|
+
NUL candidates are not semantic strings. `textFrom` is the preview address; `complete`,
|
|
63
|
+
boundary evidence and `decoding` qualify it. Invalid or capped context keeps the raw hit.
|
|
64
|
+
Continue using `value.cursor`; only page budgets can change. `scan.complete` refers to search
|
|
65
|
+
coverage, not complete candidate text. Context/prefetch/rereads consume `max-bytes` (minimum
|
|
66
|
+
32768), and the default payload cap is 1024 bytes. Retain all `(address,encoding)` pairs,
|
|
67
|
+
including overlaps and UTF-16 at odd addresses. It performs no definitions, analysis or save.
|
|
68
|
+
Then pass selected exact match addresses to one batched `analysis code-references`, and
|
|
69
|
+
selected code addresses to `functions inspect` with the explicit resolution mode above.
|
|
70
|
+
|
|
71
|
+
For arbitrary masked binary patterns, encode ASCII/UTF-16 as appropriate with the existing
|
|
72
|
+
`analysis search-byte-patterns`; for example `--pattern '53 50 41 52 53 45'` is ASCII `SPARSE`.
|
|
73
|
+
Quote spaced hex patterns. Read `complete`, `scanned_bytes`, `next_address` and the bounds;
|
|
74
|
+
continue with `--scan-from <next_address>`. `--offset` on defined-string results does not
|
|
75
|
+
advance memory coverage. A narrowed text filter does not skip earlier non-string defined data.
|
|
76
|
+
Use `memory list` to identify initialized/executable blocks; do not assume a guessed block name
|
|
77
|
+
or that the image-base address belongs to executable code.
|
|
78
|
+
|
|
79
|
+
Byte matches are not validated code references. Existing xrefs describe saved DB metadata.
|
|
80
|
+
For exact RIP-relative operands or direct CALL destinations, use the bounded ReadOnly candidate
|
|
81
|
+
scanner below. Arbitrary scripts remain potential writes with saved-state/recovery costs;
|
|
82
|
+
a compile/transport error must not be blindly replayed.
|
|
83
|
+
|
|
84
|
+
## Raw-byte code-reference candidates (V1)
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
insight-cli ghidra analysis code-references --session S --target T \
|
|
88
|
+
--to 180080000,180080008 --forms call-rel32,lea-rip,mov-rip,call-rip-slot \
|
|
89
|
+
--scan-from 180000000 --scan-through 18002101f --limit 100 --json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`value.matches` contains instruction bytes, full length, operand index/width, exact target,
|
|
93
|
+
form, native instruction text and boundary evidence. Example row:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{"from":"180000060","to":"180080008","form":"call-rip-slot","bytes":"ff15a2ff0700","length":6,"operand_index":0,"operand_bits":64,"target_role":"pointer-slot","validation":"decoded","boundary":"unconfirmed","instruction":"CALL qword ptr [0x180080008]"}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Targets are
|
|
100
|
+
1–64 distinct default-space unsigned 64-bit addresses, comma separated; they share one pass.
|
|
101
|
+
Only x86 little-endian 64-bit languages with known 64-bit decode mode are supported. No code
|
|
102
|
+
executes, and no Listing instructions, functions or xrefs are created. This does not follow
|
|
103
|
+
register values, indirect callees, thunks, pointer contents or control flow.
|
|
104
|
+
|
|
105
|
+
| Form | Supported encoding | Target role |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| `call-rel32` | E8 + signed rel32 | `direct-call-target` |
|
|
108
|
+
| `lea-rip` | 8D, ModRM RIP-relative | `effective-address` |
|
|
109
|
+
| `mov-rip` | GPR MOV 88/89/8A/8B, ModRM RIP-relative | `effective-address` |
|
|
110
|
+
| `call-rip-slot` | FF /2, ModRM RIP-relative | `pointer-slot` |
|
|
111
|
+
|
|
112
|
+
Forms default to all four; `--forms` restricts them. Legacy 66/26/2E/36/3E and REX prefixes
|
|
113
|
+
are admitted only when the native full decode agrees with the constrained encoding/length.
|
|
114
|
+
REX before a later legacy prefix is reset. Widths are explicit: `lea eax` and `lea rax` remain
|
|
115
|
+
distinct. V1 excludes 67 address override, FS/GS, LOCK/REP, C6/C7 immediate MOV,
|
|
116
|
+
MOVSX/MOVZX/MOVSXD and SIMD/VEX/EVEX **at that candidate start**. A later byte inside any
|
|
117
|
+
instruction or immediate can independently decode as a supported candidate.
|
|
118
|
+
|
|
119
|
+
Each byte offset is tested, including overlapping and prefix-alternative starts; advancement
|
|
120
|
+
is one byte. `listing-confirmed` requires a matching stored instruction and compatible bytes,
|
|
121
|
+
length and operand display. `listing-conflict` means overlap/disagreement with a stored
|
|
122
|
+
instruction. `unconfirmed` means neither. Even listing-confirmed is not proof of execution,
|
|
123
|
+
function membership or a complete call graph. LEA is an effective address, not a memory read.
|
|
124
|
+
|
|
125
|
+
`--scan-through` is the inclusive final byte, and each match fits entirely inside the original
|
|
126
|
+
range. Only initialized executable default-space memory is visited. Adjacent eligible blocks
|
|
127
|
+
merge so an instruction may cross their boundary; holes, uninitialized blocks and non-executable
|
|
128
|
+
memory never bridge. A complete scan only exhausts this declared eligible input/form set.
|
|
129
|
+
|
|
130
|
+
`value.scan` reports `bytes_read` (including lookahead and rereads), `tested_starts`,
|
|
131
|
+
`visited_candidates` (selected-form encoding prefilter hits, including target/decode rejects),
|
|
132
|
+
`next_start` (first unchecked start), `complete`, `reason` and native `elapsed_ms`.
|
|
133
|
+
The frontier can skip ineligible gaps; it does not assert that gap bytes were decoded.
|
|
134
|
+
Reasons are `exhausted`, `byte_limit`, `candidate_limit`, `timeout` and `result_limit`.
|
|
135
|
+
The native cooperative deadline is checked even in no-match regions. Compile/dispatch/view
|
|
136
|
+
observation time is outside that deadline; it remains part of command wall time.
|
|
137
|
+
|
|
138
|
+
Defaults: 4MiB bytes, 200000 candidates, 5 seconds and 100 matches. Maxima: 16MiB,
|
|
139
|
+
1000000 candidates, 30 seconds and 1000 matches. Minimum byte budget is15, so a maximum-length
|
|
140
|
+
x86 start can progress with its lookahead. No semantic completeness is implied by these limits.
|
|
141
|
+
|
|
142
|
+
For an incomplete result, continue with the opaque stateless token:
|
|
143
|
+
|
|
144
|
+
```sh
|
|
145
|
+
insight-cli ghidra analysis code-references --session S --target T \
|
|
146
|
+
--cursor TOKEN --limit 1000 --max-bytes 8388608 --json
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Cursor excludes `--to`, `--forms`, `--scan-from` and `--scan-through`; omitted controls inherit
|
|
150
|
+
the previous page. It binds the normalized original query, frontier, algorithm version, selected
|
|
151
|
+
context/snapshot/generation, native modification observation and process incarnation. Scope,
|
|
152
|
+
format or version mismatch fails; view changes, including restoring the same snapshot in a new
|
|
153
|
+
JVM, fail with `changed_view`. Start a new query after such a change. Before/after observations
|
|
154
|
+
share the context's ordered action; a native modification guard additionally covers the scan.
|
|
155
|
+
|
|
156
|
+
Tokens are unsigned, untrusted continuation parameters, not evidence that earlier offsets were
|
|
157
|
+
scanned. There is no cursor registry, per-query snapshot or journal save. Retain page results
|
|
158
|
+
if coverage evidence is needed. The trusted helper still uses the existing inline-script
|
|
159
|
+
transport and incurs its compile/dispatch cost; arbitrary user scripts remain Update operations.
|
|
160
|
+
|
|
161
|
+
## PE runtime regions for sparse function inspection
|
|
162
|
+
|
|
163
|
+
Use `ghidra functions inspect --functions <addresses> --resolve-address containing-or-pe-runtime`
|
|
164
|
+
when PE32+/AMD64 runtime metadata can replace manual preceding-entry checks.
|
|
165
|
+
`--max-unwind-bytes` bounds returned header/table bytes across the batch (default4194304,
|
|
166
|
+
1–16777216); lookup has a fixed5-second cooperative deadline. It reads current mapped headers
|
|
167
|
+
at the actual image base and the whole declared Exception Directory, without a file fallback,
|
|
168
|
+
section-name assumption, analysis or function creation. Unavailable/malformed/incomplete lookup
|
|
169
|
+
blocks selection and retains DB facts; `boundary_conflict` and `runtime_entry_not_defined` retain
|
|
170
|
+
validated bounds. A runtime region does not prove instruction boundaries, semantic membership
|
|
171
|
+
or whole-function bounds; leaf routines may have no record. No preceding fallback is used.
|
|
172
|
+
Batch unresolved rows are partial; a single unresolved selector returns a partial CLI error
|
|
173
|
+
with lookup/view/evidence. Guards cover failed dispatch; existing text paging/save rules apply.
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
# Analysis storage and migration
|
|
2
2
|
|
|
3
3
|
`storage show --json` reports effective profile storage, availability, active file/byte usage,
|
|
4
|
-
exact included trees
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
to
|
|
4
|
+
exact included trees, retained migration and installation default base. Before selecting a
|
|
5
|
+
base, storage starts in Factory profile AppData. `configure` and `migrate` select that base
|
|
6
|
+
for subsequent new/empty profiles as well as moving the current profile. Add `--profile-only`
|
|
7
|
+
to keep the installation default unchanged. The effective root appends `insight-cli/<profile>`.
|
|
8
|
+
Initialized profiles keep their existing locations when the default changes; profiles with
|
|
9
|
+
ordinary AppData analysis trees stay there until explicitly migrated.
|
|
10
|
+
|
|
11
|
+
The per-profile non-secret `analysisDirectory` setting remains in Factory's profile. The
|
|
12
|
+
installation default is bound storage-control metadata beside Factory's profile store, paired
|
|
13
|
+
with ownership metadata on the chosen base. It is not an environment or checkout setting.
|
|
14
|
+
Missing/replaced storage fails before creating analysis data; there is no system-disk fallback.
|
|
15
|
+
New profiles initialize on their first ordinary command, durably bind their own empty directory,
|
|
16
|
+
and keep permanent compatibility paths. `storage show` remains passive.
|
|
8
17
|
|
|
9
18
|
```sh
|
|
10
19
|
insight-cli permissions grant Update
|
|
@@ -29,7 +38,20 @@ user-selected outputs outside these trees keep their locations.
|
|
|
29
38
|
|
|
30
39
|
Factory keeps profiles, permissions, IPC election/socket, migration-control metadata and
|
|
31
40
|
application logs in current-user AppData. Secrets stay in the OS keyring. Credential/profile
|
|
32
|
-
identities do not change. Updating/installing npm
|
|
41
|
+
identities do not change. Updating/installing npm preserves existing profile locations and does not select a disk on its own.
|
|
42
|
+
|
|
43
|
+
## Select a default after an earlier migration
|
|
44
|
+
|
|
45
|
+
For installations migrated with an older CLI, select their existing mounted base once:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
insight-cli storage default --directory "/mnt/analysis volume" --json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This Update operation changes the installation default without moving existing data. Future
|
|
52
|
+
profiles inherit it without repeating configuration. The base cannot be inside a profile data
|
|
53
|
+
root or overlap Factory control storage. A base owned by another installation is rejected.
|
|
54
|
+
A missing volume or replaced base/ownership marker is never adopted automatically.
|
|
33
55
|
|
|
34
56
|
## Move an existing profile
|
|
35
57
|
|
|
@@ -44,7 +66,7 @@ insight-cli storage migrate --directory "/mnt/analysis volume" --json
|
|
|
44
66
|
insight-cli storage show --json
|
|
45
67
|
```
|
|
46
68
|
|
|
47
|
-
Dry-run checks separation, destination contents, access, conservative capacity and quiescence
|
|
69
|
+
Dry-run reports whether it would select the installation default and checks separation, destination contents, access, conservative capacity and quiescence
|
|
48
70
|
without reserving/copying a migration. Source/destination/configuration roots cannot be equal
|
|
49
71
|
or nested. Destination symlink roots, escaping source links, special files, unresolved links
|
|
50
72
|
and inventories above one million entries or 128 directory levels are rejected. Internal
|
|
@@ -72,7 +94,9 @@ file, rechecks capacity and finishes the retained transaction. Source and destin
|
|
|
72
94
|
anchor identities are bound durably. Missing/replaced volumes fail without creating a system-disk
|
|
73
95
|
fallback; mount the original volume before resuming.
|
|
74
96
|
|
|
75
|
-
Rollback restores retained source and the prior Factory setting.
|
|
97
|
+
Rollback restores retained source and the prior Factory setting. The installation default stays
|
|
98
|
+
selected because subsequent profiles may already use it; a resumed older migration cannot
|
|
99
|
+
overwrite a newer default selection. After activation it requires
|
|
76
100
|
an unchanged destination and a verified retained source. Native reopening or later findings can
|
|
77
101
|
make rollback unsafe, in which case it refuses and preserves both copies. Use forward migration
|
|
78
102
|
to another empty base after using the new location. A rolled-back destination remains for manual
|
|
@@ -97,3 +121,7 @@ before starting another. This release provides no nonempty-destination adoption,
|
|
|
97
121
|
synchronization, live-DB snapshotting or network-filesystem guarantees. POSIX directory fsync
|
|
98
122
|
is used. Windows has file fsync and rename/junction semantics; Node cannot fsync directories
|
|
99
123
|
there, and internal symlinks can require OS privileges.
|
|
124
|
+
|
|
125
|
+
Empty-profile initialization resumes automatically on its next command after interruption. Its
|
|
126
|
+
retained source contains no analysis entries, so the CLI cleans only that owned empty backup
|
|
127
|
+
automatically. Migration of existing data always retains its source for explicit cleanup.
|
|
@@ -3,7 +3,7 @@ name: insight-ilspy
|
|
|
3
3
|
description: Recover C#, inspect IL/types/metadata, extract resources or export projects from managed .NET assemblies through insight-cli ILSpy. Choose native analysis for NativeAOT or ordinary PE machine code.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Insight ILSpy 0.
|
|
6
|
+
# Insight ILSpy 0.4.0
|
|
7
7
|
|
|
8
8
|
If local help/status reports AppData or IPC access denied, retry that **read-only probe**
|
|
9
9
|
with the agent host's normal permission escalation, then use that route for later authorized
|
|
@@ -3,7 +3,7 @@ name: insight-interop
|
|
|
3
3
|
description: Trace a .NET P/Invoke declaration to an explicitly supplied native library export and Ghidra function through insight-cli ilspy query, binary query and scoped ghidra APIs. Use for managed/native linkage evidence while keeping static correspondence separate from observed loading or execution.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Insight Interop 0.
|
|
6
|
+
# Insight Interop 0.4.0
|
|
7
7
|
|
|
8
8
|
If local help/status reports AppData or IPC access denied, retry that **read-only probe**
|
|
9
9
|
with the agent host's normal permission escalation, then use that route for later authorized
|