Exemple #1
0
    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
Exemple #2
0
    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