⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utility.java

📁 Java Bytecode Editor 是一个 JAVA 的字节码反汇编和修改器。它可以很方便的修改已经编译成 Class 文件的 JAVA 文件。
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
      if(Constants.TYPE_NAMES[i].equals(type)) {
	found = true;
	buf.append(Constants.SHORT_TYPE_NAMES[i]);
      }
    }
    
    if(!found) // Class name
      buf.append('L' + type.replace('.', '/') + ';');

    return buf.toString();
  }

  private static int countBrackets(String brackets) {
    char[]  chars = brackets.toCharArray();
    int     count = 0;
    boolean open  = false;

    for(int i=0; i<chars.length; i++) {
      switch(chars[i]) {
      case '[':
	if(open)
	  throw new RuntimeException("Illegally nested brackets:" + brackets);
	open = true;
	break;

      case ']':
	if(!open)
	  throw new RuntimeException("Illegally nested brackets:" + brackets);
	open = false;
	count++;
	break;

      default:
	// Don't care
      }
    }

    if(open)
      throw new RuntimeException("Illegally nested brackets:" + brackets);

    return count;
  }

  /**
   * Return type of method signature as a byte value as defined in <em>Constants</em>
   *
   * @param  signature in format described above
   * @return type of method signature
   * @see    Constants
   */
  public static final byte typeOfMethodSignature(String signature)
    throws ClassFormatException
  {
    int index;

    try {
      if(signature.charAt(0) != '(')
	throw new ClassFormatException("Invalid method signature: " + signature);

      index = signature.lastIndexOf(')') + 1;
      return typeOfSignature(signature.substring(index));
    } catch(StringIndexOutOfBoundsException e) {
      throw new ClassFormatException("Invalid method signature: " + signature);
    }
  }

  /**
   * Return type of signature as a byte value as defined in <em>Constants</em>
   *
   * @param  signature in format described above
   * @return type of signature
   * @see    Constants
   */
  public static final byte typeOfSignature(String signature)
    throws ClassFormatException
  {
    try {
      switch(signature.charAt(0)) {
      case 'B' : return Constants.T_BYTE;
      case 'C' : return Constants.T_CHAR;
      case 'D' : return Constants.T_DOUBLE;
      case 'F' : return Constants.T_FLOAT;
      case 'I' : return Constants.T_INT;
      case 'J' : return Constants.T_LONG;
      case 'L' : return Constants.T_REFERENCE;
      case '[' : return Constants.T_ARRAY;
      case 'V' : return Constants.T_VOID;
      case 'Z' : return Constants.T_BOOLEAN;
      case 'S' : return Constants.T_SHORT;
      default:  
	throw new ClassFormatException("Invalid method signature: " + signature);
      }
    } catch(StringIndexOutOfBoundsException e) {
      throw new ClassFormatException("Invalid method signature: " + signature);
    }
  }

  /** Map opcode names to opcode numbers. E.g., return Constants.ALOAD for "aload"
   */
  public static short searchOpcode(String name) {
    name = name.toLowerCase();

    for(short i=0; i < Constants.OPCODE_NAMES.length; i++)
      if(Constants.OPCODE_NAMES[i].equals(name))
	return i;
    
    return -1;
  }

  /**
   * Convert (signed) byte to (unsigned) short value, i.e., all negative
   * values become positive.
   */
  private static final short byteToShort(byte b) {
    return (b < 0)? (short)(256 + b) : (short)b;
  }

  /** Convert bytes into hexidecimal string
   *
   * @return bytes as hexidecimal string, e.g. 00 FA 12 ...
   */
  public static final String toHexString(byte[] bytes) {
    StringBuffer buf = new StringBuffer();

    for(int i=0; i < bytes.length; i++) {
      short  b   = byteToShort(bytes[i]);
      String hex = Integer.toString(b, 0x10);

      if(b < 0x10) // just one digit, prepend '0'
	buf.append('0');

      buf.append(hex);

      if(i < bytes.length - 1)
	buf.append(' ');
    }

    return buf.toString();
  }

  /**
   * Return a string for an integer justified left or right and filled up with
   * `fill' characters if necessary.
   *
   * @param i integer to format
   * @param length length of desired string
   * @param left_justify format left or right
   * @param fill fill character
   * @return formatted int
   */
  public static final String format(int i, int length, boolean left_justify, char fill) {
    return fillup(Integer.toString(i), length, left_justify, fill);
  }

  /**
   * Fillup char with up to length characters with char `fill' and justify it left or right.
   *
   * @param str string to format
   * @param length length of desired string
   * @param left_justify format left or right
   * @param fill fill character
   * @return formatted string
   */
  public static final String fillup(String str, int length, boolean left_justify, char fill) {
    int    len = length - str.length();
    char[] buf = new char[(len < 0)? 0 : len];

    for(int j=0; j < buf.length; j++)
      buf[j] = fill;

    if(left_justify)
      return str + new String(buf);    
    else
      return new String(buf) + str;
  }

  static final boolean equals(byte[] a, byte[] b) {
    int size;

    if((size=a.length) != b.length)
      return false;

    for(int i=0; i < size; i++)
      if(a[i] != b[i])
	return false;

    return true;
  }

  public static final void printArray(PrintStream out, Object[] obj) {
    out.println(printArray(obj, true));
  }

  public static final void printArray(PrintWriter out, Object[] obj) {
    out.println(printArray(obj, true));
  }

  public static final String printArray(Object[] obj) {
    return printArray(obj, true);
  }

  public static final String printArray(Object[] obj, boolean braces) {
    return printArray(obj, braces, false);
  }

  public static final String printArray(Object[] obj, boolean braces,
					boolean quote) {
    if(obj == null)
      return null;

    StringBuffer buf = new StringBuffer();
    if(braces)
      buf.append('{');

    for(int i=0; i < obj.length; i++) {
      if(obj[i] != null) {
	buf.append((quote? "\"" : "") + obj[i].toString() + (quote? "\"" : ""));
      } else {
	buf.append("null");
      }

      if(i < obj.length - 1) {
	buf.append(", ");
      }
    }

    if(braces)
      buf.append('}');

    return buf.toString();
  }

  /** @return true, if character is one of (a, ... z, A, ... Z, 0, ... 9, _)
   */
  public static boolean isJavaIdentifierPart(char ch) {
    return ((ch >= 'a') && (ch <= 'z')) ||
      ((ch >= 'A') && (ch <= 'Z')) ||
      ((ch >= '0') && (ch <= '9')) ||
      (ch == '_');
  }

  /** Encode byte array it into Java identifier string, i.e., a string
   * that only contains the following characters: (a, ... z, A, ... Z,
   * 0, ... 9, _, $).  The encoding algorithm itself is not too
   * clever: if the current byte's ASCII value already is a valid Java
   * identifier part, leave it as it is. Otherwise it writes the
   * escape character($) followed by <p><ul><li> the ASCII value as a
   * hexadecimal string, if the value is not in the range
   * 200..247</li> <li>a Java identifier char not used in a lowercase
   * hexadecimal string, if the value is in the range
   * 200..247</li><ul></p>
   *
   * <p>This operation inflates the original byte array by roughly 40-50%</p>
   *
   * @param bytes the byte array to convert
   * @param compress use gzip to minimize string
   */
  public static String encode(byte[] bytes, boolean compress) throws IOException {
    if(compress) {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      GZIPOutputStream      gos  = new GZIPOutputStream(baos);

      gos.write(bytes, 0, bytes.length);
      gos.close();
      baos.close();

      bytes = baos.toByteArray();
    }

    CharArrayWriter caw = new CharArrayWriter();
    JavaWriter      jw  = new JavaWriter(caw);

    for(int i=0; i < bytes.length; i++) {
      int in = bytes[i] & 0x000000ff; // Normalize to unsigned
      jw.write(in);
    }

    return caw.toString();
  }

  /** Decode a string back to a byte array.
   *
   * @param bytes the byte array to convert
   * @param uncompress use gzip to uncompress the stream of bytes
   */
  public static byte[] decode(String s, boolean uncompress) throws IOException {
    char[] chars = s.toCharArray();

    CharArrayReader car = new CharArrayReader(chars);
    JavaReader      jr  = new JavaReader(car);

    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    int ch;

    while((ch = jr.read()) >= 0) {
      bos.write(ch);
    }

    bos.close();
    car.close();
    jr.close();

    byte[] bytes = bos.toByteArray();

    if(uncompress) {
      GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes));

      byte[] tmp   = new byte[bytes.length * 3]; // Rough estimate
      int    count = 0;
      int    b;

      while((b = gis.read()) >= 0)
	tmp[count++] = (byte)b;

      bytes = new byte[count];
      System.arraycopy(tmp, 0, bytes, 0, count);
    }

    return bytes;
  }

  // A-Z, g-z, _, $
  private static final int   FREE_CHARS  = 48;
  private static       int[] CHAR_MAP    = new int[FREE_CHARS];
  private static       int[] MAP_CHAR    = new int[256]; // Reverse map
  private static final char  ESCAPE_CHAR = '$';

  static {
    int j = 0;
    for(int i='A'; i <= 'Z'; i++) {
      CHAR_MAP[j] = i;
      MAP_CHAR[i] = j;
      j++;
    }

    for(int i='g'; i <= 'z'; i++) {
      CHAR_MAP[j] = i;
      MAP_CHAR[i] = j;
      j++;
    }

    CHAR_MAP[j]   = '$';
    MAP_CHAR['$'] = j;
    j++;

    CHAR_MAP[j]   = '_';
    MAP_CHAR['_'] = j;
  }

  /** Decode characters into bytes.
   * Used by <a href="Utility.html#decode(java.lang.String, boolean)">decode()</a>
   */
  private static class JavaReader extends FilterReader {
    public JavaReader(Reader in) {
      super(in);
    }

    public int read() throws IOException {
      int b = in.read();

      if(b != ESCAPE_CHAR) {
	return b;
      } else {
	int i = in.read();

	if(i < 0)
	  return -1;

	if(((i >= '0') && (i <= '9')) || ((i >= 'a') && (i <= 'f'))) { // Normal escape
	  int j = in.read();

	  if(j < 0)
	    return -1;

	  char[] tmp = { (char)i, (char)j };
	  int    s   = Integer.parseInt(new String(tmp), 16);

	  return s;
	} else { // Special escape
	  return MAP_CHAR[i];
	}
      }
    }

    public int read(char[] cbuf, int off, int len) throws IOException {
      for(int i=0; i < len; i++)
	cbuf[off + i] = (char)read();

      return len;
    }
  }

  /** Encode bytes into valid java identifier characters.
   * Used by <a href="Utility.html#encode(byte[], boolean)">encode()</a>
   */
  private static class JavaWriter extends FilterWriter {
    public JavaWriter(Writer out) {
      super(out);
    }

    public void write(int b) throws IOException {
      if(isJavaIdentifierPart((char)b) && (b != ESCAPE_CHAR)) {
	out.write(b);
      } else {
	out.write(ESCAPE_CHAR); // Escape character

	// Special escape
	if(b >= 0 && b < FREE_CHARS) {
	  out.write(CHAR_MAP[b]);
	} else { // Normal escape
	  char[] tmp = Integer.toHexString(b).toCharArray();

	  if(tmp.length == 1) {
	    out.write('0');
	    out.write(tmp[0]);
	  } else {
	    out.write(tmp[0]);
	    out.write(tmp[1]);
	  }
	}
      }
    }

    public void write(char[] cbuf, int off, int len) throws IOException {
      for(int i=0; i < len; i++)
	write(cbuf[off + i]);
    }

    public void write(String str, int off, int len) throws IOException {
      write(str.toCharArray(), off, len);
    }
  }

  /**
   * Escape all occurences of newline chars '\n', quotes \", etc.
   */
  public static final String convertString(String label) {
    char[]       ch  = label.toCharArray();
    StringBuffer buf = new StringBuffer();

    for(int i=0; i < ch.length; i++) {
      switch(ch[i]) {
      case '\n':
	buf.append("\\n"); break;
      case '\r':
	buf.append("\\r"); break;
      case '\"':
	buf.append("\\\""); break;
      case '\'':
	buf.append("\\'"); break;
      case '\\':
	buf.append("\\\\"); break;
      default:
	buf.append(ch[i]); break;
      }
    }

    return buf.toString();
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -