def split_variables(graph, lvars, DU, UD): variables = group_variables(lvars, DU, UD) if lvars: nb_vars = max(lvars) + 1 else: nb_vars = 0 for var, versions in variables.items(): nversions = len(versions) if nversions == 1: continue orig_var = lvars.pop(var) for i, (defs, uses) in enumerate(versions): if min(defs) < 0: # Param if orig_var.this: new_version = ThisParam(var, orig_var.type) else: new_version = Param(var, orig_var.type) lvars[var] = new_version else: new_version = Variable(nb_vars) new_version.type = orig_var.type lvars[nb_vars] = new_version # add new version to variables nb_vars += 1 new_version.name = '%d_%d' % (var, i) for loc in defs: if loc < 0: continue ins = graph.get_ins_from_loc(loc) curlhs = ins.var_map[ins.get_lhs()] if isinstance(curlhs, Variable): lhsType = ins.var_map[ins.get_lhs()].get_type_with_ins(ins) else: lhsType = orig_var.type new_version.type = lhsType ins.replace_lhs(new_version) DU[(new_version.value(), loc)] = DU.pop((var, loc)) for loc in uses: ins = graph.get_ins_from_loc(loc) ins.replace_var(var, new_version) UD[(new_version.value(), loc)] = UD.pop((var, loc))
def __init__(self, methanalysis): """ :param androguard.core.analysis.analysis.MethodAnalysis methanalysis: """ method = methanalysis.get_method() self.method = method self.start_block = next(methanalysis.get_basic_blocks().get(), None) self.cls_name = method.get_class_name() self.name = method.get_name() self.lparams = [] self.var_to_name = defaultdict() self.writer = None self.graph = None self.ast = None self.access = util.get_access_method(method.get_access_flags()) desc = method.get_descriptor() self.type = desc.split(')')[-1] self.params_type = util.get_params_type(desc) self.triple = method.get_triple() self.exceptions = methanalysis.exceptions.exceptions code = method.get_code() if code is None: logger.debug('No code : %s %s', self.name, self.cls_name) else: start = code.registers_size - code.ins_size if 'static' not in self.access: self.var_to_name[start] = ThisParam(start, self.cls_name) self.lparams.append(start) start += 1 num_param = 0 for ptype in self.params_type: param = start + num_param self.lparams.append(param) self.var_to_name[param] = Param(param, ptype) num_param += util.get_type_size(ptype) if not __debug__: from androguard.core import bytecode # TODO: use tempfile to create a correct tempfile (cross platform compatible) bytecode.method2png( '/tmp/dad/graphs/{}#{}.png'.format( self.cls_name.split('/')[-1][:-1], self.name), methanalysis)
def __init__(self, methanalysis): method = methanalysis.get_method() self.start_block = next(methanalysis.get_basic_blocks().get(), None) self.cls_name = method.get_class_name() self.name = method.get_name() self.lparams = [] self.var_to_name = {} self.writer = None self.graph = None access = method.get_access_flags() self.access = [ name for flag, name in util.ACCESS_FLAGS_METHODS.iteritems() if flag & access ] desc = method.get_descriptor() self.type = util.get_type(desc.split(')')[-1]) self.params_type = util.get_params_type(desc) self.exceptions = methanalysis.exceptions.exceptions code = method.get_code() if code is None: logger.debug('No code : %s %s', self.name, self.cls_name) else: start = code.registers_size - code.ins_size if 'static' not in self.access: self.var_to_name[start] = ThisParam(start, self.name) self.lparams.append(start) start += 1 num_param = 0 for ptype in self.params_type: param = start + num_param self.lparams.append(param) self.var_to_name.setdefault(param, Param(param, ptype)) num_param += util.get_type_size(ptype) if 0: from androguard.core import bytecode bytecode.method2png('/tmp/dad/graphs/%s#%s.png' % \ (self.cls_name.split('/')[-1][:-1], self.name), methanalysis)
def split_variables(graph, lvars, DU, UD): variables = group_variables(lvars, DU, UD) if lvars: nb_vars = max(lvars) + 1 else: nb_vars = 0 for var, versions in variables.items(): nversions = len(versions) if nversions == 1: continue orig_var = lvars.pop(var) for i, (defs, uses) in enumerate(versions): if min(defs) < 0: # Param if orig_var.this: new_version = ThisParam(var, orig_var.type) else: new_version = Param(var, orig_var.type) lvars[var] = new_version else: new_version = Variable(nb_vars) new_version.type = orig_var.type lvars[nb_vars] = new_version # add new version to variables nb_vars += 1 new_version.name = '%d_%d' % (var, i) for loc in defs: if loc < 0: continue ins = graph.get_ins_from_loc(loc) ins.replace_lhs(new_version) DU[(new_version.value(), loc)] = DU.pop((var, loc)) for loc in uses: ins = graph.get_ins_from_loc(loc) ins.replace_var(var, new_version) UD[(new_version.value(), loc)] = UD.pop((var, loc))
def split_variables(graph, lvars, DU, UD): treated = defaultdict(list) variables = defaultdict(list) for var, loc in sorted(DU): if var not in lvars: continue if loc in treated[var]: continue defs = [loc] uses = set(DU[(var, loc)]) change = True while change: change = False for use in uses: ldefs = UD[(var, use)] for ldef in ldefs: if ldef not in defs: defs.append(ldef) change = True for ldef in defs[1:]: luses = set(DU[(var, ldef)]) for use in luses: if use not in uses: uses.add(use) change = True treated[var].extend(defs) variables[var].append((defs, list(uses))) if lvars: nb_vars = max(lvars) + 1 else: nb_vars = 0 for var, versions in variables.iteritems(): nversions = len(versions) if nversions == 1: continue orig_var = lvars.pop(var) for i, (defs, uses) in enumerate(versions): if min(defs) < 0: # Param if orig_var.this: new_version = ThisParam(var, orig_var.type) else: new_version = Param(var, orig_var.type) lvars[var] = new_version else: new_version = Variable(nb_vars) new_version.type = orig_var.type lvars[nb_vars] = new_version # add new version to variables nb_vars += 1 new_version.name = '%d_%d' % (var, i) for loc in defs: if loc < 0: continue ins = graph.get_ins_from_loc(loc) ins.replace_lhs(new_version) DU[(new_version.value(), loc)] = DU.pop((var, loc)) for loc in uses: ins = graph.get_ins_from_loc(loc) ins.replace_var(var, new_version) UD[(new_version.value(), loc)] = UD.pop((var, loc))
def __init__(self, methanalysis, adi): method = methanalysis.get_method() self.method = method self.start_block = next(methanalysis.get_basic_blocks().get(), None) self.cls_name = method.get_class_name() self.name = method.get_name() self.lparams = [] self.var_to_name = defaultdict() self.adi = adi self.writer = None self.graph = None self.ast = None self.access = util.get_access_method(method.get_access_flags()) desc = method.get_descriptor() self.type = desc.split(')')[-1] self.params_type = util.get_params_type(desc) self.triple = method.get_triple() self.exceptions = methanalysis.exceptions.exceptions code = method.get_code() if code is None: logger.debug('No code : %s %s', self.name, self.cls_name) else: start = code.registers_size - code.ins_size if 'static' not in self.access: self.var_to_name[start] = ThisParam(start, self.cls_name) self.lparams.append(start) start += 1 num_param = 0 for ptype in self.params_type: param = start + num_param self.lparams.append(param) self.var_to_name[param] = Param(param, ptype) num_param += util.get_type_size(ptype) if self.adi != None: method_idx = method.get_method_idx() method_annotations = [ x.get_annotations_off() for x in self.adi.get_method_annotations() if x.get_method_idx() == method_idx ] param_annotations = [ x for x in self.adi.get_parameter_annotations() if x.get_method_idx() == method_idx ] self.method_annotations = get_annotations(method.CM, method_annotations) if len(param_annotations) > 0: self.param_annotations = get_parameter_annotations( method.CM, param_annotations) if len(self.param_annotations) != len(self.params_type): if len(self.params_type) - len( self.param_annotations) == 1: self.param_annotations.insert(0, []) else: print( "Failed to extract annotation from {} - {}".format( self.cls_name, self.name)) self.param_annotations = [[]] * len(self.params_type) else: self.param_annotations = [[]] * len(self.params_type) else: self.method_annotations = [] self.param_annotations = [[]] * len(self.params_type) if not __debug__: from androguard.core import bytecode # TODO: use tempfile to create a correct tempfile (cross platform compatible) bytecode.method2png( '/tmp/dad/graphs/{}#{}.png'.format( self.cls_name.split('/')[-1][:-1], self.name), methanalysis)