From 0a74de4ab025c196e5747c9e4e38cfc24710401c Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Sun, 8 Mar 2015 14:31:21 -0500 Subject: [PATCH] Shared Library Rebuilding Support - handles references with shared resources - adds support for --shared-lib - update unit-tests --- .../src/main/java/brut/androlib/Androlib.java | 1 + .../src/main/java/brut/androlib/ApkDecoder.java | 5 +++++ .../brut/androlib/res/AndrolibResources.java | 11 ++++++++++- .../main/java/brut/androlib/res/data/ResID.java | 2 +- .../java/brut/androlib/res/data/ResTable.java | 16 ++++++++++++++++ .../brut/androlib/res/decoder/ARSCDecoder.java | 1 + .../resources/brut/apktool/testapp/apktool.yml | 1 + .../resources/brut/apktool/testjar/apktool.yml | 1 + 8 files changed, 36 insertions(+), 2 deletions(-) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java index 8899d904..9b77bed1 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java @@ -270,6 +270,7 @@ public class Androlib { mAndRes.setPackageId((Map) meta.get("packageInfo")); mAndRes.setPackageInfo((Map) meta.get("packageInfo")); mAndRes.setVersionInfo((Map) meta.get("versionInfo")); + mAndRes.setSharedLibrary((boolean) meta.get("sharedLibrary")); if (outFile == null) { String outFileName = (String) meta.get("apkFileName"); 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 474aafec..4efabc9e 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 @@ -320,6 +320,7 @@ public class ApkDecoder { putPackageInfo(meta); putVersionInfo(meta); putCompressionInfo(meta); + putSharedLibraryInfo(meta); } putUnknownInfo(meta); @@ -393,6 +394,10 @@ public class ApkDecoder { meta.put("compressionType", getCompressionType()); } + private void putSharedLibraryInfo(Map meta) throws AndrolibException { + meta.put("sharedLibrary", mResTable.getSharedLibrary()); + } + private boolean getCompressionType() { return mCompressResources; } 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 1f68d172..a034d5fb 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 @@ -379,6 +379,10 @@ final public class AndrolibResources { } } + public void setSharedLibrary(boolean flag) { + mSharedLibrary = flag; + } + public void aaptPackage(File apkFile, File manifest, File resDir, File rawDir, File assetDir, File[] include) throws AndrolibException { @@ -428,10 +432,13 @@ final public class AndrolibResources { // force package id so that some frameworks build with correct id // disable if user adds own aapt (can't know if they have this feature) - if (mPackageId != null && ! customAapt) { + if (mPackageId != null && ! customAapt && ! mSharedLibrary) { cmd.add("--forced-package-id"); cmd.add(mPackageId); } + if (mSharedLibrary) { + cmd.add("--shared-lib"); + } if (mMinSdkVersion != null) { cmd.add("--min-sdk-version"); cmd.add(mMinSdkVersion); @@ -847,6 +854,8 @@ final public class AndrolibResources { private String mPackageOriginal = null; private String mPackageId = null; + private boolean mSharedLibrary = false; + private File mAaptBinary = null; private final static String[] IGNORED_PACKAGES = new String[] { diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java index 21372fb0..593d28b9 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResID.java @@ -35,7 +35,7 @@ public class ResID { } public ResID(int package_, int type, int entry, int id) { - this.package_ = package_; + this.package_ = (package_ == 0) ? 2 : package_; this.type = type; this.entry = entry; this.id = id; diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java index 411a2672..15bdb0ca 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResTable.java @@ -37,6 +37,7 @@ public class ResTable { private String mPackageOriginal; private int mPackageId; private boolean mAnalysisMode = false; + private boolean mSharedLibrary = false; private Map mSdkInfo = new LinkedHashMap(); private Map mVersionInfo = new LinkedHashMap(); @@ -50,6 +51,13 @@ public class ResTable { } public ResResSpec getResSpec(int resID) throws AndrolibException { + // The pkgId is 0x00. That means a shared library is using its + // own resource, so lie to the caller replacing with its own + // packageId + if (resID >> 24 == 0) { + int pkgId = (mPackageId == 0 ? 2 : mPackageId); + resID = (0xFF000000 & (pkgId << 24)) | resID; + } return getResSpec(new ResID(resID)); } @@ -158,6 +166,10 @@ public class ResTable { mPackageId = id; } + public void setSharedLibrary(boolean flag) { + mSharedLibrary = flag; + } + public void clearSdkInfo() { mSdkInfo.clear(); } @@ -193,4 +205,8 @@ public class ResTable { public int getPackageId() { return mPackageId; } + + public boolean getSharedLibrary() { + return mSharedLibrary; + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java index 57caf4ad..d1af5654 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java @@ -90,6 +90,7 @@ public class ARSCDecoder { // for Apktool's use we need a non-zero packageId. // AOSP indicates 0x02 is next, as 0x01 is system and 0x7F is private. id = 2; + mResTable.setSharedLibrary(true); } String name = mIn.readNullEndedString(128, true); diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/apktool.yml b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/apktool.yml index 51536bc9..967ade59 100644 --- a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/apktool.yml +++ b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/apktool.yml @@ -10,6 +10,7 @@ versionInfo: versionCode: '1' versionName: '1.0' compressionType: false +sharedLibrary: false unknownFiles: hidden.file: '8' unk_folder/unknown_file: '8' diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testjar/apktool.yml b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testjar/apktool.yml index 92bc2cf6..f2ad0b25 100644 --- a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testjar/apktool.yml +++ b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testjar/apktool.yml @@ -1,2 +1,3 @@ version: 2.0.0 apkFileName: testjar.jar +sharedLibrary: false