soot.jimple.FieldRef Java Examples

The following examples show how to use soot.jimple.FieldRef. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DexNullTransformer.java    From JAADAS with GNU General Public License v3.0 6 votes vote down vote up
private boolean isObjectArray(Value v, Body body) {
	for (Unit u : body.getUnits()) {
		if (u instanceof AssignStmt) {
			AssignStmt assign = (AssignStmt) u;
			if (assign.getLeftOp() == v) {
				if (assign.getRightOp() instanceof NewArrayExpr) {
					NewArrayExpr nea = (NewArrayExpr) assign.getRightOp();
					if (isObject(nea.getBaseType()))
						return true;
				}
				else if (assign.getRightOp() instanceof FieldRef) {
					FieldRef fr = (FieldRef) assign.getRightOp();
					if (fr.getType() instanceof ArrayType)
						if (isObject(((ArrayType) fr.getType())
								.getArrayElementType()))
							return true;
				}
			}
		}
	}
	return false;
}
 
Example #2
Source File: ConstantValueToInitializerTransformer.java    From JAADAS with GNU General Public License v3.0 6 votes vote down vote up
private SootMethod getOrCreateInitializer(SootClass sc,
		Set<SootField> alreadyInitialized) {
	SootMethod smInit;
	// Create a static initializer if we don't already have one
	smInit = sc.getMethodByNameUnsafe("<clinit>");
	if (smInit == null) {
		smInit = new SootMethod("<clinit>", Collections.<Type>emptyList(), VoidType.v());
		smInit.setActiveBody(Jimple.v().newBody(smInit));
		sc.addMethod(smInit);
		smInit.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
	}
	else {
		smInit.retrieveActiveBody();
		
		// We need to collect those variables that are already initialized somewhere
		for (Unit u : smInit.getActiveBody().getUnits()) {
			Stmt s = (Stmt) u;
			for (ValueBox vb : s.getDefBoxes())
				if (vb.getValue() instanceof FieldRef)
					alreadyInitialized.add(((FieldRef) vb.getValue()).getField());
		}
	}
	return smInit;
}
 
Example #3
Source File: StmtTranslator.java    From JAADAS with GNU General Public License v3.0 6 votes vote down vote up
void handleAssign(DefinitionStmt stmt) {
	Value lval = stmt.getLeftOp();
	Value rval = stmt.getRightOp();
	Variable rvar;
	if (lval instanceof Local) {
		rvar = getLocalVariable((Local)lval);
	} else {
		rvar = jt.makeVariable(rval);
	}
	et.translateExpr(rvar, stmt.getRightOpBox());
	if (lval instanceof ArrayRef) {
		notSupported("We do not support arrays");
	} else if (lval instanceof FieldRef) {
		notSupported("We do not support field references");
	}
}
 
Example #4
Source File: ValueTemplatePrinter.java    From JAADAS with GNU General Public License v3.0 6 votes vote down vote up
private void printFieldRef(FieldRef v) {
	String refTypeName = v.getClass().getSimpleName();
	
	p.openBlock();
	String oldName = varName;
	
	SootField f = v.getField();
	ttp.setVariableName("type");
	f.getType().apply(ttp);
	p.print("SootFieldRef fieldRef = ");
	p.printNoIndent("Scene.v().makeFieldRef(");
	String className = f.getDeclaringClass().getName();
	p.printNoIndent("Scene.v().getSootClass(\""+className+"\"),");
	p.printNoIndent("\""+f.getName()+"\",");
	p.printNoIndent("type,");	
	p.printNoIndent(f.isStatic()+");");		

	p.println("Value "+oldName+" = Jimple.v().new"+refTypeName+"(fieldRef);");
	varName = oldName;
	p.closeBlock();
}
 
Example #5
Source File: NullnessAssumptionAnalysis.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
private void handleFieldRef(FieldRef fieldRef,
			AnalysisInfo out) {
		if(fieldRef instanceof InstanceFieldRef) {
			InstanceFieldRef instanceFieldRef = (InstanceFieldRef) fieldRef;
			//here we know that the receiver must point to an object
			Value base = instanceFieldRef.getBase();
			out.put(base,NON_NULL);
		}
		//but the referenced object might point to everything
//		out.put(fieldRef, TOP);
	}
 
Example #6
Source File: StaticDefinitionFinder.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
public void inDefinitionStmt(DefinitionStmt s){
Value leftOp = s.getLeftOp();
if(leftOp instanceof FieldRef){
    //System.out.println("leftOp is a fieldRef:"+s);
    SootField field = ((FieldRef)leftOp).getField();
    //check if this is a final field
    if(field.isFinal()){
	//System.out.println("the field is a final variable");
	finalFieldDefined=true;
    }
}

   }
 
