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 8019aa8f..859f589a 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 @@ -21,8 +21,6 @@ import brut.androlib.exceptions.InFileNotFoundException; import brut.androlib.exceptions.OutDirExistsException; import brut.androlib.apk.ApkInfo; import brut.androlib.res.ResourcesDecoder; -import brut.androlib.res.data.*; -import brut.androlib.res.xml.ResXmlPatcher; import brut.androlib.src.SmaliDecoder; import brut.directory.Directory; import brut.directory.ExtFile; @@ -41,9 +39,7 @@ public class ApkDecoder { private final static Logger LOGGER = Logger.getLogger(ApkDecoder.class.getName()); private final Config mConfig; - private final ExtFile mApkFile; - protected final ResUnknownFiles mResUnknownFiles; - private ApkInfo mApkInfo; + private final ApkInfo mApkInfo; private int mMinSdkVersion = 0; private final static String SMALI_DIRNAME = "smali"; @@ -73,17 +69,17 @@ public class ApkDecoder { public ApkDecoder(Config config, ExtFile apkFile) { mConfig = config; - mApkFile = apkFile; - mResUnknownFiles = new ResUnknownFiles(); + mApkInfo = new ApkInfo(apkFile); } public ApkInfo decode(File outDir) throws AndrolibException, IOException, DirectoryException { + ExtFile apkFile = mApkInfo.getApkFile(); try { if (!mConfig.forceDelete && outDir.exists()) { throw new OutDirExistsException(); } - if (!mApkFile.isFile() || !mApkFile.canRead()) { + if (!apkFile.isFile() || !apkFile.canRead()) { throw new InFileNotFoundException(); } @@ -94,11 +90,9 @@ public class ApkDecoder { } outDir.mkdirs(); - LOGGER.info("Using Apktool " + ApktoolProperties.getVersion() + " on " + mApkFile.getName()); + LOGGER.info("Using Apktool " + ApktoolProperties.getVersion() + " on " + mApkInfo.apkFileName); - mApkInfo = new ApkInfo(mApkFile); - - ResourcesDecoder resourcesDecoder = new ResourcesDecoder(mConfig, mApkFile, mApkInfo); + ResourcesDecoder resourcesDecoder = new ResourcesDecoder(mConfig, mApkInfo); if (mApkInfo.hasResources()) { switch (mConfig.decodeResources) { @@ -136,7 +130,7 @@ public class ApkDecoder { if (mApkInfo.hasMultipleSources()) { // foreach unknown dex file in root, lets disassemble it - Set files = mApkFile.getDirectory().getFiles(true); + Set files = apkFile.getDirectory().getFiles(true); for (String file : files) { if (file.endsWith(".dex")) { if (!file.equalsIgnoreCase("classes.dex")) { @@ -174,7 +168,7 @@ public class ApkDecoder { return mApkInfo; } finally { try { - mApkFile.close(); + apkFile.close(); } catch (IOException ignored) {} } } @@ -186,7 +180,7 @@ public class ApkDecoder { private void copyManifestRaw(File outDir) throws AndrolibException { try { LOGGER.info("Copying raw manifest..."); - mApkFile.getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES); + mApkInfo.getApkFile().getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES); } catch (DirectoryException ex) { throw new AndrolibException(ex); } @@ -195,7 +189,7 @@ public class ApkDecoder { private void copyResourcesRaw(File outDir) throws AndrolibException { try { LOGGER.info("Copying raw resources..."); - mApkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES); + mApkInfo.getApkFile().getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES); } catch (DirectoryException ex) { throw new AndrolibException(ex); } @@ -204,7 +198,7 @@ public class ApkDecoder { private void copySourcesRaw(File outDir, String filename) throws AndrolibException { try { LOGGER.info("Copying raw " + filename + " file..."); - mApkFile.getDirectory().copyToDir(outDir, filename); + mApkInfo.getApkFile().getDirectory().copyToDir(outDir, filename); } catch (DirectoryException ex) { throw new AndrolibException(ex); } @@ -222,7 +216,7 @@ public class ApkDecoder { //noinspection ResultOfMethodCallIgnored smaliDir.mkdirs(); LOGGER.info("Baksmaling " + filename + "..."); - DexFile dexFile = SmaliDecoder.decode(mApkFile, smaliDir, filename, + DexFile dexFile = SmaliDecoder.decode(mApkInfo.getApkFile(), smaliDir, filename, mConfig.baksmaliDebugMode, mConfig.apiLevel); int minSdkVersion = dexFile.getOpcodes().api; if (mMinSdkVersion == 0 || mMinSdkVersion > minSdkVersion) { @@ -236,7 +230,7 @@ public class ApkDecoder { private void copyRawFiles(File outDir) throws AndrolibException { LOGGER.info("Copying assets and libs..."); try { - Directory in = mApkFile.getDirectory(); + Directory in = mApkInfo.getApkFile().getDirectory(); if (mConfig.decodeAssets == Config.DECODE_ASSETS_FULL) { if (in.containsDir("assets")) { @@ -270,7 +264,7 @@ public class ApkDecoder { LOGGER.info("Copying unknown files..."); File unknownOut = new File(outDir, UNK_DIRNAME); try { - Directory unk = mApkFile.getDirectory(); + Directory unk = mApkInfo.getApkFile().getDirectory(); // loop all items in container recursively, ignoring any that are pre-defined by aapt Set files = unk.getFiles(true); @@ -281,11 +275,9 @@ public class ApkDecoder { unk.copyToDir(unknownOut, file); // let's record the name of the file, and its compression type // so that we may re-include it the same way - mResUnknownFiles.addUnknownFileInfo(file, String.valueOf(unk.getCompressionLevel(file))); + mApkInfo.addUnknownFileInfo(file, String.valueOf(unk.getCompressionLevel(file))); } } - // update apk info - mApkInfo.unknownFiles = mResUnknownFiles.getUnknownFiles(); } catch (DirectoryException ex) { throw new AndrolibException(ex); } @@ -300,7 +292,7 @@ public class ApkDecoder { } try { - Directory in = mApkFile.getDirectory(); + Directory in = mApkInfo.getApkFile().getDirectory(); if (in.containsFile("AndroidManifest.xml")) { in.copyToDir(originalDir, "AndroidManifest.xml"); } @@ -326,7 +318,7 @@ public class ApkDecoder { private void recordUncompressedFiles(Map resFileMapping) throws AndrolibException { try { List uncompressedFilesOrExts = new ArrayList<>(); - Directory unk = mApkFile.getDirectory(); + Directory unk = mApkInfo.getApkFile().getDirectory(); Set files = unk.getFiles(true); for (String file : files) { diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java index ed966b31..884b2a42 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java @@ -39,7 +39,7 @@ public class ApkInfo implements YamlSerializable { public boolean resourcesAreCompressed; public boolean sharedLibrary; public boolean sparseResources; - public Map unknownFiles; + public Map unknownFiles = new LinkedHashMap<>(); public List doNotCompress; /** @deprecated use {@link #resourcesAreCompressed} */ @@ -120,6 +120,10 @@ public class ApkInfo implements YamlSerializable { } } + public void addUnknownFileInfo(String file, String value) { + unknownFiles.put(file, value); + } + public String checkTargetSdkVersionBounds() { int target = mapSdkShorthandToVersion(getTargetSdkVersion()); @@ -295,7 +299,9 @@ public class ApkInfo implements YamlSerializable { writer.writeBool("resourcesAreCompressed", resourcesAreCompressed); writer.writeBool("sharedLibrary", sharedLibrary); writer.writeBool("sparseResources", sparseResources); - writer.writeStringMap("unknownFiles", unknownFiles); + if (unknownFiles.size() > 0) { + writer.writeStringMap("unknownFiles", unknownFiles); + } writer.writeList("doNotCompress", doNotCompress); } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/ResourcesDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/ResourcesDecoder.java index 517c7256..a9507b6b 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/ResourcesDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/ResourcesDecoder.java @@ -27,7 +27,6 @@ import brut.androlib.res.xml.ResValuesXmlSerializable; import brut.androlib.res.xml.ResXmlPatcher; import brut.directory.Directory; import brut.directory.DirectoryException; -import brut.directory.ExtFile; import brut.directory.FileDirectory; import org.xmlpull.v1.XmlSerializer; @@ -39,7 +38,6 @@ public class ResourcesDecoder { private final static Logger LOGGER = Logger.getLogger(ResourcesDecoder.class.getName()); private final Config mConfig; - private final ExtFile mApkFile; private final ApkInfo mApkInfo; private final ResTable mResTable; private final Map mResFileMapping = new HashMap<>(); @@ -48,9 +46,8 @@ public class ResourcesDecoder { "android", "com.htc", "com.lge", "com.lge.internal", "yi", "flyme", "air.com.adobe.appentry", "FFFFFFFFFFFFFFFFFFFFFF" }; - public ResourcesDecoder(Config config, ExtFile apkFile, ApkInfo apkInfo) { + public ResourcesDecoder(Config config, ApkInfo apkInfo) { mConfig = config; - mApkFile = apkFile; mApkInfo = apkInfo; mResTable = new ResTable(mConfig, mApkInfo); } @@ -68,7 +65,7 @@ public class ResourcesDecoder { } public void loadMainPkg() throws AndrolibException { - mResTable.loadMainPkg(mApkFile); + mResTable.loadMainPkg(mApkInfo.getApkFile()); } public void decodeManifest(File outDir) throws AndrolibException { @@ -81,7 +78,7 @@ public class ResourcesDecoder { Directory inApk, out; try { - inApk = mApkFile.getDirectory(); + inApk = mApkInfo.getApkFile().getDirectory(); out = new FileDirectory(outDir); if (mApkInfo.hasResources()) { @@ -147,7 +144,7 @@ public class ResourcesDecoder { return; } - mResTable.loadMainPkg(mApkFile); + mResTable.loadMainPkg(mApkInfo.getApkFile()); ResStreamDecoderContainer decoders = new ResStreamDecoderContainer(); decoders.setDecoder("raw", new ResRawStreamDecoder()); @@ -161,7 +158,7 @@ public class ResourcesDecoder { try { out = new FileDirectory(outDir); - in = mApkFile.getDirectory(); + in = mApkInfo.getApkFile().getDirectory(); out = out.createDir("res"); } catch (DirectoryException ex) { throw new AndrolibException(ex); diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResUnknownFiles.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResUnknownFiles.java deleted file mode 100644 index f95c3d74..00000000 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResUnknownFiles.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010 Ryszard Wiśniewski - * Copyright (C) 2010 Connor Tumbleson - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package brut.androlib.res.data; - -import java.util.LinkedHashMap; -import java.util.Map; - -public class ResUnknownFiles { - - private final Map mUnknownFiles = new LinkedHashMap<>(); - - public void addUnknownFileInfo(String file, String value) { - mUnknownFiles.put(file, value); - } - - public Map getUnknownFiles() { - return mUnknownFiles; - } -} diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/NonStandardPkgIdTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/NonStandardPkgIdTest.java index 659c42b1..34ea0c6b 100644 --- a/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/NonStandardPkgIdTest.java +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/NonStandardPkgIdTest.java @@ -54,7 +54,7 @@ public class NonStandardPkgIdTest extends BaseTest { LOGGER.info("Decoding pkgid8.apk..."); ApkInfo testInfo = new ApkInfo(testApk); - ResourcesDecoder resourcesDecoder = new ResourcesDecoder(Config.getDefaultConfig(), testApk, testInfo); + ResourcesDecoder resourcesDecoder = new ResourcesDecoder(Config.getDefaultConfig(), testInfo); sTestNewDir.mkdirs(); resourcesDecoder.decodeResources(sTestNewDir); diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java index 941e6dd6..61faaac0 100644 --- a/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java @@ -55,7 +55,7 @@ public class DecodeArrayTest extends BaseTest { ExtFile apkFile = new ExtFile(sTmpDir, "issue1994.apk"); ApkInfo apkInfo = new ApkInfo(apkFile); //ApkDecoder apkDecoder = new ApkDecoder(apkFile); - ResourcesDecoder resourcesDecoder = new ResourcesDecoder(Config.getDefaultConfig(), apkFile, apkInfo); + ResourcesDecoder resourcesDecoder = new ResourcesDecoder(Config.getDefaultConfig(), apkInfo); resourcesDecoder.loadMainPkg(); ResTable resTable = resourcesDecoder.getResTable(); @@ -68,7 +68,7 @@ public class DecodeArrayTest extends BaseTest { public void decodeArray() throws BrutException { ExtFile apkFile = new ExtFile(sTmpDir, "issue1994.apk"); ApkInfo apkInfo = new ApkInfo(apkFile); - ResourcesDecoder resourcesDecoder = new ResourcesDecoder(Config.getDefaultConfig(), apkFile, apkInfo); + ResourcesDecoder resourcesDecoder = new ResourcesDecoder(Config.getDefaultConfig(), apkInfo); resourcesDecoder.loadMainPkg(); ResTable resTable = resourcesDecoder.getResTable();