From 1a20b3de6756156aea5ecc2bfbde5daaee122c23 Mon Sep 17 00:00:00 2001 From: Jon-Becker Date: Wed, 16 Oct 2024 11:19:16 -0400 Subject: [PATCH] wip --- crates/decompile/src/interfaces/function.rs | 1 + .../decompile/src/utils/heuristics/extcall.rs | 37 ++++++++++--------- .../src/utils/heuristics/solidity.rs | 11 +++--- crates/decompile/src/utils/heuristics/yul.rs | 7 ++-- 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/crates/decompile/src/interfaces/function.rs b/crates/decompile/src/interfaces/function.rs index 5a1a3ff0..64f0367d 100644 --- a/crates/decompile/src/interfaces/function.rs +++ b/crates/decompile/src/interfaces/function.rs @@ -61,6 +61,7 @@ pub struct AnalyzedFunction { #[derive(Clone, Debug)] pub struct StorageFrame { pub operation: WrappedOpcode, + pub value: U256, } #[derive(Clone, Debug)] diff --git a/crates/decompile/src/utils/heuristics/extcall.rs b/crates/decompile/src/utils/heuristics/extcall.rs index e245989d..f24d51e0 100644 --- a/crates/decompile/src/utils/heuristics/extcall.rs +++ b/crates/decompile/src/utils/heuristics/extcall.rs @@ -1,6 +1,9 @@ use alloy::primitives::U256; use alloy_dyn_abi::{DynSolType, DynSolValue}; -use heimdall_common::utils::strings::encode_hex_reduced; +use heimdall_common::utils::{ + hex::ToLowerHex, + strings::{encode_hex, encode_hex_reduced}, +}; use heimdall_vm::core::{opcodes::opcode_name, vm::State}; use crate::{ @@ -21,7 +24,12 @@ pub fn extcall_heuristic( let gas = format!("gas: {}", instruction.input_operations[0].solidify()); let address = instruction.input_operations[1].solidify(); let value = format!("value: {}", instruction.input_operations[2].solidify()); - let calldata = function.get_memory_range(instruction.inputs[3], instruction.inputs[4]); + let memory = function.get_memory_range(instruction.inputs[3], instruction.inputs[4]); + let extcalldata = memory + .iter() + .map(|x| x.value.to_lower_hex().trim_start_matches("0x").to_owned()) + .collect::>() + .join(""); // build the modifier w/ gas and value let modifier = format!("{{ {}, {} }}", gas, value); @@ -29,7 +37,7 @@ pub fn extcall_heuristic( // check if the external call is a precompiled contract match decode_precompile( instruction.inputs[1], - &calldata, + &memory, &instruction.input_operations[5], ) { (true, precompile_logic) => { @@ -38,13 +46,7 @@ pub fn extcall_heuristic( _ => { function.logic.push(format!( "(bool success, bytes memory ret0) = address({}).call{}(abi.encode({}));", - address, - modifier, - calldata - .iter() - .map(|x| x.operation.solidify()) - .collect::>() - .join(", ") + address, modifier, extcalldata )); } } @@ -54,7 +56,12 @@ pub fn extcall_heuristic( 0xfa | 0xf4 => { let gas = format!("gas: {}", instruction.input_operations[0].solidify()); let address = instruction.input_operations[1].solidify(); - let calldata = function.get_memory_range(instruction.inputs[2], instruction.inputs[3]); + let memory = function.get_memory_range(instruction.inputs[2], instruction.inputs[3]); + let extcalldata = memory + .iter() + .map(|x| x.value.to_lower_hex().trim_start_matches("0x").to_owned()) + .collect::>() + .join(""); // build the modifier w/ gas let modifier = format!("{{ {} }}", gas); @@ -62,7 +69,7 @@ pub fn extcall_heuristic( // check if the external call is a precompiled contract match decode_precompile( instruction.inputs[1], - &calldata, + &memory, &instruction.input_operations[4], ) { (true, precompile_logic) => { @@ -74,11 +81,7 @@ pub fn extcall_heuristic( address, opcode_name(instruction.opcode).to_lowercase(), modifier, - calldata - .iter() - .map(|x| x.operation.solidify()) - .collect::>() - .join(", ") + extcalldata )); } } diff --git a/crates/decompile/src/utils/heuristics/solidity.rs b/crates/decompile/src/utils/heuristics/solidity.rs index e467f7cc..c508c861 100644 --- a/crates/decompile/src/utils/heuristics/solidity.rs +++ b/crates/decompile/src/utils/heuristics/solidity.rs @@ -68,10 +68,11 @@ pub fn solidity_heuristic( // MSTORE / MSTORE8 0x52 | 0x53 => { let key = instruction.inputs[0]; + let value = instruction.inputs[1]; let operation = instruction.input_operations[1].to_owned(); // add the mstore to the function's memory map - function.memory.insert(key, StorageFrame { operation }); + function.memory.insert(key, StorageFrame { operation, value }); function.logic.push(format!( "memory[{}] = {};", encode_hex_reduced(key), @@ -95,10 +96,10 @@ pub fn solidity_heuristic( // perform a series of checks to determine if the condition // is added by the compiler and can be ignored - if (conditional.contains("msg.data.length") && conditional.contains("0x04")) || - VARIABLE_SIZE_CHECK_REGEX.is_match(&conditional).unwrap_or(false) || - (conditional.replace('!', "") == "success") || - (conditional == "!msg.value") + if (conditional.contains("msg.data.length") && conditional.contains("0x04")) + || VARIABLE_SIZE_CHECK_REGEX.is_match(&conditional).unwrap_or(false) + || (conditional.replace('!', "") == "success") + || (conditional == "!msg.value") { return Ok(()); } diff --git a/crates/decompile/src/utils/heuristics/yul.rs b/crates/decompile/src/utils/heuristics/yul.rs index cdbbeeb8..352f4eb4 100644 --- a/crates/decompile/src/utils/heuristics/yul.rs +++ b/crates/decompile/src/utils/heuristics/yul.rs @@ -18,10 +18,11 @@ pub fn yul_heuristic( // MSTORE / MSTORE8 0x52 | 0x53 => { let key = instruction.inputs[0]; + let value = instruction.inputs[1]; let operation = instruction.input_operations[1].clone(); // add the mstore to the function's memory map - function.memory.insert(key, StorageFrame { operation }); + function.memory.insert(key, StorageFrame { operation, value }); function.logic.push(format!( "{}({}, {})", opcode_name(instruction.opcode).to_lowercase(), @@ -76,8 +77,8 @@ pub fn yul_heuristic( // CALLDATACOPY, CODECOPY, EXTCODECOPY, RETURNDATACOPY, TSTORE, // SSTORE, RETURN, SELFDESTRUCT, LOG0, LOG1, LOG2, LOG3, LOG4 // we simply want to add the operation to the function's logic - 0x37 | 0x39 | 0x3c | 0x3e | 0x55 | 0x5d | 0xf0 | 0xf1 | 0xf2 | 0xf4 | 0xf5 | 0xfa | - 0xff | 0xA0 | 0xA1 | 0xA2 | 0xA3 | 0xA4 => { + 0x37 | 0x39 | 0x3c | 0x3e | 0x55 | 0x5d | 0xf0 | 0xf1 | 0xf2 | 0xf4 | 0xf5 | 0xfa + | 0xff | 0xA0 | 0xA1 | 0xA2 | 0xA3 | 0xA4 => { function.logic.push(format!( "{}({})", opcode_name(instruction.opcode).to_lowercase(),