コード例 #1
0
ファイル: evm.py プロジェクト: f0rki/ethersplay
    def init(self):
        self.arch = Architecture['EVM']
        self.platform = Architecture['EVM'].standalone_platform
        self.max_function_size_for_analysis = 0

        file_size = len(self.raw)

        # Find swarm hashes and make them data
        evm_bytes = self.raw.read(0, file_size)

        # code is everything that isn't a swarm hash
        code = IntervalSet([Interval(0, file_size)])

        log_debug('Finding swarm hashes')
        swarm_hashes = self.find_swarm_hashes(evm_bytes)
        for start, sz in swarm_hashes:
            self.add_auto_segment(
                start, sz, start, sz,
                (SegmentFlag.SegmentContainsData
                 | SegmentFlag.SegmentDenyExecute | SegmentFlag.SegmentReadable
                 | SegmentFlag.SegmentDenyWrite))

            code -= IntervalSet([Interval(start, start + sz)])

        for interval in code:
            if isinstance(interval, int):
                continue
            self.add_auto_segment(
                interval.lower_bound, interval.upper_bound,
                interval.lower_bound, interval.upper_bound,
                (SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable))

        log_debug('Building CFG with evm_cfg_builder')
        cfg = CFG(evm_bytes, remove_metadata=False)
        log_debug('Finished building CFG with evm_cfg_builder')
        Function.set_default_session_data('cfg', cfg)

        log_debug("registering VsaNotification")
        self.register_notification(VsaNotification())

        log_debug("specifiying entry point and functions")
        self.add_entry_point(0)

        for function in cfg.functions:
            function_start = (function._start_addr +
                              1 if function._start_addr != 0 else 0)

            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, function_start,
                       function.name))

            self.add_function(function_start)

        # disable linear sweep
        Settings().set_bool('analysis.linearSweep.autorun',
                            False,
                            view=self,
                            scope=SettingsScope.SettingsUserScope)

        return True
コード例 #2
0
ファイル: bridge.py プロジェクト: whitequark/dwarf_import
    def _translate_parameter(self, param: Parameter,
                             binja_function: bn.Function, locals: VariableSet):
        num_resolved = 0
        for loc in param.locations:
            # Resolve the location to a MLIL variable.
            binja_var, preexists = locals.add(param.name, loc)
            if binja_var is None:
                continue
            if preexists:
                continue
            if isinstance(binja_var, bn.DataVariable):
                continue

            num_resolved += 1
            binja_type = self._construct_binja_type(param.type,
                                                    as_specifier=True)

            # Set the name and type.
            new_name = param.name if param.name else binja_var.name
            if binja_var.source_type == bn.VariableSourceType.StackVariableSourceType:
                # self._log.debug(f'stack user var: storage {binja_var.storage}, name {new_name}')
                binja_function.create_user_stack_var(binja_var.storage,
                                                     binja_type, new_name)
            else:
                # self._log.debug(str(binja_var)+' '+str(binja_type)+' '+new_name)
                binja_function.create_user_var(binja_var, binja_type, new_name)
            if binja_var.name != new_name:
                binja_var.name = new_name

        if num_resolved == 0:
            # Don't report errors translating the functions of inlined subroutines.
            if not isinstance(param.function.owner, Function):
                issues = []
                for loc in param.locations:
                    assert (loc.type == LocationType.STATIC_LOCAL)
                    # was the specified location actually in this subroutine?
                    if loc.begin != 0 and binja_function in self._binary_view.get_functions_containing(
                            loc.begin):
                        issues.append(loc)
                if issues:
                    self.statistics['num_parameters_unresolved'] += 1
                    self._log.debug(
                        f'In {binja_function.symbol.short_name}(): unable to resolve parameter ("{param.name}")'
                    )
                    for loc in param.locations:
                        self._log.debug(
                            f'    (0x{loc.begin:08x}, 0x{loc.end:08x}, {loc.expr})'
                        )
                else:
                    if len(param.locations) > 0:
                        self.statistics['num_parameters_other'] += 1
        else:
            self.statistics['num_parameters_resolved'] += 1
コード例 #3
0
ファイル: bridge.py プロジェクト: whitequark/dwarf_import
 def _translate_function_type(self, function: Function,
                              binja_function: bn.Function):
     # Memoize
     if function.has_attribute('function_type'):
         function_type = function.get_attribute('function_type')
         if function_type != binja_function.function_type:
             binja_function.function_type = function_type
         return
     try:
         locals = VariableSet(binja_function, self._log)
         function_type = self._create_function_type(function,
                                                    binja_function, locals)
         if function_type is not None:
             binja_function.function_type = function_type
     except:
         self._log.warning(f'while creating function type',
                           exc_info=sys.exc_info())
コード例 #4
0
 def _translate_function_type(self, function: Function,
                              binja_function: bn.Function):
     try:
         local_vars = LocationIndex(binja_function, None, self._log)
         function_type = self._create_function_type(function,
                                                    binja_function,
                                                    local_vars)
         if function_type is not None:
             binja_function.function_type = function_type
     except Exception:
         self._log.warning('while creating function type',
                           exc_info=sys.exc_info())
コード例 #5
0
 def _is_call_site(self, func: bn.Function, ea: int) -> bool:
     inst_il = func.get_low_level_il_at(ea)
     if is_function_call(self._bv, inst_il):
         return True
     return False
コード例 #6
0
ファイル: bridge.py プロジェクト: whitequark/dwarf_import
    def _translate_local_variable(self, var: LocalVariable,
                                  binja_function: bn.Function,
                                  locals: VariableSet):
        num_resolved = 0
        num_preexists = 0
        for loc in var.locations:
            # Resolve the location to a MLIL variable.
            binja_var, preexists = locals.add(var.name, loc)
            if binja_var is None:
                continue
            if preexists:
                num_preexists += 1
                continue
            if isinstance(binja_var, bn.DataVariable):
                # A static (local scope) variable.
                binja_type = self._construct_binja_type(var.type,
                                                        as_specifier=True)
                # Set the name of the symbol.
                symbol: bn.Symbol = self._binary_view.get_symbol_at(
                    binja_var.address)
                if symbol is None or symbol.short_name != var.name:
                    name = '::'.join(var.name) if isinstance(
                        var.name, tuple) else var.name
                    self._binary_view.define_user_symbol(
                        bn.Symbol(bn.SymbolType.DataSymbol, binja_var.address,
                                  name))
                num_resolved += 1
                continue

            num_resolved += 1
            binja_type = self._construct_binja_type(var.type,
                                                    as_specifier=True)
            # Coerce to a reference type, as needed
            if (binja_var.source_type
                    == bn.VariableSourceType.RegisterVariableSourceType
                    and var.type.composite_type is not None
                    and var.type.byte_size is not None and
                    var.type.byte_size > self._binary_view.arch.address_size):
                binja_type = bn.Type.pointer(
                    self._binary_view.arch,
                    binja_type,
                    ref_type=bn.ReferenceType.ReferenceReferenceType)
                self._log.debug(
                    f'in {binja_function.symbol.short_name}, coercing to a reference: {binja_type}'
                )

            # Then set the name and type.
            new_name = var.name if var.name is not None else binja_var.name
            if binja_var.source_type == bn.VariableSourceType.StackVariableSourceType:
                binja_function.create_user_stack_var(binja_var.storage,
                                                     binja_type, new_name)
            else:
                # self._log.debug(f'Creating user variable {binja_var} with name {new_name}')
                binja_function.create_user_var(binja_var, binja_type, new_name)
            binja_var.name = var.name
            binja_var.type = binja_type

        if num_resolved == 0:
            issues = []
            for loc in var.locations:
                assert (loc.type == LocationType.STATIC_LOCAL)
                if loc.begin != 0 and binja_function in self._binary_view.get_functions_containing(
                        loc.begin):
                    issues.append(loc)
            if issues:
                self.statistics['num_variables_unresolved'] += 1
                self._log.debug(
                    f'In {binja_function.symbol.short_name}()@{binja_function.start:x}: unable to resolve variable ("{var.name}"), # of locations already assigned = {num_preexists}'
                )
                for loc in issues:
                    self._log.debug(
                        f'    (0x{loc.begin:08x}, 0x{loc.end:08x}, {loc.expr})'
                    )
            else:
                if len(var.locations) > 0:
                    self.statistics['num_variables_other'] += 1
        else:
            self.statistics['num_variables_resolved'] += 1
コード例 #7
0
def return_and_reanalyze(function: Function, result=None):
    function.reanalyze()
    return result