{"action":"created","comment":{"url":"https://api.github.com/repos/trailofbits/manticore/pulls/comments/139058302","pull_request_review_id":62939688,"id":139058302,"diff_hunk":"@@ -0,0 +1,1760 @@\n+'''\n+Solidity / Smart contract VM\n+Implements the yellow paper: http://gavwood.com/paper.pdf\n+Get example contracts from here:\n+https://ethereum.github.io/browser-solidity/#version=soljson-latest.js\n+'''\n+import random, copy\n+from ..platforms.platform import *\n+from ..core.smtlib import solver, TooManySolutions, Expression, Bool, BitVec, Array, Operators, Constant, BitVecConstant, ConstraintSet\n+from ..core.state import ForkState, TerminateState\n+from ..utils.helpers import issymbolic\n+from ..utils.event import Eventful\n+from ..core.smtlib.visitors import pretty_print, arithmetic_simplifier, translate_to_smtlib\n+from ..core.state import Concretize,TerminateState\n+import logging\n+import sys, hashlib\n+if sys.version_info < (3, 6):\n+    import sha3\n+\n+logger = logging.getLogger('PLATFORM')\n+\n+TT256 = 2 ** 256\n+TT256M1 = 2 ** 256 - 1\n+TT255 = 2 ** 255\n+TOOHIGHMEM = 0x100\n+\n+def to_signed(i):\n+    return i if i < TT255 else i - TT256\n+\n+def pack(i, size=32):\n+    assert size >=1\n+    o = [0] * size\n+    for x in range(size):\n+        o[(size-1) - x] = i & 0xff\n+        i >>= 8\n+    return ''.join(map(chr,o))\n+\n+class EVMMemory(object):\n+    '''\n+    The EVM symbolic memory manager.\n+    '''\n+    def __init__(self, constraints, address_size=256, value_size=8, *args, **kwargs):\n+        '''\n+        Builds a memory.\n+\n+        :param constraints:  a set of constraints\n+        :param symbols: Symbolic chunks\n+        '''\n+        assert isinstance(constraints, ConstraintSet)\n+        self._constraints = constraints\n+        self._allocated = 0\n+        self._symbols = {}\n+        self._memory = {}\n+        self._address_size=address_size\n+        self._value_size=value_size\n+\n+    def __copy__(self):\n+        new_mem = EVMMemory(self.constraints, self._address_size,  self._value_size)\n+        new_mem._allocated = self._allocated\n+        new_mem._memory = dict(self._memory)\n+        new_mem._symbols = dict(self._symbols)\n+        return new_mem\n+\n+    def __reduce__(self):\n+        return (self.__class__, (self.constraints, ), {'_symbols':self._symbols, '_allocated':self._allocated, '_memory':self._memory, '_address_size':self._address_size, \n+        '_value_size':self._value_size } )\n+\n+    @property\n+    def constraints(self):\n+        return self._constraints\n+\n+    @constraints.setter\n+    def constraints(self, constraints):\n+        self._constraints = constraints\n+\n+    def _get_size(self, index):\n+        size = index.stop - index.start\n+        if isinstance(size, BitVec):\n+            size = arithmetic_simplifier(size)\n+        else:\n+            size = BitVecConstant(self._array.index_bits, size)\n+        assert isinstance(size, BitVecConstant)\n+        return size.value\n+\n+    def __getitem__(self, index):\n+        if isinstance(index, slice):\n+            size = self._get_size(index)\n+            return self.read(index, size)\n+        else:\n+            return self.read(index, 1)[0]\n+\n+    def __setitem__(self, index, value):\n+        if isinstance(index, slice):\n+            size = self._get_size(index)\n+            assert len(value) == size\n+            for i in xrange(size):\n+                self.write(index.start+i, [value[i]])\n+        else:\n+            self.write(index, [value])\n+\n+    def __len__(self):\n+        return self._allocated\n+\n+\n+    def __str__(self):\n+        m = []\n+        if len(self._memory.keys()):\n+            for i in range(max([0] + self._memory.keys())+1):\n+                c = self.read(i,1)[0]\n+                if issymbolic(c):\n+                    c = '?'\n+                m.append(c)\n+        return ''.join(m)\n+\n+    def allocate(self, address):\n+        '''\n+            Allocate more memory\n+        '''\n+        new_max = address % 32\n+        self._allocated = Operators.ITEBV(256, self._allocated < new_max, new_max, self._allocated)\n+\n+    def _concrete_read(self, address):\n+        return self._memory.get(address, 0)\n+\n+    def _concrete_write(self, address, value):\n+        assert not issymbolic(address) \n+        assert not issymbolic(value)\n+        assert value & ~(pow(2,self._value_size)-1) == 0 , \"Not the correct size sor a value\"\n+        self._memory[address] = value\n+\n+    def read(self, address, size):\n+        '''\n+        Read a stream of potentially symbolic items from a potentially symbolic\n+        address\n+\n+        :param address: Where to read from\n+        :param size: How many items\n+        :rtype: list\n+        '''\n+        #size = self._get_size(size)\n+        assert not issymbolic(size)\n+\n+        if issymbolic(address):\n+            assert solver.check(self.constraints)\n+            logger.debug('Reading %d items from symbolic offset %s', size, address)\n+            try:\n+                solutions = solver.get_all_values(self.constraints, address, maxcnt=0x100) #if more than 0x3000 exception\n+            except TooManySolutions as e:\n+                m, M = solver.minmax(self.constraints, address)\n+                logger.debug('Got TooManySolutions on a symbolic read. Range [%x, %x]. Not crashing!', m, M)\n+\n+                #FIXME When we implement gas calculate the max index to exhaust gas \n+                if M >= TOOHIGHMEM:\n+                    if m<TOOHIGHMEM:\n+                        raise ForkState('address too high', address.ult(TOOHIGHMEM))\n+                    else:\n+                        raise NotEnoughGas(\"Accessing memory too high\")\n+\n+                assert(M<TOOHIGHMEM)\n+\n+                #INCOMPLETE Result! Using the 0x100 values sampled before\n+                logger.info('INCOMPLETE Result! Using the sampled solutions we have as result')\n+                condition = False\n+                for base in e.solutions:\n+                    condition = Operators.OR(address == base, condition )\n+                raise ForkState('address too high', condition)\n+\n+            #So here we have all potential solutions of symbolic address (complete set)\n+            assert len(solutions) > 0            \n+\n+            outofgas_condition = False\n+            for base in solutions:\n+                if base + size > TOOHIGHMEM:\n+                    outofgas_condition = Operators.OR(address == base, outofgas_condition)\n+\n+            #FIXME: if we can out of gas we jump to it and wont explore the othe option\n+            outofgas_solutions = set(solver.get_all_values(self.constraints, outofgas_condition))\n+            if outofgas_solutions == set([True]):\n+                raise NotEnoughGas(\"Accessing memory too high\")\n+    \n+            elif outofgas_solutions == set([True, False]):\n+                raise ForkState('address too high', outofgas_condition)\n+\n+            assert outofgas_solutions == set([False])\n+\n+            condition = False\n+            for base in solutions:\n+                condition = Operators.OR(address == base, condition )\n+\n+            result = []\n+            #consider size ==1 to read following code\n+            for offset in range(size):\n+                #Given ALL solutions for the symbolic address\n+                for base in solutions:\n+                    addr_value = base + offset\n+                    item = self._concrete_read(addr_value)\n+                    if addr_value in self._symbols:\n+                        for condition, value in self._symbols[addr_value]:\n+                            item = Operators.ITEBV(self._value_size, condition, value, item)\n+                    if len(result) > offset:\n+                        result[offset] = Operators.ITEBV(self._value_size, address == base, item, result[offset])\n+                    else:\n+                        result.append(item)\n+                    assert len(result) == offset+1\n+            return result\n+        else:\n+            result = []\n+            for i in range(size):\n+                result.append(self._concrete_read(address+i))\n+            for offset in range(size):\n+                if address+offset in self._symbols:\n+                    for condition, value in self._symbols[address+offset]:\n+                        if condition is True:\n+                            result[offset] = value\n+                        else:\n+                            result[offset] = Operators.ITEBV(self._value_size, condition, value, result[offset])\n+            return result\n+\n+    def write(self, address, value):\n+        '''\n+        Write a value at address.\n+        :param address: The address at which to write\n+        :type address: int or long or Expression\n+        :param value: Bytes to write\n+        :type value: str or list\n+        '''\n+        size = len(value)\n+        #FIXME consider calling self.allocate?\n+        if issymbolic(address):\n+\n+            solutions = solver.get_all_values(self.constraints, address, maxcnt=0x1000) #if more than 0x3000 exception\n+\n+            crashing_condition = False\n+            for base in solutions:\n+                if any(not self.access_ok(i, 'w') for i in xrange(base, base + size, self.page_size)):\n+                    crashing_condition = Operators.OR(address == base, crashing_condition)\n+\n+            if solver.can_be_true(self.constraints, crashing_condition):\n+                raise InvalidSymbolicMemoryAccess(address, 'w', size, crashing_condition)\n+\n+            for offset in xrange(size):\n+                for base in solutions:\n+                    condition = base == address\n+                    self._symbols.setdefault(base+offset, []).append((condition, value[offset]))\n+\n+        else:\n+\n+            for offset in xrange(size):\n+                if issymbolic(value[offset]):\n+                    self._symbols[address+offset] = [(True, value[offset])]\n+                else:\n+                    # overwrite all previous items\n+                    if address+offset in self._symbols:\n+                        del self._symbols[address+offset]\n+                    self._concrete_write(address+offset, value[offset])\n+\n+\n+class EVMInstruction(object):\n+    '''This represents an EVM instruction '''\n+    def __init__(self, opcode, name, operand_size, pops, pushes, description, operand=None):\n+        self._opcode = opcode \n+        self._name = name \n+        self._operand_size = operand_size\n+        self._pops = pops\n+        self._pushes = pushes\n+        self._description = description\n+        self._operand = operand           #Immediate operand if any\n+    \n+    def parse_operand(self, buf):\n+        operand = 0\n+        for _ in range(self.operand_size):\n+            operand <<= 8\n+            operand |= ord(next(buf))\n+        self._operand = operand\n+\n+    @property\n+    def operand_size(self):\n+        return self._operand_size\n+\n+    @property\n+    def has_operand(self):\n+        return self.operand_size > 0\n+\n+    @property\n+    def operand(self):\n+        return self._operand\n+\n+    @property\n+    def pops(self):\n+        return self._pops\n+\n+    @property\n+    def pushes(self):\n+        return self._pushes\n+\n+    @property\n+    def size(self):\n+        return self._operand_size + 1\n+\n+    def __len__(self):\n+        return self.size\n+\n+    @property\n+    def name(self):\n+        if self._name == 'PUSH':\n+            return 'PUSH%d'%self.operand_size\n+        elif self._name == 'DUP':\n+            return 'DUP%d'%self.pops\n+        elif self._name == 'SWAP':\n+            return 'SWAP%d'%(self.pops-1)\n+        elif self._name == 'LOG':\n+            return 'LOG%d'%(self.pops-2)\n+        return self._name\n+\n+    def __str__(self):\n+        bytes = self.bytes.encode('hex')\n+\n+        output = '<%s> '%bytes + self.name + (' 0x%x'%self.operand if self.has_operand else '')\n+        if True:\n+            output += ' '*(80-len(output))+self.description\n+        return output\n+\n+    @property\n+    def semantics(self):\n+        return self._name\n+\n+    @property\n+    def description(self):\n+        return self._description\n+\n+    @property\n+    def bytes(self):\n+        bytes = []\n+        bytes.append(chr(self._opcode))\n+        for offset in reversed(xrange(self.operand_size)):\n+            c = (self.operand >> offset*8 ) & 0xff \n+            bytes.append(chr(c))\n+        return ''.join(bytes)\n+\n+        \n+class EVMDecoder(object):\n+    ''' \n+        EVM Instruction factory\n+    '''\n+    #from http://gavwood.com/paper.pdf\n+    _table = {#opcode: (name, immediate_operand_size, pops, pushes, gas, description)\n+                0x00: ('STOP', 0, 0, 0, 0, 'Halts execution.'),\n+                0x01: ('ADD', 0, 2, 1, 3, 'Addition operation.'),\n+                0x02: ('MUL', 0, 2, 1, 5, 'Multiplication operation.'),\n+                0x03: ('SUB', 0, 2, 1, 3, 'Subtraction operation.'),\n+                0x04: ('DIV', 0, 2, 1, 5, 'Integer division operation.'),\n+                0x05: ('SDIV', 0, 2, 1, 5, 'Signed integer division operation (truncated).'),\n+                0x06: ('MOD', 0, 2, 1, 5, 'Modulo remainder operation.'),\n+                0x07: ('SMOD', 0, 2, 1, 5, 'Signed modulo remainder operation.'),\n+                0x08: ('ADDMOD', 0, 3, 1, 8, 'Modulo addition operation.'),\n+                0x09: ('MULMOD', 0, 3, 1, 8, 'Modulo multiplication operation.'),\n+                0x0a: ('EXP', 0, 2, 1, 10, 'Exponential operation.'),\n+                0x0b: ('SIGNEXTEND', 0, 2, 1, 5, \"Extend length of two's complement signed integer.\"),\n+                0x10: ('LT', 0, 2, 1, 3, 'Less-than comparision.'),\n+                0x11: ('GT', 0, 2, 1, 3, 'Greater-than comparision.'),\n+                0x12: ('SLT', 0, 2, 1, 3, 'Signed less-than comparision.'),\n+                0x13: ('SGT', 0, 2, 1, 3, 'Signed greater-than comparision.'),\n+                0x14: ('EQ', 0, 2, 1, 3, 'Equality comparision.'),\n+                0x15: ('ISZERO', 0, 1, 1, 3, 'Simple not operator.'),\n+                0x16: ('AND', 0, 2, 1, 3, 'Bitwise AND operation.'),\n+                0x17: ('OR', 0, 2, 1, 3, 'Bitwise OR operation.'),\n+                0x18: ('XOR', 0, 2, 1, 3, 'Bitwise XOR operation.'),\n+                0x19: ('NOT', 0, 1, 1, 3, 'Bitwise NOT operation.'),\n+                0x1a: ('BYTE', 0, 2, 1, 3, 'Retrieve single byte from word.'),\n+                0x20: ('SHA3', 0, 2, 1, 30, 'Compute Keccak-256 hash.'),\n+                0x30: ('ADDRESS', 0, 0, 1, 2, 'Get address of currently executing account     .'),\n+                0x31: ('BALANCE', 0, 1, 1, 20, 'Get balance of the given account.'),\n+                0x32: ('ORIGIN', 0, 0, 1, 2, 'Get execution origination address.'),\n+                0x33: ('CALLER', 0, 0, 1, 2, 'Get caller address.'),\n+                0x34: ('CALLVALUE', 0, 0, 1, 2, 'Get deposited value by the instruction/transaction responsible for this execution.'),\n+                0x35: ('CALLDATALOAD', 0, 1, 1, 3, 'Get input data of current environment.'),\n+                0x36: ('CALLDATASIZE', 0, 0, 1, 2, 'Get size of input data in current environment.'),\n+                0x37: ('CALLDATACOPY', 0, 3, 0, 3, 'Copy input data in current environment to memory.'),\n+                0x38: ('CODESIZE', 0, 0, 1, 2, 'Get size of code running in current environment.'),\n+                0x39: ('CODECOPY', 0, 3, 0, 3, 'Copy code running in current environment to memory.'),\n+                0x3a: ('GASPRICE', 0, 0, 1, 2, 'Get price of gas in current environment.'),\n+                0x3b: ('EXTCODESIZE', 0, 1, 1, 20, \"Get size of an account's code.\"),\n+                0x3c: ('EXTCODECOPY', 0, 4, 0, 20, \"Copy an account's code to memory.\"),\n+                0x40: ('BLOCKHASH', 0, 1, 1, 20, 'Get the hash of one of the 256 most recent complete blocks.'),\n+                0x41: ('COINBASE', 0, 0, 1, 2, \"Get the block's beneficiary address.\"),\n+                0x42: ('TIMESTAMP', 0, 0, 1, 2, \"Get the block's timestamp.\"),\n+                0x43: ('NUMBER', 0, 0, 1, 2, \"Get the block's number.\"),\n+                0x44: ('DIFFICULTY', 0, 0, 1, 2, \"Get the block's difficulty.\"),\n+                0x45: ('GASLIMIT', 0, 0, 1, 2, \"Get the block's gas limit.\"),\n+                0x50: ('POP', 0, 1, 0, 2, 'Remove item from stack.'),\n+                0x51: ('MLOAD', 0, 1, 1, 3, 'Load word from memory.'),\n+                0x52: ('MSTORE', 0, 2, 0, 3, 'Save word to memory.'),\n+                0x53: ('MSTORE8', 0, 2, 0, 3, 'Save byte to memory.'),\n+                0x54: ('SLOAD', 0, 1, 1, 50, 'Load word from storage.'),\n+                0x55: ('SSTORE', 0, 2, 0, 0, 'Save word to storage.'),\n+                0x56: ('JUMP', 0, 1, 0, 8, 'Alter the program counter.'),\n+                0x57: ('JUMPI', 0, 2, 0, 10, 'Conditionally alter the program counter.'),\n+                0x58: ('GETPC', 0, 0, 1, 2, 'Get the value of the program counter prior to the increment.'),\n+                0x59: ('MSIZE', 0, 0, 1, 2, 'Get the size of active memory in bytes.'),\n+                0x5a: ('GAS', 0, 0, 1, 2, 'Get the amount of available gas, including the corresponding reduction the amount of available gas.'),\n+                0x5b: ('JUMPDEST', 0, 0, 0, 1, 'Mark a valid destination for jumps.'),\n+                0x60: ('PUSH', 1, 0, 1, 0, 'Place 1 byte item on stack.'),\n+                0x61: ('PUSH', 2, 0, 1, 0, 'Place 2-byte item on stack.'),\n+                0x62: ('PUSH', 3, 0, 1, 0, 'Place 3-byte item on stack.'),\n+                0x63: ('PUSH', 4, 0, 1, 0, 'Place 4-byte item on stack.'),\n+                0x64: ('PUSH', 5, 0, 1, 0, 'Place 5-byte item on stack.'),\n+                0x65: ('PUSH', 6, 0, 1, 0, 'Place 6-byte item on stack.'),\n+                0x66: ('PUSH', 7, 0, 1, 0, 'Place 7-byte item on stack.'),\n+                0x67: ('PUSH', 8, 0, 1, 0, 'Place 8-byte item on stack.'),\n+                0x68: ('PUSH', 9, 0, 1, 0, 'Place 9-byte item on stack.'),\n+                0x69: ('PUSH', 10, 0, 1, 0, 'Place 10-byte item on stack.'),\n+                0x6a: ('PUSH', 11, 0, 1, 0, 'Place 11-byte item on stack.'),\n+                0x6b: ('PUSH', 12, 0, 1, 0, 'Place 12-byte item on stack.'),\n+                0x6c: ('PUSH', 13, 0, 1, 0, 'Place 13-byte item on stack.'),\n+                0x6d: ('PUSH', 14, 0, 1, 0, 'Place 14-byte item on stack.'),\n+                0x6e: ('PUSH', 15, 0, 1, 0, 'Place 15-byte item on stack.'),\n+                0x6f: ('PUSH', 16, 0, 1, 0, 'Place 16-byte item on stack.'),\n+                0x70: ('PUSH', 17, 0, 1, 0, 'Place 17-byte item on stack.'),\n+                0x71: ('PUSH', 18, 0, 1, 0, 'Place 18-byte item on stack.'),\n+                0x72: ('PUSH', 19, 0, 1, 0, 'Place 19-byte item on stack.'),\n+                0x73: ('PUSH', 20, 0, 1, 0, 'Place 20-byte item on stack.'),\n+                0x74: ('PUSH', 21, 0, 1, 0, 'Place 21-byte item on stack.'),\n+                0x75: ('PUSH', 22, 0, 1, 0, 'Place 22-byte item on stack.'),\n+                0x76: ('PUSH', 23, 0, 1, 0, 'Place 23-byte item on stack.'),\n+                0x77: ('PUSH', 24, 0, 1, 0, 'Place 24-byte item on stack.'),\n+                0x78: ('PUSH', 25, 0, 1, 0, 'Place 25-byte item on stack.'),\n+                0x79: ('PUSH', 26, 0, 1, 0, 'Place 26-byte item on stack.'),\n+                0x7a: ('PUSH', 27, 0, 1, 0, 'Place 27-byte item on stack.'),\n+                0x7b: ('PUSH', 28, 0, 1, 0, 'Place 28-byte item on stack.'),\n+                0x7c: ('PUSH', 29, 0, 1, 0, 'Place 29-byte item on stack.'),\n+                0x7d: ('PUSH', 30, 0, 1, 0, 'Place 30-byte item on stack.'),\n+                0x7e: ('PUSH', 31, 0, 1, 0, 'Place 31-byte item on stack.'),\n+                0x7f: ('PUSH', 32, 0, 1, 0, 'Place 32-byte (full word) item on stack.'),\n+                0x80: ('DUP', 0, 1, 2, 0, 'Duplicate 1st stack item.'),\n+                0x81: ('DUP', 0, 2, 3, 0, 'Duplicate 2nd stack item.'),\n+                0x82: ('DUP', 0, 3, 4, 0, 'Duplicate 3rd stack item.'),\n+                0x83: ('DUP', 0, 4, 5, 0, 'Duplicate 4th stack item.'),\n+                0x84: ('DUP', 0, 5, 6, 0, 'Duplicate 5th stack item.'),\n+                0x85: ('DUP', 0, 6, 7, 0, 'Duplicate 6th stack item.'),\n+                0x86: ('DUP', 0, 7, 8, 0, 'Duplicate 7th stack item.'),\n+                0x87: ('DUP', 0, 8, 9, 0, 'Duplicate 8th stack item.'),\n+                0x88: ('DUP', 0, 9, 10, 0, 'Duplicate 9th stack item.'),\n+                0x89: ('DUP', 0, 10, 11, 0, 'Duplicate 10th stack item.'),\n+                0x8a: ('DUP', 0, 11, 12, 0, 'Duplicate 11th stack item.'),\n+                0x8b: ('DUP', 0, 12, 13, 0, 'Duplicate 12th stack item.'),\n+                0x8c: ('DUP', 0, 13, 14, 0, 'Duplicate 13th stack item.'),\n+                0x8d: ('DUP', 0, 14, 15, 0, 'Duplicate 14th stack item.'),\n+                0x8e: ('DUP', 0, 15, 16, 0, 'Duplicate 15th stack item.'),\n+                0x8f: ('DUP', 0, 16, 17, 0, 'Duplicate 16th stack item.'),\n+                0x90: ('SWAP', 0, 2, 2, 0, 'Exchange 1st and 2nd stack items.'),\n+                0x91: ('SWAP', 0, 3, 3, 0, 'Exchange 1st and 3rd stack items.'),\n+                0x92: ('SWAP', 0, 4, 4, 0, 'Exchange 1st and 4rd stack items.'),\n+                0x93: ('SWAP', 0, 5, 5, 0, 'Exchange 1st and 5rd stack items.'),\n+                0x94: ('SWAP', 0, 6, 6, 0, 'Exchange 1st and 6rd stack items.'),\n+                0x95: ('SWAP', 0, 7, 7, 0, 'Exchange 1st and 7rd stack items.'),\n+                0x96: ('SWAP', 0, 8, 8, 0, 'Exchange 1st and 8rd stack items.'),\n+                0x97: ('SWAP', 0, 9, 9, 0, 'Exchange 1st and 9rd stack items.'),\n+                0x98: ('SWAP', 0, 10, 10, 0, 'Exchange 1st and 10rd stack items.'),\n+                0x99: ('SWAP', 0, 11, 11, 0, 'Exchange 1st and 11rd stack items.'),\n+                0x9a: ('SWAP', 0, 12, 12, 0, 'Exchange 1st and 12rd stack items.'),\n+                0x9b: ('SWAP', 0, 13, 13, 0, 'Exchange 1st and 13rd stack items.'),\n+                0x9c: ('SWAP', 0, 14, 14, 0, 'Exchange 1st and 14rd stack items.'),\n+                0x9d: ('SWAP', 0, 15, 15, 0, 'Exchange 1st and 15rd stack items.'),\n+                0x9e: ('SWAP', 0, 16, 16, 0, 'Exchange 1st and 16rd stack items.'),\n+                0x9f: ('SWAP', 0, 17, 17, 0, 'Exchange 1st and 17th stack items.'),\n+                0xa0: ('LOG', 0, 2, 0, 375, 'Append log record with no topics.'),\n+                0xa1: ('LOG', 0, 3, 0, 750, 'Append log record with one topic.'),\n+                0xa2: ('LOG', 0, 4, 0, 1125, 'Append log record with two topics.'),\n+                0xa3: ('LOG', 0, 5, 0, 1500, 'Append log record with three topics.'),\n+                0xa4: ('LOG', 0, 6, 0, 1875, 'Append log record with four topics.'),\n+                0xf0: ('CREATE', 0, 3, 1, 32000, 'Create a new account with associated code.'),\n+                0xf1: ('CALL', 0, 7, 1, 40, 'Message-call into an account.'),\n+                0xf2: ('CALLCODE', 0, 7, 1, 40, \"Message-call into this account with alternative account's code.\"),\n+                0xf3: ('RETURN', 0, 2, 0, 0, 'Halt execution returning output data.'),\n+                0xf4: ('DELEGATECALL', 0, 6, 1, 40, \"Message-call into this account with an alternative account's code, but persisting into this account with an alternative account's code.\"),\n+                0xf5: ('BREAKPOINT', 0, 0, 0, 40, 'Not in yellow paper FIXME'),\n+                0xf6: ('RNGSEED', 0, 1, 1, 0, 'Not in yellow paper FIXME'),\n+                0xf7: ('SSIZEEXT', 0, 2, 1, 0, 'Not in yellow paper FIXME'),\n+                0xf8: ('SLOADBYTES', 0, 3, 0, 0, 'Not in yellow paper FIXME'),\n+                0xf9: ('SSTOREBYTES', 0, 3, 0, 0, 'Not in yellow paper FIXME'),\n+                0xfa: ('SSIZE', 0, 1, 1, 40, 'Not in yellow paper FIXME'),\n+                0xfb: ('STATEROOT', 0, 1, 1, 0, 'Not in yellow paper FIXME'),\n+                0xfc: ('TXEXECGAS', 0, 0, 1, 0, 'Not in yellow paper FIXME'),\n+                0xfd: ('REVERT', 0, 2, 0, 0, 'Stop execution and revert state changes, without consuming all provided gas and providing a reason.'),\n+                0xfe: ('INVALID', 0, 0, 0, 0, 'Designated invalid instruction.'),\n+                0xff: ('SELFDESTRUCT', 0, 1, 0, 0, 'Halt execution and register account for later deletion.')\n+            }\n+\n+\n+    @staticmethod\n+    def decode_one(bytecode):\n+        '''\n+        '''\n+        bytecode = iter(bytecode)\n+        opcode = ord(next(bytecode))\n+        invalid = ('INVALID', 0, 0, 0, 0, 'Unknown opcode')\n+        name, operand_size, pops, pushes, gas, description = EVMDecoder._table.get(opcode, invalid)\n+\n+        instruction = EVMInstruction(opcode, name, operand_size, pops, pushes, description)\n+        if instruction.has_operand:\n+            instruction.parse_operand(bytecode)\n+\n+        return instruction\n+\n+    @staticmethod\n+    def decode_all(bytecode):\n+        bytecode = iter(bytecode)\n+        while True:\n+            yield EVMDecoder.decode_one(bytecode)\n+\n+    @staticmethod\n+    def disassemble(bytecode):\n+        output = ''\n+        address = 0\n+        for i in EVMDecoder.decode_all(bytecode) :\n+            output += \"0x%04x %s\\n\"%(address, i)\n+            address += i.size\n+        return output\n+\n+class EVMException(Exception):\n+    pass\n+\n+class ConcretizeStack(EVMException):\n+    '''\n+    Raised when a symbolic memory cell needs to be concretized.\n+    '''\n+    def __init__(self, pos, expression, policy='MINMAX'):\n+        self.message = \"Concretizing evm stack item {}\".format(pos)\n+        self.pos = pos\n+        self.expression = expression\n+\n+class StackOverflow(EVMException):\n+    ''' Attemped to push more than 1024 items '''\n+    pass\n+\n+class StackUnderflow(EVMException):\n+    ''' Attemped to popo from an empty stack '''\n+    pass\n+\n+class InvalidOpcode(EVMException):\n+    ''' Trying to execute invalid opcode '''\n+    pass\n+\n+\n+class Call(EVMException):\n+    def __init__(self, gas, to, value, data, out_offset=None, out_size=None):\n+        self.gas = gas\n+        self.to = to\n+        self.value = value\n+        self.data = data\n+        self.out_offset = out_offset\n+        self.out_size = out_size\n+\n+    def __reduce__(self):\n+        return (self.__class__, (self.gas, self.to, self.value, self.data, self.out_offset, self.out_size) )\n+\n+\n+class Create(Call):\n+    def __init__(self, value, offset, size):\n+        super(Create, self).__init__(gas=None, to=None, value=value, data='')\n+\n+class DelegateCall(Call):\n+    pass\n+\n+class Stop(EVMException):\n+    ''' Program reached a STOP instruction '''\n+    pass\n+\n+class Return(EVMException):\n+    ''' Program reached a RETURN instruction '''\n+    def __init__(self, data):\n+        self.data = data\n+    def __reduce__(self):\n+        return (self.__class__, (self.data) )\n+\n+class Revert(EVMException):\n+    ''' Program reached a RETURN instruction '''\n+    def __init__(self, data):\n+        self.data = data\n+    def __reduce__(self):\n+        return (self.__class__, (self.data) )\n+\n+class SelfDestruct(EVMException):\n+    ''' Program reached a RETURN instruction '''\n+    def __init__(self, to):\n+        self.to = to\n+\n+class NotEnoughGas(EVMException):\n+    ''' Not enough gas for operation '''\n+    pass\n+\n+class Sha3(EVMException):\n+    def __init__(self, data):\n+        self.data = data\n+\n+    def __reduce__(self):\n+        return (self.__class__, (self.data, ))\n+\n+\n+class EVM(Eventful):\n+    '''Machine State. The machine state is defined as\n+        the tuple (g, pc, m, i, s) which are the gas available, the\n+        program counter pc , the memory contents, the active\n+        number of words in memory (counting continuously\n+        from position 0), and the stack contents. The memory\n+        contents are a series of zeroes of bitsize 256\n+    '''\n+\n+    def __init__(self, constraints, address, origin, price, data, caller, value, code, header, world=None, depth=0, **kwargs):\n+        '''\n+        memory, the initial memory\n+        address, the address of the account which owns the code that is executing.\n+        origin, the sender address of the transaction that originated this execution. A 160-bit code used for identifying Accounts.\n+        price, the price of gas in the transaction that originated this execution.\n+        data, the byte array that is the input data to this execution\n+        caller, the address of the account which caused the code to be executing. A 160-bit code used for identifying Accounts\n+        value, the value, in Wei, passed to this account as part of the same procedure as execution. One Ether is defined as being 10**18 Wei.\n+        bytecode, the byte array that is the machine code to be executed.\n+        header, the block header of the present block.\n+        depth, the depth of the present message-call or contract-creation (i.e. the number of CALLs or CREATEs being executed at present).","path":"manticore/platforms/evm.py","position":620,"original_position":620,"commit_id":"67bdbd05654b38948613583f3c2ef175670d89d3","original_commit_id":"67bdbd05654b38948613583f3c2ef175670d89d3","user":{"login":"yan","id":18771,"avatar_url":"https://avatars2.githubusercontent.com/u/18771?v=4","gravatar_id":"","url":"https://api.github.com/users/yan","html_url":"https://github.com/yan","followers_url":"https://api.github.com/users/yan/followers","following_url":"https://api.github.com/users/yan/following{/other_user}","gists_url":"https://api.github.com/users/yan/gists{/gist_id}","starred_url":"https://api.github.com/users/yan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yan/subscriptions","organizations_url":"https://api.github.com/users/yan/orgs","repos_url":"https://api.github.com/users/yan/repos","events_url":"https://api.github.com/users/yan/events{/privacy}","received_events_url":"https://api.github.com/users/yan/received_events","type":"User","site_admin":false},"body":"Update format to sphinx docstrings?","created_at":"2017-09-15T03:41:16Z","updated_at":"2017-09-15T03:41:16Z","html_url":"https://github.com/trailofbits/manticore/pull/426#discussion_r139058302","pull_request_url":"https://api.github.com/repos/trailofbits/manticore/pulls/426","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/trailofbits/manticore/pulls/comments/139058302"},"html":{"href":"https://github.com/trailofbits/manticore/pull/426#discussion_r139058302"},"pull_request":{"href":"https://api.github.com/repos/trailofbits/manticore/pulls/426"}}},"pull_request":{"url":"https://api.github.com/repos/trailofbits/manticore/pulls/426","id":133531514,"html_url":"https://github.com/trailofbits/manticore/pull/426","diff_url":"https://github.com/trailofbits/manticore/pull/426.diff","patch_url":"https://github.com/trailofbits/manticore/pull/426.patch","issue_url":"https://api.github.com/repos/trailofbits/manticore/issues/426","number":426,"state":"open","locked":false,"title":"EVM support for manticore","user":{"login":"feliam","id":1017522,"avatar_url":"https://avatars1.githubusercontent.com/u/1017522?v=4","gravatar_id":"","url":"https://api.github.com/users/feliam","html_url":"https://github.com/feliam","followers_url":"https://api.github.com/users/feliam/followers","following_url":"https://api.github.com/users/feliam/following{/other_user}","gists_url":"https://api.github.com/users/feliam/gists{/gist_id}","starred_url":"https://api.github.com/users/feliam/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/feliam/subscriptions","organizations_url":"https://api.github.com/users/feliam/orgs","repos_url":"https://api.github.com/users/feliam/repos","events_url":"https://api.github.com/users/feliam/events{/privacy}","received_events_url":"https://api.github.com/users/feliam/received_events","type":"User","site_admin":false},"body":"Fixes #416\r\n\r\n* Supports most EVM instructions concrete and symbolic\r\n* Supports inter contract calls and recursive calls\r\n* Supports arbitrary symbolic multi-contract attacks/analysis \r\n* Fair symbolic SHA3 concretization mechanism\r\n\r\nLacks:\r\n* GAS support\r\n* Good reporting\r\n","created_at":"2017-08-01T17:44:02Z","updated_at":"2017-09-15T03:41:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c296cefee176fd2fd3258689e3dd3880ccee59f0","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/trailofbits/manticore/pulls/426/commits","review_comments_url":"https://api.github.com/repos/trailofbits/manticore/pulls/426/comments","review_comment_url":"https://api.github.com/repos/trailofbits/manticore/pulls/comments{/number}","comments_url":"https://api.github.com/repos/trailofbits/manticore/issues/426/comments","statuses_url":"https://api.github.com/repos/trailofbits/manticore/statuses/67bdbd05654b38948613583f3c2ef175670d89d3","head":{"label":"trailofbits:dev-evm","ref":"dev-evm","sha":"67bdbd05654b38948613583f3c2ef175670d89d3","user":{"login":"trailofbits","id":2314423,"avatar_url":"https://avatars0.githubusercontent.com/u/2314423?v=4","gravatar_id":"","url":"https://api.github.com/users/trailofbits","html_url":"https://github.com/trailofbits","followers_url":"https://api.github.com/users/trailofbits/followers","following_url":"https://api.github.com/users/trailofbits/following{/other_user}","gists_url":"https://api.github.com/users/trailofbits/gists{/gist_id}","starred_url":"https://api.github.com/users/trailofbits/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trailofbits/subscriptions","organizations_url":"https://api.github.com/users/trailofbits/orgs","repos_url":"https://api.github.com/users/trailofbits/repos","events_url":"https://api.github.com/users/trailofbits/events{/privacy}","received_events_url":"https://api.github.com/users/trailofbits/received_events","type":"Organization","site_admin":false},"repo":{"id":81612762,"name":"manticore","full_name":"trailofbits/manticore","owner":{"login":"trailofbits","id":2314423,"avatar_url":"https://avatars0.githubusercontent.com/u/2314423?v=4","gravatar_id":"","url":"https://api.github.com/users/trailofbits","html_url":"https://github.com/trailofbits","followers_url":"https://api.github.com/users/trailofbits/followers","following_url":"https://api.github.com/users/trailofbits/following{/other_user}","gists_url":"https://api.github.com/users/trailofbits/gists{/gist_id}","starred_url":"https://api.github.com/users/trailofbits/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trailofbits/subscriptions","organizations_url":"https://api.github.com/users/trailofbits/orgs","repos_url":"https://api.github.com/users/trailofbits/repos","events_url":"https://api.github.com/users/trailofbits/events{/privacy}","received_events_url":"https://api.github.com/users/trailofbits/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/trailofbits/manticore","description":"Dynamic binary analysis tool","fork":false,"url":"https://api.github.com/repos/trailofbits/manticore","forks_url":"https://api.github.com/repos/trailofbits/manticore/forks","keys_url":"https://api.github.com/repos/trailofbits/manticore/keys{/key_id}","collaborators_url":"https://api.github.com/repos/trailofbits/manticore/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/trailofbits/manticore/teams","hooks_url":"https://api.github.com/repos/trailofbits/manticore/hooks","issue_events_url":"https://api.github.com/repos/trailofbits/manticore/issues/events{/number}","events_url":"https://api.github.com/repos/trailofbits/manticore/events","assignees_url":"https://api.github.com/repos/trailofbits/manticore/assignees{/user}","branches_url":"https://api.github.com/repos/trailofbits/manticore/branches{/branch}","tags_url":"https://api.github.com/repos/trailofbits/manticore/tags","blobs_url":"https://api.github.com/repos/trailofbits/manticore/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/trailofbits/manticore/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/trailofbits/manticore/git/refs{/sha}","trees_url":"https://api.github.com/repos/trailofbits/manticore/git/trees{/sha}","statuses_url":"https://api.github.com/repos/trailofbits/manticore/statuses/{sha}","languages_url":"https://api.github.com/repos/trailofbits/manticore/languages","stargazers_url":"https://api.github.com/repos/trailofbits/manticore/stargazers","contributors_url":"https://api.github.com/repos/trailofbits/manticore/contributors","subscribers_url":"https://api.github.com/repos/trailofbits/manticore/subscribers","subscription_url":"https://api.github.com/repos/trailofbits/manticore/subscription","commits_url":"https://api.github.com/repos/trailofbits/manticore/commits{/sha}","git_commits_url":"https://api.github.com/repos/trailofbits/manticore/git/commits{/sha}","comments_url":"https://api.github.com/repos/trailofbits/manticore/comments{/number}","issue_comment_url":"https://api.github.com/repos/trailofbits/manticore/issues/comments{/number}","contents_url":"https://api.github.com/repos/trailofbits/manticore/contents/{+path}","compare_url":"https://api.github.com/repos/trailofbits/manticore/compare/{base}...{head}","merges_url":"https://api.github.com/repos/trailofbits/manticore/merges","archive_url":"https://api.github.com/repos/trailofbits/manticore/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/trailofbits/manticore/downloads","issues_url":"https://api.github.com/repos/trailofbits/manticore/issues{/number}","pulls_url":"https://api.github.com/repos/trailofbits/manticore/pulls{/number}","milestones_url":"https://api.github.com/repos/trailofbits/manticore/milestones{/number}","notifications_url":"https://api.github.com/repos/trailofbits/manticore/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/trailofbits/manticore/labels{/name}","releases_url":"https://api.github.com/repos/trailofbits/manticore/releases{/id}","deployments_url":"https://api.github.com/repos/trailofbits/manticore/deployments","created_at":"2017-02-10T22:28:34Z","updated_at":"2017-09-15T01:44:19Z","pushed_at":"2017-09-14T22:51:13Z","git_url":"git://github.com/trailofbits/manticore.git","ssh_url":"git@github.com:trailofbits/manticore.git","clone_url":"https://github.com/trailofbits/manticore.git","svn_url":"https://github.com/trailofbits/manticore","homepage":"https://blog.trailofbits.com/2017/04/27/manticore-symbolic-execution-for-humans/","size":16178,"stargazers_count":735,"watchers_count":735,"language":"Python","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":90,"mirror_url":null,"open_issues_count":77,"forks":90,"open_issues":77,"watchers":735,"default_branch":"master"}},"base":{"label":"trailofbits:master","ref":"master","sha":"b9333838ad8973df8d99923b406cde709b26ac2f","user":{"login":"trailofbits","id":2314423,"avatar_url":"https://avatars0.githubusercontent.com/u/2314423?v=4","gravatar_id":"","url":"https://api.github.com/users/trailofbits","html_url":"https://github.com/trailofbits","followers_url":"https://api.github.com/users/trailofbits/followers","following_url":"https://api.github.com/users/trailofbits/following{/other_user}","gists_url":"https://api.github.com/users/trailofbits/gists{/gist_id}","starred_url":"https://api.github.com/users/trailofbits/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trailofbits/subscriptions","organizations_url":"https://api.github.com/users/trailofbits/orgs","repos_url":"https://api.github.com/users/trailofbits/repos","events_url":"https://api.github.com/users/trailofbits/events{/privacy}","received_events_url":"https://api.github.com/users/trailofbits/received_events","type":"Organization","site_admin":false},"repo":{"id":81612762,"name":"manticore","full_name":"trailofbits/manticore","owner":{"login":"trailofbits","id":2314423,"avatar_url":"https://avatars0.githubusercontent.com/u/2314423?v=4","gravatar_id":"","url":"https://api.github.com/users/trailofbits","html_url":"https://github.com/trailofbits","followers_url":"https://api.github.com/users/trailofbits/followers","following_url":"https://api.github.com/users/trailofbits/following{/other_user}","gists_url":"https://api.github.com/users/trailofbits/gists{/gist_id}","starred_url":"https://api.github.com/users/trailofbits/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trailofbits/subscriptions","organizations_url":"https://api.github.com/users/trailofbits/orgs","repos_url":"https://api.github.com/users/trailofbits/repos","events_url":"https://api.github.com/users/trailofbits/events{/privacy}","received_events_url":"https://api.github.com/users/trailofbits/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/trailofbits/manticore","description":"Dynamic binary analysis tool","fork":false,"url":"https://api.github.com/repos/trailofbits/manticore","forks_url":"https://api.github.com/repos/trailofbits/manticore/forks","keys_url":"https://api.github.com/repos/trailofbits/manticore/keys{/key_id}","collaborators_url":"https://api.github.com/repos/trailofbits/manticore/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/trailofbits/manticore/teams","hooks_url":"https://api.github.com/repos/trailofbits/manticore/hooks","issue_events_url":"https://api.github.com/repos/trailofbits/manticore/issues/events{/number}","events_url":"https://api.github.com/repos/trailofbits/manticore/events","assignees_url":"https://api.github.com/repos/trailofbits/manticore/assignees{/user}","branches_url":"https://api.github.com/repos/trailofbits/manticore/branches{/branch}","tags_url":"https://api.github.com/repos/trailofbits/manticore/tags","blobs_url":"https://api.github.com/repos/trailofbits/manticore/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/trailofbits/manticore/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/trailofbits/manticore/git/refs{/sha}","trees_url":"https://api.github.com/repos/trailofbits/manticore/git/trees{/sha}","statuses_url":"https://api.github.com/repos/trailofbits/manticore/statuses/{sha}","languages_url":"https://api.github.com/repos/trailofbits/manticore/languages","stargazers_url":"https://api.github.com/repos/trailofbits/manticore/stargazers","contributors_url":"https://api.github.com/repos/trailofbits/manticore/contributors","subscribers_url":"https://api.github.com/repos/trailofbits/manticore/subscribers","subscription_url":"https://api.github.com/repos/trailofbits/manticore/subscription","commits_url":"https://api.github.com/repos/trailofbits/manticore/commits{/sha}","git_commits_url":"https://api.github.com/repos/trailofbits/manticore/git/commits{/sha}","comments_url":"https://api.github.com/repos/trailofbits/manticore/comments{/number}","issue_comment_url":"https://api.github.com/repos/trailofbits/manticore/issues/comments{/number}","contents_url":"https://api.github.com/repos/trailofbits/manticore/contents/{+path}","compare_url":"https://api.github.com/repos/trailofbits/manticore/compare/{base}...{head}","merges_url":"https://api.github.com/repos/trailofbits/manticore/merges","archive_url":"https://api.github.com/repos/trailofbits/manticore/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/trailofbits/manticore/downloads","issues_url":"https://api.github.com/repos/trailofbits/manticore/issues{/number}","pulls_url":"https://api.github.com/repos/trailofbits/manticore/pulls{/number}","milestones_url":"https://api.github.com/repos/trailofbits/manticore/milestones{/number}","notifications_url":"https://api.github.com/repos/trailofbits/manticore/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/trailofbits/manticore/labels{/name}","releases_url":"https://api.github.com/repos/trailofbits/manticore/releases{/id}","deployments_url":"https://api.github.com/repos/trailofbits/manticore/deployments","created_at":"2017-02-10T22:28:34Z","updated_at":"2017-09-15T01:44:19Z","pushed_at":"2017-09-14T22:51:13Z","git_url":"git://github.com/trailofbits/manticore.git","ssh_url":"git@github.com:trailofbits/manticore.git","clone_url":"https://github.com/trailofbits/manticore.git","svn_url":"https://github.com/trailofbits/manticore","homepage":"https://blog.trailofbits.com/2017/04/27/manticore-symbolic-execution-for-humans/","size":16178,"stargazers_count":735,"watchers_count":735,"language":"Python","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":90,"mirror_url":null,"open_issues_count":77,"forks":90,"open_issues":77,"watchers":735,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/trailofbits/manticore/pulls/426"},"html":{"href":"https://github.com/trailofbits/manticore/pull/426"},"issue":{"href":"https://api.github.com/repos/trailofbits/manticore/issues/426"},"comments":{"href":"https://api.github.com/repos/trailofbits/manticore/issues/426/comments"},"review_comments":{"href":"https://api.github.com/repos/trailofbits/manticore/pulls/426/comments"},"review_comment":{"href":"https://api.github.com/repos/trailofbits/manticore/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/trailofbits/manticore/pulls/426/commits"},"statuses":{"href":"https://api.github.com/repos/trailofbits/manticore/statuses/67bdbd05654b38948613583f3c2ef175670d89d3"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"yan"}}