Example #1
0
 /**
  * Constructs a <code>method_info</code> structure. The initial value of <code>access_flags</code>
  * is zero.
  *
  * @param cp a constant pool table
  * @param methodname method name
  * @param desc method descriptor
  * @see Descriptor
  */
 public MethodInfo(ConstPool cp, String methodname, String desc) {
   this(cp);
   accessFlags = 0;
   name = cp.addUtf8Info(methodname);
   cachedName = methodname;
   descriptor = constPool.addUtf8Info(desc);
 }
Example #2
0
  /* skipSuper        1: this(), 0: super(), -1: both.
   */
  private int skipSuperConstructor0(int skipThis) throws BadBytecode {
    begin();
    ConstPool cp = codeAttr.getConstPool();
    String thisClassName = codeAttr.getDeclaringClass();
    int nested = 0;
    while (hasNext()) {
      int index = next();
      int c = byteAt(index);
      if (c == NEW) ++nested;
      else if (c == INVOKESPECIAL) {
        int mref = ByteArray.readU16bit(bytecode, index + 1);
        if (cp.getMethodrefName(mref).equals(MethodInfo.nameInit))
          if (--nested < 0) {
            if (skipThis < 0) return index;

            String cname = cp.getMethodrefClassName(mref);
            if (cname.equals(thisClassName) == (skipThis > 0)) return index;
            else break;
          }
      }
    }

    begin();
    return -1;
  }
Example #3
0
 @Override
 public AttributeInfo copy(final ConstPool newCp, final Map classnames) {
   final byte[] src = this.get();
   final byte[] dest = new byte[src.length];
   final ConstPool cp = this.getConstPool();
   final InnerClassesAttribute attr = new InnerClassesAttribute(newCp, dest);
   final int n = ByteArray.readU16bit(src, 0);
   ByteArray.write16bit(n, dest, 0);
   int j = 2;
   for (int i = 0; i < n; ++i) {
     int innerClass = ByteArray.readU16bit(src, j);
     int outerClass = ByteArray.readU16bit(src, j + 2);
     int innerName = ByteArray.readU16bit(src, j + 4);
     final int innerAccess = ByteArray.readU16bit(src, j + 6);
     if (innerClass != 0) {
       innerClass = cp.copy(innerClass, newCp, classnames);
     }
     ByteArray.write16bit(innerClass, dest, j);
     if (outerClass != 0) {
       outerClass = cp.copy(outerClass, newCp, classnames);
     }
     ByteArray.write16bit(outerClass, dest, j + 2);
     if (innerName != 0) {
       innerName = cp.copy(innerName, newCp, classnames);
     }
     ByteArray.write16bit(innerName, dest, j + 4);
     ByteArray.write16bit(innerAccess, dest, j + 6);
     j += 8;
   }
   return attr;
 }
Example #4
0
  void prune(ConstPool cp) {
    LinkedList newAttributes = new LinkedList();
    AttributeInfo invisibleAnnotations = getAttribute(AnnotationsAttribute.invisibleTag);
    if (invisibleAnnotations != null) {
      invisibleAnnotations = invisibleAnnotations.copy(cp, null);
      newAttributes.add(invisibleAnnotations);
    }

    AttributeInfo visibleAnnotations = getAttribute(AnnotationsAttribute.visibleTag);
    if (visibleAnnotations != null) {
      visibleAnnotations = visibleAnnotations.copy(cp, null);
      newAttributes.add(visibleAnnotations);
    }

    AttributeInfo signature = getAttribute(SignatureAttribute.tag);
    if (signature != null) {
      signature = signature.copy(cp, null);
      newAttributes.add(signature);
    }

    int index = getConstantValue();
    if (index != 0) {
      index = constPool.copy(index, cp, null);
      newAttributes.add(new ConstantAttribute(cp, index));
    }

    attribute = newAttributes;
    name = cp.addUtf8Info(getName());
    descriptor = cp.addUtf8Info(getDescriptor());
    constPool = cp;
  }
