From 5025dfb21903177e55a3fd7949ee0ac2446e20bd Mon Sep 17 00:00:00 2001 From: Kadiray Karakaya Date: Wed, 7 Jun 2023 15:41:53 +0200 Subject: [PATCH] featureResources --- .gitignore | 2 + config.yaml | 8 +++- pom.xml | 2 +- src/main/java/api/CLI.java | 22 ++++++++-- src/main/java/api/Config.java | 10 +++++ src/main/java/api/FeatureResource.java | 23 +++++++++++ src/main/java/api/SootFX.java | 4 +- .../WholeProgramAPICallCount.java | 40 +++++++++++++++++++ src/main/java/manager/ManifestFX.java | 6 +++ src/main/java/manager/SingleInstanceFX.java | 3 ++ src/main/java/manager/WholeProgramFX.java | 38 +++++++++++++++++- src/main/java/resource/FileConnector.java | 22 ++++++++++ 12 files changed, 170 insertions(+), 10 deletions(-) create mode 100644 src/main/java/api/FeatureResource.java create mode 100644 src/main/java/core/fx/wholeprogrambased/WholeProgramAPICallCount.java create mode 100644 src/main/java/resource/FileConnector.java diff --git a/.gitignore b/.gitignore index c2c1a8c..7661642 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ target/ /SootFXPy/venv/ assets eval +input +output diff --git a/config.yaml b/config.yaml index 7605682..6c3319c 100644 --- a/config.yaml +++ b/config.yaml @@ -1,4 +1,8 @@ -methodFeatureInclusion: - - MethodAssignStmtCount +#methodFeatureInclusion: +# - MethodAssignStmtCount +wholeProgFeatureInclusion: + - WholeProgramAPICallCount +featureResources: + - {featureName: "WholeProgramAPICallCount", resourcePath: "./input/methods.txt"} #methodFeatureExclusion: # - MethodBranchCountK \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0a0f0d5..993bfe2 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ org.soot-oss soot - 4.2.1 + 4.4.1 net.sf.py4j diff --git a/src/main/java/api/CLI.java b/src/main/java/api/CLI.java index 20e1d09..1cf63ee 100644 --- a/src/main/java/api/CLI.java +++ b/src/main/java/api/CLI.java @@ -46,7 +46,7 @@ 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); @@ -54,9 +54,10 @@ public static void main(String[] args) throws IOException { }else if(!StringUtils.isEmpty(configPath)){ Config config = getConfig(configPath); + List 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()); } @@ -65,6 +66,9 @@ public static void main(String[] args) throws IOException { public static void methodFeatures(String path, String out, List include, List exclude) throws IOException { + if(include == null){ + return; + } SootFX sootFX = new SootFX(); sootFX.addClassPath(path); sootFX.appOnly(); @@ -82,6 +86,9 @@ public static void methodFeatures(String path, String out, List include, } public static void classFeatures(String path, String out, List include, List exclude) throws IOException { + if(include == null){ + return; + } SootFX sootFX = new SootFX(); sootFX.addClassPath(path); sootFX.appOnly(); @@ -98,9 +105,13 @@ public static void classFeatures(String path, String out, List include, sootFX.printMultiSetToCSV(featureSets, out + "class.csv"); } - public static void wpFeatures(String path, String out, List include, List exclude) throws IOException { + public static void wpFeatures(String path, String out, String androidJars, List include, List exclude, List 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())){ @@ -108,7 +119,7 @@ public static void wpFeatures(String path, String out, List include, Lis } 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."); } @@ -116,6 +127,9 @@ public static void wpFeatures(String path, String out, List include, Lis } public static void manifestFeatures(String path, String out, String androidJars, List include, List exclude) throws IOException { + if(include == null){ + return; + } SootFX sootFX = new SootFX(); sootFX.addClassPath(path); sootFX.appOnly(); diff --git a/src/main/java/api/Config.java b/src/main/java/api/Config.java index 0106410..322b1cd 100644 --- a/src/main/java/api/Config.java +++ b/src/main/java/api/Config.java @@ -15,6 +15,8 @@ public class Config { private List manifestFeatureInclusion; private List manifestFeatureExclusion; + private List featureResources; + public List getMethodFeatureInclusion() { return methodFeatureInclusion; @@ -79,4 +81,12 @@ public List getManifestFeatureExclusion() { public void setManifestFeatureExclusion(List manifestFeatureExclusion) { this.manifestFeatureExclusion = manifestFeatureExclusion; } + + public List getFeatureResources() { + return featureResources; + } + + public void setFeatureResources(List featureResources) { + this.featureResources = featureResources; + } } diff --git a/src/main/java/api/FeatureResource.java b/src/main/java/api/FeatureResource.java new file mode 100644 index 0000000..e7c4e14 --- /dev/null +++ b/src/main/java/api/FeatureResource.java @@ -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; + } +} diff --git a/src/main/java/api/SootFX.java b/src/main/java/api/SootFX.java index 3de0bc1..ed2b383 100644 --- a/src/main/java/api/SootFX.java +++ b/src/main/java/api/SootFX.java @@ -125,10 +125,10 @@ public WholeProgramFeatureSet extractWholeProgramFeaturesExclude(Set exc return new WholeProgramFX().getAllFeaturesExclude(exclusion); } - public WholeProgramFeatureSet extractWholeProgramFeaturesInclude(List featureExtractors) { + public WholeProgramFeatureSet extractWholeProgramFeaturesInclude(List featureExtractors, List featureResources) { validate(); SootConnector.setupSoot(mainClass, classPaths, appOnly, androidJars); - return new WholeProgramFX().getFeatures(featureExtractors); + return new WholeProgramFX().getFeatures(featureExtractors, featureResources); } public ManifestFeatureSet extractManifestFeaturesInclude(Set featureExtractors) { diff --git a/src/main/java/core/fx/wholeprogrambased/WholeProgramAPICallCount.java b/src/main/java/core/fx/wholeprogrambased/WholeProgramAPICallCount.java new file mode 100644 index 0000000..3b1bb9f --- /dev/null +++ b/src/main/java/core/fx/wholeprogrambased/WholeProgramAPICallCount.java @@ -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> { + + private List methodSignatures; + + public WholeProgramAPICallCount(String resourcePath) { + this.methodSignatures = FileConnector.getMethodSignatures(resourcePath); + } + + @Override + public Feature> extract(CallGraph target) { + Iterator iterator = target.iterator(); + Map methodCount = new HashMap<>(); + Stream 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); + } +} \ No newline at end of file diff --git a/src/main/java/manager/ManifestFX.java b/src/main/java/manager/ManifestFX.java index b6f3647..99d948f 100644 --- a/src/main/java/manager/ManifestFX.java +++ b/src/main/java/manager/ManifestFX.java @@ -1,6 +1,7 @@ package manager; import api.FeatureDescription; +import api.FeatureResource; import core.fx.FxUtil; import resource.ManifestConnector; import core.fx.base.ManifestFEU; @@ -73,4 +74,9 @@ public ManifestFeatureSet getFeatures(List featureExtractors) { } return getFeatures(fxSet); } + + @Override + public ManifestFeatureSet getFeatures(List featureExtractors, List featureResources) { + return null; + } } diff --git a/src/main/java/manager/SingleInstanceFX.java b/src/main/java/manager/SingleInstanceFX.java index 1660a07..c96b48a 100644 --- a/src/main/java/manager/SingleInstanceFX.java +++ b/src/main/java/manager/SingleInstanceFX.java @@ -1,5 +1,6 @@ package manager; +import api.FeatureResource; import core.fx.base.FeatureExtractionUnit; import core.rm.AbstractFeatureSet; @@ -16,4 +17,6 @@ public interface SingleInstanceFX featureExtractors); + S getFeatures(List featureExtractors, List featureResources); + } \ No newline at end of file diff --git a/src/main/java/manager/WholeProgramFX.java b/src/main/java/manager/WholeProgramFX.java index 9713ef6..423e300 100644 --- a/src/main/java/manager/WholeProgramFX.java +++ b/src/main/java/manager/WholeProgramFX.java @@ -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; @@ -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; @@ -49,7 +51,7 @@ public WholeProgramFeatureSet getFeatures(List 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); } @@ -59,4 +61,38 @@ public WholeProgramFeatureSet getFeatures(List featureExtractors) { } return getFeatures(fxSet); } + + @Override + public WholeProgramFeatureSet getFeatures(List featureExtractors, List featureResources) { + Set fxSet = new HashSet<>(); + for (String str : featureExtractors) { + Class cls = null; + WholeProgramFEU newInstance = null; + try { + cls = Class.forName("core.fx.wholeprogrambased." + str); + Optional 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 getResourcePath(List featureResources, String featureName) { + Optional first = featureResources.stream().filter(featureResource -> + featureResource.getFeatureName().equals(featureName)).findFirst(); + return first; + } + } diff --git a/src/main/java/resource/FileConnector.java b/src/main/java/resource/FileConnector.java new file mode 100644 index 0000000..0c755af --- /dev/null +++ b/src/main/java/resource/FileConnector.java @@ -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 getMethodSignatures(String path){ + List result = null; + try (Stream lines = Files.lines(Paths.get(path))) { + result = lines.collect(Collectors.toList()); + }catch (IOException e){ + e.printStackTrace(); + } + return result; + } + +}