77import java .util .List ;
88import java .util .Set ;
99import java .util .concurrent .atomic .AtomicInteger ;
10- import java .util .function .Function ;
1110import java .util .regex .Matcher ;
1211import java .util .regex .Pattern ;
1312
1413import heros .solver .Pair ;
1514import heros .solver .PathEdge ;
16- import soot .*;
17- import soot .jimple .*;
15+ import soot .ArrayType ;
16+ import soot .FastHierarchy ;
17+ import soot .Hierarchy ;
18+ import soot .Local ;
19+ import soot .Modifier ;
20+ import soot .PrimType ;
21+ import soot .RefType ;
22+ import soot .Scene ;
23+ import soot .SootClass ;
24+ import soot .SootField ;
25+ import soot .SootFieldRef ;
26+ import soot .SootMethod ;
27+ import soot .Type ;
28+ import soot .Unit ;
29+ import soot .Value ;
30+ import soot .VoidType ;
31+ import soot .jimple .DefinitionStmt ;
32+ import soot .jimple .DynamicInvokeExpr ;
33+ import soot .jimple .InstanceInvokeExpr ;
34+ import soot .jimple .InvokeExpr ;
35+ import soot .jimple .ReturnStmt ;
36+ import soot .jimple .StaticInvokeExpr ;
37+ import soot .jimple .Stmt ;
1838import soot .jimple .infoflow .InfoflowConfiguration ;
1939import soot .jimple .infoflow .InfoflowManager ;
2040import soot .jimple .infoflow .data .Abstraction ;
2444import soot .jimple .infoflow .handlers .PreAnalysisHandler ;
2545import soot .jimple .infoflow .methodSummary .data .provider .IMethodSummaryProvider ;
2646import soot .jimple .infoflow .methodSummary .data .sourceSink .AbstractFlowSinkSource ;
47+ import soot .jimple .infoflow .methodSummary .data .sourceSink .FlowSource ;
2748import soot .jimple .infoflow .methodSummary .data .summary .ClassMethodSummaries ;
2849import soot .jimple .infoflow .methodSummary .data .summary .ClassSummaries ;
2950import soot .jimple .infoflow .methodSummary .data .summary .GapDefinition ;
@@ -507,8 +528,18 @@ public Set<Abstraction> getTaintsForMethod(Stmt stmt, Abstraction d1, Abstractio
507528 ByReferenceBoolean classSupported = new ByReferenceBoolean (false );
508529
509530 // Compute the wrapper taints for the current method
510- final SootMethod callee = stmt .getInvokeExpr ().getMethod ();
511- Set <AccessPath > res = computeTaintsForMethod (stmt , d1 , taintedAbs , callee , killIncomingTaint , classSupported );
531+ final InvokeExpr inv = stmt .getInvokeExpr ();
532+ final SootMethod callee = inv .getMethod ();
533+ Set <AccessPath > res ;
534+ if (inv instanceof DynamicInvokeExpr ) {
535+ final DynamicInvokeExpr dyn = (DynamicInvokeExpr ) inv ;
536+ SootMethod m = dyn .getBootstrapMethodRef ().tryResolve ();
537+ if (m == null )
538+ return null ;
539+
540+ res = computeTaintsForMethod (stmt , d1 , taintedAbs , m , killIncomingTaint , classSupported );
541+ } else
542+ res = computeTaintsForMethod (stmt , d1 , taintedAbs , callee , killIncomingTaint , classSupported );
512543
513544 // Create abstractions from the access paths
514545 if (res != null && !res .isEmpty ()) {
@@ -522,7 +553,7 @@ public Set<Abstraction> getTaintsForMethod(Stmt stmt, Abstraction d1, Abstractio
522553 if (!killIncomingTaint .value && (resAbs == null || resAbs .isEmpty ())) {
523554 // Is this method explicitly excluded?
524555 if (!this .flows .isMethodExcluded (callee .getDeclaringClass ().getName (), callee .getSubSignature ())) {
525- // wrapperMisses.incrementAndGet();
556+ // wrapperMisses.incrementAndGet();
526557
527558 if (classSupported .value )
528559 return Collections .singleton (taintedAbs );
@@ -584,7 +615,7 @@ protected void reportMissingMethod(SootMethod method) {
584615 */
585616 private Set <AccessPath > computeTaintsForMethod (Stmt stmt , Abstraction d1 , Abstraction taintedAbs ,
586617 final SootMethod method , ByReferenceBoolean killIncomingTaint , ByReferenceBoolean classSupported ) {
587- // wrapperHits.incrementAndGet();
618+ // wrapperHits.incrementAndGet();
588619
589620 // Get the cached data flows
590621 ClassSummaries flowsInCallees = getFlowSummariesForMethod (stmt , method , taintedAbs , classSupported );
@@ -965,23 +996,28 @@ protected ClassSummaries getFlowSummariesForMethod(Stmt stmt, final SootMethod m
965996 */
966997 protected SootClass getSummaryDeclaringClass (Stmt stmt , AccessPath taintedAP ) {
967998 Type declaredType = null ;
968- if (stmt != null && stmt .getInvokeExpr () instanceof InstanceInvokeExpr ) {
969- // If the base object of the call is tainted, we may have a more precise type in
970- // the access path
971- InstanceInvokeExpr iinv = (InstanceInvokeExpr ) stmt .getInvokeExpr ();
972- if (taintedAP != null && iinv .getBase () == taintedAP .getPlainValue ()) {
973- declaredType = taintedAP .getBaseType ();
974- }
999+ if (stmt != null ) {
1000+ if (stmt .getInvokeExpr () instanceof InstanceInvokeExpr ) {
1001+ // If the base object of the call is tainted, we may have a more precise type in
1002+ // the access path
1003+ InstanceInvokeExpr iinv = (InstanceInvokeExpr ) stmt .getInvokeExpr ();
1004+ if (taintedAP != null && iinv .getBase () == taintedAP .getPlainValue ()) {
1005+ declaredType = taintedAP .getBaseType ();
1006+ }
1007+
1008+ // We may have a call such as
1009+ // x = editable.toString();
1010+ // In that case, the callee is Object.toString(), since in the stub Android
1011+ // JAR, the class android.text.Editable does not override toString(). On a
1012+ // real device, it does. Consequently, we have a summary in the "Editable"
1013+ // class. To handle such weird cases, we walk the class hierarchy based on
1014+ // the declared type of the base object.
1015+ Type baseType = iinv .getBase ().getType ();
1016+ declaredType = manager .getTypeUtils ().getMorePreciseType (declaredType , baseType );
1017+ } else if (stmt .getInvokeExpr () instanceof DynamicInvokeExpr ) {
1018+ return ((DynamicInvokeExpr ) stmt .getInvokeExpr ()).getBootstrapMethodRef ().getDeclaringClass ();
9751019
976- // We may have a call such as
977- // x = editable.toString();
978- // In that case, the callee is Object.toString(), since in the stub Android
979- // JAR, the class android.text.Editable does not override toString(). On a
980- // real device, it does. Consequently, we have a summary in the "Editable"
981- // class. To handle such weird cases, we walk the class hierarchy based on
982- // the declared type of the base object.
983- Type baseType = iinv .getBase ().getType ();
984- declaredType = manager .getTypeUtils ().getMorePreciseType (declaredType , baseType );
1020+ }
9851021 }
9861022 return declaredType instanceof RefType ? ((RefType ) declaredType ).getSootClass () : null ;
9871023 }
@@ -1102,6 +1138,8 @@ private boolean flowMatchesTaint(final AbstractFlowSinkSource flowSource, final
11021138 if (compareFields (taint , flowSource ))
11031139 return true ;
11041140 }
1141+ if (flowSource .getParameterIndex () == FlowSource .ANY_PARAMETER )
1142+ return true ;
11051143 } else if (flowSource .isField ()) {
11061144 // Flows from a field can either be applied to the same field or
11071145 // the base object in total
0 commit comments