def project_selected_changed(self):
     """
     This method listens for a change in the current project and updates the singleton and updates the view.
     :return: none
     """
     if self.project_tab.listWidget.count() != 0:
         project = self.project_tab.listWidget.selectedItems()
         project_name = [item.text().encode("ascii") for item in project]
         if project_name:
             self.project_name = str(project_name[0], 'utf-8')
             try:
                 Singleton.set_project(self.project_name)
                 project_db = DBConnection.get_collection(self.project_name)
                 project_info = project_db["projectInfo"]
                 bin_info = project_db["binaryInfo"]
                 cursor = project_info.find()
                 for db in cursor:
                     self.project_tab.textEdit_2.setPlainText(db['ProjectDescription'])
                     self.project_tab.lineEdit_2.setText(db['ProjectName'])
                     self.project_tab.lineEdit_3.setText(db['BnyFilePath'])
                     Singleton.set_path(db['BnyFilePath'])
                 cursor_bin = bin_info.find()
                 for db in cursor_bin:
                     self.set_binary_prop()
                     self.fill_binary_prop(db)
                 self.selected_project_changed.emit()
             except Exception as e:
                 msg = ErrorDialog(self.project_tab, str(e), "Error")
                 msg.exec()
    def save_project(self):
        """
        This method saves the newly created project into the database.
        :return: none
        """
        if self.project_tab.lineEdit_3.text() != "":
            saved = False
            project_db = DBConnection.get_collection(self.project_name)
            project_info = project_db["projectInfo"]
            info = {"ProjectName": self.project_tab.lineEdit_2.text(),
                    "ProjectDescription": self.project_tab.textEdit_2.toPlainText(),
                    "BnyFilePath": self.project_tab.lineEdit_3.text()}
            insert_info = project_info.insert(info, check_keys=False)
            bin_info = project_db["binaryInfo"]
            insert_obj = bin_info.insert(r2_bin_info, check_keys=False)
            msg = QtWidgets.QMessageBox()
            msg.setIcon(QtWidgets.QMessageBox.Information)
            msg.setWindowTitle("Save Project")
            msg.setText("Project Saved")
            msg.setStandardButtons(QtWidgets.QMessageBox.Ok)
            retval = msg.exec_()
            Singleton.set_path(self.project_tab.lineEdit_3.text())
            Singleton.set_project(self.project_name)
            self.project_tab.textEdit_2.setReadOnly(True)
            self.delete_save_operations(self.project_creation_finished, [self.project_tab.pushButton_7],
                                   [self.project_tab.pushButton_8, self.project_tab.pushButton_10],
                                   self.project_tab.listWidget)

        else:
            msg = ErrorDialog(self.project_tab, "Please select a binary file", "Error Saving Project")
            msg.exec_()
    def delete_project(self):
        """
        This method gets the selected project and deletes it form the database.
        :return: none
        """
        if self.project_name != "":
            button_reply = QtWidgets.QMessageBox.question(self.project_tab, 'PyQt5 message',
                                                          "Do you like to erase Project %s ?" % self.project_name,
                                                          QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                                                          QtWidgets.QMessageBox.No)
            if button_reply == QtWidgets.QMessageBox.Yes:

                DBConnection.drop_db(self.project_name)

                self.project_tab.lineEdit_2.setText("")
                self.project_tab.textEdit_2.setText("")
                self.project_tab.lineEdit_3.setText("")
                self.set_binary_prop()
                self.delete_save_operations(self.project_creation_finished, [self.project_tab.pushButton_7],
                                            [self.project_tab.pushButton_8, self.project_tab.pushButton_10],
                                            self.project_tab.listWidget)

                list_items = self.project_tab.listWidget.selectedItems()
                if not list_items:
                    return
                for item in list_items:
                    self.project_tab.listWidget.takeItem(self.project_tab.listWidget.row(item))
                Singleton.set_project("BEAT")
                Singleton.set_path("")
                self.delete_project_signal.emit()
                self.project_selected_changed()
        else:
            msg = ErrorDialog(self.project_tab, "Please select a project", "Error Deleting Project")
            msg.exec_()
