Skip to content

Commit 28afc3e

Browse files
committed
Call Graph is now generated && PFP is done using existent ASTs
1 parent 280a219 commit 28afc3e

File tree

14 files changed

+552
-574
lines changed

14 files changed

+552
-574
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>edu.uniandes.thesoftwaredesignlab</groupId>
66
<artifactId>MutAPK</artifactId>
7-
<version>1.0.0</version>
7+
<version>2.0.0</version>
88
<name>MutAPK</name>
99
<description>Android Application Mutation Testion over APK files</description>
1010
<build>

src/main/java/edu/uniandes/tsdl/mutapk/MutAPK.java

Lines changed: 123 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010
import java.io.UnsupportedEncodingException;
1111
import java.nio.file.Paths;
1212
import java.util.HashMap;
13+
import java.util.Iterator;
1314
import java.util.List;
15+
import java.util.Map.Entry;
1416
import java.util.Set;
1517

1618
import javax.xml.parsers.ParserConfigurationException;
1719

20+
import org.antlr.runtime.RecognitionException;
21+
import org.antlr.runtime.tree.CommonTree;
1822
import org.json.simple.JSONObject;
1923
import org.json.simple.parser.JSONParser;
2024
import org.json.simple.parser.ParseException;
@@ -26,8 +30,12 @@
2630
import edu.uniandes.tsdl.mutapk.hashfunction.sha3.ApkHashOrder;
2731
import edu.uniandes.tsdl.mutapk.hashfunction.sha3.ApkHashSeparator;
2832
import edu.uniandes.tsdl.mutapk.helper.APKToolWrapper;
33+
import edu.uniandes.tsdl.mutapk.helper.ASTHelper;
34+
import edu.uniandes.tsdl.mutapk.helper.CallGraphHelper;
2935
import edu.uniandes.tsdl.mutapk.helper.Helper;
36+
import edu.uniandes.tsdl.mutapk.model.CallGraphNode;
3037
import edu.uniandes.tsdl.mutapk.model.MutationType;
38+
import edu.uniandes.tsdl.mutapk.model.SmaliAST;
3139
import edu.uniandes.tsdl.mutapk.model.location.MutationLocation;
3240
import edu.uniandes.tsdl.mutapk.operators.OperatorBundle;
3341
import edu.uniandes.tsdl.mutapk.processors.MutationsProcessor;
@@ -65,6 +73,8 @@ public class MutAPK {
6573

6674
static OperatorBundle operatorBundle;
6775

76+
static HashMap<String, SmaliAST> smaliASTs = new HashMap<String, SmaliAST>();
77+
6878
public static void main(String[] args) {
6979
try {
7080
// long initialTime = System.currentTimeMillis();
@@ -83,7 +93,7 @@ public static void main(String[] args) {
8393
}
8494
}
8595

86-
public static void runMutAPK(String[] args) throws NumberFormatException, FileNotFoundException, IOException, ParseException, MutAPKException, InterruptedException, ParserConfigurationException, SAXException {
96+
public static void runMutAPK(String[] args) throws NumberFormatException, FileNotFoundException, IOException, ParseException, MutAPKException, InterruptedException, ParserConfigurationException, SAXException, RecognitionException {
8797

8898
// Read JSON config file
8999
readConfig(args[0]);
@@ -109,77 +119,121 @@ public static void runMutAPK(String[] args) throws NumberFormatException, FileNo
109119
// Run detection phase for Text-based detectors
110120
HashMap<MutationType, List<MutationLocation>> locations = TextBasedDetectionsProcessor.process("temp", textBasedDetectors);
111121

122+
//--------------------------------------------
112123
// Run detection phase for AST-based detectors
113-
SourceCodeProcessor scp = new SourceCodeProcessor(operatorBundle);
114-
locations.putAll(scp.processFolder("temp", extraPath, appName));
115-
116-
// Report the statistics of the found Potential Fault Locations
117-
Set<MutationType> keys = locations.keySet();
118-
List<MutationLocation> list = null;
119-
int totalMutants = 0;
120-
System.out.println("## Amount of Potential Fault Locations per Mutation Operator\n");
121-
System.out.println("Amount Mutants | Mutation Operator");
122-
System.out.println("----------------|---------------------");
123-
for (MutationType mutationType : keys) {
124-
list = locations.get(mutationType);
125-
totalMutants += list.size();
126-
System.out.println(list.size() + " | " + mutationType);
127-
}
128-
129-
// Check if the amount of PFLocations is lower than the requested by the user
130-
if(totalMutants < amountMutants) {
131-
throw new MutAPKException("The total of mutants need to be greater than the amount of mutants asked");
132-
}
133-
System.out.println("");
134-
135-
// Build MutationLocation List
136-
List<MutationLocation> mutationLocationList = MutationLocationListBuilder.buildList(locations);
137-
printLocationList(mutationLocationList, mutantsFolder, appName);
138-
System.out.println("\nTotal Locations: " + mutationLocationList.size());
139-
System.out.println();
140-
System.out.println("--------------------------------------");
124+
//--------------------------------------------
125+
126+
// Generate HashMap with all the ASTs
127+
SourceCodeProcessor scp = new SourceCodeProcessor();
128+
scp.generateASTsMap(extraPath, appName, smaliASTs);
129+
130+
// Generate the Call Graph
131+
132+
HashMap<String, HashMap<String, CallGraphNode>> callGraph = CallGraphHelper.getCallGraph(smaliASTs);
133+
134+
// for(Entry<String, HashMap<String, CallGraphNode>> entry : callGraph.entrySet()) {
135+
// System.out.println(entry.getKey());
136+
// for(Entry<String, CallGraphNode> entryy : entry.getValue().entrySet()) {
137+
// CallGraphNode temp = entryy.getValue();
138+
// System.out.println(" "+entryy.getKey()+" "+temp.getCallees().size()+" "+temp.getCallers().size());
139+
// }
140+
// }
141+
142+
// Prune ASTs
143+
144+
145+
// // Generate PFP over pruned ASTs
146+
// for(Entry<String, SmaliAST> entry : smaliASTs.entrySet()) {
147+
// SmaliAST temp = entry.getValue();
148+
//
149+
// HashMap<MutationType, List<MutationLocation>> fileLocations = ASTHelper.findLocations(temp, operatorBundle);
150+
// appendLocations(fileLocations, locations);
151+
// }
152+
//
153+
// // Report the statistics of the found Potential Fault Locations
154+
// Set<MutationType> keys = locations.keySet();
155+
// List<MutationLocation> list = null;
156+
// int totalMutants = 0;
157+
// System.out.println("## Amount of Potential Fault Locations per Mutation Operator\n");
158+
// System.out.println("Amount Mutants | Mutation Operator");
159+
// System.out.println("----------------|---------------------");
160+
// for (MutationType mutationType : keys) {
161+
// list = locations.get(mutationType);
162+
// totalMutants += list.size();
163+
// System.out.println(list.size() + " | " + mutationType);
164+
// }
165+
//
166+
// // Check if the amount of PFLocations is lower than the requested by the user
167+
// if(totalMutants < amountMutants) {
168+
// throw new MutAPKException("The total of mutants need to be greater than the amount of mutants asked");
169+
// }
170+
// System.out.println("");
171+
//
172+
// // Build MutationLocation List
173+
// List<MutationLocation> mutationLocationList = MutationLocationListBuilder.buildList(locations);
174+
// printLocationList(mutationLocationList, mutantsFolder, appName);
175+
// System.out.println("\nTotal Locations: " + mutationLocationList.size());
176+
// System.out.println();
177+
// System.out.println("--------------------------------------");
178+
//
179+
// // Select Selector
180+
// switch (selectionStrategy) {
181+
// case AMOUNT_MUTANTS_SS:
182+
// SelectorAmountMutantsMethod selectorAmountMutantsMethod = new SelectorAmountMutantsMethod();
183+
// SelectorAmountMutants selectorAmountMutants = new SelectorAmountMutants(false, false, totalMutants,
184+
// amountMutants);
185+
// mutationLocationList = selectorAmountMutantsMethod.mutantSelector(locations, selectorAmountMutants);
186+
// break;
187+
// case REPRESENTATIVE_SUBSET_SS:
188+
// SelectorConfidenceInterval selectorConfidenceInterval = new SelectorConfidenceInterval(true, false,
189+
// totalMutants, isRSPerOPerator, confidenceLevel, marginError);
190+
// SelectorConfidenceIntervalMethod CIMS = new SelectorConfidenceIntervalMethod();
191+
// mutationLocationList = CIMS.mutantSelector(locations, selectorConfidenceInterval);
192+
// break;
193+
// default:
194+
// break;
195+
// }
196+
// System.out.println("");
197+
//
198+
// System.out.println("## Mutation Process Log");
199+
// System.out.println();
200+
// System.out.println("```sh");
201+
//
202+
// // Execute mutation phase
203+
// MutationsProcessor mProcessor = new MutationsProcessor("temp", appName, mutantsFolder);
204+
//
205+
// // Create de apkhash for the base folder
206+
// File manifest = new File(apkAbsolutePath + File.separator + "AndroidManifest.xml");
207+
// File smali = new File(apkAbsolutePath + File.separator + "smali");
208+
// File resource = new File(apkAbsolutePath + File.separator + "res");
209+
//
210+
//
211+
// // Create ApkHashSeparator
212+
// ApkHashSeparator apkHashSeparator = mProcessor.generateApkHashSeparator(manifest, smali, resource, 0);
213+
// // Add the base apkHashSeparator
214+
// ApkHashOrder.getInstance().setApkHashSeparator(apkHashSeparator);
215+
//
216+
// if (multithread) {
217+
// mProcessor.processMultithreaded(mutationLocationList, extraPath, apkName);
218+
// } else {
219+
// mProcessor.process(mutationLocationList, extraPath, apkName);
220+
// }
141221

142-
// Select Selector
143-
switch (selectionStrategy) {
144-
case AMOUNT_MUTANTS_SS:
145-
SelectorAmountMutantsMethod selectorAmountMutantsMethod = new SelectorAmountMutantsMethod();
146-
SelectorAmountMutants selectorAmountMutants = new SelectorAmountMutants(false, false, totalMutants,
147-
amountMutants);
148-
mutationLocationList = selectorAmountMutantsMethod.mutantSelector(locations, selectorAmountMutants);
149-
break;
150-
case REPRESENTATIVE_SUBSET_SS:
151-
SelectorConfidenceInterval selectorConfidenceInterval = new SelectorConfidenceInterval(true, false,
152-
totalMutants, isRSPerOPerator, confidenceLevel, marginError);
153-
SelectorConfidenceIntervalMethod CIMS = new SelectorConfidenceIntervalMethod();
154-
mutationLocationList = CIMS.mutantSelector(locations, selectorConfidenceInterval);
155-
break;
156-
default:
157-
break;
158-
}
159-
System.out.println("");
160-
161-
System.out.println("## Mutation Process Log");
162-
System.out.println();
163-
System.out.println("```sh");
164-
165-
// Execute mutation phase
166-
MutationsProcessor mProcessor = new MutationsProcessor("temp", appName, mutantsFolder);
222+
}
167223

168-
// Create de apkhash for the base folder
169-
File manifest = new File(apkAbsolutePath + File.separator + "AndroidManifest.xml");
170-
File smali = new File(apkAbsolutePath + File.separator + "smali");
171-
File resource = new File(apkAbsolutePath + File.separator + "res");
224+
private static void appendLocations(HashMap<MutationType, List<MutationLocation>> source, HashMap<MutationType, List<MutationLocation>> target){
172225

226+
for(Entry<MutationType, List<MutationLocation>> entry : source.entrySet()){
227+
List<MutationLocation> sourceLocations = source.get(entry.getKey());
228+
List<MutationLocation> targetLocations = target.get(entry.getKey());
173229

174-
// Create ApkHashSeparator
175-
ApkHashSeparator apkHashSeparator = mProcessor.generateApkHashSeparator(manifest, smali, resource, 0);
176-
// Add the base apkHashSeparator
177-
ApkHashOrder.getInstance().setApkHashSeparator(apkHashSeparator);
230+
if(targetLocations != null){
231+
targetLocations.addAll(sourceLocations);
232+
} else {
233+
targetLocations = sourceLocations;
234+
}
178235

179-
if (multithread) {
180-
mProcessor.processMultithreaded(mutationLocationList, extraPath, apkName);
181-
} else {
182-
mProcessor.process(mutationLocationList, extraPath, apkName);
236+
target.put(entry.getKey(), targetLocations);
183237
}
184238

185239
}
@@ -246,15 +300,14 @@ private static void readConfig(String configFilePath) throws NumberFormatExcepti
246300
}
247301

248302
private static void checkAndPrepareParameters() throws MutAPKException, IOException {
249-
// TODO Auto-generated method stub
250303

251304
// Preprocess paths to fit to OS filsesystem format
252305
String os = System.getProperty("os.name").toLowerCase();
253306
if (os.indexOf("win") >= 0) {
254307
mutantsFolder = mutantsFolder.replaceFirst("/", File.separator+File.separator) +File.separator;
255308
apkPath = apkPath.replaceAll("/", File.separator+File.separator);
256309
apkName = apkPath.substring(apkPath.lastIndexOf("\\"));
257-
310+
258311
extraPath = extraPath.equals("")?"":extraPath.replaceAll("/", File.separator+File.separator) + File.separator;
259312
operatorsDir = operatorsDir.equals("")?"":operatorsDir.replaceAll("/", File.separator+File.separator) + File.separator;
260313
} else {
@@ -281,7 +334,7 @@ private static void checkAndPrepareParameters() throws MutAPKException, IOExcept
281334
}
282335
System.out.println(operFolderFO.getCanonicalPath().toString());
283336
File[] properties = operFolderFO.listFiles(new FilenameFilter() {
284-
337+
285338
@Override
286339
public boolean accept(File dir, String name) {
287340
return name.endsWith("operators.properties");
@@ -296,7 +349,7 @@ public boolean accept(File dir, String name) {
296349
throw new MutAPKException("Path to extra folder is not correct. The path does not exist.");
297350
}
298351
File[] extraFO = extraFolderFO.listFiles(new FilenameFilter() {
299-
352+
300353
@Override
301354
public boolean accept(File dir, String name) {
302355
return ( name.endsWith("apktool.jar") || name.endsWith("uber-apk-signer.jar") || name.endsWith("materialistic.jks"));

src/main/java/edu/uniandes/tsdl/mutapk/detectors/code/visitors/APICallVO.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ public class APICallVO {
66

77
private CommonTree tree;
88
private int line;
9-
private String filePath;
109
private int[] muTypes;
1110

12-
public APICallVO(CommonTree tree, int line, String filePath, int[] muTypes) {
11+
public APICallVO(CommonTree tree, int line, int[] muTypes) {
1312
super();
1413
this.tree = tree;
1514
this.line = line;
16-
this.filePath = filePath;
1715
this.muTypes = muTypes;
1816
}
1917

@@ -29,12 +27,6 @@ public int getLine() {
2927
public void setLine(int line) {
3028
this.line = line;
3129
}
32-
public String getFilePath() {
33-
return filePath;
34-
}
35-
public void setFilePath(String filePath) {
36-
this.filePath = filePath;
37-
}
3830

3931
public int[] getMuTypes() {
4032
return muTypes;

src/main/java/edu/uniandes/tsdl/mutapk/detectors/code/visitors/TreeVisitorInstance.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@
1111
public class TreeVisitorInstance extends TreeVisitor{
1212

1313
private HashSet<APICallVO> calls;
14-
String filePath;
1514

16-
public TreeVisitorInstance(String filePath) {
15+
public TreeVisitorInstance() {
1716
calls = new HashSet<APICallVO>();
18-
this.filePath = filePath;
1917
}
2018

2119
@Override
@@ -26,7 +24,7 @@ public Object visit(Object tt, TreeVisitorAction action) {
2624
// System.out.println(t.toStringTree());
2725
// System.out.println(t.getChildIndex());
2826
// System.out.println(t.getParent().getChild(t.getChildIndex()).toStringTree());
29-
calls.add(new APICallVO(t, t.getLine(), filePath, muTypes));
27+
calls.add(new APICallVO(t, t.getLine(), muTypes));
3028
}
3129
return super.visit(t, action);
3230
}

src/main/java/edu/uniandes/tsdl/mutapk/helper/APKToolWrapper.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ public static String openAPK(String path, String extraPath) throws IOException,
1414
// Creates folder for decoded app
1515
// System.out.println(decodedPath);
1616
File tempFolder = new File(decodedPath+File.separator+"temp");
17-
if(tempFolder.exists()) {
18-
tempFolder.delete();
19-
}
20-
tempFolder.mkdirs();
21-
Process ps = Runtime.getRuntime().exec(new String[]{"java","-jar",Paths.get(decodedPath,extraPath,"apktool.jar").toAbsolutePath().toString(),"d",Paths.get(decodedPath,path).toAbsolutePath().toString(),"-o",Paths.get(decodedPath,"temp").toAbsolutePath().toString(),"-f"});
17+
// if(tempFolder.exists()) {
18+
// tempFolder.delete();
19+
// }
20+
// tempFolder.mkdirs();
2221
System.out.println("> Processing your APK... ");
23-
ps.waitFor();
22+
// Process ps = Runtime.getRuntime().exec(new String[]{"java","-jar",Paths.get(decodedPath,extraPath,"apktool.jar").toAbsolutePath().toString(),"d",Paths.get(decodedPath,path).toAbsolutePath().toString(),"-o",Paths.get(decodedPath,"temp").toAbsolutePath().toString(),"-f"});
23+
// ps.waitFor();
2424
System.out.println("> Wow... that was an amazing APK to proccess!!! :D");
2525
System.out.println("");
2626
return tempFolder.getAbsolutePath();

0 commit comments

Comments
 (0)