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

View File

@ -45,9 +45,11 @@ import org.jf.util.StringWrapper;
import org.jf.util.jcommander.CommaColonParameterSplitter;
import org.jf.util.jcommander.ExtendedParameter;
import org.jf.util.jcommander.ExtendedParameters;
import org.xml.sax.SAXException;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.util.List;
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.")
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 " +
"comment with the name of the resource being referenced. The value should be a comma/colon" +
"separated list of prefix=file pairs. For example R=res/values/public.xml:android.R=" +
"$ANDROID_HOME/platforms/android-19/data/res/values/public.xml")
@ExtendedParameter(argumentNames = "resource spec")
"comment with the name of the resource being referenced. The parameter accepts 2 values:" +
"an arbitrary resource prefix and the path to a public.xml file. For example: " +
"--resolve-resources android.R framework/res/values/public.xml. This option can be specified " +
"multiple times to provide resources from multiple packages.")
@ExtendedParameter(argumentNames = {"resource prefix", "public.xml file"})
private List<String> resourceIdFiles = Lists.newArrayList();
@Parameter(names = {"-j", "--jobs"},
@ -230,26 +233,32 @@ public class DisassembleCommand extends DexInputCommand {
if (!resourceIdFiles.isEmpty()) {
Map<String, File> resourceFiles = Maps.newHashMap();
for (String resourceIdFileSpec: resourceIdFiles) {
int separatorIndex = resourceIdFileSpec.indexOf('=');
if (separatorIndex == -1) {
System.err.println(String.format("Invalid resource id spec: %s", resourceIdFileSpec));
usage();
System.exit(-1);
}
String prefix = resourceIdFileSpec.substring(0, separatorIndex);
String resourceIdFilePath = resourceIdFileSpec.substring(separatorIndex+1);
File resourceIdFile = new File(resourceIdFilePath);
assert (resourceIdFiles.size() % 2) == 0;
for (int i=0; i<resourceIdFiles.size(); i+=2) {
String resourcePrefix = resourceIdFiles.get(i);
String publicXml = resourceIdFiles.get(i+1);
if (!resourceIdFile.exists()) {
System.err.println(String.format("Can't find file: %s", resourceIdFilePath));
File publicXmlFile = new File(publicXml);
if (!publicXmlFile.exists()) {
System.err.println(String.format("Can't find file: %s", publicXmlFile));
System.exit(-1);
}
resourceFiles.put(prefix, resourceIdFile);
resourceFiles.put(resourcePrefix, publicXmlFile);
}
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;