def __init__(self, vm, path_dex2jar="./decompiler/dex2jar/", bin_dex2jar="dex2jar.sh", path_fernflower="./decompiler/fernflower/", bin_fernflower="fernflower.jar", options_fernflower={"dgs": '1', "asc": '1'}, tmp_dir="/tmp/"): self.classes = {} self.classes_failed = [] pathtmp = tmp_dir if not os.path.exists(pathtmp): os.makedirs(pathtmp) fd, fdname = tempfile.mkstemp(dir=pathtmp) with os.fdopen(fd, "w+b") as fd: fd.write(vm.get_buff()) fd.flush() compile = Popen([path_dex2jar + bin_dex2jar, fdname], stdout=PIPE, stderr=STDOUT) stdout, stderr = compile.communicate() os.unlink(fdname) pathclasses = fdname + "dex2jar/" compile = Popen(["unzip", fdname + "_dex2jar.jar", "-d", pathclasses], stdout=PIPE, stderr=STDOUT) stdout, stderr = compile.communicate() os.unlink(fdname + "_dex2jar.jar") for root, dirs, files in os.walk(pathclasses, followlinks=True): if files != []: for f in files: real_filename = root if real_filename[-1] != "/": real_filename += "/" real_filename += f l = ["java", "-jar", path_fernflower + bin_fernflower] for option in options_fernflower: l.append("-%s:%s" % (option, options_fernflower[option])) l.append(real_filename) l.append(root) compile = Popen(l, stdout=PIPE, stderr=STDOUT) stdout, stderr = compile.communicate() for i in vm.get_classes(): fname = pathclasses + "/" + i.get_name()[1:-1] + ".java" if os.path.isfile(fname) == True: self.classes[i.get_name()] = read(fname, binary=False) else: self.classes_failed.append(i.get_name()) rrmdir(pathclasses)
def __init__(self, vm, path_dex2jar="./decompiler/dex2jar/", bin_dex2jar="dex2jar.sh", path_jad="./decompiler/jad/", bin_jad="jad", tmp_dir="/tmp/"): self.classes = {} self.classes_failed = [] pathtmp = tmp_dir if not os.path.exists(pathtmp): os.makedirs(pathtmp) fd, fdname = tempfile.mkstemp(dir=pathtmp) with os.fdopen(fd, "w+b") as fd: fd.write(vm.get_buff()) fd.flush() compile = Popen([path_dex2jar + bin_dex2jar, fdname], stdout=PIPE, stderr=STDOUT) stdout, stderr = compile.communicate() os.unlink(fdname) pathclasses = fdname + "dex2jar/" compile = Popen(["unzip", fdname + "_dex2jar.jar", "-d", pathclasses], stdout=PIPE, stderr=STDOUT) stdout, stderr = compile.communicate() os.unlink(fdname + "_dex2jar.jar") for root, dirs, files in os.walk(pathclasses, followlinks=True): if files != []: for f in files: real_filename = root if real_filename[-1] != "/": real_filename += "/" real_filename += f compile = Popen(["wine", path_jad + bin_jad, "-o", "-d", root, real_filename], stdout=PIPE, stderr=STDOUT) stdout, stderr = compile.communicate() for i in vm.get_classes(): fname = pathclasses + "/" + i.get_name()[1:-1] + ".jad" if os.path.isfile(fname) == True: self.classes[i.get_name()] = read(fname, binary=False) else: self.classes_failed.append(i.get_name()) rrmdir(pathclasses)
def __init__(self, vm, path="./decompiler/ded/", bin_ded="ded.sh", tmp_dir="/tmp/"): self.classes = {} self.classes_failed = [] pathtmp = tmp_dir if not os.path.exists(pathtmp): os.makedirs( pathtmp ) fd, fdname = tempfile.mkstemp( dir=pathtmp ) with os.fdopen(fd, "w+b") as fd: fd.write( vm.get_buff() ) fd.flush() dirname = tempfile.mkdtemp(prefix=fdname + "-src") compile = Popen([ path + bin_ded, "-c", "-o", "-d", dirname, fdname ], stdout=PIPE, stderr=STDOUT) stdout, stderr = compile.communicate() os.unlink( fdname ) findsrc = None for root, dirs, files in os.walk( dirname + "/optimized-decompiled/" ): if dirs != []: for f in dirs: if f == "src": findsrc = root if findsrc[-1] != "/": findsrc += "/" findsrc += f break if findsrc != None: break for i in vm.get_classes(): fname = findsrc + "/" + i.get_name()[1:-1] + ".java" #print fname if os.path.isfile(fname) == True: self.classes[ i.get_name() ] = read(fname, binary=False) else: self.classes_failed.append( i.get_name() ) rrmdir( dirname )
def export_apps_to_format(filename, a, output, methods_filter=None, jar=None, decompiler_type=None, format=None): print "Dump information %s in %s" % (filename, output) if not os.path.exists(output): print "Create directory %s" % output os.makedirs(output) else: print "Clean directory %s" % output androconf.rrmdir(output) os.makedirs(output) methods_filter_expr = None if methods_filter: methods_filter_expr = re.compile(methods_filter) output_name = output if output_name[-1] != "/": output_name = output_name + "/" dump_classes = [] for vm in a.get_vms(): print "Analysis ...", sys.stdout.flush() vmx = analysis.VMAnalysis(vm) print "End" print "Decompilation ...", sys.stdout.flush() if not decompiler_type: vm.set_decompiler(decompiler.DecompilerDAD(vm, vmx)) elif decompiler_type == "dex2jad": vm.set_decompiler(decompiler.DecompilerDex2Jad(vm, androconf.CONF["PATH_DEX2JAR"], androconf.CONF["BIN_DEX2JAR"], androconf.CONF["PATH_JAD"], androconf.CONF["BIN_JAD"], androconf.CONF["TMP_DIRECTORY"])) elif decompiler_type == "dex2winejad": vm.set_decompiler(decompiler.DecompilerDex2WineJad(vm, androconf.CONF["PATH_DEX2JAR"], androconf.CONF["BIN_DEX2JAR"], androconf.CONF["PATH_JAD"], androconf.CONF["BIN_WINEJAD"], androconf.CONF["TMP_DIRECTORY"])) elif decompiler_type == "ded": vm.set_decompiler(decompiler.DecompilerDed(vm, androconf.CONF["PATH_DED"], androconf.CONF["BIN_DED"], androconf.CONF["TMP_DIRECTORY"])) elif decompiler_type == "dex2fernflower": vm.set_decompiler(decompiler.DecompilerDex2Fernflower(vm, androconf.CONF["PATH_DEX2JAR"], androconf.CONF["BIN_DEX2JAR"], androconf.CONF["PATH_FERNFLOWER"], androconf.CONF["BIN_FERNFLOWER"], androconf.CONF["OPTIONS_FERNFLOWER"], androconf.CONF["TMP_DIRECTORY"])) else: raise("invalid decompiler !") print "End" if options.jar: print "jar ...", filenamejar = decompiler.Dex2Jar(vm, androconf.CONF["PATH_DEX2JAR"], androconf.CONF["BIN_DEX2JAR"], androconf.CONF["TMP_DIRECTORY"]).get_jar() shutil.move(filenamejar, output + "classes.jar") print "End" for method in vm.get_methods(): if methods_filter_expr: msig = "%s%s%s" % (method.get_class_name(), method.get_name(), method.get_descriptor()) if not methods_filter_expr.search(msig): continue filename_class = valid_class_name(method.get_class_name()) create_directory(filename_class, output) print "Dump %s %s %s ..." % (method.get_class_name(), method.get_name(), method.get_descriptor()), filename_class = output_name + filename_class if filename_class[-1] != "/": filename_class = filename_class + "/" descriptor = method.get_descriptor() descriptor = descriptor.replace(";", "") descriptor = descriptor.replace(" ", "") descriptor = descriptor.replace("(", "-") descriptor = descriptor.replace(")", "-") descriptor = descriptor.replace("/", "_") filename = filename_class + method.get_name() + descriptor if len(method.get_name() + descriptor) > 250: all_identical_name_methods = vm.get_methods_descriptor(method.get_class_name(), method.get_name()) pos = 0 for i in all_identical_name_methods: if i.get_descriptor() == method.get_descriptor(): break pos += 1 filename = filename_class + method.get_name() + "_%d" % pos buff = method2dot(vmx.get_method(method)) if format: print "%s ..." % format, method2format(filename + "." + format, format, None, buff) if method.get_class_name() not in dump_classes: print "source codes ...", current_class = vm.get_class(method.get_class_name()) current_filename_class = valid_class_name(current_class.get_name()) create_directory(filename_class, output) current_filename_class = output_name + current_filename_class + ".java" with open(current_filename_class, "w") as fd: fd.write(current_class.get_source()) dump_classes.append(method.get_class_name()) print "bytecodes ...", bytecode_buff = dvm.get_bytecodes_method(vm, vmx, method) with open(filename + ".ag", "w") as fd: fd.write(bytecode_buff) print