Skip to content

Commit f9542d6

Browse files
authored
chore: update jingle APIs (#72)
* Update APIs * fmt * clippy
1 parent c1a5577 commit f9542d6

File tree

18 files changed

+163
-167
lines changed

18 files changed

+163
-167
lines changed

crackers/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ toml = ["dep:toml_edit"]
2424
z3-gh-release = ["z3/gh-release"]
2525

2626
[dependencies]
27-
jingle = { version = "0.2.6", features = ["gimli"] }
27+
jingle = { version = "0.3.0", features = ["gimli"] }
2828
z3 = "0.18.2"
2929
serde = { version = "1.0.203", features = ["derive"] }
3030
thiserror = "2.0"

crackers/src/config/constraint.rs

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::error::CrackersError;
22
use crate::synthesis::builder::{StateConstraintGenerator, TransitionConstraintGenerator};
33
use jingle::modeling::{ModeledBlock, ModelingContext, State};
4-
use jingle::sleigh::{ArchInfoProvider, VarNode};
4+
use jingle::sleigh::{SleighArchInfo, VarNode};
55
use jingle::varnode::{ResolvedIndirectVarNode, ResolvedVarnode};
66
#[cfg(feature = "pyo3")]
77
use pyo3::pyclass;
88
use serde::{Deserialize, Serialize};
9+
use std::borrow::Borrow;
910
use std::collections::HashMap;
1011
use std::ops::Add;
1112
use std::sync::Arc;
@@ -21,22 +22,23 @@ pub struct ConstraintConfig {
2122
}
2223

2324
impl ConstraintConfig {
24-
pub fn get_preconditions<'a, T: ArchInfoProvider>(
25-
&'a self,
26-
sleigh: &'a T,
27-
) -> impl Iterator<Item = Arc<StateConstraintGenerator>> + 'a {
25+
pub fn get_preconditions<T: Borrow<SleighArchInfo>>(
26+
&self,
27+
sleigh: T,
28+
) -> impl Iterator<Item = Arc<StateConstraintGenerator>> {
29+
let sleigh = sleigh.borrow().clone();
2830
self.precondition
2931
.iter()
30-
.flat_map(|c| c.constraints(sleigh, self.pointer.clone()))
32+
.flat_map(move |c| c.constraints(sleigh.clone(), self.pointer.clone()))
3133
}
3234

33-
pub fn get_postconditions<'a, T: ArchInfoProvider>(
34-
&'a self,
35-
sleigh: &'a T,
36-
) -> impl Iterator<Item = Arc<StateConstraintGenerator>> + 'a {
35+
pub fn get_postconditions<T: Borrow<SleighArchInfo>>(
36+
&self,
37+
sleigh: T,
38+
) -> impl Iterator<Item = Arc<StateConstraintGenerator>> {
3739
self.postcondition
3840
.iter()
39-
.flat_map(|c| c.constraints(sleigh, self.pointer.clone()))
41+
.flat_map(move |c| c.constraints(sleigh.borrow().clone(), self.pointer.clone()))
4042
}
4143

