Skip to content

Commit

Permalink
feat(decompile): use run_with_timeout for symbolic execution
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon-Becker committed Dec 30, 2023
1 parent 8836d20 commit feb7834
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 6 deletions.
2 changes: 1 addition & 1 deletion common/src/ether/evm/ext/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::{
};
use std::collections::HashMap;

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Default)]
pub struct VMTrace {
pub instruction: u128,
pub gas_used: u128,
Expand Down
39 changes: 34 additions & 5 deletions core/src/decompile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ pub mod precompile;
pub mod resolve;
pub mod util;
use heimdall_common::{
debug_max, ether::bytecode::get_bytecode_from_target, utils::strings::get_shortned_target,
debug_max,
ether::{bytecode::get_bytecode_from_target, evm::ext::exec::VMTrace},
utils::{strings::get_shortned_target, threading::run_with_timeout},
};

use crate::{
Expand Down Expand Up @@ -80,6 +82,10 @@ pub struct DecompilerArgs {
/// The name for the output file
#[clap(long, short, default_value = "", hide_default_value = true)]
pub name: String,

/// The timeout for each function's symbolic execution in milliseconds.
#[clap(long, short, default_value = "10000", hide_default_value = true)]
pub timeout: u64,
}

impl DecompilerArgsBuilder {
Expand All @@ -94,6 +100,7 @@ impl DecompilerArgsBuilder {
include_yul: Some(false),
output: Some(String::new()),
name: Some(String::new()),
timeout: Some(10000),
}
}
}
Expand Down Expand Up @@ -252,8 +259,22 @@ pub async fn decompile(
);

// get a map of possible jump destinations
let (map, jumpdest_count) =
&evm.clone().symbolic_exec_selector(&selector, function_entry_point);
let mut evm_clone = evm.clone();
let selector_clone = selector.clone();
let (map, jumpdest_count) = match run_with_timeout(
move || evm_clone.symbolic_exec_selector(&selector_clone, function_entry_point),
Duration::from_millis(args.timeout),
) {
Some(map) => map,
None => {
trace.add_error(
func_analysis_trace,
line!(),
&format!("symbolic execution timed out!"),
);
(VMTrace::default(), 0)
}
};

trace.add_debug(
func_analysis_trace,
Expand All @@ -276,7 +297,7 @@ pub async fn decompile(
if args.include_yul {
debug_max!("analyzing symbolic execution trace '0x{}' with yul analyzer", selector);
analyzed_function = analyze_yul(
map,
&map,
Function {
selector: selector.clone(),
entry_point: function_entry_point,
Expand All @@ -301,7 +322,7 @@ pub async fn decompile(
} else {
debug_max!("analyzing symbolic execution trace '0x{}' with sol analyzer", selector);
analyzed_function = analyze_sol(
map,
&map,
Function {
selector: selector.clone(),
entry_point: function_entry_point,
Expand All @@ -326,6 +347,14 @@ pub async fn decompile(
);
}

// add notice to analyzed_function if jumpdest_count == 0, indicating that
// symbolic execution timed out
if jumpdest_count == 0 {
analyzed_function
.notices
.push("symbolic execution timed out. please report this!".to_string());
}

let argument_count = analyzed_function.arguments.len();

if argument_count != 0 {
Expand Down
10 changes: 10 additions & 0 deletions core/tests/test_decompile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod benchmark {
include_yul: false,
output: String::from(""),
name: String::from(""),
timeout: 10000,
};
let _ = heimdall_core::decompile::decompile(args).await;
}
Expand All @@ -38,6 +39,7 @@ mod benchmark {
include_yul: false,
output: String::from(""),
name: String::from(""),
timeout: 10000,
};
let _ = heimdall_core::decompile::decompile(args).await;
}
Expand All @@ -58,6 +60,7 @@ mod benchmark {
include_yul: true,
output: String::from(""),
name: String::from(""),
timeout: 10000,
};
let _ = heimdall_core::decompile::decompile(args).await;
}
Expand All @@ -78,6 +81,7 @@ mod benchmark {
include_yul: true,
output: String::from(""),
name: String::from(""),
timeout: 10000,
};
let _ = heimdall_core::decompile::decompile(args).await;
}
Expand All @@ -98,6 +102,7 @@ mod benchmark {
include_yul: false,
output: String::from(""),
name: String::from(""),
timeout: 10000,
};
let _ = heimdall_core::decompile::decompile(args).await;
}
Expand All @@ -118,6 +123,7 @@ mod benchmark {
include_yul: false,
output: String::from(""),
name: String::from(""),
timeout: 10000,
};
let _ = heimdall_core::decompile::decompile(args).await;
}
Expand All @@ -144,6 +150,7 @@ mod integration_tests {
include_yul: false,
output: String::from(""),
name: String::from(""),
timeout: 10000,
})
.await
.unwrap();
Expand Down Expand Up @@ -173,6 +180,7 @@ mod integration_tests {
include_yul: false,
output: String::from(""),
name: String::from(""),
timeout: 10000,
})
.await
.unwrap();
Expand Down Expand Up @@ -209,6 +217,7 @@ mod integration_tests {
include_yul: false,
output: String::from(""),
name: String::from(""),
timeout: 10000,
})
.await
.unwrap();
Expand Down Expand Up @@ -322,6 +331,7 @@ mod integration_tests {
include_yul: false,
output: String::from(""),
name: String::from(""),
timeout: 10000,
})
.await
.unwrap();
Expand Down

0 comments on commit feb7834

Please sign in to comment.