@Override protected void internalTransform(Body body, String phaseName, Map<String, String> options) { // Do not instrument methods in framework classes if (!canInstrumentMethod(body.getMethod())) return; instrumentInfoAboutNonAPICall(body); //important to use snapshotIterator here Iterator<Unit> iterator = body.getUnits().snapshotIterator(); while(iterator.hasNext()){ Unit unit = iterator.next(); if(unit instanceof ReturnStmt || unit instanceof ReturnVoidStmt) instrumentInfoAboutReturnStmt(body, unit); else if(unit instanceof DefinitionStmt || unit instanceof InvokeStmt) instrumentInfoAboutNonApiCaller(body, unit); else if(unit instanceof IfStmt) instrumentEachBranchAccess(body, (IfStmt)unit); } }
public boolean tryBodyPattern(List<Object> body,SETNodeLabel label, List<Object> otherBody){ Stmt lastStmt = getLastStmt(body); if(lastStmt == null){ //dont have a last stmt so cant match pattern return false; } if(! (lastStmt instanceof ReturnStmt || lastStmt instanceof ReturnVoidStmt || lastStmt instanceof DAbruptStmt)){ //lastStmt is not an abrupt stmt return false; } if(bodyTargetsLabel(label,body) || bodyTargetsLabel(label,otherBody)){ //one of the bodies targets the label on the ifelse cant match pattern return false; } //pattern matched return true; }
public static Stmt getReturnStmt(SootMethod sootMethod) { Stmt rtVal = null; Body b = sootMethod.retrieveActiveBody(); PatchingChain<Unit> units = b.getUnits(); for (Iterator<Unit> iter = units.iterator(); iter.hasNext(); ) { Stmt stmt = (Stmt) iter.next(); if (stmt instanceof ReturnStmt || stmt instanceof ReturnVoidStmt) { rtVal = stmt; } } return rtVal; }
public static void insertBeforeReturn(Chain<Unit> units, Chain<Unit> toInsert) { Unit point = null; Iterator<Unit> unitIt = units.snapshotIterator(); while (unitIt.hasNext()) { Unit unit = unitIt.next(); if (unit instanceof ReturnVoidStmt) { point = unit; break; } } if (point == null) { units.addAll(toInsert); } else { units.insertBefore(toInsert, point); } }
public static boolean isBranch(Unit u){ if(u instanceof IfStmt || u instanceof GotoStmt || u instanceof SwitchStmt || u instanceof ThrowStmt || u instanceof ReturnStmt || u instanceof ReturnVoidStmt) return true; return false; }
@Override public void caseReturnVoidStmt(ReturnVoidStmt stmt) { //do nothing return; }
private boolean isEmpty(Body activeBody) { for (Unit u : activeBody.getUnits()) if (!(u instanceof IdentityStmt || u instanceof ReturnVoidStmt)) return false; return true; }
public void caseReturnVoidStmt(ReturnVoidStmt stmt) { Return r = new Return(); r.setAssignmentTarget(null); addStatement(r); }
public void caseReturnVoidStmt(ReturnVoidStmt stmt) { printStmt(stmt); }
public void caseReturnVoidStmt(ReturnVoidStmt stmt) { }
@Override public void caseReturnVoidStmt(ReturnVoidStmt stmt) { addInsn(new Insn10x(Opcode.RETURN_VOID), stmt); }
private boolean isInstanceofReturn(Unit u) { if (u instanceof ReturnStmt || u instanceof ReturnVoidStmt) return true; return false; }
public void jimplify (DexBody body) { ReturnVoidStmt returnStmt = Jimple.v().newReturnVoidStmt(); setUnit(returnStmt); addTags(returnStmt); body.add(returnStmt); }
/** * Whenever a statement has to be processed the first step is to invoke this * method. This is to remove the tedious work of adding code to deal with * abrupt control flow from the programmer of the analysis. The method * invokes the processStatement method for all other statements * * A programmer can decide to override this method if they want to do * something specific */ public DavaFlowSet processAbruptStatements(Stmt s, DavaFlowSet input) { if (s instanceof ReturnStmt || s instanceof RetStmt || s instanceof ReturnVoidStmt) { // dont need to remember this path return NOPATH; } else if (s instanceof DAbruptStmt) { DAbruptStmt abStmt = (DAbruptStmt) s; // see if its a break or continue if (!(abStmt.is_Continue() || abStmt.is_Break())) { // DAbruptStmt is of only two kinds throw new RuntimeException("Found a DAbruptStmt which is neither break nor continue!!"); } DavaFlowSet temp = NOPATH; SETNodeLabel nodeLabel = abStmt.getLabel(); // System.out.println("here"); if (nodeLabel != null && nodeLabel.toString() != null) { // explicit abrupt stmt if (abStmt.is_Continue()) temp.addToContinueList(nodeLabel.toString(), input); else if (abStmt.is_Break()) temp.addToBreakList(nodeLabel.toString(), input); else throw new RuntimeException("Found abruptstmt which is neither break nor continue"); } else { // found implicit break/continue if (abStmt.is_Continue()) temp.addToImplicitContinues(abStmt, input); else if (abStmt.is_Break()) temp.addToImplicitBreaks(abStmt, input); else throw new RuntimeException("Found abruptstmt which is neither break nor continue"); } return temp; } else { /**************************************************************/ /****** ALL OTHER STATEMENTS HANDLED BY PROGRAMMER **************/ /**************************************************************/ return processStatement(s, input); } }
@Override public DavaFlowSet processAbruptStatements(Stmt s, DavaFlowSet input){ if(DEBUG) System.out.println("processing stmt "+s); if(s instanceof ReturnStmt || s instanceof RetStmt || s instanceof ReturnVoidStmt){ //dont need to remember this path UnreachableCodeFlowSet toReturn = new UnreachableCodeFlowSet(); toReturn.add(new Boolean(false)); toReturn.copyInternalDataFrom(input); //false indicates NOPATH if(DEBUG) System.out.println("\tstmt is a return stmt. Hence sending forward false"); return toReturn; } else if(s instanceof DAbruptStmt){ DAbruptStmt abStmt = (DAbruptStmt)s; //see if its a break or continue if(!(abStmt.is_Continue()|| abStmt.is_Break())){ //DAbruptStmt is of only two kinds throw new RuntimeException("Found a DAbruptStmt which is neither break nor continue!!"); } DavaFlowSet temp = new UnreachableCodeFlowSet(); SETNodeLabel nodeLabel = abStmt.getLabel(); // notice we ignore continues for this analysis if (abStmt.is_Break()){ if(nodeLabel != null && nodeLabel.toString() != null){ //explicit break stmt temp.addToBreakList(nodeLabel.toString(),input); } else{ //found implicit break temp.addToImplicitBreaks(abStmt,input); } } temp.add(new Boolean(false)); temp.copyInternalDataFrom(input); if(DEBUG) System.out.println("\tstmt is an abrupt stmt. Hence sending forward false"); return temp; } else{ if(DEBUG) System.out.println("\tstmt is not an abrupt stmt."); return processStatement(s,input); } }
@Override public void caseReturnVoidStmt(ReturnVoidStmt s) { // result = result.add(mgr.ILLEGAL_MONITOR_STATE_EXCEPTION); }
@Override public void caseReturnVoidStmt(ReturnVoidStmt arg0) { injectLabelStatements(arg0); this.boogieStatements.add(this.pf.mkReturnStatement()); }
public final void caseReturnVoidStmt(ReturnVoidStmt s) { statement = s; caseReturnStmt( (Local) null ); }
@Override public void run(SpyResult result, AppDescription app) { Scene scene = Scene.v(); int count = 0; Iterator<SootClass> classes = scene.getApplicationClasses().iterator(); while(classes.hasNext()) { SootClass clazz = classes.next(); for (SootMethod method : clazz.getMethods()) { if(!method.hasActiveBody()) continue; Body body = method.getActiveBody(); Chain<Unit> code = body.getUnits(); Iterator<Trap> traps = body.getTraps().iterator(); while(traps.hasNext()) { boolean bogus = false; Trap trap = traps.next(); Unit lastOfCatch = trap.getEndUnit(); // System.err.println("Last of catch " + lastOfCatch); Unit firstHandler = trap.getHandlerUnit(); // System.err.println("First of handler " + firstHandler); Unit nextHandler = code.getSuccOf(firstHandler); // System.err.println("Next handler " + nextHandler); if (nextHandler == null) continue; Unit handlerTarget = seekTarget(nextHandler); if (handlerTarget == null) continue; // System.err.println("handler goto " + handlerTarget + handlerTarget.getClass()); if (handlerTarget instanceof ReturnVoidStmt) { bogus = true; } else if (lastOfCatch instanceof GotoStmt) { bogus = handlerTarget.equals(seekTarget(lastOfCatch)); } else { if (!lastOfCatch.fallsThrough()) continue; Unit targetCatch = code.getSuccOf(lastOfCatch); if (targetCatch == null) continue; // This had to be a return. // System.err.println("Target 1" + targetCatch); if (handlerTarget.equals(targetCatch)) bogus = true; if (targetCatch.fallsThrough() && !targetCatch.branches()) { targetCatch = code.getSuccOf(targetCatch); // System.err.println("Target 2" + targetCatch); if (handlerTarget.equals(targetCatch)) bogus = true; } } // System.err.println(bogus); if (bogus) { BytecodeOffsetTag tag = (BytecodeOffsetTag) firstHandler.getTag("BytecodeOffsetTag"); int offset = (tag == null) ? -1 : tag.getBytecodeOffset(); result.setCustomResult(listItem("android.empty.exception.class",count),clazz.getName()); result.setCustomResult(listItem("android.empty.exception.method",count),method.getSubSignature()); result.setCustomResult(listItem("android.empty.exception.pos",count),offset); count++; } } result.setCustomResult("android.empty.exception.error", count > 0); result.setCustomResult("android.empty.exception.count", count); } } }
@Override public void caseReturnVoidStmt(ReturnVoidStmt stmt) { returnStmt = stmt; }
@Override public void caseReturnVoidStmt(ReturnVoidStmt stmt) { logger.fine("\n > > > Return void statement identified < < <"); valueSwitch.callingStmt = stmt; }
@Override public void caseReturnVoidStmt(ReturnVoidStmt stmt) { logger.fine("\n > > > Return void statement identified < < <"); }
/** * DOC * * @see soot.jimple.StmtSwitch#caseReturnVoidStmt(soot.jimple.ReturnVoidStmt) */ @Override public void caseReturnVoidStmt(ReturnVoidStmt stmt) { }
/** * Method, which should process the given statement of type * {@link ReturnVoidStmt}. Therefore the method checks whether the analyzed * method is a 'void' return <em>security level</em>, if not then an error * will be logged. * * @param stmt * Statement that should be processed to check for security * violations. * @see soot.jimple.StmtSwitch#caseReturnVoidStmt(soot.jimple.ReturnVoidStmt) */ @Override public void caseReturnVoidStmt(ReturnVoidStmt stmt) { // Nothing to do in case of a void return }