vaguue/Ghidra.js
GitHub: vaguue/Ghidra.js
为 Ghidra 逆向工程框架提供基于 V8 引擎的 JavaScript/TypeScript 脚本绑定及 AI Agent 支持。
Stars: 38 | Forks: 3
# Ghidra JavaScript 集成 [](https://github.com/vaguue/Ghidra.js/blob/main/LICENSE) [](https://www.npmjs.com/package/ghidra.js)
## 概述
本项目使用 [Javet](https://github.com/caoccao/Javet) 库将 JavaScript 集成到 Ghidra 逆向工程框架中。有关选择该库的更多详细信息,请参阅[库的选择](#library-choice)章节。
## 与 AI 编程 Agent 配合使用
Ghidra.js 提供了一个 [Agent Skill](https://agentskills.io/),用于教 AI 编程 Agent(Claude Code、Cursor、Codex 以及[更多](https://github.com/vercel-labs/skills))如何编写和运行 Ghidra.js 脚本——包括 CLI 工作流、注入的全局变量、事务以及运行时限制。只需一条命令即可将其安装到你的 agent 中:
```
npx skills add vaguue/Ghidra.js
```
然后只需让你的 agent 分析一个二进制文件,它就会知道如何导入该文件并对其运行脚本。该 Skill 位于 [`skills/ghidra-scripting`](skills/ghidra-scripting/SKILL.md)。
## 系统要求
- 已安装 [Ghidra](https://github.com/NationalSecurityAgency/ghidra) 框架
- 支持的平台:Windows (x86_64)、Linux (x86_64)、MacOS (x86_64 或 arm64)
- (可选)已安装 npm
## 快速入门
你可以从 Releases 页面下载适用于你平台的 .zip 压缩包。然后打开你的 Ghidra 安装目录,转到 `File -> Install Extensions`,点击 `+` 符号,然后选择下载的压缩包。该扩展将在下次启动 Ghidra 时生效。或者,你可以通过 npm 安装,但需确保 Ghidra 的安装文件夹(包含 `ghidraRun` 脚本的文件夹)在你的 PATH 中。例如:
```
export PATH="$PATH:/path/to/your/Ghidra"
npm install -g ghidra.js
```
## 命令行界面
安装该软件包还会为你提供一个 `ghidra.js` CLI,它封装了 Ghidra 的 `analyzeHeadless`,因此你可以直接从终端导入二进制文件并对其运行脚本——无需 GUI。系统会自动定位你的 Ghidra 安装路径(通过 `ghidraRun` 启动器、常见的安装路径或 `GHIDRA_INSTALL_DIR`)。
使用 `npx ghidra.js
` 运行,或者全局安装(`npm install -g ghidra.js`)后直接调用 `ghidra.js`。
### 快速开始
```
# 1. 将 binary 导入 Ghidra 项目(运行一次 auto-analysis)
npx ghidra.js import ./target.bin
# 2. 针对已分析的程序运行脚本(JavaScript 或 TypeScript)
npx ghidra.js run analyze.ts target.bin
```
其模式是**导入一次,多次运行**:`import` 会在当前目录创建一个 Ghidra 项目并分析二进制文件;`run` 会复用已经分析过的程序,因此在脚本上迭代非常快。脚本会获得与 Ghidra 内部相同的全局变量(`currentProgram`、`JavaHelper`、Node 内置模块等)——参见[示例代码](#example-code)。脚本所做的更改会被保存回项目中。
### 命令
```
# 导入 binary(添加 --no-analysis 以跳过分析,--overwrite 以重新导入)
ghidra.js import [--no-analysis] [--overwrite] [--folder ]
# 运行脚本;在 `--` 之后向脚本传递参数
ghidra.js run [-- ]
# 在最近的 package.json 中读取/写入项目设置(git-config 风格)
ghidra.js config [value] [--unset] # keys: project, name, connect, keystore
```
用于 `run` 的 `` 可以是源文件路径、项目中的程序名称,或者是项目内的路径(如 `/malware/foo.so`)(或使用 `--folder`)。
### 项目配置
在无配置的情况下,`import`/`run` 会使用以最近的 `package.json`(或 `ghidra`)命名的项目,该项目位于该包的目录中——因此这些命令在任何项目中均可直接运行。要固定特定的项目目录或名称,请使用 `config` 或在 `package.json` 中添加 `"ghidra"` 字段:
```
// package.json
"ghidra": {
"project": "./re", // directory holding the .gpr, or a ghidra:// URL
"name": "analysis" // project name
}
```
### TypeScript
`run` 在将脚本交给 Ghidra 之前会使用 [esbuild](https://esbuild.github.io/) 进行构建,因此 `.ts` 文件可以直接使用——无需手动编译。安装类型定义以获得编辑器支持:
```
npm install --save-dev @types/ghidra.js
```
### 远程 / 共享项目
要连接到 [Ghidra Server](https://ghidra.re/) 仓库,请将 `project` 指向 `ghidra://` URL 并提供凭据:
```
npx ghidra.js config project ghidra://server:13100/my-repo
npx ghidra.js config connect alice
npx ghidra.js import ./target.bin --commit "initial import"
npx ghidra.js run analyze.ts target.bin
```
连接标志(`--connect `、`--password`、`--keystore `)也可按命令单独使用。
## 在 Ghidra 内部编写 TypeScript 脚本
当通过 Ghidra 自带的 Script Manager(而非 CLI)运行脚本时,没有构建步骤,因此必须先将 TypeScript 编译为 JavaScript。[`@types/ghidra.js`](#typescript) 类型定义在两种情况下的工作方式相同。
## 示例代码
要开始使用该扩展,请参考以下代码示例。更多信息可在 [Ghidra API 文档](https://ghidra.re/ghidra_docs/api/ghidra/program/flatapi/FlatProgramAPI.html)中找到。更多示例可以在 [ghidra_scripts](https://github.com/vaguue/Ghidra.js/tree/main/ghidra_scripts) 文件夹中找到。
```
//you can use Node.js modules
const fs = require('fs');
// JavaHelper.getClass is a helper method to import Java classes
const EmulatorHelper = JavaHelper.getClass('ghidra.app.emulator.EmulatorHelper');
const domainFile = currentProgram.getDomainFile();
console.log('Current arch:', process.arch); //Node globals are also available
console.log('Program Name:', currentProgram.getName());
console.log('Program Path:', domainFile.getPathname());
console.log('File Format:', currentProgram.getExecutableFormat());
console.log('Language:', currentProgram.getLanguageID().getIdAsString());
console.log('Compiler Spec:', currentProgram.getCompilerSpec().getCompilerSpecID().getIdAsString());
// To make changes, use Ghidra's transaction API
// This is to give users more flexibility without automatic setup
const id = currentProgram.startTransaction('Hello world comment');
const functionManager = currentProgram.getFunctionManager();
const symbols = currentProgram.getSymbolTable().getGlobalSymbols('main')
if (symbols) {
const [mainSymbol] = symbols;
const main = functionManager.getFunctionAt(mainSymbol.getAddress());
main.setComment('Hello world from JavaScript');
}
else {
console.log('[!] Main function not found');
}
currentProgram.endTransaction(id, true);
```
## 运行脚本
### 在 Ghidra 内部
要在 Ghidra 环境中运行脚本,请按照以下步骤操作:
1. 打开 Ghidra 并加载你的项目。
2. 点击 "Window" 菜单并选择 "Script Manager",导航到 "Script Manager"。
3. 在 Script Manager 中,找到你的 JavaScript 文件。你可以通过点击 "Manage Script Directories" 图标并添加脚本所在目录来导入你的脚本。
4. 双击脚本运行它,或者选中脚本后点击 "Run" 按钮。
### 使用 analyzeHeadless
你也可以使用 `analyzeHeadless` 命令以 headless(无 GUI)模式运行脚本。这对于自动化分析或批处理特别有用。以下是一个命令示例:
```
/path/to/Ghidra/support/analyzeHeadless /path/to/projectDir -process yourExecutable -scriptPath /path/to/scripts -postScript YourScript.js
```
将 /path/to/Ghidra 替换为 Ghidra 的安装目录,/path/to/projectDir 替换为你的项目目录路径,yourExecutable 替换为你要分析的文件,/path/to/scripts 替换为包含你脚本的目录,YourScript.js 替换为你的 JavaScript 文件名。
## 库的选择
我为扩展的后端考虑了三个选项:Rhino、GraalJS 和 Javet。所有选项在某种程度上都适用,但 Javet 最合适,原因如下:
- **性能:** Javet 使用 V8 引擎,在我的基准测试中,它比其他替代方案快几百倍。
- **ESM 标准:** Javet 支持最新的 JavaScript 标准,与 Rhino 相比,这是一个显著的优势。
- **无需修改 JVM:** 这一要求使得 GraalJS 的充分利用变得极其复杂。
这些论点并不是对其他替代方案的批评,而是我为扩展选择后端的理由。仓库中仍然保留了用于运行 Rhino 和 GraalJS 的代码,以防万一。
## 问题或建议
欢迎在本仓库的 Issues 部分提交任何 issue。目前对格式没有任何限制。标签:CMS安全, Ghidra, JavaScript, JS文件枚举, MITM代理, 云资产清单, 域名枚举, 数据可视化, 自动化分析, 跨站脚本, 逆向工程