mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 20:20:12 +02:00
Add more programmatic-friendly entry points for smali/baksmali
This adds entry points that are more friendly to programmatic usage. E.g. no calls to System.exit()
This commit is contained in:
parent
a198b46e20
commit
87d10dac27
@ -82,6 +82,9 @@ public class baksmaliOptions {
|
|||||||
public int registerInfo = 0;
|
public int registerInfo = 0;
|
||||||
public ClassPath classPath = null;
|
public ClassPath classPath = null;
|
||||||
public int jobs = Runtime.getRuntime().availableProcessors();
|
public int jobs = Runtime.getRuntime().availableProcessors();
|
||||||
|
public boolean disassemble = true;
|
||||||
|
public boolean dump = false;
|
||||||
|
public String dumpFileName = null;
|
||||||
|
|
||||||
public SyntheticAccessorResolver syntheticAccessorResolver = null;
|
public SyntheticAccessorResolver syntheticAccessorResolver = null;
|
||||||
|
|
||||||
|
@ -40,7 +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, boolean experimental) throws IOException {
|
public static void dump(DexBackedDexFile dexFile, String dumpFileName, int apiLevel) throws IOException {
|
||||||
if (dumpFileName != null) {
|
if (dumpFileName != null) {
|
||||||
Writer writer = null;
|
Writer writer = null;
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ import org.jf.dexlib2.analysis.InlineMethodResolver;
|
|||||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||||
import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
|
import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
|
||||||
import org.jf.dexlib2.dexbacked.OatFile.OatDexFile;
|
import org.jf.dexlib2.dexbacked.OatFile.OatDexFile;
|
||||||
|
import org.jf.dexlib2.iface.DexFile;
|
||||||
import org.jf.util.ConsoleUtil;
|
import org.jf.util.ConsoleUtil;
|
||||||
import org.jf.util.SmaliHelpFormatter;
|
import org.jf.util.SmaliHelpFormatter;
|
||||||
|
|
||||||
@ -83,6 +84,45 @@ public class main {
|
|||||||
private main() {
|
private main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A more programmatic-friendly entry point for baksmali
|
||||||
|
*
|
||||||
|
* @param options a baksmaliOptions object with the options to run baksmali with
|
||||||
|
* @param inputDexFile The DexFile to disassemble
|
||||||
|
* @return true if disassembly completed with no errors, or false if errors were encountered
|
||||||
|
*/
|
||||||
|
public static boolean run(@Nonnull baksmaliOptions options, @Nonnull DexFile inputDexFile) throws IOException {
|
||||||
|
if (options.bootClassPathEntries.isEmpty() &&
|
||||||
|
(options.deodex || options.registerInfo != 0 || options.normalizeVirtualMethods)) {
|
||||||
|
if (inputDexFile instanceof DexBackedOdexFile) {
|
||||||
|
options.bootClassPathEntries = ((DexBackedOdexFile)inputDexFile).getDependencies();
|
||||||
|
} else {
|
||||||
|
options.bootClassPathEntries = getDefaultBootClassPathForApi(options.apiLevel,
|
||||||
|
options.experimental);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.customInlineDefinitions == null && inputDexFile instanceof DexBackedOdexFile) {
|
||||||
|
options.inlineResolver =
|
||||||
|
InlineMethodResolver.createInlineMethodResolver(
|
||||||
|
((DexBackedOdexFile)inputDexFile).getOdexVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean errorOccurred = false;
|
||||||
|
if (options.disassemble) {
|
||||||
|
errorOccurred = !baksmali.disassembleDexFile(inputDexFile, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.dump) {
|
||||||
|
if (!(inputDexFile instanceof DexBackedDexFile)) {
|
||||||
|
throw new IllegalArgumentException("Annotated hex-dumps require a DexBackedDexFile");
|
||||||
|
}
|
||||||
|
dump.dump((DexBackedDexFile)inputDexFile, options.dumpFileName, options.apiLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !errorOccurred;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run!
|
* Run!
|
||||||
*/
|
*/
|
||||||
@ -102,11 +142,6 @@ public class main {
|
|||||||
|
|
||||||
baksmaliOptions options = new baksmaliOptions();
|
baksmaliOptions options = new baksmaliOptions();
|
||||||
|
|
||||||
boolean disassemble = true;
|
|
||||||
boolean doDump = false;
|
|
||||||
String dumpFileName = null;
|
|
||||||
boolean setBootClassPath = false;
|
|
||||||
|
|
||||||
String[] remainingArgs = commandLine.getArgs();
|
String[] remainingArgs = commandLine.getArgs();
|
||||||
Option[] clOptions = commandLine.getOptions();
|
Option[] clOptions = commandLine.getOptions();
|
||||||
|
|
||||||
@ -187,7 +222,6 @@ public class main {
|
|||||||
if (bcp != null && bcp.charAt(0) == ':') {
|
if (bcp != null && bcp.charAt(0) == ':') {
|
||||||
options.addExtraClassPath(bcp);
|
options.addExtraClassPath(bcp);
|
||||||
} else {
|
} else {
|
||||||
setBootClassPath = true;
|
|
||||||
options.setBootClassPath(bcp);
|
options.setBootClassPath(bcp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -223,11 +257,11 @@ public class main {
|
|||||||
options.normalizeVirtualMethods = true;
|
options.normalizeVirtualMethods = true;
|
||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
disassemble = false;
|
options.disassemble = false;
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
doDump = true;
|
options.dump = true;
|
||||||
dumpFileName = commandLine.getOptionValue("D");
|
options.dumpFileName = commandLine.getOptionValue("D");
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
options.ignoreErrors = true;
|
options.ignoreErrors = true;
|
||||||
@ -245,11 +279,10 @@ public class main {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String inputDexFileName = remainingArgs[0];
|
String inputDexPath = remainingArgs[0];
|
||||||
|
File dexFileFile = new File(inputDexPath);
|
||||||
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 " + inputDexPath);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,6 +294,7 @@ public class main {
|
|||||||
System.err.println(String.format("%s contains multiple dex files. You must specify which one to " +
|
System.err.println(String.format("%s contains multiple dex files. You must specify which one to " +
|
||||||
"disassemble with the -e option", dexFileFile.getName()));
|
"disassemble with the -e option", dexFileFile.getName()));
|
||||||
System.err.println("Valid entries include:");
|
System.err.println("Valid entries include:");
|
||||||
|
|
||||||
for (OatDexFile oatDexFile: ex.oatFile.getDexFiles()) {
|
for (OatDexFile oatDexFile: ex.oatFile.getDexFiles()) {
|
||||||
System.err.println(oatDexFile.filename);
|
System.err.println(oatDexFile.filename);
|
||||||
}
|
}
|
||||||
@ -278,34 +312,18 @@ public class main {
|
|||||||
options.deodex = false;
|
options.deodex = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!setBootClassPath && (options.deodex || options.registerInfo != 0 || options.normalizeVirtualMethods)) {
|
if (options.dump) {
|
||||||
if (dexFile instanceof DexBackedOdexFile) {
|
if (options.dumpFileName == null) {
|
||||||
options.bootClassPathEntries = ((DexBackedOdexFile)dexFile).getDependencies();
|
options.dumpFileName = inputDexPath + ".dump";
|
||||||
} else {
|
|
||||||
options.bootClassPathEntries = getDefaultBootClassPathForApi(options.apiLevel,
|
|
||||||
options.experimental);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.customInlineDefinitions == null && dexFile instanceof DexBackedOdexFile) {
|
try {
|
||||||
options.inlineResolver =
|
if (!run(options, dexFile)) {
|
||||||
InlineMethodResolver.createInlineMethodResolver(
|
System.exit(1);
|
||||||
((DexBackedOdexFile)dexFile).getOdexVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean errorOccurred = false;
|
|
||||||
if (disassemble) {
|
|
||||||
errorOccurred = !baksmali.disassembleDexFile(dexFile, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doDump) {
|
|
||||||
if (dumpFileName == null) {
|
|
||||||
dumpFileName = commandLine.getOptionValue(inputDexFileName + ".dump");
|
|
||||||
}
|
}
|
||||||
dump.dump(dexFile, dumpFileName, options.apiLevel, options.experimental);
|
} catch (IllegalArgumentException ex) {
|
||||||
}
|
System.err.println(ex.getMessage());
|
||||||
|
|
||||||
if (errorOccurred) {
|
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
52
smali/src/main/java/org/jf/smali/SmaliOptions.java
Normal file
52
smali/src/main/java/org/jf/smali/SmaliOptions.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016, 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.smali;
|
||||||
|
|
||||||
|
public class SmaliOptions {
|
||||||
|
public int apiLevel = 15;
|
||||||
|
public String outputDexFile = "out.dex";
|
||||||
|
|
||||||
|
public int jobs = Runtime.getRuntime().availableProcessors();
|
||||||
|
public boolean allowOdex = false;
|
||||||
|
public boolean verboseErrors = false;
|
||||||
|
public boolean printTokens = false;
|
||||||
|
public boolean experimental = false;
|
||||||
|
|
||||||
|
public boolean listMethods = false;
|
||||||
|
public String methodListFilename = null;
|
||||||
|
|
||||||
|
public boolean listFields = false;
|
||||||
|
public String fieldListFilename = null;
|
||||||
|
|
||||||
|
public boolean listTypes = false;
|
||||||
|
public String typeListFilename = null;
|
||||||
|
}
|
@ -46,10 +46,7 @@ import org.jf.util.SmaliHelpFormatter;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class for smali. It recognizes enough options to be able to dispatch
|
* Main class for smali. It recognizes enough options to be able to dispatch
|
||||||
@ -92,6 +89,95 @@ public class main {
|
|||||||
private main() {
|
private main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A more programmatic-friendly entry point for smali
|
||||||
|
*
|
||||||
|
* @param options a SmaliOptions object with the options to run smali with
|
||||||
|
* @param input The files/directories to process
|
||||||
|
* @return true if assembly completed with no errors, or false if errors were encountered
|
||||||
|
*/
|
||||||
|
public static boolean run(final SmaliOptions options, String... input) throws IOException {
|
||||||
|
LinkedHashSet<File> filesToProcessSet = new LinkedHashSet<File>();
|
||||||
|
|
||||||
|
for (String fileToProcess: input) {
|
||||||
|
File argFile = new File(fileToProcess);
|
||||||
|
|
||||||
|
if (!argFile.exists()) {
|
||||||
|
throw new IllegalArgumentException("Cannot find file or directory \"" + fileToProcess + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argFile.isDirectory()) {
|
||||||
|
getSmaliFilesInDir(argFile, filesToProcessSet);
|
||||||
|
} else if (argFile.isFile()) {
|
||||||
|
filesToProcessSet.add(argFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean errors = false;
|
||||||
|
|
||||||
|
final DexBuilder dexBuilder = DexBuilder.makeDexBuilder(
|
||||||
|
Opcodes.forApi(options.apiLevel, options.experimental));
|
||||||
|
|
||||||
|
ExecutorService executor = Executors.newFixedThreadPool(options.jobs);
|
||||||
|
List<Future<Boolean>> tasks = Lists.newArrayList();
|
||||||
|
|
||||||
|
for (final File file: filesToProcessSet) {
|
||||||
|
tasks.add(executor.submit(new Callable<Boolean>() {
|
||||||
|
@Override public Boolean call() throws Exception {
|
||||||
|
return assembleSmaliFile(file, dexBuilder, options);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Future<Boolean> task: tasks) {
|
||||||
|
while(true) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
if (!task.get()) {
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
} catch (ExecutionException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
executor.shutdown();
|
||||||
|
|
||||||
|
if (errors) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.listMethods) {
|
||||||
|
if (Strings.isNullOrEmpty(options.methodListFilename)) {
|
||||||
|
options.methodListFilename = options.outputDexFile + ".methods";
|
||||||
|
}
|
||||||
|
writeReferences(dexBuilder.getMethodReferences(), options.methodListFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.listFields) {
|
||||||
|
if (Strings.isNullOrEmpty(options.fieldListFilename)) {
|
||||||
|
options.fieldListFilename = options.outputDexFile + ".fields";
|
||||||
|
}
|
||||||
|
writeReferences(dexBuilder.getFieldReferences(), options.fieldListFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.listTypes) {
|
||||||
|
if (Strings.isNullOrEmpty(options.typeListFilename)) {
|
||||||
|
options.typeListFilename = options.outputDexFile + ".types";
|
||||||
|
}
|
||||||
|
writeReferences(dexBuilder.getTypeReferences(), options.typeListFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
dexBuilder.writeTo(new FileDataStore(new File(options.outputDexFile)));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run!
|
* Run!
|
||||||
*/
|
*/
|
||||||
@ -109,24 +195,7 @@ public class main {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int jobs = Runtime.getRuntime().availableProcessors();
|
SmaliOptions smaliOptions = new SmaliOptions();
|
||||||
boolean allowOdex = false;
|
|
||||||
boolean verboseErrors = false;
|
|
||||||
boolean printTokens = false;
|
|
||||||
boolean experimental = false;
|
|
||||||
|
|
||||||
boolean listMethods = false;
|
|
||||||
String methodListFilename = null;
|
|
||||||
|
|
||||||
boolean listFields = false;
|
|
||||||
String fieldListFilename = null;
|
|
||||||
|
|
||||||
boolean listTypes = false;
|
|
||||||
String typeListFilename = null;
|
|
||||||
|
|
||||||
int apiLevel = 15;
|
|
||||||
|
|
||||||
String outputDexFile = "out.dex";
|
|
||||||
|
|
||||||
String[] remainingArgs = commandLine.getArgs();
|
String[] remainingArgs = commandLine.getArgs();
|
||||||
|
|
||||||
@ -150,37 +219,37 @@ public class main {
|
|||||||
usage(false);
|
usage(false);
|
||||||
return;
|
return;
|
||||||
case 'o':
|
case 'o':
|
||||||
outputDexFile = commandLine.getOptionValue("o");
|
smaliOptions.outputDexFile = commandLine.getOptionValue("o");
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
allowOdex = true;
|
smaliOptions.allowOdex = true;
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
experimental = true;
|
smaliOptions.experimental = true;
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
apiLevel = Integer.parseInt(commandLine.getOptionValue("a"));
|
smaliOptions.apiLevel = Integer.parseInt(commandLine.getOptionValue("a"));
|
||||||
break;
|
break;
|
||||||
case 'j':
|
case 'j':
|
||||||
jobs = Integer.parseInt(commandLine.getOptionValue("j"));
|
smaliOptions.jobs = Integer.parseInt(commandLine.getOptionValue("j"));
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
listMethods = true;
|
smaliOptions.listMethods = true;
|
||||||
methodListFilename = commandLine.getOptionValue("m");
|
smaliOptions.methodListFilename = commandLine.getOptionValue("m");
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
listFields = true;
|
smaliOptions.listFields = true;
|
||||||
fieldListFilename = commandLine.getOptionValue("f");
|
smaliOptions.fieldListFilename = commandLine.getOptionValue("f");
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
listTypes = true;
|
smaliOptions.listTypes = true;
|
||||||
typeListFilename = commandLine.getOptionValue("t");
|
smaliOptions.typeListFilename = commandLine.getOptionValue("t");
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
verboseErrors = true;
|
smaliOptions.verboseErrors = true;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
printTokens = true;
|
smaliOptions.printTokens = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert false;
|
assert false;
|
||||||
@ -193,84 +262,9 @@ public class main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LinkedHashSet<File> filesToProcess = new LinkedHashSet<File>();
|
if (!run(smaliOptions, remainingArgs)) {
|
||||||
|
|
||||||
for (String arg: remainingArgs) {
|
|
||||||
File argFile = new File(arg);
|
|
||||||
|
|
||||||
if (!argFile.exists()) {
|
|
||||||
throw new RuntimeException("Cannot find file or directory \"" + arg + "\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argFile.isDirectory()) {
|
|
||||||
getSmaliFilesInDir(argFile, filesToProcess);
|
|
||||||
} else if (argFile.isFile()) {
|
|
||||||
filesToProcess.add(argFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean errors = false;
|
|
||||||
|
|
||||||
final DexBuilder dexBuilder = DexBuilder.makeDexBuilder(Opcodes.forApi(apiLevel, experimental));
|
|
||||||
|
|
||||||
ExecutorService executor = Executors.newFixedThreadPool(jobs);
|
|
||||||
List<Future<Boolean>> tasks = Lists.newArrayList();
|
|
||||||
|
|
||||||
final boolean finalVerboseErrors = verboseErrors;
|
|
||||||
final boolean finalPrintTokens = printTokens;
|
|
||||||
final boolean finalAllowOdex = allowOdex;
|
|
||||||
final int finalApiLevel = apiLevel;
|
|
||||||
final boolean finalExperimental = experimental;
|
|
||||||
for (final File file: filesToProcess) {
|
|
||||||
tasks.add(executor.submit(new Callable<Boolean>() {
|
|
||||||
@Override public Boolean call() throws Exception {
|
|
||||||
return assembleSmaliFile(file, dexBuilder, finalVerboseErrors, finalPrintTokens,
|
|
||||||
finalAllowOdex, finalApiLevel, finalExperimental);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Future<Boolean> task: tasks) {
|
|
||||||
while(true) {
|
|
||||||
try {
|
|
||||||
if (!task.get()) {
|
|
||||||
errors = true;
|
|
||||||
}
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
executor.shutdown();
|
|
||||||
|
|
||||||
if (errors) {
|
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listMethods) {
|
|
||||||
if (Strings.isNullOrEmpty(methodListFilename)) {
|
|
||||||
methodListFilename = outputDexFile + ".methods";
|
|
||||||
}
|
|
||||||
writeReferences(dexBuilder.getMethodReferences(), methodListFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listFields) {
|
|
||||||
if (Strings.isNullOrEmpty(fieldListFilename)) {
|
|
||||||
fieldListFilename = outputDexFile + ".fields";
|
|
||||||
}
|
|
||||||
writeReferences(dexBuilder.getFieldReferences(), fieldListFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listTypes) {
|
|
||||||
if (Strings.isNullOrEmpty(typeListFilename)) {
|
|
||||||
typeListFilename = outputDexFile + ".types";
|
|
||||||
}
|
|
||||||
writeReferences(dexBuilder.getTypeReferences(), typeListFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
dexBuilder.writeTo(new FileDataStore(new File(outputDexFile)));
|
|
||||||
} catch (RuntimeException ex) {
|
} catch (RuntimeException ex) {
|
||||||
System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
|
System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
@ -312,9 +306,7 @@ public class main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean assembleSmaliFile(File smaliFile, DexBuilder dexBuilder, boolean verboseErrors,
|
private static boolean assembleSmaliFile(File smaliFile, DexBuilder dexBuilder, SmaliOptions options)
|
||||||
boolean printTokens, boolean allowOdex, int apiLevel,
|
|
||||||
boolean experimental)
|
|
||||||
throws Exception {
|
throws Exception {
|
||||||
CommonTokenStream tokens;
|
CommonTokenStream tokens;
|
||||||
|
|
||||||
@ -327,7 +319,7 @@ public class main {
|
|||||||
((smaliFlexLexer)lexer).setSourceFile(smaliFile);
|
((smaliFlexLexer)lexer).setSourceFile(smaliFile);
|
||||||
tokens = new CommonTokenStream((TokenSource)lexer);
|
tokens = new CommonTokenStream((TokenSource)lexer);
|
||||||
|
|
||||||
if (printTokens) {
|
if (options.printTokens) {
|
||||||
tokens.getTokens();
|
tokens.getTokens();
|
||||||
|
|
||||||
for (int i=0; i<tokens.size(); i++) {
|
for (int i=0; i<tokens.size(); i++) {
|
||||||
@ -343,9 +335,9 @@ public class main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
smaliParser parser = new smaliParser(tokens);
|
smaliParser parser = new smaliParser(tokens);
|
||||||
parser.setVerboseErrors(verboseErrors);
|
parser.setVerboseErrors(options.verboseErrors);
|
||||||
parser.setAllowOdex(allowOdex);
|
parser.setAllowOdex(options.allowOdex);
|
||||||
parser.setApiLevel(apiLevel, experimental);
|
parser.setApiLevel(options.apiLevel, options.experimental);
|
||||||
|
|
||||||
smaliParser.smali_file_return result = parser.smali_file();
|
smaliParser.smali_file_return result = parser.smali_file();
|
||||||
|
|
||||||
@ -358,14 +350,14 @@ public class main {
|
|||||||
CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t);
|
CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t);
|
||||||
treeStream.setTokenStream(tokens);
|
treeStream.setTokenStream(tokens);
|
||||||
|
|
||||||
if (printTokens) {
|
if (options.printTokens) {
|
||||||
System.out.println(t.toStringTree());
|
System.out.println(t.toStringTree());
|
||||||
}
|
}
|
||||||
|
|
||||||
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
|
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
|
||||||
dexGen.setApiLevel(apiLevel, experimental);
|
dexGen.setApiLevel(options.apiLevel, options.experimental);
|
||||||
|
|
||||||
dexGen.setVerboseErrors(verboseErrors);
|
dexGen.setVerboseErrors(options.verboseErrors);
|
||||||
dexGen.setDexBuilder(dexBuilder);
|
dexGen.setDexBuilder(dexBuilder);
|
||||||
dexGen.smali_file();
|
dexGen.smali_file();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user