Advertisement
Guest User

Untitled

a guest
Jul 5th, 2014
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.53 KB | None | 0 0
  1. package pickandcraftSkin;
  2.  
  3. import static org.objectweb.asm.Opcodes.ALOAD;
  4. import static org.objectweb.asm.Opcodes.ARETURN;
  5. import static org.objectweb.asm.Opcodes.INVOKESTATIC;
  6.  
  7. import java.io.File;
  8. import java.io.InputStream;
  9. import java.util.Iterator;
  10. import java.util.zip.ZipEntry;
  11. import java.util.zip.ZipFile;
  12.  
  13. import org.objectweb.asm.ClassReader;
  14. import org.objectweb.asm.ClassWriter;
  15. import org.objectweb.asm.tree.ClassNode;
  16. import org.objectweb.asm.tree.InsnList;
  17. import org.objectweb.asm.tree.InsnNode;
  18. import org.objectweb.asm.tree.MethodInsnNode;
  19. import org.objectweb.asm.tree.MethodNode;
  20. import org.objectweb.asm.tree.VarInsnNode;
  21.  
  22.  
  23. public class SkinClassTransformer implements net.minecraft.launchwrapper.IClassTransformer {
  24. @Override
  25. public byte[] transform(String arg0, String arg1, byte[] arg2) {
  26.  
  27. //on cherche la classe qui nous interressent. On gere les deux cas: si elle est "obscurcie" ou pas
  28. if (arg0.equals("beu")) {
  29. System.out.println("********* INSIDE OBFUSCATED AbstractClientPlayer TRANSFORMER ABOUT TO PATCH: " + arg0);
  30. return patchClassASM(arg0, arg2, true);
  31. }
  32.  
  33. if (arg0.equals("net.minecraft.client.entity.AbstractClientPlayer")) {
  34. System.out.println("********* INSIDE AbstractClientPlayer TRANSFORMER ABOUT TO PATCH: " + arg0);
  35. return patchClassASM(arg0, arg2, false);
  36. }
  37.  
  38. //Check if the JVM is about to process the te.class or the EntityCreeper.class
  39. if (arg0.equals("bfn")
  40. || arg0.equals("net.minecraft.client.renderer.ImageBufferDownload")) {
  41. System.out
  42. .println("********* INSIDE ImageBufferDownload TRANSFORMER ABOUT TO PATCH: "
  43. + arg0);
  44. arg2 = patchClassInJar(arg0, arg2, arg0,
  45. SkinFMLLoadingPlugin.location);
  46. }
  47.  
  48. return arg2;
  49. }
  50.  
  51. //a small helper method that takes the class name we want to replace and our jar file.
  52. //It then uses the java zip library to open up the jar file and extract the classes.
  53. //Afterwards it serializes the class in bytes and pushes it on to the JVM.
  54. //with the original bytes that JVM was about to process ignored completly
  55.  
  56. public byte[] patchClassInJar(String name, byte[] bytes, String ObfName,
  57. File location) {
  58. try {
  59. // open the jar as zip
  60. ZipFile zip = new ZipFile(location);
  61. // find the file inside the zip that is called te.class or
  62. // net.minecraft.entity.monster.EntityCreeper.class
  63. // replacing the . to / so it would look for
  64. // net/minecraft/entity/monster/EntityCreeper.class
  65. ZipEntry entry = zip.getEntry(name.replace('.', '/') + ".class");
  66.  
  67. if (entry == null) {
  68. System.out
  69. .println(name + " not found in " + location.getName());
  70. } else {
  71.  
  72. // serialize the class file into the bytes array
  73. InputStream zin = zip.getInputStream(entry);
  74. bytes = new byte[(int) entry.getSize()];
  75. zin.read(bytes);
  76. zin.close();
  77. System.out.println("[" + "SkinCustomHD" + "]: " + "Class "
  78. + name + " patched!");
  79. }
  80. zip.close();
  81. } catch (Exception e) {
  82. throw new RuntimeException("Error overriding " + name + " from "
  83. + location.getName(), e);
  84. }
  85.  
  86. // return the new bytes
  87. return bytes;
  88. }
  89.  
  90. public byte[] patchClassASM(String name, byte[] bytes, boolean obfuscated) {
  91.  
  92. String targetMethod1Name = "", targetMethod2Name = "";
  93. boolean ok1 = false, ok2 = false;
  94.  
  95. if(obfuscated == true) {
  96. targetMethod1Name ="d";
  97. targetMethod2Name = "e";
  98. }
  99. else {
  100. targetMethod1Name ="getSkinUrl";
  101. targetMethod2Name = "getCapeUrl";
  102. }
  103.  
  104.  
  105. //on prepare la manipulation
  106. ClassNode classNode = new ClassNode();
  107. ClassReader classReader = new ClassReader(bytes);
  108. classReader.accept(classNode, 0);
  109.  
  110.  
  111. //Maintenant, on boucle sur toutes les methodes declarees dans la classe jusqu'a trouver la/les methode(s) cible(s)
  112. Iterator<MethodNode> methods = classNode.methods.iterator();
  113. while(methods.hasNext())
  114. {
  115. MethodNode m = methods.next();
  116. System.out.println("********* Method Name: "+m.name + " Desc:" + m.desc);
  117.  
  118.  
  119. //On verifie si il s'agit de la methode cible et si elle a la meme signature (plus de detail ici: http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html)
  120. if ((m.name.equals(targetMethod1Name) && m.desc.equals("(Ljava/lang/String;)Ljava/lang/String;")))
  121. {
  122. System.out.println("********* Inside target method1!");
  123.  
  124. //on creer une liste d'instruction pour invoquer une methode statique
  125. InsnList toInject = new InsnList();
  126. toInject.add(new VarInsnNode(ALOAD, 0));
  127. //new MethodInsnNode(on declare le type de la methode, "le chemin de la classe", "le nom de la methode", "sa signature")
  128. toInject.add(new MethodInsnNode(INVOKESTATIC, "pickandcraftSkin/PlayerCustom", "getURLSkinCustom", "(Ljava/lang/String;)Ljava/lang/String;"));
  129. toInject.add(new InsnNode(ARETURN));
  130.  
  131. // on remplace les instructions deja presente dans la methode par notre liste d'instruction
  132. m.instructions = toInject;
  133. ok1 = true;
  134. System.out.println("Patching Method1 Complete!");
  135. }
  136. else if ((m.name.equals(targetMethod2Name) && m.desc.equals("(Ljava/lang/String;)Ljava/lang/String;")))
  137. {
  138. System.out.println("********* Inside target2 method!");
  139. InsnList toInject = new InsnList();
  140.  
  141. toInject.add(new VarInsnNode(ALOAD, 0));
  142. toInject.add(new MethodInsnNode(INVOKESTATIC, "pickandcraftSkin/PlayerCustom", "getURLCapeCustom", "(Ljava/lang/String;)Ljava/lang/String;"));
  143. toInject.add(new InsnNode(ARETURN));
  144.  
  145. // on remplace les instructions deja presente dans la methode par notre liste d'instruction
  146. m.instructions = toInject;
  147. ok2 = true;
  148. System.out.println("Patching Method2 Complete!");
  149. }
  150.  
  151. if(ok1 && ok2)
  152. break;
  153. }
  154.  
  155. //on finit la manipulation
  156. ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
  157. classNode.accept(writer);
  158. return writer.toByteArray();
  159. }
  160.  
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement