def test_rename_a_function_in_disasm_and_pseudocode_views(self):
        main = self._open_a_project()

        func = main.workspace.instance.project.kb.functions['main']
        self.assertIsNotNone(func)

        # decompile the function
        disasm_view = main.workspace._get_or_create_disassembly_view()
        disasm_view._t_flow_graph_visible = True
        disasm_view.display_function(func)
        disasm_view.decompile_current_function()
        main.workspace.instance.join_all_jobs()
        pseudocode_view = main.workspace._get_or_create_pseudocode_view()

        # find the node for function
        for _, item in pseudocode_view.codegen.map_pos_to_node.items():
            if isinstance(
                    item.obj,
                    angr.analyses.decompiler.structured_codegen.c.CFunction):
                func_node = item.obj
                break
        else:
            self.fail("The CFunction instance is not found.")

        self.assertEqual(func_node.name, "main")

        # rename the function in the disassembly view
        rlabel = RenameLabel(disasm_view, func.addr, parent=None)
        rlabel._name_box.setText("")
        QTest.keyClicks(rlabel._name_box, "asdf")
        QTest.mouseClick(rlabel._ok_button, Qt.MouseButton.LeftButton)

        self.assertEqual(func.name, "asdf")
        self.assertEqual(func_node.name, "main")

        # rename the function in the pseudocode view
        rnode = RenameNode(code_view=pseudocode_view, node=func_node)
        rnode._name_box.setText("")
        QTest.keyClicks(rnode._name_box, "fdsa")
        QTest.mouseClick(rnode._ok_button, Qt.MouseButton.LeftButton)

        self.assertEqual(func.name, "fdsa")

        sleep(5)
        self.session = Slacrs(database=Conf.checrs_backend_str).session()
        function_rename = self.session.query(HumanActivity).filter(
            HumanActivity.project_md5 == self.project_md5,
            HumanActivity.category == HumanActivityEnum.FunctionRename,
            HumanActivity.old_name == "main",
            HumanActivity.new_name == "fdsa",
        ).one()
        self.session.close()
        self.assertIsNotNone(function_rename)
    def test_rename_a_function_in_disasm_and_pseudocode_views(self):
        main = MainWindow(show=False)
        binpath = os.path.join(test_location, "x86_64", "fauxware")
        main.workspace.instance.project.am_obj = angr.Project(
            binpath, auto_load_libs=False)
        main.workspace.instance.project.am_event()
        main.workspace.instance.join_all_jobs()

        func = main.workspace.instance.project.kb.functions['main']
        self.assertIsNotNone(func)

        # decompile the function
        disasm_view = main.workspace._get_or_create_disassembly_view()
        disasm_view._t_flow_graph_visible = True
        disasm_view.display_function(func)
        disasm_view.decompile_current_function()
        main.workspace.instance.join_all_jobs()
        pseudocode_view = main.workspace._get_or_create_pseudocode_view()

        # find the node for function
        for _, item in pseudocode_view.codegen.map_pos_to_node.items():
            if isinstance(
                    item.obj,
                    angr.analyses.decompiler.structured_codegen.c.CFunction):
                func_node = item.obj
                break
        else:
            self.fail("The CFunction instance is not found.")

        self.assertEqual(func_node.name, "main")

        # rename the function in the disassembly view
        rlabel = RenameLabel(disasm_view, func.addr, parent=None)
        rlabel._name_box.setText("")
        QTest.keyClicks(rlabel._name_box, "asdf")
        QTest.mouseClick(rlabel._ok_button, Qt.MouseButton.LeftButton)

        self.assertEqual(func.name, "asdf")
        self.assertEqual(func_node.name, "main")

        # rename the function in the pseudocode view
        rnode = RenameNode(code_view=pseudocode_view, node=func_node)
        rnode._name_box.setText("")
        QTest.keyClicks(rnode._name_box, "fdsa")
        QTest.mouseClick(rnode._ok_button, Qt.MouseButton.LeftButton)

        self.assertEqual(func.name, "fdsa")
    def test_rename_a_variable_in_pseudocode_view(self):
        main = self._open_a_project()

        func = main.workspace.instance.project.kb.functions['main']
        self.assertIsNotNone(func)

        # decompile the function
        disasm_view = main.workspace._get_or_create_disassembly_view()
        disasm_view._t_flow_graph_visible = True
        disasm_view.display_function(func)
        disasm_view.decompile_current_function()
        main.workspace.instance.join_all_jobs()
        pseudocode_view = main.workspace._get_or_create_pseudocode_view()

        # find an arbitrary node for a variable
        for _, item in pseudocode_view.codegen.map_pos_to_node.items():
            if isinstance(item.obj, angr.analyses.decompiler.structured_codegen.c.CVariable) \
                    and item.obj.unified_variable is not None:
                variable_node = item.obj
                break
        else:
            self.fail("Cannot find a testing variable.")

        # rename the variable in the pseudocode view
        rnode = RenameNode(code_view=pseudocode_view, node=variable_node)
        rnode._name_box.setText("")
        QTest.keyClicks(rnode._name_box, "fdsa")
        QTest.mouseClick(rnode._ok_button, Qt.MouseButton.LeftButton)

        self.assertEqual(variable_node.unified_variable.name, "fdsa")

        sleep(5)
        self.session = Slacrs(database=Conf.checrs_backend_str).session()
        variable_rename = self.session.query(HumanActivity).filter(
            HumanActivity.project_md5 == self.project_md5,
            HumanActivity.new_name == "fdsa",
        ).one()
        self.session.close()
        self.assertIsNotNone(variable_rename)
Exemple #4
0
 def rename_function(self, main, func, new_function_name):
     """
     Renames a given function
     """
     disasm_view = main.workspace._get_or_create_disassembly_view()
     disasm_view._t_flow_graph_visible = True
     disasm_view.display_function(func)
     disasm_view.decompile_current_function()
     main.workspace.instance.join_all_jobs()
     pseudocode_view = main.workspace._get_or_create_pseudocode_view()
     for _, item in pseudocode_view.codegen.map_pos_to_node.items():
         if isinstance(
                 item.obj,
                 angr.analyses.decompiler.structured_codegen.c.CFunction):
             func_node = item.obj
             break
     else:
         self.fail("The CFunction _instance is not found.")
     rnode = RenameNode(code_view=pseudocode_view, node=func_node)
     rnode._name_box.setText("")
     QTest.keyClicks(rnode._name_box, new_function_name)
     QTest.mouseClick(rnode._ok_button, Qt.MouseButton.LeftButton)
     self.assertEqual(func.name, new_function_name)
Exemple #5
0
    def rename_stack_variable(self, main, func, var_offset, new_var_name):
        """
        Renames a stack variable at a given function and offset
        """
        disasm_view = main.workspace._get_or_create_disassembly_view()
        disasm_view._t_flow_graph_visible = True
        disasm_view.display_function(func)
        disasm_view.decompile_current_function()
        main.workspace.instance.join_all_jobs()
        pseudocode_view = main.workspace._get_or_create_pseudocode_view()
        for _, item in pseudocode_view.codegen.map_pos_to_node.items():
            if isinstance(item.obj, angr.analyses.decompiler.structured_codegen.c.CVariable) and \
                    isinstance(item.obj.variable, angr.sim_variable.SimStackVariable) and \
                    item.obj.variable.offset == var_offset:
                var_node = item.obj
                break
        else:
            self.fail("The CVariable _instance is not found.")

        rnode = RenameNode(code_view=pseudocode_view, node=var_node)
        rnode._name_box.setText("")
        QTest.keyClicks(rnode._name_box, new_var_name)
        QTest.mouseClick(rnode._ok_button, Qt.MouseButton.LeftButton)
