安全与风控
在没有 GUI 的情况下用 Ghidra 无头分析二进制时…
适用于批量化或命令行逆向分析可执行文件/固件,通过 Ghidra analyzeHeadless 与内置导出脚本快速产出可分析结果。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在没有 GUI 的情况下用 Ghidra特定
解决思路
- 通过主包装脚本调用 Ghidra analyzeHeadless:`./scripts/ghidra-analyze.sh [options] <binary>`,由它处理项目创建/清理并提供更简单接口。
- 使用 `-o, --output <dir>` 指定结果输出目录,默认当前目录。
- 使用 `-s, --script <name>` 指定分析后要运行的脚本,可重复指定。
- 使用 `-a, --script-args <args>` 为最后指定的脚本传入参数。
- 使用 `--script-path <path>` 添加额外脚本搜索路径。
- 使用 `-p, --processor <id>` 指定处理器/架构,例如 `x86:LE:32:default`。
- 使用 `-c, --cspec <id>` 指定编译器规范,例如 `gcc`、`windows`。
- 使用 `--no-analysis` 跳过自动分析,以更快获取较少信息。
- 使用 `--timeout <seconds>` 设置每个文件的分析超时时间。
- 使用 `--keep-project` 在分析后保留 Ghidra 项目。
- 使用 `--project-dir <dir>` 指定 Ghidra 项目目录,默认 `/tmp`。
- 使用 `--project-name <name>` 指定项目名,默认自动生成。
- 使用 `-v, --verbose` 输出详细日志。
- 执行全量分析并导出全部内容:`ghidra-analyze.sh -s ExportAll.java -o ./output binary`。
- 反编译为 C 代码:`ghidra-analyze.sh -s ExportDecompiled.java -o ./output binary`。
- 列出函数:`ghidra-analyze.sh -s ExportFunctions.java -o ./output binary`。
- 提取字符串:`ghidra-analyze.sh -s ExportStrings.java -o ./output binary`。
- 获取调用图:`ghidra-analyze.sh -s ExportCalls.java -o ./output binary`。
- 导出符号:`ghidra-analyze.sh -s ExportSymbols.java -o ./output binary`。
- 查找 Ghidra 路径:`find-ghidra.sh`。
- 使用 ExportAll.java 做综合导出并生成摘要,适合初次分析;它运行所有其他导出。
- 检查 ExportAll.java 生成的 `{name}_summary.txt`,查看架构、内存段和函数数量概览。
- 检查 ExportAll.java 生成的 `{name}_decompiled.c`,获取所有函数反编译后的 C 代码。
- 检查 ExportAll.java 生成的 `{name}_functions.json`,获取带签名和调用的函数列表。
- 检查 ExportAll.java 生成的 `{name}_strings.txt`,获取所有字符串。
- 检查 ExportAll.java 生成的 `{name}_interesting.txt`,获取匹配安全相关模式的函数。
- 使用 ExportDecompiled.java 将所有函数反编译为 C 伪代码,输出 `{name}_decompiled.c`。
- 使用 ExportFunctions.java 导出函数列表 JSON,输出 `{name}_functions.json`,其中每个函数包含 `name`、`address`、`size`、`signature`、`returnType`、`callingConvention`、`isExternal`、`parameters`、`calls`、`calledBy`,顶层包含 `program`、`architecture`、`functions`。
- 使用 ExportStrings.java 提取所有 ASCII 和 Unicode 字符串及地址,输出 `{name}_strings.json`。
- 使用 ExportCalls.java 导出调用者/被调用者关系,输出 `{name}_calls.json`。
- 在 ExportCalls.java 输出中查看完整调用图、潜在入口点(无调用者的函数)和被调用最频繁的函数。
- 使用 ExportSymbols.java 导出所有符号,包括导入、导出和内部符号,输出 `{name}_symbols.json`。
- 分析未知二进制时,先创建输出目录:`mkdir -p ./analysis`。
- 分析未知二进制时,运行综合导出:`./scripts/ghidra-analyze.sh -s ExportAll.java -o ./analysis unknown_binary`。
- 分析未知二进制时,先查看摘要:`cat ./analysis/unknown_binary_summary.txt`。
- 分析未知二进制时,查看安全相关模式:`cat ./analysis/unknown_binary_interesting.txt`。
- 分析未知二进制时,检查特定反编译函数:`grep -A 50 "encrypt" ./analysis/unknown_binary_decompiled.c`。
- 分析固件时,指定 ARM 架构:`./scripts/ghidra-analyze.sh -p "ARM:LE:32:v7" -s ExportAll.java -o ./firmware_analysis firmware.bin`。
- 快速列出函数名和地址:`./scripts/ghidra-analyze.sh --no-analysis -s ExportFunctions.java -o . program`。
- 用 jq 解析函数 JSON:`cat program_functions.json | jq '.functions[] | "\(.address): \(.name)"'`。
- 在 `output_decompiled.c` 中搜索敏感模式:`grep -n "password\|secret\|key" output_decompiled.c`。
- 在 `output_decompiled.c` 中搜索危险函数:`grep -n "strcpy\|sprintf\|gets" output_decompiled.c`。
- 批量分析多个二进制:对 `./samples/*` 循环,使用 `basename` 生成名称,并运行 `./scripts/ghidra-analyze.sh -s ExportAll.java -o "./results/$name" "$bin"`。
- 需要指定架构时使用常见 processor ID:x86 32 位 `x86:LE:32:default`、x86 64 位 `x86:LE:64:default`、ARM 32 位 `ARM:LE:32:v7`、ARM 64 位 `AARCH64:LE:64:v8A`、MIPS 32 位 `MIPS:BE:32:default` 或 `MIPS:LE:32:default`、PowerPC `PowerPC:BE:32:default`。
- 查找所有可用处理器:`ls "$(dirname $(./scripts/find-ghidra.sh))/../Ghidra/Processors/"`。
- Ghidra 未找到时,运行 `./scripts/find-ghidra.sh` 检查安装。
- Ghidra 安装在非标准位置时,设置 `GHIDRA_HOME`:`export GHIDRA_HOME=/path/to/ghidra_11.x_PUBLIC`,然后运行 `./scripts/ghidra-analyze.sh ...`。
- 分析太久时,设置超时:`./scripts/ghidra-analyze.sh --timeout 300 -s ExportAll.java binary`。
- 需要快速导出时,跳过分析:`./scripts/ghidra-analyze.sh --no-analysis -s ExportSymbols.java binary`。
- 内存不足时,编辑 `analyzeHeadless` 脚本或设置 `export MAXMEM=4G`。
- 架构识别错误时,显式指定处理器,例如:`./scripts/ghidra-analyze.sh -p "ARM:LE:32:v7" -s ExportAll.java firmware.bin`。
- 从 ExportAll.java 开始分析,因为它提供全部导出且摘要有助于定位。
- 检查 `interesting.txt` 文件,它自动突出安全相关函数。
- 使用 jq 解析 JSON 导出,因为这些导出设计为机器可读。
- 反编译不完美,应将其作为指引,并与反汇编交叉参考。
- 大型二进制耗时较长,使用 `--timeout`,并考虑用 `--no-analysis` 做快速扫描。
适用边界 · 注意事项
- 未安装 Ghidra 或 Java OpenJDK 17+ 时不适用。
- 需要交互式 GUI、动态调试或完全可靠的反编译结果时不适合仅依赖该无头反编译流程。
- 大型二进制未设置 `--timeout` 或内存不足时可能耗时过长/失败,不适合作为快速扫描方案。