crytic / ethersplay

EVM dissassembler
GNU Affero General Public License v3.0
834 stars 116 forks source link

IndexError @ last_jump = stack[-1] #23

Closed gaasedelen closed 6 years ago

gaasedelen commented 6 years ago

I've experienced this crash in a handful of contracts. As a result, Ethersplay fails to explore the remainder of the contract, leaving much of it undefined.

Sample contract: poc.zip

To repro, simply open poc.bytecode with BinaryNinja + Ethersplay.

Traceback (most recent call last):
  File "C:\tools\disassemblers\BinaryNinja\plugins\lib\threading.py", line 810, in __bootstrap_inner
    self.run()
  File "C:\tools\disassemblers\BinaryNinja\plugins\..\python\binaryninja\plugin.py", line 420, in run
    self.task.run()
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\evm.py", line 390, in run
    run_initial_analysis(self.bv)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\evm.py", line 414, in run_initial_analysis
    function_dynamic_jump_start(view, f)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 285, in function_dynamic_jump_start
    sv.explore(func.basic_blocks[0])
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 272, in explore
    self._transfer_func(bb, [], [])
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 230, in _transfer_func
    self._transfer_func(son, bb_saw, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 223, in _transfer_func
    (stack, last_jump) = self._update_stack(bb, stack)
  File "C:\Users\user\AppData\Roaming\Binary Ninja\plugins\ethersplay\stack_value_analysis.py", line 202, in _update_stack
    last_jump = stack[-1]
IndexError: list index out of range
gaasedelen commented 6 years ago

Adding a second, different test case for robustness.

Sample contract: poc2.zip

montyly commented 6 years ago

Thanks for reporting this issue (and #22). I am currently working on a new version of the value analysis used for the branches discovery. Hopefully, it will fix these bugs.

joshwatson commented 6 years ago

This is fixed in master