Merge pull request #19 from whydoubt/master

Match and comment on resource IDs while performing baksmali
This commit is contained in:
Ben Gruver 2013-12-07 14:53:21 -08:00
commit ee3fb21461
7 changed files with 96 additions and 1 deletions

View File

@ -65,6 +65,8 @@ public class ArrayDataMethodItem extends InstructionMethodItem<ArrayPayload> {
for (Number number: elements) {
LongRenderer.writeSignedIntOrLongTo(writer, number.longValue());
writer.write(suffix);
if (elementWidth == 4)
writeResourceId(writer, number.intValue());
writer.write("\n");
}
writer.deindent(4);

View File

@ -43,6 +43,7 @@ import org.jf.util.IndentingWriter;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.Map;
public class InstructionMethodItem<T extends Instruction> extends MethodItem {
@Nonnull protected final MethodDefinition methodDef;
@ -140,6 +141,8 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
writeFirstRegister(writer);
writer.write(", ");
writeLiteral(writer);
if (instruction.getOpcode().setsWideRegister() == false)
writeResourceId(writer);
return true;
case Format21t:
case Format31t:
@ -337,6 +340,18 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
LongRenderer.writeSignedIntOrLongTo(writer, ((WideLiteralInstruction)instruction).getWideLiteral());
}
protected void writeResourceId(IndentingWriter writer) throws IOException {
writeResourceId(writer, ((NarrowLiteralInstruction)instruction).getNarrowLiteral());
}
protected void writeResourceId(IndentingWriter writer, int val) throws IOException {
Map<Integer,String> resourceIds = methodDef.classDef.options.resourceIds;
String resource = resourceIds.get(Integer.valueOf(val));
if (resource != null) {
writer.write(" # ");
writer.write(resource);
}
}
protected void writeFieldOffset(IndentingWriter writer) throws IOException {
writer.write("field@0x");

View File

@ -82,9 +82,12 @@ public class PackedSwitchMethodItem extends InstructionMethodItem<PackedSwitchPa
IntegerRenderer.writeTo(writer, firstKey);
writer.indent(4);
writer.write('\n');
int key = firstKey;
for (PackedSwitchTarget target: targets) {
target.writeTargetTo(writer);
writeResourceId(writer, key);
writer.write('\n');
key++;
}
writer.deindent(4);
writer.write(".end packed-switch");

View File

@ -71,6 +71,7 @@ public class SparseSwitchMethodItem extends InstructionMethodItem<SparseSwitchPa
IntegerRenderer.writeTo(writer, target.getKey());
writer.write(" -> ");
target.writeTargetTo(writer);
writeResourceId(writer, target.getKey());
writer.write('\n');
}
writer.deindent(4);

View File

@ -39,11 +39,19 @@ import org.jf.dexlib2.iface.DexFile;
import org.jf.dexlib2.util.SyntheticAccessorResolver;
import org.jf.util.ClassFileNameHandler;
import org.jf.util.IndentingWriter;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.io.*;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.*;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;
public class baksmali {
public static boolean disassembleDexFile(DexFile dexFile, final baksmaliOptions options) {
@ -66,6 +74,47 @@ public class baksmali {
}
}
if (options.resourceIdFileEntries != null) {
class PublicHandler extends DefaultHandler {
String prefix = null;
public PublicHandler(String prefix) {
super();
this.prefix = prefix;
}
public void startElement(String uri, String localName,
String qName, Attributes attr) throws SAXException {
if (qName.equals("public")) {
String type = attr.getValue("type");
String name = attr.getValue("name").replace('.', '_');
Integer public_key = Integer.decode(attr.getValue("id"));
String public_val = new StringBuffer()
.append(prefix)
.append(".")
.append(type)
.append(".")
.append(name)
.toString();
options.resourceIds.put(public_key, public_val);
}
}
};
for (Entry<String,String> entry: options.resourceIdFileEntries.entrySet()) {
try {
SAXParser saxp = SAXParserFactory.newInstance().newSAXParser();
String prefix = entry.getValue();
saxp.parse(entry.getKey(), new PublicHandler(prefix));
} catch (ParserConfigurationException e) {
continue;
} catch (SAXException e) {
continue;
} catch (IOException e) {
continue;
}
}
}
File outputDirectoryFile = new File(options.outputDirectory);
if (!outputDirectoryFile.exists()) {
if (!outputDirectoryFile.mkdirs()) {

View File

@ -37,7 +37,9 @@ import org.jf.dexlib2.analysis.InlineMethodResolver;
import org.jf.dexlib2.util.SyntheticAccessorResolver;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class baksmaliOptions {
// register info values
@ -56,6 +58,9 @@ public class baksmaliOptions {
public List<String> bootClassPathEntries = Lists.newArrayList();
public List<String> extraClassPathEntries = Lists.newArrayList();
public Map<String,String> resourceIdFileEntries = new HashMap<String,String>();
public Map<Integer,String> resourceIds = new HashMap<Integer,String>();
public boolean noParameterRegisters = false;
public boolean useLocalsDirective = false;
public boolean useSequentialLabels = false;
@ -82,4 +87,11 @@ public class baksmaliOptions {
}
extraClassPathEntries.addAll(Arrays.asList(extraClassPath.split(":")));
}
public void setResourceIdFiles(String resourceIdFiles) {
for (String resourceIdFile: resourceIdFiles.split(":")) {
String[] entry = resourceIdFile.split("=");
resourceIdFileEntries.put(entry[1], entry[0]);
}
}
}

View File

@ -218,6 +218,10 @@ public class main {
case 'K':
options.checkPackagePrivateAccess = true;
break;
case 'R':
String rif = commandLine.getOptionValue("R");
options.setResourceIdFiles(rif);
break;
default:
assert false;
}
@ -407,6 +411,14 @@ public class main {
.withArgName("NUM_THREADS")
.create("j");
Option resourceIdFilesOption = OptionBuilder.withLongOpt("resource-id-files")
.withDescription("the resource ID files to use, for analysis. A 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")
.hasArg()
.withArgName("FILES")
.create("i");
Option dumpOption = OptionBuilder.withLongOpt("dump-to")
.withDescription("dumps the given dex file into a single annotated dump file named FILE" +
" (<dexfile>.dump by default), along with the normal disassembly")
@ -451,6 +463,7 @@ public class main {
basicOptions.addOption(noAccessorCommentsOption);
basicOptions.addOption(apiLevelOption);
basicOptions.addOption(jobsOption);
basicOptions.addOption(resourceIdFilesOption);
debugOptions.addOption(dumpOption);
debugOptions.addOption(ignoreErrorsOption);
@ -521,4 +534,4 @@ public class main {
"/system/framework/apache-xml.jar");
}
}
}
}