From 0e5c7898deb5adbfea18e38ef2e03f1c302697e4 Mon Sep 17 00:00:00 2001 From: Slava Volkov Date: Wed, 28 Jun 2023 18:21:18 +0300 Subject: [PATCH] refactor Apkecoder - streamline decode procedure --- .../main/java/brut/androlib/ApkDecoder.java | 143 ++++++++---------- 1 file changed, 60 insertions(+), 83 deletions(-) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java index 29fb181d93..6e6faf73a3 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java @@ -53,7 +53,7 @@ public class ApkDecoder { private final static String SMALI_DIRNAME = "smali"; private final static String UNK_DIRNAME = "unknown"; private final static String[] APK_RESOURCES_FILENAMES = new String[] { - "resources.arsc", "AndroidManifest.xml", "res", "r", "R" }; + "resources.arsc", "res", "r", "R" }; private final static String[] APK_MANIFEST_FILENAMES = new String[] { "AndroidManifest.xml" }; private final static String[] APK_STANDARD_ALL_FILENAMES = new String[] { @@ -101,46 +101,17 @@ public void decode(File outDir) throws AndrolibException, IOException, Directory LOGGER.info("Using Apktool " + ApktoolProperties.getVersion() + " on " + mApkFile.getName()); - if (hasResources()) { - switch (config.decodeResources) { - case Config.DECODE_RESOURCES_NONE: - copyResourcesRaw(mApkFile, outDir); - if (config.forceDecodeManifest == Config.FORCE_DECODE_MANIFEST_FULL) { - // done after raw decoding of resources because copyToDir overwrites dest files - if (hasManifest()) { - decodeManifestWithResources(mApkFile, outDir, getResTable()); - } - } - break; - case Config.DECODE_RESOURCES_FULL: - if (hasManifest()) { - decodeManifestWithResources(mApkFile, outDir, getResTable()); - } - decodeResourcesFull(mApkFile, outDir, getResTable()); - break; - } - } else { - // if there's no resources.arsc, decode the manifest without looking - // up attribute references - if (hasManifest()) { - if (config.decodeResources == Config.DECODE_RESOURCES_FULL - || config.forceDecodeManifest == Config.FORCE_DECODE_MANIFEST_FULL) { - decodeManifestFull(mApkFile, outDir, getResTable()); - } - else { - copyManifestRaw(mApkFile, outDir); - } - } - } + decodeManifest(outDir); + decodeResources(outDir); if (hasSources()) { switch (config.decodeSources) { case Config.DECODE_SOURCES_NONE: - copySourcesRaw(mApkFile, outDir, "classes.dex"); + copySourcesRaw(outDir, "classes.dex"); break; case Config.DECODE_SOURCES_SMALI: case Config.DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES: - decodeSourcesSmali(mApkFile, outDir, "classes.dex"); + decodeSourcesSmali(outDir, "classes.dex"); break; } } @@ -153,16 +124,16 @@ public void decode(File outDir) throws AndrolibException, IOException, Directory if (! file.equalsIgnoreCase("classes.dex")) { switch(config.decodeSources) { case Config.DECODE_SOURCES_NONE: - copySourcesRaw(mApkFile, outDir, file); + copySourcesRaw(outDir, file); break; case Config.DECODE_SOURCES_SMALI: - decodeSourcesSmali(mApkFile, outDir, file); + decodeSourcesSmali(outDir, file); break; case Config.DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES: if (file.startsWith("classes") && file.endsWith(".dex")) { - decodeSourcesSmali(mApkFile, outDir, file); + decodeSourcesSmali(outDir, file); } else { - copySourcesRaw(mApkFile, outDir, file); + copySourcesRaw(outDir, file); } break; } @@ -171,11 +142,11 @@ public void decode(File outDir) throws AndrolibException, IOException, Directory } } - copyRawFiles(mApkFile, outDir); - copyUnknownFiles(mApkFile, outDir); + copyRawFiles(outDir); + copyUnknownFiles(outDir); mUncompressedFiles = new ArrayList<>(); - recordUncompressedFiles(mApkFile, mUncompressedFiles); - copyOriginalFiles(mApkFile, outDir); + recordUncompressedFiles(mUncompressedFiles); + copyOriginalFiles(outDir); writeMetaFile(outDir); } finally { try { @@ -276,17 +247,17 @@ private Map getMinSdkInfo() { return sdkInfo; } - private void copySourcesRaw(ExtFile apkFile, File outDir, String filename) + private void copySourcesRaw(File outDir, String filename) throws AndrolibException { try { LOGGER.info("Copying raw " + filename + " file..."); - apkFile.getDirectory().copyToDir(outDir, filename); + mApkFile.getDirectory().copyToDir(outDir, filename); } catch (DirectoryException ex) { throw new AndrolibException(ex); } } - private void decodeSourcesSmali(File apkFile, File outDir, String filename) + private void decodeSourcesSmali(File outDir, String filename) throws AndrolibException { try { File smaliDir; @@ -299,7 +270,7 @@ private void decodeSourcesSmali(File apkFile, File outDir, String filename) //noinspection ResultOfMethodCallIgnored smaliDir.mkdirs(); LOGGER.info("Baksmaling " + filename + "..."); - DexFile dexFile = SmaliDecoder.decode(apkFile, smaliDir, filename, + DexFile dexFile = SmaliDecoder.decode(mApkFile, smaliDir, filename, config.baksmaliDebugMode, config.apiLevel); int minSdkVersion = dexFile.getOpcodes().api; if (mMinSdkVersion == 0 || mMinSdkVersion > minSdkVersion) { @@ -310,46 +281,52 @@ private void decodeSourcesSmali(File apkFile, File outDir, String filename) } } - private void copyManifestRaw(ExtFile apkFile, File outDir) - throws AndrolibException { - try { - LOGGER.info("Copying raw manifest..."); - apkFile.getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES); - } catch (DirectoryException ex) { - throw new AndrolibException(ex); + private void decodeManifest(File outDir) throws AndrolibException { + if (hasManifest()) { + if (config.decodeResources == Config.DECODE_RESOURCES_FULL || + config.forceDecodeManifest == Config.FORCE_DECODE_MANIFEST_FULL) { + if (hasResources()) { + mAndRes.decodeManifestWithResources(getResTable(), mApkFile, outDir); + } else { + // if there's no resources.arsc, decode the manifest without looking + // up attribute references + mAndRes.decodeManifest(getResTable(), mApkFile, outDir); + } + } + else { + try { + LOGGER.info("Copying raw manifest..."); + mApkFile.getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES); + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } + } } } - private void decodeManifestFull(ExtFile apkFile, File outDir, ResTable resTable) - throws AndrolibException { - mAndRes.decodeManifest(resTable, apkFile, outDir); - } - - private void copyResourcesRaw(ExtFile apkFile, File outDir) - throws AndrolibException { - try { - LOGGER.info("Copying raw resources..."); - apkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES); - } catch (DirectoryException ex) { - throw new AndrolibException(ex); + private void decodeResources(File outDir) throws AndrolibException { + if (hasResources()) { + switch (config.decodeResources) { + case Config.DECODE_RESOURCES_NONE: + try { + LOGGER.info("Copying raw resources..."); + mApkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES); + } catch (DirectoryException ex) { + throw new AndrolibException(ex); + } + break; + case Config.DECODE_RESOURCES_FULL: + mAndRes.decode(getResTable(), mApkFile, outDir); + break; + } } } - private void decodeResourcesFull(ExtFile apkFile, File outDir, ResTable resTable) - throws AndrolibException { - mAndRes.decode(resTable, apkFile, outDir); - } - - private void decodeManifestWithResources(ExtFile apkFile, File outDir, ResTable resTable) - throws AndrolibException { - mAndRes.decodeManifestWithResources(resTable, apkFile, outDir); - } - - private void copyRawFiles(ExtFile apkFile, File outDir) + private void copyRawFiles(File outDir) throws AndrolibException { LOGGER.info("Copying assets and libs..."); try { - Directory in = apkFile.getDirectory(); + Directory in = mApkFile.getDirectory(); if (config.decodeAssets == Config.DECODE_ASSETS_FULL) { if (in.containsDir("assets")) { @@ -379,12 +356,12 @@ private boolean isAPKFileNames(String file) { return false; } - private void copyUnknownFiles(ExtFile apkFile, File outDir) + private void copyUnknownFiles(File outDir) throws AndrolibException { LOGGER.info("Copying unknown files..."); File unknownOut = new File(outDir, UNK_DIRNAME); try { - Directory unk = apkFile.getDirectory(); + Directory unk = mApkFile.getDirectory(); // loop all items in container recursively, ignoring any that are pre-defined by aapt Set files = unk.getFiles(true); @@ -403,7 +380,7 @@ private void copyUnknownFiles(ExtFile apkFile, File outDir) } } - private void copyOriginalFiles(ExtFile apkFile, File outDir) + private void copyOriginalFiles(File outDir) throws AndrolibException { LOGGER.info("Copying original files..."); File originalDir = new File(outDir, "original"); @@ -413,7 +390,7 @@ private void copyOriginalFiles(ExtFile apkFile, File outDir) } try { - Directory in = apkFile.getDirectory(); + Directory in = mApkFile.getDirectory(); if (in.containsFile("AndroidManifest.xml")) { in.copyToDir(originalDir, "AndroidManifest.xml"); } @@ -436,9 +413,9 @@ private void copyOriginalFiles(ExtFile apkFile, File outDir) } } - private void recordUncompressedFiles(ExtFile apkFile, Collection uncompressedFilesOrExts) throws AndrolibException { + private void recordUncompressedFiles(Collection uncompressedFilesOrExts) throws AndrolibException { try { - Directory unk = apkFile.getDirectory(); + Directory unk = mApkFile.getDirectory(); Set files = unk.getFiles(true); for (String file : files) {