Skip to content

Commit

Permalink
fix oracle
Browse files Browse the repository at this point in the history
  • Loading branch information
shouc committed Aug 22, 2023
1 parent 963aff0 commit 99fdcb5
Show file tree
Hide file tree
Showing 23 changed files with 372 additions and 278 deletions.
5 changes: 1 addition & 4 deletions cli/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,10 +371,6 @@ pub fn evm_main(args: EvmArgs) {
oracles.push(flashloan_oracle.clone());
}

if args.selfdestruct_oracle {
oracles.push(Rc::new(RefCell::new(SelfdestructOracle::new())));
}

if args.ierc20_oracle || args.pair_oracle {
producers.push(pair_producer);
}
Expand Down Expand Up @@ -553,6 +549,7 @@ pub fn evm_main(args: EvmArgs) {
panic_on_bug: args.panic_on_bug,
spec_id: args.spec_id,
typed_bug: args.typed_bug_oracle,
selfdestruct_bug: args.selfdestruct_oracle,
builder,
};

Expand Down
84 changes: 77 additions & 7 deletions src/evm/blaz/builder.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
use std::cell::RefCell;
use std::collections::HashMap;
use std::process::id;
use std::rc::Rc;
use std::thread::sleep;
use std::time::Duration;
use bytes::Bytes;
use libafl::impl_serdeany;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::evm::blaz::get_client;
use crate::evm::host::FuzzHost;
use crate::evm::input::{ConciseEVMInput, EVMInput};
use crate::evm::onchain::endpoints::Chain;
use crate::evm::srcmap::parser::{decode_instructions, SourceMapLocation};
use crate::evm::types::EVMAddress;
use crate::evm::types::{EVMAddress, EVMFuzzState, ProjectSourceMapTy};
use crate::evm::vm::{EVMExecutor, EVMState};
use crate::generic_vm::vm_executor::GenericVM;

#[derive(Clone)]
pub struct BuildJob {
Expand Down Expand Up @@ -102,9 +108,28 @@ pub struct BuildJobResult {
pub source_maps: String,
pub bytecodes: Bytes,
pub abi: String,

_cache_src_map: HashMap<usize, SourceMapLocation>,
_cached: bool
}

impl BuildJobResult {
pub fn new(
sources: Vec<(String, String)>,
source_maps: String,
bytecodes: Bytes,
abi: String,
) -> Self {
Self {
sources,
source_maps,
bytecodes,
abi,
_cache_src_map: Default::default(),
_cached: false,
}
}

pub fn from_json_url(url: String) -> Option<Self> {
let client = get_client();
let resp = client.get(&url)
Expand Down Expand Up @@ -132,19 +157,60 @@ impl BuildJobResult {
source_maps: sourcemap.to_string(),
bytecodes: Bytes::from(hex::decode(bytecode).expect("decode bytecode failed")),
abi: abi.to_string(),
_cache_src_map: Default::default(),
_cached: false,
})
}

pub fn from_artifact() -> Option<Self> {
None
}

pub fn get_sourcemap(&self, bytecode: Vec<u8>) -> HashMap<usize, SourceMapLocation> {
decode_instructions(
bytecode,
self.source_maps.clone(),
&self.sources.iter().map(|(name, _)| (name)).cloned().collect()
)
pub fn get_sourcemap(&mut self, bytecode: Vec<u8>) -> HashMap<usize, SourceMapLocation> {
if self._cached {
return self._cache_src_map.clone();
} else {
let result = decode_instructions(
bytecode,
self.source_maps.clone(),
&self.sources.iter().map(|(name, _)| (name)).cloned().collect()
);
self._cache_src_map = result.clone();
self._cached = true;
return result;
}
}

pub fn get_sourcemap_executor<VS, Addr, Code, By, Loc, SlotTy, Out, I, S: 'static, CI>(
_self: Option<&mut Self>,
executor: &mut Rc<RefCell<dyn GenericVM<VS, Code, By, Loc, Addr, SlotTy, Out, I, S, CI>>>,
addr: &EVMAddress,
additional_sourcemap: &ProjectSourceMapTy,
pc: usize,
) -> Option<SourceMapLocation> {
if let Some(_self) = _self {
if _self._cached {
return _self._cache_src_map.get(&pc).cloned();
}

let bytecode = Vec::from((**executor)
.borrow_mut()
.as_any()
.downcast_ref::<EVMExecutor<EVMInput, EVMFuzzState, EVMState, ConciseEVMInput>>()
.unwrap()
.host
.code
.get(addr)
.unwrap()
.clone()
.bytecode());
return _self.get_sourcemap(bytecode).get(&pc).cloned();
}

if let Some(Some(srcmap)) = additional_sourcemap.get(addr) {
return srcmap.get(&pc).cloned();
}
None
}
}

