From dd81dbfc9cd126a3b193a5ac4ea64a298b7cc9fe Mon Sep 17 00:00:00 2001 From: Ruben Anagua Date: Thu, 7 Dec 2017 11:33:04 +0000 Subject: [PATCH] Add ability to force decoding of manifest --- .../src/main/java/brut/apktool/Main.java | 10 ++++++ .../main/java/brut/androlib/ApkDecoder.java | 34 ++++++++++++++----- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java b/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java index bf640fed..ae509349 100644 --- a/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java +++ b/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java @@ -124,6 +124,9 @@ public class Main { if (cli.hasOption("r") || cli.hasOption("no-res")) { decoder.setDecodeResources(ApkDecoder.DECODE_RESOURCES_NONE); } + if (cli.hasOption("force-manifest")) { + decoder.setForceDecodeManifest(ApkDecoder.FORCE_DECODE_MANIFEST_FULL); + } if (cli.hasOption("no-assets")) { decoder.setDecodeAssets(ApkDecoder.DECODE_ASSETS_NONE); } @@ -286,6 +289,11 @@ public class Main { .desc("Do not decode resources.") .build(); + Option forceManOption = Option.builder() + .longOpt("force-manifest") + .desc("Decode the APK's compiled manifest, even if decoding of resources is set to \"false\".") + .build(); + Option noAssetOption = Option.builder() .longOpt("no-assets") .desc("Do not decode assets.") @@ -405,6 +413,7 @@ public class Main { DecodeOptions.addOption(analysisOption); DecodeOptions.addOption(apiLevelOption); DecodeOptions.addOption(noAssetOption); + DecodeOptions.addOption(forceManOption); BuildOptions.addOption(debugBuiOption); BuildOptions.addOption(aaptOption); @@ -453,6 +462,7 @@ public class Main { allOptions.addOption(analysisOption); allOptions.addOption(debugDecOption); allOptions.addOption(noDbgOption); + allOptions.addOption(forceManOption); allOptions.addOption(noAssetOption); allOptions.addOption(keepResOption); allOptions.addOption(debugBuiOption); 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 23f9d3b3..eb03780d 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 @@ -104,6 +104,15 @@ public class ApkDecoder { switch (mDecodeResources) { case DECODE_RESOURCES_NONE: mAndrolib.decodeResourcesRaw(mApkFile, outDir); + if (mForceDecodeManifest == FORCE_DECODE_MANIFEST_FULL) { + setTargetSdkVersion(); + setAnalysisMode(mAnalysisMode, true); + + // done after raw decoding of resources because copyToDir overwrites dest files + if (hasManifest()) { + mAndrolib.decodeManifestWithResources(mApkFile, outDir, getResTable()); + } + } break; case DECODE_RESOURCES_FULL: setTargetSdkVersion(); @@ -119,14 +128,12 @@ public class ApkDecoder { // if there's no resources.asrc, decode the manifest without looking // up attribute references if (hasManifest()) { - switch (mDecodeResources) { - case DECODE_RESOURCES_NONE: - mAndrolib.decodeManifestRaw(mApkFile, outDir); - break; - case DECODE_RESOURCES_FULL: - mAndrolib.decodeManifestFull(mApkFile, outDir, - getResTable()); - break; + if (mDecodeResources == DECODE_RESOURCES_FULL + || mForceDecodeManifest == FORCE_DECODE_MANIFEST_FULL) { + mAndrolib.decodeManifestFull(mApkFile, outDir, getResTable()); + } + else { + mAndrolib.decodeManifestRaw(mApkFile, outDir); } } } @@ -190,6 +197,13 @@ public class ApkDecoder { mDecodeResources = mode; } + public void setForceDecodeManifest(short mode) throws AndrolibException { + if (mode != FORCE_DECODE_MANIFEST_NONE && mode != FORCE_DECODE_MANIFEST_FULL) { + throw new AndrolibException("Invalid force decode manifest mode"); + } + mForceDecodeManifest = mode; + } + public void setDecodeAssets(short mode) throws AndrolibException { if (mode != DECODE_ASSETS_NONE && mode != DECODE_ASSETS_FULL) { throw new AndrolibException("Invalid decode asset mode"); @@ -306,6 +320,9 @@ public class ApkDecoder { public final static short DECODE_RESOURCES_NONE = 0x0100; public final static short DECODE_RESOURCES_FULL = 0x0101; + public final static short FORCE_DECODE_MANIFEST_NONE = 0x0000; + public final static short FORCE_DECODE_MANIFEST_FULL = 0x0001; + public final static short DECODE_ASSETS_NONE = 0x0000; public final static short DECODE_ASSETS_FULL = 0x0001; @@ -417,6 +434,7 @@ public class ApkDecoder { private ResTable mResTable; private short mDecodeSources = DECODE_SOURCES_SMALI; private short mDecodeResources = DECODE_RESOURCES_FULL; + private short mForceDecodeManifest = FORCE_DECODE_MANIFEST_NONE; private short mDecodeAssets = DECODE_ASSETS_FULL; private boolean mForceDelete = false; private boolean mKeepBrokenResources = false;