Example #5
0
 private void renameType(int pos, int index) {
   String name = cpool.getUtf8Info(index);
   String newName = Descriptor.rename(name, classnames);
   if (!name.equals(newName)) {
     int index2 = cpool.addUtf8Info(newName);
     ByteArray.write16bit(index2, info, pos);
   }
 }
 public EnclosingMethodAttribute(
     final ConstPool cp,
     final String className,
     final String methodName,
     final String methodDesc) {
   super(cp, "EnclosingMethod");
   final int ci = cp.addClassInfo(className);
   final int ni = cp.addNameAndTypeInfo(methodName, methodDesc);
   final byte[] bvalue = {(byte) (ci >>> 8), (byte) ci, (byte) (ni >>> 8), (byte) ni};
   this.set(bvalue);
 }
 private static String fieldInfo(ConstPool pool, int index) {
   return "#"
       + index
       + " = Field "
       + pool.getFieldrefClassName(index)
       + "."
       + pool.getFieldrefName(index)
       + "("
       + pool.getFieldrefType(index)
       + ")";
 }
 private static String methodInfo(ConstPool pool, int index) {
   return "#"
       + index
       + " = Method "
       + pool.getMethodrefClassName(index)
       + "."
       + pool.getMethodrefName(index)
       + "("
       + pool.getMethodrefType(index)
       + ")";
 }
  /**
   * Copies the contents from a source attribute. Specified class names are replaced during the
   * copy.
   *
   * @param srcAttr source Exceptions attribute
   * @param classnames pairs of replaced and substituted class names.
   */
  private void copyFrom(ExceptionsAttribute srcAttr, Map classnames) {
    ConstPool srcCp = srcAttr.constPool;
    ConstPool destCp = this.constPool;
    byte[] src = srcAttr.info;
    int num = src.length;
    byte[] dest = new byte[num];
    dest[0] = src[0];
    dest[1] = src[1]; // the number of elements.
    for (int i = 2; i < num; i += 2) {
      int index = ByteArray.readU16bit(src, i);
      ByteArray.write16bit(srcCp.copy(index, destCp, classnames), dest, i);
    }

    this.info = dest;
  }
Example #10
0
  /**
   * Changes a super constructor called by this constructor.
   *
   * <p>This method modifies a call to <code>super()</code>, which should be at the head of a
   * constructor body, so that a constructor in a different super class is called. This method does
   * not change actural parameters. Hence the new super class must have a constructor with the same
   * signature as the original one.
   *
   * <p>This method should be called when the super class of the class declaring this method is
   * changed.
   *
   * <p>This method does not perform anything unless this <code>MethodInfo</code> represents a
   * constructor.
   *
   * @param superclass the new super class
   */
  public void setSuperclass(String superclass) throws BadBytecode {
    if (!isConstructor()) return;

    CodeAttribute ca = getCodeAttribute();
    byte[] code = ca.getCode();
    CodeIterator iterator = ca.iterator();
    int pos = iterator.skipSuperConstructor();
    if (pos >= 0) { // not this()
      ConstPool cp = constPool;
      int mref = ByteArray.readU16bit(code, pos + 1);
      int nt = cp.getMethodrefNameAndType(mref);
      int sc = cp.addClassInfo(superclass);
      int mref2 = cp.addMethodrefInfo(sc, nt);
      ByteArray.write16bit(mref2, code, pos + 1);
    }
  }
Example #11
0
 private static void copyConstPoolInfo(
     int i, byte[] code, ConstPool srcCp, byte[] newcode, ConstPool destCp, Map classnameMap) {
   int index = ((code[i] & 0xff) << 8) | (code[i + 1] & 0xff);
   index = srcCp.copy(index, destCp, classnameMap);
   newcode[i] = (byte) (index >> 8);
   newcode[i + 1] = (byte) index;
 }
