关于 analysis
analysis 是面向 IDA 二进制逆向分析的技能,帮助分析人员从导入函数、字符串和函数关系等线索开展安全排查与行为研判。它提供 SQL 查询模式,并可将工作衔接到交叉引用、反编译和注释等技能。
主要功能
- 01从导入函数与字符串提取线索
- 02通过 SQL 查询函数和调用关系
- 03分析控制流、调用链与数据引用
- 04定位安全相关函数进行分诊
- 05将发现交接至反编译或注释
适用场景
- 01初步判断二进制文件的行为
- 02筛查网络、加密及进程相关代码
- 03追踪字符串或 API 的调用位置
- 04整理高风险函数以供深入审查
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ allthingsida/ idasql-skills --skill analysis安装后在 Claude Code 中输入/analysis确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/analysis-cookbook.mdcrypto-detection.mdnetwork-detection.md详细介绍
补充资源
- 加密/网络检测模式:references/crypto-detection.md、references/network-detection.md
- 高级 SQL 模式(CTE、窗口函数、批量分析、分页)及扩展查询手册:references/analysis-cookbook.md
触发意图
当用户的提示类似以下内容时,使用此技能:
- “这个二进制文件有什么作用?”
- “查找可疑/与安全相关的行为。”
- “存在哪些库/框架?”
- “给我一个按优先级排列的分诊计划。”
- “展示更高层次的见解,而不只是原始行。”
- “将此反编译结果与源代码进行比较。”
- “帮助整理此函数,使其便于审查。”
必要时转交给相邻技能:
- 需要原始调用者/被调用者详情:
xrefs - 需要汇编级调查:
disassembly - 需要伪代码语义:
decompiler - 需要编辑/注释:
annotations
首先执行此操作(热启动流程)
先广泛搜索,再逐步缩小范围:
-- 1) Binary orientation
SELECT * FROM binary;
-- 2) Capability hints from imports
SELECT module, name FROM imports ORDER BY module, name;
-- 3) Behavioral hints from strings
SELECT content, printf('0x%X', addr) AS addr
FROM strings
WHERE length >= 8
ORDER BY length DESC
LIMIT 40;
解读建议:
- 加密/网络/进程 API 与可疑字符串通常表明,应优先检查这些高价值函数。
- 通过
xrefs/disasm_calls从“信号”转向“函数”,然后反编译可能的热点。
故障与恢复
- 结果为空/噪声过多:
- 收紧模式,并转向特定模块的导入项。
- 添加与
funcs的 JOIN,并按大小/名称或调用密度进行限制。
- 缺少反编译器视图:
- 继续使用
disassembly+xrefs模式。
- 继续使用
- 复杂分析超时:
- 将分析拆分为分阶段的 CTE 和较小的候选集。
交接模式
analysis->xrefs:将信号地址映射到调用者/被调用者图。analysis->decompiler:检查最高风险函数中的语义逻辑。analysis->annotations:将发现保存为注释/重命名,并使反编译结果便于审查。
高保真审查交接
当用户希望与源代码并排比较,或要求“整理”某个函数以提高可读性时,不要再将任务视为只读分诊,而应交接给 annotations。
首先使用此审查探查:
SELECT decompile(0x401000);
SELECT idx, name, type FROM ctree_lvars WHERE func_addr = 0x401000 ORDER BY idx;
SELECT callee_name FROM disasm_calls WHERE func_addr = 0x401000;
然后转交给 annotations 进行编辑。函数达到便于审查的状态时,通常具有以下特征:
- 带类型的签名和更清晰的字段访问
- 命名过的局部变量、全局变量和标签
- 函数开头附近有一条标题式摘要注释
- 函数属于持久化分诊/审查分类时,将其放入相应文件夹
- 原始指针运算更少,通用临时变量名称更少
将摘要注释视为分析成果的一部分,而不只是展示上的润色:
- 它应支持后续的语义搜索
- 当许多函数都已添加注释时,它应有助于理解整个程序
非目标:
- 精确还原源代码语法。如果名称、类型和注释正确,那么
qmemcpy(...)等稳定的反编译形式仍然可以接受。
快速入门示例
“这个二进制文件有什么作用?”
-- Entry points
SELECT * FROM entries;
-- Imported APIs (hints at functionality)
SELECT module, name FROM imports ORDER BY module, name;
-- Interesting strings
SELECT content FROM strings WHERE length > 10 ORDER BY length DESC LIMIT 20;
“查找与安全相关的代码”
-- Dangerous string functions
SELECT DISTINCT (SELECT name FROM funcs WHERE func_addr >= addr AND func_addr < end_addr LIMIT 1) FROM disasm_calls
WHERE callee_name IN ('strcpy', 'strcat', 'sprintf', 'gets');
-- Crypto-related
SELECT * FROM imports WHERE name LIKE '%Crypt%' OR name LIKE '%Hash%';
-- Network-related
SELECT * FROM imports WHERE name LIKE '%socket%' OR name LIKE '%connect%' OR name LIKE '%send%';
-- File likely network triage candidates under a durable folder
INSERT INTO dirtree_folders(tree, path) VALUES ('funcs', 'idasql/triage/network');
UPDATE funcs
SET folder_path = 'idasql/triage/network'
WHERE addr IN (
SELECT DISTINCT func_addr FROM disasm_calls
WHERE callee_name LIKE '%socket%' OR callee_name LIKE '%connect%' OR callee_name LIKE '%send%'
);
“理解特定函数”
-- Basic info
SELECT * FROM funcs WHERE addr = 0x401000;
-- Full disassembly
SELECT disasm_func(0x401000);
-- Decompile (if Hex-Rays available)
SELECT decompile(0x401000);
-- Local variables
SELECT name, type, size FROM ctree_lvars WHERE func_addr = 0x401000;
-- What it calls
SELECT callee_name FROM disasm_calls WHERE func_addr = 0x401000;
-- What calls it
SELECT (SELECT name FROM funcs WHERE from_addr >= addr AND from_addr < end_addr LIMIT 1) FROM xrefs WHERE to_addr = 0x401000 AND is_code = 1;
“查找字符串的所有用法”
SELECT s.content, (SELECT name FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) as function, printf('0x%X', x.from_addr) as location
FROM strings s
JOIN xrefs x ON s.addr = x.to_addr
WHERE s.content LIKE '%config%';
自然语言查询示例
函数签名查询
“显示返回整数的函数”
SELECT name, return_type, arg_count FROM funcs
WHERE return_is_integral = 1 LIMIT 20;
-- Or via types_func_args (typedef-aware)
SELECT DISTINCT type_name FROM types_func_args
WHERE arg_index = -1 AND is_integral_resolved = 1;
“显示接受 4 个字符串参数的函数”
SELECT type_name, COUNT(*) as string_args
FROM types_func_args
WHERE arg_index >= 0
AND is_ptr_resolved = 1
AND base_type_resolved IN ('char', 'wchar_t', 'CHAR', 'WCHAR')
GROUP BY type_ordinal
HAVING string_args = 4;
“哪些函数返回指针?”
SELECT name, return_type FROM funcs
WHERE return_is_ptr = 1 ORDER BY name LIMIT 20;
“查找参数较多的 void 函数”
SELECT name, arg_count FROM funcs
WHERE return_is_void = 1 AND arg_count >= 4
ORDER BY arg_count DESC;
“使用了哪些调用约定?”
SELECT calling_conv, COUNT(*) as count FROM funcs
WHERE calling_conv IS NOT NULL AND calling_conv != ''
GROUP BY calling_conv ORDER BY count DESC;
返回值分析
“哪些函数返回 0?”
SELECT DISTINCT f.name FROM funcs f
JOIN ctree_v_returns r ON r.func_addr = f.addr
WHERE r.return_num = 0;
“查找返回 -1 的函数(错误模式)”
SELECT DISTINCT f.name FROM funcs f
JOIN ctree_v_returns r ON r.func_addr = f.addr
WHERE r.return_num = -1;
“返回其输入参数的函数”
SELECT DISTINCT f.name FROM funcs f
JOIN ctree_v_returns r ON r.func_addr = f.addr
WHERE r.returns_arg = 1;
“返回另一个调用结果的函数(包装器)”
SELECT DISTINCT f.name FROM funcs f
JOIN ctree_v_returns r ON r.func_addr = f.addr
WHERE r.returns_call_result = 1;
“包含多个 return 语句的函数”
SELECT f.name, COUNT(*) as return_count
FROM funcs f
JOIN ctree_v_returns r ON r.func_addr = f.addr
GROUP BY f.addr
HAVING return_count > 1
ORDER BY return_count DESC LIMIT 20;
常见查询模式
查找调用次数最多的函数
SELECT f.name, COUNT(*) as callers
FROM funcs f
JOIN xrefs x ON f.addr = x.to_addr
WHERE x.is_code = 1
GROUP BY f.addr
ORDER BY callers DESC
LIMIT 10;
查找调用特定 API 的函数
SELECT DISTINCT (SELECT name FROM funcs WHERE from_addr >= addr AND from_addr < end_addr LIMIT 1) as caller
FROM xrefs
WHERE to_addr = (SELECT addr FROM imports WHERE name = 'CreateFileW');
字符串交叉引用分析
SELECT s.content, (SELECT name FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) as used_by
FROM strings s
JOIN xrefs x ON s.addr = x.to_addr
WHERE s.content LIKE '%password%';
函数复杂度(按块数)
SELECT (SELECT name FROM funcs WHERE func_addr >= addr AND func_addr < end_addr LIMIT 1) as name, COUNT(*) as block_count
FROM blocks
GROUP BY func_addr
ORDER BY block_count DESC
LIMIT 10;
查找叶子函数(没有外部调用)
SELECT f.name, f.size
FROM funcs f
LEFT JOIN disasm_calls c ON c.func_addr = f.addr
GROUP BY f.addr
HAVING COUNT(c.addr) = 0
ORDER BY f.size DESC;
调用链较深的函数
SELECT f.name, MAX(cc.depth) as max_depth
FROM disasm_v_call_chains cc
JOIN funcs f ON f.addr = cc.root_func
GROUP BY cc.root_func
ORDER BY max_depth DESC
LIMIT 10;
进行定向遍历时,优先使用 call_graph 表,而不是 disasm_v_call_chains:
-- Map all functions in a call subtree
SELECT func_name, depth FROM call_graph
WHERE start = 0x401000 AND direction = 'down' AND max_depth = 5;
追踪到目标函数的调用路径
-- Trace call path to an internal helper
SELECT step, func_name FROM shortest_path
WHERE from_addr = (SELECT addr FROM funcs WHERE name = 'main')
AND to_addr = (SELECT addr FROM funcs WHERE name = 'copy_user_input')
AND max_depth = 20;
如果目标是导入的 API,请结合使用 call_graph、disasm_calls 和 imports。shortest_path 的端点必须解析为函数。
查找从某个函数可达的所有字符串
SELECT DISTINCT sr.string_value
FROM call_graph cg
JOIN string_refs sr ON sr.func_addr = cg.func_addr
WHERE cg.start = 0x401000 AND cg.direction = 'down' AND cg.max_depth = 3;
三路查询:查找从某个函数可达的字符串和导入项
-- Three-way: strings + imports reachable from a function
SELECT 'string' as kind, sr.string_value as detail, cg.func_name as via_func
FROM call_graph cg
JOIN string_refs sr ON sr.func_addr = cg.func_addr
WHERE cg.start = 0x401000 AND cg.direction = 'down' AND cg.max_depth = 5
AND sr.string_value LIKE '%http%'
UNION ALL
SELECT 'import', i.name, cg.func_name
FROM call_graph cg
JOIN disasm_calls dc ON dc.func_addr = cg.func_addr
JOIN imports i ON dc.callee_addr = i.addr
WHERE cg.start = 0x401000 AND cg.direction = 'down' AND cg.max_depth = 5
ORDER BY kind, detail;
另请参阅
xrefs— 将调用/数据线索转换为调用者/被调用者链。data— 将字符串、导入项和字节模式作为分类证据。decompiler— 深入分析通过分类查询识别出的可疑函数。
评论
支持 Markdown