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
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