Bap_wp.EnvironmentThis module represents the environment of a BIR program and is used when determining pre-conditions.
It contains a Z3 context, a var_gen, the association between BIR variables and Z3 constants, preconditions for previously visited blocks, a mapping of Z3 variables to function calls during runtime, subroutine summaries, a handler for loop unrolling, and expression verification conditions.
module Constr = ConstraintThe state type which is maintained when creating preconditions. It contains, among other things, summaries for subroutines, the associations between BIR variables and Z3 constants, and preconditions for already visited blocks, if relevant.
This type is used to create fresh variables when needed. It's internals should be irrelevant.
The type that specifies whether a fun_spec should calculate the precondition based off a summary or by inlining the function and visiting it with Precondition.visit_sub.
Type that specifies what rules should be used when calculating the precondition of a subroutine.
Type that specifies what rules should be used when encountering an indirect call
Type that specifies what rules should be used when visiting a jump in a BIR program.
Type that specifies what rules should be used when calculating the precondition of an interrupt.
The loop handling procedure for the appropriate blocks.
Condition generated when exploring an expression: BeforeExec will generate a Constr.goal to be added to the postcondition before any substitution is made, and AfterExec will generate the goal to be added after all substitutions are completed.
Conditions generated when exploring an expression: if it is a Verify, this represents an additional proof obligation, an Assume represents an assumption, typically about the definedness of the expression.
Type that generates a Verification Condition on encountering a given pattern, typically a correctness constraint, like no overflow or no null dereference.
A map containing the current depth for a block when unrolling a loop.
val init_loop_handler :
default:loop_handler ->
( Bap.Std.Tid.t -> loop_handler option ) list ->
loop_handlerinit_loop_handler default handlers takes in a list of handlers that will be used when visiting a loop in the subroutine. The handler used is based off of the loop's tid.
val mk_env :
subs:Bap.Std.Sub.t Bap.Std.Seq.t ->
specs:
( Bap.Std.Sub.t -> Bap_core_theory.Theory.target -> fun_spec option ) list ->
default_spec:( Bap.Std.Sub.t -> Bap_core_theory.Theory.target -> fun_spec ) ->
indirect_spec:indirect_spec ->
jmp_spec:jmp_spec ->
int_spec:int_spec ->
exp_conds:exp_cond list ->
loop_handlers:( Bap.Std.Tid.t -> loop_handler option ) list ->
default_loop_handler:loop_handler ->
target:Bap_core_theory.Theory.target ->
freshen_vars:bool ->
use_fun_input_regs:bool ->
stack_range:mem_range ->
data_section_range:mem_range ->
func_name_map:string Core.String.Map.t ->
smtlib_compat:bool ->
Z3.context ->
var_gen ->
tCreates a new environment with
fun_specs that each summarize the precondition for its mapped functionindirect_spec for handling indirect callsjmp_spec for handling branchesint_spec for handling interruptsexp_conds to satisfyval env_to_string : t -> stringCreates a string representation of the environment.
Create a Z3 context, used to generate every Z3 expression. Simply defined as Z3.mk_context [].
val mk_var_gen : unit -> var_genCreate a new variable generator. Two fresh variables created with the same generator will be distinct.
val get_fresh : ?name:string -> var_gen -> stringGet a fresh variable name, possibly prefixed by a given name string.
Set variable freshening, which will cause constraint generation to create fresh variables.
freshen ~name constr env vars creates fresh names for vars found in constr. Optionally takes in name, which is a function that maps the original variable name to the fresh name. Defaults to fresh_var.
val add_call_pred : t -> Constr.z3_expr -> tAdd a z3 expression representing a function call predicate generated during the analysis to the environment.
Removes all z3 expressions representing function call predicates from the environment. This is used because the initial pass through a binary generates predicates that are not used during precondition computation.
val add_var : t -> Bap.Std.Var.t -> Constr.z3_expr -> tAdd a new binding to the environment for a bap variable to a Z3 expression, typically a constant.
val find_var : t -> Bap.Std.Var.t -> Constr.z3_expr optionLooks up the Z3 variable that represents a BIR variable.
Add a precondition to be associated to a block b to the environment.
Creates a list of assumptions and verification conditions as hooks on an expression being visited during analysis.
val get_context : t -> Z3.contextObtains the Z3 context within a given environment.
Obtains the var_gen used to create fresh variables within a given environment.
val get_subs : t -> Bap.Std.Sub.t Bap.Std.Seq.tObtains the sequence of subroutines that belongs to a BIR program.
val get_var_map : t -> Constr.z3_expr EnvMap.tObtains the var_map containing a mapping of BIR variables to Z3 variables.
val get_init_var_map : t -> Constr.z3_expr EnvMap.tObtains the var_map containing a mapping of BIR variables to the Z3 variables that represent their initial states.
val get_var : t -> Bap.Std.Var.t -> Constr.z3_expr * tLooks up the Z3 variable that represents a BIR variable. Produces fresh z3_expr if not found.
Looks up the precondition for a given block in the environment. Currently returns True if the block is not yet visited.
val get_sub_name : t -> Bap.Std.Tid.t -> string optionLooks up the subroutine's name given its tid.
val get_fun_name_tid : t -> string -> Bap.Std.Tid.t optionFinds the tid of a function in the environment.
val get_called : t -> Bap.Std.tid -> string optionLook up the string name for the variable which represents a call made to a subroutine with a given tid.
val get_sub_handler : t -> Bap.Std.Tid.t -> fun_spec_type optionLooks up the specification of a subroutine that is used to calculate the precondition of a function call.
val get_indirect_handler : t -> Bap.Std.Exp.t -> indirect_specLooks up the indirect call spec for an expression. Used to calculate the precondition of an indirect call.
Looks up the list of jmp_specs that is used to calculate the precondition of jumps in a BIR program.
Updates the list of jmp_specs used to calculate the precondition of jumps in a BIR program.
Looks up the specification of calculating the precondition of an interrupt.
val get_loop_handler :
t ->
t ->
Constr.t ->
start:Bap.Std.Graphs.Ir.Node.t ->
Bap.Std.Graphs.Ir.t ->
tFinds the loop_handler that is used to unroll loops when it is visited in the BIR program.
val get_target : t -> Bap_core_theory.Theory.targetObtains the target architecture of the program.
val get_gprs : t -> Bap.Std.Var.Set.tObtains the general purpose registers of the target architecture of the program.
val get_sp : t -> Bap.Std.Var.tObtains the name of the program's stack pointer
val get_mem : t -> Bap.Std.Var.tObtains the BAP variable representing a program's memory.
val get_all_target_vars : t -> Bap.Std.Var.Set.tObtain the set of all registers and memories for the target.
val get_call_preds : t -> ExprSet.tObtains a list of all the Constr.z3_exprs that represents function call predicates that were generated during analysis.
val fold_fun_tids :
t ->
init:'a ->
f:( key:string -> data:Bap.Std.Tid.t -> 'a -> 'a ) ->
'aPerforms a fold on the map of of function names to tids to generate a Constr.z3_expr.
val use_input_regs : t -> boolChecks to see if the environment supports using all possible input registers when generating symbols in the function specs at a function call site.
val get_smtlib_compat : t -> boolDetermine whether to generate constraints that are smtlib compatible or using optimizations that are Z3 specific. Put to true if using external smt solver
val in_stack : t -> Constr.z3_expr -> Constr.z3_exprin_stack env addr is the constraint STACK_MIN < addr <= STACK_MAX as defined by the concrete range of the stack in the env.
val get_stack_end : t -> intget_stack_end retrieves the address of the largest address that the top of the stack can take. It is assumed the stack grows downwards, from high addresss to low address. The top and start of the stack is defined as stack_base and is the largest address in the stack. The stack end (retrieved by this function) is the smallest value that the stack pointer can take.
val in_data_section : t -> Constr.z3_expr -> Constr.z3_exprin_data_section env addr is the constraint DATA_MIN <= addr < DATA_MAX as defined by the concrete range of the data section in the env.
val init_stack_ptr : t -> Constr.z3_expr -> Constr.z3_exprinit_stack_ptr env ptr initializes the constraint STACK_MIN + 128 < sp <= STACK_MAX which is the region of the stack that the stack pointer may point to at the beginning of a subroutine. The 128 is based off of the 128 bytes of red zone underneath the stack pointer in x86_64.
update_stack_base range base updates the highest address of the stack to be the same value as base.
update_stack_size range size updates the size of the stack to be the same value as size.
val mk_init_var : t -> Bap.Std.Var.t -> Constr.z3_expr * tmk_init_var env var creates a fresh Z3 variable that represents the initial state of variable var. Adds a new binding to env for the bap variable to is generated init variable.
val get_init_var : t -> Bap.Std.Var.t -> Constr.z3_expr optionget_init_var var obtains the Z3 expression that represents the initial state of a bap variable var.
val map_sub_name : t -> string -> stringmap_sub_name env name_mod obtains the name of the subroutine in the original binary based off its name in the modified binary. In the case there is no mapping for the subroutine, get_sub_name will return name_mod (when calling this function from the original binary.
val get_unroll_depth : t -> Bap.Std.Blk.t -> int optionget_unroll_depth env node obtains the unroll depth for node when unrolling a loop.
set_unroll_depth env node depth updates the map with the new unroll depth for node.
val mk_z3_expr :
Z3.context ->
name:string ->
typ:Bap.Std.Type.t ->
Constr.z3_exprCreate a constant Z3 expression of a type that corresponds to a bap type, where the correspondence is as follows:
w -> BitVector of width wa and word size w -> Functional array from BitVector a to BitVector w.val new_z3_expr : ?name:string -> t -> Bap.Std.Type.t -> Constr.z3_exprCreate a Z3 constant of the appropriate name and type, but ensure that the constant is "fresh" with the Environment.var_gen.