def deoatApp(oatApkDir, bootClassFolder): """ De-oat app """ if OPTIONS.formatApp == False: return Log.i( TAG, "De-oat files of oat-format in %s, with BOOTCLASSFOLDER=%s" % (oatApkDir, bootClassFolder)) for (dirpath, dirnames, filenames) in os.walk(oatApkDir): dirnames = dirnames # no use, to avoid warning for filename in filenames: if filename.endswith(".odex"): # no need to de-oat if original apk does not exist apkFile = filename[0:-5] + ".apk" apkPath = os.path.dirname(dirpath) if not os.path.exists(os.path.join(apkPath, apkFile)): continue oatApk = os.path.join(dirpath, filename) deoatApk = oatApk[0:-5] + ".dex" if os.path.exists(deoatApk): Log.d(TAG, "Delete the already exists %s" % deoatApk) os.remove(deoatApk) Utils.runWithOutput( [OatZip.OAT2DEX, oatApk, bootClassFolder])
def deoatAppWithArch(appsDir, frwDir, arch, arch2): """ De-oat app """ if OPTIONS.formatApp == False: return Log.i(TAG, "De-oat files of oat-format in %s" % (appsDir)) bootClassFolderArch = os.path.join(frwDir, arch, "odex") bootClassFolderArch2 = os.path.join(frwDir, arch2, "odex") #for app in $( ls $appdir ); do for app in os.listdir(appsDir): appPath = os.path.join(appsDir, app) apkFile = os.path.join(appPath, app + ".apk") archPath = os.path.join(appPath, "oat", arch) #if [[ -d "$appdir/$app/$arch" ]]; if os.path.exists(archPath): odexFile = os.path.join(archPath, app + ".odex") #java -Xmx512m -jar $oat2dex $appdir/$app/$arch/$app.odex $framedir/$arch/odex Utils.runWithOutput( [OatZip.OAT2DEX, odexFile, bootClassFolderArch]) else: # if exists arch2 if arch2.strip(): arch2Path = os.path.join(appPath, "oat", arch2) if os.path.exists(arch2Path): odexFile2 = os.path.join(arch2Path, app + ".odex") Utils.runWithOutput( [OatZip.OAT2DEX, odexFile2, bootClassFolderArch2])
def repackageFrw(frwDir, bootClassFolder): """ Repackage the classes.dex into jar of frwDir. """ if OPTIONS.formatFrw == False : return # Keep the old directory, we will change back after some operations. oldDir = os.path.abspath(os.curdir) # Some dexFiles are parted, such as framework-classes2.dex regex = re.compile("(.*)-(classes\d?).dex") Log.i(TAG, "Repackage JARs of %s" %(frwDir)) os.chdir(frwDir) for dexFile in os.listdir(bootClassFolder): if dexFile.endswith(".dex"): jarFile = dexFile[0:-4] + ".jar" dexName = "classes.dex" if not os.path.exists(jarFile): # Match out the jar file with regex matcher = regex.match(dexFile) if matcher != None: jarFile = matcher.group(1) + ".jar" dexName = matcher.group(2) + ".dex" Log.d(TAG, "Repackage %s" %(jarFile)) # Put the dex and framework's jar in the same folder, and jar into the jarFile shutil.move(os.path.join(bootClassFolder, dexFile), os.path.join(frwDir, dexName)) Utils.runWithOutput(["jar", "uf", jarFile, dexName]) if os.path.exists(dexName): os.remove(dexName) os.chdir(oldDir)
def deoatApp(oatApkDir, bootClassFolder): """ De-oat app """ if OPTIONS.formatApp == False: return Log.i(TAG, "De-oat files of oat-format in %s, with BOOTCLASSFOLDER=%s" %(oatApkDir, bootClassFolder)) for (dirpath, dirnames, filenames) in os.walk(oatApkDir): dirnames = dirnames # no use, to avoid warning for filename in filenames: if filename.endswith(".odex"): # no need to de-oat if original apk does not exist apkFile = filename[0:-5] + ".apk" apkPath = os.path.dirname(dirpath) if not os.path.exists(os.path.join(apkPath, apkFile)): continue oatApk = os.path.join(dirpath, filename) deoatApk = oatApk[0:-5] + ".dex" if os.path.exists(deoatApk): Log.d(TAG, "Delete the already exists %s" % deoatApk) os.remove(deoatApk) Utils.runWithOutput([OatZip.OAT2DEX, oatApk, bootClassFolder])
def dealWithAdditionalApks(systemDir, frwDir, arch, arch2, allAppDirs): ''' deal with additional apks ''' if OPTIONS.formatApp == False: return # Keep the old directory, we will change back after some operations. oldDir = os.path.abspath(os.curdir) bootClassFolderArch = os.path.join(frwDir, arch, "odex") bootClassFolderArch2 = os.path.join(frwDir, arch2, "odex") for (dirpath, dirnames, filenames) in os.walk(systemDir): # Exclude scanned directories if dirpath in allAppDirs: continue dirnames = dirnames # no use, to avoid warning for filename in filenames: if filename.endswith(".apk") or filename.endswith(".jar"): apkFile = os.path.join(dirpath, filename) if not OatZip.check_validate(apkFile, arch, arch2): continue archDir = os.path.join(dirpath, "oat", arch) #app name app = filename[0:-4] if os.path.exists(archDir): if not OatZip.isDeodexed(apkFile): odexFile = os.path.join(archDir, app + ".odex") if os.path.exists(odexFile): Utils.runWithOutput([ OatZip.OAT2DEX, odexFile, bootClassFolderArch ]) OatZip.packageDexToAppWithArch(apkFile, arch) #rm -rf $appdir/$app/$arch shutil.rmtree(archDir) arch2Dir = os.path.join(dirpath, "oat", arch2) if os.path.exists(arch2Dir): if not OatZip.isDeodexed(apkFile): odexFile = os.path.join(arch2Dir, app + ".odex") if os.path.exists(odexFile): Utils.runWithOutput([ OatZip.OAT2DEX, odexFile, bootClassFolderArch2 ]) OatZip.packageDexToAppWithArch(apkFile, arch2) #rm -rf $appdir/$app/$arch shutil.rmtree(arch2Dir) if os.path.exists(os.path.join(dirpath, "oat")): shutil.rmtree(os.path.join(dirpath, "oat"))
def deoatFrw(oatJarDir): """ De-oat framework """ if not OPTIONS.formatFrw: return Log.i(TAG, "De-oat files of oat-format in %s" % oatJarDir) for item in os.listdir(oatJarDir): if item.endswith(".odex"): # COMMANDS: oat2dex boot <jar-of-oat-format> oatJar = os.path.join(oatJarDir, item) Utils.runWithOutput([OatZip.OAT2DEX, "boot", oatJar])
def deoatFrwWithArch(frwDir, arch): """ De-oat framework """ if not OPTIONS.formatFrw: return Log.i(TAG, "De-oat files of oat-format in %s" % frwDir) archDir = os.path.join(frwDir, arch) odexDir = os.path.join(archDir, "odex") for item in os.listdir(archDir): if item.endswith(".odex"): jarFile = os.path.join(frwDir, item[0:-5] + ".jar") if not OatZip.isDeodexed(jarFile): odexFile = os.path.join(archDir, item) Utils.runWithOutput([OatZip.OAT2DEX, odexFile, odexDir])
def deoatBootOAT(bootOAT): """ De-oat boot.oat """ bootClassFolder = os.path.dirname(bootOAT) bootClassFolderDex = os.path.join(bootClassFolder, "dex") bootClassFolderOdex = os.path.join(bootClassFolder, "odex") if os.path.exists(bootClassFolderDex): Log.d(TAG, "Delete the already exists %s" % bootClassFolderDex) shutil.rmtree(bootClassFolderDex) if os.path.exists(bootClassFolderOdex): Log.d(TAG, "Delete the already exists %s" % bootClassFolderOdex) shutil.rmtree(bootClassFolderOdex) Log.i(TAG, "De-oat %s" % bootOAT) Utils.runWithOutput([OatZip.OAT2DEX, "boot", bootOAT])
def repackageFrwWithArch(frwDir, dexFolder): """ Repackage the classes.dex into jar of frwDir. """ if OPTIONS.formatFrw == False: return # Keep the old directory, we will change back after some operations. oldDir = os.path.abspath(os.curdir) Log.i(TAG, "Repackage JARs of %s - %s" % (frwDir, dexFolder)) os.chdir(dexFolder) for dexFile in os.listdir(dexFolder): if dexFile.endswith(".dex") and dexFile.find("classes") == -1: appName = dexFile[0:-4] jarFile = os.path.join(frwDir, appName + ".apk") if not os.path.exists(jarFile): jarFile = jarFile[0:-4] + ".jar" if not os.path.exists(jarFile): dexName = "classes.dex" shutil.move(os.path.join(dexFolder, dexFile), os.path.join(dexFolder, dexName)) Utils.runWithOutput(["jar", "cf", jarFile, dexName]) os.remove(os.path.join(dexFolder, dexName)) continue Log.d(TAG, "Repackage %s" % (jarFile)) if not OatZip.isDeodexed(jarFile): # Put the dex and framework's jar in the same folder, and jar into the jarFile dexName = "classes.dex" shutil.move(os.path.join(dexFolder, dexFile), os.path.join(dexFolder, dexName)) Utils.runWithOutput(["jar", "uf", jarFile, dexName]) os.remove(os.path.join(dexFolder, dexName)) dexName = "classes2.dex" dexFile = appName + "-" + dexName if os.path.exists(os.path.join(dexFolder, dexFile)): shutil.move(os.path.join(dexFolder, dexFile), os.path.join(dexFolder, dexName)) Utils.runWithOutput(["jar", "uf", jarFile, dexName]) os.remove(os.path.join(dexFolder, dexName)) dexName = "classes3.dex" dexFile = appName + "-" + dexName if os.path.exists(os.path.join(dexFolder, dexFile)): shutil.move(os.path.join(dexFolder, dexFile), os.path.join(dexFolder, dexName)) Utils.runWithOutput(["jar", "uf", jarFile, dexName]) os.remove(os.path.join(dexFolder, dexName)) os.chdir(oldDir)
def repackageApp(appDir): """ Repackage the classes.dex into apk of appDir """ if OPTIONS.formatApp == False: return # Keep the old directory, we will change back after some operations. oldDir = os.path.abspath(os.curdir) Log.i(TAG, "Repackage APKs of %s" % (appDir)) for (dirpath, dirnames, filenames) in os.walk(appDir): dirnames = dirnames # no use, to avoid warning for dexFile in filenames: if dexFile.endswith(".dex"): apkFile = dexFile[0:-4] + ".apk" apkPath = os.path.dirname(dirpath) if not os.path.exists(os.path.join(apkPath, apkFile)): Log.d(TAG, "No apk matched with %s, Ignore" % dexFile) continue dexName = "classes.dex" Log.d(TAG, "Repackage %s" % (apkPath)) # Put the dex and apk in the same folder, and jar into the apk shutil.move(os.path.join(dirpath, dexFile), os.path.join(apkPath, dexName)) os.chdir(apkPath) Utils.runWithOutput(["jar", "uf", apkFile, dexName]) if os.path.exists(dexName): os.remove(dexName) shutil.rmtree(dirpath) os.chdir(oldDir)
def repackageApp(appDir): """ Repackage the classes.dex into apk of appDir """ if OPTIONS.formatApp == False: return # Keep the old directory, we will change back after some operations. oldDir = os.path.abspath(os.curdir) Log.i(TAG, "Repackage APKs of %s" %(appDir)) for (dirpath, dirnames, filenames) in os.walk(appDir): dirnames = dirnames # no use, to avoid warning for dexFile in filenames: if dexFile.endswith(".dex"): apkFile = dexFile[0:-4] + ".apk" apkPath = os.path.dirname(dirpath) if not os.path.exists(os.path.join(apkPath, apkFile)): Log.d(TAG, "No apk matched with %s, Ignore" %dexFile) continue dexName = "classes.dex" Log.d(TAG, "Repackage %s" %(apkPath)) # Put the dex and apk in the same folder, and jar into the apk shutil.move(os.path.join(dirpath, dexFile), os.path.join(apkPath, dexName)) os.chdir(apkPath) Utils.runWithOutput(["jar", "uf", apkFile, dexName]) if os.path.exists(dexName): os.remove(dexName) shutil.rmtree(dirpath) os.chdir(oldDir)
def deoatBootOAT(frwDir, arch): """ De-oat boot.oat """ bootClassFolder = os.path.join(frwDir, arch) bootOatPath = os.path.join(bootClassFolder, "boot.oat") bootClassFolderDex = os.path.join(frwDir, arch + "-dex") bootClassFolderOdex = os.path.join(frwDir, arch + "-odex") if os.path.exists(bootClassFolderDex): Log.d(TAG, "Delete the already exists %s" % bootClassFolderDex) shutil.rmtree(bootClassFolderDex) if os.path.exists(bootClassFolderOdex): Log.d(TAG, "Delete the already exists %s" % bootClassFolderOdex) shutil.rmtree(bootClassFolderOdex) Log.i(TAG, "De-oat %s" % bootClassFolder) if OPTIONS.use_baksmali: for item in os.listdir(bootClassFolder): if item.endswith(".oat"): oatPath = os.path.join(bootClassFolder, item) dexlist = Utils.runWithResult( [OatZip.BAKSMALI, "list", "dex", oatPath]) jarName = os.path.basename(dexlist[0].strip("\n")) jarOutDir = os.path.join(frwDir, arch + "-odex", jarName + ".out") dexDir = os.path.join(frwDir, arch + "-dex") if not os.path.exists(dexDir): os.makedirs(dexDir) for dex in dexlist: if dex.strip("\n").endswith(".jar"): dexName = "" smaliDir = "smali" dexSaveName = jarName[0:-4] + ".dex" else: dexName = dex.strip("\n").split(":")[1] smaliDir = "smali_" + dexName[0:-4] dexSaveName = jarName[0:-4] + "-" + dexName Log.d( TAG, "baksmali deodex -b %s %s -o %s" % (bootOatPath, os.path.join(oatPath, dexName), os.path.join(jarOutDir, smaliDir))) Utils.runWithOutput([ OatZip.BAKSMALI, "deodex", "-b", bootOatPath, os.path.join(oatPath, dexName), "-o", os.path.join(jarOutDir, smaliDir) ]) Log.d( TAG, "smali assemble %s -o %s" % (os.path.join(jarOutDir, smaliDir), os.path.join(dexDir, dexSaveName))) Utils.runWithOutput([ OatZip.SMALI, "assemble", os.path.join(jarOutDir, smaliDir), "-o", os.path.join(dexDir, dexSaveName) ]) else: Utils.runWithOutput([OatZip.OAT2DEX, "boot", bootClassFolder])
def repackageFrw(frwDir, bootClassFolder): """ Repackage the classes.dex into jar of frwDir. """ if OPTIONS.formatFrw == False: return # Keep the old directory, we will change back after some operations. oldDir = os.path.abspath(os.curdir) # Some dexFiles are parted, such as framework-classes2.dex regex = re.compile("(.*)-(classes\d?).dex") Log.i(TAG, "Repackage JARs of %s" % (frwDir)) os.chdir(frwDir) for dexFile in os.listdir(bootClassFolder): if dexFile.endswith(".dex"): jarFile = dexFile[0:-4] + ".jar" dexName = "classes.dex" if not os.path.exists(jarFile): # Match out the jar file with regex matcher = regex.match(dexFile) if matcher != None: jarFile = matcher.group(1) + ".jar" dexName = matcher.group(2) + ".dex" Log.d(TAG, "Repackage %s" % (jarFile)) # Put the dex and framework's jar in the same folder, and jar into the jarFile shutil.move(os.path.join(bootClassFolder, dexFile), os.path.join(frwDir, dexName)) Utils.runWithOutput(["jar", "uf", jarFile, dexName]) if os.path.exists(dexName): os.remove(dexName) os.chdir(oldDir)
def packageDexToAppWithArch(apkFile, arch): # Keep the old directory, we will change back after some operations. oldDir = os.path.abspath(os.curdir) apkPath = os.path.dirname(apkFile) appName = os.path.basename(apkFile) app = appName[0:-4] archPath = os.path.join(apkPath, "oat", arch) # chagnge to arch path os.chdir(archPath) Log.d(TAG, "Repackage %s" % (apkFile)) dexFile = os.path.join(archPath, app + ".dex") # mv $appdir/$app/$arch/$app.dex $appdir/$app/$arch/classes.dex if os.path.exists(dexFile): shutil.move(dexFile, os.path.join(archPath, "classes.dex")) Utils.runWithOutput(["jar", "uf", apkFile, "classes.dex"]) else: Log.d(TAG, "Repackage ERROR %s" % (apkFile)) dexFile = os.path.join(archPath, app + "-classes2.dex") # if [[ -f "$appdir/$app/$arch/$app-classes2.dex" ]]; then # mv $appdir/$app/$arch/$app-classes2.dex $appdir/$app/$arch/classes2.dex if os.path.exists(dexFile): shutil.move(dexFile, os.path.join(archPath, "classes2.dex")) Utils.runWithOutput(["jar", "uf", apkFile, "classes2.dex"]) dexFile = os.path.join(archPath, app + "-classes3.dex") # if [[ -f "$appdir/$app/$arch/$app-classes3.dex" ]]; then # mv $appdir/$app/$arch/$app-classes3.dex $appdir/$app/$arch/classes3.dex if os.path.exists(dexFile): shutil.move(dexFile, os.path.join(archPath, "classes3.dex")) Utils.runWithOutput(["jar", "uf", apkFile, "classes3.dex"]) os.chdir(oldDir)
def deoatFrwOatWithArch(frwDir, arch): """ De-oat framework oat """ if not OPTIONS.formatFrw: return Log.i(TAG, "De-oat files of oat-format in %s/oat" % frwDir) archDir = os.path.join(frwDir, arch) #odexDir = os.path.join(archDir, "odex") oatDir = os.path.join(frwDir, "oat", arch) if not os.path.exists(oatDir): return for item in os.listdir(oatDir): if item.endswith(".odex"): jarFile = os.path.join(frwDir, item[0:-5] + ".jar") if not OatZip.isDeodexed(jarFile): odexFile = os.path.join(oatDir, item) if OPTIONS.use_baksmali: bootOatPath = os.path.join(archDir, "boot.oat") jarOutDir = os.path.join(oatDir, item[0:-5] + ".jar.out") dexFile = os.path.join(oatDir, item[0:-5] + ".dex") Log.d( TAG, "baksmali deodex -b %s %s -o %s" % (bootOatPath, odexFile, jarOutDir)) Utils.runWithOutput([ OatZip.BAKSMALI, "deodex", "-b", bootOatPath, odexFile, "-o", jarOutDir ]) Log.d(TAG, "smali assemble %s -o %s" % (jarOutDir, dexFile)) Utils.runWithOutput([ OatZip.SMALI, "assemble", jarOutDir, "-o", dexFile ]) else: Utils.runWithOutput( [OatZip.OAT2DEX, odexFile, archDir])
def deoatBootOAT(bootOAT): """ De-oat boot.oat """ Log.i(TAG, "De-oat %s" % bootOAT) Utils.runWithOutput([OatZip.OAT2DEX, "boot", bootOAT])
def deoatAppWithArch(appsDir, frwDir, arch, arch2): """ De-oat app """ if OPTIONS.formatApp == False: return Log.i(TAG, "De-oat files of oat-format in %s" % (appsDir)) bootClassFolderArch = os.path.join(frwDir, arch + "-odex") bootClassFolderArch2 = os.path.join(frwDir, arch2 + "-odex") #for app in $( ls $appdir ); do for app in os.listdir(appsDir): appPath = os.path.join(appsDir, app) apkFile = os.path.join(appPath, app + ".apk") archPath = os.path.join(appPath, "oat", arch) #if [[ -d "$appdir/$app/$arch" ]]; if os.path.exists(archPath): odexFile = os.path.join(archPath, app + ".odex") if OPTIONS.use_baksmali: bootOatPath = os.path.join(frwDir, arch, "boot.oat") dexOutDir = os.path.join(archPath, app + ".out") dexFile = os.path.join(archPath, app + ".dex") Log.d( TAG, "baksmali deodex -b %s %s -o %s" % (bootOatPath, odexFile, dexOutDir)) Utils.runWithOutput([ OatZip.BAKSMALI, "deodex", "-b", bootOatPath, odexFile, "-o", dexOutDir ]) Log.d(TAG, "smali assemble %s -o %s" % (dexOutDir, dexFile)) Utils.runWithOutput( [OatZip.SMALI, "assemble", dexOutDir, "-o", dexFile]) else: #java -Xmx512m -jar $oat2dex $appdir/$app/$arch/$app.odex $framedir/$arch/odex Utils.runWithOutput( [OatZip.OAT2DEX, odexFile, bootClassFolderArch]) else: # if exists arch2 if arch2.strip(): arch2Path = os.path.join(appPath, "oat", arch2) if os.path.exists(arch2Path): odexFile2 = os.path.join(arch2Path, app + ".odex") if OPTIONS.use_baksmali: bootOatPath2 = os.path.join( frwDir, arch2, "boot.oat") dexOutDir2 = os.path.join(arch2Path, app + ".out") dexFile2 = os.path.join(arch2Path, app + ".dex") Log.d( TAG, "baksmali deodex -b %s %s -o %s" % (bootOatPath2, odexFile2, dexOutDir2)) Utils.runWithOutput([ OatZip.BAKSMALI, "deodex", "-b", bootOatPath2, odexFile2, "-o", dexOutDir2 ]) Log.d( TAG, "smali assemble %s -o %s" % (dexOutDir2, dexFile2)) Utils.runWithOutput([ OatZip.SMALI, "assemble", dexOutDir2, "-o", dexFile2 ]) else: Utils.runWithOutput([ OatZip.OAT2DEX, odexFile2, bootClassFolderArch2 ])
def dealWithAdditionalApks(systemDir, frwDir, arch, arch2, allAppDirs): ''' deal with additional apks ''' if OPTIONS.formatApp == False: return # Keep the old directory, we will change back after some operations. oldDir = os.path.abspath(os.curdir) bootClassFolderArch = os.path.join(frwDir, arch) bootClassFolderArch2 = os.path.join(frwDir, arch2) for (dirpath, dirnames, filenames) in os.walk(systemDir): # Exclude scanned directories if dirpath in allAppDirs: continue dirnames = dirnames # no use, to avoid warning for filename in filenames: if filename.endswith(".apk") or filename.endswith(".jar"): apkFile = os.path.join(dirpath, filename) if not OatZip.check_validate(apkFile, arch, arch2): continue archDir = os.path.join(dirpath, "oat", arch) #app name app = filename[0:-4] if os.path.exists(archDir): if not OatZip.isDeodexed(apkFile): odexFile = os.path.join(archDir, app + ".odex") if os.path.exists(odexFile): if OPTIONS.use_baksmali: bootOatPath = os.path.join( frwDir, arch, "boot.oat") dexOutDir = os.path.join( archDir, app + ".out") dexFile = os.path.join( archDir, app + ".dex") Log.d( TAG, "baksmali deodex -b %s %s -o %s" % (bootOatPath, odexFile, dexOutDir)) Utils.runWithOutput([ OatZip.BAKSMALI, "deodex", "-b", bootOatPath, odexFile, "-o", dexOutDir ]) Log.d( TAG, "smali assemble %s -o %s" % (dexOutDir, dexFile)) Utils.runWithOutput([ OatZip.SMALI, "assemble", dexOutDir, "-o", dexFile ]) else: Utils.runWithOutput([ OatZip.OAT2DEX, odexFile, bootClassFolderArch ]) OatZip.packageDexToAppWithArch(apkFile, arch) #rm -rf $appdir/$app/$arch shutil.rmtree(archDir) arch2Dir = os.path.join(dirpath, "oat", arch2) if os.path.exists(arch2Dir): if not OatZip.isDeodexed(apkFile): odexFile2 = os.path.join(arch2Dir, app + ".odex") if os.path.exists(odexFile2): if OPTIONS.use_baksmali: bootOatPath2 = os.path.join( frwDir, arch2, "boot.oat") dexOutDir2 = os.path.join( arch2Dir, app + ".out") dexFile2 = os.path.join( arch2Dir, app + ".dex") Log.d( TAG, "baksmali deodex -b %s %s -o %s" % (bootOatPath2, odexFile2, dexOutDir2)) Utils.runWithOutput([ OatZip.BAKSMALI, "deodex", "-b", bootOatPath2, odexFile2, "-o", dexOutDir2 ]) Log.d( TAG, "smali assemble %s -o %s" % (dexOutDir2, dexFile2)) Utils.runWithOutput([ OatZip.SMALI, "assemble", dexOutDir2, "-o", dexFile2 ]) else: Utils.runWithOutput([ OatZip.OAT2DEX, odexFile2, bootClassFolderArch2 ]) OatZip.packageDexToAppWithArch(apkFile, arch2) #rm -rf $appdir/$app/$arch shutil.rmtree(arch2Dir) if os.path.exists(os.path.join(dirpath, "oat")): shutil.rmtree(os.path.join(dirpath, "oat"))