storage

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese


netnode_kv

netnode_kv

Persistent key-value store backed by IDA netnodes. Data is saved inside the IDB automatically. Supports full CRUD and O(1) key lookup via
WHERE key = '...'
.
ColumnTypeWritableDescription
key
TEXTUnique key (identity, read-only)
value
TEXTYesArbitrary-length value (blob storage)
sql
-- 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';
基于IDA netnode实现的持久化键值存储。数据会自动保存到IDB中。支持完整的CRUD操作,以及通过
WHERE key = '...'
实现O(1)时间复杂度的键查找。
列名类型可写性描述
key
TEXT唯一键(标识,只读)
value
TEXT任意长度的值(二进制大对象存储)
sql
-- 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';

Use Cases

使用场景

  • Session state: Track analysis progress across sessions (e.g., which functions have been annotated)
  • Metadata: Store custom metadata like analyst name, analysis date, notes
  • Bookkeeping: Track which functions have been re-sourced, annotated, or reviewed
  • Configuration: Store per-database analysis settings
sql
-- 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';

  • 会话状态:跨会话跟踪分析进度(例如,哪些函数已被注释)
  • 元数据:存储自定义元数据,如分析人员姓名、分析日期、备注
  • 记录管理:跟踪哪些函数已被重新反编译、注释或审核
  • 配置:存储每个数据库的分析设置
sql
-- 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';

Performance Rules

性能规则

OperationComplexityNotes
WHERE key = '...'
O(1)IDA's netnode
hashval_long()
— always use exact key lookup
WHERE key LIKE 'prefix%'
O(n)Scans all entries; acceptable for small datasets
SELECT * FROM netnode_kv
O(n)Full netnode scan; fine for typical use (dozens to hundreds of entries)
Key rules:
  • Exact key lookup (
    WHERE key = '...'
    ) is O(1) — this is the preferred access pattern.
  • Prefix scans (
    LIKE 'prefix%'
    ) iterate all entries but are fast for typical netnode sizes.
  • netnode_kv is stored inside the IDB file — it persists automatically with
    save_database()
    .

操作时间复杂度说明
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()
    时会自动持久化。

Advanced Storage Patterns

高级存储模式

JSON-based progress tracking

基于JSON的进度跟踪

Store structured analysis state as JSON for richer querying:
sql
-- 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';
将结构化分析状态存储为JSON以实现更丰富的查询:
sql
-- 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';

Per-function annotation status tracking

按函数跟踪注释状态

Track which functions have been annotated and what was done:
sql
-- 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.address) 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.address)
  )
ORDER BY f.size DESC
LIMIT 20;
跟踪哪些函数已被注释以及注释内容:
sql
-- 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.address) 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.address)
  )
ORDER BY f.size DESC
LIMIT 20;

Naming conventions for keys

键的命名规范

Use a
namespace:entity:id
format for organized storage:
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
sql
-- 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;
使用
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
sql
-- 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;