📄 classfilerenamer.java
字号:
public void visitAnnotationDefaultAttrInfo(ClassFile classFile, AnnotationDefaultAttrInfo annotationDefaultAttrInfo) { // Rename the annotation. annotationDefaultAttrInfo.defaultValueAccept(classFile, this); } // Implementations for LocalVariableInfoVisitor. public void visitLocalVariableInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableInfo localVariableInfo) { // Compute the new descriptor. String newDescriptor = newClassName(classFile.getCpString(localVariableInfo.u2descriptorIndex), localVariableInfo.referencedClassFile); if (newDescriptor != null) { // Refer to a new Utf8 entry. localVariableInfo.u2descriptorIndex = createUtf8CpInfo((ProgramClassFile)classFile, newDescriptor); } } // Implementations for LocalVariableTypeInfoVisitor. public void visitLocalVariableTypeInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTypeInfo localVariableTypeInfo) { // Compute the new signature. String newSignature = newDescriptor(classFile.getCpString(localVariableTypeInfo.u2signatureIndex), localVariableTypeInfo.referencedClassFiles); if (newSignature != null) { localVariableTypeInfo.u2signatureIndex = createUtf8CpInfo((ProgramClassFile)classFile, newSignature); } } // Implementations for AnnotationVisitor. public void visitAnnotation(ClassFile classFile, Annotation annotation) { // Compute the new type name. String newTypeName = newDescriptor(classFile.getCpString(annotation.u2typeIndex), annotation.referencedClassFiles); if (newTypeName != null) { // Refer to a new Utf8 entry. annotation.u2typeIndex = createUtf8CpInfo((ProgramClassFile)classFile, newTypeName); } // Rename the element values. annotation.elementValuesAccept(classFile, this); } // Implementations for ElementValueVisitor. public void visitConstantElementValue(ClassFile classFile, Annotation annotation, ConstantElementValue constantElementValue) { renameElementValue(classFile, constantElementValue); } public void visitEnumConstantElementValue(ClassFile classFile, Annotation annotation, EnumConstantElementValue enumConstantElementValue) { renameElementValue(classFile, enumConstantElementValue); // Compute the new type name. String newTypeName = newDescriptor(classFile.getCpString(enumConstantElementValue.u2typeNameIndex), enumConstantElementValue.referencedClassFiles); if (newTypeName != null) { // Refer to a new Utf8 entry. enumConstantElementValue.u2typeNameIndex = createUtf8CpInfo((ProgramClassFile)classFile, newTypeName); } } public void visitClassElementValue(ClassFile classFile, Annotation annotation, ClassElementValue classElementValue) { renameElementValue(classFile, classElementValue); // Compute the new class name. String newClassName = newDescriptor(classFile.getCpString(classElementValue.u2classInfoIndex), classElementValue.referencedClassFiles); if (newClassName != null) { // Refer to a new Utf8 entry. classElementValue.u2classInfoIndex = createUtf8CpInfo((ProgramClassFile)classFile, newClassName); } } public void visitAnnotationElementValue(ClassFile classFile, Annotation annotation, AnnotationElementValue annotationElementValue) { renameElementValue(classFile, annotationElementValue); // Rename the annotation. annotationElementValue.annotationAccept(classFile, this); } public void visitArrayElementValue(ClassFile classFile, Annotation annotation, ArrayElementValue arrayElementValue) { renameElementValue(classFile, arrayElementValue); // Rename the element values. arrayElementValue.elementValuesAccept(classFile, annotation, this); } /** * Renames the method reference of the element value, if any. */ public void renameElementValue(ClassFile classFile, ElementValue elementValue) { // Compute the new class member name. String newMethodName = newMemberName(elementValue.referencedMethodInfo); if (newMethodName != null) { // Refer to a new NameAndType entry. elementValue.u2elementName = createUtf8CpInfo((ProgramClassFile)classFile, newMethodName); } } // Small utility methods. /** * Finds or creates a NameAndTypeCpInfo constant pool entry with the given * name and type, in the given class file. * @return the constant pool index of the NameAndTypeCpInfo. */ private int createNameAndTypeCpInfo(ProgramClassFile programClassFile, String name, String type) { CpInfo[] constantPool = programClassFile.constantPool; int u2constantPoolCount = programClassFile.u2constantPoolCount; // Pick up the right list of referenced class files, in case we need to // create a new NameAndTypeCpInfo. ClassFile[] referencedClassFiles = null; // Check if there is a NameAndTypeCpInfo with the given name and type already. for (int index = 1; index < u2constantPoolCount; index++) { CpInfo cpInfo = constantPool[index]; if (cpInfo != null && cpInfo.getTag() == ClassConstants.CONSTANT_NameAndType) { NameAndTypeCpInfo nameAndTypeCpInfo = (NameAndTypeCpInfo)cpInfo; if (nameAndTypeCpInfo.getType(programClassFile).equals(type)) { if (nameAndTypeCpInfo.getName(programClassFile).equals(name)) { return index; } referencedClassFiles = nameAndTypeCpInfo.referencedClassFiles; } } } int u2nameIndex = createUtf8CpInfo(programClassFile, name); int u2descriptorIndex = createUtf8CpInfo(programClassFile, type); return addCpInfo(programClassFile, new NameAndTypeCpInfo(u2nameIndex, u2descriptorIndex, referencedClassFiles)); } /** * Finds or creates an Utf8CpInfo constant pool entry for the given string, * in the given class file. * @return the constant pool index of the Utf8CpInfo. */ private int createUtf8CpInfo(ProgramClassFile programClassFile, String string) { CpInfo[] constantPool = programClassFile.constantPool; int u2constantPoolCount = programClassFile.u2constantPoolCount; // Check if there is a Utf8CpInfo with the given string already. for (int index = 1; index < u2constantPoolCount; index++) { CpInfo cpInfo = constantPool[index]; if (cpInfo != null && cpInfo.getTag() == ClassConstants.CONSTANT_Utf8) { Utf8CpInfo utf8CpInfo = (Utf8CpInfo)cpInfo; if (utf8CpInfo.getString().equals(string)) { return index; } } } return addCpInfo(programClassFile, new Utf8CpInfo(string)); } /** * Adds a given constant pool entry to the end of the constant pool. * @return the constant pool index for the added entry. */ private int addCpInfo(ProgramClassFile programClassFile, CpInfo cpInfo) { CpInfo[] constantPool = programClassFile.constantPool; int u2constantPoolCount = programClassFile.u2constantPoolCount; // Make sure there is enough space for another constant pool entry. if (u2constantPoolCount == constantPool.length) { programClassFile.constantPool = new CpInfo[u2constantPoolCount+1]; System.arraycopy(constantPool, 0, programClassFile.constantPool, 0, u2constantPoolCount); constantPool = programClassFile.constantPool; } // Create a new Utf8CpInfo for the given string. constantPool[programClassFile.u2constantPoolCount++] = cpInfo; return u2constantPoolCount; } /** * Returns the new descriptor based on the given descriptor and the new * names of the given referenced class files. */ private String newDescriptor(String descriptor, ClassFile[] referencedClassFiles) { // If there are no referenced classes, the descriptor doesn't change. if (referencedClassFiles == null) { return null; } // Unravel and reconstruct the class elements of the descriptor. DescriptorClassEnumeration descriptorClassEnumeration = new DescriptorClassEnumeration(descriptor); String newDescriptor = descriptorClassEnumeration.nextFluff(); int index = 0; while (descriptorClassEnumeration.hasMoreClassNames()) { String className = descriptorClassEnumeration.nextClassName(); String fluff = descriptorClassEnumeration.nextFluff(); String newClassName = newClassName(className, referencedClassFiles[index++]); // Fall back on the original class name if there is no new name. if (newClassName == null) { newClassName = className; } newDescriptor = newDescriptor + newClassName + fluff; } // If the descriptor hasn't changed after all, just return null. if (descriptor.equals(newDescriptor)) { return null; } return newDescriptor; } /** * Returns the new class name based on the given class name and the new * name of the given referenced class file. Class names of array types * are handled properly. */ private String newClassName(String className, ClassFile referencedClassFile) { // If there is no referenced class, the descriptor doesn't change. if (referencedClassFile == null) { return null; } String newClassName = ClassFileObfuscator.newClassName(referencedClassFile); // If there is no new class name, the descriptor doesn't change. if (newClassName == null) { return null; } // Is it an array type? if (className.charAt(0) == ClassConstants.INTERNAL_TYPE_ARRAY) { // Add the array prefixes and suffix "[L...;". newClassName = className.substring(0, className.indexOf(ClassConstants.INTERNAL_TYPE_CLASS_START)+1) + newClassName + ClassConstants.INTERNAL_TYPE_CLASS_END; } return newClassName; } /** * Returns the new class member name based on the given referenced class * member. */ private String newMemberName(MemberInfo referencedMemberInfo) { if (referencedMemberInfo == null) { return null; } return MemberInfoObfuscator.newMemberName(referencedMemberInfo); } /** * Returns whether the given access flags specify a package visible class * or class member (including public or protected access). */ private boolean isPackageVisible(int accessFlags) { return AccessUtil.accessLevel(accessFlags) >= AccessUtil.PACKAGE_VISIBLE; } /** * Returns the given access flags, modified such that the class or class * member becomes public. */ private int makePublic(int accessFlags) { return AccessUtil.replaceAccessFlags(accessFlags, ClassConstants.INTERNAL_ACC_PUBLIC); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -