mirror of
https://github.com/revanced/smali.git
synced 2025-05-30 04:30:13 +02:00
Significant rewrite of the command line interface, using apache commons CLI
git-svn-id: https://smali.googlecode.com/svn/trunk@216 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
44682fe235
commit
2cd9246976
@ -78,5 +78,10 @@
|
|||||||
<artifactId>dexlib</artifactId>
|
<artifactId>dexlib</artifactId>
|
||||||
<version>0.91-SNAPSHOT</version>
|
<version>0.91-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-cli</groupId>
|
||||||
|
<artifactId>commons-cli</artifactId>
|
||||||
|
<version>1.2</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jf.smali;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple exception class used to communicate that the command-line tool
|
|
||||||
* should print the usage message.
|
|
||||||
*/
|
|
||||||
public class UsageException extends RuntimeException {
|
|
||||||
// This space intentionally left blank.
|
|
||||||
}
|
|
@ -16,71 +16,158 @@
|
|||||||
|
|
||||||
package org.jf.smali;
|
package org.jf.smali;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.*;
|
||||||
|
import org.jf.dexlib.DexFile;
|
||||||
|
import org.jf.dexlib.Util.ByteArrayAnnotatedOutput;
|
||||||
|
import org.antlr.runtime.ANTLRInputStream;
|
||||||
|
import org.antlr.runtime.CommonTokenStream;
|
||||||
|
import org.antlr.runtime.tree.CommonTree;
|
||||||
|
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
* to the right "actual" main.
|
* to the right "actual" main.
|
||||||
*/
|
*/
|
||||||
public class main {
|
public class main {
|
||||||
|
|
||||||
public static final String VERSION = "0.5b";
|
public static final String VERSION = "0.91";
|
||||||
|
|
||||||
|
private final static Options options;
|
||||||
|
|
||||||
|
static {
|
||||||
|
options = new Options();
|
||||||
|
buildOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static String USAGE_MESSAGE =
|
|
||||||
"usage:\n" +
|
|
||||||
" java -jar smali.jar --dex [--output=<file>]\n" +
|
|
||||||
" [--dump-to=<file>] [--dump-width=<width>]\n" +
|
|
||||||
" [--] [<file> | <dir> | -]+\n" +
|
|
||||||
" Convert a set of smali assembly files into a dex file.\n" +
|
|
||||||
" <file> - assemble the specified smali file\n" +
|
|
||||||
" <dir> - recusively find and assemble all *.smali files in\n" +
|
|
||||||
" the specified directory\n"+
|
|
||||||
" - - additionally read a list of files and directories\n" +
|
|
||||||
" from stdin\n" +
|
|
||||||
" java -jar smali.jar --version\n" +
|
|
||||||
" Print the version of this tool (" + VERSION +
|
|
||||||
").\n" +
|
|
||||||
" java -jar smali.jar --help\n" +
|
|
||||||
" Print this message.";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is uninstantiable.
|
* This class is uninstantiable.
|
||||||
*/
|
*/
|
||||||
private main() {
|
private main() {
|
||||||
// This space intentionally left blank.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run!
|
* Run!
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
boolean gotCmd = false;
|
CommandLineParser parser = new PosixParser();
|
||||||
boolean showUsage = false;
|
CommandLine commandLine;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < args.length; i++) {
|
commandLine = parser.parse(options, args);
|
||||||
String arg = args[i];
|
} catch (ParseException ex) {
|
||||||
if (arg.equals("--") || !arg.startsWith("--")) {
|
usage();
|
||||||
gotCmd = false;
|
return;
|
||||||
showUsage = true;
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
gotCmd = true;
|
boolean doDump = false;
|
||||||
if (arg.equals("--dex")) {
|
boolean sort = false;
|
||||||
smali.main(without(args, i));
|
|
||||||
break;
|
String outputDexFile = "out.dex";
|
||||||
} else if (arg.equals("--version")) {
|
String dumpFileName = null;
|
||||||
version();
|
|
||||||
break;
|
String[] remainingArgs = commandLine.getArgs();
|
||||||
} else if (arg.equals("--help")) {
|
|
||||||
showUsage = true;
|
if (commandLine.hasOption("v")) {
|
||||||
break;
|
version();
|
||||||
} else {
|
return;
|
||||||
gotCmd = false;
|
}
|
||||||
|
|
||||||
|
if (commandLine.hasOption("?")) {
|
||||||
|
usage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remainingArgs.length == 0) {
|
||||||
|
usage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commandLine.hasOption("o")) {
|
||||||
|
outputDexFile = commandLine.getOptionValue("o");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commandLine.hasOption("d")) {
|
||||||
|
doDump = true;
|
||||||
|
dumpFileName = commandLine.getOptionValue("d", outputDexFile + ".dump");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commandLine.hasOption("s")) {
|
||||||
|
sort = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
LinkedHashSet<File> filesToProcess = new LinkedHashSet<File>();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DexFile dexFile = new DexFile();
|
||||||
|
|
||||||
|
boolean errors = false;
|
||||||
|
|
||||||
|
for (File file: filesToProcess) {
|
||||||
|
if (!assembleSmaliFile(file, dexFile)) {
|
||||||
|
errors = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (UsageException ex) {
|
|
||||||
showUsage = true;
|
if (errors) {
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (sort) {
|
||||||
|
dexFile.setSortAllItems(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
dexFile.place();
|
||||||
|
|
||||||
|
ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
|
||||||
|
|
||||||
|
if (dumpFileName != null) {
|
||||||
|
out.enableAnnotations(120, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
dexFile.writeTo(out);
|
||||||
|
|
||||||
|
byte[] bytes = out.toByteArray();
|
||||||
|
|
||||||
|
DexFile.calcSignature(bytes);
|
||||||
|
DexFile.calcChecksum(bytes);
|
||||||
|
|
||||||
|
if (dumpFileName != null) {
|
||||||
|
out.finishAnnotating();
|
||||||
|
|
||||||
|
FileWriter fileWriter = new FileWriter(dumpFileName);
|
||||||
|
out.writeAnnotationsTo(fileWriter);
|
||||||
|
fileWriter.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileOutputStream fileOutputStream = new FileOutputStream(outputDexFile);
|
||||||
|
|
||||||
|
fileOutputStream.write(bytes);
|
||||||
|
fileOutputStream.close();
|
||||||
} catch (RuntimeException ex) {
|
} catch (RuntimeException ex) {
|
||||||
System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
|
System.err.println("\nUNEXPECTED TOP-LEVEL EXCEPTION:");
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
@ -90,46 +177,104 @@ public class main {
|
|||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
System.exit(3);
|
System.exit(3);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!gotCmd) {
|
|
||||||
System.err.println("error: no command specified");
|
private static void getSmaliFilesInDir(File dir, Set<File> smaliFiles) {
|
||||||
showUsage = true;
|
for(File file: dir.listFiles()) {
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
getSmaliFilesInDir(file, smaliFiles);
|
||||||
|
} else if (file.getName().endsWith(".smali")) {
|
||||||
|
smaliFiles.add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean assembleSmaliFile(File smaliFile, DexFile dexFile)
|
||||||
|
throws Exception {
|
||||||
|
ANTLRInputStream input = new ANTLRInputStream(new FileInputStream(smaliFile));
|
||||||
|
input.name = smaliFile.getAbsolutePath();
|
||||||
|
|
||||||
|
smaliLexer lexer = new smaliLexer(input);
|
||||||
|
|
||||||
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
|
smaliParser parser = new smaliParser(tokens);
|
||||||
|
|
||||||
|
smaliParser.smali_file_return result = parser.smali_file();
|
||||||
|
|
||||||
|
if (parser.getNumberOfSyntaxErrors() > 0 || lexer.getNumberOfLexerErrors() > 0) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showUsage) {
|
CommonTree t = (CommonTree) result.getTree();
|
||||||
usage();
|
|
||||||
System.exit(1);
|
CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t);
|
||||||
|
treeStream.setTokenStream(tokens);
|
||||||
|
|
||||||
|
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
|
||||||
|
|
||||||
|
dexGen.dexFile = dexFile;
|
||||||
|
dexGen.smali_file();
|
||||||
|
|
||||||
|
if (dexGen.getNumberOfSyntaxErrors() > 0) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dexFile.ClassDefsSection.intern(dexGen.classDefItem);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the usage message.
|
||||||
|
*/
|
||||||
|
private static void usage() {
|
||||||
|
HelpFormatter formatter = new HelpFormatter();
|
||||||
|
formatter.printHelp("java -jar smali.jar [options] [--] [<smali-file>|folder]*",
|
||||||
|
"assembles a set of smali files into a dex file, and optionally generats an annotated dump of the output file", options, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints the version message.
|
* Prints the version message.
|
||||||
*/
|
*/
|
||||||
private static void version() {
|
private static void version() {
|
||||||
System.err.println("smali version " + VERSION);
|
System.out.println("smali " + VERSION + " (http://smali.googlecode.com)");
|
||||||
|
System.out.println("Copyright (C) 2009 Ben Gruver");
|
||||||
|
System.out.println("BSD license (http://www.opensource.org/licenses/bsd-license.php)");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints the usage message.
|
|
||||||
*/
|
|
||||||
private static void usage() {
|
|
||||||
System.err.println(USAGE_MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
private static void buildOptions() {
|
||||||
* Returns a copy of the given args array, but without the indicated
|
Option versionOption = OptionBuilder.withLongOpt("version")
|
||||||
* element.
|
.withDescription("prints the version then exits")
|
||||||
*
|
.create("v");
|
||||||
* @param orig non-null; original array
|
|
||||||
* @param n which element to omit
|
Option helpOption = OptionBuilder.withLongOpt("help")
|
||||||
* @return non-null; new array
|
.withDescription("prints the help message then exits")
|
||||||
*/
|
.create("?");
|
||||||
private static String[] without(String[] orig, int n) {
|
|
||||||
int len = orig.length - 1;
|
Option dumpOption = OptionBuilder.withLongOpt("dump-to")
|
||||||
String[] newa = new String[len];
|
.withDescription("additionally writes a dump of written dex file to FILE (<dexfile>.dump by default)")
|
||||||
System.arraycopy(orig, 0, newa, 0, n);
|
.hasOptionalArg()
|
||||||
System.arraycopy(orig, n + 1, newa, n, len - n);
|
.withArgName("FILE")
|
||||||
return newa;
|
.create("d");
|
||||||
|
|
||||||
|
Option outputOption = OptionBuilder.withLongOpt("output")
|
||||||
|
.withDescription("the directory where the disassembled files will be placed. The default is out.dex")
|
||||||
|
.hasArg()
|
||||||
|
.withArgName("FILE")
|
||||||
|
.create("o");
|
||||||
|
|
||||||
|
Option sortOption = OptionBuilder.withLongOpt("sort")
|
||||||
|
.withDescription("sort the items in the dex file into a canonical order before writing")
|
||||||
|
.create("s");
|
||||||
|
|
||||||
|
options.addOption(versionOption);
|
||||||
|
options.addOption(helpOption);
|
||||||
|
options.addOption(dumpOption);
|
||||||
|
options.addOption(outputOption);
|
||||||
|
options.addOption(sortOption);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,209 +0,0 @@
|
|||||||
/*
|
|
||||||
* [The "BSD licence"]
|
|
||||||
* Copyright (c) 2009 Ben Gruver
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. 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.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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;
|
|
||||||
|
|
||||||
import org.antlr.runtime.ANTLRInputStream;
|
|
||||||
import org.antlr.runtime.CommonTokenStream;
|
|
||||||
import org.antlr.runtime.tree.CommonTree;
|
|
||||||
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
|
||||||
import org.jf.dexlib.DexFile;
|
|
||||||
import org.jf.dexlib.AnnotationItem;
|
|
||||||
import org.jf.dexlib.Util.ByteArrayAnnotatedOutput;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class smali
|
|
||||||
{
|
|
||||||
public static void main(String[] args) throws Exception
|
|
||||||
{
|
|
||||||
LinkedHashSet<File> filesToProcess = new LinkedHashSet<File>();
|
|
||||||
|
|
||||||
boolean getFilesFromStdin = false;
|
|
||||||
String outputFilename = "classes.dex";
|
|
||||||
String dumpFilename = null;
|
|
||||||
int dumpWidth = 120;
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i<args.length; i++) {
|
|
||||||
String arg = args[i];
|
|
||||||
if (arg.equals("--") || !arg.startsWith("--")) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (arg.startsWith("--output=")) {
|
|
||||||
outputFilename = arg.substring(arg.indexOf('=') + 1);
|
|
||||||
} else if (arg.startsWith("--dump-to=")) {
|
|
||||||
dumpFilename = arg.substring(arg.indexOf("=") + 1);
|
|
||||||
} else if (arg.startsWith("--dump-width=")) {
|
|
||||||
dumpWidth = Integer.parseInt(arg.substring(arg.indexOf("=") + 1));
|
|
||||||
} else {
|
|
||||||
System.err.println("unknown option: " + arg);
|
|
||||||
throw new UsageException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=i; i<args.length; i++) {
|
|
||||||
String arg = args[i];
|
|
||||||
|
|
||||||
if (arg.compareTo("-") == 0) {
|
|
||||||
getFilesFromStdin = true;
|
|
||||||
} else {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getFilesFromStdin) {
|
|
||||||
InputStreamReader isr = new InputStreamReader(System.in);
|
|
||||||
BufferedReader in = new BufferedReader(isr);
|
|
||||||
|
|
||||||
String line = in.readLine();
|
|
||||||
while (line != null) {
|
|
||||||
File file = new File(line);
|
|
||||||
|
|
||||||
if (!file.exists()) {
|
|
||||||
throw new RuntimeException("Cannot find file or directory \"" + line + "\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.isDirectory()) {
|
|
||||||
getSmaliFilesInDir(file, filesToProcess);
|
|
||||||
} else {
|
|
||||||
filesToProcess.add(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
line = in.readLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DexFile dexFile = DexFile.makeBlankDexFile();
|
|
||||||
|
|
||||||
boolean errors = false;
|
|
||||||
|
|
||||||
for (File file: filesToProcess) {
|
|
||||||
if (!assembleSmaliFile(file, dexFile)) {
|
|
||||||
errors = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errors) {
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
dexFile.place(false);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ByteArrayAnnotatedOutput out = new ByteArrayAnnotatedOutput();
|
|
||||||
|
|
||||||
if (dumpFilename != null) {
|
|
||||||
out.enableAnnotations(dumpWidth, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
dexFile.writeTo(out);
|
|
||||||
|
|
||||||
byte[] bytes = out.toByteArray();
|
|
||||||
|
|
||||||
DexFile.calcSignature(bytes);
|
|
||||||
DexFile.calcChecksum(bytes);
|
|
||||||
|
|
||||||
if (dumpFilename != null) {
|
|
||||||
out.finishAnnotating();
|
|
||||||
|
|
||||||
FileWriter fileWriter = new FileWriter(dumpFilename);
|
|
||||||
out.writeAnnotationsTo(fileWriter);
|
|
||||||
fileWriter.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
FileOutputStream fileOutputStream = new FileOutputStream(outputFilename);
|
|
||||||
|
|
||||||
fileOutputStream.write(bytes);
|
|
||||||
fileOutputStream.close();
|
|
||||||
} catch (Exception ex)
|
|
||||||
{
|
|
||||||
System.out.println(ex.toString());
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void getSmaliFilesInDir(File dir, Set<File> smaliFiles) {
|
|
||||||
for(File file: dir.listFiles()) {
|
|
||||||
if (file.isDirectory()) {
|
|
||||||
getSmaliFilesInDir(file, smaliFiles);
|
|
||||||
} else if (file.getName().endsWith(".smali")) {
|
|
||||||
smaliFiles.add(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean assembleSmaliFile(File smaliFile, DexFile dexFile)
|
|
||||||
throws Exception {
|
|
||||||
ANTLRInputStream input = new ANTLRInputStream(new FileInputStream(smaliFile));
|
|
||||||
input.name = smaliFile.getAbsolutePath();
|
|
||||||
|
|
||||||
smaliLexer lexer = new smaliLexer(input);
|
|
||||||
|
|
||||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
|
||||||
smaliParser parser = new smaliParser(tokens);
|
|
||||||
|
|
||||||
smaliParser.smali_file_return result = parser.smali_file();
|
|
||||||
|
|
||||||
if (parser.getNumberOfSyntaxErrors() > 0 || lexer.getNumberOfLexerErrors() > 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CommonTree t = (CommonTree) result.getTree();
|
|
||||||
|
|
||||||
CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t);
|
|
||||||
treeStream.setTokenStream(tokens);
|
|
||||||
|
|
||||||
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
|
|
||||||
|
|
||||||
dexGen.dexFile = dexFile;
|
|
||||||
dexGen.smali_file();
|
|
||||||
|
|
||||||
if (dexGen.getNumberOfSyntaxErrors() > 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dexFile.ClassDefsSection.intern(dexFile, dexGen.classDefItem);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user