mirror of
https://github.com/revanced/Apktool.git
synced 2024-08-28 18:16:41 +02:00
properly store package information (manifest AND resources.arsc info) in apktool.yml for renamed packages
This commit is contained in:
parent
4410e466f5
commit
f065a5be92
1
.gitignore
vendored
1
.gitignore
vendored
@ -26,3 +26,4 @@ build*
|
||||
*.settings
|
||||
*.setting
|
||||
bin/
|
||||
*.iml
|
||||
|
@ -96,12 +96,12 @@ public class ApkDecoder {
|
||||
mAndrolib.decodeResourcesRaw(mApkFile, outDir);
|
||||
break;
|
||||
case DECODE_RESOURCES_FULL:
|
||||
mAndrolib.decodeResourcesFull(mApkFile, outDir,
|
||||
getResTable());
|
||||
mAndrolib.decodeResourcesFull(mApkFile, outDir, getResTable());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// if there's no resources.asrc, decode the manifest without looking up
|
||||
// if there's no resources.asrc, decode the manifest without looking
|
||||
// up
|
||||
// attribute references
|
||||
if (hasManifest()) {
|
||||
switch (mDecodeResources) {
|
||||
@ -209,7 +209,6 @@ public class ApkDecoder {
|
||||
public final static short DECODE_RESOURCES_NONE = 0x0100;
|
||||
public final static short DECODE_RESOURCES_FULL = 0x0101;
|
||||
|
||||
|
||||
private File getOutDir() throws AndrolibException {
|
||||
if (mOutDir == null) {
|
||||
throw new AndrolibException("Out dir not set");
|
||||
@ -222,7 +221,8 @@ public class ApkDecoder {
|
||||
meta.put("version", Androlib.getVersion());
|
||||
meta.put("apkFileName", mApkFile.getName());
|
||||
|
||||
if (mDecodeResources != DECODE_RESOURCES_NONE && (hasManifest() || hasResources())) {
|
||||
if (mDecodeResources != DECODE_RESOURCES_NONE
|
||||
&& (hasManifest() || hasResources())) {
|
||||
meta.put("isFrameworkApk",
|
||||
Boolean.valueOf(mAndrolib.isFrameworkApk(getResTable())));
|
||||
putUsesFramework(meta);
|
||||
@ -257,8 +257,7 @@ public class ApkDecoder {
|
||||
meta.put("usesFramework", uses);
|
||||
}
|
||||
|
||||
private void putSdkInfo(Map<String, Object> meta)
|
||||
throws AndrolibException {
|
||||
private void putSdkInfo(Map<String, Object> meta) throws AndrolibException {
|
||||
Map<String, String> info = getResTable().getSdkInfo();
|
||||
if (info.size() > 0) {
|
||||
meta.put("sdkInfo", info);
|
||||
|
@ -42,7 +42,8 @@ final public class AndrolibResources {
|
||||
return getResTable(apkFile, true);
|
||||
}
|
||||
|
||||
public ResTable getResTable(ExtFile apkFile, boolean loadMainPkg) throws AndrolibException {
|
||||
public ResTable getResTable(ExtFile apkFile, boolean loadMainPkg)
|
||||
throws AndrolibException {
|
||||
ResTable resTable = new ResTable(this);
|
||||
if (loadMainPkg) {
|
||||
loadMainPkg(resTable, apkFile);
|
||||
@ -53,8 +54,8 @@ final public class AndrolibResources {
|
||||
public ResPackage loadMainPkg(ResTable resTable, ExtFile apkFile)
|
||||
throws AndrolibException {
|
||||
LOGGER.info("Loading resource table...");
|
||||
ResPackage[] pkgs = getResPackagesFromApk(
|
||||
apkFile, resTable, sKeepBroken);
|
||||
ResPackage[] pkgs = getResPackagesFromApk(apkFile, resTable,
|
||||
sKeepBroken);
|
||||
ResPackage pkg = null;
|
||||
|
||||
switch (pkgs.length) {
|
||||
@ -87,8 +88,8 @@ final public class AndrolibResources {
|
||||
File apk = getFrameworkApk(id, frameTag);
|
||||
|
||||
LOGGER.info("Loading resource table from file: " + apk);
|
||||
ResPackage[] pkgs = getResPackagesFromApk(
|
||||
new ExtFile(apk), resTable, true);
|
||||
ResPackage[] pkgs = getResPackagesFromApk(new ExtFile(apk), resTable,
|
||||
true);
|
||||
|
||||
if (pkgs.length != 1) {
|
||||
throw new AndrolibException(
|
||||
@ -97,8 +98,8 @@ final public class AndrolibResources {
|
||||
|
||||
ResPackage pkg = pkgs[0];
|
||||
if (pkg.getId() != id) {
|
||||
throw new AndrolibException("Expected pkg of id: " +
|
||||
String.valueOf(id) + ", got: " + pkg.getId());
|
||||
throw new AndrolibException("Expected pkg of id: "
|
||||
+ String.valueOf(id) + ", got: " + pkg.getId());
|
||||
}
|
||||
|
||||
resTable.addPackage(pkg, false);
|
||||
@ -125,8 +126,8 @@ final public class AndrolibResources {
|
||||
out = new FileDirectory(outDir);
|
||||
|
||||
LOGGER.info("Decoding AndroidManifest.xml with only framework resources...");
|
||||
fileDecoder.decodeManifest(
|
||||
inApk, "AndroidManifest.xml", out, "AndroidManifest.xml");
|
||||
fileDecoder.decodeManifest(inApk, "AndroidManifest.xml", out,
|
||||
"AndroidManifest.xml");
|
||||
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException(ex);
|
||||
@ -139,8 +140,8 @@ final public class AndrolibResources {
|
||||
ResFileDecoder fileDecoder = duo.m1;
|
||||
ResAttrDecoder attrDecoder = duo.m2.getAttrDecoder();
|
||||
|
||||
attrDecoder.setCurrentPackage(
|
||||
resTable.listMainPackages().iterator().next());
|
||||
attrDecoder.setCurrentPackage(resTable.listMainPackages().iterator()
|
||||
.next());
|
||||
|
||||
Directory inApk, in = null, out;
|
||||
try {
|
||||
@ -149,8 +150,8 @@ final public class AndrolibResources {
|
||||
|
||||
LOGGER.info("Decoding AndroidManifest.xml with resources...");
|
||||
|
||||
fileDecoder.decodeManifest(
|
||||
inApk, "AndroidManifest.xml", out, "AndroidManifest.xml");
|
||||
fileDecoder.decodeManifest(inApk, "AndroidManifest.xml", out,
|
||||
"AndroidManifest.xml");
|
||||
|
||||
if (inApk.containsDir("res")) {
|
||||
in = inApk.getDir("res");
|
||||
@ -198,8 +199,8 @@ final public class AndrolibResources {
|
||||
}
|
||||
|
||||
public void aaptPackage(File apkFile, File manifest, File resDir,
|
||||
File rawDir, File assetDir, File[] include, HashMap<String, Boolean> flags)
|
||||
throws AndrolibException {
|
||||
File rawDir, File assetDir, File[] include,
|
||||
HashMap<String, Boolean> flags) throws AndrolibException {
|
||||
|
||||
List<String> cmd = new ArrayList<String>();
|
||||
|
||||
@ -279,8 +280,8 @@ final public class AndrolibResources {
|
||||
|
||||
Iterator<String> it;
|
||||
try {
|
||||
it = IOUtils.lineIterator(
|
||||
new FileReader(new File(appDir, "res/values/public.xml")));
|
||||
it = IOUtils.lineIterator(new FileReader(new File(appDir,
|
||||
"res/values/public.xml")));
|
||||
} catch (FileNotFoundException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not detect whether app is framework one", ex);
|
||||
@ -295,42 +296,41 @@ final public class AndrolibResources {
|
||||
new ResSmaliUpdater().tagResIDs(resTable, smaliDir);
|
||||
}
|
||||
|
||||
public void updateSmaliResIDs(ResTable resTable, File smaliDir) throws AndrolibException {
|
||||
public void updateSmaliResIDs(ResTable resTable, File smaliDir)
|
||||
throws AndrolibException {
|
||||
new ResSmaliUpdater().updateResIDs(resTable, smaliDir);
|
||||
}
|
||||
|
||||
public Duo<ResFileDecoder, AXmlResourceParser> getResFileDecoder() {
|
||||
ResStreamDecoderContainer decoders =
|
||||
new ResStreamDecoderContainer();
|
||||
ResStreamDecoderContainer decoders = new ResStreamDecoderContainer();
|
||||
decoders.setDecoder("raw", new ResRawStreamDecoder());
|
||||
decoders.setDecoder("9patch", new Res9patchStreamDecoder());
|
||||
|
||||
AXmlResourceParser axmlParser = new AXmlResourceParser();
|
||||
axmlParser.setAttrDecoder(new ResAttrDecoder());
|
||||
decoders.setDecoder("xml",
|
||||
new XmlPullStreamDecoder(axmlParser, getResXmlSerializer()));
|
||||
decoders.setDecoder("xml", new XmlPullStreamDecoder(axmlParser,
|
||||
getResXmlSerializer()));
|
||||
|
||||
return new Duo<ResFileDecoder, AXmlResourceParser>(
|
||||
new ResFileDecoder(decoders), axmlParser);
|
||||
return new Duo<ResFileDecoder, AXmlResourceParser>(new ResFileDecoder(
|
||||
decoders), axmlParser);
|
||||
}
|
||||
|
||||
public Duo<ResFileDecoder, AXmlResourceParser> getManifestFileDecoder() {
|
||||
ResStreamDecoderContainer decoders =
|
||||
new ResStreamDecoderContainer();
|
||||
ResStreamDecoderContainer decoders = new ResStreamDecoderContainer();
|
||||
|
||||
AXmlResourceParser axmlParser = new AXmlResourceParser();
|
||||
|
||||
decoders.setDecoder("xml",
|
||||
new XmlPullStreamDecoder(axmlParser, getResXmlSerializer()));
|
||||
decoders.setDecoder("xml", new XmlPullStreamDecoder(axmlParser,
|
||||
getResXmlSerializer()));
|
||||
|
||||
return new Duo<ResFileDecoder, AXmlResourceParser>(
|
||||
new ResFileDecoder(decoders), axmlParser);
|
||||
return new Duo<ResFileDecoder, AXmlResourceParser>(new ResFileDecoder(
|
||||
decoders), axmlParser);
|
||||
}
|
||||
|
||||
public ExtMXSerializer getResXmlSerializer() {
|
||||
ExtMXSerializer serial = new ExtMXSerializer();
|
||||
serial.setProperty(ExtXmlSerializer.PROPERTY_SERIALIZER_INDENTATION
|
||||
, " ");
|
||||
serial.setProperty(ExtXmlSerializer.PROPERTY_SERIALIZER_INDENTATION,
|
||||
" ");
|
||||
serial.setProperty(ExtXmlSerializer.PROPERTY_SERIALIZER_LINE_SEPARATOR,
|
||||
System.getProperty("line.separator"));
|
||||
serial.setProperty(ExtMXSerializer.PROPERTY_DEFAULT_ENCODING, "utf-8");
|
||||
@ -360,11 +360,11 @@ final public class AndrolibResources {
|
||||
serial.flush();
|
||||
outStream.close();
|
||||
} catch (IOException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not generate: " + valuesFile.getPath(), ex);
|
||||
throw new AndrolibException("Could not generate: "
|
||||
+ valuesFile.getPath(), ex);
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not generate: " + valuesFile.getPath(), ex);
|
||||
throw new AndrolibException("Could not generate: "
|
||||
+ valuesFile.getPath(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -380,8 +380,8 @@ final public class AndrolibResources {
|
||||
serial.startTag(null, "public");
|
||||
serial.attribute(null, "type", spec.getType().getName());
|
||||
serial.attribute(null, "name", spec.getName());
|
||||
serial.attribute(null, "id", String.format(
|
||||
"0x%08x", spec.getId().id));
|
||||
serial.attribute(null, "id",
|
||||
String.format("0x%08x", spec.getId().id));
|
||||
serial.endTag(null, "public");
|
||||
}
|
||||
|
||||
@ -390,11 +390,11 @@ final public class AndrolibResources {
|
||||
serial.flush();
|
||||
outStream.close();
|
||||
} catch (IOException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not generate public.xml file", ex);
|
||||
throw new AndrolibException("Could not generate public.xml file",
|
||||
ex);
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not generate public.xml file", ex);
|
||||
throw new AndrolibException("Could not generate public.xml file",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -402,8 +402,8 @@ final public class AndrolibResources {
|
||||
ResTable resTable, boolean keepBroken) throws AndrolibException {
|
||||
try {
|
||||
return ARSCDecoder.decode(
|
||||
apkFile.getDirectory().getFileInput("resources.arsc"), false,
|
||||
keepBroken, resTable).getPackages();
|
||||
apkFile.getDirectory().getFileInput("resources.arsc"),
|
||||
false, keepBroken, resTable).getPackages();
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not load resources.arsc from file: " + apkFile, ex);
|
||||
@ -431,8 +431,8 @@ final public class AndrolibResources {
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
in = AndrolibResources.class.getResourceAsStream(
|
||||
"/brut/androlib/android-framework.jar");
|
||||
in = AndrolibResources.class
|
||||
.getResourceAsStream("/brut/androlib/android-framework.jar");
|
||||
out = new FileOutputStream(apk);
|
||||
IOUtils.copy(in, out);
|
||||
return apk;
|
||||
@ -442,12 +442,14 @@ final public class AndrolibResources {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ex) {}
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ex) {}
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -470,13 +472,14 @@ final public class AndrolibResources {
|
||||
in = zip.getInputStream(entry);
|
||||
byte[] data = IOUtils.toByteArray(in);
|
||||
|
||||
ARSCData arsc = ARSCDecoder.decode(
|
||||
new ByteArrayInputStream(data), true, true);
|
||||
ARSCData arsc = ARSCDecoder.decode(new ByteArrayInputStream(data),
|
||||
true, true);
|
||||
publicizeResources(data, arsc.getFlagsOffsets());
|
||||
|
||||
File outFile = new File(getFrameworkDir(),
|
||||
String.valueOf(arsc.getOnePackage().getId()) +
|
||||
(tag == null ? "" : '-' + tag) + ".apk");
|
||||
File outFile = new File(getFrameworkDir(), String.valueOf(arsc
|
||||
.getOnePackage().getId())
|
||||
+ (tag == null ? "" : '-' + tag)
|
||||
+ ".apk");
|
||||
|
||||
out = new ZipOutputStream(new FileOutputStream(outFile));
|
||||
out.setMethod(ZipOutputStream.STORED);
|
||||
@ -496,12 +499,14 @@ final public class AndrolibResources {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ex) {}
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ex) {}
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -525,12 +530,14 @@ final public class AndrolibResources {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ex) {}
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ex) {}
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -561,17 +568,18 @@ final public class AndrolibResources {
|
||||
path = sFrameworkFolder;
|
||||
} else if (System.getProperty("os.name").equals("Mac OS X")) {
|
||||
/* store in user-home, for Mac OS X */
|
||||
path = System.getProperty("user.home") + File.separatorChar +
|
||||
"Library/apktool/framework"; }
|
||||
else {
|
||||
path = System.getProperty("user.home") + File.separatorChar +
|
||||
"apktool" + File.separatorChar + "framework";
|
||||
path = System.getProperty("user.home") + File.separatorChar
|
||||
+ "Library/apktool/framework";
|
||||
} else {
|
||||
path = System.getProperty("user.home") + File.separatorChar
|
||||
+ "apktool" + File.separatorChar + "framework";
|
||||
}
|
||||
File dir = new File(path);
|
||||
if (!dir.exists()) {
|
||||
if (!dir.mkdirs()) {
|
||||
if (sFrameworkFolder != null) {
|
||||
System.out.println("Can't create Framework directory: " + dir);
|
||||
System.out.println("Can't create Framework directory: "
|
||||
+ dir);
|
||||
}
|
||||
throw new AndrolibException("Can't create directory: " + dir);
|
||||
}
|
||||
@ -581,19 +589,19 @@ final public class AndrolibResources {
|
||||
|
||||
public File getAndroidResourcesFile() throws AndrolibException {
|
||||
try {
|
||||
return Jar.getResourceAsFile("/brut/androlib/android-framework.jar");
|
||||
return Jar
|
||||
.getResourceAsFile("/brut/androlib/android-framework.jar");
|
||||
} catch (BrutException ex) {
|
||||
throw new AndrolibException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: dirty static hack. I have to refactor decoding mechanisms.
|
||||
public static boolean sKeepBroken = false;
|
||||
public static String sFrameworkFolder = null;
|
||||
|
||||
private final static Logger LOGGER =
|
||||
Logger.getLogger(AndrolibResources.class.getName());
|
||||
private final static Logger LOGGER = Logger
|
||||
.getLogger(AndrolibResources.class.getName());
|
||||
|
||||
private String mMinSdkVersion = null;
|
||||
private String mMaxSdkVersion = null;
|
||||
|
@ -143,4 +143,8 @@ public class ResTable {
|
||||
public Map<String, String> getPackageInfo() {
|
||||
return mPackageInfo;
|
||||
}
|
||||
|
||||
public boolean isPackageInfoValueSet(String key) {
|
||||
return (mPackageInfo.containsKey(key));
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,10 @@ public class ARSCDecoder {
|
||||
packages[i] = readPackage();
|
||||
}
|
||||
|
||||
// store package
|
||||
if (this.mResTable.isPackageInfoValueSet("cur_package") != true) {
|
||||
this.mResTable.addPackageInfo("cur_package", packages[0].getName());
|
||||
}
|
||||
return packages;
|
||||
}
|
||||
|
||||
|
@ -53,30 +53,31 @@ public class XmlPullStreamDecoder implements ResStreamDecoder {
|
||||
if ("manifest".equalsIgnoreCase(pp.getName())) {
|
||||
try {
|
||||
hidePackageInfo = parseManifest(pp);
|
||||
if (hidePackageInfo) {
|
||||
return;
|
||||
}
|
||||
} catch (AndrolibException e) {}
|
||||
}
|
||||
if ("uses-sdk".equalsIgnoreCase(pp.getName())) {
|
||||
}else if ("uses-sdk".equalsIgnoreCase(pp.getName())) {
|
||||
try {
|
||||
hideSdkInfo = parseAttr(pp);
|
||||
if(hideSdkInfo) {
|
||||
return;
|
||||
}
|
||||
} catch (AndrolibException e) {}
|
||||
}
|
||||
} else if (hideSdkInfo && type == XmlPullParser.END_TAG &&
|
||||
"uses-sdk".equalsIgnoreCase(pp.getName())) {
|
||||
"uses-sdk".equalsIgnoreCase(pp.getName()) ||
|
||||
hidePackageInfo && type == XmlPullParser.END_TAG &&
|
||||
"manifest".equalsIgnoreCase(pp.getName())) {
|
||||
return;
|
||||
}
|
||||
super.event(pp);
|
||||
}
|
||||
|
||||
private boolean parseManifest(XmlPullParser pp) throws AndrolibException {
|
||||
ResTable restable = resTable;
|
||||
|
||||
// @todo read <manifest> for package:
|
||||
return false;
|
||||
// read <manifest> for package:
|
||||
for (int i = 0; i < pp.getAttributeCount(); i++) {
|
||||
if (pp.getAttributeName(i).equalsIgnoreCase(("package"))) {
|
||||
restable.addPackageInfo("orig_package", pp.getAttributeValue(i));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean parseAttr(XmlPullParser pp) throws AndrolibException {
|
||||
|
Loading…
Reference in New Issue
Block a user