Пример #4
0
def static_functions(rlocal, cplugin):
    """
    analysis all the functions in the binary and filters with the selected plugin and adds them to the database
    :param rlocal: R2Connection of the binary file
    :param cplugin: string current selected plugin
    :return: List of dict with filtered functions
    """
    items = []
    s = Singleton.get_project()
    project_db = DBConnection.get_collection(s)

    #if project_db["functions"]:
    #    project_db.drop_collection("functions")

    func_db = project_db["functions"]
    func_all = rlocal.cmdj("aflj")
    func_plg = Plugin.plugin_types("Function", cplugin)

    for fc in func_all:

        if fc["name"] in func_plg:
            function = rlocal.cmdj("axtj %s" % fc["name"])
            tmp = fc["name"]
            for f in function:
                fc["name"] = tmp + " " + hex(f["from"])
                items.append(fc["name"])
                fc["comment"] = ""
                fc["runs"] = []
                fc["from"] = hex(f["from"])
                if "_id" in fc:
                    del fc["_id"]
                if func_db.find({"name": fc["name"]}).count() == 0:
                    func_db.insert_one(fc)
    return items
Пример #5
0
 def open_comment(self):
     """
     This method opens the comment pop-up to add a comment/ or edit an exiting comment.Afterwards it updates
     the information to the detailed point of interest in the database.
     :return: none
     """
     item = self.analysis_tab.poi_listWidget.currentItem()
     value = DBConnection.search_by_item(item)
     project_db = DBConnection.get_collection(Singleton.get_project())
     if item.toolTip() == "Functions":
         db_info = project_db["functions"]
     elif item.toolTip() == "Strings":
         db_info = project_db["string"]
     if value is not None:
         id = value["_id"]
         cmt = value["comment"]
         if cmt is None:
             cmt = ""
         pop_up = CommentDialog(self.analysis_tab, cmt)
         comm = pop_up.exec_()
         index = {"_id": id}
         new_value = {"$set": {"comment": comm}}
         db_info.update_one(index, new_value)
         self.detailed_poi(item)
         new_font = QtGui.QFont()
         new_font.setBold(True)
         item.setFont(new_font)
Пример #6
0
 def input_terminal(self, text):
     """
     This method checks if the dynamic analysis thread is running if it's being run it passes the text as an input
     pipe.Otherwise passes the text as a command for Radare.
     :param text: text for argument
     :return: none
     """
     if self.run == 0:
         if Singleton.get_project() != "BEAT":
             try:
                 r2 = model.analysis.StaticAnalysis.static_all(Singleton.get_path())
                 self.terminal(text + ' >\n')
                 self.terminal(r2.cmd(text))
             except Exception as e:
                 x = ErrorDialog(self.analysis_tab, str(e), "Error")
                 x.exec_()
             self.analysis_tab.terminal_window_lineEdit.setText("")
         else:
             x = ErrorDialog(self.analysis_tab, "First select a project", "Error")
             x.exec_()
     elif self.run == 1:
         thread.input(text)
     self.analysis_tab.terminal_window_lineEdit.clear()
Пример #7
0
    def poi_comboBox_change(self, text):
        """
        This function listens for a change in the  poi window to change the current filter and updates the
        filtered pois which are stored in the database in the list view
        :param text: poi's type
        :return: none
        """
        s = Singleton.get_project()
        if s == "BEAT":
            msg = ErrorDialog(self.analysis_tab, "Please select a project first", "Static analysis Error")
            msg.exec_()
            return

        self.analysis_tab.poi_listWidget.clear()

        project_db = DBConnection.get_collection(s)

        if text == "Functions":
            project_info = project_db["functions"]
            cursor = project_info.find()
            for db in cursor:
                item = self.set_item(db["name"], "Functions")
                item = self.change_font(item)
                self.analysis_tab.poi_listWidget.addItem(item)
        elif text == "Strings":
            project_info = project_db["string"]
            cursor = project_info.find()
            for db in cursor:
                text = db["string"]
                item = self.set_item(text, "Strings")
                item = self.change_font(item)
                self.analysis_tab.poi_listWidget.addItem(item)

        elif text == "All":
            project_info = project_db["functions"]
            cursor = project_info.find()
            for db in cursor:
                item = self.set_item(db["name"], "Functions")
                item = self.change_font(item)
                self.analysis_tab.poi_listWidget.addItem(item)
            project_info = project_db["string"]
            cursor = project_info.find()
            for db in cursor:
                text = db["string"]
                item = self.set_item(text, "Strings")
                item = self.change_font(item)
                self.analysis_tab.poi_listWidget.addItem(item)
