mirror of
https://github.com/pxb1988/dex2jar.git
synced 2025-03-01 09:26:05 +00:00
add cmd asm-verify jar2dex
--HG-- branch : 0.0.9.x
This commit is contained in:
parent
62898aa689
commit
329080cd95
@ -52,7 +52,7 @@ public class ASMifierFileV implements OdexFileVisitor {
|
||||
}
|
||||
|
||||
public static void main(String... args) throws IOException {
|
||||
if (args.length < 2) {
|
||||
if (args.length < 1) {
|
||||
System.out.println("ASMifier 1.dex 2.dex ... n.dex");
|
||||
return;
|
||||
}
|
||||
|
@ -2,4 +2,4 @@
|
||||
set CLASSPATH=
|
||||
FOR %%i IN ("%~dp0lib\*.jar") DO CALL "%~dp0setclasspath.bat" %%i
|
||||
|
||||
java -Xms512m -Xmx1024m -cp "%CLASSPATH%" "com.googlecode.dex2jar.tools.to.Do" %*
|
||||
java -Xms512m -Xmx1024m -cp "%CLASSPATH%" "com.googlecode.dex2jar.tools.AsmVerify" %*
|
@ -20,4 +20,4 @@ for k in "$PRGDIR"/lib/*.jar
|
||||
do
|
||||
_classpath="${_classpath}:${k}"
|
||||
done
|
||||
java -Xms512m -Xmx1024m -classpath "${_classpath}" "com.googlecode.dex2jar.tools.to.Do" $@
|
||||
java -Xms512m -Xmx1024m -classpath "${_classpath}" "com.googlecode.dex2jar.tools.AsmVerify" $@
|
@ -2,4 +2,4 @@
|
||||
set CLASSPATH=
|
||||
FOR %%i IN ("%~dp0lib\*.jar") DO CALL "%~dp0setclasspath.bat" %%i
|
||||
|
||||
java -Xms512m -Xmx1024m -cp "%CLASSPATH%" "com.googlecode.dex2jar.tools.to.Do" %*
|
||||
java -Xms512m -Xmx1024m -cp "%CLASSPATH%" "com.googlecode.dex2jar.tools.Jar2Dex" %*
|
||||
|
@ -20,4 +20,4 @@ for k in "$PRGDIR"/lib/*.jar
|
||||
do
|
||||
_classpath="${_classpath}:${k}"
|
||||
done
|
||||
java -Xms512m -Xmx1024m -classpath "${_classpath}" "com.googlecode.dex2jar.tools.to.Do" $@
|
||||
java -Xms512m -Xmx1024m -classpath "${_classpath}" "com.googlecode.dex2jar.tools.Jar2Dex" $@
|
||||
|
@ -32,6 +32,5 @@ public class BinGen {
|
||||
FileUtils.writeStringToFile(new File(binDir, key.toString() + ".bat"),
|
||||
bat.replaceAll("__@class_name@__", p.getProperty(name)), "UTF-8");
|
||||
}
|
||||
System.out.println("Done.");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,186 @@
|
||||
package com.googlecode.dex2jar.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.cli.PosixParser;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.objectweb.asm.tree.TryCatchBlockNode;
|
||||
import org.objectweb.asm.tree.analysis.Analyzer;
|
||||
import org.objectweb.asm.tree.analysis.BasicVerifier;
|
||||
import org.objectweb.asm.tree.analysis.Frame;
|
||||
import org.objectweb.asm.util.AbstractVisitor;
|
||||
import org.objectweb.asm.util.CheckClassAdapter;
|
||||
import org.objectweb.asm.util.TraceMethodVisitor;
|
||||
|
||||
public class AsmVerify {
|
||||
private static final Options options = new Options();;
|
||||
static {
|
||||
options.addOption(new Option("d", "detail", false, "print detail error message"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the usage message.
|
||||
*/
|
||||
private static void usage() {
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.setOptionComparator(new Comparator<Option>() {
|
||||
|
||||
@Override
|
||||
public int compare(Option o1, Option o2) {
|
||||
|
||||
return o1.getOpt().compareTo(o2.getOpt());
|
||||
}
|
||||
});
|
||||
formatter.printHelp("d2j-asm-verify [options] <jar0> [jar1 ... jarN]", "verify .class in jar", options, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args
|
||||
* @throws IOException
|
||||
* @throws IllegalAccessException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public static void main(String[] args) throws IOException, IllegalArgumentException, IllegalAccessException {
|
||||
CommandLineParser parser = new PosixParser();
|
||||
CommandLine commandLine;
|
||||
|
||||
try {
|
||||
commandLine = parser.parse(options, args);
|
||||
} catch (ParseException ex) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
String[] remainingArgs = commandLine.getArgs();
|
||||
if (remainingArgs.length < 1) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
List<File> files = new ArrayList<File>();
|
||||
for (String fn : remainingArgs) {
|
||||
File file = new File(fn);
|
||||
if (!file.exists() || !file.isFile()) {
|
||||
System.err.println(fn + " is not exists");
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
files.add(file);
|
||||
}
|
||||
boolean detail = false;
|
||||
for (Option option : commandLine.getOptions()) {
|
||||
String opt = option.getOpt();
|
||||
switch (opt.charAt(0)) {
|
||||
case 'd':
|
||||
detail = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (File file : files) {
|
||||
ZipFile zip = null;
|
||||
try {
|
||||
zip = new ZipFile(file);
|
||||
} catch (IOException e1) {
|
||||
System.err.println(file + " is not a validate zip file");
|
||||
if (detail) {
|
||||
e1.printStackTrace(System.err);
|
||||
}
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
for (Enumeration<? extends ZipEntry> e = zip.entries(); e.hasMoreElements();) {
|
||||
ZipEntry zipEntry = e.nextElement();
|
||||
System.out.println("Verify jar " + zipEntry.getName());
|
||||
if (!zipEntry.isDirectory() && zipEntry.getName().endsWith(".class")) {
|
||||
InputStream is = zip.getInputStream(zipEntry);
|
||||
ClassReader cr = new ClassReader(is);
|
||||
ClassNode cn = new ClassNode();
|
||||
cr.accept(new CheckClassAdapter(cn, false), ClassReader.SKIP_DEBUG);
|
||||
|
||||
List methods = cn.methods;
|
||||
for (int i = 0; i < methods.size(); ++i) {
|
||||
MethodNode method = (MethodNode) methods.get(i);
|
||||
BasicVerifier verifier = new BasicVerifier();
|
||||
Analyzer a = new Analyzer(verifier);
|
||||
try {
|
||||
a.analyze(cn.name, method);
|
||||
} catch (Exception ex) {
|
||||
System.err.println("Error verify method " + method.name + " " + method.desc);
|
||||
if (detail) {
|
||||
printAnalyzerResult(method, a, new PrintWriter(System.err));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void printAnalyzerResult(MethodNode method, Analyzer a, final PrintWriter pw)
|
||||
throws IllegalArgumentException, IllegalAccessException {
|
||||
Frame[] frames = a.getFrames();
|
||||
TraceMethodVisitor mv = new TraceMethodVisitor();
|
||||
String format = "%05d %-" + (method.maxStack + method.maxLocals + 6) + "s|%s";
|
||||
for (int j = 0; j < method.instructions.size(); ++j) {
|
||||
method.instructions.get(j).accept(mv);
|
||||
|
||||
StringBuffer s = new StringBuffer();
|
||||
Frame f = frames[j];
|
||||
if (f == null) {
|
||||
s.append('?');
|
||||
} else {
|
||||
for (int k = 0; k < f.getLocals(); ++k) {
|
||||
s.append(getShortName(f.getLocal(k).toString()));
|
||||
}
|
||||
s.append(" : ");
|
||||
for (int k = 0; k < f.getStackSize(); ++k) {
|
||||
s.append(getShortName(f.getStack(k).toString()));
|
||||
}
|
||||
}
|
||||
pw.printf(format, j, s, buf.get(mv)); // mv.text.get(j));
|
||||
}
|
||||
for (int j = 0; j < method.tryCatchBlocks.size(); ++j) {
|
||||
((TryCatchBlockNode) method.tryCatchBlocks.get(j)).accept(mv);
|
||||
pw.print(" " + buf.get(mv));
|
||||
}
|
||||
pw.println();
|
||||
pw.flush();
|
||||
}
|
||||
|
||||
private static String getShortName(final String name) {
|
||||
int n = name.lastIndexOf('/');
|
||||
return n == -1 ? name : "o";
|
||||
}
|
||||
|
||||
static Field buf;
|
||||
|
||||
static {
|
||||
try {
|
||||
buf = AbstractVisitor.class.getDeclaredField("buf");
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
buf.setAccessible(true);
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
package com.googlecode.dex2jar.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.cli.PosixParser;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
public class Jar2Dex {
|
||||
private static final Options options = new Options();;
|
||||
static {
|
||||
options.addOption(new Option("o", "output", true,
|
||||
"output .dex file, default is $current_dir/[jar-name]-jar2dex.dex"));
|
||||
options.addOption(new Option("f", "force", false, "force overwrite"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the usage message.
|
||||
*/
|
||||
private static void usage() {
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.setOptionComparator(new Comparator<Option>() {
|
||||
|
||||
@Override
|
||||
public int compare(Option o1, Option o2) {
|
||||
|
||||
return o1.getOpt().compareTo(o2.getOpt());
|
||||
}
|
||||
});
|
||||
formatter.printHelp("d2j-jar2dex [options] <dir>", "invoke dx to convert jar to dex", options, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args
|
||||
* @throws InvocationTargetException
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws SecurityException
|
||||
* @throws NoSuchMethodException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException,
|
||||
InvocationTargetException, ClassNotFoundException, NoSuchMethodException, SecurityException, IOException {
|
||||
CommandLineParser parser = new PosixParser();
|
||||
CommandLine commandLine;
|
||||
|
||||
try {
|
||||
commandLine = parser.parse(options, args);
|
||||
} catch (ParseException ex) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
String[] remainingArgs = commandLine.getArgs();
|
||||
if (remainingArgs.length != 1) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
File jar = new File(remainingArgs[0]);
|
||||
if (!jar.exists() || !jar.isFile()) {
|
||||
System.err.println(jar + " is not exists");
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
File output = null;
|
||||
boolean force = false;
|
||||
for (Option option : commandLine.getOptions()) {
|
||||
String opt = option.getOpt();
|
||||
switch (opt.charAt(0)) {
|
||||
case 'o': {
|
||||
String v = commandLine.getOptionValue("o");
|
||||
if (v != null) {
|
||||
output = new File(v);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'f': {
|
||||
force = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (output == null) {
|
||||
output = new File(FilenameUtils.getBaseName(jar.getName()) + "-jar2dex.dex");
|
||||
}
|
||||
|
||||
if (output.exists() && !force) {
|
||||
System.err.println(output + " exists, use --force to overwrite");
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
Class<?> c = Class.forName("com.android.dx.command.Main");
|
||||
Method m = c.getMethod("main", String[].class);
|
||||
|
||||
List<String> ps = new ArrayList<String>();
|
||||
ps.addAll(Arrays.asList("--dex", "--no-strict", "--output=" + output.getCanonicalPath(), jar.getCanonicalPath()));
|
||||
System.out.println("call com.android.dx.command.Main.main" + ps);
|
||||
m.invoke(null, new Object[] { ps.toArray(new String[0]) });
|
||||
}
|
||||
|
||||
}
|
@ -27,7 +27,7 @@ public class Jar2Jasmin {
|
||||
static {
|
||||
options.addOption(new Option("d", "debug", false, "disassemble debug info"));
|
||||
options.addOption(new Option("o", "output", true,
|
||||
"output dir of .j files, default is $current_dir/[jar-name]-2jasmin"));
|
||||
"output dir of .j files, default is $current_dir/[jar-name]-jar2jasmin/"));
|
||||
options.addOption(new Option("f", "force", false, "force overwrite"));
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ public class Jar2Jasmin {
|
||||
}
|
||||
|
||||
if (output == null) {
|
||||
output = new File(FilenameUtils.getBaseName(jar.getName()) + "2jasmin/");
|
||||
output = new File(FilenameUtils.getBaseName(jar.getName()) + "-jar2jasmin/");
|
||||
}
|
||||
|
||||
if (output.exists() && !force) {
|
||||
@ -134,6 +134,5 @@ public class Jar2Jasmin {
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Done.");
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.cli.PosixParser;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
public class Jasmin2Jar {
|
||||
@ -98,7 +97,7 @@ public class Jasmin2Jar {
|
||||
}
|
||||
}
|
||||
if (output == null) {
|
||||
output = new File(FilenameUtils.getBaseName(dir.getName()) + "-jasmin2jar.jar");
|
||||
output = new File(dir.getName() + "-jasmin2jar.jar");
|
||||
}
|
||||
|
||||
if (output.exists() && !force) {
|
||||
@ -106,6 +105,9 @@ public class Jasmin2Jar {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("assemble " + dir + " to " + output);
|
||||
|
||||
Class<?> clz = Class.forName("jasmin.ClassFile");
|
||||
Method readJasmin = clz.getMethod("readJasmin", Reader.class, String.class, boolean.class);
|
||||
Method errorCount = clz.getMethod("errorCount");
|
||||
|
@ -10,8 +10,8 @@ d2j-dex-dump=com.googlecode.dex2jar.util.Dump
|
||||
|
||||
# from dex-tool
|
||||
d2j-apk-extract=com.googlecode.dex2jar.tools.to.Do
|
||||
d2j-jar2dex=com.googlecode.dex2jar.tools.to.Do
|
||||
d2j-jar-verify=com.googlecode.dex2jar.tools.to.Do
|
||||
d2j-jar2dex=com.googlecode.dex2jar.tools.Jar2Dex
|
||||
d2j-asm-verify=com.googlecode.dex2jar.tools.AsmVerify
|
||||
d2j-jar2jasmin=com.googlecode.dex2jar.tools.Jar2Jasmin
|
||||
d2j-jasmin2jar=com.googlecode.dex2jar.tools.Jasmin2Jar
|
||||
d2j-apk-sign=com.googlecode.dex2jar.tools.to.Do
|
||||
|
Loading…
x
Reference in New Issue
Block a user