From ce3c37c6abbcaa960ddced48c55c6cd437f56d3d Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Fri, 3 Oct 2014 11:31:43 -0500 Subject: [PATCH] Handle ARSC files with multiple ResPackages - superseeds - 68c1809a481f96b4092355a04ffcc737a07dcc37 --- CHANGES | 1 + .../brut/androlib/res/AndrolibResources.java | 32 ++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 8c1d295f..7995404d 100644 --- a/CHANGES +++ b/CHANGES @@ -43,6 +43,7 @@ v2.0.0 (TBA) -Fixed (issue #512) - Fixed AndroidManifest missing attributes. -Fixed (issue #677) - Fixed ignoring formatted attribute in . -Fixed (issue #675) - Fixed multiple overlapping catches. +-Fixed (issue #684) - Fixed issue with multiple ResPackages in ARSC file. -Fixed issue with APKs with multiple dex files. -Fixed issue with using Apktool without smali/baksmali for ApktoolProperties (Thanks teprrr) -Fixed issue with non-URI standard characters in apk name (Thanks rover12421) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java index e4ef395f..cadabe5d 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java @@ -74,7 +74,6 @@ final public class AndrolibResources { ResPackage[] pkgs = getResPackagesFromApk(apkFile, resTable, sKeepBroken); ResPackage pkg = null; - // @todo handle multiple packages using findPackageWithMostResSpecs() switch (pkgs.length) { case 1: pkg = pkgs[0]; @@ -83,21 +82,42 @@ final public class AndrolibResources { if (pkgs[0].getName().equals("android")) { LOGGER.warning("Skipping \"android\" package group"); pkg = pkgs[1]; + break; } else if (pkgs[0].getName().equals("com.htc")) { LOGGER.warning("Skipping \"htc\" package group"); pkg = pkgs[1]; + break; } + + default: + pkg = selectPkgWithMostResSpecs(pkgs); break; } if (pkg == null) { - throw new AndrolibException("Arsc files with zero or multiple packages"); + throw new AndrolibException("arsc files with zero packages or no arsc file found."); } resTable.addPackage(pkg, true); return pkg; } + public ResPackage selectPkgWithMostResSpecs(ResPackage[] pkgs) + throws AndrolibException { + int id = 0; + int value = 0; + + for (ResPackage resPackage : pkgs) { + if (resPackage.getResSpecCount() > value && ! resPackage.getName().equalsIgnoreCase("android")) { + value = resPackage.getResSpecCount(); + id = resPackage.getId(); + } + } + + // if id is still 0, we only have one pkgId which is "android" -> 1 + return (id == 0) ? pkgs[0] : pkgs[1]; + } + public ResPackage loadFrameworkPkg(ResTable resTable, int id, String frameTag) throws AndrolibException { File apk = getFrameworkApk(id, frameTag); @@ -105,11 +125,15 @@ final public class AndrolibResources { LOGGER.info("Loading resource table from file: " + apk); ResPackage[] pkgs = getResPackagesFromApk(new ExtFile(apk), resTable, true); - if (pkgs.length != 1) { + ResPackage pkg; + if (pkgs.length > 1) { + pkg = selectPkgWithMostResSpecs(pkgs); + } else if (pkgs.length == 0) { throw new AndrolibException("Arsc files with zero or multiple packages"); + } else { + pkg = pkgs[0]; } - ResPackage pkg = pkgs[0]; if (pkg.getId() != id) { throw new AndrolibException("Expected pkg of id: " + String.valueOf(id) + ", got: " + pkg.getId()); }