Skip to content

Commit be8ac09

Browse files
committed
add value ref to cli, small changes
1 parent dfb7b5b commit be8ac09

File tree

10 files changed

+82
-34
lines changed

10 files changed

+82
-34
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn main() {
3939
let mut state = radius.call_state(0x004006fd);
4040
let addr: u64 = 0x100000;
4141
let flag_val = state.symbolic_value("flag", 12*8);
42-
state.memory.write_value(addr, &flag_val, 12);
42+
state.memory_write_value(addr, &flag_val, 12);
4343
state.registers.set("rdi", state.concrete_value(addr, 64));
4444

4545
radius.breakpoint(0x004007a1);

examples/babyre/src/main.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use radius2::state::State;
22
use radius2::value::Value;
3+
use radius2::sims::Sim;
34
use radius2::{Radius, RadiusOption};
45

56
// simulates the scanf("%d", dst) calls with sym inputs
@@ -24,7 +25,11 @@ fn main() {
2425
let scanf = radius.get_address("sym.imp.__isoc99_scanf").unwrap();
2526

2627
// register the custom sim
27-
radius.simulate(scanf, scanf_sim);
28+
radius.simulate(scanf, Sim{
29+
symbol: "scanf".to_owned(),
30+
function: scanf_sim,
31+
arguments: 2
32+
});
2833

2934
let state = radius.call_state(main); // start at main
3035
let new_state = radius.run_until(state, 0x004028e9, &[0x00402941]).unwrap();

radius/src/main.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -585,17 +585,25 @@ fn main() {
585585
for i in 0..matches.occurrences_of("set") as usize {
586586
// easiest way to interpret the stuff is just to use
587587
let ind = 3 * i;
588-
let length: u32 = sets[ind + 2].parse().unwrap();
588+
let mut length: u32 = sets[ind + 2].parse().unwrap();
589589

590-
let lit = radius.processor.get_literal(sets[ind + 1]);
591-
let value = if let Some(Word::Literal(val)) = lit {
590+
let mut is_ref = false;
591+
let valstr = if sets[ind + 1][0..1].to_owned() == "&" {
592+
is_ref = true;
593+
&sets[ind + 1][1..]
594+
} else {
595+
&sets[ind + 1][0..]
596+
};
597+
598+
let lit = radius.processor.get_literal(valstr);
599+
let mut value = if let Some(Word::Literal(val)) = lit {
592600
val
593-
} else if let Some(bv) = symbol_map.get(sets[ind + 1]) {
601+
} else if let Some(bv) = symbol_map.get(valstr) {
594602
Value::Symbolic(bv.slice(length - 1, 0), 0)
595603
} else {
596604
// this is a real workaround of the system
597605
// i need a better place for these kinds of utils
598-
let bytes = sets[ind + 1].as_bytes();
606+
let bytes = valstr.as_bytes();
599607
let bv = BV::from_hex_str(
600608
state.solver.btor.clone(),
601609
hex_encode(bytes).as_str(),
@@ -605,6 +613,13 @@ fn main() {
605613
Value::Symbolic(bv, 0)
606614
};
607615

616+
if is_ref {
617+
let addr = state.memory_alloc(&Value::Concrete(length as u64/8, 0));
618+
state.memory_write_value(&addr, &value, length as usize/8);
619+
value = addr;
620+
length = state.memory.bits as u32;
621+
}
622+
608623
let lit = radius.processor.get_literal(sets[ind]);
609624
if let Some(Word::Literal(address)) = lit {
610625
state.memory_write_value(&address, &value, (length / 8) as usize);

radius/src/memory.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ impl Memory {
490490
if length == 0 {
491491
return;
492492
}
493-
//let make_sym = self.blank && !self.check_permission(addr, length as u64, 'i');
493+
let make_sym = self.blank && !self.check_permission(addr, length as u64, 'i');
494494

495495
let size = READ_CACHE as u64;
496496
let mask = -1i64 as u64 ^ (size - 1);
@@ -504,6 +504,13 @@ impl Memory {
504504

505505
let mem = if let Some(m) = self.mem.get(&caddr) {
506506
m
507+
} else if make_sym {
508+
let mut vals = Vec::with_capacity(READ_CACHE);
509+
for i in 0..size {
510+
let sym_name = format!("mem_{:08x}", caddr+i);
511+
vals.push(Value::Symbolic(self.solver.bv(&sym_name, 8), 0));
512+
}
513+
self.mem.entry(caddr).or_insert(vals)
507514
} else {
508515
let bytes = self.r2api.read(caddr, READ_CACHE).unwrap();
509516
let vals = bytes.iter().map(|b| Value::Concrete(*b as u64, 0)).collect();

radius/src/processor.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::state::{
99
};
1010

1111
use crate::sims::syscall::syscall;
12-
use crate::sims::SimMethod;
12+
use crate::sims::{Sim, SimMethod};
1313

1414
use std::collections::BinaryHeap;
1515
use std::mem;
@@ -47,7 +47,7 @@ pub struct Processor {
4747
pub instructions: BTreeMap<u64, InstructionEntry>,
4848
pub hooks: HashMap<u64, Vec<HookMethod>>,
4949
pub esil_hooks: HashMap<u64, Vec<String>>,
50-
pub sims: HashMap<u64, SimMethod>,
50+
pub sims: HashMap<u64, Sim>,
5151
pub traps: HashMap<u64, SimMethod>,
5252
pub interrupts: HashMap<u64, SimMethod>,
5353
pub syscalls: HashMap<u64, Syscall>,
@@ -206,9 +206,8 @@ impl Processor {
206206

207207
/// print instruction if debug output is enabled
208208
pub fn print_instr(&self, state: &mut State, instr: &Instruction) {
209-
if self.sims.contains_key(&instr.offset) {
210-
let flag = state.r2api.cmd(&format!("fd @ {}", instr.offset)).unwrap_or_default();
211-
println!("\n0x{:08x} ( {} )\n", instr.offset, "simulated ".to_owned() + &flag.trim());
209+
if let Some(sim) = self.sims.get(&instr.offset) {
210+
println!("\n0x{:08x} ( {} )\n", instr.offset, "simulated ".to_owned() + &sim.symbol);
212211
} else if !self.color {
213212
println!(
214213
"0x{:08x} {:<40} | {}",
@@ -584,7 +583,7 @@ impl Processor {
584583
let cc = state.r2api.get_cc(pc).unwrap_or_default();
585584
let args = self.get_args(state, &cc);
586585

587-
let ret = sim(state, &args);
586+
let ret = (sim.function)(state, &args);
588587
state.registers.set_with_alias(cc.ret.as_str(), ret);
589588

590589
// don't ret if sim changes the PC value

radius/src/r2_api.rs

+11
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,17 @@ impl R2Api {
902902
self.cmd(format!("e {}={}", key, value).as_str())
903903
}
904904

905+
// is.j returns a weird format
906+
pub fn get_symbol(&mut self, addr: u64) -> R2Result<Symbol> {
907+
let json = self.cmd(&format!("is.j @ {}", addr))?;
908+
let result: Option<HashMap<String, Symbol>> = serde_json::from_str(json.as_str()).ok();
909+
if let Some(mut symmap) = result {
910+
Ok(symmap.remove("symbols").unwrap())
911+
} else {
912+
Err("symbol not found".to_owned())
913+
}
914+
}
915+
905916
pub fn get_symbols(&mut self) -> R2Result<Vec<Symbol>> {
906917
let json = self.cmd("isj")?;
907918
r2_result(serde_json::from_str(json.as_str()))

radius/src/radius.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::r2_api::{BasicBlock, FunctionInfo, Information, Instruction, R2Api, R
33
use crate::state::State;
44
//use crate::value::Value;
55
use crate::sims::syscall::indirect;
6-
use crate::sims::{get_sims, zero, SimMethod};
6+
use crate::sims::{get_sims, zero, SimMethod, Sim};
77
use crate::value::{vc, Value};
88

99
// use std::collections::VecDeque;
@@ -409,14 +409,18 @@ impl Radius {
409409
for sim in &sims {
410410
let addropt = symmap.remove(&sim.symbol);
411411
if let Some(addr) = addropt {
412-
processor.sims.insert(addr, sim.function);
412+
processor.sims.insert(addr, sim.to_owned());
413413
}
414414
}
415415

416416
if sim_all {
417-
for addr in symmap.values() {
418-
// we are gonna go with unconstrained by default
419-
processor.sims.insert(*addr, zero);
417+
for name in symmap.keys() {
418+
// we are gonna go with zero by default
419+
processor.sims.insert(symmap[name], Sim {
420+
symbol: name.to_owned(),
421+
function: zero,
422+
arguments: 0,
423+
});
420424
}
421425
}
422426
}
@@ -431,7 +435,7 @@ impl Radius {
431435
}
432436

433437
/// Register a `SimMethod` for the provided function address
434-
pub fn simulate(&mut self, addr: u64, sim: SimMethod) {
438+
pub fn simulate(&mut self, addr: u64, sim: Sim) {
435439
self.processor.sims.insert(addr, sim);
436440
}
437441

radius/src/sims/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod syscall;
88

99
pub type SimMethod = fn(&mut State, &[Value]) -> Value;
1010

11+
#[derive(Clone)]
1112
pub struct Sim {
1213
pub symbol: String,
1314
pub function: SimMethod,

radius/src/solver.rs

+9
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,15 @@ impl Solver {
124124
}
125125
}
126126
} else {
127+
// add exception for if(c, y, y) for concrete y
128+
if let Some(x) = if_val.as_u64() {
129+
if let Some(y) = else_val.as_u64() {
130+
if x == y {
131+
return Value::Concrete(if_val.as_u64().unwrap(),
132+
if_val.get_taint() | else_val.get_taint());
133+
}
134+
}
135+
}
127136
max_bit = 64;
128137
}
129138

radius/src/state.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -696,21 +696,18 @@ impl State {
696696
}
697697
}
698698

699-
let mut addrs = self.memory.addresses();
700-
addrs.sort_unstable();
701-
702-
let mut chunk: Vec<u8> = Vec::with_capacity(256);
703-
for (i, addr) in addrs.iter().enumerate() {
704-
let bval = self.memory.read_value(*addr, 1);
705-
let b = self.solver.evalcon_to_u64(&bval).unwrap() as u8;
706-
chunk.push(b);
707-
708-
if chunk.len() > 255 || i >= addrs.len() - 1 || addrs[i + 1] != addrs[i] + 1 {
709-
self.r2api
710-
.write(1 + addr - chunk.len() as u64, chunk.clone());
711-
chunk.clear();
712-
}
699+
let mut bvals = vec![Value::Concrete(0, 0); READ_CACHE];
700+
for addr in self.memory.addresses() {
701+
self.memory.read(addr, READ_CACHE, &mut bvals);
702+
let bytes: Vec<u8> = bvals
703+
.iter()
704+
.map(|bval| self.solver.evalcon_to_u64(&bval).unwrap() as u8)
705+
.collect();
706+
707+
self.r2api.write(addr, bytes.clone());
713708
}
709+
710+
// TODO: evaluate files and write to real FS? maybe a bad idea
714711
}
715712

716713
/// merges the argument state into self

0 commit comments

Comments
 (0)