Beispiel #1
0
def extract_contract_code(code):
    """
    Extract actual contract code from deployment code
    :param code: deployment code (as output)
    :return: code of deployed contract
    """
    icfg = CFG(generate_BBs_recursive(code), fix_xrefs=True)
    p = Project(code, cfg=icfg)
    returns = icfg.filter_ins('RETURN')
    memory_infos = resolve_all_memory(icfg, code)
    for r in returns:
        if not r in memory_infos:
            continue
        rmi = memory_infos[r].reads
        if len(rmi.points) != 2:
            continue
        (start, _), (stop, _) = rmi.points
        bs = backward_slice(r, memory_info=memory_infos)
        for b in bs:
            try:
                state = p.run(slice_to_program(b))
                return state.memory[start:stop]
            except (ExternalData, VMException) as e:
                logging.exception('Exception while running', e)
                pass
    return None
Beispiel #2
0
 def get_succ_addrs_full(self, valid_jump_targets):
     from teether.slicing import slice_to_program, backward_slice
     from teether.evm.exceptions import ExternalData
     from teether.memory import UninitializedRead
     from teether.evm.evm import run
     new_succ_addrs = set()
     if self.indirect_jump and not self.jump_resolved:
         bs = backward_slice(self.ins[-1], [0], must_visits=self.must_visit)
         for b in bs:
             if 0x60 <= b[-1].op <= 0x7f:
                 succ_addr = int.from_bytes(b[-1].arg, byteorder='big')
             else:
                 p = slice_to_program(b)
                 try:
                     succ_addr = run(p, check_initialized=True).stack.pop()
                 except (ExternalData, UninitializedRead):
                     logging.warning(
                         'Failed to compute jump target for BB@{}, slice: \n{}'
                         .format(self.start, '\n'.join('\t{}'.format(ins)
                                                       for ins in b)))
                     continue
             if succ_addr not in valid_jump_targets:
                 logging.warning('Jump to invalid address')
                 continue
             path = tuple(unique(ins.bb.start for ins in b if ins.bb))
             if succ_addr not in self.succ_addrs:
                 self.succ_addrs.add(succ_addr)
             if (path, succ_addr) not in new_succ_addrs:
                 new_succ_addrs.add((path, succ_addr))
     # We did our best,
     # if someone finds a new edge, jump_resolved will be set to False by the BFS in add_succ
     self.must_visit = []
     return self.succ_addrs, new_succ_addrs
Beispiel #3
0
 def _analyze_writes(self):
     sstore_ins = self.filter_ins('SSTORE')
     self._writes = defaultdict(set)
     for store in sstore_ins:
         for bs in interesting_slices(store):
             bs.append(store)
             prg = slice_to_program(bs)
             path = sorted(prg.keys())
             try:
                 r = run_symbolic(prg, path, self.code, inclusive=True)
             except IntractablePath:
                 logging.exception(
                     'Intractable Path while analyzing writes')
                 continue
             addr = r.state.stack[-1]
             if concrete(addr):
                 self._writes[addr].add(store)
             else:
                 self._writes[None].add(store)
     self._writes = dict(self._writes)