Skip to content

Commit 923e7ec

Browse files
committed
Merge branch 'develop' of https://github.com/secure-software-engineering/FlowDroid into dev-experimental
2 parents dce0ebd + b091315 commit 923e7ec

22 files changed

Lines changed: 679 additions & 562 deletions

File tree

README.MD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ Steven Arzt</a> is a good place to start.
109109
## Contributing to FlowDroid
110110

111111
Contributions are always welcome. FlowDroid is an open source project that we published in the hope that it will be useful to
112-
the research community as a whole. If you have a new feature of a bug fix that you would like to see in the official code
112+
the research community as a whole. If you have a new feature or a bug fix that you would like to see in the official code
113113
repository, please open a merge request here on Github and contact us (see below) with a short description of what you have
114114
done.
115115

soot-infoflow-android/src/soot/jimple/infoflow/android/callbacks/DefaultCallbackAnalyzer.java

Lines changed: 1 addition & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.io.IOException;
44
import java.util.ArrayList;
5-
import java.util.Collection;
65
import java.util.Collections;
76
import java.util.HashSet;
87
import java.util.Iterator;
@@ -28,7 +27,6 @@
2827
import soot.jimple.infoflow.android.callbacks.filters.ICallbackFilter;
2928
import soot.jimple.infoflow.android.entryPointCreators.AndroidEntryPointConstants;
3029
import soot.jimple.infoflow.android.entryPointCreators.AndroidEntryPointUtils;
31-
import soot.jimple.infoflow.android.entryPointCreators.AndroidEntryPointUtils.ComponentType;
3230
import soot.jimple.infoflow.memory.IMemoryBoundedSolver;
3331
import soot.jimple.infoflow.memory.ISolverTerminationReason;
3432
import soot.jimple.infoflow.util.SystemClassHandler;
@@ -105,7 +103,7 @@ protected void internalTransform(String phaseName, @SuppressWarnings("rawtypes")
105103
break;
106104

107105
List<MethodOrMethodContext> methods = new ArrayList<MethodOrMethodContext>(
108-
getLifecycleMethods(sc));
106+
entryPointUtils.getLifecycleMethods(sc));
109107

110108
// Check for callbacks registered in the code
111109
analyzeReachableMethods(sc, methods);
@@ -187,77 +185,6 @@ protected void internalTransform(String phaseName, @SuppressWarnings("rawtypes")
187185
PackManager.v().getPack("wjtp").add(transform);
188186
}
189187

