dynamicclassreferenceinitializer.java
来自「proguard 一个java的混淆器」· Java 代码 · 共 441 行 · 第 1/2 页
JAVA
441 行
WarningPrinter notePrinter, StringMatcher noteExceptionMatcher) { this.programClassPool = programClassPool; this.libraryClassPool = libraryClassPool; this.notePrinter = notePrinter; this.noteExceptionMatcher = noteExceptionMatcher; } // Implementations for InstructionVisitor. public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) { // Try to match the Class.forName("SomeClass") construct. instruction.accept(clazz, method, codeAttribute, offset, constantClassForNameMatcher); // Did we find a match? if (constantClassForNameMatcher.isMatching()) { // Fill out the matched string constant. clazz.constantPoolEntryAccept(constantClassForNameMatcher.matchedConstantIndex(X), this); // Don't look for the dynamic construct. classForNameCastMatcher.reset(); } // Try to match the (SomeClass)Class.forName(someName).newInstance() // construct. instruction.accept(clazz, method, codeAttribute, offset, classForNameCastMatcher); // Did we find a match? if (classForNameCastMatcher.isMatching()) { // Print out a note about the construct. clazz.constantPoolEntryAccept(classForNameCastMatcher.matchedConstantIndex(X), this); } // Try to match the javac .class construct. instruction.accept(clazz, method, codeAttribute, offset, dotClassJavacMatcher); // Did we find a match? if (dotClassJavacMatcher.isMatching() && isDotClassMethodref(clazz, dotClassJavacMatcher.matchedConstantIndex(0))) { // Fill out the matched string constant. clazz.constantPoolEntryAccept(dotClassJavacMatcher.matchedConstantIndex(X), this); } // Try to match the jikes .class construct. instruction.accept(clazz, method, codeAttribute, offset, dotClassJikesMatcher); // Did we find a match? if (dotClassJikesMatcher.isMatching() && isDotClassMethodref(clazz, dotClassJikesMatcher.matchedConstantIndex(0))) { // Fill out the matched string constant. clazz.constantPoolEntryAccept(dotClassJikesMatcher.matchedConstantIndex(X), this); } } // Implementations for ConstantVisitor. /** * Fills out the link to the referenced class. */ public void visitStringConstant(Clazz clazz, StringConstant stringConstant) { // Save a reference to the corresponding class. String externalClassName = stringConstant.getString(clazz); String internalClassName = ClassUtil.internalClassName(externalClassName); stringConstant.referencedClass = findClass(internalClassName); } /** * Prints out a note about the class cast to this class, if applicable. */ public void visitClassConstant(Clazz clazz, ClassConstant classConstant) { // Print out a note about the class cast. if (notePrinter != null && (noteExceptionMatcher == null || !noteExceptionMatcher.matches(classConstant.getName(clazz)))) { notePrinter.print("Note: " + ClassUtil.externalClassName(clazz.getName()) + " calls '(" + ClassUtil.externalClassName(classConstant.getName(clazz)) + ")Class.forName(variable).newInstance()'"); } } /** * Checks whether the referenced method is a .class method. */ public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant) { String methodType = methodrefConstant.getType(clazz); // Do the method's class and type match? if (methodType.equals(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JAVAC) || methodType.equals(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JIKES)) { String methodName = methodrefConstant.getName(clazz); // Does the method's name match one of the special names? isClassForNameInvocation = methodName.equals(ClassConstants.INTERNAL_METHOD_NAME_DOT_CLASS_JAVAC) || methodName.equals(ClassConstants.INTERNAL_METHOD_NAME_DOT_CLASS_JIKES); if (isClassForNameInvocation) { return; } String className = methodrefConstant.getClassName(clazz); // Note that we look for the class by name, since the referenced // class has not been initialized yet. Clazz referencedClass = programClassPool.getClass(className); if (referencedClass != null) { // Check if the code of the referenced method is .class code. // Note that we look for the method by name and type, since the // referenced method has not been initialized yet. referencedClass.methodAccept(methodName, methodType, new AllAttributeVisitor(this)); } } } // Implementations for AttributeVisitor. public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { // Check whether this is class$(String), as generated by javac, or // class(String, boolean), as generated by jikes, or an optimized // version. isClassForNameInvocation = isDotClassMethodCode(clazz, method, codeAttribute, dotClassJavacImplementationMatcher, 5) || isDotClassMethodCode(clazz, method, codeAttribute, dotClassJikesImplementationMatcher, 12) || isDotClassMethodCode(clazz, method, codeAttribute, dotClassJikesImplementationMatcher2, 8); } // Small utility methods. /** * Returns whether the given method reference corresponds to a .class * method, as generated by javac or by jikes. */ private boolean isDotClassMethodref(Clazz clazz, int methodrefConstantIndex) { isClassForNameInvocation = false; // Check if the code of the referenced method is .class code. clazz.constantPoolEntryAccept(methodrefConstantIndex, this); return isClassForNameInvocation; } /** * Returns whether the first whether the first instructions of the * given code attribute match with the given instruction matcher. */ private boolean isDotClassMethodCode(Clazz clazz, Method method, CodeAttribute codeAttribute, InstructionSequenceMatcher codeMatcher, int codeLength) { // Check the minimum code length. if (codeAttribute.u4codeLength < codeLength) { return false; } // Check the actual instructions. codeMatcher.reset(); codeAttribute.instructionsAccept(clazz, method, 0, codeLength, codeMatcher); return codeMatcher.isMatching(); } /** * Returns the class with the given name, either for the program class pool * or from the library class pool, or <code>null</code> if it can't be found. */ private Clazz findClass(String name) { // First look for the class in the program class pool. Clazz clazz = programClassPool.getClass(name); // Otherwise look for the class in the library class pool. if (clazz == null) { clazz = libraryClassPool.getClass(name); } return clazz; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?