use of org.objectweb.asm.ClassReader in project LogisticsPipes by RS485.
the class LogisticsPipesClassInjector method transform.
@Override
@SuppressWarnings("unchecked")
public byte[] transform(String name, String transformedName, byte[] bytes) {
if (bytes != null) {
if (name.startsWith("logisticspipes.")) {
final ClassReader reader = new ClassReader(bytes);
final ClassNode node = new ClassNode();
reader.accept(node, 0);
if (node.visibleAnnotations != null) {
for (AnnotationNode a : node.visibleAnnotations) {
if (a.desc.equals("Llogisticspipes/asm/ModVersionedClass;")) {
if (a.values.size() == 8 && a.values.get(0).equals("modId") && a.values.get(2).equals("version") && a.values.get(4).equals("classData") && a.values.get(6).equals("classDataDev")) {
String modId = a.values.get(1).toString();
String version = a.values.get(3).toString();
String classData = a.values.get(5).toString();
String classDataDev = a.values.get(7).toString();
if (ModStatusHelper.isModLoaded(modId) && !ModStatusHelper.isModVersionEqualsOrHigher(modId, version)) {
if (isObfEnv == null) {
try {
isObfEnv = (Class.forName("net.minecraft.world.World").getDeclaredField("chunkProvider") == null);
} catch (Throwable e) {
isObfEnv = true;
}
}
bytes = transform(name, transformedName, DatatypeConverter.parseBase64Binary(isObfEnv ? classData : classDataDev));
}
} else {
throw new UnsupportedOperationException("Can't parse the annotations correctly");
}
}
}
}
}
return bytes;
}
try {
if (name.startsWith("logisticspipes.proxy.opencomputers.asm.BaseWrapperClass$") && name.endsWith("$OpenComputersWrapper")) {
String correctName = name.substring(56, name.length() - 21);
Class<?> clazz = Launch.classLoader.findClass(correctName);
bytes = ClassCreator.getWrappedClassAsBytes(CCObjectWrapper.getWrapperInformation(clazz), clazz.getName());
Set<String> set = new TreeSet<>();
set.add(name);
Launch.classLoader.clearNegativeEntries(set);
Map<String, byte[]> map = (Map<String, byte[]>) fResourceCache.get(Launch.classLoader);
map.put(name, bytes);
return bytes;
}
} catch (Exception e) {
if (LPConstants.DEBUG) {
// For better Debugging
e.printStackTrace();
return bytes;
}
throw new RuntimeException(e);
}
return bytes;
}
use of org.objectweb.asm.ClassReader in project LogisticsPipes by RS485.
the class ParamProfiler method handleClass.
public static byte[] handleClass(byte[] bytes) {
if (!isActive)
return bytes;
final ClassReader reader = new ClassReader(bytes);
final ClassNode node = new ClassNode();
reader.accept(node, 0);
final String className = node.name;
for (final MethodNode m : node.methods) {
final String methodName = m.name;
final String methodDesc = m.desc;
final boolean isConst = methodName.contains("<") || methodName.contains(">");
if (isConst)
continue;
final long methodId = minMethodId++;
final List<String> varList = new ArrayList<>();
if (!methodDesc.startsWith("("))
throw new UnsupportedOperationException(methodDesc);
outer: for (int i = 1; i < methodDesc.length(); i++) {
switch(methodDesc.charAt(i)) {
case ')':
break outer;
case 'L':
int startA = i;
while (methodDesc.charAt(i) != ';') i++;
varList.add(methodDesc.substring(startA, i + 1));
break;
case '[':
int startB = i;
while (methodDesc.charAt(i) == '[') i++;
if (methodDesc.charAt(i) == 'L') {
while (methodDesc.charAt(i) != ';') i++;
}
varList.add(methodDesc.substring(startB, i + 1));
break;
default:
varList.add(String.valueOf(methodDesc.charAt(i)));
}
}
final List<Label> catchStatement = new ArrayList<>();
MethodNode mv = new MethodNode(Opcodes.ASM4, m.access, m.name, m.desc, m.signature, m.exceptions.toArray(new String[0])) {
@Override
public void visitCode() {
super.visitCode();
Label l0 = new Label();
visitLabel(l0);
visitLdcInsn(new Long(methodId));
visitLdcInsn(className + "+" + methodName + "+" + methodDesc);
if ((m.access & Opcodes.ACC_STATIC) != 0) {
visitInsn(Opcodes.ACONST_NULL);
} else {
visitVarInsn(Opcodes.ALOAD, 0);
}
visitIntInsn(Opcodes.BIPUSH, varList.size());
visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
int count = 0;
int pos = 0;
if ((m.access & Opcodes.ACC_STATIC) == 0) {
pos = 1;
}
for (String varNode : varList) {
visitInsn(Opcodes.DUP);
visitIntInsn(Opcodes.BIPUSH, count++);
if (!varNode.startsWith("L") && !varNode.startsWith("[")) {
String primitiveType = varNode;
switch(primitiveType.charAt(0)) {
case 'I':
visitVarInsn(Opcodes.ILOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
break;
case 'J':
visitVarInsn(Opcodes.LLOAD, pos);
pos += 2;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
break;
case 'Z':
visitVarInsn(Opcodes.ILOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
break;
case 'B':
visitVarInsn(Opcodes.ILOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
break;
case 'C':
visitVarInsn(Opcodes.ILOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
break;
case 'S':
visitVarInsn(Opcodes.ILOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
break;
case 'F':
visitVarInsn(Opcodes.FLOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
break;
case 'D':
visitVarInsn(Opcodes.DLOAD, pos);
pos += 2;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
break;
default:
throw new UnsupportedOperationException("'" + primitiveType + "'");
}
} else {
visitVarInsn(Opcodes.ALOAD, pos);
pos += 1;
}
visitInsn(Opcodes.AASTORE);
}
visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/asm/ParamProfiler", "methodStart", "(JLjava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;)V", false);
}
@Override
public void visitInsn(int opcode) {
if (opcode == Opcodes.RETURN || opcode == Opcodes.IRETURN || opcode == Opcodes.LRETURN || opcode == Opcodes.FRETURN || opcode == Opcodes.DRETURN || opcode == Opcodes.ARETURN) {
visitLdcInsn(new Long(methodId));
visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/asm/ParamProfiler", "methodEnd", "(J)V", false);
}
super.visitInsn(opcode);
}
@Override
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
catchStatement.add(handler);
super.visitTryCatchBlock(start, end, handler, type);
}
boolean watchForHandling = false;
@Override
public void visitLabel(Label label) {
watchForHandling = false;
super.visitLabel(label);
if (catchStatement.contains(label)) {
watchForHandling = true;
}
}
@Override
public void visitVarInsn(int opcode, int var) {
super.visitVarInsn(opcode, var);
if (watchForHandling) {
watchForHandling = false;
Label l = new Label();
visitLabel(l);
visitVarInsn(Opcodes.ALOAD, var);
visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/asm/ParamProfiler", "handleException", "(Ljava/lang/Throwable;)V", false);
}
}
};
m.accept(mv);
node.methods.set(node.methods.indexOf(m), mv);
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
node.accept(writer);
return writer.toByteArray();
}
use of org.objectweb.asm.ClassReader in project malmo by Microsoft.
the class OverclockingClassTransformer method transform.
private static byte[] transform(byte[] serverClass, boolean isObfuscated, transformType type) {
System.out.println("MALMO: Attempting to transform MinecraftServer");
try {
ClassNode cnode = new ClassNode();
ClassReader creader = new ClassReader(serverClass);
creader.accept(cnode, 0);
switch(type) {
case SERVER:
overclockServer(cnode, isObfuscated);
break;
case RENDERER:
overclockRenderer(cnode, isObfuscated);
break;
}
ClassWriter cwriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
cnode.accept(cwriter);
return cwriter.toByteArray();
} catch (Exception e) {
System.out.println("MALMO FAILED to transform MinecraftServer - overclocking not available!");
}
return serverClass;
}
use of org.objectweb.asm.ClassReader in project MinecraftForge by MinecraftForge.
the class AccessTransformer method processJar.
private static void processJar(File inFile, File outFile, AccessTransformer[] transformers) throws IOException {
ZipInputStream inJar = null;
ZipOutputStream outJar = null;
try {
try {
inJar = new ZipInputStream(new BufferedInputStream(new FileInputStream(inFile)));
} catch (FileNotFoundException e) {
throw new FileNotFoundException("Could not open input file: " + e.getMessage());
}
try {
outJar = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outFile)));
} catch (FileNotFoundException e) {
throw new FileNotFoundException("Could not open output file: " + e.getMessage());
}
ZipEntry entry;
while ((entry = inJar.getNextEntry()) != null) {
if (entry.isDirectory()) {
outJar.putNextEntry(entry);
continue;
}
byte[] data = new byte[4096];
ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream();
int len;
do {
len = inJar.read(data);
if (len > 0) {
entryBuffer.write(data, 0, len);
}
} while (len != -1);
byte[] entryData = entryBuffer.toByteArray();
String entryName = entry.getName();
if (entryName.endsWith(".class") && !entryName.startsWith(".")) {
ClassNode cls = new ClassNode();
ClassReader rdr = new ClassReader(entryData);
rdr.accept(cls, 0);
String name = cls.name.replace('/', '.').replace('\\', '.');
for (AccessTransformer trans : transformers) {
entryData = trans.transform(name, name, entryData);
}
}
ZipEntry newEntry = new ZipEntry(entryName);
outJar.putNextEntry(newEntry);
outJar.write(entryData);
}
} finally {
IOUtils.closeQuietly(outJar);
IOUtils.closeQuietly(inJar);
}
}
use of org.objectweb.asm.ClassReader in project MinecraftForge by MinecraftForge.
the class BlamingTransformer method transform.
@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
if (bytes == null) {
return null;
}
ClassReader classReader = new ClassReader(bytes);
VersionVisitor visitor = new VersionVisitor();
classReader.accept(visitor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG);
return bytes;
}
Aggregations