dsh-plugin-rea 1.0.5 → 2.0.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/CHANGELOG.md +139 -1
- package/README.md +210 -210
- package/README.zh-CN.md +239 -0
- package/assets/make-screenshots.ps1 +14 -8
- package/assets/screenshot-1.png +0 -0
- package/bin/rea-shim.mjs +356 -0
- package/check-updates.ps1 +71 -1
- package/cordis.patch.yml +39 -31
- package/docs/bundle-design.md +186 -0
- package/manifest/bundle.manifest.json +399 -0
- package/package.json +23 -3
- package/scripts/audit-manifest.mjs +445 -0
- package/scripts/rea-bundle-bootstrap.ps1 +192 -0
- package/scripts/setup.mjs +1453 -0
- package/scripts/setup.test.mjs +418 -0
- package/scripts/verify-branch.ps1 +131 -0
package/README.md
CHANGED
|
@@ -2,255 +2,255 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/dsh-plugin-rea)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
> -
|
|
13
|
-
>
|
|
14
|
-
>
|
|
15
|
-
>
|
|
16
|
-
>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
**What this plugin adds.** Exactly two things: it registers that MCP server into DSH's tool layer
|
|
43
|
-
under the `mcp__rea__*` names, and it lets the engine environment (`GHIDRA_INSTALL_DIR`, …) be scoped
|
|
44
|
-
to that MCP child process instead of the whole harness.
|
|
45
|
-
|
|
46
|
-
**What it can and cannot do.** The analysis is upstream's; this section only restates upstream's own
|
|
47
|
-
contract so expectations are right.
|
|
5
|
+
**English** · [简体中文](README.zh-CN.md)
|
|
6
|
+
|
|
7
|
+
Brings the upstream **[REA — Reverse Engineer Anything](https://github.com/morluto/rea)** MCP server into
|
|
8
|
+
**DeepSeek Harness** (dsh), so its tools show up in a session as `mcp__rea__*`.
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
> **This is the 2.x line, and `main` is it.** The all-in-one variant: it provisions the runtime (Node, the REA
|
|
13
|
+
> CLI, a JDK, Ghidra) and then wires the row itself. The original configuration-only adapter — 1.x, which
|
|
14
|
+
> assumed you had installed Node, `rea-agents` and Ghidra yourself — is preserved on the
|
|
15
|
+
> [`v1` branch](https://github.com/czcdr/dsh-plugin-rea/tree/v1) and on npm as `dsh-plugin-rea@1.0.6`.
|
|
16
|
+
> The two lines are compared in [Two lines: 1.x and 2.x](#two-lines-1x-and-2x).
|
|
17
|
+
|
|
18
|
+
## What this is
|
|
19
|
+
|
|
20
|
+
A **Cordis bundle with a provisioning layer**. `package.json` declares `dsh.bundle.patch`, and that patch
|
|
21
|
+
inserts one row of the official MCP client plugin (`@deepseek-ai/dsh-mcp-client`). The row launches
|
|
22
|
+
`bin/rea-shim.mjs` with the running Node executable; the shim reads the machine-local state that
|
|
23
|
+
`scripts/setup.mjs` wrote and starts the REA CLI it provisioned. There is no analysis code here, and the
|
|
24
|
+
published patch contains no machine path.
|
|
25
|
+
|
|
26
|
+
> **Third-party adapter.** This repository is not part of REA, ships none of REA's code, and is not
|
|
27
|
+
> maintained by REA's authors. It composes one configuration row and fetches upstream's own releases.
|
|
28
|
+
> Upstream: [github.com/morluto/rea](https://github.com/morluto/rea) (MIT) ·
|
|
29
|
+
> [docs](https://github.com/morluto/rea#what-you-can-analyze) ·
|
|
30
|
+
> [rea.tools](https://rea.tools/) · npm package `rea-agents`.
|
|
31
|
+
> REA's own problems go to its tracker; **this plugin's** problems go to
|
|
32
|
+
> [this repository's issues](https://github.com/czcdr/dsh-plugin-rea/issues).
|
|
33
|
+
|
|
34
|
+
**It adds exactly three things:** the tool registration under the `mcp__rea__*` names, the per-machine
|
|
35
|
+
engine environment (`GHIDRA_INSTALL_DIR`, `JAVA_HOME`, `REA_ADB_PATH`, `REA_APKTOOL_COMMAND`,
|
|
36
|
+
`REA_JADX_MCP_JAR`, `REA_BROWSER_EXECUTABLE`, …) scoped to that MCP child instead of the whole harness, and
|
|
37
|
+
the provisioning that puts those components on disk.
|
|
38
|
+
|
|
39
|
+
## What it can and cannot do
|
|
40
|
+
|
|
41
|
+
The analysis is upstream's; this section only restates upstream's own contract so expectations are right.
|
|
48
42
|
|
|
49
43
|
- **It cannot recover complete source code.** For native binaries upstream returns *pseudocode and
|
|
50
|
-
assembly*, for Android APKs *decompiled methods*, for JEB units *pseudocode*, and for
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- Not recoverable in practice: original identifier names, types, comments, macros and template
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- Every result carries **confidence and limitations** (`observed` / `derived` / `inferred`, plus an
|
|
57
|
-
|
|
44
|
+
assembly*, for Android APKs *decompiled methods*, for JEB units *pseudocode*, and for JavaScript/Electron
|
|
45
|
+
*modules and their relations*. Upstream's tool contract states the pseudocode "is decompiler output, not
|
|
46
|
+
original source and not text-equivalent" to another provider's output.
|
|
47
|
+
- Not recoverable in practice: original identifier names, types, comments, macros and template expansion,
|
|
48
|
+
build scripts and assets. Optimisation (inlining, reordering), symbol stripping, obfuscation, packing and
|
|
49
|
+
VM protection only make the output worse.
|
|
50
|
+
- Every result carries **confidence and limitations** (`observed` / `derived` / `inferred`, plus an explicit
|
|
51
|
+
limitations list). Read them as evidence, never as recovered source.
|
|
58
52
|
- Good for: understanding behaviour, locating an implementation, interoperability and compatible
|
|
59
|
-
re-implementation, security review, migration reference. To obtain actual source code, use the
|
|
60
|
-
|
|
53
|
+
re-implementation, security review, migration reference. To obtain actual source code, use the legitimate
|
|
54
|
+
route — the upstream repository, vendor authorisation, or the vendor's own SDK.
|
|
61
55
|
|
|
62
|
-
**
|
|
56
|
+
**What provisioning cannot buy you.** These are upstream host gates, not settings this plugin forgot:
|
|
63
57
|
|
|
64
|
-
|
|
|
58
|
+
| Capability | Gate |
|
|
65
59
|
|---|---|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
|
60
|
+
| Hopper provider | macOS only |
|
|
61
|
+
| IDA provider | needs your own IDA and `REA_IDA_MCP_CONFIG`; REA never launches IDA |
|
|
62
|
+
| firmware `binwalk` / `unblob` | Linux only |
|
|
63
|
+
| Wakaru JS recovery, pwntools ELF/recorded-crash paths | Linux x64 only |
|
|
64
|
+
| pwndbg / gdb core context | Linux, macOS |
|
|
65
|
+
| native mitmproxy captures | Linux (`REA_MITMDUMP_COMMAND`); HAR needs no engine |
|
|
66
|
+
| Apple toolchain (Mach-O, plist, asset catalog, LLDB) | macOS only |
|
|
67
|
+
| `capture_process_scenario` | Linux/macOS PTY |
|
|
68
|
+
| apktool (Android resource decoding) | available only when `REA_APKTOOL_COMMAND` points at something Node can **execute directly**: upstream `execFile`s that command without a shell, and Windows cannot execute a `.bat`/`.cmd` that way (EINVAL). This bundle wires the official `apktool.bat` as upstream documents, so on Windows the launcher reports no version and the capability stays unavailable; JADX (a jar) is unaffected |
|
|
69
|
+
|
|
70
|
+
## Two lines: 1.x and 2.x
|
|
71
|
+
|
|
72
|
+
| | **2.x** — this line, `main` | **1.x** — [`v1`](https://github.com/czcdr/dsh-plugin-rea/tree/v1) |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| What it is | the adapter **plus provisioning**: it prepares Node, the REA CLI, a JDK and Ghidra, then wires the row | configuration-only adapter: one MCP row pointing at a `rea` you installed yourself |
|
|
75
|
+
| What you need first | nothing for the runtime — provisioning fetches what is missing (with `--reuse` it adopts an existing Ghidra/JDK instead) | Node.js on REA's engines, `npm i -g rea-agents`, and Ghidra 12.1.x for native analysis |
|
|
76
|
+
| First run | run `scripts/setup.mjs` (or the bootstrap) once, then restart dsh | nothing to run |
|
|
77
|
+
| The row launches | the running Node executable plus `<DSH_HOME>/plugins/rea-bundle/bin/rea-shim.mjs`, which reads that machine's state | `cmd.exe /c rea mcp` on Windows, `rea mcp` on macOS/Linux |
|
|
78
|
+
| Machine state | `<DSH_HOME>/plugins/rea-bundle/` — `bundle.json`, `vendor/`, `cache/` | your own REA and Ghidra installs |
|
|
79
|
+
| Install | `dsh plugin --profile <profile> add dsh-plugin-rea` (npm `latest` ≥ 2.0.0) | `… add dsh-plugin-rea@1.0.6`, or `github:czcdr/dsh-plugin-rea#v1.0.6` |
|
|
80
|
+
|
|
81
|
+
Both lines ship the **same patch shape** — one `insert` row of `@deepseek-ai/dsh-mcp-client` — and offer the
|
|
82
|
+
same `mcp__rea__*` surface; they differ in who prepares the runtime. Moving from 1.x to 2.x takes two
|
|
83
|
+
commands: see [Upgrading from 1.x](#upgrading-from-1x).
|
|
84
|
+
|
|
85
|
+
## Install
|
|
86
|
+
|
|
87
|
+
**Nothing to install first.** On a bare Windows x64 machine:
|
|
72
88
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
**Prerequisites.** Node.js (a version REA accepts) and the REA CLI installed globally
|
|
78
|
-
(`npm i -g rea-agents`). For native analysis, Ghidra 12.1.x (Hopper / IDA are alternatives under
|
|
79
|
-
their own licences). Static JavaScript/Electron and .NET analysis need no engine.
|
|
89
|
+
```
|
|
90
|
+
powershell -ExecutionPolicy Bypass -File scripts\rea-bundle-bootstrap.ps1 -Reuse
|
|
91
|
+
```
|
|
80
92
|
|
|
81
|
-
|
|
93
|
+
`-Reuse` adopts a Ghidra/JDK you already have; omit it to download both (about 775 MB from the official
|
|
94
|
+
releases, checksum-verified). Then install the plugin for your profile:
|
|
82
95
|
|
|
83
96
|
```
|
|
84
|
-
dsh plugin --profile <profile> add github:czcdr/dsh-plugin-rea
|
|
85
|
-
# or, from npm:
|
|
86
97
|
dsh plugin --profile <profile> add dsh-plugin-rea
|
|
98
|
+
# or pin this release instead of tracking npm latest:
|
|
99
|
+
dsh plugin --profile <profile> add github:czcdr/dsh-plugin-rea#v2.0.0
|
|
87
100
|
```
|
|
88
101
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
102
|
+
> **On an Electron host (the DeepSeek Harness desktop app) the profile is owned by the application.**
|
|
103
|
+
> `dsh plugin --profile desktop …` is refused by the CLI (`profile "desktop" is managed exclusively by
|
|
104
|
+
> the Electron application`) — install or update through the in-app plugin manager instead. The CLI form
|
|
105
|
+
> above is for a profile you created yourself with the CLI under another name.
|
|
93
106
|
|
|
94
|
-
|
|
95
|
-
required.
|
|
96
|
-
- macOS/Linux: `command: rea`, `args: ['mcp']` — see
|
|
97
|
-
[`examples/cordis.patch.posix.yml`](examples/cordis.patch.posix.yml).
|
|
107
|
+
If Node is already installed, you can skip the bootstrap and run provisioning directly:
|
|
98
108
|
|
|
99
|
-
|
|
100
|
-
|
|
109
|
+
```
|
|
110
|
+
node scripts/setup.mjs --reuse # or --dry-run to see the plan first
|
|
111
|
+
```
|
|
101
112
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
113
|
+
Installing the plugin **first** also works, but it takes two steps. The row resolves to
|
|
114
|
+
`<DSH_HOME>/plugins/rea-bundle/bin/rea-shim.mjs`, and that file is created by setup — so until the first
|
|
115
|
+
provisioning run the row exits with `MODULE_NOT_FOUND`, and nothing is there to start a background
|
|
116
|
+
provisioning (the harness itself is unaffected: `failOnStartupError: false` is deliberate). Run
|
|
117
|
+
`node scripts/setup.mjs` once; from then on the shim is in place, and every later missing state is picked up
|
|
118
|
+
by the shim itself, which provisions in the background.
|
|
105
119
|
|
|
106
|
-
|
|
107
|
-
environment to the child (minus names that look like secrets), and the patch dialect evaluates
|
|
108
|
-
`!!js` expressions, so `GHIDRA_INSTALL_DIR: !!js process.env.GHIDRA_INSTALL_DIR` also works.
|
|
120
|
+
## Configure — nothing
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
`cordis.patch.yml` (id-targeted config override). That file is machine-local and never published:
|
|
122
|
+
The shipped row carries **no machine path**:
|
|
112
123
|
|
|
113
124
|
```yaml
|
|
114
|
-
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
125
|
+
- insert:
|
|
126
|
+
- id: mcp-rea
|
|
127
|
+
name: '@deepseek-ai/dsh-mcp-client'
|
|
128
|
+
config:
|
|
129
|
+
serverName: rea
|
|
130
|
+
transport: stdio
|
|
131
|
+
command: !!js process.execPath
|
|
132
|
+
args:
|
|
133
|
+
- !!js "(process.env.DSH_HOME && process.env.DSH_HOME.trim() !== '' ? process.env.DSH_HOME : (process.env.USERPROFILE || process.env.HOME || '') + '/.dsh') + '/plugins/rea-bundle/bin/rea-shim.mjs'"
|
|
134
|
+
- mcp
|
|
135
|
+
env:
|
|
136
|
+
ELECTRON_RUN_AS_NODE: '1'
|
|
137
|
+
failOnStartupError: false
|
|
118
138
|
```
|
|
119
139
|
|
|
120
|
-
|
|
140
|
+
Three details in that row are load-bearing, and all three were bugs first:
|
|
121
141
|
|
|
122
|
-
**
|
|
123
|
-
|
|
124
|
-
`
|
|
142
|
+
- **The `!!js` scalar is quoted.** A bare scalar containing `? ` and `: ` is not one scalar: YAML reads it as an explicit key/value pair, so the loader receives a *mapping* where an expression belongs. Measured against the harness's own dialect (`JSON_SCHEMA` plus the `!!js` type from `app.asar`), the unquoted form made `args[0]` into `{"[object Object]": "..."}` — an object the row cannot launch with. Quoting removes the ambiguity, and the JS string literals inside then use single quotes.
|
|
143
|
+
- **Forward slashes, never backslashes.** A single-quoted YAML scalar keeps `\` literal, and JavaScript then consumes it: `'\plugins'` is not a path but the BEL control character, `'\rea-bundle'` becomes a carriage return and `'\bin'` a backspace — the path is destroyed silently. Forward slashes work on Windows and on POSIX.
|
|
144
|
+
- **The `DSH_HOME` fallback is `<home>/.dsh`, not `<home>`.** The shim, `setup.mjs` and `bootstrap.ps1` all resolve an unset `DSH_HOME` to `<home>/.dsh/...`; a fallback that stopped one level higher made the row point at a file provisioning never writes — invisible on any machine where `DSH_HOME` happens to be set.
|
|
145
|
+
- **No `path`/`require` in a `!!js` expression**: `ctx` is the loader scope, so the DSH_HOME fallback is written as plain concatenation.
|
|
146
|
+
|
|
147
|
+
`npm run bundle:audit` enforces the first three: it evaluates this exact expression with `DSH_HOME` unset, empty and set, and rejects a bare scalar that YAML would read as a mapping.
|
|
125
148
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
**Updating — two independent things, both manual.**
|
|
132
|
-
|
|
133
|
-
- **This plugin** never updates itself. Installed from a plugin market? Update it **in that market**.
|
|
134
|
-
Installed from a local `file:` checkout? Overwrite the directory and install it again. Updating REA
|
|
135
|
-
below does **not** update this plugin, and updating this plugin does not touch REA.
|
|
136
|
-
- **Upstream REA**: `npm i -g rea-agents@latest`. Its `bin` entry (`scripts/rea.mjs`) is stable across
|
|
137
|
-
releases, so this needs no change here.
|
|
138
|
-
- **Ghidra** is version-gated by REA (12.1.x today): update REA first, then check that it accepts a
|
|
139
|
-
newer Ghidra.
|
|
140
|
-
- **DeepSeek Harness**: a harness upgrade may change the MCP client's config schema — inspect the row
|
|
141
|
-
with `Config.listConfigs name=@deepseek-ai/dsh-mcp-client` and adjust the field names.
|
|
142
|
-
|
|
143
|
-
`check-updates.ps1` (Windows PowerShell) reports the state of all four at once, and
|
|
144
|
-
`.github/workflows/validate.yml` enforces the bundle's shape — including "the shipped patch must not
|
|
145
|
-
contain a machine-specific path" — in CI.
|
|
146
|
-
|
|
147
|
-
**License.** MIT (this adapter). REA is MIT and owned by its authors; Ghidra is Apache-2.0 and owned
|
|
148
|
-
by the NSA. No upstream code is redistributed here.
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
## 中文
|
|
153
|
-
|
|
154
|
-
**作用。** 本插件**自身不做任何逆向分析**。它把上游 REA 的 MCP 服务接入 DeepSeek Harness,
|
|
155
|
-
让 REA 提供的那套工具在会话里变成可直接调用的 `mcp__rea__*`。
|
|
156
|
-
|
|
157
|
-
按上游自述,REA 是「**通过一个 MCP 服务,逆向分析二进制文件、应用程序和运行时行为**」——
|
|
158
|
-
「看到喜欢的功能,弄清它的工作原理,深入到二进制层面」。它「将智能体连接到分析工具,用于检查
|
|
159
|
-
原生二进制文件、JavaScript 和 Electron 应用、.NET 程序集以及网站」;分析在本机运行,结果包含
|
|
160
|
-
支撑各项结论的证据和相关限制。原生分析可以使用已有的 Hopper、Ghidra 或 IDA,静态 JavaScript 分析
|
|
161
|
-
不需要原生引擎。
|
|
162
|
-
|
|
163
|
-
上游列出的可分析目标(原文见 [README_zh.md#可以分析什么](https://github.com/morluto/rea/blob/main/README_zh.md#可以分析什么)):
|
|
164
|
-
原生二进制文件——伪代码、汇编、字符串、符号、调用和引用;JavaScript / Electron——模块、导入、
|
|
165
|
-
source map、路由与 IPC;网站——页面结构、脚本、网络观察结果与截图;.NET 程序集;Android APK;
|
|
166
|
-
Android 设备(adb);JEB 项目;Android 资源;固件;软件包与资源;进程行为;以及离线 ELF 布局、
|
|
167
|
-
EVM 字节码、已记录的 Linux 崩溃与已保存的网络捕获。
|
|
168
|
-
|
|
169
|
-
**本插件在此之上只增加两件事**:把该 MCP 服务注册进 DSH 的工具层(工具名 `mcp__rea__*`),
|
|
170
|
-
以及让引擎环境变量(`GHIDRA_INSTALL_DIR` 等)只作用于这个 MCP 子进程,而不是整个 harness。
|
|
171
|
-
|
|
172
|
-
**能做什么、不能做什么(重要)。** 分析能力由上游提供;这里只复述上游自己的契约,避免预期错位。
|
|
173
|
-
|
|
174
|
-
- **无法完整还原源代码。** 上游对原生二进制返回的是**伪代码与汇编**,对 Android APK 返回
|
|
175
|
-
**反编译的方法**,对 JEB 单元返回**伪代码**,对 JavaScript/Electron 返回**模块及其关系**。
|
|
176
|
-
上游的工具契约明确写着:伪代码是反编译器输出,**不是原始源码**,且与其他提供方的输出
|
|
177
|
-
**不保证文本等价**。
|
|
178
|
-
- 实践中不可恢复的内容:原始标识符命名、类型、注释、宏与模板展开、构建脚本与资源;
|
|
179
|
-
优化(内联、指令重排)、去符号(strip)、混淆、加壳与 VM 保护只会让可读性更差。
|
|
180
|
-
- 每条结论都自带**置信度与限制**(`observed` / `derived` / `inferred`,另有 limitations 列表):
|
|
181
|
-
请把它们当作证据使用,而不要当作"已还原的源码"。
|
|
182
|
-
- 适合做:理解行为、定位实现、互操作与兼容实现、安全审计、迁移参考。
|
|
183
|
-
**要拿到真正的源码,请走正规渠道**——上游代码仓库、厂商授权,或厂商自己的 SDK。
|
|
184
|
-
|
|
185
|
-
**已验证版本**(作者机器,2026-10-12/13):REA `6.4.0`、DeepSeek Harness 桌面运行时 `0.2.0-rc.2`
|
|
186
|
-
(自带 dsh CLI `0.1.7-rc.2`)、Ghidra `12.1.4`、Node `24.21.0`、Windows 11 x64。行提供方
|
|
187
|
-
`@deepseek-ai/dsh-mcp-client` 由 harness 自带(npm 最新 `0.0.1-rc.1`)。发布用的这一行**实测跑通过**:
|
|
188
|
-
`list_documents` 在 `cmd.exe` 形式下正常应答,`open_binary` 走 `ghidra` 提供方成功,
|
|
189
|
-
而引擎目录仅来自本机 profile 覆盖。
|
|
190
|
-
|
|
191
|
-
**前置条件。** 满足 REA 要求的 Node;全局安装 REA(`npm i -g rea-agents`)。原生分析需要
|
|
192
|
-
Ghidra 12.1.x(Hopper / IDA 为替代方案,各自需授权);静态 JavaScript/Electron 与 .NET 分析
|
|
193
|
-
不需要引擎。
|
|
194
|
-
|
|
195
|
-
**安装。**
|
|
149
|
+
`ELECTRON_RUN_AS_NODE` only matters if the harness itself runs on Electron; it is harmless for a plain Node host, and stating it explicitly beats relying on it surviving the child-env scrub.
|
|
150
|
+
|
|
151
|
+
`command` is the running Node executable and `args[0]` is computed from `DSH_HOME`, so the same patch works
|
|
152
|
+
on Windows, macOS and Linux without a PATH entry. Everything machine-specific lives in
|
|
153
|
+
`<DSH_HOME>/plugins/rea-bundle/bundle.json`, written by setup and readable with:
|
|
196
154
|
|
|
197
155
|
```
|
|
198
|
-
|
|
199
|
-
#
|
|
200
|
-
dsh plugin --profile <profile> add dsh-plugin-rea
|
|
156
|
+
node bin/rea-shim.mjs --shim-status # resolved paths, versions, verification state
|
|
157
|
+
node bin/rea-shim.mjs --shim-print-env # the environment the MCP child will see
|
|
201
158
|
```
|
|
202
159
|
|
|
203
|
-
|
|
204
|
-
|
|
160
|
+
Both commands answer with the same bundle whether you run them from the plugin directory (the checkout copy)
|
|
161
|
+
or from `<DSH_HOME>/plugins/rea-bundle` (the mirrored copy): the checkout resolves the location by the same
|
|
162
|
+
rule setup uses, while the mirror uses its own position — it cannot rely on `DSH_HOME`, which the harness
|
|
163
|
+
strips from an MCP child's environment.
|
|
205
164
|
|
|
206
|
-
|
|
165
|
+
Setting `REA_BUNDLE_AUTO_PROVISION=0` disables the first-run background provisioning.
|
|
207
166
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
167
|
+
To pin a different launch command on this machine (for example your own globally installed `rea`), override
|
|
168
|
+
the row from the profile's own `cordis.patch.yml` — that file is machine-local and never published. Only one
|
|
169
|
+
row may use `serverName: rea` in a profile.
|
|
211
170
|
|
|
212
|
-
|
|
171
|
+
## Verify
|
|
213
172
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
173
|
+
Ask for a `mcp__rea__*` call — `binary_session` reports the engine checks
|
|
174
|
+
(`configuration` / `installation` / `headless` / `native_decompiler` / `java`), all of which should be
|
|
175
|
+
`ok: true`. Then `open_binary` a PE, `binary_overview`, and `procedure_pseudo_code`.
|
|
217
176
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
同样可用。
|
|
177
|
+
Provisioning itself ends with two probes: `rea doctor --json` (reported, with unmet checks named) and the
|
|
178
|
+
exact shim launch the MCP row will use.
|
|
221
179
|
|
|
222
|
-
|
|
223
|
-
该文件只在你本机、永不随插件发布:
|
|
180
|
+
## Verified against
|
|
224
181
|
|
|
225
|
-
|
|
226
|
-
- id: mcp-rea
|
|
227
|
-
config:
|
|
228
|
-
env:
|
|
229
|
-
GHIDRA_INSTALL_DIR: '<你的 Ghidra 12.1.x 目录>'
|
|
230
|
-
```
|
|
182
|
+
Author's machine, 2026-10-13 / 14:
|
|
231
183
|
|
|
232
|
-
|
|
184
|
+
| Component | Version |
|
|
185
|
+
|---|---|
|
|
186
|
+
| REA (`rea-agents`) | **6.4.0** (170 tools) |
|
|
187
|
+
| DeepSeek Harness | desktop runtime **0.2.0-rc.2**, with its bundled dsh CLI 0.1.7-rc.2 |
|
|
188
|
+
| `@deepseek-ai/dsh-mcp-client` (row provider) | bundled by the harness |
|
|
189
|
+
| Ghidra | 12.1.4 |
|
|
190
|
+
| JDK | Temurin 21 (provisioned) / Microsoft OpenJDK 25.0.4 (adopted) |
|
|
191
|
+
| Node.js | 24.21.0 (REA engines: `^22.19.0 \|\| ^24.11.0 \|\| >=26.0.0`) |
|
|
192
|
+
| Host | Windows 11 x64 (build 26200) |
|
|
193
|
+
|
|
194
|
+
Exercised live: a clean `setup.mjs --reuse` run reached `setup complete`; an MCP `initialize` handshake
|
|
195
|
+
**through the shim with no `rea` on PATH** answered `serverInfo {name: rea, version: 6.4.0}`; and the whole
|
|
196
|
+
chain ran under the real desktop host — its own Electron binary launched
|
|
197
|
+
`<DSH_HOME>/plugins/rea-bundle/bin/rea-shim.mjs mcp`, the shim started the **vendored** REA, and a live tool
|
|
198
|
+
call reported `path_source: environment` for a path only that machine's `bundle.json` knows.
|
|
233
199
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
200
|
+
Not exercised end to end here, and therefore not claimed: the ~775 MB JDK + Ghidra download branch (planned
|
|
201
|
+
by `--dry-run`, but this machine adopted its existing installs with `--reuse`), and first runs on
|
|
202
|
+
macOS/Linux.
|
|
237
203
|
|
|
238
|
-
|
|
239
|
-
`failOnStartupError: false`,因此 REA 缺失也不会阻塞 harness 启动。部分 REA 工具会启动进程、
|
|
240
|
-
写文件、访问网络,按 DSH 的权限策略执行。请仅分析你已获得授权的目标。
|
|
204
|
+
## Scope and caveats
|
|
241
205
|
|
|
242
|
-
|
|
206
|
+
- REA exposes 170 tools at 6.4.0, so every session's tool list grows.
|
|
207
|
+
- Provisioning is honest about checksums: where a vendor publishes one it is pinned and verified; where none
|
|
208
|
+
exists (jadx-headless-mcp, the apktool wrapper, Android platform-tools, the rolling "latest" URLs) the
|
|
209
|
+
hash is **measured once and recorded**, and later drift is reported rather than silently accepted.
|
|
210
|
+
`bundle.json` lists which components are in that state under `unverifiedChecksums`.
|
|
211
|
+
- Downloads are slow on some networks (measured 0.35–0.54 MiB/s from the GitHub release CDN here, so Ghidra
|
|
212
|
+
alone takes ~25–45 min). Fetching is resumable: the cache is kept and re-verified, and a killed run
|
|
213
|
+
continues instead of restarting.
|
|
214
|
+
- Some REA tools launch processes, write files and access the network — DSH's permission policy applies.
|
|
215
|
+
Analyse only artifacts you are authorized to inspect.
|
|
216
|
+
- `scripts/setup.mjs` runs `npm install` for the REA CLI with `--ignore-scripts`: the published tarball
|
|
217
|
+
carries no `node_modules`, so a dependency closure must be resolved, and package lifecycle scripts are
|
|
218
|
+
skipped on purpose during provisioning.
|
|
243
219
|
|
|
244
|
-
|
|
245
|
-
覆盖目录后在插件管理器里重装。下面更新 REA **不会**更新本插件,反过来也一样。
|
|
246
|
-
- **上游 REA**:用 `npm i -g rea-agents@latest` 更新。它的 `bin` 入口(`scripts/rea.mjs`)
|
|
247
|
-
跨版本稳定,所以本插件无需改动。
|
|
248
|
-
- **Ghidra**:受 REA 版本门槛限制(当前 12.1.x),先升 REA,再确认它接受新版 Ghidra。
|
|
249
|
-
- **DeepSeek Harness**:升级可能改变 MCP 客户端配置结构,用
|
|
250
|
-
`Config.listConfigs name=@deepseek-ai/dsh-mcp-client` 看该行 schema 并调整字段名。
|
|
220
|
+
## Updating — three independent things
|
|
251
221
|
|
|
252
|
-
|
|
253
|
-
|
|
222
|
+
### Upgrading from 1.x
|
|
223
|
+
|
|
224
|
+
Install 2.x, then run provisioning **once** before restarting dsh:
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
node scripts/setup.mjs # or: powershell -File scripts\rea-bundle-bootstrap.ps1 -Reuse
|
|
228
|
+
```
|
|
254
229
|
|
|
255
|
-
|
|
256
|
-
|
|
230
|
+
Why it matters: the 1.x row launched `rea mcp` from PATH, while the 2.x row launches
|
|
231
|
+
`<DSH_HOME>/plugins/rea-bundle/bin/rea-shim.mjs` — a file only `setup.mjs` creates. Upgrade and restart
|
|
232
|
+
without provisioning and that row exits with `MODULE_NOT_FOUND`: the harness stays up
|
|
233
|
+
(`failOnStartupError: false` is deliberate), but the `mcp__rea__*` tools are gone and you get **no
|
|
234
|
+
remediation message**, because the shim that prints one does not exist yet. After the setup run they are
|
|
235
|
+
back on the next start.
|
|
236
|
+
|
|
237
|
+
- **This plugin** never updates itself. Installed from a market? Update it there. Installed from a `file:`
|
|
238
|
+
checkout? Overwrite the directory and reinstall.
|
|
239
|
+
- **Upgrading from `2.0.0-bundle.1`**: that release mirrored the shim and `setup.mjs` but not the manifest,
|
|
240
|
+
and recorded nothing about the plugin checkout, so a bundle it provisioned cannot repair itself — its
|
|
241
|
+
background provisioning dies on the missing manifest, invisibly, and its own lock suppresses retries for
|
|
242
|
+
six hours. Re-run `node scripts/setup.mjs` **from the plugin directory** once; it re-mirrors all three
|
|
243
|
+
files and writes the record that lets later runs find the checkout. `check-updates.ps1` reports this state.
|
|
244
|
+
- **Provisioned components**: re-run `node scripts/setup.mjs`; it re-verifies what is on disk and only
|
|
245
|
+
fetches what is missing or wrong. Pins live in `manifest/bundle.manifest.json`.
|
|
246
|
+
- **Upstream REA / Ghidra**: update the pins in the manifest, then re-run setup. REA version-gates Ghidra
|
|
247
|
+
(12.1.x today), so update REA first.
|
|
248
|
+
|
|
249
|
+
`check-updates.ps1` (Windows PowerShell) reports the state of all of these at once.
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
MIT (this adapter). REA is MIT and owned by its authors; Ghidra is Apache-2.0 and owned by the NSA; Temurin
|
|
254
|
+
is GPLv2+CE; Node.js is MIT; apktool, jadx-headless-mcp and Android platform-tools keep their own licences.
|
|
255
|
+
**No upstream code or binary is redistributed in this package** — provisioning fetches each component from
|
|
256
|
+
its official source.
|