1 19 20 25 26 package soot.jimple.toolkits.invoke; 27 28 import soot.*; 29 import soot.jimple.*; 30 import soot.util.*; 31 import java.util.*; 32 33 34 public class SynchronizerManager 35 { 36 public SynchronizerManager( Singletons.Global g ) {} 37 public static SynchronizerManager v() { return G.v().soot_jimple_toolkits_invoke_SynchronizerManager(); } 38 39 public HashMap classToClassField = new HashMap(); 40 41 58 public Local addStmtsToFetchClassBefore(JimpleBody jb, Stmt target) 59 { 60 SootClass sc = jb.getMethod().getDeclaringClass(); 61 SootField classCacher = (SootField)classToClassField.get(sc); 62 if (classCacher == null) 63 { 64 String n = "class$"+sc.getName().replace('.', '$'); 66 while (sc.declaresFieldByName(n)) 67 n = "_" + n; 68 69 classCacher = new SootField(n, RefType.v("java.lang.Class"), Modifier.STATIC); 70 sc.addField(classCacher); 71 classToClassField.put(sc, classCacher); 72 } 73 74 String lName = "$uniqueClass"; 75 76 while (true) 78 { 79 Iterator it = jb.getLocals().iterator(); 80 boolean oops = false; 81 while (it.hasNext()) 82 { 83 Local jbLocal = (Local)it.next(); 84 if (jbLocal.getName().equals(lName)) 85 oops = true; 86 } 87 if (!oops) 88 break; 89 lName = "_" + lName; 90 } 91 92 Local l = Jimple.v().newLocal(lName, RefType.v("java.lang.Class")); 93 jb.getLocals().add(l); 94 Chain units = jb.getUnits(); 95 units.insertBefore(Jimple.v().newAssignStmt(l, 96 Jimple.v().newStaticFieldRef(classCacher.makeRef())), 97 target); 98 99 IfStmt ifStmt; 100 units.insertBefore(ifStmt = Jimple.v().newIfStmt 101 (Jimple.v().newNeExpr(l, NullConstant.v()), 102 target), target); 103 104 units.insertBefore(Jimple.v().newAssignStmt 105 (l, Jimple.v().newStaticInvokeExpr(getClassFetcherFor(sc).makeRef(), 106 Arrays.asList(new Value[] {StringConstant.v(sc.getName())}))), 107 target); 108 units.insertBefore(Jimple.v().newAssignStmt 109 (Jimple.v().newStaticFieldRef(classCacher.makeRef()), 110 l), target); 111 112 ifStmt.setTarget(target); 113 return l; 114 } 115 116 122 public SootMethod getClassFetcherFor(SootClass c) 123 { 124 String methodName = "class$"; 125 for ( ; true; methodName = "_" + methodName) 126 { 127 if (!c.declaresMethodByName(methodName)) 128 return createClassFetcherFor(c, methodName); 129 130 SootMethod m = c.getMethodByName(methodName); 131 132 if (!m.getSignature().equals 134 ("<"+c.getName().replace('.', '$')+": java.lang.Class "+ 135 methodName+"(java.lang.String)>")) 136 continue; 137 138 Body b = null; 139 b = m.retrieveActiveBody(); 140 141 Iterator unitsIt = b.getUnits().iterator(); 142 143 144 149 150 if (!unitsIt.hasNext()) 151 continue; 152 153 Stmt s = (Stmt)unitsIt.next(); 154 if (!(s instanceof IdentityStmt)) 155 continue; 156 157 IdentityStmt is = (IdentityStmt)s; 158 Value lo = is.getLeftOp(), ro = is.getRightOp(); 159 160 if (!(ro instanceof ParameterRef)) 161 continue; 162 163 ParameterRef pr = (ParameterRef)ro; 164 if (pr.getIndex() != 0) 165 continue; 166 167 if (!unitsIt.hasNext()) 168 continue; 169 170 s = (Stmt)unitsIt.next(); 171 if (!(s instanceof AssignStmt)) 172 continue; 173 174 AssignStmt as = (AssignStmt)s; 175 Value retVal = as.getLeftOp(), ie = as.getRightOp(); 176 177 if (!ie.toString().equals(".staticinvoke <java.lang.Class: java.lang.Class forName(java.lang.String)>("+lo+")")) 178 continue; 179 180 if (!unitsIt.hasNext()) 181 continue; 182 183 s = (Stmt)unitsIt.next(); 184 if (!(s instanceof ReturnStmt)) 185 continue; 186 187 ReturnStmt rs = (ReturnStmt) s; 188 if (!rs.getOp().equivTo(retVal)) 189 continue; 190 191 192 193 return m; 194 } 195 } 196 197 226 public SootMethod createClassFetcherFor(SootClass c, 227 String methodName) 228 { 229 SootMethod method = new SootMethod(methodName, 231 Arrays.asList(new Type[] {RefType.v("java.lang.String")}), 232 RefType.v("java.lang.Class"), Modifier.STATIC); 233 234 c.addMethod(method); 235 236 { 238 JimpleBody body = Jimple.v().newBody(method); 239 240 method.setActiveBody(body); 241 Chain units = body.getUnits(); 242 Local l_r0, l_r1, l_r2, l_r3, l_r4, l_r5; 243 244 l_r0 = Jimple.v().newLocal 246 ("r0", RefType.v("java.lang.String")); 247 l_r1 = Jimple.v().newLocal 248 ("r1", RefType.v("java.lang.ClassNotFoundException")); 249 l_r2 = Jimple.v().newLocal 250 ("$r2", RefType.v("java.lang.Class")); 251 l_r3 = Jimple.v().newLocal 252 ("$r3", RefType.v("java.lang.ClassNotFoundException")); 253 l_r4 = Jimple.v().newLocal 254 ("$r4", RefType.v("java.lang.NoClassDefFoundError")); 255 l_r5 = Jimple.v().newLocal 256 ("$r5", RefType.v("java.lang.String")); 257 258 body.getLocals().add(l_r0); 259 body.getLocals().add(l_r1); 260 body.getLocals().add(l_r2); 261 body.getLocals().add(l_r3); 262 body.getLocals().add(l_r4); 263 body.getLocals().add(l_r5); 264 265 units.add(Jimple.v().newIdentityStmt(l_r0, 267 Jimple.v().newParameterRef 268 (RefType.v("java.lang.String"), 0))); 269 270 AssignStmt asi; 272 units.add(asi = Jimple.v().newAssignStmt(l_r2, 273 Jimple.v().newStaticInvokeExpr( 274 Scene.v().getMethod( 275 "<java.lang.Class: java.lang.Class"+ 276 " forName(java.lang.String)>").makeRef(), 277 Arrays.asList(new Value[] {l_r0})))); 278 279 units.add(Jimple.v().newReturnStmt(l_r2)); 281 282 Stmt handlerStart; 284 units.add(handlerStart = Jimple.v().newIdentityStmt(l_r3, 285 Jimple.v().newCaughtExceptionRef())); 286 287 units.add(Jimple.v().newAssignStmt(l_r1, l_r3)); 289 290 units.add(Jimple.v().newAssignStmt(l_r4, 292 Jimple.v().newNewExpr(RefType.v 293 ("java.lang.NoClassDefFoundError")))); 294 295 units.add(Jimple.v().newAssignStmt(l_r5, 297 Jimple.v().newVirtualInvokeExpr(l_r1, 298 Scene.v().getMethod("<java.lang.Throwable: java.lang.String getMessage()>").makeRef(), 299 new LinkedList()))); 300 301 units.add(Jimple.v().newInvokeStmt( 303 Jimple.v().newSpecialInvokeExpr(l_r4, 304 Scene.v().getMethod( 305 "<java.lang.NoClassDefFoundError: void"+ 306 " <init>(java.lang.String)>").makeRef(), 307 Arrays.asList(new Value[] {l_r5})))); 308 309 units.add(Jimple.v().newThrowStmt(l_r4)); 311 312 body.getTraps().add(Jimple.v().newTrap 313 (Scene.v().getSootClass("java.lang.ClassNotFoundException"), 314 asi, handlerStart, handlerStart)); 315 } 316 317 return method; 318 } 319 320 323 public void synchronizeStmtOn(Stmt stmt, JimpleBody b, Local lock) 324 { 325 Chain units = b.getUnits(); 326 327 329 units.insertBefore(Jimple.v().newEnterMonitorStmt(lock), stmt); 330 331 Stmt exitMon = Jimple.v().newExitMonitorStmt(lock); 332 units.insertAfter(exitMon, stmt); 333 334 342 346 349 351 355 360 { 362 Stmt newGoto = Jimple.v().newGotoStmt((Stmt)units.getSuccOf(exitMon)); 363 units.insertAfter(newGoto, exitMon); 364 365 List l = new ArrayList(); 366 Local eRef = Jimple.v().newLocal("__exception", RefType.v("java.lang.Throwable")); 367 b.getLocals().add(eRef); 368 Stmt handlerStmt = Jimple.v().newIdentityStmt(eRef, Jimple.v().newCaughtExceptionRef()); 369 l.add(handlerStmt); 370 l.add(exitMon.clone()); 371 l.add(Jimple.v().newThrowStmt(eRef)); 372 units.insertAfter(l, newGoto); 373 374 Trap newTrap = Jimple.v().newTrap(Scene.v().getSootClass("java.lang.Throwable"), 375 stmt, (Stmt)units.getSuccOf(stmt), 376 handlerStmt); 377 b.getTraps().addFirst(newTrap); 378 } 379 } 380 } 381 | Popular Tags |