| 1 19 20 25 26 package soot.jimple.toolkits.invoke; 27 28 import java.util.ArrayList ; 29 import java.util.Iterator ; 30 import java.util.LinkedList ; 31 32 import soot.*; 33 import soot.javaToJimple.LocalGenerator; 34 import soot.jimple.*; 35 import soot.util.Chain; 36 37 38 public class AccessManager 39 { 40 50 public static boolean isAccessLegal(SootMethod container, ClassMember target) 51 { 52 SootClass targetClass = target.getDeclaringClass(); 53 SootClass containerClass = container.getDeclaringClass(); 54 55 if (!isAccessLegal(container, targetClass)) 56 return false; 57 58 if (target.isPrivate() && 60 !targetClass.getName().equals(containerClass.getName())) 61 return false; 62 63 if (!target.isPrivate() && !target.isProtected() 65 && !target.isPublic()) 66 { 67 if (!targetClass.getPackageName().equals 68 (containerClass.getPackageName())) 69 return false; 70 } 71 72 if (target.isProtected()) 74 { 75 Hierarchy h = Scene.v().getActiveHierarchy(); 76 77 if (h.isClassSuperclassOfIncluding(targetClass, containerClass)) 80 return true; 81 82 return false; 83 } 84 85 return true; 86 } 87 88 89 public static boolean isAccessLegal(SootMethod container, SootClass target) 90 { 91 return target.isPublic() || 92 container.getDeclaringClass().getPackageName().equals(target.getPackageName()); 93 } 94 95 102 public static boolean isAccessLegal(SootMethod container, Stmt stmt) { 103 if (stmt.containsInvokeExpr()) { 104 return AccessManager.isAccessLegal(container, stmt.getInvokeExpr().getMethod()); 105 } else if (stmt instanceof AssignStmt) { 106 AssignStmt as=(AssignStmt)stmt; 107 if (as.getRightOp() instanceof FieldRef) { 108 FieldRef r=(FieldRef)as.getRightOp(); 109 return AccessManager.isAccessLegal(container, r.getField()); 110 } 111 if (as.getLeftOp() instanceof FieldRef) { 112 FieldRef r=(FieldRef)as.getLeftOp(); 113 return AccessManager.isAccessLegal(container, r.getField()); 114 } 115 } 116 return true; 117 } 118 119 127 public static void createAccessorMethods(Body body, Stmt before, Stmt after) { 128 soot.util.Chain units=body.getUnits(); 129 130 if (before!=null && !units.contains(before)) 131 throw new RuntimeException (); 132 if (after!=null && !units.contains(after)) 133 throw new RuntimeException (); 134 135 ArrayList unitList = new ArrayList (); unitList.addAll(units); 136 137 boolean bInside=before==null; 138 for (java.util.Iterator it=unitList.iterator(); it.hasNext();) { 139 Stmt s=(Stmt)it.next(); 140 141 if (bInside) { 142 if (s==after) 143 return; 144 145 if (!isAccessLegal(body.getMethod(), s)) 146 createAccessorMethod(body.getMethod(), s); 147 148 } else { 149 if (s==before) 150 bInside=true; 151 } 152 } 153 154 } 155 156 157 163 public static String createAccessorName(ClassMember member, boolean setter) { 164 SootClass target=member.getDeclaringClass(); 165 166 String name="access$"; 167 if (member instanceof SootField) { 168 SootField f=(SootField)member; 169 if (setter) { 170 name +="set$"; 171 } else { 172 name +="get$"; 173 } 174 name +=f.getName(); 175 } else { 176 SootMethod m=(SootMethod)member; 177 name += m.getName() + "$"; 178 179 for (Iterator it=m.getParameterTypes().iterator(); it.hasNext();) { 180 Type type=(Type)it.next(); 181 name += type.toString().replaceAll("\\.", "\\$\\$") + "$"; 182 } 183 } 184 return name; 185 } 186 187 193 public static void createAccessorMethod(SootMethod container, Stmt stmt) 194 { 195 199 Body containerBody=container.getActiveBody(); 200 soot.util.Chain containerStmts=containerBody.getUnits(); 201 if (!containerStmts.contains(stmt)) 202 throw new RuntimeException (); 203 204 if (stmt.containsInvokeExpr()) { 205 createInvokeAccessor(container, stmt); 206 } else if (stmt instanceof AssignStmt) { 207 AssignStmt as=(AssignStmt)stmt; 208 FieldRef ref; 209 if (as.getLeftOp() instanceof FieldRef) { 210 ref=(FieldRef)as.getLeftOp(); 212 createSetAccessor(container, as, ref); 213 214 } else if (as.getRightOp() instanceof FieldRef) { 215 ref=(FieldRef)as.getRightOp(); 217 createGetAccessor(container, as, ref); 218 } else { 219 throw new RuntimeException ("Expected class member access"); 220 } 221 } else 222 throw new RuntimeException ("Expected class member access"); 223 } 224 225 private static void createGetAccessor(SootMethod container, AssignStmt as, FieldRef ref) { 226 java.util.List parameterTypes=new LinkedList (); 227 java.util.List thrownExceptions=new LinkedList (); 228 229 230 Body accessorBody = Jimple.v().newBody(); 231 soot.util.Chain accStmts=accessorBody.getUnits(); 232 LocalGenerator lg=new LocalGenerator(accessorBody); 233 234 Body containerBody=container.getActiveBody(); 235 soot.util.Chain containerStmts=containerBody.getUnits(); 236 237 SootClass target=ref.getField().getDeclaringClass(); 238 239 SootMethod accessor; 240 241 String name=createAccessorName(ref.getField(), false); 242 if (target.declaresMethodByName(name)) { 243 accessor=target.getMethodByName(name); 244 } else { 245 Type returnType=ref.getField().getType(); 246 Local thisLocal=lg.generateLocal(target.getType()); 247 if (ref instanceof InstanceFieldRef) { 248 parameterTypes.add(target.getType()); 249 accStmts.addFirst( 250 Jimple.v().newIdentityStmt(thisLocal, 251 Jimple.v().newParameterRef(target.getType(),0))); 252 } 253 Local l=lg.generateLocal(ref.getField().getType()); 254 Value v; 255 if (ref instanceof InstanceFieldRef) { 256 v=Jimple.v().newInstanceFieldRef(thisLocal,ref.getFieldRef()); 257 } else { 258 v=Jimple.v().newStaticFieldRef(ref.getFieldRef()); 259 } 260 accStmts.add(Jimple.v().newAssignStmt(l, v)); 261 accStmts.add(Jimple.v().newReturnStmt(l)); 262 263 accessor=new SootMethod(name, parameterTypes, returnType, 264 Modifier.PUBLIC | Modifier.STATIC, 265 thrownExceptions); 266 accessorBody.setMethod(accessor); 267 accessor.setActiveBody(accessorBody); 268 target.addMethod(accessor); 269 } 270 java.util.List args=new LinkedList (); 271 if (ref instanceof InstanceFieldRef) { 272 args.add(((InstanceFieldRef)ref).getBase()); 273 } 274 InvokeExpr newExpr= 275 Jimple.v().newStaticInvokeExpr(accessor.makeRef(), args); 276 277 as.setRightOp(newExpr); 278 } 279 280 private static void createSetAccessor(SootMethod container, AssignStmt as, FieldRef ref) { 281 java.util.List parameterTypes=new LinkedList (); 282 java.util.List thrownExceptions=new LinkedList (); 283 284 Body accessorBody = Jimple.v().newBody(); 285 soot.util.Chain accStmts=accessorBody.getUnits(); 286 LocalGenerator lg=new LocalGenerator(accessorBody); 287 288 Body containerBody=container.getActiveBody(); 289 soot.util.Chain containerStmts=containerBody.getUnits(); 290 291 SootClass target=ref.getField().getDeclaringClass(); 292 SootMethod accessor; 293 294 String name=createAccessorName(ref.getField(), true); 295 if (target.declaresMethodByName(name)) { 296 accessor=target.getMethodByName(name); 297 } else { 298 Local thisLocal=lg.generateLocal(target.getType()); 299 int paramID=0; 300 if (ref instanceof InstanceFieldRef) { 301 accStmts.add( 302 Jimple.v().newIdentityStmt(thisLocal, 303 Jimple.v().newParameterRef(target.getType(),paramID))); 304 parameterTypes.add(target.getType()); 305 paramID++; 306 } 307 parameterTypes.add(ref.getField().getType()); 308 Local l=lg.generateLocal(ref.getField().getType()); 309 accStmts.add( 310 Jimple.v().newIdentityStmt(l, 311 Jimple.v().newParameterRef(ref.getField().getType(),paramID))); 312 paramID++; 313 if (ref instanceof InstanceFieldRef) { 314 accStmts.add(Jimple.v().newAssignStmt( 315 Jimple.v().newInstanceFieldRef(thisLocal,ref.getFieldRef()), l)); 316 } else { 317 accStmts.add(Jimple.v().newAssignStmt( 318 Jimple.v().newStaticFieldRef(ref.getFieldRef()), l)); 319 } 320 accStmts.addLast(Jimple.v().newReturnVoidStmt()); 321 Type returnType=VoidType.v(); 322 323 accessor=new SootMethod(name, parameterTypes, returnType, 324 Modifier.PUBLIC | Modifier.STATIC, 325 thrownExceptions); 326 accessorBody.setMethod(accessor); 327 accessor.setActiveBody(accessorBody); 328 target.addMethod(accessor); 329 } 330 331 java.util.List args=new LinkedList (); 332 if (ref instanceof InstanceFieldRef) { 333 args.add(((InstanceFieldRef)ref).getBase()); 334 } 335 args.add(as.getRightOp()); 336 InvokeExpr newExpr= 337 Jimple.v().newStaticInvokeExpr(accessor.makeRef(), args); 338 339 Stmt newStmt=Jimple.v().newInvokeStmt(newExpr); 340 341 containerStmts.insertAfter(newStmt, as); 342 containerStmts.remove(as); 343 } 344 345 private static void createInvokeAccessor(SootMethod container, Stmt stmt) { 346 java.util.List parameterTypes=new LinkedList (); 347 java.util.List thrownExceptions=new LinkedList (); 348 Type returnType; 349 350 Body accessorBody = Jimple.v().newBody(); 351 soot.util.Chain accStmts=accessorBody.getUnits(); 352 LocalGenerator lg=new LocalGenerator(accessorBody); 353 354 Body containerBody=container.getActiveBody(); 355 soot.util.Chain containerStmts=containerBody.getUnits(); 356 357 InvokeExpr expr=stmt.getInvokeExpr(); 358 SootMethod method=expr.getMethod(); 359 361 SootClass target=method.getDeclaringClass(); 362 364 366 SootMethod accessor; 367 368 String name=createAccessorName(method, true); 369 if (target.declaresMethodByName(name)) { 370 accessor=target.getMethodByName(name); 371 } else { 372 java.util.List arguments=new LinkedList (); 373 374 if (expr instanceof InstanceInvokeExpr) { 375 parameterTypes.add(target.getType()); 376 } 377 378 parameterTypes.addAll(method.getParameterTypes()); 379 returnType=method.getReturnType(); 380 thrownExceptions.addAll(method.getExceptions()); 381 382 int paramID=0; 383 for (java.util.Iterator it=parameterTypes.iterator(); it.hasNext();) { 384 Type type=(Type)it.next(); 385 Local l=lg.generateLocal(type); 386 accStmts.add( 388 Jimple.v().newIdentityStmt(l, 389 Jimple.v().newParameterRef(type, paramID))); 390 arguments.add(l); 391 paramID++; 392 } 393 394 InvokeExpr accExpr; 395 396 if (expr instanceof StaticInvokeExpr) { 397 accExpr=Jimple.v().newStaticInvokeExpr(method.makeRef(), arguments); 398 } else if (expr instanceof VirtualInvokeExpr) { 399 Local thisLocal=(Local)arguments.get(0); 400 arguments.remove(0); 401 accExpr=Jimple.v().newVirtualInvokeExpr(thisLocal, method.makeRef(), arguments); 402 } else if (expr instanceof SpecialInvokeExpr) { 403 Local thisLocal=(Local)arguments.get(0); 404 arguments.remove(0); 405 accExpr=Jimple.v().newSpecialInvokeExpr(thisLocal, method.makeRef(), arguments); 406 } else 407 throw new RuntimeException (""); 408 409 Stmt s; 410 if (returnType instanceof VoidType) { 411 s=Jimple.v().newInvokeStmt(accExpr); 412 accStmts.add(s); 413 accStmts.add(Jimple.v().newReturnVoidStmt()); 414 } else { 415 Local resultLocal=lg.generateLocal(returnType); 416 s=Jimple.v().newAssignStmt(resultLocal,accExpr); 417 accStmts.add(s); 418 accStmts.add(Jimple.v().newReturnStmt(resultLocal)); 419 } 420 421 accessor=new SootMethod(name, parameterTypes, returnType, 422 Modifier.PUBLIC | Modifier.STATIC, 423 thrownExceptions); 424 accessorBody.setMethod(accessor); 425 accessor.setActiveBody(accessorBody); 426 target.addMethod(accessor); 427 } 428 429 java.util.List args=new LinkedList (); 430 if (expr instanceof InstanceInvokeExpr) { 431 args.add(((InstanceInvokeExpr)expr).getBase()); 432 } 433 args.addAll(expr.getArgs()); 434 InvokeExpr newExpr= 435 Jimple.v().newStaticInvokeExpr(accessor.makeRef(), args); 436 437 stmt.getInvokeExprBox().setValue(newExpr); 438 } 439 440 446 public static boolean ensureAccess(SootMethod container, ClassMember target, String options) 447 { 448 boolean accessors=options.equals("accessors"); 449 boolean allowChanges = !(options.equals("none")); 450 boolean safeChangesOnly = !(options.equals("unsafe")); 451 452 453 SootClass targetClass = target.getDeclaringClass(); 454 if (!ensureAccess(container, targetClass, options)) 455 return false; 456 457 if (isAccessLegal(container, target)) 458 return true; 459 460 if (!allowChanges && !accessors) 461 return false; 462 463 464 466 if (target.getDeclaringClass().isApplicationClass()) 467 { 468 if (accessors) 469 return true; 470 471 if (safeChangesOnly) 472 throw new RuntimeException ("Not implemented yet!"); 473 474 target.setModifiers(target.getModifiers() | Modifier.PUBLIC); 475 return true; 476 } 477 else 478 return false; 479 } 480 481 482 public static boolean ensureAccess(SootMethod container, SootClass target, String options) 483 { 484 boolean accessors=options.equals("accessors"); 485 boolean allowChanges = !(options.equals("none")); 486 boolean safeChangesOnly = !(options.equals("unsafe")); 487 488 if (isAccessLegal(container, target)) 489 return true; 490 491 if (!allowChanges && !accessors) 492 return false; 493 494 if (safeChangesOnly && !accessors) 495 throw new RuntimeException ("Not implemented yet!"); 496 497 if (accessors) 498 return false; 499 500 if (target.isApplicationClass()) 501 { 502 503 target.setModifiers(target.getModifiers() | Modifier.PUBLIC); 504 return true; 505 } 506 else 507 return false; 508 } 509 510 } 511 | Popular Tags |