Skip to content

Commit e9bd38c

Browse files
committed
More tweaks to use jingle context
1 parent 6185783 commit e9bd38c

File tree

5 files changed

+57
-57
lines changed

5 files changed

+57
-57
lines changed

src/config/constraint.rs

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
use std::collections::HashMap;
2-
use std::sync::Arc;
3-
1+
use crate::error::CrackersError;
2+
use crate::synthesis::builder::{StateConstraintGenerator, TransitionConstraintGenerator};
43
use jingle::modeling::{ModeledBlock, ModelingContext, State};
54
use jingle::sleigh::{IndirectVarNode, RegisterManager, SpaceManager, VarNode};
65
use jingle::varnode::{ResolvedIndirectVarNode, ResolvedVarnode};
6+
use jingle::JingleContext;
77
use serde::{Deserialize, Serialize};
8+
use std::collections::HashMap;
9+
use std::sync::Arc;
810
use tracing::{event, Level};
911
use z3::ast::{Ast, Bool, BV};
10-
use z3::Context;
11-
12-
use crate::error::CrackersError;
13-
use crate::synthesis::builder::{StateConstraintGenerator, TransitionConstraintGenerator};
1412

1513
#[derive(Clone, Debug, Deserialize, Serialize)]
1614
pub struct Constraint {
@@ -122,14 +120,14 @@ pub struct PointerRange {
122120
/// Generates a state constraint that a given varnode must be equal to a given value
123121
pub fn gen_memory_constraint(
124122
m: MemoryEqualityConstraint,
125-
) -> impl for<'a, 'b> Fn(&'a Context, &'b State<'a>, u64) -> Result<Bool<'a>, CrackersError>
123+
) -> impl for<'a,> Fn(&JingleContext<'a>, &State<'a>, u64) -> Result<Bool<'a>, CrackersError>
126124
+ Send
127125
+ Sync
128126
+ Clone
129127
+ 'static {
130-
return move |z3, state, _addr| {
128+
return move |jingle, state, _addr| {
131129
let data = state.read_varnode(&state.varnode(&m.space, m.address, m.size).unwrap())?;
132-
let constraint = data._eq(&BV::from_u64(z3, m.value as u64, data.get_size()));
130+
let constraint = data._eq(&BV::from_u64(jingle.z3, m.value as u64, data.get_size()));
133131
Ok(constraint)
134132
};
135133
}
@@ -139,14 +137,14 @@ pub fn gen_memory_constraint(
139137
pub fn gen_register_constraint(
140138
vn: VarNode,
141139
value: u64,
142-
) -> impl for<'a, 'b> Fn(&'a Context, &'b State<'a>, u64) -> Result<Bool<'a>, CrackersError>
140+
) -> impl for<'a> Fn(&JingleContext<'a>, &State<'a>, u64) -> Result<Bool<'a>, CrackersError>
143141
+ 'static
144142
+ Send
145143
+ Sync
146144
+ Clone {
147-
return move |z3, state, _addr| {
145+
return move |jingle, state, _addr| {
148146
let data = state.read_varnode(&vn)?;
149-
let constraint = data._eq(&BV::from_u64(z3, value, data.get_size()));
147+
let constraint = data._eq(&BV::from_u64(jingle.z3, value, data.get_size()));
150148
Ok(constraint)
151149
};
152150
}
@@ -157,14 +155,14 @@ pub fn gen_register_pointer_constraint<'ctx>(
157155
vn: VarNode,
158156
value: String,
159157
m: Option<PointerRangeConstraints>,
160-
) -> impl for<'a, 'b> Fn(&'a Context, &'b State<'a>, u64) -> Result<Bool<'a>, CrackersError> + 'ctx + Clone
158+
) -> impl for<'a> Fn(&JingleContext<'a>, &State<'a>, u64) -> Result<Bool<'a>, CrackersError> + 'ctx + Clone
161159
{
162-
return move |z3, state, _addr| {
160+
return move |jingle, state, _addr| {
163161
let m = m.clone();
164162
let val = value
165163
.as_bytes()
166164
.iter()
167-
.map(|b| BV::from_u64(z3, *b as u64, 8))
165+
.map(|b| BV::from_u64(jingle.z3, *b as u64, 8))
168166
.reduce(|a, b| a.concat(&b))
169167
.unwrap();
170168
let pointer = state.read_varnode(&vn)?;
@@ -182,9 +180,9 @@ pub fn gen_register_pointer_constraint<'ctx>(
182180
let mut constraint = data._eq(&val);
183181
if let Some(c) = m.and_then(|m| m.read) {
184182
let callback = gen_pointer_range_state_invariant(c);
185-
let cc = callback(z3, &resolved, state)?;
183+
let cc = callback(jingle, &resolved, state)?;
186184
if let Some(b) = cc {
187-
constraint = Bool::and(z3, &[constraint, b])
185+
constraint = Bool::and(jingle.z3, &[constraint, b])
188186
}
189187
}
190188
Ok(constraint)
@@ -195,14 +193,14 @@ pub fn gen_register_pointer_constraint<'ctx>(
195193
/// the given range.
196194
pub fn gen_pointer_range_state_invariant<'ctx>(
197195
m: Vec<PointerRange>,
198-
) -> impl for<'a, 'b> Fn(
199-
&'a Context,
200-
&'b ResolvedVarnode<'a>,
201-
&'b State<'a>,
196+
) -> impl for<'a> Fn(
197+
&JingleContext<'a>,
198+
&ResolvedVarnode<'a>,
199+
&State<'a>,
202200
) -> Result<Option<Bool<'a>>, CrackersError>
203201
+ 'ctx
204202
+ Clone {
205-
return move |z3, vn, state| {
203+
return move |jingle, vn, state| {
206204
match vn {
207205
ResolvedVarnode::Direct(d) => {
208206
// todo: this is gross
@@ -213,51 +211,51 @@ pub fn gen_pointer_range_state_invariant<'ctx>(
213211
let bool = m
214212
.iter()
215213
.any(|mm| d.offset >= mm.min && (d.offset + d.size as u64) <= mm.max);
216-
Ok(Some(Bool::from_bool(z3, bool)))
214+
Ok(Some(Bool::from_bool(jingle.z3, bool)))
217215
}
218216
}
219217
}
220218
ResolvedVarnode::Indirect(vn) => {
221219
let mut terms = vec![];
222220
for mm in &m {
223-
let min = BV::from_u64(z3, mm.min, vn.pointer.get_size());
224-
let max = BV::from_u64(z3, mm.max, vn.pointer.get_size());
221+
let min = BV::from_u64(jingle.z3, mm.min, vn.pointer.get_size());
222+
let max = BV::from_u64(jingle.z3, mm.max, vn.pointer.get_size());
225223
let constraint =
226-
Bool::and(z3, &[vn.pointer.bvuge(&min), vn.pointer.bvule(&max)]);
224+
Bool::and(jingle.z3, &[vn.pointer.bvuge(&min), vn.pointer.bvule(&max)]);
227225
terms.push(constraint);
228226
}
229227

230-
Ok(Some(Bool::or(z3, terms.as_slice())))
228+
Ok(Some(Bool::or(jingle.z3, terms.as_slice())))
231229
}
232230
}
233231
};
234232
}
235233

236234
pub fn gen_pointer_range_transition_invariant(
237235
m: PointerRangeConstraints,
238-
) -> impl for<'a, 'b> Fn(&'a Context, &'b ModeledBlock<'a>) -> Result<Option<Bool<'a>>, CrackersError>
236+
) -> impl for<'a> Fn(&JingleContext<'a>, &ModeledBlock<'a>) -> Result<Option<Bool<'a>>, CrackersError>
239237
+ Send
240238
+ Sync
241239
+ Clone
242240
+ 'static {
243-
return move |z3, block| {
241+
return move |jingle, block| {
244242
let mut bools = vec![];
245243
if let Some(r) = &m.read {
246244
let inv = gen_pointer_range_state_invariant(r.clone());
247245
for x in block.get_inputs() {
248-
if let Some(c) = inv(z3, &x, block.get_final_state())? {
246+
if let Some(c) = inv(jingle, &x, block.get_final_state())? {
249247
bools.push(c);
250248
}
251249
}
252250
}
253251
if let Some(r) = &m.write {
254252
let inv = gen_pointer_range_state_invariant(r.clone());
255253
for x in block.get_outputs() {
256-
if let Some(c) = inv(z3, &x, block.get_final_state())? {
254+
if let Some(c) = inv(jingle, &x, block.get_final_state())? {
257255
bools.push(c);
258256
}
259257
}
260258
}
261-
Ok(Some(Bool::and(z3, &bools)))
259+
Ok(Some(Bool::and(jingle.z3, &bools)))
262260
};
263261
}

src/synthesis/builder.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::sync::Arc;
33
use derive_builder::Builder;
44
use jingle::modeling::{ModeledBlock, State};
55
use jingle::sleigh::Instruction;
6+
use jingle::JingleContext;
67
use serde::{Deserialize, Serialize};
78
use z3::ast::Bool;
89
use z3::Context;
@@ -21,11 +22,11 @@ pub enum SynthesisSelectionStrategy {
2122
OptimizeStrategy,
2223
}
2324

24-
pub type StateConstraintGenerator = dyn for<'a, 'b> Fn(&'a Context, &'b State<'a>, u64) -> Result<Bool<'a>, CrackersError>
25+
pub type StateConstraintGenerator = dyn for<'a> Fn(&JingleContext<'a>, &State<'a>, u64) -> Result<Bool<'a>, CrackersError>
2526
+ Send
2627
+ Sync
2728
+ 'static;
28-
pub type TransitionConstraintGenerator = dyn for<'a, 'b> Fn(&'a Context, &'b ModeledBlock<'a>) -> Result<Option<Bool<'a>>, CrackersError>
29+
pub type TransitionConstraintGenerator = dyn for<'a> Fn(&JingleContext<'a>, &ModeledBlock<'a>) -> Result<Option<Bool<'a>>, CrackersError>
2930
+ Send
3031
+ Sync
3132
+ 'static;

src/synthesis/mod.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ impl<'ctx> AssignmentSynthesis<'ctx> {
140140
let worker = TheoryWorker::new(&z3, idx, r, req_receiver, t).unwrap();
141141
event!(Level::TRACE, "Created worker {}", idx);
142142
worker.run();
143-
std::mem::drop(worker);
143+
drop(worker);
144144
});
145145
});
146146
}
147-
std::mem::drop(resp_sender);
147+
drop(resp_sender);
148148
for (i, x) in req_channels.iter().enumerate() {
149149
event!(
150150
Level::TRACE,
@@ -185,7 +185,7 @@ impl<'ctx> AssignmentSynthesis<'ctx> {
185185
"Theory returned SAT for {:?}!",
186186
response.assignment
187187
);
188-
dbg!("huh");
188+
dbg!("Terminating remaining workers");
189189
req_channels.clear();
190190
for x in &kill_senders {
191191
x.send(()).unwrap();
@@ -195,10 +195,11 @@ impl<'ctx> AssignmentSynthesis<'ctx> {
195195
let jingle = JingleContext::new(self.z3, self.library.as_ref());
196196
let a: PcodeAssignment<'ctx> =
197197
t.build_assignment(&jingle, response.assignment)?;
198-
dbg!("huh2");
198+
dbg!("Workers Terminated; building and checking model");
199199
let solver = Solver::new(self.z3);
200-
let model = a.check(self.z3, &solver)?;
201-
dbg!("here");
200+
let jingle = JingleContext::new(self.z3, self.library.as_ref());
201+
let model = a.check(&jingle, &solver)?;
202+
dbg!("Model built");
202203
return Ok(DecisionResult::AssignmentFound(model));
203204
}
204205
Some(c) => {

src/synthesis/pcode_theory/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ impl<'ctx, S: ModelingContext<'ctx>> PcodeTheory<'ctx, S> {
121121
for (index, (spec, g)) in self.templates.iter().zip(&gadgets).enumerate() {
122122
let sem = Bool::fresh_const(self.j.z3, "c");
123123
self.solver.assert_and_track(
124-
&assert_compatible_semantics(self.j.z3, spec, g, &self.pointer_invariants)?,
124+
&assert_compatible_semantics(&self.j, spec, g, &self.pointer_invariants)?,
125125
&sem,
126126
);
127127
assertions.push(ConjunctiveConstraint::new(
@@ -165,15 +165,15 @@ impl<'ctx, S: ModelingContext<'ctx>> PcodeTheory<'ctx, S> {
165165
state: &State<'ctx>,
166166
addr: u64,
167167
) -> Result<Bool<'ctx>, CrackersError> {
168-
assert_state_constraints(self.j.z3, &self.preconditions, state, addr)
168+
assert_state_constraints(&self.j, &self.preconditions, state, addr)
169169
}
170170

171171
fn assert_postconditions(
172172
&self,
173173
state: &State<'ctx>,
174174
addr: u64,
175175
) -> Result<Bool<'ctx>, CrackersError> {
176-
assert_state_constraints(self.j.z3, &self.postconditions, state, addr)
176+
assert_state_constraints(&self.j, &self.postconditions, state, addr)
177177
}
178178

179179
fn collect_conflicts(

src/synthesis/pcode_theory/pcode_assignment.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use std::sync::Arc;
2-
31
use jingle::modeling::{ModeledBlock, ModeledInstruction, ModelingContext, State};
2+
use jingle::JingleContext;
3+
use std::sync::Arc;
44
use z3::ast::Bool;
55
use z3::{Context, SatResult, Solver};
66

@@ -35,30 +35,30 @@ impl<'ctx> PcodeAssignment<'ctx> {
3535

3636
pub fn check(
3737
&self,
38-
z3: &'ctx Context,
38+
jingle: &JingleContext<'ctx>,
3939
solver: &Solver<'ctx>,
4040
) -> Result<AssignmentModel<'ctx, ModeledBlock<'ctx>>, CrackersError> {
41-
solver.assert(&assert_concat(z3, &self.spec_trace)?);
41+
solver.assert(&assert_concat(jingle.z3, &self.spec_trace)?);
4242
for x in self.eval_trace.windows(2) {
4343
solver.assert(&x[0].assert_concat(&x[1])?);
4444
solver.assert(&x[0].can_branch_to_address(x[1].get_address())?);
4545
}
4646
for (spec_inst, trace_inst) in self.spec_trace.iter().zip(&self.eval_trace) {
4747
solver.assert(&assert_compatible_semantics(
48-
z3,
48+
jingle,
4949
spec_inst,
5050
trace_inst,
5151
&self.pointer_invariants,
5252
)?);
5353
}
5454
solver.assert(&assert_state_constraints(
55-
z3,
55+
jingle,
5656
&self.preconditions,
5757
self.eval_trace.as_slice().get_original_state(),
5858
self.eval_trace[0].get_first_address(),
5959
)?);
6060
solver.assert(&assert_state_constraints(
61-
z3,
61+
jingle,
6262
&self.postconditions,
6363
self.eval_trace.as_slice().get_final_state(),
6464
self.eval_trace.last().unwrap().get_last_address(),
@@ -86,7 +86,7 @@ pub fn assert_concat<'ctx, T: ModelingContext<'ctx>>(
8686
}
8787

8888
pub fn assert_compatible_semantics<'ctx, S: ModelingContext<'ctx>>(
89-
z3: &'ctx Context,
89+
jingle: &JingleContext<'ctx>,
9090
spec: &S,
9191
item: &ModeledBlock<'ctx>,
9292
invariants: &[Arc<TransitionConstraintGenerator>],
@@ -102,24 +102,24 @@ pub fn assert_compatible_semantics<'ctx, S: ModelingContext<'ctx>>(
102102
}
103103
// Thirdly, every input and output address must pass our pointer constraints
104104
for invariant in invariants.iter() {
105-
let inv = invariant(z3, item)?;
105+
let inv = invariant(jingle, item)?;
106106
if let Some(b) = inv {
107107
bools.push(b)
108108
}
109109
}
110-
Ok(Bool::and(z3, &bools))
110+
Ok(Bool::and(jingle.z3, &bools))
111111
}
112112

113113
pub fn assert_state_constraints<'ctx>(
114-
z3: &'ctx Context,
114+
jingle: &JingleContext<'ctx>,
115115
constraints: &[Arc<StateConstraintGenerator>],
116116
state: &State<'ctx>,
117117
addr: u64,
118118
) -> Result<Bool<'ctx>, CrackersError> {
119119
let mut bools = vec![];
120120
for x in constraints.iter() {
121-
let assertion = x(z3, state, addr)?;
121+
let assertion = x(jingle, state, addr)?;
122122
bools.push(assertion);
123123
}
124-
Ok(Bool::and(z3, &bools))
124+
Ok(Bool::and(jingle.z3, &bools))
125125
}

0 commit comments

Comments
 (0)