关于 storage
面向 IDASQL 用户的存储技能,介绍 IDA 的 netnode_kv 持久化键值存储。数据保存在 IDB 中,可用于记录分析状态和元数据,并提供精确键查询及跨会话进度跟踪方式。
主要功能
- 01在 IDB 中持久保存键值数据
- 02创建、读取、更新和删除值
- 03按精确键查找条目
- 04以 JSON 保存结构化分析状态
- 05通过命名空间组织键
适用场景
- 01跨会话继续分析进度
- 02记录分析人员和数据库元数据
- 03跟踪各函数的注释状态
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ allthingsida/ idasql-skills --skill storage安装后在 Claude Code 中输入/storage确认已加载。
附带文件agents/openai.yaml
详细介绍
netnode_kv
由 IDA netnode 提供支持的持久化键值存储。数据会自动保存在 IDB 中。支持完整的 CRUD 操作,并可通过 WHERE key = '...' 实现 O(1) 键查找。
| 列 | 类型 | 可写 | 描述 |
|---|---|---|---|
key | TEXT | — | 唯一键(标识符,只读) |
value | TEXT | 是 | 任意长度的值(Blob 存储) |
-- Store a value
INSERT OR REPLACE INTO netnode_kv(key, value) VALUES('author', 'alice');
-- Read by key (O(1) lookup)
SELECT value FROM netnode_kv WHERE key = 'author';
-- List all entries
SELECT * FROM netnode_kv;
-- Update a value
UPDATE netnode_kv SET value = '2.0' WHERE key = 'version';
-- Delete an entry
DELETE FROM netnode_kv WHERE key = 'author';
使用场景
- 会话状态:跨会话跟踪分析进度(例如,哪些函数已添加注释)
- 元数据:存储自定义元数据,如分析人员姓名、分析日期、备注
- 簿记:跟踪哪些函数已重新设置来源、添加注释或审核
- 配置:存储每个数据库的分析设置
-- Track analysis progress
INSERT OR REPLACE INTO netnode_kv(key, value) VALUES('annotated_funcs', '["main","init_config"]');
-- Update progress
UPDATE netnode_kv SET value = '["main","init_config","process_input"]'
WHERE key = 'annotated_funcs';
-- Read progress in a new session
SELECT value FROM netnode_kv WHERE key = 'annotated_funcs';
性能规则
| 操作 | 复杂度 | 说明 |
|---|---|---|
WHERE key = '...' | O(1) | IDA 的 netnode hashval_long() —— 始终使用精确键查找 |
WHERE key LIKE 'prefix%' | O(n) | 扫描所有条目;对于小型数据集可以接受 |
SELECT * FROM netnode_kv | O(n) | 全量扫描 netnode;对于典型用量(几十到几百个条目)来说没问题 |
键规则:
- 精确键查找(
WHERE key = '...')为 O(1) —— 这是首选的访问模式。 - 前缀扫描(
LIKE 'prefix%')会遍历所有条目,但对于典型的 netnode 大小来说速度很快。 - netnode_kv 存储在 IDB 文件中 —— 使用
save_database()后会自动持久化。
高级存储模式
基于 JSON 的进度跟踪
将结构化分析状态存储为 JSON,以便进行更丰富的查询:
-- Store progress with structured metadata
INSERT OR REPLACE INTO netnode_kv(key, value)
VALUES('progress:overview', json_object(
'total_funcs', (SELECT COUNT(*) FROM funcs),
'named_funcs', (SELECT COUNT(*) FROM funcs WHERE name NOT LIKE 'sub_%'),
'timestamp', datetime('now')
));
-- Read and parse progress
SELECT json_extract(value, '$.total_funcs') AS total,
json_extract(value, '$.named_funcs') AS named,
json_extract(value, '$.timestamp') AS ts
FROM netnode_kv WHERE key = 'progress:overview';
按函数跟踪注释状态
跟踪哪些函数已添加注释以及执行了哪些操作:
-- Mark a function as annotated
INSERT OR REPLACE INTO netnode_kv(key, value)
VALUES('re_source:' || printf('0x%X', 0x401000),
json_object('status', 'done', 'summary', 'DriverEntry init',
'analyst', 'alice', 'date', date('now')));
-- Find unannotated functions by joining with funcs
SELECT f.name, printf('0x%X', f.addr) AS addr
FROM funcs f
WHERE f.name NOT LIKE 'sub_%'
AND NOT EXISTS (
SELECT 1 FROM netnode_kv
WHERE key = 're_source:' || printf('0x%X', f.addr)
)
ORDER BY f.size DESC
LIMIT 20;
键的命名约定
使用 namespace:entity:id 格式进行有序存储:
re_source:0x401000 → per-function annotation status
config:string_minlen → analysis configuration
snapshot:2024-01-15 → point-in-time analysis snapshot
tag:crypto:0x401000 → function tags/categories
-- List all keys in a namespace
SELECT key, value FROM netnode_kv WHERE key LIKE 'tag:crypto:%';
-- Count entries per namespace
SELECT SUBSTR(key, 1, INSTR(key, ':') - 1) AS namespace,
COUNT(*) AS entries
FROM netnode_kv
WHERE key LIKE '%:%'
GROUP BY namespace
ORDER BY entries DESC;
另请参阅
annotations—— 用于应保存在地址空间中的分析人员线索(注释、书签)。跨地址的会话状态请使用netnode_kv。
评论
支持 Markdown