aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--baksmali/src/main/java/org/jf/baksmali/DisassembleCommand.java8
-rw-r--r--baksmali/src/main/java/org/jf/baksmali/ListVtablesCommand.java49
-rw-r--r--util/src/main/java/org/jf/util/StringWrapper.java12
3 files changed, 47 insertions, 22 deletions
diff --git a/baksmali/src/main/java/org/jf/baksmali/DisassembleCommand.java b/baksmali/src/main/java/org/jf/baksmali/DisassembleCommand.java
index c6a6ec6c..90e8d44f 100644
--- a/baksmali/src/main/java/org/jf/baksmali/DisassembleCommand.java
+++ b/baksmali/src/main/java/org/jf/baksmali/DisassembleCommand.java
@@ -43,7 +43,6 @@ import org.jf.dexlib2.dexbacked.DexBackedDexFile;
import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
import org.jf.dexlib2.iface.DexFile;
import org.jf.dexlib2.util.SyntheticAccessorResolver;
-import org.jf.util.ConsoleUtil;
import org.jf.util.StringWrapper;
import org.jf.util.jcommander.CommaColonParameterSplitter;
@@ -184,10 +183,9 @@ public class DisassembleCommand extends DexInputCommand {
}
if (showDeodexWarning() && dexFile.hasOdexOpcodes()) {
- System.err.println(StringWrapper.wrapStringOnBreaks(
- "Warning: You are disassembling an odex/oat file without deodexing it. " +
- "You won't be able to re-assemble the results unless you deodex it. See " +
- "\"baksmali help deodex\"", ConsoleUtil.getConsoleWidth()));
+ StringWrapper.printWrappedString(System.err,
+ "Warning: You are disassembling an odex/oat file without deodexing it. You won't be able to " +
+ "re-assemble the results unless you deodex it. See \"baksmali help deodex\"");
}
if (needsClassPath() && bootClassPath.isEmpty()) {
diff --git a/baksmali/src/main/java/org/jf/baksmali/ListVtablesCommand.java b/baksmali/src/main/java/org/jf/baksmali/ListVtablesCommand.java
index 84d9dea2..ae74c811 100644
--- a/baksmali/src/main/java/org/jf/baksmali/ListVtablesCommand.java
+++ b/baksmali/src/main/java/org/jf/baksmali/ListVtablesCommand.java
@@ -96,6 +96,10 @@ public class ListVtablesCommand extends DexInputCommand {
"supported in the Android runtime yet.")
private boolean experimentalOpcodes = false;
+ @Parameter(names = "--classes",
+ description = "A comma separated list of classes: Only print the vtable for these classes")
+ private String classes = null;
+
public ListVtablesCommand(@Nonnull JCommander jc) {
this.jc = jc;
}
@@ -121,28 +125,39 @@ public class ListVtablesCommand extends DexInputCommand {
}
try {
- for (ClassDef classDef : dexFile.getClasses()) {
- ClassProto classProto = (ClassProto) options.classPath.getClass(classDef);
- List<Method> methods = classProto.getVtable();
- String className = "Class " + classDef.getType() + " extends " + classDef.getSuperclass() + " : " + methods.size() + " methods\n";
- System.out.write(className.getBytes());
- for (int i = 0; i < methods.size(); i++) {
- Method method = methods.get(i);
-
- String methodString = i + ":" + method.getDefiningClass() + "->" + method.getName() + "(";
- for (CharSequence parameter : method.getParameterTypes()) {
- methodString += parameter;
- }
- methodString += ")" + method.getReturnType() + "\n";
- System.out.write(methodString.getBytes());
+ if (classes != null) {
+ for (String cls: classes.split(",")) {
+ listClassVtable((ClassProto)options.classPath.getClass(cls));
}
- System.out.write("\n".getBytes());
+ return;
+ }
+
+ for (ClassDef classDef : dexFile.getClasses()) {
+ listClassVtable((ClassProto)options.classPath.getClass(classDef));
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
+ private void listClassVtable(ClassProto classProto) throws IOException {
+ List<Method> methods = classProto.getVtable();
+ String className = "Class " + classProto.getType() + " extends " + classProto.getSuperclass() +
+ " : " + methods.size() + " methods\n";
+ System.out.write(className.getBytes());
+ for (int i = 0; i < methods.size(); i++) {
+ Method method = methods.get(i);
+
+ String methodString = i + ":" + method.getDefiningClass() + "->" + method.getName() + "(";
+ for (CharSequence parameter : method.getParameterTypes()) {
+ methodString += parameter;
+ }
+ methodString += ")" + method.getReturnType() + "\n";
+ System.out.write(methodString.getBytes());
+ }
+ System.out.write("\n".getBytes());
+ }
+
protected BaksmaliOptions getOptions(DexFile dexFile) {
final BaksmaliOptions options = new BaksmaliOptions();
@@ -150,8 +165,8 @@ public class ListVtablesCommand extends DexInputCommand {
try {
options.classPath = ClassPath.fromClassPath(classPathDirectories,
- Iterables.concat(bootClassPath, classPath), dexFile, apiLevel,
- checkPackagePrivateAccess, experimentalOpcodes);
+ Iterables.concat(bootClassPath, classPath), dexFile, apiLevel, checkPackagePrivateAccess,
+ experimentalOpcodes);
} catch (Exception ex) {
System.err.println("Error occurred while loading class path files.");
ex.printStackTrace(System.err);
diff --git a/util/src/main/java/org/jf/util/StringWrapper.java b/util/src/main/java/org/jf/util/StringWrapper.java
index 052924fb..304c2972 100644
--- a/util/src/main/java/org/jf/util/StringWrapper.java
+++ b/util/src/main/java/org/jf/util/StringWrapper.java
@@ -33,6 +33,7 @@ package org.jf.util;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import java.io.PrintStream;
import java.text.BreakIterator;
import java.util.Iterator;
@@ -46,6 +47,7 @@ public class StringWrapper {
* @return An iterable of Strings containing the wrapped lines
*/
public static Iterable<String> wrapStringOnBreaks(@Nonnull final String string, final int maxWidth) {
+ // TODO: should we strip any trailing newlines?
final BreakIterator breakIterator = BreakIterator.getLineInstance();
breakIterator.setText(string);
@@ -184,4 +186,14 @@ public class StringWrapper {
System.arraycopy(arr, 0, newArr, 0, arr.length);
return newArr;
}
+
+ public static void printWrappedString(@Nonnull PrintStream stream, @Nonnull String string) {
+ printWrappedString(stream, string, ConsoleUtil.getConsoleWidth());
+ }
+
+ public static void printWrappedString(@Nonnull PrintStream stream, @Nonnull String string, int maxWidth) {
+ for (String str: wrapStringOnBreaks(string, maxWidth)) {
+ stream.println(str);
+ }
+ }
}