angr.analyses.variable_recovery.variable_recovery

class angr.analyses.variable_recovery.variable_recovery.VariableRecoveryState

Bases: VariableRecoveryStateBase

The abstract state of variable recovery analysis.

Variables:

variable_manager (angr.knowledge.variable_manager.VariableManager) – The variable manager.

__init__(project, block_addr, analysis, arch, func, concrete_states, *, tv_manager, stack_region=None, register_region=None)
Parameters:
property concrete_states
get_concrete_state(addr)
Parameters:

addr

Returns:

copy()
register_callbacks(concrete_states)
Parameters:

concrete_states

Returns:

merge(others, successor=None)

Merge two abstract states.

Parameters:

others (tuple[VariableRecoveryState, ...]) – Other abstract states to merge.

Returns:

The merged abstract state.

Return type:

tuple[VariableRecoveryState, bool]

class angr.analyses.variable_recovery.variable_recovery.VariableRecovery

Bases: ForwardAnalysis, VariableRecoveryBase

Recover “variables” from a function using forced execution.

While variables play a very important role in programming, it does not really exist after compiling. However, we can still identify and recovery their counterparts in binaries. It is worth noting that not every variable in source code can be identified in binaries, and not every recognized variable in binaries have a corresponding variable in the original source code. In short, there is no guarantee that the variables we identified/recognized in a binary are the same variables in its source code.

This analysis uses heuristics to identify and recovers the following types of variables: - Register variables. - Stack variables. - Heap variables. (not implemented yet) - Global variables. (not implemented yet)

This analysis takes a function as input, and performs a data-flow analysis on nodes. It runs concrete execution on every statement and hooks all register/memory accesses to discover all places that are accessing variables. It is slow, but has a more accurate analysis result. For a fast but inaccurate variable recovery, you may consider using VariableRecoveryFast.

This analysis follows SSA, which means every write creates a new variable in registers or memory (statck, heap, etc.). Things may get tricky when overlapping variable (in memory, as you cannot really have overlapping accesses to registers) accesses exist, and in such cases, a new variable will be created, and this new variable will overlap with one or more existing variables. A decision procedure (which is pretty much TODO) is required at the end of this analysis to resolve the conflicts between overlapping variables.

__init__(func, max_iterations=20, store_live_variables=False)
Parameters:

func (knowledge.Function) – The function to analyze.