protected void flowThrough(HashMap<Local,Set<NewExpr>> in, Unit unit, HashMap<Local,Set<NewExpr>> out) { Stmt s = (Stmt) unit; out.clear(); out.putAll(in); if (s instanceof DefinitionStmt) { DefinitionStmt ds = (DefinitionStmt) s; Value lhs = ds.getLeftOp(); Value rhs = ds.getRightOp(); if (lhs instanceof Local) { HashSet<NewExpr> lv = new HashSet<NewExpr>(); out.put((Local) lhs, lv); if (rhs instanceof NewExpr) { lv.add((NewExpr) rhs); } else if (rhs instanceof Local) { lv.addAll(in.get(rhs)); } else lv.add(UNKNOWN); } } }
public void jimplify (DexBody body) { Instruction21c i = (Instruction21c)instruction; int dest = i.getRegisterA(); String className = dottedClassName(((TypeReference)(i.getReference())).toString()); RefType type = RefType.v(className); NewExpr n = Jimple.v().newNewExpr(type); assign = Jimple.v().newAssignStmt(body.getRegisterLocal(dest), n); setUnit(assign); addTags(assign); body.add(assign); if (IDalvikTyper.ENABLE_DVKTYPER) { Debug.printDbg(IDalvikTyper.DEBUG, "constraint: "+ assign); int op = (int)instruction.getOpcode().value; //DalvikTyper.v().captureAssign((JAssignStmt)assign, op); // TODO: ref. type may be null! DalvikTyper.v().setType(assign.getLeftOpBox(), type, false); } }
private void javafy_expr(ValueBox vb) { Expr e = (Expr) vb.getValue(); if (e instanceof BinopExpr) javafy_binop_expr(vb); else if (e instanceof UnopExpr) javafy_unop_expr(vb); else if (e instanceof CastExpr) javafy_cast_expr(vb); else if (e instanceof NewArrayExpr) javafy_newarray_expr(vb); else if (e instanceof NewMultiArrayExpr) javafy_newmultiarray_expr(vb); else if (e instanceof InstanceOfExpr) javafy_instanceof_expr(vb); else if (e instanceof InvokeExpr) javafy_invoke_expr(vb); else if (e instanceof NewExpr) javafy_new_expr(vb); }
private void javafy_new_expr(ValueBox vb) { NewExpr ne = (NewExpr) vb.getValue(); String className = ne.getBaseType().getSootClass().toString(); String packageName = ne.getBaseType().getSootClass().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); }
Type h2t(Unit h) { if(h instanceof JAssignStmt){ JAssignStmt j = (JAssignStmt)h; if(SootUtilities.isNewStmt(j)){ NewExpr ne = (NewExpr)j.rightBox.getValue(); return ne.getType(); }else if(SootUtilities.isNewArrayStmt(j)){ NewArrayExpr nae = (NewArrayExpr)j.rightBox.getValue(); return nae.getType(); }else if(SootUtilities.isNewMultiArrayStmt(j)){ JNewMultiArrayExpr jnmae = (JNewMultiArrayExpr)j.rightBox.getValue(); return jnmae.getType(); } } return null; }
private void performMapping(SootMethod meth, Map<Integer,String> anonymClasses) { if(!meth.isConcrete()) return; for(Unit u : meth.retrieveActiveBody().getUnits()){ Stmt stmt = (Stmt) u; if(!(stmt instanceof AssignStmt)) continue; Value rightOp = ((AssignStmt) stmt).getRightOp(); if(!(rightOp instanceof NewExpr)) continue; String className = rightOp.getType().toString(); int lineNum = this.sourceInfo.stmtLineNum(stmt); String anonymClassName = anonymClasses.get(lineNum); if(anonymClassName == null) continue; String prevBinding = bcClNameToSrcClName.put(className, anonymClassName); System.out.println("binding " + className + " " + anonymClassName); if(prevBinding != null){ System.out.println("Multiple anonymous classes in the same line " + anonymClassName); bcClNameToSrcClName.put(className, null); } } }
@Override protected void analyse(SootClass clazz, final SootMethod method, Body body) { for (Unit unit : body.getUnits()) { for (ValueBox valueBox : unit.getUseBoxes()) { valueBox.getValue().apply(new AbstractJimpleValueSwitch() { @Override public void caseNewExpr(NewExpr value) { SootClass type = value.getBaseType().getSootClass(); if (type.hasTag(HostnameVerifierTag.NAME)) { HostnameVerifierTag tag = (HostnameVerifierTag) type.getTag(HostnameVerifierTag.NAME); vulnerabilities.add(new Vulnerability(method, VulnerabilityType.INIT_HOSTNAME_VERIFIER, tag.getState())); } } }); } } }
@Override protected void analyse(SootClass clazz, final SootMethod method, Body body) { for (Unit unit : body.getUnits()) { for (ValueBox valueBox : unit.getUseBoxes()) { valueBox.getValue().apply(new AbstractJimpleValueSwitch() { @Override public void caseNewExpr(NewExpr value) { SootClass type = value.getBaseType().getSootClass(); if (type.hasTag(TrustManagerTag.NAME)) { TrustManagerTag tag = (TrustManagerTag) type.getTag(TrustManagerTag.NAME); vulnerabilities.add(new Vulnerability(method, VulnerabilityType.INIT_TRUST_MANAGER, tag.getState())); } } }); } } }
/** * 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; }
public void caseNewExpr(NewExpr v) { String oldName = varName; suggestVariableName("type"); String typeName = varName; ttp.setVariableName(varName); v.getType().apply(ttp); p.println("Value "+oldName+" = Jimple.v().newNewExpr("+typeName+");"); varName = oldName; }
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); } }
protected void merge(HashMap<Local,Set<NewExpr>> in1, HashMap<Local,Set<NewExpr>> in2, HashMap<Local,Set<NewExpr>> o) { for (Local l : locals) { Set<NewExpr> l1 = in1.get(l), l2 = in2.get(l); Set<NewExpr> out = o.get(l); out.clear(); if (l1.contains(UNKNOWN) || l2.contains(UNKNOWN)) { out.add(UNKNOWN); } else { out.addAll(l1); out.addAll(l2); } } }
protected HashMap<Local,Set<NewExpr>> entryInitialFlow() { HashMap<Local,Set<NewExpr>> m = new HashMap<Local,Set<NewExpr>>(); for (Local l : (Collection<Local>) locals) { HashSet<NewExpr> s = new HashSet<NewExpr>(); s.add(UNKNOWN); m.put(l, s); } return m; }
protected HashMap<Local,Set<NewExpr>> newInitialFlow() { HashMap<Local,Set<NewExpr>> m = new HashMap<Local,Set<NewExpr>>(); for (Local l : (Collection<Local>) locals) { HashSet<NewExpr> s = new HashSet<NewExpr>(); m.put(l, s); } return m; }
/** * Returns true if this analysis has any information about local l * at statement s (i.e. it is not {@link #UNKNOWN}). * In particular, it is safe to pass in locals/statements that are not * even part of the right method. In those cases <code>false</code> * will be returned. * Permits s to be <code>null</code>, in which case <code>false</code> will be returned. */ public boolean hasInfoOn(Local l, Stmt s) { HashMap<Local,Set<NewExpr>> flowBefore = getFlowBefore(s); if(flowBefore==null) { return false; } else { Set<NewExpr> info = flowBefore.get(l); return info!=null && !info.contains(UNKNOWN); } }
/** * @return true if values of l1 (at s1) and l2 (at s2) are known * to point to different objects */ public boolean notMayAlias(Local l1, Stmt s1, Local l2, Stmt s2) { Set<NewExpr> l1n = getFlowBefore(s1).get(l1); Set<NewExpr> l2n = getFlowBefore(s2).get(l2); if (l1n.contains(UNKNOWN) || l2n.contains(UNKNOWN)) return false; Set<NewExpr> n = new HashSet<NewExpr>(); n.addAll(l1n); n.retainAll(l2n); return n.isEmpty(); }
/** * If the given local at the given statement was initialized with a single, concrete new-expression * then the type of this expression is returned. Otherwise this method returns null. */ public RefType concreteType(Local l, Stmt s) { HashMap<Local,Set<NewExpr>> flowBefore = getFlowBefore(s); Set<NewExpr> set = flowBefore.get(l); if(set.size()!=1) return null; else { NewExpr singleNewExpr = set.iterator().next(); if(singleNewExpr==UNKNOWN) return null; return (RefType) singleNewExpr.getType(); } }
@SuppressWarnings("rawtypes") public void caseNewExpr(NewExpr expr) { result = result.add(mgr.INITIALIZATION_ERRORS); for (Iterator i = expr.getUseBoxes().iterator(); i.hasNext(); ) { ValueBox box = (ValueBox) i.next(); result = result.add(mightThrow(box.getValue())); } }
private SootClass findExceptionType(ThrowStmt s) { if (s.getOp() instanceof NewExpr) { NewExpr ne = (NewExpr) s.getOp(); return ne.getBaseType().getSootClass(); } else if (s.getOp() instanceof Local) { Local l = (Local) s.getOp(); if (l.getType() instanceof RefType) { return ((RefType) l.getType()).getSootClass(); } } // System.err.println("Unexpected value in throw stmt " + s.getOp()); return Scene.v().loadClass("java.lang.Throwable", SootClass.SIGNATURES); }
private SootClass findExceptionType(ThrowStmt s) { if (s.getOp() instanceof NewExpr) { NewExpr ne = (NewExpr) s.getOp(); return ne.getBaseType().getSootClass(); } else if (s.getOp() instanceof Local) { Local l = (Local) s.getOp(); if (l.getType() instanceof RefType) { return ((RefType) l.getType()).getSootClass(); } } System.err.println("Unexpected value in throw stmt " + s.getOp()); return Scene.v().loadClass("java.lang.Throwable", SootClass.SIGNATURES); }
private AbsValue analyzeNewExpr(NewExpr r, Unit u, Set<Unit> seen) { ProgramSpy.debug("************ NEW ********"); String typ = (((NewExpr) r).getBaseType ()).toString (); if (typ.equals("java.lang.StringBuffer") || typ.equals("java.lang.StringBuilder")) return StringValue.NIL_STRING; else return new UnknownValue(r.toString()); }
/** * Analyze an expression (a value) and computes an abstract value representing its contents. * @param r the expression to analyse. * @param u The unit that encapsulate the value. * @param seen What has already be seen (avoid loops). * @return */ public AbsValue analyze_expr(Value r, Unit u, Set<Unit> seen) { AbsValue result; if (r instanceof Local) { result = analyzeLocal((Local) r, u, seen); } else if (r instanceof StringConstant) result = new StringValue(((StringConstant) r).value); else if (r instanceof Constant) result = new ConstantValue((Constant) r,((Constant) r).getType()); else if (r instanceof InvokeExpr) { result = analyzeInvoke((InvokeExpr) r,u,seen); } else if (r instanceof CastExpr) { result = analyze_expr(((CastExpr) r).getOp(),u,seen); } else if (r instanceof ParameterRef) { result = analyzeParameterRef((ParameterRef) r, u, seen); } else if (r instanceof ConditionExpr) { result = analyzeConditionExpr((ConditionExpr) r, u, seen); } else if (r instanceof InstanceOfExpr) { result = analyzeInstanceOfExpr((InstanceOfExpr) r, u, seen); } else if (r instanceof StaticFieldRef) { result = analyzeStaticFieldRef((StaticFieldRef) r,u,seen); } else if (r instanceof InstanceFieldRef) { result = analyzeInstanceFieldRef((InstanceFieldRef) r,u,seen); } else if (r instanceof ArrayRef) { result = analyzeArrayRef((ArrayRef) r,u,seen); } else if (r instanceof NewExpr) { result = analyzeNewExpr((NewExpr) r, u, seen); } else { result = new UnknownValue(r.toString()); } return solve_init(result,u,seen); }
@Override public void caseNewExpr(NewExpr v) { rightElement = RightElement.NEW_UNDEF_OBJECT; logger.finest("NewExpr identified " + v.getBaseType()); if (actualContext == StmtContext.ASSIGNRIGHT) { // new InternalAnalyzerException("new Expr"); if (!ExternalClasses.classMap.contains(v.toString())) { // TODO Standardverfahren } else { // TODO special methods } } }
/** * Assigns a constant to a root variable. */ public void assignConstant(Local lhs, Constant rhs) { // Get the allocation site of this constant NewExpr newExpr = constantNewExpr(rhs); // If it was a null constant, assign null, otherwise assign alloc site if (newExpr == null) { assign(lhs, null); } else { assignNew(lhs, newExpr); } }
/** * Creates a new node for a constant. */ private NewExpr constantNewExpr(Constant constant) { if (constant instanceof StringConstant) { return STRING_SITE; } else if (constant instanceof ClassConstant) { return CLASS_SITE; } else if (constant instanceof NullConstant) { return null; } else { throw new RuntimeException(constant.toString()); } }
/** * Stores a constant into a field of objects pointed-to by a root variable. */ public void setFieldConstant(Local lhs, SootField field, Constant rhs) { // Find out the alloc site of the constant NewExpr newExpr = constantNewExpr(rhs); // If null, do nothing, as we handle only weak updates, // otherwise, add the edge if (newExpr != null) { setFieldNew(lhs, field, newExpr); } }
private void checkAndReport(Body b, Stmt curStmt, Value value, int paramIdx) { LocalGenerator localGenerator = new LocalGenerator(b); RefType stringType = RefType.v("java.lang.String"); Value lhs = value; if(lhs instanceof StringConstant) return; else if(lhs instanceof IntConstant) return; // If this is a CharSequence, we need to convert it into a string if (lhs.getType() == RefType.v("java.lang.CharSequence") || lhs.getType() == RefType.v("java.lang.StringBuilder") && lhs instanceof Local) { SootMethodRef toStringRef = Scene.v().getMethod("<java.lang.Object: " + "java.lang.String toString()>").makeRef(); Local stringLocal = localGenerator.generateLocal(stringType); Stmt stringAssignStmt = Jimple.v().newAssignStmt(stringLocal, Jimple.v().newVirtualInvokeExpr((Local) lhs, toStringRef)); stringAssignStmt.addTag(new InstrumentedCodeTag()); b.getUnits().insertBefore(stringAssignStmt, curStmt); lhs = stringLocal; } else if (lhs.getType() != IntType.v() && lhs.getType() != stringType) return; //new String() case if (value instanceof NewExpr) return; // Depending on the type of the value, we might need an intermediate local if (!(lhs instanceof Local)) { Local newLhs = localGenerator.generateLocal(lhs.getType()); AssignStmt assignLocalStmt = Jimple.v().newAssignStmt(newLhs, lhs); assignLocalStmt.addTag(new InstrumentedCodeTag()); b.getUnits().insertBefore(assignLocalStmt, curStmt); lhs = newLhs; } // Report the value Stmt reportValueStmt; if (lhs.getType() == stringType) { reportValueStmt = Jimple.v().newInvokeStmt( Jimple.v().newStaticInvokeExpr(refString, lhs, IntConstant.v(paramIdx))); } else if (lhs.getType() == IntType.v()) { reportValueStmt = Jimple.v().newInvokeStmt( Jimple.v().newStaticInvokeExpr(refInt, lhs, IntConstant.v(paramIdx))); } else return; reportValueStmt.addTag(new InstrumentedCodeTag()); b.getUnits().insertBefore(reportValueStmt, curStmt); }
@Override public void caseNewExpr(NewExpr v) { throw new RuntimeException("todo"); }
/** * Create getManager_ for managers created through <init> methods * @param initMethod * @return */ private Body createNewInstance(SootMethod initMethod) { SootClass servicesInitClass = Scene.v().getSootClass(GenerateServiceInit.servicesInitClassName); RefType newType = initMethod.getDeclaringClass().getType(); Body b = Jimple.v().newBody(); LocalGenerator lg = new LocalGenerator(b); Local newLocal = lg.generateLocal(newType); SootField sf = servicesInitClass.getFieldByName("androidcontentContext"); Value newR = Jimple.v().newStaticFieldRef(sf.makeRef()); Local contextLocal = lg.generateLocal(sf.getType()); Unit u0 = Jimple.v().newAssignStmt(contextLocal, newR); boolean addU0 = false; NewExpr n1 = Jimple.v().newNewExpr(newType); Unit u1 = Jimple.v().newAssignStmt(newLocal, n1); List<Value> args = new ArrayList<Value>(); for (Type t : initMethod.getParameterTypes()) { if (t.toString().startsWith("android.content.Context")) { args.add(contextLocal); addU0 = true; } else { args.add(NullConstant.v()); } } InvokeExpr n2 = Jimple.v().newSpecialInvokeExpr(newLocal, initMethod.makeRef(), args); Unit u2 = Jimple.v().newInvokeStmt(n2); Unit u3 = Jimple.v().newReturnStmt(newLocal); if (addU0) b.getUnits().addFirst(u0); else b.getLocals().remove(contextLocal); System.out.println("u1: "+ u1); System.out.println("u1: "+ u2); System.out.println("u1: "+ u3); if (addU0) b.getUnits().insertAfter(u1, u0); else b.getUnits().addFirst(u1); b.getUnits().insertAfter(u2, u1); b.getUnits().insertAfter(u3, u2); return b; }
private boolean isAllocationSite(Value val) { return (val instanceof StringConstant || val instanceof NewExpr || val instanceof NewArrayExpr || val instanceof NewMultiArrayExpr); }
public void caseNewExpr(NewExpr expr) { st.addStatement(new Nop()); }
/** * Creates a method body that throws an "unresolved compilation error" * message * @param declaringClass The class that was supposed to contain the method * @return The created SootMethod */ private SootMethod createUnresolvedErrorMethod(SootClass declaringClass) { SootMethod m = new SootMethod(name, parameterTypes, returnType, isStatic()?Modifier.STATIC:0); int modifiers = Modifier.PUBLIC; // we don't know who will be calling us if (isStatic()) modifiers |= Modifier.STATIC; m.setModifiers(modifiers); JimpleBody body = Jimple.v().newBody(m); m.setActiveBody(body); final LocalGenerator lg = new LocalGenerator(body); // For producing valid Jimple code, we need to access all parameters. // Otherwise, methods like "getThisLocal()" will fail. if (!isStatic) { RefType thisType = RefType.v(declaringClass); Local lThis = lg.generateLocal(thisType); body.getUnits().add(Jimple.v().newIdentityStmt(lThis, Jimple.v().newThisRef(thisType))); } for (int i = 0; i < m.getParameterCount(); i++) { Type paramType = m.getParameterType(i); Local lParam = lg.generateLocal(paramType); body.getUnits().add(Jimple.v().newIdentityStmt(lParam, Jimple.v().newParameterRef(paramType, i))); } //exc = new Error RefType runtimeExceptionType = RefType.v("java.lang.Error"); NewExpr newExpr = Jimple.v().newNewExpr(runtimeExceptionType); Local exceptionLocal = lg.generateLocal(runtimeExceptionType); AssignStmt assignStmt = Jimple.v().newAssignStmt(exceptionLocal, newExpr); body.getUnits().add(assignStmt); //exc.<init>(message) SootMethodRef cref = Scene.v().makeConstructorRef(runtimeExceptionType.getSootClass(), Collections.<Type>singletonList(RefType.v("java.lang.String"))); SpecialInvokeExpr constructorInvokeExpr = Jimple.v().newSpecialInvokeExpr(exceptionLocal, cref, StringConstant.v("Unresolved compilation error: Method "+getSignature()+" does not exist!")); InvokeStmt initStmt = Jimple.v().newInvokeStmt(constructorInvokeExpr); body.getUnits().insertAfter(initStmt, assignStmt); //throw exc body.getUnits().insertAfter(Jimple.v().newThrowStmt(exceptionLocal), initStmt); declaringClass.addMethod(m); return m; }
private void split_new() { LocalDefs defs = LocalDefs.Factory.newLocalDefs(jb); PatchingChain<Unit> units = this.jb.getUnits(); Stmt[] stmts = new Stmt[units.size()]; units.toArray(stmts); for ( Stmt stmt : stmts ) { if ( stmt instanceof InvokeStmt ) { InvokeStmt invoke = (InvokeStmt)stmt; if ( invoke.getInvokeExpr() instanceof SpecialInvokeExpr ) { SpecialInvokeExpr special = (SpecialInvokeExpr)invoke.getInvokeExpr(); if ( special.getMethodRef().name().equals("<init>") ) { List<Unit> deflist = defs.getDefsOfAt( (Local)special.getBase(), invoke); while ( deflist.size() == 1 ) { Stmt stmt2 = (Stmt)deflist.get(0); if ( stmt2 instanceof AssignStmt ) { AssignStmt assign = (AssignStmt)stmt2; if ( assign.getRightOp() instanceof Local ) { deflist = defs.getDefsOfAt( (Local)assign.getRightOp(), assign); continue; } else if ( assign.getRightOp() instanceof NewExpr ) { Local newlocal = Jimple.v().newLocal( "tmp", null); newlocal.setName("tmp$" + System.identityHashCode(newlocal)); this.jb.getLocals().add(newlocal); special.setBase(newlocal); DefinitionStmt assignStmt = Jimple.v().newAssignStmt( assign.getLeftOp(), newlocal); Unit u = Util.findLastIdentityUnit(jb, assign); units.insertAfter(assignStmt, u); assign.setLeftOp(newlocal); this.addLocal(newlocal); this.initAssignment(assignStmt); } } break; } } } } } }
private void split_new() { LocalDefs defs = LocalDefs.Factory.newLocalDefs(stmtBody); PatchingChain<Unit> units = stmtBody.getUnits(); Stmt[] stmts = new Stmt[units.size()]; units.toArray(stmts); for (Stmt stmt : stmts) { if(stmt instanceof InvokeStmt) { InvokeStmt invoke = (InvokeStmt) stmt; if(invoke.getInvokeExpr() instanceof SpecialInvokeExpr) { SpecialInvokeExpr special = (SpecialInvokeExpr) invoke.getInvokeExpr(); if("<init>".equals(special.getMethodRef().name())) { List<Unit> deflist = defs.getDefsOfAt((Local) special.getBase(), invoke); while(deflist.size() == 1) { Stmt stmt2 = (Stmt) deflist.get(0); if(stmt2 instanceof AssignStmt) { AssignStmt assign = (AssignStmt) stmt2; if(assign.getRightOp() instanceof Local) { deflist = defs.getDefsOfAt((Local) assign.getRightOp(), assign); continue; } else if(assign.getRightOp() instanceof NewExpr) { // We split the local. //G.v().out.println("split: [" + assign + "] and [" + stmt + "]"); Local newlocal = Jimple.v().newLocal("tmp", null); stmtBody.getLocals().add(newlocal); special.setBase(newlocal); units.insertAfter(Jimple.v().newAssignStmt(assign.getLeftOp(), newlocal), assign); assign.setLeftOp(newlocal); } } break; } } } } } }
private void split_new() { LocalDefs defs = LocalDefs.Factory.newLocalDefs(stmtBody); PatchingChain<Unit> units = stmtBody.getUnits(); Stmt[] stmts = new Stmt[units.size()]; units.toArray(stmts); for (Stmt stmt : stmts) { if(stmt instanceof InvokeStmt) { InvokeStmt invoke = (InvokeStmt) stmt; if(invoke.getInvokeExpr() instanceof SpecialInvokeExpr) { SpecialInvokeExpr special = (SpecialInvokeExpr) invoke.getInvokeExpr(); if(special.getMethodRef().name().equals("<init>")) { List<Unit> deflist = defs.getDefsOfAt((Local) special.getBase(), invoke); while(deflist.size() == 1) { Stmt stmt2 = (Stmt) deflist.get(0); if(stmt2 instanceof AssignStmt) { AssignStmt assign = (AssignStmt) stmt2; if(assign.getRightOp() instanceof Local) { deflist = defs.getDefsOfAt((Local) assign.getRightOp(), assign); continue; } else if(assign.getRightOp() instanceof NewExpr) { // We split the local. //G.v().out.println("split: [" + assign + "] and [" + stmt + "]"); Local newlocal = Jimple.v().newLocal("tmp", null); stmtBody.getLocals().add(newlocal); special.setBase(newlocal); units.insertAfter(Jimple.v().newAssignStmt(assign.getLeftOp(), newlocal), assign); assign.setLeftOp(newlocal); } } break; } } } } } }
protected void copy(HashMap<Local,Set<NewExpr>> source, HashMap<Local,Set<NewExpr>> dest) { dest.putAll(source); }
@Override public void caseNewExpr(NewExpr ne) { BuilderReference baseType = DexPrinter.toTypeReference (ne.getBaseType(), stmtV.getBelongingFile()); stmtV.addInsn(new Insn21c(Opcode.NEW_INSTANCE, destinationReg, baseType), origStmt); }
/** * <p> * Utility method for checking if a {@link Unit} might have side effects. It * simply returns true for any unit which invokes a method directly or which * might invoke static initializers indirectly (by creating a new object or * by refering to a static field; see sections 2.17.4, 2.17.5, and 5.5 of * the Java Virtual Machine Specification). * </p> * * <code>mightHaveSideEffects()</code> is declared package-private so that * it is available to unit tests that are part of this package. * * @param u * The unit whose potential for side effects is to be checked. * * @return whether or not <code>u</code> has the potential for side effects. */ static boolean mightHaveSideEffects(Unit u) { if (u instanceof Inst) { Inst i = (Inst) u; return (i.containsInvokeExpr() || (i instanceof StaticPutInst) || (i instanceof StaticGetInst) || (i instanceof NewInst)); } else if (u instanceof Stmt) { for (ValueBox vb : u.getUseBoxes()) { Value v = vb.getValue(); if ((v instanceof StaticFieldRef) || (v instanceof InvokeExpr) || (v instanceof NewExpr)) { return true; } } } return false; }