Allow multiple class path directories to be specified

git-svn-id: https://smali.googlecode.com/svn/trunk@639 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2010-02-22 07:01:40 +00:00
parent e9b722eab0
commit 819e8b92a0
4 changed files with 54 additions and 33 deletions

View File

@ -50,7 +50,7 @@ public class baksmali {
public static String bootClassPath; public static String bootClassPath;
public static void disassembleDexFile(DexFile dexFile, boolean deodex, String outputDirectory, public static void disassembleDexFile(DexFile dexFile, boolean deodex, String outputDirectory,
String bootClassPathDir, String bootClassPath, boolean noParameterRegisters, String[] classPathDirs, String bootClassPath, boolean noParameterRegisters,
boolean useLocalsDirective, boolean useSequentialLabels, boolean useLocalsDirective, boolean useSequentialLabels,
boolean outputDebugInfo, boolean addCodeOffsets, int registerInfo) boolean outputDebugInfo, boolean addCodeOffsets, int registerInfo)
{ {
@ -65,7 +65,7 @@ public class baksmali {
if (registerInfo != 0 || deodex) { if (registerInfo != 0 || deodex) {
try { try {
ClassPath.InitializeClassPath(bootClassPathDir, bootClassPath==null?null:bootClassPath.split(":"), dexFile); ClassPath.InitializeClassPath(classPathDirs, bootClassPath==null?null:bootClassPath.split(":"), dexFile);
} 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);

View File

@ -3,6 +3,9 @@ package org.jf.baksmali;
import org.apache.commons.cli.*; import org.apache.commons.cli.*;
import org.jf.dexlib.Code.Analysis.ClassPath; import org.jf.dexlib.Code.Analysis.ClassPath;
import java.util.ArrayList;
import java.util.List;
public class deodexCheck { public class deodexCheck {
public static void main(String[] args) { public static void main(String[] args) {
CommandLineParser parser = new PosixParser(); CommandLineParser parser = new PosixParser();
@ -18,7 +21,8 @@ public class deodexCheck {
} }
String bootClassPath = "core.jar:ext.jar:framework.jar:android.policy.jar:services.jar"; String bootClassPath = "core.jar:ext.jar:framework.jar:android.policy.jar:services.jar";
String bootClassPathDir = "."; List<String> bootClassPathDirs = new ArrayList<String>();
bootClassPathDirs.add(".");
String deodexerantHost = null; String deodexerantHost = null;
int deodexerantPort = 0; int deodexerantPort = 0;
int classStartIndex = 0; int classStartIndex = 0;
@ -59,8 +63,8 @@ public class deodexCheck {
} }
} }
if (commandLine.hasOption("C")) { if (commandLine.hasOption("d")) {
bootClassPathDir = commandLine.getOptionValue("C"); bootClassPathDirs.add(commandLine.getOptionValue("d"));
} }
if (commandLine.hasOption("x")) { if (commandLine.hasOption("x")) {
@ -83,7 +87,12 @@ public class deodexCheck {
} }
} }
ClassPath.InitializeClassPath(bootClassPathDir, bootClassPath==null?null:bootClassPath.split(":"), null); String[] bootClassPathDirsArray = new String[bootClassPathDirs.size()];
for (int i=0; i<bootClassPathDirsArray.length; i++) {
bootClassPathDirsArray[i] = bootClassPathDirs.get(i);
}
ClassPath.InitializeClassPath(bootClassPathDirsArray, bootClassPath==null?null:bootClassPath.split(":"), null);
ClassPath.validateAgainstDeodexerant(deodexerantHost, deodexerantPort, classStartIndex); ClassPath.validateAgainstDeodexerant(deodexerantHost, deodexerantPort, classStartIndex);
} }
@ -119,10 +128,10 @@ public class deodexCheck {
Option classPathDirOption = OptionBuilder.withLongOpt("bootclasspath-dir") Option classPathDirOption = OptionBuilder.withLongOpt("bootclasspath-dir")
.withDescription("the base folder to look for the bootclasspath files in. Defaults to the current " + .withDescription("the base folder to look for the bootclasspath files in. Defaults to the current " +
"directory") "directory.")
.hasArg() .hasArg()
.withArgName("DIR") .withArgName("DIR")
.create("C"); .create("d");
Option deodexerantOption = OptionBuilder.withLongOpt("deodexerant") Option deodexerantOption = OptionBuilder.withLongOpt("deodexerant")
.isRequired() .isRequired()

View File

@ -22,6 +22,8 @@ import org.jf.dexlib.DexFile;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties; import java.util.Properties;
public class main { public class main {
@ -96,7 +98,8 @@ public class main {
String outputDexFileName = null; String outputDexFileName = null;
String inputDexFileName = null; String inputDexFileName = null;
String bootClassPath = "core.jar:ext.jar:framework.jar:android.policy.jar:services.jar"; String bootClassPath = "core.jar:ext.jar:framework.jar:android.policy.jar:services.jar";
String bootClassPathDir = "."; List<String> bootClassPathDirs = new ArrayList<String>();
bootClassPathDirs.add(".");
String[] remainingArgs = commandLine.getArgs(); String[] remainingArgs = commandLine.getArgs();
@ -136,7 +139,7 @@ public class main {
outputDebugInfo = false; outputDebugInfo = false;
break; break;
case 'd': case 'd':
bootClassPathDir = commandLine.getOptionValue("d"); bootClassPathDirs.add(option.getValue());
break; break;
case 'f': case 'f':
addCodeOffsets = true; addCodeOffsets = true;
@ -240,7 +243,12 @@ public class main {
} }
if (disassemble) { if (disassemble) {
baksmali.disassembleDexFile(dexFile, deodex, outputDirectory, bootClassPathDir, bootClassPath, String[] bootClassPathDirsArray = new String[bootClassPathDirs.size()];
for (int i=0; i<bootClassPathDirsArray.length; i++) {
bootClassPathDirsArray[i] = bootClassPathDirs.get(i);
}
baksmali.disassembleDexFile(dexFile, deodex, outputDirectory, bootClassPathDirsArray, bootClassPath,
noParameterRegisters, useLocalsDirective, useSequentialLabels, outputDebugInfo, addCodeOffsets, noParameterRegisters, useLocalsDirective, useSequentialLabels, outputDebugInfo, addCodeOffsets,
registerInfo); registerInfo);
} }

View File

@ -17,23 +17,23 @@ public class ClassPath {
private final HashMap<String, ClassDef> classDefs; private final HashMap<String, ClassDef> classDefs;
protected ClassDef javaLangObjectClassDef; //Ljava/lang/Object; protected ClassDef javaLangObjectClassDef; //Ljava/lang/Object;
public static void InitializeClassPath(String bootClassPathDir, String[] bootClassPath, DexFile dexFile) { public static void InitializeClassPath(String[] classPathDirs, String[] bootClassPath, DexFile dexFile) {
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(bootClassPathDir, bootClassPath, dexFile); theClassPath.initClassPath(classPathDirs, bootClassPath, dexFile);
} }
private ClassPath() { private ClassPath() {
classDefs = new HashMap<String, ClassDef>(); classDefs = new HashMap<String, ClassDef>();
} }
private void initClassPath(String bootClassPathDir, String[] bootClassPath, DexFile dexFile) { private void initClassPath(String[] classPathDirs, String[] bootClassPath, DexFile dexFile) {
if (bootClassPath != null) { if (bootClassPath != null) {
for (String bootClassPathEntry: bootClassPath) { for (String bootClassPathEntry: bootClassPath) {
loadBootClassPath(bootClassPathDir, bootClassPathEntry); loadBootClassPath(classPathDirs, bootClassPathEntry);
} }
} }
@ -47,26 +47,30 @@ public class ClassPath {
} }
} }
private void loadBootClassPath(String bootClassPathDir, String bootClassPathEntry) { private void loadBootClassPath(String[] classPathDirs, String bootClassPathEntry) {
File file = new File(bootClassPathDir, bootClassPathEntry); for (String classPathDir: classPathDirs) {
File file = new File(classPathDir, bootClassPathEntry);
if (!file.exists()) { if (!file.exists()) {
throw new ExceptionWithContext("ClassPath entry \"" + bootClassPathEntry + "\" does not exist."); continue;
}
if (!file.canRead()) {
throw new ExceptionWithContext("Cannot read ClassPath entry \"" + bootClassPathEntry + "\".");
}
DexFile dexFile;
try {
dexFile = new DexFile(file, false, true);
} catch (Exception ex) {
throw ExceptionWithContext.withContext(ex, "Error while reading boot class path entry \"" +
bootClassPathEntry + "\".");
}
loadDexFile(dexFile);
return;
} }
throw new ExceptionWithContext(String.format("Cannot locate boot class path file %s", bootClassPathEntry));
if (!file.canRead()) {
throw new ExceptionWithContext("Cannot read ClassPath entry \"" + bootClassPathEntry + "\".");
}
DexFile dexFile;
try {
dexFile = new DexFile(file, false, true);
} catch (Exception ex) {
throw ExceptionWithContext.withContext(ex, "Error while reading ClassPath entry \"" +
bootClassPathEntry + "\".");
}
loadDexFile(dexFile);
} }
private void loadDexFile(DexFile dexFile) { private void loadDexFile(DexFile dexFile) {