Example #12
0
  void prune(ConstPool cp) {
    LinkedList newAttributes = new LinkedList();

    AttributeInfo invisibleAnnotations = getAttribute(AnnotationsAttribute.invisibleTag);
    if (invisibleAnnotations != null) {
      invisibleAnnotations = invisibleAnnotations.copy(cp, null);
      newAttributes.add(invisibleAnnotations);
    }

    AttributeInfo visibleAnnotations = getAttribute(AnnotationsAttribute.visibleTag);
    if (visibleAnnotations != null) {
      visibleAnnotations = visibleAnnotations.copy(cp, null);
      newAttributes.add(visibleAnnotations);
    }

    AttributeInfo parameterInvisibleAnnotations =
        getAttribute(ParameterAnnotationsAttribute.invisibleTag);
    if (parameterInvisibleAnnotations != null) {
      parameterInvisibleAnnotations = parameterInvisibleAnnotations.copy(cp, null);
      newAttributes.add(parameterInvisibleAnnotations);
    }

    AttributeInfo parameterVisibleAnnotations =
        getAttribute(ParameterAnnotationsAttribute.visibleTag);
    if (parameterVisibleAnnotations != null) {
      parameterVisibleAnnotations = parameterVisibleAnnotations.copy(cp, null);
      newAttributes.add(parameterVisibleAnnotations);
    }

    AnnotationDefaultAttribute defaultAttribute =
        (AnnotationDefaultAttribute) getAttribute(AnnotationDefaultAttribute.tag);
    if (defaultAttribute != null) newAttributes.add(defaultAttribute);

    ExceptionsAttribute ea = getExceptionsAttribute();
    if (ea != null) newAttributes.add(ea);

    AttributeInfo signature = getAttribute(SignatureAttribute.tag);
    if (signature != null) {
      signature = signature.copy(cp, null);
      newAttributes.add(signature);
    }

    attribute = newAttributes;
    name = cp.addUtf8Info(getName());
    descriptor = cp.addUtf8Info(getDescriptor());
    constPool = cp;
  }
