def _load_database(self, file_path): if AngrDB is None: QMessageBox.critical(None, 'Error', 'AngrDB is not enabled. Maybe you do not have SQLAlchemy installed?') return angrdb = AngrDB() try: proj = angrdb.load(file_path) except angr.errors.AngrIncompatibleDBError as ex: QMessageBox.critical(None, 'Error', "Failed to load the angr database because of compatibility issues.\n" "Details: %s" % str(ex)) return except angr.errors.AngrDBError as ex: QMessageBox.critical(None, 'Error', 'Failed to load the angr database.\n' 'Details: %s' % str(ex)) _l.critical("Failed to load the angr database.", exc_info=True) return cfg = proj.kb.cfgs['CFGFast'] cfb = proj.analyses.CFB() # it will load functions from kb self.workspace.instance.database_path = file_path self.workspace.instance.initialized = True # skip automated CFG recovery self.workspace.instance.project = proj self.workspace.instance.cfg = cfg self.workspace.instance.cfb = cfb # trigger callbacks self.workspace.reload() self.workspace.on_cfg_generated()
def _save_database(self, file_path): if self.workspace.instance is None or self.workspace.instance.project.am_none: return False if AngrDB is None: QMessageBox.critical( None, 'Error', 'AngrDB is not enabled. Maybe you do not have SQLAlchemy installed?' ) return False self.workspace.plugins.handle_project_save(file_path) angrdb = AngrDB(project=self.workspace.instance.project) extra_info = self.workspace.plugins.angrdb_store_entries() angrdb.dump( file_path, kbs=[ self.workspace.instance.kb, self.workspace.instance.pseudocode_variable_kb, ], extra_info=extra_info, ) self.workspace.instance.database_path = file_path return True
def _load_database(self, file_path): if AngrDB is None: QMessageBox.critical( None, 'Error', 'AngrDB is not enabled. Maybe you do not have SQLAlchemy installed?' ) return angrdb = AngrDB() other_kbs = {} extra_info = {} try: proj = angrdb.load(file_path, kb_names=["global", "pseudocode_variable_kb"], other_kbs=other_kbs, extra_info=extra_info) except angr.errors.AngrIncompatibleDBError as ex: QMessageBox.critical( None, 'Error', "Failed to load the angr database because of compatibility issues.\n" f"Details: {ex}") return except angr.errors.AngrDBError as ex: QMessageBox.critical( None, 'Error', 'Failed to load the angr database.\n' f'Details: {ex}') _l.critical("Failed to load the angr database.", exc_info=True) return self._recent_file(file_path) cfg = proj.kb.cfgs['CFGFast'] cfb = proj.analyses.CFB() # it will load functions from kb self.workspace.instance.database_path = file_path self.workspace.instance._reset_containers() self.workspace.instance.project = proj self.workspace.instance.cfg = cfg self.workspace.instance.cfb = cfb if "pseudocode_variable_kb" in other_kbs: self.workspace.instance.pseudocode_variable_kb = other_kbs[ "pseudocode_variable_kb"] else: self.workspace.instance.initialize_pseudocode_variable_kb() self.workspace.instance.project.am_event(initialized=True) # trigger callbacks self.workspace.reload() self.workspace.on_cfg_generated() self.workspace.plugins.angrdb_load_entries(extra_info)
def _save_database(self, file_path): if self.workspace.instance is None or self.workspace.instance.project is None: return False if AngrDB is None: QMessageBox.critical(None, 'Error', 'AngrDB is not enabled. Maybe you do not have SQLAlchemy installed?') return False angrdb = AngrDB(project=self.workspace.instance.project) angrdb.dump(file_path) self.workspace.instance.database_path = file_path return True
def test_angrdb_fauxware(): bin_path = os.path.join(test_location, "x86_64", "fauxware") proj = angr.Project(bin_path, auto_load_libs=False) cfg = proj.analyses.CFGFast(data_references=True, cross_references=True, normalize=True) # type: angr.analyses.CFGFast proj.kb.comments[proj.entry] = "Entry point" dtemp = tempfile.mkdtemp() db_file = os.path.join(dtemp, "fauxware.adb") db = AngrDB(proj) db.dump(db_file) db1 = AngrDB() new_proj = db1.load(db_file) assert len(new_proj.kb.cfgs['CFGFast'].nodes()) == len(cfg.model.nodes()) assert len(new_proj.kb.functions) == len(proj.kb.functions) # compare each function for func in proj.kb.functions.values(): new_func = new_proj.kb.functions[func.addr] assert func.addr == new_func.addr assert func.normalized == new_func.normalized assert len(func.transition_graph.nodes()) == len( new_func.transition_graph.nodes()) assert len(func.transition_graph.edges()) == len( new_func.transition_graph.edges()) # compare CFG new_cfg = new_proj.kb.cfgs['CFGFast'] for node in cfg.model.nodes(): new_node = new_cfg.get_any_node(node.addr) assert new_node.addr == node.addr assert new_node.size == node.size # compare memory data for addr, memory_data in cfg.model.memory_data.items(): new_memory_data = new_cfg.memory_data[addr] assert memory_data.addr == new_memory_data.addr assert memory_data.size == new_memory_data.size assert memory_data.sort == new_memory_data.sort assert memory_data.content == new_memory_data.content assert cfg.model.insn_addr_to_memory_data.keys( ) == new_cfg.insn_addr_to_memory_data.keys() # comments for addr, comment in proj.kb.comments.items(): new_comment = new_proj.kb.comments.get(addr, None) assert comment == new_comment
def test_angrdb_open_multiple_times(): bin_path = os.path.join(test_location, "x86_64", "fauxware") proj = angr.Project(bin_path, auto_load_libs=False) _ = proj.analyses.CFGFast(data_references=True, cross_references=True, normalize=True) # type: angr.analyses.CFGFast proj.kb.comments[proj.entry] = "Entry point" dtemp = tempfile.mkdtemp() db_file = os.path.join(dtemp, "fauxware.adb") db = AngrDB(proj) db.dump(db_file) # attempt 0 db0 = AngrDB() proj0 = db0.load(db_file) # attempt 1 db1 = AngrDB() proj1 = db1.load(db_file) # attempt 2 db2 = AngrDB() proj2 = db2.load(db_file) # attempt 3 db3 = AngrDB() proj3 = db3.load(db_file) # compare functions for func in proj.kb.functions.values(): for p in [proj0, proj1, proj2, proj3]: new_func = p.kb.functions[func.addr] assert func.addr == new_func.addr assert func.normalized == new_func.normalized assert len(func.transition_graph.nodes()) == len( new_func.transition_graph.nodes()) assert len(func.transition_graph.edges()) == len( new_func.transition_graph.edges())
def test_angrdb_save_multiple_times(): bin_path = os.path.join(test_location, "x86_64", "fauxware") proj = angr.Project(bin_path, auto_load_libs=False) _ = proj.analyses.CFGFast(data_references=True, cross_references=True, normalize=True) # type: angr.analyses.CFGFast proj.kb.comments[proj.entry] = "Entry point" dtemp = tempfile.mkdtemp() db_file = os.path.join(dtemp, "fauxware.adb") # attempt 0 db = AngrDB(proj) db.dump(db_file) # attempt 1 proj0 = AngrDB().load(db_file) assert proj0.kb.comments[proj.entry] == "Entry point" proj0.kb.comments[proj.entry] = "Comment 0" AngrDB(proj0).dump(db_file) # attempt 2 proj1 = AngrDB().load(db_file) assert proj1.kb.comments[proj.entry] == "Comment 0" proj1.kb.comments[proj.entry] = "Comment 1" AngrDB(proj1).dump(db_file) # attempt 3 proj1 = AngrDB().load(db_file) assert proj1.kb.comments[proj.entry] == "Comment 1" proj1.kb.comments[proj.entry] = "Comment 22222222222222222222222" AngrDB(proj1).dump(db_file) # attempt 4 proj1 = AngrDB().load(db_file) assert proj1.kb.comments[proj.entry] == "Comment 22222222222222222222222"