Android 4.2 support finally ? updated some internal libs, fixed --renamed-package

This commit is contained in:
Connor Tumbleson 2012-12-18 19:40:42 -06:00
parent f065a5be92
commit 04b5508c3a
6 changed files with 100 additions and 25 deletions

View File

@ -24,6 +24,8 @@ import brut.androlib.err.CantFindFrameworkResException;
import brut.androlib.err.InFileNotFoundException; import brut.androlib.err.InFileNotFoundException;
import brut.androlib.err.OutDirExistsException; import brut.androlib.err.OutDirExistsException;
import brut.androlib.res.util.ExtFile; import brut.androlib.res.util.ExtFile;
import brut.common.BrutException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
@ -35,7 +37,7 @@ import java.util.logging.*;
*/ */
public class Main { public class Main {
public static void main(String[] args) public static void main(String[] args)
throws IOException, AndrolibException, InterruptedException { throws IOException, InterruptedException, BrutException {
try { try {
Verbosity verbosity = Verbosity.NORMAL; Verbosity verbosity = Verbosity.NORMAL;
int i; int i;
@ -156,8 +158,7 @@ public class Main {
} }
} }
private static void cmdBuild(String[] args) throws InvalidArgsError, private static void cmdBuild(String[] args) throws BrutException {
AndrolibException {
// hold all the fields // hold all the fields
HashMap<String, Boolean> flags = new HashMap<String, Boolean>(); HashMap<String, Boolean> flags = new HashMap<String, Boolean>();

View File

@ -33,10 +33,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger; 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.DumperOptions;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
@ -106,7 +102,7 @@ public class Androlib {
public void decodeResourcesRaw(ExtFile apkFile, File outDir) public void decodeResourcesRaw(ExtFile apkFile, File outDir)
throws AndrolibException { throws AndrolibException {
try { try {
Directory apk = apkFile.getDirectory(); //Directory apk = apkFile.getDirectory();
LOGGER.info("Copying raw resources..."); LOGGER.info("Copying raw resources...");
apkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES); apkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES);
} catch (DirectoryException ex) { } catch (DirectoryException ex) {
@ -176,12 +172,12 @@ public class Androlib {
} }
public void build(File appDir, File outFile, public void build(File appDir, File outFile,
HashMap<String, Boolean> flags, ExtFile origApk) throws AndrolibException { HashMap<String, Boolean> flags, ExtFile origApk) throws BrutException {
build(new ExtFile(appDir), outFile, flags, origApk); build(new ExtFile(appDir), outFile, flags, origApk);
} }
public void build(ExtFile appDir, File outFile, public void build(ExtFile appDir, File outFile,
HashMap<String, Boolean> flags, ExtFile origApk) throws AndrolibException { HashMap<String, Boolean> flags, ExtFile origApk) throws BrutException {
Map<String, Object> meta = readMetaFile(appDir); Map<String, Object> meta = readMetaFile(appDir);
Object t1 = meta.get("isFrameworkApk"); Object t1 = meta.get("isFrameworkApk");
flags.put("framework", t1 == null ? false : (Boolean) t1); flags.put("framework", t1 == null ? false : (Boolean) t1);
@ -280,7 +276,7 @@ public class Androlib {
public void buildResources(ExtFile appDir, HashMap<String, Boolean> flags, public void buildResources(ExtFile appDir, HashMap<String, Boolean> flags,
Map<String, Object> usesFramework) Map<String, Object> usesFramework)
throws AndrolibException { throws BrutException {
if (! buildResourcesRaw(appDir, flags) if (! buildResourcesRaw(appDir, flags)
&& ! buildResourcesFull(appDir, flags, usesFramework) && ! buildResourcesFull(appDir, flags, usesFramework)
&& ! buildManifest(appDir, flags, usesFramework)) { && ! buildManifest(appDir, flags, usesFramework)) {
@ -346,13 +342,18 @@ public class Androlib {
tmpDir.copyToDir(apkDir, tmpDir.copyToDir(apkDir,
tmpDir.containsDir("res") ? APK_RESOURCES_FILENAMES : tmpDir.containsDir("res") ? APK_RESOURCES_FILENAMES :
APK_RESOURCES_WITHOUT_RES_FILENAMES); APK_RESOURCES_WITHOUT_RES_FILENAMES);
// delete tmpDir
OS.rmdir(tmpDir.toString());
} }
return true; return true;
} catch (IOException ex) { } catch (IOException ex) {
throw new AndrolibException(ex); throw new AndrolibException(ex);
} catch (DirectoryException ex) { } catch (DirectoryException ex) {
throw new AndrolibException(ex); throw new AndrolibException(ex);
} } catch (BrutException ex) {
throw new AndrolibException(ex);
}
} }
public boolean buildManifestRaw(ExtFile appDir, HashMap<String, Boolean> flags) public boolean buildManifestRaw(ExtFile appDir, HashMap<String, Boolean> flags)
@ -370,7 +371,7 @@ public class Androlib {
public boolean buildManifest(ExtFile appDir, HashMap<String, Boolean> flags, public boolean buildManifest(ExtFile appDir, HashMap<String, Boolean> flags,
Map<String, Object> usesFramework) Map<String, Object> usesFramework)
throws AndrolibException { throws BrutException {
try { try {
if (! new File(appDir, "AndroidManifest.xml").exists()) { if (! new File(appDir, "AndroidManifest.xml").exists()) {
return false; return false;
@ -397,11 +398,14 @@ public class Androlib {
new File(appDir, "AndroidManifest.xml"), new File(appDir, "AndroidManifest.xml"),
null, null,
ninePatch, null, parseUsesFramework(usesFramework), ninePatch, null, parseUsesFramework(usesFramework),
flags flags
); );
Directory tmpDir = new ExtFile(apkFile).getDirectory(); Directory tmpDir = new ExtFile(apkFile).getDirectory();
tmpDir.copyToDir(apkDir, APK_MANIFEST_FILENAMES); tmpDir.copyToDir(apkDir, APK_MANIFEST_FILENAMES);
// delete tmp
OS.rmdir(apkDir.getAbsolutePath());
} }
return true; return true;
} catch (IOException ex) { } catch (IOException ex) {

View File

@ -101,8 +101,7 @@ public class ApkDecoder {
} }
} else { } else {
// if there's no resources.asrc, decode the manifest without looking // if there's no resources.asrc, decode the manifest without looking
// up // up attribute references
// attribute references
if (hasManifest()) { if (hasManifest()) {
switch (mDecodeResources) { switch (mDecodeResources) {
case DECODE_RESOURCES_NONE: case DECODE_RESOURCES_NONE:

View File

@ -31,7 +31,24 @@ import java.io.*;
import java.util.*; import java.util.*;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.zip.*; 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.apache.commons.io.IOUtils;
import org.xml.sax.SAXException;
import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlSerializer;
/** /**
@ -128,11 +145,54 @@ final public class AndrolibResources {
LOGGER.info("Decoding AndroidManifest.xml with only framework resources..."); LOGGER.info("Decoding AndroidManifest.xml with only framework resources...");
fileDecoder.decodeManifest(inApk, "AndroidManifest.xml", out, fileDecoder.decodeManifest(inApk, "AndroidManifest.xml", out,
"AndroidManifest.xml"); "AndroidManifest.xml");
} catch (DirectoryException ex) { } catch (DirectoryException ex) {
throw new AndrolibException(ex); throw new AndrolibException(ex);
} }
} }
public void adjust_package_manifest(ResTable resTable, String filePath)
throws AndrolibException {
// check if packages different
Map<String, String> 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) public void decode(ResTable resTable, ExtFile apkFile, File outDir)
throws AndrolibException { throws AndrolibException {
@ -152,6 +212,9 @@ final public class AndrolibResources {
fileDecoder.decodeManifest(inApk, "AndroidManifest.xml", out, fileDecoder.decodeManifest(inApk, "AndroidManifest.xml", out,
"AndroidManifest.xml"); "AndroidManifest.xml");
// fix package if needed
adjust_package_manifest(resTable, outDir.getAbsolutePath() + "/AndroidManifest.xml");
if (inApk.containsDir("res")) { if (inApk.containsDir("res")) {
in = inApk.getDir("res"); in = inApk.getDir("res");
@ -228,7 +291,6 @@ final public class AndrolibResources {
cmd.add("--max-sdk-version"); cmd.add("--max-sdk-version");
cmd.add(mMaxSdkVersion); cmd.add(mMaxSdkVersion);
} }
if (mPackageRenamed != null) { if (mPackageRenamed != null) {
cmd.add("--rename-manifest-package"); cmd.add("--rename-manifest-package");
cmd.add(mPackageRenamed); cmd.add(mPackageRenamed);

View File

@ -16,14 +16,21 @@
package brut.androlib.res.decoder; 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.AndrolibException;
import brut.androlib.res.data.ResTable; import brut.androlib.res.data.ResTable;
import brut.androlib.res.util.ExtXmlSerializer; 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 <brut.alll@gmail.com> * @author Ryszard Wiśniewski <brut.alll@gmail.com>
@ -63,6 +70,8 @@ public class XmlPullStreamDecoder implements ResStreamDecoder {
"uses-sdk".equalsIgnoreCase(pp.getName()) || "uses-sdk".equalsIgnoreCase(pp.getName()) ||
hidePackageInfo && type == XmlPullParser.END_TAG && hidePackageInfo && type == XmlPullParser.END_TAG &&
"manifest".equalsIgnoreCase(pp.getName())) { "manifest".equalsIgnoreCase(pp.getName())) {
super.event(pp);
return; return;
} }
super.event(pp); super.event(pp);

View File

@ -105,8 +105,8 @@ subprojects {
} }
compile project(':brut.j.dir'), project(':brut.j.util'), project(':brut.j.common'), project(':brut.apktool.smali:util'), 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'), 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.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", "net.lingala.zip4j:zip4j:1.3.1" "org.apache.commons:commons-lang3:3.1"
} }
} }
project(':brut.apktool:apktool-cli') { project(':brut.apktool:apktool-cli') {