ReachingDefinitionsAnalysis (RDA) is a text-book implementation of static data-flow analysis that works on functions or basic blocks. It supports both VEX and AIL (angr Intermediate Language).
By registering observers at observation points, you can use RDA to generate:
- Use-def chains
- Def-use chains
- Reaching definitions
- Liveness analysis
- Other traditional data-flow analyses
Constructor
The subject of analysis - a function or a single basic block. Can also be a
Subject wrapper object.Alternative graph to use instead of
function.graph.Maximum number of iterations before the analysis is terminated.
Whether temporary variables should be tracked during analysis.
Whether constant values should be tracked.
Collection of tuples defining where reaching definitions should be captured. Format:
("node"|"insn"|"stmt", address, OP_BEFORE|OP_AFTER).Optional initialization state. If provided, the analysis works on a copy.
Calling convention of the function.
Function handler to update analysis state on function calls. If
None, a default handler is created.True: Generate a dependency graphFalseorNone: Skip dependency graph generationDepGraphinstance: Use existing graph
Observe every statement, both before and after execution.
Size in bytes that objects with
UNKNOWN_SIZE are treated as.Whether to track liveness information. Can consume significant RAM on large functions.
Maximum number of elements in definition sets before merging to TOP.
Merge known values into TOP if TOP is present.
True:{TOP} ∨ {0xabc} = {TOP}False:{TOP} ∨ {0xabc} = {TOP, 0xabc}
Advanced Parameters
Number of functions to recurse into for interprocedural analysis. Only used if
function_handler is not provided.Whether to use callee-saved registers at function returns.
Properties
Dictionary mapping observation points to their corresponding
LiveDefinitions at that point.Set of all definitions encountered during analysis.
Set of all uses encountered during analysis.
The dependency graph if
dep_graph=True was specified.The model containing all analysis results and live definitions.
Convenience property to get a single result when only one observation point exists. Raises
ValueError if zero or multiple results exist.Set of all blocks visited during analysis.
Methods
get_reaching_definitions_by_insn(ins_addr, op_type)
Get reaching definitions at a specific instruction.The instruction address.
Whether to get definitions before or after the instruction.
LiveDefinitions object.
Raises: KeyError if the observation point was not registered.
get_reaching_definitions_by_node(node_addr, op_type)
Get reaching definitions at a CFG node.The node address.
Whether to get definitions before or after the node.
LiveDefinitions object.
Example Usage
Basic Analysis
Observation Points
Observe All Statements
Working with LiveDefinitions
Interprocedural Analysis
Using Custom Function Handler
Dependency Graph
Single Block Analysis
AIL-based Analysis
Observation Point Types
Observation points are tuples with the format:(type, identifier, op_type)
Observe at the beginning or end of a CFG node.
- Identifier: node address (int) or (address, idx) for AIL
- Example:
('node', 0x401000, OP_BEFORE)
Observe at a specific instruction.
- Identifier: instruction address (int)
- Example:
('insn', 0x401234, OP_AFTER)
Observe at a specific statement.
- Identifier: (block_addr, block_idx, stmt_idx)
- Example:
('stmt', (0x401000, None, 5), OP_BEFORE)
Observe at a block exit.
- Identifier: (node_address, exit_stmt_idx)
- Example:
('exit', (0x401000, 10), OP_AFTER)
Performance Considerations
Optimization Tips
- Limit observation points: Only observe what you need
- Disable liveness tracking for large functions
- Adjust
element_limit: Lower values merge to TOP sooner, reducing memory - Use
merge_into_tops=True: Reduces set sizes - Limit
max_iterations: Stop early if convergence is slow