use of org.objectweb.asm.ClassVisitor in project quasar by puniverse.
the class QuasarInstrumentor method instrumentClass.
@VisibleForTesting
byte[] instrumentClass(ClassLoader loader, String className, InputStream is, boolean forceInstrumentation) throws IOException {
className = className != null ? className.replace('.', '/') : null;
byte[] cb = toByteArray(is);
MethodDatabase db = getMethodDatabase(loader);
if (className != null) {
log(LogLevel.INFO, "TRANSFORM: %s %s", className, (db.getClassEntry(className) != null && db.getClassEntry(className).requiresInstrumentation()) ? "request" : "");
// DEBUG
if (EXAMINED_CLASS != null && className.startsWith(EXAMINED_CLASS)) {
writeToFile(className.replace('/', '.') + "-" + new Date().getTime() + "-quasar-1-preinstr.class", cb);
// cv1 = new TraceClassVisitor(cv, new PrintWriter(System.err));
}
} else {
log(LogLevel.INFO, "TRANSFORM: null className");
}
// Phase 1, add a label before any suspendable calls, event API is enough
final ClassReader r1 = new ClassReader(cb);
final ClassWriter cw1 = new ClassWriter(r1, 0);
final LabelSuspendableCallSitesClassVisitor ic1 = new LabelSuspendableCallSitesClassVisitor(cw1, db);
r1.accept(ic1, 0);
cb = cw1.toByteArray();
// DEBUG
if (EXAMINED_CLASS != null && className != null && className.startsWith(EXAMINED_CLASS)) {
writeToFile(className.replace('/', '.') + "-" + new Date().getTime() + "-quasar-2.class", cb);
// cv1 = new TraceClassVisitor(cv, new PrintWriter(System.err));
}
// Phase 2, instrument, tree API
final ClassReader r2 = new ClassReader(cb);
final ClassWriter cw2 = new DBClassWriter(db, r2);
final ClassVisitor cv2 = (check && EXAMINED_CLASS == null) ? new CheckClassAdapter(cw2) : cw2;
final InstrumentClass ic2 = new InstrumentClass(cv2, db, forceInstrumentation);
try {
r2.accept(ic2, ClassReader.SKIP_FRAMES);
cb = cw2.toByteArray();
} catch (final Exception e) {
if (ic2.hasSuspendableMethods()) {
error("Unable to instrument class " + className, e);
throw e;
} else {
if (!MethodDatabase.isProblematicClass(className))
log(LogLevel.DEBUG, "Unable to instrument class " + className);
return null;
}
}
// DEBUG
if (EXAMINED_CLASS != null && className != null && className.startsWith(EXAMINED_CLASS)) {
writeToFile(className.replace('/', '.') + "-" + new Date().getTime() + "-quasar-4.class", cb);
// cv1 = new TraceClassVisitor(cv, new PrintWriter(System.err));
}
// Phase 4, fill suspendable call offsets, event API is enough
final OffsetClassReader r3 = new OffsetClassReader(cb);
final ClassWriter cw3 = new ClassWriter(r3, 0);
final SuspOffsetsAfterInstrClassVisitor ic3 = new SuspOffsetsAfterInstrClassVisitor(cw3, db);
r3.accept(ic3, 0);
cb = cw3.toByteArray();
// DEBUG
if (EXAMINED_CLASS != null) {
if (className != null && className.startsWith(EXAMINED_CLASS))
writeToFile(className.replace('/', '.') + "-" + new Date().getTime() + "-quasar-5-final.class", cb);
if (check) {
ClassReader r4 = new ClassReader(cb);
ClassVisitor cv4 = new CheckClassAdapter(new TraceClassVisitor(null), true);
r4.accept(cv4, 0);
}
}
return cb;
}
use of org.objectweb.asm.ClassVisitor in project quasar by puniverse.
the class JavaAgent method crazyClojureOnceDisable.
public static byte[] crazyClojureOnceDisable(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if (!Boolean.parseBoolean(System.getProperty("co.paralleluniverse.pulsar.disableOnce", "false")))
return classfileBuffer;
final ClassReader cr = new ClassReader(classfileBuffer);
final ClassWriter cw = new ClassWriter(cr, 0);
final ClassVisitor cv = new ClassVisitor(ASMAPI, cw) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new MethodVisitor(api, super.visitMethod(access, name, desc, signature, exceptions)) {
@Override
public void visitLdcInsn(Object cst) {
if (cst instanceof String && cst.equals("once")) {
super.visitLdcInsn("once$disabled-by-pulsar");
} else
super.visitLdcInsn(cst);
}
};
}
};
cr.accept(cv, 0);
return cw.toByteArray();
}
use of org.objectweb.asm.ClassVisitor in project dex2jar by pxb1988.
the class InitOut method collect.
private List<ClassInfo> collect(File file) throws IOException {
final List<ClassInfo> clzList = new ArrayList<ClassInfo>();
final ClassVisitor collectVisitor = new ClassVisitor(ASM4) {
private static final String ASSERTION_DISABLED_FIELD_NAME = "$assertionsDisabled";
private static final String ENUM_VALUES_FIELD_NAME = "ENUM$VALUES";
ClassInfo clz;
boolean isEnum = false;
Map<String, String> enumFieldMap = new HashMap<String, String>();
@Override
public void visitSource(String source, String debug) {
if (initSourceNames && !clz.name.contains("$") && source.endsWith(".java")) {
clz.suggestName = source.substring(0, source.length() - 5);
}
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
clz.addMethod(access, name, desc);
if (initEnumNames && isEnum && name.equals("<clinit>")) {
final String thisDesc = "L" + clz.name + ";";
return new MethodNode(ASM4, access, name, desc, signature, exceptions) {
@Override
public void visitEnd() {
if (this.instructions != null) {
int status = 0;
String eFieldName = null;
for (AbstractInsnNode p = this.instructions.getFirst(); p != null; p = p.getNext()) {
if (status == 0) {
// init
if (p.getOpcode() == NEW) {
TypeInsnNode ti = (TypeInsnNode) p;
if (thisDesc.equals(ti.desc)) {
status = 1;
}
}
} else if (status == 1) {
// find NEW
if (p.getOpcode() == DUP) {
status = 2;
} else {
status = 0;
}
} else if (status == 2) {
//find DUP
if (p.getOpcode() == LDC) {
LdcInsnNode ldc = (LdcInsnNode) p;
if (ldc.cst instanceof String) {
eFieldName = (String) ldc.cst;
status = 3;
} else {
status = 0;
}
} else {
status = 0;
}
} else if (status == 3) {
//find LDC
if (p.getOpcode() == PUTSTATIC) {
FieldInsnNode fin = (FieldInsnNode) p;
if (fin.owner.equals(thisDesc) && fin.desc.equals(thisDesc)) {
if (!fin.name.equals(eFieldName)) {
enumFieldMap.put(fin.name, eFieldName);
}
eFieldName = null;
status = 0;
}
}
}
}
}
}
};
}
return null;
}
@Override
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
MemberInfo mi = clz.addField(access, name, desc);
if (initEnumNames && isEnum && isPrivate(access) && isFinal(access) && isSynthetic(access) && !ENUM_VALUES_FIELD_NAME.equals(name) && ("[L" + clz.name + ";").equals(desc)) {
mi.suggestName = ENUM_VALUES_FIELD_NAME;
}
if (initAssertionNames && isSynthetic(access) && isStatic(access) && !isPrivate(access) && !isPublic(access) && !isProtected(access) && desc.equals("Z") && !ASSERTION_DISABLED_FIELD_NAME.equals(name)) {
mi.suggestName = ASSERTION_DISABLED_FIELD_NAME;
}
return null;
}
@Override
public void visitEnd() {
if (initEnumNames) {
final String thisDesc = "L" + clz.name + ";";
for (Map.Entry<String, String> e : enumFieldMap.entrySet()) {
String name = e.getKey();
String suggestName = e.getValue();
for (MemberInfo mi : clz.fields) {
if (isFinal(mi.access) && isStatic(mi.access) && mi.name.equals(name) && mi.desc.equals(thisDesc)) {
mi.suggestName = suggestName;
}
}
}
}
clzList.add(clz);
clz = null;
isEnum = false;
enumFieldMap.clear();
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
this.clz = new ClassInfo(name);
isEnum = isEnum(access);
}
};
// fileWalker.walk(file);
return clzList;
}
use of org.objectweb.asm.ClassVisitor in project dex2jar by pxb1988.
the class Dex2jarMultiThreadCmd method run0.
private void run0(String fileName, final ExecutorService executorService) throws IOException {
// long baseTS = System.currentTimeMillis();
String baseName = getBaseName(new File(fileName).toPath());
Path currentDir = new File(".").toPath();
Path file = currentDir.resolve(baseName + "-dex2jar.jar");
final Path errorFile = currentDir.resolve(baseName + "-error.zip");
System.err.println("dex2jar " + fileName + " -> " + file);
final BaksmaliBaseDexExceptionHandler exceptionHandler = new BaksmaliBaseDexExceptionHandler();
BaseDexFileReader reader = MultiDexFileReader.open(Files.readAllBytes(new File(fileName).toPath()));
DexFileNode fileNode = new DexFileNode();
try {
reader.accept(fileNode, DexFileReader.SKIP_DEBUG | DexFileReader.IGNORE_READ_EXCEPTION);
} catch (Exception ex) {
exceptionHandler.handleFileException(ex);
throw ex;
}
final FileSystem fs = createZip(file);
final Path dist = fs.getPath("/");
ClassVisitorFactory cvf = new ClassVisitorFactory() {
@Override
public ClassVisitor create(final String name) {
return new ClassVisitor(Opcodes.ASM4, new ClassWriter(ClassWriter.COMPUTE_MAXS)) {
@Override
public void visitEnd() {
super.visitEnd();
ClassWriter cw = (ClassWriter) super.cv;
byte[] data;
try {
// FIXME handle 'java.lang.RuntimeException: Method code too large!'
data = cw.toByteArray();
} catch (Exception ex) {
System.err.println(String.format("ASM fail to generate .class file: %s", name));
exceptionHandler.handleFileException(ex);
return;
}
try {
Path dist1 = dist.resolve(name + ".class");
BaseCmd.createParentDirectories(dist1);
Files.write(dist1, data);
} catch (IOException e) {
exceptionHandler.handleFileException(e);
}
}
};
}
};
new ExDex2Asm(exceptionHandler) {
@Override
public void convertDex(DexFileNode fileNode, final ClassVisitorFactory cvf) {
if (fileNode.clzs != null) {
final Map<String, Clz> classes = collectClzInfo(fileNode);
final List<Future<?>> results = new ArrayList<>(fileNode.clzs.size());
for (final DexClassNode classNode : fileNode.clzs) {
results.add(executorService.submit(new Runnable() {
@Override
public void run() {
convertClass(classNode, cvf, classes);
}
}));
}
executorService.submit(new Runnable() {
@Override
public void run() {
for (Future<?> result : results) {
try {
result.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
BaksmaliBaseDexExceptionHandler exceptionHandler1 = (BaksmaliBaseDexExceptionHandler) exceptionHandler;
if (exceptionHandler1.hasException()) {
exceptionHandler1.dump(errorFile, new String[0]);
}
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
}.convertDex(fileNode, cvf);
}
use of org.objectweb.asm.ClassVisitor in project robovm by robovm.
the class InterfaceBuilderClassesPlugin method getCustomClass.
private String getCustomClass(URL url, Map<URL, String> customClassValuesCache) throws IOException {
if (customClassValuesCache.containsKey(url)) {
return customClassValuesCache.get(url);
}
class Visitor extends ClassVisitor {
String customClass;
Visitor() {
super(Opcodes.ASM4);
}
@Override
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
if (CUSTOM_CLASS.equals(desc)) {
return new AnnotationVisitor(Opcodes.ASM4) {
public void visit(String name, Object value) {
customClass = (String) value;
}
};
}
return super.visitAnnotation(desc, visible);
}
}
Visitor visitor = new Visitor();
new ClassReader(IOUtils.toByteArray(url)).accept(visitor, 0);
customClassValuesCache.put(url, visitor.customClass);
return visitor.customClass;
}
Aggregations