Rework and fix the --resolve-resources parameter

This commit is contained in:
Ben Gruver 2016-09-04 13:58:54 -07:00
parent fdfb6d10f4
commit 99394b3daf
2 changed files with 35 additions and 40 deletions

View File

@ -34,10 +34,10 @@ package org.jf.baksmali;
import org.jf.dexlib2.analysis.ClassPath; import org.jf.dexlib2.analysis.ClassPath;
import org.jf.dexlib2.analysis.InlineMethodResolver; import org.jf.dexlib2.analysis.InlineMethodResolver;
import org.jf.dexlib2.util.SyntheticAccessorResolver; import org.jf.dexlib2.util.SyntheticAccessorResolver;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import javax.annotation.Nonnull;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParserFactory;
@ -45,7 +45,6 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.jar.Attributes;
public class BaksmaliOptions { public class BaksmaliOptions {
public int apiLevel = 15; public int apiLevel = 15;
@ -83,24 +82,15 @@ public class BaksmaliOptions {
* *
* @param resourceFiles A map of resource prefixes -> public.xml files * @param resourceFiles A map of resource prefixes -> public.xml files
*/ */
public void loadResourceIds(Map<String, File> resourceFiles) { public void loadResourceIds(Map<String, File> resourceFiles) throws SAXException, IOException {
class PublicResourceHandler extends DefaultHandler {
@Nonnull private final String prefix;
public PublicResourceHandler(@Nonnull String prefix) {
super();
this.prefix = prefix;
}
}
for (Map.Entry<String, File> entry: resourceFiles.entrySet()) { for (Map.Entry<String, File> entry: resourceFiles.entrySet()) {
try { try {
SAXParser saxp = SAXParserFactory.newInstance().newSAXParser(); SAXParser saxp = SAXParserFactory.newInstance().newSAXParser();
final String prefix = entry.getKey(); final String prefix = entry.getKey();
saxp.parse(entry.getValue(), new DefaultHandler() { saxp.parse(entry.getValue(), new DefaultHandler() {
public void startElement(String uri, String localName, String qName, Attributes attr) @Override
throws SAXException { public void startElement(String uri, String localName, String qName,
Attributes attr) throws SAXException {
if (qName.equals("public")) { if (qName.equals("public")) {
String resourceType = attr.getValue("type"); String resourceType = attr.getValue("type");
String resourceName = attr.getValue("name").replace('.', '_'); String resourceName = attr.getValue("name").replace('.', '_');
@ -111,12 +101,8 @@ public class BaksmaliOptions {
} }
} }
}); });
} catch (ParserConfigurationException e) { } catch (ParserConfigurationException ex) {
continue; throw new RuntimeException(ex);
} catch (SAXException e) {
continue;
} catch (IOException e) {
continue;
} }
} }
} }

View File

@ -45,9 +45,11 @@ import org.jf.util.StringWrapper;
import org.jf.util.jcommander.CommaColonParameterSplitter; import org.jf.util.jcommander.CommaColonParameterSplitter;
import org.jf.util.jcommander.ExtendedParameter; import org.jf.util.jcommander.ExtendedParameter;
import org.jf.util.jcommander.ExtendedParameters; import org.jf.util.jcommander.ExtendedParameters;
import org.xml.sax.SAXException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -98,12 +100,13 @@ public class DisassembleCommand extends DexInputCommand {
description = "Add a comment before each instruction with it's code offset within the method.") description = "Add a comment before each instruction with it's code offset within the method.")
private boolean codeOffsets = false; private boolean codeOffsets = false;
@Parameter(names = "--resolve-resources", arity=1, @Parameter(names = {"--resolve-resources", "--rr"}, arity = 2,
description = "This will attempt to find any resource id references within the bytecode and add a " + description = "This will attempt to find any resource id references within the bytecode and add a " +
"comment with the name of the resource being referenced. The value should be a comma/colon" + "comment with the name of the resource being referenced. The parameter accepts 2 values:" +
"separated list of prefix=file pairs. For example R=res/values/public.xml:android.R=" + "an arbitrary resource prefix and the path to a public.xml file. For example: " +
"$ANDROID_HOME/platforms/android-19/data/res/values/public.xml") "--resolve-resources android.R framework/res/values/public.xml. This option can be specified " +
@ExtendedParameter(argumentNames = "resource spec") "multiple times to provide resources from multiple packages.")
@ExtendedParameter(argumentNames = {"resource prefix", "public.xml file"})
private List<String> resourceIdFiles = Lists.newArrayList(); private List<String> resourceIdFiles = Lists.newArrayList();
@Parameter(names = {"-j", "--jobs"}, @Parameter(names = {"-j", "--jobs"},
@ -230,26 +233,32 @@ public class DisassembleCommand extends DexInputCommand {
if (!resourceIdFiles.isEmpty()) { if (!resourceIdFiles.isEmpty()) {
Map<String, File> resourceFiles = Maps.newHashMap(); Map<String, File> resourceFiles = Maps.newHashMap();
for (String resourceIdFileSpec: resourceIdFiles) { assert (resourceIdFiles.size() % 2) == 0;
int separatorIndex = resourceIdFileSpec.indexOf('='); for (int i=0; i<resourceIdFiles.size(); i+=2) {
if (separatorIndex == -1) { String resourcePrefix = resourceIdFiles.get(i);
System.err.println(String.format("Invalid resource id spec: %s", resourceIdFileSpec)); String publicXml = resourceIdFiles.get(i+1);
usage();
System.exit(-1);
}
String prefix = resourceIdFileSpec.substring(0, separatorIndex);
String resourceIdFilePath = resourceIdFileSpec.substring(separatorIndex+1);
File resourceIdFile = new File(resourceIdFilePath);
if (!resourceIdFile.exists()) { File publicXmlFile = new File(publicXml);
System.err.println(String.format("Can't find file: %s", resourceIdFilePath));
if (!publicXmlFile.exists()) {
System.err.println(String.format("Can't find file: %s", publicXmlFile));
System.exit(-1); System.exit(-1);
} }
resourceFiles.put(prefix, resourceIdFile); resourceFiles.put(resourcePrefix, publicXmlFile);
} }
options.loadResourceIds(resourceFiles); try {
options.loadResourceIds(resourceFiles);
} catch (IOException ex) {
System.err.println("Error while loading resource files:");
ex.printStackTrace(System.err);
System.exit(-1);
} catch (SAXException ex) {
System.err.println("Error while loading resource files:");
ex.printStackTrace(System.err);
System.exit(-1);
}
} }
options.parameterRegisters = parameterRegisters; options.parameterRegisters = parameterRegisters;