Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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())
Ejemplo n.º 7
0
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"