Example #7
Source File: AsmMethodSource.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
private void convertGetFieldInsn(FieldInsnNode insn) {
	StackFrame frame = getFrame(insn);
	Operand[] out = frame.out();
	Operand opr;
	Type type;
	if (out == null) {
		SootClass declClass = Scene.v().getSootClass(
				AsmUtil.toQualifiedName(insn.owner));
		type = AsmUtil.toJimpleType(insn.desc);
		Value val;
		SootFieldRef ref;
		if (insn.getOpcode() == GETSTATIC) {
			ref = Scene.v().makeFieldRef(declClass, insn.name, type, true);
			val = Jimple.v().newStaticFieldRef(ref);
		} else {
			Operand base = popLocal();
			ref = Scene.v().makeFieldRef(declClass, insn.name, type, false);
			InstanceFieldRef ifr =
					Jimple.v().newInstanceFieldRef(
							base.stackOrValue(), ref);
			val = ifr;
			base.addBox(ifr.getBaseBox());
			frame.in(base);
			frame.boxes(ifr.getBaseBox());
		}
		opr = new Operand(insn, val);
		frame.out(opr);
	} else {
		opr = out[0];
		type = opr.<FieldRef>value().getFieldRef().type();
		if (insn.getOpcode() == GETFIELD)
			frame.mergeIn(pop());
	}
	push(type, opr);
}
 
Example #8
Source File: LocalMayEquivValueAnalysis.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
private Value wrapValue(Value value)
{
    if(value instanceof EquivalentValue)
    {
        return value;
    }
    else if(value instanceof FieldRef)
    {
        return new EquivalentValue(value);
    }
    else
    {
        return value;
    }
}
 
Example #9
Source File: NullnessAnalysis.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
private void handleFieldRef(FieldRef fieldRef,
		AnalysisInfo out) {
	if(fieldRef instanceof InstanceFieldRef) {
		InstanceFieldRef instanceFieldRef = (InstanceFieldRef) fieldRef;
		//here we know that the receiver must point to an object
		Value base = instanceFieldRef.getBase();
		out.put(base,NON_NULL);
	}
}
 
Example #10
Source File: JimpleReduceStaticFieldsTransformer.java    From soot-infoflow-android-iccta with GNU Lesser General Public License v2.1 5 votes vote down vote up
private void replaceSootField(SootClass sc, Body b, AssignStmt aStmt, SootField sf)
{
	SootClass sfClass = sf.getDeclaringClass();
	
	LocalGenerator lg = new LocalGenerator(b);
	Local sfLocal = lg.generateLocal(sc.getType());
	Unit sfLocalAssignU = Jimple.v().newAssignStmt(
               sfLocal, 
               Jimple.v().newStaticFieldRef(sc.getField("instance", sc.getType()).makeRef()));
	
	Local sfLocal2 = lg.generateLocal(sfClass.getType());
	Unit sfLocalAssignU2 = Jimple.v().newAssignStmt(
               sfLocal2, 
               Jimple.v().newInstanceFieldRef(sfLocal, sc.getField(sfClass.getName(), sfClass.getType()).makeRef()));

	Unit assignU = null;
	
	if (aStmt.getLeftOp() instanceof FieldRef)
	{
		assignU = Jimple.v().newAssignStmt(Jimple.v().newInstanceFieldRef(sfLocal2, sf.makeRef()), aStmt.getRightOp());
	}
	else
	{
		assignU = Jimple.v().newAssignStmt(aStmt.getLeftOp(), Jimple.v().newInstanceFieldRef(sfLocal2, sf.makeRef()));
	}
	
	b.getUnits().insertBefore(sfLocalAssignU, aStmt);
	b.getUnits().insertBefore(sfLocalAssignU2, aStmt);
	b.getUnits().insertBefore(assignU, aStmt);
	b.getUnits().remove(aStmt);
	
	System.out.println(b);
}
 
Example #11
Source File: IFDSReachingDefinitionWithField.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
public static Value getFieldRefWrap(Value value) {
	if (value instanceof FieldRef) {
		return new EquivalentValue((FieldRef) value);
	} else {
		return value;
	}
}
 
Example #12
Source File: ImplicitFlowAliasStrategy.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Computes the global non-flow-sensitive alias information for the given
 * method
 * @param method The method for which to compute the alias information
 */
private Map<AccessPath, Set<AccessPath>> computeGlobalAliases(SootMethod method) {
	Map<AccessPath, Set<AccessPath>> res = new HashMap<AccessPath, Set<AccessPath>>();

	// Find the aliases
	for (Unit u : method.getActiveBody().getUnits()) {
		if (!(u instanceof AssignStmt))
			continue;
		final AssignStmt assign = (AssignStmt) u;
		
		// Aliases can only be generated on the heap
		if (!(assign.getLeftOp() instanceof FieldRef
				&& (assign.getRightOp() instanceof FieldRef
						|| assign.getRightOp() instanceof Local)))
			if (!(assign.getRightOp() instanceof FieldRef
					&& (assign.getLeftOp() instanceof FieldRef
							|| assign.getLeftOp() instanceof Local)))
				continue;
		
		final AccessPath apLeft = new AccessPath(assign.getLeftOp(), true);
		final AccessPath apRight = new AccessPath(assign.getRightOp(), true);
		
		Set<AccessPath> mapLeft = res.get(apLeft);
		if (mapLeft == null) {
			mapLeft = new HashSet<AccessPath>();
			res.put(apLeft, mapLeft);
		}
		mapLeft.add(apRight);
		
		Set<AccessPath> mapRight = res.get(apRight);
		if (mapRight == null) {
			mapRight = new HashSet<AccessPath>();
			res.put(apRight, mapRight);
		}
		mapLeft.add(apLeft);
	}
	return res;
}
 
