Implement returndatacopy and returndatasize

Also includes a few minor bugfixes
pull/870/head
Nathan 6 years ago
parent 1a7d8c679c
commit 0c242a0823
  1. 6
      mythril/analysis/report.py
  2. 57
      mythril/laser/ethereum/instructions.py

@ -38,7 +38,11 @@ class Issue:
try:
keccak = sha3.keccak_256()
keccak.update(bytes.fromhex(bytecode))
keccak.update(
bytes.fromhex(bytecode[2:])
if bytecode[:2] == "0x"
else bytes.fromhex(bytecode)
)
self.bytecode_hash = "0x" + keccak.hexdigest()
except ValueError:
log.debug(

@ -802,15 +802,58 @@ class Instruction:
@StateTransition()
def returndatacopy_(self, global_state: GlobalState) -> List[GlobalState]:
# FIXME: not implemented
state = global_state.mstate
start, s2, size = state.stack.pop(), state.stack.pop(), state.stack.pop()
memory_offset, return_offset, size = (
state.stack.pop(),
state.stack.pop(),
state.stack.pop(),
)
try:
concrete_memory_offset = helper.get_concrete_int(memory_offset)
except TypeError:
log.debug("Unsupported symbolic memory offset in RETURNDATACOPY")
return [global_state]
try:
concrete_return_offset = helper.get_concrete_int(return_offset)
except TypeError:
log.debug("Unsupported symbolic return offset in RETURNDATACOPY")
try:
concrete_size = helper.get_concrete_int(size)
except TypeError:
log.debug("Unsupported symbolic max_length offset in RETURNDATACOPY")
if (
concrete_size is None
or global_state.last_return_data is None
or concrete_return_offset is None
):
return [global_state]
global_state.mstate.mem_extend(concrete_memory_offset, concrete_size)
for i in range(concrete_size):
global_state.mstate.memory[concrete_memory_offset + i] = (
global_state.last_return_data[concrete_return_offset + i]
if i < len(global_state.last_return_data)
else 0
)
return [global_state]
@StateTransition()
def returndatasize_(self, global_state: GlobalState) -> List[GlobalState]:
global_state.mstate.stack.append(global_state.new_bitvec("returndatasize", 256))
if global_state.last_return_data is None:
log.debug(
"No last_return_data found, adding an unconstrained bitvec to the stack"
)
global_state.mstate.stack.append(
global_state.new_bitvec("returndatasize", 256)
)
else:
global_state.mstate.stack.append(len(global_state.last_return_data))
return [global_state]
@StateTransition()
@ -1295,14 +1338,14 @@ class Instruction:
global_state.new_bitvec("retval_" + str(instr["address"]), 256)
)
return [global_state]
global_state.mstate.stack.append(
global_state.new_bitvec("retval_" + str(instr["address"]), 256)
)
native_result = native_call(
global_state, callee_address, call_data, memory_out_offset, memory_out_size
)
if native_result:
global_state.mstate.stack.append(
global_state.new_bitvec("retval_" + str(instr["address"]), 256)
)
return native_result
transaction = MessageCallTransaction(
@ -1324,7 +1367,7 @@ class Instruction:
instr = global_state.get_current_instruction()
try:
callee_address, _, _, value, _, _, memory_out_offset, memory_out_size = get_call_parameters(
callee_address, callee_account, call_data, value, gas, memory_out_offset, memory_out_size = get_call_parameters(
global_state, self.dynamic_loader, True
)
except ValueError as e:

Loading…
Cancel
Save