diff --git a/feature_extraction/methods/AuroraFE/src/check.py b/feature_extraction/methods/AuroraFE/src/check.py index a09d6d5..df11daf 100644 --- a/feature_extraction/methods/AuroraFE/src/check.py +++ b/feature_extraction/methods/AuroraFE/src/check.py @@ -44,6 +44,39 @@ 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: + found = False + 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 + 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 + + if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('results') @@ -62,3 +95,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..15c4aba --- /dev/null +++ b/feature_extraction/methods/AuroraFE/src/predicate.py @@ -0,0 +1,131 @@ +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 + + 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}, "\ + 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 + + if self.location == other.location and self.flag == other.flag: + return 0 + else: + return -1 + + 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 + + if self.location == other.location: + return 0 + else: + return -1 + + 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