Example #13
Source File: CallFlowFunctionFactory.java    From DroidRA with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Returns a call flow function.
 * 
 * @param src A statement that is the source of a call edge in the call graph. This is generally a
 *          call statement, but field accesses can also lead to edges leading to class
 *          initializers.
 * @param dest The destination method.
 * @param zeroValue The zero value for the analysis, which represents the absence of a data flow
 *          fact.
 * @return The call flow function for the input statement.
 */
public FlowFunction<Value> getCallFlowFunction(Unit src, final SootMethod dest,
    final Value zeroValue) {
  if (logger.isDebugEnabled()) {
    logger.debug("Call: " + src);
  }

  String declaringClass = dest.getDeclaringClass().getName();

  if (!AnalysisParameters.v().isAnalysisClass(declaringClass)) {
    // Only propagate through analysis classes.
    return KillAll.v();
  }

  Stmt stmt = (Stmt) src;
  // Some statements other than call statements (e.g., field accesses) can lead to call edges to
  // class initializers.
  boolean containsInvokeExpr = stmt.containsInvokeExpr();

  final InvokeExpr ie = containsInvokeExpr ? stmt.getInvokeExpr() : null;

  if (containsInvokeExpr
      && (Model.v().getArgumentsForGenMethod(ie) != null || Model.v()
          .getArgumentsForCopyConstructor(ie.getMethodRef()) != null)) {
    return KillAll.v();
  }

  return new FlowFunction<Value>() {
    @Override
    public Set<Value> computeTargets(Value source) {
      if (logger.isDebugEnabled()) {
        logger.debug("Source: " + source);
      }

      if (dest.getName().equals(SootMethod.staticInitializerName)) {
        if (source instanceof FieldRef) {
          return Collections.singleton(source);
        } else {
          return Collections.emptySet();
        }
      }

      final List<Value> paramLocals = new ArrayList<Value>();

      for (int i = 0; i < dest.getParameterCount(); ++i) {
        // TODO (Damien): maybe activate again?
        // if (ie.getArg(i) instanceof NullConstant && source.equals(zeroValue)) {
        // return Collections.singleton((Value) dest.getActiveBody().getParameterLocal(i));
        // }
        paramLocals.add(dest.getActiveBody().getParameterLocal(i));
      }

      int argIndex = FunctionFactoryUtils.shouldPropagateSource(source, ie.getArgs());
      if (argIndex != -1) {
        if (logger.isDebugEnabled()) {
          logger.debug("Returning " + paramLocals.get(argIndex));
        }
        return Collections.singleton(paramLocals.get(argIndex));
      }

      if (source instanceof StaticFieldRef) {
        // Always propagate static fields.
        return Collections.singleton(source);
      } else if (source instanceof InstanceFieldRef) {
        if (FunctionFactoryUtils.shouldPropagateInstanceField((InstanceFieldRef) source, ie)) {
          return Collections.singleton(source);
        }
      }

      if (logger.isDebugEnabled()) {
        logger.debug("Returning empty set");
      }
      return Collections.emptySet();
    }
  };
}
 
Example #14
Source File: LocalMustAliasAnalysis.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
/**
    * Computes the set of {@link EquivalentValue}s of all field references that are used
    * in this method but not set by the method or any method transitively called by this method.
    */
   private Set<Value> trackableFields() {
   	Set<Value> usedFieldRefs = new HashSet<Value>();
       //add all field references that are in use boxes
       for (Unit unit : this.graph) {
		Stmt s = (Stmt) unit;
		List<ValueBox> useBoxes = s.getUseBoxes();
		for (ValueBox useBox : useBoxes) {
			Value val = useBox.getValue();
			if(val instanceof FieldRef) {
				FieldRef fieldRef = (FieldRef) val;
				if(fieldRef.getType() instanceof RefLikeType)
					usedFieldRefs.add(new EquivalentValue(fieldRef));						
			}
		}
	}
       
       //prune all fields that are written to
       if(!usedFieldRefs.isEmpty()) {
   	
    	if(!Scene.v().hasCallGraph()) {
    		throw new IllegalStateException("No call graph found!");
    	}
    	    	
		CallGraph cg = Scene.v().getCallGraph();
		ReachableMethods reachableMethods = new ReachableMethods(cg,Collections.<MethodOrMethodContext>singletonList(container));
		reachableMethods.update();
		for (Iterator<MethodOrMethodContext> iterator = reachableMethods.listener(); iterator.hasNext();) {
			SootMethod m = (SootMethod) iterator.next();
			if(m.hasActiveBody() &&
			//exclude static initializer of same class (assume that it has already been executed)
			 !(m.getName().equals(SootMethod.staticInitializerName) && m.getDeclaringClass().equals(container.getDeclaringClass()))) {				
				for (Unit u : m.getActiveBody().getUnits()) {
					List<ValueBox> defBoxes = u.getDefBoxes();
					for (ValueBox defBox : defBoxes) {
						Value value = defBox.getValue();
						if(value instanceof FieldRef) {
							usedFieldRefs.remove(new EquivalentValue(value));
						}
					}
				}
			}
		}
       }
       
	return usedFieldRefs;
}
 
