From 29fb74efa29ec54296016d963724315e743689fa Mon Sep 17 00:00:00 2001 From: Dreg Date: Fri, 26 Apr 2024 17:35:03 +0200 Subject: [PATCH] add layout mapping API for external plugins (#1093) ## Description This fixes all the issues with the context panes and it now works as it did before the plugins were created. In the GEF part, it was just a minor refactor and a new external API. In the gef-extras part, it was only necessary to call this new function! I think the proposed solution is simple and it works. Related to hugsy/gef-extras#111 --- docs/api.md | 25 +++++++++++++++++++++++++ gef.py | 15 +++++++++++++-- scripts/gef-extras.sh | 4 +++- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/docs/api.md b/docs/api.md index 214bf836e..ef381ee3b 100644 --- a/docs/api.md +++ b/docs/api.md @@ -121,6 +121,31 @@ def register_external_context_pane( * `condition_callback` (optional): a function that returns a boolean deciding whether this context pane should be shown +### Context Layout Mapping API + +This API is designed for registering a new layout mapping for a GEF Context View. It specifies +the interface for the function register_external_context_layout_mapping which operates similarly +to the previously discussed register_external_context_pane. Pane must have been previously +established in the layout configuration. + +```python +def register_external_context_layout_mapping( + current_pane_name: str, + display_pane_function: Callable[[], None], + pane_title_function: Callable[[], Optional[str]], + condition: Optional[Callable[[], bool]] = None +) -> None: +``` + +Registers a new mapping for an existing pane within the GEF Context View. + +* `current_pane_name`: the name of an already registered pane in the layout +* `display_pane_function`: a function that prints content in the pane using `gef_print()` +* `pane_title_function`: a function that returns a string to be used as the pane title or +None if no title should be displayed +* `condition`: (optional) a predicate function that must return True for the pane content +and title to be displayed; if it returns False, the pane is skipped + ## API Some of the most important parts of the API for creating new commands are mentioned (but not limited diff --git a/gef.py b/gef.py index 2b8b13f66..d05f918ef 100644 --- a/gef.py +++ b/gef.py @@ -4550,6 +4550,10 @@ def pane_title(): gef.gdb.add_context_pane(pane_name, display_pane_function, pane_title_function, condition) return +def register_external_context_layout_mapping(current_pane_name: str, display_pane_function: Callable[[], None], pane_title_function: Callable[[], Optional[str]], condition : Optional[Callable[[], bool]] = None) -> None: + gef.gdb.add_context_layout_mapping(current_pane_name, display_pane_function, pane_title_function, condition) + return + # # Commands @@ -9836,6 +9840,14 @@ def invoke(self, args: Any, from_tty: bool) -> None: gdb.execute("gef help") return + def add_context_layout_mapping(self, current_pane_name: str, display_pane_function: Callable, pane_title_function: Callable, condition: Optional[Callable]) -> None: + """Add a new context layout mapping.""" + context = self.commands["context"] + assert isinstance(context, ContextCommand) + + # overload the printing of pane title + context.layout_mapping[current_pane_name] = (display_pane_function, pane_title_function, condition) + def add_context_pane(self, pane_name: str, display_pane_function: Callable, pane_title_function: Callable, condition: Optional[Callable]) -> None: """Add a new context pane to ContextCommand.""" context = self.commands["context"] @@ -9845,8 +9857,7 @@ def add_context_pane(self, pane_name: str, display_pane_function: Callable, pane corrected_settings_name: str = pane_name.replace(" ", "_") gef.config["context.layout"] += f" {corrected_settings_name}" - # overload the printing of pane title - context.layout_mapping[corrected_settings_name] = (display_pane_function, pane_title_function, condition) + add_context_layout_mapping(corrected_settings_name, display_pane_function, pane_title_function, condition) def load(self) -> None: """Load all the commands and functions defined by GEF into GDB.""" diff --git a/scripts/gef-extras.sh b/scripts/gef-extras.sh index fc8fa7b33..8b7311381 100755 --- a/scripts/gef-extras.sh +++ b/scripts/gef-extras.sh @@ -38,7 +38,9 @@ fi git clone --branch ${branch} https://github.com/hugsy/gef-extras.git "${DIR}" ver=$(gdb -q -nx -ex 'pi print(f"{sys.version_info.major}.{sys.version_info.minor}", end="")' -ex quit) python${ver} -m pip install --requirement "${DIR}"/requirements.txt --upgrade -gdb -q -ex "gef config gef.extra_plugins_dir '${DIR}/scripts'" \ +gdb -q -ex "pi gef.config['context.layout'] += ' syscall_args'" \ + -ex "pi gef.config['context.layout'] += ' libc_function_args'" \ + -ex "gef config gef.extra_plugins_dir '${DIR}/scripts'" \ -ex "gef config pcustom.struct_path '${DIR}/structs'" \ -ex "gef config syscall-args.path '${DIR}/syscall-tables'" \ -ex "gef config context.libc_args True" \