Exemple #6
0
    def test_function_rename(self):
        binpath = os.path.join(common.test_location, "x86_64", "fauxware")
        new_function_name = "leet_main"
        user_1 = "user_1"
        user_2 = "user_2"

        with tempfile.TemporaryDirectory() as sync_dir_path:
            # ====== USER 1 ======
            # setup GUI
            main = MainWindow(show=False)
            main.workspace.instance.project.am_obj = angr.Project(
                binpath, auto_load_libs=False)
            main.workspace.instance.project.am_event()
            main.workspace.instance.join_all_jobs()
            func = main.workspace.instance.project.kb.functions['main']
            self.assertIsNotNone(func)

            # find the binsync plugin
            # noinspection PyTypeChecker
            binsync_plugin = next(
                iter([
                    p for p in main.workspace.plugins.active_plugins
                    if "Binsync" in str(p)
                ]))  # type: BinsyncPlugin

            # configure, and connect
            config = SyncConfig(main.workspace.instance,
                                binsync_plugin.controller)
            config._user_edit.setText("")
            config._repo_edit.setText("")
            QTest.keyClicks(config._user_edit, user_1)
            QTest.keyClicks(config._repo_edit, sync_dir_path)
            # always init for first user
            QTest.mouseClick(config._initrepo_checkbox,
                             Qt.MouseButton.LeftButton)
            QTest.mouseClick(config._ok_button, Qt.MouseButton.LeftButton)

            self.assertTrue(binsync_plugin.controller.sync.connected)
            self.assertEqual(binsync_plugin.controller.sync.client.master_user,
                             user_1)

            # trigger a function rename in decompilation
            disasm_view = main.workspace._get_or_create_disassembly_view()
            disasm_view._t_flow_graph_visible = True
            disasm_view.display_function(func)
            disasm_view.decompile_current_function()
            main.workspace.instance.join_all_jobs()
            pseudocode_view = main.workspace._get_or_create_pseudocode_view()
            for _, item in pseudocode_view.codegen.map_pos_to_node.items():
                if isinstance(
                        item.obj, angr.analyses.decompiler.structured_codegen.
                        c.CFunction):
                    func_node = item.obj
                    break
            else:
                self.fail("The CFunction instance is not found.")
            rnode = RenameNode(code_view=pseudocode_view, node=func_node)
            rnode._name_box.setText("")
            QTest.keyClicks(rnode._name_box, new_function_name)
            QTest.mouseClick(rnode._ok_button, Qt.MouseButton.LeftButton)

            self.assertEqual(func.name, new_function_name)

            # assure a new commit makes it to the repo
            time.sleep(10)
            # reset the repo
            os.remove(sync_dir_path + "/.git/binsync.lock")

            # ====== USER 2 ======
            # setup GUI
            main = MainWindow(show=False)
            main.workspace.instance.project.am_obj = angr.Project(
                binpath, auto_load_libs=False)
            main.workspace.instance.project.am_event()
            main.workspace.instance.join_all_jobs()
            func = main.workspace.instance.project.kb.functions['main']
            self.assertIsNotNone(func)

            # find the binsync plugin
            # noinspection PyTypeChecker
            binsync_plugin = next(
                iter([
                    p for p in main.workspace.plugins.active_plugins
                    if "Binsync" in str(p)
                ]))  # type: BinsyncPlugin

            # configure, and connect
            config = SyncConfig(main.workspace.instance,
                                binsync_plugin.controller)
            config._user_edit.setText("")
            config._repo_edit.setText("")
            QTest.keyClicks(config._user_edit, user_2)
            QTest.keyClicks(config._repo_edit, sync_dir_path)
            QTest.mouseClick(config._ok_button, Qt.MouseButton.LeftButton)

            self.assertTrue(binsync_plugin.controller.sync.connected)
            self.assertEqual(binsync_plugin.controller.sync.client.master_user,
                             user_2)
            self.assertIn(
                user_1,
                [u.name for u in binsync_plugin.controller.sync.users()])

            # pull down the changes
            # TODO: this could be more GUI based
            sync_menu = SyncMenu(binsync_plugin.controller, [func])
            sync_menu._do_action("Sync", user_1, func)

            # get the current decompilation of the function
            func_code = binsync_plugin.controller.decompile_function(func)

            self.assertEqual(func_code.cfunc.name, new_function_name)
            self.assertEqual(func.name, new_function_name)

            common.app.exit(0)