From bcc96d643dc02a8ab7bda5bdc23b3ce5876d1d95 Mon Sep 17 00:00:00 2001 From: Burhan Rajgara Date: Sat, 27 Jul 2024 22:02:34 -0700 Subject: [PATCH] use decompiler addresses in ui --- .../decompiler_specific/deci_extras.py | 26 +++++++++--- .../src/patcherex2/decompiler_plugins/ui.py | 42 ++++++++++++++++--- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/decompiler-plugins/src/patcherex2/decompiler_plugins/decompiler_specific/deci_extras.py b/decompiler-plugins/src/patcherex2/decompiler_plugins/decompiler_specific/deci_extras.py index 786280a..1ae4e82 100644 --- a/decompiler-plugins/src/patcherex2/decompiler_plugins/decompiler_specific/deci_extras.py +++ b/decompiler-plugins/src/patcherex2/decompiler_plugins/decompiler_specific/deci_extras.py @@ -9,16 +9,32 @@ log = logging.getLogger("patcherex2") +def normalize_addr(deci: DecompilerInterface, addr): + if isinstance(deci,AngrInterface): + proj = deci.workspace.main_instance.project + offset = ( + proj.loader.main_object.mapped_base if proj.loader.main_object.pic else 0 + ) + return addr - offset + else: + return addr + +def denormalize_addr(deci: DecompilerInterface, addr): + if isinstance(deci,AngrInterface): + proj = deci.workspace.main_instance.project + offset = ( + proj.loader.main_object.mapped_base if proj.loader.main_object.pic else 0 + ) + return addr + offset + else: + return addr + def get_ctx_address(deci: DecompilerInterface): try: if isinstance(deci, AngrInterface): # NOTE: need to find actual api way to do this curr_view: DisassemblyView = deci.workspace.view_manager.current_tab - proj = deci.workspace.main_instance.project - offset = ( - proj.loader.main_object.mapped_base if proj.loader.main_object.pic else 0 - ) - return curr_view._insn_addr_on_context_menu - offset + return curr_view._insn_addr_on_context_menu elif isinstance(deci, GhidraDecompilerInterface): return deci.ghidra.currentAddress.getOffset() except Exception: diff --git a/decompiler-plugins/src/patcherex2/decompiler_plugins/ui.py b/decompiler-plugins/src/patcherex2/decompiler_plugins/ui.py index 82f013c..efe430f 100644 --- a/decompiler-plugins/src/patcherex2/decompiler_plugins/ui.py +++ b/decompiler-plugins/src/patcherex2/decompiler_plugins/ui.py @@ -2,7 +2,6 @@ import re import select # noqa: F401 - from libbs.ui.qt_objects import ( QAbstractItemView, QCheckBox, @@ -35,8 +34,8 @@ from PySide6.QtGui import QFont from PySide6.QtWidgets import QTextEdit else: - from PyQt5.QtWidgets import QTextEdit from PyQt5.QtGui import QFont + from PyQt5.QtWidgets import QTextEdit import logging @@ -139,7 +138,7 @@ def add_patch_list_row(self, patch_type, patch_args): loc = patch_args.get("addr", patch_args.get("addr_or_name", "")) if isinstance(loc, int): - loc = hex(loc) + loc = hex(denormalize_addr(self.controller.deci, loc)) self.patch_table.setCellWidget(self.patch_table.rowCount() - 1, 1, QLabel(loc)) remove_button = QPushButton("Remove") remove_button.clicked.connect(self.remove_patch) @@ -212,18 +211,38 @@ def edit_patch(self): button = self.sender() row = self.patch_table.indexAt(button.pos()).row() patch_type = self.patch_table.cellWidget(row, 0).text() - patch_args = self.controller.patches[row].args + patch_args = self.controller.patches[row].args.copy() + if "addr" in patch_args.keys(): + patch_args["addr"] = denormalize_addr( + self.controller.deci, patch_args["addr"] + ) + if "addr_or_name" in patch_args.keys() and isinstance( + patch_args["addr_or_name"], int + ): + patch_args["addr_or_name"] = denormalize_addr( + self.controller.deci, patch_args["addr_or_name"] + ) patch_args = { k: hex(v) if isinstance(v, int) else v for k, v in patch_args.items() } dialog = PatchCreateDialog(patch_type, patch_args) dialog.exec_() new_patch_args = dialog.get_values() + if "addr" in patch_args.keys(): + patch_args["addr"] = normalize_addr( + self.controller.deci, patch_args["addr"] + ) + if "addr_or_name" in patch_args.keys() and isinstance( + patch_args["addr_or_name"], int + ): + patch_args["addr_or_name"] = normalize_addr( + self.controller.deci, patch_args["addr_or_name"] + ) self.controller.patches[row] = UIPatch(patch_type, new_patch_args) loc = new_patch_args.get("addr", new_patch_args.get("addr_or_name", "")) if isinstance(loc, int): - loc = hex(loc) + loc = hex(denormalize_addr(self.controller.deci, loc)) self.patch_table.cellWidget(row, 1).setText(loc) def add_patch_script_editor(self): @@ -377,7 +396,7 @@ def patch_binary(self): QMessageBox.critical(None, "Error", f"Failed to patch binary: {e}") return QMessageBox.information(None, "Success", "Binary patched!") - self.controller.patched_patches = self.controller.patches.copy() + self.controller.patched_patches = self.controller.patches.copy() dialog = LoadBinaryDialog() if dialog.exec() == QDialog.Accepted: load_patched_binary(self.controller.deci, binary_path=binary_path) @@ -398,6 +417,17 @@ def add_patch(self): return patch_args = dialog.get_values() + if "addr" in patch_args.keys(): + patch_args["addr"] = normalize_addr( + self.controller.deci, patch_args["addr"] + ) + if "addr_or_name" in patch_args.keys() and isinstance( + patch_args["addr_or_name"], int + ): + patch_args["addr_or_name"] = normalize_addr( + self.controller.deci, patch_args["addr_or_name"] + ) + self.add_patch_list_row(patch_type, patch_args) self.controller.patches.append(UIPatch(patch_type, patch_args))