private void instrumentEachBranchAccess(Body body, Unit unit){ SootClass sootClass = Scene.v().getSootClass( UtilInstrumenter.JAVA_CLASS_FOR_PATH_INSTRUMENTATION); // Create the method invocation SootMethod createAndAdd = sootClass.getMethod("reportConditionOutcomeSynchronous", Collections.<Type>singletonList(BooleanType.v())); StaticInvokeExpr sieThen = Jimple.v().newStaticInvokeExpr( createAndAdd.makeRef(), IntConstant.v(1)); StaticInvokeExpr sieElse = Jimple.v().newStaticInvokeExpr( createAndAdd.makeRef(), IntConstant.v(0)); Unit sieThenUnit = Jimple.v().newInvokeStmt(sieThen); sieThenUnit.addTag(new InstrumentedCodeTag()); Unit sieElseUnit = Jimple.v().newInvokeStmt(sieElse); sieElseUnit.addTag(new InstrumentedCodeTag()); //treatment of target statement ("true"-branch) IfStmt ifStmt = (IfStmt)unit; Stmt targetStmt = ifStmt.getTarget(); if(!branchTargetStmt.contains(targetStmt.toString())) { branchTargetStmt.add(sieThenUnit.toString()); body.getUnits().insertBefore(sieThenUnit, targetStmt); NopStmt nop = Jimple.v().newNopStmt(); GotoStmt gotoNop = Jimple.v().newGotoStmt(nop); body.getUnits().insertBeforeNoRedirect(nop, targetStmt); body.getUnits().insertBeforeNoRedirect(gotoNop, sieThenUnit); } //treatment of "else"-branch body.getUnits().insertAfter(sieElseUnit, unit); }
/** Removes {@link NopStmt}s from the passed body (which must be a {@link JimpleBody}). Complexity is linear with respect to the statements. */ protected void internalTransform(Body b, String phaseName, Map<String, String> options) { JimpleBody body = (JimpleBody)b; if(Options.v().verbose()) G.v().out.println("[" + body.getMethod().getName() + "] Removing nops..."); Chain<Unit> units = body.getUnits(); // Just do one trivial pass. { Iterator<Unit> stmtIt = units.snapshotIterator(); while(stmtIt.hasNext()) { Unit u = stmtIt.next(); if (u instanceof NopStmt) { // Hack: do not remove nop, if is is used for a Trap which // is at the very end of the code. boolean keepNop = false; if (b.getUnits().getLast() == u) { for (Trap t : b.getTraps()) { if (t.getEndUnit() == u) { keepNop = true; } } } if (!keepNop) { units.remove(u); } } } } }
private static void insertNopStatements() { for (Iterator<MethodOrMethodContext> iter = Scene.v().getReachableMethods().listener(); iter.hasNext();) { SootMethod m = iter.next().method(); if (m.hasActiveBody()) { Body b = m.getActiveBody(); NopStmt newNopStmt = Jimple.v().newNopStmt(); newNopStmt.addAllTagsOf(b.getUnits().getFirst()); b.getUnits().addFirst(newNopStmt); ActiveBodyVerifier.markActive(m); } else ActiveBodyVerifier.markInactive(m); } }
private static void instrumentOnKey(SootClass activity, String methodSubSignature, SootMethod toCall) { SootMethod method; try { method = activity.getMethod(methodSubSignature); } catch (RuntimeException e) { throw new RuntimeException("Method not found: " + methodSubSignature + " in class: " + activity.getJavaStyleName() + "\n" + e.getMessage()); } method.setModifiers(method.getModifiers() & (~Modifier.FINAL)); Body body = method.retrieveActiveBody(); Chain<Unit> toInsert = new HashChain<Unit>(); Local thislocal = Util.findthislocal(body.getUnits()); Local firstparam = Util.findparamlocal(body.getUnits()); Local secondparam = Util.findsecondparamlocal(body.getUnits()); Local returnvalue = Jimple.v().newLocal("returnvalue", BooleanType.v()); body.getLocals().add(returnvalue); toInsert.add(Jimple.v(). newAssignStmt(returnvalue, Jimple.v(). newStaticInvokeExpr(toCall.makeRef(), thislocal, firstparam, secondparam))); NopStmt jumpTarget = Jimple.v().newNopStmt(); toInsert.add(Jimple.v(). newIfStmt(Jimple.v(). newEqExpr( returnvalue, IntConstant.v(0)), jumpTarget)); toInsert.add(Jimple.v().newReturnStmt(returnvalue)); toInsert.add(jumpTarget); Util.insertAfterIdentityStmt(body.getUnits(), toInsert); }
@Override public void caseNopStmt(NopStmt stmt) { throw new RuntimeException("todo"); }
@Override public Collection<? extends IPathEdge<Unit, AccessGraph>> unbalancedReturnFunction( IPathEdge<Unit, AccessGraph> currEdge, Unit callSite, Unit returnSite, SootMethod callee) { // Unbalanced return only occurs when the start statement of the path edge is not the first // statement of the method, i.e. a NopStmt if (currEdge.getStart() instanceof NopStmt) { return Collections.emptySet(); } // Retrieve the backward edges associated with the forward edge Collection<IPathEdge<Unit, AccessGraph>> collection = fwToBwEdge.get(currEdge.getStartNode()); if (collection == null) return Collections.emptySet(); for (IPathEdge<Unit, AccessGraph> currBwEdge : collection) { if (context.getSubQuery() == null) return Collections.emptySet(); // Retrieve the incoming set for the backward edges, to know, where the forward analysis can // return to in an unbalanced manner (forward analysis follows backward analysis, hence it // also should do so at returns.) Collection<IPathEdge<Unit, AccessGraph>> incomingMap = context.getSubQuery().backwardIncoming(currBwEdge.getStartNode(), callee); if (incomingMap == null) return Collections.emptySet(); matchingAllocationIncomingEdge = new HashSet<>(); // check that parentsolver has callSite in incomingMap, Otherwise we do not need to return; for (IPathEdge<Unit, AccessGraph> inc : incomingMap) { Unit callSiteOfAlloc = inc.getTarget(); if (callSiteOfAlloc.equals(callSite)) { matchingAllocationIncomingEdge.add(inc); constructPath(inc); } } } // There was no incoming in the ASolver for the appropriate callSite. if (matchingAllocationIncomingEdge == null || matchingAllocationIncomingEdge.isEmpty()) { return Collections.emptySet(); } return super.unbalancedReturnFunction(currEdge, callSite, returnSite, callee); }
public void caseNopStmt(NopStmt stmt) { printStmt(stmt); }
public void caseNopStmt(NopStmt stmt) { }
@Override public void caseNopStmt(NopStmt stmt) { addInsn(new Insn10x(Opcode.NOP), stmt); }
/** * Creates an intermediate jump instruction between the original jump * instruction and its target * @param targetInsPos The jump target index * @param jumpInsPos The position of the jump instruction * @param stmtV The statement visitor used for constructing the instructions * @param instructions The list of Dalvik instructions * @param labelAssigner The label assigner to be used for creating new labels */ private void insertIntermediateJump(int targetInsPos, int jumpInsPos, StmtVisitor stmtV, List<BuilderInstruction> instructions, LabelAssigner labelAssigner) { // Get the original jump instruction BuilderInstruction originalJumpInstruction = instructions.get(jumpInsPos); Insn originalJumpInsn = stmtV.getInsnForInstruction(originalJumpInstruction); if (originalJumpInsn == null) return; if (!(originalJumpInsn instanceof InsnWithOffset)) throw new RuntimeException("Unexpected jump instruction target"); InsnWithOffset offsetInsn = (InsnWithOffset) originalJumpInsn; // Find a position where we can jump to int distance = Math.max(targetInsPos, jumpInsPos) - Math.min(targetInsPos, jumpInsPos); if (distance == 0) return; int newJumpIdx = Math.min(targetInsPos, jumpInsPos) + (distance / 2); int sign = (int) Math.signum(targetInsPos - jumpInsPos); if (distance > offsetInsn.getMaxJumpOffset()) newJumpIdx = jumpInsPos + sign; // There must be a statement at the instruction after the jump target while (stmtV.getStmtForInstruction(instructions.get(newJumpIdx)) == null) { newJumpIdx += sign; if (newJumpIdx < 0 || newJumpIdx >= instructions.size()) throw new RuntimeException("No position for inserting intermediate " + "jump instruction found"); } // Create a jump instruction from the middle to the end NopStmt nop = Jimple.v().newNopStmt(); Insn30t newJump = new Insn30t(Opcode.GOTO_32); newJump.setTarget(stmtV.getStmtForInstruction(instructions.get(targetInsPos))); BuilderInstruction newJumpInstruction = newJump.getRealInsn(labelAssigner); instructions.add(newJumpIdx, newJumpInstruction); stmtV.fakeNewInsn(nop, newJump, newJumpInstruction); // We have added something, so we need to fix indices if (newJumpIdx < jumpInsPos) jumpInsPos++; if (newJumpIdx < targetInsPos) targetInsPos++; // Jump from the original instruction to the new one in the middle offsetInsn.setTarget(nop); BuilderInstruction replacementJumpInstruction = offsetInsn.getRealInsn(labelAssigner); instructions.add(jumpInsPos, replacementJumpInstruction); instructions.remove(originalJumpInstruction); stmtV.fakeNewInsn(stmtV.getStmtForInstruction(originalJumpInstruction), originalJumpInsn, replacementJumpInstruction); // Our indices are still fine, because we just replaced something Stmt afterNewJump = stmtV.getStmtForInstruction(instructions.get(newJumpIdx + 1)); // Make the original control flow jump around the new artificial jump instruction Insn10t jumpAround = new Insn10t(Opcode.GOTO); jumpAround.setTarget(afterNewJump); BuilderInstruction jumpAroundInstruction = jumpAround.getRealInsn(labelAssigner); instructions.add(newJumpIdx, jumpAroundInstruction); }
public void jimplify (DexBody body) { NopStmt nop = Jimple.v().newNopStmt(); setUnit(nop); addTags(nop); body.add(nop); }
@Override public void caseNopStmt(NopStmt s) { }
@Override public void caseNopStmt(NopStmt arg0) { injectLabelStatements(arg0); // Log.error("NopStmt: " + arg0.toString()); // assert (false); }
@Override public void caseNopStmt(NopStmt stmt) { }
@Override public void caseNopStmt(NopStmt stmt) { logger.fine("\n > > > Nop statement identified < < <"); }
/** * DOC * * @see soot.jimple.StmtSwitch#caseNopStmt(soot.jimple.NopStmt) */ @Override public void caseNopStmt(NopStmt stmt) { }
/** * Method, which should process the given statement of type {@link NopStmt}. * In this case, there is no reason to check the statement in more detail. * Because of that nothing will be done for a nop statement. * * @param stmt * Statement that should be processed to check for security * violations. * @see soot.jimple.StmtSwitch#caseNopStmt(soot.jimple.NopStmt) */ @Override public void caseNopStmt(NopStmt stmt) { // Nothing to do in case of a nop stmt }