Skip to content

Commit

Permalink
handle instrinc tx value (real_balance) (#250)
Browse files Browse the repository at this point in the history
* handle instrinc tx

* feature real_balance

* Update Cargo.toml

* remove debug print

fix #237
  • Loading branch information
0xAWM authored Oct 12, 2023
1 parent d30a166 commit 9fa074c
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 94 deletions.
16 changes: 13 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ edition = "2021"
criterion = "0.4.0"

[features]
default = ["cmp", "dataflow", "evm", "print_txn_corpus", "full_trace"]
default = [
"cmp",
"dataflow",
"evm",
"print_txn_corpus",
"full_trace"
]
evm = []
cmp = []
dataflow = []
Expand Down Expand Up @@ -89,9 +95,13 @@ revm-interpreter = { git = "https://github.com/fuzzland/revm", rev = "f9fdf3e66f
heimdall = { git = "https://github.com/fuzzland/heimdall-rs", rev = "32363c9c59cf14c6839e48e5548cc862dfc54842" }

move-binary-format = { git = "https://github.com/fuzzland/ityfuzz-sui-fork.git", package = "move-binary-format", optional = true }
move-core-types = { git = "https://github.com/fuzzland/ityfuzz-sui-fork.git", package = "move-core-types", features = ["address32"], optional = true }
move-core-types = { git = "https://github.com/fuzzland/ityfuzz-sui-fork.git", package = "move-core-types", features = [
"address32",
], optional = true }
move-stdlib = { git = "https://github.com/fuzzland/ityfuzz-sui-fork.git", package = "move-stdlib", optional = true }
move-vm-runtime = { git = "https://github.com/fuzzland/ityfuzz-sui-fork.git", package = "move-vm-runtime", features = ["lazy_natives"], optional = true }
move-vm-runtime = { git = "https://github.com/fuzzland/ityfuzz-sui-fork.git", package = "move-vm-runtime", features = [
"lazy_natives",
], optional = true }
move-vm-types = { git = "https://github.com/fuzzland/ityfuzz-sui-fork.git", package = "move-vm-types", optional = true }
sui-move-natives-latest = { git = "https://github.com/fuzzland/ityfuzz-sui-fork.git", package = "sui-move-natives-latest", optional = true }
sui-protocol-config = { git = "https://github.com/fuzzland/ityfuzz-sui-fork.git", package = "sui-protocol-config", optional = true }
Expand Down
1 change: 0 additions & 1 deletion src/evm/contract_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ impl ContractLoader {
}

pub fn parse_abi_str(data: &str) -> Vec<ABIConfig> {
println!("Parsing ABI: {}", data);
let json: Vec<Value> = serde_json::from_str(data).expect("failed to parse abis file");
json.iter()
.flat_map(|abi| {
Expand Down
99 changes: 55 additions & 44 deletions src/evm/feedbacks.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
use std::borrow::BorrowMut;
use std::cell::RefCell;
use std::fmt::{Debug, Formatter};
use std::ops::Deref;
use std::rc::Rc;
use libafl::Error;
use libafl::events::EventFirer;
use libafl::executors::ExitKind;
use libafl::feedbacks::Feedback;
use libafl::observers::ObserversTuple;
use libafl::prelude::{HasCorpus, HasMetadata, HasRand, State, UsesInput, Input, Testcase};
use libafl::schedulers::Scheduler;
use libafl_bolts::Named;
use libafl::state::HasClientPerfMonitor;
use crate::evm::input::{ConciseEVMInput, EVMInputT};
use crate::evm::middlewares::sha3_bypass::Sha3TaintAnalysis;
use crate::evm::types::EVMAddress;
use crate::evm::vm::EVMExecutor;
use crate::generic_vm::vm_state::VMStateT;
use crate::input::VMInputT;
use crate::state::{HasCaller, HasCurrentInputIdx, HasItyState};
use libafl::events::EventFirer;
use libafl::executors::ExitKind;
use libafl::feedbacks::Feedback;
use libafl::observers::ObserversTuple;
use libafl::prelude::{HasCorpus, HasMetadata, HasRand, Input, State, Testcase, UsesInput};
use libafl::schedulers::Scheduler;
use libafl::state::HasClientPerfMonitor;
use libafl::Error;
use libafl_bolts::Named;
use std::cell::RefCell;
use std::fmt::{Debug, Formatter};
use std::ops::Deref;
use std::rc::Rc;

/// A wrapper around a feedback that also performs sha3 taint analysis
/// when the feedback is interesting.
Expand All @@ -38,33 +37,42 @@ where

impl<I, S, VS, F, SC> Feedback<S> for Sha3WrappedFeedback<I, S, VS, F, SC>
where
S: State + HasRand
+ HasCorpus
+ HasItyState<EVMAddress, EVMAddress, VS, ConciseEVMInput>
+ HasMetadata
+ HasCaller<EVMAddress>
+ HasCurrentInputIdx
+ HasClientPerfMonitor
+ Default
+ Clone
+ Debug
+ UsesInput<Input = I>
+ 'static,
S: State
+ HasRand
+ HasCorpus
+ HasItyState<EVMAddress, EVMAddress, VS, ConciseEVMInput>
+ HasMetadata
+ HasCaller<EVMAddress>
+ HasCurrentInputIdx
+ HasClientPerfMonitor
+ Default
+ Clone
+ Debug
+ UsesInput<Input = I>
+ 'static,
I: VMInputT<VS, EVMAddress, EVMAddress, ConciseEVMInput> + EVMInputT + 'static,
VS: VMStateT + 'static,
F: Feedback<S>,
SC: Scheduler<State = S> + Clone + 'static,
{
fn is_interesting<EM, OT>(&mut self,
state: &mut S,
manager: &mut EM,
input: &S::Input,
observers: &OT,
exit_kind: &ExitKind)
-> Result<bool, Error> where EM: EventFirer<State = S>, OT: ObserversTuple<S> {
fn is_interesting<EM, OT>(
&mut self,
state: &mut S,
manager: &mut EM,
input: &S::Input,
observers: &OT,
exit_kind: &ExitKind,
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
{
// checks if the inner feedback is interesting
if self.enabled {
match self.inner_feedback.is_interesting(state, manager, input, observers, exit_kind) {
match self
.inner_feedback
.is_interesting(state, manager, input, observers, exit_kind)
{
Ok(true) => {
if !input.is_step() {
// reexecute with sha3 taint analysis
Expand All @@ -77,12 +85,13 @@ where
);
}
Ok(true)
},
}
Ok(false) => Ok(false),
Err(e) => Err(e)
Err(e) => Err(e),
}
} else {
self.inner_feedback.is_interesting(state, manager, input, observers, exit_kind)
self.inner_feedback
.is_interesting(state, manager, input, observers, exit_kind)
}
}

Expand All @@ -97,11 +106,12 @@ where
where
OT: ObserversTuple<S>,
{
self.inner_feedback.as_mut().append_metadata(state, observers, testcase)
self.inner_feedback
.as_mut()
.append_metadata(state, observers, testcase)
}
}


impl<I, S, VS, F, SC> Sha3WrappedFeedback<I, S, VS, F, SC>
where
S: State + HasCorpus + HasCaller<EVMAddress> + Debug + Clone + HasClientPerfMonitor + 'static,
Expand All @@ -110,16 +120,17 @@ where
F: Feedback<S>,
SC: Scheduler<State = S> + Clone,
{
pub(crate) fn new(inner_feedback: F,
sha3_taints: Rc<RefCell<Sha3TaintAnalysis>>,
evm_executor: Rc<RefCell<EVMExecutor<I, S, VS, ConciseEVMInput, SC>>>,
enabled: bool
pub(crate) fn new(
inner_feedback: F,
sha3_taints: Rc<RefCell<Sha3TaintAnalysis>>,
evm_executor: Rc<RefCell<EVMExecutor<I, S, VS, ConciseEVMInput, SC>>>,
enabled: bool,
) -> Self {
Self {
inner_feedback: Box::new(inner_feedback),
sha3_taints,
evm_executor,
enabled
enabled,
}
}
}
Expand Down
68 changes: 48 additions & 20 deletions src/evm/types.rs
Original file line number Diff line number Diff line change
@@ -1,58 +1,84 @@
use std::collections::HashMap;
/// Common generic types for EVM fuzzing
use crate::evm::input::{ConciseEVMInput, EVMInput};
use crate::evm::mutator::FuzzMutator;
use crate::evm::vm::{EVMState, EVMExecutor};
use crate::evm::vm::{EVMExecutor, EVMState};
use std::collections::HashMap;

use crate::evm::srcmap::parser::SourceMapLocation;
use crate::executor::FuzzExecutor;
use crate::generic_vm::vm_executor::ExecutionResult;
use crate::oracle::OracleCtx;
use crate::scheduler::SortedDroppingScheduler;
use crate::state::{FuzzState, InfantStateState};
use crate::state_input::StagedVMState;
use bytes::Bytes;
use libafl::prelude::HasRand;
use libafl::schedulers::QueueScheduler;
use primitive_types::{H160, H256};
use revm_primitives::{B160, Bytecode, U256};
use libafl_bolts::bolts_prelude::{Rand, RomuDuoJrRand};
use primitive_types::{H160, H256};
use revm_primitives::ruint::aliases::U512;
use crate::evm::srcmap::parser::SourceMapLocation;
use crate::executor::FuzzExecutor;
use crate::generic_vm::vm_executor::ExecutionResult;
use revm_primitives::{Bytecode, B160, U256};

pub type EVMAddress = B160;
pub type EVMU256 = U256;
pub type EVMU512 = U512;
pub type EVMFuzzState = FuzzState<EVMInput, EVMState, EVMAddress, EVMAddress, Vec<u8>, ConciseEVMInput>;
pub type EVMOracleCtx<'a> =
OracleCtx<'a, EVMState, EVMAddress, Bytecode, Bytes, EVMAddress, EVMU256, Vec<u8>, EVMInput, EVMFuzzState, ConciseEVMInput>;
pub type EVMFuzzState =
FuzzState<EVMInput, EVMState, EVMAddress, EVMAddress, Vec<u8>, ConciseEVMInput>;
pub type EVMOracleCtx<'a> = OracleCtx<
'a,
EVMState,
EVMAddress,
Bytecode,
Bytes,
EVMAddress,
EVMU256,
Vec<u8>,
EVMInput,
EVMFuzzState,
ConciseEVMInput,
>;
pub type EVMFuzzMutator<'a> = FuzzMutator<
EVMState,
EVMAddress,
EVMAddress,
SortedDroppingScheduler<InfantStateState<EVMAddress, EVMAddress, EVMState, ConciseEVMInput>>,
ConciseEVMInput
ConciseEVMInput,
>;

pub type EVMInfantStateState = InfantStateState<EVMAddress, EVMAddress, EVMState, ConciseEVMInput>;

pub type EVMStagedVMState = StagedVMState<EVMAddress, EVMAddress, EVMState, ConciseEVMInput>;

pub type EVMExecutionResult = ExecutionResult<EVMAddress, EVMAddress, EVMState, Vec<u8>, ConciseEVMInput>;
pub type EVMExecutionResult =
ExecutionResult<EVMAddress, EVMAddress, EVMState, Vec<u8>, ConciseEVMInput>;

pub type ProjectSourceMapTy = HashMap<EVMAddress, Option<HashMap<usize, SourceMapLocation>>>;

pub type EVMFuzzExecutor<OT> = FuzzExecutor<EVMState, EVMAddress, Bytecode, Bytes, EVMAddress, EVMU256, Vec<u8>, EVMInput, EVMFuzzState, OT, ConciseEVMInput>;
pub type EVMFuzzExecutor<OT> = FuzzExecutor<
EVMState,
EVMAddress,
Bytecode,
Bytes,
EVMAddress,
EVMU256,
Vec<u8>,
EVMInput,
EVMFuzzState,
OT,
ConciseEVMInput,
>;

pub type EVMQueueExecutor = EVMExecutor<EVMInput, EVMFuzzState, EVMState, ConciseEVMInput, QueueScheduler<EVMFuzzState>>;
pub type EVMQueueExecutor =
EVMExecutor<EVMInput, EVMFuzzState, EVMState, ConciseEVMInput, QueueScheduler<EVMFuzzState>>;

/// convert array of 20x u8 to H160
pub fn convert_H160(v: [u8; 20]) -> H160 {
return v.into();
v.into()
}

/// convert U256 to H160 by taking the last 20 bytes
pub fn convert_u256_to_h160(v: EVMU256) -> EVMAddress {
let mut data: [u8; 32] = v.to_be_bytes();
let data: [u8; 32] = v.to_be_bytes();
EVMAddress::from_slice(&data[12..32])
}

Expand All @@ -67,10 +93,12 @@ pub fn float_scale_to_u512(v: f64, decimals: u32) -> U512 {
}

/// Generate a random H160 address.
pub fn generate_random_address<S>(s: &mut S) -> EVMAddress where S: HasRand{
pub fn generate_random_address<S>(s: &mut S) -> EVMAddress
where
S: HasRand,
{
let mut rand_seed: RomuDuoJrRand = RomuDuoJrRand::with_seed(s.rand_mut().next());
let mut address = EVMAddress::random_using(&mut rand_seed);
address
EVMAddress::random_using(&mut rand_seed)
}

/// Generate a fixed H160 address from a hex string.
Expand All @@ -85,7 +113,6 @@ pub fn is_zero(v: EVMU256) -> bool {
v == EVMU256::ZERO
}


/// As u64
pub fn as_u64(v: EVMU256) -> u64 {
v.as_limbs()[0]
Expand All @@ -98,6 +125,7 @@ pub fn bytes_to_u64(v: &[u8]) -> u64 {
u64::from_be_bytes(data)
}

#[cfg(test)]
mod tests {
use crate::evm::types::{as_u64, EVMU256};

Expand Down
Loading

0 comments on commit 9fa074c

Please sign in to comment.