Skip to content

Instantly share code, notes, and snippets.

@jsyeo
Created September 8, 2015 09:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsyeo/87ec523a58f860952f75 to your computer and use it in GitHub Desktop.
Save jsyeo/87ec523a58f860952f75 to your computer and use it in GitHub Desktop.
ASM and Reflection
/*
* © Copyright 2015 - SourceClear Inc
*/
import com.codepoetics.protonpack.StreamUtils;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.stream.Stream;
/**
*
*/
public class Main {
public static void main(String[] args) throws IOException {
InputStream is = Main.class.getClassLoader().getResourceAsStream("dotclass.jar");
List<Type> reflectedClasses = new ArrayList<>();
List<String> reflectedMethods = new ArrayList<>();
StreamUtils.takeUntil(jarToClassReaders(is), x -> x == null).
forEach(cr -> cr.accept(new ReflectionClassVisitor(Opcodes.ASM5, reflectedClasses, reflectedMethods), Opcodes.ASM5));
is = Main.class.getClassLoader().getResourceAsStream("classForName.jar");
StreamUtils.takeUntil(jarToClassReaders(is), x -> x == null).
forEach(cr -> cr.accept(new ReflectionClassVisitor(Opcodes.ASM5, reflectedClasses, reflectedMethods), Opcodes.ASM5));
System.out.println(reflectedClasses);
System.out.println(reflectedMethods);
}
static Stream<ClassReader> jarToClassReaders(InputStream jar) throws IOException {
JarInputStream jis = new JarInputStream(jar);
return Stream.generate(() -> {
try {
JarEntry jarEntry = jis.getNextJarEntry();
if (jarEntry != null &&
!jarEntry.isDirectory() &&
jarEntry.getName().toLowerCase().endsWith(".class")) {
ClassReader cr = new ClassReader(jis);
return cr;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
});
}
}
/*
* © Copyright 2015 - SourceClear Inc
*/
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import java.util.Collection;
/**
*
*/
public class ReflectionClassVisitor extends ClassVisitor {
///////////////////////////// Class Attributes \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
////////////////////////////// Class Methods \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//////////////////////////////// Attributes \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
private final int version;
private final Collection<Type> reflectedClasses;
private final Collection<String> reflectedMethods;
/////////////////////////////// Constructors \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
public ReflectionClassVisitor(int version, Collection<Type> reflectedClasses, Collection<String> reflectedMethods) {
super(version);
this.version = version;
this.reflectedClasses = reflectedClasses;
this.reflectedMethods = reflectedMethods;
}
////////////////////////////////// Methods \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//------------------------ Implements:
//------------------------ Overrides:
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new ReflectionMethodVisitor(version, reflectedClasses, reflectedMethods);
}
//---------------------------- Abstract Methods -----------------------------
//---------------------------- Utility Methods ------------------------------
//---------------------------- Property Methods -----------------------------
}
/*
* © Copyright 2015 - SourceClear Inc
*/
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import java.util.Collection;
import java.util.regex.Pattern;
/**
*
*/
public class ReflectionMethodVisitor extends MethodVisitor {
///////////////////////////// Class Attributes \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
////////////////////////////// Class Methods \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//////////////////////////////// Attributes \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
private final Collection<Type> reflectedClasses;
private final Collection<String> reflectedMethods;
private String currentLoadedString;
/////////////////////////////// Constructors \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
public ReflectionMethodVisitor(int version, Collection<Type> reflectedClasses, Collection<String> reflectedMethods) {
super(version);
this.reflectedClasses = reflectedClasses;
this.reflectedMethods = reflectedMethods;
}
////////////////////////////////// Methods \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//------------------------ Implements:
//------------------------ Overrides:
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (opcode == Opcodes.INVOKEVIRTUAL &&
owner.equals("java/lang/Class") &&
name.equals("getMethod") &&
desc.equals("(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;")) {
reflectedMethods.add(currentLoadedString);
} else if (opcode == Opcodes.INVOKEVIRTUAL &&
owner.equals("java/lang/reflect/Method") &&
name.equals("invoke") &&
desc.equals("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;")) {
System.out.println("invoke called!");
} else if (opcode == Opcodes.INVOKESTATIC &&
owner.equals("java/lang/Class") &&
name.equals("forName") &&
desc.equals("(Ljava/lang/String;)Ljava/lang/Class;")) {
reflectedClasses.add(Type.getObjectType(classNameToInternalName(currentLoadedString)));
}
}
private String classNameToInternalName(String className) {
return className.replaceAll(Pattern.quote("."), "/");
}
@Override
public void visitLdcInsn(Object arg) {
if (arg instanceof Type) {
Type type = (Type) arg;
if (type.getSort() == Type.OBJECT) {
reflectedClasses.add(type);
}
} else if (arg instanceof String) {
currentLoadedString = (String) arg;
}
}
//---------------------------- Abstract Methods -----------------------------
//---------------------------- Utility Methods ------------------------------
//---------------------------- Property Methods -----------------------------
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment