1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/* 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of Java bytecode. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 52270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu) 6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it 8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free 9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option) 10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version. 11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT 13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details. 16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along 18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc., 19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.obfuscate; 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*; 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.util.*; 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.util.ListUtil; 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/** 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This MappingKeeper applies the mappings that it receives to its class pool, 30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * so these mappings are ensured in a subsequent obfuscation step. 31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune 33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class MappingKeeper implements MappingProcessor 35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{ 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final ClassPool classPool; 37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final WarningPrinter warningPrinter; 38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // A field acting as a parameter. 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private Clazz clazz; 41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new MappingKeeper. 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param classPool the class pool in which class names and class 46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * member names have to be mapped. 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param warningPrinter the optional warning printer to which warnings 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * can be printed. 49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public MappingKeeper(ClassPool classPool, 51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato WarningPrinter warningPrinter) 52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.classPool = classPool; 54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.warningPrinter = warningPrinter; 55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for MappingProcessor. 59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public boolean processClassMapping(String className, 61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String newClassName) 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Find the class. 64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String name = ClassUtil.internalClassName(className); 65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz = classPool.getClass(name); 67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (clazz != null) 68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String newName = ClassUtil.internalClassName(newClassName); 70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Print out a warning if the mapping conflicts with a name that 72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // was set before. 73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (warningPrinter != null) 74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String currentNewName = ClassObfuscator.newClassName(clazz); 76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (currentNewName != null && 77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato !currentNewName.equals(newName)) 78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato warningPrinter.print(name, 80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato currentNewName, 81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato "Warning: " + 82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato className + 83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato " is not being kept as '" + 84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassUtil.externalClassName(currentNewName) + 85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato "', but remapped to '" + 86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato newClassName + "'"); 87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassObfuscator.setNewClassName(clazz, newName); 91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // The class members have to be kept as well. 93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return true; 94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return false; 97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void processFieldMapping(String className, 101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String fieldType, 102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String fieldName, 103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String newFieldName) 104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (clazz != null) 106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Find the field. 108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String name = fieldName; 109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String descriptor = ClassUtil.internalType(fieldType); 110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Field field = clazz.findField(name, descriptor); 112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (field != null) 113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Print out a warning if the mapping conflicts with a name that 115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // was set before. 116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (warningPrinter != null) 117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String currentNewName = MemberObfuscator.newMemberName(field); 119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (currentNewName != null && 120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato !currentNewName.equals(newFieldName)) 121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato warningPrinter.print(ClassUtil.internalClassName(className), 123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato "Warning: " + 124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato className + 125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ": field '" + fieldType + " " + fieldName + 126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato "' is not being kept as '" + currentNewName + 127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato "', but remapped to '" + newFieldName + "'"); 128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Make sure the mapping name will be kept. 132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato MemberObfuscator.setFixedNewMemberName(field, newFieldName); 133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void processMethodMapping(String className, 139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int firstLineNumber, 140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int lastLineNumber, 141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String methodReturnType, 142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String methodName, 143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String methodArguments, 144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String newMethodName) 145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (clazz != null) 147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Find the method. 149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String descriptor = ClassUtil.internalMethodDescriptor(methodReturnType, 150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ListUtil.commaSeparatedList(methodArguments)); 151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Method method = clazz.findMethod(methodName, descriptor); 153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (method != null) 154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Print out a warning if the mapping conflicts with a name that 156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // was set before. 157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (warningPrinter != null) 158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String currentNewName = MemberObfuscator.newMemberName(method); 160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (currentNewName != null && 161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato !currentNewName.equals(newMethodName)) 162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato warningPrinter.print(ClassUtil.internalClassName(className), 164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato "Warning: " + 165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato className + 1662270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom ": method '" + methodReturnType + " " + methodName + JavaConstants.METHOD_ARGUMENTS_OPEN + methodArguments + JavaConstants.METHOD_ARGUMENTS_CLOSE + 167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato "' is not being kept as '" + currentNewName + 168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato "', but remapped to '" + newMethodName + "'"); 169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Make sure the mapping name will be kept. 173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato MemberObfuscator.setFixedNewMemberName(method, newMethodName); 174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 178