Example #15
Source File: SootHelper.java    From soot-infoflow-android-iccta with GNU Lesser General Public License v2.1 4 votes vote down vote up
public static List<Value> getAllImmediateValue(Stmt stmt)
{
	List<Value> rtVal = new ArrayList<Value>();
	
	List<ValueBox> vbs = stmt.getUseAndDefBoxes();
	Set<String> frs = new HashSet<String>();
	
	for (ValueBox vb : vbs)
	{
		Value v = vb.getValue();
		
		if (v instanceof FieldRef)
		{
			int endPos = v.toString().indexOf('.');
			String name = v.toString().substring(0, endPos);
			frs.add(name);
			
			Value existV = null;
			for (ValueBox vBox : vbs)
			{
				if (name.equals(vBox.getValue().toString()))
				{
					existV = vBox.getValue();
					break;
				}
			}
			
			if (null != existV)
			{
				rtVal.remove(existV);
			}

			rtVal.add(v);
		}
		
		if (v instanceof Immediate)
		{
			if (! frs.contains(v.toString()))
			{
				rtVal.add(v);
			}
		}
	}
	
	return rtVal;
}
 
Example #16
Source File: AsmMethodSource.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
private void convertPutFieldInsn(FieldInsnNode insn) {
	boolean instance = insn.getOpcode() == PUTFIELD;
	StackFrame frame = getFrame(insn);
	Operand[] out = frame.out();
	Operand opr, rvalue;
	Type type;
	if (out == null) {
		SootClass declClass = Scene.v().getSootClass(
				AsmUtil.toQualifiedName(insn.owner));
		type = AsmUtil.toJimpleType(insn.desc);
		Value val;
		SootFieldRef ref;
		rvalue = popImmediate(type);
		if (!instance) {
			ref = Scene.v().makeFieldRef(declClass, insn.name, type, true);
			val = Jimple.v().newStaticFieldRef(ref);
			frame.in(rvalue);
		} else {
			Operand base = popLocal();
			ref = Scene.v().makeFieldRef(declClass, insn.name, type, false);
			InstanceFieldRef ifr =
					Jimple.v().newInstanceFieldRef(
							base.stackOrValue(), ref);
			val = ifr;
			base.addBox(ifr.getBaseBox());
			frame.in(rvalue, base);
		}
		opr = new Operand(insn, val);
		frame.out(opr);
		AssignStmt as = Jimple.v().newAssignStmt(val, rvalue.stackOrValue()); 
		rvalue.addBox(as.getRightOpBox());
		if (!instance) {
			frame.boxes(as.getRightOpBox());
		} else {
			frame.boxes(as.getRightOpBox(),
					((InstanceFieldRef) val).getBaseBox());
		}
		setUnit(insn, as);
	} else {
		opr = out[0];
		type = opr.<FieldRef>value().getFieldRef().type();
		rvalue = pop(type);
		if (!instance) {
			/* PUTSTATIC only needs one operand on the stack, the rvalue */
			frame.mergeIn(rvalue);
		} else {
			/* PUTFIELD has a rvalue and a base */
			frame.mergeIn(rvalue, pop());
		}
	}
	/*
	 * in case any static field or array is read from, and the static constructor
	 * or the field this instruction writes to, modifies that field, write out any
	 * previous read from field/array
	 */
	assignReadOps(null);
}
 
Example #17
Source File: SootAnalyzer.java    From paprika with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * Should be called after all classes have been processed once
 */
public void collectMethodsMetrics(SootMethod sootMethod){
    SootClass sootClass = sootMethod.getDeclaringClass();
    PaprikaClass paprikaClass = classMap.get(sootClass);
    if (paprikaClass == null){
        //Should be R or external classes
        //LOGGER.warning("Class not analyzed : "+ sootClass);
        sootClass.setLibraryClass();
        return;
        /*
        paprikaClass = PaprikaClass.createPaprikaClass(sootClass.getName(), this.paprikaApp);
        classMap.put(sootClass, paprikaClass);
        */
    }
    PaprikaModifiers modifiers = PaprikaModifiers.PRIVATE;
    if(sootMethod.isPublic()){
        modifiers = PaprikaModifiers.PUBLIC;
    }else if(sootMethod.isProtected()){
        modifiers = PaprikaModifiers.PROTECTED;
    }

    PaprikaMethod paprikaMethod = PaprikaMethod.createPaprikaMethod(sootMethod.getName(),modifiers,sootMethod.getReturnType().toString(),paprikaClass);
    methodMap.put(sootMethod, paprikaMethod);
    if(sootMethod.isStatic()){
        IsStatic.createIsStatic(paprikaMethod, true);
    }
    if(sootMethod.isFinal()){
        IsFinal.createIsFinal(paprikaMethod, true);
    }
    if(sootMethod.isSynchronized()){
        IsSynchronized.createIsSynchronized(paprikaMethod, true);
    }
    if(sootMethod.isAbstract()){
        IsAbstract.createIsAbstract(paprikaMethod, true);
    }
    NumberOfParameters.createNumberOfParameters(paprikaMethod, sootMethod.getParameterCount());
    if(sootMethod.hasActiveBody()){
        //Args
        int i = 0;
        for(Type type : sootMethod.getParameterTypes()){
            i++;
            PaprikaArgument.createPaprikaArgument(type.toString(),i,paprikaMethod);
        }
        GrimpBody activeBody = (GrimpBody) sootMethod.getActiveBody();
        // Number of lines is the number of Units - number of Parameter - 1 (function name)
        int nbOfLines =  activeBody.getUnits().size() - sootMethod.getParameterCount() - 1;
        NumberOfDeclaredLocals.createNumberOfDeclaredLocals(paprikaMethod, activeBody.getLocals().size());
        NumberOfInstructions.createNumberOfInstructions(paprikaMethod, nbOfLines);
        // Cyclomatic complexity & Lack of Cohesion methods
        int nbOfBranches = 1;
        PaprikaVariable paprikaVariable = null;
        for (Unit sootUnit : activeBody.getUnits()){
            //LCOM

            List<ValueBox> boxes = sootUnit.getUseAndDefBoxes();
            for (ValueBox valueBox : boxes){
                Value value = valueBox.getValue();
                if (value instanceof FieldRef) {
                    SootFieldRef field = ((FieldRef) value).getFieldRef();
                    if(field.declaringClass() == sootClass){
                        paprikaVariable = paprikaClass.findVariable(field.name());
                        //If we don't find the field it's inherited and thus not used for LCOM2
                        if(paprikaVariable != null){
                            paprikaMethod.useVariable(paprikaVariable);
                        }
                    }
                }
            }
            //Cyclomatic complexity
            if (sootUnit.branches()){
                if(sootUnit.fallsThrough()) nbOfBranches++;
                else if(sootUnit instanceof GLookupSwitchStmt) nbOfBranches += ((GLookupSwitchStmt) sootUnit).getLookupValues().size();
            }
        }
        CyclomaticComplexity.createCyclomaticComplexity(paprikaMethod, nbOfBranches);
        if(isInit(sootMethod)) {
            IsInit.createIsInit(paprikaMethod, true);
        }else{
            if(isOverride(sootMethod)){
                IsOverride.createIsOverride(paprikaMethod,true);
            }
            //Is it a probable getter/setter ?
            if (nbOfBranches == 1 && paprikaMethod.getUsedVariables().size() == 1 && sootMethod.getExceptions().size() == 0) {
                paprikaVariable = paprikaMethod.getUsedVariables().iterator().next();
                int parameterCount  = sootMethod.getParameterCount();
                int unitSize = sootMethod.getActiveBody().getUnits().size();
                String returnType = paprikaMethod.getReturnType();
                if (parameterCount == 1 && unitSize <= 4 && returnType.equals("void")) {
                    IsSetter.createIsSetter(paprikaMethod, true);
                } else if (parameterCount == 0 && unitSize <= 3 && returnType.equals(paprikaVariable.getType())) {
                    IsGetter.createIsGetter(paprikaMethod, true);
                }
            }
        }
    }else{
        //LOGGER.info("No body for "+paprikaMethod);
    }
}
 
Example #18
Source File: CP.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
private Object isANotTopConstantInInputSet(CPFlowSet set, Value toCheck) {
	if (toCheck instanceof Local || toCheck instanceof FieldRef) {
		String toCheckClassName = null;
		if (toCheck instanceof Local)
			toCheckClassName = localClassName;
		else
			toCheckClassName = ((FieldRef) toCheck).getField().getDeclaringClass().getName();

		for (CPTuple tempTuple : set) {
			// check that the classNames are the same
			if (!(tempTuple.getSootClassName().equals(toCheckClassName))) {
				// classNames are not the same no point in continuing with
				// checks
				continue;
			}

			boolean tupleFound = false;
			if (tempTuple.containsLocal() && toCheck instanceof Local) {
				// check they are the same Local
				Local tempLocal = tempTuple.getVariable().getLocal();
				if (tempLocal.getName().equals(((Local) toCheck).getName())) {
					// the set does have a constant value for this local
					tupleFound = true;
				}
			} else if (tempTuple.containsField() && toCheck instanceof FieldRef) {
				SootField toCheckField = ((FieldRef) toCheck).getField();
				SootField tempField = tempTuple.getVariable().getSootField();

				if (tempField.getName().equals(toCheckField.getName())) {
					// the set contains a constant value for this field
					tupleFound = true;
				}
			}

			if (tupleFound) {
				if (tempTuple.isTop())
					return null;
				else
					return tempTuple.getValue();
			}
		}

	}
	return null;
}
 
Example #19
Source File: DexReturnValuePropagator.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
       ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body, DalvikThrowAnalysis.v(), true);
       LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(graph);
       LocalUses localUses = null;
       LocalCreation localCreation = null;
       
	// If a return statement's operand has only one definition and this is
	// a copy statement, we take the original operand
	for (Unit u : body.getUnits())
		if (u instanceof ReturnStmt) {
			ReturnStmt retStmt = (ReturnStmt) u;
			if (retStmt.getOp() instanceof Local) {
				List<Unit> defs = localDefs.getDefsOfAt((Local) retStmt.getOp(), retStmt);
				if (defs.size() == 1 && defs.get(0) instanceof AssignStmt) {
					AssignStmt assign = (AssignStmt) defs.get(0);
					final Value rightOp = assign.getRightOp();
					final Value leftOp = assign.getLeftOp();
					
					// Copy over the left side if it is a local
					if (rightOp instanceof Local) {
						// We must make sure that the definition we propagate to
						// the return statement is not overwritten in between
						// a = 1; b = a; a = 3; return b; may not be translated
						// to return a;
						if (!isRedefined((Local) rightOp, u, assign, graph))
							retStmt.setOp(rightOp);
					}
					else if (rightOp instanceof Constant) {
						retStmt.setOp(rightOp);
					}
					// If this is a field access which has no other uses,
					// we rename the local to help splitting
					else if (rightOp instanceof FieldRef) {
						if (localUses == null)
							localUses = LocalUses.Factory.newLocalUses(body, localDefs);
						if (localUses.getUsesOf(assign).size() == 1) {
							if (localCreation == null)
								localCreation = new LocalCreation(body.getLocals(), "ret");
							Local newLocal = localCreation.newLocal(leftOp.getType());
							assign.setLeftOp(newLocal);
							retStmt.setOp(newLocal);
						}
					}
				}
			}
		}
}
 
Example #20
Source File: DexRefsChecker.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
protected void internalTransform(final Body body, String phaseName, @SuppressWarnings("rawtypes") Map options) {
//final ExceptionalUnitGraph g = new ExceptionalUnitGraph(body);
//final SmartLocalDefs localDefs = new SmartLocalDefs(g, new SimpleLiveLocals(g));
//final SimpleLocalUses localUses = new SimpleLocalUses(g, localDefs);


      for (Unit u: getRefCandidates(body)) {
        Stmt s = (Stmt)u;
        boolean hasField = false;
        FieldRef fr = null;
        SootField sf = null;
        if (s.containsFieldRef()) {
          fr = s.getFieldRef();
          sf = fr.getField();
          if (sf != null) {             
            hasField = true;
          }
        } else {
          throw new RuntimeException("Unit '"+ u +"' does not contain array ref nor field ref.");
        }
        
        if (!hasField) {
          Debug.printDbg("field ", fr ," '", fr ,"' has not been found!");
          System.out.println("Warning: add missing field '"+ fr +"' to class!");
          SootClass sc = null;
          String frStr = fr.toString();
          if (frStr.contains(".<")) {
           sc = Scene.v().getSootClass(frStr.split(".<")[1].split(" ")[0].split(":")[0]);
          } else {
           sc = Scene.v().getSootClass(frStr.split(":")[0].replaceAll("^<", ""));
          }
          String fname = fr.toString().split(">")[0].split(" ")[2];
          int modifiers = soot.Modifier.PUBLIC;
          Type ftype = fr.getType();
          Debug.printDbg("missing field: to class '", sc ,"' field name '", fname ,"' field modifiers '", modifiers ,"' field type '", ftype ,"'");
          sc.addField(new SootField(fname, ftype, modifiers));
        } else {
          //System.out.println("field "+ sf.getName() +" '"+ sf +"' phantom: "+ isPhantom +" declared: "+ isDeclared);
        }
        
      } // for if statements
  }
 
Example #21
Source File: AndroidSourceSinkManager.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Finds the last assignment to the given local representing a resource ID
 * by searching upwards from the given statement
 * 
 * @param stmt
 *            The statement from which to look backwards
 * @param local
 *            The variable for which to look for assignments
 * @return The last value assigned to the given variable
 */
private Integer findLastResIDAssignment(Stmt stmt, Local local, BiDiInterproceduralCFG<Unit, SootMethod> cfg, Set<Stmt> doneSet) {
	if (!doneSet.add(stmt))
		return null;

	// If this is an assign statement, we need to check whether it changes
	// the variable we're looking for
	if (stmt instanceof AssignStmt) {
		AssignStmt assign = (AssignStmt) stmt;
		if (assign.getLeftOp() == local) {
			// ok, now find the new value from the right side
			if (assign.getRightOp() instanceof IntConstant)
				return ((IntConstant) assign.getRightOp()).value;
			else if (assign.getRightOp() instanceof FieldRef) {
				SootField field = ((FieldRef) assign.getRightOp()).getField();
				for (Tag tag : field.getTags())
					if (tag instanceof IntegerConstantValueTag)
						return ((IntegerConstantValueTag) tag).getIntValue();
					else
						System.err.println("Constant " + field + " was of unexpected type");
			} else if (assign.getRightOp() instanceof InvokeExpr) {
				InvokeExpr inv = (InvokeExpr) assign.getRightOp();
				if (inv.getMethod().getName().equals("getIdentifier") && inv.getMethod().getDeclaringClass().getName().equals("android.content.res.Resources") && this.resourcePackages != null) {
					// The right side of the assignment is a call into the
					// well-known
					// Android API method for resource handling
					if (inv.getArgCount() != 3) {
						System.err.println("Invalid parameter count for call to getIdentifier");
						return null;
					}

					// Find the parameter values
					String resName = "";
					String resID = "";
					String packageName = "";

					// In the trivial case, these values are constants
					if (inv.getArg(0) instanceof StringConstant)
						resName = ((StringConstant) inv.getArg(0)).value;
					if (inv.getArg(1) instanceof StringConstant)
						resID = ((StringConstant) inv.getArg(1)).value;
					if (inv.getArg(2) instanceof StringConstant)
						packageName = ((StringConstant) inv.getArg(2)).value;
					else if (inv.getArg(2) instanceof Local)
						packageName = findLastStringAssignment(stmt, (Local) inv.getArg(2), cfg);
					else {
						System.err.println("Unknown parameter type in call to getIdentifier");
						return null;
					}

					// Find the resource
					ARSCFileParser.AbstractResource res = findResource(resName, resID, packageName);
					if (res != null)
						return res.getResourceID();
				}
			}
		}
	}

	// Continue the search upwards
	for (Unit pred : cfg.getPredsOf(stmt)) {
		if (!(pred instanceof Stmt))
			continue;
		Integer lastAssignment = findLastResIDAssignment((Stmt) pred, local, cfg, doneSet);
		if (lastAssignment != null)
			return lastAssignment;
	}
	return null;
}
 
Example #22
Source File: NullnessAnalysis.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
/**
 * {@inheritDoc}
 */
@Override
protected void flowThrough(AnalysisInfo in, Unit u, List<AnalysisInfo> fallOut, List<AnalysisInfo> branchOuts) {
	AnalysisInfo out = new AnalysisInfo(in);
	AnalysisInfo outBranch = new AnalysisInfo(in);
	
	Stmt s = (Stmt)u;
	
	//in case of an if statement, we neet to compute the branch-flow;
	//e.g. for a statement "if(x!=null) goto s" we have x==null for the fallOut and
	//x!=null for the branchOut
	//or for an instanceof expression
	if(s instanceof JIfStmt) {
		JIfStmt ifStmt = (JIfStmt) s;
		handleIfStmt(ifStmt, in, out, outBranch);
	}
	//in case of a monitor statement, we know that if it succeeds, we have a non-null value
	else if(s instanceof MonitorStmt) {
		MonitorStmt monitorStmt = (MonitorStmt) s;
		out.put(monitorStmt.getOp(), NON_NULL);
	}
	
	// if we have an array ref, set the base to non-null
	if(s.containsArrayRef()) {
		ArrayRef arrayRef = s.getArrayRef();
		handleArrayRef(arrayRef,out);
	}
	// for field refs, set the receiver object to non-null, if there is one
	if(s.containsFieldRef()) {
		FieldRef fieldRef = s.getFieldRef();
		handleFieldRef(fieldRef, out);
	}
	// for invoke expr, set the receiver object to non-null, if there is one
	if(s.containsInvokeExpr()) {
		InvokeExpr invokeExpr = s.getInvokeExpr();
		handleInvokeExpr(invokeExpr, out);
	}
	
	//if we have a definition (assignment) statement to a ref-like type, handle it,
	//i.e. assign it TOP, except in the following special cases:
	// x=null,               assign NULL
	// x=@this or x= new...  assign NON_NULL
	// x=y,                  copy the info for y (for locals x,y)
	if(s instanceof DefinitionStmt) {
		DefinitionStmt defStmt = (DefinitionStmt) s;
		if(defStmt.getLeftOp().getType() instanceof RefLikeType) {
			handleRefTypeAssignment(defStmt, out);
		}
	}
	
	// now copy the computed info to all successors
	for( Iterator<AnalysisInfo> it = fallOut.iterator(); it.hasNext(); ) {
		copy( out, it.next() );
	}
	for( Iterator<AnalysisInfo> it = branchOuts.iterator(); it.hasNext(); ) {
		copy( outBranch, it.next() );
	}
}
 
Example #23
Source File: InterproceduralConstantValuePropagator.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Checks whether the given method or one of its transitive callees has
 * side-effects or calls a sink method
 * @param method The method to check
 * @param runList A set to receive all methods that have already been
 * processed
 * @param cache The cache in which to store the results
 * @return True if the given method or one of its transitive callees has
 * side-effects or calls a sink method, otherwise false.
 */
private boolean hasSideEffectsOrReadsThis(SootMethod method,
		Set<SootMethod> runList) {		
	// Without a body, we cannot say much
	if (!method.hasActiveBody())
		return false;
	
	// Do we already have an entry?
	Boolean hasSideEffects = methodSideEffects.get(method);
	if (hasSideEffects != null)
		return hasSideEffects;
	
	// Do not process the same method twice
	if (!runList.add(method))
		return false;
	
	// If this is an Android stub method that just throws a stub exception,
	// this will never happen in practice and can be removed
	if (methodIsAndroidStub(method)) {
		methodSideEffects.put(method, false);
		return false;
	}
	
	// Scan for references to this variable
	Local thisLocal = method.isStatic() ? null : method.getActiveBody().getThisLocal();
	for (Unit u : method.getActiveBody().getUnits()) {
		if (u instanceof AssignStmt) {
			AssignStmt assign = (AssignStmt) u;
			if (assign.getLeftOp() instanceof FieldRef
					|| assign.getLeftOp() instanceof ArrayRef) {
				methodSideEffects.put(method, true);
				return true;
			}
		}
		
		Stmt s = (Stmt) u;
		
		// If this statement uses the "this" local, we have to
		// conservatively assume that is can read data
		if (thisLocal != null)
			for (ValueBox vb : s.getUseBoxes())
				if (vb.getValue() == thisLocal)
					return true;
		
		if (s.containsInvokeExpr()) {
			// Check the callees
			for (Iterator<Edge> edgeIt = Scene.v().getCallGraph().edgesOutOf(u); edgeIt.hasNext(); ) {
				Edge e = edgeIt.next();
				if (hasSideEffectsOrReadsThis(e.getTgt().method(), runList))
					return true;
			}
		}
	}
	
	// Variable is not read
	methodSideEffects.put(method, false);
	return false;
}
 
