From 04b5508c3a40f6f05194e1b024366833bfee3845 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Tue, 18 Dec 2012 19:40:42 -0600 Subject: [PATCH] Android 4.2 support finally ? updated some internal libs, fixed --renamed-package --- .../src/main/java/brut/apktool/Main.java | 7 +- .../src/main/java/brut/androlib/Androlib.java | 26 ++++---- .../main/java/brut/androlib/ApkDecoder.java | 3 +- .../brut/androlib/res/AndrolibResources.java | 66 ++++++++++++++++++- .../res/decoder/XmlPullStreamDecoder.java | 19 ++++-- build.gradle | 4 +- 6 files changed, 100 insertions(+), 25 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 83f43374..07c11e26 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 @@ -24,6 +24,8 @@ import brut.androlib.err.CantFindFrameworkResException; import brut.androlib.err.InFileNotFoundException; import brut.androlib.err.OutDirExistsException; import brut.androlib.res.util.ExtFile; +import brut.common.BrutException; + import java.io.File; import java.io.IOException; import java.util.Arrays; @@ -35,7 +37,7 @@ import java.util.logging.*; */ public class Main { public static void main(String[] args) - throws IOException, AndrolibException, InterruptedException { + throws IOException, InterruptedException, BrutException { try { Verbosity verbosity = Verbosity.NORMAL; int i; @@ -156,8 +158,7 @@ public class Main { } } - private static void cmdBuild(String[] args) throws InvalidArgsError, - AndrolibException { + private static void cmdBuild(String[] args) throws BrutException { // hold all the fields HashMap flags = new HashMap(); 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 2680db19..0f855f29 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 @@ -33,10 +33,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; -import net.lingala.zip4j.core.ZipFile; -import net.lingala.zip4j.exception.ZipException; -import net.lingala.zip4j.model.ZipParameters; -import net.lingala.zip4j.util.Zip4jConstants; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @@ -106,7 +102,7 @@ public class Androlib { public void decodeResourcesRaw(ExtFile apkFile, File outDir) throws AndrolibException { try { - Directory apk = apkFile.getDirectory(); + //Directory apk = apkFile.getDirectory(); LOGGER.info("Copying raw resources..."); apkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES); } catch (DirectoryException ex) { @@ -176,12 +172,12 @@ public class Androlib { } public void build(File appDir, File outFile, - HashMap flags, ExtFile origApk) throws AndrolibException { + HashMap flags, ExtFile origApk) throws BrutException { build(new ExtFile(appDir), outFile, flags, origApk); } public void build(ExtFile appDir, File outFile, - HashMap flags, ExtFile origApk) throws AndrolibException { + HashMap flags, ExtFile origApk) throws BrutException { Map meta = readMetaFile(appDir); Object t1 = meta.get("isFrameworkApk"); flags.put("framework", t1 == null ? false : (Boolean) t1); @@ -280,7 +276,7 @@ public class Androlib { public void buildResources(ExtFile appDir, HashMap flags, Map usesFramework) - throws AndrolibException { + throws BrutException { if (! buildResourcesRaw(appDir, flags) && ! buildResourcesFull(appDir, flags, usesFramework) && ! buildManifest(appDir, flags, usesFramework)) { @@ -346,13 +342,18 @@ public class Androlib { tmpDir.copyToDir(apkDir, tmpDir.containsDir("res") ? APK_RESOURCES_FILENAMES : APK_RESOURCES_WITHOUT_RES_FILENAMES); + + // delete tmpDir + OS.rmdir(tmpDir.toString()); } return true; } catch (IOException ex) { throw new AndrolibException(ex); } catch (DirectoryException ex) { throw new AndrolibException(ex); - } + } catch (BrutException ex) { + throw new AndrolibException(ex); + } } public boolean buildManifestRaw(ExtFile appDir, HashMap flags) @@ -370,7 +371,7 @@ public class Androlib { public boolean buildManifest(ExtFile appDir, HashMap flags, Map usesFramework) - throws AndrolibException { + throws BrutException { try { if (! new File(appDir, "AndroidManifest.xml").exists()) { return false; @@ -397,11 +398,14 @@ public class Androlib { new File(appDir, "AndroidManifest.xml"), null, ninePatch, null, parseUsesFramework(usesFramework), - flags + flags ); Directory tmpDir = new ExtFile(apkFile).getDirectory(); tmpDir.copyToDir(apkDir, APK_MANIFEST_FILENAMES); + + // delete tmp + OS.rmdir(apkDir.getAbsolutePath()); } return true; } catch (IOException ex) { 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 6962debf..9b6099d5 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 @@ -101,8 +101,7 @@ public class ApkDecoder { } } else { // if there's no resources.asrc, decode the manifest without looking - // up - // attribute references + // up attribute references if (hasManifest()) { switch (mDecodeResources) { case DECODE_RESOURCES_NONE: 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 238f2724..67587ea0 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 @@ -31,7 +31,24 @@ import java.io.*; import java.util.*; import java.util.logging.Logger; import java.util.zip.*; + +import java.io.File; +import java.io.IOException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + import org.apache.commons.io.IOUtils; +import org.xml.sax.SAXException; import org.xmlpull.v1.XmlSerializer; /** @@ -128,11 +145,54 @@ final public class AndrolibResources { LOGGER.info("Decoding AndroidManifest.xml with only framework resources..."); fileDecoder.decodeManifest(inApk, "AndroidManifest.xml", out, "AndroidManifest.xml"); - + } catch (DirectoryException ex) { throw new AndrolibException(ex); } } + + public void adjust_package_manifest(ResTable resTable, String filePath) + throws AndrolibException { + + // check if packages different + Map packageInfo = resTable.getPackageInfo(); + if (!(packageInfo.get("cur_package").equalsIgnoreCase(packageInfo.get("orig_package")))) { + try { + + LOGGER.info("Renamed manifest package found! Fixing..."); + DocumentBuilderFactory docFactory = DocumentBuilderFactory + .newInstance(); + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + Document doc = docBuilder.parse(filePath.toString()); + + // Get the manifest line + Node manifest = doc.getFirstChild(); + + // update package attribute + NamedNodeMap attr = manifest.getAttributes(); + Node nodeAttr = attr.getNamedItem("package"); + mPackageRenamed = nodeAttr.getNodeValue(); + nodeAttr.setNodeValue(packageInfo.get("cur_package")); + + // re-save manifest. + // fancy an auto-sort :p + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + DOMSource source = new DOMSource(doc); + StreamResult result = new StreamResult(new File(filePath)); + transformer.transform(source, result); + + } catch (ParserConfigurationException ex) { + throw new AndrolibException(ex); + } catch (TransformerException ex) { + throw new AndrolibException(ex); + } catch (IOException ex) { + throw new AndrolibException(ex); + } catch (SAXException ex) { + throw new AndrolibException(ex); + } + } + } public void decode(ResTable resTable, ExtFile apkFile, File outDir) throws AndrolibException { @@ -152,6 +212,9 @@ final public class AndrolibResources { fileDecoder.decodeManifest(inApk, "AndroidManifest.xml", out, "AndroidManifest.xml"); + + // fix package if needed + adjust_package_manifest(resTable, outDir.getAbsolutePath() + "/AndroidManifest.xml"); if (inApk.containsDir("res")) { in = inApk.getDir("res"); @@ -228,7 +291,6 @@ final public class AndrolibResources { cmd.add("--max-sdk-version"); cmd.add(mMaxSdkVersion); } - if (mPackageRenamed != null) { cmd.add("--rename-manifest-package"); cmd.add(mPackageRenamed); diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java index 474c6656..912721f1 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/XmlPullStreamDecoder.java @@ -16,14 +16,21 @@ package brut.androlib.res.decoder; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.logging.Logger; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.wrapper.XmlPullParserWrapper; +import org.xmlpull.v1.wrapper.XmlPullWrapperFactory; +import org.xmlpull.v1.wrapper.XmlSerializerWrapper; +import org.xmlpull.v1.wrapper.classic.StaticXmlSerializerWrapper; + import brut.androlib.AndrolibException; import brut.androlib.res.data.ResTable; import brut.androlib.res.util.ExtXmlSerializer; -import java.io.*; -import java.util.logging.Logger; -import org.xmlpull.v1.*; -import org.xmlpull.v1.wrapper.*; -import org.xmlpull.v1.wrapper.classic.StaticXmlSerializerWrapper; /** * @author Ryszard Wiśniewski @@ -63,6 +70,8 @@ public class XmlPullStreamDecoder implements ResStreamDecoder { "uses-sdk".equalsIgnoreCase(pp.getName()) || hidePackageInfo && type == XmlPullParser.END_TAG && "manifest".equalsIgnoreCase(pp.getName())) { + + super.event(pp); return; } super.event(pp); diff --git a/build.gradle b/build.gradle index 4db77849..8eecb384 100644 --- a/build.gradle +++ b/build.gradle @@ -105,8 +105,8 @@ subprojects { } compile project(':brut.j.dir'), project(':brut.j.util'), project(':brut.j.common'), project(':brut.apktool.smali:util'), project(':brut.apktool.smali:dexlib'), project(':brut.apktool.smali:baksmali'),project(':brut.apktool.smali:smali'), - "org.yaml:snakeyaml:1.7", "xpp3:xpp3:1.1.4c","xmlunit:xmlunit:1.3", "com.google.guava:guava:12.0", - "org.apache.commons:commons-lang3:3.1", "net.lingala.zip4j:zip4j:1.3.1" + "org.yaml:snakeyaml:1.11", "xpp3:xpp3:1.1.4c","xmlunit:xmlunit:1.3", "com.google.guava:guava:12.0", + "org.apache.commons:commons-lang3:3.1" } } project(':brut.apktool:apktool-cli') {