Пример #8
0
    def return_funcitions(self, text):
        """ This method receives the information from the breakpoint and stores the information into the database.
        :param text: information received
        :return: none
        """
        value = DBConnection.search_by_name(text["name"], "Functions")
        project_db = DBConnection.get_collection(Singleton.get_project())
        db_info = project_db["functions"]
        if value is not None:
            id = value["_id"]

            index = {"_id": id}
            runs = value["runs"]
            run = {"name":input,"rtnPara": text["rtnPara"], "rtnFnc": text["rtnFnc"]}
            runs.append(run)
            new_value = {"$set": {"runs": runs}}
            db_info.update_one(index, new_value)
Пример #9
0
def search_by_name(name, type):
    """
    Gets all the information of poi from the database
    :param name: String name of poi
    :param type: String type of the poi
    :return: Dict with all poi info
    """
    s = Singleton.get_project()
    project_db = get_collection(s)
    value = None
    if type == "Functions":
        project_info = project_db["functions"]
        cursor = project_info.find_one({"name": name})
        if cursor is not None:
            value = {"_id": cursor["_id"], 'name': cursor["name"], 'signature': cursor["signature"],
                     'varaddress': hex(cursor["offset"]), 'from': cursor["from"], 'comment': cursor["comment"], 'runs':cursor["runs"]}
    return value
Пример #10
0
    def dynamic(self):
        """
        This method asks the user for parameters, creates a list with the selected pois and  stats dynamic analysis
        thread with the list of pois and parameters as arguments.
         :return:
        """
        if self.analysis_tab.poi_listWidget.count() == 0:
            x = ErrorDialog(self.analysis_tab, "Please run Static analysis first", "Error in DYnamic analysis")
            x.exec_()
            return
        global input
        input, ok_pressed = QtWidgets.QInputDialog.getText(self.analysis_tab, "Dynamic analysis", "Args to pass:"******"")

        if ok_pressed:
            self.run += 1
            pois_checked = []

            r2 = model.analysis.StaticAnalysis.static_all(Singleton.get_path())
            self.terminal('r2 > \n')
            self.terminal(r2.cmd("doo %s" % input))

            for i in range(self.analysis_tab.poi_listWidget.count()):
                item = self.analysis_tab.poi_listWidget.item(i)
                if item.checkState() == QtCore.Qt.Checked:
                    if item.toolTip() == "Functions":
                        value = DBConnection.search_by_item(item)
                        poi = {"name": item.text(), "from": value["from"], "type": item.toolTip(), "rtnPara": [],
                               "rtnFnc": ""}
                        pois_checked.append(poi)

            sort = sorted(pois_checked, key=lambda i: i["from"])

            global thread
            try:
                self.run = 1
                self.dynamic_started.emit()
                thread = model.analysis.DynamicThread.DynamicThread(rlocal=r2, pois=sort)
                thread.textSignal.connect(lambda x: self.terminal(x))
                thread.listSignal.connect(lambda x: self.return_funcitions(x))
                thread.errorSignal.connect(lambda x: self.error_thread(x))
                thread.start()
            except Exception as e:
                print(e)
Пример #11
0
def static_strings(rlocal, cplugin):
    """
    analysis all the strings in the binary and filters with nthe selected plugin and adds them to the database
    :param rlocal: R2Connection of the binary file
    :param cplugin: string current selected plugin
    :return: List of dict with filtered strings
    """
    items = []
    s = Singleton.get_project()
    project_db = DBConnection.get_collection(s)
    # Strings
    strings = rlocal.cmdj("izj")
    str_plg = Plugin.plugin_types("String", cplugin)

    #if project_db["string"]:
    #    project_db.drop_collection("string")

    str_db = project_db["string"]
    for string in strings:
        text = string["string"]
        text_decoded = base64.b64decode(text)
        for i in str_plg:
            if i.upper() in text_decoded.decode().upper():
                x = rlocal.cmdj("axtj %s" % string["vaddr"])
                tmp = text_decoded.decode()
                for str in x:
                    string["string"] = tmp + " " + hex(str["from"])
                    items.append(string["string"])
                    string["from"] = hex(str["from"])
                    string["comment"] = ""
                    if "_id" in string:
                        del string["_id"]
                    if str_db.find({"string": string["string"]}).count() == 0:
                        str_db.insert_one(string)
                break
    return items