4244
pub fn get_pointer_constraints(
@@ -55,14 +57,17 @@ pub struct StateEqualityConstraint {
5557
}
5658

5759
impl StateEqualityConstraint {
58-
pub fn constraints<'a, T: ArchInfoProvider>(
59-
&'a self,
60-
sleigh: &'a T,
60+
pub fn constraints<T: Borrow<SleighArchInfo>>(
61+
&self,
62+
info: T,
6163
c: Option<PointerRangeConstraints>,
62-
) -> impl Iterator<Item = Arc<StateConstraintGenerator>> + 'a {
63-
let register_iterator = self.register.iter().flat_map(|map| {
64-
map.iter().filter_map(|(name, value)| {
65-
if let Some(vn) = sleigh.get_register(name) {
64+
) -> impl Iterator<Item = Arc<StateConstraintGenerator>> {
65+
let info = info.borrow().clone();
66+
let info2 = info.clone();
67+
let register_iterator = self.register.iter().flat_map(move |map| {
68+
let info = info.clone();
69+
map.iter().filter_map(move |(name, value)| {
70+
if let Some(vn) = info.register(name) {
6671
Some(Arc::new(gen_register_constraint(vn.clone(), *value as u64))
6772
as Arc<StateConstraintGenerator>)
6873
} else {
@@ -75,10 +80,12 @@ impl StateEqualityConstraint {
7580
.memory
7681
.iter()
7782
.map(|c| Arc::new(gen_memory_constraint(c.clone())) as Arc<StateConstraintGenerator>);
83+
let info = info2;
7884
let pointer_iterator = self.pointer.iter().flat_map(move |map| {
7985
let c1 = c.clone();
86+
let info = info.clone();
8087
map.iter().filter_map(move |(name, value)| {
81-
if let Some(vn) = sleigh.get_register(name) {
88+
if let Some(vn) = info.register(name) {
8289
Some(Arc::new(gen_register_pointer_constraint(
8390
vn.clone(),
8491
value.clone(),
@@ -129,7 +136,12 @@ pub fn gen_memory_constraint(
129136
m: MemoryEqualityConstraint,
130137
) -> impl Fn(&State, u64) -> Result<Bool, CrackersError> + Send + Sync + Clone + 'static {
131138
move |state, _addr| {
132-
let data = state.read_varnode(&state.varnode(&m.space, m.address, m.size).unwrap())?;
139+
let data = state.read_varnode(
140+
&state
141+
.arch_info()
142+
.varnode(&m.space, m.address, m.size)
143+
.unwrap(),
144+
)?;
133145
let constraint = data.eq(BV::from_u64(m.value as u64, data.get_size()));
134146
Ok(constraint)
135147
}
@@ -166,15 +178,15 @@ pub fn gen_register_pointer_constraint(
166178
pointer_location: vn.clone(),
167179
pointer: pointer.clone().add(i as u64),
168180
access_size_bytes: 1,
169-
pointer_space_idx: state.get_code_space_idx(),
181+
pointer_space_idx: state.get_default_code_space_info().index,
170182
});
171183
let actual = state.read_resolved(&char_ptr)?;
172184
bools.push(actual.eq(&expected))
173185
}
174186
let pointer = state.read_varnode(&vn)?;
175187
let resolved = ResolvedVarnode::Indirect(ResolvedIndirectVarNode {
176188
pointer_location: vn.clone(),
177-
pointer_space_idx: state.get_code_space_idx(),
189+
pointer_space_idx: state.get_default_code_space_info().index,
178190
access_size_bytes: value.len(),
179191
pointer,
180192
});
@@ -199,7 +211,8 @@ pub fn gen_pointer_range_state_invariant(
199211
match vn {
200212
ResolvedVarnode::Direct(d) => {
201213
// todo: this is gross
202-
let should_constrain = state.get_code_space_idx() == d.space_index;
214+
let should_constrain =
215+
state.arch_info().default_code_space_index() == d.space_index;
203216
match should_constrain {
204217
false => Ok(None),
205218
true => {

crackers/src/config/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ impl CrackersConfig {
3737
let library = self.library.build(&self.sleigh)?;
3838
let mut b = SynthesisParamsBuilder::default();
3939
if let Some(c) = &self.constraint {
40-
b.preconditions(c.get_preconditions(&library).collect());
41-
b.postconditions(c.get_postconditions(&library).collect());
40+
b.preconditions(c.get_preconditions(&library.arch_info()).collect());
41+
b.postconditions(c.get_postconditions(&library.arch_info()).collect());
4242
b.pointer_invariants(c.get_pointer_constraints().collect());
4343
}
4444
b.gadget_library(library)

crackers/src/gadget/another_iterator.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use jingle::JingleContext;
21
use jingle::modeling::{ModeledInstruction, ModelingContext};
3-
use jingle::sleigh::{Instruction, OpCode};
2+
use jingle::sleigh::{Instruction, OpCode, SleighArchInfo};
3+
use std::borrow::Borrow;
44
use tracing::trace;
55
use z3::Solver;
66
use z3::ast::Ast;
@@ -12,7 +12,7 @@ pub struct TraceCandidateIterator<'a, T>
1212
where
1313
T: Iterator<Item = &'a Gadget>,
1414
{
15-
jingle: JingleContext,
15+
info: SleighArchInfo,
1616
_solver: Solver,
1717
gadgets: T,
1818
trace: Vec<ModeledInstruction>,
@@ -22,10 +22,14 @@ impl<'a, T> TraceCandidateIterator<'a, T>
2222
where
2323
T: Iterator<Item = &'a Gadget>,
2424
{
25-
pub(crate) fn new(jingle: &JingleContext, gadgets: T, trace: Vec<ModeledInstruction>) -> Self {
25+
pub(crate) fn new<S: Borrow<SleighArchInfo>>(
26+
jingle: S,
27+
gadgets: T,
28+
trace: Vec<ModeledInstruction>,
29+
) -> Self {
2630
let _solver = Solver::new();
2731
Self {
28-
jingle: jingle.clone(),
32+
info: jingle.borrow().clone(),
2933
_solver,
3034
gadgets,
3135
trace,
@@ -53,12 +57,13 @@ where
5357
i.instr.disassembly, gadget
5458
);
5559

56-
gadget_signature.covers(&GadgetSignature::from_instr(&i.instr, i))
60+
gadget_signature
61+
.covers(&GadgetSignature::from_instr(&i.instr, i.get_arch_info()))
5762
&& has_compatible_control_flow(&i.instr, gadget)
5863
})
5964
.collect();
6065
if is_candidate.iter().any(|b| *b) {
61-
let model = gadget.model(&self.jingle);
66+
let model = gadget.model(&self.info);
6267
if let Ok(model) = &model {
6368
is_candidate.iter().enumerate().for_each(|(i, c)| {
6469
if *c {

crackers/src/gadget/candidates.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use jingle::JingleContext;
2-
use jingle::modeling::ModeledBlock;
3-
41
use crate::error::CrackersError;
52
use crate::error::CrackersError::UnsimulatedOperation;
63
use crate::gadget::Gadget;
4+
use jingle::modeling::ModeledBlock;
5+
use jingle::sleigh::SleighArchInfo;
6+
use std::borrow::Borrow;
77

88
#[derive(Clone, Debug, Default)]
99
pub struct CandidateBuilder {
@@ -58,12 +58,16 @@ pub struct Candidates {
5858
}
5959

6060
impl Candidates {
61-
pub fn model(&self, jingle: &JingleContext) -> Result<Vec<Vec<ModeledBlock>>, CrackersError> {
61+
pub fn model<T: Borrow<SleighArchInfo>>(
62+
&self,
63+
info: T,
64+
) -> Result<Vec<Vec<ModeledBlock>>, CrackersError> {
65+
let info = info.borrow();
6266
let mut result = vec![];
6367
for x in &self.candidates {
6468
let mut v = vec![];
6569
for g in x {
66-
v.push(g.model(jingle)?);
70+
v.push(g.model(info)?);
6771
}
6872
result.push(v)
6973
}

crackers/src/gadget/library/mod.rs

Lines changed: 17 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
use jingle::JingleError;
12
use jingle::modeling::ModeledInstruction;
23
use jingle::sleigh::context::loaded::LoadedSleighContext;
3-
use jingle::sleigh::{ArchInfoProvider, Instruction, SleighArchInfo, SpaceInfo, VarNode};
4-
use jingle::{JingleContext, JingleError};
4+
use jingle::sleigh::{Instruction, SleighArchInfo};
55
use rand::SeedableRng;
66
use rand::rngs::StdRng;
77
use rand::seq::IndexedRandom;
8+
use std::borrow::Borrow;
89
use tracing::{Level, event};
910

1011
use crate::gadget::Gadget;
@@ -17,9 +18,13 @@ pub mod image;
1718
#[derive(Clone, Debug)]
1819
pub struct GadgetLibrary {
1920
pub(crate) gadgets: Vec<Gadget>,
20-
spaces: Vec<SpaceInfo>,
21-
default_code_space_index: usize,
22-
registers: Vec<(VarNode, String)>,
21+
arch_info: SleighArchInfo,
22+
}
23+
24+
impl AsRef<SleighArchInfo> for GadgetLibrary {
25+
fn as_ref(&self) -> &SleighArchInfo {
26+
&self.arch_info
27+
}
2328
}
2429

2530
impl GadgetLibrary {
@@ -28,40 +33,25 @@ impl GadgetLibrary {
2833
}
2934

3035
pub(crate) fn arch_info(&self) -> SleighArchInfo {
31-
SleighArchInfo::new(
32-
self.get_registers(),
33-
self.get_all_space_info(),
34-
self.default_code_space_index,
35-
)
36+
self.arch_info.clone()
3637
}
37-
pub fn get_random_candidates_for_trace<'a>(
38+
pub fn get_random_candidates_for_trace<'a, S: Borrow<SleighArchInfo>>(
3839
&'a self,
39-
jingle: &JingleContext,
40+
info: S,
4041
trace: &[ModeledInstruction],
4142
seed: i64,
4243
) -> impl Iterator<Item = Vec<Option<&'a Gadget>>> {
4344
let mut rng = StdRng::seed_from_u64(seed as u64);
4445
let r = self.gadgets.choose_multiple(&mut rng, self.gadgets.len());
45-
TraceCandidateIterator::new(jingle, r, trace.to_vec())
46+
TraceCandidateIterator::new(info, r, trace.to_vec())
4647
}
4748
pub(super) fn build_from_image(
4849
sleigh: LoadedSleighContext,
4950
builder: &GadgetLibraryConfig,
5051
) -> Result<Self, JingleError> {
51-
let spaces: Vec<_> = sleigh.get_all_space_info().cloned().collect();
52-
let mut registers = vec![];
53-
let default_code_space_index = sleigh.get_code_space_idx();
54-
for (varnode, register) in sleigh.get_registers() {
55-
registers.push((varnode.clone(), register));
56-
}
5752
let mut lib: GadgetLibrary = GadgetLibrary {
5853
gadgets: vec![],
59-
spaces,
60-
default_code_space_index,
61-
registers: registers
62-
.iter()
63-
.map(|(varnode, register)| (varnode.clone(), register.to_string()))
64-
.collect(),
54+
arch_info: sleigh.arch_info().clone(),
6555
};
6656
event!(Level::INFO, "Loading gadgets from sleigh");
6757
for section in sleigh.get_sections().filter(|s| s.perms.exec) {
@@ -74,8 +64,8 @@ impl GadgetLibrary {
7464
sleigh.read(curr, builder.max_gadget_length).collect();
7565
if let Some(i) = instrs.iter().position(|b| b.terminates_basic_block()) {
7666
let gadget = Gadget {
77-
code_space_idx: sleigh.get_code_space_idx(),
78-
spaces: sleigh.get_all_space_info().cloned().collect(),
67+
code_space_idx: sleigh.arch_info().default_code_space_index(),
68+
spaces: sleigh.arch_info().spaces().to_vec(),
7969
instructions: instrs[0..=i].to_vec(),
8070
};
8171
if !gadget.has_blacklisted_op(&builder.operation_blacklist) {
@@ -90,37 +80,6 @@ impl GadgetLibrary {
9080
}
9181
}
9282

93-
impl ArchInfoProvider for GadgetLibrary {
94-
fn get_space_info(&self, idx: usize) -> Option<&SpaceInfo> {
95-
self.spaces.get(idx)
96-
}
97-
fn get_all_space_info(&self) -> impl Iterator<Item = &SpaceInfo> {
98-
self.spaces.iter()
99-
}
100-
101-
fn get_code_space_idx(&self) -> usize {
102-
self.default_code_space_index
103-
}
104-
105-
fn get_register(&self, name: &str) -> Option<&VarNode> {
106-
self.registers
107-
.iter()
108-
.find(|(_, reg_name)| reg_name.as_str() == name)
109-
.map(|(vn, _)| vn)
110-
}
111-
112-
fn get_register_name(&self, location: &VarNode) -> Option<&str> {
113-
self.registers
114-
.iter()
115-
.find(|(vn, _)| vn == location)
116-
.map(|(_, name)| name.as_str())
117-
}
118-
119-
fn get_registers(&self) -> impl Iterator<Item = (&VarNode, &str)> {
120-
self.registers.iter().map(|(vn, name)| (vn, name.as_str()))
121-
}
122-
}
123-
12483
#[cfg(test)]
12584
mod tests {
12685
use std::fs;

crackers/src/gadget/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use jingle::JingleContext;
21
use jingle::modeling::ModeledBlock;
3-
use jingle::sleigh::{Instruction, OpCode, PcodeOperation, SpaceInfo};
2+
use jingle::sleigh::{Instruction, OpCode, PcodeOperation, SleighArchInfo, SpaceInfo};
43
use serde::{Deserialize, Serialize};
4+
use std::borrow::Borrow;
55
use std::collections::HashSet;
66
use std::fmt::{Debug, Display, Formatter};
77

@@ -49,7 +49,10 @@ impl Gadget {
4949
.any(|i| i.ops.iter().any(|o| blacklist.contains(&o.opcode())))
5050
}
5151

52-
pub fn model(&self, jingle: &JingleContext) -> Result<ModeledBlock, CrackersError> {
52+
pub fn model<I: Borrow<SleighArchInfo>>(
53+
&self,
54+
jingle: I,
55+
) -> Result<ModeledBlock, CrackersError> {
5356
let blk = ModeledBlock::read(jingle, self.instructions.clone().into_iter())?;
5457
Ok(blk)
5558
}

0 commit comments

Comments
 (0)