Example #13
0
  private void read(MethodInfo src, String methodname, Map classnames) throws BadBytecode {
    ConstPool destCp = constPool;
    accessFlags = src.accessFlags;
    name = destCp.addUtf8Info(methodname);
    cachedName = methodname;
    ConstPool srcCp = src.constPool;
    String desc = srcCp.getUtf8Info(src.descriptor);
    String desc2 = Descriptor.rename(desc, classnames);
    descriptor = destCp.addUtf8Info(desc2);

    attribute = new LinkedList();
    ExceptionsAttribute eattr = src.getExceptionsAttribute();
    if (eattr != null) attribute.add(eattr.copy(destCp, classnames));

    CodeAttribute cattr = src.getCodeAttribute();
    if (cattr != null) attribute.add(cattr.copy(destCp, classnames));
  }
    protected int[] copyData(int[] tags, int[] data) {
      int[] newData = new int[data.length];
      for (int i = 0; i < data.length; i++)
        if (tags[i] == OBJECT) newData[i] = srcPool.copy(data[i], destPool, classnames);
        else newData[i] = data[i];

      return newData;
    }
  static AttributeInfo read(ConstPool cp, DataInputStream in) throws IOException {
    int name = in.readUnsignedShort();
    String nameStr = cp.getUtf8Info(name);
    if (nameStr.charAt(0) < 'L') {
      if (nameStr.equals(AnnotationDefaultAttribute.tag))
        return new AnnotationDefaultAttribute(cp, name, in);
      else if (nameStr.equals(CodeAttribute.tag)) return new CodeAttribute(cp, name, in);
      else if (nameStr.equals(ConstantAttribute.tag)) return new ConstantAttribute(cp, name, in);
      else if (nameStr.equals(DeprecatedAttribute.tag))
        return new DeprecatedAttribute(cp, name, in);
      else if (nameStr.equals(EnclosingMethodAttribute.tag))
        return new EnclosingMethodAttribute(cp, name, in);
      else if (nameStr.equals(ExceptionsAttribute.tag))
        return new ExceptionsAttribute(cp, name, in);
      else if (nameStr.equals(InnerClassesAttribute.tag))
        return new InnerClassesAttribute(cp, name, in);
    } else {
      /* Note that the names of Annotations attributes begin with 'R'.
       */
      if (nameStr.equals(LineNumberAttribute.tag)) return new LineNumberAttribute(cp, name, in);
      else if (nameStr.equals(LocalVariableAttribute.tag)
          || nameStr.equals(LocalVariableAttribute.typeTag))
        return new LocalVariableAttribute(cp, name, in);
      else if (nameStr.equals(AnnotationsAttribute.visibleTag)
          || nameStr.equals(AnnotationsAttribute.invisibleTag)) {
        // RuntimeVisibleAnnotations or RuntimeInvisibleAnnotations
        return new AnnotationsAttribute(cp, name, in);
      } else if (nameStr.equals(ParameterAnnotationsAttribute.visibleTag)
          || nameStr.equals(ParameterAnnotationsAttribute.invisibleTag))
        return new ParameterAnnotationsAttribute(cp, name, in);
      else if (nameStr.equals(SignatureAttribute.tag)) return new SignatureAttribute(cp, name, in);
      else if (nameStr.equals(SourceFileAttribute.tag))
        return new SourceFileAttribute(cp, name, in);
      else if (nameStr.equals(SyntheticAttribute.tag)) return new SyntheticAttribute(cp, name, in);
      else if (nameStr.equals(StackMapTable.tag)) return new StackMapTable(cp, name, in);
    }

    return new AttributeInfo(cp, name, in);
  }
 private static String ldc(ConstPool pool, int index) {
   int tag = pool.getTag(index);
   switch (tag) {
     case ConstPool.CONST_String:
       return "#" + index + " = \"" + pool.getStringInfo(index) + "\"";
     case ConstPool.CONST_Integer:
       return "#" + index + " = int " + pool.getIntegerInfo(index);
     case ConstPool.CONST_Float:
       return "#" + index + " = float " + pool.getFloatInfo(index);
     case ConstPool.CONST_Long:
       return "#" + index + " = long " + pool.getLongInfo(index);
     case ConstPool.CONST_Double:
       return "#" + index + " = int " + pool.getDoubleInfo(index);
     case ConstPool.CONST_Class:
       return classInfo(pool, index);
     default:
       throw new RuntimeException("bad LDC: " + tag);
   }
 }
Example #17
0
 /**
  * Returns a method descriptor.
  *
  * @see Descriptor
  */
 public String getDescriptor() {
   return constPool.getUtf8Info(descriptor);
 }
 /**
  * Constructs an <code>attribute_info</code> structure.
  *
  * @param cp constant pool table
  * @param attrname attribute name
  * @param attrinfo <code>info</code> field of <code>attribute_info</code> structure.
  */
 public AttributeInfo(ConstPool cp, String attrname, byte[] attrinfo) {
   this(cp, cp.addUtf8Info(attrname), attrinfo);
 }
 /** Returns an attribute name. */
 public String getName() {
   return constPool.getUtf8Info(name);
 }
Example #20
0
 /**
  * Copies a constant pool entry into the destination constant pool and returns the index of the
  * copied entry. That entry must be a Utf8Info representing a class name in the L<class name>;
  * form.
  *
  * @param srcIndex the index of the copied entry into the source constant pool.
  * @return the index of the copied item into the destination constant pool.
  */
 int copyType(int srcIndex) {
   String name = srcPool.getUtf8Info(srcIndex);
   String newName = Descriptor.rename(name, classnames);
   return destPool.addUtf8Info(newName);
 }
