Skip to content

Commit 257032a

Browse files
committed
some refactoring to make it easier to use FlowDroid in custom settings
1 parent af814ce commit 257032a

11 files changed

Lines changed: 439 additions & 355 deletions

File tree

soot-infoflow-android/src/soot/jimple/infoflow/android/SetupApplication.java

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
import soot.jimple.infoflow.solver.memory.IMemoryManagerFactory;
108108
import soot.jimple.infoflow.sourcesSinks.definitions.ISourceSinkDefinition;
109109
import soot.jimple.infoflow.sourcesSinks.definitions.ISourceSinkDefinitionProvider;
110+
import soot.jimple.infoflow.sourcesSinks.definitions.InMemorySourceSinkDefinitionProvider;
110111
import soot.jimple.infoflow.sourcesSinks.definitions.MethodSourceSinkDefinition;
111112
import soot.jimple.infoflow.sourcesSinks.manager.ISourceSinkManager;
112113
import soot.jimple.infoflow.taintWrappers.ITaintPropagationWrapper;
@@ -1477,29 +1478,7 @@ public InfoflowResults runInfoflow(Set<AndroidMethod> sources, Set<AndroidMethod
14771478
for (AndroidMethod am : sinks)
14781479
sinkDefs.add(new MethodSourceSinkDefinition(am));
14791480

1480-
ISourceSinkDefinitionProvider parser = new ISourceSinkDefinitionProvider() {
1481-
1482-
@Override
1483-
public Set<ISourceSinkDefinition> getSources() {
1484-
return sourceDefs;
1485-
}
1486-
1487-
@Override
1488-
public Set<ISourceSinkDefinition> getSinks() {
1489-
return sinkDefs;
1490-
}
1491-
1492-
@Override
1493-
public Set<ISourceSinkDefinition> getAllMethods() {
1494-
Set<ISourceSinkDefinition> sourcesSinks = new HashSet<>(sourceDefs.size() + sinkDefs.size());
1495-
sourcesSinks.addAll(sourceDefs);
1496-
sourcesSinks.addAll(sinkDefs);
1497-
return sourcesSinks;
1498-
}
1499-
1500-
};
1501-
1502-
return runInfoflow(parser);
1481+
return runInfoflow(new InMemorySourceSinkDefinitionProvider(sourceDefs, sinkDefs));
15031482
}
15041483

15051484
/**
@@ -1527,6 +1506,21 @@ public InfoflowResults runInfoflow() throws IOException {
15271506
File sourceSinkFile = config.getAnalysisFileConfig().getSourceSinkFile();
15281507
if (sourceSinkFile == null || !sourceSinkFile.exists())
15291508
throw new RuntimeException("No source/sink file specified for the data flow analysis");
1509+
1510+
ISourceSinkDefinitionProvider parser = parseSourceSinkDefinitions(sourceSinkFile);
1511+
return runInfoflow(parser);
1512+
}
1513+
1514+
/**
1515+
* Parses the given source/sink definition file to make it accessible to the
1516+
* data flow analysis
1517+
*
1518+
* @param sourceSinkFile The source/sink definition file to parse
1519+
* @return The {@link ISourceSinkDefinitionProvider} that provides access to the
1520+
* source/sink definitions
1521+
* @throws IOException Thrown if the given source/sink file could not be read.
1522+
*/
1523+
protected ISourceSinkDefinitionProvider parseSourceSinkDefinitions(File sourceSinkFile) throws IOException {
15301524
String fileExtension = FilenameUtils.getExtension(sourceSinkFile.getName());
15311525
fileExtension = fileExtension.toLowerCase();
15321526

@@ -1544,8 +1538,7 @@ else if (fileExtension.equals("rifl"))
15441538
} catch (SAXException ex) {
15451539
throw new IOException("Could not read XML file", ex);
15461540
}
1547-
1548-
return runInfoflow(parser);
1541+
return parser;
15491542
}
15501543

15511544
/**

soot-infoflow-android/src/soot/jimple/infoflow/android/source/parsers/xml/AbstractXMLSourceSinkParser.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@
2424
import soot.jimple.infoflow.android.data.AndroidMethod;
2525
import soot.jimple.infoflow.android.data.CategoryDefinition;
2626
import soot.jimple.infoflow.data.AbstractMethodAndClass;
27-
import soot.jimple.infoflow.river.AdditionalFlowCondition;
27+
import soot.jimple.infoflow.river.conditions.SignatureFlowCondition;
2828
import soot.jimple.infoflow.sourcesSinks.definitions.AccessPathTuple;
29+
import soot.jimple.infoflow.sourcesSinks.definitions.FieldSourceSinkDefinition;
2930
import soot.jimple.infoflow.sourcesSinks.definitions.IAccessPathBasedSourceSinkDefinition;
3031
import soot.jimple.infoflow.sourcesSinks.definitions.ISourceSinkCategory;
3132
import soot.jimple.infoflow.sourcesSinks.definitions.ISourceSinkDefinition;
33+
import soot.jimple.infoflow.sourcesSinks.definitions.MethodSourceSinkDefinition;
3234
import soot.jimple.infoflow.sourcesSinks.definitions.MethodSourceSinkDefinition.CallType;
3335
import soot.jimple.infoflow.sourcesSinks.definitions.SourceSinkCondition;
3436
import soot.jimple.infoflow.sourcesSinks.definitions.SourceSinkType;
@@ -393,7 +395,7 @@ public void endElement(String uri, String localName, String qName) throws SAXExc
393395

394396
case XMLConstants.ADDITIONAL_FLOW_CONDITION_TAG:
395397
if (!classNamesOnPath.isEmpty() || !signaturesOnPath.isEmpty()) {
396-
AdditionalFlowCondition additionalFlowCondition = new AdditionalFlowCondition(classNamesOnPath,
398+
SignatureFlowCondition additionalFlowCondition = new SignatureFlowCondition(classNamesOnPath,
397399
signaturesOnPath, excludedClassNames);
398400
// Reset both for a new condition
399401
classNamesOnPath = new HashSet<>();
@@ -532,8 +534,8 @@ protected void handleEndtagAccesspath() {
532534
* category is requested, the respective definition is created. Otherwise, the
533535
* existing one is returned.
534536
*
535-
* @param categoryID The user-defined category name
536-
* @param desc The human-readable description
537+
* @param categoryID The user-defined category name
538+
* @param desc The human-readable description
537539
* @return The category definition object for the given category names
538540
*/
539541
private ISourceSinkCategory getOrMakeCategory(String categoryID, String desc) {

soot-infoflow-android/test/soot/jimple/infoflow/android/test/xmlParser/XmlParserTest.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import soot.jimple.infoflow.android.data.parsers.PermissionMethodParser;
1515
import soot.jimple.infoflow.android.source.parsers.xml.XMLSourceSinkParser;
1616
import soot.jimple.infoflow.android.test.BaseJUnitTests;
17-
import soot.jimple.infoflow.river.AdditionalFlowCondition;
17+
import soot.jimple.infoflow.river.conditions.SignatureFlowCondition;
1818
import soot.jimple.infoflow.sourcesSinks.definitions.ISourceSinkDefinition;
1919
import soot.jimple.infoflow.sourcesSinks.definitions.MethodSourceSinkDefinition;
2020
import soot.jimple.infoflow.sourcesSinks.definitions.SourceSinkCondition;
@@ -218,7 +218,7 @@ public void additionalFlowsXMLTest() throws IOException {
218218
switch (methodSig) {
219219
case stringWriteSig: {
220220
Assert.assertEquals(1, conds.size());
221-
AdditionalFlowCondition cond = (AdditionalFlowCondition) conds.stream().findAny().get();
221+
SignatureFlowCondition cond = (SignatureFlowCondition) conds.stream().findAny().get();
222222
Set<String> mRefs = cond.getSignaturesOnPath();
223223
Assert.assertEquals(1, mRefs.size());
224224
Assert.assertTrue(mRefs.contains(openConSig));
@@ -229,7 +229,7 @@ public void additionalFlowsXMLTest() throws IOException {
229229
}
230230
case stringOffsetWriteSig: {
231231
Assert.assertEquals(1, conds.size());
232-
AdditionalFlowCondition cond = (AdditionalFlowCondition) conds.stream().findAny().get();
232+
SignatureFlowCondition cond = (SignatureFlowCondition) conds.stream().findAny().get();
233233
Assert.assertEquals(0, cond.getSignaturesOnPath().size());
234234
Set<String> cRefs = cond.getClassNamesOnPath();
235235
Assert.assertEquals(1, cRefs.size());
@@ -240,7 +240,7 @@ public void additionalFlowsXMLTest() throws IOException {
240240
}
241241
case intWriteSig: {
242242
Assert.assertEquals(1, conds.size());
243-
AdditionalFlowCondition cond = (AdditionalFlowCondition) conds.stream().findAny().get();
243+
SignatureFlowCondition cond = (SignatureFlowCondition) conds.stream().findAny().get();
244244
Set<String> mRefs = cond.getSignaturesOnPath();
245245
Assert.assertEquals(2, mRefs.size());
246246
Assert.assertTrue(mRefs.contains(servletSig));
@@ -254,19 +254,19 @@ public void additionalFlowsXMLTest() throws IOException {
254254
Assert.assertEquals(2, conds.size());
255255
boolean foundServlet = false, foundHttpServlet = false;
256256
for (SourceSinkCondition cond : conds) {
257-
Set<String> mRefs = ((AdditionalFlowCondition) cond).getSignaturesOnPath();
257+
Set<String> mRefs = ((SignatureFlowCondition) cond).getSignaturesOnPath();
258258
Assert.assertEquals(1, mRefs.size());
259-
Assert.assertEquals(0, ((AdditionalFlowCondition) cond).getClassNamesOnPath().size());
259+
Assert.assertEquals(0, ((SignatureFlowCondition) cond).getClassNamesOnPath().size());
260260

261261
if (mRefs.contains(servletSig)) {
262262
foundServlet = true;
263-
Assert.assertEquals(2, ((AdditionalFlowCondition) cond).getExcludedClassNames().size());
264-
Assert.assertTrue(((AdditionalFlowCondition) cond).getExcludedClassNames().stream()
263+
Assert.assertEquals(2, ((SignatureFlowCondition) cond).getExcludedClassNames().size());
264+
Assert.assertTrue(((SignatureFlowCondition) cond).getExcludedClassNames().stream()
265265
.allMatch(cn -> cn.equals(byteArrayClass) || cn.equals("java.lang.Object")));
266266
} else if (mRefs.contains(httpSrvSig)) {
267267
foundHttpServlet = true;
268-
Assert.assertEquals(1, ((AdditionalFlowCondition) cond).getExcludedClassNames().size());
269-
Assert.assertTrue(((AdditionalFlowCondition) cond).getExcludedClassNames().stream()
268+
Assert.assertEquals(1, ((SignatureFlowCondition) cond).getExcludedClassNames().size());
269+
Assert.assertTrue(((SignatureFlowCondition) cond).getExcludedClassNames().stream()
270270
.allMatch(cn -> cn.equals(byteArrayClass) || cn.equals("java.lang.String")));
271271
} else {
272272
Assert.fail();

soot-infoflow/src/soot/jimple/infoflow/results/InfoflowResults.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.HashSet;
2020
import java.util.List;
2121
import java.util.Set;
22+
import java.util.stream.Collectors;
2223

2324
import org.slf4j.Logger;
2425
import org.slf4j.LoggerFactory;
@@ -629,6 +630,29 @@ public void removeAll(Collection<ResultSinkInfo> sinks) {
629630
remove(sink);
630631
}
631632

633+
/**
634+
* Gets all sink statements to which there is at least one data flow
635+
*
636+
* @return The set of sink statements to which there is at least one data flow
637+
*/
638+
public Set<Stmt> getAllSinkStmts() {
639+
if (this.results == null)
640+
return Collections.emptySet();
641+
return this.results.keySet().stream().map(s -> s.getStmt()).collect(Collectors.toSet());
642+
}
643+
644+
/**
645+
* Gets all source statements from which there is at least one data flow
646+
*
647+
* @return The set of source statements from which there is at least one data
648+
* flow
649+
*/
650+
public Set<Stmt> getAllSourceStmts() {
651+
if (this.results == null)
652+
return Collections.emptySet();
653+
return this.results.values().stream().map(s -> s.getStmt()).collect(Collectors.toSet());
654+
}
655+
632656
@Override
633657
public String toString() {
634658
if (this.results == null)

0 commit comments

Comments
 (0)