Install
$ agentstack add skill-cristallin2006-ghidra-skill-for-dsh-ghidra-core ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Ghidra Core(执行底座)
唯一的代码与命令知识层。场景 skill(re-triage / ghidra-static / vuln-audit)只含方法论,具体命令一律回本文件查。
- 场景路由:未知样本分诊 →
~/.dsh/skills/re-triage;脱壳与验证 →~/.dsh/skills/re-unpack;静态深挖/patch/交付 →~/.dsh/skills/ghidra-static;漏洞模式排查 →~/.dsh/skills/vuln-audit - 本 skill 内容:§0 环境 / §1 十四条铁律 / §2 快速上手(含长任务、GUI、doctor)/ §4 legacy 裸命令 / §5 能力清单(三层)/ §7 移植坑 / §8 能力边界
- engine 内部补丁细节不在本文件:见
engine/VENDOR.md
0. 环境(本机已配好)
> WSL/Linux 部署的路径映射(当 uname 是 Linux 时,本节常量按下表替换;脚本内部已自动按平台分支,此处供人工/排障参考): > - GHIDRA_HOME = /opt/ghidra,JDK = /usr/lib/jvm/java-21-openjdk-amd64(apt openjdk-21) > - 引擎 venv = ~/ghidra-rpc-venv(bin/python,无 .exe),legacy venv = ~/pyghidra-venv > - re-tools venv = ~/re-tools-venv,unpacker venv = ~/unpacker-venv,pwn venv = ~/re-pwn-venv > - 工具目录 = ~/tools/(goresym、jadx、pyinstxtractor);系统工具(file/upx/gdb/tshark/pycdc…)全在 PATH,直接裸名调用 > - junction 在 Linux 是 symlink ~/dsh-ghidra-workspace,语义相同 > - win_gui_drive.py、pywin32、Android SDK/emulator 为 Windows-only,Linux 下不可用
GHIDRA_HOME = C:\t001s\ghidra_12.1.3_PUBLIC_20260817\ghidra_12.1.3_PUBLIC(含support/的内层目录)- 执行引擎:ghidra-rpc 常驻 daemon(vendor 在
engine/ghidra-rpc/,上游 Cellebrite Labs 0.2.0 + dsh 补丁,见engine/VENDOR.md)。统一入口scripts/rpc_driver.py;GUI 用scripts/launch_gui.py(见 §2「GUI」节) - JDK 21+(本机
C:\Java,Java 25),且必须是 JDK 而非 JRE——PyGhidra 通过 JPype 起 JVM - Python 环境 ×2:
- 引擎 venv:
$HOME/Desktop/src/ghidra-bridge/ghidra-rpc-venv(Python 3.12;ghidra-rpc 0.2.0 editable 安装自engine/ghidra-rpc/,pyghidra 3.1.0 + JPype1 1.5.2)——引擎代码改动即时生效 - legacy venv:
$HOME/Desktop/src/ghidra-bridge/pyghidra-venv(Python 3.10,pyghidra 3.1.0)——仅供driver.py后路使用 - 工作区:
~/.dsh/ghidra-workspace/(projects/legacy 项目缓存、projects-rpc/daemon 项目、out/产物、logs/日志) - 传给 Ghidra 的路径必须走 junction
~/dsh-ghidra-workspace:Ghidra 的ProjectLocator拒绝任何以.开头的路径元素(~/.dsh/...会 abort)。上游 ghidra-rpc 会resolve()掉 junction——已打补丁(engine/VENDOR.md补丁 2),junction 路径全程可用
为什么不是 Jython / analyzeHeadless(重要:原设计其实没错)
Jython 扩展本身是装好的,就在 %APPDATA%\ghidra\ghidra_12.1.3_PUBLIC\Extensions\Jython(内含 jython-2.7.4\Lib)。用 GUI(ghidraRun.bat,不重定向 APPDATA)跑,原本的 @runtime Jython 脚本是能用的。
真正的坑是 APPDATA 重定向:为了满足 DSH 的文件沙箱(只允许写工作区),driver 把 APPDATA/LOCALAPPDATA/USERPROFILE/TMP 指到工作区内的 settings 目录。Ghidra 于是去 \ghidra\ghidra_12.1.3_PUBLIC\Extensions\ 找扩展——那里没有 Jython,于是报:
ghidra.app.script.JythonStubScriptProvider$JythonStubException:
In order to use Jython based scripts, you must install the Jython Ghidra Extension,
or (recommended) port your script to PyGhidra or Java.
一句话:不是 skill 的脚本有问题,是重定向把一个已装好的扩展藏起来了。两个可选解法:
- 想用 Jython:在被重定向的 settings 目录下建 junction 指到真实扩展
mklink /J \...\Extensions\Jython %APPDATA%\ghidra\ghidra_12.1.3_PUBLIC\Extensions\Jython (实测可行;但 PyGhidra 流程下仍不建议回退,见下)
- 继续用 PyGhidra(当前选择):不依赖扩展、脚本是真正的 Python 3、错误信息更清楚。代价是要过下面的启动/API 关口。
另外注意:PyGhidra 启动器下 analyzeHeadless 完全不可用——把 .py 交给它会得到 Ghidra was not started with PyGhidra. Python is not available。所以一旦选 PyGhidra,就必须整条链走 driver.py。
上游 19 个 + 本 skill 早期的 triage_scan/decompile_all 共 21 个脚本已全部移植为 @runtime PyGhidra 并统一由 driver.py 启动(原 run-headless.sh 入口已废弃并删除,见 §2),此后又新增 4 个。2026-09-15 起执行引擎迁移为 ghidra-rpc 常驻 daemon,这 25 个脚本冻结为 legacy 备查(见 §5 第 3 层),driver.py 保留为 daemon 挂掉时的后路。
1. 十四条铁律(先读这个再动手)
- 开工先 ensure;批量场景用批量工具:daemon 温热后单次命令 ~0.2s,"一个函数一次调用"不再是罪。但全量反编译/全文搜索仍优先
decompile-all/search-decompiled这类服务端批量工具——别 for 循环 1000 次单条decompile(每条都要序列化过锁)。 - 导入分析一次做足:
rpc_driver.py ensure的 load 只做一次全量分析;之后所有查询/写操作都打在同一个已分析程序上,不会重跑分析。 - 大输出落文件:所有脚本约定首个参数
@绝对路径= 完整结果写该文件(JSON/文本),stdout 只留状态行。agent 用 Read 读文件,不要从 stdout 抠大输出。 - Triage 硬门:未记录 imports(DLL/SYS 还要 exports)+ 语言/壳判定之前,MUST NOT 进入深挖或动态分析。导入表只有 kernel32/ntdll 且极少 → 高度怀疑
LoadLibrary+GetProcAddress动态加载,禁止宣称"无网络/无文件能力"。 - 确认即标注:搞清一个函数立即
rename-function改成语义名 +set-comment --type plate写 plate comment(地址/作用/依据)。结论必须带地址和可复现命令。daemon 写操作即刻生效并自动存盘。 - 时间盒:静态深挖 ~15 分钟无关键路径 → 转动态(Frida/GDB/Qiling/angr,选型见 ghidra-static
references/ctf-patterns.md§6);同一路径失败 2 次 → 换工具,禁止空转。量化判据(什么算"卡住"):同一假设上连续 3 次工具调用没有产出新观测(新地址/新常量/新结构),即判定卡住——不许靠"再试一次"拖延,立即按铁律 7 的菜单升级;给同一思路"换措辞重试"(改脚本变量名/换种写法跑同一模型)计入失败次数,不重置计数。拟合/接线类推断熔断(chal session:wiring→wiring2→fitwiring 连错 5 次):手写拟合/接线求解脚本连错 2 次 → 强制升级 z3/SMT 求解或emulate_blob/emulate-function仿真取数,禁止写第 3 个手写拟合脚本;升级前先查依赖图——存在可剥离递推/可逆算子时优先手工剥离(Reverse-chal:掩码二阶递推逐层反解成功,z3 60s 超时反而没用上);hooks 层gate_churn.py会在脚本堆积(目录近 24h ≥8 个 .py)且台账零 stuck 时机械阻断。探索运行熔断(f862c151 session:97 次 heredoc 探索、128 个手写结构变体盲搜,gdb/framemap/modeldiff/emulate 全程 0 次):heredoc/python -c/stdin 管道这类不落盘的探索运行不过 churn 闸门(载体盲区),由 hooks 层gate_explore.py计数封堵——30 分钟 ≥25 次且台账零 stuck → 机械阻断;脚本体与窗内 ≥2 次历史高度相似(换措辞重试的指纹)且台账无新条目 → 阻断并直指model_diff.py分歧指纹分类。ARX/模乘类密文升级阶梯(禁止跳档):① gdb 断轮体读帧槽位真值(先frame_map.py定位槽位)→ ②model_diff.py分歧指纹分类 → ③emulate-function/p-code 插桩取语句级真值 → ④ 把已有 trace 当方程组解接线(数据够时差的是"解"不是"枚举")→ ⑤ angr 殿后且须先论证对本密文可行(16 轮 × 68 次 mod-65537 乘 + 192 次查表的规模必爆)——未走完前四档就调 angr 会被gate_explore.py机械阻断。Cython/CPython 扩展前置:triage 报python_ext=true时,建模轮函数之前必须先跑const_scan.py --binary(§12 元数据常量重建)+frame_map.py(栈帧槽位)并落账,否则深挖被机械阻断。 - 死循环断路器(机械触发,不靠自觉):循环签名 = 第二次回到同一字节区域/同一假设继续分析。执行载体是
scripts/ledger.py:每个区域级观察 MUST 走ledger.py observe落账——同一区域第二次 observe 时脚本拒绝入账(exit 2),除非--delta回答"这次观测和上次差在哪";答不出 = 断路器触发,按脚本打印的菜单升级:换工具 / 转动态 / 问用户,并用ledger.py stuck留痕——禁止换第 3 种方式重试同一路径。字节只能通过工具解读(反汇编、反编译、脚本输出);肉眼/裸 hex 仅用于验证工具输出,脚本对同一区域只放行 2 次,第 3 次直接拒绝。packed/加密字节在信息论上是噪声,内容级死磕一律禁止——先脱壳(re-unpack)或仿真(emulate-function)。断路器的盲区自查:observe 熔断只统计同 binary 同 region——给同一思路"换措辞重试"(36 个脚本各写各的 region/文件名)一次都响不了(DEFCON26 复盘 R3)。外部信号:work 目录脚本数 ÷ 台账条目数 > 5 = 记账死掉/同路径重试,用ledger.py status --workdir机械统计,命中立即 stuck + 审视。定时器(chal 复盘 E4):单样本目录下每 ~20 分钟主动跑一次status --workdir——本次 churn 12 倍于红线而没人去跑;注意比值 >5 只触发一次记账(落 observe/stuck),是否停手由当时的 delta 决定,不由比值决定;阈值 5 仅在单样本目录有意义,多文件/协议/多阶段题型天然"脚本多、样本少",只当记账提醒。非地址型题目(协议/算法/多方件)没有自然 binary 键:用题目名当 binary 键、conclude --locus proto:/channel:/region:前缀落账。
铁律 6 管时间(多久没进展就换路),铁律 7 管循环签名(ledger.py 机械拦截原地打转)——先命中哪条执行哪条。台账 = /out/.ledger.jsonl(机器真相,append-only)+ 每次入账自动重建的 .ledger.md(人读视图):权威结论写入即锁定(同 id 覆盖必须 --overturn+新证据)、先查后析(ledger.py query)、推翻留痕——机制细节见 references/evidence-ledger.md。
- 读数纪律(第一嫌疑人是读数,不是程序):关键常量(密文/密钥/换表/魔数)的唯一权威读数 =
scripts/read_views.py三视图(hexdump + 带字节数的 fromhex-ready hex + cstr),读到立即ledger.py conclude锁定(注明地址+长度+工具);禁止从终端手工转录 hex(可信度最低的通道不能承载最关键的事实)。反编译器/IDA 的字符串与 hex 渲染只是视图——会把0x01/0x0E渲染成1/E吞掉前导 0——凡要引用渲染文本,先read_views.py --expect-hex ""与真实字节对照。观测矛盾(伪码声明长度 vs 实测处理长度、同一事实两次读出不同值、strcmp对任何输入都不等)→ 先怀疑读数:任何"这段逻辑是坏的/反的"的结论,必须先排除读数错误才允许提出;同一事实第二次读出不同结果 = 熔断信号,立即停止推断、用 read_views 建立权威读数。求逆之前先正向验证:拿到疑似密钥/密文后,先用已知输入把完整流水线正向跑一遍(oracle.py/emulate-function)确认模型能复现已知输出,再求逆——直接求逆错了也不知道错在哪。字段/读数冲突时,在宣称"题目设计有矛盾"之前,必须先排除"该值是多字段复合函数"(如 tsval ^ payload ^ seq 片段)这一可能——同键冲突恰恰证明单字段不是明文。 - 缓冲区归属(字节是谁的):从
MOV [EBP+disp], imm序列重建栈上字符串时,必须按 disp 区间归属变量,禁止按指令出现顺序拼接——相邻变量的写入区间相接(end_A + 1 == start_B)时极易把别人的字节拼进自己的常量(encode 复盘 E1:28 字节密文被读成 49 字符)。拼接结果 MUSTread_views.py --expect-len与该变量声明长度核对。任何常量长度不符合其用途(hex 必须偶数、base64 必须 4 的倍数、XOR/RC4 密文必须等于明文长度)→ 以「读数可疑」中止,禁止进入求逆。机械门 =scripts/crypto_sanity.py:求逆前 MUST 过check,求逆后 MUST 过check-result——49 字符的 base64、28≠21 的密文、不可打印的反推结果都会被它 exit 2 拦下。候选合法性 = 方程校验信号(92a0a107 临门一脚):反演候选全部不可打印 / 尾部不符合填充格式(PKCS#7 等),且原程序对非 ASCII 输入直接崩溃时,判定本轮方程错了(常量或比对对象选错),禁止在同一方程上加补丁续命、禁止归因「还有未建模的编码分支」继续探测——先核对方程两边各是什么(trace 里输入构造用的常量与输出比对的常量未必是同一个)。check-result的不可打印判定就是这条的机械触发器。 - 验证独立性(同源验证 = 没验证):用自己 patch 的进程、自己写的 harness、自己算的偏移来验证自己对程序的理解,三者一致不构成任何证据(encode 复盘 E2/E3)。① 被 patch 过的运行态只能用于探索控制流,禁止用于验证数据模型——验证数据模型要求进程未修改(或修改点与测量点无数据依赖)+ 至少一个独立来源(静态常量/第二输入/已知明文)交叉印证;被迫在 patch 后测量的结论必须
conclude --independent no标注。② 自建 harness(投喂/读数脚本)在支撑结论前必须用已知答案的输入自检;自检失败或结果不稳定 → 该 harness 全部输出作废;「偶发命中」必须复跑 ≥100 次确认可复现才算发现。凡「由观测反推中间量」的脚本(白化/搬运公式、角色字反推、偏移表)无已知答案自检 ⇒ 其输出标 ⚠UNVERIFIED 且不得用于否定模型——「模型像坏的」时第一嫌疑人永远是 harness 自己:差异呈现规律(如低半字全对、高半字共用一个常数)是"接口/搬运写错"的典型指纹,不是"程序少了运算"。③ledger.py conclude强制标注--source/--independent(self-script 必须给--harness路径),无独立来源的结论在 render 里标 ⚠UNVERIFIED,禁止原样交付。④ 否定性结论门槛更高:说「不可满足/程序是坏的」之前,必须先用已知输入正向复现成功(铁律 8),且结论必须能指认一个「如果它错了,结论就崩」的外部事实——指认不出就不许交付。「这是诱饵/假 check/作者逻辑坏了」同属否定性结论:判某分支为假之前,必须先做判定性实验——钉随机源为不同值看输出是否变(判 mask vs target)、读校验涉及的状态量(dir()/__dict__/hook 目标函数)并用已知输入拟合其表达式;实验做不了就不许判。混淆实验不算判定性实验(f862c151 诱饵门事故:stub_p3返回_var2得到 "yes" 是人为满足第一道门,推不出"真门是_var2";真指纹是_p3输出被os.urandom掩码 ⇒_p3(...)==_var2恒不可满足——恒不可满足的"判定条件"本身就是诱饵签名)。「工具不可用/装不上」同属否定性结论(chal 复盘 §8.3):下此结论前必须换第二种方式复核(离线 pip 缓存 / 系统包 / 独立可执行 / 另一包管理器)——检查器自身也会假阴性(tag 重建错、缺--target),"不可用"的结论被信了之后,整条工具升级路线都会被误关。细则见 re-dynamic §4。⑤ flag 类结论的唯一合法 VERIFIED 证据 = 未修改的原程序/平台接受候选输入(chal session 循环论证事故:把自写探针[ord(c) for c in _var1] == _var3当程序判定,交付错 flag 并标--independent yes——探针里_var1就是输入本身,恒真)。自写探针/等价式只能支撑--kind finding;flag/答案类结论必须conclude --kind flag --program-accept "投喂命令 + 原程序成功响应原文"(缺证据 exit 2,且禁止--source self-script),远程题则为平台接受回执。⑥ 自检强度分级 + 闭合锚定(f862c151/92a0a107 双会话临门一脚:用恒真的右逆自检确认了一个错的方程):L1fwd(inv(B))==B恒真——任何逆函数实现都构造性满足,零信息量,禁止落账为「已验证」;L2inv(fwd(X_known))==X_known左逆锚定——能抓常量/分支/接线错,手握 ground truth(如'A'*L采的 trace,反演结果前 L 字节必须是0x41)必须拿它当锚,一行 assert 的事;L3 未修改原程序接受候选 = 唯一终审(⑤)。宣布「模型/反演已闭合」的结论必须conclude --kind model --anchor "L2 断言+实测输出"(缺证据 exit 2)。只验变换不验方程 = 没验。 - 手写解析器必须双源验证(工具缺失 ≠ 自造轮子的许可证):自行实现的格式/字节码解析器(opcode 表、结构体偏移、指令解码、文件格式 parser),在据此下任何结论前,MUST 与第二个独立实现逐条比对至少一次——官方实现优先(SDK 自带工具),其次成熟第三方库;比对不上就装工具,装不了就标 ⚠UNVERIFIED(铁律 10③)禁止交付。「输出看起来合理」不构成正确性证据——表偏移类错误恰恰只产生语法合法、语义自洽、看似合理的输出(五题复盘:DEX opcode 表在 0x2d 多塞一个条目,
if-lt被读成if-ne,标准 ROT13 显示成残废实现,差点自信交付)。已知的静默偏移陷阱(手写同类代码前先当自检清单过一遍):scripts/pe_info.py的 PE32 ImageBase(PE32 在 opt+28,opt+24 是 BaseOfData;PE32+ 才在 opt+24)与 PE32+ 导入 thunk 宽度(8 字节 QWORD——按 4 字节读会撞上全零高半部,把导入列表静默截断成「每 DLL 1 个函数」)、AXML 字符串池偏移、DEX opcode 表条目数。配套纪律:oracle 必须成对(证明「正确输入被接受」之外,必须给出「近似错值被拒绝」的负对照,否则无法排除「凡输入皆通过」);解空间可枚举时穷举优先于公式(穷举同时产出答案与唯一性证明)。 - 异常即约束:观测到的不一致(重复键冲突、伪码长度 vs 实测、同一事实两次读数不同)必须
ledger.py anomaly --consequence "..."转成可检验假设落账,禁止降级为"噪声/歧义待枚举";台账自身两条结论互相矛盾同样是异常(f862c151:_var232 项 ⇒ flag 17–32 字节 与len(_p3res)==48⇒ flag 33–48 字节并存却 0 条 anomaly——自相矛盾正是诱饵的指纹);存在 open anomaly 时 stuck 必须--ack引用或先resolve --waive;工具缺失导致的客观不可查走 waive,不许硬卡。待检验的模型/推断(不止观测到的不一致)落ledger.py hypothesis --text --if-true --if-false --test——"不一致必须转成可检验假设"的假设对象就是它,open 在 render 单列置顶,关闭(confirmed/killed)必须--evidence(与 resolve 反向门同构,缺证据 exit 2),客观不可检验走--status waived --waive "理由"(豁免理由强制入账,render 单列可见)。写下就必须有下文:stop_check 收尾时机械检查 open hypothesis,带着未闭环假设交卷直接 deny(92a0a107 临门一脚:H1 精确写出真因却没跑,恢复轮把最后 3 分钟花在写报告上)。关闭异常的机械门(反向门,比正向门更重要):resolve --note必须同时给--evidence(复核命令/地址/读数),否则 exit 2——叙述性机制解释不是证据,不许用它解除约束;waive 通道豁免--evidence(豁免理由强制入账),但waived在 status/render 里与resolved单独可见。 - 轴必须交叉(限枚举类解码/搜索任务):仅适用于候选空间可枚举的解码/搜索任务(隐信道解码、爆破类)——开跑前先出轴矩阵+候选预算(候选数 = Σ C(字段数,k) × 算子数 × 顺序源 × 打包 × 后变换),且轴矩阵+预算必须
ledger.py plan --axes --budget落账,禁止只写在聊天里(复盘实证:不落账的轴矩阵永远不会被执行);预算算得出却仍剪轴必须写明理由;任一轴恒为 identity/常量 = 未覆盖,不得声称"试过"。与铁律 6 时间盒联动:预算 > 时间盒承受能力时升级方法(找 oracle/换数学洞察)而不是硬跑。不适用于需要数学洞察的密码题——那里穷举是最后手段。 模型内拟合搜索预算门(chal 复盘 G2):在自己写的模型(Python 拟合脚本)里做 >1e5 次候选搜索前,先自证输入数据(铁律 10②——"用错的观测数据做对的搜索"是最大时间黑洞,本次 10^7 组搜索全部建立错数据上),再找可分离未知量或检查点把搜索变求解;都不行 → 换观测手段(机器级取数/打桩/仿真);该题型不存在观测手段时退回纯推断 + ⚠UNVERIFIED,不停手。正当爆破(弱 KDF/口令/小密钥空间异或)不归此门——走 hashcat/GPU 等专用工具。 - 判定性实验优先于继续读数:任一关键量(参数角色 / 通道归属 / 某因子是否参与计算)在 30 分钟或 3 次工具调用内未被扰动实验确认(钉住可疑因子为常量看输出是否变、翻转一个输入看哪路输出动),必须停止读码转做打桩实验,并按
--source runtime-oracle落账。参数角色不得仅由调用约定/寄存器推断——"第 N 参数按惯例是输出缓冲区"是假设不是读数(DEFCON26 复盘:FUN_13d74第一参数实为文件缓冲区,被读成输出,错模型持有数小时;推翻它只需一次几分钟的打桩实验)。瓶颈不是算力是"到证伪的距离":最高杠杆的两个动作是 oracle 打桩隔离单因子(oracle_family.py)与模型差分校验(model_diff.py),关键量存疑时先用它们,不要继续读码。
2. 快速上手(3 行)
RD="$HOME/.dsh/skills/ghidra-core/scripts/rpc_driver.py"
# 1) 开工:daemon 没起就起、二进制没 load 就 load(幂等),含全量分析
python "$RD" ensure /path/to/binary
# 2) 一键分诊 → @out 落盘;之后所有命令直接跟二进制路径,key 自动映射
python "$RD" "@$HOME/.dsh/ghidra-workspace/out/app.triage.json" triage /path/to/binary
python "$RD" decompile /path/to/binary main
python "$RD" xrefs-to /path/to/binary check_flag
# 3) 写操作(重命名/注释/patch)即刻生效并自动存盘,无需 exec-w
python "$RD" rename-function /path/to/binary FUN_00401000 check_flag
rpc_driver.py 做的事:项目映射(~/dsh-ghidra-workspace/projects-rpc/dsh_.gpr,junction 路径)、binary key 自动替换(不用记 /name-hash6 后缀)、--project 注入、@out 落盘、环境变量自给(GHIDRAINSTALLDIR/JAVA_HOME/LOCALAPPDATA 重定向/USERNAME=dsh)。 子命令:ensure|status|stop (ensure 支持 --timeout N 秒,等待期间每 12s 向 stderr 打心跳,大二进制首载不再像死掉)+ 其余全部透传给 ghidra-rpc CLI(decompile/functions/strings/disassemble/assemble/write-bytes/triage/exec-code/export-binary/emulate-function/version-track…,全量见 ghidra-rpc --help)。 二进制比对:version-track / function-diff 会自动把 B 也 load 进 A 的项目(VT 要求同项目)。
长任务(后台执行)
daemon 常驻后日常命令都是亚秒级,真正的长任务只剩 load(大文件导入+分析)和 version-track(全函数关联)——这类用 dsh Bash 工具的 run_in_background 跑,靠 @out 落盘拿结果:
# 后台跑 version-track(大样本对),结果落 @out 文件
python "$RD" "@$HOME/.dsh/ghidra-workspace/out/vt.json" version-track old.exe new.exe --changed-only
# → 拿到 task_id 后继续干别的;完成通知到达后 Read 该 json
判断完成的信号是 @out 文件出现且 JSON 有效;stdout 摘要行只有几行,不要从前台输出抠大结果。
本地计算型长任务(爆破/拟合/搜索,timeout ≥300s)必须走 scripts/guarded_run.py(chal session 事故:nohup timeout 1200 python3 bf.py > log & ——python 块缓冲 + 到点 SIGTERM,20 分钟计算日志 0 字节):
python3 "$SK/guarded_run.py" --timeout 1200 --log out/job.log -- python3 -u bf.py
逐行 tee 落盘(每行 flush,杀掉也有)、静默 30s 心跳、到点先 terminate 宽限 5s 再 kill、结束打印 rc/耗时/log 路径;超时退出码 124 对齐 timeout(1)。hooks 层 gate_longrun.py 会拦下裸 timeout ≥300s + python 脚本 的命令。
GUI(launch_gui.py)
python "$SK/launch_gui.py" # 裸启动 Ghidra GUI
python "$SK/launch_gui.py" --open /path/to/bin # 打开该二进制的 dsh_ 项目
python "$SK/launch_gui.py" --project dsh_ # 按项目名打开
detached 启动,脚本立即返回 PID,GUI 输出进 logs/gui-launch.log;关闭用 taskkill //PID //F 或 GUI 内退出。GUI 以 USERNAME=dsh 启动(与 headless 创建的项目的属主一致,不会 NotOwnerException),settings 用真实用户目录。
何时该去 GUI:交互式 CFG/函数图深挖、人工比对多个函数、type archive(FIDB)制作、plugin 类交互工具(GOOMBA 等)。headless 已覆盖的事别去 GUI:导出 patched 二进制(export_binary.py)、patch(patch_bytes.py)、批量反编译、分诊。
环境自检(doctor.py)
python "$SK/doctor.py" # 全绿 exit 0;任一 fail exit 1
输出分两块:
- Ghidra 核心 8 项(决定 exit code,fail 即 exit 1):安装与两个启动器、JAVA_HOME/java 版本、pyghidra-venv、ghidra-rpc-venv、ghidra-rpc 包(editable 自 engine/)、工作区可写 + junction 解析、现有项目清单、daemon 起停冒烟(
--quick可跳过这项慢的) - toolchain 三层(独立成节,不进 exit code):Tier A 轻量高频(checksec/GoReSym/pyinstxtractor/frida/z3/rust-demangler/upx/unpacker,缺失=warn 按 hint 补装);Tier B 按需重装(angr/qiling/speakeasy/unipacker/ghidriff/SiMBA/strings/readelf);Tier C GUI/手工(dnSpyEx/de4dot/DIE/x64dbg/GOOMBA/golang-loader)
任何 skill 的路由表提到外部工具时,可用性以 doctor 的 toolchain 节为准——那是唯一真相源。换机器/升级 Ghidra/排查"怎么又起不来"时先跑它。
外来旧项目:从别处拷来的项目若 project.prp 的 OWNER 不是 dsh,headless open_project 首次打开会自动改写属主;GUI 则要求属主一致,手动把 OWNER VALUE="..." 改成 dsh 即可。
4. 裸命令模板(legacy 排障专用;日常用 rpc_driver.py)
daemon 整体不可用时的后路是 driver.py(pyghidra-venv,每次调用一个冷启动 JVM):
PY="$HOME/Desktop/src/ghidra-bridge/pyghidra-venv/Scripts/python.exe"
GH="C:/t001s/ghidra_12.1.3_PUBLIC_20260817/ghidra_12.1.3_PUBLIC"
WS="$HOME/dsh-ghidra-workspace" # junction → ~/.dsh/ghidra-workspace;Ghidra 拒绝含 . 的路径元素,必须用 junction
export GHIDRA_INSTALL_DIR="$GH"
export JAVA_HOME="C:/Java"
# 首次:导入 + 全量分析 + 分诊(项目名 dsh_)
"$PY" -m pyghidra --project-path "$WS/projects" --project-name dsh_ \
"C:/abs/path/binary.exe" "$SK/triage_scan.p
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [Cristallin2006](https://github.com/Cristallin2006)
- **Source:** [Cristallin2006/ghidra-skill-for-dsh](https://github.com/Cristallin2006/ghidra-skill-for-dsh)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.