@Override public void caseVirtualInvokeExpr(VirtualInvokeExpr virtualInvokeExpr) { //is the invokeExpr a source method? if(isSourceMethod(virtualInvokeExpr)) { StringConstant newSourceValue = StringConstant.v("loggingPoint"); SMTBinding binding = stmtVisitor.createNewBindingForValue(newSourceValue); stmtVisitor.addValueBindingToVariableDeclaration(newSourceValue, binding); //no smt-statement required, just return the binding this.result = binding; // Additionally check whether the source method need special treatment if(isExpressionThatNeedsToBeConvertedToSMT(virtualInvokeExpr)) { convertSpecialExpressionsToSMT(virtualInvokeExpr, currentStatement); } } else { if(isStringOperationSupportedBySMT(virtualInvokeExpr)) convertStringOperationToSMT(virtualInvokeExpr, virtualInvokeExpr.getBase()); else if(isExpressionThatNeedsToBeConvertedToSMT(virtualInvokeExpr)) convertSpecialExpressionsToSMT(virtualInvokeExpr, currentStatement); else convertAPIMethodToSMT(virtualInvokeExpr); } }
@Override public void caseVirtualInvokeExpr(VirtualInvokeExpr v) { logger.fine("Invoke expression is of type VirtualInvoke"); logger.finest(v.toString()); rightElement = RightElement.NOT; if (actualContext == StmtContext.INVOKE || actualContext == StmtContext.ASSIGNRIGHT ) { Local[] args = vh.getArgumentsForInvokedMethod(v); String method = v.getMethod().toString(); if (ExternalClasses.methodMap.containsKey(method)) { logger.fine("Found an external class " + method); logger.fine("This class is treated in a special way"); ExternalClasses.receiveCommand(method, callingStmt, args); } else { logger.fine("Found an external class " + method); logger.fine("This class is treated as an internal class"); JimpleInjector.storeArgumentLevels(callingStmt, args); } } else { throw new InternalAnalyzerException( "Unexpected Context for Invoke Expression"); } }
@Override public void caseVirtualInvokeExpr(VirtualInvokeExpr vie) { /* * for final methods we build an invoke-virtual opcode, too, although the dex spec says that a virtual method is not final. * An alternative would be the invoke-direct opcode, but this is inconsistent with dx's output... */ BuilderMethodReference method = DexPrinter.toMethodReference (vie.getMethodRef(), dexFile); List<Register> argumentRegs = getInstanceInvokeArgumentRegs(vie); stmtV.addInsn(buildInvokeInsn("INVOKE_VIRTUAL", method, argumentRegs), origStmt); }
private Value checkThreadStartStmt(Stmt sootStmt) { // Check for function calls if(sootStmt instanceof InvokeStmt) { InvokeStmt invokeStmt = (InvokeStmt)sootStmt; // Check if the current statement is a constructor if(invokeStmt.getInvokeExpr() instanceof VirtualInvokeExpr) { // It's a constructor. Check if it's a Thread allocation site VirtualInvokeExpr invokeExpr = (VirtualInvokeExpr)invokeStmt.getInvokeExpr(); String functionSignature = invokeExpr.getMethod().getSignature(); String className = SusHelper.getClassFromSignature(functionSignature); String functionName = invokeExpr.getMethod().getName(); try { if((Thread.class.isAssignableFrom( Class.forName(className, false, this.getClass().getClassLoader()))) && (functionName.equals("start")) && (invokeExpr.getMethod().getParameterCount() == 0)) { //System.out.println("Invoke method "+invokeExpr.getMethod()+" on "+invokeExpr.getBase()); //System.out.println("run() called on "+innerRunnable.get(invokeExpr.getBase())); return invokeExpr.getBase(); } } catch (ClassNotFoundException e) { System.err.println("Unable to find class "+className); } } } return null; }
public static void main(String[] args) { PackManager.v().getPack("wjtp").add(new Transform("wjtp.onflyicfg", new SceneTransformer() { @Override protected void internalTransform(String phaseName, Map<String, String> options) { if (Scene.v().hasCallGraph()) throw new RuntimeException("call graph present!"); loadAllClassesOnClassPathToSignatures(); SootMethod mainMethod = Scene.v().getMainMethod(); JitIcfg icfg = new JitIcfg(mainMethod); Set<SootMethod> worklist = new LinkedHashSet<SootMethod>(); Set<SootMethod> visited = new HashSet<SootMethod>(); worklist.add(mainMethod); int monomorphic = 0, polymorphic = 0; while (!worklist.isEmpty()) { Iterator<SootMethod> iter = worklist.iterator(); SootMethod currMethod = iter.next(); iter.remove(); visited.add(currMethod); System.err.println(currMethod); // MUST call this method to initialize ICFG for // every method Body body = currMethod.getActiveBody(); if (body == null) continue; for (Unit u : body.getUnits()) { Stmt s = (Stmt) u; if (s.containsInvokeExpr()) { Set<SootMethod> calleesOfCallAt = icfg.getCalleesOfCallAt(s); if (s.getInvokeExpr() instanceof VirtualInvokeExpr || s.getInvokeExpr() instanceof InterfaceInvokeExpr) { if (calleesOfCallAt.size() <= 1) monomorphic++; else polymorphic++; System.err.println("mono: " + monomorphic + " poly: " + polymorphic); } for (SootMethod callee : calleesOfCallAt) { if (!visited.contains(callee)) { System.err.println(callee); // worklist.add(callee); } } } } } } })); Options.v().set_on_the_fly(true); soot.Main.main(args); }
public void caseVirtualInvokeExpr(VirtualInvokeExpr expr) { caseInstanceInvokeExpr(expr); }
public void caseVirtualInvokeExpr(VirtualInvokeExpr v) { printInvokeExpr(v); }
public static void main(String[] args) { PackManager.v().getPack("wjtp").add(new Transform("wjtp.onflyicfg", new SceneTransformer() { @Override protected void internalTransform(String phaseName, Map<String, String> options) { if(Scene.v().hasCallGraph()) throw new RuntimeException("call graph present!"); loadAllClassesOnClassPathToSignatures(); SootMethod mainMethod = Scene.v().getMainMethod(); OnTheFlyJimpleBasedICFG icfg = new OnTheFlyJimpleBasedICFG(mainMethod); Set<SootMethod> worklist = new LinkedHashSet<SootMethod>(); Set<SootMethod> visited = new HashSet<SootMethod>(); worklist.add(mainMethod); int monomorphic = 0, polymorphic = 0; while(!worklist.isEmpty()) { Iterator<SootMethod> iter = worklist.iterator(); SootMethod currMethod = iter.next(); iter.remove(); visited.add(currMethod); System.err.println(currMethod); //MUST call this method to initialize ICFG for every method Body body = currMethod.getActiveBody(); if(body==null) continue; for(Unit u: body.getUnits()) { Stmt s = (Stmt)u; if(s.containsInvokeExpr()) { Set<SootMethod> calleesOfCallAt = icfg.getCalleesOfCallAt(s); if(s.getInvokeExpr() instanceof VirtualInvokeExpr || s.getInvokeExpr() instanceof InterfaceInvokeExpr) { if(calleesOfCallAt.size()<=1) monomorphic++; else polymorphic++; System.err.println("mono: "+monomorphic+" poly: "+polymorphic); } for (SootMethod callee : calleesOfCallAt) { if(!visited.contains(callee)) { System.err.println(callee); //worklist.add(callee); } } } } } } })); Options.v().set_on_the_fly(true); soot.Main.main(args); }
static private boolean specialCaseInvoke(SootStmtSwitch ss, Value lhs, InvokeExpr ivk) { SootValueSwitch valueswitch = ss.getValueSwitch(); ProgramFactory pf = GlobalsCache.v().getPf(); // java.lang.String.length is treated as a special case: resolveBaseIfNecessary(ivk); if (ivk.getMethod().getSignature() .contains("<java.lang.String: int length()>") && lhs != null) { if (ivk instanceof SpecialInvokeExpr) { ((SpecialInvokeExpr) ivk).getBase().apply(valueswitch); } else if (ivk instanceof VirtualInvokeExpr) { ((VirtualInvokeExpr) ivk).getBase().apply(valueswitch); } else { throw new RuntimeException("Bad usage of String.length?"); } Expression[] indices = { valueswitch.getExpression() }; Expression right = pf.mkArrayAccessExpression(pf.getIntType(), SootPrelude.v().getStringSizeHeapVariable(), indices); lhs.apply(valueswitch); Expression left = valueswitch.getExpression(); AssignmentTranslation.translateAssignment(ss, left, right); return true; } if (ivk.getMethod().getSignature() .contains("<java.lang.System: void exit(int)>")) { Log.debug("Surppressing false positive from call to System.exit"); // this is not a return statement, it actually ends the application. // ss.addStatement(pf.mkAssumeStatement(new // Attribute[]{pf.mkNoVerifyAttribute()}, // pf.mkBooleanLiteral(false))); ss.addStatement(pf.mkReturnStatement()); return true; } if (ivk.getMethod() .getSignature() .contains( "java.lang.Throwable: void addSuppressed(java.lang.Throwable)")) { ss.addStatement(TranslationHelpers.mkLocationAssertion( ss.getCurrentStatement(), true)); return true; } if (ivk.getMethod().getSignature().contains("addSuppressed")) { System.err.println(ivk.getMethod().getSignature()); } return false; }
@Override public void caseVirtualInvokeExpr(VirtualInvokeExpr arg0) { throw new RuntimeException("This must be handeled by SootStmtSwitch!"); }
static private boolean specialCaseInvoke(SootStmtSwitch ss, Value lhs, InvokeExpr ivk) { SootValueSwitch valueswitch = ss.getValueSwitch(); ProgramFactory pf = GlobalsCache.v().getPf(); // java.lang.String.length is treated as a special case: if (ivk.getMethod().getSignature() .contains("<java.lang.String: int length()>") && lhs != null) { if (ivk instanceof SpecialInvokeExpr) { ((SpecialInvokeExpr) ivk).getBase().apply(valueswitch); } else if (ivk instanceof VirtualInvokeExpr) { ((VirtualInvokeExpr) ivk).getBase().apply(valueswitch); } else { throw new RuntimeException("Bad usage of String.length?"); } Expression[] indices = { valueswitch.getExpression() }; Expression right = pf.mkArrayAccessExpression(pf.getIntType(), SootPrelude.v().getStringSizeHeapVariable(), indices); lhs.apply(valueswitch); Expression left = valueswitch.getExpression(); AssignmentTranslation.translateAssignment(ss, left, right); return true; } if (ivk.getMethod().getSignature() .contains("<java.lang.System: void exit(int)>")) { Log.info("Surppressing false positive from call to System.exit"); // this is not a return statement, it actually ends the application. // ss.addStatement(pf.mkAssumeStatement(new // Attribute[]{pf.mkNoVerifyAttribute()}, // pf.mkBooleanLiteral(false))); ss.addStatement(pf.mkReturnStatement()); return true; } if (ivk.getMethod() .getSignature() .contains( "java.lang.Throwable: void addSuppressed(java.lang.Throwable)")) { ss.addStatement(TranslationHelpers.mkLocationAssertion( ss.getCurrentStatement(), true)); return true; } if (ivk.getMethod().getSignature().contains("addSuppressed")) { System.err.println(ivk.getMethod().getSignature()); } return false; }
@Override public void caseVirtualInvokeExpr(VirtualInvokeExpr v) { throwInvalidWriteException(v); }
@Override public void caseVirtualInvokeExpr(VirtualInvokeExpr v) { handleBase(v.getBase()); handleInvoke(v); }
/** * Computes the targets of an invoke expression using a given points-to graph. * * <p>For static invocations, there is only target. For instance method * invocations, the targets depend on the type of receiver objects pointed-to * by the instance variable whose method is being invoked.</p> * * <p>If the instance variable points to a summary node, then the returned * value is <tt>null</tt> signifying a <em>default</em> call-site.</p> */ private Set<SootMethod> getTargets(SootMethod callerMethod, Stmt callStmt, InvokeExpr ie, PointsToGraph ptg) { Set<SootMethod> targets = new HashSet<SootMethod>(); SootMethod invokedMethod = ie.getMethod(); String subsignature = invokedMethod.getSubSignature(); // Static and special invocations refer to the target method directly if (ie instanceof StaticInvokeExpr || ie instanceof SpecialInvokeExpr) { targets.add(invokedMethod); return targets; } else { assert (ie instanceof InterfaceInvokeExpr || ie instanceof VirtualInvokeExpr); // Get the receiver Local receiver = (Local) ((InstanceInvokeExpr) ie).getBase(); // Get what objects the receiver points-to Set<AnyNewExpr> heapNodes = ptg.getTargets(receiver); if (heapNodes != null) { // For each object, find the invoked method for the declared type for (AnyNewExpr heapNode : heapNodes) { if (heapNode == PointsToGraph.SUMMARY_NODE) { // If even one pointee is a summary node, then this is a default site return null; } else if (heapNode instanceof NewArrayExpr) { // Probably getClass() or something like that on an array return null; } // Find the top-most class that declares a method with the given // signature and add it to the resulting targets SootClass sootClass = ((RefType) heapNode.getType()).getSootClass(); do { if (sootClass.declaresMethod(subsignature)) { targets.add(sootClass.getMethod(subsignature)); break; } else if (sootClass.hasSuperclass()) { sootClass = sootClass.getSuperclass(); } else { sootClass = null; } } while (sootClass != null); } } if (targets.isEmpty()) { // System.err.println("Warning! Null call at: " + callStmt+ " in " + callerMethod); } return targets; } }
/** * Looks up the <em>security level</em> of the given invoke expression with * the type {@link VirtualInvokeExpr} and stores the resulting level in * {@link SecurityLevelValueReadSwitch#level}. Also the parameter * <em>security level</em> and the <em>write effects</em> will be handled. * Additionally, the base of the invoke expression will be checked and if * the level of the base if stronger than the resulting * <em>security level</em> of the invoke expression, then this base * <em>security level</em> will be stored in * {@link SecurityLevelValueReadSwitch#level}. * * @param v * The invoke expression, for which the level should be looked * up. * @see soot.jimple.ExprSwitch#caseVirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) * @see SecurityLevelValueReadSwitch#handleInvokeExpr(InvokeExpr) * @see SecurityLevelValueReadSwitch#handleBase(Value, Value) */ @Override public void caseVirtualInvokeExpr(VirtualInvokeExpr v) { handleInvokeExpr(v); Value base = v.getBase(); handleBase(base, v); }
/** * The method should update the <em>security level</em> of an invoke * expression with type {@link VirtualInvokeExpr}, but it is not possible to * update the level of an invoke expression. * * @param v * The invoke expression for which the <em>security level</em> * should be updated. * @see soot.jimple.ExprSwitch#caseVirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) * @throws InvalidSwitchException * Always, because the update is not possible. */ @Override public void caseVirtualInvokeExpr(VirtualInvokeExpr v) { throw new SwitchException(getMsg("exception.analysis.switch.update_error", this.getClass().getSimpleName(), v.getClass().getSimpleName(), v.toString(), getSourceLine())); }
/** * DOC * * @see soot.jimple.ExprSwitch#caseVirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) */ @Override public void caseVirtualInvokeExpr(VirtualInvokeExpr v) { this.extractor.addMethodEnvironmentForMethod(v.getMethod()); }