mirror of
https://github.com/revanced/smali.git
synced 2025-05-09 19:04:32 +02:00
Misc baksmali cleanup
This commit is contained in:
parent
0e103007d1
commit
4b171afedb
@ -62,7 +62,7 @@ public class ArrayDataMethodItem extends InstructionMethodItem<ArrayPayload> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Number number: instruction.getArrayElements()) {
|
for (Number number: elements) {
|
||||||
LongRenderer.writeSignedIntOrLongTo(writer, number.longValue());
|
LongRenderer.writeSignedIntOrLongTo(writer, number.longValue());
|
||||||
writer.write(suffix);
|
writer.write(suffix);
|
||||||
writer.write("\n");
|
writer.write("\n");
|
||||||
|
@ -176,9 +176,7 @@ public class MethodDefinition {
|
|||||||
writer.write('\n');
|
writer.write('\n');
|
||||||
|
|
||||||
List<MethodItem> methodItems = getMethodItems();
|
List<MethodItem> methodItems = getMethodItems();
|
||||||
int size = methodItems.size();
|
for (MethodItem methodItem: methodItems) {
|
||||||
for (int i=0; i<size; i++) {
|
|
||||||
MethodItem methodItem = methodItems.get(i);
|
|
||||||
if (methodItem.writeTo(writer)) {
|
if (methodItem.writeTo(writer)) {
|
||||||
writer.write('\n');
|
writer.write('\n');
|
||||||
}
|
}
|
||||||
|
@ -28,14 +28,10 @@
|
|||||||
|
|
||||||
package org.jf.baksmali;
|
package org.jf.baksmali;
|
||||||
|
|
||||||
import com.google.common.base.Splitter;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import org.jf.baksmali.Adaptors.ClassDefinition;
|
import org.jf.baksmali.Adaptors.ClassDefinition;
|
||||||
import org.jf.dexlib2.analysis.ClassPath;
|
import org.jf.dexlib2.analysis.ClassPath;
|
||||||
import org.jf.dexlib2.analysis.CustomInlineMethodResolver;
|
|
||||||
import org.jf.dexlib2.analysis.InlineMethodResolver;
|
|
||||||
import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
|
|
||||||
import org.jf.dexlib2.iface.ClassDef;
|
import org.jf.dexlib2.iface.ClassDef;
|
||||||
import org.jf.dexlib2.iface.DexFile;
|
import org.jf.dexlib2.iface.DexFile;
|
||||||
import org.jf.dexlib2.util.SyntheticAccessorResolver;
|
import org.jf.dexlib2.util.SyntheticAccessorResolver;
|
||||||
@ -44,57 +40,22 @@ import org.jf.util.IndentingWriter;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class baksmali {
|
public class baksmali {
|
||||||
public static void disassembleDexFile(String dexFilePath, DexFile dexFile, int apiLevel, boolean deodex,
|
|
||||||
String outputDirectory, String[] classPathDirs, String bootClassPath,
|
|
||||||
String extraBootClassPath, boolean noParameterRegisters,
|
|
||||||
boolean useLocalsDirective, boolean useSequentialLabels,
|
|
||||||
boolean outputDebugInfo, boolean addCodeOffsets, boolean noAccessorComments,
|
|
||||||
int registerInfo, boolean ignoreErrors, String inlineTable,
|
|
||||||
boolean checkPackagePrivateAccess)
|
|
||||||
{
|
|
||||||
baksmaliOptions options = new baksmaliOptions();
|
|
||||||
|
|
||||||
options.noParameterRegisters = noParameterRegisters;
|
public static void disassembleDexFile(DexFile dexFile, baksmaliOptions options) {
|
||||||
options.useLocalsDirective = useLocalsDirective;
|
if (options.registerInfo != 0 || options.deodex) {
|
||||||
options.useSequentialLabels = useSequentialLabels;
|
|
||||||
options.outputDebugInfo = outputDebugInfo;
|
|
||||||
options.addCodeOffsets = addCodeOffsets;
|
|
||||||
options.noAccessorComments = noAccessorComments;
|
|
||||||
options.deodex = deodex;
|
|
||||||
options.registerInfo = registerInfo;
|
|
||||||
options.bootClassPath = bootClassPath;
|
|
||||||
|
|
||||||
if (registerInfo != 0 || deodex) {
|
|
||||||
try {
|
try {
|
||||||
Iterable<String> extraBootClassPaths = null;
|
Iterable<String> extraClassPathEntries;
|
||||||
if (extraBootClassPath != null && extraBootClassPath.length() > 0) {
|
if (options.extraClassPathEntries != null) {
|
||||||
assert extraBootClassPath.charAt(0) == ':';
|
extraClassPathEntries = options.extraClassPathEntries;
|
||||||
extraBootClassPaths = Splitter.on(':').split(extraBootClassPath.substring(1));
|
|
||||||
} else {
|
} else {
|
||||||
extraBootClassPaths = ImmutableList.of();
|
extraClassPathEntries = ImmutableList.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<String> bootClassPaths = null;
|
options.classPath = ClassPath.fromClassPath(options.bootClassPathDirs,
|
||||||
if (bootClassPath != null) {
|
Iterables.concat(options.bootClassPathEntries, extraClassPathEntries), dexFile,
|
||||||
bootClassPaths = Splitter.on(':').split(bootClassPath);
|
options.apiLevel);
|
||||||
} else if (dexFile instanceof DexBackedOdexFile) {
|
|
||||||
bootClassPaths = ((DexBackedOdexFile)dexFile).getDependencies();
|
|
||||||
}else {
|
|
||||||
bootClassPaths = ImmutableList.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
options.classPath = ClassPath.fromClassPath(Arrays.asList(classPathDirs),
|
|
||||||
Iterables.concat(bootClassPaths, extraBootClassPaths), dexFile, apiLevel);
|
|
||||||
|
|
||||||
if (inlineTable != null) {
|
|
||||||
options.inlineResolver = new CustomInlineMethodResolver(options.classPath, new File(inlineTable));
|
|
||||||
} else if (dexFile instanceof DexBackedOdexFile) {
|
|
||||||
options.inlineResolver = InlineMethodResolver.createInlineMethodResolver(((DexBackedOdexFile) dexFile).getOdexVersion());
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
System.err.println("\n\nError occured while loading boot class path files. Aborting.");
|
System.err.println("\n\nError occured while loading boot class path files. Aborting.");
|
||||||
ex.printStackTrace(System.err);
|
ex.printStackTrace(System.err);
|
||||||
@ -102,10 +63,10 @@ public class baksmali {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File outputDirectoryFile = new File(outputDirectory);
|
File outputDirectoryFile = new File(options.outputDirectory);
|
||||||
if (!outputDirectoryFile.exists()) {
|
if (!outputDirectoryFile.exists()) {
|
||||||
if (!outputDirectoryFile.mkdirs()) {
|
if (!outputDirectoryFile.mkdirs()) {
|
||||||
System.err.println("Can't create the output directory " + outputDirectory);
|
System.err.println("Can't create the output directory " + options.outputDirectory);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,85 +83,84 @@ public class baksmali {
|
|||||||
});
|
});
|
||||||
classDefs = ImmutableList.copyOf(classDefs);
|
classDefs = ImmutableList.copyOf(classDefs);
|
||||||
|
|
||||||
if (!noAccessorComments) {
|
if (!options.noAccessorComments) {
|
||||||
options.syntheticAccessorResolver = new SyntheticAccessorResolver(classDefs);
|
options.syntheticAccessorResolver = new SyntheticAccessorResolver(classDefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDirectoryFile, ".smali");
|
ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDirectoryFile, ".smali");
|
||||||
|
|
||||||
for (ClassDef classDef: classDefs) {
|
for (ClassDef classDef: classDefs) {
|
||||||
/**
|
disassembleClass(classDef, fileNameHandler, options);
|
||||||
* The path for the disassembly file is based on the package name
|
|
||||||
* The class descriptor will look something like:
|
|
||||||
* Ljava/lang/Object;
|
|
||||||
* Where the there is leading 'L' and a trailing ';', and the parts of the
|
|
||||||
* package name are separated by '/'
|
|
||||||
*/
|
|
||||||
|
|
||||||
String classDescriptor = classDef.getType();
|
|
||||||
|
|
||||||
//validate that the descriptor is formatted like we expect
|
|
||||||
if (classDescriptor.charAt(0) != 'L' ||
|
|
||||||
classDescriptor.charAt(classDescriptor.length()-1) != ';') {
|
|
||||||
System.err.println("Unrecognized class descriptor - " + classDescriptor + " - skipping class");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);
|
|
||||||
|
|
||||||
//create and initialize the top level string template
|
|
||||||
ClassDefinition classDefinition = new ClassDefinition(options, classDef);
|
|
||||||
|
|
||||||
//write the disassembly
|
|
||||||
Writer writer = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File smaliParent = smaliFile.getParentFile();
|
|
||||||
if (!smaliParent.exists()) {
|
|
||||||
if (!smaliParent.mkdirs()) {
|
|
||||||
System.err.println("Unable to create directory " + smaliParent.toString() + " - skipping class");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!smaliFile.exists()){
|
|
||||||
if (!smaliFile.createNewFile()) {
|
|
||||||
System.err.println("Unable to create file " + smaliFile.toString() + " - skipping class");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedWriter bufWriter = new BufferedWriter(new OutputStreamWriter(
|
|
||||||
new FileOutputStream(smaliFile), "UTF8"));
|
|
||||||
|
|
||||||
writer = new IndentingWriter(bufWriter);
|
|
||||||
classDefinition.writeTo((IndentingWriter)writer);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
System.err.println("\n\nError occured while disassembling class " + classDescriptor.replace('/', '.') + " - skipping class");
|
|
||||||
ex.printStackTrace();
|
|
||||||
smaliFile.delete();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (writer != null) {
|
|
||||||
try {
|
|
||||||
writer.close();
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
System.err.println("\n\nError occured while closing file " + smaliFile.toString());
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ignoreErrors && classDefinition.hadValidationErrors()) {
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Pattern extJarPattern = Pattern.compile("(?:^|\\\\|/)ext.(?:jar|odex)$");
|
private static void disassembleClass(ClassDef classDef, ClassFileNameHandler fileNameHandler,
|
||||||
private static boolean isExtJar(String dexFilePath) {
|
baksmaliOptions options) {
|
||||||
Matcher m = extJarPattern.matcher(dexFilePath);
|
/**
|
||||||
return m.find();
|
* The path for the disassembly file is based on the package name
|
||||||
|
* The class descriptor will look something like:
|
||||||
|
* Ljava/lang/Object;
|
||||||
|
* Where the there is leading 'L' and a trailing ';', and the parts of the
|
||||||
|
* package name are separated by '/'
|
||||||
|
*/
|
||||||
|
String classDescriptor = classDef.getType();
|
||||||
|
|
||||||
|
//validate that the descriptor is formatted like we expect
|
||||||
|
if (classDescriptor.charAt(0) != 'L' ||
|
||||||
|
classDescriptor.charAt(classDescriptor.length()-1) != ';') {
|
||||||
|
System.err.println("Unrecognized class descriptor - " + classDescriptor + " - skipping class");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);
|
||||||
|
|
||||||
|
//create and initialize the top level string template
|
||||||
|
ClassDefinition classDefinition = new ClassDefinition(options, classDef);
|
||||||
|
|
||||||
|
//write the disassembly
|
||||||
|
Writer writer = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File smaliParent = smaliFile.getParentFile();
|
||||||
|
if (!smaliParent.exists()) {
|
||||||
|
if (!smaliParent.mkdirs()) {
|
||||||
|
System.err.println("Unable to create directory " + smaliParent.toString() + " - skipping class");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!smaliFile.exists()){
|
||||||
|
if (!smaliFile.createNewFile()) {
|
||||||
|
System.err.println("Unable to create file " + smaliFile.toString() + " - skipping class");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedWriter bufWriter = new BufferedWriter(new OutputStreamWriter(
|
||||||
|
new FileOutputStream(smaliFile), "UTF8"));
|
||||||
|
|
||||||
|
writer = new IndentingWriter(bufWriter);
|
||||||
|
classDefinition.writeTo((IndentingWriter)writer);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
System.err.println("\n\nError occured while disassembling class " + classDescriptor.replace('/', '.') + " - skipping class");
|
||||||
|
ex.printStackTrace();
|
||||||
|
// noinspection ResultOfMethodCallIgnored
|
||||||
|
smaliFile.delete();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (writer != null) {
|
||||||
|
try {
|
||||||
|
writer.close();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
System.err.println("\n\nError occured while closing file " + smaliFile.toString());
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.ignoreErrors && classDefinition.hadValidationErrors()) {
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,14 @@
|
|||||||
|
|
||||||
package org.jf.baksmali;
|
package org.jf.baksmali;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import org.jf.dexlib2.analysis.ClassPath;
|
import org.jf.dexlib2.analysis.ClassPath;
|
||||||
import org.jf.dexlib2.analysis.InlineMethodResolver;
|
import org.jf.dexlib2.analysis.InlineMethodResolver;
|
||||||
import org.jf.dexlib2.util.SyntheticAccessorResolver;
|
import org.jf.dexlib2.util.SyntheticAccessorResolver;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class baksmaliOptions {
|
public class baksmaliOptions {
|
||||||
// register info values
|
// register info values
|
||||||
public static final int ALL = 1;
|
public static final int ALL = 1;
|
||||||
@ -45,6 +49,13 @@ public class baksmaliOptions {
|
|||||||
public static final int MERGE = 32;
|
public static final int MERGE = 32;
|
||||||
public static final int FULLMERGE = 64;
|
public static final int FULLMERGE = 64;
|
||||||
|
|
||||||
|
public int apiLevel = 15;
|
||||||
|
public String outputDirectory = "out";
|
||||||
|
public List<String> bootClassPathDirs = Lists.newArrayList();
|
||||||
|
|
||||||
|
public List<String> bootClassPathEntries = Lists.newArrayList();
|
||||||
|
public List<String> extraClassPathEntries = Lists.newArrayList();
|
||||||
|
|
||||||
public boolean noParameterRegisters = false;
|
public boolean noParameterRegisters = false;
|
||||||
public boolean useLocalsDirective = false;
|
public boolean useLocalsDirective = false;
|
||||||
public boolean useSequentialLabels = false;
|
public boolean useSequentialLabels = false;
|
||||||
@ -52,10 +63,22 @@ public class baksmaliOptions {
|
|||||||
public boolean addCodeOffsets = false;
|
public boolean addCodeOffsets = false;
|
||||||
public boolean noAccessorComments = false;
|
public boolean noAccessorComments = false;
|
||||||
public boolean deodex = false;
|
public boolean deodex = false;
|
||||||
|
public boolean ignoreErrors = false;
|
||||||
|
public boolean checkPackagePrivateAccess = false;
|
||||||
public InlineMethodResolver inlineResolver = null;
|
public InlineMethodResolver inlineResolver = null;
|
||||||
public int registerInfo = 0;
|
public int registerInfo = 0;
|
||||||
public String bootClassPath;
|
|
||||||
public ClassPath classPath = null;
|
public ClassPath classPath = null;
|
||||||
|
|
||||||
public SyntheticAccessorResolver syntheticAccessorResolver = null;
|
public SyntheticAccessorResolver syntheticAccessorResolver = null;
|
||||||
|
|
||||||
|
public void setBootClassPath(String bootClassPath) {
|
||||||
|
bootClassPathEntries = Lists.newArrayList(bootClassPath.split(":"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addExtraClassPath(String extraClassPath) {
|
||||||
|
if (extraClassPath.startsWith(":")) {
|
||||||
|
extraClassPath = extraClassPath.substring(1);
|
||||||
|
}
|
||||||
|
extraClassPathEntries.addAll(Arrays.asList(extraClassPath.split(":")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,7 @@ import java.io.IOException;
|
|||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
|
||||||
public class dump {
|
public class dump {
|
||||||
public static void dump(DexBackedDexFile dexFile, String dumpFileName, int apiLevel)
|
public static void dump(DexBackedDexFile dexFile, String dumpFileName, int apiLevel) throws IOException {
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
if (dumpFileName != null) {
|
if (dumpFileName != null) {
|
||||||
Writer writer = null;
|
Writer writer = null;
|
||||||
|
|
||||||
|
@ -28,16 +28,19 @@
|
|||||||
|
|
||||||
package org.jf.baksmali;
|
package org.jf.baksmali;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import org.apache.commons.cli.*;
|
import org.apache.commons.cli.*;
|
||||||
import org.jf.dexlib2.DexFileFactory;
|
import org.jf.dexlib2.DexFileFactory;
|
||||||
|
import org.jf.dexlib2.analysis.CustomInlineMethodResolver;
|
||||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||||
|
import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
|
||||||
import org.jf.util.ConsoleUtil;
|
import org.jf.util.ConsoleUtil;
|
||||||
import org.jf.util.SmaliHelpFormatter;
|
import org.jf.util.SmaliHelpFormatter;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
@ -63,6 +66,7 @@ public class main {
|
|||||||
properties.load(templateStream);
|
properties.load(templateStream);
|
||||||
version = properties.getProperty("application.version");
|
version = properties.getProperty("application.version");
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
VERSION = version;
|
VERSION = version;
|
||||||
}
|
}
|
||||||
@ -76,7 +80,7 @@ public class main {
|
|||||||
/**
|
/**
|
||||||
* Run!
|
* Run!
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) throws IOException {
|
||||||
Locale locale = new Locale("en", "US");
|
Locale locale = new Locale("en", "US");
|
||||||
Locale.setDefault(locale);
|
Locale.setDefault(locale);
|
||||||
|
|
||||||
@ -90,37 +94,18 @@ public class main {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
baksmaliOptions options = new baksmaliOptions();
|
||||||
|
|
||||||
boolean disassemble = true;
|
boolean disassemble = true;
|
||||||
boolean doDump = false;
|
boolean doDump = false;
|
||||||
boolean noParameterRegisters = false;
|
|
||||||
boolean useLocalsDirective = false;
|
|
||||||
boolean useSequentialLabels = false;
|
|
||||||
boolean outputDebugInfo = true;
|
|
||||||
boolean addCodeOffsets = false;
|
|
||||||
boolean noAccessorComments = false;
|
|
||||||
boolean deodex = false;
|
|
||||||
boolean ignoreErrors = false;
|
|
||||||
boolean checkPackagePrivateAccess = false;
|
|
||||||
|
|
||||||
int apiLevel = 15;
|
|
||||||
|
|
||||||
int registerInfo = 0;
|
|
||||||
|
|
||||||
String outputDirectory = "out";
|
|
||||||
String dumpFileName = null;
|
String dumpFileName = null;
|
||||||
String inputDexFileName = null;
|
|
||||||
String bootClassPath = null;
|
|
||||||
StringBuffer extraBootClassPathEntries = new StringBuffer();
|
|
||||||
List<String> bootClassPathDirs = new ArrayList<String>();
|
|
||||||
bootClassPathDirs.add(".");
|
|
||||||
String inlineTable = null;
|
|
||||||
|
|
||||||
String[] remainingArgs = commandLine.getArgs();
|
String[] remainingArgs = commandLine.getArgs();
|
||||||
|
|
||||||
Option[] options = commandLine.getOptions();
|
Option[] clOptions = commandLine.getOptions();
|
||||||
|
|
||||||
for (int i=0; i<options.length; i++) {
|
for (int i=0; i<clOptions.length; i++) {
|
||||||
Option option = options[i];
|
Option option = clOptions[i];
|
||||||
String opt = option.getOpt();
|
String opt = option.getOpt();
|
||||||
|
|
||||||
switch (opt.charAt(0)) {
|
switch (opt.charAt(0)) {
|
||||||
@ -128,8 +113,8 @@ public class main {
|
|||||||
version();
|
version();
|
||||||
return;
|
return;
|
||||||
case '?':
|
case '?':
|
||||||
while (++i < options.length) {
|
while (++i < clOptions.length) {
|
||||||
if (options[i].getOpt().charAt(0) == '?') {
|
if (clOptions[i].getOpt().charAt(0) == '?') {
|
||||||
usage(true);
|
usage(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -137,28 +122,29 @@ public class main {
|
|||||||
usage(false);
|
usage(false);
|
||||||
return;
|
return;
|
||||||
case 'o':
|
case 'o':
|
||||||
outputDirectory = commandLine.getOptionValue("o");
|
options.outputDirectory = commandLine.getOptionValue("o");
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
noParameterRegisters = true;
|
options.noParameterRegisters = true;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
useLocalsDirective = true;
|
options.useLocalsDirective = true;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
useSequentialLabels = true;
|
options.useSequentialLabels = true;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
outputDebugInfo = false;
|
options.outputDebugInfo = false;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
bootClassPathDirs.add(option.getValue());
|
options.bootClassPathDirs.add(option.getValue());
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
addCodeOffsets = true;
|
options.addCodeOffsets = true;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
String[] values = commandLine.getOptionValues('r');
|
String[] values = commandLine.getOptionValues('r');
|
||||||
|
int registerInfo = 0;
|
||||||
|
|
||||||
if (values == null || values.length == 0) {
|
if (values == null || values.length == 0) {
|
||||||
registerInfo = baksmaliOptions.ARGS | baksmaliOptions.DEST;
|
registerInfo = baksmaliOptions.ARGS | baksmaliOptions.DEST;
|
||||||
@ -188,39 +174,40 @@ public class main {
|
|||||||
registerInfo &= ~baksmaliOptions.MERGE;
|
registerInfo &= ~baksmaliOptions.MERGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
options.registerInfo = registerInfo;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
String bcp = commandLine.getOptionValue("c");
|
String bcp = commandLine.getOptionValue("c");
|
||||||
if (bcp != null && bcp.charAt(0) == ':') {
|
if (bcp != null && bcp.charAt(0) == ':') {
|
||||||
extraBootClassPathEntries.append(bcp);
|
options.addExtraClassPath(bcp);
|
||||||
} else {
|
} else {
|
||||||
bootClassPath = bcp;
|
options.setBootClassPath(bcp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
deodex = true;
|
options.deodex = true;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
noAccessorComments = true;
|
options.noAccessorComments = true;
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
apiLevel = Integer.parseInt(commandLine.getOptionValue("a"));
|
options.apiLevel = Integer.parseInt(commandLine.getOptionValue("a"));
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
disassemble = false;
|
disassemble = false;
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
doDump = true;
|
doDump = true;
|
||||||
dumpFileName = commandLine.getOptionValue("D", inputDexFileName + ".dump");
|
dumpFileName = commandLine.getOptionValue("D");
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
ignoreErrors = true;
|
options.ignoreErrors = true;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
inlineTable = commandLine.getOptionValue("T");
|
options.inlineResolver = new CustomInlineMethodResolver(options.classPath, new File(commandLine.getOptionValue("T")));
|
||||||
break;
|
break;
|
||||||
case 'K':
|
case 'K':
|
||||||
checkPackagePrivateAccess = true;
|
options.checkPackagePrivateAccess = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert false;
|
assert false;
|
||||||
@ -232,60 +219,45 @@ public class main {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputDexFileName = remainingArgs[0];
|
String inputDexFileName = remainingArgs[0];
|
||||||
|
|
||||||
try {
|
File dexFileFile = new File(inputDexFileName);
|
||||||
File dexFileFile = new File(inputDexFileName);
|
if (!dexFileFile.exists()) {
|
||||||
if (!dexFileFile.exists()) {
|
System.err.println("Can't find the file " + inputDexFileName);
|
||||||
System.err.println("Can't find the file " + inputDexFileName);
|
System.exit(1);
|
||||||
System.exit(1);
|
}
|
||||||
|
|
||||||
|
//Read in and parse the dex file
|
||||||
|
DexBackedDexFile dexFile = DexFileFactory.loadDexFile(dexFileFile, options.apiLevel);
|
||||||
|
|
||||||
|
if (dexFile.isOdexFile()) {
|
||||||
|
if (!options.deodex) {
|
||||||
|
System.err.println("Warning: You are disassembling an odex file without deodexing it. You");
|
||||||
|
System.err.println("won't be able to re-assemble the results unless you deodex it with the -x");
|
||||||
|
System.err.println("option");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
options.deodex = false;
|
||||||
|
}
|
||||||
|
|
||||||
//Read in and parse the dex file
|
|
||||||
DexBackedDexFile dexFile = DexFileFactory.loadDexFile(dexFileFile, apiLevel);
|
|
||||||
|
|
||||||
if (dexFile.isOdexFile()) {
|
if ((options.deodex || options.registerInfo != 0) && options.bootClassPathEntries == null) {
|
||||||
if (!deodex) {
|
if (dexFile instanceof DexBackedOdexFile) {
|
||||||
System.err.println("Warning: You are disassembling an odex file without deodexing it. You");
|
((DexBackedOdexFile)dexFile).getDependencies();
|
||||||
System.err.println("won't be able to re-assemble the results unless you deodex it with the -x");
|
|
||||||
System.err.println("option");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
deodex = false;
|
options.bootClassPathEntries = getDefaultBootClassPathForApi(options.apiLevel);
|
||||||
|
|
||||||
if (bootClassPath == null) {
|
|
||||||
bootClassPath = "core.jar:ext.jar:framework.jar:android.policy.jar:services.jar";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (disassemble) {
|
if (disassemble) {
|
||||||
String[] bootClassPathDirsArray = new String[bootClassPathDirs.size()];
|
baksmali.disassembleDexFile(dexFile, options);
|
||||||
for (int i=0; i<bootClassPathDirsArray.length; i++) {
|
}
|
||||||
bootClassPathDirsArray[i] = bootClassPathDirs.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
baksmali.disassembleDexFile(dexFileFile.getPath(), dexFile, apiLevel, deodex, outputDirectory,
|
if (doDump) {
|
||||||
bootClassPathDirsArray, bootClassPath, extraBootClassPathEntries.toString(),
|
if (dumpFileName == null) {
|
||||||
noParameterRegisters, useLocalsDirective, useSequentialLabels, outputDebugInfo, addCodeOffsets,
|
dumpFileName = commandLine.getOptionValue(inputDexFileName + ".dump");
|
||||||
noAccessorComments, registerInfo, ignoreErrors, inlineTable, checkPackagePrivateAccess);
|
|
||||||
}
|
}
|
||||||
|
dump.dump(dexFile, dumpFileName, options.apiLevel);
|
||||||
if (doDump) {
|
|
||||||
try {
|
|
||||||
dump.dump(dexFile, dumpFileName, apiLevel);
|
|
||||||
}catch (IOException ex) {
|
|
||||||
System.err.println("Error occured while writing dump file");
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (RuntimeException ex) {
|
|
||||||
System.err.println("\n\nUNEXPECTED TOP-LEVEL EXCEPTION:");
|
|
||||||
ex.printStackTrace();
|
|
||||||
System.exit(1);
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
System.err.println("\n\nUNEXPECTED TOP-LEVEL ERROR:");
|
|
||||||
ex.printStackTrace();
|
|
||||||
System.exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,6 +291,7 @@ public class main {
|
|||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("AccessStaticViaInstance")
|
||||||
private static void buildOptions() {
|
private static void buildOptions() {
|
||||||
Option versionOption = OptionBuilder.withLongOpt("version")
|
Option versionOption = OptionBuilder.withLongOpt("version")
|
||||||
.withDescription("prints the version then exits")
|
.withDescription("prints the version then exits")
|
||||||
@ -459,4 +432,60 @@ public class main {
|
|||||||
options.addOption((Option)option);
|
options.addOption((Option)option);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static List<String> getDefaultBootClassPathForApi(int apiLevel) {
|
||||||
|
if (apiLevel < 9) {
|
||||||
|
return Lists.newArrayList(
|
||||||
|
"/system/framework/core.jar",
|
||||||
|
"/system/framework/ext.jar",
|
||||||
|
"/system/framework/framework.jar",
|
||||||
|
"/system/framework/android.policy.jar",
|
||||||
|
"/system/framework/services.jar");
|
||||||
|
} else if (apiLevel < 12) {
|
||||||
|
return Lists.newArrayList(
|
||||||
|
"/system/framework/core.jar",
|
||||||
|
"/system/framework/bouncycastle.jar",
|
||||||
|
"/system/framework/ext.jar",
|
||||||
|
"/system/framework/framework.jar",
|
||||||
|
"/system/framework/android.policy.jar",
|
||||||
|
"/system/framework/services.jar",
|
||||||
|
"/system/framework/core-junit.jar");
|
||||||
|
} else if (apiLevel < 14) {
|
||||||
|
return Lists.newArrayList(
|
||||||
|
"/system/framework/core.jar",
|
||||||
|
"/system/framework/apache-xml.jar",
|
||||||
|
"/system/framework/bouncycastle.jar",
|
||||||
|
"/system/framework/ext.jar",
|
||||||
|
"/system/framework/framework.jar",
|
||||||
|
"/system/framework/android.policy.jar",
|
||||||
|
"/system/framework/services.jar",
|
||||||
|
"/system/framework/core-junit.jar");
|
||||||
|
} else if (apiLevel < 16) {
|
||||||
|
return Lists.newArrayList(
|
||||||
|
"/system/framework/core.jar",
|
||||||
|
"/system/framework/core-junit.jar",
|
||||||
|
"/system/framework/bouncycastle.jar",
|
||||||
|
"/system/framework/ext.jar",
|
||||||
|
"/system/framework/framework.jar",
|
||||||
|
"/system/framework/android.policy.jar",
|
||||||
|
"/system/framework/services.jar",
|
||||||
|
"/system/framework/apache-xml.jar",
|
||||||
|
"/system/framework/filterfw.jar");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// this is correct as of api 17/4.2.2
|
||||||
|
return Lists.newArrayList(
|
||||||
|
"/system/framework/core.jar",
|
||||||
|
"/system/framework/core-junit.jar",
|
||||||
|
"/system/framework/bouncycastle.jar",
|
||||||
|
"/system/framework/ext.jar",
|
||||||
|
"/system/framework/framework.jar",
|
||||||
|
"/system/framework/telephony-common.jar",
|
||||||
|
"/system/framework/mms-common.jar",
|
||||||
|
"/system/framework/android.policy.jar",
|
||||||
|
"/system/framework/services.jar",
|
||||||
|
"/system/framework/apache-xml.jar");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013, Google Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above
|
|
||||||
* copyright notice, this list of conditions and the following disclaimer
|
|
||||||
* in the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* * Neither the name of Google Inc. nor the names of its
|
|
||||||
* contributors may be used to endorse or promote products derived from
|
|
||||||
* this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jf.baksmali;
|
|
||||||
|
|
||||||
import org.jf.dexlib2.dexbacked.BaseDexBuffer;
|
|
||||||
|
|
||||||
public class temp {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
BaseDexBuffer bdb = new BaseDexBuffer(new byte[]{1,2,3,4,5,6,7,8});
|
|
||||||
long start = System.nanoTime();
|
|
||||||
|
|
||||||
for (long i=0; i<10000000000l; i++) {
|
|
||||||
bdb.readLong(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
long end = System.nanoTime();
|
|
||||||
|
|
||||||
System.out.println((end-start)/1E9d);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user