def _init_native_methods(self, vm): for m in vm.get_methods(): cls_name, name, _ = get_method_triple(m) access = get_access_method(m.get_access_flags()) if 'native' in access: self.native_methods.add((cls_name, name))
def should_compile(self, method): # don't compile functions that have same parameter but differ return type if method in self.conflict_methods: return False method_triple = get_method_triple(method) cls_name, name, _ = method_triple # Android VM may find the wrong method using short jni name # don't compile function if there is a same named native method if (cls_name, name) in self.native_methods: return False full_name = ''.join(method_triple) if full_name in self._compile_full_match: return True for rule in self._keep_filters: if rule.search(full_name): return False for rule in self._compile_filters: if rule.search(full_name): return True return False
def _init_conflict_methods(self, vm): all_methods = {} for m in vm.get_methods(): method_triple = get_method_triple(m, return_type=False) if method_triple in all_methods: self.conflict_methods.add(m) self.conflict_methods.add(all_methods[method_triple]) else: all_methods[method_triple] = m
def compile_dex(apkfile, filtercfg): show_logging(level=logging.INFO) d = auto_vm(apkfile) dx = analysis.Analysis(d) method_filter = MethodFilter(filtercfg, d) compiler = Dex2C(d, dx) compiled_method_code = {} errors = [] for m in d.get_methods(): method_triple = get_method_triple(m) jni_longname = JniLongName(*method_triple) full_name = ''.join(method_triple) if len(jni_longname) > 220: logger.debug("name to long %s(> 220) %s" % (jni_longname, full_name)) continue if method_filter.should_compile(m): logger.debug("compiling %s" % (full_name)) try: code = compiler.get_source_method(m) except Exception as e: logger.warning("compile method failed:%s (%s)" % (full_name, str(e)), exc_info=True) errors.append('%s:%s' % (full_name, str(e))) continue if code: compiled_method_code[method_triple] = code return compiled_method_code, errors