aboutsummaryrefslogtreecommitdiff
path: root/smali
diff options
context:
space:
mode:
authorBen Gruver <bgruv@google.com>2015-10-01 08:34:21 -0700
committerBen Gruver <bgruv@google.com>2015-10-01 08:34:21 -0700
commitea3fdd7e860db85a062bbadc90f3a5a7555d0d25 (patch)
tree4aae5978087484137ef0a55da1c5d38059c8d102 /smali
parent546fdfe3d10ed255daf016d9707c12ac659dd50e (diff)
parenta9dcd62b92ceac9cadb5a3b828852f13349ae78e (diff)
downloadsmali-ea3fdd7e860db85a062bbadc90f3a5a7555d0d25.tar.gz
Merge branch 'master' into smalidea
Diffstat (limited to 'smali')
-rw-r--r--smali/src/main/antlr/smaliParser.g2
-rw-r--r--smali/src/main/antlr/smaliTreeWalker.g2
-rw-r--r--smali/src/main/java/org/jf/smali/SmaliTestUtils.java5
-rw-r--r--smali/src/main/java/org/jf/smali/main.java90
-rw-r--r--smali/src/main/jflex/smaliLexer.jflex6
-rw-r--r--smali/src/test/resources/LexerTest/InstructionTest.smali5
-rw-r--r--smali/src/test/resources/LexerTest/InstructionTest.tokens5
7 files changed, 106 insertions, 9 deletions
diff --git a/smali/src/main/antlr/smaliParser.g b/smali/src/main/antlr/smaliParser.g
index 9fcf2f1d..0ce825c1 100644
--- a/smali/src/main/antlr/smaliParser.g
+++ b/smali/src/main/antlr/smaliParser.g
@@ -257,7 +257,7 @@ import org.jf.dexlib2.Opcodes;
private boolean verboseErrors = false;
private boolean allowOdex = false;
private int apiLevel = 15;
- private Opcodes opcodes = new Opcodes(apiLevel, false);
+ private Opcodes opcodes = Opcodes.forApi(apiLevel);
public void setVerboseErrors(boolean verboseErrors) {
this.verboseErrors = verboseErrors;
diff --git a/smali/src/main/antlr/smaliTreeWalker.g b/smali/src/main/antlr/smaliTreeWalker.g
index 0d2623b0..c3a50994 100644
--- a/smali/src/main/antlr/smaliTreeWalker.g
+++ b/smali/src/main/antlr/smaliTreeWalker.g
@@ -77,7 +77,7 @@ import java.util.*;
public String classType;
private boolean verboseErrors = false;
private int apiLevel = 15;
- private Opcodes opcodes = new Opcodes(apiLevel, false);
+ private Opcodes opcodes = Opcodes.forApi(apiLevel);
private DexBuilder dexBuilder;
public void setDexBuilder(DexBuilder dexBuilder) {
diff --git a/smali/src/main/java/org/jf/smali/SmaliTestUtils.java b/smali/src/main/java/org/jf/smali/SmaliTestUtils.java
index 26de0089..bef07414 100644
--- a/smali/src/main/java/org/jf/smali/SmaliTestUtils.java
+++ b/smali/src/main/java/org/jf/smali/SmaliTestUtils.java
@@ -57,7 +57,7 @@ public class SmaliTestUtils {
throws RecognitionException, IOException {
CommonTokenStream tokens;
LexerErrorInterface lexer;
- DexBuilder dexBuilder = DexBuilder.makeDexBuilder(apiLevel);
+ DexBuilder dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(apiLevel, experimental));
Reader reader = new StringReader(smaliText);
@@ -94,8 +94,7 @@ public class SmaliTestUtils {
dexBuilder.writeTo(dataStore);
- DexBackedDexFile dexFile = new DexBackedDexFile(
- new Opcodes(apiLevel, experimental), dataStore.getData());
+ DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(apiLevel, experimental), dataStore.getData());
return Iterables.getFirst(dexFile.getClasses(), null);
}
diff --git a/smali/src/main/java/org/jf/smali/main.java b/smali/src/main/java/org/jf/smali/main.java
index 31f65a88..b36b088d 100644
--- a/smali/src/main/java/org/jf/smali/main.java
+++ b/smali/src/main/java/org/jf/smali/main.java
@@ -28,14 +28,16 @@
package org.jf.smali;
+import com.google.common.base.Strings;
import com.google.common.collect.Lists;
+import com.google.common.collect.Ordering;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.Token;
import org.antlr.runtime.TokenSource;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream;
-import org.antlr.runtime.tree.TreeNodeStream;
import org.apache.commons.cli.*;
+import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.writer.builder.DexBuilder;
import org.jf.dexlib2.writer.io.FileDataStore;
import org.jf.util.ConsoleUtil;
@@ -113,6 +115,15 @@ public class main {
boolean printTokens = false;
boolean experimental = false;
+ boolean listMethods = false;
+ String methodListFilename = null;
+
+ boolean listFields = false;
+ String fieldListFilename = null;
+
+ boolean listTypes = false;
+ String typeListFilename = null;
+
int apiLevel = 15;
String outputDexFile = "out.dex";
@@ -153,6 +164,18 @@ public class main {
case 'j':
jobs = Integer.parseInt(commandLine.getOptionValue("j"));
break;
+ case 'm':
+ listMethods = true;
+ methodListFilename = commandLine.getOptionValue("m");
+ break;
+ case 'f':
+ listFields = true;
+ fieldListFilename = commandLine.getOptionValue("f");
+ break;
+ case 't':
+ listTypes = true;
+ typeListFilename = commandLine.getOptionValue("t");
+ break;
case 'V':
verboseErrors = true;
break;
@@ -195,7 +218,8 @@ public class main {
boolean errors = false;
- final DexBuilder dexBuilder = DexBuilder.makeDexBuilder(apiLevel);
+ final DexBuilder dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(apiLevel, experimental));
+
ExecutorService executor = Executors.newFixedThreadPool(jobs);
List<Future<Boolean>> tasks = Lists.newArrayList();
@@ -232,6 +256,27 @@ public class main {
System.exit(1);
}
+ if (listMethods) {
+ if (Strings.isNullOrEmpty(methodListFilename)) {
+ methodListFilename = outputDexFile + ".methods";
+ }
+ writeReferences(dexBuilder.getMethodReferences(), methodListFilename);
+ }
+
+ if (listFields) {
+ if (Strings.isNullOrEmpty(fieldListFilename)) {
+ fieldListFilename = outputDexFile + ".fields";
+ }
+ writeReferences(dexBuilder.getFieldReferences(), fieldListFilename);
+ }
+
+ if (listTypes) {
+ if (Strings.isNullOrEmpty(typeListFilename)) {
+ typeListFilename = outputDexFile + ".types";
+ }
+ writeReferences(dexBuilder.getTypeReferences(), typeListFilename);
+ }
+
dexBuilder.writeTo(new FileDataStore(new File(outputDexFile)));
} catch (RuntimeException ex) {
System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
@@ -244,6 +289,23 @@ public class main {
}
}
+ private static void writeReferences(List<String> references, String filename) {
+ PrintWriter writer = null;
+ try {
+ writer = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
+
+ for (String reference: Ordering.natural().sortedCopy(references)) {
+ writer.println(reference);
+ }
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ } finally {
+ if (writer != null) {
+ writer.close();
+ }
+ }
+ }
+
private static void getSmaliFilesInDir(@Nonnull File dir, @Nonnull Set<File> smaliFiles) {
File[] files = dir.listFiles();
if (files != null) {
@@ -378,6 +440,27 @@ public class main {
.withArgName("API_LEVEL")
.create("a");
+ Option listMethodsOption = OptionBuilder.withLongOpt("list-methods")
+ .withDescription("Lists all the method references to FILE" +
+ " (<output_dex_filename>.methods by default)")
+ .hasOptionalArg()
+ .withArgName("FILE")
+ .create("m");
+
+ Option listFieldsOption = OptionBuilder.withLongOpt("list-fields")
+ .withDescription("Lists all the field references to FILE" +
+ " (<output_dex_filename>.fields by default)")
+ .hasOptionalArg()
+ .withArgName("FILE")
+ .create("f");
+
+ Option listClassesOption = OptionBuilder.withLongOpt("list-types")
+ .withDescription("Lists all the type references to FILE" +
+ " (<output_dex_filename>.types by default)")
+ .hasOptionalArg()
+ .withArgName("FILE")
+ .create("t");
+
Option experimentalOption = OptionBuilder.withLongOpt("experimental")
.withDescription("enable experimental opcodes to be assembled, even if they " +
" aren't necessarily supported by the Android runtime yet")
@@ -405,6 +488,9 @@ public class main {
basicOptions.addOption(apiLevelOption);
basicOptions.addOption(experimentalOption);
basicOptions.addOption(jobsOption);
+ basicOptions.addOption(listMethodsOption);
+ basicOptions.addOption(listFieldsOption);
+ basicOptions.addOption(listClassesOption);
debugOptions.addOption(verboseErrorsOption);
debugOptions.addOption(printTokensOption);
diff --git a/smali/src/main/jflex/smaliLexer.jflex b/smali/src/main/jflex/smaliLexer.jflex
index d7fd6cab..2f57a438 100644
--- a/smali/src/main/jflex/smaliLexer.jflex
+++ b/smali/src/main/jflex/smaliLexer.jflex
@@ -421,7 +421,7 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayPrefix} ({ClassDescriptor} |
return newToken(INSTRUCTION_FORMAT10x);
}
- "return-void-barrier" {
+ "return-void-barrier" | "return-void-no-barrier" {
return newToken(INSTRUCTION_FORMAT10x_ODEX);
}
@@ -522,7 +522,9 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayPrefix} ({ClassDescriptor} |
"liberate-variable" {
return newToken(INSTRUCTION_FORMAT22c_STRING);
}
- "iget-quick" | "iget-wide-quick" | "iget-object-quick" | "iput-quick" | "iput-wide-quick" | "iput-object-quick" {
+
+ "iget-quick" | "iget-wide-quick" | "iget-object-quick" | "iput-quick" | "iput-wide-quick" | "iput-object-quick" |
+ "iput-boolean-quick" | "iput-byte-quick" | "iput-char-quick" | "iput-short-quick" {
return newToken(INSTRUCTION_FORMAT22cs_FIELD);
}
diff --git a/smali/src/test/resources/LexerTest/InstructionTest.smali b/smali/src/test/resources/LexerTest/InstructionTest.smali
index f6dcbb1e..174cff8c 100644
--- a/smali/src/test/resources/LexerTest/InstructionTest.smali
+++ b/smali/src/test/resources/LexerTest/InstructionTest.smali
@@ -2,6 +2,7 @@ goto
return-void
nop
return-void-barrier
+return-void-no-barrier
const/4
move-result
move-result-wide
@@ -132,6 +133,10 @@ iget-object-quick
iput-quick
iput-wide-quick
iput-object-quick
+iput-boolean-quick
+iput-byte-quick
+iput-char-quick
+iput-short-quick
rsub-int
add-int/lit16
mul-int/lit16
diff --git a/smali/src/test/resources/LexerTest/InstructionTest.tokens b/smali/src/test/resources/LexerTest/InstructionTest.tokens
index fb5503b5..fa959bad 100644
--- a/smali/src/test/resources/LexerTest/InstructionTest.tokens
+++ b/smali/src/test/resources/LexerTest/InstructionTest.tokens
@@ -2,6 +2,7 @@ INSTRUCTION_FORMAT10t("goto")
INSTRUCTION_FORMAT10x("return-void")
INSTRUCTION_FORMAT10x("nop")
INSTRUCTION_FORMAT10x_ODEX("return-void-barrier")
+INSTRUCTION_FORMAT10x_ODEX("return-void-no-barrier")
INSTRUCTION_FORMAT11n("const/4")
INSTRUCTION_FORMAT11x("move-result")
INSTRUCTION_FORMAT11x("move-result-wide")
@@ -132,6 +133,10 @@ INSTRUCTION_FORMAT22cs_FIELD("iget-object-quick")
INSTRUCTION_FORMAT22cs_FIELD("iput-quick")
INSTRUCTION_FORMAT22cs_FIELD("iput-wide-quick")
INSTRUCTION_FORMAT22cs_FIELD("iput-object-quick")
+INSTRUCTION_FORMAT22cs_FIELD("iput-boolean-quick")
+INSTRUCTION_FORMAT22cs_FIELD("iput-byte-quick")
+INSTRUCTION_FORMAT22cs_FIELD("iput-char-quick")
+INSTRUCTION_FORMAT22cs_FIELD("iput-short-quick")
INSTRUCTION_FORMAT22s_OR_ID("rsub-int")
INSTRUCTION_FORMAT22s("add-int/lit16")
INSTRUCTION_FORMAT22s("mul-int/lit16")