Example #21
0
 /**
  * Copies a constant pool entry into the destination constant pool and returns the index of the
  * copied entry.
  *
  * @param srcIndex the index of the copied entry into the source constant pool.
  * @return the index of the copied item into the destination constant pool.
  */
 int copy(int srcIndex) {
   return srcPool.copy(srcIndex, destPool, classnames);
 }
 public String methodName() {
   final ConstPool cp = this.getConstPool();
   final int mi = this.methodIndex();
   final int ni = cp.getNameAndTypeName(mi);
   return cp.getUtf8Info(ni);
 }
Example #23
0
 public boolean match(String filename, ClassFile classFile, ClassMap tempClassMap) {
   for (Object o : classFile.getMethods()) {
     MethodInfo methodInfo = (MethodInfo) o;
     classMod.methodInfo = methodInfo;
     CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
     if (codeAttribute == null) {
       continue;
     }
     if (getClassMap().hasMap(deobfMethod)) {
       MethodRef obfTarget = (MethodRef) getClassMap().map(deobfMethod);
       if (!methodInfo.getName().equals(obfTarget.getName())) {
         continue;
       }
     }
     ArrayList<String> deobfTypes = null;
     ArrayList<String> obfTypes = null;
     if (deobfMethod != null && deobfMethod.getType() != null) {
       deobfTypes = ConstPoolUtils.parseDescriptor(deobfMethod.getType());
       obfTypes = ConstPoolUtils.parseDescriptor(methodInfo.getDescriptor());
       if (!isPotentialTypeMatch(deobfTypes, obfTypes)) {
         continue;
       }
     }
     ConstPool constPool = methodInfo.getConstPool();
     CodeIterator codeIterator = codeAttribute.iterator();
     initMatcher();
     ArrayList<JavaRef> tempMappings = new ArrayList<JavaRef>();
     try {
       match:
       for (int offset = 0;
           offset < codeIterator.getCodeLength() && matcher.match(methodInfo, offset);
           offset = codeIterator.next()) {
         tempMappings.clear();
         for (Map.Entry<Integer, JavaRef> entry : xrefs.entrySet()) {
           int captureGroup = entry.getKey();
           JavaRef xref = entry.getValue();
           byte[] code = matcher.getCaptureGroup(captureGroup);
           int index = Util.demarshal(code, 1, 2);
           ConstPoolUtils.matchOpcodeToRefType(code[0], xref);
           ConstPoolUtils.matchConstPoolTagToRefType(constPool.getTag(index), xref);
           JavaRef newRef = ConstPoolUtils.getRefForIndex(constPool, index);
           if (!isPotentialTypeMatch(xref.getType(), newRef.getType())) {
             if (deobfMethod != null) {
               Logger.log(
                   Logger.LOG_METHOD,
                   "method %s %s matches %s %s, but",
                   methodInfo.getName(),
                   methodInfo.getDescriptor(),
                   deobfMethod.getName(),
                   deobfMethod.getType());
             }
             Logger.log(
                 Logger.LOG_METHOD,
                 "method %s %s failed xref #%d %s %s -> %s %s",
                 methodInfo.getName(),
                 methodInfo.getDescriptor(),
                 captureGroup,
                 xref.getName(),
                 xref.getType(),
                 newRef.getName(),
                 newRef.getType());
             continue match;
           }
           tempMappings.add(xref);
           tempMappings.add(newRef);
         }
         for (int i = 0; i + 1 < tempMappings.size(); i += 2) {
           tempClassMap.addMap(tempMappings.get(i), tempMappings.get(i + 1));
         }
         if (deobfMethod != null) {
           String deobfName = classMod.getDeobfClass();
           tempClassMap.addClassMap(deobfName, ClassMap.filenameToClassName(filename));
           tempClassMap.addMethodMap(
               deobfName, deobfMethod.getName(), methodInfo.getName(), methodInfo.getDescriptor());
           if (deobfTypes != null && obfTypes != null) {
             for (int i = 0; i < deobfTypes.size(); i++) {
               String desc = ClassMap.descriptorToClassName(deobfTypes.get(i));
               String obf = ClassMap.descriptorToClassName(obfTypes.get(i));
               if (!obf.equals(desc)) {
                 tempClassMap.addClassMap(desc, obf);
               }
             }
           }
         }
         afterMatch(classFile, methodInfo);
         classMod.methodInfo = null;
         return true;
       }
     } catch (BadBytecode e) {
       Logger.log(e);
     }
   }
   classMod.methodInfo = null;
   return false;
 }
