dynamicmemberreferenceinitializer.java

来自「proguard 一个java的混淆器」· Java 代码 · 共 591 行 · 第 1/2 页

JAVA
591
字号
        this.notePrinter                = notePrinter;        this.noteFieldExceptionMatcher  = noteFieldExceptionMatcher;        this.noteMethodExceptionMatcher = noteMethodExceptionMatcher;    }    // Implementations for InstructionVisitor.    public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)    {        // Try to match the SomeClass.class.getField("someField") construct.        matchGetMember(clazz, method, codeAttribute, offset, instruction,                       constantGetFieldMatcher,                       getFieldMatcher, true, false);        // Try to match the SomeClass.class.getDeclaredField("someField") construct.        matchGetMember(clazz, method, codeAttribute, offset, instruction,                       constantGetDeclaredFieldMatcher,                       getDeclaredFieldMatcher, true, true);        // Try to match the SomeClass.class.getMethod("someMethod", new Class[]        // {}) construct.        matchGetMember(clazz, method, codeAttribute, offset, instruction,                       constantGetMethodMatcher0,                       getMethodMatcher0, false, false);        // Try to match the SomeClass.class.getDeclaredMethod("someMethod",        //  new Class[] {}) construct.        matchGetMember(clazz, method, codeAttribute, offset, instruction,                       constantGetDeclaredMethodMatcher0,                       getDeclaredMethodMatcher0, false, true);        // Try to match the SomeClass.class.getMethod("someMethod", new Class[]        // { A.class }) construct.        matchGetMember(clazz, method, codeAttribute, offset, instruction,                       constantGetMethodMatcher1,                       getMethodMatcher1, false, false);        // Try to match the SomeClass.class.getDeclaredMethod("someMethod",        //  new Class[] { A.class }) construct.        matchGetMember(clazz, method, codeAttribute, offset, instruction,                       constantGetDeclaredMethodMatcher1,                       getDeclaredMethodMatcher1, false, true);        // Try to match the SomeClass.class.getMethod("someMethod", new Class[]        // { A.class, B.class }) construct.        matchGetMember(clazz, method, codeAttribute, offset, instruction,                       constantGetMethodMatcher2,                       getMethodMatcher2, false, false);        // Try to match the SomeClass.class.getDeclaredMethod("someMethod",        //  new Class[] { A.class, B.class }) construct.        matchGetMember(clazz, method, codeAttribute, offset, instruction,                       constantGetDeclaredMethodMatcher2,                       getDeclaredMethodMatcher2, false, true);    }    /**     * Tries to match the next instruction and fills out the string constant     * or prints out a note accordingly.     */    private void matchGetMember(Clazz                      clazz,                                Method                     method,                                CodeAttribute              codeAttribute,                                int                        offset,                                Instruction                instruction,                                InstructionSequenceMatcher constantSequenceMatcher,                                InstructionSequenceMatcher variableSequenceMatcher,                                boolean                    isField,                                boolean                    isDeclared)    {        // Try to match the next instruction in the constant sequence.        instruction.accept(clazz, method, codeAttribute, offset,                           constantSequenceMatcher);        // Did we find a match to fill out the string constant?        if (constantSequenceMatcher.isMatching())        {            this.isField    = isField;            this.isDeclared = isDeclared;            // Get the member's class.            clazz.constantPoolEntryAccept(constantSequenceMatcher.matchedConstantIndex(X), this);            // Fill out the matched string constant.            clazz.constantPoolEntryAccept(constantSequenceMatcher.matchedConstantIndex(Y), this);            // Don't look for the dynamic construct.            variableSequenceMatcher.reset();        }        // Try to match the next instruction in the variable sequence.        instruction.accept(clazz, method, codeAttribute, offset,                           variableSequenceMatcher);        // Did we find a match to print out a note?        if (variableSequenceMatcher.isMatching())        {            // Print out a note about the dynamic invocation.            printDynamicInvocationNote(clazz,                                       variableSequenceMatcher,                                       isField,                                       isDeclared);        }    }    // Implementations for ConstantVisitor.    /**     * Remembers the referenced class.     */    public void visitClassConstant(Clazz clazz, ClassConstant classConstant)    {        // Remember the referenced class.        referencedClass = ClassUtil.isInternalArrayType(classConstant.getName(clazz)) ?            null :            classConstant.referencedClass;    }    /**     * Fills out the link to the referenced class member.     */    public void visitStringConstant(Clazz clazz, StringConstant stringConstant)    {        if (referencedClass != null)        {            String name = stringConstant.getString(clazz);            // See if we can find the referenced class member locally, or            // somewhere in the hierarchy.            Member referencedMember = isDeclared ? isField ?                (Member)referencedClass.findField(name, null) :                (Member)referencedClass.findMethod(name, null) :                (Member)memberFinder.findMember(clazz,                                                referencedClass,                                                name,                                                null,                                                isField);            if (referencedMember != null)            {                stringConstant.referencedMember = referencedMember;                stringConstant.referencedClass  = isDeclared ?                    referencedClass :                    memberFinder.correspondingClass();            }        }    }    // Small utility methods.    /**     * Prints out a note on the matched dynamic invocation, if necessary.     */    private void printDynamicInvocationNote(Clazz                      clazz,                                            InstructionSequenceMatcher noteSequenceMatcher,                                            boolean                    isField,                                            boolean                    isDeclared)    {        // Print out a note about the dynamic invocation.        if (notePrinter != null)        {            // Is the class member name in the list of exceptions?            StringMatcher noteExceptionMatcher = isField ?                noteFieldExceptionMatcher :                noteMethodExceptionMatcher;            int    memberNameIndex = noteSequenceMatcher.matchedConstantIndex(Y);            String memberName      = clazz.getStringString(memberNameIndex);            if (noteExceptionMatcher == null ||                !noteExceptionMatcher.matches(memberName))            {                // Compose the external member name and partial descriptor.                String externalMemberDescription = memberName;                if (!isField)                {                    externalMemberDescription += '(';                    for (int count = 0; count < 2; count++)                    {                        int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(A + count);                        if (memberArgumentIndex > 0)                        {                            if (count > 0)                            {                                externalMemberDescription += ',';                            }                            String className = clazz.getClassName(memberArgumentIndex);                            externalMemberDescription += ClassUtil.isInternalArrayType(className) ?                                ClassUtil.externalType(className) :                                ClassUtil.externalClassName(className);                        }                    }                    externalMemberDescription += ')';                }                // Print out the actual note.                notePrinter.print("Note: " +                                  ClassUtil.externalClassName(clazz.getName()) +                                  " accesses a " +                                  (isDeclared ? "declared " : "") +                                  (isField    ? "field" : "method") +                                  " '" +                                  externalMemberDescription +                                  "' dynamically");                // Print out notes about potential candidates.                ClassVisitor classVisitor;                if (isField)                {                    classVisitor =                       new AllFieldVisitor(                       new MemberNameFilter(memberName, this));                }                else                {                    // Compose the partial method descriptor.                    String methodDescriptor = "(";                    for (int count = 0; count < 2; count++)                    {                        int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(A + count);                        if (memberArgumentIndex > 0)                        {                            if (count > 0)                            {                                methodDescriptor += ',';                            }                            String className = clazz.getClassName(memberArgumentIndex);                            methodDescriptor += ClassUtil.isInternalArrayType(className) ?                                className :                                ClassUtil.internalTypeFromClassName(className);                        }                    }                    methodDescriptor += ")L///;";                    classVisitor =                        new AllMethodVisitor(                        new MemberNameFilter(memberName,                        new MemberDescriptorFilter(methodDescriptor, this)));                }                programClassPool.classesAcceptAlphabetically(classVisitor);                libraryClassPool.classesAcceptAlphabetically(classVisitor);            }        }    }    // Implementations for MemberVisitor.    public void visitProgramField(ProgramClass programClass, ProgramField programField)    {        System.out.println("      Maybe this is program field '" +                           ClassUtil.externalFullClassDescription(0, programClass.getName()) +                           " { " +                           ClassUtil.externalFullFieldDescription(0, programField.getName(programClass), programField.getDescriptor(programClass)) +                           "; }'");    }    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)    {        System.out.println("      Maybe this is program method '" +                           ClassUtil.externalFullClassDescription(0, programClass.getName()) +                           " { " +                           ClassUtil.externalFullMethodDescription(null, 0, programMethod.getName(programClass), programMethod.getDescriptor(programClass)) +                           "; }'");    }    public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)    {        System.out.println("      Maybe this is library field '" +                           ClassUtil.externalFullClassDescription(0, libraryClass.getName()) +                           " { " +                           ClassUtil.externalFullFieldDescription(0, libraryField.getName(libraryClass), libraryField.getDescriptor(libraryClass)) +                           "; }'");    }    public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)    {        System.out.println("      Maybe this is library method '" +                           ClassUtil.externalFullClassDescription(0, libraryClass.getName()) +                           " { " +                           ClassUtil.externalFullMethodDescription(null, 0, libraryMethod.getName(libraryClass), libraryMethod.getDescriptor(libraryClass)) +                           "; }'");    }}

⌨️ 快捷键说明

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