pub trait TaintAnalysis<'a>: HasCfg<'a> + HasVsaResult<Data> + AsRef<Project> {
    // Provided methods
    fn handle_empty_state_out(&self, _tid: &Tid) -> Option<State> { ... }
    fn update_call_generic(
        &self,
        state: &State,
        call_tid: &Tid,
        calling_convention_hint: &Option<String>
    ) -> Option<State> { ... }
    fn update_call(
        &self,
        _state: &State,
        _call: &Term<Jmp>,
        _target: &CfgNode<'_>,
        _calling_convention: &Option<String>
    ) -> Option<State> { ... }
    fn update_extern_call(
        &self,
        state: &State,
        _call: &Term<Jmp>,
        project: &Project,
        extern_symbol: &ExternSymbol
    ) -> Option<State> { ... }
    fn update_call_stub(&self, state: &State, call: &Term<Jmp>) -> Option<State> { ... }
    fn update_jump(
        &self,
        state: &State,
        jump: &Term<Jmp>,
        _untaken_conditional: Option<&Term<Jmp>>,
        _target: &Term<Blk>
    ) -> Option<State> { ... }
    fn update_return_callee(
        &self,
        _state: &State,
        _call_term: &Term<Jmp>,
        _return_term: &Term<Jmp>,
        _calling_convention: &Option<String>
    ) -> Option<State> { ... }
    fn update_return(
        &self,
        state_before_return: Option<&State>,
        state_before_call: Option<&State>,
        call_term: &Term<Jmp>,
        return_term: &Term<Jmp>,
        calling_convention: &Option<String>
    ) -> Option<State> { ... }
    fn update_def_assign(
        &self,
        state: &State,
        _tid: &Tid,
        var: &Variable,
        value: &Expression
    ) -> State { ... }
    fn update_def_load(
        &self,
        state: &State,
        tid: &Tid,
        var: &Variable,
        _address: &Expression
    ) -> State { ... }
    fn update_def_store(
        &self,
        state: &State,
        tid: &Tid,
        _address: &Expression,
        value: &Expression
    ) -> State { ... }
    fn update_def_post(
        &self,
        _old_state: &State,
        new_state: State,
        def: &Term<Def>
    ) -> Option<State> { ... }
}
Expand description

Trait representing the definition of a Taint Analysis.

Taken together, these callbacks define the transfer function of the Taint Analysis. Individual callbacks define the transfer functions for the different kinds of statements that can occur in the intermediate representation.

The property space of this analysis is the State type, it represents the taint information we have about a particular point in the program.

Default Implementations

Many callbacks have default implementations that contain a behavior common to many taint analyses. However, you almost certainly want to override some of them to implement the custom logic of your analysis.

Provided Methods§

source

fn handle_empty_state_out(&self, _tid: &Tid) -> Option<State>

Called when a transition function mapped the input state to the empty state.

This function will be called every time a default transition function maps a (possibly empty) input state to the empty state. Its return value will override the Some(empty_state) return value of the transition function.

Default

Just returns None. This is the desired behavior as long as it is impossible for transition functions to generate taint from an empty state.

source

fn update_call_generic( &self, state: &State, call_tid: &Tid, calling_convention_hint: &Option<String> ) -> Option<State>

Update taint state on a function call without further target information.

Default

Only remove taint from non-callee-saved registers.

source

fn update_call( &self, _state: &State, _call: &Term<Jmp>, _target: &CfgNode<'_>, _calling_convention: &Option<String> ) -> Option<State>

Transition function for edges of type Call.

Corresponds to intra-program calls, i.e., the target function is defined in the same binary. Return None here to keep the analysis intraprocedural.

Default

Just returns None to keep the analysis intraprocedural.

source

fn update_extern_call( &self, state: &State, _call: &Term<Jmp>, project: &Project, extern_symbol: &ExternSymbol ) -> Option<State>

Transition function for calls to external functions.

Default

Removes taint from non-callee-saved registers.

source

fn update_call_stub(&self, state: &State, call: &Term<Jmp>) -> Option<State>

Transition function for edges of type ExternCallStub.

Corresponds to inter-program calls, i.e., calls to shared libraries. Currently, indirect calls also lead to edges of type ExternCallStub. If you are only interested in handling calls to library functions consider implementing update_extern_call instead.

Default

Remove taint from non-callee-saved registers.

source

fn update_jump( &self, state: &State, jump: &Term<Jmp>, _untaken_conditional: Option<&Term<Jmp>>, _target: &Term<Blk> ) -> Option<State>

Returns the new taint state after a jump.

Default

Clones the state before the jump.

source

fn update_return_callee( &self, _state: &State, _call_term: &Term<Jmp>, _return_term: &Term<Jmp>, _calling_convention: &Option<String> ) -> Option<State>

Corresponds to returns from calls to other functions within the program.

Only invoked if we have information about the taint state in the called subroutine at the time it returns, i.e., we are in the first column of the table in update_return. The state parameter corresponds to the taint state at the return sites of the called subroutine.

By implementing this method you can perform an interprocedural taint analysis:

  • If you return Some(state) you may influence the taint state in the caller (see the documentation of update_return for more information), by having it be merged into the state coming from the call site.
  • If you return None, no information will be propagated through this call. (This includes possible state information from the call site!); thus, return the empty state if you want to keep the analysis in the caller going.
Default

Returns an empty state, i.e., information is propagated through the call but the analysis stays intraprocedural.

source

fn update_return( &self, state_before_return: Option<&State>, state_before_call: Option<&State>, call_term: &Term<Jmp>, return_term: &Term<Jmp>, calling_convention: &Option<String> ) -> Option<State>

Corresponds to returns from calls to other functions within the program.

By implementing this method you can perform interprocedural taint analysis. See forward_interprocedural_fixpoint::Context::update_return for more information.

Default

Depending on the availability of state_before_call and state_before_return the return value is computed according to the following scheme:

| state_before_call/    |                                                       |                     |
|   state_before_return | Some                                                  | None                |
|-----------------------|-------------------------------------------------------|---------------------|
| Some                  | Some(update_call_generic.merge(update_return_callee)) | update_call_generic |
|                       | IF both are Some ELSE None                            |                     |
|-----------------------|-------------------------------------------------------|---------------------|
| None                  | update_return_callee                                  | None                |
source

fn update_def_assign( &self, state: &State, _tid: &Tid, var: &Variable, value: &Expression ) -> State

Returns the new taint state after an assignment.

Default

Taints the destination register if the value that is assigned to it is tainted.

source

fn update_def_load( &self, state: &State, tid: &Tid, var: &Variable, _address: &Expression ) -> State

Returns the new taint state after a load from memory.

Default

Taints the destination register if the memory location was tainted. In cases where the address is unknown the destination register is not tainted.

source

fn update_def_store( &self, state: &State, tid: &Tid, _address: &Expression, value: &Expression ) -> State

Returns the new taint state after a store to memory.

Default

Taints the destination memory if the value that is being stored is tainted. If the destination is unknown, all memory taint is removed from the state.

source

fn update_def_post( &self, _old_state: &State, new_state: State, def: &Term<Def> ) -> Option<State>

Returns the new taint state after processing a single Def term.

Receives both, the taint state before processing the Def and after processing it. Has a chance to overrule the default processing in special cases, usually when this Def is a sink.

Default

Just returns the proposed state.

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<'a> TaintAnalysis<'a> for Context<'a>