Unverified Commit 41f10fa1 by Enkelmann Committed by GitHub

prepare usage of FunctionSignature analysis in PointerInference (#277)

parent 7b6c6f4a
...@@ -10,7 +10,7 @@ use cwe_checker_lib::utils::{get_ghidra_plugin_path, read_config_file}; ...@@ -10,7 +10,7 @@ use cwe_checker_lib::utils::{get_ghidra_plugin_path, read_config_file};
use cwe_checker_lib::AnalysisResults; use cwe_checker_lib::AnalysisResults;
use cwe_checker_lib::{intermediate_representation::Project, utils::log::LogMessage}; use cwe_checker_lib::{intermediate_representation::Project, utils::log::LogMessage};
use nix::{sys::stat, unistd}; use nix::{sys::stat, unistd};
use std::collections::HashSet; use std::collections::{BTreeSet, HashSet};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use std::thread; use std::thread;
...@@ -176,8 +176,9 @@ fn run_with_ghidra(args: &CmdlineArgs) { ...@@ -176,8 +176,9 @@ fn run_with_ghidra(args: &CmdlineArgs) {
&project, &project,
); );
let modules_depending_on_string_abstraction = vec!["CWE78"]; let modules_depending_on_string_abstraction = BTreeSet::from_iter(["CWE78"]);
let modules_depending_on_pointer_inference = vec!["CWE134", "CWE476", "Memory"]; let modules_depending_on_pointer_inference =
BTreeSet::from_iter(["CWE134", "CWE476", "Memory"]);
let string_abstraction_needed = modules let string_abstraction_needed = modules
.iter() .iter()
...@@ -188,14 +189,23 @@ fn run_with_ghidra(args: &CmdlineArgs) { ...@@ -188,14 +189,23 @@ fn run_with_ghidra(args: &CmdlineArgs) {
.iter() .iter()
.any(|module| modules_depending_on_pointer_inference.contains(&module.name)); .any(|module| modules_depending_on_pointer_inference.contains(&module.name));
// Compute function signatures if required
let function_signatures = if pi_analysis_needed {
let (function_signatures, mut logs) = analysis_results.compute_function_signatures();
all_logs.append(&mut logs);
Some(function_signatures)
} else {
None
};
let analysis_results = analysis_results.with_function_signatures(function_signatures.as_ref());
// Compute pointer inference if required
let pi_analysis_results = if pi_analysis_needed { let pi_analysis_results = if pi_analysis_needed {
Some(analysis_results.compute_pointer_inference(&config["Memory"], args.statistics)) Some(analysis_results.compute_pointer_inference(&config["Memory"], args.statistics))
} else { } else {
None None
}; };
let analysis_results = analysis_results.with_pointer_inference(pi_analysis_results.as_ref());
let analysis_results = analysis_results.set_pointer_inference(pi_analysis_results.as_ref()); // Compute string abstraction analysis if required
let string_abstraction_results = let string_abstraction_results =
if string_abstraction_needed { if string_abstraction_needed {
Some(analysis_results.compute_string_abstraction( Some(analysis_results.compute_string_abstraction(
...@@ -205,18 +215,15 @@ fn run_with_ghidra(args: &CmdlineArgs) { ...@@ -205,18 +215,15 @@ fn run_with_ghidra(args: &CmdlineArgs) {
} else { } else {
None None
}; };
let analysis_results = let analysis_results =
analysis_results.set_string_abstraction(string_abstraction_results.as_ref()); analysis_results.with_string_abstraction(string_abstraction_results.as_ref());
// Print debug and then return. // Print debug and then return.
// Right now there is only one debug printing function. // Right now there is only one debug printing function.
// When more debug printing modes exist, this behaviour will change! // When more debug printing modes exist, this behaviour will change!
if args.debug { if args.debug {
cwe_checker_lib::analysis::pointer_inference::run( cwe_checker_lib::analysis::pointer_inference::run(
&project, &analysis_results,
&runtime_memory_image,
&control_flow_graph,
serde_json::from_value(config["Memory"].clone()).unwrap(), serde_json::from_value(config["Memory"].clone()).unwrap(),
true, true,
false, false,
......
...@@ -62,7 +62,9 @@ fn generate_fixpoint_computation<'a>( ...@@ -62,7 +62,9 @@ fn generate_fixpoint_computation<'a>(
NodeValue::Value(State::new( NodeValue::Value(State::new(
&sub.tid, &sub.tid,
&project.stack_pointer_register, &project.stack_pointer_register,
project.get_standard_calling_convention().unwrap(), project
.get_specific_calling_convention(&sub.term.calling_convention)
.unwrap(),
)), )),
) )
} }
...@@ -129,7 +131,7 @@ fn extract_fn_signatures_from_fixpoint<'a>( ...@@ -129,7 +131,7 @@ fn extract_fn_signatures_from_fixpoint<'a>(
pub fn compute_function_signatures<'a>( pub fn compute_function_signatures<'a>(
project: &'a Project, project: &'a Project,
graph: &'a Graph, graph: &'a Graph,
) -> (Vec<LogMessage>, BTreeMap<Tid, FunctionSignature>) { ) -> (BTreeMap<Tid, FunctionSignature>, Vec<LogMessage>) {
let mut computation = generate_fixpoint_computation(project, graph); let mut computation = generate_fixpoint_computation(project, graph);
computation.compute_with_max_steps(100); computation.compute_with_max_steps(100);
let mut fn_sig_map = extract_fn_signatures_from_fixpoint(project, graph, computation); let mut fn_sig_map = extract_fn_signatures_from_fixpoint(project, graph, computation);
...@@ -145,7 +147,7 @@ pub fn compute_function_signatures<'a>( ...@@ -145,7 +147,7 @@ pub fn compute_function_signatures<'a>(
} }
} }
(logs, fn_sig_map) (fn_sig_map, logs)
} }
/// The signature of a function. /// The signature of a function.
......
use super::object::ObjectType; use super::object::ObjectType;
use crate::analysis::function_signature::FunctionSignature;
use crate::analysis::graph::Graph; use crate::analysis::graph::Graph;
use crate::intermediate_representation::*; use crate::intermediate_representation::*;
use crate::prelude::*; use crate::prelude::*;
...@@ -27,6 +28,8 @@ pub struct Context<'a> { ...@@ -27,6 +28,8 @@ pub struct Context<'a> {
pub runtime_memory_image: &'a RuntimeMemoryImage, pub runtime_memory_image: &'a RuntimeMemoryImage,
/// Maps the TIDs of functions that shall be treated as extern symbols to the `ExternSymbol` object representing it. /// Maps the TIDs of functions that shall be treated as extern symbols to the `ExternSymbol` object representing it.
pub extern_symbol_map: &'a BTreeMap<Tid, ExternSymbol>, pub extern_symbol_map: &'a BTreeMap<Tid, ExternSymbol>,
/// Maps the TIDs of internal functions to the function signatures computed for it.
pub fn_signatures: &'a BTreeMap<Tid, FunctionSignature>,
/// A channel where found CWE warnings and log messages should be sent to. /// A channel where found CWE warnings and log messages should be sent to.
/// The receiver may filter or modify the warnings before presenting them to the user. /// The receiver may filter or modify the warnings before presenting them to the user.
/// For example, the same CWE warning will be found several times /// For example, the same CWE warning will be found several times
...@@ -43,17 +46,16 @@ impl<'a> Context<'a> { ...@@ -43,17 +46,16 @@ impl<'a> Context<'a> {
/// Create a new context object for a given project. /// Create a new context object for a given project.
/// Also needs two channels as input to know where CWE warnings and log messages should be sent to. /// Also needs two channels as input to know where CWE warnings and log messages should be sent to.
pub fn new( pub fn new(
project: &'a Project, analysis_results: &'a AnalysisResults<'a>,
runtime_memory_image: &'a RuntimeMemoryImage,
control_flow_graph: &'a Graph<'a>,
config: Config, config: Config,
log_collector: crossbeam_channel::Sender<LogThreadMsg>, log_collector: crossbeam_channel::Sender<LogThreadMsg>,
) -> Context<'a> { ) -> Context<'a> {
Context { Context {
graph: control_flow_graph, graph: analysis_results.control_flow_graph,
project, project: analysis_results.project,
runtime_memory_image, runtime_memory_image: analysis_results.runtime_memory_image,
extern_symbol_map: &project.program.term.extern_symbols, extern_symbol_map: &analysis_results.project.program.term.extern_symbols,
fn_signatures: analysis_results.function_signatures.unwrap(),
log_collector, log_collector,
allocation_symbols: config.allocation_symbols, allocation_symbols: config.allocation_symbols,
deallocation_symbols: config.deallocation_symbols, deallocation_symbols: config.deallocation_symbols,
......
use crate::intermediate_representation::DatatypeProperties;
use super::*; use super::*;
use std::{collections::HashSet, iter::FromIterator}; use crate::intermediate_representation::DatatypeProperties;
fn bv(value: i64) -> ValueDomain { fn bv(value: i64) -> ValueDomain {
ValueDomain::from(Bitvector::from_i64(value)) ValueDomain::from(Bitvector::from_i64(value))
...@@ -126,10 +124,9 @@ fn context_problem_implementation() { ...@@ -126,10 +124,9 @@ fn context_problem_implementation() {
use Expression::*; use Expression::*;
let (project, config) = mock_project(); let (project, config) = mock_project();
let runtime_memory_image = RuntimeMemoryImage::mock();
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let (log_sender, _log_receiver) = crossbeam_channel::unbounded(); let (log_sender, _log_receiver) = crossbeam_channel::unbounded();
let context = Context::new(&project, &runtime_memory_image, &graph, config, log_sender); let analysis_results = AnalysisResults::mock_from_project(&project);
let context = Context::new(&analysis_results, config, log_sender);
let mut state = State::new(&register("RSP"), Tid::new("main")); let mut state = State::new(&register("RSP"), Tid::new("main"));
let def = Term { let def = Term {
...@@ -287,10 +284,9 @@ fn update_return() { ...@@ -287,10 +284,9 @@ fn update_return() {
use crate::analysis::pointer_inference::object::ObjectType; use crate::analysis::pointer_inference::object::ObjectType;
use crate::analysis::pointer_inference::Data; use crate::analysis::pointer_inference::Data;
let (project, config) = mock_project(); let (project, config) = mock_project();
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let runtime_memory_image = RuntimeMemoryImage::mock();
let (log_sender, _log_receiver) = crossbeam_channel::unbounded(); let (log_sender, _log_receiver) = crossbeam_channel::unbounded();
let context = Context::new(&project, &runtime_memory_image, &graph, config, log_sender); let analysis_results = AnalysisResults::mock_from_project(&project);
let context = Context::new(&analysis_results, config, log_sender);
let state_before_return = State::new(&register("RSP"), Tid::new("callee")); let state_before_return = State::new(&register("RSP"), Tid::new("callee"));
let mut state_before_return = context let mut state_before_return = context
.update_def( .update_def(
...@@ -387,10 +383,9 @@ fn update_return() { ...@@ -387,10 +383,9 @@ fn update_return() {
fn specialize_conditional() { fn specialize_conditional() {
use crate::analysis::forward_interprocedural_fixpoint::Context as IpFpContext; use crate::analysis::forward_interprocedural_fixpoint::Context as IpFpContext;
let (project, config) = mock_project(); let (project, config) = mock_project();
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let runtime_memory_image = RuntimeMemoryImage::mock();
let (log_sender, _log_receiver) = crossbeam_channel::unbounded(); let (log_sender, _log_receiver) = crossbeam_channel::unbounded();
let context = Context::new(&project, &runtime_memory_image, &graph, config, log_sender); let analysis_results = AnalysisResults::mock_from_project(&project);
let context = Context::new(&analysis_results, config, log_sender);
let mut state = State::new(&register("RSP"), Tid::new("func")); let mut state = State::new(&register("RSP"), Tid::new("func"));
state.set_register(&register("RAX"), IntervalDomain::mock(-10, 20).into()); state.set_register(&register("RAX"), IntervalDomain::mock(-10, 20).into());
......
...@@ -29,14 +29,11 @@ ...@@ -29,14 +29,11 @@
use super::fixpoint::Computation; use super::fixpoint::Computation;
use super::forward_interprocedural_fixpoint::GeneralizedContext; use super::forward_interprocedural_fixpoint::GeneralizedContext;
use super::interprocedural_fixpoint_generic::NodeValue; use super::interprocedural_fixpoint_generic::NodeValue;
use crate::abstract_domain::{DataDomain, IntervalDomain};
use crate::analysis::graph::{Graph, Node}; use crate::analysis::graph::{Graph, Node};
use crate::intermediate_representation::*; use crate::intermediate_representation::*;
use crate::prelude::*; use crate::prelude::*;
use crate::utils::log::*; use crate::utils::log::*;
use crate::{
abstract_domain::{DataDomain, IntervalDomain},
utils::binary::RuntimeMemoryImage,
};
use petgraph::graph::NodeIndex; use petgraph::graph::NodeIndex;
use petgraph::visit::IntoNodeReferences; use petgraph::visit::IntoNodeReferences;
use petgraph::Direction; use petgraph::Direction;
...@@ -91,20 +88,13 @@ pub struct PointerInference<'a> { ...@@ -91,20 +88,13 @@ pub struct PointerInference<'a> {
impl<'a> PointerInference<'a> { impl<'a> PointerInference<'a> {
/// Generate a new pointer inference compuation for a project. /// Generate a new pointer inference compuation for a project.
pub fn new( pub fn new(
project: &'a Project, analysis_results: &'a AnalysisResults<'a>,
runtime_memory_image: &'a RuntimeMemoryImage,
control_flow_graph: &'a Graph<'a>,
config: Config, config: Config,
log_sender: crossbeam_channel::Sender<LogThreadMsg>, log_sender: crossbeam_channel::Sender<LogThreadMsg>,
print_stats: bool, print_stats: bool,
) -> PointerInference<'a> { ) -> PointerInference<'a> {
let context = Context::new( let context = Context::new(analysis_results, config, log_sender.clone());
project, let project = analysis_results.project;
runtime_memory_image,
control_flow_graph,
config,
log_sender.clone(),
);
let mut entry_sub_to_entry_blocks_map = HashMap::new(); let mut entry_sub_to_entry_blocks_map = HashMap::new();
for sub_tid in project.program.term.entry_points.iter() { for sub_tid in project.program.term.entry_points.iter() {
...@@ -466,9 +456,7 @@ pub fn extract_pi_analysis_results( ...@@ -466,9 +456,7 @@ pub fn extract_pi_analysis_results(
/// If `print_debug` is set to `true` print debug information to *stdout*. /// If `print_debug` is set to `true` print debug information to *stdout*.
/// Note that the format of the debug information is currently unstable and subject to change. /// Note that the format of the debug information is currently unstable and subject to change.
pub fn run<'a>( pub fn run<'a>(
project: &'a Project, analysis_results: &'a AnalysisResults<'a>,
runtime_memory_image: &'a RuntimeMemoryImage,
control_flow_graph: &'a Graph<'a>,
config: Config, config: Config,
print_debug: bool, print_debug: bool,
print_stats: bool, print_stats: bool,
...@@ -476,15 +464,13 @@ pub fn run<'a>( ...@@ -476,15 +464,13 @@ pub fn run<'a>(
let logging_thread = LogThread::spawn(collect_all_logs); let logging_thread = LogThread::spawn(collect_all_logs);
let mut computation = PointerInference::new( let mut computation = PointerInference::new(
project, analysis_results,
runtime_memory_image,
control_flow_graph,
config, config,
logging_thread.get_msg_sender(), logging_thread.get_msg_sender(),
print_stats, print_stats,
); );
computation.compute_with_speculative_entry_points(project, print_stats); computation.compute_with_speculative_entry_points(analysis_results.project, print_stats);
if print_debug { if print_debug {
computation.print_compact_json(); computation.print_compact_json();
...@@ -541,17 +527,15 @@ mod tests { ...@@ -541,17 +527,15 @@ mod tests {
use super::*; use super::*;
impl<'a> PointerInference<'a> { impl<'a> PointerInference<'a> {
pub fn mock( pub fn mock(project: &'a Project) -> PointerInference<'a> {
project: &'a Project, let analysis_results = Box::new(AnalysisResults::mock_from_project(project));
mem_image: &'a RuntimeMemoryImage, let analysis_results: &'a AnalysisResults = Box::leak(analysis_results);
graph: &'a Graph,
) -> PointerInference<'a> {
let config = Config { let config = Config {
allocation_symbols: vec!["malloc".to_string()], allocation_symbols: vec!["malloc".to_string()],
deallocation_symbols: vec!["free".to_string()], deallocation_symbols: vec!["free".to_string()],
}; };
let (log_sender, _) = crossbeam_channel::unbounded(); let (log_sender, _) = crossbeam_channel::unbounded();
PointerInference::new(project, mem_image, graph, config, log_sender, false) PointerInference::new(analysis_results, config, log_sender, false)
} }
pub fn set_node_value(&mut self, node_value: State, node_index: NodeIndex) { pub fn set_node_value(&mut self, node_value: State, node_index: NodeIndex) {
......
...@@ -197,9 +197,6 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte ...@@ -197,9 +197,6 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::{BTreeMap, BTreeSet, HashSet};
use crate::{ use crate::{
abstract_domain::{ abstract_domain::{
AbstractIdentifier, AbstractLocation, CharacterInclusionDomain, CharacterSet, AbstractIdentifier, AbstractLocation, CharacterInclusionDomain, CharacterSet,
...@@ -210,8 +207,8 @@ mod tests { ...@@ -210,8 +207,8 @@ mod tests {
tests::mock_project_with_intraprocedural_control_flow, tests::mock_project_with_intraprocedural_control_flow,
}, },
intermediate_representation::{Bitvector, Tid, Variable}, intermediate_representation::{Bitvector, Tid, Variable},
utils::binary::RuntimeMemoryImage,
}; };
use std::collections::{BTreeMap, BTreeSet};
use super::*; use super::*;
...@@ -222,9 +219,7 @@ mod tests { ...@@ -222,9 +219,7 @@ mod tests {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -287,9 +282,7 @@ mod tests { ...@@ -287,9 +282,7 @@ mod tests {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -314,9 +307,7 @@ mod tests { ...@@ -314,9 +307,7 @@ mod tests {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -344,9 +335,7 @@ mod tests { ...@@ -344,9 +335,7 @@ mod tests {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -369,9 +358,7 @@ mod tests { ...@@ -369,9 +358,7 @@ mod tests {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -413,9 +400,7 @@ mod tests { ...@@ -413,9 +400,7 @@ mod tests {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -461,9 +446,7 @@ mod tests { ...@@ -461,9 +446,7 @@ mod tests {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
......
...@@ -191,17 +191,12 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte ...@@ -191,17 +191,12 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::super::tests::*;
use std::collections::HashSet; use super::*;
use crate::abstract_domain::{AbstractIdentifier, AbstractLocation, CharacterInclusionDomain}; use crate::abstract_domain::{AbstractIdentifier, AbstractLocation, CharacterInclusionDomain};
use crate::analysis::pointer_inference::PointerInference as PointerInferenceComputation; use crate::analysis::pointer_inference::PointerInference as PointerInferenceComputation;
use crate::analysis::string_abstraction::tests::mock_project_with_intraprocedural_control_flow; use crate::analysis::string_abstraction::tests::mock_project_with_intraprocedural_control_flow;
use crate::intermediate_representation::{Expression, Variable}; use crate::intermediate_representation::{Expression, Variable};
use crate::utils::binary::RuntimeMemoryImage;
use super::super::tests::*;
use super::*;
#[test] #[test]
fn test_handle_scanf_calls() { fn test_handle_scanf_calls() {
...@@ -211,9 +206,7 @@ mod tests { ...@@ -211,9 +206,7 @@ mod tests {
vec![(scanf_symbol.clone(), vec![true])], vec![(scanf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -296,9 +289,7 @@ mod tests { ...@@ -296,9 +289,7 @@ mod tests {
vec![(sscanf_symbol.clone(), vec![true, true])], vec![(sscanf_symbol.clone(), vec![true, true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -374,9 +365,7 @@ mod tests { ...@@ -374,9 +365,7 @@ mod tests {
vec![(scanf_symbol.clone(), vec![false])], vec![(scanf_symbol.clone(), vec![false])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -449,9 +438,7 @@ mod tests { ...@@ -449,9 +438,7 @@ mod tests {
vec![(sscanf_symbol.clone(), vec![false, false])], vec![(sscanf_symbol.clone(), vec![false, false])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -493,9 +480,7 @@ mod tests { ...@@ -493,9 +480,7 @@ mod tests {
vec![(sscanf_symbol.clone(), vec![false, false])], vec![(sscanf_symbol.clone(), vec![false, false])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -516,9 +501,7 @@ mod tests { ...@@ -516,9 +501,7 @@ mod tests {
vec![(sscanf_symbol.clone(), vec![true, false])], vec![(sscanf_symbol.clone(), vec![true, false])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -539,9 +522,7 @@ mod tests { ...@@ -539,9 +522,7 @@ mod tests {
vec![(sscanf_symbol.clone(), vec![false, true])], vec![(sscanf_symbol.clone(), vec![false, true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -594,9 +575,7 @@ mod tests { ...@@ -594,9 +575,7 @@ mod tests {
vec![(sscanf_symbol.clone(), vec![true, true])], vec![(sscanf_symbol.clone(), vec![true, true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -678,9 +657,7 @@ mod tests { ...@@ -678,9 +657,7 @@ mod tests {
vec![(sscanf_symbol.clone(), vec![true, true])], vec![(sscanf_symbol.clone(), vec![true, true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -738,9 +715,7 @@ mod tests { ...@@ -738,9 +715,7 @@ mod tests {
vec![(sscanf_symbol.clone(), vec![true, true])], vec![(sscanf_symbol.clone(), vec![true, true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
......
use std::collections::{BTreeSet, HashSet}; use std::collections::BTreeSet;
use super::*; use super::*;
use crate::abstract_domain::{AbstractIdentifier, AbstractLocation}; use crate::abstract_domain::{AbstractIdentifier, AbstractLocation};
...@@ -9,7 +9,6 @@ use crate::{ ...@@ -9,7 +9,6 @@ use crate::{
analysis::string_abstraction::{ analysis::string_abstraction::{
context::symbol_calls::tests::Setup, tests::mock_project_with_intraprocedural_control_flow, context::symbol_calls::tests::Setup, tests::mock_project_with_intraprocedural_control_flow,
}, },
utils::binary::RuntimeMemoryImage,
}; };
#[test] #[test]
...@@ -19,9 +18,7 @@ fn test_handle_sprintf_and_snprintf_calls() { ...@@ -19,9 +18,7 @@ fn test_handle_sprintf_and_snprintf_calls() {
vec![(sprintf_symbol.clone(), vec![true])], vec![(sprintf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -80,9 +77,7 @@ fn test_parse_format_string_and_add_new_string_domain() { ...@@ -80,9 +77,7 @@ fn test_parse_format_string_and_add_new_string_domain() {
vec![(sprintf_symbol.clone(), vec![true])], vec![(sprintf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -122,9 +117,7 @@ fn test_create_string_domain_for_sprintf_snprintf() { ...@@ -122,9 +117,7 @@ fn test_create_string_domain_for_sprintf_snprintf() {
vec![(sprintf_symbol.clone(), vec![true])], vec![(sprintf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -157,9 +150,7 @@ fn test_create_string_domain_using_data_type_approximations() { ...@@ -157,9 +150,7 @@ fn test_create_string_domain_using_data_type_approximations() {
vec![(sprintf_symbol.clone(), vec![true])], vec![(sprintf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -202,9 +193,7 @@ fn test_create_string_domain_using_constants_and_sub_domains() { ...@@ -202,9 +193,7 @@ fn test_create_string_domain_using_constants_and_sub_domains() {
vec![(sprintf_symbol.clone(), vec![true])], vec![(sprintf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -368,9 +357,7 @@ fn test_fetch_constant_and_domain_for_format_specifier() { ...@@ -368,9 +357,7 @@ fn test_fetch_constant_and_domain_for_format_specifier() {
vec![(sprintf_symbol.clone(), vec![true])], vec![(sprintf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -551,9 +538,7 @@ fn test_fetch_subdomains_if_available() { ...@@ -551,9 +538,7 @@ fn test_fetch_subdomains_if_available() {
vec![(sprintf_symbol.clone(), vec![true])], vec![(sprintf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -611,9 +596,7 @@ fn test_fetch_constant_domain_if_available() { ...@@ -611,9 +596,7 @@ fn test_fetch_constant_domain_if_available() {
vec![(sprintf_symbol.clone(), vec![true])], vec![(sprintf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
......
...@@ -99,8 +99,6 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte ...@@ -99,8 +99,6 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::HashSet;
use crate::{ use crate::{
abstract_domain::{CharacterInclusionDomain, CharacterSet, IntervalDomain}, abstract_domain::{CharacterInclusionDomain, CharacterSet, IntervalDomain},
analysis::pointer_inference::PointerInference as PointerInferenceComputation, analysis::pointer_inference::PointerInference as PointerInferenceComputation,
...@@ -109,7 +107,6 @@ mod tests { ...@@ -109,7 +107,6 @@ mod tests {
tests::mock_project_with_intraprocedural_control_flow, tests::mock_project_with_intraprocedural_control_flow,
}, },
intermediate_representation::{ByteSize, Variable}, intermediate_representation::{ByteSize, Variable},
utils::binary::RuntimeMemoryImage,
}; };
use super::*; use super::*;
...@@ -121,9 +118,7 @@ mod tests { ...@@ -121,9 +118,7 @@ mod tests {
vec![(strcat_symbol.clone(), vec![true])], vec![(strcat_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -157,9 +152,7 @@ mod tests { ...@@ -157,9 +152,7 @@ mod tests {
vec![(strcat_symbol.clone(), vec![false])], vec![(strcat_symbol.clone(), vec![false])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -210,9 +203,7 @@ mod tests { ...@@ -210,9 +203,7 @@ mod tests {
vec![(strcat_symbol.clone(), vec![true])], vec![(strcat_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -234,9 +225,7 @@ mod tests { ...@@ -234,9 +225,7 @@ mod tests {
vec![(strcat_symbol.clone(), vec![false])], vec![(strcat_symbol.clone(), vec![false])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -263,9 +252,7 @@ mod tests { ...@@ -263,9 +252,7 @@ mod tests {
vec![(strcat_symbol.clone(), vec![false])], vec![(strcat_symbol.clone(), vec![false])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
......
use std::collections::{HashMap, HashSet}; use std::collections::HashMap;
use std::fmt::Debug; use std::fmt::Debug;
use petgraph::graph::NodeIndex; use petgraph::graph::NodeIndex;
...@@ -17,7 +17,7 @@ use crate::intermediate_representation::{Bitvector, ExternSymbol, Project, Sub}; ...@@ -17,7 +17,7 @@ use crate::intermediate_representation::{Bitvector, ExternSymbol, Project, Sub};
use crate::{ use crate::{
abstract_domain::{AbstractIdentifier, AbstractLocation}, abstract_domain::{AbstractIdentifier, AbstractLocation},
intermediate_representation::{Tid, Variable}, intermediate_representation::{Tid, Variable},
utils::{binary::RuntimeMemoryImage, symbol_utils::get_symbol_map}, utils::symbol_utils::get_symbol_map,
}; };
pub struct Setup<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String> + Debug> { pub struct Setup<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String> + Debug> {
...@@ -114,9 +114,7 @@ fn test_handle_generic_symbol_calls() { ...@@ -114,9 +114,7 @@ fn test_handle_generic_symbol_calls() {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -140,9 +138,7 @@ fn test_handle_unknown_symbol_calls() { ...@@ -140,9 +138,7 @@ fn test_handle_unknown_symbol_calls() {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -170,9 +166,7 @@ fn test_add_new_string_abstract_domain() { ...@@ -170,9 +166,7 @@ fn test_add_new_string_abstract_domain() {
vec![(sprintf_symbol.clone(), vec![true])], vec![(sprintf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -227,9 +221,7 @@ fn test_merge_domains_from_multiple_pointer_targets() { ...@@ -227,9 +221,7 @@ fn test_merge_domains_from_multiple_pointer_targets() {
vec![(sprintf_symbol.clone(), vec![true])], vec![(sprintf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -311,9 +303,7 @@ fn test_handle_sprintf_and_snprintf_calls_known_format_string() { ...@@ -311,9 +303,7 @@ fn test_handle_sprintf_and_snprintf_calls_known_format_string() {
vec![(sprintf_symbol.clone(), vec![true])], vec![(sprintf_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -348,9 +338,7 @@ fn test_handle_sprintf_and_snprintf_calls_unknown_format_string() { ...@@ -348,9 +338,7 @@ fn test_handle_sprintf_and_snprintf_calls_unknown_format_string() {
vec![(sprintf_symbol.clone(), vec![false])], vec![(sprintf_symbol.clone(), vec![false])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -385,9 +373,7 @@ fn test_insert_constant_char_into_format_string() { ...@@ -385,9 +373,7 @@ fn test_insert_constant_char_into_format_string() {
vec![(ExternSymbol::mock_sprintf_symbol_arm(), vec![false])], vec![(ExternSymbol::mock_sprintf_symbol_arm(), vec![false])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -419,9 +405,7 @@ fn test_insert_constant_string_into_format_string() { ...@@ -419,9 +405,7 @@ fn test_insert_constant_string_into_format_string() {
vec![(ExternSymbol::mock_sprintf_symbol_arm(), vec![false])], vec![(ExternSymbol::mock_sprintf_symbol_arm(), vec![false])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -450,12 +434,7 @@ fn test_handle_free() { ...@@ -450,12 +434,7 @@ fn test_handle_free() {
"func", "func",
); );
let extern_subs: HashSet<Tid> = vec![malloc_symbol.tid, free_symbol.clone().tid] let mut pi_results = PointerInferenceComputation::mock(&project);
.into_iter()
.collect();
let mem_image = RuntimeMemoryImage::mock();
let graph = crate::analysis::graph::get_program_cfg(&project.program, extern_subs);
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
......
...@@ -24,8 +24,7 @@ fn test_update_def() { ...@@ -24,8 +24,7 @@ fn test_update_def() {
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mem_image = RuntimeMemoryImage::mock();
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new()); let mut pi_results = PointerInferenceComputation::mock(&project);
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -138,9 +137,7 @@ fn test_update_jump() { ...@@ -138,9 +137,7 @@ fn test_update_jump() {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -165,9 +162,7 @@ fn test_update_return() { ...@@ -165,9 +162,7 @@ fn test_update_return() {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let mut setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
...@@ -223,9 +218,7 @@ fn test_update_call_stub() { ...@@ -223,9 +218,7 @@ fn test_update_call_stub() {
vec![(memcpy_symbol.clone(), vec![true])], vec![(memcpy_symbol.clone(), vec![true])],
"func", "func",
); );
let mem_image = RuntimeMemoryImage::mock(); let mut pi_results = PointerInferenceComputation::mock(&project);
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = PointerInferenceComputation::mock(&project, &mem_image, &graph);
pi_results.compute(); pi_results.compute();
let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results); let setup: Setup<CharacterInclusionDomain> = Setup::new(&pi_results);
......
...@@ -470,7 +470,7 @@ impl ExternSymbol { ...@@ -470,7 +470,7 @@ impl ExternSymbol {
calling_convention: Some("__stdcall".to_string()), calling_convention: Some("__stdcall".to_string()),
parameters: vec![Arg::mock_register("r0", 4)], parameters: vec![Arg::mock_register("r0", 4)],
return_values: vec![], return_values: vec![],
no_return: true, no_return: false,
has_var_args: false, has_var_args: false,
} }
} }
......
...@@ -209,6 +209,9 @@ pub mod tests { ...@@ -209,6 +209,9 @@ pub mod tests {
sub.term.blocks.push(block2); sub.term.blocks.push(block2);
project.program.term.subs.insert(sub.tid.clone(), sub); project.program.term.subs.insert(sub.tid.clone(), sub);
project.program.term.entry_points.insert(Tid::new("func")); project.program.term.entry_points.insert(Tid::new("func"));
project
.calling_conventions
.insert("__stdcall".to_string(), CallingConvention::mock());
project project
} }
...@@ -219,8 +222,7 @@ pub mod tests { ...@@ -219,8 +222,7 @@ pub mod tests {
let runtime_memory_image = RuntimeMemoryImage::mock(); let runtime_memory_image = RuntimeMemoryImage::mock();
let project = mock_project(); let project = mock_project();
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new()); let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new());
let mut pi_results = let mut pi_results = PointerInferenceComputation::mock(&project);
PointerInferenceComputation::mock(&project, &runtime_memory_image, &graph);
pi_results.compute(); pi_results.compute();
let mut format_string_index: HashMap<String, usize> = HashMap::new(); let mut format_string_index: HashMap<String, usize> = HashMap::new();
format_string_index.insert("sprintf".to_string(), 1); format_string_index.insert("sprintf".to_string(), 1);
......
...@@ -418,7 +418,6 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont ...@@ -418,7 +418,6 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
mod tests { mod tests {
use super::*; use super::*;
use crate::utils::binary::RuntimeMemoryImage; use crate::utils::binary::RuntimeMemoryImage;
use std::collections::HashSet;
impl<'a> Context<'a> { impl<'a> Context<'a> {
pub fn mock( pub fn mock(
...@@ -447,8 +446,7 @@ mod tests { ...@@ -447,8 +446,7 @@ mod tests {
fn check_parameter_arg_for_taint() { fn check_parameter_arg_for_taint() {
let project = Project::mock_empty(); let project = Project::mock_empty();
let runtime_memory_image = RuntimeMemoryImage::mock(); let runtime_memory_image = RuntimeMemoryImage::mock();
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new()); let pi_results = PointerInferenceComputation::mock(&project);
let pi_results = PointerInferenceComputation::mock(&project, &runtime_memory_image, &graph);
let context = Context::mock(&project, &runtime_memory_image, &pi_results); let context = Context::mock(&project, &runtime_memory_image, &pi_results);
let (mut state, _pi_state) = State::mock_with_pi_state(); let (mut state, _pi_state) = State::mock_with_pi_state();
...@@ -479,8 +477,7 @@ mod tests { ...@@ -479,8 +477,7 @@ mod tests {
fn handle_generic_call() { fn handle_generic_call() {
let project = Project::mock_empty(); let project = Project::mock_empty();
let runtime_memory_image = RuntimeMemoryImage::mock(); let runtime_memory_image = RuntimeMemoryImage::mock();
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new()); let pi_results = PointerInferenceComputation::mock(&project);
let pi_results = PointerInferenceComputation::mock(&project, &runtime_memory_image, &graph);
let context = Context::mock(&project, &runtime_memory_image, &pi_results); let context = Context::mock(&project, &runtime_memory_image, &pi_results);
let mut state = State::mock(); let mut state = State::mock();
...@@ -501,8 +498,7 @@ mod tests { ...@@ -501,8 +498,7 @@ mod tests {
fn update_def() { fn update_def() {
let project = Project::mock_empty(); let project = Project::mock_empty();
let runtime_memory_image = RuntimeMemoryImage::mock(); let runtime_memory_image = RuntimeMemoryImage::mock();
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new()); let pi_results = PointerInferenceComputation::mock(&project);
let pi_results = PointerInferenceComputation::mock(&project, &runtime_memory_image, &graph);
let context = Context::mock(&project, &runtime_memory_image, &pi_results); let context = Context::mock(&project, &runtime_memory_image, &pi_results);
let (mut state, pi_state) = State::mock_with_pi_state(); let (mut state, pi_state) = State::mock_with_pi_state();
state.set_pointer_inference_state(Some(pi_state)); state.set_pointer_inference_state(Some(pi_state));
...@@ -555,8 +551,7 @@ mod tests { ...@@ -555,8 +551,7 @@ mod tests {
fn update_jump() { fn update_jump() {
let project = Project::mock_empty(); let project = Project::mock_empty();
let runtime_memory_image = RuntimeMemoryImage::mock(); let runtime_memory_image = RuntimeMemoryImage::mock();
let graph = crate::analysis::graph::get_program_cfg(&project.program, HashSet::new()); let pi_results = PointerInferenceComputation::mock(&project);
let pi_results = PointerInferenceComputation::mock(&project, &runtime_memory_image, &graph);
let context = Context::mock(&project, &runtime_memory_image, &pi_results); let context = Context::mock(&project, &runtime_memory_image, &pi_results);
let (state, _pi_state) = State::mock_with_pi_state(); let (state, _pi_state) = State::mock_with_pi_state();
......
...@@ -60,14 +60,7 @@ You can find out more information about each check, including known false positi ...@@ -60,14 +60,7 @@ You can find out more information about each check, including known false positi
by reading the check-specific module documentation in the [`checkers`] module. by reading the check-specific module documentation in the [`checkers`] module.
*/ */
use abstract_domain::BricksDomain; use std::collections::BTreeMap;
use crate::analysis::graph::Graph;
use crate::analysis::pointer_inference::PointerInference;
use crate::analysis::string_abstraction::StringAbstraction;
use crate::intermediate_representation::Project;
use crate::utils::binary::RuntimeMemoryImage;
use crate::utils::log::{CweWarning, LogMessage};
pub mod abstract_domain; pub mod abstract_domain;
pub mod analysis; pub mod analysis;
...@@ -76,6 +69,15 @@ pub mod intermediate_representation; ...@@ -76,6 +69,15 @@ pub mod intermediate_representation;
pub mod pcode; pub mod pcode;
pub mod utils; pub mod utils;
use abstract_domain::BricksDomain;
use analysis::function_signature::FunctionSignature;
use analysis::graph::Graph;
use analysis::pointer_inference::PointerInference;
use analysis::string_abstraction::StringAbstraction;
use intermediate_representation::Project;
use utils::binary::RuntimeMemoryImage;
use utils::log::{CweWarning, LogMessage};
mod prelude { mod prelude {
pub use apint::Width; pub use apint::Width;
pub use serde::{Deserialize, Serialize}; pub use serde::{Deserialize, Serialize};
...@@ -85,6 +87,7 @@ mod prelude { ...@@ -85,6 +87,7 @@ mod prelude {
pub use crate::AnalysisResults; pub use crate::AnalysisResults;
pub use anyhow::{anyhow, Error}; pub use anyhow::{anyhow, Error};
} }
use prelude::*;
/// The generic function signature for the main function of a CWE module /// The generic function signature for the main function of a CWE module
pub type CweModuleFn = pub type CweModuleFn =
...@@ -141,6 +144,8 @@ pub struct AnalysisResults<'a> { ...@@ -141,6 +144,8 @@ pub struct AnalysisResults<'a> {
pub control_flow_graph: &'a Graph<'a>, pub control_flow_graph: &'a Graph<'a>,
/// A pointer to the project struct /// A pointer to the project struct
pub project: &'a Project, pub project: &'a Project,
/// The results of the function signature analysis if already computed.
pub function_signatures: Option<&'a BTreeMap<Tid, FunctionSignature>>,
/// The result of the pointer inference analysis if already computed. /// The result of the pointer inference analysis if already computed.
pub pointer_inference: Option<&'a PointerInference<'a>>, pub pointer_inference: Option<&'a PointerInference<'a>>,
/// The result of the string abstraction if already computed. /// The result of the string abstraction if already computed.
...@@ -160,11 +165,33 @@ impl<'a> AnalysisResults<'a> { ...@@ -160,11 +165,33 @@ impl<'a> AnalysisResults<'a> {
runtime_memory_image, runtime_memory_image,
control_flow_graph, control_flow_graph,
project, project,
function_signatures: None,
pointer_inference: None, pointer_inference: None,
string_abstraction: None, string_abstraction: None,
} }
} }
/// Compute the function signatures for internal functions.
pub fn compute_function_signatures(
&self,
) -> (BTreeMap<Tid, FunctionSignature>, Vec<LogMessage>) {
analysis::function_signature::compute_function_signatures(
self.project,
self.control_flow_graph,
)
}
/// Create a new `AnalysisResults` struct containing the given function signature analysis results.
pub fn with_function_signatures(
self,
function_signatures: Option<&'a BTreeMap<Tid, FunctionSignature>>,
) -> AnalysisResults<'a> {
AnalysisResults {
function_signatures,
..self
}
}
/// Compute the pointer inference analysis. /// Compute the pointer inference analysis.
/// The result gets returned, but not saved to the `AnalysisResults` struct itself. /// The result gets returned, but not saved to the `AnalysisResults` struct itself.
pub fn compute_pointer_inference( pub fn compute_pointer_inference(
...@@ -173,9 +200,7 @@ impl<'a> AnalysisResults<'a> { ...@@ -173,9 +200,7 @@ impl<'a> AnalysisResults<'a> {
print_stats: bool, print_stats: bool,
) -> PointerInference<'a> { ) -> PointerInference<'a> {
crate::analysis::pointer_inference::run( crate::analysis::pointer_inference::run(
self.project, self,
self.runtime_memory_image,
self.control_flow_graph,
serde_json::from_value(config.clone()).unwrap(), serde_json::from_value(config.clone()).unwrap(),
false, false,
print_stats, print_stats,
...@@ -183,7 +208,7 @@ impl<'a> AnalysisResults<'a> { ...@@ -183,7 +208,7 @@ impl<'a> AnalysisResults<'a> {
} }
/// Create a new `AnalysisResults` struct containing the given pointer inference analysis results. /// Create a new `AnalysisResults` struct containing the given pointer inference analysis results.
pub fn set_pointer_inference<'b: 'a>( pub fn with_pointer_inference<'b: 'a>(
self, self,
pi_results: Option<&'b PointerInference<'a>>, pi_results: Option<&'b PointerInference<'a>>,
) -> AnalysisResults<'b> { ) -> AnalysisResults<'b> {
...@@ -212,7 +237,7 @@ impl<'a> AnalysisResults<'a> { ...@@ -212,7 +237,7 @@ impl<'a> AnalysisResults<'a> {
} }
/// Create a new `AnalysisResults` struct containing the given string abstraction results. /// Create a new `AnalysisResults` struct containing the given string abstraction results.
pub fn set_string_abstraction<'b: 'a>( pub fn with_string_abstraction<'b: 'a>(
self, self,
string_abstraction: Option<&'b StringAbstraction<'a, BricksDomain>>, string_abstraction: Option<&'b StringAbstraction<'a, BricksDomain>>,
) -> AnalysisResults<'b> { ) -> AnalysisResults<'b> {
...@@ -222,3 +247,30 @@ impl<'a> AnalysisResults<'a> { ...@@ -222,3 +247,30 @@ impl<'a> AnalysisResults<'a> {
} }
} }
} }
#[cfg(test)]
mod tests {
use super::*;
use crate::analysis::graph::get_program_cfg;
use std::collections::HashSet;
impl<'a> AnalysisResults<'a> {
/// Mocks the `AnalysisResults` struct with a given project.
/// Note that the function leaks memory!
pub fn mock_from_project(project: &'a Project) -> AnalysisResults<'a> {
let extern_subs =
HashSet::from_iter(project.program.term.extern_symbols.keys().cloned());
let graph = Box::new(get_program_cfg(&project.program, extern_subs));
let graph: &'a Graph = Box::leak(graph);
let runtime_mem_image = Box::new(RuntimeMemoryImage::mock());
let runtime_mem_image: &'a RuntimeMemoryImage = Box::leak(runtime_mem_image);
let binary: &'a Vec<u8> = Box::leak(Box::new(Vec::new()));
let analysis_results = AnalysisResults::new(binary, runtime_mem_image, graph, project);
let (fn_sigs, _) = analysis_results.compute_function_signatures();
let fn_sigs: &'a BTreeMap<_, _> = Box::leak(Box::new(fn_sigs));
let analysis_results = analysis_results.with_function_signatures(Some(fn_sigs));
analysis_results
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment