@Override public void caseIdentityStmt(IdentityStmt stmt) { Value lhs = stmt.getLeftOp(); Value rhs = stmt.getRightOp(); if (rhs instanceof CaughtExceptionRef) { // save the caught exception with move-exception Register localReg = regAlloc.asLocal(lhs); addInsn(new Insn11x(Opcode.MOVE_EXCEPTION, localReg), stmt); this.insnRegisterMap.put(insns.get(insns.size() - 1), LocalRegisterAssignmentInformation.v(localReg, (Local)lhs)); } else if (rhs instanceof ThisRef || rhs instanceof ParameterRef) { /* * do not save the ThisRef or ParameterRef in a local, because it always has a parameter register already. * at least use the local for further reference in the statements */ Local localForThis = (Local) lhs; regAlloc.asParameter(belongingMethod, localForThis); parameterInstructionsList.add(LocalRegisterAssignmentInformation.v(regAlloc.asLocal(localForThis).clone(), localForThis)); } else { throw new Error("unknown Value as right-hand side of IdentityStmt: " + rhs); } }
@Override public void caseIdentityStmt(IdentityStmt stmt) { AnnotationValueSwitch valueSwitch = new AnnotationValueSwitch(stmt, StmtContext.IDENTITY); logger.fine("\n > > > Identity statement identified < < <"); // for all statements i = parameter[0] if (stmt.getRightOp() instanceof ParameterRef) { if (!body.getMethod().isMain()) { int posInArgList = ((ParameterRef) stmt.getRightOp()) .getIndex(); JimpleInjector.assignArgumentToLocal(posInArgList, (Local) stmt.getLeftOp()); } } else if (stmt.getRightOp() instanceof ThisRef) { // TODO im Grunde nicht nötig... } else if (stmt.getRightOp() instanceof CaughtExceptionRef) { logger.fine("Right operand in IdentityStmt is a CaughtException"); throw new InternalAnalyzerException("Catching exceptions is not supported"); } else { throw new InternalAnalyzerException( "Unexpected type of right value " + stmt.getRightOp().toString() + " in IdentityStmt"); } }
public SMTBinding createNewBindingForThisRef(ThisRef thisRef) { SMTBinding binding = null; if(hasBindingForThisRef(thisRef)) { SMTBinding oldBinding = getLatestBindingForThisRef(thisRef); int ssaVersionOldBinding = oldBinding.getVersion(); //increment version ssaVersionOldBinding += 1; binding = new SMTBinding(oldBinding.getVariableName(), oldBinding.getType(), ssaVersionOldBinding); return binding; } else { return new SMTBinding(thisRef.getType().toString(), TYPE.String); } }
/** * Checks whether the given method is a library stub method * @param method The method to check * @return True if the given method is an Android library stub, false * otherwise */ private boolean methodIsAndroidStub(SootMethod method) { if (!(Options.v().src_prec() == Options.src_prec_apk && method.getDeclaringClass().isLibraryClass() && SystemClassHandler.isClassInSystemPackage( method.getDeclaringClass().getName()))) return false; // Check whether there is only a single throw statement for (Unit u : method.getActiveBody().getUnits()) { if (u instanceof DefinitionStmt) { DefinitionStmt defStmt = (DefinitionStmt) u; if (!(defStmt.getRightOp() instanceof ThisRef) && !(defStmt.getRightOp() instanceof ParameterRef) && !(defStmt.getRightOp() instanceof NewExpr)) return false; } else if (u instanceof InvokeStmt) { InvokeStmt stmt = (InvokeStmt) u; // Check for exception constructor invocations SootMethod callee = stmt.getInvokeExpr().getMethod(); if (!callee.getSubSignature().equals("void <init>(java.lang.String)")) // Check for super class constructor invocation if (!(method.getDeclaringClass().hasSuperclass() && callee.getDeclaringClass() == method.getDeclaringClass().getSuperclass() && callee.getName().equals("<init>"))) return false; } else if (!(u instanceof ThrowStmt)) return false; } return true; }
/** * Gets the first statement in the body of the given method that does not * assign the "this" local or a parameter local * @param sm The method in whose body to look * @return The first non-identity statement in the body of the given method. */ private Unit getFirstNonIdentityStmt(SootMethod sm) { for (Unit u : sm.getActiveBody().getUnits()) { if (!(u instanceof IdentityStmt)) return u; IdentityStmt id = (IdentityStmt) u; if (!(id.getRightOp() instanceof ThisRef) && !(id.getRightOp() instanceof ParameterRef)) return u; } return null; }
public void caseThisRef(ThisRef v) { String oldName = varName; Type paramType= v.getType(); suggestVariableName("type"); String typeName = this.varName; ttp.setVariableName(typeName); paramType.apply(ttp); p.println("Value "+oldName+" = Jimple.v().newThisRef("+typeName+");"); varName = oldName; }
public static Local buildThisLocal(PatchingChain<Unit> units, ThisRef tr, Collection<Local> locals) { Local ths = Jimple.v().newLocal("ths", tr.getType()); locals.add(ths); units.add(Jimple.v().newIdentityStmt(ths, Jimple.v().newThisRef((RefType) tr.getType()))); return ths; }
private IdentityStmt findIdentityStmt(Body b){ for (Unit u : b.getUnits()) { Stmt s = (Stmt)u; if ((s instanceof IdentityStmt) && (((IdentityStmt)s).getRightOp() instanceof ThisRef)){ return (IdentityStmt)s; } } return null; }
private void handleRefTypeAssignment(DefinitionStmt assignStmt, AnalysisInfo out) { Value left = assignStmt.getLeftOp(); Value right = assignStmt.getRightOp(); //unbox casted value if(right instanceof JCastExpr) { JCastExpr castExpr = (JCastExpr) right; right = castExpr.getOp(); } //if we have a definition (assignment) statement to a ref-like type, handle it, if ( isAlwaysNonNull(right) || right instanceof NewExpr || right instanceof NewArrayExpr || right instanceof NewMultiArrayExpr || right instanceof ThisRef || right instanceof StringConstant || right instanceof ClassConstant || right instanceof CaughtExceptionRef) { //if we assign new... or @this, the result is non-null out.put(left,NON_NULL); } else if(right==NullConstant.v()) { //if we assign null, well, it's null out.put(left, NULL); } else if(left instanceof Local && right instanceof Local) { out.put(left, out.get(right)); } else { out.put(left, TOP); } }
private boolean isDexInstruction(Unit unit) { if (unit instanceof IdentityStmt) { IdentityStmt is = (IdentityStmt) unit; return !(is.getRightOp() instanceof ThisRef || is.getRightOp() instanceof ParameterRef); } return true; }
/** Return LHS of the first identity stmt assigning from \@this. **/ public Local getThisLocal() { for (Unit s : getUnits()) { if (s instanceof IdentityStmt && ((IdentityStmt)s).getRightOp() instanceof ThisRef) return (Local)(((IdentityStmt)s).getLeftOp()); } throw new RuntimeException("couldn't find identityref!"+" in "+getMethod()); }
@Override public void caseIdentityStmt(IdentityStmt stmt) { valueSwitch.callingStmt = stmt; valueSwitch.actualContext = StmtContext.IDENTITY; logger.fine("\n > > > Identity statement identified < < <"); if (stmt.getRightOp() instanceof ParameterRef) { if (!body.getMethod().isMain()) { int posInArgList = ((ParameterRef) stmt.getRightOp()) .getIndex(); JimpleInjector.assignArgumentToLocal(posInArgList, (Local) stmt.getLeftOp(), stmt); } } else if (stmt.getRightOp() instanceof ThisRef) { // TODO im Grunde nicht nötig... } else if (stmt.getRightOp() instanceof CaughtExceptionRef) { logger.fine("Right operand in IdentityStmt is a CaughtException"); } else { throw new InternalAnalyzerException( "Unexpected type of right value " + stmt.getRightOp().toString() + " in IdentityStmt"); } valueSwitch.actualContext = StmtContext.UNDEF; }
/** * Add the instance of the actual class-object to the object map. * This is only done in "init". */ public static void addInstanceObjectToObjectMap() { // Check if the first unit is a reference to the actual object if (!(units.getFirst() instanceof IdentityStmt) || !(units.getFirst().getUseBoxes().get(0).getValue() instanceof ThisRef)) { throw new InternalAnalyzerException("Expected @this reference"); } String thisObj = units.getFirst().getUseBoxes().get(0).getValue().toString(); logger.log(Level.INFO, "Add object {0} to ObjectMap in method {1}", new Object[] {thisObj, b.getMethod().getName()} ); ArrayList<Type> parameterTypes = new ArrayList<Type>(); parameterTypes.add(RefType.v("java.lang.Object")); Expr addObj = Jimple.v().newVirtualInvokeExpr( hs, Scene.v().makeMethodRef( Scene.v().getSootClass(HANDLE_CLASS), "addObjectToObjectMap", parameterTypes, VoidType.v(), false), units.getFirst().getDefBoxes().get(0).getValue()); Unit assignExpr = Jimple.v().newInvokeStmt(addObj); unitStore_After.insertElement(unitStore_After.new Element(assignExpr, lastPos)); lastPos = assignExpr; }
/** * Add a field to the object map. * @param field the SootField. */ public static void addInstanceFieldToObjectMap(SootField field) { logger.log(Level.INFO, "Adding field {0} to ObjectMap in method {1}", new Object[] { field.getSignature() ,b.getMethod().getName()}); if (!(units.getFirst() instanceof IdentityStmt) || !(units.getFirst().getUseBoxes().get(0).getValue() instanceof ThisRef)) { throw new InternalAnalyzerException("Expected @this reference"); } String fieldSignature = getSignatureForField(field); ArrayList<Type> parameterTypes = new ArrayList<Type>(); parameterTypes.add(RefType.v("java.lang.Object")); parameterTypes.add(RefType.v("java.lang.String")); Local tmpLocal = (Local) units.getFirst().getDefBoxes().get(0).getValue(); Unit assignSignature = Jimple.v().newAssignStmt(local_for_Strings, StringConstant.v(fieldSignature)); Expr addObj = Jimple.v().newVirtualInvokeExpr( hs, Scene.v().makeMethodRef( Scene.v().getSootClass(HANDLE_CLASS), "addFieldToObjectMap", parameterTypes, Scene.v().getObjectType(), false), tmpLocal, local_for_Strings); Unit assignExpr = Jimple.v().newInvokeStmt(addObj); unitStore_After.insertElement( unitStore_After.new Element(assignSignature, lastPos)); unitStore_After.insertElement( unitStore_After.new Element(assignExpr, assignSignature)); lastPos = assignExpr; }
public SMTBinding getLatestBindingForThisRef(ThisRef thisRef) { if(hasBindingForThisRef(thisRef)) return thisRefSSAFormHelper.get(thisRef); else return null; }
public boolean hasBindingForThisRef(ThisRef thisRef) { return this.thisRefSSAFormHelper.containsKey(thisRef); }
private void javafy_ref(ValueBox vb) { Ref r = (Ref) vb.getValue(); if (r instanceof StaticFieldRef) { SootFieldRef fieldRef = ((StaticFieldRef) r).getFieldRef(); //addPackage(fieldRef.declaringClass().getJavaPackageName()); String className = fieldRef.declaringClass().toString(); String packageName = fieldRef.declaringClass().getJavaPackageName(); String classPackageName = packageName; if (className.lastIndexOf('.') > 0) {// 0 doesnt make sense classPackageName = className.substring(0, className.lastIndexOf('.')); } if(!packageName.equals(classPackageName)) throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer."); addToImportList(className); vb.setValue(new DStaticFieldRef(fieldRef, getMethod().getDeclaringClass().getName())); } else if (r instanceof ArrayRef) { ArrayRef ar = (ArrayRef) r; javafy(ar.getBaseBox()); javafy(ar.getIndexBox()); } else if (r instanceof InstanceFieldRef) { InstanceFieldRef ifr = (InstanceFieldRef) r; javafy(ifr.getBaseBox()); vb.setValue(new DInstanceFieldRef(ifr.getBase(), ifr.getFieldRef(), thisLocals)); } else if (r instanceof ThisRef) { ThisRef tr = (ThisRef) r; vb.setValue(new DThisRef((RefType) tr.getType())); } }
public void identityRef( IdentityRef r ) { handleIndent(); if( r instanceof ThisRef ) { literal("this"); } else throw new RuntimeException(); }
public void caseThisRef(ThisRef v) { }
@Override public void caseInstanceFieldRef(InstanceFieldRef arg0) { boolean islhs = this.isLeftHandSide; this.isLeftHandSide = false; arg0.getBase().apply(this); Expression base = this.getExpression(); Expression field = GlobalsCache.v().lookupSootField(arg0.getField()); boolean nullCheckNeeded = true; // check if the field may be modified by another thread. if (!islhs && checkSharedField(arg0, field)) { havocField(field, base); nullCheckNeeded = false; } SootProcedureInfo pinfo = this.stmtSwitch.getProcInfo(); // check if base is trivially non-null if (pinfo != null) { CustomNullnessAnalysis nna = this.stmtSwitch.getProcInfo() .getNullnessAnalysis(); if (nna != null && arg0.getBase() instanceof Immediate) { if (nna.isAlwaysNonNullBefore( this.stmtSwitch.getCurrentStatement(), (Immediate) arg0.getBase())) { nullCheckNeeded = false; } } //TODO: this is a very clumsy way of obtaining thislocal // but it is not obvious when it throws an exception. Local thislocal = null; try { thislocal = pinfo.getSootMethod().getActiveBody().getThisLocal(); } catch (Exception e) { thislocal = null; } //check if base is "this" or a local variable //that is an alias of "this". if (arg0.getBase() ==thislocal || arg0.getBase() instanceof ThisRef) { nullCheckNeeded = false; // TODO: check if this is actually needed. } } // We are checking if this is a @NonNull field // if so, we add an assume to ensure that it actually is // not null here. checkFieldAnnotations( this.makeHeapAccessExpression(base, field, false), arg0); this.expressionStack.push(this.makeHeapAccessExpression(base, field, nullCheckNeeded)); }
@Override public void caseThisRef(ThisRef arg0) { this.expressionStack.push(this.procInfo.getThisReference()); }
@Override public void caseThisRef(ThisRef v) { throwInvalidWriteException(v); }
@Override public void caseThisRef(ThisRef v) { addReadComponent(getWeakestSecurityLevel()); }
@Override public void caseThisRef(ThisRef v) { logger.finer("@This reference identified " + v.toString()); throw new NotSupportedStmtException("ThisRef"); }
public static Var<ThisRef> fromThis(ThisRef tr) { return new Var<>(tr); }
/** * The method should look up the <em>security level</em> of a * {@link ThisRef}, but the look up of the level of a this reference is * implemented in the {@link SecurityLevelValueWriteSwitch}. * * @param v * The this reference for which the <em>security level</em> * should be looked up. * @see soot.jimple.RefSwitch#caseThisRef(soot.jimple.ThisRef) * @throws UnimplementedSwitchException * Method throws always this exception, because this method may * not be invoked. */ @Override public void caseThisRef(ThisRef v) { throw new SwitchException(getMsg("exception.analysis.switch.not_implemented", v.toString(), getSourceLine(), v.getClass().getSimpleName(), this.getClass().getSimpleName())); }
/** * DOC * * @see soot.jimple.RefSwitch#caseThisRef(soot.jimple.ThisRef) */ @Override public void caseThisRef(ThisRef v) { }