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

📄 classfile.java

📁 Java Bytecode Editor 是一个 JAVA 的字节码反汇编和修改器。它可以很方便的修改已经编译成 Class 文件的 JAVA 文件。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
     * @throws InvalidByteCodeException if the entry is invalid
     */
    public String getConstantPoolEntryName(int index)
            throws InvalidByteCodeException {

        if (!checkValidConstantPoolIndex(index)) {
            return null;
        }

        CPInfo cpInfo = constantPool[index];
        if (cpInfo == null) {
            return "invalid constant pool index";
        } else {
            return cpInfo.getVerbose();
        }
    }

    /**
     * Get the index of a field for given field name and signature.
     *
     * @param name       the field name.
     * @param descriptor the signature.
     * @return the index or <tt>-1</tt> if not found.
     * @throws InvalidByteCodeException
     */
    public int getFieldIndex(String name, String descriptor) throws InvalidByteCodeException {

        for (int i = 0; i < fields.length; i++) {
            FieldInfo field = fields[i];
            if (field.getName().equals(name) && field.getDescriptor().equals(descriptor)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Get the <tt>FieldInfo</tt> for given field name and signature.
     *
     * @param name       the field name.
     * @param descriptor the signature.
     * @return the <tt>FieldInfo</tt> or <tt>null</tt> if not found.
     * @throws InvalidByteCodeException
     */
    public FieldInfo getField(String name, String descriptor) throws InvalidByteCodeException {

        int index = getFieldIndex(name, descriptor);
        if (index < 0) {
            return null;
        } else {
            return fields[index];
        }
    }

    /**
     * Get the index of a method for given method name and signature.
     *
     * @param name       the method name.
     * @param descriptor the signature.
     * @return the index or <tt>-1</tt> if not found.
     * @throws InvalidByteCodeException
     */
    public int getMethodIndex(String name, String descriptor) throws InvalidByteCodeException {

        for (int i = 0; i < methods.length; i++) {
            MethodInfo method = methods[i];
            if (method.getName().equals(name) && method.getDescriptor().equals(descriptor)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Get the <tt>MethodInfo</tt> for given method name and signature.
     *
     * @param name       the method name.
     * @param descriptor the signature.
     * @return the <tt>MethodInfo</tt> or <tt>null</tt> if not found.
     * @throws InvalidByteCodeException
     */
    public MethodInfo getMethod(String name, String descriptor) throws InvalidByteCodeException {

        int index = getMethodIndex(name, descriptor);
        if (index < 0) {
            return null;
        } else {
            return methods[index];
        }
    }

    public void read(DataInput in)
            throws InvalidByteCodeException, IOException {

        readMagicNumber(in);
        readVersion(in);
        readConstantPool(in);
        readAccessFlags(in);
        readThisClass(in);
        readSuperClass(in);
        readInterfaces(in);
        readFields(in);
        readMethods(in);
        readAttributes(in);
    }

    public void write(DataOutput in)
            throws InvalidByteCodeException, IOException {

        writeMagicNumber(in);
        writeVersion(in);
        writeConstantPool(in);
        writeAccessFlags(in);
        writeThisClass(in);
        writeSuperClass(in);
        writeInterfaces(in);
        writeFields(in);
        writeMethods(in);
        writeAttributes(in);

    }

    private boolean checkValidConstantPoolIndex(int index) {

        if (index < 1 || index >= constantPool.length) {
            return false;
        }
        return true;

    }

    private void readMagicNumber(DataInput in)
            throws InvalidByteCodeException, IOException {

        int magicNumber = in.readInt();
        if (magicNumber != MAGIC_NUMBER) {
            throw new InvalidByteCodeException("Invalid magic number 0x" +
                    Integer.toHexString(magicNumber) +
                    " instead of 0x" +
                    Integer.toHexString(MAGIC_NUMBER));
        }

        if (debug) debug("read magic number");
    }

    private void writeMagicNumber(DataOutput out) throws IOException {

        out.writeInt(MAGIC_NUMBER);
        if (debug) debug("wrote magic number");
    }

    private void readVersion(DataInput in) throws IOException {

        minorVersion = in.readUnsignedShort();
        if (debug) debug("read minor version " + minorVersion);

        majorVersion = in.readUnsignedShort();
        if (debug) debug("read major version " + majorVersion);

        checkMajorVersion(majorVersion);
    }

    private void writeVersion(DataOutput out) throws IOException {

        out.writeShort(minorVersion);
        if (debug) debug("wrote minor version " + minorVersion);

        out.writeShort(majorVersion);
        if (debug) debug("wrote major version " + majorVersion);

        checkMajorVersion(majorVersion);
    }

    private void readConstantPool(DataInput in)
            throws InvalidByteCodeException, IOException {

        constantPoolEntryToIndex.clear();
        int constantPoolCount = in.readUnsignedShort();
        if (debug) debug("read constant pool count " + constantPoolCount);

        constantPool = new CPInfo[constantPoolCount];

        // constantPool has effective length constantPoolCount - 1
        // constantPool[0] defaults to null
        for (int i = 1; i < constantPoolCount; i++) {
            if (skipConstantPool) {
                // see below for i++
                i += CPInfo.skip(in);
            } else {
                // create CPInfos via factory method since the actual type
                // of the constant is not yet known
                if (debug) debug("reading constant pool entry " + i);
                constantPool[i] = CPInfo.create(in, this);
                constantPoolEntryToIndex.put(constantPool[i], new Integer(i));
                if (constantPool[i] instanceof ConstantLargeNumeric) {
                    // CONSTANT_Double_info and CONSTANT_Long_info take 2 constant
                    // pool entries, the second entry is unusable (design mistake)
                    i++;
                }
            }
        }
    }

    private void writeConstantPool(DataOutput out)
            throws InvalidByteCodeException, IOException {

        int lastFreeIndex;
        for (lastFreeIndex = getLength(constantPool) - 1;
             lastFreeIndex >= 0 && constantPool[lastFreeIndex] == null;
             lastFreeIndex--) {
        }

        out.writeShort(lastFreeIndex + 1);
        if (debug) debug("wrote constant pool count " + (lastFreeIndex + 1));

        // constantPool[0] defaults to null and is not written into the class file
        for (int i = 1; i <= lastFreeIndex; i++) {
            if (constantPool[i] == null) {
                throw new InvalidByteCodeException("constant pool entry " + i + " is null");
            }
            if (debug) debug("writing constant pool entry " + i);
            constantPool[i].write(out);
            if (constantPool[i] instanceof ConstantLargeNumeric) {
                // CONSTANT_Double_info and CONSTANT_Long_info take 2 constant
                // pool entries, the second entry is unusable (design mistake)
                i++;
            }
        }
    }

    private void readAccessFlags(DataInput in) throws IOException {

        accessFlags = in.readUnsignedShort();
        if (debug) debug("read access flags " + printAccessFlags(accessFlags));
    }

    private void writeAccessFlags(DataOutput out) throws IOException {

        out.writeShort(accessFlags);
        if (debug) debug("wrote access flags " + printAccessFlags(accessFlags));
    }

    private void readThisClass(DataInput in) throws IOException {

        thisClass = in.readUnsignedShort();
        if (debug) debug("read this_class index " + thisClass);
    }

    private void writeThisClass(DataOutput out) throws IOException {

        out.writeShort(thisClass);
        if (debug) debug("wrote this_class index " + thisClass);
    }

    private void readSuperClass(DataInput in) throws IOException {

        superClass = in.readUnsignedShort();
        if (debug) debug("read super_class index " + superClass);
    }

    private void writeSuperClass(DataOutput out) throws IOException {

        out.writeShort(superClass);
        if (debug) debug("wrote super_class index " + superClass);
    }

    private void readInterfaces(DataInput in) throws IOException {

        int interfacesCount = in.readUnsignedShort();
        if (debug) debug("read interfaces count " + interfacesCount);

        interfaces = new int[interfacesCount];

        for (int i = 0; i < interfacesCount; i++) {
            interfaces[i] = in.readUnsignedShort();
            if (debug) debug("read interface index " + interfaces[i]);
        }

    }

    private void writeInterfaces(DataOutput out) throws IOException {

        int interfacesCount = getLength(interfaces);

        out.writeShort(interfacesCount);
        if (debug) debug("wrote interfaces count " + interfacesCount);

        for (int i = 0; i < interfacesCount; i++) {
            out.writeShort(interfaces[i]);
            if (debug) debug("wrote interface index " + interfaces[i]);
        }

    }

    private void readFields(DataInput in)
            throws InvalidByteCodeException, IOException {

        int fieldsCount = in.readUnsignedShort();
        if (debug) debug("read fields count " + fieldsCount);

        fields = new FieldInfo[fieldsCount];

        for (int i = 0; i < fieldsCount; i++) {
            fields[i] = FieldInfo.create(in, this);
        }

    }

    private void writeFields(DataOutput out)
            throws InvalidByteCodeException, IOException {

        int fieldsCount = getLength(fields);

        out.writeShort(fieldsCount);
        if (debug) debug("wrote fields count " + fieldsCount);

        for (int i = 0; i < fieldsCount; i++) {
            if (fields[i] == null) {
                throw new InvalidByteCodeException("field " + i + " is null");
            }
            fields[i].write(out);
        }

    }

    private void readMethods(DataInput in)
            throws InvalidByteCodeException, IOException {

        int methodsCount = in.readUnsignedShort();
        if (debug) debug("read methods count " + methodsCount);

        methods = new MethodInfo[methodsCount];

        for (int i = 0; i < methodsCount; i++) {
            methods[i] = MethodInfo.create(in, this);
        }

    }

    private void writeMethods(DataOutput out)
            throws InvalidByteCodeException, IOException {

        int methodsCount = getLength(methods);

        out.writeShort(methodsCount);
        if (debug) debug("wrote methods count " + methodsCount);

        for (int i = 0; i < methodsCount; i++) {
            if (methods[i] == null) {
                throw new InvalidByteCodeException("method " + i + " is null");
            }
            methods[i].write(out);
        }

    }

    protected void readAttributes(DataInput in)
            throws InvalidByteCodeException, IOException {

        super.readAttributes(in);
        if (debug) debug("read " + getLength(attributes) + " attributes for the ClassFile structure");
    }

    protected void writeAttributes(DataOutput out)
            throws InvalidByteCodeException, IOException {

        super.writeAttributes(out);
        if (debug) debug("wrote " + getLength(attributes) + " attributes for the ClassFile structure");
    }

    private void checkMajorVersion(int majorVersion) {

        if (majorVersion < 45 || majorVersion > 49) {
            Log.warning("major version should be between 45 and 49 for JDK <= 1.5");
        }

    }

    protected String printAccessFlagsVerbose(int accessFlags) {
        return printAccessFlagsVerbose(AccessFlags.CLASS_ACCESS_FLAGS, AccessFlags.CLASS_ACCESS_FLAGS_VERBOSE, accessFlags);
    }
}

⌨️ 快捷键说明

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