Пример #12
0
def search_by_item(item):
    """
    Gets all the information of a poi from a listwidget item
    :param item: ListwidgetItem selected poi
    :return: dict with pois info
    """
    if item is not None:
        s = Singleton.get_project()
        project_db = get_collection(s)
        value = None
        if item.toolTip() == "Functions":
            project_info = project_db["functions"]
            cursor = project_info.find_one({"name": item.text()})
            if cursor is not None:
                value = {"_id":cursor["_id"],'name': cursor["name"], 'signature': cursor["signature"], 'varaddress': hex(cursor["offset"]),
                         'from': cursor["from"], 'comment': cursor["comment"],"runs": cursor["runs"]}
        elif item.toolTip() == "Strings":
            project_info = project_db["string"]
            cursor = project_info.find_one({"string": item.text()})
            if cursor is not None:
                value = {"_id":cursor["_id"],'string': cursor["string"], 'varaddress': hex(cursor["vaddr"]), 'from': cursor["from"],
                         'comment': cursor["comment"]}
        return value
    return None
Пример #13
0
    def static(self):
        """
        This method listens to the click of the static analysis button and connects with the model to preform
        static analysis.This method also saves into the database depending on the type.
        :return: none
        """
        s = Singleton.get_project()
        if s == "BEAT":
            x = ErrorDialog(self.analysis_tab, "Please select a project", "Static analysis Error")
            x.exec_()
            return
        if self.analysis_tab.plugin_comboBox.count() == 0:
            x = ErrorDialog(self.analysis_tab, "Please install a plugin", "Static analysis Error")
            x.exec_()
            return

        QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)

        self.analysis_tab.poi_listWidget.clear()
        print(Singleton.get_path())
        rlocal = model.analysis.StaticAnalysis.static_all(Singleton.get_path())
        try:
            if self.analysis_tab.poi_comboBox.currentText() == "All":

                strings = model.analysis.StaticAnalysis.static_strings(rlocal,
                                                                       self.analysis_tab.plugin_comboBox.currentText())
                for st in strings:
                    item = self.set_item(st, "Strings")
                    item = self.change_font(item)
                    self.analysis_tab.poi_listWidget.addItem(item)

                functions = model.analysis.StaticAnalysis.static_functions(rlocal,
                                                                           self.analysis_tab.plugin_comboBox.currentText())
                for fc in functions:
                    item = self.set_item(fc, "Functions")
                    item = self.change_font(item)
                    self.analysis_tab.poi_listWidget.addItem(item)

            elif self.analysis_tab.poi_comboBox.currentText() == "Functions":

                functions = model.analysis.StaticAnalysis.static_functions(rlocal,
                                                                           self.analysis_tab.plugin_comboBox.currentText())
                for fc in functions:
                    item = self.set_item(fc, "Functions")
                    item = self.change_font(item)
                    self.analysis_tab.poi_listWidget.addItem(item)

            elif self.analysis_tab.poi_comboBox.currentText() == "Strings":

                strings = model.analysis.StaticAnalysis.static_strings(rlocal,
                                                                       self.analysis_tab.plugin_comboBox.currentText())
                for st in strings:
                    item = self.set_item(st, "Strings")
                    item = self.change_font(item)
                    self.analysis_tab.poi_listWidget.addItem(item)

        except Exception as e:
            x = ErrorDialog(self.analysis_tab, str(e), "Static analysis Error")
            x.exec_()
        rlocal.quit()
        QtWidgets.QApplication.restoreOverrideCursor()
Пример #14
0
 def set_running(self):
     self.main_window.setWindowTitle("BEAT | Running " + Singleton.get_project())
Пример #15
0
 def set_project_name(self):
     self.main_window.setWindowTitle("BEAT | " + Singleton.get_project())