Expand All @@ -167,6 +233,10 @@ impl ArtifactInfoMetadata {
pub fn get(&self, addr: &EVMAddress) -> Option<&BuildJobResult> {
self.info.get(addr)
}

pub fn get_mut(&mut self, addr: &EVMAddress) -> Option<&mut BuildJobResult> {
self.info.get_mut(addr)
}
}

impl_serdeany!(ArtifactInfoMetadata);
Expand Down
10 changes: 5 additions & 5 deletions src/evm/blaz/offchain_artifacts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,12 @@ impl OffChainArtifact {
let contract_artifact = &existing_artifacts[candidates[selected_idx].0].contracts[&candidates[selected_idx].1];
let sources = existing_artifacts[candidates[selected_idx].0].sources.clone();

Some(BuildJobResult {
Some(BuildJobResult::new(
sources,
source_maps: contract_artifact.source_map.clone(),
bytecodes: contract_artifact.deploy_bytecode.clone(),
abi: contract_artifact.abi.clone(),
})
contract_artifact.source_map.clone(),
contract_artifact.deploy_bytecode.clone(),
contract_artifact.abi.clone(),
))
}
}

Expand Down
1 change: 1 addition & 0 deletions src/evm/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,6 @@ pub struct Config<VS, Addr, Code, By, Loc, SlotTy, Out, I, S, CI> {
pub spec_id: String,
pub only_fuzz: HashSet<EVMAddress>,
pub typed_bug: bool,
pub selfdestruct_bug: bool,
pub builder: Option<BuildJob>,
}
10 changes: 5 additions & 5 deletions src/evm/contract_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,12 +476,12 @@ impl ContractLoader {
constructor_args,
deployed_address: contract_info.address,
source_map: None,
build_artifact: Some(BuildJobResult {
build_artifact: Some(BuildJobResult::new(
sources,
source_maps: more_info.source_map,
bytecodes: more_info.deploy_bytecode,
abi: more_info.abi.clone(),
})
more_info.source_map,
more_info.deploy_bytecode,
more_info.abi.clone(),
))
})
}

Expand Down
8 changes: 6 additions & 2 deletions src/evm/corpus_initializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,12 @@ impl<'a> EVMCorpusInitializer<'a> {
contract.deployed_address,
Bytecode::new_raw(Bytes::from(code))
);
artifacts.address_to_name.insert(contract.deployed_address,
contract.name.clone().trim_end_matches('*').to_string());

let mut name = contract.name.clone().trim_end_matches('*').to_string();
if name != format!("{:?}", contract.deployed_address) {
name = format!("{}({:?})", name, contract.deployed_address.clone());
}
artifacts.address_to_name.insert(contract.deployed_address, name);

