Trigger Intents
Use this skill when user asks for:
- Function/segment/instruction inspection
- Call-site or control-flow analysis from disassembly
- Operand formatting and low-level code structure
- Raw byte/instruction-level evidence
Route to:
decompilerfor AST/pseudocode semanticsxrefsfor relationship-heavy caller/callee workflowsdebuggerfor patching/breakpoint actions
Do This First (Warm-Start Sequence)
-- 1) Orientation
SELECT * FROM binary;
-- 2) Segment map
SELECT name, printf('0x%X', start_addr) AS start_addr, printf('0x%X', end_addr) AS end_addr, perm
FROM segments
ORDER BY start_addr;
-- 3) Largest functions (triage anchors)
SELECT name, printf('0x%X', addr) AS addr, size
FROM funcs
ORDER BY size DESC
LIMIT 20;
Interpretation guidance:
- Start from executable segments and largest/highly connected functions.
- Use
func_addrconstraints early when querying instruction-heavy surfaces.
Failure and Recovery
- Slow queries on
instructions/heads:- Add
WHERE func_addr = Xor tight EA ranges.
- Add
- Missing expected symbol names:
- Pivot to address-based workflows and enrich via
namesupdates later.
- Pivot to address-based workflows and enrich via
- Ambiguous control-flow behavior:
- Cross-check with
disasm_callsand then escalate todecompiler.
- Cross-check with
Handoff Patterns
disassembly->xrefsfor relation expansion.disassembly->decompilerfor semantic interpretation.disassembly->debuggerfor patch/breakpoint execution.
Entity Tables
funcs
All detected functions in the binary with prototype information.
| Column | Type | Description |
|---|---|---|
addr |
INT | Function start address |
name |
TEXT | Function name |
size |
INT | Function size in bytes |
end_addr |
INT | Function end address |
flags |
INT | Function flags |
folder_path |
TEXT | RW function folder relative to Function window root; NULL/'' means root |
full_path |
TEXT | RO full dirtree path, including function name |
Prototype columns (populated when type info available):
| Column | Type | Description |
|---|---|---|
return_type |
TEXT | Return type string (e.g., "int", "void *") |
return_is_ptr |
INT | 1 if return type is pointer |
return_is_int |
INT | 1 if return type is exactly int |
return_is_integral |
INT | 1 if return type is int-like (int, long, DWORD, BOOL) |
return_is_void |
INT | 1 if return type is void |
arg_count |
INT | Number of function arguments |
calling_conv |
TEXT | Calling convention (cdecl, stdcall, fastcall, etc.) |
-- 10 largest functions
SELECT name, size FROM funcs ORDER BY size DESC LIMIT 10;
-- Functions starting with "sub_" (auto-named, not analyzed)
SELECT name, printf('0x%X', addr) as addr FROM funcs WHERE name LIKE 'sub_%';
-- Functions returning integers with 3+ arguments
SELECT name, return_type, arg_count FROM funcs
WHERE return_is_integral = 1 AND arg_count >= 3;
-- Functions organized by IDASQL annotation folders
SELECT addr, name, folder_path
FROM funcs
WHERE folder_path LIKE 'idasql/%'
ORDER BY folder_path, name;
Write operations:
-- Create a function
INSERT INTO funcs (addr) VALUES (0x401000);
-- Rename a function
UPDATE funcs SET name = 'my_func' WHERE addr = 0x401000;
-- Move a function into an IDA Function window folder
INSERT INTO dirtree_folders(tree, path) VALUES ('funcs', 'idasql/triage/network');
UPDATE funcs SET folder_path = 'idasql/triage/network' WHERE addr = 0x401000;
-- Move it back to root
UPDATE funcs SET folder_path = NULL WHERE addr = 0x401000;
-- Delete a function
DELETE FROM funcs WHERE addr = 0x401000;
Folder paths are relative / paths. IDASQL rejects ./.., duplicate separators, backslashes, non-empty folder deletes, and folder renames whose destination already exists.
segments
Memory segments. Full CRUD: INSERT a region, DELETE it, and UPDATE start_addr
(rebase/move), end_addr (resize), name, class, perm.
| Column | Type | RW | Description |
|---|---|---|---|
start_addr |
INT | RW | Segment start; UPDATE rebases (moves) the segment |
end_addr |
INT | RW | Segment end; UPDATE resizes the segment |
name |
TEXT | RW | Segment name (.text, .data, etc.) |
class |
TEXT | RW | Segment class (CODE, DATA) |
perm |
INT | RW | Permissions (R=4, W=2, X=1) |
-- Find executable segments
SELECT name, printf('0x%X', start_addr) as start FROM segments WHERE perm & 1 = 1;
-- Rename a segment
UPDATE segments SET name = '.mytext' WHERE start_addr = 0x401000;
-- Add a region (e.g. SRAM for a raw firmware image), then rebase it
INSERT INTO segments(start_addr, end_addr, name, class, perm)
VALUES (0x20000000, 0x20005000, 'SRAM', 'DATA', 6);
UPDATE segments SET start_addr = 0x08000000 WHERE name = '.text'; -- rebase
names
All named locations (functions, labels, data). Supports INSERT, UPDATE, and DELETE.
| Column | Type | RW | Description |
|---|---|---|---|
addr |
INT | R | Address |
name |
TEXT | RW | Name |
folder_path |
TEXT | RW | Name-folder path; NULL means root |
full_path |
TEXT | R | Full name dirtree path |
-- Create/set a name
INSERT INTO names (addr, name) VALUES (0x401000, 'my_symbol');
-- Rename
UPDATE names SET name = 'my_symbol_renamed' WHERE addr = 0x401000;
-- Organize globals/labels into IDA name folders
UPDATE names SET folder_path = 'idasql/names/globals' WHERE name LIKE 'g_%';
UPDATE names SET folder_path = NULL WHERE addr = 0x401000;
entries
Entry points (exports, program entry, tls callbacks, etc.).
| Column | Type | Description |
|---|---|---|
ordinal |
INT | Export ordinal |
addr |
INT | Entry address |
name |
TEXT | Entry name |
Instruction Tables
instructions
instructions is the disassembly table. For scalar disassembly text at a specific EA, use disasm_at(addr[, context]).
Use disasm_func() or disasm_range() when you explicitly need a function/range listing.
Decoded instructions support DELETE (converts instruction to unexplored bytes) and operand representation updates via operand*_format_spec.
WHERE func_addr = X is the fast path (function-item iterator). Without it, the table scans all code heads.
| Column | Type | Description |
|---|---|---|
addr |
INT | Instruction address |
func_addr |
INT | Containing function |
itype |
INT | Instruction type (architecture-specific) |
mnemonic |
TEXT | Instruction mnemonic |
size |
INT | Instruction size |
operand0..operand7 |
TEXT | Operand text (0..7) |
disasm |
TEXT | Full disassembly line |
operand0_class..operand7_class |
TEXT | Operand class: reg, imm, displ, mem, ... |
operand0_repr_kind..operand7_repr_kind |
TEXT | Current representation: plain, hex, dec, oct, bin, char, float, enum, offset, stroff, sizeof, segment, stkvar, forced |
operand0_repr_type_name..operand7_repr_type_name |
TEXT | Enum/stroff/sizeof type, offset base (hex), or forced text |
operand0_format_spec..operand7_format_spec |
TEXT (RW) | Apply/clear representation for a specific operand (see vocabulary below) |
-- Instruction profile of a function (FAST)
SELECT mnemonic, COUNT(*) as count
FROM instructions WHERE func_addr = 0x401330
GROUP BY mnemonic ORDER BY count DESC;
-- Find all call instructions in a function
SELECT addr, disasm FROM instructions
WHERE func_addr = 0x401000 AND mnemonic = 'call';
-- Apply enum representation to operand 1
UPDATE instructions
SET operand1_format_spec = 'enum:MY_ENUM'
WHERE addr = 0x401020;
-- Apply struct-offset representation to operand 0
-- e.g. makes `[rax+10h]` display as `[rax+command_t.field_name]`
UPDATE instructions
SET operand0_format_spec = 'stroff:command_t'
WHERE addr = 0x140001BE8;
-- Struct-offset with a base delta (subtracted before member resolution)
UPDATE instructions
SET operand0_format_spec = 'stroff:command_t,delta=16'
WHERE addr = 0x140001BE8;
-- Nested member path: separate type names with '/'
UPDATE instructions
SET operand0_format_spec = 'stroff:outer_t/inner_t'
WHERE addr = 0x140001BE8;
-- Clear representation back to plain
UPDATE instructions
SET operand1_format_spec = 'clear'
WHERE addr = 0x401020;
The format-spec is verified after apply: the UPDATE re-reads the operand and
fails (as a SQL error) if the resulting repr_kind, type path, or delta don't
match what was requested. Read back operandN_repr_kind /
operandN_repr_type_name to confirm.
Full operandN_format_spec vocabulary (all disassembly-level, no IDAPython
needed):
| Spec | Effect |
|---|---|
hex dec oct bin |
number base (radix) |
char |
character constant |
float |
floating-point |
offset |
plain offset, base 0 |
offset:<base> |
offset with a user-defined base (<base> = symbol name or address) |
enum:<NAME>[,serial=N] / enum:<NAME>::<MEMBER> |
enum constant |
stroff:<Type[/Nested...]>[,delta=N] |
struct-member offset |
sizeof:<STRUCT> |
struct-size constant — renders size STRUCT |
segment |
segment selector |
stkvar |
stack variable (operand must be a stack reference) |
forced:<text> |
forced (manual) operand text, e.g. forced:5 shl 3 |
clear / plain / none |
revert to default representation |
Combinable modifiers (suffix on any base, or standalone to modify the current
representation): ,signed / ,unsigned (toggle negative display) and
,bnot / ,nobnot (toggle bitwise-not display). Example: dec,signed,
hex,bnot, or just signed.
-- Number base, character, and sign/bitwise-not modifiers
UPDATE instructions SET operand1_format_spec = 'hex' WHERE addr = 0x401020;
UPDATE instructions SET operand1_format_spec = 'dec,signed' WHERE addr = 0x401020;
UPDATE instructions SET operand1_format_spec = 'char' WHERE addr = 0x401020;
-- Offsets (plain and user-defined base)
UPDATE instructions SET operand1_format_spec = 'offset' WHERE addr = 0x401020;
UPDATE instructions SET operand1_format_spec = 'offset:tbl_start' WHERE addr = 0x401020;
-- sizeof: an immediate equal to sizeof(STRUCT) renders as `size STRUCT`
UPDATE instructions SET operand1_format_spec = 'sizeof:FILEDEF' WHERE addr = 0x4015EB;
-- Forced operand text
UPDATE instructions SET operand1_format_spec = 'forced:5 shl 3' WHERE addr = 0x401020;
instruction_operands
One row per decoded non-void operand. Use this table for operand type/value details and for joinable replacements of old operand/decode helper functions.
| Column | Type | Description |
|---|---|---|
addr |
INT | Instruction address |
func_addr |
INT | Containing function |
opnum |
INT | Operand index |
text |
TEXT | Operand text |
type_code |
INT | IDA operand type code |
type_name |
TEXT | Operand type name (reg, imm, near, ...) |
dtype |
INT | Operand dtype |
reg |
INT | Register number when applicable |
op_addr |
INT | Referenced address/displacement when applicable |
raw_value |
INT | Raw operand value |
value |
INT | Best-effort scalar operand value |
Note (addr vs op_addr):
addris the instruction address; the operand's referenced address isop_addr. If you want the target an operand points at (e.g. a jump/call/data reference), selectop_addr—addridentifies the instruction the operand belongs to, not what it references.
SELECT opnum, text, type_name, value
FROM instruction_operands
WHERE addr = 0x401000
ORDER BY opnum;
SELECT i.addr, i.itype, i.mnemonic, o.opnum, o.text, o.type_name, o.value
FROM instructions i
LEFT JOIN instruction_operands o
ON o.addr = i.addr AND o.func_addr = 0x401000
WHERE i.func_addr = 0x401000
ORDER BY i.addr, o.opnum;
Performance: WHERE addr = X decodes one instruction; WHERE func_addr = X uses O(function_size) iteration. Without one of these constraints, it scans the entire database.
disasm_calls
All call instructions with resolved targets and optional call-site prototype overrides.
| Column | Type | Description |
|---|---|---|
func_addr |
INT | Function containing the call |
addr |
INT | Call instruction address |
callee_addr |
INT | Target address (0 if unknown) |
callee_name |
TEXT | Target name |
callee_type |
TEXT | RW nullable call-site prototype; UPDATE applies/replaces, NULL or empty clears |
-- Functions that call malloc
SELECT DISTINCT (SELECT name FROM funcs WHERE func_addr >= addr AND func_addr < end_addr LIMIT 1) as caller
FROM disasm_calls WHERE callee_name LIKE '%malloc%';
-- Apply/replace a call-site prototype, then clear it
UPDATE disasm_calls
SET callee_type = 'int (__fastcall *)(const char *path)'
WHERE addr = 0x401234;
UPDATE disasm_calls SET callee_type = NULL WHERE addr = 0x401234;
Applying callee_type on a direct call preserves the real callee symbol, so
re-decompiling the caller afterward is safe (no microcode INTERR); on an indirect
call it types that site. Empty/NULL clears the override.
blocks
Basic blocks within functions. Use func_addr constraint for performance.
| Column | Type | Description |
|---|---|---|
func_addr |
INT | Containing function |
start_addr |
INT | Block start |
end_addr |
INT | Block end |
size |
INT | Block size |
-- Blocks in a specific function (FAST - uses constraint pushdown)
SELECT * FROM blocks WHERE func_addr = 0x401000;
-- Functions with most basic blocks
SELECT (SELECT name FROM funcs WHERE func_addr >= addr AND func_addr < end_addr LIMIT 1) as name, COUNT(*) as blocks
FROM blocks GROUP BY func_addr ORDER BY blocks DESC LIMIT 10;
cfg_edges
Control flow graph edges between basic blocks. Always use WHERE func_addr = X (filter_eq pushdown, O(blocks in function)).
| Column | Type | Description |
|---|---|---|
func_addr |
INT | Containing function |
from_block |
INT | Source block address |
to_block |
INT | Target block address |
edge_type |
TEXT | normal (single-successor or fallback label), true/false (generic first/second arms for a two-way branch; labels follow successor order, not taken/fallthrough semantics) |
-- Get CFG structure
SELECT * FROM cfg_edges WHERE func_addr = 0x401000;
-- Find branch points (conditional blocks)
SELECT from_block, COUNT(*) as succ_count
FROM cfg_edges WHERE func_addr = 0x401000
GROUP BY from_block HAVING succ_count > 1;
-- Find merge points (blocks with multiple predecessors)
SELECT to_block, COUNT(*) as pred_count
FROM cfg_edges WHERE func_addr = 0x401000
GROUP BY to_block HAVING pred_count > 1;
-- Function complexity ranking: combine CFG, loops, and call metrics
SELECT f.name, f.size,
(SELECT COUNT(*)
FROM (
SELECT ce.from_block
FROM cfg_edges ce
WHERE ce.func_addr = f.addr
GROUP BY ce.from_block
HAVING COUNT(*) > 1
) branch_blocks) as branch_sites,
(SELECT COUNT(*) FROM disasm_loops dl WHERE dl.func_addr = f.addr) as loops,
(SELECT COUNT(*) FROM disasm_calls dc WHERE dc.func_addr = f.addr) as calls_made
FROM funcs f
WHERE f.size > 32
ORDER BY branch_sites DESC
LIMIT 20;
function_chunks
Cached table with one row per function chunk. Aggregate by func_addr when you
need function-level span or density metrics.
| Column | Type | Description |
|---|---|---|
func_addr |
INT | Function address |
chunk_start |
INT | Chunk start address |
chunk_end |
INT | Chunk end address |
block_count |
INT | Number of blocks in chunk |
total_size |
INT | Total size of chunk |
SELECT * FROM function_chunks WHERE func_addr = 0x401000;
SQL Functions -- Disassembly
| Function | Description |
|---|---|
disasm_at(addr) |
Canonical listing line for containing head (works for code/data) |
disasm_at(addr, n) |
Canonical listing line with +/- n neighboring heads |
disasm(addr) |
Single disassembly line at address |
disasm(addr, n) |
Next N instructions from address (count-based) |
disasm_range(start, end) |
All disassembly lines in address range [start, end) |
disasm_func(addr) |
Full disassembly of function containing address |
make_code(addr) |
Create instruction at address (returns 1/0) |
make_code_range(start, end) |
Create instructions in range, returns created count |
Disassembly Examples
-- Canonical single-EA disassembly (safe for code or data)
SELECT disasm_at(0x401000);
-- Canonical context window (+/- 2 heads)
SELECT disasm_at(0x401000, 2);
-- Full function disassembly (resolves boundaries via get_func)
SELECT disasm_func(addr) FROM funcs WHERE name = '_main';
-- Disassemble a specific address range
SELECT disasm_range(0x401000, 0x401100);
-- Sliding window: next 5 instructions from an address
SELECT disasm(0x401000, 5);
SQL Functions -- Names & Functions
Use table lookups for address and containing-function metadata. Resolve symbol names to integer EAs before using these patterns.
| Pattern | Description |
|---|---|
SELECT name FROM names WHERE addr = :addr LIMIT 1 |
Name at address |
SELECT name FROM funcs WHERE :addr >= addr AND :addr < end_addr LIMIT 1 |
Function containing address |
SELECT addr FROM funcs WHERE :addr >= addr AND :addr < end_addr LIMIT 1 |
Start of containing function |
SELECT end_addr FROM funcs WHERE :addr >= addr AND :addr < end_addr LIMIT 1 |
End of containing function |
Function count and index lookup are table-driven:
SELECT COUNT(*) AS function_count FROM funcs;
SELECT addr FROM funcs WHERE rowid = 0;
SQL Functions -- Navigation
Use heads ordering for defined-item navigation and SQLite formatting functions for display strings. Address equality/range filters are optimized; ORDER BY addr or ORDER BY addr DESC is consumed for next/previous-item lookups.
SELECT addr
FROM heads
WHERE addr > 0x401000
ORDER BY addr
LIMIT 1;
SELECT addr
FROM heads
WHERE addr < 0x401000
ORDER BY addr DESC
LIMIT 1;
SELECT printf('0x%llx', addr) AS address_hex
FROM heads
LIMIT 10;
Segment lookup is table-driven:
SELECT name
FROM segments
WHERE 0x401000 >= start_addr
AND 0x401000 < end_addr
LIMIT 1;
SQL Functions -- Item Analysis
Use heads for item classification, size, and raw flags:
SELECT addr, size, type, flags, disasm
FROM heads
WHERE addr = 0x401000;
SQL Functions -- Instruction Details
Use instructions and instruction_operands for decoded instruction facts:
SELECT addr, itype, mnemonic
FROM instructions
WHERE func_addr = 0x401000
LIMIT 10;
SELECT opnum, text, type_code, type_name, value
FROM instruction_operands
WHERE addr = 0x401000
ORDER BY opnum;
SELECT i.addr, i.itype, i.mnemonic, i.size, o.opnum, o.text, o.type_name, o.value
FROM instructions i
LEFT JOIN instruction_operands o
ON o.addr = i.addr AND o.addr = 0x401000
WHERE i.addr = 0x401000
ORDER BY o.opnum;
SQL Functions -- File Generation
| Function | Description |
|---|---|
gen_listing(path) |
Generate full-database listing output (LST) |
SQL Functions -- Graph Generation
| Function | Description |
|---|---|
gen_cfg_dot(addr) |
Generate CFG as DOT graph string |
gen_cfg_dot_file(addr, path) |
Write CFG DOT to file |
gen_schema_dot() |
Generate database schema as DOT |
-- Get CFG for a function as DOT format
SELECT gen_cfg_dot(0x401000);
Performance Rules
| Table | Architecture | Key Constraint | Notes |
|---|---|---|---|
funcs |
Index-Based | none needed | O(1) per row via getn_func(i) -- always fast |
instructions |
Iterator | func_addr |
Function-item iterator (fast) vs full code-head scan (slow) |
blocks |
Iterator | func_addr |
Constraint pushdown: iterates blocks of one function |
cfg_edges |
Iterator | func_addr |
filter_eq pushdown: O(blocks in function) |
disasm_calls |
Generator | func_addr, addr for writes |
Lazy streaming, respects LIMIT; callee_type is writable |
heads |
Generator | addr =, addr range |
Consumes ORDER BY addr for next/previous navigation; broad scans can still be large |
instruction_operands |
Iterator | addr, func_addr |
Address lookup decodes one instruction; function lookup iterates one function |
segments |
Index-Based | none needed | Small table, always fast |
names |
Iterator | none needed | Iterates IDA's name list |
Key rules:
funcsis always fast -- no constraint needed.instructionswithoutfunc_addrscans every code head -- usefunc_addrfor per-function queries.blockswithoutfunc_addriterates all functions' flowcharts -- always constrain.headsis often large. Useaddr = Xfor item facts and address range plusORDER BY addr [DESC] LIMIT 1for navigation.
Cost model:
funcs (full scan) -> O(number of functions), typically ~1000s, fast
instructions WHERE func_addr -> O(function_size / avg_insn_size)
instructions (no constraint) -> O(total_code_heads), potentially 100K+
blocks WHERE func_addr -> O(block_count_in_func), fast
cfg_edges WHERE func_addr -> O(block_count_in_func), fast
disasm_calls WHERE func_addr -> O(instructions_in_func), streaming
disasm_calls UPDATE callee_type WHERE addr -> O(1) call-site lookup
heads WHERE addr -> O(1) IDA head check
heads next/prev LIMIT 1 -> O(distance to next/previous defined head)
instruction_operands addr -> O(operands in one instruction)
instruction_operands func -> O(operands in one function)
Additional Resources
- For advanced CTE patterns and instruction lifecycle playbooks: references/disassembly-examples.md
- For additional table schemas (fchunks, heads, bytes, signatures, problems, fixups, etc.): references/disassembly-tables.md
See Also
decompiler— pseudocode and ctree on the same function; pivot when disassembly is too noisy.xrefs— call graph and data references centered on a function or call site.data— operand-targeted bytes/strings;bytestable for per-byte reads and bounded windows viaWHERE start_addr = X AND n = Ncomposed withhex(blob_concat(value))for bulk hex.