Clean up how api levels are handled in various places

Now that dex files store an associated Opcodes instance, we don't need to
pass the api level around as much.
This commit is contained in:
Ben Gruver 2016-10-23 22:09:52 -07:00
parent 7a95aa296f
commit 8e1afdda32
10 changed files with 24 additions and 40 deletions

View File

@ -49,11 +49,6 @@ import java.util.List;
import static org.jf.dexlib2.analysis.ClassPath.NOT_ART;
public class AnalysisArguments {
@Parameter(names = {"-a", "--api"},
description = "The numeric api level of the file being disassembled.")
@ExtendedParameter(argumentNames = "api")
public int apiLevel = 15;
@Parameter(names = {"-b", "--bootclasspath", "--bcp"},
description = "A colon separated list of the files to include in the bootclasspath when analyzing the " +
"dex file. If not specified, baksmali will attempt to choose an " +
@ -131,7 +126,7 @@ public class AnalysisArguments {
if (bootClassPath == null) {
// TODO: we should be able to get the api from the Opcodes object associated with the dexFile..
// except that the oat version -> api mapping doesn't fully work yet
resolver = new ClassPathResolver(filteredClassPathDirectories, classPath, dexFile, apiLevel);
resolver = new ClassPathResolver(filteredClassPathDirectories, classPath, dexFile);
} else if (bootClassPath.size() == 1 && bootClassPath.get(0).length() == 0) {
// --bootclasspath "" is a special case, denoting that no bootclasspath should be used
resolver = new ClassPathResolver(

View File

@ -52,6 +52,11 @@ import java.util.List;
*/
public abstract class DexInputCommand extends Command {
@Parameter(names = {"-a", "--api"},
description = "The numeric api level of the file being disassembled.")
@ExtendedParameter(argumentNames = "api")
public int apiLevel = 15;
@Parameter(description = "A dex/apk/oat/odex file. For apk or oat files that contain multiple dex " +
"files, you can specify the specific entry to use as if the apk/oat file was a directory. " +
"e.g. \"app.apk/classes2.dex\". For more information, see \"baksmali help input\".")
@ -100,9 +105,8 @@ public abstract class DexInputCommand extends Command {
* framework/arm/framework.oat/"system/framework/framework.jar:classes2.dex"
*
* @param input The name of a dex, apk, odex or oat file/entry.
* @param opcodes The set of opcodes to load the dex file with.
*/
protected void loadDexFile(@Nonnull String input, Opcodes opcodes) {
protected void loadDexFile(@Nonnull String input) {
File file = new File(input);
while (file != null && !file.exists()) {
@ -131,13 +135,13 @@ public abstract class DexInputCommand extends Command {
inputEntry = dexEntry;
try {
dexFile = DexFileFactory.loadDexEntry(file, dexEntry, exactMatch, opcodes);
dexFile = DexFileFactory.loadDexEntry(file, dexEntry, exactMatch, Opcodes.forApi(apiLevel));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} else {
try {
dexFile = DexFileFactory.loadDexFile(file, opcodes);
dexFile = DexFileFactory.loadDexFile(file, Opcodes.forApi(apiLevel));
} catch (IOException ex) {
throw new RuntimeException(ex);
}

View File

@ -38,7 +38,6 @@ import com.beust.jcommander.ParametersDelegate;
import com.beust.jcommander.validators.PositiveInteger;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.util.SyntheticAccessorResolver;
import org.jf.util.StringWrapper;
import org.jf.util.jcommander.ExtendedParameter;
@ -155,7 +154,7 @@ public class DisassembleCommand extends DexInputCommand {
}
String input = inputList.get(0);
loadDexFile(input, Opcodes.getDefault());
loadDexFile(input);
if (showDeodexWarning() && dexFile.hasOdexOpcodes()) {
StringWrapper.printWrappedString(System.err,

View File

@ -34,12 +34,10 @@ package org.jf.baksmali;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
import org.jf.dexlib2.dexbacked.raw.RawDexFile;
import org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
import org.jf.util.ConsoleUtil;
import org.jf.util.jcommander.ExtendedParameter;
import org.jf.util.jcommander.ExtendedParameters;
import javax.annotation.Nonnull;
@ -56,11 +54,6 @@ public class DumpCommand extends DexInputCommand {
description = "Show usage information for this command.")
private boolean help;
@Parameter(names = {"-a", "--api"},
description = "The numeric api level of the file being disassembled.")
@ExtendedParameter(argumentNames = "api")
private int apiLevel = 15;
public DumpCommand(@Nonnull List<JCommander> commandAncestors) {
super(commandAncestors);
}
@ -78,10 +71,10 @@ public class DumpCommand extends DexInputCommand {
}
String input = inputList.get(0);
loadDexFile(input, Opcodes.getDefault());
loadDexFile(input);
try {
dump(dexFile, System.out, apiLevel);
dump(dexFile, System.out);
} catch (IOException ex) {
System.err.println("There was an error while dumping the dex file");
ex.printStackTrace(System.err);
@ -94,11 +87,10 @@ public class DumpCommand extends DexInputCommand {
* @param dexFile The dex file to dump
* @param output An OutputStream to write the annotated hex dump to. The caller is responsible for closing this
* when needed.
* @param apiLevel The api level to use when dumping the dex file
*
* @throws IOException
*/
public static void dump(@Nonnull DexBackedDexFile dexFile, @Nonnull OutputStream output, int apiLevel)
public static void dump(@Nonnull DexBackedDexFile dexFile, @Nonnull OutputStream output)
throws IOException {
Writer writer = new BufferedWriter(new OutputStreamWriter(output));

View File

@ -34,7 +34,6 @@ package org.jf.baksmali;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.util.jcommander.ExtendedParameters;
@ -68,7 +67,7 @@ public class ListClassesCommand extends DexInputCommand {
}
String input = inputList.get(0);
loadDexFile(input, Opcodes.getDefault());
loadDexFile(input);
for (ClassDef classDef: dexFile.getClasses()) {
System.out.println(classDef.getType());

View File

@ -35,7 +35,6 @@ import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.beust.jcommander.ParametersDelegate;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.analysis.ClassProto;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.reference.FieldReference;
@ -76,7 +75,7 @@ public class ListFieldOffsetsCommand extends DexInputCommand {
}
String input = inputList.get(0);
loadDexFile(input, Opcodes.getDefault());
loadDexFile(input);
BaksmaliOptions options = getOptions();
try {
@ -105,7 +104,7 @@ public class ListFieldOffsetsCommand extends DexInputCommand {
final BaksmaliOptions options = new BaksmaliOptions();
options.apiLevel = analysisArguments.apiLevel;
options.apiLevel = apiLevel;
try {
options.classPath = analysisArguments.loadClassPathForDexFile(

View File

@ -33,7 +33,6 @@ package org.jf.baksmali;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.iface.reference.Reference;
import org.jf.dexlib2.util.ReferenceUtil;
@ -66,7 +65,7 @@ public abstract class ListReferencesCommand extends DexInputCommand {
}
String input = inputList.get(0);
loadDexFile(input, Opcodes.getDefault());
loadDexFile(input);
for (Reference reference: dexFile.getReferences(referenceType)) {
System.out.println(ReferenceUtil.getReferenceString(reference));

View File

@ -37,7 +37,6 @@ import com.beust.jcommander.Parameters;
import com.beust.jcommander.ParametersDelegate;
import org.jf.baksmali.AnalysisArguments.CheckPackagePrivateArgument;
import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.analysis.ClassProto;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.Method;
@ -92,7 +91,7 @@ public class ListVtablesCommand extends DexInputCommand {
}
String input = inputList.get(0);
loadDexFile(input, Opcodes.getDefault());
loadDexFile(input);
BaksmaliOptions options = getOptions();
if (options == null) {
@ -142,7 +141,7 @@ public class ListVtablesCommand extends DexInputCommand {
final BaksmaliOptions options = new BaksmaliOptions();
options.apiLevel = analysisArguments.apiLevel;
options.apiLevel = apiLevel;
try {
options.classPath = analysisArguments.loadClassPathForDexFile(inputFile.getAbsoluteFile().getParentFile(),

View File

@ -81,7 +81,6 @@ public final class DexFileFactory {
throw new DexFileNotFoundException("%s does not exist", file.getName());
}
try {
ZipDexContainer container = new ZipDexContainer(file, opcodes);
return new DexEntryFinder(file.getPath(), container).findEntry("classes.dex", true);

View File

@ -82,7 +82,7 @@ public class ClassPathResolver {
public ClassPathResolver(@Nonnull List<String> bootClassPathDirs, @Nonnull List<String> bootClassPathEntries,
@Nonnull List<String> extraClassPathEntries, @Nonnull DexFile dexFile)
throws IOException {
this(bootClassPathDirs, bootClassPathEntries, extraClassPathEntries, dexFile, dexFile.getOpcodes().api);
this(bootClassPathDirs, bootClassPathEntries, extraClassPathEntries, dexFile, true);
}
/**
@ -92,7 +92,6 @@ public class ClassPathResolver {
* @param extraClassPathEntries A list of additional classpath entries to load. Can be empty. All entries must be
* local paths. Device paths are not supported.
* @param dexFile The dex file that the classpath will be used to analyze
* @param apiLevel The api level of the device. This is used to select an appropriate set of boot classpath entries.
* @throws IOException If any IOException occurs
* @throws ResolveException If any classpath entries cannot be loaded for some reason
*
@ -101,19 +100,19 @@ public class ClassPathResolver {
* classpath entries will be loaded
*/
public ClassPathResolver(@Nonnull List<String> bootClassPathDirs, @Nonnull List<String> extraClassPathEntries,
@Nonnull DexFile dexFile, int apiLevel)
@Nonnull DexFile dexFile)
throws IOException {
this(bootClassPathDirs, null, extraClassPathEntries, dexFile, apiLevel);
this(bootClassPathDirs, null, extraClassPathEntries, dexFile, true);
}
private ClassPathResolver(@Nonnull List<String> bootClassPathDirs, @Nullable List<String> bootClassPathEntries,
@Nonnull List<String> extraClassPathEntries, @Nonnull DexFile dexFile, int apiLevel)
@Nonnull List<String> extraClassPathEntries, @Nonnull DexFile dexFile, boolean unused)
throws IOException {
this.classPathDirs = bootClassPathDirs;
opcodes = dexFile.getOpcodes();
if (bootClassPathEntries == null) {
bootClassPathEntries = getDefaultBootClassPath(dexFile, apiLevel);
bootClassPathEntries = getDefaultBootClassPath(dexFile, opcodes.api);
}
for (String entry : bootClassPathEntries) {