diff options
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); + } + } } |