Skip to content

Commit

Permalink
featureResources
Browse files Browse the repository at this point in the history
  • Loading branch information
kadirayk committed Jun 7, 2023
1 parent e149cd8 commit 5025dfb
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ target/
/SootFXPy/venv/
assets
eval
input
output
8 changes: 6 additions & 2 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
methodFeatureInclusion:
- MethodAssignStmtCount
#methodFeatureInclusion:
# - MethodAssignStmtCount
wholeProgFeatureInclusion:
- WholeProgramAPICallCount
featureResources:
- {featureName: "WholeProgramAPICallCount", resourcePath: "./input/methods.txt"}
#methodFeatureExclusion:
# - MethodBranchCountK
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
<dependency>
<groupId>org.soot-oss</groupId>
<artifactId>soot</artifactId>
<version>4.2.1</version>
<version>4.4.1</version>
</dependency>
<dependency>
<groupId>net.sf.py4j</groupId>
Expand Down
22 changes: 18 additions & 4 deletions src/main/java/api/CLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,18 @@ public static void main(String[] args) throws IOException {
// extract all features
methodFeatures(classPath, outPath, null, null);
classFeatures(classPath, outPath, null, null);
wpFeatures(classPath, outPath, null, null);
wpFeatures(classPath, outPath, androidJars,null, null, null);

if(!StringUtils.isEmpty(androidJars) && classPath.endsWith(".apk")){
manifestFeatures(classPath, outPath, androidJars, null, null);
}

}else if(!StringUtils.isEmpty(configPath)){
Config config = getConfig(configPath);
List<FeatureResource> featureResources = config.getFeatureResources();
methodFeatures(classPath, outPath, config.getMethodFeatureInclusion(), config.getMethodFeatureExclusion());
classFeatures(classPath, outPath, config.getClassFeatureInclusion(), config.getClassFeatureExclusion());
wpFeatures(classPath, outPath, config.getWholeProgFeatureInclusion(), config.getWholeProgFeatureExclusion());
wpFeatures(classPath, outPath, androidJars, config.getWholeProgFeatureInclusion(), config.getWholeProgFeatureExclusion(), featureResources);
if(!StringUtils.isEmpty(androidJars) && classPath.endsWith(".apk")) {
manifestFeatures(classPath, outPath, androidJars, config.getManifestFeatureInclusion(), config.getManifestFeatureExclusion());
}
Expand All @@ -65,6 +66,9 @@ public static void main(String[] args) throws IOException {


public static void methodFeatures(String path, String out, List<String> include, List<String> exclude) throws IOException {
if(include == null){
return;
}
SootFX sootFX = new SootFX();
sootFX.addClassPath(path);
sootFX.appOnly();
Expand All @@ -82,6 +86,9 @@ public static void methodFeatures(String path, String out, List<String> include,
}

public static void classFeatures(String path, String out, List<String> include, List<String> exclude) throws IOException {
if(include == null){
return;
}
SootFX sootFX = new SootFX();
sootFX.addClassPath(path);
sootFX.appOnly();
Expand All @@ -98,24 +105,31 @@ public static void classFeatures(String path, String out, List<String> include,
sootFX.printMultiSetToCSV(featureSets, out + "class.csv");
}

public static void wpFeatures(String path, String out, List<String> include, List<String> exclude) throws IOException {
public static void wpFeatures(String path, String out, String androidJars, List<String> include, List<String> exclude, List<FeatureResource> featureResources) throws IOException {
if(include == null){
return;
}
SootFX sootFX = new SootFX();
sootFX.addClassPath(path);
sootFX.androidJars(androidJars);
sootFX.appOnly();
WholeProgramFeatureSet featureSet = null;
if((include==null || include.isEmpty()) && (exclude==null || exclude.isEmpty())){
featureSet = sootFX.extractAllWholeProgramFeatures();
} else if(include==null || include.isEmpty()){
featureSet = sootFX.extractWholeProgramFeaturesExclude(new HashSet<>(exclude));
} else if(exclude==null || exclude.isEmpty()){
featureSet = sootFX.extractWholeProgramFeaturesInclude(include);
featureSet = sootFX.extractWholeProgramFeaturesInclude(include, featureResources);
}else if(!include.isEmpty() && !exclude.isEmpty()){
throw new RuntimeException("You must either provide wholeProgFeatureInclusion or wholeProgFeatureExclusion in config.yaml. \n Inclusion list only extracts the selected features. Exclusion list extracts all but the selected features.");
}
sootFX.printSingleSetToCSV(featureSet, out + "wp.csv");
}

public static void manifestFeatures(String path, String out, String androidJars, List<String> include, List<String> exclude) throws IOException {
if(include == null){
return;
}
SootFX sootFX = new SootFX();
sootFX.addClassPath(path);
sootFX.appOnly();
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/api/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public class Config {
private List<String> manifestFeatureInclusion;
private List<String> manifestFeatureExclusion;

private List<FeatureResource> featureResources;


public List<String> getMethodFeatureInclusion() {
return methodFeatureInclusion;
Expand Down Expand Up @@ -79,4 +81,12 @@ public List<String> getManifestFeatureExclusion() {
public void setManifestFeatureExclusion(List<String> manifestFeatureExclusion) {
this.manifestFeatureExclusion = manifestFeatureExclusion;
}

public List<FeatureResource> getFeatureResources() {
return featureResources;
}

public void setFeatureResources(List<FeatureResource> featureResources) {
this.featureResources = featureResources;
}
}
23 changes: 23 additions & 0 deletions src/main/java/api/FeatureResource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package api;

public class FeatureResource {

private String featureName;
private String resourcePath;

public String getFeatureName() {
return featureName;
}

public void setFeatureName(String featureName) {
this.featureName = featureName;
}

public String getResourcePath() {
return resourcePath;
}

public void setResourcePath(String resourcePath) {
this.resourcePath = resourcePath;
}
}
4 changes: 2 additions & 2 deletions src/main/java/api/SootFX.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ public WholeProgramFeatureSet extractWholeProgramFeaturesExclude(Set<String> exc
return new WholeProgramFX().getAllFeaturesExclude(exclusion);
}

public WholeProgramFeatureSet extractWholeProgramFeaturesInclude(List<String> featureExtractors) {
public WholeProgramFeatureSet extractWholeProgramFeaturesInclude(List<String> featureExtractors, List<FeatureResource> featureResources) {
validate();
SootConnector.setupSoot(mainClass, classPaths, appOnly, androidJars);
return new WholeProgramFX().getFeatures(featureExtractors);
return new WholeProgramFX().getFeatures(featureExtractors, featureResources);
}

public ManifestFeatureSet extractManifestFeaturesInclude(Set<ManifestFEU> featureExtractors) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package core.fx.wholeprogrambased;

import com.google.common.collect.Streams;
import core.fx.base.Feature;
import core.fx.base.WholeProgramFEU;
import resource.FileConnector;
import soot.SootMethod;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.jimple.toolkits.callgraph.Edge;

import java.util.*;
import java.util.stream.Stream;

public class WholeProgramAPICallCount implements WholeProgramFEU<Map<String, Long>> {

private List<String> methodSignatures;

public WholeProgramAPICallCount(String resourcePath) {
this.methodSignatures = FileConnector.getMethodSignatures(resourcePath);
}

@Override
public Feature<Map<String, Long>> extract(CallGraph target) {
Iterator<Edge> iterator = target.iterator();
Map<String, Long> methodCount = new HashMap<>();
Stream<Edge> stream = Streams.stream(iterator);
stream.forEach(e-> {
if(methodSignatures.contains(e.tgt().getSignature())){
if(methodCount.containsKey(e.tgt().getSignature())){
Long count = methodCount.get(e.tgt().getSignature());
methodCount.put(e.tgt().getSignature(), ++count);
}else{
methodCount.put(e.tgt().getSignature(), 1L);
}
}
System.out.println(e.tgt());
});
return new Feature<>(this.getClass().getSimpleName(), methodCount);
}
}
6 changes: 6 additions & 0 deletions src/main/java/manager/ManifestFX.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package manager;

import api.FeatureDescription;
import api.FeatureResource;
import core.fx.FxUtil;
import resource.ManifestConnector;
import core.fx.base.ManifestFEU;
Expand Down Expand Up @@ -73,4 +74,9 @@ public ManifestFeatureSet getFeatures(List<String> featureExtractors) {
}
return getFeatures(fxSet);
}

@Override
public ManifestFeatureSet getFeatures(List<String> featureExtractors, List<FeatureResource> featureResources) {
return null;
}
}
3 changes: 3 additions & 0 deletions src/main/java/manager/SingleInstanceFX.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package manager;

import api.FeatureResource;
import core.fx.base.FeatureExtractionUnit;
import core.rm.AbstractFeatureSet;

Expand All @@ -16,4 +17,6 @@ public interface SingleInstanceFX<S extends AbstractFeatureSet, E extends Featur

S getFeatures(List<String> featureExtractors);

S getFeatures(List<String> featureExtractors, List<FeatureResource> featureResources);

}
38 changes: 37 additions & 1 deletion src/main/java/manager/WholeProgramFX.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package manager;

import api.FeatureDescription;
import api.FeatureResource;
import core.fx.FxUtil;
import core.fx.base.WholeProgramFEU;
import core.rm.WholeProgramFeatureSet;
Expand All @@ -9,6 +10,7 @@

import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -49,7 +51,7 @@ public WholeProgramFeatureSet getFeatures(List<String> featureExtractors) {
cls = Class.forName("core.fx.wholeprogrambased." + str);
newInstance = (WholeProgramFEU) cls.newInstance();
} catch (InstantiationException e) {
// System.out.println("ignoring feature that takes an input value:" + str);
// System.out.println("ignoring feature that takes an input value:" + str);
} catch (Exception e) {
System.err.println("feature not found:" + str);
}
Expand All @@ -59,4 +61,38 @@ public WholeProgramFeatureSet getFeatures(List<String> featureExtractors) {
}
return getFeatures(fxSet);
}

@Override
public WholeProgramFeatureSet getFeatures(List<String> featureExtractors, List<FeatureResource> featureResources) {
Set<WholeProgramFEU> fxSet = new HashSet<>();
for (String str : featureExtractors) {
Class<?> cls = null;
WholeProgramFEU newInstance = null;
try {
cls = Class.forName("core.fx.wholeprogrambased." + str);
Optional<FeatureResource> fr = getResourcePath(featureResources, str);
if(fr.isPresent()){
String resourcePath = fr.get().getResourcePath();
newInstance = (WholeProgramFEU) cls.getConstructor(String.class).newInstance(resourcePath);
}else{
newInstance = (WholeProgramFEU) cls.newInstance();
}
} catch (InstantiationException e) {
// System.out.println("ignoring feature that takes an input value:" + str);
} catch (Exception e) {
System.err.println("feature not found:" + str);
}
if (newInstance != null) {
fxSet.add(newInstance);
}
}
return getFeatures(fxSet);
}

private Optional<FeatureResource> getResourcePath(List<FeatureResource> featureResources, String featureName) {
Optional<FeatureResource> first = featureResources.stream().filter(featureResource ->
featureResource.getFeatureName().equals(featureName)).findFirst();
return first;
}

}
22 changes: 22 additions & 0 deletions src/main/java/resource/FileConnector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package resource;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FileConnector {

public static List<String> getMethodSignatures(String path){
List<String> result = null;
try (Stream<String> lines = Files.lines(Paths.get(path))) {
result = lines.collect(Collectors.toList());
}catch (IOException e){
e.printStackTrace();
}
return result;
}

}

0 comments on commit 5025dfb

Please sign in to comment.