Clean up method. and documentation

pull/112/head
Joran Honig 7 years ago
parent 8b0f6d4ec8
commit a70c861e21
  1. 30
      mythril/analysis/modules/integer.py
  2. 1
      tests/testdata/inputs/overflow.sol

@ -12,6 +12,7 @@ MODULE DESCRIPTION:
Check for integer underflows. Check for integer underflows.
For every SUB instruction, check if there's a possible state where op1 > op0. For every SUB instruction, check if there's a possible state where op1 > op0.
For every ADD instruction, check if there's a possible state where op1 + op0 > 2^32 - 1
''' '''
@ -65,7 +66,10 @@ def _check_integer_overflow(statespace, state, node):
model = solver.get_model(constraints) model = solver.get_model(constraints)
# If we get to this point then there has been an integer overflow # If we get to this point then there has been an integer overflow
# Find out if the overflowed value is actually used
interesting_usages = _search_children(statespace, node, (op0 + op1), index=node.states.index(state)) interesting_usages = _search_children(statespace, node, (op0 + op1), index=node.states.index(state))
# Stop if it isn't
if len(interesting_usages) == 0: if len(interesting_usages) == 0:
return issues return issues
@ -141,9 +145,6 @@ def _check_integer_underflow(state, node):
return issues return issues
MAX_SEARCH_DEPTH = 64
def _check_usage(state, expression): def _check_usage(state, expression):
"""Delegates checks to _check_{instruction_name}()""" """Delegates checks to _check_{instruction_name}()"""
opcode = state.get_current_instruction()['opcode'] opcode = state.get_current_instruction()['opcode']
@ -171,35 +172,36 @@ def _check_sstore(state, expression):
return str(expression) in str(value) return str(expression) in str(value)
def _search_children(statespace, node, expression, index=0, depth=0, analyze=_check_usage, opcodes=('JUMPI', 'SSTORE')): def _search_children(statespace, node, expression, index=0, depth=0, max_depth=64):
""" """
Checks the statespace for child states with instructions that match the opcodes and see if their elements are Checks the statespace for children states, with JUMPI or SSTORE instuctions,
dependent on expression. for dependency on expression
:param statespace: The statespace to explore :param statespace: The statespace to explore
:param node: Current node to explore from :param node: Current node to explore from
:param expression: expression to look for :param expression: Expression to look for
:param index: Current state index node.states[index] == current_state :param index: Current state index node.states[index] == current_state
:param depth: Current depth level :param depth: Current depth level
:param analyze: Analysis method, returns array of positive children :param max_depth: Max depth to explore
:param opcodes: opcodes to look for
:return: List of states that match the opcodes and are dependent on expression :return: List of states that match the opcodes and are dependent on expression
""" """
logging.debug("SEARCHING NODE %d", node.uid) logging.debug("SEARCHING NODE %d", node.uid)
results = [] results = []
if depth >= MAX_SEARCH_DEPTH: if depth >= max_depth:
return [] return []
# Explore current node from index
for j in range(index, len(node.states)): for j in range(index, len(node.states)):
current_state = node.states[j] current_state = node.states[j]
current_instruction = current_state.get_current_instruction() current_instruction = current_state.get_current_instruction()
if current_instruction['opcode'] in opcodes: if current_instruction['opcode'] in ('JUMPI', 'SSTORE'):
results += analyze(current_state, expression) results += _check_usage(current_state, expression)
children = [edge.node_to for edge in statespace.edges if edge.node_from is node] # Recursively search children
children = [statespace.nodes[edge.node_to] for edge in statespace.edges if edge.node_from == node.uid]
for child in children: for child in children:
results += _search_children(statespace, child, depth=depth+1, analyze=analyze, opcodes=opcodes) results += _search_children(statespace, child, depth=depth+1, max_depth=max_depth)
return results return results

@ -11,6 +11,7 @@ contract Over {
require(balances[msg.sender] - _value >= 0); require(balances[msg.sender] - _value >= 0);
balances[msg.sender] -= _value; balances[msg.sender] -= _value;
balances[_to] += _value; balances[_to] += _value;
balances[_to] = 2;
return true; return true;
} }

Loading…
Cancel
Save