190-
/**
191-
* Gets all lifecycle methods in the given entry point class
192-
*
193-
* @param sc The class in which to look for lifecycle methods
194-
* @return The set of lifecycle methods in the given class
195-
*/
196-
private Collection<? extends MethodOrMethodContext> getLifecycleMethods(SootClass sc) {
197-
return getLifecycleMethods(entryPointUtils.getComponentType(sc), sc);
198-
}
199-
200-
/**
201-
* Gets all lifecycle methods in the given entry point class
202-
*
203-
* @param componentType the component type
204-
* @param sc The class in which to look for lifecycle methods
205-
* @return The set of lifecycle methods in the given class
206-
*/
207-
public static Collection<? extends MethodOrMethodContext> getLifecycleMethods(ComponentType componentType,
208-
SootClass sc) {
209-
switch (componentType) {
210-
case Activity:
211-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getActivityLifecycleMethods());
212-
case Service:
213-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getServiceLifecycleMethods());
214-
case Application:
215-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getApplicationLifecycleMethods());
216-
case BroadcastReceiver:
217-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getBroadcastLifecycleMethods());
218-
case Fragment:
219-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getFragmentLifecycleMethods());
220-
case ContentProvider:
221-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getContentproviderLifecycleMethods());
222-
case GCMBaseIntentService:
223-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getGCMIntentServiceMethods());
224-
case GCMListenerService:
225-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getGCMListenerServiceMethods());
226-
case ServiceConnection:
227-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getServiceConnectionMethods());
228-
case Plain:
229-
return Collections.emptySet();
230-
}
231-
return Collections.emptySet();
232-
}
233-
234-
/**
235-
* This method takes a lifecycle class and the list of lifecycle method
236-
* subsignatures. For each subsignature, it checks whether the given class or
237-
* one of its superclass overwrites the respective methods. All findings are
238-
* collected in a set and returned.
239-
*
240-
* @param sc The class in which to look for lifecycle method
241-
* implementations
242-
* @param methods The list of lifecycle method subsignatures for the type of
243-
* component that the given class corresponds to
244-
* @return The set of implemented lifecycle methods in the given class
245-
*/
246-
private static Collection<? extends MethodOrMethodContext> getLifecycleMethods(SootClass sc, List<String> methods) {
247-
Set<MethodOrMethodContext> lifecycleMethods = new HashSet<>();
248-
SootClass currentClass = sc;
249-
while (currentClass != null) {
250-
for (String sig : methods) {
251-
SootMethod sm = currentClass.getMethodUnsafe(sig);
252-
if (sm != null)
253-
if (!SystemClassHandler.v().isClassInSystemPackage(sm.getDeclaringClass().getName()))
254-
lifecycleMethods.add(sm);
255-
}
256-
currentClass = currentClass.hasSuperclass() ? currentClass.getSuperclass() : null;
257-
}
258-
return lifecycleMethods;
259-
}
260-
261188
private void analyzeReachableMethods(SootClass lifecycleElement, List<MethodOrMethodContext> methods) {
262189
// Make sure to exclude all other edges in the callgraph except for the
263190
// edges start in the lifecycle methods we explicitly pass in

soot-infoflow-android/src/soot/jimple/infoflow/android/callbacks/filters/ApplicationCallbackFilter.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import java.util.Set;
44

5+
import soot.FastHierarchy;
6+
import soot.RefType;
57
import soot.Scene;
68
import soot.SootClass;
79
import soot.SootMethod;
@@ -21,6 +23,7 @@ public class ApplicationCallbackFilter extends AbstractCallbackFilter {
2123
private SootClass activityLifecycleCallbacks;
2224
private SootClass provideAssistDataListener;
2325
private SootClass componentCallbacks;
26+
private SootClass componentCallbacks2;
2427

2528
/**
2629
* Creates a new instance of the {@link ApplicationCallbackFilter} class
@@ -65,12 +68,11 @@ public boolean accepts(SootClass component, SootClass callbackHandler) {
6568
// not implemented there
6669
if (this.applicationClass != null && component.getName().equals(this.applicationClass)
6770
&& !callbackHandler.getName().equals(applicationClass)) {
68-
if (!Scene.v().getOrMakeFastHierarchy().canStoreType(callbackHandler.getType(),
69-
this.activityLifecycleCallbacks.getType())
70-
&& !Scene.v().getOrMakeFastHierarchy().canStoreType(callbackHandler.getType(),
71-
this.provideAssistDataListener.getType())
72-
&& !Scene.v().getOrMakeFastHierarchy().canStoreType(callbackHandler.getType(),
73-
this.componentCallbacks.getType()))
71+
final FastHierarchy fh = Scene.v().getOrMakeFastHierarchy();
72+
final RefType callbackType = callbackHandler.getType();
73+
if (!fh.canStoreType(callbackType, this.activityLifecycleCallbacks.getType())
74+
&& !fh.canStoreType(callbackType, this.provideAssistDataListener.getType())
75+
&& !fh.canStoreType(callbackType, this.componentCallbacks.getType()))
7476
return false;
7577
}
7678

@@ -84,6 +86,8 @@ public void reset() {
8486
this.provideAssistDataListener = Scene.v()
8587
.getSootClassUnsafe("android.app.Application$OnProvideAssistDataListener");
8688
this.componentCallbacks = Scene.v().getSootClassUnsafe(AndroidEntryPointConstants.COMPONENTCALLBACKSINTERFACE);
89+
this.componentCallbacks2 = Scene.v()
90+
.getSootClassUnsafe(AndroidEntryPointConstants.COMPONENTCALLBACKS2INTERFACE);
8791
}
8892

8993
@Override
@@ -92,10 +96,18 @@ public boolean accepts(SootClass component, SootMethod callback) {
9296
// components that are not the application
9397
if (component.getName().equals(applicationClass))
9498
return true;
99+
95100
String subSig = callback.getSubSignature();
96-
return !AndroidEntryPointConstants.getActivityLifecycleCallbackMethods().contains(subSig)
97-
&& !AndroidEntryPointConstants.getComponentCallbackMethods().contains(subSig)
98-
&& !AndroidEntryPointConstants.getComponentCallback2Methods().contains(subSig);
101+
final FastHierarchy fh = Scene.v().getOrMakeFastHierarchy();
102+
final RefType callbackType = callback.getDeclaringClass().getType();
103+
if (AndroidEntryPointConstants.getActivityLifecycleCallbackMethods().contains(subSig))
104+
return fh.canStoreType(callbackType, this.activityLifecycleCallbacks.getType());
105+
if (AndroidEntryPointConstants.getComponentCallbackMethods().contains(subSig))
106+
return fh.canStoreType(callbackType, this.componentCallbacks.getType());
107+
if (AndroidEntryPointConstants.getComponentCallback2Methods().contains(subSig))
108+
return fh.canStoreType(callbackType, this.componentCallbacks2.getType());
109+
110+
return true;
99111
}
100112

101113
}

soot-infoflow-android/src/soot/jimple/infoflow/android/entryPointCreators/AndroidEntryPointConstants.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ public class AndroidEntryPointConstants {
125125

126126
private static final String[] activityMethods = { ACTIVITY_ONCREATE, ACTIVITY_ONDESTROY, ACTIVITY_ONPAUSE,
127127
ACTIVITY_ONRESTART, ACTIVITY_ONRESUME, ACTIVITY_ONSTART, ACTIVITY_ONSTOP, ACTIVITY_ONSAVEINSTANCESTATE,
128-
ACTIVITY_ONRESTOREINSTANCESTATE, ACTIVITY_ONCREATEDESCRIPTION, ACTIVITY_ONPOSTCREATE,
129-
ACTIVITY_ONPOSTRESUME };
128+
ACTIVITY_ONRESTOREINSTANCESTATE, ACTIVITY_ONCREATEDESCRIPTION, ACTIVITY_ONPOSTCREATE, ACTIVITY_ONPOSTRESUME,
129+
ACTIVITY_ONATTACHFRAGMENT };
130130
private static final List<String> activityMethodList = Arrays.asList(activityMethods);
131131

132132
private static final String[] serviceMethods = { SERVICE_ONCREATE, SERVICE_ONDESTROY, SERVICE_ONSTART1,
@@ -135,7 +135,8 @@ public class AndroidEntryPointConstants {
135135

136136
private static final String[] fragmentMethods = { FRAGMENT_ONCREATE, FRAGMENT_ONDESTROY, FRAGMENT_ONPAUSE,
137137
FRAGMENT_ONATTACH, FRAGMENT_ONDESTROYVIEW, FRAGMENT_ONRESUME, FRAGMENT_ONSTART, FRAGMENT_ONSTOP,
138-
FRAGMENT_ONCREATEVIEW, FRAGMENT_ONACTIVITYCREATED, FRAGMENT_ONVIEWSTATERESTORED, FRAGMENT_ONDETACH };
138+
FRAGMENT_ONCREATEVIEW, FRAGMENT_ONACTIVITYCREATED, FRAGMENT_ONVIEWSTATERESTORED, FRAGMENT_ONDETACH,
139+
FRAGMENT_ONSAVEINSTANCESTATE, FRAGMENT_ONVIEWCREATED };
139140
private static final List<String> fragmentMethodList = Arrays.asList(fragmentMethods);
140141

141142
private static final String[] gcmIntentServiceMethods = { GCMINTENTSERVICE_ONDELETEDMESSAGES,
@@ -163,7 +164,8 @@ public class AndroidEntryPointConstants {
163164
ACTIVITYLIFECYCLECALLBACK_ONACTIVITYDESTROYED, ACTIVITYLIFECYCLECALLBACK_ONACTIVITYCREATED };
164165
private static final List<String> activityLifecycleMethodList = Arrays.asList(activityLifecycleMethods);
165166

166-
private static final String[] componentCallbackMethods = { COMPONENTCALLBACKS_ONCONFIGURATIONCHANGED };
167+
private static final String[] componentCallbackMethods = { COMPONENTCALLBACKS_ONCONFIGURATIONCHANGED,
168+
COMPONENTCALLBACKS_ONLOWMEMORY };
167169
private static final List<String> componentCallbackMethodList = Arrays.asList(componentCallbackMethods);
168170

169171
public static final String[] componentCallback2Methods = { COMPONENTCALLBACKS2_ONTRIMMEMORY };

soot-infoflow-android/src/soot/jimple/infoflow/android/entryPointCreators/AndroidEntryPointUtils.java

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
package soot.jimple.infoflow.android.entryPointCreators;
22

3+
import java.util.Collection;
4+
import java.util.Collections;
35
import java.util.HashMap;
6+
import java.util.HashSet;
7+
import java.util.List;
48
import java.util.Map;
9+
import java.util.Set;
510

611
import org.slf4j.Logger;
712
import org.slf4j.LoggerFactory;
813

914
import soot.FastHierarchy;
15+
import soot.MethodOrMethodContext;
1016
import soot.Scene;
1117
import soot.SootClass;
1218
import soot.SootMethod;
19+
import soot.jimple.infoflow.util.SystemClassHandler;
1320

1421
/**
1522
* Class containing common utility methods for dealing with Android entry points
@@ -21,7 +28,7 @@ public class AndroidEntryPointUtils {
2128

2229
private static final Logger logger = LoggerFactory.getLogger(AndroidEntryPointUtils.class);
2330

24-
private Map<SootClass, ComponentType> componentTypeCache = new HashMap<SootClass, ComponentType>();
31+
private Map<SootClass, ComponentType> componentTypeCache = new HashMap<>();
2532

2633
private SootClass osClassApplication;
2734
private SootClass osClassActivity;
@@ -162,6 +169,9 @@ public boolean isEntryPointMethod(SootMethod method) {
162169
if (componentType == ComponentType.Service
163170
&& AndroidEntryPointConstants.getServiceLifecycleMethods().contains(subsignature))
164171
return true;
172+
if (componentType == ComponentType.Application
173+
&& AndroidEntryPointConstants.getApplicationLifecycleMethods().contains(subsignature))
174+
return true;
165175
if (componentType == ComponentType.Fragment
166176
&& AndroidEntryPointConstants.getFragmentLifecycleMethods().contains(subsignature))
167177
return true;
@@ -184,4 +194,75 @@ public boolean isEntryPointMethod(SootMethod method) {
184194
return false;
185195
}
186196

197+
/**
198+
* Gets all lifecycle methods in the given entry point class
199+
*
200+
* @param sc The class in which to look for lifecycle methods
201+
* @return The set of lifecycle methods in the given class
202+
*/
203+
public Collection<? extends MethodOrMethodContext> getLifecycleMethods(SootClass sc) {
204+
return getLifecycleMethods(getComponentType(sc), sc);
205+
}
206+
207+
/**
208+
* Gets all lifecycle methods in the given entry point class
209+
*
210+
* @param componentType the component type
211+
* @param sc The class in which to look for lifecycle methods
212+
* @return The set of lifecycle methods in the given class
213+
*/
214+
public static Collection<? extends MethodOrMethodContext> getLifecycleMethods(ComponentType componentType,
215+
SootClass sc) {
216+
switch (componentType) {
217+
case Activity:
218+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getActivityLifecycleMethods());
219+
case Service:
220+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getServiceLifecycleMethods());
221+
case Application:
222+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getApplicationLifecycleMethods());
223+
case BroadcastReceiver:
224+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getBroadcastLifecycleMethods());
225+
case Fragment:
226+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getFragmentLifecycleMethods());
227+
case ContentProvider:
228+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getContentproviderLifecycleMethods());
229+
case GCMBaseIntentService:
230+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getGCMIntentServiceMethods());
231+
case GCMListenerService:
232+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getGCMListenerServiceMethods());
233+
case ServiceConnection:
234+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getServiceConnectionMethods());
235+
case Plain:
236+
return Collections.emptySet();
237+
}
238+
return Collections.emptySet();
239+
}
240+
241+
/**
242+
* This method takes a lifecycle class and the list of lifecycle method
243+
* subsignatures. For each subsignature, it checks whether the given class or
244+
* one of its superclass overwrites the respective methods. All findings are
245+
* collected in a set and returned.
246+
*
247+
* @param sc The class in which to look for lifecycle method
248+
* implementations
249+
* @param methods The list of lifecycle method subsignatures for the type of
250+
* component that the given class corresponds to
251+
* @return The set of implemented lifecycle methods in the given class
252+
*/
253+
private static Collection<? extends MethodOrMethodContext> getLifecycleMethods(SootClass sc, List<String> methods) {
254+
Set<MethodOrMethodContext> lifecycleMethods = new HashSet<>();
255+
SootClass currentClass = sc;
256+
while (currentClass != null) {
257+
for (String sig : methods) {
258+
SootMethod sm = currentClass.getMethodUnsafe(sig);
259+
if (sm != null)
260+
if (!SystemClassHandler.v().isClassInSystemPackage(sm.getDeclaringClass().getName()))
261+
lifecycleMethods.add(sm);
262+
}
263+
currentClass = currentClass.hasSuperclass() ? currentClass.getSuperclass() : null;
264+
}
265+
return lifecycleMethods;
266+
}
267+
187268
}

0 commit comments

Comments
 (0)