aboutsummaryrefslogtreecommitdiff
path: root/src/Java/gtPlusPlus/preloader/asm/Preloader_ClassTransformer.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/Java/gtPlusPlus/preloader/asm/Preloader_ClassTransformer.java')
-rw-r--r--src/Java/gtPlusPlus/preloader/asm/Preloader_ClassTransformer.java88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/Java/gtPlusPlus/preloader/asm/Preloader_ClassTransformer.java b/src/Java/gtPlusPlus/preloader/asm/Preloader_ClassTransformer.java
new file mode 100644
index 0000000000..330aef318a
--- /dev/null
+++ b/src/Java/gtPlusPlus/preloader/asm/Preloader_ClassTransformer.java
@@ -0,0 +1,88 @@
+package gtPlusPlus.preloader.asm;
+
+import static org.objectweb.asm.Opcodes.ALOAD;
+import static org.objectweb.asm.Opcodes.INVOKESTATIC;
+
+import java.util.Iterator;
+
+import org.objectweb.asm.*;
+import org.objectweb.asm.tree.*;
+
+import gtPlusPlus.core.util.Utils;
+import net.minecraft.launchwrapper.IClassTransformer;
+
+public class Preloader_ClassTransformer implements IClassTransformer {
+
+ @Override
+ public byte[] transform(String name, String transformedName, byte[] basicClass) {
+
+ /*if (name.equals("abq")) {
+ Utils.LOG_ASM("[ASM] INSIDE OBFUSCATED EXPLOSION TRANSFORMER ABOUT TO PATCH: " + name);
+ return patchClassASM(name, basicClass, true);
+ }
+
+ else if (name.equals("net.minecraftforge.oredict.OreDictionary")) {
+ Utils.LOG_ASM("[ASM] INSIDE OREDICT TRANSFORMER ABOUT TO PATCH: " + name);
+ return patchClassASM(name, basicClass, false);
+ }*/
+ return basicClass;
+ }
+
+ public byte[] patchClassASM(String name, byte[] bytes, boolean obfuscated) {
+
+ String targetMethodName = "";
+
+ if(obfuscated == true)
+ targetMethodName ="a";
+ else
+ targetMethodName ="registerOreImpl";
+
+
+ //set up ASM class manipulation stuff. Consult the ASM docs for details
+ ClassNode classNode = new ClassNode();
+ ClassReader classReader = new ClassReader(bytes);
+ classReader.accept(classNode, 0);
+
+
+
+ //Now we loop over all of the methods declared inside the Explosion class until we get to the targetMethodName "doExplosionB"
+
+ // find method to inject into
+ Iterator<MethodNode> methods = classNode.methods.iterator();
+ while(methods.hasNext())
+ {
+ MethodNode m = methods.next();
+ Utils.LOG_ASM("[ASM] Method Name: "+m.name + " Desc:" + m.desc);
+
+ //Check if this is doExplosionB and it's method signature is (Z)V which means that it accepts a boolean (Z) and returns a void (V)
+ if ((m.name.equals(targetMethodName) && m.desc.equals("(Ljava/lang/String;Lnet/minecraft/item/ItemStack;)V")))
+ {
+ Utils.LOG_ASM("[ASM] Inside target method!");
+ // find interesting instructions in method, there is a single FDIV instruction we use as target
+
+ // make new instruction list
+ InsnList toInject = new InsnList();
+
+ //toInject.add(new VarInsnNode(ALOAD, 0));
+
+ toInject.add(new VarInsnNode(ALOAD, 1));
+ toInject.add(new MethodInsnNode(INVOKESTATIC, "gtPlusPlus/preloader/Preloader_GT_OreDict", "removeCircuit", "(Lnet/minecraft/item/ItemStack;)Z, false"));
+ toInject.add(new VarInsnNode(Opcodes.IFEQ, 1));
+ toInject.add(new VarInsnNode(Opcodes.RETURN, 0));
+ //toInject.add(new VarInsnNode(org.objectweb.asm.Opcodes.LABEL END, 0));
+
+ // inject new instruction list into method instruction list
+ m.instructions.insert(toInject);
+
+ Utils.LOG_ASM("Patching Complete!");
+ break;
+ }
+ }
+
+ //ASM specific for cleaning up and returning the final bytes for JVM processing.
+ ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
+ classNode.accept(writer);
+ return writer.toByteArray();
+ }
+
+}