| 1 19 20 package jode.obfuscator.modules; 21 import jode.bytecode.Handler; 22 import jode.bytecode.Opcodes; 23 import jode.bytecode.ClassInfo; 24 import jode.bytecode.BytecodeInfo; 25 import jode.bytecode.Instruction; 26 import jode.bytecode.Reference; 27 import jode.bytecode.TypeSignature; 28 import jode.obfuscator.Identifier; 29 import jode.obfuscator.*; 30 import jode.GlobalOptions; 31 32 import java.util.Iterator ; 33 import java.util.ListIterator ; 34 35 public class SimpleAnalyzer implements CodeAnalyzer, Opcodes { 36 37 private ClassInfo canonizeIfaceRef(ClassInfo clazz, Reference ref) { 38 while (clazz != null) { 39 if (clazz.findMethod(ref.getName(), ref.getType()) != null) 40 return clazz; 41 ClassInfo[] ifaces = clazz.getInterfaces(); 42 for (int i = 0; i < ifaces.length; i++) { 43 ClassInfo realClass = canonizeIfaceRef(ifaces[i], ref); 44 if (realClass != null) 45 return realClass; 46 } 47 clazz = clazz.getSuperclass(); 48 } 49 return null; 50 } 51 52 public Identifier canonizeReference(Instruction instr) { 53 Reference ref = instr.getReference(); 54 Identifier ident = Main.getClassBundle().getIdentifier(ref); 55 String clName = ref.getClazz(); 56 String realClazzName; 57 if (ident != null) { 58 ClassIdentifier clazz = (ClassIdentifier)ident.getParent(); 59 realClazzName = "L" + (clazz.getFullName() 60 .replace('.', '/')) + ";"; 61 } else { 62 65 ClassInfo clazz; 66 if (clName.charAt(0) == '[') { 67 70 clazz = ClassInfo.javaLangObject; 71 } else { 72 clazz = ClassInfo.forName 73 (clName.substring(1, clName.length()-1) 74 .replace('/','.')); 75 } 76 if (instr.getOpcode() == opc_invokeinterface) { 77 clazz = canonizeIfaceRef(clazz, ref); 78 } else if (instr.getOpcode() >= opc_invokevirtual) { 79 while (clazz != null 80 && clazz.findMethod(ref.getName(), 81 ref.getType()) == null) 82 clazz = clazz.getSuperclass(); 83 } else { 84 while (clazz != null 85 && clazz.findField(ref.getName(), 86 ref.getType()) == null) 87 clazz = clazz.getSuperclass(); 88 } 89 90 if (clazz == null) { 91 GlobalOptions.err.println("WARNING: Can't find reference: " 92 +ref); 93 realClazzName = clName; 94 } else 95 realClazzName = "L" + clazz.getName().replace('.', '/') + ";"; 96 } 97 if (!realClazzName.equals(ref.getClazz())) { 98 ref = Reference.getReference(realClazzName, 99 ref.getName(), ref.getType()); 100 instr.setReference(ref); 101 } 102 return ident; 103 } 104 105 106 111 public void analyzeCode(MethodIdentifier m, BytecodeInfo bytecode) { 112 for (Iterator iter = bytecode.getInstructions().iterator(); 113 iter.hasNext(); ) { 114 Instruction instr = (Instruction) iter.next(); 115 switch (instr.getOpcode()) { 116 case opc_checkcast: 117 case opc_instanceof: 118 case opc_multianewarray: { 119 String clName = instr.getClazzType(); 120 int i = 0; 121 while (i < clName.length() && clName.charAt(i) == '[') 122 i++; 123 if (i < clName.length() && clName.charAt(i) == 'L') { 124 clName = clName.substring(i+1, clName.length()-1) 125 .replace('/','.'); 126 Main.getClassBundle().reachableClass(clName); 127 } 128 break; 129 } 130 case opc_invokespecial: 131 case opc_invokestatic: 132 case opc_invokeinterface: 133 case opc_invokevirtual: 134 case opc_putstatic: 135 case opc_putfield: 136 m.setGlobalSideEffects(); 137 138 case opc_getstatic: 139 case opc_getfield: { 140 Identifier ident = canonizeReference(instr); 141 if (ident != null) { 142 if (instr.getOpcode() == opc_putstatic 143 || instr.getOpcode() == opc_putfield) { 144 FieldIdentifier fi = (FieldIdentifier) ident; 145 if (fi != null && !fi.isNotConstant()) 146 fi.setNotConstant(); 147 } else if (instr.getOpcode() == opc_invokevirtual 148 || instr.getOpcode() == opc_invokeinterface) { 149 ((ClassIdentifier) ident.getParent()) 150 .reachableReference(instr.getReference(), true); 151 } else { 152 ident.setReachable(); 153 } 154 } 155 break; 156 } 157 } 158 } 159 160 Handler[] handlers = bytecode.getExceptionHandlers(); 161 for (int i=0; i< handlers.length; i++) { 162 if (handlers[i].type != null) 163 Main.getClassBundle() 164 .reachableClass(handlers[i].type); 165 } 166 } 167 168 public void transformCode(BytecodeInfo bytecode) { 169 for (ListIterator iter = bytecode.getInstructions().listIterator(); 170 iter.hasNext(); ) { 171 Instruction instr = (Instruction) iter.next(); 172 if (instr.getOpcode() == opc_putstatic 173 || instr.getOpcode() == opc_putfield) { 174 Reference ref = instr.getReference(); 175 FieldIdentifier fi = (FieldIdentifier) 176 Main.getClassBundle().getIdentifier(ref); 177 if (fi != null 178 && (Main.stripping & Main.STRIP_UNREACH) != 0 179 && !fi.isReachable()) { 180 181 int stacksize = 182 (instr.getOpcode() 183 == Instruction.opc_putstatic) ? 0 : 1; 184 stacksize += TypeSignature.getTypeSize(ref.getType()); 185 switch (stacksize) { 186 case 1: 187 iter.set(new Instruction(Instruction.opc_pop)); 188 break; 189 case 2: 190 iter.set(new Instruction(Instruction.opc_pop2)); 191 break; 192 case 3: 193 iter.set(new Instruction(Instruction.opc_pop2)); 194 iter.add(new Instruction(Instruction.opc_pop)); 195 break; 196 } 197 } 198 } 199 } 200 } 201 } 202 | Popular Tags |