Esempio n. 1
0
  @Override
  public byte[] transform(String name, String transformedName, byte[] bytes) {
    if (bytes == null) {
      return null;
    }

    if (DEBUG) {
      FMLRelaunchLog.fine("Considering all methods and fields on %s (%s)\n", name, transformedName);
    }
    if (!modifiers.containsKey(name)) {
      return bytes;
    }

    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);

    Collection<Modifier> mods = modifiers.get(name);
    for (Modifier m : mods) {
      if (m.modifyClassVisibility) {
        classNode.access = getFixedAccess(classNode.access, m);
        if (DEBUG) {
          System.out.println(
              String.format(
                  "Class: %s %s -> %s", name, toBinary(m.oldAccess), toBinary(m.newAccess)));
        }
        continue;
      }
      if (m.desc.isEmpty()) {
        for (FieldNode n : classNode.fields) {
          if (n.name.equals(m.name) || m.name.equals("*")) {
            n.access = getFixedAccess(n.access, m);
            if (DEBUG) {
              System.out.println(
                  String.format(
                      "Field: %s.%s %s -> %s",
                      name, n.name, toBinary(m.oldAccess), toBinary(m.newAccess)));
            }

            if (!m.name.equals("*")) {
              break;
            }
          }
        }
      } else {
        for (MethodNode n : classNode.methods) {
          if ((n.name.equals(m.name) && n.desc.equals(m.desc)) || m.name.equals("*")) {
            n.access = getFixedAccess(n.access, m);
            if (DEBUG) {
              System.out.println(
                  String.format(
                      "Method: %s.%s%s %s -> %s",
                      name, n.name, n.desc, toBinary(m.oldAccess), toBinary(m.newAccess)));
            }

            if (!m.name.equals("*")) {
              break;
            }
          }
        }
      }
    }

    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(writer);
    return writer.toByteArray();
  }
Esempio n. 2
0
  @Override
  public byte[] transform(String name, String transformedName, byte[] bytes) {
    if (bytes == null) {
      return null;
    }
    boolean makeAllPublic = FMLDeobfuscatingRemapper.INSTANCE.isRemappedClass(name);

    if (DEBUG) {
      FMLRelaunchLog.fine(
          "Considering all methods and fields on %s (%s): %b\n",
          name, transformedName, makeAllPublic);
    }
    if (!makeAllPublic && !modifiers.containsKey(name)) {
      return bytes;
    }

    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);

    if (makeAllPublic) {
      // class
      Modifier m = new Modifier();
      m.targetAccess = ACC_PUBLIC;
      m.modifyClassVisibility = true;
      modifiers.put(name, m);
      // fields
      m = new Modifier();
      m.targetAccess = ACC_PUBLIC;
      m.name = "*";
      modifiers.put(name, m);
      // methods
      m = new Modifier();
      m.targetAccess = ACC_PUBLIC;
      m.name = "*";
      m.desc = "<dummy>";
      modifiers.put(name, m);
      if (DEBUG) {
        System.out.printf("Injected all public modifiers for %s (%s)\n", name, transformedName);
      }
    }

    Collection<Modifier> mods = modifiers.get(name);
    for (Modifier m : mods) {
      if (m.modifyClassVisibility) {
        classNode.access = getFixedAccess(classNode.access, m);
        if (DEBUG) {
          System.out.println(
              String.format(
                  "Class: %s %s -> %s", name, toBinary(m.oldAccess), toBinary(m.newAccess)));
        }
        continue;
      }
      if (m.desc.isEmpty()) {
        for (FieldNode n : classNode.fields) {
          if (n.name.equals(m.name) || m.name.equals("*")) {
            n.access = getFixedAccess(n.access, m);
            if (DEBUG) {
              System.out.println(
                  String.format(
                      "Field: %s.%s %s -> %s",
                      name, n.name, toBinary(m.oldAccess), toBinary(m.newAccess)));
            }

            if (!m.name.equals("*")) {
              break;
            }
          }
        }
      } else {
        for (MethodNode n : classNode.methods) {
          if ((n.name.equals(m.name) && n.desc.equals(m.desc)) || m.name.equals("*")) {
            n.access = getFixedAccess(n.access, m);
            if (DEBUG) {
              System.out.println(
                  String.format(
                      "Method: %s.%s%s %s -> %s",
                      name, n.name, n.desc, toBinary(m.oldAccess), toBinary(m.newAccess)));
            }

            if (!m.name.equals("*")) {
              break;
            }
          }
        }
      }
    }

    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(writer);
    return writer.toByteArray();
  }
