Struct cwe_checker_lib::analysis::string_abstraction::context::Context
source · pub struct Context<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> {
pub project: &'a Project,
pub pointer_inference_results: &'a PointerInference<'a>,
pub string_symbol_map: HashMap<Tid, &'a ExternSymbol>,
pub extern_symbol_map: HashMap<Tid, &'a ExternSymbol>,
pub format_string_index_map: HashMap<String, usize>,
pub block_start_node_map: HashMap<(Tid, Tid), NodeIndex>,
pub block_first_def_set: HashSet<(Tid, Tid)>,
pub jmp_to_blk_end_node_map: HashMap<(Tid, Tid), NodeIndex>,
/* private fields */
}
Expand description
Contains all context information needed for the string abstract fixpoint computation.
The struct also implements the interprocedural_fixpoint::Context
trait to enable the fixpoint computation.
Fields§
§project: &'a Project
A reference to the Project
object representing the binary
pointer_inference_results: &'a PointerInference<'a>
A pointer to the results of the pointer inference analysis. They are used to determine the targets of pointers to memory, which in turn is used to keep track of taint on the stack or on the heap.
string_symbol_map: HashMap<Tid, &'a ExternSymbol>
Maps the TIDs of functions that shall be treated as string extern symbols to the ExternSymbol
object representing it.
extern_symbol_map: HashMap<Tid, &'a ExternSymbol>
Maps the TIDs of functions that shall be treated as general extern symbols to the ExternSymbol
object representing it.
format_string_index_map: HashMap<String, usize>
Maps string symbols to their corresponding format string parameter index.
block_start_node_map: HashMap<(Tid, Tid), NodeIndex>
A map to get the node index of the BlkStart
node containing a given Def
as the first Def
of the block.
The keys are of the form (Def-TID, Current-Sub-TID)
to distinguish the nodes for blocks contained in more than one function.
block_first_def_set: HashSet<(Tid, Tid)>
A set containing a given Def
as the first Def
of the block.
The keys are of the form (Def-TID, Current-Sub-TID)
to distinguish the nodes for blocks contained in more than one function.
jmp_to_blk_end_node_map: HashMap<(Tid, Tid), NodeIndex>
A map to get the node index of the BlkEnd
node containing a given Jmp
.
The keys are of the form (Jmp-TID, Current-Sub-TID)
to distinguish the nodes for blocks contained in more than one function.
Implementations§
source§impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a, T>
impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a, T>
sourcepub fn handle_memcpy_calls(
&self,
state: &State<T>,
extern_symbol: &ExternSymbol
) -> State<T>
pub fn handle_memcpy_calls( &self, state: &State<T>, extern_symbol: &ExternSymbol ) -> State<T>
Handles the detection of string parameters to memcpy calls.
sourcepub fn has_return_target(
&self,
extern_symbol: &ExternSymbol,
pi_state: &PointerInferenceState
) -> Result<DataDomain<IntervalDomain>, Error>
pub fn has_return_target( &self, extern_symbol: &ExternSymbol, pi_state: &PointerInferenceState ) -> Result<DataDomain<IntervalDomain>, Error>
Checks whether the first input parameter contains a return target.
sourcepub fn has_input_target(
&self,
extern_symbol: &ExternSymbol,
pi_state: &PointerInferenceState
) -> Result<DataDomain<IntervalDomain>, Error>
pub fn has_input_target( &self, extern_symbol: &ExternSymbol, pi_state: &PointerInferenceState ) -> Result<DataDomain<IntervalDomain>, Error>
Checks whether the second input parameter contains a source target.
sourcepub fn process_domains_for_memcpy_calls(
&self,
state: &mut State<T>,
pi_state: &PointerInferenceState,
return_data: DataDomain<IntervalDomain>,
input_data: Option<DataDomain<IntervalDomain>>
)
pub fn process_domains_for_memcpy_calls( &self, state: &mut State<T>, pi_state: &PointerInferenceState, return_data: DataDomain<IntervalDomain>, input_data: Option<DataDomain<IntervalDomain>> )
Processes string domains in memcpy calls on a case by case basis.
-
Case 1: Both the destination pointer domain and the source pointer domain have multiple targets. In this case all targets of the destination pointer receive Top values as it is unclear which source target correspondence to which destination target due to path insentivity.
-
Case 2: Only the destination pointer domain has multiple targets. In this case it is checked whether a string domain is tracked at the corresponding source position. If so, a new map entry is created for the string domain at all destination targets. Otherwise, a Top value is created.
-
Case 3: Both pointer domains have unique targets. In this case a potential string domain is simply copied to the destination target.
Note that it is assumed that a memcpy input is always a string as it is part of the string.h C header file.
sourcepub fn process_domains_for_memcpy_calls_with_one_unique_input(
&self,
state: &mut State<T>,
pi_state: &PointerInferenceState,
input_target: &DataDomain<IntervalDomain>,
relative_return_targets: &BTreeMap<AbstractIdentifier, IntervalDomain>
)
pub fn process_domains_for_memcpy_calls_with_one_unique_input( &self, state: &mut State<T>, pi_state: &PointerInferenceState, input_target: &DataDomain<IntervalDomain>, relative_return_targets: &BTreeMap<AbstractIdentifier, IntervalDomain> )
Processes domains for memcpy calls where at least one of the parameters contains a unique target.
sourcepub fn get_constant_target(
&self,
input_target: &DataDomain<IntervalDomain>
) -> Option<T>
pub fn get_constant_target( &self, input_target: &DataDomain<IntervalDomain> ) -> Option<T>
Returns the content of a global memory target if there is some.
sourcepub fn has_multiple_targets(data: &DataDomain<IntervalDomain>) -> bool
pub fn has_multiple_targets(data: &DataDomain<IntervalDomain>) -> bool
Checks whether a data domain has multiple targets.
source§impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a, T>
impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a, T>
sourcepub fn handle_scanf_calls(
&self,
state: &State<T>,
extern_symbol: &ExternSymbol
) -> State<T>
pub fn handle_scanf_calls( &self, state: &State<T>, extern_symbol: &ExternSymbol ) -> State<T>
Handles the detection of string parameters to scanf calls. Adds new string abstract domains to the current state.
sourcepub fn create_abstract_domain_entries_for_function_return_values(
&self,
pi_state: &PointerInferenceState,
state: &mut State<T>,
arg_to_value_map: HashMap<Arg, Option<String>>
)
pub fn create_abstract_domain_entries_for_function_return_values( &self, pi_state: &PointerInferenceState, state: &mut State<T>, arg_to_value_map: HashMap<Arg, Option<String>> )
Creates string abstract domains for return values of (s)scanf calls.
sourcepub fn add_constant_or_top_value_to_return_locations(
state: &mut State<T>,
pi_state: &PointerInferenceState,
return_target: DataDomain<IntervalDomain>,
value: Option<String>
)
pub fn add_constant_or_top_value_to_return_locations( state: &mut State<T>, pi_state: &PointerInferenceState, return_target: DataDomain<IntervalDomain>, value: Option<String> )
Adds constant or Top value to return location given a pointer and a potential value.
sourcepub fn handle_sscanf_calls(
&self,
state: &State<T>,
extern_symbol: &ExternSymbol
) -> State<T>
pub fn handle_sscanf_calls( &self, state: &State<T>, extern_symbol: &ExternSymbol ) -> State<T>
Handles calls to sscanf. If the source string is known, it is split by spaces and for each substring a string abstract domain is generated at its corresponding location.
sourcepub fn source_string_mapped_to_return_locations(
&self,
pi_state: &PointerInferenceState,
state: &mut State<T>,
source_string: &DataDomain<IntervalDomain>,
extern_symbol: &ExternSymbol
) -> bool
pub fn source_string_mapped_to_return_locations( &self, pi_state: &PointerInferenceState, state: &mut State<T>, source_string: &DataDomain<IntervalDomain>, extern_symbol: &ExternSymbol ) -> bool
Maps the source string to the return locations of the call and returns an boolean which indicates whether the operation was successful.
sourcepub fn map_source_string_parameters_to_return_arguments(
&self,
pi_state: &PointerInferenceState,
extern_symbol: &ExternSymbol,
source_string: &str
) -> Result<HashMap<Arg, Option<String>>, Error>
pub fn map_source_string_parameters_to_return_arguments( &self, pi_state: &PointerInferenceState, extern_symbol: &ExternSymbol, source_string: &str ) -> Result<HashMap<Arg, Option<String>>, Error>
Maps source strings parameters to return arguments for sscanf calls.
source§impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a, T>
impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a, T>
sourcepub fn handle_sprintf_and_snprintf_calls(
&self,
state: &State<T>,
extern_symbol: &ExternSymbol
) -> State<T>
pub fn handle_sprintf_and_snprintf_calls( &self, state: &State<T>, extern_symbol: &ExternSymbol ) -> State<T>
Handles the detection of string parameters to sprintf and snprintf calls. Is able to identify a string constant parameter and to insert it into the format string. e.g. the format string is “cat %s” and the analysis detected that the input string is a constant in memory, for instance “bash.sh”. Then the abstract string domain is constructed with the string “cat bash.sh”.
sourcepub fn parse_format_string_and_add_new_string_domain(
&self,
state: &mut State<T>,
pi_state: &PointerInferenceState,
extern_symbol: &ExternSymbol,
format_string_index: usize,
return_pointer: &DataDomain<IntervalDomain>
)
pub fn parse_format_string_and_add_new_string_domain( &self, state: &mut State<T>, pi_state: &PointerInferenceState, extern_symbol: &ExternSymbol, format_string_index: usize, return_pointer: &DataDomain<IntervalDomain> )
Gets the input format string, parses the input parameters and adds the generated domain to the string maps.
sourcepub fn create_string_domain_for_sprintf_snprintf(
&self,
pi_state: &PointerInferenceState,
state: &State<T>,
extern_symbol: &ExternSymbol,
input_format_string: String
) -> T
pub fn create_string_domain_for_sprintf_snprintf( &self, pi_state: &PointerInferenceState, state: &State<T>, extern_symbol: &ExternSymbol, input_format_string: String ) -> T
Creates a string domain for a s(n)printf call by considering input constants and other domains.
sourcepub fn create_string_domain_using_data_type_approximations(
&self,
format_string: String
) -> T
pub fn create_string_domain_using_data_type_approximations( &self, format_string: String ) -> T
Creates a domain from a format string where all specifiers are approximated according to their data type. This ensures that, if there is a long data type, that the domain is no returned as Top.
sourcepub fn create_string_domain_using_constants_and_sub_domains(
&self,
format_string: String,
var_args: &[Arg],
pi_state: &PointerInferenceState,
state: &State<T>
) -> T
pub fn create_string_domain_using_constants_and_sub_domains( &self, format_string: String, var_args: &[Arg], pi_state: &PointerInferenceState, state: &State<T> ) -> T
Creates a string domain from found constants and sub domains.
sourcepub fn push_format_specifier_approximation(
domains: &mut Vec<T>,
specifier: Match<'_>
)
pub fn push_format_specifier_approximation( domains: &mut Vec<T>, specifier: Match<'_> )
Creates a string domain by approximating a format specifier and pushes it to the domain vector.
sourcepub fn push_constant_subsequences_before_and_between_specifiers(
domains: &mut Vec<T>,
format_string: &str,
specifier: Match<'_>,
last_specifier_end: usize,
index: usize
)
pub fn push_constant_subsequences_before_and_between_specifiers( domains: &mut Vec<T>, format_string: &str, specifier: Match<'_>, last_specifier_end: usize, index: usize )
Creates string domains from constant subsequences that either appear at the beginning of the format string or between specifiers.
sourcepub fn push_constant_suffix_if_available(
domains: &mut Vec<T>,
format_string: &str,
last_specifier_end: usize
)
pub fn push_constant_suffix_if_available( domains: &mut Vec<T>, format_string: &str, last_specifier_end: usize )
Pushes a potential constant suffix to the string domain vector.
sourcepub fn concat_domains(domains: &mut Vec<T>) -> T
pub fn concat_domains(domains: &mut Vec<T>) -> T
Takes a vector of string domains and concatenates them.
sourcepub fn no_specifiers(format_string: String) -> bool
pub fn no_specifiers(format_string: String) -> bool
Checks whether the string has no format specifiers.
sourcepub fn fetch_constant_and_domain_for_format_specifier(
&self,
arg: &Arg,
specifier: String,
pi_state: &PointerInferenceState,
state: &State<T>
) -> T
pub fn fetch_constant_and_domain_for_format_specifier( &self, arg: &Arg, specifier: String, pi_state: &PointerInferenceState, state: &State<T> ) -> T
Tries to fetch a constant or sub domain for the format specifier. If no data is available, it approximates the sub domain corresponding to the characters that can be contained in the data type.
sourcepub fn trim_format_specifier(specifier: String) -> String
pub fn trim_format_specifier(specifier: String) -> String
Removes the ‘%’ character and any size number from a format specifier.
sourcepub fn fetch_subdomains_if_available(
data: &DataDomain<IntervalDomain>,
state: &State<T>,
pi_state: &PointerInferenceState,
arg: &Arg,
constant_domain: Option<T>
) -> Option<T>
pub fn fetch_subdomains_if_available( data: &DataDomain<IntervalDomain>, state: &State<T>, pi_state: &PointerInferenceState, arg: &Arg, constant_domain: Option<T> ) -> Option<T>
Fetches subdomains if they are available for a pointer domain and merges a potential constant domain into the result.
sourcepub fn fetch_constant_domain_if_available(
&self,
data: &DataDomain<IntervalDomain>,
arg: &Arg
) -> Option<T>
pub fn fetch_constant_domain_if_available( &self, data: &DataDomain<IntervalDomain>, arg: &Arg ) -> Option<T>
Takes a data domain and tries to get a constant value.
source§impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a, T>
impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a, T>
sourcepub fn handle_strcat_and_strncat_calls(
&self,
state: &State<T>,
extern_symbol: &ExternSymbol
) -> State<T>
pub fn handle_strcat_and_strncat_calls( &self, state: &State<T>, extern_symbol: &ExternSymbol ) -> State<T>
Handles the resulting string domain from strcat and strncat calls. The symbol call returns the pointer to the destination string in its return register.
sourcepub fn process_second_input_domain(
&self,
state: &State<T>,
extern_symbol: &ExternSymbol,
pi_state: &PointerInferenceState
) -> T
pub fn process_second_input_domain( &self, state: &State<T>, extern_symbol: &ExternSymbol, pi_state: &PointerInferenceState ) -> T
Processes the contents of the second input parameter.
source§impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a, T>
impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a, T>
sourcepub fn handle_generic_symbol_calls(
&self,
extern_symbol: &ExternSymbol,
state: &State<T>
) -> State<T>
pub fn handle_generic_symbol_calls( &self, extern_symbol: &ExternSymbol, state: &State<T> ) -> State<T>
Handles generic symbol calls by deleting all non callee saved pointer entries.
sourcepub fn handle_unknown_symbol_calls(&self, state: &mut State<T>)
pub fn handle_unknown_symbol_calls(&self, state: &mut State<T>)
Handles calls to external symbols for which no ExternSymbol object is known.
sourcepub fn handle_string_symbol_calls(
&self,
extern_symbol: &ExternSymbol,
state: &State<T>
) -> State<T>
pub fn handle_string_symbol_calls( &self, extern_symbol: &ExternSymbol, state: &State<T> ) -> State<T>
The output of a string symbol is added to the map of abstract strings. If the symbol returns a format string, the string is approximated as good as possible by checking the input parameters.
sourcepub fn add_new_string_abstract_domain(
state: &mut State<T>,
pi_state: &PointerInferenceState,
pointer: &BTreeMap<AbstractIdentifier, IntervalDomain>,
domain_input_string: T
)
pub fn add_new_string_abstract_domain( state: &mut State<T>, pi_state: &PointerInferenceState, pointer: &BTreeMap<AbstractIdentifier, IntervalDomain>, domain_input_string: T )
Takes the pointer target if there is only one and checks whether the target is inside the current stack frame. If so, the string domain is added to the analysis.
sourcepub fn re_format_specifier() -> Regex
pub fn re_format_specifier() -> Regex
Regex that filters format specifier from a format string.
sourcepub fn merge_domains_from_multiple_pointer_targets(
state: &State<T>,
pi_state: &PointerInferenceState,
pointer: &BTreeMap<AbstractIdentifier, IntervalDomain>
) -> T
pub fn merge_domains_from_multiple_pointer_targets( state: &State<T>, pi_state: &PointerInferenceState, pointer: &BTreeMap<AbstractIdentifier, IntervalDomain> ) -> T
Merges domains from multiple pointer targets. The merged domain serves as input to a format string. If one of the targets does not contain a domain or the offset of a stack target cannot be parsed, a Top value is returned as no assumption can be made about the input.
sourcepub fn approximate_string_domain_from_datatype(specifier: String) -> T
pub fn approximate_string_domain_from_datatype(specifier: String) -> T
Calls the appropriate data type approximator.
sourcepub fn get_constant_integer_domain(constant: Bitvector) -> Option<T>
pub fn get_constant_integer_domain(constant: Bitvector) -> Option<T>
Inserts an integer constant into the format string.
sourcepub fn get_constant_char_domain(&self, constant: Bitvector) -> Option<T>
pub fn get_constant_char_domain(&self, constant: Bitvector) -> Option<T>
Inserts a char constant into the format string.
sourcepub fn parse_bitvec_to_char(char_code: Bitvector) -> Option<char>
pub fn parse_bitvec_to_char(char_code: Bitvector) -> Option<char>
Parses a bitvector to a char if possible.
sourcepub fn get_constant_string_domain(&self, constant: Bitvector) -> Option<T>
pub fn get_constant_string_domain(&self, constant: Bitvector) -> Option<T>
Inserts a string constant into the format string.
sourcepub fn handle_free(
&self,
state: &State<T>,
extern_symbol: &ExternSymbol
) -> State<T>
pub fn handle_free( &self, state: &State<T>, extern_symbol: &ExternSymbol ) -> State<T>
Deletes string entries in the heap to string map if the corresponding pointer is used to free memory space.
source§impl<'a, T: AbstractDomain + HasTop + Eq + From<String> + DomainInsertion> Context<'a, T>
impl<'a, T: AbstractDomain + HasTop + Eq + From<String> + DomainInsertion> Context<'a, T>
Trait Implementations§
source§impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a> for Context<'a, T>
impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Context<'a> for Context<'a, T>
source§fn merge(&self, state1: &Self::Value, state2: &Self::Value) -> State<T>
fn merge(&self, state1: &Self::Value, state2: &Self::Value) -> State<T>
Merge two state values.
§type Value = State<T>
type Value = State<T>
source§fn update_def(&self, state: &State<T>, def: &Term<Def>) -> Option<State<T>>
fn update_def(&self, state: &State<T>, def: &Term<Def>) -> Option<State<T>>
Def
terms.
The transition function for a basic block is computed
by iteratively applying this function to the starting value for each Def
term in the basic block.
The iteration short-circuits and returns None
if update_def
returns None
at any point.source§fn update_jump(
&self,
state: &State<T>,
_jump: &Term<Jmp>,
_untaken_conditional: Option<&Term<Jmp>>,
_target: &Term<Blk>
) -> Option<State<T>>
fn update_jump( &self, state: &State<T>, _jump: &Term<Jmp>, _untaken_conditional: Option<&Term<Jmp>>, _target: &Term<Blk> ) -> Option<State<T>>
Jmp
terms.