Skip to content

Commit 5174bc4

Browse files
authored
Merge pull request #840 from MarcMil/faster-sysclass
Improvements on Summary APIs
2 parents 21aac0d + f76b07b commit 5174bc4

File tree

4 files changed

+165
-20
lines changed

4 files changed

+165
-20
lines changed

soot-infoflow-summaries/src/soot/jimple/infoflow/methodSummary/data/provider/EagerSummaryProvider.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.Collections;
88
import java.util.Set;
99

10+
import soot.jimple.infoflow.methodSummary.taintWrappers.TaintWrapperFactory;
1011
import soot.jimple.infoflow.methodSummary.xml.SummaryReader;
1112

1213
/**
@@ -15,6 +16,16 @@
1516
*/
1617
public class EagerSummaryProvider extends XMLSummaryProvider {
1718

19+
/**
20+
* Loads a summary from within the StubDroid jar file.
21+
*
22+
* @throws URISyntaxException
23+
* @throws IOException
24+
*/
25+
public EagerSummaryProvider() throws URISyntaxException, IOException {
26+
this(TaintWrapperFactory.DEFAULT_SUMMARY_DIR);
27+
}
28+
1829
/**
1930
* Loads a summary from a folder within the StubDroid jar file.
2031
*

soot-infoflow-summaries/src/soot/jimple/infoflow/methodSummary/data/provider/LazySummaryProvider.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import soot.jimple.infoflow.collect.ConcurrentHashSet;
1616
import soot.jimple.infoflow.methodSummary.data.summary.ClassMethodSummaries;
1717
import soot.jimple.infoflow.methodSummary.data.summary.ClassSummaries;
18+
import soot.jimple.infoflow.methodSummary.taintWrappers.TaintWrapperFactory;
1819

1920
/**
2021
* This class loads method summary xml files on demand.
@@ -27,6 +28,16 @@ public class LazySummaryProvider extends XMLSummaryProvider {
2728
protected Set<Path> pathes = new HashSet<>();
2829
protected Set<String> loadableClasses = new ConcurrentHashSet<>();
2930

31+
/**
32+
* Loads a summary from within the StubDroid jar file.
33+
*
34+
* @throws URISyntaxException
35+
* @throws IOException
36+
*/
37+
public LazySummaryProvider() throws URISyntaxException, IOException {
38+
this(TaintWrapperFactory.DEFAULT_SUMMARY_DIR);
39+
}
40+
3041
/**
3142
* Loads a summary from a folder within the StubDroid jar file.
3243
*

soot-infoflow-summaries/src/soot/jimple/infoflow/methodSummary/taintWrappers/ReportMissingSummaryWrapper.java

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.File;
44
import java.io.IOException;
55
import java.util.Comparator;
6+
import java.util.HashMap;
67
import java.util.Map;
78
import java.util.Map.Entry;
89
import java.util.TreeMap;
@@ -12,6 +13,7 @@
1213
import javax.xml.parsers.DocumentBuilder;
1314
import javax.xml.parsers.DocumentBuilderFactory;
1415
import javax.xml.parsers.ParserConfigurationException;
16+
import javax.xml.transform.OutputKeys;
1517
import javax.xml.transform.Transformer;
1618
import javax.xml.transform.TransformerException;
1719
import javax.xml.transform.TransformerFactory;
@@ -25,17 +27,29 @@
2527
import soot.SootMethod;
2628
import soot.jimple.infoflow.methodSummary.data.provider.IMethodSummaryProvider;
2729

30+
/**
31+
* Reports missing summaries by writing the results to a XML file.
32+
*/
2833
public class ReportMissingSummaryWrapper extends SummaryTaintWrapper {
2934

3035
public ReportMissingSummaryWrapper(IMethodSummaryProvider flows) {
3136
super(flows);
3237
}
3338

34-
ConcurrentHashMap<SootClass, AtomicInteger> classSummariesMissing = new ConcurrentHashMap<>();
39+
private ConcurrentHashMap<SootClass, AtomicInteger> classSummariesMissing = new ConcurrentHashMap<>();
40+
private ConcurrentHashMap<SootMethod, AtomicInteger> methodSummariesMissing = new ConcurrentHashMap<>();
41+
private boolean prettyPrint = false;
42+
private boolean showAppClasses = false;
43+
private boolean countMethods = false;
3544

3645
@Override
3746
protected void reportMissingMethod(SootMethod method) {
38-
count(method.getDeclaringClass(), classSummariesMissing);
47+
SootClass decl = method.getDeclaringClass();
48+
if (!showAppClasses && decl.isApplicationClass())
49+
return;
50+
count(decl, classSummariesMissing);
51+
if (countMethods)
52+
count(method, methodSummariesMissing);
3953
}
4054

4155
private static <T> void count(T item, Map<T, AtomicInteger> map) {
@@ -49,6 +63,58 @@ private static <T> void count(T item, Map<T, AtomicInteger> map) {
4963
ai.incrementAndGet();
5064
}
5165

66+
/**
67+
* Sets the pretty printing flag. When enabled, pretty printing
68+
* creates new lines for each XML node, and uses indentation for the XML tree
69+
* @param prettyPrint whether pretty printing should be enabled
70+
*/
71+
public void setPrettyPrinting(boolean prettyPrint) {
72+
this.prettyPrint = prettyPrint;
73+
}
74+
75+
/**
76+
* Pretty printing creates new lines for each XML node, and uses indentation for the XML tree
77+
* @return returns true if enabled, otherwise false
78+
*/
79+
public boolean isPrettyPrinting() {
80+
return prettyPrint;
81+
}
82+
83+
/**
84+
* When the given parameter is true, the class also reports application classes,
85+
* i.e. classes that are part of the application being analyzed.
86+
* @param showAppClasses whether app classes should be shown
87+
*/
88+
public void setShowApplicationClasses(boolean showAppClasses) {
89+
this.showAppClasses = showAppClasses;
90+
}
91+
92+
/**
93+
* Returns whether this class also reports application classes,
94+
* i.e. classes that are part of the application being analyzed
95+
* @return returns true if enabled, otherwise false
96+
*/
97+
public boolean isShowingApplicationClasses() {
98+
return showAppClasses;
99+
}
100+
101+
/**
102+
* If the given parameter is true, this class will report counts
103+
* on a per class and per method basis.
104+
* @param countMethods whether to count methods
105+
*/
106+
public void setCountMethods(boolean countMethods) {
107+
this.countMethods = countMethods;
108+
}
109+
110+
/**
111+
* Returns whether counting methods is enabled
112+
* @return returns true if enabled, otherwise false
113+
*/
114+
public boolean isCountMethods() {
115+
return countMethods;
116+
}
117+
52118
public void writeResults(File file) throws IOException, ParserConfigurationException, TransformerException {
53119
Map<SootClass, Integer> sortedClassSummariesMissing = sortMap(classSummariesMissing);
54120
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
@@ -65,12 +131,34 @@ public void writeResults(File file) throws IOException, ParserConfigurationExcep
65131
Element clazz = doc.createElement("Class");
66132
clazz.setAttribute("Name", i.getKey().getName());
67133
clazz.setAttribute("Count", String.valueOf(i.getValue()));
134+
if (countMethods) {
135+
SootClass c = i.getKey();
136+
Map<SootMethod, AtomicInteger> methods = new HashMap<>(c.getMethods().size());
137+
for (SootMethod m : c.getMethods()) {
138+
AtomicInteger v = methodSummariesMissing.get(m);
139+
if (v != null) {
140+
methods.put(m, v);
141+
}
142+
}
143+
sortMap(methods);
144+
for (Entry<SootMethod, AtomicInteger> m : methods.entrySet()) {
145+
Element method = doc.createElement("Method");
146+
method.setAttribute("Name", m.getKey().getSubSignature());
147+
method.setAttribute("Count", String.valueOf(m.getValue()));
148+
clazz.appendChild(method);
149+
}
150+
}
68151
classes.appendChild(clazz);
69152
}
70153
rootElement.appendChild(classes);
71154

72155
TransformerFactory transformerFactory = TransformerFactory.newInstance();
73156
Transformer transformer = transformerFactory.newTransformer();
157+
158+
if (prettyPrint) {
159+
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
160+
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
161+
}
74162
DOMSource source = new DOMSource(doc);
75163
StreamResult result = new StreamResult(file);
76164

soot-infoflow-summaries/src/soot/jimple/infoflow/methodSummary/taintWrappers/SummaryTaintWrapper.java

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package soot.jimple.infoflow.methodSummary.taintWrappers;
22

3+
import java.io.IOException;
4+
import java.net.URISyntaxException;
35
import java.util.ArrayList;
46
import java.util.Arrays;
57
import java.util.Collection;
@@ -60,6 +62,7 @@
6062
import soot.jimple.infoflow.data.ContainerContext;
6163
import soot.jimple.infoflow.data.SootMethodAndClass;
6264
import soot.jimple.infoflow.handlers.PreAnalysisHandler;
65+
import soot.jimple.infoflow.methodSummary.data.provider.EagerSummaryProvider;
6366
import soot.jimple.infoflow.methodSummary.data.provider.IMethodSummaryProvider;
6467
import soot.jimple.infoflow.methodSummary.data.sourceSink.AbstractFlowSinkSource;
6568
import soot.jimple.infoflow.methodSummary.data.sourceSink.ConstraintType;
@@ -235,7 +238,8 @@ protected void handleFlowBackFromGap(Unit u, Abstraction d2, Set<AccessPathPropa
235238
for (AccessPathPropagator propagator : propagators) {
236239
// Propagate these taints up. We leave the current gap
237240
AccessPathPropagator parent = safePopParent(propagator);
238-
GapDefinition parentGap = propagator.getParent() == null ? null : propagator.getParent().getGap();
241+
final AccessPathPropagator pparent = propagator.getParent();
242+
GapDefinition parentGap = pparent == null ? null : pparent.getGap();
239243

240244
// Create taints from the abstractions
241245
Set<Taint> returnTaints = createTaintFromAccessPathOnReturn(d2.getAccessPath(), (Stmt) u,
@@ -250,10 +254,16 @@ protected void handleFlowBackFromGap(Unit u, Abstraction d2, Set<AccessPathPropa
250254
// Create the new propagator, one for every taint
251255
Set<AccessPathPropagator> workSet = new HashSet<>();
252256
for (Taint returnTaint : returnTaints) {
253-
AccessPathPropagator newPropagator = new AccessPathPropagator(returnTaint, parentGap, parent,
254-
propagator.getParent() == null ? null : propagator.getParent().getStmt(),
255-
propagator.getParent() == null ? null : propagator.getParent().getD1(),
256-
propagator.getParent() == null ? null : propagator.getParent().getD2());
257+
Stmt stmt = null;
258+
Abstraction d1 = null;
259+
Abstraction nd2 = null;
260+
if (pparent != null) {
261+
stmt = pparent.getStmt();
262+
d1 = pparent.getD1();
263+
nd2 = pparent.getD2();
264+
}
265+
AccessPathPropagator newPropagator = new AccessPathPropagator(returnTaint, parentGap, parent, stmt,
266+
d1, nd2);
257267
workSet.add(newPropagator);
258268
}
259269

@@ -335,9 +345,10 @@ private AccessPathPropagator getOriginalCallSite(AccessPathPropagator propagator
335345
// Get the original call site
336346
AccessPathPropagator curProp = propagator;
337347
while (curProp != null) {
338-
if (curProp.getParent() == null)
348+
final AccessPathPropagator parent = curProp.getParent();
349+
if (parent == null)
339350
return curProp;
340-
curProp = curProp.getParent();
351+
curProp = parent;
341352
}
342353
return null;
343354
}
@@ -354,6 +365,14 @@ public SummaryTaintWrapper(IMethodSummaryProvider flows) {
354365
setContainerStrategyFactory(new DefaultConfigContainerStrategyFactory());
355366
}
356367

368+
/**
369+
* Creates a new instance of the {@link SummaryTaintWrapper} class.
370+
* Uses summaries present within the StubDroid JAR file.
371+
*/
372+
public SummaryTaintWrapper() throws URISyntaxException, IOException {
373+
this(new EagerSummaryProvider());
374+
}
375+
357376
/**
358377
* Sets the container strategy factory.
359378
*
@@ -1105,7 +1124,8 @@ protected Set<AccessPathPropagator> spawnAnalysisIntoClientCode(SootMethod imple
11051124

11061125
// We need to pop the last gap element off the stack
11071126
AccessPathPropagator parent = safePopParent(propagator);
1108-
GapDefinition gap = propagator.getParent() == null ? null : propagator.getParent().getGap();
1127+
AccessPathPropagator pparent = propagator.getParent();
1128+
GapDefinition gap = pparent == null ? null : pparent.getGap();
11091129

11101130
// We might already have a summary for the callee
11111131
Set<AccessPathPropagator> outgoingTaints = null;
@@ -1122,10 +1142,16 @@ protected Set<AccessPathPropagator> spawnAnalysisIntoClientCode(SootMethod imple
11221142
propagator.getGap());
11231143
if (newTaints != null) {
11241144
for (Taint newTaint : newTaints) {
1125-
AccessPathPropagator newPropagator = new AccessPathPropagator(newTaint, gap, parent,
1126-
propagator.getParent() == null ? null : propagator.getParent().getStmt(),
1127-
propagator.getParent() == null ? null : propagator.getParent().getD1(),
1128-
propagator.getParent() == null ? null : propagator.getParent().getD2());
1145+
Stmt nstmt = null;
1146+
Abstraction d1 = null;
1147+
Abstraction d2 = null;
1148+
if (pparent != null) {
1149+
nstmt = pparent.getStmt();
1150+
d1 = pparent.getD1();
1151+
d2 = pparent.getD2();
1152+
}
1153+
AccessPathPropagator newPropagator = new AccessPathPropagator(newTaint, gap, parent, nstmt,
1154+
d1, d2);
11291155
outgoingTaints.add(newPropagator);
11301156
}
11311157
}
@@ -1147,9 +1173,10 @@ protected Set<AccessPathPropagator> spawnAnalysisIntoClientCode(SootMethod imple
11471173
}
11481174

11491175
protected AccessPathPropagator safePopParent(AccessPathPropagator curPropagator) {
1150-
if (curPropagator.getParent() == null)
1176+
AccessPathPropagator parent = curPropagator.getParent();
1177+
if (parent == null)
11511178
return null;
1152-
return curPropagator.getParent().getParent();
1179+
return parent.getParent();
11531180
}
11541181

11551182
/**
@@ -1382,10 +1409,18 @@ protected AccessPathPropagator applyFlow(MethodFlow flow, AccessPathPropagator p
13821409
taintGap = null;
13831410
} else {
13841411
parent = safePopParent(propagator);
1385-
gap = propagator.getParent() == null ? null : propagator.getParent().getGap();
1386-
stmt = propagator.getParent() == null ? propagator.getStmt() : propagator.getParent().getStmt();
1387-
d1 = propagator.getParent() == null ? propagator.getD1() : propagator.getParent().getD1();
1388-
d2 = propagator.getParent() == null ? propagator.getD2() : propagator.getParent().getD2();
1412+
AccessPathPropagator pparent = propagator.getParent();
1413+
if (pparent == null) {
1414+
gap = null;
1415+
stmt = propagator.getStmt();
1416+
d1 = propagator.getD1();
1417+
d2 = propagator.getD2();
1418+
} else {
1419+
gap = pparent.getGap();
1420+
stmt = pparent.getStmt();
1421+
d1 = pparent.getD1();
1422+
d2 = pparent.getD2();
1423+
}
13891424
taintGap = propagator.getGap();
13901425
}
13911426

0 commit comments

Comments
 (0)