mirror of
https://github.com/revanced/smali.git
synced 2025-06-13 04:27:38 +02:00
Exit on the first error by default, but add the -I option for ignoring errors and continuing with disassembly
git-svn-id: https://smali.googlecode.com/svn/trunk@701 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
@ -52,7 +52,7 @@ public class baksmali {
|
|||||||
String[] classPathDirs, String bootClassPath, String extraBootClassPath,
|
String[] classPathDirs, String bootClassPath, String extraBootClassPath,
|
||||||
boolean noParameterRegisters, boolean useLocalsDirective,
|
boolean noParameterRegisters, boolean useLocalsDirective,
|
||||||
boolean useSequentialLabels, boolean outputDebugInfo, boolean addCodeOffsets,
|
boolean useSequentialLabels, boolean outputDebugInfo, boolean addCodeOffsets,
|
||||||
int registerInfo, boolean verify)
|
int registerInfo, boolean verify, boolean ignoreErrors)
|
||||||
{
|
{
|
||||||
baksmali.noParameterRegisters = noParameterRegisters;
|
baksmali.noParameterRegisters = noParameterRegisters;
|
||||||
baksmali.useLocalsDirective = useLocalsDirective;
|
baksmali.useLocalsDirective = useLocalsDirective;
|
||||||
@ -64,6 +64,16 @@ public class baksmali {
|
|||||||
baksmali.bootClassPath = bootClassPath;
|
baksmali.bootClassPath = bootClassPath;
|
||||||
baksmali.verify = verify;
|
baksmali.verify = verify;
|
||||||
|
|
||||||
|
ClassPath.ClassPathErrorHandler classPathErrorHandler = null;
|
||||||
|
if (ignoreErrors) {
|
||||||
|
classPathErrorHandler = new ClassPath.ClassPathErrorHandler() {
|
||||||
|
public void ClassPathError(String className, Exception ex) {
|
||||||
|
System.err.println(String.format("Skipping %s", className));
|
||||||
|
ex.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (registerInfo != 0 || deodex || verify) {
|
if (registerInfo != 0 || deodex || verify) {
|
||||||
try {
|
try {
|
||||||
String[] extraBootClassPathArray = null;
|
String[] extraBootClassPathArray = null;
|
||||||
@ -80,14 +90,15 @@ public class baksmali {
|
|||||||
if (extraBootClassPathArray == null && isExtJar(dexFilePath)) {
|
if (extraBootClassPathArray == null && isExtJar(dexFilePath)) {
|
||||||
extraBootClassPathArray = new String[] {"framework.jar"};
|
extraBootClassPathArray = new String[] {"framework.jar"};
|
||||||
}
|
}
|
||||||
ClassPath.InitializeClassPathFromOdex(classPathDirs, extraBootClassPathArray, dexFilePath, dexFile);
|
ClassPath.InitializeClassPathFromOdex(classPathDirs, extraBootClassPathArray, dexFilePath, dexFile,
|
||||||
|
classPathErrorHandler);
|
||||||
} else {
|
} else {
|
||||||
String[] bootClassPathArray = null;
|
String[] bootClassPathArray = null;
|
||||||
if (bootClassPath != null) {
|
if (bootClassPath != null) {
|
||||||
bootClassPathArray = bootClassPath.split(":");
|
bootClassPathArray = bootClassPath.split(":");
|
||||||
}
|
}
|
||||||
ClassPath.InitializeClassPath(classPathDirs, bootClassPathArray, extraBootClassPathArray,
|
ClassPath.InitializeClassPath(classPathDirs, bootClassPathArray, extraBootClassPathArray,
|
||||||
dexFilePath, dexFile);
|
dexFilePath, dexFile, classPathErrorHandler);
|
||||||
}
|
}
|
||||||
} 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.");
|
||||||
@ -189,6 +200,10 @@ public class baksmali {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ignoreErrors && classDefinition.hadValidationErrors()) {
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ public class deodexCheck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClassPath.InitializeClassPath(bootClassPathDirsArray, bootClassPath==null?null:bootClassPath.split(":"), null,
|
ClassPath.InitializeClassPath(bootClassPathDirsArray, bootClassPath==null?null:bootClassPath.split(":"), null,
|
||||||
null, null);
|
null, null, null);
|
||||||
|
|
||||||
ClassPath.validateAgainstDeodexerant(deodexerantHost, deodexerantPort, classStartIndex);
|
ClassPath.validateAgainstDeodexerant(deodexerantHost, deodexerantPort, classStartIndex);
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,7 @@ public class main {
|
|||||||
boolean addCodeOffsets = false;
|
boolean addCodeOffsets = false;
|
||||||
boolean deodex = false;
|
boolean deodex = false;
|
||||||
boolean verify = false;
|
boolean verify = false;
|
||||||
|
boolean ignoreErrors = false;
|
||||||
|
|
||||||
int registerInfo = 0;
|
int registerInfo = 0;
|
||||||
|
|
||||||
@ -209,6 +210,9 @@ public class main {
|
|||||||
doDump = true;
|
doDump = true;
|
||||||
dumpFileName = commandLine.getOptionValue("D", inputDexFileName + ".dump");
|
dumpFileName = commandLine.getOptionValue("D", inputDexFileName + ".dump");
|
||||||
break;
|
break;
|
||||||
|
case 'I':
|
||||||
|
ignoreErrors = true;
|
||||||
|
break;
|
||||||
case 'W':
|
case 'W':
|
||||||
write = true;
|
write = true;
|
||||||
outputDexFileName = commandLine.getOptionValue("W");
|
outputDexFileName = commandLine.getOptionValue("W");
|
||||||
@ -273,7 +277,7 @@ public class main {
|
|||||||
baksmali.disassembleDexFile(dexFileFile.getPath(), dexFile, deodex, outputDirectory,
|
baksmali.disassembleDexFile(dexFileFile.getPath(), dexFile, deodex, outputDirectory,
|
||||||
bootClassPathDirsArray, bootClassPath, extraBootClassPathEntries.toString(),
|
bootClassPathDirsArray, bootClassPath, extraBootClassPathEntries.toString(),
|
||||||
noParameterRegisters, useLocalsDirective, useSequentialLabels, outputDebugInfo, addCodeOffsets,
|
noParameterRegisters, useLocalsDirective, useSequentialLabels, outputDebugInfo, addCodeOffsets,
|
||||||
registerInfo, verify);
|
registerInfo, verify, ignoreErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((doDump || write) && !dexFile.isOdex()) {
|
if ((doDump || write) && !dexFile.isOdex()) {
|
||||||
@ -411,6 +415,12 @@ public class main {
|
|||||||
.withArgName("FILE")
|
.withArgName("FILE")
|
||||||
.create("D");
|
.create("D");
|
||||||
|
|
||||||
|
Option ignoreErrorsOption = OptionBuilder.withLongOpt("ignore-errors")
|
||||||
|
.withDescription("ignores any non-fatal errors that occur while disassembling/deodexing," +
|
||||||
|
" ignoring the class if needed, and continuing with the next class. The default" +
|
||||||
|
" behavior is to stop disassembling and exit once an error is encountered")
|
||||||
|
.create("I");
|
||||||
|
|
||||||
Option noDisassemblyOption = OptionBuilder.withLongOpt("no-disassembly")
|
Option noDisassemblyOption = OptionBuilder.withLongOpt("no-disassembly")
|
||||||
.withDescription("suppresses the output of the disassembly")
|
.withDescription("suppresses the output of the disassembly")
|
||||||
.create("N");
|
.create("N");
|
||||||
@ -448,6 +458,7 @@ public class main {
|
|||||||
basicOptions.addOption(codeOffsetOption);
|
basicOptions.addOption(codeOffsetOption);
|
||||||
|
|
||||||
debugOptions.addOption(dumpOption);
|
debugOptions.addOption(dumpOption);
|
||||||
|
debugOptions.addOption(ignoreErrorsOption);
|
||||||
debugOptions.addOption(noDisassemblyOption);
|
debugOptions.addOption(noDisassemblyOption);
|
||||||
debugOptions.addOption(writeDexOption);
|
debugOptions.addOption(writeDexOption);
|
||||||
debugOptions.addOption(sortOption);
|
debugOptions.addOption(sortOption);
|
||||||
|
@ -53,6 +53,11 @@ public class ClassPath {
|
|||||||
|
|
||||||
private static final Pattern dalvikCacheOdexPattern = Pattern.compile("@([^@]+)@classes.dex$");
|
private static final Pattern dalvikCacheOdexPattern = Pattern.compile("@([^@]+)@classes.dex$");
|
||||||
|
|
||||||
|
|
||||||
|
public static interface ClassPathErrorHandler {
|
||||||
|
void ClassPathError(String className, Exception ex);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the class path using the dependencies from an odex file
|
* Initialize the class path using the dependencies from an odex file
|
||||||
* @param classPathDirs The directories to search for boot class path files
|
* @param classPathDirs The directories to search for boot class path files
|
||||||
@ -60,9 +65,12 @@ public class ClassPath {
|
|||||||
* from the odex file
|
* from the odex file
|
||||||
* @param dexFilePath The path of the dex file (used for error reporting purposes only)
|
* @param dexFilePath The path of the dex file (used for error reporting purposes only)
|
||||||
* @param dexFile The DexFile to load - it must represents an odex file
|
* @param dexFile The DexFile to load - it must represents an odex file
|
||||||
|
* @param errorHandler a ClassPathErrorHandler object to receive and handle any errors that occur while loading
|
||||||
|
* classes
|
||||||
*/
|
*/
|
||||||
public static void InitializeClassPathFromOdex(String[] classPathDirs, String[] extraBootClassPathEntries,
|
public static void InitializeClassPathFromOdex(String[] classPathDirs, String[] extraBootClassPathEntries,
|
||||||
String dexFilePath, DexFile dexFile) {
|
String dexFilePath, DexFile dexFile,
|
||||||
|
ClassPathErrorHandler errorHandler) {
|
||||||
if (!dexFile.isOdex()) {
|
if (!dexFile.isOdex()) {
|
||||||
throw new ExceptionWithContext("Cannot use InitialiazeClassPathFromOdex with a non-odex DexFile");
|
throw new ExceptionWithContext("Cannot use InitialiazeClassPathFromOdex with a non-odex DexFile");
|
||||||
}
|
}
|
||||||
@ -99,7 +107,8 @@ public class ClassPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
theClassPath = new ClassPath();
|
theClassPath = new ClassPath();
|
||||||
theClassPath.initClassPath(classPathDirs, bootClassPath, extraBootClassPathEntries, dexFilePath, dexFile);
|
theClassPath.initClassPath(classPathDirs, bootClassPath, extraBootClassPathEntries, dexFilePath, dexFile,
|
||||||
|
errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,15 +117,19 @@ public class ClassPath {
|
|||||||
* @param bootClassPath A list of the boot class path entries to search for and load
|
* @param bootClassPath A list of the boot class path entries to search for and load
|
||||||
* @param dexFilePath The path of the dex file (used for error reporting purposes only)
|
* @param dexFilePath The path of the dex file (used for error reporting purposes only)
|
||||||
* @param dexFile the DexFile to load
|
* @param dexFile the DexFile to load
|
||||||
|
* @param errorHandler a ClassPathErrorHandler object to receive and handle any errors that occur while loading
|
||||||
|
* classes
|
||||||
*/
|
*/
|
||||||
public static void InitializeClassPath(String[] classPathDirs, String[] bootClassPath,
|
public static void InitializeClassPath(String[] classPathDirs, String[] bootClassPath,
|
||||||
String[] extraBootClassPathEntries, String dexFilePath, DexFile dexFile) {
|
String[] extraBootClassPathEntries, String dexFilePath, DexFile dexFile,
|
||||||
|
ClassPathErrorHandler errorHandler) {
|
||||||
if (theClassPath != null) {
|
if (theClassPath != null) {
|
||||||
throw new ExceptionWithContext("Cannot initialize ClassPath multiple times");
|
throw new ExceptionWithContext("Cannot initialize ClassPath multiple times");
|
||||||
}
|
}
|
||||||
|
|
||||||
theClassPath = new ClassPath();
|
theClassPath = new ClassPath();
|
||||||
theClassPath.initClassPath(classPathDirs, bootClassPath, extraBootClassPathEntries, dexFilePath, dexFile);
|
theClassPath.initClassPath(classPathDirs, bootClassPath, extraBootClassPathEntries, dexFilePath, dexFile,
|
||||||
|
errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassPath() {
|
private ClassPath() {
|
||||||
@ -124,7 +137,7 @@ public class ClassPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initClassPath(String[] classPathDirs, String[] bootClassPath, String[] extraBootClassPathEntries,
|
private void initClassPath(String[] classPathDirs, String[] bootClassPath, String[] extraBootClassPathEntries,
|
||||||
String dexFilePath, DexFile dexFile) {
|
String dexFilePath, DexFile dexFile, ClassPathErrorHandler errorHandler) {
|
||||||
tempClasses = new LinkedHashMap<String, TempClassInfo>();
|
tempClasses = new LinkedHashMap<String, TempClassInfo>();
|
||||||
|
|
||||||
if (bootClassPath != null) {
|
if (bootClassPath != null) {
|
||||||
@ -150,8 +163,12 @@ public class ClassPath {
|
|||||||
classDef = ClassPath.loadClassDef(classType);
|
classDef = ClassPath.loadClassDef(classType);
|
||||||
assert classDef != null;
|
assert classDef != null;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
System.err.println(String.format("Skipping %s", classType));
|
if (errorHandler != null) {
|
||||||
ex.printStackTrace(System.err);
|
errorHandler.ClassPathError(classType, ex);
|
||||||
|
} else {
|
||||||
|
throw ExceptionWithContext.withContext(ex,
|
||||||
|
String.format("Error while loading ClassPath class %s", classType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classType.equals("Ljava/lang/Object;")) {
|
if (classType.equals("Ljava/lang/Object;")) {
|
||||||
|
Reference in New Issue
Block a user