关于 data
这是一项使用 SQL 查询 IDA 数据库中字符串、字节模式等原始数据的分析技能,帮助分析人员将命中项关联到代码引用,并将发现转交进一步分析或调试。
主要功能
- 01搜索已缓存的二进制字符串
- 02查找字节和操作码模式
- 03关联字符串引用与函数
- 04读取有界字节范围
- 05提供分析交接指引
适用场景
- 01在二进制文件中查找指标或常量
- 02定位引用特定字符串的函数
- 03高效搜索操作码模式
- 04将数据发现交由分诊或调试
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ allthingsida/ idasql-skills --skill data安装后在 Claude Code 中输入/data确认已加载。
附带文件agents/openai.yaml
详细介绍
触发意图
在用户要求执行以下操作时使用此技能:
- 快速搜索字符串/字节/模式
- 将字符串证据映射到代码用法
- 调查原始数据层面的指标(IOC、常量、签名)
转交给:
xrefs,从匹配的地址扩展关系analysis,根据数据信号综合研判debugger,在发现结果应驱动补丁/断点操作时使用
首先执行(热启动序列)
-- 1) Validate string availability
SELECT COUNT(*) AS strings FROM strings;
-- 2) Sample high-value strings
SELECT content, printf('0x%X', addr) AS addr
FROM strings
WHERE length >= 8
ORDER BY length DESC
LIMIT 40;
-- 3) If expected strings are missing, rebuild once
SELECT rebuild_strings();
解读指南:
- 字符串通常是最快的行为线索;应立即转到
xrefs获取执行上下文。 - 搜索操作码/模式时,优先使用
byte_search表,而不是扫描全部指令。
故障与恢复
- 没有字符串或数量异常偏少:
- 运行
rebuild_strings(),并使用COUNT(*) FROM strings验证。
- 运行
- 误报过多:
- 提高特异性(使用
LIKE、类似正则表达式的模式收窄,以及模块/函数联接筛选条件)。
- 提高特异性(使用
- 字节模式搜索范围过广:
- 限制范围,或将匹配的字节地址联接到
funcs。
- 限制范围,或将匹配的字节地址联接到
- 需要的是命名函数、标签、结构体或成员,而非字符串内容:
- 使用
grep,不要使用strings或byte_search。
- 使用
交接模式
data->xrefs,将数据命中结果转换为代码路径/函数。data->analysis,用于风险评分和活动级洞察。data->debugger,用于设置可执行的补丁/监视点。
strings
在二进制文件中找到的字符串字面量。IDA 会维护一个可配置的缓存字符串列表。
| 列 | 类型 | 描述 |
|---|---|---|
addr | INT | 字符串地址 |
length | INT | 字符串长度 |
type | INT | 字符串类型(原始编码位) |
type_name | TEXT | 类型名称:ascii、utf16、utf32 |
width | INT | 字符宽度(0=1 字节,1=2 字节,2=4 字节) |
width_name | TEXT | 宽度名称:1-byte、2-byte、4-byte |
layout | INT | 字符串布局(0=以 null 结尾,1-3=Pascal 格式) |
layout_name | TEXT | 布局名称:termchr、pascal1、pascal2、pascal4 |
encoding | INT | 编码索引(0=默认) |
content | TEXT | 字符串内容(实际文本——不是 value 或 text) |
字符串类型编码: IDA 将字符串类型存储为一个 32 位值:
- 位 0-1:宽度(0=1B/ASCII,1=2B/UTF-16,2=4B/UTF-32)
- 位 2-7:布局(0=TERMCHR,1=PASCAL1,2=PASCAL2,3=PASCAL4)
- 位 8-15:term1(第一个终止字符)
- 位 16-23:term2(第二个终止字符)
- 位 24-31:编码索引
-- Find error messages
SELECT content, printf('0x%X', addr) as addr FROM strings WHERE content LIKE '%error%';
-- ASCII strings only
SELECT * FROM strings WHERE type_name = 'ascii';
-- UTF-16 strings (common in Windows)
SELECT * FROM strings WHERE type_name = 'utf16';
-- Count strings by type
SELECT type_name, layout_name, COUNT(*) as count
FROM strings GROUP BY type_name, layout_name ORDER BY count DESC;
重要: 对于新的分析(exe/dll),字符串会自动生成。对于现有数据库(i64/idb),字符串已保存。如果意外看到 0 个字符串,请运行一次 SELECT rebuild_strings() 以重建列表。请参阅下文的“字符串列表界面”部分。
字符串引用(显式联接模式)
直接使用 strings + xrefs + funcs。这是标准模式。
-- Find call sites/functions referencing error-like strings
SELECT
s.content as string_value,
printf('0x%X', x.from_addr) as ref_addr,
(SELECT name FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) as func_name
FROM strings s
JOIN xrefs x ON x.to_addr = s.addr
WHERE s.content LIKE '%error%' OR s.content LIKE '%fail%'
ORDER BY func_name, ref_addr;
-- Functions with most string references
SELECT
(SELECT name FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) as func_name,
COUNT(*) as string_refs
FROM strings s
JOIN xrefs x ON x.to_addr = s.addr
GROUP BY func_name
ORDER BY string_refs DESC
LIMIT 10;
bytes 表——读取、修补和有界窗口
所有字节访问都通过 bytes 表进行。 隐藏的 start_addr 和
n 输入列成对用于有界读取;批量读取十六进制时使用
hex(blob_concat(value)),批量读取 BLOB 时使用 blob_concat(value)。
| 形式 | SQL |
|---|---|
| 读取 1 个字节 | SELECT value FROM bytes WHERE addr = 0x401000 |
| 将 N 个字节读取为十六进制(大写,无空格) | SELECT hex(blob_concat(value)) FROM (SELECT value FROM bytes WHERE start_addr = 0x401000 AND n = 16 ORDER BY addr) |
| 将 N 个字节读取为 BLOB | SELECT blob_concat(value) FROM (SELECT value FROM bytes WHERE start_addr = 0x401000 AND n = 16 ORDER BY addr) |
| 读取一个范围 | SELECT value FROM bytes WHERE addr >= 0x401000 AND addr < 0x401010 ORDER BY addr |
隐藏的 start_addr + n 列会请求从 X 开始的恰好 N 个连续字节。它们特意与可见的 addr 列区分开,这样针对 addr 的任何谓词(连接、复合 WHERE)都能由 SQLite 执行。读取有界窗口时不会跳过未映射的地址;映射区域之外的行会返回 get_byte() 在该处的结果。
blob_concat(value) 是一个内置聚合函数,可将行值拼接为一个 BLOB;hex() 是 SQLite 内置的 BLOB→十六进制辅助函数(大写)。
无界范围注意事项
WHERE addr > X 如果没有上界或 LIMIT,会从 X 开始遍历直到映像末尾的所有已映射字节——数百万行,耗时数秒。读取时始终配合以下条件之一:
WHERE start_addr = X AND n = N(有界读取形式)AND addr < B(双边范围)- 外层
LIMIT N
该表没有单次调用上限;只要约束对有界,就支持任意大的窗口。
需要 IDA 项的大小/类型元数据时,请使用 heads。
二进制搜索表
对原始字节/操作码使用 byte_search。它要求 WHERE pattern = ...;matched_hex 是输出列,不是搜索输入。
| 列 | 类型 | 描述 |
|---|---|---|
addr | INT | 匹配地址 |
matched_hex | TEXT | 以十六进制文本呈现的匹配字节 |
matched_bytes | BLOB | 原始字节形式的匹配字节 |
size | INT | 匹配大小(字节) |
pattern | HIDDEN TEXT | 必需的 IDA 字节模式输入 |
start_addr | HIDDEN INT | 可选的包含式下界 |
end_addr | HIDDEN INT | 可选的排除式上界 |
max_results | HIDDEN INT | 可选的生成结果上限 |
模式语法(IDA 原生):
"48 8B 05"- 精确字节(十六进制,以空格分隔)"48 ? 05"或"48 ?? 05"-?= 任意字节通配符(仅限完整字节)"(01 02 03)"- 可选项(匹配其中任意字节)
注意: 字节模式不支持半字节通配符和正则表达式。
示例:
-- Find all matches for a pattern
SELECT addr, matched_hex, size
FROM byte_search
WHERE pattern = '48 8B ? 00'
LIMIT 10;
-- First match only
SELECT printf('0x%llX', addr) AS addr
FROM byte_search
WHERE pattern = 'CC CC CC'
ORDER BY addr
LIMIT 1;
-- Search with alternatives
SELECT addr, matched_hex
FROM byte_search
WHERE pattern = 'E8 (01 02 03 04)'
LIMIT 20;
优化模式:查找使用特定指令的函数
若要高效回答“有多少个函数使用了 RDTSC 指令?”:
-- Count unique functions containing RDTSC (opcode: 0F 31)
SELECT COUNT(DISTINCT f.addr) as count
FROM byte_search b
JOIN funcs f ON b.addr >= f.addr AND b.addr < f.end_addr
WHERE b.pattern = '0F 31';
-- List those functions with names
SELECT DISTINCT
f.addr as func_addr,
f.name as func_name
FROM byte_search b
JOIN funcs f ON b.addr >= f.addr AND b.addr < f.end_addr
WHERE b.pattern = '0F 31';
这比扫描所有反汇编行快得多,因为:
byte_search使用 IDA 的原生二进制搜索- 包含关系连接使用紧凑的
funcs表,而不是扫描每条指令
选择合适的搜索方式
- 对函数、标签、结构体、枚举和成员等命名实体使用
grep。 - 用户要搜索二进制中的字面字符串内容时,使用
strings。 - 目标是原始字节或操作码模式时,使用
byte_search。
SQL 界面 — 字符串列表
IDA 会维护一个缓存字符串列表。使用 rebuild_strings() 检测并缓存字符串,使用 COUNT(*) FROM strings 获取当前数量,并使用 strings 进行行级分析。
| 界面 | 描述 |
|---|---|
rebuild_strings() | 使用 ASCII + UTF-16 重建,最小长度为 5(默认值) |
rebuild_strings(minlen) | 使用自定义最小长度重建 |
rebuild_strings(minlen, types) | 使用自定义长度和类型掩码重建 |
SELECT COUNT(*) FROM strings | 当前字符串列表数量(无需实例化行即可优化获取) |
类型掩码值:
1= 仅 ASCII(STRTYPE_C)2= 仅 UTF-16(STRTYPE_C_16)4= 仅 UTF-32(STRTYPE_C_32)3= ASCII + UTF-16(默认值)7= 所有类型
-- Check current string count
SELECT COUNT(*) AS strings FROM strings;
-- Rebuild with defaults (ASCII + UTF-16, minlen 5)
SELECT rebuild_strings();
-- Rebuild with shorter minimum length
SELECT rebuild_strings(4);
-- Rebuild with specific types
SELECT rebuild_strings(5, 1); -- ASCII only
SELECT rebuild_strings(5, 7); -- All types (ASCII + UTF-16 + UTF-32)
-- Typical workflow: rebuild then query
SELECT rebuild_strings();
SELECT * FROM strings WHERE content LIKE '%error%';
重要 — Agent 处理字符串查询的行为: 当用户询问字符串(例如,“显示字符串”“这个二进制文件中有哪些字符串”)时:
- 首先运行
SELECT rebuild_strings(),确保已检测到字符串 - 然后查询
strings表
rebuild_strings() 函数会使用合理的默认值(ASCII + UTF-16,最小长度为 5)配置 IDA 的字符串检测,并重建字符串列表。这样即使数据库之前未进行过字符串分析,用户也能获得结果。
性能规则
| 表/函数 | 架构 | 说明 |
|---|---|---|
COUNT(*) FROM strings | 缓存表计数路径 | O(1) 获取当前字符串列表数量 |
strings | 查询范围内 | 每次扫描时从 IDA 的实时字符串列表实例化(不使用持久化的 vtable 缓存);速度快,因为 IDA 的 strlist 已构建完成。rebuild_strings() 会重新生成 IDA 底层的字符串列表 |
byte_search | 原生二进制搜索表 | 远快于遍历 instructions 表 |
bytes WHERE addr = X | 点查找 | O(1);虚拟表索引 |
bytes WHERE start_addr = X AND n = N | 通过隐藏的 start_addr + n 进行有界读取 | O(N);虚拟表索引 |
bytes WHERE addr >= A AND addr < B | 范围扫描 | O(范围);虚拟表索引 |
bytes WHERE addr > X(无界) | 范围扫描 | 避免使用 — 会遍历直到映像末尾的每个已映射字节;请使用有界形式 |
关键规则:
- 在新数据库中首次查询字符串之前,或在可能创建新字符串的代码/数据更改之后,始终调用
rebuild_strings()。 byte_search使用 IDA 的原生二进制搜索引擎;要“查找包含操作码 X 的函数”,应将匹配项按包含关系与funcs联接,而不是扫描instructions表。strings表是缓存字符串列表的快照。如果 IDA 的分析在首次查询后创建了新字符串,请再次调用rebuild_strings()。- 将字符串与函数交叉引用时,
strings + xrefs + funcsJOIN 模式是标准做法 — IDA 的 xref 索引让 JOIN 十分快速。
高级数据模式(CTE)
安全相关字符串分流
按安全相关性对字符串分类,以便快速评估威胁:
-- Categorize strings by security relevance
SELECT rebuild_strings();
WITH categorized AS (
SELECT addr, content,
CASE
WHEN content LIKE '%password%' OR content LIKE '%passwd%' OR content LIKE '%secret%'
THEN 'credential'
WHEN content LIKE '%http://%' OR content LIKE '%https://%' OR content LIKE '%ftp://%'
THEN 'url'
WHEN content LIKE '%error%' OR content LIKE '%fail%' OR content LIKE '%exception%'
THEN 'error'
WHEN content LIKE '%debug%' OR content LIKE '%trace%' OR content LIKE '%assert%'
THEN 'debug'
WHEN content LIKE '%.exe%' OR content LIKE '%.dll%' OR content LIKE '%.sys%'
THEN 'file_path'
WHEN content LIKE '%HKEY_%' OR content LIKE '%SOFTWARE\\%'
THEN 'registry'
ELSE 'other'
END AS category
FROM strings
WHERE length >= 5
)
SELECT category, COUNT(*) AS count,
GROUP_CONCAT(SUBSTR(content, 1, 60), ' | ') AS samples
FROM categorized
WHERE category != 'other'
GROUP BY category
ORDER BY count DESC;
将字符串引用与函数大小结合进行可疑度评分
引用安全相关字符串且规模较大的函数是高优先级目标:
-- Suspicious functions: reference interesting strings AND are non-trivial
WITH interesting_strings AS (
SELECT addr, content FROM strings
WHERE content LIKE '%password%' OR content LIKE '%encrypt%'
OR content LIKE '%decrypt%' OR content LIKE '%http%'
OR content LIKE '%socket%' OR content LIKE '%connect%'
),
string_funcs AS (
SELECT DISTINCT (SELECT addr FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) AS func_addr,
s.content AS matched_string
FROM interesting_strings s
JOIN xrefs x ON x.to_addr = s.addr
WHERE (SELECT addr FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) IS NOT NULL
)
SELECT (SELECT name FROM funcs WHERE sf.func_addr >= addr AND sf.func_addr < end_addr LIMIT 1) AS func_name,
printf('0x%X', sf.func_addr) AS addr,
f.size AS func_size,
GROUP_CONCAT(sf.matched_string, ' | ') AS strings_referenced
FROM string_funcs sf
JOIN funcs f ON f.addr = sf.func_addr
GROUP BY sf.func_addr
ORDER BY f.size DESC
LIMIT 20;
查找同时引用加密相关字符串和网络相关字符串的函数
跨类别关联有助于识别数据外泄或 C2 通信:
-- Functions touching both crypto and network strings
WITH crypto_refs AS (
SELECT DISTINCT (SELECT addr FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) AS func_addr
FROM strings s JOIN xrefs x ON x.to_addr = s.addr
WHERE s.content LIKE '%crypt%' OR s.content LIKE '%aes%'
OR s.content LIKE '%cipher%' OR s.content LIKE '%hash%'
),
network_refs AS (
SELECT DISTINCT (SELECT addr FROM funcs WHERE x.from_addr >= addr AND x.from_addr < end_addr LIMIT 1) AS func_addr
FROM strings s JOIN xrefs x ON x.to_addr = s.addr
WHERE s.content LIKE '%socket%' OR s.content LIKE '%connect%'
OR s.content LIKE '%send%' OR s.content LIKE '%recv%'
OR s.content LIKE '%http%'
)
SELECT (SELECT name FROM funcs WHERE c.func_addr >= addr AND c.func_addr < end_addr LIMIT 1) AS func_name,
printf('0x%X', c.func_addr) AS addr
FROM crypto_refs c
JOIN network_refs n ON n.func_addr = c.func_addr;
另请参阅
disassembly— 字符串/字节在代码中的引用位置(针对操作数的读取)。xrefs— 指向目标地址的数据引用;从数据命中项跳转到其使用者的标准途径。debugger— 字节修补会使用bytes表;此技能负责读取形式。analysis— 将字符串/导入项用作分流信号。