Example #24
Source File: InterproceduralConstantValuePropagator.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Checks whether the given method or one of its transitive callees has
 * side-effects or calls a sink method
 * @param method The method to check
 * @param runList A set to receive all methods that have already been
 * processed
 * @param cache The cache in which to store the results
 * @return True if the given method or one of its transitive callees has
 * side-effects or calls a sink method, otherwise false.
 */
private boolean hasSideEffectsOrCallsSink(SootMethod method,
		Set<SootMethod> runList) {		
	// Without a body, we cannot say much
	if (!method.hasActiveBody())
		return false;
	
	// Do we already have an entry?
	Boolean hasSideEffects = methodSideEffects.get(method);
	if (hasSideEffects != null)
		return hasSideEffects;
	
	Boolean hasSink = methodSinks.get(method);
	if (hasSink != null)
		return hasSink;
	
	// Do not process the same method twice
	if (!runList.add(method))
		return false;
			
	// If this is an Android stub method that just throws a stub exception,
	// this will never happen in practice and can be removed
	if (methodIsAndroidStub(method)) {
		methodSideEffects.put(method, false);
		return false;
	}
	
	// Scan for references to this variable
	for (Unit u : method.getActiveBody().getUnits()) {
		if (u instanceof AssignStmt) {
			AssignStmt assign = (AssignStmt) u;
			if (assign.getLeftOp() instanceof FieldRef
					|| assign.getLeftOp() instanceof ArrayRef) {
				methodSideEffects.put(method, true);
				return true;
			}
		}
		
		Stmt s = (Stmt) u;
		
		// If this method calls another method for which we have a taint
		// wrapper, we need to conservatively assume that the taint wrapper
		// can do anything
		if (taintWrapper != null && taintWrapper.supportsCallee(s)) {
			methodSideEffects.put(method, true);
			return true;
		}
		
		if (s.containsInvokeExpr()) {
			// If this method calls a sink, we need to keep it
			if (sourceSinkManager != null
					&& sourceSinkManager.isSink((Stmt) u, icfg, null)) {
				methodSinks.put(method, true);
				return true;
			}
			
			// Check the callees
			for (Iterator<Edge> edgeIt = Scene.v().getCallGraph().edgesOutOf(u); edgeIt.hasNext(); ) {
				Edge e = edgeIt.next();
					if (hasSideEffectsOrCallsSink(e.getTgt().method(), runList))
						return true;
			}
		}
	}
	
	// Variable is not read
	methodSideEffects.put(method, false);
	return false;
}
 
Example #25
Source File: Aliasing.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Gets whether a value and an access path may potentially point to the same
 * runtime object
 * @param ap The access path
 * @param val The value
 * @return The access path that actually matched if the given value and
 * access path alias. In the simplest case, this is the given access path.
 * When using recursive access paths, it can however also be a base
 * expansion. If the given access path and value do not alias, null is
 * returned.
 */
public AccessPath mayAlias(AccessPath ap, Value val) {
	// What cannot be represented in an access path cannot alias
	if (!AccessPath.canContainValue(val))
		return null;
	
	// Constants can never alias
	if (val instanceof Constant)
		return null;
	
	// For instance field references, the base must match
	if (val instanceof Local)
		if (ap.getPlainValue() != val)
			return null;
	
	// For array references, the base must match
	if (val instanceof ArrayRef)
		if (ap.getPlainValue() != ((ArrayRef) val).getBase())
			return null;
	
	// For instance field references, the base local must match
	if (val instanceof InstanceFieldRef) {
		if (!ap.isLocal() && !ap.isInstanceFieldRef())
			return null;
		if (((InstanceFieldRef) val).getBase() != ap.getPlainValue())
			return null;
	}
	
	// If the value is a static field reference, the access path must be
	// static as well
	if (val instanceof StaticFieldRef)
		if (!ap.isStaticFieldRef())
			return null;
					
	// If we have an interactive aliasing algorithm, we check that as well
	/*
	if (aliasingStrategy.isInteractive())
		return aliasingStrategy.mayAlias(new AccessPath(val1, false), new AccessPath(val2, false));
	*/
	
	// Get the field set from the value
	SootField[] fields = val instanceof FieldRef
			? new SootField[] { ((FieldRef) val).getField() } : new SootField[0];
	return getReferencedAPBase(ap, fields);
}