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