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 + -
显示快捷键?