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

📄 classfilereferenceinitializer.java

📁 出色的混淆器
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    public void visitInstruction(ClassFile classFile, Instruction instruction)    {        // Just ignore generic instructions and reset the constant pool indices.        switch (instruction.getOpcode())        {            case Instruction.OP_ICONST_0:            case Instruction.OP_ICONST_1:                // Still remember any loaded string; it might be the argument of                // class$(String, boolean).                break;            default:                ldcStringCpIndex = -1;                break;        }        invokestaticMethodRefCpIndex  = -1;        invokevirtualMethodRefCpIndex = -1;    }    public void visitCpInstruction(ClassFile classFile, CpInstruction cpInstruction)    {        int currentCpIndex = cpInstruction.getCpIndex();        switch (cpInstruction.getOpcode())        {            case Instruction.OP_LDC:            case Instruction.OP_LDC_WIDE:                // Are we loading a constant String?                int currentCpTag = classFile.getCpTag(currentCpIndex);                if (currentCpTag == ClassConstants.CONSTANT_String)                {                    // Remember it; it might be the argument of                    // Class.forName(String), class$(String), or                    // class$(String, boolean).                    ldcStringCpIndex = currentCpIndex;                }                invokestaticMethodRefCpIndex  = -1;                invokevirtualMethodRefCpIndex = -1;                break;            case Instruction.OP_INVOKESTATIC:                // Are we invoking a static method that might have a constant                // String argument?                if (ldcStringCpIndex > 0)                {                    classForNameFinder.reset();                    // First check whether the method reference points to Class.forName.                    classFile.constantPoolEntryAccept(classForNameFinder, currentCpIndex);                    // Then fill out the class file reference in the String, if applicable.                    classFile.constantPoolEntryAccept(classForNameFinder, ldcStringCpIndex);                    invokestaticMethodRefCpIndex = -1;                }                else                {                    // Just remember it; it might still be a Class.forName.                    invokestaticMethodRefCpIndex = currentCpIndex;                }                ldcStringCpIndex              = -1;                invokevirtualMethodRefCpIndex = -1;                break;            case Instruction.OP_INVOKEVIRTUAL:                // Are we invoking a virtual method right after a static method?                if (invokestaticMethodRefCpIndex > 0)                {                    // Remember it; it might be Class.newInstance after a Class.forName.                    invokevirtualMethodRefCpIndex = currentCpIndex;                }                else                {                    invokestaticMethodRefCpIndex  = -1;                    invokevirtualMethodRefCpIndex = -1;                }                ldcStringCpIndex = -1;                break;            case Instruction.OP_CHECKCAST:                // Are we checking a cast right after a static method and a                // virtual method?                if (invokestaticMethodRefCpIndex  > 0 &&                    invokevirtualMethodRefCpIndex > 0)                {                    classForNameFinder.reset();                    // First check whether the first method reference points to Class.forName.                    classFile.constantPoolEntryAccept(classForNameFinder, invokestaticMethodRefCpIndex);                    // Then check whether the second method reference points to Class.newInstance.                    classFile.constantPoolEntryAccept(classForNameFinder, invokevirtualMethodRefCpIndex);                    // Then figure out which class is being cast to.                    classFile.constantPoolEntryAccept(classForNameFinder, currentCpIndex);                }                ldcStringCpIndex              = -1;                invokestaticMethodRefCpIndex  = -1;                invokevirtualMethodRefCpIndex = -1;                break;            default:                // Nothing interesting; just forget about previous indices.                ldcStringCpIndex              = -1;                invokestaticMethodRefCpIndex  = -1;                invokevirtualMethodRefCpIndex = -1;                break;        }    }    /**     * This CpInfoVisitor is designed to visit one or two method references first,     * and then a string or a class reference.     * If the method reference is Class.forName or .class, the class file     * reference of the string is filled out.     * If the method reference is Class.forName and then Class.newInstance,     * a note of it is printed.     */    private class MyClassForNameFinder implements CpInfoVisitor    {        private boolean isClassForNameInvocation;        private boolean isDotClassInvocation;        private boolean isClassForNameInstanceInvocation;        public void reset()        {            isClassForNameInvocation         = false;            isDotClassInvocation             = false;            isClassForNameInstanceInvocation = false;        }        public void visitIntegerCpInfo(ClassFile classFile, IntegerCpInfo integerCpInfo) {}        public void visitLongCpInfo(ClassFile classFile, LongCpInfo longCpInfo) {}        public void visitFloatCpInfo(ClassFile classFile, FloatCpInfo floatCpInfo) {}        public void visitDoubleCpInfo(ClassFile classFile, DoubleCpInfo doubleCpInfo) {}        public void visitUtf8CpInfo(ClassFile classFile, Utf8CpInfo utf8CpInfo) {}        public void visitFieldrefCpInfo(ClassFile classFile, FieldrefCpInfo fieldrefCpInfo) {}        public void visitInterfaceMethodrefCpInfo(ClassFile classFile, InterfaceMethodrefCpInfo interfaceMethodrefCpInfo) {}        public void visitNameAndTypeCpInfo(ClassFile classFile, NameAndTypeCpInfo nameAndTypeCpInfo) {}        public void visitMethodrefCpInfo(ClassFile classFile, MethodrefCpInfo methodrefCpInfo)        {            String className  = methodrefCpInfo.getClassName(classFile);            String methodName = methodrefCpInfo.getName(classFile);            String methodType = methodrefCpInfo.getType(classFile);            // Is it a reference to Class.newInstance, following a reference to            // Class.forName?            isClassForNameInstanceInvocation =                isClassForNameInvocation                                              &&                className .equals(ClassConstants.INTERNAL_CLASS_NAME_JAVA_LANG_CLASS) &&                methodName.equals(ClassConstants.INTERNAL_METHOD_NAME_NEW_INSTANCE)   &&                methodType.equals(ClassConstants.INTERNAL_METHOD_TYPE_NEW_INSTANCE);            // Is it a reference to Class.forName?            isClassForNameInvocation =                className .equals(ClassConstants.INTERNAL_CLASS_NAME_JAVA_LANG_CLASS) &&                methodName.equals(ClassConstants.INTERNAL_METHOD_NAME_CLASS_FOR_NAME) &&                methodType.equals(ClassConstants.INTERNAL_METHOD_TYPE_CLASS_FOR_NAME);            // Is it a reference to .class?            // Note that .class is implemented as "static Class class$(String)"            // or as "static Class class$(String, boolean)".            isDotClassInvocation =                methodName.equals(ClassConstants.INTERNAL_METHOD_NAME_DOT_CLASS) &&                (methodType.equals(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JAVAC) ||                 methodType.equals(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JIKES));        }        public void visitStringCpInfo(ClassFile classFile, StringCpInfo stringCpInfo)        {            if (isClassForNameInvocation ||                isDotClassInvocation)            {                // Save a reference to the corresponding class file.                String externalClassName = stringCpInfo.getString(classFile);                String internalClassName = ClassUtil.internalClassName(externalClassName);                stringCpInfo.referencedClassFile =                    programClassPool.getClass(internalClassName);            }        }        public void visitClassCpInfo(ClassFile classFile, ClassCpInfo classCpInfo)        {            if (isClassForNameInstanceInvocation)            {                if (note)                {                    noteCount++;                    System.err.println("Note: " +                                       ClassUtil.externalClassName(classFile.getName()) +                                       " calls '(" +                                       ClassUtil.externalClassName(classCpInfo.getName(classFile)) +                                       ")Class.forName(variable).newInstance()'");                }            }        }    }    // Small utility methods.    /**     * Returns an array of class files referenced by the given descriptor, or     * <code>null</code> if there aren't any useful references.     */    private ClassFile[] findReferencedClassFiles(String aDescriptor)    {        DescriptorClassEnumeration enumeration =            new DescriptorClassEnumeration(aDescriptor);        int classCount = enumeration.classCount();        if (classCount > 0)        {            ClassFile[] referencedClassFiles = new ClassFile[classCount];            boolean foundReferencedClassFiles = false;            for (int i = 0; i < classCount; i++)            {                String name = enumeration.nextClassName();                ClassFile referencedClassFile = programClassPool.getClass(name);                if (referencedClassFile != null)                {                    referencedClassFiles[i] = referencedClassFile;                    foundReferencedClassFiles = true;                }            }            if (foundReferencedClassFiles)            {                return referencedClassFiles;            }        }        return null;    }    /**     * A utility class that throws a MemberFoundException whenever it visits     * a member. For program class files, it then also stores the class file     * and member info.     */    private static class MyMemberFinder implements MemberInfoVisitor    {        private static class MemberFoundException extends IllegalArgumentException {};        private static final MemberFoundException MEMBER_FOUND = new MemberFoundException();        private ProgramClassFile  programClassFile;        private ProgramMemberInfo programMemberInfo;        // Implementations for MemberInfoVisitor        public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo)        {            this.programClassFile  = programClassFile;            this.programMemberInfo = programFieldInfo;            throw MEMBER_FOUND;        }        public void visitProgramMethodInfo(ProgramClassFile programClassFile, ProgramMethodInfo programMethodInfo)        {            this.programClassFile  = programClassFile;            this.programMemberInfo = programMethodInfo;            throw MEMBER_FOUND;        }        public void visitLibraryFieldInfo(LibraryClassFile libraryClassFile, LibraryFieldInfo libraryFieldInfo)        {            throw MEMBER_FOUND;        }        public void visitLibraryMethodInfo(LibraryClassFile libraryClassFile, LibraryMethodInfo libraryMethodInfo)        {            throw MEMBER_FOUND;        }    }}

⌨️ 快捷键说明

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