mirror of
https://github.com/revanced/Apktool.git
synced 2024-12-05 02:22:55 +01:00
Android 4.2 support finally ? updated some internal libs, fixed --renamed-package
This commit is contained in:
parent
f065a5be92
commit
04b5508c3a
@ -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>();
|
||||||
|
@ -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) {
|
||||||
|
@ -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:
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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') {
|
||||||
|
Loading…
Reference in New Issue
Block a user