Esempio n. 3
0
  void writeHeader() {
    int access = 0;
    if (statement != null) {
      if (compiler.getScope().isDebugMode()) {
        statement.setDynamicLocal(true);
      }

      switch (statement.getModifier()) {
        case PRIVATE:
          access += Opcodes.ACC_PRIVATE;
          break;
        case PROTECTED:
          access += Opcodes.ACC_PROTECTED;
          break;
        case PUBLIC:
          access += Opcodes.ACC_PUBLIC;
          break;
      }

      if (statement.isStatic()) access += Opcodes.ACC_STATIC;
      // if (statement.isAbstract()) access += Opcodes.ACC_ABSTRACT;
      if (statement.isFinal()) access += Opcodes.ACC_FINAL;

      node.access = access;
      node.name =
          clazz.isSystem() || entity == null
              ? statement.getName().getName()
              : entity.getInternalName();
      node.desc =
          Type.getMethodDescriptor(
              Type.getType(Memory.class),
              Type.getType(Environment.class),
              Type.getType(Memory[].class));

      if (external) {
        node.desc =
            Type.getMethodDescriptor(
                Type.getType(Memory.class),
                Type.getType(Environment.class),
                Type.getType(Memory[].class),
                Type.getType(ArrayMemory.class));
      }
    }

    if (statement != null) {
      LabelNode label = labelStart = writeLabel(node, statement.getMeta().getStartLine());

      if (!statement.isStatic()) addLocalVariable("~this", label, Object.class);

      ExpressionStmtCompiler expressionCompiler = new ExpressionStmtCompiler(this, null);

      addLocalVariable("~env", label, Environment.class); // Environment env
      LocalVariable args = addLocalVariable("~args", label, Memory[].class); // Memory[] arguments

      if (statement.isDynamicLocal()) {
        if (external) addLocalVariable("~passedLocal", label, ArrayMemory.class);

        LocalVariable local = addLocalVariable("~local", label, ArrayMemory.class);

        if (external) {
          expressionCompiler.writeVarLoad("~passedLocal");
          expressionCompiler.writeSysStaticCall(
              ArrayMemory.class, "valueOfRef", ArrayMemory.class, ArrayMemory.class);
          expressionCompiler.setStackPeekAsImmutable();
          expressionCompiler.writeVarStore(local, false, true);
        } else {
          expressionCompiler.writePushConstNull();
          expressionCompiler.writeSysStaticCall(
              ArrayMemory.class, "valueOfRef", ArrayMemory.class, ArrayMemory.class);
          expressionCompiler.setStackPeekAsImmutable();
          expressionCompiler.writeVarStore(local, false, true);
        }
      }

      if (statement.getUses() != null && !statement.getUses().isEmpty()) {
        int i = 0;
        expressionCompiler.writeVarLoad("~this");
        expressionCompiler.writeGetDynamic("uses", Memory[].class);

        for (ArgumentStmtToken argument : statement.getUses()) {
          LocalVariable local;
          if (statement.isDynamicLocal()) {
            expressionCompiler.writeDefineVariable(argument.getName());
            local = getLocalVariable(argument.getName().getName());
          } else {
            local = addLocalVariable(argument.getName().getName(), label, Memory.class);
          }

          if (argument.isReference()) {
            local.setReference(true);
            statement.variable(argument.getName()).setUnstable(true);
          }

          expressionCompiler.writePushDup();
          expressionCompiler.writePushGetFromArray(i, Memory.class);

          if (statement.isDynamicLocal()) {
            expressionCompiler.writeVarAssign(local, argument.getName(), false, false);
          } else {
            expressionCompiler.writeVarStore(local, false, false);
          }

          local.pushLevel();
          i++;
        }
        expressionCompiler.writePopAll(1);
      }

      int i = 0;

      for (ArgumentStmtToken argument : statement.getArguments()) {
        if (argument.isReference()) {
          statement.variable(argument.getName()).setReference(true).setUnstable(true);
        }

        LabelNode next = new LabelNode();

        expressionCompiler.writeDefineVariable(argument.getName());
        LocalVariable local = getLocalVariable(argument.getName().getName());

        if (local != null) {
          expressionCompiler.writeVarLoad(args);
          expressionCompiler.writePushGetFromArray(i, Memory.class);
          expressionCompiler.writeVarAssign(local, argument.getName(), true, false);

          // if length <= i then undefined
          node.instructions.add(new JumpInsnNode(Opcodes.IFNONNULL, next));
          expressionCompiler.stackPop();

          if (argument.getValue() == null) expressionCompiler.writePushNull();
          else expressionCompiler.writeExpression(argument.getValue(), true, false);

          expressionCompiler.writeVarAssign(local, argument.getName(), false, false);
          node.instructions.add(next);

          local.pushLevel();
        }

        i++;
      }
    } else {
      LabelNode label = labelStart = writeLabel(node, clazz.statement.getMeta().getStartLine());
    }
  }