Example #24
0
 /** Returns the name of the class declaring the method including this code attribute. */
 public String getDeclaringClass() {
   ConstPool cp = getConstPool();
   return cp.getClassName();
 }
Example #25
0
  private static LdcEntry copyCode(
      byte[] code,
      int beginPos,
      int endPos,
      ConstPool srcCp,
      byte[] newcode,
      ConstPool destCp,
      Map classnameMap)
      throws BadBytecode {
    int i2, index;
    LdcEntry ldcEntry = null;

    for (int i = beginPos; i < endPos; i = i2) {
      i2 = CodeIterator.nextOpcode(code, i);
      byte c = code[i];
      newcode[i] = c;
      switch (c & 0xff) {
        case LDC_W:
        case LDC2_W:
        case GETSTATIC:
        case PUTSTATIC:
        case GETFIELD:
        case PUTFIELD:
        case INVOKEVIRTUAL:
        case INVOKESPECIAL:
        case INVOKESTATIC:
        case NEW:
        case ANEWARRAY:
        case CHECKCAST:
        case INSTANCEOF:
          copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp, classnameMap);
          break;
        case LDC:
          index = code[i + 1] & 0xff;
          index = srcCp.copy(index, destCp, classnameMap);
          if (index < 0x100) newcode[i + 1] = (byte) index;
          else {
            newcode[i] = NOP;
            newcode[i + 1] = NOP;
            LdcEntry ldc = new LdcEntry();
            ldc.where = i;
            ldc.index = index;
            ldc.next = ldcEntry;
            ldcEntry = ldc;
          }
          break;
        case INVOKEINTERFACE:
          copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp, classnameMap);
          newcode[i + 3] = code[i + 3];
          newcode[i + 4] = code[i + 4];
          break;
        case INVOKEDYNAMIC:
          copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp, classnameMap);
          newcode[i + 3] = 0;
          newcode[i + 4] = 0;
          break;
        case MULTIANEWARRAY:
          copyConstPoolInfo(i + 1, code, srcCp, newcode, destCp, classnameMap);
          newcode[i + 3] = code[i + 3];
          break;
        default:
          while (++i < i2) newcode[i] = code[i];

          break;
      }
    }

    return ldcEntry;
  }
 public String methodDescriptor() {
   final ConstPool cp = this.getConstPool();
   final int mi = this.methodIndex();
   final int ti = cp.getNameAndTypeDescriptor(mi);
   return cp.getUtf8Info(ti);
 }
Example #27
0
 /**
  * Copies all constant pool items to a given new constant pool and replaces the original items
  * with the new ones. This is used for garbage collecting the items of removed fields and methods.
  *
  * @param cp the destination
  */
 void compact(ConstPool cp) {
   name = cp.addUtf8Info(getName());
   descriptor = cp.addUtf8Info(getDescriptor());
   attribute = AttributeInfo.copyAll(attribute, cp);
   constPool = cp;
 }
Example #28
0
  /** Returns a method name. */
  public String getName() {
    if (cachedName == null) cachedName = constPool.getUtf8Info(name);

    return cachedName;
  }
Example #29
0
 /**
  * Sets a method descriptor.
  *
  * @see Descriptor
  */
 public void setDescriptor(String desc) {
   if (!desc.equals(getDescriptor())) descriptor = constPool.addUtf8Info(desc);
 }
Example #30
0
 /** Sets a method name. */
 public void setName(String newName) {
   name = constPool.addUtf8Info(newName);
   cachedName = newName;
 }