def main(options, arguments) : ri = risk.RiskIndicator() ri.add_risk_analysis( risk.RedFlags() ) ri.add_risk_analysis( risk.FuzzyRisk() ) if options.input != None : ret_type = androconf.is_android( options.input ) if ret_type == "APK" : a = apk.APK( options.input ) analyze_app( options.input, ri, a ) elif ret_type == "DEX" : analyze_dex( options.input, ri, read(options.input, binary=False) ) elif options.directory != None : for root, dirs, files in os.walk( options.directory, followlinks=True ) : if files != [] : for f in files : real_filename = root if real_filename[-1] != "/" : real_filename += "/" real_filename += f ret_type = androconf.is_android( real_filename ) if ret_type == "APK" : try : a = apk.APK( real_filename ) analyze_app( real_filename, ri, a ) except Exception, e : print e elif ret_type == "DEX" : analyze_dex( real_filename, ri, read(real_filename, binary=False) )
def auto_vm(filename): ret = androconf.is_android(filename) if ret == 'APK': return dvm.DalvikVMFormat(apk.APK(filename).get_dex()) elif ret == 'DEX': return dvm.DalvikVMFormat(read(filename)) elif ret == 'DEY': return dvm.DalvikOdexVMFormat(read(filename)) return None
def main(options, arguments): if options.database == None or options.config == None: return s = dalvik_elsign.MSignature( options.database, options.config, options.verbose != None, ps=dalvik_elsign.PublicSignature ) if options.input != None: ret_type = androconf.is_android(options.input) print(os.path.basename(options.input), ":", end=" ") sys.stdout.flush() if ret_type == "APK": try: a = apk.APK(options.input) if a.is_valid_APK(): display(s.check_apk(a), options.verbose) else: print("INVALID") except Exception as e: print("ERROR", e) elif ret_type == "DEX": display(s.check_dex(read(options.input)), options.verbose) elif options.directory != None: for root, dirs, files in os.walk(options.directory, followlinks=True): if files != []: for f in files: real_filename = root if real_filename[-1] != "/": real_filename += "/" real_filename += f ret_type = androconf.is_android(real_filename) if ret_type == "APK": print(os.path.basename(real_filename), ":", end=" ") sys.stdout.flush() try: a = apk.APK(real_filename) if a.is_valid_APK(): display(s.check_apk(a), options.verbose) else: print("INVALID APK") except Exception as e: print("ERROR", e) elif ret_type == "DEX": try: print(os.path.basename(real_filename), ":", end=" ") sys.stdout.flush() display(s.check_dex(read(real_filename)), options.verbose) except Exception as e: print("ERROR", e) elif options.version != None: print("Androsign version %s" % androconf.ANDROGUARD_VERSION)
def main(options, arguments): if options.input != None: buff = "" ret_type = androconf.is_android(options.input) if ret_type == "APK": a = apk.APK(options.input) buff = a.get_android_manifest_xml().toprettyxml(encoding="utf-8") elif ".xml" in options.input: ap = apk.AXMLPrinter(read(options.input)) buff = minidom.parseString(ap.get_buff()).toprettyxml( encoding="utf-8") else: print("Unknown file type") return if options.output != None: fd = codecs.open(options.output, "w", "utf-8") fd.write(buff) fd.close() else: print(buff) elif options.version != None: print("Androaxml version %s" % androconf.ANDROGUARD_VERSION)
def __init__(self, vm, bin_ded="ded.sh", tmp_dir="/tmp/"): """ DED is an old, probably deprecated, decompiler http://siis.cse.psu.edu/ded/ .. deprecated:: 3.3.5 DED is not supported by androguard anymore! It is now replaced by DARE. :param vm: `DalvikVMFormat` object :param bin_ded: :param tmp_dir: """ warnings.warn("DED is deprecated since 3.3.5.", DeprecationWarning) 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") cmd = Popen([bin_ded, "-c", "-o", "-d", dirname, fdname], stdout=PIPE, stderr=STDOUT) stdout, stderr = cmd.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 is not None: break for i in vm.get_classes(): fname = findsrc + "/" + i.get_name()[1:-1] + ".java" # print fname if os.path.isfile(fname): self.classes[i.get_name()] = read(fname, binary=False) else: self.classes_failed.append(i.get_name()) rrmdir(dirname)
def __init__(self, vm, bin_dex2jar="dex2jar.sh", bin_jad="jad", tmp_dir="/tmp/"): """ Use JAD on wine :param vm: :param bin_dex2jar: :param bin_jad: :param tmp_dir: """ 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() cmd = Popen([bin_dex2jar, fdname], stdout=PIPE, stderr=STDOUT) stdout, stderr = cmd.communicate() os.unlink(fdname) pathclasses = fdname + "dex2jar/" cmd = Popen(["unzip", fdname + "_dex2jar.jar", "-d", pathclasses], stdout=PIPE, stderr=STDOUT) stdout, stderr = cmd.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 cmd = Popen(["wine", bin_jad, "-o", "-d", root, real_filename], stdout=PIPE, stderr=STDOUT) stdout, stderr = cmd.communicate() for i in vm.get_classes(): fname = pathclasses + "/" + i.get_name()[1:-1] + ".jad" if os.path.isfile(fname): self.classes[i.get_name()] = read(fname, binary=False) else: self.classes_failed.append(i.get_name()) rrmdir(pathclasses)
def get_info(self, srules) : rules = json.loads( srules ) ret_type = androconf.is_android( rules[0]["SAMPLE"] ) if ret_type == "APK" : a = apk.APK( rules[0]["SAMPLE"] ) classes_dex = a.get_dex() elif ret_type == "DEX" : classes_dex = read( rules[0]["SAMPLE"]) #elif ret_type == "ELF" : #elf_file = read( rules[0]["SAMPLE"]) else : return None if ret_type == "APK" or ret_type == "DEX" : vm = dvm.DalvikVMFormat( classes_dex ) vmx = analysis.VMAnalysis( vm ) res = [] for i in rules[1:] : for j in i["SIGNATURE"] : if j["TYPE"] == "METHSIM" : m = vm.get_method_descriptor( j["CN"], j["MN"], j["D"] ) if m == None : print "impossible to find", j["CN"], j["MN"], j["D"] else : res.append( m ) elif j["TYPE"] == "CLASSSIM" : for c in vm.get_classes() : if j["CN"] == c.get_name() : res.append( c ) return vm, vmx, res
def check_db(self, output) : ids = {} meth_sim = [] class_sim = [] buff = json.loads( read(output, binary=False) ) for i in buff : nb = 0 for ssign in buff[i][0] : if ssign[0] == METHSIM : value = base64.b64decode( ssign[1] ) if value in ids : print "IDENTICAL", ids[ value ], i, nb else : ids[ value ] = (i, nb) meth_sim.append( value ) elif ssign[0] == CLASSSIM : ids[ base64.b64decode( ssign[1] ) ] = (i, nb) class_sim.append( base64.b64decode( ssign[1] ) ) nb += 1 from elsim.similarity import similarity s = similarity.SIMILARITY( "./elsim/elsim/similarity/libsimilarity/libsimilarity.so" ) s.set_compress_type( similarity.SNAPPY_COMPRESS ) self.__check_db( s, ids, meth_sim ) self.__check_db( s, ids, class_sim )
def main(options, arguments): if options.database == None or options.config == None: return s = dalvik_elsign.MSignature(options.database, options.config, options.verbose != None, ps=dalvik_elsign.PublicSignature) if options.input != None: ret_type = androconf.is_android(options.input) print os.path.basename(options.input), ":", sys.stdout.flush() if ret_type == "APK": try: a = apk.APK(options.input) if a.is_valid_APK(): display(s.check_apk(a), options.verbose) else: print "INVALID" except Exception, e: print "ERROR", e elif ret_type == "DEX": display(s.check_dex(read(options.input)), options.verbose)
def __init__(self, files, raw=False): self.__files = files self.__orig_raw = {} for i in self.__files: self.__orig_raw[ i ] = read(i) self.__bc = [] self._analyze()
def _analyze(self): for i in self.__files: ret_type = androconf.is_android( i ) if ret_type == "APK": x = apk.APK( i ) bc = dvm.DalvikVMFormat( x.get_dex() ) elif ret_type == "DEX": bc = dvm.DalvikVMFormat( read(i) ) elif ret_type == "DEY": bc = dvm.DalvikOdexVMFormat( read(i) ) elif ret_type == "ELF": from androguard.core.binaries import elf bc = elf.ELF( read(i) ) else: raise( "Unknown format" ) self.__bc.append( (i, BC( bc )) )
def run(self): self.view = self.window.active_view() filename = self.view.file_name() ret = androconf.is_android(filename) if ret == "APK": at = AnalyseAPKThread(self.window.new_file(), filename, read(filename)) at.run() elif ret == "DEX" or ret == "DEY": at = AnalyseDexThread(self.window.new_file(), filename, read(filename)) at.run() elif ret == "AXML": at = AnalyseAXMLSimpleThread(self.window.new_file(), filename, read(filename)) at.run() elif ret == "ARSC": at = AnalyseARSCThread(self.window.new_file(), filename, read(filename)) at.run()
def fetcher(self, q): for root, dirs, files in os.walk(self.directory, followlinks=True): if files != []: for f in files: real_filename = root if real_filename[-1] != "/": real_filename += "/" real_filename += f q.put((real_filename, read(real_filename))) return False
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 _load(self): self.DE.load_config( json.loads( read(self.config) ) ) buff = json.loads( read(self.database) ) for i in buff: type_signature = None sub_signatures = [] for j in buff[i][0]: if j[0] == METHSIM: type_signature = METHSIM sub_signatures.append( [ j[2:], str(base64.b64decode( j[1] ) ) ] ) elif j[0] == CLASSSIM: type_signature = CLASSSIM sub_signatures.append( [ j[2:], str(base64.b64decode( j[1] ) ) ] ) if type_signature != None: self.DE.add_signature( type_signature, i, buff[i][1], sub_signatures ) else: print i, "ERROR"
def __init__(self, name): """ :param name: filename to load """ self.vma = analysis.Analysis() # Proper detection which supports multidex inside APK ftype = androconf.is_android(name) if ftype == 'APK': for d in apk.APK(name).get_all_dex(): self.vma.add(dvm.DalvikVMFormat(d)) elif ftype == 'DEX': self.vma.add(dvm.DalvikVMFormat(read(name))) elif ftype == 'DEY': self.vma.add(dvm.DalvikOdexVMFormat(read(name))) else: raise ValueError("Format not recognised for filename '%s'" % name) self.classes = {dvclass.orig_class.get_name(): dvclass.orig_class for dvclass in self.vma.get_classes()}
def list_indb(self, output) : from elsim.similarity import similarity s = similarity.SIMILARITY( "./elsim/elsim/similarity/libsimilarity/libsimilarity.so" ) s.set_compress_type( similarity.ZLIB_COMPRESS ) buff = json.loads( read(output, binary=False) ) for i in buff : print i for j in buff[i][0] : sign = base64.b64decode(j[1]) print "\t", j[0], "ENTROPIES:", j[2:], "L:%d" % len(sign), "K:%d" % s.kolmogorov(sign)[0] print "\tFORMULA:", buff[i][-1]
def run_loader(self): """ Load the target APK and return the loaded instance, which will be stored as a global """ if self.args[0] == enum.apk: # Load APK without classes.dex # The second element in this array should be the file path if os.path.splitext(self.args[1])[1] != ".apk": print(t.red("[{0}] ".format(datetime.now())) + t.white(enum.NOT_AN_APK)) else: print(t.green("[{0}] ".format(datetime.now()) + t.yellow("Loading : ") + "{0}".format(self.args[1]))) try: # Return an APK object apk = APK(self.args[1]) return apk except IOError as e: raise e elif self.args[0] == enum.dex: # Load classes.dex # The second element in this array should be the file path if os.path.splitext(self.args[1])[1] != ".dex": print(t.red("[{0}] ".format(datetime.now())) + t.white(enum.NOT_A_DEX)) else: print(t.green("[{0}] ".format(datetime.now()) + t.yellow("Loading : ") + "{0}".format(self.args[1]))) try: # Return a DalvikVM object d = dvm.DalvikVMFormat(read(self.args[1], binary=False)) return d except IOError as e: raise e else: # Load APK with classes.dex # The first argument should be the file path if os.path.splitext(self.args[0])[1] != ".apk": print(t.red("[{0}] ".format(datetime.now())) + t.white(enum.NOT_AN_APK)) else: print(t.green("[{0}] ".format(datetime.now()) + t.yellow("Loading : ") + "{0}".format(self.args[0]))) try: # Return an APK and APKS object apk = APK(self.args[0]) apks = AndroguardS(self.args[0]) return apk, apks except struct.error: print(t.red("[{0}] ".format(datetime.now())) + t.white(enum.FILE_TYPE_ERROR)) print(t.red("[{0}] ".format(datetime.now())) + t.white(enum.APK_ONLY_ERROR)) sys.exit(1)
def AnalyzeElf(filename, raw=False): # avoid to install smiasm for everybody from androguard.core.binaries.elf import ELF e = None if raw == False: e = ELF(read(filename)) else: e = ELF(filename) ExportElfToPython(e) return e
def load_session(filename): """ load your session ! :param filename: the filename where the session has been saved :type filename: string :rtype: the elements of your session :) :Example: a, vm, vmx = load_session("mysession.json") """ return loads(read(filename, binary=False))
def main(options, arguments) : if options.input != None : el = Elsim( ProxyText( read(options.input[0]) ), ProxyText( read(options.input[1]) ), FILTERS_TEXT, libpath="elsim/similarity/libsimilarity/libsimilarity.so") el.show() print "\t--> sentences: %f%% of similarities" % el.get_similarity_value() if options.display : print "SIMILAR sentences:" diff_methods = el.get_similar_elements() for i in diff_methods : el.show_element( i ) print "IDENTICAL sentences:" new_methods = el.get_identical_elements() for i in new_methods : el.show_element( i ) print "NEW sentences:" new_methods = el.get_new_elements() for i in new_methods : el.show_element( i, False ) print "DELETED sentences:" del_methods = el.get_deleted_elements() for i in del_methods : el.show_element( i ) print "SKIPPED sentences:" skip_methods = el.get_skipped_elements() for i in skip_methods : el.show_element( i ) elif options.version != None : print "example text sim %s" % ELSIM_VERSION
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 main(inp, outp=None): ret_type = androconf.is_android(inp) if ret_type == "APK": a = apk.APK(inp) axml = a.get_android_manifest_xml() elif ".xml" in inp: axml = apk.AXMLPrinter(read(inp)).get_xml_obj() else: print("Unknown file type") return buff = etree.tostring(axml, pretty_print=True, encoding="utf-8") if outp: with open(outp, "wb") as fd: fd.write(buff) else: print(buff.decode("UTF-8"))
def androaxml_main(inp, outp=None): ret_type = androconf.is_android(inp) if ret_type == "APK": a = apk.APK(inp) axml = a.get_android_manifest_xml() elif ".xml" in inp: axml = apk.AXMLPrinter(read(inp)).get_xml_obj() else: print("Unknown file type") return buff = etree.tostring(axml, pretty_print=True, encoding="utf-8") if outp: with open(outp, "wb") as fd: fd.write(buff) else: print(buff.decode("UTF-8"))
def main(options, arguments): if options.input != None: buff = "" arscobj = None ret_type = androconf.is_android(options.input) if ret_type == "APK": a = apk.APK(options.input) arscobj = a.get_android_resources() elif ret_type == "ARSC": arscobj = apk.ARSCParser(read(options.input)) else: # print("Unknown file type") return if not options.package and not options.type and not options.locale: buff = "" for package in arscobj.get_packages_names(): buff += package + "\n" for locale in arscobj.get_locales(package): buff += "\t" + repr(locale) + "\n" for ttype in arscobj.get_types(package, locale): buff += "\t\t" + ttype + "\n" else: package = options.package or arscobj.get_packages_names()[0] ttype = options.type or "public" locale = options.locale or '\x00\x00' buff = minidom.parseString( getattr(arscobj, "get_" + ttype + "_resources")(package, locale)).toprettyxml() if options.output != None: fd = codecs.open(options.output, "w", "utf-8") fd.write(buff) fd.close() else: # print(buff) psdd elif options.version != None: # print("Androarsc version %s" % androconf.ANDROGUARD_VERSION) pass
def main(options, arguments): s = dalvik_elsign.CSignature(pcs=dalvik_elsign.PublicCSignature) if options.input != None: ret = s.add_file(read(options.input)) if ret != None and options.output != None: s.add_indb(ret, options.output) elif options.list != None: s.list_indb(options.list) elif options.remove != None: s.remove_indb(options.remove, options.output) elif options.check != None: s.check_db(options.check) elif options.version != None: print("Androcsign version %s" % androconf.ANDROGUARD_VERSION)
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( [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 check_one_directory(directory): for root, dirs, files in os.walk(directory, followlinks=True): if files != []: for f in files: real_filename = root if real_filename[-1] != "/": real_filename += "/" real_filename += f print "filename: %s ..." % real_filename ret_type = androconf.is_android(real_filename) if ret_type == "APK": a = apk.APK(real_filename) d1 = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX": d1 = dvm.DalvikVMFormat(read(real_filename)) dx1 = analysis.VMAnalysis(d1) check_one_file(d1, dx1)
def check_one_directory(directory): for root, dirs, files in os.walk(directory, followlinks=True): if files != []: for f in files: real_filename = root if real_filename[-1] != "/": real_filename += "/" real_filename += f print("filename: %s ..." % real_filename) ret_type = androconf.is_android(real_filename) if ret_type == "APK": a = apk.APK(real_filename) d1 = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX": d1 = dvm.DalvikVMFormat(read(real_filename)) dx1 = analysis.VMAnalysis(d1) check_one_file(d1, dx1)
def run_loader(self): """ Load the target APK and return the loaded instance, which will be stored as a global """ if self.args[0] == "apk": print( t.green("[{0}] ".format(datetime.now()) + t.yellow("Loading : ") + "{0}".format(self.args[1]))) try: apk = APK(self.args[1]) return apk except IOError as e: raise e elif self.args[0] == "dex": print( t.green("[{0}] ".format(datetime.now()) + t.yellow("Loading : ") + "{0}".format(self.args[1]))) try: d = dvm.DalvikVMFormat(read(self.args[1], binary=False)) return d except IOError as e: raise e else: print( t.green("[{0}] ".format(datetime.now()) + t.yellow("Loading : ") + "{0}".format(self.args[0]))) try: apk = APK(self.args[0]) apks = AndroguardS(self.args[0]) return apk, apks except struct.error: print( t.red("[{0}] ".format(datetime.now())) + t.white( "The application does not contain an executable file")) print( t.red("[{0}] ".format(datetime.now())) + t.white("Please load the application as an APK only")) sys.exit(1)
def main(options, arguments): if options.input is not None: buff = "" arscobj = None ret_type = androconf.is_android(options.input) if ret_type == "APK": a = apk.APK(options.input) arscobj = a.get_android_resources() elif ret_type == "ARSC": arscobj = apk.ARSCParser(read(options.input)) else: print("Unknown file type") return if not options.package and not options.type and not options.locale: buff = "" for package in arscobj.get_packages_names(): buff += package + "\n" for locale in arscobj.get_locales(package): buff += "\t" + repr(locale) + "\n" for ttype in arscobj.get_types(package, locale): buff += "\t\t" + ttype + "\n" else: package = options.package or arscobj.get_packages_names()[0] ttype = options.type or "public" locale = options.locale or '\x00\x00' buff = minidom.parseString(getattr( arscobj, "get_" + ttype + "_resources")(package, locale)).toprettyxml() if options.output is not None: fd = codecs.open(options.output, "w", "utf-8") fd.write(buff) fd.close() else: print(buff) elif options.version is not None: print("Androarsc version %s" % androconf.ANDROGUARD_VERSION)
def main(options, arguments) : if options.input != None and options.output != None and options.name != None and options.subname != None : edi = ElsimDBIn( options.output ) ret_type = androconf.is_android( options.input ) if ret_type == "APK" : a = apk.APK( options.input ) d1 = dvm.DalvikVMFormat( a.get_dex() ) elif ret_type == "DEX" : d1 = dvm.DalvikVMFormat( read(options.input) ) dx1 = analysis.VMAnalysis( d1 ) regexp_pattern = None regexp_exclude_pattern = None edi.add( d1, dx1, options.name, options.sname, regexp_pattern, regexp_exclude_pattern) edi.save() elif options.version != None : print "Androapptodb version %s" % androconf.ANDROGUARD_VERSION
def main(options, arguments): if options.input is not None: ret_type = androconf.is_android(options.input) if ret_type == "APK": a = apk.APK(options.input) axml = a.get_android_manifest_xml() elif ".xml" in options.input: axml = apk.AXMLPrinter(read(options.input)).get_xml_obj() else: print("Unknown file type") return buff = etree.tostring(axml, pretty_print=True) if options.output: with open(options.output, "wb") as fd: fd.write(buff) else: print(buff.decode("UTF-8")) elif options.version is not None: print("Androaxml version %s" % androconf.ANDROGUARD_VERSION)
def main(options, arguments): if options.input != None and options.database != None: ret_type = androconf.is_android(options.input) if ret_type == "APK": a = apk.APK(options.input) d1 = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX": d1 = dvm.DalvikVMFormat(read(options.input)) dx1 = analysis.VMAnalysis(d1) check_one_file(d1, dx1) elif options.directory != None and options.database != None: check_one_directory(options.directory) elif options.database != None and options.listdatabase != None: db = DBFormat(options.database) db.show() elif options.version != None: print "Androappindb version %s" % androconf.ANDROGUARD_VERSION
def main(options, arguments): if options.input != None and options.output != None and options.name != None and options.subname != None: edi = ElsimDBIn(options.output) ret_type = androconf.is_android(options.input) if ret_type == "APK": a = apk.APK(options.input) d1 = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX": d1 = dvm.DalvikVMFormat(read(options.input)) dx1 = analysis.VMAnalysis(d1) regexp_pattern = None regexp_exclude_pattern = None edi.add(d1, dx1, options.name, options.sname, regexp_pattern, regexp_exclude_pattern) edi.save() elif options.version != None: print("Androapptodb version %s" % androconf.ANDROGUARD_VERSION)
def main(options, arguments): if options.input != None and options.database != None: ret_type = androconf.is_android(options.input) if ret_type == "APK": a = apk.APK(options.input) d1 = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX": d1 = dvm.DalvikVMFormat(read(options.input)) dx1 = analysis.VMAnalysis(d1) check_one_file(d1, dx1) elif options.directory != None and options.database != None: check_one_directory(options.directory) elif options.database != None and options.listdatabase != None: db = DBFormat(options.database) db.show() elif options.version != None: print("Androappindb version %s" % androconf.ANDROGUARD_VERSION)
def main(options, arguments): if options.input != None: a = None ret_type = androconf.is_android(options.input[0]) if ret_type == "APK": a = apk.APK(options.input[0]) d1 = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX": d1 = dvm.DalvikVMFormat(read(options.input[0])) dx1 = analysis.VMAnalysis(d1) threshold = None if options.threshold != None: threshold = float(options.threshold) FS = FILTERS_DALVIK_SIM FS[elsim.FILTER_SKIPPED_METH].set_regexp(options.exclude) FS[elsim.FILTER_SKIPPED_METH].set_size(options.size) new = True if options.new != None: new = False library = False if options.library != None: library = options.library if options.library == "python": library = False if os.path.isdir(options.input[1]) == False: check_one_file(a, d1, dx1, FS, threshold, options.input[1], options.xstrings, new, library) else: check_one_directory(a, d1, dx1, FS, threshold, options.input[1], options.xstrings, new, library) elif options.version != None: print "Androsim version %s" % androconf.ANDROGUARD_VERSION
def AnalyzeDex(filename, raw=False, decompiler=None): """ Analyze an android dex file and setup all stuff for a more quickly analysis ! :param filename: the filename of the android dex file or a buffer which represents the dex file :type filename: string :param raw: True is you would like to use a buffer (optional) :type raw: boolean :rtype: return the :class:`DalvikVMFormat`, and :class:`VMAnalysis` objects """ androconf.debug("DalvikVMFormat ...") d = None if raw == False: d = DalvikVMFormat(read(filename)) else: d = DalvikVMFormat(filename) androconf.debug("Export VM to python namespace") d.create_python_export() androconf.debug("VMAnalysis ...") dx = uVMAnalysis(d) androconf.debug("GVMAnalysis ...") gx = GVMAnalysis(dx, None) d.set_vmanalysis(dx) d.set_gvmanalysis(gx) RunDecompiler(d, dx, decompiler) androconf.debug("XREF ...") d.create_xref() androconf.debug("DREF ...") d.create_dref() return d, dx
def main(options, arguments): if options.input != None: a = None ret_type = androconf.is_android(options.input[0]) if ret_type == "APK": a = apk.APK(options.input[0]) d1 = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX": d1 = dvm.DalvikVMFormat(read(options.input[0])) dx1 = analysis.VMAnalysis(d1) threshold = None if options.threshold != None: threshold = float(options.threshold) FS = FILTERS_DALVIK_SIM FS[elsim.FILTER_SKIPPED_METH].set_regexp(options.exclude) FS[elsim.FILTER_SKIPPED_METH].set_size(options.size) new = True if options.new != None: new = False library = True if options.library != None: library = options.library if options.library == "python": library = False if os.path.isdir(options.input[1]) == False: check_one_file(a, d1, dx1, FS, threshold, options.input[1], options.xstrings, new, library) else: check_one_directory(a, d1, dx1, FS, threshold, options.input[1], options.xstrings, new, library) elif options.version != None: print "Androsim version %s" % androconf.ANDROGUARD_VERSION
def main(options, arguments): if options.database == None or options.config == None: return s = dalvik_elsign.MSignature( options.database, options.config, options.verbose != None, ps = dalvik_elsign.PublicSignature) if options.input != None: ret_type = androconf.is_android( options.input ) print os.path.basename(options.input), ":", sys.stdout.flush() if ret_type == "APK": try: a = apk.APK( options.input ) if a.is_valid_APK(): display( s.check_apk( a ), options.verbose ) else: print "INVALID" except Exception, e: print "ERROR", e elif ret_type == "DEX": display( s.check_dex( read(options.input) ), options.verbose )
def main(options, arguments): if options.input != None and options.output != None: ret_type = androconf.is_android(options.input) vm = None a = None if ret_type == "APK": a = apk.APK(options.input) if a.is_valid_APK(): vm = dvm.DalvikVMFormat(a.get_dex()) else: print("INVALID APK") elif ret_type == "DEX": try: vm = dvm.DalvikVMFormat(read(options.input)) except Exception as e: print("INVALID DEX", e) vmx = analysis.VMAnalysis(vm) gvmx = ganalysis.GVMAnalysis(vmx, a) b = gvmx.export_to_gexf() androconf.save_to_disk(b, options.output)
def main(options, arguments): if options.input != None and options.output != None: ret_type = androconf.is_android(options.input) vm = None a = None if ret_type == "APK": a = apk.APK(options.input) if a.is_valid_APK(): vm = dvm.DalvikVMFormat(a.get_dex()) else: print "INVALID APK" elif ret_type == "DEX": try: vm = dvm.DalvikVMFormat(read(options.input)) except Exception, e: print "INVALID DEX", e vmx = analysis.VMAnalysis(vm) gvmx = ganalysis.GVMAnalysis(vmx, a) create_directories(vm, options.output) # dv.export_to_gml( options.output ) dd = data.Data(vm, vmx, gvmx, a) buff = dd.export_apk_to_gml() androconf.save_to_disk(buff, options.output + "/" + "apk.graphml") buff = dd.export_methodcalls_to_gml() androconf.save_to_disk(buff, options.output + "/" + "methodcalls.graphml") buff = dd.export_dex_to_gml() for i in buff: androconf.save_to_disk(buff[i], options.output + "/" + i + ".graphml")
def androaxml_main(inp, outp=None, resource=None): ret_type = androconf.is_android(inp) if ret_type == "APK": a = apk.APK(inp) if resource: if resource not in a.files: print("The APK does not contain a file called '{}'".format(resource), file=sys.stderr) sys.exit(1) axml = AXMLPrinter(a.get_file(resource)).get_xml_obj() else: axml = a.get_android_manifest_xml() elif ".xml" in inp: axml = AXMLPrinter(read(inp)).get_xml_obj() else: print("Unknown file type") sys.exit(1) buff = etree.tostring(axml, pretty_print=True, encoding="utf-8") if outp: with open(outp, "wb") as fd: fd.write(buff) else: sys.stdout.write(highlight(buff.decode("UTF-8"), get_lexer_by_name("xml"), TerminalFormatter()))
def fetcher(self, q): for root, _, files in os.walk(self.directory, followlinks=True): for f in files: real_filename = os.path.join(root, f) q.put((real_filename, read(real_filename))) return False
def main(options, arguments): details = False if options.display != None: details = True if options.input != None: ret_type = androconf.is_android(options.input[0]) if ret_type == "APK": a = apk.APK(options.input[0]) d1 = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX": d1 = dvm.DalvikVMFormat(read(options.input[0])) dx1 = analysis.VMAnalysis(d1) ret_type = androconf.is_android(options.input[1]) if ret_type == "APK": a = apk.APK(options.input[1]) d2 = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX": d2 = dvm.DalvikVMFormat(read(options.input[1])) dx2 = analysis.VMAnalysis(d2) print d1, dx1, d2, dx2 sys.stdout.flush() threshold = None if options.threshold != None: threshold = float(options.threshold) FS = FILTERS_DALVIK_SIM FS[elsim.FILTER_SKIPPED_METH].set_regexp(options.exclude) FS[elsim.FILTER_SKIPPED_METH].set_size(options.size) el = elsim.Elsim(ProxyDalvik(d1, dx1), ProxyDalvik(d2, dx2), FS, threshold, options.compressor) el.show() e1 = elsim.split_elements(el, el.get_similar_elements()) for i in e1: j = e1[i] elb = elsim.Elsim(ProxyDalvikMethod(i), ProxyDalvikMethod(j), FILTERS_DALVIK_BB, threshold, options.compressor) #elb.show() eld = elsim.Eldiff(ProxyDalvikBasicBlock(elb), FILTERS_DALVIK_DIFF_BB) #eld.show() ddm = DiffDalvikMethod(i, j, elb, eld) ddm.show() print "NEW METHODS" enew = el.get_new_elements() for i in enew: el.show_element(i, False) print "DELETED METHODS" edel = el.get_deleted_elements() for i in edel: el.show_element(i) elif options.version != None: print "Androdiff version %s" % androconf.ANDROGUARD_VERSION
if ret_type == "APK": print os.path.basename(real_filename), ":", sys.stdout.flush() try: a = apk.APK(real_filename) if a.is_valid_APK(): display(s.check_apk(a), options.verbose) else: print "INVALID APK" except Exception, e: print "ERROR", e elif ret_type == "DEX": try: print os.path.basename(real_filename), ":", sys.stdout.flush() display(s.check_dex(read(real_filename)), options.verbose) except Exception, e: print "ERROR", e elif options.version != None: print "Androsign version %s" % androconf.ANDROGUARD_VERSION if __name__ == "__main__": parser = OptionParser() for option in options: param = option['name'] del option['name'] parser.add_option(*param, **option)
def check_one_file(a, d1, dx1, FS, threshold, file_input, view_strings=False, new=True, library=True): d2 = None ret_type = androconf.is_android(file_input) if ret_type == "APK": a = apk.APK(file_input) d2 = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX": d2 = dvm.DalvikVMFormat(read(file_input)) if d2 == None: return dx2 = analysis.VMAnalysis(d2) el = elsim.Elsim(ProxyDalvik(d1, dx1), ProxyDalvik(d2, dx2), FS, threshold, options.compressor, libnative=library) el.show() print "\t--> methods: %f%% of similarities" % el.get_similarity_value(new) if options.display: print "SIMILAR methods:" diff_methods = el.get_similar_elements() for i in diff_methods: el.show_element(i) print "IDENTICAL methods:" new_methods = el.get_identical_elements() for i in new_methods: el.show_element(i) print "NEW methods:" new_methods = el.get_new_elements() for i in new_methods: el.show_element(i, False) print "DELETED methods:" del_methods = el.get_deleted_elements() for i in del_methods: el.show_element(i) print "SKIPPED methods:" skipped_methods = el.get_skipped_elements() for i in skipped_methods: el.show_element(i) if view_strings: els = elsim.Elsim(ProxyDalvikStringMultiple(d1, dx1), ProxyDalvikStringMultiple(d2, dx2), FILTERS_DALVIK_SIM_STRING, threshold, options.compressor, libnative=library) #els = elsim.Elsim( ProxyDalvikStringOne(d1, dx1), # ProxyDalvikStringOne(d2, dx2), FILTERS_DALVIK_SIM_STRING, threshold, options.compressor, libnative=library ) els.show() print "\t--> strings: %f%% of similarities" % els.get_similarity_value( new) if options.display: print "SIMILAR strings:" diff_strings = els.get_similar_elements() for i in diff_strings: els.show_element(i) print "IDENTICAL strings:" new_strings = els.get_identical_elements() for i in new_strings: els.show_element(i) print "NEW strings:" new_strings = els.get_new_elements() for i in new_strings: els.show_element(i, False) print "DELETED strings:" del_strings = els.get_deleted_elements() for i in del_strings: els.show_element(i) print "SKIPPED strings:" skipped_strings = els.get_skipped_elements() for i in skipped_strings: els.show_element(i)
def __init__(self, vm, bin_dex2jar="dex2jar.sh", bin_jad="jad", tmp_dir="/tmp/"): """ Use JAD on wine .. deprecated:: 3.3.5 JAD is not supported anymore by androguard! :param vm: :param bin_dex2jar: :param bin_jad: :param tmp_dir: """ warnings.warn("JAD is deprecated since 3.3.5.", DeprecationWarning) 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() cmd = Popen([bin_dex2jar, fdname], stdout=PIPE, stderr=STDOUT) stdout, stderr = cmd.communicate() os.unlink(fdname) pathclasses = fdname + "dex2jar/" cmd = Popen(["unzip", fdname + "_dex2jar.jar", "-d", pathclasses], stdout=PIPE, stderr=STDOUT) stdout, stderr = cmd.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 cmd = Popen( ["wine", bin_jad, "-o", "-d", root, real_filename], stdout=PIPE, stderr=STDOUT) stdout, stderr = cmd.communicate() for i in vm.get_classes(): fname = pathclasses + "/" + i.get_name()[1:-1] + ".jad" if os.path.isfile(fname): self.classes[i.get_name()] = read(fname, binary=False) else: self.classes_failed.append(i.get_name()) rrmdir(pathclasses)
def decode_manifest(xml_path, out_path): manifest = AXMLPrinter(read(xml_path)).get_xml_obj() buff = etree.tounicode(manifest, pretty_print=True) with open(out_path + '/{}/manifest.xml'.format(xml_path.split('/')[-2]), 'w') as f: f.write(buff)
#!/usr/bin/env python import sys PATH_INSTALL = "./" sys.path.append(PATH_INSTALL) from androguard.core.bytecodes import dvm from androguard.core.analysis import analysis from androguard.decompiler.dad import decompile from androguard.util import read TEST = 'examples/android/TestsAndroguard/bin/classes.dex' vm = dvm.DalvikVMFormat(read(TEST, binary=False)) vmx = analysis.VMAnalysis(vm) # CFG for method in vm.get_methods(): mx = vmx.get_method(method) if method.get_code() == None: continue print method.get_class_name(), method.get_name(), method.get_descriptor() ms = decompile.DvMethod(mx) ms.process() print ms.get_source()
#!/usr/bin/env python import sys PATH_INSTALL = "./" sys.path.append(PATH_INSTALL) from androguard.core.bytecodes import apk from androguard.util import read from xml.dom import minidom ap = apk.AXMLPrinter( read("examples/axml/AndroidManifest2.xml", binary=False) ) print(minidom.parseString( ap.getBuff() ).toxml())
if ret_type == "APK": print os.path.basename( real_filename ), ":", sys.stdout.flush() try: a = apk.APK( real_filename ) if a.is_valid_APK(): display( s.check_apk( a ), options.verbose ) else: print "INVALID APK" except Exception, e: print "ERROR", e elif ret_type == "DEX": try: print os.path.basename( real_filename ), ":", sys.stdout.flush() display( s.check_dex( read(real_filename) ), options.verbose ) except Exception, e: print "ERROR", e elif options.version != None: print "Androsign version %s" % androconf.ANDROGUARD_VERSION if __name__ == "__main__": parser = OptionParser() for option in options: param = option['name'] del option['name'] parser.add_option(*param, **option) options, arguments = parser.parse_args() sys.argv[:] = arguments
if not args.input and not args.file: print("Give one file to decode!", file=sys.stderr) sys.exit(1) if args.input: fname = args.input else: fname = args.file ret_type = androconf.is_android(fname) if ret_type == "APK": a = apk.APK(fname) arscobj = a.get_android_resources() elif ret_type == "ARSC": arscobj = apk.ARSCParser(read(fname)) else: print("Unknown file type!", file=sys.stderr) sys.exit(1) if args.list_packages: print("\n".join(arscobj.get_packages_names())) sys.exit(0) if args.list_locales: for p in arscobj.get_packages_names(): print("In Package:", p) print("\n".join(map(lambda x: " \\x00\\x00" if x == "\x00\x00" else " {}".format(x), sorted(arscobj.get_locales(p))))) sys.exit(0)
for each_method in methods: each_method.pretty_show() print print "\n\n\n" isAPK = True if isAPK: apkFile = sys.argv[1] a = apk.APK(apkFile) dex = dvm.DalvikVMFormat(a.get_dex()) else: DEXFile = sys.argv[1] dex = dvm.DalvikVMFormat(read(DEXFile)) ''' access_dex_header(dex) print_classes_name(dex, classNameFilter) access_classes(dex, classNameFilter) access_class(dex, class_name) print_methods_name(dex, methodNameFilter) access_methods_name(dex, methodNameFilter) access_methods_descriptor(dex, class_name, method_name) access_methods_class(dex, class_name) access_method(methodObj) /* search specific API invoked
def __init__(self, vm, bin_dex2jar="dex2jar.sh", bin_fernflower="fernflower.jar", options_fernflower={ "dgs": '1', "asc": '1' }, tmp_dir="/tmp/"): """ Decompiler interface for Fernflower Fernflower is a java decompiler by IntelliJ: https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine As it can not decompile Dalvik code directly, the DEX is first decompiled as a JAR file. :param vm: `DalvikVMFormtat` object :param bin_dex2jar: :param bin_fernflower: :param options_fernflower: :param tmp_dir: """ 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() cmd = Popen([bin_dex2jar, fdname], stdout=PIPE, stderr=STDOUT) stdout, stderr = cmd.communicate() os.unlink(fdname) pathclasses = fdname + "dex2jar/" cmd = Popen(["unzip", fdname + "_dex2jar.jar", "-d", pathclasses], stdout=PIPE, stderr=STDOUT) stdout, stderr = cmd.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", bin_fernflower] for option in options_fernflower: l.append("-%s:%s" % (option, options_fernflower[option])) l.append(real_filename) l.append(root) cmd = Popen(l, stdout=PIPE, stderr=STDOUT) stdout, stderr = cmd.communicate() for i in vm.get_classes(): fname = pathclasses + "/" + i.get_name()[1:-1] + ".java" if os.path.isfile(fname): self.classes[i.get_name()] = read(fname, binary=False) else: self.classes_failed.append(i.get_name()) rrmdir(pathclasses)
def __init__(self, filename, raw=False, magic_file=None, skip_analysis=False, testzip=False): """ This class can access to all elements in an APK file :param filename: specify the path of the file, or raw data :param raw: specify if the filename is a path or raw data (optional) :param magic_file: specify the magic file (optional) :param skip_analysis: Skip the analysis, e.g. no manifest files are read. (default: False) :param testzip: Test the APK for integrity, e.g. if the ZIP file is broken. Throw an exception on failure (default False) :type filename: string :type raw: boolean :type magic_file: string :type skip_analysis: boolean :type testzip: boolean :Example: APK("myfile.apk") APK(read("myfile.apk"), raw=True) """ self.filename = filename self.xml = {} self.axml = {} self.arsc = {} self.package = "" self.androidversion = {} self.permissions = [] self.uses_permissions = [] self.declared_permissions = {} self.valid_apk = False self._is_signed_v2 = None self._v2_blocks = {} self._files = {} self.files_crc32 = {} self.magic_file = magic_file if raw is True: self.__raw = bytearray(filename) self._sha256 = hashlib.sha256(self.__raw).hexdigest() # Set the filename to something sane self.filename = "raw_apk_sha256:{}".format(self._sha256) else: self.__raw = bytearray(read(filename)) self.zip = zipfile.ZipFile(io.BytesIO(self.__raw), mode="r") if testzip: # Test the zipfile for integrity before continuing. # This process might be slow, as the whole file is read. # Therefore it is possible to enable it as a separate feature. # # A short benchmark showed, that testing the zip takes about 10 times longer! # e.g. normal zip loading (skip_analysis=True) takes about 0.01s, where # testzip takes 0.1s! ret = self.zip.testzip() if ret is not None: # we could print the filename here, but there are zip which are so broken # That the filename is either very very long or does not make any sense. # Thus we do not do it, the user might find out by using other tools. raise BrokenAPKError( "The APK is probably broken: testzip returned an error.") if not skip_analysis: self._apk_analysis()
#!/usr/bin/env python import sys PATH_INSTALL = "./" sys.path.append(PATH_INSTALL) from androguard.core.bytecodes import dvm from androguard.core import androconf from androguard.util import read FILENAME_INPUT = "examples/android/TestsAndroguard/bin/classes.dex" FILENAME_OUTPUT = "./toto.dex" androconf.set_debug() vm = dvm.DalvikVMFormat(read(FILENAME_INPUT)) print hex(vm.header.link_off), hex(vm.header.link_size) vm.header.link_off, vm.header.link_size = 0x41414141, 0x1337 print hex(vm.header.link_off), hex(vm.header.link_size) new_dex = vm.save() with open(FILENAME_OUTPUT, "wb") as fd: fd.write(new_dex)