1 19 20 package jode.obfuscator; 21 import jode.AssertError; 22 import jode.GlobalOptions; 23 import jode.bytecode.*; 24 25 import java.util.Collections ; 26 import java.util.Iterator ; 27 import java.util.Map ; 28 29 import java.lang.reflect.Modifier ; 30 import java.util.BitSet ; 31 32 public class MethodIdentifier extends Identifier implements Opcodes { 33 ClassIdentifier clazz; 34 MethodInfo info; 35 String name; 36 String type; 37 38 boolean globalSideEffects; 39 BitSet localSideEffects; 40 41 44 CodeAnalyzer codeAnalyzer; 45 46 public MethodIdentifier(ClassIdentifier clazz, MethodInfo info) { 47 super(info.getName()); 48 this.name = info.getName(); 49 this.type = info.getType(); 50 this.clazz = clazz; 51 this.info = info; 52 53 BytecodeInfo bytecode = info.getBytecode(); 54 if (bytecode != null) { 55 if ((Main.stripping & Main.STRIP_LVT) != 0) 56 info.getBytecode().setLocalVariableTable(null); 57 if ((Main.stripping & Main.STRIP_LNT) != 0) 58 info.getBytecode().setLineNumberTable(null); 59 codeAnalyzer = Main.getClassBundle().getCodeAnalyzer(); 60 61 CodeTransformer[] trafos 62 = Main.getClassBundle().getPreTransformers(); 63 for (int i = 0; i < trafos.length; i++) { 64 trafos[i].transformCode(bytecode); 65 } 66 info.setBytecode(bytecode); 67 } 68 } 69 70 public Iterator getChilds() { 71 return Collections.EMPTY_LIST.iterator(); 72 } 73 74 public void setSingleReachable() { 75 super.setSingleReachable(); 76 Main.getClassBundle().analyzeIdentifier(this); 77 } 78 79 public void analyze() { 80 if (GlobalOptions.verboseLevel > 1) 81 GlobalOptions.err.println("Analyze: "+this); 82 83 String type = getType(); 84 int index = type.indexOf('L'); 85 while (index != -1) { 86 int end = type.indexOf(';', index); 87 Main.getClassBundle().reachableClass 88 (type.substring(index+1, end).replace('/', '.')); 89 index = type.indexOf('L', end); 90 } 91 92 String [] exceptions = info.getExceptions(); 93 if (exceptions != null) { 94 for (int i=0; i< exceptions.length; i++) 95 Main.getClassBundle() 96 .reachableClass(exceptions[i]); 97 } 98 99 BytecodeInfo code = info.getBytecode(); 100 if (code != null) 101 codeAnalyzer.analyzeCode(this, code); 102 } 103 104 public Identifier getParent() { 105 return clazz; 106 } 107 108 public String getFullName() { 109 return clazz.getFullName() + "." + getName() + "." + getType(); 110 } 111 112 public String getFullAlias() { 113 return clazz.getFullAlias() + "." + getAlias() + "." 114 + Main.getClassBundle().getTypeAlias(getType()); 115 } 116 117 public String getName() { 118 return name; 119 } 120 121 public String getType() { 122 return type; 123 } 124 125 public int getModifiers() { 126 return info.getModifiers(); 127 } 128 129 public boolean conflicting(String newAlias) { 130 return clazz.methodConflicts(this, newAlias); 131 } 132 133 public String toString() { 134 return "MethodIdentifier "+getFullName(); 135 } 136 137 public boolean hasGlobalSideEffects() { 138 return globalSideEffects; 139 } 140 141 public boolean getLocalSideEffects(int paramNr) { 142 return globalSideEffects || localSideEffects.get(paramNr); 143 } 144 145 public void setGlobalSideEffects() { 146 globalSideEffects = true; 147 } 148 149 public void setLocalSideEffects(int paramNr) { 150 localSideEffects.set(paramNr); 151 } 152 153 160 boolean wasTransformed = false; 161 public void doTransformations() { 162 if (wasTransformed) 163 throw new jode.AssertError 164 ("doTransformation called on transformed method"); 165 wasTransformed = true; 166 info.setName(getAlias()); 167 ClassBundle bundle = Main.getClassBundle(); 168 info.setType(bundle.getTypeAlias(type)); 169 if (codeAnalyzer != null) { 170 BytecodeInfo bytecode = info.getBytecode(); 171 try { 172 175 if (isReachable()) 176 codeAnalyzer.transformCode(bytecode); 177 CodeTransformer[] trafos = bundle.getPostTransformers(); 178 for (int i = 0; i < trafos.length; i++) { 179 trafos[i].transformCode(bytecode); 180 } 181 } catch (RuntimeException ex) { 182 ex.printStackTrace(GlobalOptions.err); 183 bytecode.dumpCode(GlobalOptions.err); 184 } 185 186 for (Iterator iter = bytecode.getInstructions().iterator(); 187 iter.hasNext(); ) { 188 Instruction instr = (Instruction) iter.next(); 189 switch (instr.getOpcode()) { 190 case opc_invokespecial: 191 case opc_invokestatic: 192 case opc_invokeinterface: 193 case opc_invokevirtual: { 194 instr.setReference 195 (Main.getClassBundle() 196 .getReferenceAlias(instr.getReference())); 197 break; 198 199 } 200 case opc_putstatic: 201 case opc_putfield: 202 case opc_getstatic: 203 case opc_getfield: { 204 instr.setReference 205 (Main.getClassBundle() 206 .getReferenceAlias(instr.getReference())); 207 break; 208 } 209 case opc_new: 210 case opc_checkcast: 211 case opc_instanceof: 212 case opc_multianewarray: { 213 instr.setClazzType 214 (Main.getClassBundle() 215 .getTypeAlias(instr.getClazzType())); 216 break; 217 } 218 } 219 } 220 221 Handler[] handlers = bytecode.getExceptionHandlers(); 222 for (int i=0; i< handlers.length; i++) { 223 if (handlers[i].type != null) { 224 ClassIdentifier ci = Main.getClassBundle() 225 .getClassIdentifier(handlers[i].type); 226 if (ci != null) 227 handlers[i].type = ci.getFullAlias(); 228 } 229 } 230 info.setBytecode(bytecode); 231 } 232 233 String [] exceptions = info.getExceptions(); 234 if (exceptions != null) { 235 for (int i=0; i< exceptions.length; i++) { 236 ClassIdentifier ci = Main.getClassBundle() 237 .getClassIdentifier(exceptions[i]); 238 if (ci != null) 239 exceptions[i] = ci.getFullAlias(); 240 } 241 } 242 } 243 } 244 | Popular Tags |