BNQL Reference¶
Binary Ninja Query Language (BNQL) is a path-oriented query language for navigating and filtering the object graph of one or more analyzed binaries. Every query produces an ordered set of Binary Ninja objects.
For practical usage, see Building and Using Indexes and Using Semantic Indexing.
Query Structure¶
A BNQL query is a sequence of steps separated by /. Each step transforms the current set of objects into a new set by traversing a relationship (an axis) or by calling a function. An optional predicate in [...] filters the set after each step.
A leading / makes the path absolute: it starts from the root, the set of binary views in the analysis target. The root's only child axis is view, so absolute paths begin with /view (for example /view/function); every other node type is reached from a view. A bare /function, /datavar, or /section is a path-type error. When run through Sidekick's query tool, a call can narrow the root to specific binaries by view ID, and /view lists the selected views and their @id values. A path without a leading / is relative to the current context object (used inside predicates and function arguments).
Steps¶
Axis step¶
Traverse a relationship from the current objects to target objects of the specified type.
axis— the relationship to follow (see Axes). Defaults tocontainswhen omitted.node_type— the type of target objects, or*to match any type.predicate— optional filter expression in[...].
Shorthand:
| Shorthand | Equivalent |
|---|---|
/view/function |
/view/contains::function |
address(0x1000)/^function |
address(0x1000)/contained-in::function |
Function step¶
A built-in function call used as a step. The function produces the set for the next step.
Functions support both positional and named arguments. Positional arguments must precede named arguments. Pass the main target argument positionally, and pass only the optional parameters (depth, size, similarity, limit, avoid, via) by name. The first-argument names in the Signature columns below describe the argument and are not keyword names.
Predicates¶
A predicate is a boolean expression wrapped in [...] that filters objects after a step. The context item (the current object being tested) is referred to as ..
/view/function[@name == "main"]
/view/datavar[entropy(.) > 7.0]
/view/function[calls::function[@name == "malloc"]]
A predicate that is itself a path expression evaluates to true if that path returns a non-empty set.
An integer literal inside [...] selects by zero-based index:
The index applies to each input object separately: /view/function/block[0] is the first block of every function. An out-of-range index returns nothing, and negative indexes are not supported.
Operators¶
Comparison operators¶
Used in predicate expressions.
| Operator | Meaning |
|---|---|
== |
Equal (numeric or string) |
!= |
Not equal |
< |
Less than |
> |
Greater than |
<= |
Less than or equal |
>= |
Greater than or equal |
~= |
Regex match — right-hand side is a regex pattern |
in |
Membership — left value is contained in right set or list |
Logical operators¶
| Operator | Meaning |
|---|---|
and |
Both conditions true |
or |
Either condition true |
not |
Negation |
Set operators¶
Combine two path or function-call expressions. intersect and except bind more tightly than union (|), and chains are evaluated left to right. Operands must be paths or function calls: parentheses cannot be used to group a set expression as an operand of intersect or except, so A union B intersect C means A union (B intersect C).
| Operator | Alias | Meaning |
|---|---|---|
union |
\| |
All items from either set |
intersect |
— | Items present in both sets |
except |
— | Items in the left set that are not in the right set |
callers("malloc") union callers("free")
callers("malloc") intersect callers("free")
callers("malloc") except callers("free")
Attribute access¶
Inside a predicate, @attribute_name reads a property of the current object.
/view/function[@name == "main"]
/view/section[@name ~= r"\.text"]
/view/tag[@scope == "instruction"]
/view/datavar[@size >= 16]
/view/function[@stack_size >= 256]
Special attributes available on all addressable objects:
| Attribute | Notes |
|---|---|
@name |
Object name. On datavar, defaults to data_<hex> if unnamed. |
@address |
Address of the object. Alias for @start on objects that have a start attribute (functions, blocks, sections, segments, strings); native on data variables, symbols, tags, constants, and comments. |
@start |
Start address of functions, blocks, sections, segments, strings, and address ranges. For data variables and symbols, use @address. |
@attribute also reads any property of the underlying Binary Ninja object (for example @executable or @operation). Enum-valued properties compare by member name (@operation == "HLIL_CALL"). An unknown attribute on a known node type is rejected before the query runs, and the error lists close matches.
Symbol-specific attributes:
| Attribute | Notes |
|---|---|
@type |
Symbol type name, such as FunctionSymbol, DataSymbol, ImportedFunctionSymbol, ImportedDataSymbol, or ImportAddressSymbol. |
@binding |
GlobalBinding, WeakBinding, or LocalBinding. |
Note
@imported and @exported only work on symbols returned by name from symbol("name") or s("name"). They never match symbols reached by traversal, such as /view/symbol, or symbols looked up by address. Filter with @type and @binding instead.
String-specific attributes:
| Attribute | Notes |
|---|---|
@value |
The text content of the string literal. |
Data-variable-specific attributes:
| Attribute | Notes |
|---|---|
@size |
Size in bytes of the data variable's type. If the type has no width, numeric predicates do not match. |
Function-specific attributes:
| Attribute | Notes |
|---|---|
@is_entry_point |
true if the function is one of the binary's entry points. |
@stack_size |
Recovered stack-frame size approximation in bytes, derived from Binary Ninja stack_layout. If no stack-layout data is recovered, the attribute is unavailable and numeric predicates do not match. |
Comment-specific attributes:
| Attribute | Notes |
|---|---|
@address |
Address of the comment. |
@text |
Comment text. /view/comment lists only address comments. |
Constant-specific attributes:
| Attribute | Notes |
|---|---|
@value |
The constant's integer value. |
@address |
Address of the instruction that contains the constant. |
A constant compared directly uses its value, for example constant[. == 0x10].
Argument-specific attributes:
Arguments come from contains::argument on an HLIL or MLIL call instruction.
| Attribute | Notes |
|---|---|
@pos |
Zero-based argument index. |
@value |
The argument value. |
@address |
Address of the call site. |
An argument compared directly uses its value, for example callsites("memcpy")/argument[@pos == 2].
Type-specific attributes:
| Attribute | Notes |
|---|---|
@user_defined |
true if the type is defined by the user (Sidekick, scripts, or manual edits), including user overrides of automatic types. |
@auto_defined |
true if the type was defined automatically by the loader, platform, type libraries, or analysis. |
Both are unavailable (neither true nor false) for anonymous types that are not defined by name in the view, such as some instance-of::type results.
/view/type[@user_defined] # Types the user has defined
/view/type[@auto_defined and @name ~= r"^_IO_"] # Automatic types matching a pattern
Tag-specific attributes:
| Attribute | Notes |
|---|---|
@scope |
"data", "function", or "instruction". |
@type |
Tag type name. |
@data |
The tag text. |
@address |
Address the tag is attached to. |
@function_address |
Start address of the containing function, for function and instruction tags. Unavailable for data tags. |
@icon |
The tag type icon. |
@id |
Tag id. |
Type-member-specific attributes:
| Attribute | Notes |
|---|---|
@name |
Member name. |
@offset |
Offset of the member within its struct or union. |
@type |
Member type. |
@parent_name |
Name of the containing type. |
Region-specific attributes:
| Attribute | Notes |
|---|---|
@name, @display_name |
Region name and display name. |
@start, @length, @end |
Address span of the region. |
@flags, @fill |
Region flags and fill value. |
@enabled, @rebaseable, @local |
Region state. |
View-specific attributes:
| Attribute | Notes |
|---|---|
@id |
Sidekick BinaryView id for this view. |
@binary_view_id |
Alias for @id. |
Literals¶
| Form | Type | Examples |
|---|---|---|
"text" or 'text' |
String | "main", 'malloc' |
123, 0x1a2b, 3.14 |
Number (integer or float; non-negative only) | 0x401000, 7.0 |
true, false |
Boolean | true |
r"pattern" or r'pattern' |
Regex | r"sub_.*", r"^_Z" |
[v1, v2, ...] |
List of literals. Used with in, and also as a function argument to look up several targets at once. |
["malloc", "free"], f(["main", 0x401000]), address([0x1000, 0x2000])/^function |
Negative number literals are not supported: @offset == -8 is a syntax error. Compare against non-negative values instead.
Object types¶
The following type names are used in axis steps (e.g., /view/function, /view/function/calls::*). Use * to match any type.
Reachability. /view can contain only function, datavar, string, symbol, segment, section, region, component, type, hlil, mlil, llil, comment, tag, platform, and architecture. Every other type is reached through one of those: function contains block, variable, instruction, and tag; hlil, mlil, and llil contain their *_instruction and *_block types; block contains instruction and IL instructions; MLIL and HLIL instructions contain constant and argument; type contains type_member; platform contains type_library, which contains library_type and library_object. For example, /view/block is an error; use /view/function/block.
Core types¶
| Node type | Binary Ninja class | Description |
|---|---|---|
view |
BinaryView |
The analyzed binary view |
function |
Function |
Disassembled function |
block |
BasicBlock |
Assembly basic block |
instruction |
AssemblyInstruction |
Native assembly instruction |
datavar |
DataVariable |
Global or static data variable |
variable |
Variable |
Local variable within a function |
ssa_variable |
SSAVariableWrapper |
SSA-versioned local variable |
string |
StringWrapper |
String literal found in the binary |
symbol |
SymbolWrapper |
Named symbol (function, data, import, export) |
type |
TypeWrapper |
Data type definition (struct, enum, typedef) |
segment |
SegmentWrapper |
Loadable memory segment |
section |
SectionWrapper |
Named section (.text, .data, etc.) |
component |
Component |
User-defined grouping of functions and data |
tag |
TagWrapper |
Binary Ninja tag on a function, instruction, or data location |
comment |
Comment |
User or auto-generated comment at an address |
region |
MemoryRegionWrapper |
Named memory-map region overlaid on the view, including disabled and covered regions |
type_member |
TypeMemberWrapper |
Field of a struct or union type (reach with /view/type/type_member) |
constant |
Constant |
Constant value used in code |
argument |
Argument |
Function call argument value |
platform |
PlatformWrapper |
Target OS/ABI platform |
architecture |
ArchitectureWrapper |
CPU architecture |
IL types¶
| Node type | Description |
|---|---|
llil |
Low-Level IL function representation |
mlil |
Medium-Level IL function representation |
hlil |
High-Level IL function representation (decompiled) |
llil_instruction |
Single LLIL instruction |
mlil_instruction |
Single MLIL instruction |
hlil_instruction |
Single HLIL instruction |
llil_block |
LLIL basic block |
mlil_block |
MLIL basic block |
hlil_block |
HLIL basic block |
Type library types¶
| Node type | Description |
|---|---|
type_library |
Collection of type definitions for a platform |
library_type |
Named type definition from a type library |
library_object |
Function or variable signature from a type library |
Query-internal types¶
These types appear in query results but cannot always be used as step inputs.
| Node type | Description |
|---|---|
address |
Specific virtual address (from address() or pattern()) |
address_range |
Address range (from address-range()) |
graph_path |
Path through a relationship graph (from path()) |
Axes¶
Axes define the relationships traversed by axis steps. Every axis has a direction and an inverse.
Structural axes¶
| Axis | Inverse | Description |
|---|---|---|
contains |
contained-in |
Children of the current object. Default — can be omitted. Shorthand: /node_type. |
contained-in |
contains |
Parent container of the current object. Shorthand: ^node_type. |
Call graph axes¶
| Axis | Inverse | Description |
|---|---|---|
calls |
called-by |
Functions called by the current function or instruction (calls::function). Calls through imports or other symbols are returned only by calls::*, as symbol objects; calls::symbol returns nothing. |
called-by |
calls |
Functions that call the current function or symbol. |
Control flow axes¶
| Axis | Inverse | Description |
|---|---|---|
next |
prev |
Successor blocks in the control flow graph. |
prev |
next |
Predecessor blocks in the control flow graph. |
back |
back-from |
Back-edge targets (loop headers). |
back-from |
back |
Blocks that have a back edge to the current block. |
Dominance axes¶
These axes apply to basic blocks.
| Axis | Inverse | Description |
|---|---|---|
dominates |
dominated-by |
Blocks dominated by the current block (every path to them passes through the current block). |
dominated-by |
dominates |
Blocks that dominate the current block. |
immediately-dominates |
immediate-dominator |
Blocks that the current block immediately dominates. |
immediate-dominator |
immediately-dominates |
The immediate dominator of the current block. |
post-dominates |
post-dominated-by |
Blocks post-dominated by the current block (every path from them passes through the current block). |
post-dominated-by |
post-dominates |
Blocks that post-dominate the current block. |
dominance-frontier |
— | Dominance frontier of the current block. |
Data flow axes¶
| Axis | Inverse | Description |
|---|---|---|
reads |
read-by |
Variables or data locations read by the current function or instruction. |
read-by |
reads |
Functions or instructions that read the current variable or data. |
writes |
written-by |
Variables or data locations written by the current function or instruction. |
written-by |
writes |
Functions or instructions that write to the current variable or data. |
uses |
used-by |
Things the current object refers to. For a function: its local variables plus the strings, data variables, and functions it references. For an IL instruction: the strings and data variables it references. |
used-by |
uses |
Objects that reference the current string, address, data variable, or variable: instructions, functions, and data variables (HLIL instructions for a local variable). |
Pointer analysis axes¶
| Axis | Inverse | Description |
|---|---|---|
address-taken-by |
takes-address-of |
Code or data that takes the address of the current object. |
takes-address-of |
address-taken-by |
Objects whose address is taken by the current code. |
Type system axes¶
| Axis | Inverse | Description |
|---|---|---|
type-references |
referenced-by |
Named types referenced by a function (its signature and local variables), basic block, or instruction. Not supported from type objects. |
referenced-by |
type-references |
Code references to the current type, returned as IL instructions (or the containing function when no IL is available). Map the instructions back to functions with ^*/il-of::function, for example t("Config")/referenced-by::*/^*/il-of::function; ^function does not work on IL instructions. |
instance-of |
instance |
Type of the current variable, function, or data variable. Data-variable type results can represent anonymous/non-registered types. |
instance |
instance-of |
Local variables, functions, and data variables of the current type. |
inherits |
— | Base types of the current type. |
implements |
— | Placeholder — transition map is currently empty; reserved for future use. |
Symbol axes¶
| Axis | Inverse | Description |
|---|---|---|
has-symbol |
symbol-of |
Symbol associated with the current function or data variable. |
symbol-of |
has-symbol |
Object (function or data) that owns the current symbol. |
IL representation axes¶
| Axis | Inverse | Description |
|---|---|---|
il |
il-of |
IL representation of the current function. Use with a node type to specify the level: il::hlil, il::mlil, il::llil. |
il-of |
il |
Source function of the current IL function (hlil, mlil, llil). |
To map instructions or blocks between IL levels, use the hlil(), mlil(), and llil() functions.
Expression tree axes (IL instructions only)¶
| Axis | Inverse | Description |
|---|---|---|
child |
— | Immediate sub-expressions of the current IL instruction. |
descendant |
— | All sub-expressions recursively. |
Note
The parent and ancestor axes are reserved but not yet implemented. Using them is an error or returns no results.
Built-in functions¶
All functions receive the current evaluation context and the current context item. Arguments listed below are those you provide in the query.
Functions that resolve a target by name or address accept strings, integers, Binary Ninja objects, or sets of any of these.
Lookup functions¶
These functions return sets of objects by name, address, or identifier.
| Function | Signature | Returns | Description |
|---|---|---|---|
function |
function(val) |
set[function] |
Functions by name (string) or address (int or addressable object). Alias: f. |
f |
f(val) |
set[function] |
Alias for function. |
symbol |
symbol(val) |
set[symbol] |
Symbols by name or address. Alias: s. |
s |
s(val) |
set[symbol] |
Alias for symbol. |
datavar |
datavar(val) |
set[datavar] |
Data variables by name or address. Alias: g (mnemonic: global). |
g |
g(val) |
set[datavar] |
Alias for datavar. |
type |
type(val) |
set[type] |
Types by name. Alias: t. |
t |
t(val) |
set[type] |
Alias for type. |
tag |
tag(name) |
set[tag] |
All tags whose type name exactly matches the given string. |
address |
address(val) |
set[address] |
Address node from an int, hex or decimal string, symbol name, or addressable object. |
address-range |
address-range(start, size=256) |
set[address_range] |
Address range starting at start of size bytes. |
section |
section(val) |
set[section] |
Sections that contain the given address. val must be an addressable object. |
bv |
bv(filename) |
set[view] |
Binary views whose file basename matches the given string. |
function("main") # function named "main"
f(0x401000) # function at address
datavar("g_config") # global named g_config
tag("Reviewed") # all Reviewed tags
address(0x1000)/^function # function containing address 0x1000
address-range(0x500000, 512) # 512-byte region starting at 0x500000
bv("libc.so.6")/function # functions in a specific binary
Search functions¶
| Function | Signature | Returns | Description |
|---|---|---|---|
pattern |
pattern(bytes) |
set[address] |
Addresses where the byte pattern occurs. bytes is a hex string with optional spaces (e.g., "48 89 5c 24"), or a list of them. Returns address nodes — use /^function to find containing functions. |
xref |
xref(val) |
set[address] |
Code and data cross-references to the given address. Returns address nodes. |
syscall |
syscall(number) |
set[hlil_instruction] |
HLIL syscall instructions (HighLevelILSyscall) where at least one integer parameter in insn.params matches number. Searches the selected binary views. |
concept |
concept(text_or_obj, similarity=0.45, limit=20) |
set[concept_node] |
Semantic search using the embedding index. text_or_obj is a string, a list of strings, or an object (for example concept(f("main"))/function); multiple inputs are averaged. limit must be an integer of at least 1. Returns a concept node you traverse with /node_type to get matching objects. When the semantic index is disabled, silently returns an empty set (logs a warning; does not raise an error). |
pattern("48 89 5c 24")/^function # functions containing byte pattern
xref(0x401000)/^function # functions that reference address
syscall(1)/^hlil/il-of::function # functions making syscall 1 (write on Linux)
concept("string decryption")/function # functions semantically related to string decryption
Note
concept() requires the semantic index to be enabled and built. When the semantic index is disabled, concept() returns an empty set and logs a warning rather than raising an error. See Using Semantic Indexing.
Call graph functions¶
| Function | Signature | Returns | Description |
|---|---|---|---|
callers |
callers(target) |
set[function] |
Functions that call the target function or symbol. target can be a name, address, function, or symbol. |
callees |
callees(target) |
set[function \| symbol] |
Functions and symbols called by the target function. |
callsites |
callsites(target) |
set[hlil_instruction \| mlil_instruction \| llil_instruction] |
Call instructions that call the target. IL level is inferred from the target type: /il::llil gives LLIL, /il::mlil gives MLIL, otherwise HLIL. |
reachable-from |
reachable-from(roots, depth=None) |
set[function] |
All functions reachable from roots in the call graph (the roots themselves are included). Limited to 1000 functions. |
reaching-to |
reaching-to(targets, depth=None) |
set[function] |
All functions that can reach targets in the call graph (the targets themselves are included). Limited to 1000 functions. |
path |
path(sources, sinks, avoid=None, via="calls", depth=None) |
set[graph_path] |
Shortest path from any source to any sink using BFS. via names the axis to traverse. Returns a graph_path object; traverse with /contains::* to enumerate nodes. |
path-exists |
path-exists(sources, sinks, depth=None) |
bool |
true if any path exists from a source to a sink. |
is-leaf |
is-leaf(val=.) |
bool |
true if the function has no callees (no direct calls and no indirect calls via MLIL). When called with no argument inside a predicate, tests the context item. |
callers("malloc") # all callers of malloc
callees("parse_header") # what parse_header calls
callsites("memcpy") # HLIL call instructions to memcpy
callsites(function("malloc")/il::mlil) # MLIL call instructions to malloc
reachable-from(f("main"), depth=5) # call graph within 5 hops of main
reaching-to(f("dangerous_func")) # anything that can reach dangerous_func
path(f("recv"), f("system")) # call path from recv to system
path(f("open"), f("exec"), avoid=f("check")) # path avoiding the check function
/view/function[is-leaf(.)] # all leaf functions
Note
reachable-from and reaching-to cap results at 1000 functions. path uses BFS and returns the shortest path.
IL representation functions¶
| Function | Signature | Returns | Description |
|---|---|---|---|
hlil |
hlil(val) |
set[hlil \| hlil_instruction] |
High-Level IL representation. Accepts a function name, address, Function, AssemblyInstruction, or other IL instruction. BasicBlock — HLIL block mapping is not supported. |
mlil |
mlil(val) |
set[mlil \| mlil_instruction \| mlil_block] |
Medium-Level IL representation. Accepts functions, instructions, and basic blocks. |
llil |
llil(val) |
set[llil \| llil_instruction \| llil_block] |
Low-Level IL representation. Accepts functions, instructions, and basic blocks. |
hlil("main") # HLIL function for main
mlil(/view/function) # MLIL for all functions
/view/string/used-by::instruction/hlil(.) # HLIL instructions using strings
Utility functions¶
| Function | Signature | Returns | Description |
|---|---|---|---|
count |
count(set) |
int |
Number of items in set. |
first |
first(set) |
set |
Single-element set containing only the first item of set. |
entropy |
entropy(val) |
float |
Shannon entropy (bits) of the bytes in the object's address range. Range 0.0—8.0. |
contains-address |
contains-address(addr) |
bool |
true if the context object's address range includes addr. |
/view/function[count(calls::*) > 10] # functions with more than 10 calls
/view/function[0] # first function of each view (use first(/view/function) for a single item)
/view/datavar[entropy(.) > 7.0] # high-entropy globals (potential keys)
/view/section[contains-address(0x401234)] # section that contains an address
Evaluation semantics¶
Absolute vs. relative paths. A query beginning with / starts from the set of binary views in the analysis target, so its first step selects views: use /view/<node_type> (for example /view/function) to reach objects inside them. A query without a leading / starts from the current context object (the dynamic context item). Inside predicates, . always refers to the item being tested.
Set semantics. Every step produces an ordered set. Duplicate objects are automatically deduplicated. Order is insertion order — generally the order Binary Ninja enumerates objects.
Short-circuit evaluation. and evaluates right-to-left and stops on the first false. or evaluates right-to-left and stops on the first true.
Timeout. Long-running queries time out automatically. If a timeout occurs on the final step, partial results are returned. If it occurs on an intermediate step, an empty set is returned for that step.
Multi-binary queries. Absolute queries search every analyzed view in the analysis target, not only the active view (a file's Raw view is used only when it has no analyzed view). Narrow the search with bv("name"), with a predicate such as /view[@id == "<binary_view_id>"], or, when calling the query tool, with its binary_view_ids parameter. /view lists the selected views and their IDs. An unknown or ambiguous view ID is an error.
Errors. Syntax errors report the line and column. Before running, Sidekick type-checks the query: an unknown @attribute on a known node type, an axis that does not apply to the source type, or a node type that is not reachable via an axis fails with a message listing the valid alternatives. An unknown function name is rejected when the query is parsed, and invalid function arguments (for example a non-string bv() argument, or a concept() limit below 1) fail when the function runs. A traversal that is unsupported for a particular object at run time is skipped and contributes no results.
Examples¶
All functions in the binary:
Function by name:
Function by address:
Functions whose name matches a pattern:
Functions that call malloc:
callers("malloc") resolves a function named malloc and, when there is none, the imported symbol of that name. The equivalent predicate form needs calls::*, as in /view/function[calls::*[@name == "malloc"]], because calls::function misses calls made through imports.
Call instructions to memcpy (the instructions themselves):
All tags of a specific type:
Tags filtered by scope:
High-entropy data variables (potential keys or encrypted data):
Leaf functions (no outgoing calls):
Functions reachable from main within 3 hops:
Call path from network input to a sensitive sink:
Enumerate nodes in a path:
Functions that call malloc but not free:
Functions that call both malloc and free:
Functions that use a specific string:
Functions by semantic concept (requires semantic index):
concept("file encryption")/function
# or to filter within a predicate:
/view/function[concept("encryption loop")]
Use concept(...) as the whole predicate. It cannot be combined with in, and, or, or not.
Find byte pattern and get containing functions:
Functions in a specific binary (multi-binary project):
Functions that make syscall number 59 (execve on Linux):
syscall(59) alone returns the HLIL syscall instructions.
Data variables in the .data section: