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..d380e093 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") == null ? false : 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/java/brut/androlib/SharedLibraryTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/SharedLibraryTest.java index 7e30486d..2006a2d3 100644 --- a/brut.apktool/apktool-lib/src/test/java/brut/androlib/SharedLibraryTest.java +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/SharedLibraryTest.java @@ -70,29 +70,42 @@ public class SharedLibraryTest { } @Test - public void isSharedResourceDecodingWorking() throws IOException, BrutException { - String framework = "library.apk"; + public void isSharedResourceDecodingAndRebuildingWorking() throws IOException, BrutException { + String library = "library.apk"; String client = "client.apk"; - + // setup apkOptions ApkOptions apkOptions = new ApkOptions(); apkOptions.frameworkFolderLocation = sTmpDir.getAbsolutePath(); apkOptions.frameworkTag = "shared"; - new Androlib(apkOptions).installFramework(new File(sTmpDir + File.separator + framework)); - + // install library/framework + new Androlib(apkOptions).installFramework(new File(sTmpDir + File.separator + library)); assertTrue(fileExists("2-shared.apk")); + // decode client.apk ApkDecoder apkDecoder = new ApkDecoder(new File(sTmpDir + File.separator + client)); apkDecoder.setOutDir(new File(sTmpDir + File.separator + client + ".out")); apkDecoder.setFrameworkDir(apkOptions.frameworkFolderLocation); apkDecoder.setFrameworkTag(apkOptions.frameworkTag); apkDecoder.decode(); - ExtFile testApk = new ExtFile(sTmpDir, client + ".out"); - new Androlib(apkOptions).build(testApk, null); + // decode library.apk + ApkDecoder libraryDecoder = new ApkDecoder(new File(sTmpDir + File.separator + library)); + libraryDecoder.setOutDir(new File(sTmpDir + File.separator + library + ".out")); + libraryDecoder.setFrameworkDir(apkOptions.frameworkFolderLocation); + libraryDecoder.setFrameworkTag(apkOptions.frameworkTag); + libraryDecoder.decode(); + // build client.apk + ExtFile clientApk = new ExtFile(sTmpDir, client + ".out"); + new Androlib(apkOptions).build(clientApk, null); assertTrue(fileExists(client + ".out" + File.separator + "dist" + File.separator + client)); + + // build library.apk (shared library) + ExtFile libraryApk = new ExtFile(sTmpDir, library + ".out"); + new Androlib(apkOptions).build(libraryApk, null); + assertTrue(fileExists(library + ".out" + File.separator + "dist" + File.separator + library)); } private boolean fileExists(String filepath) { 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..f0d049ba 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,2 @@ version: 2.0.0 -apkFileName: testjar.jar +apkFileName: testjar.jar \ No newline at end of file