Пример #16
0
    def setup_ui(self, main_window):
        """Sets up the ui for the main window and establishes the ui_implementation and their connections for each tab"""
        self.main_window = main_window
        self.main_window.setObjectName("BEAT")
        self.main_window.resize(804, 615)
        self.main_window.setFixedSize(self.main_window.width(), self.main_window.height())
        self.setWindowIcon(QtGui.QIcon('./resources/beat.png'))

        self.main_window.setWindowTitle("BEAT")

        s = Singleton()
        s.set_project("BEAT")

        self.centralwidget = QtWidgets.QWidget(self.main_window)
        self.centralwidget.setObjectName("centralwidget")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(5, 5, 794, 605))
        self.tabWidget.setObjectName("tabWidget")

        self.ProjectTab = Tab1.Tab1(self)
        self.tabWidget.addTab(self.ProjectTab, "")

        self.analysisTab = Tab2.Tab2(self)
        self.tabWidget.addTab(self.analysisTab, "")

        self.pluginTab = Tab3.Tab3(self)
        self.tabWidget.addTab(self.pluginTab, "")

        self.pointsOfInterestTab = Tab4.Tab4(self)
        self.tabWidget.addTab(self.pointsOfInterestTab, "")

        self.documentationTab = Tab5.Tab5(self)
        self.tabWidget.addTab(self.documentationTab, "")

        self.project_implementation = ProjectTabImplementation.ProjectTabImplementation(self.ProjectTab)
        self.project_implementation.establish_connections()
        self.project_implementation.establish_calls()

        self.analysis_implementation = AnalysisTabImplementation.AnalysisTabImplementation(self.analysisTab)
        self.analysis_implementation.establish_connections()
        self.analysis_implementation.establish_calls()

        self.plugin_implementation = PluginTabImplementation.PluginTabImplementation(self.pluginTab)
        self.plugin_implementation.establish_connections()
        self.plugin_implementation.establish_calls()

        self.poi_implementation = POITabImplementation.POITabImplementation(self.pointsOfInterestTab)
        self.poi_implementation.establish_connections()
        self.poi_implementation.establish_calls()

        self.doc_implementation = DocumentationTabImplementation.DocumentationTabImplementation(self.documentationTab)
        self.doc_implementation.establish_connections()
        self.doc_implementation.establish_calls()

        self.project_implementation.selected_project_changed.connect(
            lambda: self.analysis_implementation.poi_comboBox_change("All"))
        self.project_implementation.selected_project_changed.connect(lambda: self.set_project_name())
        self.project_implementation.selected_project_changed.connect(
            lambda: self.analysisTab.terminal_output_textEdit.clear())
        self.project_implementation.project_creation_started.connect(lambda: self.disable_tabs())
        self.project_implementation.project_creation_finished.connect(lambda: self.enable_tabs())
        self.project_implementation.delete_project_signal.connect(lambda: self.analysisTab.poi_listWidget.clear())
        self.project_implementation.delete_project_signal.connect(lambda: self.set_clear_name())
        self.project_implementation.delete_project_signal.connect(
            lambda: self.analysisTab.poi_content_area_textEdit.clear())

        self.analysis_implementation.dynamic_started.connect(lambda: self.set_running())
        self.analysis_implementation.dynamic_stopped.connect(lambda: self.set_project_name())
        self.analysis_implementation.dynamic_started.connect(lambda: self.disable_tabs())
        self.analysis_implementation.dynamic_stopped.connect(lambda: self.enable_tabs())

        self.plugin_implementation.plugin_signal.connect(self.analysis_implementation.set_plugins)
        self.plugin_implementation.plugin_signal.connect(self.poi_implementation.set_plugins)
        self.plugin_implementation.plugin_creation_started.connect(lambda: self.disable_tabs())
        self.plugin_implementation.plugin_creation_finished.connect(lambda: self.enable_tabs())
        self.plugin_implementation.plugin_delete_signal.connect(self.poi_implementation.set_plugins)
        self.plugin_implementation.plugin_delete_signal.connect(
            lambda: self.poi_implementation.fill_poi(self.pointsOfInterestTab.comboBox_2.currentText()))
        self.plugin_implementation.plugin_delete_signal.connect(self.pointsOfInterestTab.textEdit.clear)
        self.plugin_implementation.plugin_delete_signal.connect(self.analysis_implementation.set_plugins)

        self.poi_implementation.add_poi_signal.connect(self.plugin_implementation.item_activated)

        self.main_window.setCentralWidget(self.centralwidget)
        self.retranslate_ui()
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(main_window)