From b1f0a89921e2f8db45592e91a2127090b66f1338 Mon Sep 17 00:00:00 2001 From: Yuichi Sugiyama Date: Tue, 14 Nov 2023 04:27:21 +0000 Subject: [PATCH 1/4] Add a script to automatically parse the results of Aurora's predicate --- .../methods/AuroraFE/src/check.py | 38 ++++++ .../methods/AuroraFE/src/predicate.py | 122 ++++++++++++++++++ .../root_causes/predicates | 4 +- 3 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 feature_extraction/methods/AuroraFE/src/predicate.py diff --git a/feature_extraction/methods/AuroraFE/src/check.py b/feature_extraction/methods/AuroraFE/src/check.py index a09d6d5..3942eb5 100644 --- a/feature_extraction/methods/AuroraFE/src/check.py +++ b/feature_extraction/methods/AuroraFE/src/check.py @@ -44,6 +44,35 @@ def check_locations(ranking, locs): return (r+1, ru+1) +def check_predicates(ranking, oracle_preds_str): + from predicate import decode_predicate + ranking_preds = [ + decode_predicate(r.split("--")[1].strip(), r.split("//")[-1].split()[2]) + for r in ranking if (not "inlined by" in r) and ("at" in r.split("//")[-1])] + + oracle_preds = [decode_predicate(r.split("//")[0].strip(), r.split("//")[1].strip()) + for r in oracle_preds_str] + + res = [] + for oracle_pred in oracle_preds: + for rank, ranking_pred in enumerate(ranking_preds): + # print(oracle_pred, ranking_pred) + cmp = oracle_pred.compare_to(ranking_pred) + # Not match at all + if cmp == -1: + continue + + # Found a exact or partial match predicate + if cmp == 0: + res.append(f"{oracle_pred}: Exact match at rank {rank}") + else: + res.append(f"{oracle_pred}: Partial match with rank {rank} and difference {cmp}") + break + assert(len(res) == len(oracle_preds)) + + return res + + if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('results') @@ -62,3 +91,12 @@ def check_locations(ranking, locs): print("loc_uniq:{}".format(loc_uniq)) print("loc_dup:{}".format(loc_dup)) + + with open(args.results) as fres,\ + open(args.rc_dir + "/predicates") as fpredef: + + ranking = [l for l in fres.readlines() if " -- " in l] + + res = check_predicates(ranking, fpredef.readlines()) + for r in res: + print(r) diff --git a/feature_extraction/methods/AuroraFE/src/predicate.py b/feature_extraction/methods/AuroraFE/src/predicate.py new file mode 100644 index 0000000..f7c20b1 --- /dev/null +++ b/feature_extraction/methods/AuroraFE/src/predicate.py @@ -0,0 +1,122 @@ +import sys +from abc import ABC, abstractmethod + +class Predicate(ABC): + def __init__(self, location: str): + self.location = location + + @abstractmethod + def compare_to(self, other) -> int: + pass + + @abstractmethod + def __str__(self): + pass + +class ComparePredicate(Predicate): + def __init__(self, destination: str, compare: str, value: int, location: str): + super().__init__(location) + self.destination = destination + self.compare = compare + self.value = value + + def compare_to(self, other) -> int: + # Check if the other object is an instance of ComparePredicate + if not isinstance(other, ComparePredicate): + return -1 + + # Check if destination and compare match + if self.location != other.location or \ + self.destination != other.destination or \ + self.compare != other.compare: + return -1 + # Return the absolute difference of values + return abs(self.value - other.value) + + def __str__(self): + return f"ComparePredicate(destination={self.destination}, "\ + f"compare={self.compare}, value={self.value})" + +class EdgePredicate(Predicate): + def __init__(self, source: int, transition: str, destination: int, location: str): + super().__init__(location) + self.source = source + self.transition = transition + self.destination = destination + + def compare_to(self, other) -> int: + # Check if the other object is an instance of EdgePredicate + if not isinstance(other, EdgePredicate): + return -1 + + return int(self.location == other.location and + self.source == other.source and + self.transition == other.transition and + self.destination == other.destination) + + def __str__(self): + return f"EdgePredicate(source={self.source}, "\ + f"transition={self.transition}, destination={self.destination})" + +class FlagSet(Predicate): + def __init__(self, flag, location: str): + super().__init__(location) + self.flag = flag + + def compare_to(self, other) -> int: + # Check if the other object is an instance of FlagSet + if not isinstance(other, FlagSet): + return -1 + + return int(self.location == other.location and self.flag == other.flag) + + def __str__(self): + return f"FlagSet(flag={self.flag})" + +class Visited(Predicate): + def __init__(self, location: str): + super().__init__(location) + + def compare_to(self, other) -> int: + # Check if the other object is an instance of Visited + if not isinstance(other, Visited): + return -1 + + return int(self.location == other.location) + + def __str__(self): + return "Visited" + +class Unsupported(Predicate): + def __init__(self, location: str): + super().__init__(location) + + def compare_to(self, other) -> int: + return -1 + + def __str__(self): + return "Unsupported" + +def decode_predicate(predicate: str, location: str) -> Predicate: + parts = predicate.split() + if len(parts) == 3: + if "reg_val" in parts[1]: + return ComparePredicate(parts[0], parts[1], int(parts[2][2:], 16), location) + if "edge" in parts[1]: + source = int(parts[0][2:], 16) + destination = int(parts[2][2:], 16) + return EdgePredicate(source, parts[1], destination, location) + else: + print(f"Unknown predicate format: {predicate}", file=sys.stderr) + return Unsupported(location) + elif len(parts) == 1: + if parts[0].endswith("flag_set"): + return FlagSet(parts[0], location) + elif parts[0] == "is_visited": + return Visited(location) + else: + print(f"Unknown predicate format: {predicate}", file=sys.stderr) + return Unsupported(location) + else: + print(f"Unknown predicate format: {predicate}", file=sys.stderr) + return Unsupported(location) diff --git a/targets/libtiff_cve-2016-10094/root_causes/predicates b/targets/libtiff_cve-2016-10094/root_causes/predicates index e98de81..c794aeb 100644 --- a/targets/libtiff_cve-2016-10094/root_causes/predicates +++ b/targets/libtiff_cve-2016-10094/root_causes/predicates @@ -1,2 +1,2 @@ -max_zero_flag_set -- cmp ., 0x4 -. min_reg_val_greater_or_equal 0x4 -- mov .,. +max_zero_flag_set // tiff2pdf.c:2898 +rax min_reg_val_greater_or_equal 0x4 // tiff2pdf.c:2898 From a7e08385f9368ba7467c7c0b605c9fbb4a9f0dc5 Mon Sep 17 00:00:00 2001 From: Yuichi Sugiyama Date: Tue, 14 Nov 2023 09:10:09 +0000 Subject: [PATCH 2/4] Fix return value of Predicate::compare_to --- .../methods/AuroraFE/src/predicate.py | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/feature_extraction/methods/AuroraFE/src/predicate.py b/feature_extraction/methods/AuroraFE/src/predicate.py index f7c20b1..95fdc86 100644 --- a/feature_extraction/methods/AuroraFE/src/predicate.py +++ b/feature_extraction/methods/AuroraFE/src/predicate.py @@ -49,10 +49,13 @@ def compare_to(self, other) -> int: if not isinstance(other, EdgePredicate): return -1 - return int(self.location == other.location and - self.source == other.source and - self.transition == other.transition and - self.destination == other.destination) + if self.location == other.location and + self.source == other.source and + self.transition == other.transition and + self.destination == other.destination: + return 0 + else: + return -1 def __str__(self): return f"EdgePredicate(source={self.source}, "\ @@ -68,7 +71,10 @@ def compare_to(self, other) -> int: if not isinstance(other, FlagSet): return -1 - return int(self.location == other.location and self.flag == other.flag) + if self.location == other.location and self.flag == other.flag: + return 0 + else: + return -1 def __str__(self): return f"FlagSet(flag={self.flag})" @@ -82,7 +88,10 @@ def compare_to(self, other) -> int: if not isinstance(other, Visited): return -1 - return int(self.location == other.location) + if self.location == other.location: + return 0 + else: + return -1 def __str__(self): return "Visited" From 398b177f496e1490a24aa71f57ae31708dffc8a8 Mon Sep 17 00:00:00 2001 From: Yuichi Sugiyama Date: Tue, 14 Nov 2023 09:12:37 +0000 Subject: [PATCH 3/4] Fix invalid syntax --- feature_extraction/methods/AuroraFE/src/predicate.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/feature_extraction/methods/AuroraFE/src/predicate.py b/feature_extraction/methods/AuroraFE/src/predicate.py index 95fdc86..15c4aba 100644 --- a/feature_extraction/methods/AuroraFE/src/predicate.py +++ b/feature_extraction/methods/AuroraFE/src/predicate.py @@ -49,9 +49,9 @@ def compare_to(self, other) -> int: if not isinstance(other, EdgePredicate): return -1 - if self.location == other.location and - self.source == other.source and - self.transition == other.transition and + if self.location == other.location and \ + self.source == other.source and \ + self.transition == other.transition and \ self.destination == other.destination: return 0 else: From 83dc623b5891b4f34cc8af41cfe1abc114d2be15 Mon Sep 17 00:00:00 2001 From: Yuichi Sugiyama Date: Tue, 14 Nov 2023 09:15:57 +0000 Subject: [PATCH 4/4] Add handling of missing predicate --- feature_extraction/methods/AuroraFE/src/check.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/feature_extraction/methods/AuroraFE/src/check.py b/feature_extraction/methods/AuroraFE/src/check.py index 3942eb5..df11daf 100644 --- a/feature_extraction/methods/AuroraFE/src/check.py +++ b/feature_extraction/methods/AuroraFE/src/check.py @@ -55,6 +55,7 @@ def check_predicates(ranking, oracle_preds_str): res = [] for oracle_pred in oracle_preds: + found = False for rank, ranking_pred in enumerate(ranking_preds): # print(oracle_pred, ranking_pred) cmp = oracle_pred.compare_to(ranking_pred) @@ -63,11 +64,14 @@ def check_predicates(ranking, oracle_preds_str): continue # Found a exact or partial match predicate + found = True if cmp == 0: res.append(f"{oracle_pred}: Exact match at rank {rank}") else: res.append(f"{oracle_pred}: Partial match with rank {rank} and difference {cmp}") break + if not found: + res.append(f"{oracle_pred}: Not found") assert(len(res) == len(oracle_preds)) return res