package helper;
import java.io.File;
import java.io.PrintWriter;
import java.util.List;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type;
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.Frame;
import org.objectweb.asm.tree.analysis.SimpleVerifier;
import org.objectweb.asm.util.CheckClassAdapter;
import org.objectweb.asm.util.TraceClassVisitor;
import org.objectweb.asm.util.TraceMethodVisitor;
public class Utils {
public static Class<?> loadClass(String className, byte[] b) {
Class<?> clazz = null;
try {
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class<?> cls = Class.forName("java.lang.ClassLoader");
java.lang.reflect.Method method = cls.getDeclaredMethod(
"defineClass", new Class[] { String.class, byte[].class,
int.class, int.class });
method.setAccessible(true);
try {
Object[] args = new Object[] { className, b, new Integer(0),
new Integer(b.length) };
clazz = (Class<?>) method.invoke(loader, args);
} finally {
method.setAccessible(false);
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
return clazz;
}
public static void dump(byte[] bytes) throws Exception {
int flags = ClassReader.SKIP_DEBUG;
ClassReader cr;
cr = new ClassReader(bytes);
cr.accept(new TraceClassVisitor(new PrintWriter(System.out)), new Attribute[0], flags);
}
public static void dumpForCompare(byte[] orgs, byte[] bytes) throws Exception {
int flags = 0;
ClassReader cr;
cr = new ClassReader(bytes);
cr.accept(new TraceClassVisitor(new PrintWriter(new File("out.dump"))), new Attribute[0], flags);
CheckClassAdapter.verify(cr, false, new PrintWriter(new File("out_chk.log")));
ClassReader cr2;
cr2 = new ClassReader(orgs);
cr2.accept(new TraceClassVisitor(new PrintWriter(new File("in.dump"))), new Attribute[0], flags);
}
public static void verify(
final ClassReader cr,
final boolean dump,
final PrintWriter pw)
{
ClassNode cn = new ClassNode();
cr.accept(new CheckClassAdapter(cn), 0);
Type syperType = cn.superName == null
? null
: Type.getObjectType(cn.superName);
List methods = cn.methods;
for (int i = 0; i < methods.size(); ++i) {
MethodNode method = (MethodNode) methods.get(i);
Analyzer a = new Analyzer(new SimpleVerifier(Type.getObjectType(cn.name),
syperType,
false));
try {
a.analyze(cn.name, method);
if (!dump) {
continue;
}
} catch (Exception e) {
e.printStackTrace(pw);
}
Frame[] frames = a.getFrames();
TraceMethodVisitor mv = new TraceMethodVisitor();
pw.println(method.name + method.desc);
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())).append(' ');
}
s.append(" : ");
for (int k = 0; k < f.getStackSize(); ++k) {
s.append(getShortName(f.getStack(k).toString()))
.append(' ');
}
}
while (s.length() < method.maxStack + method.maxLocals + 1) {
s.append(' ');
}
pw.print(Integer.toString(j + 100000).substring(1));
// pw.print(" " + s + " : " + mv.buf); // mv.text.get(j));
}
for (int j = 0; j < method.tryCatchBlocks.size(); ++j) {
((TryCatchBlockNode) method.tryCatchBlocks.get(j)).accept(mv);
// pw.print(" " + mv.buf);
}
pw.println();
}
pw.flush();
}
private static String getShortName(final String name) {
int n = name.lastIndexOf('/');
int k = name.length();
if (name.charAt(k - 1) == ';') {
k--;
}
return n == -1 ? name : name.substring(n + 1, k);
}
}