Misc baksmali cleanup

This commit is contained in:
Ben Gruver 2013-05-11 13:37:19 -07:00
parent 0e103007d1
commit 4b171afedb
7 changed files with 226 additions and 268 deletions

View File

@ -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");

View File

@ -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');
} }

View File

@ -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);
}
} }
} }

View File

@ -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(":")));
}
} }

View File

@ -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;

View File

@ -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");
}
}
} }

View File

@ -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);
}
}