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)
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)
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)
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)