#!/usr/bin/env python3 # -*-coding=utf-8-*- # This tool is used to analyze the file generated by compare_binary_iodump.py. # parse() can build a dependency tree with those varnodes # where accuracy shake occurs and show the root varnodes. # get_varNode()/get_dependence_list()/get_reference_list()/show_src_info() # are some functions which are used to query dependencies between varnodes. import argparse import os class varNode: var_node_dict = {} var_node_root_dict = {} def __init__(self, id, dependence_list, src_info): self.src_info = src_info if not id in varNode.var_node_dict.keys(): self.id = id self.dependence_list = [] self.reference_list = [] else: self = varNode.var_node_dict[id] if dependence_list: self.vitrual = False self.is_root = True else: self.vitrual = True self.is_root = False for i in dependence_list: if not i in varNode.var_node_dict.keys(): varNode.var_node_dict[i] = varNode(i, [], "") dv = varNode.var_node_dict[i] self.dependence_list.append(dv) if not dv.vitrual: self.is_root = False dv.reference_list.append(self) for i in self.reference_list: i.is_root = False varNode.var_node_root_dict.pop[i.id] if self.is_root: varNode.var_node_root_dict[id] = self varNode.var_node_dict[id] = self @staticmethod def get_varNode(id): return varNode.var_node_dict[id] def get_dependence_list(self): return self.dependence_list def get_reference_list(self): return self.reference_list def show_src_info(self): print(self.src_info) def get_dependence(string, src_info): start1 = "id:" end1 = "," e = 0 count = string.count(start1) dependence_list = [] for x in range(0, count): s = string.find(start1, e) e = string.find(end1, s) sub_str = string[s:e] if x == 0: var = sub_str else: dependence_list.append(sub_str) varNode(var, dependence_list, src_info) def parse(filename): with open(filename) as f: varNode.var_node_dict.clear() varNode.var_node_root_dict.clear() line = f.readline() s = ["", "", ""] idx = 1 while line: if line.find("not equal: ") != -1: s[2] = line src_info = s[0] + "\n" + s[1] + "\n" + s[2] get_dependence(s[0], src_info) else: if line.find("var={id:") != -1: idx = idx ^ 1 s[idx] = "" s[idx] = s[idx] + line.strip() line = f.readline() return varNode.var_node_root_dict def main(): parser = argparse.ArgumentParser( description=( "Analyze the outputs of compare_binary_iodump.py" "Should save the outputs of compare_binary_iodump.py" "as a file" ), formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) parser.add_argument( "filename", help="file which save the outputs of compare_binary_iodump.py" ) args = parser.parse_args() parse(args.filename) print("varnode root:") for key, value in varNode.var_node_root_dict.items(): print(key) print("detail info:") value.show_src_info() if __name__ == "__main__": main()