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

📄 utility.java

📁 Java Bytecode Editor 是一个 JAVA 的字节码反汇编和修改器。它可以很方便的修改已经编译成 Class 文件的 JAVA 文件。
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
   * @param str The long class name
   * @param prefix The prefix the get rid off
   * @param chopit Flag that determines whether chopping is executed or not
   * @return Compacted class name
   */
  public static final String compactClassName(String str, 
					      String prefix,
					      boolean chopit)
  {
    int len = prefix.length();

    str = str.replace('/', '.'); // Is `/' on all systems, even DOS

    if(chopit) {
      // If string starts with `prefix' and contains no further dots
      if(str.startsWith(prefix) &&
	 (str.substring(len).indexOf('.') == -1))
	str = str.substring(len);
    }
	
    return str;
  }

  /**
   * Shorten long class names, <em>java/lang/String</em> becomes 
   * <em>java.lang.String</em>,
   * e.g.. If <em>chopit</em> is <em>true</em> the prefix <em>java.lang</em>
   * is also removed.
   *
   * @param str The long class name
   * @param chopit Flag that determines whether chopping is executed or not
   * @return Compacted class name
   */
  public static final String compactClassName(String str, boolean chopit) {
    return compactClassName(str, "java.lang.", chopit);
  }    

  /**
   * @return `flag' with bit `i' set to 1
   */
  public static final int setBit(int flag, int i) {
    return flag | pow2(i); 
  }

  /**
   * @return `flag' with bit `i' set to 0
   */
  public static final int clearBit(int flag, int i) {
    int bit = pow2(i); 
    return (flag & bit) == 0? flag : flag ^ bit; 
  }
   
  /**
   * @return true, if bit `i' in `flag' is set
   */
  public static final boolean isSet(int flag, int i) {
    return (flag & pow2(i)) != 0;
  }

  /**
   * Converts string containing the method return and argument types 
   * to a byte code method signature.
   *
   * @param  ret Return type of method
   * @param  argv Types of method arguments
   * @return Byte code representation of method signature
   */
  public final static String methodTypeToSignature(String ret, String[] argv)
    throws ClassFormatException
  {
    StringBuffer buf = new StringBuffer("(");
    String       str;

    if(argv != null)
      for(int i=0; i < argv.length; i++) {
	str = getSignature(argv[i]);

	if(str.endsWith("V")) // void can't be a method argument
	  throw new ClassFormatException("Invalid type: " + argv[i]);

	buf.append(str);
      }

    str = getSignature(ret);

    buf.append(")" + str);

    return buf.toString();
  }

  /**
   * @param  signature    Method signature
   * @return Array of argument types
   * @throws  ClassFormatException  
   */
  public static final String[] methodSignatureArgumentTypes(String signature)
    throws ClassFormatException 
  {
    return methodSignatureArgumentTypes(signature, true);
  }    

  /**
   * @param  signature    Method signature
   * @param chopit Shorten class names ?
   * @return Array of argument types
   * @throws  ClassFormatException  
   */
  public static final String[] methodSignatureArgumentTypes(String signature,
							    boolean chopit)
    throws ClassFormatException
  {
    ArrayList<String> vec = new ArrayList<String>();
    int       index;
    String[]  types;

    try { // Read all declarations between for `(' and `)'
      if(signature.charAt(0) != '(')
	throw new ClassFormatException("Invalid method signature: " + signature);

      index = 1; // current string position

      while(signature.charAt(index) != ')') {
	vec.add(signatureToString(signature.substring(index), chopit));
	index += consumed_chars; // update position
      }
    } catch(StringIndexOutOfBoundsException e) { // Should never occur
      throw new ClassFormatException("Invalid method signature: " + signature);
    }
	
    types = new String[vec.size()];
    vec.toArray(types);
    return types;
  }      
  /**
   * @param  signature    Method signature
   * @return return type of method
   * @throws  ClassFormatException  
   */
  public static final String methodSignatureReturnType(String signature)
       throws ClassFormatException 
  {
    return methodSignatureReturnType(signature, true);
  }    
  /**
   * @param  signature    Method signature
   * @param chopit Shorten class names ?
   * @return return type of method
   * @throws  ClassFormatException  
   */
  public static final String methodSignatureReturnType(String signature,
						       boolean chopit)
       throws ClassFormatException
  {
    int    index;
    String type;

    try {
      // Read return type after `)'
      index = signature.lastIndexOf(')') + 1; 
      type = signatureToString(signature.substring(index), chopit);
    } catch(StringIndexOutOfBoundsException e) { // Should never occur
      throw new ClassFormatException("Invalid method signature: " + signature);
    }

    return type;
  }

  /**
   * Converts method signature to string with all class names compacted.
   *
   * @param signature to convert
   * @param name of method
   * @param access flags of method
   * @return Human readable signature
   */
  public static final String methodSignatureToString(String signature,
						     String name,
						     String access) {
    return methodSignatureToString(signature, name, access, true);
  }

  public static final String methodSignatureToString(String signature,
						     String name,
						     String access,
						     boolean chopit) {
    return methodSignatureToString(signature, name, access, chopit, null);
  }

  /**
   * A return璽ype signature represents the return value from a method.
   * It is a series of bytes in the following grammar:
   *
   * <return_signature> ::= <field_type> | V
   *
   * The character V indicates that the method returns no value. Otherwise, the
   * signature indicates the type of the return value.
   * An argument signature represents an argument passed to a method:
   *
   * <argument_signature> ::= <field_type>
   *
   * A method signature represents the arguments that the method expects, and
   * the value that it returns.
   * <method_signature> ::= (<arguments_signature>) <return_signature>
   * <arguments_signature>::= <argument_signature>*
   *
   * This method converts such a string into a Java type declaration like
   * `void main(String[])' and throws a `ClassFormatException' when the parsed 
   * type is invalid.
   *
   * @param  signature    Method signature
   * @param  name         Method name
   * @param  access       Method access rights
   * @return Java type declaration
   * @throws  ClassFormatException  
   */
  public static final String methodSignatureToString(String signature,
						     String name,
						     String access,
						     boolean chopit,
						     LocalVariableTable vars)
    throws ClassFormatException
  {
    StringBuffer buf = new StringBuffer("(");
    String       type;
    int          index;
    int          var_index = (access.indexOf("static") >= 0)? 0 : 1;

    try { // Read all declarations between for `(' and `)'
      if(signature.charAt(0) != '(')
	throw new ClassFormatException("Invalid method signature: " + signature);

      index = 1; // current string position

      while(signature.charAt(index) != ')') {
	String param_type = signatureToString(signature.substring(index), chopit);
	buf.append(param_type);

	if(vars != null) {
	  LocalVariable l = vars.getLocalVariable(var_index);

	  if(l != null)
	    buf.append(" " + l.getName());
	} else
	  buf.append(" arg" + var_index);

	if("double".equals(param_type) || "long".equals(param_type))
	  var_index += 2;
	else
	  var_index++;

	buf.append(", ");
	index += consumed_chars; // update position
      }

      index++; // update position

      // Read return type after `)'
      type = signatureToString(signature.substring(index), chopit);

    } catch(StringIndexOutOfBoundsException e) { // Should never occur
      throw new ClassFormatException("Invalid method signature: " + signature);
    }

    if(buf.length() > 1) // Tack off the extra ", "
      buf.setLength(buf.length() - 2);

    buf.append(")");

    return access + ((access.length() > 0)? " " : "") + // May be an empty string
      type + " " + name + buf.toString();
  }

  // Guess what this does
  private static final int pow2(int n) {
    return 1 << n;
  }
    
  /**
   * Replace all occurences of <em>old</em> in <em>str</em> with <em>new</em>.
   *
   * @param str String to permute
   * @param old String to be replaced
   * @param new Replacement string
   * @return new String object
   */
  public static final String replace(String str, String old, String new_) {
    int          index, old_index;
    StringBuffer buf = new StringBuffer();

    try {
      if((index = str.indexOf(old)) != -1) { // `old' found in str
	old_index = 0;                       // String start offset
	  
	// While we have something to replace
	while((index = str.indexOf(old, old_index)) != -1) {
	  buf.append(str.substring(old_index, index)); // append prefix
	  buf.append(new_);                            // append replacement
	      
	  old_index = index + old.length(); // Skip `old'.length chars
	}

	buf.append(str.substring(old_index)); // append rest of string
	str = buf.toString();	
      }
    } catch(StringIndexOutOfBoundsException e) { // Should not occur
      System.err.println(e);
    }

    return str;
  }

  /**
   * Converts signature to string with all class names compacted.
   *
   * @param signature to convert
   * @return Human readable signature
   */
  public static final String signatureToString(String signature) {
    return signatureToString(signature, true);
  }    

  /**
   * The field signature represents the value of an argument to a function or 
   * the value of a variable. It is a series of bytes generated by the 
   * following grammar:
   *
   * <PRE>
   * <field_signature> ::= <field_type>
   * <field_type>      ::= <base_type>|<object_type>|<array_type>
   * <base_type>       ::= B|C|D|F|I|J|S|Z
   * <object_type>     ::= L<fullclassname>;
   * <array_type>      ::= [<field_type>
   *
   * The meaning of the base types is as follows:
   * B byte signed byte
   * C char character
   * D double double precision IEEE float
   * F float single precision IEEE float
   * I int integer
   * J long long integer
   * L<fullclassname>; ... an object of the given class
   * S short signed short
   * Z boolean true or false
   * [<field sig> ... array
   * </PRE>
   *
   * This method converts this string into a Java type declaration such as
   * `String[]' and throws a `ClassFormatException' when the parsed type is 
   * invalid.
   *
   * @param  signature  Class signature
   * @param chopit Flag that determines whether chopping is executed or not
   * @return Java type declaration
   * @throws ClassFormatException
   */
  public static final String signatureToString(String signature,
					       boolean chopit)
  {
    consumed_chars = 1; // This is the default, read just one char like `B'

    try {
      switch(signature.charAt(0)) {
      case 'B' : return "byte";
      case 'C' : return "char";
      case 'D' : return "double";
      case 'F' : return "float";
      case 'I' : return "int";
      case 'J' : return "long";

      case 'L' : { // Full class name
	int    index = signature.indexOf(';'); // Look for closing `;'

	if(index < 0)
	  throw new ClassFormatException("Invalid signature: " + signature);
	
	consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed

	return compactClassName(signature.substring(1, index), chopit);
      }

      case 'S' : return "short";
      case 'Z' : return "boolean";

      case '[' : { // Array declaration
	int          n;
	StringBuffer brackets;
	String       type;
	int          consumed_chars; // Shadows global var

	brackets = new StringBuffer(); // Accumulate []'s

	// Count opening brackets and look for optional size argument
	for(n=0; signature.charAt(n) == '['; n++)
	  brackets.append("[]");

	consumed_chars = n; // Remember value

	// The rest of the string denotes a `<field_type>'
	type = signatureToString(signature.substring(n), chopit);
	
	Utility.consumed_chars += consumed_chars;
	return type + brackets.toString();
      }

      case 'V' : return "void";

      default  : throw new ClassFormatException("Invalid signature: `" +
					    signature + "'");
      }
    } catch(StringIndexOutOfBoundsException e) { // Should never occur
      throw new ClassFormatException("Invalid signature: " + e + ":" + signature);
    }
  }

  /** Parse Java type such as "char", or "java.lang.String[]" and return the
   * signature in byte code format, e.g. "C" or "[Ljava/lang/String;" respectively.
   *
   * @param  type Java type
   * @return byte code signature
   */
  public static String getSignature(String type) {
    StringBuffer buf        = new StringBuffer();
    char[]       chars      = type.toCharArray();
    boolean      char_found = false, delim = false;
    int          index      = -1;

  loop:
    for(int i=0; i < chars.length; i++) {
      switch(chars[i]) {
      case ' ': case '\t': case '\n': case '\r': case '\f':
	if(char_found)
	  delim = true;
	break;

      case '[':
	if(!char_found)
	  throw new RuntimeException("Illegal type: " + type);

	index = i;
	break loop;

      default:
	char_found = true;
	if(!delim)
	  buf.append(chars[i]);
      }
    }

    int brackets = 0;

    if(index > 0)
      brackets = countBrackets(type.substring(index));

    type = buf.toString();
    buf.setLength(0);

    for(int i=0; i < brackets; i++)
      buf.append('[');

    boolean found = false;

    for(int i=Constants.T_BOOLEAN; (i <= Constants.T_VOID) && !found; i++) {

⌨️ 快捷键说明

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