if let Some(build_artifact) = &contract.build_artifact {
artifacts.build_artifacts.insert(contract.deployed_address, build_artifact.clone());
Expand Down
13 changes: 10 additions & 3 deletions src/evm/cov_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,26 @@ impl<EM, Z, OT> Stage<EVMFuzzExecutor<OT>, EM, EVMFuzzState, Z> for CoverageStag
corpus_idx: usize
) -> Result<(), Error> {
let total = state.corpus().count();
if self.last_corpus_idx == total {
return Ok(());
}

let mut exec = self.executor.deref().borrow_mut();
exec.host.add_middlewares(self.call_printer.clone());

let meta = state.metadata().get::<BugMetadata>().unwrap();
let meta = state.metadata().get::<BugMetadata>().unwrap().clone();
for i in self.last_corpus_idx..total {
self.call_printer.deref().borrow_mut().cleanup();
let testcase = state.corpus().get(i).unwrap().borrow().clone();
let input = testcase.input().as_ref().expect("Input should be present");
unsafe { EVAL_COVERAGE = true; }
exec.execute(input, state);
self.call_printer.deref().borrow_mut().save_trace(format!("{}/{}", self.trace_dir, i).as_str());
if let Some(bug_idx) = meta.corpus_idx_to_bug.get(&i).is_some() {
fs::copy(format!("{}/{}", self.trace_dir, i), format!("{}/bug_{}", self.trace_dir, bug_idx)).unwrap();
if let Some(bug_idx) = meta.corpus_idx_to_bug.get(&i) {

for id in bug_idx {
fs::copy(format!("{}/{}.json", self.trace_dir, i), format!("{}/bug_{}.json", self.trace_dir, id)).unwrap();
}
}
unsafe { EVAL_COVERAGE = false; }
}
Expand Down
13 changes: 8 additions & 5 deletions src/evm/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ where
// set_code data
pub setcode_data: HashMap<EVMAddress, Bytecode>,
// selftdestruct
pub selfdestruct_hit:bool,
pub current_self_destructs: Vec<(EVMAddress, usize)>,
// relations file handle
relations_file: std::fs::File,
// Filter duplicate relations
Expand Down Expand Up @@ -214,7 +214,7 @@ where
#[cfg(feature = "print_logs")]
logs: Default::default(),
setcode_data:self.setcode_data.clone(),
selfdestruct_hit:self.selfdestruct_hit,
current_self_destructs: self.current_self_destructs.clone(),
relations_file: self.relations_file.try_clone().unwrap(),
relations_hash: self.relations_hash.clone(),
current_typed_bug: self.current_typed_bug.clone(),
Expand Down Expand Up @@ -269,7 +269,7 @@ where
#[cfg(feature = "print_logs")]
logs: Default::default(),
setcode_data:HashMap::new(),
selfdestruct_hit:false,
current_self_destructs: Default::default(),
relations_file: std::fs::File::create(format!("{}/relations.log", workdir)).unwrap(),
relations_hash: HashSet::new(),
current_typed_bug: Default::default(),
Expand Down Expand Up @@ -468,7 +468,9 @@ where
if funtion_hash.len() < 0x4 {
return;
}
let cur_write_str = format!("{{caller:0x{} --> traget:0x{} function(0x{})}}\n", hex::encode(caller), hex::encode(target), hex::encode(&funtion_hash[..4]));
let cur_write_str = format!("{{caller:0x{} --> target:0x{} function(0x{})}}\n",
hex::encode(caller),
hex::encode(target), hex::encode(&funtion_hash[..4]));
let mut hasher = DefaultHasher::new();
cur_write_str.hash(&mut hasher);
let cur_wirte_hash = hasher.finish();
Expand Down Expand Up @@ -925,7 +927,7 @@ where
}
self._pc = interp.program_counter();
}
0xf0 | 0xf5 | 0xa0..=0xa4 => {
0xf0 | 0xf5 | 0xa0..=0xa4 | 0xff => {
// CREATE, CREATE2
self._pc = interp.program_counter();
}
Expand Down Expand Up @@ -1059,6 +1061,7 @@ where
}

fn selfdestruct(&mut self, _address: EVMAddress, _target: EVMAddress) -> Option<SelfDestructResult> {
self.current_self_destructs.push((_address, self._pc));
return Some(SelfDestructResult::default());
}

Expand Down
Loading

0 comments on commit 99fdcb5

Please sign in to comment.