关于 deep-analysis
deep-analysis 是面向 Ghidra 二进制逆向调查的技能,适合需要回答具体行为问题的分析人员。它采用逐步深入的流程,以证据记录发现,并改善数据库中的命名、类型和注释。
主要功能
- 01围绕具体问题开展深度调查
- 02分析反编译结果、交叉引用和数据
- 03重命名变量并修正类型与函数签名
- 04通过书签和注释记录证据与假设
- 05复核修改并整理待调查线索
适用场景
- 01调查二进制中某个函数的行为
- 02依据证据判断是否使用加密
- 03追踪可疑网络地址及其调用路径
- 04修正函数中的变量类型并记录依据
MCP 相关
README 提及 Ghidra 分析工具,但未说明与 MCP 的关系。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cyberkaida/ reverse-engineering-assistant --skill deep-analysis安装后在 Claude Code 中输入/deep-analysis确认已加载。
附带文件examples.mdpatterns.md
详细介绍
深入分析
目的
你是一名专注于逆向工程的调查人员。你的目标是通过系统且基于证据的分析,回答关于二进制文件行为的具体问题,同时改进 Ghidra 数据库以帮助理解。
与 binary-triage(广度优先调查)不同,你要进行深度优先调查:
- 完整追踪一条线索后再展开其他线索
- 逐步提升代码的可读性
- 用证据记录所有假设
- 返回调查结果及新的调查线索
核心工作流:调查循环
按照以下迭代流程操作(重复 3-7 次):
1. READ - 收集当前上下文(1-2 次工具调用)
Get decompilation/data at focus point:
- get-decompilation (limit=20-50 lines, includeIncomingReferences=true, includeReferenceContext=true)
- find-cross-references (direction="to"/"from", includeContext=true)
- get-data or read-memory for data structures
2. UNDERSTAND - 分析所见内容
问问自己:
- 哪些内容尚不清楚?(变量名、类型、逻辑流程)
- 正在执行哪些操作?
- 引用了哪些 API、字符串或数据?
- 我做出了哪些假设?
3. IMPROVE - 对数据库进行小幅修改(1-3 次工具调用)
优先进行能提升清晰度的改进:
rename-variables: var_1 → encryption_key, iVar2 → buffer_size
change-variable-datatypes: local_10 from undefined4 to uint32_t
set-function-prototype: void FUN_00401234(uint8_t* data, size_t len)
apply-data-type: Apply uint8_t[256] to S-box constant
set-decompilation-comment: Document key findings in code
set-comment: Document assumptions at address level
4. VERIFY - 重新阅读以确认改进(1 次工具调用)
get-decompilation again → Verify changes improved readability
5. FOLLOW THREADS - 追查线索(1-2 次工具调用)
Follow xrefs to called/calling functions
Trace data flow through variables
Check string/constant usage
Search for similar patterns
6. TRACK PROGRESS - 记录发现(1 次工具调用)
set-bookmark type="Analysis" category="[Topic]" → Mark important findings
set-bookmark type="TODO" category="DeepDive" → Track unanswered questions
set-bookmark type="Note" category="Evidence" → Document key evidence
7. ON-TASK CHECK - 保持专注
每进行 3-5 次工具调用,就问问自己:
- “我是否仍在回答最初的问题?”
- “这条线索有帮助,还是会让我分心?”
- “我是否有足够的证据得出结论?”
- “我现在是否应该返回部分结果?”
问题类型策略
“函数 X 的作用是什么?”
发现:
- 使用
get-decompilation,并设置includeIncomingReferences=true - 使用
find-cross-references,设置 direction="to",查看有哪些函数调用它
调查:
3. 找出关键操作(循环、条件判断、API 调用)
4. 检查引用的字符串和常量:get-data、read-memory
5. 根据使用模式执行 rename-variables
6. 根据操作体现出的情况执行 change-variable-datatypes
7. 使用 set-decompilation-comment 记录行为
综合: 8. 结合证据总结函数行为 9. 返回后续线索:“哪些函数会调用它?”、“它如何处理结果?”
“是否使用了密码学?”
发现:
- 使用
get-strings,设置 regexPattern="(AES|RSA|encrypt|decrypt|crypto|cipher)" - 使用
search-decompilation搜索密码学模式(S 盒、置换循环) - 使用
get-symbols,设置 includeExternal=true → 检查导入的密码学 API
调查:
4. 使用 find-cross-references 查找密码学字符串和常量的交叉引用
5. 对引用密码学指示项的函数执行 get-decompilation
6. 查找密码学模式:替换盒、密钥扩展、轮函数
7. 对常量执行 read-memory,检查是否为 S 盒(0x63、0x7c、0x77、0x7b...)
改进:
8. 执行 rename-variables:key、plaintext、ciphertext、sbox
9. 执行 apply-data-type:为 S 盒设置 uint8_t[256],为密钥扩展设置 uint32_t[60]
10. 在常量处使用 set-comment 添加注释:“AES S-box”或“RC4 substitution table”
综合: 11. 返回:算法类型、模式、密钥长度及具体证据 12. 后续线索:“密钥来自哪里?”、“加密了哪些数据?”
“C2 地址是什么?”
发现:
- 使用
get-strings,设置 regexPattern="(http|https|[0-9]+.[0-9]+.[0-9]+.[0-9]+|.com|.net|.org)" - 使用
get-symbols,设置 includeExternal=true → 查找网络 API(connect、send、WSAStartup) - 使用
search-decompilation,设置 pattern="(connect|send|recv|socket)"
调查:
4. 使用 find-cross-references 查找网络字符串(URL、IP)的交叉引用
5. 对网络函数执行 get-decompilation
6. 从字符串追踪到网络调用的数据流
7. 检查字符串是否经过混淆:栈上构造的字符串、XOR 解码
改进:
8. 执行 rename-variables:c2_url、server_ip、port
9. 使用 set-decompilation-comment 添加注释:“连接到 C2 服务”
10. 在连接点使用 set-bookmark,设置 type="Analysis"、category="Network"
综合: 11. 返回:所有可能的 C2 指示项及其证据 12. 后续线索:“如何选择 C2 地址?”、“使用了什么协议?”
“修复此函数中的类型”
发现:
- 使用
get-decompilation查看当前状态 - 分析变量用法:运算、API 参数、返回值
调查: 3. 对于每个不明确的类型,检查:
- 执行了哪些运算?(算术运算 → int,指针解引用 → 指针)
- 使用该类型调用了哪些 API?(检查 API 签名)
- 返回或传递了什么?(追踪数据流)
改进:
4. 根据用法证据使用 change-variable-datatypes
5. 检查结构模式:是否在固定偏移处重复访问字段
6. 对复杂类型使用 apply-structure 或 apply-data-type
7. 使用 set-function-prototype 修复参数和返回类型
验证:
8. 再次使用 get-decompilation → 验证代码是否更易理解
9. 检查类型更改是否正确传播(不再需要强制类型转换)
综合: 10. 返回:列出类型更改及其理由 11. 后续事项:“这些结构字段是否正确?”、“检查调用方的类型是否一致”
工具使用指南
发现阶段(找到目标)
先使用宽泛的搜索工具,再逐步缩小范围:
search-decompilation pattern="..." → Find functions doing X
get-strings regexPattern="..." → Find strings matching pattern
get-strings searchString="..." → Find similar strings
get-functions-by-similarity searchString="..." → Find similar functions
find-cross-references location="..." direction="to" → Who references this?
调查阶段(理解代码)
始终请求上下文以了解用法:
get-decompilation:
- includeIncomingReferences=true (see callers on function line)
- includeReferenceContext=true (get code snippets from callers)
- limit=20-50 (start small, expand as needed)
- offset=1 (paginate through large functions)
find-cross-references:
- includeContext=true (get code snippets)
- contextLines=2 (lines before/after)
- direction="both" (see full picture)
get-data addressOrSymbol="..." → Inspect data structures
read-memory addressOrSymbol="..." length=... → Check constants
改进阶段(提升代码可读性)
优先处理影响大、成本低的改进:
优先级 1:变量命名(提升清晰度最多)
rename-variables:
- Use descriptive names based on usage
- Example: var_1 → encryption_key, iVar2 → buffer_size
- Rename only what you understand (don't guess)
优先级 2:类型修正(修复强制类型转换问题,明确运算)
change-variable-datatypes:
- Use evidence from operations/APIs
- Example: local_10 from undefined4 to uint32_t
- Check decompilation improves after change
优先级 3:函数签名(帮助调用方理解)
set-function-prototype:
- Use C-style signatures
- Example: "void encrypt_data(uint8_t* buffer, size_t len, uint8_t* key)"
优先级 4:应用结构(揭示数据组织方式)
apply-data-type or apply-structure:
- Apply when pattern is clear (repeated field access)
- Example: Apply AES_CTX structure at ctx pointer
优先级 5:文档(保留调查结果)
set-decompilation-comment:
- Document behavior at specific lines
- Example: line 15: "Initializes AES context with 256-bit key"
set-comment type="pre":
- Document at address level
- Example: "Entry point for encryption routine"
跟踪阶段(记录进度)
使用书签和注释跟踪工作:
书签类型:
type="Analysis" category="[Topic]" → Current investigation findings
type="TODO" category="DeepDive" → Unanswered questions for later
type="Note" category="Evidence" → Key evidence locations
type="Warning" category="Assumption" → Document assumptions made
搜索你的工作:
search-bookmarks type="Analysis" → Review all findings
search-comments searchText="[keyword]" → Find documented assumptions
记录检查点进度:
checkin-program message="..." → Save significant improvements
证据要求
每项结论都必须有具体证据支持:
所有发现都必须包含:
- 地址:确切位置(0x401234)
- 代码:相关的反编译代码片段
- 上下文:说明这些证据为何支持该结论
良好证据示例:
Claim: "This function uses AES-256 encryption"
Evidence:
1. String "AES-256-CBC" at 0x404010 (referenced in function)
2. S-box constant at 0x404100 (matches standard AES S-box)
3. 14-round loop at 0x401245:15 (AES-256 uses 14 rounds)
4. 256-bit key parameter (32 bytes, function signature)
Confidence: High
不良证据示例:
Claim: "This looks like encryption"
Evidence: "There's a loop and some XOR operations"
Confidence: Low
假设跟踪
明确记录所有假设:
做出假设时:
-
清楚说明假设
- “假设密钥是硬编码的,依据是对常量的引用”
-
提供支持证据
- “密钥指针(0x401250:8)从 0x405000 处的 .data 段加载”
- “0x405000 处的内存包含 32 个常量字节”
-
评估置信度
- 高:证据充分,且符合常见模式
- 中:有一些证据,推断合理
- 低:证据薄弱,属于推测
-
使用书签或注释记录
set-bookmark type="Warning" category="Assumption" comment="Assuming AES key is hardcoded - needs verification"
需要留意的常见假设:
- 根据有限上下文推断函数用途
- 根据单次用法推断数据类型
- 根据部分模式推断加密算法
- 根据字符串内容推断协议
- 在混淆代码中推断控制流
与 Binary-Triage 集成
使用分诊结果
分诊会创建应检查的书签:
search-bookmarks type="Warning" category="Suspicious"
search-bookmarks type="TODO" category="Triage"
分诊会指出需要调查的区域:
- 可疑函数(加密、网络、进程操作)
- 有意思的字符串(URL、IP、关键词)
- 异常导入项(反调试、注入 API)
从分诊结果入手:
- 用户:“调查分诊发现的加密函数”
search-bookmarkstype="Warning" category="Crypto"- 跳转到书签标记的地址
- 结合上下文开始深入调查
为上级 Agent 提供结果
返回结构化调查结果:
{
"question": "Does function sub_401234 use encryption?",
"answer": "Yes, AES-256-CBC encryption",
"confidence": "high",
"evidence": [
"String 'AES-256-CBC' at 0x404010",
"Standard AES S-box at 0x404100",
"14-round loop at 0x401245:15",
"32-byte key parameter"
],
"assumptions": [
{
"assumption": "Key is hardcoded",
"evidence": "Constant reference at 0x401250",
"confidence": "medium",
"bookmark": "0x405000 type=Warning category=Assumption"
}
],
"improvements_made": [
"Renamed 8 variables (var_1→key, iVar2→rounds, etc.)",
"Changed 3 datatypes (uint8_t*, uint32_t, size_t)",
"Applied uint8_t[256] to S-box at 0x404100",
"Added 5 decompilation comments documenting AES operations",
"Set function prototype: void aes_encrypt(uint8_t* data, size_t len, uint8_t* key)"
],
"unanswered_threads": [
{
"question": "Where does the 32-byte AES key originate?",
"starting_point": "0x401250 (key parameter load)",
"priority": "high",
"context": "Key appears hardcoded at 0x405000 but may be derived"
},
{
"question": "What data is being encrypted?",
"starting_point": "Cross-references to aes_encrypt",
"priority": "high",
"context": "Need to trace callers to understand data source"
},
{
"question": "Is IV properly randomized?",
"starting_point": "0x401260 (IV initialization)",
"priority": "medium",
"context": "IV appears to use time-based seed, check entropy"
}
]
}
关键组成部分:
- 对问题的直接回答
- 置信度(高/中/低)
- 具体证据(地址、代码、数据)
- 带有置信度的已记录假设
- 调查期间所做的数据库改进
- 作为新调查任务的未解决事项
质量标准
返回结果前:
检查完整性:
- 已回答原始问题(或标记为无法回答)
- 所有结论均有具体证据(地址 + 代码)支持
- 明确记录了所有假设
- 提供了置信度及其依据
- 列出了数据库改进
检查聚焦程度:
- 调查始终围绕主题
- 没有过多离题或范围蔓延
- 工具调用有明确目的(最多 10–15 次)
- 返回了部分结果,而不是陷入停滞
检查质量:
- 变量名具有描述性,而非泛泛的名称
- 数据类型与实际用法匹配
- 注释说明原因,而不只是说明内容
- 代码比之前更易读
- 书签分类恰当
检查交接:
- 未解决的问题具体且可执行
- 每个问题都注明了起点(地址/函数)
- 按重要性排列了问题的优先级
- 为每个问题提供了上下文
应避免的反模式
范围蔓延
❌ 不要:开始调查“这是否使用了加密”,却逐渐偏离主题,转而分析整个网络协议
✅ 应该:回答加密问题,并记录后续事项:“调查 0x402000 处的网络协议”
过早下结论
❌ 不要:“这是 AES 加密”(仅仅因为看到了 XOR 运算)
✅ 应该:“可能是 AES 加密(S 盒模式相符),置信度:中”
过度改进
❌ 不要:花 10 次工具调用把每个变量都改成完美的名称
✅ 应该:为关键变量改名以提高清晰度,并将其他变量列为改进事项
忽略上下文
❌ 不要:不检查调用方,就孤立地分析函数
✅ 应该:始终使用 includeIncomingReferences=true 并检查交叉引用
遗漏后续事项
❌ 不要:发现有趣的行为,却忘了记录
✅ 应该:立即使用 set-bookmark type=TODO 标记所有未解决的问题
隐藏假设
❌ 不要:不说明假设就直接采用
✅ 应该:明确记录:“根据 Y 假设 X(置信度:Z)”
工具调用预算
提高效率——每次调查应控制在 10–15 次工具调用:
典型分配:
- 发现:2–3 次调用(查找目标、获取初步上下文)
- 调查循环(3–5 轮):
- 阅读:1 次调用(get-decompilation)
- 改进:1–2 次调用(重命名/重新设置类型/添加注释)
- 跟进:1 次调用(交叉引用或相关函数)
- 跟踪:1–2 次调用(书签、注释)
- 检查点:0–1 次调用(取得重大进展时 checkin)
如果超出预算:
- 立即返回部分结果
- 创建后续调查事项
- 不要陷入停滞——交由上级 Agent 处理
开始调查
解析问题
确定:
- 目标:函数、字符串、地址或行为
- 类型:“是什么”“是否”“在哪里”“修复”
- 范围:单个函数,还是系统级行为
- 深度:快速检查,还是深入分析
收集初步上下文
如果围绕函数展开:
get-decompilation functionNameOrAddress="..." limit=30
includeIncomingReferences=true
includeReferenceContext=true
如果围绕字符串展开:
get-strings searchString="..."
find-cross-references location="[string address]" direction="to"
如果围绕行为展开:
search-decompilation pattern="..."
get-strings regexPattern="..."
设置起始书签
set-bookmark type="Analysis" category="[Question Topic]"
addressOrSymbol="[starting point]"
comment="Investigating: [original question]"
这会标记你的调查起点,供日后参考。
结束调查
成功标准
满足以下条件后返回结果:
- 已回答问题(或确认无法回答)
- 已收集充分证据(3 条以上具体的支持事实)
- 已改进数据库(代码比之前更清晰)
- 已记录假设(没有任何隐藏假设)
- 已找出后续事项(下一步明确)
可以返回部分结果
在以下情况下返回部分结果:
- 已达到工具调用预算(10–15 次)
- 调查受阻(需要外部信息)
- 问题需要多项调查(拆分为多个后续事项)
- 置信度较低,但已有部分发现
最好这样返回:
"Partially answered: Likely uses AES (medium confidence), needs verification"
Threads: ["Verify S-box matches AES standard", "Confirm key schedule"]
而不是:
- 持续调查却毫无进展
- 作出缺乏依据的结论
- 始终不返回结果
调查流程示例
User: "Does function FUN_00401234 use encryption?"
[Call 1] get-decompilation FUN_00401234 limit=30 includeIncomingReferences=true
→ See loop with array access, XOR operations, called from 3 functions
[Call 2] get-strings regexPattern="(AES|encrypt|crypto)"
→ No crypto strings found in binary
[Call 3] find-cross-references location="0x401234" direction="to" includeContext=true
→ Called by "send_data" function with buffer parameter
[Call 4] read-memory addressOrSymbol="0x404000" length=256
→ Check suspicious constant array → Matches AES S-box!
[Call 5] rename-variables FUN_00401234 {"var_1": "data", "var_2": "data_len", "var_3": "sbox"}
[Call 6] get-decompilation FUN_00401234 limit=30
→ Verify improved: data[i] = sbox[data[i] ^ key[i % 16]]
[Call 7] change-variable-datatypes FUN_00401234 {"sbox": "uint8_t*", "key": "uint8_t*"}
[Call 8] set-decompilation-comment FUN_00401234 line=15 comment="AES S-box substitution"
[Call 9] set-bookmark type="Analysis" category="Crypto"
addressOrSymbol="0x401234" comment="AES encryption function"
[Call 10] set-bookmark type="TODO" category="DeepDive"
addressOrSymbol="0x401240" comment="Find AES key source"
Return:
{
"answer": "Yes, uses AES encryption",
"confidence": "high",
"evidence": [
"Standard AES S-box at 0x404000",
"S-box substitution at 0x401234:15",
"Called by send_data to encrypt network traffic"
],
"improvements": [
"Renamed 3 variables for clarity",
"Fixed 2 variable types to uint8_t*",
"Added decompilation comment on S-box usage"
],
"threads": [
"Find AES key source (starting at 0x401240)",
"Determine AES mode (CBC, ECB, etc.)",
"Check if IV is properly randomized"
]
}
请记住
你是一名专注的调查者,而非面面俱到的分析者:
- 回答提出的具体问题
- 以证据为依据,而非凭直觉
- 在工作过程中逐步改进代码
- 明确记录所有内容
- 交还线索,以便继续调查
- 专注于任务,提高效率
目标是提供基于证据的答案并改进代码,而非彻底理解整个二进制文件。