1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use yaxpeax_arch::Arch;
use petgraph::visit::Bfs;
use analyses::static_single_assignment::SSA;
use analyses::static_single_assignment::SSAValues;
use memory::MemoryRange;
use analyses::control_flow::ControlFlowGraph;
use arch::{DecodeFrom, InstructionSpan};
use analyses::evaluators::const_evaluator::ConstEvaluator;
use arch::x86_64::analyses::evaluators::const_evaluator::ConcreteDomain;
use arch::x86_64::analyses::evaluators::symbolizer::SymbolicDomain;
use arch::x86_64::analyses::evaluators::value_set::ValueSetDomain;
pub mod const_evaluator;
pub struct Evaluator<'program, 'function, 'ssa, A: Arch + SSAValues, M: MemoryRange<A>> {
program: &'program M,
fn_graph: &'function ControlFlowGraph<A::Address>,
ssa: &'ssa SSA<A>,
}
impl<'program, 'function, 'ssa, A, M: MemoryRange<A>> Evaluator<'program, 'function, 'ssa, A, M> where
A: Arch + SSAValues + DecodeFrom<M>,
A: ConstEvaluator<A, (), ConcreteDomain>,
A: ConstEvaluator<A, (), SymbolicDomain>,
A: ConstEvaluator<A, (), ValueSetDomain>,
A::Instruction: std::fmt::Display,
{
pub fn new(program: &'program M, fn_graph: &'function ControlFlowGraph<A::Address>, ssa: &'ssa SSA<A>) -> Self {
Evaluator {
program,
fn_graph,
ssa,
}
}
pub fn iterate_basic_block(&self, block: A::Address) {
let block = self.fn_graph.get_block(block);
let mut iter = A::instructions_spanning(self.program, block.start, block.end);
while let Some((address, instr)) = iter.next() {
<A as ConstEvaluator<A, (), ConcreteDomain>>::evaluate_instruction(&instr, address, self.ssa, &(), self.program);
<A as ConstEvaluator<A, (), SymbolicDomain>>::evaluate_instruction(&instr, address, self.ssa, &(), self.program);
<A as ConstEvaluator<A, (), ValueSetDomain>>::evaluate_instruction(&instr, address, self.ssa, &(), self.program);
}
}
pub fn full_function_iterate(&self) {
let mut bfs = Bfs::new(&self.fn_graph.graph, self.fn_graph.entrypoint);
while let Some(k) = bfs.next(&self.fn_graph.graph) {
self.iterate_basic_block(k);
}
}
}