From a6f4cc186a33baad62008e5bca3b558b78a41cf8 Mon Sep 17 00:00:00 2001 From: Alexander Zhang Date: Sat, 22 Apr 2023 07:44:56 -0700 Subject: [PATCH 01/21] Fix typo in docs (#949) --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index a8a8f293d..d1e6a2117 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,7 +17,7 @@ distros start pushing `gdb` compiled with Python3 support). * **One** single GDB script * Entirely **architecture agnostic**, **NO** dependencies: `GEF` is battery-included and [is installable instantly](https://hugsy.github.io/gef/#setup) - * **Fast** limiting the number of dependencies and optimizing code to makethe commands as fast as possible + * **Fast** limiting the number of dependencies and optimizing code to make the commands as fast as possible * Provides a great variety of commands to drastically change your debugging experience in GDB. * [**Easily** extensible](https://hugsy.github.io/gef/api/) to create other commands by providing more comprehensible layout to GDB Python API. * Full Python3 support ([Python2 support was dropped in 2020.03](https://github.com/hugsy/gef/releases/tag/2020.03)) - check out [`gef-legacy`](https://github.com/hugsy/gef-legacy) for a Python2 compatible version, and [the compatibility matrix](/docs/compat.md) for a complete rundown of version support. From ac732170ba209473aff42413bc1d076f52bd4b87 Mon Sep 17 00:00:00 2001 From: crazy hugsy Date: Mon, 24 Apr 2023 08:38:03 -0700 Subject: [PATCH 02/21] [ci] coverage use dedicated token --- .github/workflows/coverage.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index a5933c6cc..f755a9b2c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,6 +1,8 @@ name: CI Coverage -on: [pull_request] +on: + pull_request: + types: [opened, edited] jobs: coverage: @@ -38,13 +40,14 @@ jobs: SCORE_NEW: ${{ steps.get_coverage.outputs.new_coverage_score }} SCORE_DIFF: ${{ steps.get_coverage.outputs.diff_score }} with: + github-token: ${{ secrets.COVERAGE_REPORT_TOKEN }} script: | const comment = `## 🤖 Coverage Update * Commit: ${process.env.COMMIT} * Current Coverage: ${process.env.SCORE_OLD}% * New Coverage: ${process.env.SCORE_NEW}% - * Diff: ${process.env.SCORE_DIFF} + * Diff: ${process.env.SCORE_DIFF} `; const { owner, repo, number } = context.issue; await github.rest.issues.createComment({ owner, repo, issue_number: number, body: comment }); From 102288fd3e3be65e4a3b41579cb864dc2d4818c4 Mon Sep 17 00:00:00 2001 From: Alexander Zhang Date: Tue, 25 Apr 2023 08:56:02 -0700 Subject: [PATCH 03/21] Update sentence about Python version in docs (#948) Python 2 is no longer supported and can only be used with gef-legacy. --- docs/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index d1e6a2117..fece54116 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,8 +8,7 @@ be used mostly by exploit developers and reverse-engineers, to provide additional features to GDB using the Python API to assist during the process of dynamic analysis and exploit development. -It has full support for both Python2 and Python3 indifferently (as more and more -distros start pushing `gdb` compiled with Python3 support). +It requires Python 3, but [`gef-legacy`](https://github.com/hugsy/gef-legacy) can be used if Python 2 support is needed. ![gef-context](https://i.imgur.com/E3EuQPs.png) From 91f4d708d6feab4a997866efac56121aecf6b4f9 Mon Sep 17 00:00:00 2001 From: crazy hugsy Date: Sat, 27 May 2023 13:07:08 -0700 Subject: [PATCH 04/21] [docs] Regenerating `api/gef.md` (#951) * [scripts] make `new-release` get the latest tags * Re-generating `gef.md` Fixes #950 --- docs/api/gef.md | 23212 +++++++++++++++++++++++++++++++++++++++ scripts/new-release.py | 2 +- 2 files changed, 23213 insertions(+), 1 deletion(-) diff --git a/docs/api/gef.md b/docs/api/gef.md index e69de29bb..79af99b75 100644 --- a/docs/api/gef.md +++ b/docs/api/gef.md @@ -0,0 +1,23212 @@ + + +# module `GEF` + + + + +**Global Variables** +--------------- +- **GEF_DEFAULT_BRANCH** +- **GEF_EXTRAS_DEFAULT_BRANCH** +- **GDB_MIN_VERSION** +- **GDB_VERSION** +- **PYTHON_MIN_VERSION** +- **PYTHON_VERSION** +- **DEFAULT_PAGE_ALIGN_SHIFT** +- **DEFAULT_PAGE_SIZE** +- **GEF_TEMP_DIR** +- **GEF_MAX_STRING_LENGTH** +- **LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME** +- **ANSI_SPLIT_RE** +- **LEFT_ARROW** +- **RIGHT_ARROW** +- **DOWN_ARROW** +- **HORIZONTAL_LINE** +- **VERTICAL_LINE** +- **CROSS** +- **TICK** +- **BP_GLYPH** +- **GEF_PROMPT** +- **GEF_PROMPT_ON** +- **GEF_PROMPT_OFF** +- **PREFIX** +- **gdb_initial_settings** +- **cmd** +- **gef** +- **errmsg** + +--- + + + +## function `http_get` + +```python +http_get(url: str) → Optional[bytes] +``` + +Basic HTTP wrapper for GET request. Return the body of the page if HTTP code is OK, otherwise return None. + + +--- + + + +## function `update_gef` + +```python +update_gef(argv: List[str]) → int +``` + +Try to update `gef` to the latest version pushed on GitHub main branch. Return 0 on success, 1 on failure. + + +--- + + + +## function `reset_all_caches` + +```python +reset_all_caches() → None +``` + +Free all caches. If an object is cached, it will have a callable attribute `cache_clear` which will be invoked to purge the function cache. + + +--- + + + +## function `reset` + +```python +reset() → None +``` + + + + + + +--- + + + +## function `highlight_text` + +```python +highlight_text(text: str) → str +``` + +Highlight text using `gef.ui.highlight_table` { match -> color } settings. + +If RegEx is enabled it will create a match group around all items in the `gef.ui.highlight_table` and wrap the specified color in the `gef.ui.highlight_table` around those matches. + +If RegEx is disabled, split by ANSI codes and 'colorify' each match found within the specified string. + + +--- + + + +## function `gef_print` + +```python +gef_print(*args: str, end='\n', sep=' ', **kwargs: Any) → None +``` + +Wrapper around print(), using string buffering feature. + + +--- + + + +## function `bufferize` + +```python +bufferize(f: Callable) → Callable +``` + +Store the content to be printed for a function in memory, and flush it on function exit. + + +--- + + + +## function `p8` + +```python +p8( + x: int, + s: bool = False, + e: Optional[ForwardRef('Endianness')] = None +) → bytes +``` + +Pack one byte respecting the current architecture endianness. + + +--- + + + +## function `p16` + +```python +p16( + x: int, + s: bool = False, + e: Optional[ForwardRef('Endianness')] = None +) → bytes +``` + +Pack one word respecting the current architecture endianness. + + +--- + + + +## function `p32` + +```python +p32( + x: int, + s: bool = False, + e: Optional[ForwardRef('Endianness')] = None +) → bytes +``` + +Pack one dword respecting the current architecture endianness. + + +--- + + + +## function `p64` + +```python +p64( + x: int, + s: bool = False, + e: Optional[ForwardRef('Endianness')] = None +) → bytes +``` + +Pack one qword respecting the current architecture endianness. + + +--- + + + +## function `u8` + +```python +u8( + x: bytes, + s: bool = False, + e: Optional[ForwardRef('Endianness')] = None +) → int +``` + +Unpack one byte respecting the current architecture endianness. + + +--- + + + +## function `u16` + +```python +u16( + x: bytes, + s: bool = False, + e: Optional[ForwardRef('Endianness')] = None +) → int +``` + +Unpack one word respecting the current architecture endianness. + + +--- + + + +## function `u32` + +```python +u32( + x: bytes, + s: bool = False, + e: Optional[ForwardRef('Endianness')] = None +) → int +``` + +Unpack one dword respecting the current architecture endianness. + + +--- + + + +## function `u64` + +```python +u64( + x: bytes, + s: bool = False, + e: Optional[ForwardRef('Endianness')] = None +) → int +``` + +Unpack one qword respecting the current architecture endianness. + + +--- + + + +## function `is_ascii_string` + +```python +is_ascii_string(address: int) → bool +``` + +Helper function to determine if the buffer pointed by `address` is an ASCII string (in GDB) + + +--- + + + +## function `is_alive` + +```python +is_alive() → bool +``` + +Check if GDB is running. + + +--- + + + +## function `calling_function` + +```python +calling_function() → Optional[str] +``` + +Return the name of the calling function + + +--- + + + +## function `only_if_gdb_running` + +```python +only_if_gdb_running(f: Callable) → Callable +``` + +Decorator wrapper to check if GDB is running. + + +--- + + + +## function `only_if_gdb_target_local` + +```python +only_if_gdb_target_local(f: Callable) → Callable +``` + +Decorator wrapper to check if GDB is running locally (target not remote). + + +--- + + + +## function `deprecated` + +```python +deprecated(solution: str = '') → Callable +``` + +Decorator to add a warning when a command is obsolete and will be removed. + + +--- + + + +## function `experimental_feature` + +```python +experimental_feature(f: Callable) → Callable +``` + +Decorator to add a warning when a feature is experimental. + + +--- + + + +## function `only_if_events_supported` + +```python +only_if_events_supported(event_type: str) → Callable +``` + +Checks if GDB supports events without crashing. + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Any, **kwargs: Any) → Any +``` + + + + + + +--- + + + +## function `FakeExit` + +```python +FakeExit(*args: Any, **kwargs: Any) → NoReturn +``` + + + + + + +--- + + + +## function `parse_arguments` + +```python +parse_arguments( + required_arguments: Dict[Union[str, Tuple[str, str]], Any], + optional_arguments: Dict[Union[str, Tuple[str, str]], Any] +) → Callable +``` + +Argument parsing decorator. + + +--- + + + +## function `search_for_main_arena` + +```python +search_for_main_arena() → int +``` + +`search_for_main_arena` is **DEPRECATED** and will be removed in the future. Use GefHeapManager.find_main_arena_addr() + + +--- + + + +## function `get_libc_version` + +```python +get_libc_version() → Tuple[int, ...] +``` + +`get_libc_version` is **DEPRECATED** and will be removed in the future. Use GefLibcManager.find_libc_version() + + +--- + + + +## function `titlify` + +```python +titlify( + text: str, + color: Optional[str] = None, + msg_color: Optional[str] = None +) → str +``` + +Print a centered title. + + +--- + + + +## function `dbg` + +```python +dbg(msg: str) → None +``` + + + + + + +--- + + + +## function `err` + +```python +err(msg: str) → None +``` + + + + + + +--- + + + +## function `warn` + +```python +warn(msg: str) → None +``` + + + + + + +--- + + + +## function `ok` + +```python +ok(msg: str) → None +``` + + + + + + +--- + + + +## function `info` + +```python +info(msg: str) → None +``` + + + + + + +--- + + + +## function `push_context_message` + +```python +push_context_message(level: str, message: str) → None +``` + +Push the message to be displayed the next time the context is invoked. + + +--- + + + +## function `show_last_exception` + +```python +show_last_exception() → None +``` + +Display the last Python exception. + + +--- + + + +## function `gef_pystring` + +```python +gef_pystring(x: bytes) → str +``` + +Returns a sanitized version as string of the bytes list given in input. + + +--- + + + +## function `gef_pybytes` + +```python +gef_pybytes(x: str) → bytes +``` + +Returns an immutable bytes list from the string given as input. + + +--- + + + +## function `style_byte` + +```python +style_byte(b: int, color: bool = True) → str +``` + + + + + + +--- + + + +## function `hexdump` + +```python +hexdump( + source: ByteString, + length: int = 16, + separator: str = '.', + show_raw: bool = False, + show_symbol: bool = True, + base: int = 0 +) → str +``` + +Return the hexdump of `src` argument. @param source *MUST* be of type bytes or bytearray @param length is the length of items per line @param separator is the default character to use if one byte is not printable @param show_raw if True, do not add the line nor the text translation @param base is the start address of the block being hexdump @return a string with the hexdump + + +--- + + + +## function `is_debug` + +```python +is_debug() → bool +``` + +Check if debug mode is enabled. + + +--- + + + +## function `buffer_output` + +```python +buffer_output() → bool +``` + +Check if output should be buffered until command completion. + + +--- + + + +## function `hide_context` + +```python +hide_context() → bool +``` + +Helper function to hide the context pane. + + +--- + + + +## function `unhide_context` + +```python +unhide_context() → bool +``` + +Helper function to unhide the context pane. + + +--- + + + +## function `enable_redirect_output` + +```python +enable_redirect_output(to_file: str = '/dev/null') → None +``` + +Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`. + + +--- + + + +## function `disable_redirect_output` + +```python +disable_redirect_output() → None +``` + +Disable the output redirection, if any. + + +--- + + + +## function `gef_makedirs` + +```python +gef_makedirs(path: str, mode: int = 493) → Path +``` + +Recursive mkdir() creation. If successful, return the absolute path of the directory created. + + +--- + + + +## function `gdb_disassemble` + +```python +gdb_disassemble( + start_pc: int, + **kwargs: int +) → Generator[__main__.Instruction, NoneType, NoneType] +``` + +Disassemble instructions from `start_pc` (Integer). Accepts the following named + +**parameters:** + +- `end_pc` (Integer) only instructions whose start address fall in the interval from start_pc to end_pc are returned. +- `count` (Integer) list at most this many disassembled instructions If `end_pc` and `count` are not provided, the function will behave as if `count=1`. Return an iterator of Instruction objects + + +--- + + + +## function `gdb_get_nth_previous_instruction_address` + +```python +gdb_get_nth_previous_instruction_address(addr: int, n: int) → Optional[int] +``` + +Return the address (Integer) of the `n`-th instruction before `addr`. + + +--- + + + +## function `gdb_get_nth_next_instruction_address` + +```python +gdb_get_nth_next_instruction_address(addr: int, n: int) → int +``` + +Return the address (Integer) of the `n`-th instruction after `addr`. + + +--- + + + +## function `gef_instruction_n` + +```python +gef_instruction_n(addr: int, n: int) → Instruction +``` + +Return the `n`-th instruction after `addr` as an Instruction object. + + +--- + + + +## function `gef_get_instruction_at` + +```python +gef_get_instruction_at(addr: int) → Instruction +``` + +Return the full Instruction found at the specified address. + + +--- + + + +## function `gef_current_instruction` + +```python +gef_current_instruction(addr: int) → Instruction +``` + +Return the current instruction as an Instruction object. + + +--- + + + +## function `gef_next_instruction` + +```python +gef_next_instruction(addr: int) → Instruction +``` + +Return the next instruction as an Instruction object. + + +--- + + + +## function `gef_disassemble` + +```python +gef_disassemble( + addr: int, + nb_insn: int, + nb_prev: int = 0 +) → Generator[__main__.Instruction, NoneType, NoneType] +``` + +Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr`. Return an iterator of Instruction objects. + + +--- + + + +## function `gef_execute_external` + +```python +gef_execute_external( + command: Sequence[str], + as_list: bool = False, + **kwargs: Any +) → Union[str, List[str]] +``` + +Execute an external command and return the result. + + +--- + + + +## function `gef_execute_gdb_script` + +```python +gef_execute_gdb_script(commands: str) → None +``` + +Execute the parameter `source` as GDB command. This is done by writing `commands` to a temporary file, which is then executed via GDB `source` command. The tempfile is then deleted. + + +--- + + + +## function `checksec` + +```python +checksec(filename: str) → Dict[str, bool] +``` + +`checksec` is **DEPRECATED** and will be removed in the future. Use Elf(fname).checksec() + + +--- + + + +## function `get_entry_point` + +```python +get_entry_point() → Optional[int] +``` + +Return the binary entry point. `get_entry_point` is **DEPRECATED** and will be removed in the future. Use `gef.binary.entry_point` instead + + +--- + + + +## function `is_pie` + +```python +is_pie(fpath: str) → bool +``` + + + + + + +--- + + + +## function `is_big_endian` + +```python +is_big_endian() → bool +``` + +`is_big_endian` is **DEPRECATED** and will be removed in the future. Prefer `gef.arch.endianness == Endianness.BIG_ENDIAN` + + +--- + + + +## function `is_little_endian` + +```python +is_little_endian() → bool +``` + +`is_little_endian` is **DEPRECATED** and will be removed in the future. gef.arch.endianness == Endianness.LITTLE_ENDIAN + + +--- + + + +## function `flags_to_human` + +```python +flags_to_human(reg_value: int, value_table: Dict[int, str]) → str +``` + +Return a human readable string showing the flag states. + + +--- + + + +## function `register_architecture` + +```python +register_architecture( + cls: Type[ForwardRef('Architecture')] +) → Type[ForwardRef('Architecture')] +``` + +`register_architecture` is **DEPRECATED** and will be removed in the future. Using the decorator `register_architecture` is unecessary + + +--- + + + +## function `copy_to_clipboard` + +```python +copy_to_clipboard(data: bytes) → None +``` + +Helper function to submit data to the clipboard + + +--- + + + +## function `use_stdtype` + +```python +use_stdtype() → str +``` + + + + + + +--- + + + +## function `use_default_type` + +```python +use_default_type() → str +``` + + + + + + +--- + + + +## function `use_golang_type` + +```python +use_golang_type() → str +``` + + + + + + +--- + + + +## function `use_rust_type` + +```python +use_rust_type() → str +``` + + + + + + +--- + + + +## function `to_unsigned_long` + +```python +to_unsigned_long(v: gdb.Value) → int +``` + +Cast a gdb.Value to unsigned long. + + +--- + + + +## function `get_path_from_info_proc` + +```python +get_path_from_info_proc() → Optional[str] +``` + + + + + + +--- + + + +## function `get_os` + +```python +get_os() → str +``` + +`get_os` is **DEPRECATED** and will be removed in the future. Use `gef.session.os` + + +--- + + + +## function `get_filepath` + +```python +get_filepath() → Optional[str] +``` + +Return the local absolute path of the file currently debugged. + + +--- + + + +## function `get_function_length` + +```python +get_function_length(sym: str) → int +``` + +Attempt to get the length of the raw bytes of a function. + + +--- + + + +## function `process_lookup_address` + +```python +process_lookup_address(address: int) → Optional[__main__.Section] +``` + +Look up for an address in memory. Return an Address object if found, None otherwise. + + +--- + + + +## function `xor` + +```python +xor(data: ByteString, key: str) → bytearray +``` + +Return `data` xor-ed with `key`. + + +--- + + + +## function `is_hex` + +```python +is_hex(pattern: str) → bool +``` + +Return whether provided string is a hexadecimal value. + + +--- + + + +## function `continue_handler` + +```python +continue_handler(_: 'gdb.Event') → None +``` + +GDB event handler for new object continue cases. + + +--- + + + +## function `hook_stop_handler` + +```python +hook_stop_handler(_: 'gdb.StopEvent') → None +``` + +GDB event handler for stop cases. + + +--- + + + +## function `new_objfile_handler` + +```python +new_objfile_handler(evt: Optional[ForwardRef('gdb.NewObjFileEvent')]) → None +``` + +GDB event handler for new object file cases. + + +--- + + + +## function `exit_handler` + +```python +exit_handler(_: 'gdb.ExitedEvent') → None +``` + +GDB event handler for exit cases. + + +--- + + + +## function `memchanged_handler` + +```python +memchanged_handler(_: 'gdb.MemoryChangedEvent') → None +``` + +GDB event handler for mem changes cases. + + +--- + + + +## function `regchanged_handler` + +```python +regchanged_handler(_: 'gdb.RegisterChangedEvent') → None +``` + +GDB event handler for reg changes cases. + + +--- + + + +## function `get_terminal_size` + +```python +get_terminal_size() → Tuple[int, int] +``` + +Return the current terminal size. + + +--- + + + +## function `reset_architecture` + +```python +reset_architecture(arch: Optional[str] = None) → None +``` + +Sets the current architecture. If an architecture is explicitly specified by parameter, try to use that one. If this fails, an `OSError` exception will occur. If no architecture is specified, then GEF will attempt to determine automatically based on the current ELF target. If this fails, an `OSError` exception will occur. + + +--- + + + +## function `get_memory_alignment` + +```python +get_memory_alignment(in_bits: bool = False) → int +``` + +Try to determine the size of a pointer on this system. First, try to parse it out of the ELF header. Next, use the size of `size_t`. Finally, try the size of $pc. If `in_bits` is set to True, the result is returned in bits, otherwise in bytes. `get_memory_alignment` is **DEPRECATED** and will be removed in the future. Use `gef.arch.ptrsize` instead + + +--- + + + +## function `clear_screen` + +```python +clear_screen(tty: str = '') → None +``` + +Clear the screen. + + +--- + + + +## function `format_address` + +```python +format_address(addr: int) → str +``` + +Format the address according to its size. + + +--- + + + +## function `format_address_spaces` + +```python +format_address_spaces(addr: int, left: bool = True) → str +``` + +Format the address according to its size, but with spaces instead of zeroes. + + +--- + + + +## function `align_address` + +```python +align_address(address: int) → int +``` + +Align the provided address to the process's native length. + + +--- + + + +## function `align_address_to_size` + +```python +align_address_to_size(address: int, align: int) → int +``` + +Align the address to the given size. + + +--- + + + +## function `align_address_to_page` + +```python +align_address_to_page(address: int) → int +``` + +Align the address to a page. + + +--- + + + +## function `parse_address` + +```python +parse_address(address: str) → int +``` + +Parse an address and return it as an Integer. + + +--- + + + +## function `is_in_x86_kernel` + +```python +is_in_x86_kernel(address: int) → bool +``` + + + + + + +--- + + + +## function `is_remote_debug` + +```python +is_remote_debug() → bool +``` + +"Return True is the current debugging session is running through GDB remote session. + + +--- + + + +## function `de_bruijn` + +```python +de_bruijn(alphabet: bytes, n: int) → Generator[str, NoneType, NoneType] +``` + +De Bruijn sequence for alphabet and subsequences of length n (for compat. w/ pwnlib). + + +--- + + + +## function `generate_cyclic_pattern` + +```python +generate_cyclic_pattern(length: int, cycle: int = 4) → bytearray +``` + +Create a `length` byte bytearray of a de Bruijn cyclic pattern. + + +--- + + + +## function `safe_parse_and_eval` + +```python +safe_parse_and_eval(value: str) → Optional[ForwardRef('gdb.Value')] +``` + +GEF wrapper for gdb.parse_and_eval(): this function returns None instead of raising gdb.error if the eval failed. + + +--- + + + +## function `gef_convenience` + +```python +gef_convenience(value: Union[str, bytes]) → str +``` + +Defines a new convenience value. + + +--- + + + +## function `parse_string_range` + +```python +parse_string_range(s: str) → Iterator[int] +``` + +Parses an address range (e.g. 0x400000-0x401000) + + +--- + + + +## function `gef_get_pie_breakpoint` + +```python +gef_get_pie_breakpoint(num: int) → PieVirtualBreakpoint +``` + +`gef_get_pie_breakpoint` is **DEPRECATED** and will be removed in the future. Use `gef.session.pie_breakpoints[num]` + + +--- + + + +## function `endian_str` + +```python +endian_str() → str +``` + +`endian_str` is **DEPRECATED** and will be removed in the future. Use `str(gef.arch.endianness)` instead + + +--- + + + +## function `get_gef_setting` + +```python +get_gef_setting(name: str) → Any +``` + +`get_gef_setting` is **DEPRECATED** and will be removed in the future. Use `gef.config[key]` + + +--- + + + +## function `set_gef_setting` + +```python +set_gef_setting(name: str, value: Any) → None +``` + +`set_gef_setting` is **DEPRECATED** and will be removed in the future. Use `gef.config[key] = value` + + +--- + + + +## function `gef_getpagesize` + +```python +gef_getpagesize() → int +``` + +`gef_getpagesize` is **DEPRECATED** and will be removed in the future. Use `gef.session.pagesize` + + +--- + + + +## function `gef_read_canary` + +```python +gef_read_canary() → Optional[Tuple[int, int]] +``` + +`gef_read_canary` is **DEPRECATED** and will be removed in the future. Use `gef.session.canary` + + +--- + + + +## function `get_pid` + +```python +get_pid() → int +``` + +`get_pid` is **DEPRECATED** and will be removed in the future. Use `gef.session.pid` + + +--- + + + +## function `get_filename` + +```python +get_filename() → str +``` + +`get_filename` is **DEPRECATED** and will be removed in the future. Use `gef.session.file.name` + + +--- + + + +## function `get_glibc_arena` + +```python +get_glibc_arena() → Optional[__main__.GlibcArena] +``` + +`get_glibc_arena` is **DEPRECATED** and will be removed in the future. Use `gef.heap.main_arena` + + +--- + + + +## function `get_register` + +```python +get_register(regname) → Optional[int] +``` + +`get_register` is **DEPRECATED** and will be removed in the future. Use `gef.arch.register(regname)` + + +--- + + + +## function `get_process_maps` + +```python +get_process_maps() → List[__main__.Section] +``` + +`get_process_maps` is **DEPRECATED** and will be removed in the future. Use `gef.memory.maps` + + +--- + + + +## function `set_arch` + +```python +set_arch(arch: Optional[str] = None, _: Optional[str] = None) → None +``` + +`set_arch` is **DEPRECATED** and will be removed in the future. Use `reset_architecture` + + +--- + + + +## function `register_external_context_pane` + +```python +register_external_context_pane( + pane_name: str, + display_pane_function: Callable[[], NoneType], + pane_title_function: Callable[[], Optional[str]], + condition: Optional[Callable[[], bool]] = None +) → None +``` + +Registering function for new GEF Context View. pane_name: a string that has no spaces (used in settings) display_pane_function: a function that uses gef_print() to print strings pane_title_function: a function that returns a string or None, which will be displayed as the title. If None, no title line is displayed. condition: an optional callback: if not None, the callback will be executed first. If it returns true, then only the pane title and content will displayed. Otherwise, it's simply skipped. + +Example usage for a simple text to show when we hit a syscall: def only_syscall(): return gef_current_instruction(gef.arch.pc).is_syscall() def display_pane(): gef_print("Wow, I am a context pane!") def pane_title(): return "example:pane" register_external_context_pane("example_pane", display_pane, pane_title, only_syscall) + + +--- + + + +## function `register_external_command` + +```python +register_external_command( + cls: Type[ForwardRef('GenericCommand')] +) → Type[ForwardRef('GenericCommand')] +``` + +Registering function for new GEF (sub-)command to GDB. `register_external_command` is **DEPRECATED** and will be removed in the future. Use `register()`, and inherit from `GenericCommand` instead + + +--- + + + +## function `register_command` + +```python +register_command( + cls: Type[ForwardRef('GenericCommand')] +) → Type[ForwardRef('GenericCommand')] +``` + +Decorator for registering new GEF (sub-)command to GDB. `register_command` is **DEPRECATED** and will be removed in the future. Use `register()`, and inherit from `GenericCommand` instead + + +--- + + + +## function `register_priority_command` + +```python +register_priority_command( + cls: Type[ForwardRef('GenericCommand')] +) → Type[ForwardRef('GenericCommand')] +``` + +Decorator for registering new command with priority, meaning that it must loaded before the other generic commands. `register_priority_command` is **DEPRECATED** and will be removed in the future. + + +--- + + + +## function `register` + +```python +register( + cls: Union[Type[ForwardRef('GenericCommand')], Type[ForwardRef('GenericFunction')]] +) → Union[Type[ForwardRef('GenericCommand')], Type[ForwardRef('GenericFunction')]] +``` + + + + + + +--- + + + +## function `register_function` + +```python +register_function( + cls: Type[ForwardRef('GenericFunction')] +) → Type[ForwardRef('GenericFunction')] +``` + +Decorator for registering a new convenience function to GDB. `register_function` is **DEPRECATED** and will be removed in the future. + + +--- + +## class `AARCH64` + + + + + +--- + +#### property AARCH64.cpsr + + + + + +--- + +#### property AARCH64.endianness + + + + + +--- + +#### property AARCH64.fp + + + + + +--- + +#### property AARCH64.instruction_length + + + + + +--- + +#### property AARCH64.pc + + + + + +--- + +#### property AARCH64.ptrsize + +Determine the size of pointer from the current CPU mode + +--- + +#### property AARCH64.registers + + + + + +--- + +#### property AARCH64.sp + + + + + + + +--- + + + +## function `AARCH64.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `AARCH64.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `AARCH64.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `AARCH64.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → int +``` + + + + + +--- + + + +## function `AARCH64.is_aarch32` + +```python +is_aarch32() → bool +``` + +Determine if the CPU is currently in AARCH32 mode from runtime. + +--- + + + +## function `AARCH64.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `AARCH64.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `AARCH64.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `AARCH64.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `AARCH64.is_thumb` + +```python +is_thumb() → bool +``` + +Determine if the machine is currently in THUMB mode. + +--- + + + +## function `AARCH64.is_thumb32` + +```python +is_thumb32() → bool +``` + +Determine if the CPU is currently in THUMB32 mode from runtime. + +--- + + + +## function `AARCH64.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `AARCH64.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `AARCH64.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `AARCH64.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `ARM` + + + + + +--- + +#### property ARM.cpsr + + + + + +--- + +#### property ARM.endianness + + + + + +--- + +#### property ARM.fp + + + + + +--- + +#### property ARM.instruction_length + + + + + +--- + +#### property ARM.mode + + + + + +--- + +#### property ARM.pc + + + + + +--- + +#### property ARM.ptrsize + + + + + +--- + +#### property ARM.registers + + + + + +--- + +#### property ARM.sp + + + + + + + +--- + + + +## function `ARM.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `ARM.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `ARM.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `ARM.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → int +``` + + + + + +--- + + + +## function `ARM.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `ARM.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `ARM.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `ARM.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `ARM.is_thumb` + +```python +is_thumb() → bool +``` + +Determine if the machine is currently in THUMB mode. + +--- + + + +## function `ARM.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `ARM.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `ARM.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `ARM.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `ASLRCommand` +View/modify the ASLR setting of GDB. By default, GDB will disable ASLR when it starts the process. (i.e. not attached). This command allows to change that setting. + + + +## function `ASLRCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property ASLRCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ASLRCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ASLRCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ASLRCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `ASLRCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ASLRCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ASLRCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ASLRCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ASLRCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ASLRCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Address` +GEF representation of memory addresses. + + + +## function `Address.__init__` + +```python +__init__(**kwargs: Any) → None +``` + + + + + + +--- + +#### property Address.valid + + + + + + + +--- + + + +## function `Address.dereference` + +```python +dereference() → Optional[int] +``` + + + + + +--- + + + +## function `Address.is_in_heap_segment` + +```python +is_in_heap_segment() → bool +``` + + + + + +--- + + + +## function `Address.is_in_stack_segment` + +```python +is_in_stack_segment() → bool +``` + + + + + +--- + + + +## function `Address.is_in_text_segment` + +```python +is_in_text_segment() → bool +``` + + + + + + +--- + +## class `AliasesAddCommand` +Command to add aliases. + + + +## function `AliasesAddCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property AliasesAddCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `AliasesAddCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `AliasesAddCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `AliasesAddCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `AliasesAddCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `AliasesAddCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `AliasesAddCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `AliasesAddCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `AliasesAddCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `AliasesAddCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `AliasesCommand` +Base command to add, remove, or list aliases. + + + +## function `AliasesCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property AliasesCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `AliasesCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `AliasesCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `AliasesCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `AliasesCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `AliasesCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `AliasesCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `AliasesCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `AliasesCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `AliasesCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `AliasesListCommand` +Command to list aliases. + + + +## function `AliasesListCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property AliasesListCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `AliasesListCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `AliasesListCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `AliasesListCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `AliasesListCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `AliasesListCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `AliasesListCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `AliasesListCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `AliasesListCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `AliasesListCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `AliasesRmCommand` +Command to remove aliases. + + + +## function `AliasesRmCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property AliasesRmCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `AliasesRmCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `AliasesRmCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `AliasesRmCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `AliasesRmCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `AliasesRmCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `AliasesRmCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `AliasesRmCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `AliasesRmCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `AliasesRmCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Architecture` +Generic metaclass for the architecture supported by GEF. + + +--- + +#### property Architecture.endianness + + + + + +--- + +#### property Architecture.fp + + + + + +--- + +#### property Architecture.pc + + + + + +--- + +#### property Architecture.ptrsize + + + + + +--- + +#### property Architecture.registers + + + + + +--- + +#### property Architecture.sp + + + + + + + +--- + + + +## function `Architecture.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `Architecture.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `Architecture.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `Architecture.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int] +``` + + + + + +--- + + + +## function `Architecture.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `Architecture.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `Architecture.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `Architecture.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `Architecture.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `Architecture.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `Architecture.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `Architecture.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `ArchitectureBase` +Class decorator for declaring an architecture to GEF. + + + + + +--- + +## class `BssBaseFunction` +Return the current bss base address plus the given offset. + + + +## function `BssBaseFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `BssBaseFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +## function `BssBaseFunction.do_invoke` + +```python +do_invoke(args: List) → int +``` + + + + + +--- + + + +## function `BssBaseFunction.invoke` + +```python +invoke(*args: Any) → int +``` + + + + + + +--- + +## class `CanaryCommand` +Shows the canary value of the current process. + + + +## function `CanaryCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property CanaryCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `CanaryCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `CanaryCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `CanaryCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `CanaryCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `CanaryCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `CanaryCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `CanaryCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `CanaryCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `CanaryCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ChangeFdCommand` +ChangeFdCommand: redirect file descriptor during runtime. + + + +## function `ChangeFdCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property ChangeFdCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ChangeFdCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ChangeFdCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ChangeFdCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `ChangeFdCommand.get_fd_from_result` + +```python +get_fd_from_result(res: str) → int +``` + + + + + +--- + + + +## function `ChangeFdCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ChangeFdCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ChangeFdCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ChangeFdCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ChangeFdCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ChangeFdCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ChangePermissionBreakpoint` +When hit, this temporary breakpoint will restore the original code, and position $pc correctly. + + + +## function `ChangePermissionBreakpoint.__init__` + +```python +__init__(loc: str, code: ByteString, pc: int) → None +``` + + + + + + + + +--- + + + +## function `ChangePermissionBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `ChecksecCommand` +Checksec the security properties of the current executable or passed as argument. The command checks for the following protections: +- PIE +- NX +- RelRO +- Glibc Stack Canaries +- Fortify Source + + + +## function `ChecksecCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ChecksecCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ChecksecCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ChecksecCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ChecksecCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `ChecksecCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ChecksecCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ChecksecCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ChecksecCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ChecksecCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ChecksecCommand.print_security_properties` + +```python +print_security_properties(filename: str) → None +``` + + + + + +--- + + + +## function `ChecksecCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Color` +Used to colorify terminal output. + + + + +--- + + + +## function `Color.blinkify` + +```python +blinkify(msg: str) → str +``` + + + + + +--- + + + +## function `Color.blueify` + +```python +blueify(msg: str) → str +``` + + + + + +--- + + + +## function `Color.boldify` + +```python +boldify(msg: str) → str +``` + + + + + +--- + + + +## function `Color.colorify` + +```python +colorify(text: str, attrs: str) → str +``` + +Color text according to the given attributes. + +--- + + + +## function `Color.cyanify` + +```python +cyanify(msg: str) → str +``` + + + + + +--- + + + +## function `Color.grayify` + +```python +grayify(msg: str) → str +``` + + + + + +--- + + + +## function `Color.greenify` + +```python +greenify(msg: str) → str +``` + + + + + +--- + + + +## function `Color.highlightify` + +```python +highlightify(msg: str) → str +``` + + + + + +--- + + + +## function `Color.light_grayify` + +```python +light_grayify(msg: str) → str +``` + + + + + +--- + + + +## function `Color.pinkify` + +```python +pinkify(msg: str) → str +``` + + + + + +--- + + + +## function `Color.redify` + +```python +redify(msg: str) → str +``` + + + + + +--- + + + +## function `Color.underlinify` + +```python +underlinify(msg: str) → str +``` + + + + + +--- + + + +## function `Color.yellowify` + +```python +yellowify(msg: str) → str +``` + + + + + + +--- + +## class `ContextCommand` +Displays a comprehensive and modular summary of runtime context. Unless setting `enable` is set to False, this command will be spawned automatically every time GDB hits a breakpoint, a watchpoint, or any kind of interrupt. By default, it will show panes that contain the register states, the stack, and the disassembly code around $pc. + + + +## function `ContextCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ContextCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ContextCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ContextCommand.addr_has_breakpoint` + +```python +addr_has_breakpoint(address: int, bp_locations: List[str]) → bool +``` + + + + + +--- + + + +## function `ContextCommand.context_additional_information` + +```python +context_additional_information() → None +``` + + + + + +--- + + + +## function `ContextCommand.context_args` + +```python +context_args() → None +``` + + + + + +--- + + + +## function `ContextCommand.context_code` + +```python +context_code() → None +``` + + + + + +--- + + + +## function `ContextCommand.context_memory` + +```python +context_memory() → None +``` + + + + + +--- + + + +## function `ContextCommand.context_regs` + +```python +context_regs() → None +``` + + + + + +--- + + + +## function `ContextCommand.context_source` + +```python +context_source() → None +``` + + + + + +--- + + + +## function `ContextCommand.context_stack` + +```python +context_stack() → None +``` + + + + + +--- + + + +## function `ContextCommand.context_threads` + +```python +context_threads() → None +``` + + + + + +--- + + + +## function `ContextCommand.context_title` + +```python +context_title(m: Optional[str]) → None +``` + + + + + +--- + + + +## function `ContextCommand.context_trace` + +```python +context_trace() → None +``` + + + + + +--- + + + +## function `ContextCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ContextCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `ContextCommand.empty_extra_messages` + +```python +empty_extra_messages(_) → None +``` + + + + + +--- + + + +## function `ContextCommand.get_pc_context_info` + +```python +get_pc_context_info(pc: int, line: str) → str +``` + + + + + +--- + + + +## function `ContextCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ContextCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ContextCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ContextCommand.line_has_breakpoint` + +```python +line_has_breakpoint( + file_name: str, + line_number: int, + bp_locations: List[str] +) → bool +``` + + + + + +--- + + + +## function `ContextCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ContextCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ContextCommand.print_arguments_from_symbol` + +```python +print_arguments_from_symbol(function_name: str, symbol: 'gdb.Symbol') → None +``` + +If symbols were found, parse them and print the argument adequately. + +--- + + + +## function `ContextCommand.print_guessed_arguments` + +```python +print_guessed_arguments(function_name: str) → None +``` + +When no symbol, read the current basic block and look for "interesting" instructions. + +--- + + + +## function `ContextCommand.show_legend` + +```python +show_legend() → None +``` + + + + + +--- + + + +## function `ContextCommand.update_registers` + +```python +update_registers(_) → None +``` + + + + + +--- + + + +## function `ContextCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `DereferenceCommand` +Dereference recursively from an address and display information. This acts like WinDBG `dps` command. + + + +## function `DereferenceCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property DereferenceCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `DereferenceCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `DereferenceCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `DereferenceCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `DereferenceCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `DereferenceCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `DereferenceCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `DereferenceCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `DereferenceCommand.pprint_dereferenced` + +```python +pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) → str +``` + + + + + +--- + + + +## function `DereferenceCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `DereferenceCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `DetailRegistersCommand` +Display full details on one, many or all registers value from current architecture. + + + +## function `DetailRegistersCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property DetailRegistersCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `DetailRegistersCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `DetailRegistersCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `DetailRegistersCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `DetailRegistersCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `DetailRegistersCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `DetailRegistersCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `DetailRegistersCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `DetailRegistersCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `DetailRegistersCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `DisableContextOutputContext` + + + + + + + + +--- + +## class `Elf` +Basic ELF parsing. Ref: +- http://www.skyfree.org/linux/references/ELF_Format.pdf +- https://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf +- https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html + + + +## function `Elf.__init__` + +```python +__init__(path: Union[str, pathlib.Path]) → None +``` + +Instantiate an ELF object. A valid ELF must be provided, or an exception will be thrown. + + +--- + +#### property Elf.checksec + +Check the security property of the ELF binary. The following properties are: +- Canary +- NX +- PIE +- Fortify +- Partial/Full RelRO. Return a dict() with the different keys mentioned above, and the boolean associated whether the protection was found. + +--- + +#### property Elf.entry_point + + + + + + + +--- + + + +## function `Elf.is_valid` + +```python +is_valid(path: pathlib.Path) → bool +``` + + + + + +--- + + + +## function `Elf.read` + +```python +read(size: int) → bytes +``` + + + + + +--- + + + +## function `Elf.read_and_unpack` + +```python +read_and_unpack(fmt: str) → Tuple[Any, ...] +``` + + + + + +--- + + + +## function `Elf.seek` + +```python +seek(off: int) → None +``` + + + + + + +--- + +## class `ElfInfoCommand` +Display a limited subset of ELF header information. If no argument is provided, the command will show information about the current ELF being debugged. + + + +## function `ElfInfoCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ElfInfoCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ElfInfoCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ElfInfoCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ElfInfoCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `ElfInfoCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ElfInfoCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ElfInfoCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ElfInfoCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ElfInfoCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ElfInfoCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Endianness` +An enumeration. + + + + + +--- + +## class `EntryBreakBreakpoint` +Breakpoint used internally to stop execution at the most convenient entry point. + + + +## function `EntryBreakBreakpoint.__init__` + +```python +__init__(location: str) → None +``` + + + + + + + + +--- + + + +## function `EntryBreakBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `EntryPointBreakCommand` +Tries to find best entry point and sets a temporary breakpoint on it. The command will test for well-known symbols for entry points, such as `main`, `_main`, `__libc_start_main`, etc. defined by the setting `entrypoint_symbols`. + + + +## function `EntryPointBreakCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property EntryPointBreakCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `EntryPointBreakCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `EntryPointBreakCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `EntryPointBreakCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `EntryPointBreakCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `EntryPointBreakCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `EntryPointBreakCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `EntryPointBreakCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `EntryPointBreakCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `EntryPointBreakCommand.set_init_tbreak` + +```python +set_init_tbreak(addr: int) → EntryBreakBreakpoint +``` + + + + + +--- + + + +## function `EntryPointBreakCommand.set_init_tbreak_pie` + +```python +set_init_tbreak_pie(addr: int, argv: List[str]) → EntryBreakBreakpoint +``` + + + + + +--- + + + +## function `EntryPointBreakCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ExternalStructureManager` + + + + + + +## function `ExternalStructureManager.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ExternalStructureManager.modules + + + + + +--- + +#### property ExternalStructureManager.path + + + + + +--- + +#### property ExternalStructureManager.structures + + + + + + +--- + +#### handler ExternalStructureManager.find + + +--- + + + +## function `ExternalStructureManager.clear_caches` + +```python +clear_caches() → None +``` + + + + + + +--- + +## class `FileFormat` + + + + + + +## function `FileFormat.__init__` + +```python +__init__(path: Union[str, pathlib.Path]) → None +``` + + + + + + + + +--- + + + +## function `FileFormat.is_valid` + +```python +is_valid(path: pathlib.Path) → bool +``` + + + + + + +--- + +## class `FileFormatSection` + + + + + + + + +--- + +## class `FlagsCommand` +Edit flags in a human friendly way. + + + +## function `FlagsCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property FlagsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `FlagsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `FlagsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `FlagsCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `FlagsCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `FlagsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `FlagsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `FlagsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `FlagsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `FlagsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `FormatStringBreakpoint` +Inspect stack for format string. + + + +## function `FormatStringBreakpoint.__init__` + +```python +__init__(spec: str, num_args: int) → None +``` + + + + + + + + +--- + + + +## function `FormatStringBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `FormatStringSearchCommand` +Exploitable format-string helper: this command will set up specific breakpoints at well-known dangerous functions (printf, snprintf, etc.), and check if the pointer holding the format string is writable, and therefore susceptible to format string attacks if an attacker can control its content. + + + +## function `FormatStringSearchCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property FormatStringSearchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `FormatStringSearchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `FormatStringSearchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `FormatStringSearchCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `FormatStringSearchCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `FormatStringSearchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `FormatStringSearchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `FormatStringSearchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `FormatStringSearchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `FormatStringSearchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GdbRemoveReadlineFinder` + + + + + + + +--- + + + +## function `GdbRemoveReadlineFinder.find_module` + +```python +find_module(fullname, path=None) +``` + + + + + +--- + + + +## function `GdbRemoveReadlineFinder.load_module` + +```python +load_module(fullname) +``` + + + + + + +--- + +## class `Gef` +The GEF root class, which serves as a entrypoint for all the debugging session attributes (architecture, memory, settings, etc.). + + + +## function `Gef.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `Gef.reinitialize_managers` + +```python +reinitialize_managers() → None +``` + +Reinitialize the managers. Avoid calling this function directly, using `pi reset()` is preferred + +--- + + + +## function `Gef.reset_caches` + +```python +reset_caches() → None +``` + +Recursively clean the cache of all the managers. Avoid calling this function directly, using `reset-cache` is preferred + +--- + + + +## function `Gef.setup` + +```python +setup() → None +``` + +Setup initialize the runtime setup, which may require for the `gef` to be not None. + + +--- + +## class `GefAlias` +Simple aliasing wrapper because GDB doesn't do what it should. + + + +## function `GefAlias.__init__` + +```python +__init__( + alias: str, + command: str, + completer_class: int = 0, + command_class: int = -1 +) → None +``` + + + + + + + + +--- + + + +## function `GefAlias.invoke` + +```python +invoke(args: Any, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GefAlias.lookup_command` + +```python +lookup_command(cmd: str) → Optional[Tuple[str, __main__.GenericCommand]] +``` + + + + + + +--- + +## class `GefCommand` +GEF main command: view all new commands by typing `gef`. + + + +## function `GefCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefCommand.loaded_command_names + + + + + +--- + +#### property GefCommand.loaded_commands + + + + + +--- + +#### property GefCommand.loaded_functions + + + + + +--- + +#### property GefCommand.missing_commands + + + + + + + +--- + + + +## function `GefCommand.add_context_pane` + +```python +add_context_pane( + pane_name: str, + display_pane_function: Callable, + pane_title_function: Callable, + condition: Optional[Callable] +) → None +``` + +Add a new context pane to ContextCommand. + +--- + + + +## function `GefCommand.invoke` + +```python +invoke(args: Any, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GefCommand.load` + +```python +load() → None +``` + +Load all the commands and functions defined by GEF into GDB. + +--- + + + +## function `GefCommand.load_extra_plugins` + +```python +load_extra_plugins() → int +``` + + + + + +--- + + + +## function `GefCommand.setup` + +```python +setup() → None +``` + + + + + +--- + + + +## function `GefCommand.show_banner` + +```python +show_banner() → None +``` + + + + + + +--- + +## class `GefConfigCommand` +GEF configuration sub-command This command will help set/view GEF settings for the current debugging session. It is possible to make those changes permanent by running `gef save` (refer to this command help), and/or restore previously saved settings by running `gef restore` (refer help). + + + +## function `GefConfigCommand.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GefConfigCommand.complete` + +```python +complete(text: str, word: str) → List[str] +``` + + + + + +--- + + + +## function `GefConfigCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GefConfigCommand.print_setting` + +```python +print_setting(plugin_name: str, verbose: bool = False) → None +``` + + + + + +--- + + + +## function `GefConfigCommand.print_settings` + +```python +print_settings() → None +``` + + + + + +--- + + + +## function `GefConfigCommand.set_setting` + +```python +set_setting(argv: Tuple[str, Any]) → None +``` + + + + + + +--- + +## class `GefFunctionsCommand` +List the convenience functions provided by GEF. + + + +## function `GefFunctionsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefFunctionsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GefFunctionsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GefFunctionsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GefFunctionsCommand.do_invoke` + +```python +do_invoke(argv) → None +``` + + + + + +--- + + + +## function `GefFunctionsCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GefFunctionsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GefFunctionsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GefFunctionsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GefFunctionsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GefFunctionsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GefHeapManager` +Class managing session heap. + + + +## function `GefHeapManager.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefHeapManager.arenas + + + + + +--- + +#### property GefHeapManager.base_address + + + + + +--- + +#### property GefHeapManager.chunks + + + + + +--- + +#### property GefHeapManager.main_arena + + + + + +--- + +#### property GefHeapManager.malloc_alignment + + + + + +--- + +#### property GefHeapManager.min_chunk_size + + + + + +--- + +#### property GefHeapManager.selected_arena + + + + + + +--- + +#### handler GefHeapManager.find_main_arena_addr + + +--- + + + +## function `GefHeapManager.csize2tidx` + +```python +csize2tidx(size: int) → int +``` + + + + + +--- + + + +## function `GefHeapManager.malloc_align_address` + +```python +malloc_align_address(address: int) → int +``` + +Align addresses according to glibc's MALLOC_ALIGNMENT. See also Issue #689 on Github + +--- + + + +## function `GefHeapManager.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `GefHeapManager.tidx2size` + +```python +tidx2size(idx: int) → int +``` + + + + + + +--- + +## class `GefHelpCommand` +GEF help sub-command. + + + +## function `GefHelpCommand.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GefHelpCommand.invoke` + +```python +invoke(args: Any, from_tty: bool) → None +``` + + + + + + +--- + +## class `GefInstallExtraScriptCommand` +`gef install` command: installs one or more scripts from the `gef-extras` script repo. Note that the command doesn't check for external dependencies the script(s) might require. + + + +## function `GefInstallExtraScriptCommand.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GefInstallExtraScriptCommand.invoke` + +```python +invoke(argv: str, from_tty: bool) → None +``` + + + + + + +--- + +## class `GefLibcManager` +Class managing everything libc-related (except heap). + + + +## function `GefLibcManager.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefLibcManager.version + + + + + + +--- + +#### handler GefLibcManager.find_libc_version + + +--- + + + +## function `GefLibcManager.reset_caches` + +```python +reset_caches() → None +``` + +Reset the LRU-cached attributes + + +--- + +## class `GefManager` + + + + + + + +--- + + + +## function `GefManager.reset_caches` + +```python +reset_caches() → None +``` + +Reset the LRU-cached attributes + + +--- + +## class `GefMemoryManager` +Class that manages memory access for gef. + + + +## function `GefMemoryManager.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefMemoryManager.maps + + + + + + + +--- + + + +## function `GefMemoryManager.read` + +```python +read(addr: int, length: int = 16) → bytes +``` + +Return a `length` long byte array with the copy of the process memory at `addr`. + +--- + + + +## function `GefMemoryManager.read_ascii_string` + +```python +read_ascii_string(address: int) → Optional[str] +``` + +Read an ASCII string from memory + +--- + + + +## function `GefMemoryManager.read_cstring` + +```python +read_cstring( + address: int, + max_length: int = 50, + encoding: Optional[str] = None +) → str +``` + +Return a C-string read from memory. + +--- + + + +## function `GefMemoryManager.read_integer` + +```python +read_integer(addr: int) → int +``` + +Return an integer read from memory. + +--- + + + +## function `GefMemoryManager.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `GefMemoryManager.write` + +```python +write(address: int, buffer: ByteString, length: int = 16) → None +``` + +Write `buffer` at address `address`. + + +--- + +## class `GefMissingCommand` +GEF missing sub-command Display the GEF commands that could not be loaded, along with the reason of why they could not be loaded. + + + +## function `GefMissingCommand.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GefMissingCommand.invoke` + +```python +invoke(args: Any, from_tty: bool) → None +``` + + + + + + +--- + +## class `GefRemoteSessionManager` +Class for managing remote sessions with GEF. It will create a temporary environment designed to clone the remote one. + + + +## function `GefRemoteSessionManager.__init__` + +```python +__init__( + host: str, + port: int, + pid: int = -1, + qemu: Optional[pathlib.Path] = None +) → None +``` + + + + + + +--- + +#### property GefRemoteSessionManager.auxiliary_vector + + + + + +--- + +#### property GefRemoteSessionManager.canary + +Return a tuple of the canary address and value, read from the canonical location if supported by the architecture. Otherwise, read from the auxiliary vector. + +--- + +#### property GefRemoteSessionManager.cwd + + + + + +--- + +#### property GefRemoteSessionManager.file + +Path to the file being debugged as seen by the remote endpoint. + +--- + +#### property GefRemoteSessionManager.lfile + +Local path to the file being debugged. + +--- + +#### property GefRemoteSessionManager.maps + + + + + +--- + +#### property GefRemoteSessionManager.original_canary + +Return a tuple of the initial canary address and value, read from the auxiliary vector. + +--- + +#### property GefRemoteSessionManager.os + +Return the current OS. + +--- + +#### property GefRemoteSessionManager.pagesize + +Get the system page size + +--- + +#### property GefRemoteSessionManager.pid + +Return the PID of the target process. + +--- + +#### property GefRemoteSessionManager.root + + + + + +--- + +#### property GefRemoteSessionManager.target + + + + + + + +--- + + + +## function `GefRemoteSessionManager.close` + +```python +close() → None +``` + + + + + +--- + + + +## function `GefRemoteSessionManager.connect` + +```python +connect(pid: int) → bool +``` + +Connect to remote target. If in extended mode, also attach to the given PID. + +--- + + + +## function `GefRemoteSessionManager.in_qemu_user` + +```python +in_qemu_user() → bool +``` + + + + + +--- + + + +## function `GefRemoteSessionManager.remote_objfile_event_handler` + +```python +remote_objfile_event_handler(evt: 'gdb.NewObjFileEvent') → None +``` + + + + + +--- + + + +## function `GefRemoteSessionManager.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `GefRemoteSessionManager.setup` + +```python +setup() → bool +``` + + + + + +--- + + + +## function `GefRemoteSessionManager.sync` + +```python +sync(src: str, dst: Optional[str] = None) → bool +``` + +Copy the `src` into the temporary chroot. If `dst` is provided, that path will be used instead of `src`. + + +--- + +## class `GefRestoreCommand` +GEF restore sub-command. Loads settings from file '~/.gef.rc' and apply them to the configuration of GEF. + + + +## function `GefRestoreCommand.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GefRestoreCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GefRestoreCommand.reload` + +```python +reload(quiet: bool) +``` + + + + + + +--- + +## class `GefRunCommand` +Override GDB run commands with the context from GEF. Simple wrapper for GDB run command to use arguments set from `gef set args`. + + + +## function `GefRunCommand.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GefRunCommand.invoke` + +```python +invoke(args: Any, from_tty: bool) → None +``` + + + + + + +--- + +## class `GefSaveCommand` +GEF save sub-command. Saves the current configuration of GEF to disk (by default in file '~/.gef.rc'). + + + +## function `GefSaveCommand.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GefSaveCommand.invoke` + +```python +invoke(args: Any, from_tty: bool) → None +``` + + + + + + +--- + +## class `GefSessionManager` +Class managing the runtime properties of GEF. + + + +## function `GefSessionManager.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefSessionManager.auxiliary_vector + + + + + +--- + +#### property GefSessionManager.canary + +Return a tuple of the canary address and value, read from the canonical location if supported by the architecture. Otherwise, read from the auxiliary vector. + +--- + +#### property GefSessionManager.cwd + + + + + +--- + +#### property GefSessionManager.file + +Return a Path object of the target process. + +--- + +#### property GefSessionManager.maps + +Returns the Path to the procfs entry for the memory mapping. + +--- + +#### property GefSessionManager.original_canary + +Return a tuple of the initial canary address and value, read from the auxiliary vector. + +--- + +#### property GefSessionManager.os + +Return the current OS. + +--- + +#### property GefSessionManager.pagesize + +Get the system page size + +--- + +#### property GefSessionManager.pid + +Return the PID of the target process. + +--- + +#### property GefSessionManager.root + +Returns the path to the process's root directory. + + + +--- + + + +## function `GefSessionManager.reset_caches` + +```python +reset_caches() → None +``` + + + + + + +--- + +## class `GefSetCommand` +Override GDB set commands with the context from GEF. + + + +## function `GefSetCommand.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GefSetCommand.invoke` + +```python +invoke(args: Any, from_tty: bool) → None +``` + + + + + + +--- + +## class `GefSetting` +Basic class for storing gef settings as objects + + + +## function `GefSetting.__init__` + +```python +__init__( + value: Any, + cls: Optional[type] = None, + description: Optional[str] = None, + hooks: Optional[Dict[str, Callable]] = None +) → None +``` + + + + + + + + + +--- + +## class `GefSettingsManager` +GefSettings acts as a dict where the global settings are stored and can be read, written or deleted as any other dict. For instance, to read a specific command setting: `gef.config[mycommand.mysetting]` + + + + +--- + + + +## function `GefSettingsManager.raw_entry` + +```python +raw_entry(name: str) → GefSetting +``` + + + + + + +--- + +## class `GefThemeCommand` +Customize GEF appearance. + + + +## function `GefThemeCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefThemeCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GefThemeCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GefThemeCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GefThemeCommand.do_invoke` + +```python +do_invoke(args: List[str]) → None +``` + + + + + +--- + + + +## function `GefThemeCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GefThemeCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GefThemeCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GefThemeCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GefThemeCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GefThemeCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GefTmuxSetup` +Setup a confortable tmux debugging environment. + + + +## function `GefTmuxSetup.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GefTmuxSetup.invoke` + +```python +invoke(args: Any, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GefTmuxSetup.screen_setup` + +```python +screen_setup() → None +``` + +Hackish equivalent of the tmux_setup() function for screen. + +--- + + + +## function `GefTmuxSetup.tmux_setup` + +```python +tmux_setup() → None +``` + +Prepare the tmux environment by vertically splitting the current pane, and forcing the context to be redirected there. + + +--- + +## class `GefUiManager` +Class managing UI settings. + + + +## function `GefUiManager.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GefUiManager.reset_caches` + +```python +reset_caches() → None +``` + +Reset the LRU-cached attributes + + +--- + +## class `GenericArchitecture` + + + + + +--- + +#### property GenericArchitecture.endianness + + + + + +--- + +#### property GenericArchitecture.fp + + + + + +--- + +#### property GenericArchitecture.pc + + + + + +--- + +#### property GenericArchitecture.ptrsize + + + + + +--- + +#### property GenericArchitecture.registers + + + + + +--- + +#### property GenericArchitecture.sp + + + + + + + +--- + + + +## function `GenericArchitecture.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `GenericArchitecture.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `GenericArchitecture.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `GenericArchitecture.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int] +``` + + + + + +--- + + + +## function `GenericArchitecture.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `GenericArchitecture.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `GenericArchitecture.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `GenericArchitecture.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `GenericArchitecture.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `GenericArchitecture.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `GenericArchitecture.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `GenericArchitecture.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `GenericCommand` +This is an abstract class for invoking commands, should not be instantiated. + + + +## function `GenericCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property GenericCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GenericCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GenericCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GenericCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `GenericCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GenericCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GenericCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GenericCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GenericCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GenericCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GenericFunction` +This is an abstract class for invoking convenience functions, should not be instantiated. + + + +## function `GenericFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GenericFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +## function `GenericFunction.do_invoke` + +```python +do_invoke(args: Any) → int +``` + + + + + +--- + + + +## function `GenericFunction.invoke` + +```python +invoke(*args: Any) → int +``` + + + + + + +--- + +## class `GlibcArena` +Glibc arena class + + + +## function `GlibcArena.__init__` + +```python +__init__(addr: str) → None +``` + + + + + + +--- + +#### property GlibcArena.addr + + + + + +--- + +#### property GlibcArena.address + + + + + +--- + +#### property GlibcArena.attached_threads + + + + + +--- + +#### property GlibcArena.binmap + + + + + +--- + +#### property GlibcArena.bins + + + + + +--- + +#### property GlibcArena.fastbinsY + + + + + +--- + +#### property GlibcArena.last_remainder + + + + + +--- + +#### property GlibcArena.max_system_mem + + + + + +--- + +#### property GlibcArena.next + + + + + +--- + +#### property GlibcArena.next_free + + + + + +--- + +#### property GlibcArena.sizeof + + + + + +--- + +#### property GlibcArena.system_mem + + + + + +--- + +#### property GlibcArena.top + + + + + + + +--- + + + +## function `GlibcArena.bin` + +```python +bin(i: int) → Tuple[int, int] +``` + + + + + +--- + + + +## function `GlibcArena.bin_at` + +```python +bin_at(i) → int +``` + + + + + +--- + + + +## function `GlibcArena.fastbin` + +```python +fastbin(i: int) → Optional[ForwardRef('GlibcFastChunk')] +``` + +Return head chunk in fastbinsY[i]. + +--- + + + +## function `GlibcArena.get_heap_for_ptr` + +```python +get_heap_for_ptr(ptr: int) → int +``` + +Find the corresponding heap for a given pointer (int). See https://github.com/bminor/glibc/blob/glibc-2.34/malloc/arena.c#L129 + +--- + + + +## function `GlibcArena.get_heap_info_list` + +```python +get_heap_info_list() → Optional[List[__main__.GlibcHeapInfo]] +``` + + + + + +--- + + + +## function `GlibcArena.heap_addr` + +```python +heap_addr(allow_unaligned: bool = False) → Optional[int] +``` + + + + + +--- + + + +## function `GlibcArena.is_main_arena` + +```python +is_main_arena() → bool +``` + + + + + +--- + + + +## function `GlibcArena.malloc_state_t` + +```python +malloc_state_t() → Type[_ctypes.Structure] +``` + + + + + +--- + + + +## function `GlibcArena.reset` + +```python +reset() +``` + + + + + +--- + + + +## function `GlibcArena.verify` + +```python +verify(addr: int) → bool +``` + +Verify that the address matches a possible valid GlibcArena + + +--- + +## class `GlibcChunk` +Glibc chunk class. The default behavior (from_base=False) is to interpret the data starting at the memory address pointed to as the chunk data. Setting from_base to True instead treats that data as the chunk header. Ref: https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/. + + + +## function `GlibcChunk.__init__` + +```python +__init__( + addr: int, + from_base: bool = False, + allow_unaligned: bool = True +) → None +``` + + + + + + +--- + +#### property GlibcChunk.bk + + + + + +--- + +#### property GlibcChunk.bk_nextsize + + + + + +--- + +#### property GlibcChunk.fd + + + + + +--- + +#### property GlibcChunk.fd_nextsize + + + + + +--- + +#### property GlibcChunk.flags + + + + + +--- + +#### property GlibcChunk.prev_size + + + + + +--- + +#### property GlibcChunk.size + + + + + +--- + +#### property GlibcChunk.usable_size + + + + + + + +--- + + + +## function `GlibcChunk.get_next_chunk` + +```python +get_next_chunk(allow_unaligned: bool = False) → GlibcChunk +``` + + + + + +--- + + + +## function `GlibcChunk.get_next_chunk_addr` + +```python +get_next_chunk_addr() → int +``` + + + + + +--- + + + +## function `GlibcChunk.get_prev_chunk_size` + +```python +get_prev_chunk_size() → int +``` + + + + + +--- + + + +## function `GlibcChunk.get_usable_size` + +```python +get_usable_size() → int +``` + + + + + +--- + + + +## function `GlibcChunk.has_m_bit` + +```python +has_m_bit() → bool +``` + + + + + +--- + + + +## function `GlibcChunk.has_n_bit` + +```python +has_n_bit() → bool +``` + + + + + +--- + + + +## function `GlibcChunk.has_p_bit` + +```python +has_p_bit() → bool +``` + + + + + +--- + + + +## function `GlibcChunk.is_used` + +```python +is_used() → bool +``` + +Check if the current block is used by: +- checking the M bit is true +- or checking that next chunk PREV_INUSE flag is true + +--- + + + +## function `GlibcChunk.malloc_chunk_t` + +```python +malloc_chunk_t() → Type[_ctypes.Structure] +``` + + + + + +--- + + + +## function `GlibcChunk.psprint` + +```python +psprint() → str +``` + + + + + +--- + + + +## function `GlibcChunk.reset` + +```python +reset() +``` + + + + + + +--- + +## class `GlibcFastChunk` + + + + + + +## function `GlibcFastChunk.__init__` + +```python +__init__( + addr: int, + from_base: bool = False, + allow_unaligned: bool = True +) → None +``` + + + + + + +--- + +#### property GlibcFastChunk.bk + + + + + +--- + +#### property GlibcFastChunk.bk_nextsize + + + + + +--- + +#### property GlibcFastChunk.fd + + + + + +--- + +#### property GlibcFastChunk.fd_nextsize + + + + + +--- + +#### property GlibcFastChunk.flags + + + + + +--- + +#### property GlibcFastChunk.prev_size + + + + + +--- + +#### property GlibcFastChunk.size + + + + + +--- + +#### property GlibcFastChunk.usable_size + + + + + + + +--- + + + +## function `GlibcFastChunk.get_next_chunk` + +```python +get_next_chunk(allow_unaligned: bool = False) → GlibcChunk +``` + + + + + +--- + + + +## function `GlibcFastChunk.get_next_chunk_addr` + +```python +get_next_chunk_addr() → int +``` + + + + + +--- + + + +## function `GlibcFastChunk.get_prev_chunk_size` + +```python +get_prev_chunk_size() → int +``` + + + + + +--- + + + +## function `GlibcFastChunk.get_usable_size` + +```python +get_usable_size() → int +``` + + + + + +--- + + + +## function `GlibcFastChunk.has_m_bit` + +```python +has_m_bit() → bool +``` + + + + + +--- + + + +## function `GlibcFastChunk.has_n_bit` + +```python +has_n_bit() → bool +``` + + + + + +--- + + + +## function `GlibcFastChunk.has_p_bit` + +```python +has_p_bit() → bool +``` + + + + + +--- + + + +## function `GlibcFastChunk.is_used` + +```python +is_used() → bool +``` + +Check if the current block is used by: +- checking the M bit is true +- or checking that next chunk PREV_INUSE flag is true + +--- + + + +## function `GlibcFastChunk.malloc_chunk_t` + +```python +malloc_chunk_t() → Type[_ctypes.Structure] +``` + + + + + +--- + + + +## function `GlibcFastChunk.protect_ptr` + +```python +protect_ptr(pos: int, pointer: int) → int +``` + +https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L339 + +--- + + + +## function `GlibcFastChunk.psprint` + +```python +psprint() → str +``` + + + + + +--- + + + +## function `GlibcFastChunk.reset` + +```python +reset() +``` + + + + + +--- + + + +## function `GlibcFastChunk.reveal_ptr` + +```python +reveal_ptr(pointer: int) → int +``` + +https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L341 + + +--- + +## class `GlibcHeapArenaCommand` +Display information on a heap chunk. + + + +## function `GlibcHeapArenaCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property GlibcHeapArenaCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GlibcHeapArenaCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GlibcHeapArenaCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GlibcHeapArenaCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `GlibcHeapArenaCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GlibcHeapArenaCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GlibcHeapArenaCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GlibcHeapArenaCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapArenaCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapArenaCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapBinsCommand` +Display information on the bins on an arena (default: main_arena). See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123. + + + +## function `GlibcHeapBinsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapBinsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GlibcHeapBinsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GlibcHeapBinsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GlibcHeapBinsCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `GlibcHeapBinsCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GlibcHeapBinsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GlibcHeapBinsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GlibcHeapBinsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapBinsCommand.pprint_bin` + +```python +pprint_bin(arena_addr: str, index: int, _type: str = '') → int +``` + + + + + +--- + + + +## function `GlibcHeapBinsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapBinsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapChunkCommand` +Display information on a heap chunk. See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123. + + + +## function `GlibcHeapChunkCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapChunkCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GlibcHeapChunkCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GlibcHeapChunkCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GlibcHeapChunkCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `GlibcHeapChunkCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GlibcHeapChunkCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GlibcHeapChunkCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GlibcHeapChunkCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapChunkCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapChunkCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapChunksCommand` +Display all heap chunks for the current arena. As an optional argument the base address of a different arena can be passed + + + +## function `GlibcHeapChunksCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapChunksCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GlibcHeapChunksCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GlibcHeapChunksCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GlibcHeapChunksCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `GlibcHeapChunksCommand.dump_chunks_arena` + +```python +dump_chunks_arena( + arena: __main__.GlibcArena, + print_arena: bool = False, + allow_unaligned: bool = False +) → None +``` + + + + + +--- + + + +## function `GlibcHeapChunksCommand.dump_chunks_heap` + +```python +dump_chunks_heap( + start: int, + end: int, + arena: __main__.GlibcArena, + allow_unaligned: bool = False +) → bool +``` + + + + + +--- + + + +## function `GlibcHeapChunksCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GlibcHeapChunksCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GlibcHeapChunksCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GlibcHeapChunksCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapChunksCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapChunksCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapCommand` +Base command to get information about the Glibc heap structure. + + + +## function `GlibcHeapCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GlibcHeapCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GlibcHeapCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GlibcHeapCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `GlibcHeapCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GlibcHeapCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GlibcHeapCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GlibcHeapCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapFastbinsYCommand` +Display information on the fastbinsY on an arena (default: main_arena). See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123. + + + +## function `GlibcHeapFastbinsYCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapFastbinsYCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GlibcHeapFastbinsYCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GlibcHeapFastbinsYCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GlibcHeapFastbinsYCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `GlibcHeapFastbinsYCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GlibcHeapFastbinsYCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GlibcHeapFastbinsYCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GlibcHeapFastbinsYCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapFastbinsYCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapFastbinsYCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapInfo` +Glibc heap_info struct + + + +## function `GlibcHeapInfo.__init__` + +```python +__init__(addr: Union[str, int]) → None +``` + + + + + + +--- + +#### property GlibcHeapInfo.addr + + + + + +--- + +#### property GlibcHeapInfo.address + + + + + +--- + +#### property GlibcHeapInfo.heap_end + + + + + +--- + +#### property GlibcHeapInfo.heap_start + + + + + +--- + +#### property GlibcHeapInfo.sizeof + + + + + + + +--- + + + +## function `GlibcHeapInfo.heap_info_t` + +```python +heap_info_t() → Type[_ctypes.Structure] +``` + + + + + +--- + + + +## function `GlibcHeapInfo.reset` + +```python +reset() +``` + + + + + + +--- + +## class `GlibcHeapLargeBinsCommand` +Convenience command for viewing large bins. + + + +## function `GlibcHeapLargeBinsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapLargeBinsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GlibcHeapLargeBinsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GlibcHeapLargeBinsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GlibcHeapLargeBinsCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `GlibcHeapLargeBinsCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GlibcHeapLargeBinsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GlibcHeapLargeBinsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GlibcHeapLargeBinsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapLargeBinsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapLargeBinsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapSetArenaCommand` +Set the address of the main_arena or the currently selected arena. + + + +## function `GlibcHeapSetArenaCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapSetArenaCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GlibcHeapSetArenaCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GlibcHeapSetArenaCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GlibcHeapSetArenaCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `GlibcHeapSetArenaCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GlibcHeapSetArenaCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GlibcHeapSetArenaCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GlibcHeapSetArenaCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapSetArenaCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapSetArenaCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapSmallBinsCommand` +Convenience command for viewing small bins. + + + +## function `GlibcHeapSmallBinsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapSmallBinsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GlibcHeapSmallBinsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GlibcHeapSmallBinsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GlibcHeapSmallBinsCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `GlibcHeapSmallBinsCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GlibcHeapSmallBinsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GlibcHeapSmallBinsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GlibcHeapSmallBinsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapSmallBinsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapSmallBinsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapTcachebinsCommand` +Display information on the Tcachebins on an arena (default: main_arena). See https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc. + + + +## function `GlibcHeapTcachebinsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapTcachebinsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GlibcHeapTcachebinsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GlibcHeapTcachebinsCommand.check_thread_ids` + +```python +check_thread_ids(tids: List[int]) → List[int] +``` + +Check the validity, dedup, and return all valid tids. + +--- + + + +## function `GlibcHeapTcachebinsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GlibcHeapTcachebinsCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `GlibcHeapTcachebinsCommand.find_tcache` + +```python +find_tcache() → int +``` + +Return the location of the current thread's tcache. + +--- + + + +## function `GlibcHeapTcachebinsCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GlibcHeapTcachebinsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GlibcHeapTcachebinsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GlibcHeapTcachebinsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapTcachebinsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapTcachebinsCommand.tcachebin` + +```python +tcachebin( + tcache_base: int, + i: int +) → Tuple[Optional[__main__.GlibcTcacheChunk], int] +``` + +Return the head chunk in tcache[i] and the number of chunks in the bin. + +--- + + + +## function `GlibcHeapTcachebinsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapUnsortedBinsCommand` +Display information on the Unsorted Bins of an arena (default: main_arena). See: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1689. + + + +## function `GlibcHeapUnsortedBinsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapUnsortedBinsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GlibcHeapUnsortedBinsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GlibcHeapUnsortedBinsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GlibcHeapUnsortedBinsCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `GlibcHeapUnsortedBinsCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GlibcHeapUnsortedBinsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GlibcHeapUnsortedBinsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GlibcHeapUnsortedBinsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapUnsortedBinsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GlibcHeapUnsortedBinsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcTcacheChunk` + + + + + + +## function `GlibcTcacheChunk.__init__` + +```python +__init__( + addr: int, + from_base: bool = False, + allow_unaligned: bool = True +) → None +``` + + + + + + +--- + +#### property GlibcTcacheChunk.bk + + + + + +--- + +#### property GlibcTcacheChunk.bk_nextsize + + + + + +--- + +#### property GlibcTcacheChunk.fd + + + + + +--- + +#### property GlibcTcacheChunk.fd_nextsize + + + + + +--- + +#### property GlibcTcacheChunk.flags + + + + + +--- + +#### property GlibcTcacheChunk.prev_size + + + + + +--- + +#### property GlibcTcacheChunk.size + + + + + +--- + +#### property GlibcTcacheChunk.usable_size + + + + + + + +--- + + + +## function `GlibcTcacheChunk.get_next_chunk` + +```python +get_next_chunk(allow_unaligned: bool = False) → GlibcChunk +``` + + + + + +--- + + + +## function `GlibcTcacheChunk.get_next_chunk_addr` + +```python +get_next_chunk_addr() → int +``` + + + + + +--- + + + +## function `GlibcTcacheChunk.get_prev_chunk_size` + +```python +get_prev_chunk_size() → int +``` + + + + + +--- + + + +## function `GlibcTcacheChunk.get_usable_size` + +```python +get_usable_size() → int +``` + + + + + +--- + + + +## function `GlibcTcacheChunk.has_m_bit` + +```python +has_m_bit() → bool +``` + + + + + +--- + + + +## function `GlibcTcacheChunk.has_n_bit` + +```python +has_n_bit() → bool +``` + + + + + +--- + + + +## function `GlibcTcacheChunk.has_p_bit` + +```python +has_p_bit() → bool +``` + + + + + +--- + + + +## function `GlibcTcacheChunk.is_used` + +```python +is_used() → bool +``` + +Check if the current block is used by: +- checking the M bit is true +- or checking that next chunk PREV_INUSE flag is true + +--- + + + +## function `GlibcTcacheChunk.malloc_chunk_t` + +```python +malloc_chunk_t() → Type[_ctypes.Structure] +``` + + + + + +--- + + + +## function `GlibcTcacheChunk.protect_ptr` + +```python +protect_ptr(pos: int, pointer: int) → int +``` + +https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L339 + +--- + + + +## function `GlibcTcacheChunk.psprint` + +```python +psprint() → str +``` + + + + + +--- + + + +## function `GlibcTcacheChunk.reset` + +```python +reset() +``` + + + + + +--- + + + +## function `GlibcTcacheChunk.reveal_ptr` + +```python +reveal_ptr(pointer: int) → int +``` + +https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L341 + + +--- + +## class `GotBaseFunction` +Return the current GOT base address plus the given offset. + + + +## function `GotBaseFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `GotBaseFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +## function `GotBaseFunction.do_invoke` + +```python +do_invoke(args: List) → int +``` + + + + + +--- + + + +## function `GotBaseFunction.invoke` + +```python +invoke(*args: Any) → int +``` + + + + + + +--- + +## class `GotCommand` +Display current status of the got inside the process. + + + +## function `GotCommand.__init__` + +```python +__init__() +``` + + + + + + +--- + +#### property GotCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `GotCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `GotCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `GotCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `GotCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `GotCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `GotCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `GotCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `GotCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `GotCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HeapAnalysisCommand` +Heap vulnerability analysis helper: this command aims to track dynamic heap allocation done through malloc()/free() to provide some insights on possible heap vulnerabilities. The following vulnerabilities are checked: +- NULL free +- Use-after-Free +- Double Free +- Heap overlap + + + +## function `HeapAnalysisCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HeapAnalysisCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `HeapAnalysisCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `HeapAnalysisCommand.clean` + +```python +clean(_: 'gdb.Event') → None +``` + + + + + +--- + + + +## function `HeapAnalysisCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `HeapAnalysisCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `HeapAnalysisCommand.dump_tracked_allocations` + +```python +dump_tracked_allocations() → None +``` + + + + + +--- + + + +## function `HeapAnalysisCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `HeapAnalysisCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `HeapAnalysisCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `HeapAnalysisCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `HeapAnalysisCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `HeapAnalysisCommand.setup` + +```python +setup() → None +``` + + + + + +--- + + + +## function `HeapAnalysisCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HeapBaseFunction` +Return the current heap base address plus an optional offset. + + + +## function `HeapBaseFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `HeapBaseFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +## function `HeapBaseFunction.do_invoke` + +```python +do_invoke(args: List) → int +``` + + + + + +--- + + + +## function `HeapBaseFunction.invoke` + +```python +invoke(*args: Any) → int +``` + + + + + + +--- + +## class `HexdumpByteCommand` +Display SIZE lines of hexdump as BYTE from the memory location pointed by ADDRESS. + + + +## function `HexdumpByteCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HexdumpByteCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `HexdumpByteCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `HexdumpByteCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `HexdumpByteCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `HexdumpByteCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `HexdumpByteCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `HexdumpByteCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `HexdumpByteCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `HexdumpByteCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `HexdumpByteCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HexdumpCommand` +Display SIZE lines of hexdump from the memory location pointed by LOCATION. + + + +## function `HexdumpCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HexdumpCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `HexdumpCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `HexdumpCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `HexdumpCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `HexdumpCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `HexdumpCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `HexdumpCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `HexdumpCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `HexdumpCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `HexdumpCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HexdumpDwordCommand` +Display SIZE lines of hexdump as DWORD from the memory location pointed by ADDRESS. + + + +## function `HexdumpDwordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HexdumpDwordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `HexdumpDwordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `HexdumpDwordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `HexdumpDwordCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `HexdumpDwordCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `HexdumpDwordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `HexdumpDwordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `HexdumpDwordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `HexdumpDwordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `HexdumpDwordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HexdumpQwordCommand` +Display SIZE lines of hexdump as QWORD from the memory location pointed by ADDRESS. + + + +## function `HexdumpQwordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HexdumpQwordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `HexdumpQwordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `HexdumpQwordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `HexdumpQwordCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `HexdumpQwordCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `HexdumpQwordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `HexdumpQwordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `HexdumpQwordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `HexdumpQwordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `HexdumpQwordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HexdumpWordCommand` +Display SIZE lines of hexdump as WORD from the memory location pointed by ADDRESS. + + + +## function `HexdumpWordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HexdumpWordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `HexdumpWordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `HexdumpWordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `HexdumpWordCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `HexdumpWordCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `HexdumpWordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `HexdumpWordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `HexdumpWordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `HexdumpWordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `HexdumpWordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HighlightAddCommand` +Add a match to the highlight table. + + + +## function `HighlightAddCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property HighlightAddCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `HighlightAddCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `HighlightAddCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `HighlightAddCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `HighlightAddCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `HighlightAddCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `HighlightAddCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `HighlightAddCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `HighlightAddCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `HighlightAddCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HighlightClearCommand` +Clear the highlight table, remove all matches. + + + +## function `HighlightClearCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property HighlightClearCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `HighlightClearCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `HighlightClearCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `HighlightClearCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `HighlightClearCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `HighlightClearCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `HighlightClearCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `HighlightClearCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `HighlightClearCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `HighlightClearCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HighlightCommand` +Highlight user-defined text matches in GEF output universally. + + + +## function `HighlightCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HighlightCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `HighlightCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `HighlightCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `HighlightCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `HighlightCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `HighlightCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `HighlightCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `HighlightCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `HighlightCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `HighlightCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HighlightListCommand` +Show the current highlight table with matches to colors. + + + +## function `HighlightListCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property HighlightListCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `HighlightListCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `HighlightListCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `HighlightListCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `HighlightListCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `HighlightListCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `HighlightListCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `HighlightListCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `HighlightListCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `HighlightListCommand.print_highlight_table` + +```python +print_highlight_table() → None +``` + + + + + +--- + + + +## function `HighlightListCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HighlightRemoveCommand` +Remove a match in the highlight table. + + + +## function `HighlightRemoveCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property HighlightRemoveCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `HighlightRemoveCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `HighlightRemoveCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `HighlightRemoveCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `HighlightRemoveCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `HighlightRemoveCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `HighlightRemoveCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `HighlightRemoveCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `HighlightRemoveCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `HighlightRemoveCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Instruction` +GEF representation of a CPU instruction. + + + +## function `Instruction.__init__` + +```python +__init__( + address: int, + location: str, + mnemo: str, + operands: List[str], + opcodes: bytes +) → None +``` + + + + + + + + +--- + + + +## function `Instruction.is_valid` + +```python +is_valid() → bool +``` + + + + + +--- + + + +## function `Instruction.size` + +```python +size() → int +``` + + + + + + +--- + +## class `MIPS` + + + + + +--- + +#### property MIPS.endianness + + + + + +--- + +#### property MIPS.fp + + + + + +--- + +#### property MIPS.pc + + + + + +--- + +#### property MIPS.ptrsize + + + + + +--- + +#### property MIPS.registers + + + + + +--- + +#### property MIPS.sp + + + + + + + +--- + + + +## function `MIPS.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `MIPS.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `MIPS.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `MIPS.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int] +``` + + + + + +--- + + + +## function `MIPS.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `MIPS.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `MIPS.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `MIPS.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `MIPS.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `MIPS.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `MIPS.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `MIPS.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `MIPS64` + + + + + +--- + +#### property MIPS64.endianness + + + + + +--- + +#### property MIPS64.fp + + + + + +--- + +#### property MIPS64.pc + + + + + +--- + +#### property MIPS64.ptrsize + + + + + +--- + +#### property MIPS64.registers + + + + + +--- + +#### property MIPS64.sp + + + + + + + +--- + + + +## function `MIPS64.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `MIPS64.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `MIPS64.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `MIPS64.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int] +``` + + + + + +--- + + + +## function `MIPS64.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `MIPS64.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `MIPS64.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `MIPS64.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `MIPS64.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `MIPS64.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `MIPS64.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `MIPS64.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + + + + + + +--- + +## class `MemoryCommand` +Add or remove address ranges to the memory view. + + + +## function `MemoryCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property MemoryCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `MemoryCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `MemoryCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `MemoryCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `MemoryCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `MemoryCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `MemoryCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `MemoryCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `MemoryCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `MemoryCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `MemoryUnwatchCommand` +Removes address ranges to the memory view. + + + +## function `MemoryUnwatchCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property MemoryUnwatchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `MemoryUnwatchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `MemoryUnwatchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `MemoryUnwatchCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `MemoryUnwatchCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `MemoryUnwatchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `MemoryUnwatchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `MemoryUnwatchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `MemoryUnwatchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `MemoryUnwatchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `MemoryWatchCommand` +Adds address ranges to the memory view. + + + +## function `MemoryWatchCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property MemoryWatchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `MemoryWatchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `MemoryWatchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `MemoryWatchCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `MemoryWatchCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `MemoryWatchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `MemoryWatchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `MemoryWatchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `MemoryWatchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `MemoryWatchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `MemoryWatchListCommand` +Lists all watchpoints to display in context layout. + + + +## function `MemoryWatchListCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property MemoryWatchListCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `MemoryWatchListCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `MemoryWatchListCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `MemoryWatchListCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `MemoryWatchListCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `MemoryWatchListCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `MemoryWatchListCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `MemoryWatchListCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `MemoryWatchListCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `MemoryWatchListCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `MemoryWatchResetCommand` +Removes all watchpoints. + + + +## function `MemoryWatchResetCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property MemoryWatchResetCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `MemoryWatchResetCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `MemoryWatchResetCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `MemoryWatchResetCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `MemoryWatchResetCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `MemoryWatchResetCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `MemoryWatchResetCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `MemoryWatchResetCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `MemoryWatchResetCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `MemoryWatchResetCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `NamedBreakpoint` +Breakpoint which shows a specified name, when hit. + + + +## function `NamedBreakpoint.__init__` + +```python +__init__(location: str, name: str) → None +``` + + + + + + + + +--- + + + +## function `NamedBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `NamedBreakpointCommand` +Sets a breakpoint and assigns a name to it, which will be shown, when it's hit. + + + +## function `NamedBreakpointCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property NamedBreakpointCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `NamedBreakpointCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `NamedBreakpointCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `NamedBreakpointCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `NamedBreakpointCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `NamedBreakpointCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `NamedBreakpointCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `NamedBreakpointCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `NamedBreakpointCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `NamedBreakpointCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `NopCommand` +Patch the instruction(s) pointed by parameters with NOP. Note: this command is architecture aware. + + + +## function `NopCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property NopCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `NopCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `NopCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `NopCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `NopCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `NopCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `NopCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `NopCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `NopCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `NopCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PCustomCommand` +Dump user defined structure. This command attempts to reproduce WinDBG awesome `dt` command for GDB and allows to apply structures (from symbols or custom) directly to an address. Custom structures can be defined in pure Python using ctypes, and should be stored in a specific directory, whose path must be stored in the `pcustom.struct_path` configuration setting. + + + +## function `PCustomCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PCustomCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PCustomCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PCustomCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PCustomCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PCustomCommand.explode_type` + +```python +explode_type(arg: str) → Tuple[str, str] +``` + + + + + +--- + + + +## function `PCustomCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PCustomCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PCustomCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PCustomCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PCustomCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PCustomCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PCustomEditCommand` +PCustom: edit the content of a given structure + + + +## function `PCustomEditCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PCustomEditCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PCustomEditCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PCustomEditCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PCustomEditCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `PCustomEditCommand.explode_type` + +```python +explode_type(arg: str) → Tuple[str, str] +``` + + + + + +--- + + + +## function `PCustomEditCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PCustomEditCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PCustomEditCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PCustomEditCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PCustomEditCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PCustomEditCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PCustomListCommand` +PCustom: list available structures + + + +## function `PCustomListCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PCustomListCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PCustomListCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PCustomListCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PCustomListCommand.do_invoke` + +```python +do_invoke(_: List) → None +``` + +Dump the list of all the structures and their respective. + +--- + + + +## function `PCustomListCommand.explode_type` + +```python +explode_type(arg: str) → Tuple[str, str] +``` + + + + + +--- + + + +## function `PCustomListCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PCustomListCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PCustomListCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PCustomListCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PCustomListCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PCustomListCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PCustomShowCommand` +PCustom: show the content of a given structure + + + +## function `PCustomShowCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PCustomShowCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PCustomShowCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PCustomShowCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PCustomShowCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `PCustomShowCommand.explode_type` + +```python +explode_type(arg: str) → Tuple[str, str] +``` + + + + + +--- + + + +## function `PCustomShowCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PCustomShowCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PCustomShowCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PCustomShowCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PCustomShowCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PCustomShowCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchByteCommand` +Write specified BYTE to the specified address. + + + +## function `PatchByteCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatchByteCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PatchByteCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PatchByteCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PatchByteCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PatchByteCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PatchByteCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PatchByteCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PatchByteCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PatchByteCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PatchByteCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchCommand` +Write specified values to the specified address. + + + +## function `PatchCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PatchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PatchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PatchCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PatchCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PatchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PatchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PatchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PatchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PatchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchDwordCommand` +Write specified DWORD to the specified address. + + + +## function `PatchDwordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatchDwordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PatchDwordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PatchDwordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PatchDwordCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PatchDwordCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PatchDwordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PatchDwordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PatchDwordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PatchDwordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PatchDwordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchQwordCommand` +Write specified QWORD to the specified address. + + + +## function `PatchQwordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatchQwordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PatchQwordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PatchQwordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PatchQwordCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PatchQwordCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PatchQwordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PatchQwordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PatchQwordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PatchQwordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PatchQwordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchStringCommand` +Write specified string to the specified memory location pointed by ADDRESS. + + + +## function `PatchStringCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property PatchStringCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PatchStringCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PatchStringCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PatchStringCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `PatchStringCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PatchStringCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PatchStringCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PatchStringCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PatchStringCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PatchStringCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchWordCommand` +Write specified WORD to the specified address. + + + +## function `PatchWordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatchWordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PatchWordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PatchWordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PatchWordCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PatchWordCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PatchWordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PatchWordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PatchWordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PatchWordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PatchWordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatternCommand` +Generate or Search a De Bruijn Sequence of unique substrings of length N and a total length of LENGTH. The default value of N is set to match the currently loaded architecture. + + + +## function `PatternCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatternCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PatternCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PatternCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PatternCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `PatternCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PatternCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PatternCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PatternCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PatternCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PatternCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatternCreateCommand` +Generate a De Bruijn Sequence of unique substrings of length N and a total length of LENGTH. The default value of N is set to match the currently loaded architecture. + + + +## function `PatternCreateCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property PatternCreateCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PatternCreateCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PatternCreateCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PatternCreateCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PatternCreateCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PatternCreateCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PatternCreateCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PatternCreateCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PatternCreateCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PatternCreateCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatternSearchCommand` +Search a De Bruijn Sequence of unique substrings of length N and a maximum total length of MAX_LENGTH. The default value of N is set to match the currently loaded architecture. The PATTERN argument can be a GDB symbol (such as a register name), a string or a hexadecimal value + + + +## function `PatternSearchCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property PatternSearchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PatternSearchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PatternSearchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PatternSearchCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PatternSearchCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PatternSearchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PatternSearchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PatternSearchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PatternSearchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PatternSearchCommand.search` + +```python +search(pattern: str, size: int, period: int) → None +``` + + + + + +--- + + + +## function `PatternSearchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Permission` +GEF representation of Linux permission. + + + + + +--- + +## class `Phdr` + + + + + + +## function `Phdr.__init__` + +```python +__init__(elf: __main__.Elf, off: int) → None +``` + + + + + + + + + +--- + +## class `PieAttachCommand` +Do attach with PIE breakpoint support. + + + +## function `PieAttachCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property PieAttachCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PieAttachCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PieAttachCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PieAttachCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `PieAttachCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PieAttachCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PieAttachCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PieAttachCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PieAttachCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PieAttachCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieBreakpointCommand` +Set a PIE breakpoint at an offset from the target binaries base address. + + + +## function `PieBreakpointCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property PieBreakpointCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PieBreakpointCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PieBreakpointCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PieBreakpointCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PieBreakpointCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PieBreakpointCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PieBreakpointCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PieBreakpointCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PieBreakpointCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PieBreakpointCommand.set_pie_breakpoint` + +```python +set_pie_breakpoint(set_func: Callable[[int], str], addr: int) → None +``` + + + + + +--- + + + +## function `PieBreakpointCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieCommand` +PIE breakpoint support. + + + +## function `PieCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PieCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PieCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PieCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PieCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `PieCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PieCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PieCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PieCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PieCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PieCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieDeleteCommand` +Delete a PIE breakpoint. + + + +## function `PieDeleteCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property PieDeleteCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PieDeleteCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PieDeleteCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PieDeleteCommand.delete_bp` + +```python +delete_bp(breakpoints: List[__main__.PieVirtualBreakpoint]) → None +``` + + + + + +--- + + + +## function `PieDeleteCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PieDeleteCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PieDeleteCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PieDeleteCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PieDeleteCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PieDeleteCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PieDeleteCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieInfoCommand` +Display breakpoint info. + + + +## function `PieInfoCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property PieInfoCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PieInfoCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PieInfoCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PieInfoCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PieInfoCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PieInfoCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PieInfoCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PieInfoCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PieInfoCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PieInfoCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieRemoteCommand` +Attach to a remote connection with PIE breakpoint support. + + + +## function `PieRemoteCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property PieRemoteCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PieRemoteCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PieRemoteCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PieRemoteCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `PieRemoteCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PieRemoteCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PieRemoteCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PieRemoteCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PieRemoteCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PieRemoteCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieRunCommand` +Run process with PIE breakpoint support. + + + +## function `PieRunCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property PieRunCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PieRunCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PieRunCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PieRunCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `PieRunCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PieRunCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PieRunCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PieRunCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PieRunCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PieRunCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieVirtualBreakpoint` +PIE virtual breakpoint (not real breakpoint). + + + +## function `PieVirtualBreakpoint.__init__` + +```python +__init__(set_func: Callable[[int], str], vbp_num: int, addr: int) → None +``` + + + + + + + + +--- + + + +## function `PieVirtualBreakpoint.destroy` + +```python +destroy() → None +``` + + + + + +--- + + + +## function `PieVirtualBreakpoint.instantiate` + +```python +instantiate(base: int) → None +``` + + + + + + +--- + +## class `PowerPC` + + + + + +--- + +#### property PowerPC.endianness + + + + + +--- + +#### property PowerPC.fp + + + + + +--- + +#### property PowerPC.pc + + + + + +--- + +#### property PowerPC.registers + + + + + +--- + +#### property PowerPC.sp + + + + + + + +--- + + + +## function `PowerPC.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `PowerPC.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `PowerPC.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `PowerPC.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int] +``` + + + + + +--- + + + +## function `PowerPC.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `PowerPC.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `PowerPC.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `PowerPC.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `PowerPC.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `PowerPC.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `PowerPC.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `PowerPC.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `PowerPC64` + + + + + +--- + +#### property PowerPC64.endianness + + + + + +--- + +#### property PowerPC64.fp + + + + + +--- + +#### property PowerPC64.pc + + + + + +--- + +#### property PowerPC64.registers + + + + + +--- + +#### property PowerPC64.sp + + + + + + + +--- + + + +## function `PowerPC64.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `PowerPC64.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `PowerPC64.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `PowerPC64.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int] +``` + + + + + +--- + + + +## function `PowerPC64.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `PowerPC64.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `PowerPC64.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `PowerPC64.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `PowerPC64.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `PowerPC64.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `PowerPC64.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `PowerPC64.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `PrintFormatCommand` +Print bytes format in commonly used formats, such as literals in high level languages. + + + +## function `PrintFormatCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PrintFormatCommand.format_matrix + + + + + +--- + +#### property PrintFormatCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `PrintFormatCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `PrintFormatCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `PrintFormatCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `PrintFormatCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `PrintFormatCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `PrintFormatCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `PrintFormatCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `PrintFormatCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `PrintFormatCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ProcessListingCommand` +List and filter process. If a PATTERN is given as argument, results shown will be grepped by this pattern. + + + +## function `ProcessListingCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ProcessListingCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ProcessListingCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ProcessListingCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ProcessListingCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `ProcessListingCommand.get_processes` + +```python +get_processes() → Generator[Dict[str, str], NoneType, NoneType] +``` + + + + + +--- + + + +## function `ProcessListingCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ProcessListingCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ProcessListingCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ProcessListingCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ProcessListingCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ProcessListingCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ProcessStatusCommand` +Extends the info given by GDB `info proc`, by giving an exhaustive description of the process status (file descriptors, ancestor, descendants, etc.). + + + +## function `ProcessStatusCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ProcessStatusCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ProcessStatusCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ProcessStatusCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ProcessStatusCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `ProcessStatusCommand.get_children_pids` + +```python +get_children_pids(pid: int) → List[int] +``` + + + + + +--- + + + +## function `ProcessStatusCommand.get_cmdline_of` + +```python +get_cmdline_of(pid: int) → str +``` + + + + + +--- + + + +## function `ProcessStatusCommand.get_process_path_of` + +```python +get_process_path_of(pid: int) → str +``` + + + + + +--- + + + +## function `ProcessStatusCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ProcessStatusCommand.get_state_of` + +```python +get_state_of(pid: int) → Dict[str, str] +``` + + + + + +--- + + + +## function `ProcessStatusCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ProcessStatusCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ProcessStatusCommand.list_sockets` + +```python +list_sockets(pid: int) → List[int] +``` + + + + + +--- + + + +## function `ProcessStatusCommand.parse_ip_port` + +```python +parse_ip_port(addr: str) → Tuple[str, int] +``` + + + + + +--- + + + +## function `ProcessStatusCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ProcessStatusCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ProcessStatusCommand.show_ancestor` + +```python +show_ancestor() → None +``` + + + + + +--- + + + +## function `ProcessStatusCommand.show_connections` + +```python +show_connections() → None +``` + + + + + +--- + + + +## function `ProcessStatusCommand.show_descendants` + +```python +show_descendants() → None +``` + + + + + +--- + + + +## function `ProcessStatusCommand.show_fds` + +```python +show_fds() → None +``` + + + + + +--- + + + +## function `ProcessStatusCommand.show_info_proc` + +```python +show_info_proc() → None +``` + + + + + +--- + + + +## function `ProcessStatusCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `RISCV` + + + + + +--- + +#### property RISCV.endianness + + + + + +--- + +#### property RISCV.fp + + + + + +--- + +#### property RISCV.instruction_length + + + + + +--- + +#### property RISCV.pc + + + + + +--- + +#### property RISCV.ptrsize + + + + + +--- + +#### property RISCV.registers + + + + + +--- + +#### property RISCV.sp + + + + + + + +--- + + + +## function `RISCV.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `RISCV.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `RISCV.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `RISCV.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int] +``` + + + + + +--- + + + +## function `RISCV.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `RISCV.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `RISCV.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `RISCV.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `RISCV.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `RISCV.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `RISCV.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `RISCV.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `RedirectOutputContext` + + + + + + +## function `RedirectOutputContext.__init__` + +```python +__init__(to: str = '/dev/null') → None +``` + + + + + + + + + +--- + +## class `RemoteCommand` +GDB `target remote` command on steroids. This command will use the remote procfs to create a local copy of the execution environment, including the target binary and its libraries in the local temporary directory (the value by default is in `gef.config.tempdir`). Additionally, it will fetch all the /proc/PID/maps and loads all its information. If procfs is not available remotely, the command will likely fail. You can however still use the limited command provided by GDB `target remote`. + + + +## function `RemoteCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property RemoteCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `RemoteCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `RemoteCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `RemoteCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `RemoteCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `RemoteCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `RemoteCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `RemoteCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `RemoteCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `RemoteCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ResetCacheCommand` +Reset cache of all stored data. This command is here for debugging and test purposes, GEF handles properly the cache reset under "normal" scenario. + + + +## function `ResetCacheCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property ResetCacheCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ResetCacheCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ResetCacheCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ResetCacheCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `ResetCacheCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ResetCacheCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ResetCacheCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ResetCacheCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ResetCacheCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ResetCacheCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `SPARC` +Refs: +- https://www.cse.scu.edu/~atkinson/teaching/sp05/259/sparc.pdf + + +--- + +#### property SPARC.endianness + + + + + +--- + +#### property SPARC.fp + + + + + +--- + +#### property SPARC.pc + + + + + +--- + +#### property SPARC.ptrsize + + + + + +--- + +#### property SPARC.registers + + + + + +--- + +#### property SPARC.sp + + + + + + + +--- + + + +## function `SPARC.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `SPARC.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `SPARC.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `SPARC.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int] +``` + + + + + +--- + + + +## function `SPARC.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `SPARC.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `SPARC.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `SPARC.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `SPARC.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `SPARC.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `SPARC.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `SPARC.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `SPARC64` +Refs: +- http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_sparc.pdf +- https://cr.yp.to/2005-590/sparcv9.pdf + + +--- + +#### property SPARC64.endianness + + + + + +--- + +#### property SPARC64.fp + + + + + +--- + +#### property SPARC64.pc + + + + + +--- + +#### property SPARC64.ptrsize + + + + + +--- + +#### property SPARC64.registers + + + + + +--- + +#### property SPARC64.sp + + + + + + + +--- + + + +## function `SPARC64.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `SPARC64.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `SPARC64.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `SPARC64.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int] +``` + + + + + +--- + + + +## function `SPARC64.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `SPARC64.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `SPARC64.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `SPARC64.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `SPARC64.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `SPARC64.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `SPARC64.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `SPARC64.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `ScanSectionCommand` +Search for addresses that are located in a memory mapping (haystack) that belonging to another (needle). + + + +## function `ScanSectionCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property ScanSectionCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ScanSectionCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ScanSectionCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ScanSectionCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `ScanSectionCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ScanSectionCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ScanSectionCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ScanSectionCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ScanSectionCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ScanSectionCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `SearchPatternCommand` +SearchPatternCommand: search a pattern in memory. If given an hex value (starting with 0x) the command will also try to look for upwards cross-references to this address. + + + +## function `SearchPatternCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property SearchPatternCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `SearchPatternCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `SearchPatternCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `SearchPatternCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `SearchPatternCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `SearchPatternCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `SearchPatternCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `SearchPatternCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `SearchPatternCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `SearchPatternCommand.print_loc` + +```python +print_loc(loc: Tuple[int, int, str]) → None +``` + + + + + +--- + + + +## function `SearchPatternCommand.print_section` + +```python +print_section(section: __main__.Section) → None +``` + + + + + +--- + + + +## function `SearchPatternCommand.search_binpattern_by_address` + +```python +search_binpattern_by_address( + binpattern: bytes, + start_address: int, + end_address: int +) → List[Tuple[int, int, Optional[str]]] +``` + +Search a binary pattern within a range defined by arguments. + +--- + + + +## function `SearchPatternCommand.search_pattern` + +```python +search_pattern(pattern: str, section_name: str) → None +``` + +Search a pattern within the whole userland memory. + +--- + + + +## function `SearchPatternCommand.search_pattern_by_address` + +```python +search_pattern_by_address( + pattern: str, + start_address: int, + end_address: int +) → List[Tuple[int, int, Optional[str]]] +``` + +Search a pattern within a range defined by arguments. + +--- + + + +## function `SearchPatternCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Section` +GEF representation of process memory sections. + + + +## function `Section.__init__` + +```python +__init__(**kwargs: Any) → None +``` + + + + + + +--- + +#### property Section.realpath + + + + + +--- + +#### property Section.size + + + + + + + +--- + + + +## function `Section.is_executable` + +```python +is_executable() → bool +``` + + + + + +--- + + + +## function `Section.is_readable` + +```python +is_readable() → bool +``` + + + + + +--- + + + +## function `Section.is_writable` + +```python +is_writable() → bool +``` + + + + + + +--- + +## class `SectionBaseFunction` +Return the matching file's base address plus an optional offset. Defaults to current file. Note that quotes need to be escaped + + + +## function `SectionBaseFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `SectionBaseFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +## function `SectionBaseFunction.do_invoke` + +```python +do_invoke(args: List) → int +``` + + + + + +--- + + + +## function `SectionBaseFunction.invoke` + +```python +invoke(*args: Any) → int +``` + + + + + + +--- + +## class `Shdr` + + + + + + +## function `Shdr.__init__` + +```python +__init__(elf: Optional[__main__.Elf], off: int) → None +``` + + + + + + + + + +--- + +## class `ShellcodeCommand` +ShellcodeCommand uses @JonathanSalwan simple-yet-awesome shellcode API to download shellcodes. + + + +## function `ShellcodeCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ShellcodeCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ShellcodeCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ShellcodeCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ShellcodeCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `ShellcodeCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ShellcodeCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ShellcodeCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ShellcodeCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ShellcodeCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ShellcodeCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ShellcodeGetCommand` +Download shellcode from shell-storm's shellcode database. + + + +## function `ShellcodeGetCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property ShellcodeGetCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ShellcodeGetCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ShellcodeGetCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ShellcodeGetCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `ShellcodeGetCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ShellcodeGetCommand.get_shellcode` + +```python +get_shellcode(sid: int) → None +``` + + + + + +--- + + + +## function `ShellcodeGetCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ShellcodeGetCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ShellcodeGetCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ShellcodeGetCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ShellcodeGetCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ShellcodeSearchCommand` +Search pattern in shell-storm's shellcode database. + + + +## function `ShellcodeSearchCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property ShellcodeSearchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `ShellcodeSearchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `ShellcodeSearchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `ShellcodeSearchCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `ShellcodeSearchCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `ShellcodeSearchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `ShellcodeSearchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `ShellcodeSearchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `ShellcodeSearchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `ShellcodeSearchCommand.search_shellcode` + +```python +search_shellcode(search_options: List) → None +``` + + + + + +--- + + + +## function `ShellcodeSearchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `SmartEvalCommand` +SmartEval: Smart eval (vague approach to mimic WinDBG `?`). + + + +## function `SmartEvalCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property SmartEvalCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `SmartEvalCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `SmartEvalCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `SmartEvalCommand.distance` + +```python +distance(args: Tuple[str, str]) → None +``` + + + + + +--- + + + +## function `SmartEvalCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `SmartEvalCommand.evaluate` + +```python +evaluate(expr: List[str]) → None +``` + + + + + +--- + + + +## function `SmartEvalCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `SmartEvalCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `SmartEvalCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `SmartEvalCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `SmartEvalCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `SmartEvalCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `SolveKernelSymbolCommand` +Solve kernel symbols from kallsyms table. + + + +## function `SolveKernelSymbolCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property SolveKernelSymbolCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `SolveKernelSymbolCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `SolveKernelSymbolCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `SolveKernelSymbolCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `SolveKernelSymbolCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `SolveKernelSymbolCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `SolveKernelSymbolCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `SolveKernelSymbolCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `SolveKernelSymbolCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `SolveKernelSymbolCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `StackOffsetFunction` +Return the current stack base address plus an optional offset. + + + +## function `StackOffsetFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `StackOffsetFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +## function `StackOffsetFunction.do_invoke` + +```python +do_invoke(args: List) → int +``` + + + + + +--- + + + +## function `StackOffsetFunction.invoke` + +```python +invoke(*args: Any) → int +``` + + + + + + +--- + +## class `StubBreakpoint` +Create a breakpoint to permanently disable a call (fork/alarm/signal/etc.). + + + +## function `StubBreakpoint.__init__` + +```python +__init__(func: str, retval: Optional[int]) → None +``` + + + + + + + + +--- + + + +## function `StubBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `StubCommand` +Stub out the specified function. This function is useful when needing to skip one function to be called and disrupt your runtime flow (ex. fork). + + + +## function `StubCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property StubCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `StubCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `StubCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `StubCommand.wrapper` + +```python +wrapper(*args: Any, **kwargs: Any) → Callable +``` + + + + + +--- + + + +## function `StubCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `StubCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `StubCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `StubCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `StubCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `StubCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `TraceFreeBreakpoint` +Track calls to free() and attempts to detect inconsistencies. + + + +## function `TraceFreeBreakpoint.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `TraceFreeBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceFreeRetBreakpoint` +Internal temporary breakpoint to track free()d values. + + + +## function `TraceFreeRetBreakpoint.__init__` + +```python +__init__(addr: int) → None +``` + + + + + + + + +--- + + + +## function `TraceFreeRetBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceMallocBreakpoint` +Track allocations done with malloc() or calloc(). + + + +## function `TraceMallocBreakpoint.__init__` + +```python +__init__(name: str) → None +``` + + + + + + + + +--- + + + +## function `TraceMallocBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceMallocRetBreakpoint` +Internal temporary breakpoint to retrieve the return value of malloc(). + + + +## function `TraceMallocRetBreakpoint.__init__` + +```python +__init__(size: int, name: str) → None +``` + + + + + + + + +--- + + + +## function `TraceMallocRetBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceReallocBreakpoint` +Track re-allocations done with realloc(). + + + +## function `TraceReallocBreakpoint.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +## function `TraceReallocBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceReallocRetBreakpoint` +Internal temporary breakpoint to retrieve the return value of realloc(). + + + +## function `TraceReallocRetBreakpoint.__init__` + +```python +__init__(ptr: int, size: int) → None +``` + + + + + + + + +--- + + + +## function `TraceReallocRetBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceRunCommand` +Create a runtime trace of all instructions executed from $pc to LOCATION specified. The trace is stored in a text file that can be next imported in IDA Pro to visualize the runtime path. + + + +## function `TraceRunCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property TraceRunCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `TraceRunCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `TraceRunCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `TraceRunCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `TraceRunCommand.get_frames_size` + +```python +get_frames_size() → int +``` + + + + + +--- + + + +## function `TraceRunCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `TraceRunCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `TraceRunCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `TraceRunCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `TraceRunCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `TraceRunCommand.start_tracing` + +```python +start_tracing(loc_start: int, loc_end: int, depth: int) → None +``` + + + + + +--- + + + +## function `TraceRunCommand.trace` + +```python +trace(loc_start: int, loc_end: int, depth: int) → None +``` + + + + + +--- + + + +## function `TraceRunCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `UafWatchpoint` +Custom watchpoints set TraceFreeBreakpoint() to monitor free()d pointers being used. + + + +## function `UafWatchpoint.__init__` + +```python +__init__(addr: int) → None +``` + + + + + + + + +--- + + + +## function `UafWatchpoint.stop` + +```python +stop() → bool +``` + +If this method is triggered, we likely have a UaF. Break the execution and report it. + + +--- + +## class `VMMapCommand` +Display a comprehensive layout of the virtual memory mapping. If a filter argument, GEF will filter out the mapping whose pathname do not match that filter. + + + +## function `VMMapCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property VMMapCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `VMMapCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `VMMapCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `VMMapCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `VMMapCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `VMMapCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `VMMapCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `VMMapCommand.is_integer` + +```python +is_integer(n: str) → bool +``` + + + + + +--- + + + +## function `VMMapCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `VMMapCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `VMMapCommand.print_entry` + +```python +print_entry(entry: __main__.Section) → None +``` + + + + + +--- + + + +## function `VMMapCommand.show_legend` + +```python +show_legend() → None +``` + + + + + +--- + + + +## function `VMMapCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `VersionCommand` +Display GEF version info. + + + +## function `VersionCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property VersionCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `VersionCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `VersionCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `VersionCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `VersionCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `VersionCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `VersionCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `VersionCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `VersionCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `VersionCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `X86` + + + + + +--- + +#### property X86.endianness + + + + + +--- + +#### property X86.fp + + + + + +--- + +#### property X86.pc + + + + + +--- + +#### property X86.ptrsize + + + + + +--- + +#### property X86.registers + + + + + +--- + +#### property X86.sp + + + + + + + +--- + + + +## function `X86.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `X86.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `X86.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + + + + + +--- + + + +## function `X86.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int] +``` + + + + + +--- + + + +## function `X86.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `X86.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `X86.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `X86.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `X86.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `X86.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `X86.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `X86.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `X86_64` + + + + + +--- + +#### property X86_64.endianness + + + + + +--- + +#### property X86_64.fp + + + + + +--- + +#### property X86_64.pc + + + + + +--- + +#### property X86_64.ptrsize + + + + + +--- + +#### property X86_64.registers + + + + + +--- + +#### property X86_64.sp + + + + + + + +--- + + + +## function `X86_64.canary_address` + +```python +canary_address() → int +``` + + + + + +--- + + + +## function `X86_64.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +## function `X86_64.get_ith_parameter` + +```python +get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +## function `X86_64.get_ra` + +```python +get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int] +``` + + + + + +--- + + + +## function `X86_64.is_branch_taken` + +```python +is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str] +``` + + + + + +--- + + + +## function `X86_64.is_call` + +```python +is_call(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `X86_64.is_conditional_branch` + +```python +is_conditional_branch(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `X86_64.is_ret` + +```python +is_ret(insn: __main__.Instruction) → bool +``` + + + + + +--- + + + +## function `X86_64.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str +``` + + + + + +--- + + + +## function `X86_64.register` + +```python +register(name: str) → int +``` + + + + + +--- + + + +## function `X86_64.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +## function `X86_64.supports_gdb_arch` + +```python +supports_gdb_arch(gdb_arch: str) → Optional[bool] +``` + +If implemented by a child `Architecture`, this function dictates if the current class supports the loaded ELF file (which can be accessed via `gef.binary`). This callback function will override any assumption made by GEF to determine the architecture. + + +--- + +## class `XAddressInfoCommand` +Retrieve and display runtime information for the location(s) given as parameter. + + + +## function `XAddressInfoCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property XAddressInfoCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `XAddressInfoCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `XAddressInfoCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `XAddressInfoCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `XAddressInfoCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `XAddressInfoCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `XAddressInfoCommand.infos` + +```python +infos(address: int) → None +``` + + + + + +--- + + + +## function `XAddressInfoCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `XAddressInfoCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `XAddressInfoCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `XAddressInfoCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `XFilesCommand` +Shows all libraries (and sections) loaded by binary. This command extends the GDB command `info files`, by retrieving more information from extra sources, and providing a better display. If an argument FILE is given, the output will grep information related to only that file. If an argument name is also given, the output will grep to the name within FILE. + + + +## function `XFilesCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property XFilesCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `XFilesCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `XFilesCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `XFilesCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `XFilesCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `XFilesCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `XFilesCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `XFilesCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `XFilesCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `XFilesCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `XorMemoryCommand` +XOR a block of memory. The command allows to simply display the result, or patch it runtime at runtime. + + + +## function `XorMemoryCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property XorMemoryCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `XorMemoryCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `XorMemoryCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `XorMemoryCommand.do_invoke` + +```python +do_invoke(_: List[str]) → None +``` + + + + + +--- + + + +## function `XorMemoryCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `XorMemoryCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `XorMemoryCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `XorMemoryCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `XorMemoryCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `XorMemoryCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `XorMemoryDisplayCommand` +Display a block of memory pointed by ADDRESS by xor-ing each byte with KEY. The key must be provided in hexadecimal format. + + + +## function `XorMemoryDisplayCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property XorMemoryDisplayCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `XorMemoryDisplayCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `XorMemoryDisplayCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `XorMemoryDisplayCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `XorMemoryDisplayCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `XorMemoryDisplayCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `XorMemoryDisplayCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `XorMemoryDisplayCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `XorMemoryDisplayCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `XorMemoryDisplayCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `XorMemoryPatchCommand` +Patch a block of memory pointed by ADDRESS by xor-ing each byte with KEY. The key must be provided in hexadecimal format. + + + +## function `XorMemoryPatchCommand.__init__` + +```python +__init__(*args: Any, **kwargs: Any) → None +``` + + + + + + +--- + +#### property XorMemoryPatchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +## function `XorMemoryPatchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + +`add_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name] = value` instead + +--- + + + +## function `XorMemoryPatchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + +`del_setting` is **DEPRECATED** and will be removed in the future. Use `del self[setting_name]` instead + +--- + + + +## function `XorMemoryPatchCommand.do_invoke` + +```python +do_invoke(argv: List[str]) → None +``` + + + + + +--- + + + +## function `XorMemoryPatchCommand.get_setting` + +```python +get_setting(name: str) → Any +``` + +`get_setting` is **DEPRECATED** and will be removed in the future. Use `self[setting_name]` instead + +--- + + + +## function `XorMemoryPatchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + +`has_setting` is **DEPRECATED** and will be removed in the future. Use `setting_name in self` instead + +--- + + + +## function `XorMemoryPatchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +## function `XorMemoryPatchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +## function `XorMemoryPatchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +## function `XorMemoryPatchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Zone` +Zone(name, zone_start, zone_end, filename) + + + + + +--- + +## class `classproperty` +Make the attribute a `classproperty`. + + + + + + + +--- + +_This file was automatically generated via [lazydocs](https://github.com/ml-tooling/lazydocs)._ diff --git a/scripts/new-release.py b/scripts/new-release.py index d818c51c2..59fa65949 100644 --- a/scripts/new-release.py +++ b/scripts/new-release.py @@ -46,7 +46,7 @@ def shell(x: str) -> str: def generate_changelog(args: argparse.Namespace) -> bool: """Generate the changelog for the new release.""" - latest_tag = shell("git describe --abbrev=0") + latest_tag = shell("git describe --tags --abbrev=0") print(f"Creating changelog for {args.version} in {args.output_file.name}") args.output_file.write(f"# Changelog: {args.version} - {args.codename}{os.linesep}{os.linesep}") From 0fd751ec151952c4efbdcb5b2107b19b49256239 Mon Sep 17 00:00:00 2001 From: crazy hugsy Date: Mon, 29 May 2023 08:02:01 -0700 Subject: [PATCH 05/21] Update README.md Updated Discord invite link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aada1bcb4..4fee76a4e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

- Discord + Discord Docs Try GEF

From 74e862628aa6fa887cabc9233157e81bbb9f00fe Mon Sep 17 00:00:00 2001 From: Dreg Date: Thu, 13 Jul 2023 23:10:07 +0200 Subject: [PATCH 06/21] Update `nop` command to patch entire instructions (#959) * The default behavior to `nop` is to patch entire instruction(s) unless indicated otherwise via the `--b` toggle * `--n` can be used to specify the number of nops to insert --- docs/commands/nop.md | 26 +++++++++++++---------- gef.py | 41 ++++++++++++++++++++++++++---------- tests/commands/nop.py | 49 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 88 insertions(+), 28 deletions(-) diff --git a/docs/commands/nop.md b/docs/commands/nop.md index e0d08a628..d519c290f 100644 --- a/docs/commands/nop.md +++ b/docs/commands/nop.md @@ -1,18 +1,22 @@ ## Command `nop` -The `nop` command allows you to easily skip instructions. +The `nop` command allows you to easily patch instructions with nops. ``` -gef ➤ help nop -Patch the instruction(s) pointed by parameters with NOP. Note: this command is architecture -aware. -Syntax: nop [LOCATION] [--nb NUM_BYTES] - LOCATION address/symbol to patch - --nb NUM_BYTES Instead of writing one instruction, patch the specified number of bytes +nop [LOCATION] [--n NUM_ITEMS] [--b] ``` -`LOCATION` indicates the address of the instruction to bypass. If not -specified, it will use the current value of the program counter. +`LOCATION` address/symbol to patch -If `--nb ` is entered, gef will explicitly patch the specified number of -bytes. Otherwise it will patch the _whole_ instruction at the target location. +`--n NUM_ITEMS` Instead of writing one instruction/nop, patch the specified number of instructions/nops (full instruction size by default) + +`--b` Instead of writing full instruction size, patch the specified number of nops + +```bash +gef➤ nop +gef➤ nop $pc+3 +gef➤ nop --n 2 $pc+3 +gef➤ nop --b +gef➤ nop --b $pc+3 +gef➤ nop --b --n 2 $pc+3 +``` \ No newline at end of file diff --git a/gef.py b/gef.py index 1a409c397..d10568bdd 100644 --- a/gef.py +++ b/gef.py @@ -5991,35 +5991,54 @@ class NopCommand(GenericCommand): aware.""" _cmdline_ = "nop" - _syntax_ = ("{_cmdline_} [LOCATION] [--nb NUM_BYTES]" + _syntax_ = ("{_cmdline_} [LOCATION] [--n NUM_ITEMS] [--b]" "\n\tLOCATION\taddress/symbol to patch" - "\t--nb NUM_BYTES\tInstead of writing one instruction, patch the specified number of bytes") + "\t--n NUM_ITEMS\tInstead of writing one instruction/nop, patch the specified number of instructions/nops (full instruction size by default)" + "\t--b\tInstead of writing full instruction size, patch the specified number of nops") _example_ = f"{_cmdline_} $pc" + _example_ = [f"{_cmdline_}", + f"{_cmdline_} $pc+3", + f"{_cmdline_} --n 2 $pc+3", + f"{_cmdline_} --b", + f"{_cmdline_} --b $pc+3", + f"{_cmdline_} --b --n 2 $pc+3",] + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - @parse_arguments({"address": "$pc"}, {"--nb": 0, }) + @parse_arguments({"address": "$pc"}, {"--n": 0, "--b": False}) def do_invoke(self, _: List[str], **kwargs: Any) -> None: args : argparse.Namespace = kwargs["arguments"] address = parse_address(args.address) nop = gef.arch.nop_insn - number_of_bytes = args.nb or 1 - insn = gef_get_instruction_at(address) + num_items = args.n or 1 + as_nops_flags = not args.b - if insn.size() != number_of_bytes: - warn(f"Patching {number_of_bytes} bytes at {address:#x} might result in corruption") + total_bytes = 0 + if as_nops_flags: + total_bytes = num_items * len(nop) + else: + try: + last_addr = gdb_get_nth_next_instruction_address(address, num_items) + except: + err(f"Cannot patch instruction at {address:#x}: MAYBE reaching unmapped area") + return + total_bytes = (last_addr - address) + gef_get_instruction_at(last_addr).size() - nops = bytearray(nop * number_of_bytes) - end_address = Address(value=address + len(nops)) + if total_bytes % len(nop): + warn(f"Patching {total_bytes} bytes at {address:#x} will result in a partially patched instruction and may break disassembly") + + nops = bytearray(nop * (total_bytes // len(nop))) + end_address = Address(value=address + total_bytes) if not end_address.valid: err(f"Cannot patch instruction at {address:#x}: reaching unmapped area") return - ok(f"Patching {len(nops)} bytes from {address:#x}") - gef.memory.write(address, nops, len(nops)) + ok(f"Patching {total_bytes} bytes from {address:#x}") + gef.memory.write(address, nops, total_bytes) return diff --git a/tests/commands/nop.py b/tests/commands/nop.py index 72ea670a4..0f90a1b03 100644 --- a/tests/commands/nop.py +++ b/tests/commands/nop.py @@ -19,13 +19,50 @@ def test_cmd_nop_inactive(self): res = gdb_run_cmd(f"{self.cmd}") self.assertFailIfInactiveSession(res) - @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_no_arg(self): + res = gdb_start_silent_cmd( - "pi print(f'*** *pc={u8(gef.memory.read(gef.arch.pc, 1))}')", + "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))", # 2 short jumps to pc after=( self.cmd, + "pi print(gef.memory.read(gef.arch.pc, 4))", # read 4 bytes + ) + ) + self.assertNoException(res) + self.assertIn(r'\x90\x90\xeb\xfe', res) # 2 nops + 1 short jump + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_arg(self): + + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.sp, p64(0xfeebfeebfeebfeeb))", # 4 short jumps to stack + after=( + f"{self.cmd} --n 2 $sp", + "pi print(gef.memory.read(gef.arch.sp, 8))", # read 8 bytes + ) + ) + self.assertNoException(res) + self.assertIn(r'\x90\x90\x90\x90\xeb\xfe\xeb\xfe', res) # 4 nops + 2 short jumps + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_invalid_end_address(self): + res = gdb_run_silent_cmd( + f"{self.cmd} --n 5 0x1337000+0x1000-4", + target=_target("mmap-known-address") + ) + self.assertNoException(res) + self.assertIn("reaching unmapped area", res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_as_bytes_no_arg(self): + res = gdb_start_silent_cmd( + "pi print(f'*** *pc={u8(gef.memory.read(gef.arch.pc, 1))}')", + after=( + f"{self.cmd} --b", "pi print(f'*** *pc={u8(gef.memory.read(gef.arch.pc, 1))}')", ) ) @@ -36,11 +73,11 @@ def test_cmd_nop_no_arg(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") - def test_cmd_nop_arg(self): + def test_cmd_nop_as_bytes_arg(self): res = gdb_start_silent_cmd( "pi print(f'*** *sp={u32(gef.memory.read(gef.arch.sp, 4))}')", after=( - f"{self.cmd} $sp --nb 4", + f"{self.cmd} --b --n 4 $sp", "pi print(f'*** *sp={u32(gef.memory.read(gef.arch.sp, 4))}')", ) ) @@ -51,9 +88,9 @@ def test_cmd_nop_arg(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") - def test_cmd_nop_invalid_end_address(self): + def test_cmd_nop_as_bytes_invalid_end_address(self): res = gdb_run_silent_cmd( - f"{self.cmd} 0x1337000+0x1000-4 --nb 5", + f"{self.cmd} --b --n 5 0x1337000+0x1000-4", target=_target("mmap-known-address") ) self.assertNoException(res) From ca7418c912f7bb3d250e1db6ade0b1bef54fffa8 Mon Sep 17 00:00:00 2001 From: Grazfather Date: Thu, 13 Jul 2023 21:30:49 -0400 Subject: [PATCH 07/21] nop: Fix off-by-one in unmap check (#960) --- gef.py | 4 ++-- tests/commands/nop.py | 30 ++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/gef.py b/gef.py index d10568bdd..8875fc48f 100644 --- a/gef.py +++ b/gef.py @@ -6030,9 +6030,9 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None: if total_bytes % len(nop): warn(f"Patching {total_bytes} bytes at {address:#x} will result in a partially patched instruction and may break disassembly") - + nops = bytearray(nop * (total_bytes // len(nop))) - end_address = Address(value=address + total_bytes) + end_address = Address(value=address + total_bytes - 1) if not end_address.valid: err(f"Cannot patch instruction at {address:#x}: reaching unmapped area") return diff --git a/tests/commands/nop.py b/tests/commands/nop.py index 0f90a1b03..9805c9b3e 100644 --- a/tests/commands/nop.py +++ b/tests/commands/nop.py @@ -21,7 +21,7 @@ def test_cmd_nop_inactive(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_no_arg(self): - + res = gdb_start_silent_cmd( "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))", # 2 short jumps to pc after=( @@ -30,12 +30,12 @@ def test_cmd_nop_no_arg(self): ) ) self.assertNoException(res) - self.assertIn(r'\x90\x90\xeb\xfe', res) # 2 nops + 1 short jump + self.assertIn(r"\x90\x90\xeb\xfe", res) # 2 nops + 1 short jump @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_arg(self): - + res = gdb_start_silent_cmd( "pi gef.memory.write(gef.arch.sp, p64(0xfeebfeebfeebfeeb))", # 4 short jumps to stack after=( @@ -44,7 +44,7 @@ def test_cmd_nop_arg(self): ) ) self.assertNoException(res) - self.assertIn(r'\x90\x90\x90\x90\xeb\xfe\xeb\xfe', res) # 4 nops + 2 short jumps + self.assertIn(r"\x90\x90\x90\x90\xeb\xfe\xeb\xfe", res) # 4 nops + 2 short jumps @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") @@ -63,13 +63,13 @@ def test_cmd_nop_as_bytes_no_arg(self): "pi print(f'*** *pc={u8(gef.memory.read(gef.arch.pc, 1))}')", after=( f"{self.cmd} --b", - "pi print(f'*** *pc={u8(gef.memory.read(gef.arch.pc, 1))}')", + "pi print(f'*** *pc={u8(gef.memory.read(gef.arch.pc, 1)):#x}')", ) ) self.assertNoException(res) lines = findlines("*** *pc=", res) self.assertEqual(len(lines), 2) - self.assertEqual(lines[1], "*** *pc=144") # nop -> 0x90 -> 144 + self.assertEqual(lines[1], "*** *pc=0x90") @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") @@ -78,20 +78,34 @@ def test_cmd_nop_as_bytes_arg(self): "pi print(f'*** *sp={u32(gef.memory.read(gef.arch.sp, 4))}')", after=( f"{self.cmd} --b --n 4 $sp", - "pi print(f'*** *sp={u32(gef.memory.read(gef.arch.sp, 4))}')", + "pi print(f'*** *sp={u32(gef.memory.read(gef.arch.sp, 4)):#x}')", ) ) self.assertNoException(res) lines = findlines("*** *sp=", res) self.assertEqual(len(lines), 2) - self.assertEqual(lines[1], "*** *sp=2425393296") # 4*nop -> 0x90909090 -> 2425393296 + self.assertEqual(lines[1], "*** *sp=0x90909090") @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_as_bytes_invalid_end_address(self): + # Make sure we error out if writing nops into an unmapped or RO area res = gdb_run_silent_cmd( f"{self.cmd} --b --n 5 0x1337000+0x1000-4", target=_target("mmap-known-address") ) self.assertNoException(res) self.assertIn("Cannot patch instruction at 0x1337ffc: reaching unmapped area", res) + + # We had an off-by-one bug where we couldn't write the last byte before + # an unmapped area. Make sure that we can now. + res = gdb_run_silent_cmd( + f"{self.cmd} --b --n 4 0x1337000+0x1000-4", + target=_target("mmap-known-address"), + after="pi print(f'*** *mem={u32(gef.memory.read(0x1337ffc, 4)):#x}')", + ) + self.assertNoException(res) + self.assertNotIn("Cannot patch instruction at 0x1337ffc: reaching unmapped area", res) + lines = findlines("*** *mem=", res) + self.assertEqual(len(lines), 1) + self.assertEqual(lines[0], "*** *mem=0x90909090") From 7fd94ab532b6edbb58a3f30f04b7f2a891db0873 Mon Sep 17 00:00:00 2001 From: Grazfather Date: Tue, 18 Jul 2023 14:02:08 -0400 Subject: [PATCH 08/21] Wrap docs (#962) * Wrap docs to 100 columns * Add editorconfig for markdown --- .editorconfig | 3 + docs/api.md | 93 ++++++++++-------- docs/commands/aliases.md | 26 +++-- docs/commands/aslr.md | 6 +- docs/commands/canary.md | 7 +- docs/commands/checksec.md | 5 +- docs/commands/config.md | 21 ++-- docs/commands/context.md | 98 +++++++++---------- docs/commands/dereference.md | 31 +++--- docs/commands/edit-flags.md | 15 ++- docs/commands/elf-info.md | 7 +- docs/commands/entry-break.md | 16 ++- docs/commands/eval.md | 4 +- docs/commands/format-string-helper.md | 9 +- docs/commands/functions.md | 25 ++--- docs/commands/gef-remote.md | 45 ++++++--- docs/commands/gef.md | 49 +++++----- docs/commands/got.md | 7 +- docs/commands/heap-analysis-helper.md | 49 ++++------ docs/commands/heap.md | 116 ++++++++++------------ docs/commands/hexdump.md | 11 +-- docs/commands/highlight.md | 9 +- docs/commands/hijack-fd.md | 3 +- docs/commands/ksymaddr.md | 6 +- docs/commands/memory.md | 19 ++-- docs/commands/name-break.md | 14 ++- docs/commands/nop.md | 7 +- docs/commands/pattern.md | 30 +++--- docs/commands/pcustom.md | 54 +++++++---- docs/commands/pie.md | 45 ++++----- docs/commands/print-format.md | 17 ++-- docs/commands/process-search.md | 20 ++-- docs/commands/process-status.md | 6 +- docs/commands/registers.md | 7 +- docs/commands/scan.md | 16 ++- docs/commands/search-pattern.md | 26 +++-- docs/commands/shellcode.md | 6 +- docs/commands/stub.md | 21 ++-- docs/commands/theme.md | 26 ++--- docs/commands/tmux-setup.md | 27 +++--- docs/commands/trace-run.md | 13 ++- docs/commands/version.md | 7 +- docs/commands/vmmap.md | 13 ++- docs/commands/xfiles.md | 6 +- docs/commands/xinfo.md | 15 ++- docs/commands/xor-memory.md | 3 +- docs/config.md | 21 ++-- docs/deprecated.md | 5 +- docs/faq.md | 134 +++++++++++++++----------- docs/functions/base.md | 4 +- docs/functions/bss.md | 1 - docs/functions/got.md | 1 - docs/functions/heap.md | 1 - docs/functions/stack.md | 2 - docs/index.md | 68 ++++++++----- docs/install.md | 60 ++++++++---- docs/screenshots.md | 21 ++-- docs/testing.md | 30 +++--- 58 files changed, 725 insertions(+), 682 deletions(-) diff --git a/.editorconfig b/.editorconfig index 30d459c4d..afce7e399 100644 --- a/.editorconfig +++ b/.editorconfig @@ -19,3 +19,6 @@ indent_style = tab [*.yml] indent_style = space indent_size = 2 + +[*.md] +max_line_length=100 diff --git a/docs/api.md b/docs/api.md index 8a5f83bd0..3b23b4500 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,16 +1,15 @@ # Extending GEF -`GEF` intends to provide a battery-included, quickly installable and crazy fast -debugging environment sitting on top of GDB. +`GEF` intends to provide a battery-included, quickly installable and crazy fast debugging +environment sitting on top of GDB. -But it most importantly provides all the primitives required to allow hackers to -quickly create their own commands. This page intends to summarize how to -create advanced GDB commands in moments using `GEF` as a library. +But it most importantly provides all the primitives required to allow hackers to quickly create +their own commands. This page intends to summarize how to create advanced GDB commands in moments +using `GEF` as a library. -A [dedicated repository](https://github.com/hugsy/gef-extras) was born to host -[external scripts](https://github.com/hugsy/gef-extras/tree/main/scripts). This -repo is open to all for contributions, no restrictions and the most valuable -ones will be integrated into `gef.py`. +A [dedicated repository](https://github.com/hugsy/gef-extras) was born to host [external +scripts](https://github.com/hugsy/gef-extras/tree/main/scripts). This repo is open to all for +contributions, no restrictions and the most valuable ones will be integrated into `gef.py`. ## Quick start @@ -51,17 +50,15 @@ Yes, that's it! Check out [the complete API](api/gef.md) to see what else GEF of ## Detailed explanation -Our new command must be a class that inherits from GEF's `GenericCommand`. The -*only* requirements are: +Our new command must be a class that inherits from GEF's `GenericCommand`. The *only* requirements are: - * a `_cmdline_` attribute (the command to type on the GDB prompt). - * a `_syntax_` attribute, which GEF will use to auto-generate the help menu. - * a method `do_invoke(self, args)` which will be executed when the command - is invoked. `args` is a list of the command line args provided when invoked. +* a `_cmdline_` attribute (the command to type on the GDB prompt). +* a `_syntax_` attribute, which GEF will use to auto-generate the help menu. +* a method `do_invoke(self, args)` which will be executed when the command is invoked. `args` is a + list of the command line args provided when invoked. -We make GEF aware of this new command by registering it in the `__main__` -section of the script, by invoking the global function -`register_external_command()`. +We make GEF aware of this new command by registering it in the `__main__` section of the script, by +invoking the global function `register_external_command()`. Now you have a new GEF command which you can load, either from cli: ```bash @@ -75,9 +72,8 @@ $ echo source /path/to/newcmd.py >> ~/.gdbinit ## Customizing context panes -Sometimes you want something similar to a command to run on each break-like -event and display itself as a part of the GEF context. Here is a simple example -of how to make a custom context pane: +Sometimes you want something similar to a command to run on each break-like event and display itself +as a part of the GEF context. Here is a simple example of how to make a custom context pane: ```python __start_time__ = int(time.time()) @@ -96,26 +92,25 @@ Loading it in `GEF` is as easy as loading a command gef➤ source /path/to/custom_context_pane.py ``` -It can even be included in the same file as a Command. -Now on each break you will notice a new pane near the bottom of the context. -The order can be modified in the `GEF` context config. +It can even be included in the same file as a Command. Now on each break you will notice a new pane +near the bottom of the context. The order can be modified in the `GEF` context config. ### Context Pane API The API demonstrated above requires very specific argument types: `register_external_context_pane(pane_name, display_pane_function, pane_title_function)` --`pane_name`: a string that will be used as the panes setting name --`display_pane_function`: a function that uses `gef_print()` to print content -in the pane --`pane_title_function`: a function that returns the title string or None to hide the title +* `pane_name`: a string that will be used as the panes setting name +* `display_pane_function`: a function that uses `gef_print()` to print content in the pane +* `pane_title_function`: a function that returns the title string or None to hide the title ## API -Some of the most important parts of the API for creating new commands are -mentioned (but not limited to) below. To see the full help of a function, open -GDB and GEF, and use the embedded Python interpreter's `help` command. For -example: +Some of the most important parts of the API for creating new commands are mentioned (but not limited +to) below. To see the full help of a function, open GDB and GEF, and use the embedded Python +interpreter's `help` command. + +For example: ```bash gef➤ pi help(Architecture) @@ -130,14 +125,14 @@ $ gdb -q -ex 'pi help(hexdump)' -ex quit The GEF API aims to provide a simpler and more Pythonic approach to GDB's. Some basic examples: - - read the memory +- read the memory ```python gef ➤ pi print(hexdump( gef.memory.read(parse_address("$pc"), length=0x20 ))) 0x0000000000000000 f3 0f 1e fa 31 ed 49 89 d1 5e 48 89 e2 48 83 e4 ....1.I..^H..H.. 0x0000000000000010 f0 50 54 4c 8d 05 66 0d 01 00 48 8d 0d ef 0c 01 .PTL..f...H..... ``` - - get access to the memory layout +- get access to the memory layout ``` gef ➤ pi print('\n'.join([ f"{x.page_start:#x} -> {x.page_end:#x}" for x in gef.memory.maps])) 0x555555554000 -> 0x555555558000 @@ -155,9 +150,9 @@ gef ➤ pi print('\n'.join([ f"{x.page_start:#x} -> {x.page_end:#x}" for x in ge The API also offers a number of decorators to simplify the creation of new/existing commands, such as: - - `@only_if_gdb_running` to execute only if a GDB session is running. - - `@only_if_gdb_target_local` to check if the target is local i.e. not debugging using GDB `remote`. - - and many more... +- `@only_if_gdb_running` to execute only if a GDB session is running. +- `@only_if_gdb_target_local` to check if the target is local i.e. not debugging using GDB `remote`. +- and many more... ### Reference @@ -171,9 +166,18 @@ For a complete reference of the API offered by GEF, visit [`docs/api/gef.md`](ap @parse_arguments( {"required_argument_1": DefaultValue1, ...}, {"--optional-argument-1": DefaultValue1, ...} ) ``` -This decorator aims to facilitate the argument passing to a command. If added, it will use the `argparse` module to parse arguments, and will store them in the `kwargs["arguments"]` of the calling function (therefore the function **must** have `*args, **kwargs` added to its signature). Argument type is inferred directly from the default value **except** for boolean, where a value of `True` corresponds to `argparse`'s `store_true` action. For more details on `argparse`, refer to its Python documentation. +This decorator aims to facilitate the argument passing to a command. If added, it will use the +`argparse` module to parse arguments, and will store them in the `kwargs["arguments"]` of the +calling function (therefore the function **must** have `*args, **kwargs` added to its signature). +Argument type is inferred directly from the default value **except** for boolean, where a value of +`True` corresponds to `argparse`'s `store_true` action. For more details on `argparse`, refer to its +Python documentation. -Values given for the parameters also allow list of arguments being past. This can be useful in the case where the number of exact option values is known in advance. This can be achieved simply by using a type of `tuple` or `list` for the default value. `parse_arguments` will determine the type of what to expect based on the first default value of the iterable, so make sure it's not empty. For instance: +Values given for the parameters also allow list of arguments being past. This can be useful in the +case where the number of exact option values is known in advance. This can be achieved simply by +using a type of `tuple` or `list` for the default value. `parse_arguments` will determine the type +of what to expect based on the first default value of the iterable, so make sure it's not empty. For +instance: ```python @@ -216,16 +220,21 @@ args.blah --> True # set to True because user input declared the option (would h ### Adding new architectures -Support for new architectures can be added by inheriting from the `Architecture` class. To register the new architecture with gef, the decorator `@register_architecture` has to be added to the class. Examples can be found in [gef-extras](https://github.com/hugsy/gef-extras/tree/dev/archs). +Support for new architectures can be added by inheriting from the `Architecture` class. Examples can +be found in [gef-extras](https://github.com/hugsy/gef-extras/tree/dev/archs). -Sometimes architectures can more precisely determine whether they apply to the current target by looking at the architecture determined by gdb. For these cases the custom architecture may implement the `supports_gdb_arch()` static function to signal that they should be used instead of the default. The function receives only one argument: +Sometimes architectures can more precisely determine whether they apply to the current target by +looking at the architecture determined by gdb. For these cases the custom architecture may implement +the `supports_gdb_arch()` static function to signal that they should be used instead of the default. +The function receives only one argument: - `gdb_str` (of type `str`) which is the architecture name as reported by GDB. The function **must** return: - `True` if the current `Architecture` class supports the target binary; `False` otherwise. - `None` to simply ignore this check and let GEF try to determine the architecture. -One example is the ARM Cortex-M architecture which in some cases should rather be used than the generic ARM one: +One example is the ARM Cortex-M architecture which in some cases should be used over the generic ARM +one: ```python @staticmethod diff --git a/docs/commands/aliases.md b/docs/commands/aliases.md index 8afac4e84..8cbe0002b 100644 --- a/docs/commands/aliases.md +++ b/docs/commands/aliases.md @@ -9,9 +9,9 @@ aliases (add|rm|list) ### Adding/Removing Aliases -`GEF` defines its own aliasing mechanism which overrides the traditional -alias that GDB provides through the built-in command `alias`. To add a new alias, -simply use the `aliases add` command. The "command" parameter may contain spaces. +`GEF` defines its own aliasing mechanism which overrides the traditional alias that GDB provides +through the built-in command `alias`. To add a new alias, simply use the `aliases add` command. The +"command" parameter may contain spaces. ``` aliases add [alias] [command] @@ -25,8 +25,8 @@ aliases rm [alias] ### Listing Aliases -One can list aliases by using the `aliases ls` command. Some sample output of this -command is seen below. +One can list aliases by using the `aliases ls` command. Some sample output of this command is seen +below. ``` [+] Aliases defined: @@ -46,9 +46,8 @@ ps → process-search ### Using the Configuration File -Users can also create/modify/delete aliases by editing the `GEF` configuration file, -by default located at `~/.gef.rc`. The aliases must be in the `aliases` section -of the configuration file. +Users can also create/modify/delete aliases by editing the `GEF` configuration file, by default +located at `~/.gef.rc`. The aliases must be in the `aliases` section of the configuration file. Creating a new alias is as simple as creating a new entry in this section: @@ -61,8 +60,8 @@ my-new-alias = gdb-or-gef-command #### Bringing some PEDA and WinDBG flavours into GEF -For example, for those (like me) who use WinDBG and like its bindings, they can -be integrated into GDB via GEF aliases like this: +For example, for those (like me) who use WinDBG and like its bindings, they can be integrated into +GDB via GEF aliases like this: ``` $ nano ~/.gef.rc @@ -90,8 +89,7 @@ g = gef run uf = disassemble ``` -Or here are some `PEDA` aliases for people used to using `PEDA` who made the -smart move to `GEF`. +Or here are some `PEDA` aliases for people used to using `PEDA` who made the smart move to `GEF`. ``` # some peda aliases @@ -103,8 +101,8 @@ kp = info stack findmem = search-pattern ``` -The aliases will be loaded next time you load GDB (and `GEF`). Or you can force -`GEF` to reload the settings with the command: +The aliases will be loaded next time you load GDB (and `GEF`). Or you can force `GEF` to reload the +settings with the command: ``` gef➤ gef restore diff --git a/docs/commands/aslr.md b/docs/commands/aslr.md index 39a8ac7ed..54e4c9e5c 100644 --- a/docs/commands/aslr.md +++ b/docs/commands/aslr.md @@ -22,6 +22,6 @@ gef➤ aslr off [+] Disabling ASLR ``` -**Note**: This command cannot affect a process that has already been loaded, to -which GDB attached to later. The only way to disable this randomization is by -setting the kernel setting `/proc/sys/kernel/randomize_va_space` to 0.. +**Note**: This command cannot affect a process that has already been loaded, to which GDB attached +to later. The only way to disable this randomization is by setting the kernel setting +`/proc/sys/kernel/randomize_va_space` to 0.. diff --git a/docs/commands/canary.md b/docs/commands/canary.md index abb33ec08..9bbbd2755 100644 --- a/docs/commands/canary.md +++ b/docs/commands/canary.md @@ -1,9 +1,8 @@ ## Command `canary` -If the currently debugged process was compiled with the Smash Stack Protector -(SSP) - i.e. the `-fstack-protector` flag was passed to the compiler, this -command will display the value of the canary. This makes it convenient to avoid -manually searching for this value in memory. +If the currently debugged process was compiled with the Smash Stack Protector (SSP) - i.e. the +`-fstack-protector` flag was passed to the compiler, this command will display the value of the +canary. This makes it convenient to avoid manually searching for this value in memory. The command `canary` does not take any arguments. ``` diff --git a/docs/commands/checksec.md b/docs/commands/checksec.md index 4a7938e9f..a1aa97a9c 100644 --- a/docs/commands/checksec.md +++ b/docs/commands/checksec.md @@ -1,8 +1,7 @@ ## Command `checksec` ## -The `checksec` command is inspired from -[`checksec.sh`](https://www.trapkit.de/tools/checksec.html). It provides a -convenient way to determine which security protections are enabled in a binary. +The `checksec` command is inspired from [`checksec.sh`](https://www.trapkit.de/tools/checksec.html). +It provides a convenient way to determine which security protections are enabled in a binary. You can use the command on the currently debugged process: ``` diff --git a/docs/commands/config.md b/docs/commands/config.md index 3e94f5996..b10cf8670 100644 --- a/docs/commands/config.md +++ b/docs/commands/config.md @@ -1,8 +1,8 @@ ## Command `gef config` ## -`gef` reads its config from a file which is by default located at `~/.gef.rc`, but which -can also be specified via the `GEF_RC` environment variable. In addition, `gef` can also -be configured at runtime with the `gef config` command. +`gef` reads its config from a file which is by default located at `~/.gef.rc`, but which can also be +specified via the `GEF_RC` environment variable. In addition, `gef` can also be configured at +runtime with the `gef config` command. To view all settings for all commands loaded: ``` @@ -15,21 +15,21 @@ Or to get one setting value: gef➤ gef config pcustom.struct_path ``` -Of course you can edit the values. For example, if you want the screen to be -cleared before displaying the current context when reaching a breakpoing: +Of course you can edit the values. For example, if you want the screen to be cleared before +displaying the current context when reaching a breakpoing: ``` gef➤ gef config context.clear_screen 1 ``` -To save the current settings for `GEF` to the file system to have those options -persist across all your future `GEF` sessions, simply run: +To save the current settings for `GEF` to the file system to have those options persist across all +your future `GEF` sessions, simply run: ``` gef➤ gef save [+] Configuration saved to '/home/vagrant/.gef.rc' ``` -Upon startup, if `$GEF_RC` points to an existing file, or otherwise if -`${HOME}/.gef.rc` exists, `gef` will automatically load its values. +Upon startup, if `$GEF_RC` points to an existing file, or otherwise if `${HOME}/.gef.rc` exists, +`gef` will automatically load its values. To reload the settings during the session, just run: ``` @@ -37,5 +37,4 @@ gef➤ gef restore [+] Configuration from '/home/hugsy/.gef.rc' restored ``` -You can tweak this configuration file outside your `gdb` session to suit your -needs. +You can tweak this configuration file outside your `gdb` session to suit your needs. diff --git a/docs/commands/context.md b/docs/commands/context.md index baae9b9be..7c08eac05 100644 --- a/docs/commands/context.md +++ b/docs/commands/context.md @@ -3,38 +3,32 @@ ![gef-context](https://i.imgur.com/aZiG8Yb.png) -`gef` (not unlike `PEDA` or `fG! famous gdbinit`) provides comprehensive context -menu when hitting a breakpoint. +`gef` (not unlike `PEDA` or `fG! famous gdbinit`) provides comprehensive context menu when hitting a +breakpoint. -* The register context box displays current register values. Values in red - indicate that this register has had its value changed since the last - time execution stopped. It makes it convenient to track values. Register - values can be also accessed and/or dereferenced through the `reg` command. - -* The stack context box shows the 10 (by default but can be tweaked) entries in - memory pointed by the stack pointer register. If those values are pointers, - they are successively dereferenced. - -* The code context box shows the 10 (by default but can be tweaked) next - instructions to be executed. +* The register context box displays current register values. Values in red indicate that this + register has had its value changed since the last time execution stopped. It makes it convenient + to track values. Register values can be also accessed and/or dereferenced through the `reg` + command. +* The stack context box shows the 10 (by default but can be tweaked) entries in memory pointed by + the stack pointer register. If those values are pointers, they are successively dereferenced. +* The code context box shows the 10 (by default but can be tweaked) next instructions to be executed. ### Adding custom context panes ### -As well as using the built-in context panes, you can add your own custom pane that -will be displayed at each `break`-like event with all the other panes. Custom panes -can be added using the API: +As well as using the built-in context panes, you can add your own custom pane that will be displayed +at each `break`-like event with all the other panes. Custom panes can be added using the API: ```python register_external_context_pane(pane_name, display_pane_function, pane_title_function) ``` -Check the [API](../api.md) documentation to see a full usage of the -registration API. +Check the [API](../api.md) documentation to see a full usage of the registration API. ### Editing context layout ### -`gef` allows you to configure your own setup for the display, by re-arranging -the order with which contexts will be displayed. +`gef` allows you to configure your own setup for the display, by re-arranging the order with which +contexts will be displayed. ``` gef➤ gef config context.layout @@ -42,21 +36,20 @@ gef➤ gef config context.layout There are currently 6 sections that can be displayed: - * `legend` : a text explanation of the color code - * `regs` : the state of registers - * `stack` : the content of memory pointed by `$sp` register - * `code` : the code being executed - * `args` : if stopping at a function calls, print the call arguments - * `source` : if compiled with source, this will show the corresponding line - of source code - * `threads` : all the threads - * `trace` : the execution call trace - * `extra` : if an automatic behavior is detected (vulnerable format string, - heap vulnerability, etc.) it will be displayed in this pane - * `memory` : peek into arbitrary memory locations +* `legend` : a text explanation of the color code +* `regs` : the state of registers +* `stack` : the content of memory pointed by `$sp` register +* `code` : the code being executed +* `args` : if stopping at a function calls, print the call arguments +* `source` : if compiled with source, this will show the corresponding line of source code +* `threads` : all the threads +* `trace` : the execution call trace +* `extra` : if an automatic behavior is detected (vulnerable format string, heap vulnerability, + etc.) it will be displayed in this pane +* `memory` : peek into arbitrary memory locations -To hide a section, simply use the `context.layout` setting, and prepend the -section name with `-` or just omit it. +To hide a section, simply use the `context.layout` setting, and prepend the section name with `-` or +just omit it. ``` gef➤ gef config context.layout "-legend regs stack code args -source -threads -trace extra memory" @@ -70,32 +63,29 @@ The `memory` pane will display the content of all locations specified by the gef➤ memory watch $sp 0x40 byte ``` -will print a hexdump version of 0x40 bytes of the stack. This command makes it -convenient for tracking the evolution of arbitrary locations in memory. Tracked -locations can be removed one by one using `memory unwatch`, or altogether with -`memory reset`. +will print a hexdump version of 0x40 bytes of the stack. This command makes it convenient for +tracking the evolution of arbitrary locations in memory. Tracked locations can be removed one by one +using `memory unwatch`, or altogether with `memory reset`. The size of most sections are also customizable: * `nb_lines_stack` configures how many lines of the stack to show. * `nb_lines_backtrack` configures how many lines of the backtrace to show. -* `nb_lines_code` and `nb_lines_code_prev` configure how many lines to show - after and before the PC, respectively. -* `context.nb_lines_threads` determines the number of lines to display inside - the thread pane. This is convenient when debugging heavily multi-threaded - applications (apache2, firefox, etc.). It receives an integer as value: if - this value is `-1` then all threads state will be displayed. Otherwise, if the - value is set to `N`, then at most `N` thread states will be shown. +* `nb_lines_code` and `nb_lines_code_prev` configure how many lines to show after and before the PC, + respectively. +* `context.nb_lines_threads` determines the number of lines to display inside the thread pane. This + is convenient when debugging heavily multi-threaded applications (apache2, firefox, etc.). It + receives an integer as value: if this value is `-1` then all threads state will be displayed. + Otherwise, if the value is set to `N`, then at most `N` thread states will be shown. -To have the stack displayed with the largest stack addresses on top (i.e., grow the -stack downward), enable the following setting: +To have the stack displayed with the largest stack addresses on top (i.e., grow the stack downward), +enable the following setting: ``` gef➤ gef config context.grow_stack_down True ``` -If the saved instruction pointer is not within the portion of the stack being displayed, -then a section is created that includes the saved ip and depending on the architecture -the frame pointer. +If the saved instruction pointer is not within the portion of the stack being displayed, then a +section is created that includes the saved ip and depending on the architecture the frame pointer. ``` 0x00007fffffffc9e8│+0x00: 0x00007ffff7a2d830 → <__main+240> mov edi, eax ($current_frame_savedip) 0x00007fffffffc9e0│+0x00: 0x00000000004008c0 → <__init+0> push r15 ← $rbp @@ -112,12 +102,10 @@ the frame pointer. ### Redirecting context output to another tty/file ### -By default, the `gef` context will be displayed on the current TTY. This can be -overridden by setting `context.redirect` variable to have the context sent to -another section. +By default, the `gef` context will be displayed on the current TTY. This can be overridden by +setting `context.redirect` variable to have the context sent to another section. -To do so, select the TTY/file/socket/etc. you want the context redirected to -with `gef config`. +To do so, select the TTY/file/socket/etc. you want the context redirected to with `gef config`. Enter the command `tty` in the prompt: ``` diff --git a/docs/commands/dereference.md b/docs/commands/dereference.md index 406919951..69e528cc8 100644 --- a/docs/commands/dereference.md +++ b/docs/commands/dereference.md @@ -1,16 +1,14 @@ ## Command `dereference` -The `dereference` command (also aliased `telescope` for PEDA former users) aims -to simplify the dereferencing of an address in GDB to determine the content it -actually points to. +The `dereference` command (also aliased `telescope` for PEDA former users) aims to simplify the +dereferencing of an address in GDB to determine the content it actually points to. -It is a useful convienence function to spare to process of manually tracking -values with successive `x/x` in GDB. +It is a useful convienence function to spare to process of manually tracking values with successive +`x/x` in GDB. -`dereference` takes three optional arguments, a start address (or symbol or -register, etc) to dereference (by default, `$sp`), the number of consecutive -addresses to dereference (by default, `10`) and the base location for offset -calculation (by default the same as the start address): +`dereference` takes three optional arguments, a start address (or symbol or register, etc) to +dereference (by default, `$sp`), the number of consecutive addresses to dereference (by default, +`10`) and the base location for offset calculation (by default the same as the start address): ``` gef➤ dereference @@ -40,11 +38,11 @@ gef➤ telescope $rbp+0x10 -l 8 0x00007fffffffdf78│+0x0038: 0x0000000000000000 ``` -It also optionally accepts a second argument, the number of consecutive -addresses to dereference (by default, `10`). +It also optionally accepts a second argument, the number of consecutive addresses to dereference (by +default, `10`). -For example, if you want to dereference all the stack entries inside a function -context (on a 64bit architecture): +For example, if you want to dereference all the stack entries inside a function context (on a 64bit +architecture): ``` gef➤ p ($rbp - $rsp)/8 @@ -57,8 +55,7 @@ gef➤ dereference -l 5 0x00007fffffffe190│+0x0020: 0x0000000000400690 → push r15 ← $rbp ``` -It is possible to change the offset calculation to use a different address than -the start address: +It is possible to change the offset calculation to use a different address than the start address: ``` gef➤ dereference $sp -l 7 -r $rbp @@ -71,8 +68,8 @@ gef➤ dereference $sp -l 7 -r $rbp 0x00007ffe6ddaa410│+0x0000: 0x0000000000000000 ← $rbp ``` -Just like with `x`, you can pass a negative number of addresses to dereference, to examine memory backwards -from the start address: +Just like with `x`, you can pass a negative number of addresses to dereference, to examine memory +backwards from the start address: ``` gef➤ dereference $sp -l 3 0x00007fffffffcf90│+0x0010: 0x00007ffff7f5aaa0 → 0x0000000000000000 diff --git a/docs/commands/edit-flags.md b/docs/commands/edit-flags.md index 9b80b125b..e507cc0b1 100644 --- a/docs/commands/edit-flags.md +++ b/docs/commands/edit-flags.md @@ -1,19 +1,18 @@ ## Command `edit-flags` -The `edit-flags` command (alias: `flags`) provides a quick and comprehensible -way to view and edit the flag register for the architectures that support it. -Without argument, the command will simply return a human-friendly display of the -register flags. +The `edit-flags` command (alias: `flags`) provides a quick and comprehensible way to view and edit +the flag register for the architectures that support it. Without argument, the command will simply +return a human-friendly display of the register flags. One or many arguments can be provided, following the syntax below: ``` gef➤ flags [(+|-|~)FLAGNAME ...] ``` -Where `FLAGNAME` is the name of the flag (case insensitive), and `+|-|~` indicates -the action on whether to set, unset, or toggle the flag. +Where `FLAGNAME` is the name of the flag (case insensitive), and `+|-|~` indicates the action on +whether to set, unset, or toggle the flag. -For instance, on x86 architecture, if we don't want to take a conditional jump -(e.g. a `jz` instruction), but we want to have the Carry flag set, simply go with: +For instance, on x86 architecture, if we don't want to take a conditional jump (e.g. a `jz` +instruction), but we want to have the Carry flag set, simply go with: ``` gef➤ flags -ZERO +CARRY diff --git a/docs/commands/elf-info.md b/docs/commands/elf-info.md index 687174704..16ae78f6f 100644 --- a/docs/commands/elf-info.md +++ b/docs/commands/elf-info.md @@ -1,7 +1,6 @@ ## Command `elf-info` -`elf-info` (alias `elf`) provides some basic information on the currently -loaded ELF binary: +`elf-info` (alias `elf`) provides some basic information on the currently loaded ELF binary: ``` gef➤ elf @@ -65,8 +64,8 @@ Entry point : 0x0000000000400750 [28] .shstrtab STRTAB 0x0 0x20ac 0xfc 0x0 0x0 0x0 0x1 ``` -Optionally a filepath to another ELF binary can be provided to view the basic -information for that binary instead. +Optionally a filepath to another ELF binary can be provided to view the basic information for that +binary instead. ``` gef➤ elf-info --filename /path/to/elf/executable diff --git a/docs/commands/entry-break.md b/docs/commands/entry-break.md index 14139a844..3796fe45d 100644 --- a/docs/commands/entry-break.md +++ b/docs/commands/entry-break.md @@ -1,17 +1,15 @@ ## Command `entry-break` -The `entry-break` (alias `start`) command's goal is to find and break at the -most obvious entry point available in the binary. Since the binary will start -running, some of the `PLT` entries will also be resolved, making further -debugging easier. +The `entry-break` (alias `start`) command's goal is to find and break at the most obvious entry +point available in the binary. Since the binary will start running, some of the `PLT` entries will +also be resolved, making further debugging easier. It will perform the following actions: 1. Look up a `main` symbol. If found, set a temporary breakpoint and go. -2. Otherwise, it will look up for `__libc_start_main`. If found, set a -temporary breakpoint and go. -3. Finally, if the previous two symbols are not found, it will get the entry -point from the ELF header, set a breakpoint and run. This case should never -fail if the ELF binary has a valid structure. +2. Otherwise, it will look up for `__libc_start_main`. If found, set a temporary breakpoint and go. +3. Finally, if the previous two symbols are not found, it will get the entry point from the ELF + header, set a breakpoint and run. This case should never fail if the ELF binary has a valid + structure. ![entry-break-example](https://i.imgur.com/zXSERMh.png) diff --git a/docs/commands/eval.md b/docs/commands/eval.md index 56c35dcf1..72a096451 100644 --- a/docs/commands/eval.md +++ b/docs/commands/eval.md @@ -2,8 +2,8 @@ The `$` command attempts to mimic WinDBG `?` command. -When provided one argument, it will evaluate the expression, and try to display -the result with various formats: +When provided one argument, it will evaluate the expression, and try to display the result with +various formats: ``` gef➤ $ $pc+1 diff --git a/docs/commands/format-string-helper.md b/docs/commands/format-string-helper.md index f4b7ba0a5..17d7164e5 100644 --- a/docs/commands/format-string-helper.md +++ b/docs/commands/format-string-helper.md @@ -1,8 +1,7 @@ ## Command `format-string-helper` -The `format-string-helper` command will create a `GEF` specific type of -breakpoints dedicated to detecting potentially insecure format string when -using the GlibC library. +The `format-string-helper` command will create a `GEF` specific type of breakpoints dedicated to +detecting potentially insecure format string when using the GlibC library. It will use this new breakpoint against several targets, including: @@ -25,8 +24,8 @@ Then start the binary execution. gef➤ r ``` -If a potentially insecure entry is found, the breakpoint will trigger, stop the -process execution, display the reason for trigger and the associated context. +If a potentially insecure entry is found, the breakpoint will trigger, stop the process execution, +display the reason for trigger and the associated context. ![fmtstr-helper-example](https://i.imgur.com/INU3KGn.png) diff --git a/docs/commands/functions.md b/docs/commands/functions.md index 94a323da5..c13562436 100644 --- a/docs/commands/functions.md +++ b/docs/commands/functions.md @@ -1,23 +1,16 @@ ## Command `functions` -The `functions` command will list all of -the [convenience functions](https://sourceware.org/gdb/onlinedocs/gdb/Convenience-Funs.html) -provided by GEF. +The `functions` command will list all of the [convenience +functions](https://sourceware.org/gdb/onlinedocs/gdb/Convenience-Funs.html) provided by GEF. -- `$_base([filepath])` -- Return the matching file's base address plus an - optional offset. Defaults to the current file. Note that quotes need to be - escaped. -- `$_bss([offset])` -- Return the current bss base address plus the given - offset. -- `$_got([offset])` -- Return the current bss base address plus the given - offset. -- `$_heap([offset])` -- Return the current heap base address plus an - optional offset. -- `$_stack([offset])` -- Return the current stack base address plus an - optional offset. +- `$_base([filepath])` -- Return the matching file's base address plus an optional offset. + Defaults to the current file. Note that quotes need to be escaped. +- `$_bss([offset])` -- Return the current bss base address plus the given offset. +- `$_got([offset])` -- Return the current bss base address plus the given offset. +- `$_heap([offset])` -- Return the current heap base address plus an optional offset. +- `$_stack([offset])` -- Return the current stack base address plus an optional offset. -These functions can be used as arguments to other commands to dynamically -calculate values. +These functions can be used as arguments to other commands to dynamically calculate values. ``` gef➤ deref -l 4 $_heap() diff --git a/docs/commands/gef-remote.md b/docs/commands/gef-remote.md index 46982ab1d..756cf8d68 100644 --- a/docs/commands/gef-remote.md +++ b/docs/commands/gef-remote.md @@ -1,20 +1,31 @@ ## Command `gef-remote` -[`target remote`](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Debugging.html#Remote-Debugging) is the traditional GDB way of debugging process or system remotely. However this command by itself does a limited job (80's bandwith FTW) to collect more information about the target, making the process of debugging more cumbersome. GEF greatly improves that state with the `gef-remote` command. +[`target remote`](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Debugging.html#Remote-Debugging) +is the traditional GDB way of debugging process or system remotely. However this command by itself +does a limited job (80's bandwith FTW) to collect more information about the target, making the +process of debugging more cumbersome. GEF greatly improves that state with the `gef-remote` command. -📝 **Note**: If using GEF, `gef-remote` **must** be your way or debugging remote processes, never `target remote`. Maintainers will not provide support or help if you decide to use the traditional `target remote` command. For many reasons, you **cannot** use `target remote` alone with GEF. +📝 **Note**: If using GEF, `gef-remote` **must** be your way or debugging remote processes, never +`target remote`. Maintainers will not provide support or help if you decide to use the traditional +`target remote` command. For many reasons, you **cannot** use `target remote` alone with GEF. `gef-remote` can function in 2 ways: - - `remote` which is meant to enrich use of GDB `target remote` command, when connecting to a "real" gdbserver instance - - `qemu-mode` when connecting to GDB stab of either `qemu-user` or `qemu-system`. +- `remote` which is meant to enrich use of GDB `target remote` command, when connecting to a "real" + gdbserver instance +- `qemu-mode` when connecting to GDB stab of either `qemu-user` or `qemu-system`. -The reason for this difference being that Qemu provides *a lot* less information that GEF can extract to enrich debugging. Whereas GDBServer allows to download remote file (therefore allowing to create a small identical environment), GDB stub in Qemu does not support file transfer. As a consequence, in order to use GEF in qemu mode, it is required to provide the binary being debugged. GEF will create a mock (limited) environment so that all its most useful features are available. +The reason for this difference being that Qemu provides *a lot* less information that GEF can +extract to enrich debugging. Whereas GDBServer allows to download remote file (therefore allowing to +create a small identical environment), GDB stub in Qemu does not support file transfer. As a +consequence, in order to use GEF in qemu mode, it is required to provide the binary being debugged. +GEF will create a mock (limited) environment so that all its most useful features are available. ### Remote mode #### `remote` -If you want to remotely debug a binary that you already have, you simply need to tell to `gdb` where to find the debug information. +If you want to remotely debug a binary that you already have, you simply need to tell to `gdb` where +to find the debug information. For example, if we want to debug `uname`, we do on the server: @@ -26,7 +37,8 @@ Listening on port 1234 ![gef-remote-1](https://i.imgur.com/Zc4vnBd.png) -On the client, when the original `gdb` would use `target remote`, GEF's syntax is roughly similar (shown running in debug mode for more verbose output, but you don't have to): +On the client, when the original `gdb` would use `target remote`, GEF's syntax is roughly similar +(shown running in debug mode for more verbose output, but you don't have to): ``` $ gdb -ex 'gef config gef.debug 1' @@ -62,19 +74,25 @@ And finally breaking into the program, showing the current context: ![gef-remote](https://i.imgur.com/IfsRDvK.png) -You will also notice the prompt has changed to indicate the debugging mode is now "remote". Besides that, all of GEF features are available: +You will also notice the prompt has changed to indicate the debugging mode is now "remote". Besides +that, all of GEF features are available: ![gef-remote-command](https://i.imgur.com/05epyX6.png) #### `remote-extended` -Extended mode works the same as `remote`. Being an extended session, gdbserver has not spawned or attached to any process. Therefore, all that's required is to add the `--pid` flag when calling `gef-remote`, along with the process ID of the process to debug. +Extended mode works the same as `remote`. Being an extended session, gdbserver has not spawned or +attached to any process. Therefore, all that's required is to add the `--pid` flag when calling +`gef-remote`, along with the process ID of the process to debug. ### Qemu mode -Qemu mode of `gef-remote` allows to connect to the [Qemu GDB stub](https://qemu-project.gitlab.io/qemu/system/gdb.html) which allows to live debug into either a binary (`qemu-user`) or even the kernel (`qemu-system`), of any architecture supported by GEF, which makes now even more sense 😉 And using it is very straight forward. +Qemu mode of `gef-remote` allows to connect to the [Qemu GDB +stub](https://qemu-project.gitlab.io/qemu/system/gdb.html) which allows to live debug into either a +binary (`qemu-user`) or even the kernel (`qemu-system`), of any architecture supported by GEF, which +makes now even more sense 😉 And using it is very straight forward. #### `qemu-user` @@ -84,15 +102,12 @@ Qemu mode of `gef-remote` allows to connect to the [Qemu GDB stub](https://qemu- ![qemu-user](https://user-images.githubusercontent.com/590234/175072835-e276ab6c-4f75-4313-9e66-9fe5a3fd220e.png) - #### `qemu-system` -To test locally, you can use the mini image linux x64 vm [here](https://mega.nz/file/ldQCDQiR#yJWJ8RXAHTxREKVmR7Hnfr70tIAQDFeWSYj96SvPO1k). +To test locally, you can use the mini image linux x64 vm +[here](https://mega.nz/file/ldQCDQiR#yJWJ8RXAHTxREKVmR7Hnfr70tIAQDFeWSYj96SvPO1k). 1. Run `./run.sh` 2. Use `--qemu-user` and `--qemu-binary vmlinuz` when starting `gef-remote` ![qemu-system](https://user-images.githubusercontent.com/590234/175071351-8e06aa27-dc61-4fd7-9215-c345dcebcd67.png) - - - diff --git a/docs/commands/gef.md b/docs/commands/gef.md index e1314838a..5f687786d 100644 --- a/docs/commands/gef.md +++ b/docs/commands/gef.md @@ -20,7 +20,9 @@ bytearray -- BytearrayCommand: Generate a bytearray to be compar ### GEF Missing Command -GEF is fully battery-included. However in some rare cases, it is possible that not all commands be loaded. If that's the case the command `gef missing` will detail which command failed to load, along with a (likely) reason. Read the documentation for a solution, or reach out on the Discord. +GEF is fully battery-included. However in some rare cases, it is possible that not all commands be +loaded. If that's the case the command `gef missing` will detail which command failed to load, along +with a (likely) reason. Read the documentation for a solution, or reach out on the Discord. ``` gef➤ gef missing @@ -30,11 +32,10 @@ gef➤ gef missing ### GEF Config Command -Allows the user to set/view settings for the current debugging session. For -making the changes persistent see the `gef save` entry. +Allows the user to set/view settings for the current debugging session. For making the changes +persistent see the `gef save` entry. -Using `gef config` by itself just shows all of the available settings and their -values. +Using `gef config` by itself just shows all of the available settings and their values. ``` gef➤ gef config @@ -64,8 +65,8 @@ theme.default_title_message (str) = "cyan" ``` -You can use `gef config [setting] [value]` to set a setting for the current -session (see example below). +You can use `gef config [setting] [value]` to set a setting for the current session (see example +below). ``` gef➤ gef config theme.address_stack blue @@ -73,8 +74,8 @@ gef➤ gef config theme.address_stack blue ### GEF Save Command -The `gef save` command saves the current settings (set with `gef config`) to -the user's `~/.gef.rc` file (making the changes persistent). +The `gef save` command saves the current settings (set with `gef config`) to the user's `~/.gef.rc` +file (making the changes persistent). ``` gef➤ gef save @@ -83,9 +84,9 @@ gef➤ gef save ### GEF Restore Command -Using `gef restore` loads and applies settings from the `~/.gef.rc` file to the -current session. This is useful if you are modifying your GEF configuration -file and want to see the changes without completely reloading GEF. +Using `gef restore` loads and applies settings from the `~/.gef.rc` file to the current session. +This is useful if you are modifying your GEF configuration file and want to see the changes without +completely reloading GEF. ``` gef➤ gef restore @@ -94,9 +95,8 @@ gef➤ gef restore ### GEF Set Command -The GEF set command allows the user to use GEF context within GDB set commands. -This is useful when you want to make a convenient variable which can be set and -referenced later. +The GEF set command allows the user to use GEF context within GDB set commands. This is useful when +you want to make a convenient variable which can be set and referenced later. ``` gef➤ gef set $a=1 @@ -104,8 +104,8 @@ gef➤ gef set $a=1 ### GEF Run Command -The GEF run command is a wrapper around GDB's run command, allowing the user to -use GEF context within the command. +The GEF run command is a wrapper around GDB's run command, allowing the user to use GEF context +within the command. ``` gef➤ gef run ./binary @@ -114,13 +114,15 @@ gef➤ gef run ./binary ### GEF Install Command -`gef install` allows to install one (or more) specific script(s) from `gef-extras`. The new scripts will be downloaded and sourced to be used immediately after by GEF. The syntax is straight forward: +`gef install` allows to install one (or more) specific script(s) from `gef-extras`. The new scripts +will be downloaded and sourced to be used immediately after by GEF. The syntax is straight forward: ``` gef➤ gef install SCRIPTNAME1 [SCRIPTNAME2...] ``` -Where `SCRIPTNAME1` ... are the names of script from the [`gef-extras` repository](https://github.com/hugsy/gef-extras/tree/main/scripts/). +Where `SCRIPTNAME1` ... are the names of script from the [`gef-extras` +repository](https://github.com/hugsy/gef-extras/tree/main/scripts/). ``` @@ -134,11 +136,12 @@ gef➤ gef install remote windbg stack gef➤ ``` -This makes it easier to deploy new functionalities in limited environment. By default, the command looks up for script names in the `main` branch of `gef-extras`. However you can change specify a different branch through the `gef.default_branch` configuration setting: - +This makes it easier to deploy new functionalities in limited environment. By default, the command +looks up for script names in the `main` branch of `gef-extras`. However you can change specify a +different branch through the `gef.default_branch` configuration setting: ``` gef➤ gef config gef.default_branch dev ``` -The files will be dowloaded in the path configured in the `gef.extra_plugins_dir` setting, allowing to reload it easily without having to re-download. - +The files will be dowloaded in the path configured in the `gef.extra_plugins_dir` setting, allowing +to reload it easily without having to re-download. diff --git a/docs/commands/got.md b/docs/commands/got.md index cd8867387..25b129a84 100644 --- a/docs/commands/got.md +++ b/docs/commands/got.md @@ -2,16 +2,15 @@ Display the current state of GOT table of the running process. -The `got` command optionally takes function names and filters -the output displaying only the matching functions. +The `got` command optionally takes function names and filters the output displaying only the +matching functions. ``` gef➤ got ``` ![gef-got](https://i.imgur.com/554ebM3.png) -The applied filter partially matches the name of the functions, so -you can do something like this. +The applied filter partially matches the name of the functions, so you can do something like this. ``` gef➤ got str gef➤ got print diff --git a/docs/commands/heap-analysis-helper.md b/docs/commands/heap-analysis-helper.md index a66294098..65a74fbd4 100644 --- a/docs/commands/heap-analysis-helper.md +++ b/docs/commands/heap-analysis-helper.md @@ -2,16 +2,15 @@ Please note: This feature is still under development, expect bugs and unstability. -`heap-analysis-helper` command aims to help the process of idenfitying Glibc -heap inconsistencies by tracking and analyzing allocations and deallocations of -chunks of memory. +`heap-analysis-helper` command aims to help the process of idenfitying Glibc heap inconsistencies by +tracking and analyzing allocations and deallocations of chunks of memory. Currently, the following issues can be tracked: - * NULL free - * Use-after-Free - * Double Free - * Heap overlap +- NULL free +- Use-after-Free +- Double Free +- Heap overlap The helper can simply be activated by running the command `heap-analysis-helper`. @@ -24,34 +23,29 @@ gef➤ heap-analysis [+] To disable, clear the malloc/free breakpoints (`delete breakpoints`) and restore hardware breakpoints (`set can-use-hw-watchpoints 1`) ``` -The helper will create specifically crafted breakoints to keep tracks of -allocation, which allows to discover *potential* vulnerabilities. Once -activated, one can disable the heap analysis breakpoints simply by clearing the -`__GI___libc_free()` et `__GI___libc_malloc()`. It is also possible to +The helper will create specifically crafted breakoints to keep tracks of allocation, which allows to +discover *potential* vulnerabilities. Once activated, one can disable the heap analysis breakpoints +simply by clearing the `__GI___libc_free()` et `__GI___libc_malloc()`. It is also possible to enable/disable manually punctual checks via the `gef config` command. The following settings are accepted: - * `check_null_free`: to break execution when a free(NULL) is encountered - (disabled by default); - * `check_double_free`: to break execution when a double free is encountered; +* `check_null_free`: to break execution when a free(NULL) is encountered (disabled by default); +* `check_double_free`: to break execution when a double free is encountered; ![double-free](https://i.imgur.com/S7b4FJa.png) - * `check_weird_free`: to execution when `free()` is called against a - non-tracked pointer; - * `check_uaf`: to break execution when a possible Use-after-Free condition is - found. +* `check_weird_free`: to execution when `free()` is called against a non-tracked pointer; +* `check_uaf`: to break execution when a possible Use-after-Free condition is found. ![uaf](https://i.imgur.com/NfV5Cu9.png) -Just like the format string vulnerability helper, the `heap-analysis-helper` -can fail to detect complex heap scenarios and/or provide some false positive -alerts. Each finding must of course be ascertained manually. +Just like the format string vulnerability helper, the `heap-analysis-helper` can fail to detect +complex heap scenarios and/or provide some false positive alerts. Each finding must of course be +ascertained manually. -The `heap-analysis-helper` can also be used to simply track allocation and -liberation of chunks of memory. One can simply enable the tracking by setting -all the configurations stated above to False: +The `heap-analysis-helper` can also be used to simply track allocation and liberation of chunks of +memory. One can simply enable the tracking by setting all the configurations stated above to False: ``` gef➤ gef config heap-analysis-helper.check_double_free False @@ -60,13 +54,12 @@ gef➤ gef config heap-analysis-helper.check_weird_free False gef➤ gef config heap-analysis-helper.check_uaf False ``` -Then `gef` will not notify you of any inconsistency detected, but simply display -a clear message when a chunk is allocated/freed. +Then `gef` will not notify you of any inconsistency detected, but simply display a clear message +when a chunk is allocated/freed. ![heap-track](https://i.imgur.com/68NGTvw.png) -To get information regarding the currently tracked chunks, use the `show` -subcommand: +To get information regarding the currently tracked chunks, use the `show` subcommand: ``` gef➤ heap-analysis-helper show diff --git a/docs/commands/heap.md b/docs/commands/heap.md index 170a3b5d5..ab85fb6e0 100644 --- a/docs/commands/heap.md +++ b/docs/commands/heap.md @@ -1,9 +1,9 @@ ## Command `heap` -The `heap` command provides information on the heap chunk specified as argument. For -the moment, it only supports GlibC heap format (see -[this link](https://code.woboq.org/userspace/glibc/malloc/malloc.c.html#malloc_chunk) -for `malloc` structure information). Syntax to the subcommands is straight forward: +The `heap` command provides information on the heap chunk specified as argument. For the moment, it +only supports GlibC heap format (see [this +link](https://code.woboq.org/userspace/glibc/malloc/malloc.c.html#malloc_chunk) for `malloc` +structure information). Syntax to the subcommands is straight forward: ``` gef➤ heap @@ -11,24 +11,24 @@ gef➤ heap ## `main_arena` symbol ### -If the linked glibc of the target program does not have debugging symbols it -might be tricky for GEF to find the address of the `main_arena` which is needed -for most of the `heap` subcommands. If you know the offset of this symbol from -the glibc base address you can use GEF's config to provide said value: +If the linked glibc of the target program does not have debugging symbols it might be tricky for GEF +to find the address of the `main_arena` which is needed for most of the `heap` subcommands. If you +know the offset of this symbol from the glibc base address you can use GEF's config to provide said +value: ``` gef➤ gef config gef.main_arena_offset ``` -If you do not know this offset and you want GEF to try and find it via bruteforce -when executing a `heap` command the next time, you can try this instead: +If you do not know this offset and you want GEF to try and find it via bruteforce when executing a +`heap` command the next time, you can try this instead: ``` gef➤ gef config gef.bruteforce_main_arena True ``` -Note that this might take a few seconds to complete. If GEF does find the symbol -you can then calculate the offset to the libc base address and save it in the config. +Note that this might take a few seconds to complete. If GEF does find the symbol you can then +calculate the offset to the libc base address and save it in the config. ### `heap chunks` command ### @@ -41,8 +41,8 @@ gef➤ heap chunks ![heap-chunks](https://i.imgur.com/y90SfKH.png) -To select from which arena to display chunks either use the `heap set-arena` -command or provide the base address of the other arena like this: +To select from which arena to display chunks either use the `heap set-arena` command or provide the +base address of the other arena like this: ``` gef➤ heap chunks [arena_address] @@ -58,17 +58,15 @@ gef➤ heap chunks -a ![heap-chunks-all](https://i.imgur.com/pTjRJFo.png) -Because usually the heap chunks are aligned to a certain number of bytes in -memory GEF automatically re-aligns the chunks data start addresses to match -Glibc's behavior. To be able to view unaligned chunks as well, you can disable -this with the `--allow-unaligned` flag. Note that this might result in -incorrect output. +Because usually the heap chunks are aligned to a certain number of bytes in memory GEF automatically +re-aligns the chunks data start addresses to match Glibc's behavior. To be able to view unaligned +chunks as well, you can disable this with the `--allow-unaligned` flag. Note that this might result +in incorrect output. ### `heap chunk` command ### -This command gives visual information of a Glibc malloc-ed chunked. Simply -provide the address to the user memory pointer of the chunk to show the -information related to a specific chunk: +This command gives visual information of a Glibc malloc-ed chunked. Simply provide the address to +the user memory pointer of the chunk to show the information related to a specific chunk: ``` gef➤ heap chunk [address] @@ -76,14 +74,13 @@ gef➤ heap chunk [address] ![heap-chunk](https://i.imgur.com/WXpHR58.png) -Because usually the heap chunks are aligned to a certain number of bytes in -memory GEF automatically re-aligns the chunks data start addresses to match -Glibc's behavior. To be able to view unaligned chunks as well, you can disable -this with the `--allow-unaligned` flag. Note that this might result in -incorrect output. +Because usually the heap chunks are aligned to a certain number of bytes in memory GEF automatically +re-aligns the chunks data start addresses to match Glibc's behavior. To be able to view unaligned +chunks as well, you can disable this with the `--allow-unaligned` flag. Note that this might result +in incorrect output. - -There is an optional `number` argument, to specify the number of chunks printed by this command. To do so, simply provide the `--number` argument: +There is an optional `number` argument, to specify the number of chunks printed by this command. To +do so, simply provide the `--number` argument: ``` gef➤ heap chunk --number 6 0x4e5400 @@ -98,35 +95,31 @@ Chunk(addr=0x4e6760, size=0x4c0, flags=PREV_INUSE) ### `heap arenas` command ### -Multi-threaded programs have different arenas, and the knowledge of the -`main_arena` is not enough. `gef` therefore provides the `arena` sub-commands -to help you list all the arenas allocated in your program **at the moment you -call the command**. +Multi-threaded programs have different arenas, and the knowledge of the `main_arena` is not enough. +`gef` therefore provides the `arena` sub-commands to help you list all the arenas allocated in your +program **at the moment you call the command**. ![heap-arenas](https://i.imgur.com/RUTiADa.png) ### `heap set-arena` command ### -In cases where the debug symbol are not present (e.g. statically stripped -binary), it is possible to instruct GEF to find the `main_arena` at a different -location with the command: +In cases where the debug symbol are not present (e.g. statically stripped binary), it is possible to +instruct GEF to find the `main_arena` at a different location with the command: ``` gef➤ heap set-arena [address] ``` -If the arena address is correct, all `heap` commands will be functional, and use -the specified address for `main_arena`. +If the arena address is correct, all `heap` commands will be functional, and use the specified +address for `main_arena`. ### `heap bins` command ### -Glibc uses bins for keeping tracks of `free`d chunks. This is because making -allocations through `sbrk` (requiring a syscall) is costly. Glibc uses those -bins to remember formerly allocated chunks. Because bins are structured in -single or doubly linked list, I found that quite painful to always interrogate -`gdb` to get a pointer address, dereference it, get the value chunk, etc... So -I decided to implement the `heap bins` sub-command, which allows to get info -on: +Glibc uses bins for keeping tracks of `free`d chunks. This is because making allocations through +`sbrk` (requiring a syscall) is costly. Glibc uses those bins to remember formerly allocated chunks. +Because bins are structured in single or doubly linked list, I found that quite painful to always +interrogate `gdb` to get a pointer address, dereference it, get the value chunk, etc... So I decided +to implement the `heap bins` sub-command, which allows to get info on: - `fastbins` - `bins` @@ -137,13 +130,12 @@ on: #### `heap bins fast` command #### -When exploiting heap corruption vulnerabilities, it is sometimes convenient to -know the state of the `fastbinsY` array. +When exploiting heap corruption vulnerabilities, it is sometimes convenient to know the state of the +`fastbinsY` array. -The `fast` sub-command helps by displaying the list of fast chunks in this -array. Without any other argument, it will display the info of the `main_arena` -arena. It accepts an optional argument, the address of another arena (which you -can easily find using `heap arenas`). +The `fast` sub-command helps by displaying the list of fast chunks in this array. Without any other +argument, it will display the info of the `main_arena` arena. It accepts an optional argument, the +address of another arena (which you can easily find using `heap arenas`). ``` gef➤ heap bins fast @@ -159,26 +151,24 @@ Fastbins[idx=6, size=0x80] 0x00 #### Other `heap bins X` command #### -All the other subcommands (with the exception of `tcache`) for the `heap bins` -work the same way as `fast`. If no argument is provided, `gef` will fall back -to `main_arena`. Otherwise, it will use the address pointed as the base of the -`malloc_state` structure and print out information accordingly. +All the other subcommands (with the exception of `tcache`) for the `heap bins` work the same way as +`fast`. If no argument is provided, `gef` will fall back to `main_arena`. Otherwise, it will use the +address pointed as the base of the `malloc_state` structure and print out information accordingly. #### `heap bins tcache` command #### -Modern versions of `glibc` use `tcache` bins to speed up multithreaded -programs. Unlike other bins, `tcache` bins are allocated on a per-thread -basis, so there is one set of `tcache` bins for each thread. +Modern versions of `glibc` use `tcache` bins to speed up multithreaded programs. Unlike other bins, +`tcache` bins are allocated on a per-thread basis, so there is one set of `tcache` bins for each +thread. ``` gef➤ heap bins tcache [all] [thread_ids...] ``` -Without any arguments, `heap bins tcache` will display the `tcache` for the -current thread. `heap bins tcache all` will show the `tcache`s for every -thread, or you can specify any number of thread ids to see the `tcache` for -each of them. For example, use the following command to show the `tcache` bins -for threads 1 and 2. +Without any arguments, `heap bins tcache` will display the `tcache` for the current thread. `heap +bins tcache all` will show the `tcache`s for every thread, or you can specify any number of thread +ids to see the `tcache` for each of them. For example, use the following command to show the +`tcache` bins for threads 1 and 2. ``` gef➤ heap bins tcache 1 2 diff --git a/docs/commands/hexdump.md b/docs/commands/hexdump.md index 3c8e41f8a..2bd409b76 100644 --- a/docs/commands/hexdump.md +++ b/docs/commands/hexdump.md @@ -5,14 +5,13 @@ Imitation of the WinDBG command. This command takes 4 optional arguments: - The format for representing the data (by default, byte) -- A value/address/symbol used as the location to print the hexdump from (by - default, $sp) -- The number of qword/dword/word/bytes to display (by default, 64 if the format - is byte, 16 otherwise) +- A value/address/symbol used as the location to print the hexdump from (by default, $sp) +- The number of qword/dword/word/bytes to display (by default, 64 if the format is byte, 16 + otherwise) - The direction of output lines (by default, from low to high addresses) -`hexdump byte` will also try to display the ASCII character values if the byte -is printable (similarly to the `hexdump -C` command on Linux). +`hexdump byte` will also try to display the ASCII character values if the byte is printable +(similarly to the `hexdump -C` command on Linux). The syntax is as following: diff --git a/docs/commands/highlight.md b/docs/commands/highlight.md index dfe962f5f..81b8989c0 100644 --- a/docs/commands/highlight.md +++ b/docs/commands/highlight.md @@ -10,7 +10,7 @@ highlight (add|remove|list|clear) Alias: - - `hl` +- `hl` ## Adding matches @@ -71,11 +71,10 @@ highlight.regex (bool) = True ## Performance -_**NOTE:** Adding many matches may slow down debugging while using GEF. -This includes enabling RegEx support._ +_**NOTE:** Adding many matches may slow down debugging while using GEF. This includes enabling RegEx +support._ ## Colors -To find a list of supported colors, check the -[theme](./theme.md#changing-colors) documentation. +To find a list of supported colors, check the [theme](./theme.md#changing-colors) documentation. diff --git a/docs/commands/hijack-fd.md b/docs/commands/hijack-fd.md index ee8bf48e1..7b4fd9222 100644 --- a/docs/commands/hijack-fd.md +++ b/docs/commands/hijack-fd.md @@ -16,7 +16,8 @@ Will modify the current process file descriptors to redirect STDOUT to `/dev/null`. -This command also supports connecting to an ip:port if it is provided as an argument. For example +This command also supports connecting to an ip:port if it is provided as an +argument. For example ``` gef➤ hijack-fd 0 localhost:8888 ``` diff --git a/docs/commands/ksymaddr.md b/docs/commands/ksymaddr.md index aa0545280..e6ffea221 100644 --- a/docs/commands/ksymaddr.md +++ b/docs/commands/ksymaddr.md @@ -19,6 +19,6 @@ gef➤ ksymaddr commit_creds [*] Found partial match for 'commit_creds' at 0xffffffff8fc9bfcd (type=r): __kstrtab_commit_creds ``` -Note that the debugging process needs to have the correct permissions for this -command to show kernel addresses. For more information see -also [this stackoverflow post](https://stackoverflow.com/a/55592796). \ No newline at end of file +Note that the debugging process needs to have the correct permissions for this command to show +kernel addresses. For more information see also [this stackoverflow +post](https://stackoverflow.com/a/55592796). diff --git a/docs/commands/memory.md b/docs/commands/memory.md index 56bbb8075..676065629 100644 --- a/docs/commands/memory.md +++ b/docs/commands/memory.md @@ -1,11 +1,13 @@ ## Command `memory` -As long as the 'memory' section is enabled in your context layout (which it is -by default), you can register addresses, lengths, and grouping size. +As long as the 'memory' section is enabled in your context layout (which it is by default), you can +register addresses, lengths, and grouping size. ![memory watch](https://i.imgur.com/NXYwSwW.png) -_Note_: this command **shoud NOT** be mistaken with the [GDB `watch` command](https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Watchpoints.html) meant to set breakpoints on memory access (read,write,exec). +_Note_: this command **shoud NOT** be mistaken with the [GDB `watch` +command](https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Watchpoints.html) meant to set +breakpoints on memory access (read,write,exec). ### Adding a watch @@ -17,10 +19,14 @@ Syntax: memory watch
[SIZE] [(qword|dword|word|byte|pointers)] ``` -If the format specified is `pointers`, then the output will be similar to executing the command `dereference $address`. -For all other format, the output will be an hexdump of the designated location. +If the format specified is `pointers`, then the output will be similar to executing the command +`dereference $address`. For all other format, the output will be an hexdump of the designated +location. -Note that the address format is a GDB therefore a symbol can be passed to it. It also supports [GEF functions format](https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html) allowing to easily track commonly used addresses: +Note that the address format is a GDB therefore a symbol can be passed to it. It also supports [GEF +functions +format](https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html) +allowing to easily track commonly used addresses: For example, to watch the first 5 entries of the [GOT]() as pointers: @@ -64,4 +70,3 @@ Syntax: ``` memory reset ``` - diff --git a/docs/commands/name-break.md b/docs/commands/name-break.md index 804b3301a..c0c6175f4 100644 --- a/docs/commands/name-break.md +++ b/docs/commands/name-break.md @@ -1,17 +1,15 @@ ## Command `name-break` -The command `name-break` (alias `nb`) can be used to set a breakpoint on -a location with a name assigned to it. +The command `name-break` (alias `nb`) can be used to set a breakpoint on a location with a name +assigned to it. -Every time this breakpoint is hit, the specified name will also be shown -in the `extra` section to make it easier to keep an overview when using -multiple breakpoints in a stripped binary. +Every time this breakpoint is hit, the specified name will also be shown in the `extra` section to +make it easier to keep an overview when using multiple breakpoints in a stripped binary. `name-break name [address]` -`address` may be a linespec, address, or explicit location, same as specified -for `break`. If `address` isn't specified, it will create the breakpoint at the -current instruction pointer address. +`address` may be a linespec, address, or explicit location, same as specified for `break`. If +`address` isn't specified, it will create the breakpoint at the current instruction pointer address. Examples: diff --git a/docs/commands/nop.md b/docs/commands/nop.md index d519c290f..8f8b75c76 100644 --- a/docs/commands/nop.md +++ b/docs/commands/nop.md @@ -6,9 +6,10 @@ The `nop` command allows you to easily patch instructions with nops. nop [LOCATION] [--n NUM_ITEMS] [--b] ``` -`LOCATION` address/symbol to patch +`LOCATION` address/symbol to patch -`--n NUM_ITEMS` Instead of writing one instruction/nop, patch the specified number of instructions/nops (full instruction size by default) +`--n NUM_ITEMS` Instead of writing one instruction/nop, patch the specified number of +instructions/nops (full instruction size by default) `--b` Instead of writing full instruction size, patch the specified number of nops @@ -19,4 +20,4 @@ gef➤ nop --n 2 $pc+3 gef➤ nop --b gef➤ nop --b $pc+3 gef➤ nop --b --n 2 $pc+3 -``` \ No newline at end of file +``` diff --git a/docs/commands/pattern.md b/docs/commands/pattern.md index f5ba7be92..687f05036 100644 --- a/docs/commands/pattern.md +++ b/docs/commands/pattern.md @@ -1,13 +1,11 @@ ## Command `pattern` -This command will create or search a [De -Bruijn](https://en.wikipedia.org/wiki/De_Bruijn_sequence) cyclic pattern to -facilitate determining offsets in memory. The sequence consists of a number of +This command will create or search a [De Bruijn](https://en.wikipedia.org/wiki/De_Bruijn_sequence) +cyclic pattern to facilitate determining offsets in memory. The sequence consists of a number of unique substrings of a chosen length. -It should be noted that for better compatibility, the algorithm implemented in -`GEF` is the same as the one in `pwntools`, and can therefore be used in -conjunction. +It should be noted that for better compatibility, the algorithm implemented in `GEF` is the same as +the one in `pwntools`, and can therefore be used in conjunction. ### `pattern create` ### @@ -15,10 +13,9 @@ conjunction. pattern create [-h] [-n N] [length] ``` -The sub-command `create` allows one create a new De Bruijn sequence. The -optional argument `n` determines the length of unique subsequences. Its default -value matches the currently loaded architecture. The `length` argument sets the -total length of the whole sequence. +The sub-command `create` allows one create a new De Bruijn sequence. The optional argument `n` +determines the length of unique subsequences. Its default value matches the currently loaded +architecture. The `length` argument sets the total length of the whole sequence. ``` gef➤ pattern create -n 4 128 @@ -40,14 +37,13 @@ p = cyclic(128, n=8) pattern search [-h] [-n N] [--max-length MAX_LENGTH] [pattern] ``` -The `search` sub-command seeks the `pattern` given as argument, trying to find -its offset in the De Bruijn sequence. The optional argument `n` determines the -length of unique subsequences, and it should usually match the length of -`pattern`. Using `MAX_LENGTH` the maximum length of the sequence to search in -can be adjusted. +The `search` sub-command seeks the `pattern` given as argument, trying to find its offset in the De +Bruijn sequence. The optional argument `n` determines the length of unique subsequences, and it +should usually match the length of `pattern`. Using `MAX_LENGTH` the maximum length of the sequence +to search in can be adjusted. -Note that the `pattern` can be passed as a GDB symbol (such as a register name), -a string or a hexadecimal value +Note that the `pattern` can be passed as a GDB symbol (such as a register name), a string or a +hexadecimal value ``` gef➤ pattern search 0x6161616161616167 diff --git a/docs/commands/pcustom.md b/docs/commands/pcustom.md index 0694ab4f7..d7d3a4666 100644 --- a/docs/commands/pcustom.md +++ b/docs/commands/pcustom.md @@ -1,8 +1,13 @@ ## Command `pcustom` -`gef` provides a way to create and apply to the currently debugged environment, any new structure (in the C-struct way). On top of simply displaying known and user-defined structures, it also allows to apply those structures to the current context. It intends to mimic the very useful [WinDBG `dt`](https://msdn.microsoft.com/en-us/library/windows/hardware/ff542772(v=vs.85).aspx) command. +`gef` provides a way to create and apply to the currently debugged environment, any new structure +(in the C-struct way). On top of simply displaying known and user-defined structures, it also allows +to apply those structures to the current context. It intends to mimic the very useful [WinDBG +`dt`](https://msdn.microsoft.com/en-us/library/windows/hardware/ff542772(v=vs.85).aspx) command. -This is achieved via the command `pcustom` (for `print custom`), or you can use its alias, `dt` (in reference to the WinDBG command) as provided by the [`WinDbg compatibility extension`](https://github.com/hugsy/gef-extras/blob/main/scripts/windbg.py) +This is achieved via the command `pcustom` (for `print custom`), or you can use its alias, `dt` (in +reference to the WinDBG command) as provided by the [`WinDbg compatibility +extension`](https://github.com/hugsy/gef-extras/blob/main/scripts/windbg.py) ### Configuration @@ -11,7 +16,8 @@ New structures can be stored in the location given by the configuration setting: ``` gef➤ gef config pcustom.struct_path ``` -By default, this location is in `$TEMP/gef/structs` (e.g. `/tmp/user/1000/gef/structs`). The structure can be created as a simple `ctypes` structure, in a file called `.py`. +By default, this location is in `$TEMP/gef/structs` (e.g. `/tmp/user/1000/gef/structs`). The +structure can be created as a simple `ctypes` structure, in a file called `.py`. You can naturally set this path to a new location ``` @@ -36,14 +42,17 @@ gef➤ pcustom list [...] ``` -To create or edit a structure, use `pcustom edit ` to spawn your EDITOR with the targeted structure. If the file does not exist, `gef` will nicely create the tree and file, and fill it with a `ctypes` template that you can use straight away! +To create or edit a structure, use `pcustom edit ` to spawn your EDITOR with the +targeted structure. If the file does not exist, `gef` will nicely create the tree and file, and fill +it with a `ctypes` template that you can use straight away! ``` gef➤ pcustom new mystruct_t [+] Creating '/tmp/gef/structs/mystruct_t.py' from template ``` -If the structure already exists, GEF will open the text editor to edit the known structure. This is equivalent to: +If the structure already exists, GEF will open the text editor to edit the known structure. This is +equivalent to: ``` gef➤ pcustom edit elf32_t @@ -84,7 +93,8 @@ class person_t(Structure): ] ``` -`pcustom` requires at least one argument, which is the name of the structure. With only one argument, `pcustom` will dump all the fields of this structure. +`pcustom` requires at least one argument, which is the name of the structure. With only one +argument, `pcustom` will dump all the fields of this structure. ``` gef➤ dt person_t @@ -93,9 +103,8 @@ gef➤ dt person_t +0104 id c_int /* size=0x4 */ ``` - - -By providing an address or a GDB symbol, `gef` will apply this user-defined structure to the specified address: +By providing an address or a GDB symbol, `gef` will apply this user-defined structure to the +specified address: ![gef-pcustom-with-address](https://i.imgur.com/vWGnu5g.png) @@ -105,19 +114,25 @@ For a full demo, watch the following tutorial: [![yt-gef-pcustom](https://img.youtube.com/vi/pid2aW7Bt_w/0.jpg)](https://www.youtube.com/watch?v=pid2aW7Bt_w) -Additionally, if you have successfully configured your IDA settings, you can also directly import the structure(s) that was(were) reverse-engineered in IDA directly in your GDB session: +Additionally, if you have successfully configured your IDA settings, you can also directly import +the structure(s) that was(were) reverse-engineered in IDA directly in your GDB session: ![ida-structure-examples](https://i.imgur.com/Tnsf6nt.png) - (see `gef-extras/ida-rpyc`, which is the new improved version of `ida-interact`) #### Dynamic `ctypes.Structure`-like classes -`pcustom` also supports the use of class factories to create a `ctypes.Structure` class whose structure will be adjusted based on the runtime information we provide (information about the currently debugged binary, the architecture, the size of a pointer and more). +`pcustom` also supports the use of class factories to create a `ctypes.Structure` class whose +structure will be adjusted based on the runtime information we provide (information about the +currently debugged binary, the architecture, the size of a pointer and more). -The syntax is relatively close to the way we use to create static classes (see above), but instead we define a function that will generate the class. The requirements for this class factory are: - - take a single [`Gef`](https://github.com/hugsy/gef/blob/dev/docs/api/gef.md#class-gef) positional argument - - End the function name with `_t` +The syntax is relatively close to the way we use to create static classes (see above), but instead +we define a function that will generate the class. The requirements for this class factory are: +- take a single [`Gef`](https://github.com/hugsy/gef/blob/dev/docs/api/gef.md#class-gef) positional + argument +- End the function name with `_t` -To continue the `person_t` function we defined in the example above, we could modify the static class as a dynamic one very easily: +To continue the `person_t` function we defined in the example above, we could modify the static +class as a dynamic one very easily: ```python import ctypes @@ -136,7 +151,8 @@ def person_t(gef: Optional["Gef"]=None): return person_cls ``` -Thanks to the `gef` parameter, the structure can be transparently adjusted so that GEF will parse it differently with its runtime information. For example, we can add constraints to the example above: +Thanks to the `gef` parameter, the structure can be transparently adjusted so that GEF will parse it +differently with its runtime information. For example, we can add constraints to the example above: ```python import ctypes @@ -166,7 +182,8 @@ def person_t(gef: Optional["Gef"]==None): ### Public repository of structures -A community contributed repository of structures can be found in [`gef-extras`](https://github.com/hugsy/gef-extras). To deploy it: +A community contributed repository of structures can be found in +[`gef-extras`](https://github.com/hugsy/gef-extras). To deploy it: In bash: ``` @@ -179,7 +196,8 @@ gef➤ gef config pcustom.struct_path /path/to/gef-extras/structs gef➤ gef save ``` -Then either close GDB or `gef reload`. You can confirm the structures were correctly loaded in GEF's prompt: +Then either close GDB or `gef reload`. You can confirm the structures were correctly loaded in GEF's +prompt: ``` gef➤ pcustom list diff --git a/docs/commands/pie.md b/docs/commands/pie.md index 22e232d71..2acb61966 100644 --- a/docs/commands/pie.md +++ b/docs/commands/pie.md @@ -1,21 +1,17 @@ ## Command `pie` ## -The `pie` command is handy when working with position-independent executables. -At runtime, it can automatically resolve addresses for breakpoints that are not -static. +The `pie` command is handy when working with position-independent executables. At runtime, it can +automatically resolve addresses for breakpoints that are not static. -Note that you need to use the **entire `pie` command series** to support PIE -breakpoints, especially the "`pie` run commands", like `pie attach`, `pie run`, -etc. +Note that you need to use the **entire `pie` command series** to support PIE breakpoints, especially +the "`pie` run commands", like `pie attach`, `pie run`, etc. ### `pie breakpoint` command ### -This command sets a new PIE breakpoint. It can be used like the normal -`breakpoint` command in gdb. The argument for the command is the offset from -the base address or a symbol. The breakpoints will not be set immediately after -this command. Instead, it will be set when you use `pie attach`, `pie run` or -`pie remote` to actually attach to a process, so it can resolve the right base -address. +This command sets a new PIE breakpoint. It can be used like the normal `breakpoint` command in gdb. +The argument for the command is the offset from the base address or a symbol. The breakpoints will +not be set immediately after this command. Instead, it will be set when you use `pie attach`, `pie +run` or `pie remote` to actually attach to a process, so it can resolve the right base address. Usage: @@ -25,8 +21,8 @@ gef➤ pie breakpoint OFFSET ### `pie info` command ### -Since a PIE breakpoint is not a real breakpoint, this command provides a way to -observe the state of all PIE breakpoints. +Since a PIE breakpoint is not a real breakpoint, this command provides a way to observe the state of +all PIE breakpoints. This works just like `info breakpoint` in gdb. @@ -36,8 +32,8 @@ VNum Num Addr 1 N/A 0xdeadbeef ``` -VNum stands for virtual number and is used to enumerate the PIE breakpoints. -Num is the number of the associated real breakpoints at runtime in GDB. +VNum stands for virtual number and is used to enumerate the PIE breakpoints. Num is the number of +the associated real breakpoints at runtime in GDB. You can omit the VNum argument to get info on all PIE breakpoints. @@ -60,25 +56,22 @@ gef➤ pie delete [VNum] ### `pie attach` command ### -This command behaves like GDB's `attach` command. Always use this command -instead of `attach` if you have PIE breakpoints. This will convert the PIE -breakpoints to real breakpoints at runtime. +This command behaves like GDB's `attach` command. Always use this command instead of `attach` if you +have PIE breakpoints. This will convert the PIE breakpoints to real breakpoints at runtime. The usage is just the same as `attach`. ### `pie remote` command ### -This command behaves like GDB's `remote` command. Always use this command -instead of `remote` if you have PIE breakpoints. Behind the scenes this will -connect to the remote target using `gef remote` and then convert the PIE -breakpoints to real breakpoints at runtime. +This command behaves like GDB's `remote` command. Always use this command instead of `remote` if you +have PIE breakpoints. Behind the scenes this will connect to the remote target using `gef remote` +and then convert the PIE breakpoints to real breakpoints at runtime. The usage is just the same as `remote`. ### `pie run` command ### -This command behaves like GDB's `run` command. Always use this command instead -of `run` if you have PIE breakpoints. This will convert the PIE breakpoints to -real breakpoints at runtime. +This command behaves like GDB's `run` command. Always use this command instead of `run` if you have +PIE breakpoints. This will convert the PIE breakpoints to real breakpoints at runtime. The usage is just the same as `run`. diff --git a/docs/commands/print-format.md b/docs/commands/print-format.md index de5585b33..1401e3992 100644 --- a/docs/commands/print-format.md +++ b/docs/commands/print-format.md @@ -1,13 +1,14 @@ ## Command `print-format` -The command `print-format` (alias `pf`) will dump an arbitrary location as an array of bytes following the format specified. Currently, the output formats supported are - - - Python (`py` - default) - - C (`c`) - - Assembly (`asm`) - - Javascript (`js`) - - Hex string (`hex`) - - For patch byte command or GDB $_gef[N] byte access (`bytearray`) +The command `print-format` (alias `pf`) will dump an arbitrary location as an array of bytes +following the format specified. Currently, the output formats supported are + +- Python (`py` - default) +- C (`c`) +- Assembly (`asm`) +- Javascript (`js`) +- Hex string (`hex`) +- For patch byte command or GDB $_gef[N] byte access (`bytearray`) ``` diff --git a/docs/commands/process-search.md b/docs/commands/process-search.md index 9f051a22c..62a24e675 100644 --- a/docs/commands/process-search.md +++ b/docs/commands/process-search.md @@ -1,9 +1,8 @@ ## Command `process-search` -`process-search` (aka `ps`) is a convenience command to list and filter process -on the host. It is aimed at making the debugging process a little easier when -targeting forking process (such as tcp/listening daemon that would fork upon -`accept()`). +`process-search` (aka `ps`) is a convenience command to list and filter process on the host. It is +aimed at making the debugging process a little easier when targeting forking process (such as +tcp/listening daemon that would fork upon `accept()`). Without argument, it will return all processes reachable by user: @@ -34,20 +33,19 @@ Note: Use "\\" for escaping and "\\\\" for a literal backslash" in the pattern. `ps` also accepts options: -* `--smart-scan` will filter out probably less relevant processes (belonging to - different users, pattern matched to arguments instead of the commands - themselves, etc.) +* `--smart-scan` will filter out probably less relevant processes (belonging to different users, + pattern matched to arguments instead of the commands themselves, etc.) * `--attach` will automatically attach to the first process found -So, for example, if your targeted process is called `/home/foobar/plop`, but -the existing instance is used through `socat`, like +So, for example, if your targeted process is called `/home/foobar/plop`, but the existing instance +is used through `socat`, like ``` $ socat tcp-l:1234,fork,reuseaddr exec:/home/foobar/plop ``` -Then every time a new connection is opened to tcp/1234, `plop` will be forked, -and GEF can easily attach to it with the command +Then every time a new connection is opened to tcp/1234, `plop` will be forked, and GEF can easily +attach to it with the command ``` gef➤ ps --attach --smart-scan plop diff --git a/docs/commands/process-status.md b/docs/commands/process-status.md index fb14904a6..b024126f3 100644 --- a/docs/commands/process-status.md +++ b/docs/commands/process-status.md @@ -2,9 +2,9 @@ > This command replaces the old commands `pid` and `fd`. -`process-status` provides an exhaustive description of the current running -process, by extending the information provided by GDB `info proc` command, with -all the information from the `procfs` structure. +`process-status` provides an exhaustive description of the current running process, by extending the +information provided by GDB `info proc` command, with all the information from the `procfs` +structure. ``` gef➤ ps --smart-scan zsh diff --git a/docs/commands/registers.md b/docs/commands/registers.md index 31c5f19b0..5c08d37ce 100644 --- a/docs/commands/registers.md +++ b/docs/commands/registers.md @@ -1,7 +1,6 @@ ## Command `registers` -The `registers` command will print all the registers and dereference any -pointers. +The `registers` command will print all the registers and dereference any pointers. Example on a MIPS host: @@ -51,8 +50,8 @@ $gp : 0x00418b20 ### Filtering registers ### -If one or more register names are passed to the `registers` command as optional -arguments, then only those will be shown: +If one or more register names are passed to the `registers` command as optional arguments, then only +those will be shown: ``` gef➤ reg $rax $rip $rsp diff --git a/docs/commands/scan.md b/docs/commands/scan.md index ffa9d0858..ebb744b3e 100644 --- a/docs/commands/scan.md +++ b/docs/commands/scan.md @@ -1,7 +1,7 @@ ## Command `scan` -`scan` searches for addresses of one memory region (needle) inside another -region (haystack) and lists all results. +`scan` searches for addresses of one memory region (needle) inside another region (haystack) and +lists all results. Usage: @@ -9,10 +9,9 @@ Usage: gef➤ scan NEEDLE HAYSTACK ``` -`scan` requires two arguments, the first is the memory section that will be -searched and the second is what will be searched for. The arguments are grepped -against the process's memory mappings (just like [vmmap](./vmmap.md)) to -determine the memory ranges to search. +`scan` requires two arguments, the first is the memory section that will be searched and the second +is what will be searched for. The arguments are grepped against the process's memory mappings (just +like [vmmap](./vmmap.md)) to determine the memory ranges to search. ``` gef➤ scan stack libc @@ -27,8 +26,7 @@ gef➤ scan stack libc ### Advanced Needle/Haystack syntax ### -To check mappings without a path associated, an address range (start-end) can -be used. Note that ranges don't include whitespaces. +To check mappings without a path associated, an address range (start-end) can be used. Note that +ranges don't include whitespaces. ![scan-address](https://i.imgur.com/ExJC2p7.png) - diff --git a/docs/commands/search-pattern.md b/docs/commands/search-pattern.md index beeb981b2..dc5044a82 100644 --- a/docs/commands/search-pattern.md +++ b/docs/commands/search-pattern.md @@ -1,21 +1,18 @@ ## Command `search-pattern` -`gef` allows you to search for a specific pattern at runtime in all the segments -of your process memory layout. The command `search-pattern`, alias `grep`, aims -to be straight-forward to use: +`gef` allows you to search for a specific pattern at runtime in all the segments of your process +memory layout. The command `search-pattern`, alias `grep`, aims to be straight-forward to use: ``` gef➤ search-pattern MyPattern ``` ![grep](https://i.imgur.com/YNzsFvk.png) -It will provide an easily understandable to spot occurrences of the specified -pattern, including the section it/they was/were found, and the permission -associated to that section. +It will provide an easily understandable to spot occurrences of the specified pattern, including the +section it/they was/were found, and the permission associated to that section. -`search-pattern` can also be used to search for addresses. To do so, simply -ensure that your pattern starts with `0x` and is a valid hex address. For -example: +`search-pattern` can also be used to search for addresses. To do so, simply ensure that your pattern +starts with `0x` and is a valid hex address. For example: ``` gef➤ search-pattern 0x4005f6 @@ -23,18 +20,19 @@ gef➤ search-pattern 0x4005f6 ![grep-address](https://i.imgur.com/dg1gUB5.png) -The `search-pattern` command can also be used as a way to search for -cross-references to an address. For this reason, the alias `xref` also points -to the command `search-pattern`. Therefore the command above is equivalent to -`xref 0x4005f6` which makes it more intuitive to use. +The `search-pattern` command can also be used as a way to search for cross-references to an address. +For this reason, the alias `xref` also points to the command `search-pattern`. Therefore the +command above is equivalent to `xref 0x4005f6` which makes it more intuitive to use. ### Searching in a specific range ### -Sometimes, you may need to search for a very common pattern. To limit the search space, you can also specify an address range or the section to be checked. +Sometimes, you may need to search for a very common pattern. To limit the search space, you can also +specify an address range or the section to be checked. ``` gef➤ search-pattern 0x4005f6 little libc gef➤ search-pattern 0x4005f6 little 0x603100-0x603200 ``` + ### Searching in a specific range using regex ### Sometimes, you may need an advanced search using regex. Just use --regex arg. diff --git a/docs/commands/shellcode.md b/docs/commands/shellcode.md index 1310b8188..f2d70b47b 100644 --- a/docs/commands/shellcode.md +++ b/docs/commands/shellcode.md @@ -1,8 +1,8 @@ ## Command `shellcode` -`shellcode` is a command line client for @JonathanSalwan shellcodes database. It -can be used to search and download directly via `GEF` the shellcode you're -looking for. Two primitive subcommands are available, `search` and `get` +`shellcode` is a command line client for @JonathanSalwan shellcodes database. It can be used to +search and download directly via `GEF` the shellcode you're looking for. Two primitive subcommands +are available, `search` and `get` ``` gef➤ shellcode search arm diff --git a/docs/commands/stub.md b/docs/commands/stub.md index cc23fa895..61ab0edb3 100644 --- a/docs/commands/stub.md +++ b/docs/commands/stub.md @@ -1,24 +1,21 @@ ## Command `stub` -The `stub` command allows you stub out functions, optionally specifying the -return value. +The `stub` command allows you stub out functions, optionally specifying the return value. ``` gef➤ stub [-h] [--retval RETVAL] [address] ``` -`address` indicates the address of the function to bypass. If not -specified, `GEF` will consider the instruction at the program counter to be the -start of the function. +`address` indicates the address of the function to bypass. If not specified, `GEF` will consider the +instruction at the program counter to be the start of the function. -If `--retval RETVAL` is provided, `GEF` will set the return value to the -provided value. Otherwise, it will set the return value to 0. +If `--retval RETVAL` is provided, `GEF` will set the return value to the provided value. Otherwise, +it will set the return value to 0. -For example, it is trivial to bypass `fork()` calls. Since the return value is -set to 0, it will in fact drop us into the "child" process. It must be noted -that this is a different behaviour from the classic `set follow-fork-mode -child` since here we do not spawn a new process, we only trick the parent -process into thinking it has become the child. +For example, it is trivial to bypass `fork()` calls. Since the return value is set to 0, it will in +fact drop us into the "child" process. It must be noted that this is a different behaviour from the +classic `set follow-fork-mode child` since here we do not spawn a new process, we only trick the +parent process into thinking it has become the child. ### Example ### diff --git a/docs/commands/theme.md b/docs/commands/theme.md index 22b62e8ec..0e3e19c0e 100644 --- a/docs/commands/theme.md +++ b/docs/commands/theme.md @@ -14,25 +14,25 @@ xinfo_title_message : blue bold ### Changing colors -You have the possibility to change the coloring properties of `GEF` display with -the `theme` command. The command accepts 2 arguments, the name of the property -to update, and its new coloring value. +You have the possibility to change the coloring properties of `GEF` display with the `theme` +command. The command accepts 2 arguments, the name of the property to update, and its new coloring +value. Colors can be one of the following: - - red - - green - - blue - - yellow - - gray - - pink +- red +- green +- blue +- yellow +- gray +- pink Color also accepts the following attributes: - - bold - - underline - - highlight - - blink +- bold +- underline +- highlight +- blink Any other will value simply be ignored. diff --git a/docs/commands/tmux-setup.md b/docs/commands/tmux-setup.md index 7d49fc158..cb9ce55ff 100644 --- a/docs/commands/tmux-setup.md +++ b/docs/commands/tmux-setup.md @@ -1,14 +1,14 @@ ## Command `tmux-setup` -In the purpose of always making debugging sessions easier while being more -effective, `GEF` integrates two commands: +In the purpose of always making debugging sessions easier while being more effective, `GEF` +integrates two commands: * `tmux-setup` * `screen-setup` -Those commands will check whether GDB is being spawn from inside a `tmux` -(resp. `screen`) session, and if so, will split the pane vertically, and -configure the context to be redirected to the new pane, looking something like: +Those commands will check whether GDB is being spawn from inside a `tmux` (resp. `screen`) session, +and if so, will split the pane vertically, and configure the context to be redirected to the new +pane, looking something like: ![](https://i.imgur.com/Khk3xGl.png) @@ -18,15 +18,14 @@ To set it up, simply enter gef➤ tmux-setup ``` -**Note**: Although `screen-setup` provides a similar setup, the structure of -`screen` does not allow a very clean way to do this. Therefore, if possible, it -would be recommended to use the `tmux-setup` command instead. +**Note**: Although `screen-setup` provides a similar setup, the structure of `screen` does not allow +a very clean way to do this. Therefore, if possible, it would be recommended to use the `tmux-setup` +command instead. ### Possible color issues with tmux ### -On Linux tmux only supports 8 colors with some terminal capabilities (`$TERM` -environment variable). This can mess up your color themes when using GEF with -tmux. To remedy this if your terminal supports more colors you can either set -the variable to something like `TERM=screen-256color` or if you don't want or -can't change that variable you can start `tmux` with the `-2` flag to force -tmux to use 256 colors. +On Linux tmux only supports 8 colors with some terminal capabilities (`$TERM` environment variable). +This can mess up your color themes when using GEF with tmux. To remedy this if your terminal +supports more colors you can either set the variable to something like `TERM=screen-256color` or if +you don't want or can't change that variable you can start `tmux` with the `-2` flag to force tmux +to use 256 colors. diff --git a/docs/commands/trace-run.md b/docs/commands/trace-run.md index fe35b48b9..1b30977dd 100644 --- a/docs/commands/trace-run.md +++ b/docs/commands/trace-run.md @@ -1,12 +1,11 @@ ## Command `trace-run` -The `trace-run` command is meant to be provide a visual appreciation directly -in IDA disassembler of the path taken by a specific execution. It should be -used with the IDA script +The `trace-run` command is meant to be provide a visual appreciation directly in IDA disassembler of +the path taken by a specific execution. It should be used with the IDA script [`ida_color_gdb_trace.py`](https://github.com/hugsy/stuff/blob/main/ida_scripts/ida_color_gdb_trace.py) -It will trace and store all values taken by `$pc` during the execution flow, -from its current value, until the value provided as argument. +It will trace and store all values taken by `$pc` during the execution flow, from its current value, +until the value provided as argument. ``` gef> trace-run @@ -14,8 +13,8 @@ gef> trace-run ![trace-run-1](https://i.imgur.com/yaOGste.png) -By using the script `ida_color_gdb_trace.py` on the text file generated, it -will color the path taken: +By using the script `ida_color_gdb_trace.py` on the text file generated, it will color the path +taken: ![trace-run-2](https://i.imgur.com/oAGoSMQ.png) diff --git a/docs/commands/version.md b/docs/commands/version.md index c32ec0667..3739d8a0c 100644 --- a/docs/commands/version.md +++ b/docs/commands/version.md @@ -25,12 +25,11 @@ GDB: 9.2 GDB-Python: 3.8 ``` -The `Blob Hash` can be used to easily find the git commit(s) matching -this file revision. +The `Blob Hash` can be used to easily find the git commit(s) matching this file revision. ``` git log --oneline --find-object ``` -If this command does not return anything then the file was most likely -modified and cannot be matched to a specific git commit. +If this command does not return anything then the file was most likely modified and cannot be +matched to a specific git commit. diff --git a/docs/commands/vmmap.md b/docs/commands/vmmap.md index 84b42a609..76e3bc868 100644 --- a/docs/commands/vmmap.md +++ b/docs/commands/vmmap.md @@ -4,14 +4,13 @@ ![vmmap](https://i.imgur.com/V9zMLUt.png) -Interestingly, it helps finding secret gems: as an aware reader might have -seen, memory mapping differs from one architecture to another (this is one of -the main reasons I started `GEF` in a first place). For example, you can learn -that ELF running on SPARC architectures always have their `.data` and `heap` -sections set as Read/Write/Execute. +Interestingly, it helps finding secret gems: as an aware reader might have seen, memory mapping +differs from one architecture to another (this is one of the main reasons I started `GEF` in a first +place). For example, you can learn that ELF running on SPARC architectures always have their `.data` +and `heap` sections set as Read/Write/Execute. -`vmmap` accepts one argument, either a pattern to match again mapping names, -or an address to determine which section it belongs to. +`vmmap` accepts one argument, either a pattern to match again mapping names, or an address to +determine which section it belongs to. ![vmmap-grep](https://i.imgur.com/ZFF4QVf.png) diff --git a/docs/commands/xfiles.md b/docs/commands/xfiles.md index d1a01fed1..7b0dfe29e 100644 --- a/docs/commands/xfiles.md +++ b/docs/commands/xfiles.md @@ -1,7 +1,7 @@ ## Command `xfiles` -`xfiles` is a more convenient representation of the GDB native command, `info -files` allowing you to filter by pattern given in argument. For example, if you -only want to show the code sections (i.e. `.text`): +`xfiles` is a more convenient representation of the GDB native command, `info files` allowing you to +filter by pattern given in argument. For example, if you only want to show the code sections (i.e. +`.text`): ![xfiles-example](https://i.imgur.com/lelnJ5B.png) diff --git a/docs/commands/xinfo.md b/docs/commands/xinfo.md index af5ba1327..0c31a89dd 100644 --- a/docs/commands/xinfo.md +++ b/docs/commands/xinfo.md @@ -1,14 +1,11 @@ ## Command `xinfo` -`xinfo` displays all the information known to `gef` about the specific address -given as argument: +`xinfo` displays all the information known to `gef` about the specific address given as argument: ![xinfo-example](https://i.imgur.com/x0KTAxz.png) -**Important note** : For performance reasons, `gef` caches certain results. -`gef` will try to automatically refresh its own cache to avoid relying on -obsolete information of the debugged process. However, in some dodgy scenario, -`gef` might fail detecting some new events making its cache partially obsolete. -If you notice an inconsistency on your memory mapping, you might want to force -`gef` flushing its cache and fetching brand new data, by running the command -`reset-cache`. +**Important note** : For performance reasons, `gef` caches certain results. `gef` will try to +automatically refresh its own cache to avoid relying on obsolete information of the debugged +process. However, in some dodgy scenario, `gef` might fail detecting some new events making its +cache partially obsolete. If you notice an inconsistency on your memory mapping, you might want to +force `gef` flushing its cache and fetching brand new data, by running the command `reset-cache`. diff --git a/docs/commands/xor-memory.md b/docs/commands/xor-memory.md index 279d33462..3c252611a 100644 --- a/docs/commands/xor-memory.md +++ b/docs/commands/xor-memory.md @@ -9,7 +9,8 @@ xor-memory
The first argument (`display` or `patch`) is the action to perform: -1. `display` will only show an hexdump of the result of the XOR-ed memory block, without writing the debuggee's memory. +1. `display` will only show an hexdump of the result of the XOR-ed memory block, without writing the + debuggee's memory. gef➤ xor display $rsp 16 1337 [+] Displaying XOR-ing 0x7fff589b67f8-0x7fff589b6808 with '1337' diff --git a/docs/config.md b/docs/config.md index 658f38677..21ee2dcf8 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,16 +1,23 @@ ## Configuring GEF -GEF comes with its own configuration and customization system, allowing fine tweaking. The configuration file is located under `~/.gef.rc` by default, and is automatically loaded when GEF is loaded by GDB. -If not configuration file is found, GEF will simply use the default settings. +GEF comes with its own configuration and customization system, allowing fine +tweaking. The configuration file is located under `~/.gef.rc` by default, and +is automatically loaded when GEF is loaded by GDB. If not configuration file is +found, GEF will simply use the default settings. -The configuration file is a Python [`configparser`](https://docs.python.org/3/library/configparser.html). To create a basic file with all settings and their default values, simply run +The configuration file is a Python +[`configparser`](https://docs.python.org/3/library/configparser.html). To +create a basic file with all settings and their default values, simply run ```bash gdb -ex 'gef save' -ex quit ``` You can now explore the configuration file under `~/.gef.rc`. -Once in GEF, the configuration settings can be set/unset/modified by the [command `gef config`](/docs/commands/config.md). Without argument the command will simply dump all known settings: + +Once in GEF, the configuration settings can be set/unset/modified by the +[command `gef config`](/docs/commands/config.md). Without argument the command +will simply dump all known settings: ![gef-config](https://i.imgur.com/bd2ZqsU.png) @@ -20,10 +27,12 @@ To update, follow the syntax gef➤ gef config . ``` -Any setting updated this way will be specific to the current GDB session. To make permanent, use the following command +Any setting updated this way will be specific to the current GDB session. To +make permanent, use the following command ``` gef➤ gef save ``` -Refer to the [`gef config` command documentation](/docs/commands/config.md) for complete explanation. +Refer to the `gef config` [command documentation](/docs/commands/config.md) for +complete explanation. diff --git a/docs/deprecated.md b/docs/deprecated.md index dda1fa699..64da93e39 100644 --- a/docs/deprecated.md +++ b/docs/deprecated.md @@ -1,7 +1,8 @@ # Deprecated commands -GEF is in itself a large file, but to avoid it to be out of control some commands once part of GEF were either moved to [GEF-Extras](https://github.com/hugsy/gef-extras) or even simply removed. -This page aims to track those changes. +GEF is in itself a large file, but to avoid it to be out of control some commands once part of GEF +were either moved to [GEF-Extras](https://github.com/hugsy/gef-extras) or even simply removed. This +page aims to track those changes. | Command | Status | Since | Link (if Applicable) | Notes | |--|--|--|--|--| diff --git a/docs/faq.md b/docs/faq.md index e7f623854..b065907cf 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -3,40 +3,58 @@ ## Why use GEF over PEDA? ## -[PEDA](https://github.com/longld/peda) is a fantastic tool that provides similar commands to make the exploitation development process smoother. +[PEDA](https://github.com/longld/peda) is a fantastic tool that provides similar commands to make +the exploitation development process smoother. -However, PEDA suffers from a major drawbacks, which the code is too fundamentally linked to Intel architectures (x86-32 and x86-64). On the other hand, GEF not only supports all the architecture supported by GDB (currently x86, ARM, AARCH64, MIPS, PowerPC, SPARC) but is designed to integrate new architectures very easily as well! +However, PEDA suffers from a major drawbacks, which the code is too fundamentally linked to Intel +architectures (x86-32 and x86-64). On the other hand, GEF not only supports all the architecture +supported by GDB (currently x86, ARM, AARCH64, MIPS, PowerPC, SPARC) but is designed to integrate +new architectures very easily as well! -Also, PEDA development has been quite idle for a few years now, and many new interesting features a debugger can provide simply do not exist. +Also, PEDA development has been quite idle for a few years now, and many new interesting features a +debugger can provide simply do not exist. ## What if my GDB is < 8.0 ? ## -GDB was introduced with its Python support early 2011 with the release of GDB 7. A (very) long way has gone since and the Python API has been massively improved, and GEF is taking advantage of them to provide the coolest features with as little performance impact as possible. +GDB was introduced with its Python support early 2011 with the release of GDB 7. A (very) long way +has gone since and the Python API has been massively improved, and GEF is taking advantage of them +to provide the coolest features with as little performance impact as possible. -Currently, GEF is optimized for running against GDB version 8.0+, and Python 3.6+. This allows for a best performance and best use of the GDB Python API. However, GEF can run on older versions too, check out [the version compatibility matrix](compat.md). For really older versions of GDB, you can use [`gef-legacy`](https://github.com/hugsy/gef-legacy) which supports a lot of older GDB, and a Python 2/3 compatibility layer. +Currently, GEF is optimized for running against GDB version 8.0+, and Python 3.6+. This allows for a +best performance and best use of the GDB Python API. However, GEF can run on older versions too, +check out [the version compatibility matrix](compat.md). For really older versions of GDB, you can +use [`gef-legacy`](https://github.com/hugsy/gef-legacy) which supports a lot of older GDB, and a +Python 2/3 compatibility layer. -Therefore, it is highly recommended to run GEF with the latest version of GDB. However, all functions should work on a GDB 8.0 and up. If not, send a [bug report](https://github.com/hugsy/gef/issues) and provide as much details as possible. +Therefore, it is highly recommended to run GEF with the latest version of GDB. However, all +functions should work on a GDB 8.0 and up. If not, send a [bug +report](https://github.com/hugsy/gef/issues) and provide as much details as possible. If you are running an obsolete version, GEF will show a error and message and exit. -Some pre-compiled static binaries for both recent GDB and GDBServer can be downloaded from the [`gdb-static`](https://github.com/hugsy/gdb-static) repository. +Some pre-compiled static binaries for both recent GDB and GDBServer can be downloaded from the +[`gdb-static`](https://github.com/hugsy/gdb-static) repository. ## I cannot get GEF setup!! ## -GEF will work on any GDB 8+ compiled with Python 3.6+ support. You can view that commands that failed to load using `gef missing`, but this will not affect GEF generally. +GEF will work on any GDB 8+ compiled with Python 3.6+ support. You can view that commands that +failed to load using `gef missing`, but this will not affect GEF generally. -If you experience problems setting it up on your host, first go to the [Discord channel](https://discord.gg/HCS8Hg7) for that. You will find great people there willing to help. +If you experience problems setting it up on your host, first go to the [Discord +channel](https://discord.gg/HCS8Hg7) for that. You will find great people there willing to help. -Note that the GitHub issue section is to be used to **report bugs** and **GEF issues** (like unexpected crash, improper error handling, weird edge case, etc.), not a place to ask for help. +Note that the GitHub issue section is to be used to **report bugs** and **GEF issues** (like +unexpected crash, improper error handling, weird edge case, etc.), not a place to ask for help. -All recent distributions ship packaged GDB that should be ready-to-go, with a GDB >= 8.0 and Python 3.6+. Any version higher or equal will work just fine. So you might actually only need to run `apt install gdb` to get the full-force of GEF. +All recent distributions ship packaged GDB that should be ready-to-go, with a GDB >= 8.0 and Python +3.6+. Any version higher or equal will work just fine. So you might actually only need to run `apt +install gdb` to get the full-force of GEF. ## I get a SegFault when starting GDB with GEF ## -A long standing bug in the `readline` library can make `gef` crash GDB -when displaying certain characters (SOH/ETX). As a result, this would SIGSEGV -GDB as `gef` is loading, a bit like this: +A long standing bug in the `readline` library can make `gef` crash GDB when displaying certain +characters (SOH/ETX). As a result, this would SIGSEGV GDB as `gef` is loading, a bit like this: ``` root@debian-aarch64:~# gdb -q ./test-bin-aarch64 @@ -48,8 +66,8 @@ Reading symbols from ./bof-aarch64...(no debugging symbols found)...done. Segmentation fault (core dumped) ``` -If so, this can be fixed easily by setting the `gef.readline_compat` variable to -`True` in the `~/.gef.rc` file. Something like this: +If so, this can be fixed easily by setting the `gef.readline_compat` variable to `True` in the +`~/.gef.rc` file. Something like this: ``` root@debian-aarch64:~# nano ~/.gef.rc @@ -58,13 +76,14 @@ root@debian-aarch64:~# nano ~/.gef.rc readline_compat = True ``` -You can now use all features of `gef` even on versions of GDB compiled against -old `readline` library. +You can now use all features of `gef` even on versions of GDB compiled against old `readline` +library. ## Does GEF prevent the use of other GDB plugins? ## -Definitely not! You can use any other GDB plugin on top of it for an even better debugging experience. +Definitely not! You can use any other GDB plugin on top of it for an even better debugging +experience. Some interesting plugins highly recommended too: @@ -78,25 +97,22 @@ Src: [@rick2600: terminator + gdb + gef + voltron cc: @snare @_hugsy_](https://t ## I want to contribute, where should I head first? ## -I would suggest thoroughly reading this documentation, just having a look to -the -[CONTRIBUTE](https://github.com/hugsy/gef/blob/main/.github/CONTRIBUTING.md) -file of the project to give you pointers. +I would suggest thoroughly reading this documentation, just having a look to the +[CONTRIBUTE](https://github.com/hugsy/gef/blob/main/.github/CONTRIBUTING.md) file of the project to +give you pointers. -Also a good thing would be to join our [Discord -channel](https://discord.gg/HCS8Hg7) to get in touch with the people -involved/using it. +Also a good thing would be to join our [Discord channel](https://discord.gg/HCS8Hg7) to get in touch +with the people involved/using it. ## I think I've found a bug, how can I help fixing it? ## -`gef` is only getting better through people (like you!) using it, but most -importantly reporting unexpected behavior. +`gef` is only getting better through people (like you!) using it, but most importantly reporting +unexpected behavior. -In most locations, Python exceptions will be properly intercepted. If not, `gef` -wraps all commands with a generic exception handler, to disturb as little as -possible your debugging session. If it happens, you'll only get to see a message -like this: +In most locations, Python exceptions will be properly intercepted. If not, `gef` wraps all commands +with a generic exception handler, to disturb as little as possible your debugging session. If it +happens, you'll only get to see a message like this: ![gef-exception](https://i.imgur.com/J7dUnXV.png) By switching to debug mode, `gef` will give much more information: @@ -106,26 +122,23 @@ gef➤ gef config gef.debug 1 ![gef-debug](https://i.imgur.com/SGe8oFF.png) If you think fixing it is in your skills, then send a [Pull -Request](https://github.com/hugsy/gef/pulls) with your patched version, -explaining your bug, and what was your solution for it. +Request](https://github.com/hugsy/gef/pulls) with your patched version, explaining your bug, and +what was your solution for it. -Otherwise, you can open an [issue](https://github.com/hugsy/gef/issues), give a -thorough description of your bug and copy/paste the content from above. This -will greatly help for solving the issue. +Otherwise, you can open an [issue](https://github.com/hugsy/gef/issues), give a thorough description +of your bug and copy/paste the content from above. This will greatly help for solving the issue. ## I get weird issues/characters using GDB + Python3, what's up? ## Chances are you are not using UTF-8. Python3 is [highly relying on -UTF-8](https://www.diveintopython3.net/strings.html) to display correctly -characters of any alphabet and [also some cool -emojis](https://unicode.org/emoji/charts/full-emoji-list.html). When GDB is -compiled with Python3, GEF will assume that your current charset is UTF-8 (for -instance, `en_US.UTF-8`). Use your `$LANG` environment variable to tweak this -setting. +UTF-8](https://www.diveintopython3.net/strings.html) to display correctly characters of any alphabet +and [also some cool emojis](https://unicode.org/emoji/charts/full-emoji-list.html). When GDB is +compiled with Python3, GEF will assume that your current charset is UTF-8 (for instance, +`en_US.UTF-8`). Use your `$LANG` environment variable to tweak this setting. -In addition, some unexpected results were observed when your local is not set to -English. If you aren't sure, simply run `gdb` like this: +In addition, some unexpected results were observed when your local is not set to English. If you +aren't sure, simply run `gdb` like this: ``` $ LC_ALL=en_US.UTF-8 gdb /path/to/your/binary @@ -133,8 +146,8 @@ $ LC_ALL=en_US.UTF-8 gdb /path/to/your/binary ## GDB crashes on ARM memory corruption with `gdb_exception_RETURN_MASK_ERROR` ## -This issue is **NOT** GEF related, but GDB's, or more precisely some versions of -GDB packaged with Debian/Kali for ARM +This issue is **NOT** GEF related, but GDB's, or more precisely some versions of GDB packaged with +Debian/Kali for ARM > > Original Issue and Mitigation @@ -156,13 +169,12 @@ GDB packaged with Debian/Kali for ARM > version, 8.1 as of this writing. > -**Do not file an issue**, again it is **NOT** a bug from GEF, or neither from GDB -Python API. Therefore, there is nothing GEF's developers can do about that. The -correct solution as mentioned above is to recompile your GDB with a newer -(better) version. +**Do not file an issue**, again it is **NOT** a bug from GEF, or neither from GDB Python API. +Therefore, there is nothing GEF's developers can do about that. The correct solution as mentioned +above is to recompile your GDB with a newer (better) version. -The whole topic was already internally discussed, so please refer to -the [issue #206](https://github.com/hugsy/gef/issues/206) for the whole story. +The whole topic was already internally discussed, so please refer to the [issue +#206](https://github.com/hugsy/gef/issues/206) for the whole story. ## I still don't have my answer... Where can I go? @@ -170,13 +182,19 @@ Discord is your answer: join and talk to us by clicking here [![Discord](https://img.shields.io/badge/Discord-GDB--GEF-yellow)](https://discord.gg/HCS8Hg7) -If you cannot find the answer to your problem here or on the Discord, then go to the project [Issues page](https://github.com/hugsy/gef/issues) and fill up the forms with as much information as you can! +If you cannot find the answer to your problem here or on the Discord, then go to the project [Issues +page](https://github.com/hugsy/gef/issues) and fill up the forms with as much information as you +can! ## How can I use GEF to debug a process in a container? -GEF can attach to a process running in a container using `gdb --pid=$PID`, where `$PID` is the ID of the running process *on the host*. To find this, you can use `docker top -o pid | awk '!/PID/' | xargs -I'{}' pstree -psa {}` to view the process tree for the container. +GEF can attach to a process running in a container using `gdb --pid=$PID`, where `$PID` is the ID of +the running process *on the host*. To find this, you can use `docker top -o pid | awk +'!/PID/' | xargs -I'{}' pstree -psa {}` to view the process tree for the container. -`sudo` may be required to attach to the process, which will depend on your system's security settings. - -Please note that cross-container debugging may have unexpected issues. Installing gdb and GEF inside the container, or using [the official GEF docker image](https://hub.docker.com/r/crazyhugsy/gef) may improve results. +`sudo` may be required to attach to the process, which will depend on your system's security +settings. +Please note that cross-container debugging may have unexpected issues. Installing gdb and GEF inside +the container, or using [the official GEF docker image](https://hub.docker.com/r/crazyhugsy/gef) may +improve results. diff --git a/docs/functions/base.md b/docs/functions/base.md index 897c02c49..ec442adef 100644 --- a/docs/functions/base.md +++ b/docs/functions/base.md @@ -1,6 +1,7 @@ # Function `$_base()` -Return the matching file's base address plus an optional offset. Defaults to current file. Note that quotes need to be escaped. +Return the matching file's base address plus an optional offset. Defaults to current file. Note that +quotes need to be escaped. _Note_: a debugging session must be active @@ -12,4 +13,3 @@ Example: ``` gef➤ p $_base(\"/usr/lib/ld-2.33.so\") ``` - diff --git a/docs/functions/bss.md b/docs/functions/bss.md index edcc37211..055f34d7a 100644 --- a/docs/functions/bss.md +++ b/docs/functions/bss.md @@ -12,4 +12,3 @@ Example: ``` gef➤ p $_bss(0x20) ``` - diff --git a/docs/functions/got.md b/docs/functions/got.md index 494427872..cb2ff95d7 100644 --- a/docs/functions/got.md +++ b/docs/functions/got.md @@ -12,4 +12,3 @@ Example: ``` gef➤ p $_got(0x20) ``` - diff --git a/docs/functions/heap.md b/docs/functions/heap.md index 2bf4394e1..a7ae27269 100644 --- a/docs/functions/heap.md +++ b/docs/functions/heap.md @@ -12,4 +12,3 @@ Example: ``` gef➤ p $_heap(0x20) ``` - diff --git a/docs/functions/stack.md b/docs/functions/stack.md index 56625737b..de825136d 100644 --- a/docs/functions/stack.md +++ b/docs/functions/stack.md @@ -12,5 +12,3 @@ Example: ``` gef➤ p $_stack(0x20) ``` - - diff --git a/docs/index.md b/docs/index.md index fece54116..f063bd161 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,41 +2,51 @@ [![Docs](https://img.shields.io/badge/Documentation-blue.svg)](https://hugsy.github.io/gef/) [![Coverage](https://img.shields.io/badge/Coverage-purple.svg)](https://hugsy.github.io/gef/coverage/) [![MIT](https://img.shields.io/packagist/l/doctrine/orm.svg?maxAge=2592000?style=plastic)](https://github.com/hugsy/gef/blob/main/LICENSE) [![Python 3](https://img.shields.io/badge/Python-3-green.svg)](https://github.com/hugsy/gef/) [![Discord](https://img.shields.io/badge/Discord-GDB--GEF-yellow)](https://discord.gg/HCS8Hg7) -`GEF` (pronounced ʤɛf - "Jeff") is a kick-ass set of commands for X86, ARM, -MIPS, PowerPC and SPARC to make GDB cool again for exploit dev. It is aimed to -be used mostly by exploit developers and reverse-engineers, to provide -additional features to GDB using the Python API to assist during the process of -dynamic analysis and exploit development. +`GEF` (pronounced ʤɛf - "Jeff") is a kick-ass set of commands for X86, ARM, MIPS, PowerPC and SPARC +to make GDB cool again for exploit dev. It is aimed to be used mostly by exploit developers and +reverse-engineers, to provide additional features to GDB using the Python API to assist during the +process of dynamic analysis and exploit development. -It requires Python 3, but [`gef-legacy`](https://github.com/hugsy/gef-legacy) can be used if Python 2 support is needed. +It requires Python 3, but [`gef-legacy`](https://github.com/hugsy/gef-legacy) can be used if Python +2 support is needed. ![gef-context](https://i.imgur.com/E3EuQPs.png) ## GDB Made Easy - * **One** single GDB script - * Entirely **architecture agnostic**, **NO** dependencies: `GEF` is battery-included and [is installable instantly](https://hugsy.github.io/gef/#setup) - * **Fast** limiting the number of dependencies and optimizing code to make the commands as fast as possible - * Provides a great variety of commands to drastically change your debugging experience in GDB. - * [**Easily** extensible](https://hugsy.github.io/gef/api/) to create other commands by providing more comprehensible layout to GDB Python API. - * Full Python3 support ([Python2 support was dropped in 2020.03](https://github.com/hugsy/gef/releases/tag/2020.03)) - check out [`gef-legacy`](https://github.com/hugsy/gef-legacy) for a Python2 compatible version, and [the compatibility matrix](/docs/compat.md) for a complete rundown of version support. - * Built around an architecture abstraction layer, so all commands work in any GDB-supported architecture such as x86-32/64, ARMv5/6/7, AARCH64, SPARC, MIPS, PowerPC, etc. - * Suited for real-life debugging, exploit development, just as much as for CTFs - -Check out the [showroom page](https://hugsy.github.io/gef/screenshots/) for more | or [try it online yourself!](https://demo.gef.blah.cat) (user:`gef`/password:`gef-demo`) +* **One** single GDB script +* Entirely **architecture agnostic**, **NO** dependencies: `GEF` is battery-included and [is + installable instantly](https://hugsy.github.io/gef/#setup) +* **Fast** limiting the number of dependencies and optimizing code to make the commands as fast as + possible +* Provides a great variety of commands to drastically change your debugging experience in GDB. +* [**Easily** extensible](https://hugsy.github.io/gef/api/) to create other commands by providing + more comprehensible layout to GDB Python API. +* Full Python3 support ([Python2 support was dropped in + 2020.03](https://github.com/hugsy/gef/releases/tag/2020.03)) - check out + [`gef-legacy`](https://github.com/hugsy/gef-legacy) for a Python2 compatible version, and [the + compatibility matrix](/docs/compat.md) for a complete rundown of version support. +* Built around an architecture abstraction layer, so all commands work in any GDB-supported + architecture such as x86-32/64, ARMv5/6/7, AARCH64, SPARC, MIPS, PowerPC, etc. +* Suited for real-life debugging, exploit development, just as much as for CTFs + +Check out the [showroom page](https://hugsy.github.io/gef/screenshots/) for more | or [try it online +yourself!](https://demo.gef.blah.cat) (user:`gef`/password:`gef-demo`) ## Quick start ### Automated installation -GEF has no dependencies, is fully battery-included and works out of the box. You can get started with GEF in a matter of seconds, by simply running: +GEF has no dependencies, is fully battery-included and works out of the box. You can get started +with GEF in a matter of seconds, by simply running: ```bash bash -c "$(curl -fsSL https://gef.blah.cat/sh)" ``` -For more details and other ways to install GEF please see [installation page](https://hugsy.github.io/gef/install/). +For more details and other ways to install GEF please see [installation +page](https://hugsy.github.io/gef/install/). ### Run @@ -65,23 +75,30 @@ gef➤ gef-remote -t your.ip.address:1234 -p 666 ## Bugs & Feedbacks ## -To discuss `gef`, `gdb`, exploitation or other topics, feel free to join our [Discord channel](https://discord.gg/HCS8Hg7). +To discuss `gef`, `gdb`, exploitation or other topics, feel free to join our [Discord +channel](https://discord.gg/HCS8Hg7). -For bugs or feature requests, just go [here](https://github.com/hugsy/gef/issues) and provide a thorough description if you want help. +For bugs or feature requests, just go [here](https://github.com/hugsy/gef/issues) and provide a +thorough description if you want help. -_Side Note_: `GEF` fully relies on the GDB API and other Linux-specific sources of information (such as `/proc/`). As a consequence, some of the features might not work on custom or hardened systems such as GrSec. +_Side Note_: `GEF` fully relies on the GDB API and other Linux-specific sources of information (such +as `/proc/`). As a consequence, some of the features might not work on custom or hardened +systems such as GrSec. ## Contribution ## -`gef` was created and maintained by myself, [`@_hugsy_`](https://twitter.com/_hugsy_), but kept fresh thanks to [all the contributors](https://github.com/hugsy/gef/graphs/contributors). +`gef` was created and maintained by myself, [`@_hugsy_`](https://twitter.com/_hugsy_), but kept +fresh thanks to [all the contributors](https://github.com/hugsy/gef/graphs/contributors). [ ![contributors-img](https://contrib.rocks/image?repo=hugsy/gef) ](https://github.com/hugsy/gef/graphs/contributors) -Or if you just like the tool, feel free to drop a simple *"thanks"* on Discord, Twitter or other, it is **always** very appreciated. +Or if you just like the tool, feel free to drop a simple *"thanks"* on Discord, Twitter or other, it +is **always** very appreciated. ## Sponsors ## -We would like to thank in particular the following people who've been sponsoring GEF allowing us to dedicate more time and resources to the project: +We would like to thank in particular the following people who've been sponsoring GEF allowing us to +dedicate more time and resources to the project: [](https://github.com/nkaretnikov) [](https://github.com/r3zk0n) @@ -95,8 +112,7 @@ We would like to thank in particular the following people who've been sponsoring ## Extra Credits - - The GEF logo was designed by [TheZakMan](https://twitter.com/thezakman) +- The GEF logo was designed by [TheZakMan](https://twitter.com/thezakman) ## 🍺 Happy hacking ! - diff --git a/docs/install.md b/docs/install.md index 2eb3c8c35..eac4d8fad 100644 --- a/docs/install.md +++ b/docs/install.md @@ -4,11 +4,15 @@ ### GDB -Only [GDB 8 and higher](https://www.gnu.org/s/gdb) is required. It must be compiled with Python 3.6 or higher support. For most people, simply using your distribution package manager should be enough. +Only [GDB 8 and higher](https://www.gnu.org/s/gdb) is required. It must be compiled with Python 3.6 +or higher support. For most people, simply using your distribution package manager should be enough. -As of January 2020, GEF officially doesn't support Python 2 any longer, due to Python 2 becoming officially deprecated. +As of January 2020, GEF officially doesn't support Python 2 any longer, due to Python 2 becoming +officially deprecated. -GEF will then only work for Python 3. If you absolutely require GDB + Python 2, please use [GEF-Legacy](https://github.com/hugsy/gef-legacy) instead. Note that `gef-legacy` won't provide new features, and only functional bugs will be handled. +GEF will then only work for Python 3. If you absolutely require GDB + Python 2, please use +[GEF-Legacy](https://github.com/hugsy/gef-legacy) instead. Note that `gef-legacy` won't provide new +features, and only functional bugs will be handled. You can verify it with the following command: @@ -28,16 +32,20 @@ $ gdb -nx -ex 'pi print(sys.version)' -ex quit There are **none**: `GEF` works out of the box! -GEF itself provides most (if not all 🤯) features required for typical sessions. However, GEF can be easily extended via - - community-built scripts, functions and architectures in the repo `gef-extras` (see below) - - your own script which can leverage the GEF API for the heavy lifting +GEF itself provides most (if not all 🤯) features required for typical sessions. However, GEF can be +easily extended via +- community-built scripts, functions and architectures in the repo + `gef-extras` (see below) +- your own script which can leverage the GEF API for the heavy lifting ## Standalone ### Quick install -The quickest way to get started with GEF is through the installation script available. Simply make sure you have [GDB 8.0 or higher](https://www.gnu.org/s/gdb), compiled with Python 3.6 or higher, and run +The quickest way to get started with GEF is through the installation script available. Simply make +sure you have [GDB 8.0 or higher](https://www.gnu.org/s/gdb), compiled with Python 3.6 or higher, +and run ```bash bash -c "$(curl -fsSL https://gef.blah.cat/sh)" @@ -55,7 +63,8 @@ $ gdb -q (gdb) pi import urllib.request as u, tempfile as t; g=t.NamedTemporaryFile(suffix='-gef.py'); open(g.name, 'wb+').write(u.urlopen('https://tinyurl.com/gef-main').read()); gdb.execute('source %s' % g.name) ``` -That's it! GEF is installed and correctly set up. You can confirm it by checking the `~/.gdbinit` file and see a line that sources (i.e. loads) GEF. +That's it! GEF is installed and correctly set up. You can confirm it by checking the `~/.gdbinit` +file and see a line that sources (i.e. loads) GEF. ```bash $ cat ~/.gdbinit @@ -65,14 +74,16 @@ source ~/.gdbinit-gef.py ### Update -If your host/VM is connected to the Internet, you can update `gef` easily to the latest version (even without `git` installed). with `python /path/to/gef.py --update` +If your host/VM is connected to the Internet, you can update `gef` easily to the latest version +(even without `git` installed). with `python /path/to/gef.py --update` ```bash $ python ~/.gdbinit-gef.py --update Updated ``` -This will deploy the latest version of `gef`'s _main_ branch from Github. If no updates are available, `gef` will respond `No update` instead. +This will deploy the latest version of `gef`'s _main_ branch from Github. If no +updates are available, `gef` will respond `No update` instead. ## Using git @@ -83,20 +94,24 @@ $ git clone --branch dev https://github.com/hugsy/gef.git $ echo source `pwd`/gef/gef.py >> ~/.gdbinit ``` -GEF is in very active development, so the default branch is `dev`. This is the branch you must use if you intend to submit pull requests. +GEF is in very active development, so the default branch is `dev`. This is the +branch you must use if you intend to submit pull requests. -However if you prefer a more stable life, you can then switch to the `main` branch: +However if you prefer a more stable life, you can then switch to the `main` +branch: ```bash $ git checkout main ``` -The `main` branch gets only updated for new releases, or also when critical fixes occur and need to be patched urgently. - +The `main` branch gets only updated for new releases, or also when critical +fixes occur and need to be patched urgently. ## Community repository: GEF-Extras -GEF was built to also provide a solid base for external scripts. The repository [`gef-extras`](https://github.com/hugsy/gef-extras) is an open repository where anyone can freely submit their own commands to extend GDB via GEF's API. +GEF was built to also provide a solid base for external scripts. The repository +[`gef-extras`](https://github.com/hugsy/gef-extras) is an open repository where +anyone can freely submit their own commands to extend GDB via GEF's API. To benefit from it: ```bash @@ -127,7 +142,8 @@ There, you're now fully equipped epic pwnage with **all** GEF's goodness!! ## Prevent script loading -GDB provides the `-nx` command line flag to disable the commands from the `~/.gdbinit` to be executed. +GDB provides the `-nx` command line flag to disable the commands from the +`~/.gdbinit` to be executed. ```text gdb -nx @@ -135,7 +151,8 @@ gdb -nx ## Disable GEF -To disable GEF without removing it, go to editing `~/.gdbinit`, spot the line that sources GEF, and comment / delete that line: +To disable GEF without removing it, go to editing `~/.gdbinit`, spot the line +that sources GEF, and comment / delete that line: So: @@ -150,7 +167,8 @@ $ cat ~/.gdbinit # source /my/path/to/gef.py ``` -Restart GDB, GEF is gone. Note that you can also load GEF at any moment during your GDB session as such: +Restart GDB, GEF is gone. Note that you can also load GEF at any moment during +your GDB session as such: ```text $ gdb @@ -159,8 +177,10 @@ $ gdb ## Remove GEF -GEF is a one-file GDB script. Therefore, to remove GEF simply spot the location it was installed (for example, by using `~/.gdbinit`) and delete the file. -If a configuration file was created, it will be located as `~/.gef.rc` and can also be deleted: +GEF is a one-file GDB script. Therefore, to remove GEF simply spot the location +it was installed (for example, by using `~/.gdbinit`) and delete the file. If a +configuration file was created, it will be located as `~/.gef.rc` and can also +be deleted: ```text $ cat ~/.gdbinit diff --git a/docs/screenshots.md b/docs/screenshots.md index 981702fb5..fff73a5d3 100644 --- a/docs/screenshots.md +++ b/docs/screenshots.md @@ -6,28 +6,31 @@ This page illustrates a few of the possibilities available to you when using `GE ## Multi-architecture support -`GEF` was designed to support any architecture supported by GDB via an easily extensible architecture API. +`GEF` was designed to support any architecture supported by GDB via an easily +extensible architecture API. Currently `GEF` supports the following architectures: - - Intel x86 (32b & 64b) - - ARM (v6/v7) - - AARCH64 - - MIPS/MIPS64 - - PowerPC - - SPARC/SPARCv9 +- Intel x86 (32b & 64b) +- ARM (v6/v7) +- AARCH64 +- MIPS/MIPS64 +- PowerPC +- SPARC/SPARCv9 ## Features ### Embedded hexdump view -To this day, GDB doesn't come with a hexdump-like view. Well `GEF` fixes that for you via the `hexdump` command: +To this day, GDB doesn't come with a hexdump-like view. Well `GEF` fixes that for you via the +`hexdump` command: ![hexdump](https://i.imgur.com/qt77lFQ.png) ### Dereferencing data or registers -No more endless manual pointer dereferencing `x/x` style. Just use `dereference` for that. Or for a comprehensive view of the registers, `registers` might become your best friend: +No more endless manual pointer dereferencing `x/x` style. Just use `dereference` for that. Or for a +comprehensive view of the registers, `registers` might become your best friend: ![mipsel-deref-regs](https://i.imgur.com/f5ZaWDC.png) diff --git a/docs/testing.md b/docs/testing.md index 29273d2c5..3f21625dd 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -1,7 +1,7 @@ ## Testing GEF -This page describes how GEF testing is done. Any new command/functionality must receive adequate testing to be merged. Also PR failing CI (test + linting) won't be merged either. - +This page describes how GEF testing is done. Any new command/functionality must receive adequate +testing to be merged. Also PR failing CI (test + linting) won't be merged either. ### Prerequisites @@ -13,10 +13,8 @@ python -m pip install -r tests/requirements.txt --user -U is enough to get started. - ### Running tests - #### Basic `pytest` For testing GEF on the architecture on the host running the tests (most cases), simply run @@ -26,13 +24,15 @@ cd /root/of/gef python3 -m pytest -v -k "not benchmark" tests ``` -Note that to ensure compatibility, tests must be executed with the same Python version GDB was compiled against. To obtain this version, you can execute the following command: +Note that to ensure compatibility, tests must be executed with the same Python version GDB was +compiled against. To obtain this version, you can execute the following command: ```bash gdb -q -nx -ex "pi print('.'.join(map(str, sys.version_info[:2])))" -ex quit ``` -At the end, a summary of explanation will be shown, clearly indicating the tests that have failed, for instance: +At the end, a summary of explanation will be shown, clearly indicating the tests that have failed, +for instance: ```text =================================== short test summary info ================================== @@ -47,9 +47,11 @@ You can then use `pytest` directly to help you fix each error specifically. #### Using `pytest` -GEF entirely relies on [`pytest`](https://pytest.org) for its testing. Refer to the project documentation for details. +GEF entirely relies on [`pytest`](https://pytest.org) for its testing. Refer to the project +documentation for details. -Adding a new command __requires__ for extensive testing in a new dedicated test module that should be located in `/root/of/gef/tests/commands/my_new_command.py` +Adding a new command __requires__ for extensive testing in a new dedicated test module that should +be located in `/root/of/gef/tests/commands/my_new_command.py` A skeleton of a test module would look something like: @@ -77,21 +79,25 @@ class MyCommandCommand(GefUnitTestGeneric): self.assertIn("Hello World", res) ``` -When running your test, you can summon `pytest` with the `--pdb` flag to enter the python testing environment to help you get more information about the reason of failure. +When running your test, you can summon `pytest` with the `--pdb` flag to enter the python testing +environment to help you get more information about the reason of failure. -One of the most convenient ways to test `gef` properly is using the `pytest` integration of modern editors such as VisualStudio Code or PyCharm. Without proper tests, new code will not be integrated. +One of the most convenient ways to test `gef` properly is using the `pytest` integration of modern +editors such as VisualStudio Code or PyCharm. Without proper tests, new code will not be integrated. ### Linting GEF -You can use the Makefile at the root of the project to get the proper linting settings. For most cases, the following command is enough: +You can use the Makefile at the root of the project to get the proper linting settings. For most +cases, the following command is enough: ```bash cd /root/of/gef python3 -m pylint --rcfile .pylintrc ``` -Note that to ensure compatibility, tests must be executed with the same Python version GDB was compiled against. To obtain this version, you can execute the following command: +Note that to ensure compatibility, tests must be executed with the same Python version GDB was +compiled against. To obtain this version, you can execute the following command: ```bash gdb -q -nx -ex "pi print('.'.join(map(str, sys.version_info[:2])))" -ex quit From 577ad02fd888d036f08d815a12547388e5788e3e Mon Sep 17 00:00:00 2001 From: Dreg Date: Wed, 19 Jul 2023 17:31:18 +0200 Subject: [PATCH 09/21] Add `skipi` command to skip N instructions (#964) --- docs/commands/skipi.md | 18 ++++++++++++ gef.py | 34 ++++++++++++++++++++++ tests/commands/skipi.py | 63 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 docs/commands/skipi.md create mode 100644 tests/commands/skipi.py diff --git a/docs/commands/skipi.md b/docs/commands/skipi.md new file mode 100644 index 000000000..68ca46243 --- /dev/null +++ b/docs/commands/skipi.md @@ -0,0 +1,18 @@ +## Command `skipi` + +The `skipi` command allows you to easily skip instructions execution. + +``` +skipi [LOCATION] [--n NUM_INSTRUCTIONS] +``` + +`LOCATION` address/symbol from where to skip (default is `$pc`) + +`--n NUM_INSTRUCTIONS` Skip the specified number of instructions instead of the default 1. + +```bash +gef➤ skipi +gef➤ skipi --n 3 +gef➤ skipi 0x69696969 +gef➤ skipi 0x69696969 --n 6 +``` \ No newline at end of file diff --git a/gef.py b/gef.py index 8875fc48f..e66ec0677 100644 --- a/gef.py +++ b/gef.py @@ -5985,6 +5985,40 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None: return +@register +class SkipiCommand(GenericCommand): + """Skip N instruction(s) execution""" + + _cmdline_ = "skipi" + _syntax_ = ("{_cmdline_} [LOCATION] [--n NUM_INSTRUCTIONS]" + "\n\tLOCATION\taddress/symbol from where to skip" + "\t--n NUM_INSTRUCTIONS\tSkip the specified number of instructions instead of the default 1.") + + _example_ = [f"{_cmdline_}", + f"{_cmdline_} --n 3", + f"{_cmdline_} 0x69696969", + f"{_cmdline_} 0x69696969 --n 6",] + + def __init__(self) -> None: + super().__init__(complete=gdb.COMPLETE_LOCATION) + return + + @only_if_gdb_running + @parse_arguments({"address": "$pc"}, {"--n": 1}) + def do_invoke(self, _: List[str], **kwargs: Any) -> None: + args : argparse.Namespace = kwargs["arguments"] + address = parse_address(args.address) + num_instructions = args.n + + last_addr = gdb_get_nth_next_instruction_address(address, num_instructions) + total_bytes = (last_addr - address) + gef_get_instruction_at(last_addr).size() + target_addr = address + total_bytes + + info(f"skipping {num_instructions} instructions ({total_bytes} bytes) from {address:#x} to {target_addr:#x}") + gdb.execute(f"set $pc = {target_addr:#x}") + return + + @register class NopCommand(GenericCommand): """Patch the instruction(s) pointed by parameters with NOP. Note: this command is architecture diff --git a/tests/commands/skipi.py b/tests/commands/skipi.py new file mode 100644 index 000000000..268b2aed8 --- /dev/null +++ b/tests/commands/skipi.py @@ -0,0 +1,63 @@ +""" +`skipi` command test module +""" + +import pytest + +from tests.utils import (ARCH, GefUnitTestGeneric, _target, findlines, + gdb_run_cmd, gdb_run_silent_cmd, gdb_start_silent_cmd) + + +class SkipiCommand(GefUnitTestGeneric): + """`skipi` command test module""" + + + cmd = "skipi" + + + def test_cmd_nop_inactive(self): + res = gdb_run_cmd(f"{self.cmd}") + self.assertFailIfInactiveSession(res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_skipi_no_arg(self): + + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc, p32(0x9090feeb))", # 1 short jumps to pc + 2 nops + after=( + self.cmd, + "pi print(gef.memory.read(gef.arch.pc, 2))", # read 2 bytes + ) + ) + self.assertNoException(res) + self.assertIn(r"\x90\x90", res) # 2 nops + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_skipi_skip_two_instructions(self): + + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc, p64(0x90909090feebfeeb))", # 2 short jumps to pc + 4 nops + after=( + f"{self.cmd} --n 2", + "pi print(gef.memory.read(gef.arch.pc, 4))", # read 4 bytes + ) + ) + self.assertNoException(res) + self.assertIn(r"\x90\x90\x90\x90", res) # 4 nops + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_skipi_two_instructions_from_location(self): + + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc, p64(0x9090feebfeebfeeb))", # 2 short jumps to pc + 2 nops + after=( + f"{self.cmd} $pc+2 --n 2", # from the second short jump + "pi print(gef.memory.read(gef.arch.pc, 2))", # read 2 bytes + ) + ) + self.assertNoException(res) + self.assertIn(r"\x90\x90", res) # 2 nops + From b2d3edc4af75016160da05ae531e094cb6cbd77c Mon Sep 17 00:00:00 2001 From: crazy hugsy Date: Fri, 21 Jul 2023 12:45:13 -0700 Subject: [PATCH 10/21] Update coverage.yml --- .github/workflows/coverage.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index f755a9b2c..aad63519d 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,4 +1,4 @@ -name: CI Coverage +name: CI Coverage for PR on: pull_request: @@ -40,7 +40,6 @@ jobs: SCORE_NEW: ${{ steps.get_coverage.outputs.new_coverage_score }} SCORE_DIFF: ${{ steps.get_coverage.outputs.diff_score }} with: - github-token: ${{ secrets.COVERAGE_REPORT_TOKEN }} script: | const comment = `## 🤖 Coverage Update From b0f4fa972d53ad1a8cf8d528be098d96eb9cb727 Mon Sep 17 00:00:00 2001 From: Dreg Date: Fri, 21 Jul 2023 21:48:00 +0200 Subject: [PATCH 11/21] add `site/` directory generated by mkdocs to `.gitignore` (#968) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a1b2b7cb5..6ec4d8589 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ debug.log .coverage htmlcov .benchmarks +site/ From 99c59a90573696843c4b901684d9b18ae6f3af96 Mon Sep 17 00:00:00 2001 From: Dreg Date: Fri, 21 Jul 2023 22:03:21 +0200 Subject: [PATCH 12/21] adjust the behavior (and options) for the `nop` command (#967) --- docs/commands/nop.md | 43 ++++++-- gef.py | 66 ++++++++--- tests/commands/nop.py | 249 ++++++++++++++++++++++++++++++++++++++---- 3 files changed, 310 insertions(+), 48 deletions(-) diff --git a/docs/commands/nop.md b/docs/commands/nop.md index 8f8b75c76..fd4be2476 100644 --- a/docs/commands/nop.md +++ b/docs/commands/nop.md @@ -3,21 +3,50 @@ The `nop` command allows you to easily patch instructions with nops. ``` -nop [LOCATION] [--n NUM_ITEMS] [--b] +nop [LOCATION] [--i ITEMS] [--f] [--n] [--b] ``` -`LOCATION` address/symbol to patch +`LOCATION` address/symbol to patch (by default this command replaces whole instructions) -`--n NUM_ITEMS` Instead of writing one instruction/nop, patch the specified number of -instructions/nops (full instruction size by default) +`--i ITEMS` number of items to insert (default 1) -`--b` Instead of writing full instruction size, patch the specified number of nops +`--f` Force patch even when the selected settings could overwrite partial instructions +`--n` Instead of replacing whole instructions, insert ITEMS nop instructions, no matter how many instructions it overwrites + +`--b` Instead of replacing whole instructions, fill ITEMS bytes with nops + +nop the current instruction ($pc): ```bash gef➤ nop +``` + +nop an instruction at $pc+3 address: +```bash gef➤ nop $pc+3 -gef➤ nop --n 2 $pc+3 +``` + +nop two instructions at address $pc+3: +```bash +gef➤ nop --i 2 $pc+3 +``` + +Replace 1 byte with nop at current instruction ($pc): +```bash gef➤ nop --b +``` + +Replace 1 byte with nop at address $pc+3: +```bash gef➤ nop --b $pc+3 -gef➤ nop --b --n 2 $pc+3 +``` + +Replace 2 bytes with nop(s) (breaking the last instruction) at address $pc+3: +```bash +gef➤ nop --f --b --i 2 $pc+3 +``` + +Patch 2 nops at address $pc+3: +```bash +gef➤ nop --n --i 2 $pc+3 ``` diff --git a/gef.py b/gef.py index e66ec0677..cfdd42fd6 100644 --- a/gef.py +++ b/gef.py @@ -6025,54 +6025,86 @@ class NopCommand(GenericCommand): aware.""" _cmdline_ = "nop" - _syntax_ = ("{_cmdline_} [LOCATION] [--n NUM_ITEMS] [--b]" - "\n\tLOCATION\taddress/symbol to patch" - "\t--n NUM_ITEMS\tInstead of writing one instruction/nop, patch the specified number of instructions/nops (full instruction size by default)" - "\t--b\tInstead of writing full instruction size, patch the specified number of nops") - _example_ = f"{_cmdline_} $pc" - + _syntax_ = ("{_cmdline_} [LOCATION] [--i ITEMS] [--f] [--n] [--b]" + "\n\tLOCATION\taddress/symbol to patch (by default this command replaces whole instructions)" + "\t--i ITEMS\tnumber of items to insert (default 1)" + "\t--f\tForce patch even when the selected settings could overwrite partial instructions" + "\t--n\tInstead of replacing whole instructions, insert ITEMS nop instructions, no matter how many instructions it overwrites" + "\t--b\tInstead of replacing whole instructions, fill ITEMS bytes with nops") _example_ = [f"{_cmdline_}", f"{_cmdline_} $pc+3", - f"{_cmdline_} --n 2 $pc+3", + f"{_cmdline_} --i 2 $pc+3", f"{_cmdline_} --b", f"{_cmdline_} --b $pc+3", - f"{_cmdline_} --b --n 2 $pc+3",] + f"{_cmdline_} --f --b --i 2 $pc+3" + f"{_cmdline_} --n --i 2 $pc+3",] def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - @parse_arguments({"address": "$pc"}, {"--n": 0, "--b": False}) + @parse_arguments({"address": "$pc"}, {"--i": 1, "--b": True, "--f": True, "--n": True}) def do_invoke(self, _: List[str], **kwargs: Any) -> None: args : argparse.Namespace = kwargs["arguments"] address = parse_address(args.address) nop = gef.arch.nop_insn - num_items = args.n or 1 - as_nops_flags = not args.b + num_items = args.i or 1 + fill_bytes = args.b + fill_nops = args.n + force_flag = args.f or False + + if fill_nops and fill_bytes: + err("only is possible specify --b or --n at same time") + return total_bytes = 0 - if as_nops_flags: + if fill_bytes: + total_bytes = num_items + elif fill_nops: total_bytes = num_items * len(nop) else: try: last_addr = gdb_get_nth_next_instruction_address(address, num_items) except: - err(f"Cannot patch instruction at {address:#x}: MAYBE reaching unmapped area") + err(f"Cannot patch instruction at {address:#x} reaching unmapped area") return total_bytes = (last_addr - address) + gef_get_instruction_at(last_addr).size() - if total_bytes % len(nop): - warn(f"Patching {total_bytes} bytes at {address:#x} will result in a partially patched instruction and may break disassembly") + if len(nop) > total_bytes or total_bytes % len(nop): + warn(f"Patching {total_bytes} bytes at {address:#x} will result in LAST-NOP " + f"(byte nr {total_bytes % len(nop):#x}) broken and may cause a crash or " + f"break disassembly. Use --f (force) to ignore this warning") + if not force_flag: + return + + target_end_address = address + total_bytes + curr_ins = gef_current_instruction(address) + while curr_ins.address + curr_ins.size() < target_end_address: + if not Address(value=curr_ins.address + 1).valid: + err(f"Cannot patch instruction at {address:#x}: reaching unmapped area") + return + curr_ins = gef_next_instruction(curr_ins.address) - nops = bytearray(nop * (total_bytes // len(nop))) + final_ins_end_addr = curr_ins.address + curr_ins.size() + + if final_ins_end_addr != target_end_address: + warn(f"Patching {total_bytes} bytes at {address:#x} will result in LAST-INSTRUCTION " + f"({curr_ins.address:#x}) being partial overwritten and may cause a crash or " + f"break disassembly. You must use --f to allow misaligned patching.") + if not force_flag: + return + + nops = bytearray(nop * total_bytes) end_address = Address(value=address + total_bytes - 1) if not end_address.valid: - err(f"Cannot patch instruction at {address:#x}: reaching unmapped area") + err(f"Cannot patch instruction at {address:#x}: reaching unmapped " + f"area: {end_address:#x}") return ok(f"Patching {total_bytes} bytes from {address:#x}") gef.memory.write(address, nops, total_bytes) + return diff --git a/tests/commands/nop.py b/tests/commands/nop.py index 9805c9b3e..5cb8c9881 100644 --- a/tests/commands/nop.py +++ b/tests/commands/nop.py @@ -19,38 +19,94 @@ def test_cmd_nop_inactive(self): res = gdb_run_cmd(f"{self.cmd}") self.assertFailIfInactiveSession(res) + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_no_arg(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))", # 2 short jumps to pc + "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))", after=( self.cmd, - "pi print(gef.memory.read(gef.arch.pc, 4))", # read 4 bytes + "pi print(gef.memory.read(gef.arch.pc, 4))", ) ) self.assertNoException(res) - self.assertIn(r"\x90\x90\xeb\xfe", res) # 2 nops + 1 short jump + self.assertIn(r"\x90\x90\xeb\xfe", res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_check_b_and_n_same_time(self): + + res = gdb_start_silent_cmd(f"{self.cmd} --b --n") + self.assertNoException(res) + self.assertIn(r"-b or --n at same time", res) @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") - def test_cmd_nop_arg(self): + def test_cmd_nop_no_arg_break_instruction(self): + res = gdb_start_silent_cmd( + (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", + "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))"), + + after=( + self.cmd, + "pi print(gef.memory.read(gef.arch.pc, 4))", + ) + ) + self.assertNoException(res) + self.assertIn(r"will result in LAST-NOP (byte nr 0x2)", res) + self.assertNotIn(r"\x90\x90\xeb\xfe", res) + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_force_arg_break_instruction(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.sp, p64(0xfeebfeebfeebfeeb))", # 4 short jumps to stack + (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", + "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))"), + after=( - f"{self.cmd} --n 2 $sp", - "pi print(gef.memory.read(gef.arch.sp, 8))", # read 8 bytes + f"{self.cmd} --f", + "pi print(gef.memory.read(gef.arch.pc, 4))", ) ) self.assertNoException(res) - self.assertIn(r"\x90\x90\x90\x90\xeb\xfe\xeb\xfe", res) # 4 nops + 2 short jumps + self.assertIn(r"will result in LAST-NOP (byte nr 0x2)", res) + self.assertIn(r"\x90\x91\xeb\xfe", res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_i_arg(self): + + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc+1, p64(0xfeebfeebfeebfeeb))", + after=( + f"{self.cmd} --i 2 $pc+1", + "pi print(gef.memory.read(gef.arch.pc+1, 8))", + ) + ) + self.assertNoException(res) + self.assertIn(r"\x90\x90\x90\x90\xeb\xfe\xeb\xfe", res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_i_arg_reaching_unmapped_area(self): + + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc+1, p64(0xfeebfeebfeebfeeb))", + after=( + f"{self.cmd} --i 2000000000000000000000000000000000000 $pc+1", + "pi print(gef.memory.read(gef.arch.pc+1, 8))", + ) + ) + self.assertIn(r"reaching unmapped area", res) + self.assertNoException(res) + self.assertNotIn(r"\x90\x90\x90\x90\xeb\xfe\xeb\xfe", res) @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_invalid_end_address(self): res = gdb_run_silent_cmd( - f"{self.cmd} --n 5 0x1337000+0x1000-4", + f"{self.cmd} --i 5 0x1337000+0x1000-4", target=_target("mmap-known-address") ) self.assertNoException(res) @@ -58,40 +114,185 @@ def test_cmd_nop_invalid_end_address(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") - def test_cmd_nop_as_bytes_no_arg(self): + def test_cmd_nop_nop(self): + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc, p32(0x9191))", + after=( + f"{self.cmd} --n", + "pi print(gef.memory.read(gef.arch.pc, 2))", + ) + ) + self.assertIn(r"\x90\x91", res) + self.assertNoException(res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_nop_break_instruction(self): + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", + after=( + f"{self.cmd} --n", + "pi print(gef.memory.read(gef.arch.pc, 2))", + ) + ) + self.assertIn(r"will result in LAST-INSTRUCTION", res) + self.assertIn(r"b'\xeb\xfe'", res) + self.assertNoException(res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_nop_break_instruction_force(self): res = gdb_start_silent_cmd( - "pi print(f'*** *pc={u8(gef.memory.read(gef.arch.pc, 1))}')", + "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", + after=( + f"{self.cmd} --n --f", + "pi print(gef.memory.read(gef.arch.pc, 2))", + ) + ) + self.assertIn(r"will result in LAST-INSTRUCTION", res) + self.assertIn(r"b'\x90\xfe'", res) + self.assertNoException(res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_nop_arg(self): + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))", + after=( + f"{self.cmd} --i 4 --n", + "pi print(gef.memory.read(gef.arch.pc, 8))", + ) + ) + self.assertIn(r"b'\x90\x90\x90\x90\xeb\xfe\xeb\xfe'", res) + self.assertNoException(res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_nop_arg_multibnop_breaks(self): + res = gdb_start_silent_cmd( + (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), + + after=( + f"{self.cmd} --n", + "pi print(gef.memory.read(gef.arch.pc, 8))", + ) + ) + self.assertNoException(res) + self.assertIn(r"will result in LAST-INSTRUCTION", res) + self.assertIn(r"b'\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe'", res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_nop_arg_multibnop_breaks_force(self): + res = gdb_start_silent_cmd( + (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), + + after=( + f"{self.cmd} --n --f", + "pi print(gef.memory.read(gef.arch.pc, 8))", + ) + ) + self.assertNoException(res) + self.assertIn(r"will result in LAST-INSTRUCTION", res) + self.assertIn(r"b'\x90\x91\x92\xfe\xeb\xfe\xeb\xfe'", res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_bytes(self): + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc, p16(0x9191))", + after=( + f"{self.cmd} --b", + "pi print(gef.memory.read(gef.arch.pc, 2))", + ) + ) + + self.assertIn(r"\x90\x91", res) + self.assertNoException(res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_bytes_break_instruction(self): + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", after=( f"{self.cmd} --b", - "pi print(f'*** *pc={u8(gef.memory.read(gef.arch.pc, 1)):#x}')", + "pi print(gef.memory.read(gef.arch.pc, 2))", + ) + ) + + self.assertIn(r"will result in LAST-INSTRUCTION", res) + self.assertIn(r"b'\xeb\xfe'", res) + self.assertNoException(res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_bytes_break_instruction_force(self): + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", + after=( + f"{self.cmd} --b --f", + "pi print(gef.memory.read(gef.arch.pc, 2))", + ) + ) + self.assertIn(r"will result in LAST-INSTRUCTION", res) + self.assertIn(r"b'\x90\xfe'", res) + self.assertNoException(res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_bytes_arg(self): + res = gdb_start_silent_cmd( + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))", + after=( + f"{self.cmd} --i 2 --b --f", + "pi print(gef.memory.read(gef.arch.pc, 8))", ) ) + self.assertIn(r"b'\x90\x90\xeb\xfe\xeb\xfe\xeb\xfe'", res) self.assertNoException(res) - lines = findlines("*** *pc=", res) - self.assertEqual(len(lines), 2) - self.assertEqual(lines[1], "*** *pc=0x90") @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") - def test_cmd_nop_as_bytes_arg(self): + def test_cmd_nop_bytes_arg_nops_no_fit(self): res = gdb_start_silent_cmd( - "pi print(f'*** *sp={u32(gef.memory.read(gef.arch.sp, 4))}')", + (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), + + after=( + f"{self.cmd} --i 4 --b", + "pi print(gef.memory.read(gef.arch.pc, 8))", + ) + ) + self.assertIn(r"b'\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe'", res) + self.assertIn(r"will result in LAST-NOP (byte nr 0x1)", res) + self.assertNoException(res) + + + @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") + def test_cmd_nop_bytes_arg_nops_no_fit_force(self): + res = gdb_start_silent_cmd( + (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), + after=( - f"{self.cmd} --b --n 4 $sp", - "pi print(f'*** *sp={u32(gef.memory.read(gef.arch.sp, 4)):#x}')", + f"{self.cmd} --i 5 --b --f", + "pi print(gef.memory.read(gef.arch.pc, 8))", ) ) + self.assertIn(r"b'\x90\x91\x92\x90\x91\xfe\xeb\xfe'", res) + self.assertIn(r"will result in LAST-NOP (byte nr 0x2)", res) + self.assertIn(r"will result in LAST-INSTRUCTION", res) self.assertNoException(res) - lines = findlines("*** *sp=", res) - self.assertEqual(len(lines), 2) - self.assertEqual(lines[1], "*** *sp=0x90909090") @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_as_bytes_invalid_end_address(self): # Make sure we error out if writing nops into an unmapped or RO area res = gdb_run_silent_cmd( - f"{self.cmd} --b --n 5 0x1337000+0x1000-4", + f"{self.cmd} --b --i 5 0x1337000+0x1000-4", target=_target("mmap-known-address") ) self.assertNoException(res) @@ -100,7 +301,7 @@ def test_cmd_nop_as_bytes_invalid_end_address(self): # We had an off-by-one bug where we couldn't write the last byte before # an unmapped area. Make sure that we can now. res = gdb_run_silent_cmd( - f"{self.cmd} --b --n 4 0x1337000+0x1000-4", + f"{self.cmd} --b --i 4 0x1337000+0x1000-4", target=_target("mmap-known-address"), after="pi print(f'*** *mem={u32(gef.memory.read(0x1337ffc, 4)):#x}')", ) From 9170ac0a8d0c271a0524f6216a9ae5c222746227 Mon Sep 17 00:00:00 2001 From: Grazfather Date: Fri, 21 Jul 2023 16:31:33 -0400 Subject: [PATCH 13/21] nop: Add force req when not already --f (#970) --- docs/commands/nop.md | 3 ++- gef.py | 16 +++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/commands/nop.md b/docs/commands/nop.md index fd4be2476..7c3ab011b 100644 --- a/docs/commands/nop.md +++ b/docs/commands/nop.md @@ -12,7 +12,8 @@ nop [LOCATION] [--i ITEMS] [--f] [--n] [--b] `--f` Force patch even when the selected settings could overwrite partial instructions -`--n` Instead of replacing whole instructions, insert ITEMS nop instructions, no matter how many instructions it overwrites +`--n` Instead of replacing whole instructions, insert ITEMS nop instructions, no matter how many +instructions it overwrites `--b` Instead of replacing whole instructions, fill ITEMS bytes with nops diff --git a/gef.py b/gef.py index cfdd42fd6..3834248e1 100644 --- a/gef.py +++ b/gef.py @@ -6009,7 +6009,7 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None: args : argparse.Namespace = kwargs["arguments"] address = parse_address(args.address) num_instructions = args.n - + last_addr = gdb_get_nth_next_instruction_address(address, num_instructions) total_bytes = (last_addr - address) + gef_get_instruction_at(last_addr).size() target_addr = address + total_bytes @@ -6017,7 +6017,7 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None: info(f"skipping {num_instructions} instructions ({total_bytes} bytes) from {address:#x} to {target_addr:#x}") gdb.execute(f"set $pc = {target_addr:#x}") return - + @register class NopCommand(GenericCommand): @@ -6050,10 +6050,10 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None: address = parse_address(args.address) nop = gef.arch.nop_insn num_items = args.i or 1 - fill_bytes = args.b + fill_bytes = args.b fill_nops = args.n force_flag = args.f or False - + if fill_nops and fill_bytes: err("only is possible specify --b or --n at same time") return @@ -6074,8 +6074,9 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None: if len(nop) > total_bytes or total_bytes % len(nop): warn(f"Patching {total_bytes} bytes at {address:#x} will result in LAST-NOP " f"(byte nr {total_bytes % len(nop):#x}) broken and may cause a crash or " - f"break disassembly. Use --f (force) to ignore this warning") + "break disassembly.") if not force_flag: + warn("Use --f (force) to ignore this warning.") return target_end_address = address + total_bytes @@ -6087,12 +6088,13 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None: curr_ins = gef_next_instruction(curr_ins.address) final_ins_end_addr = curr_ins.address + curr_ins.size() - + if final_ins_end_addr != target_end_address: warn(f"Patching {total_bytes} bytes at {address:#x} will result in LAST-INSTRUCTION " f"({curr_ins.address:#x}) being partial overwritten and may cause a crash or " - f"break disassembly. You must use --f to allow misaligned patching.") + "break disassembly.") if not force_flag: + warn("Use --f (force) to ignore this warning.") return nops = bytearray(nop * total_bytes) From 81ee52d32009c912000f65052f289d38bd63cd71 Mon Sep 17 00:00:00 2001 From: Grazfather Date: Sat, 22 Jul 2023 11:52:02 -0400 Subject: [PATCH 14/21] Small cleanup - sets (#972) --- gef.py | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/gef.py b/gef.py index 3834248e1..416fcec49 100644 --- a/gef.py +++ b/gef.py @@ -6416,7 +6416,7 @@ def do_invoke(self, argv: List[str]) -> None: if "all" in argv: tids = [t.num for t in threads] else: - tids = self.check_thread_ids(argv) + tids = self.check_thread_ids([int(a) for a in argv]) else: tids = [current_thread.num] @@ -6499,21 +6499,9 @@ def find_tcache() -> int: @staticmethod def check_thread_ids(tids: List[int]) -> List[int]: - """Check the validity, dedup, and return all valid tids.""" - existing_tids = [t.num for t in gdb.selected_inferior().threads()] - valid_tids = set() - for tid in tids: - try: - tid = int(tid) - except ValueError: - err(f"Invalid thread id {tid:d}") - continue - if tid in existing_tids: - valid_tids.add(tid) - else: - err(f"Unknown thread {tid}") - - return list(valid_tids) + """Return the subset of tids that are currently valid.""" + existing_tids = set(t.num for t in gdb.selected_inferior().threads()) + return list(set(tids) & existing_tids) @staticmethod def tcachebin(tcache_base: int, i: int) -> Tuple[Optional[GlibcTcacheChunk], int]: @@ -6760,11 +6748,11 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None: args : argparse.Namespace = kwargs["arguments"] if args.registers and args.registers[0]: - required_regs = set(args.registers) - valid_regs = [reg for reg in gef.arch.all_registers if reg in required_regs] + requested_regs = set(args.registers) + valid_regs = set(gef.arch.all_registers) & requested_regs if valid_regs: regs = valid_regs - invalid_regs = [reg for reg in required_regs if reg not in valid_regs] + invalid_regs = requested_regs - valid_regs if invalid_regs: err(f"invalid registers for architecture: {', '.join(invalid_regs)}") @@ -7346,7 +7334,7 @@ def context_regs(self) -> None: if self["show_registers_raw"] is False: regs = set(gef.arch.all_registers) - printable_registers = " ".join(list(regs - ignored_registers)) + printable_registers = " ".join(regs - ignored_registers) gdb.execute(f"registers {printable_registers}") return @@ -9596,10 +9584,10 @@ def add_context_pane(self, pane_name: str, display_pane_function: Callable, pane def load(self) -> None: """Load all the commands and functions defined by GEF into GDB.""" - current_commands = set( self.commands.keys() ) - new_commands = set( [x._cmdline_ for x in __registered_commands__] ) - current_commands - current_functions = set( self.functions.keys() ) - new_functions = set([x._function_ for x in __registered_functions__]) - current_functions + current_commands = set(self.commands.keys()) + new_commands = set(x._cmdline_ for x in __registered_commands__) - current_commands + current_functions = set(self.functions.keys()) + new_functions = set(x._function_ for x in __registered_functions__) - current_functions self.missing.clear() self.__load_time_ms = time.time()* 1000 From e529fbcb6ca23a6915683c639cb3d51d0242fd77 Mon Sep 17 00:00:00 2001 From: crazy hugsy Date: Sat, 22 Jul 2023 08:58:25 -0700 Subject: [PATCH 15/21] Restore `autosave_breakpoints_file` behavior (#969) * Fixes #965 * Also changes the dates 2022 -> 2023 --- LICENSE | 2 +- gef.py | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/LICENSE b/LICENSE index e84b43ea8..32ae4ca98 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013-2022 crazy rabbidz +Copyright (c) 2013-2023 crazy rabbidz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/gef.py b/gef.py index 416fcec49..85277be67 100644 --- a/gef.py +++ b/gef.py @@ -29,7 +29,7 @@ ####################################################################################### # # gef is distributed under the MIT License (MIT) -# Copyright (c) 2013-2022 crazy rabbidz +# Copyright (c) 2013-2023 crazy rabbidz # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -1202,6 +1202,7 @@ class GlibcHeapInfo: @staticmethod def heap_info_t() -> Type[ctypes.Structure]: + assert gef.libc.version class heap_info_cls(ctypes.Structure): pass pointer = ctypes.c_uint64 if gef.arch.ptrsize == 8 else ctypes.c_uint32 @@ -3508,7 +3509,7 @@ def is_hex(pattern: str) -> bool: return len(pattern) % 2 == 0 and all(c in string.hexdigits for c in pattern[2:]) -def continue_handler(_: "gdb.Event") -> None: +def continue_handler(_: "gdb.ContinueEvent") -> None: """GDB event handler for new object continue cases.""" return @@ -3552,13 +3553,31 @@ def new_objfile_handler(evt: Optional["gdb.NewObjFileEvent"]) -> None: def exit_handler(_: "gdb.ExitedEvent") -> None: """GDB event handler for exit cases.""" global gef + # flush the caches reset_all_caches() + + # disconnect properly the remote session gef.session.qemu_mode = False if gef.session.remote: gef.session.remote.close() del gef.session.remote gef.session.remote = None gef.session.remote_initializing = False + + # if `autosave_breakpoints_file` setting is configured, save the breakpoints to disk + setting = (gef.config["gef.autosave_breakpoints_file"] or "").strip() + if not setting: + return + + bkp_fpath = pathlib.Path(setting).expanduser().absolute() + if bkp_fpath.exists(): + warn(f"{bkp_fpath} exists, content will be overwritten") + + with bkp_fpath.open("w") as fd: + for bp in gdb.breakpoints(): + if not bp.enabled or not bp.is_valid: + continue + fd.write(f"{'t' if bp.temporary else ''}break {bp.location}\n") return @@ -3931,7 +3950,7 @@ def set_arch(arch: Optional[str] = None, _: Optional[str] = None) -> None: # @only_if_events_supported("cont") -def gef_on_continue_hook(func: Callable[["gdb.ThreadEvent"], None]) -> None: +def gef_on_continue_hook(func: Callable[["gdb.ContinueEvent"], None]) -> None: gdb.events.cont.connect(func) @@ -10439,6 +10458,7 @@ def main_arena(self, value: GlibcArena) -> None: @staticmethod @lru_cache() def find_main_arena_addr() -> int: + assert gef.libc.version """A helper function to find the glibc `main_arena` address, either from symbol, from its offset from `__malloc_hook` or by brute force.""" # Before anything else, use libc offset from config if available @@ -10555,6 +10575,7 @@ def min_chunk_size(self) -> int: @property def malloc_alignment(self) -> int: + assert gef.libc.version __default_malloc_alignment = 0x10 if gef.libc.version >= (2, 26) and is_x86_32(): # Special case introduced in Glibc 2.26: @@ -11160,7 +11181,8 @@ def reset_caches(self) -> None: gef_on_memchanged_hook(memchanged_handler) gef_on_regchanged_hook(regchanged_handler) - if gdb.current_progspace().filename is not None: + progspace = gdb.current_progspace() + if progspace and progspace.filename: # if here, we are sourcing gef from a gdb session already attached, force call to new_objfile (see issue #278) new_objfile_handler(None) @@ -11170,3 +11192,8 @@ def reset_caches(self) -> None: errmsg = "Using `target remote` with GEF does not work, use `gef-remote` instead. You've been warned." gdb.execute(f"define target hook-remote\n pi if calling_function() != \"connect\": err(\"{errmsg}\") \nend") gdb.execute(f"define target hook-extended-remote\n pi if calling_function() != \"connect\": err(\"{errmsg}\") \nend") + + # restore saved breakpoints (if any) + bkp_fpath = pathlib.Path(gef.config["gef.autosave_breakpoints_file"]).expanduser().absolute() + if bkp_fpath.exists() and bkp_fpath.is_file(): + gdb.execute(f"source {bkp_fpath}") From 0461d6fe6e3592f333e11ab39947905171ba9011 Mon Sep 17 00:00:00 2001 From: crazy hugsy Date: Sat, 22 Jul 2023 16:31:05 -0700 Subject: [PATCH 16/21] Fix hardcoded NOP instructions for ARM/AARCH64 (#971) * fix nop insn of arm & arm64 to `hint #0` * `gef.memory.write` should take an optional param for length * [gef] fixed off by one in gdb_get_nth_next_instruction_address for fixed insn size archs * replicate error message change to tests * deprecating `gdb_get_nth_next_instruction_address()` in favor `gef_instruction_n()` * bit more type hinting --- gef.py | 46 ++++++++++++++----------- tests/commands/nop.py | 80 +++++++++++++++++++++---------------------- 2 files changed, 66 insertions(+), 60 deletions(-) diff --git a/gef.py b/gef.py index 85277be67..21b2f43e0 100644 --- a/gef.py +++ b/gef.py @@ -1193,6 +1193,11 @@ def is_valid(self) -> bool: def size(self) -> int: return len(self.opcodes) + def next(self) -> "Instruction": + address = self.address + self.size() + return gef_get_instruction_at(address) + + @deprecated("Use GefHeapManager.find_main_arena_addr()") def search_for_main_arena() -> int: return GefHeapManager.find_main_arena_addr() @@ -2013,6 +2018,9 @@ def gdb_disassemble(start_pc: int, **kwargs: int) -> Generator[Instruction, None arch = frame.architecture() for insn in arch.disassemble(start_pc, **kwargs): + assert isinstance(insn["addr"], int) + assert isinstance(insn["length"], int) + assert isinstance(insn["asm"], str) address = insn["addr"] asm = insn["asm"].rstrip().split(None, 1) if len(asm) > 1: @@ -2066,19 +2074,15 @@ def gdb_get_nth_previous_instruction_address(addr: int, n: int) -> Optional[int] return None +@deprecated(solution="Use `gef_instruction_n().address`") def gdb_get_nth_next_instruction_address(addr: int, n: int) -> int: - """Return the address (Integer) of the `n`-th instruction after `addr`.""" - # fixed-length ABI - if gef.arch.instruction_length: - return addr + n * gef.arch.instruction_length - - # variable-length ABI - insn = list(gdb_disassemble(addr, count=n))[-1] - return insn.address + """Return the address of the `n`-th instruction after `addr`. """ + return gef_instruction_n(addr, n).address def gef_instruction_n(addr: int, n: int) -> Instruction: - """Return the `n`-th instruction after `addr` as an Instruction object.""" + """Return the `n`-th instruction after `addr` as an Instruction object. Note that `n` is treated as + an positive index, starting from 0 (current instruction address)""" return list(gdb_disassemble(addr, count=n + 1))[n] @@ -2509,8 +2513,7 @@ class ARM(Architecture): "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$sp", "$lr", "$pc", "$cpsr",) - # https://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0041c/Caccegih.html - nop_insn = b"\x01\x10\xa0\xe1" # mov r1, r1 + nop_insn = b"\x00\xf0\x20\xe3" # hint #0 return_register = "$r0" flag_register: str = "$cpsr" flags_table = { @@ -2675,6 +2678,7 @@ class AARCH64(ARM): 5: "t32", 4: "m[4]", } + nop_insn = b"\x1f\x20\x03\xd5" # hint #0 function_parameters = ("$x0", "$x1", "$x2", "$x3", "$x4", "$x5", "$x6", "$x7",) syscall_register = "$x8" syscall_instructions = ("svc $x0",) @@ -6029,8 +6033,8 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None: address = parse_address(args.address) num_instructions = args.n - last_addr = gdb_get_nth_next_instruction_address(address, num_instructions) - total_bytes = (last_addr - address) + gef_get_instruction_at(last_addr).size() + last_insn = gef_instruction_n(address, num_instructions-1) + total_bytes = (last_insn.address - address) + last_insn.size() target_addr = address + total_bytes info(f"skipping {num_instructions} instructions ({total_bytes} bytes) from {address:#x} to {target_addr:#x}") @@ -6068,13 +6072,13 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None: args : argparse.Namespace = kwargs["arguments"] address = parse_address(args.address) nop = gef.arch.nop_insn - num_items = args.i or 1 - fill_bytes = args.b - fill_nops = args.n - force_flag = args.f or False + num_items = int(args.i) or 1 + fill_bytes = bool(args.b) + fill_nops = bool(args.n) + force_flag = bool(args.f) or False if fill_nops and fill_bytes: - err("only is possible specify --b or --n at same time") + err("--b and --n cannot be specified at the same time.") return total_bytes = 0 @@ -6084,7 +6088,8 @@ def do_invoke(self, _: List[str], **kwargs: Any) -> None: total_bytes = num_items * len(nop) else: try: - last_addr = gdb_get_nth_next_instruction_address(address, num_items) + last_insn = gef_instruction_n(address, num_items-1) + last_addr = last_insn.address except: err(f"Cannot patch instruction at {address:#x} reaching unmapped area") return @@ -10274,8 +10279,9 @@ def reset_caches(self) -> None: self.__maps = None return - def write(self, address: int, buffer: ByteString, length: int = 0x10) -> None: + def write(self, address: int, buffer: ByteString, length: Optional[int] = None) -> None: """Write `buffer` at address `address`.""" + length = length or len(buffer) gdb.selected_inferior().write_memory(address, buffer, length) def read(self, addr: int, length: int = 0x10) -> bytes: diff --git a/tests/commands/nop.py b/tests/commands/nop.py index 5cb8c9881..afa60bdf5 100644 --- a/tests/commands/nop.py +++ b/tests/commands/nop.py @@ -24,14 +24,14 @@ def test_cmd_nop_inactive(self): def test_cmd_nop_no_arg(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))", + "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))", after=( self.cmd, - "pi print(gef.memory.read(gef.arch.pc, 4))", + "pi print(gef.memory.read(gef.arch.pc, 4))", ) ) self.assertNoException(res) - self.assertIn(r"\x90\x90\xeb\xfe", res) + self.assertIn(r"\x90\x90\xeb\xfe", res) @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") @@ -39,30 +39,30 @@ def test_cmd_nop_check_b_and_n_same_time(self): res = gdb_start_silent_cmd(f"{self.cmd} --b --n") self.assertNoException(res) - self.assertIn(r"-b or --n at same time", res) + self.assertIn(r"--b and --n cannot be specified at the same time.", res) @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_no_arg_break_instruction(self): res = gdb_start_silent_cmd( (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", - "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))"), + "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))"), after=( self.cmd, - "pi print(gef.memory.read(gef.arch.pc, 4))", + "pi print(gef.memory.read(gef.arch.pc, 4))", ) ) self.assertNoException(res) self.assertIn(r"will result in LAST-NOP (byte nr 0x2)", res) - self.assertNotIn(r"\x90\x90\xeb\xfe", res) + self.assertNotIn(r"\x90\x90\xeb\xfe", res) @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_force_arg_break_instruction(self): res = gdb_start_silent_cmd( (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", - "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))"), + "pi gef.memory.write(gef.arch.pc, p32(0xfeebfeeb))"), after=( f"{self.cmd} --f", @@ -71,36 +71,36 @@ def test_cmd_nop_force_arg_break_instruction(self): ) self.assertNoException(res) self.assertIn(r"will result in LAST-NOP (byte nr 0x2)", res) - self.assertIn(r"\x90\x91\xeb\xfe", res) + self.assertIn(r"\x90\x91\xeb\xfe", res) @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_i_arg(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc+1, p64(0xfeebfeebfeebfeeb))", + "pi gef.memory.write(gef.arch.pc+1, p64(0xfeebfeebfeebfeeb))", after=( f"{self.cmd} --i 2 $pc+1", - "pi print(gef.memory.read(gef.arch.pc+1, 8))", + "pi print(gef.memory.read(gef.arch.pc+1, 8))", ) ) self.assertNoException(res) - self.assertIn(r"\x90\x90\x90\x90\xeb\xfe\xeb\xfe", res) + self.assertIn(r"\x90\x90\x90\x90\xeb\xfe\xeb\xfe", res) @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_i_arg_reaching_unmapped_area(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc+1, p64(0xfeebfeebfeebfeeb))", + "pi gef.memory.write(gef.arch.pc+1, p64(0xfeebfeebfeebfeeb))", after=( f"{self.cmd} --i 2000000000000000000000000000000000000 $pc+1", - "pi print(gef.memory.read(gef.arch.pc+1, 8))", + "pi print(gef.memory.read(gef.arch.pc+1, 8))", ) ) self.assertIn(r"reaching unmapped area", res) self.assertNoException(res) - self.assertNotIn(r"\x90\x90\x90\x90\xeb\xfe\xeb\xfe", res) + self.assertNotIn(r"\x90\x90\x90\x90\xeb\xfe\xeb\xfe", res) @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") @@ -116,10 +116,10 @@ def test_cmd_nop_invalid_end_address(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_nop(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc, p32(0x9191))", + "pi gef.memory.write(gef.arch.pc, p32(0x9191))", after=( f"{self.cmd} --n", - "pi print(gef.memory.read(gef.arch.pc, 2))", + "pi print(gef.memory.read(gef.arch.pc, 2))", ) ) self.assertIn(r"\x90\x91", res) @@ -129,10 +129,10 @@ def test_cmd_nop_nop(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_nop_break_instruction(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", + "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", after=( f"{self.cmd} --n", - "pi print(gef.memory.read(gef.arch.pc, 2))", + "pi print(gef.memory.read(gef.arch.pc, 2))", ) ) self.assertIn(r"will result in LAST-INSTRUCTION", res) @@ -143,10 +143,10 @@ def test_cmd_nop_nop_break_instruction(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_nop_break_instruction_force(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", + "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", after=( f"{self.cmd} --n --f", - "pi print(gef.memory.read(gef.arch.pc, 2))", + "pi print(gef.memory.read(gef.arch.pc, 2))", ) ) self.assertIn(r"will result in LAST-INSTRUCTION", res) @@ -157,10 +157,10 @@ def test_cmd_nop_nop_break_instruction_force(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_nop_arg(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))", + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))", after=( f"{self.cmd} --i 4 --n", - "pi print(gef.memory.read(gef.arch.pc, 8))", + "pi print(gef.memory.read(gef.arch.pc, 8))", ) ) self.assertIn(r"b'\x90\x90\x90\x90\xeb\xfe\xeb\xfe'", res) @@ -171,7 +171,7 @@ def test_cmd_nop_nop_arg(self): def test_cmd_nop_nop_arg_multibnop_breaks(self): res = gdb_start_silent_cmd( (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", - "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), after=( f"{self.cmd} --n", @@ -180,14 +180,14 @@ def test_cmd_nop_nop_arg_multibnop_breaks(self): ) self.assertNoException(res) self.assertIn(r"will result in LAST-INSTRUCTION", res) - self.assertIn(r"b'\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe'", res) + self.assertIn(r"b'\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe'", res) @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_nop_arg_multibnop_breaks_force(self): res = gdb_start_silent_cmd( (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", - "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), after=( f"{self.cmd} --n --f", @@ -196,16 +196,16 @@ def test_cmd_nop_nop_arg_multibnop_breaks_force(self): ) self.assertNoException(res) self.assertIn(r"will result in LAST-INSTRUCTION", res) - self.assertIn(r"b'\x90\x91\x92\xfe\xeb\xfe\xeb\xfe'", res) + self.assertIn(r"b'\x90\x91\x92\xfe\xeb\xfe\xeb\xfe'", res) @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_bytes(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc, p16(0x9191))", + "pi gef.memory.write(gef.arch.pc, p16(0x9191))", after=( f"{self.cmd} --b", - "pi print(gef.memory.read(gef.arch.pc, 2))", + "pi print(gef.memory.read(gef.arch.pc, 2))", ) ) @@ -216,10 +216,10 @@ def test_cmd_nop_bytes(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_bytes_break_instruction(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", + "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", after=( f"{self.cmd} --b", - "pi print(gef.memory.read(gef.arch.pc, 2))", + "pi print(gef.memory.read(gef.arch.pc, 2))", ) ) @@ -231,10 +231,10 @@ def test_cmd_nop_bytes_break_instruction(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_bytes_break_instruction_force(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", + "pi gef.memory.write(gef.arch.pc, p16(0xfeeb))", after=( f"{self.cmd} --b --f", - "pi print(gef.memory.read(gef.arch.pc, 2))", + "pi print(gef.memory.read(gef.arch.pc, 2))", ) ) self.assertIn(r"will result in LAST-INSTRUCTION", res) @@ -245,10 +245,10 @@ def test_cmd_nop_bytes_break_instruction_force(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_bytes_arg(self): res = gdb_start_silent_cmd( - "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))", + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))", after=( f"{self.cmd} --i 2 --b --f", - "pi print(gef.memory.read(gef.arch.pc, 8))", + "pi print(gef.memory.read(gef.arch.pc, 8))", ) ) self.assertIn(r"b'\x90\x90\xeb\xfe\xeb\xfe\xeb\xfe'", res) @@ -259,11 +259,11 @@ def test_cmd_nop_bytes_arg(self): def test_cmd_nop_bytes_arg_nops_no_fit(self): res = gdb_start_silent_cmd( (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", - "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), after=( f"{self.cmd} --i 4 --b", - "pi print(gef.memory.read(gef.arch.pc, 8))", + "pi print(gef.memory.read(gef.arch.pc, 8))", ) ) self.assertIn(r"b'\xeb\xfe\xeb\xfe\xeb\xfe\xeb\xfe'", res) @@ -274,12 +274,12 @@ def test_cmd_nop_bytes_arg_nops_no_fit(self): @pytest.mark.skipif(ARCH not in ("i686", "x86_64"), reason=f"Skipped for {ARCH}") def test_cmd_nop_bytes_arg_nops_no_fit_force(self): res = gdb_start_silent_cmd( - (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", - "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), + (r"pi gef.arch.nop_insn=b'\x90\x91\x92'", + "pi gef.memory.write(gef.arch.pc, p64(0xfeebfeebfeebfeeb))"), after=( f"{self.cmd} --i 5 --b --f", - "pi print(gef.memory.read(gef.arch.pc, 8))", + "pi print(gef.memory.read(gef.arch.pc, 8))", ) ) self.assertIn(r"b'\x90\x91\x92\x90\x91\xfe\xeb\xfe'", res) From 27a29d9685bf243b393af0c6b3af85f1b1041221 Mon Sep 17 00:00:00 2001 From: Grazfather Date: Sun, 30 Jul 2023 11:47:32 -0400 Subject: [PATCH 17/21] Reformat README (#976) --- README.md | 56 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 4fee76a4e..7985bd718 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,17 @@ Try GEF

-`GEF` (pronounced ʤɛf - "Jeff") is a set of commands for x86/64, ARM, MIPS, PowerPC and SPARC to assist exploit developers and reverse-engineers when using old school GDB. It provides additional features to GDB using the Python API to assist during the process of dynamic analysis and exploit development. Application developers will also benefit from it, as GEF lifts a great part of regular GDB obscurity, avoiding repeating traditional commands, or bringing out the relevant information from the debugging runtime. - - +`GEF` (pronounced ʤɛf - "Jeff") is a set of commands for x86/64, ARM, MIPS, PowerPC and SPARC to +assist exploit developers and reverse-engineers when using old school GDB. It provides additional +features to GDB using the Python API to assist during the process of dynamic analysis and exploit +development. Application developers will also benefit from it, as GEF lifts a great part of regular +GDB obscurity, avoiding repeating traditional commands, or bringing out the relevant information +from the debugging runtime. ## Instant Setup ## -Simply make sure you have [GDB 8.0 or higher](https://www.gnu.org/s/gdb) compiled with Python3.6+ bindings, then: +Simply make sure you have [GDB 8.0 or higher](https://www.gnu.org/s/gdb) compiled with Python3.6+ +bindings, then: ```bash @@ -34,7 +38,8 @@ $ gdb -q (gdb) pi import urllib.request as u, tempfile as t; g=t.NamedTemporaryFile(suffix='-gef.py'); open(g.name, 'wb+').write(u.urlopen('https://tinyurl.com/gef-main').read()); gdb.execute('source %s' % g.name) ``` -_Note_: to fetch the latest of GEF (i.e. from the `dev` branch), simply replace in the URL to https://gef.blah.cat/dev. +_Note_: to fetch the latest of GEF (i.e. from the `dev` branch), simply replace in the URL to +https://gef.blah.cat/dev. You can immediately see that GEF is correctly installed by launching GDB: @@ -42,21 +47,32 @@ You can immediately see that GEF is correctly installed by launching GDB: A few of `GEF` features include: - * **One** single GDB script - * Entirely **architecture agnostic**, **NO** dependencies: `GEF` is battery-included and [is installable instantly](https://hugsy.github.io/gef/#setup) - * **Fast** limiting the number of dependencies and optimizing code to make the commands as fast as possible - * Provides a great variety of commands to drastically change your experience in GDB. - * [**Easily** extensible](https://hugsy.github.io/gef/api/) to create other commands by providing more comprehensible layout to GDB Python API. - * Full Python3 support ([Python2 support was dropped](https://github.com/hugsy/gef/releases/tag/2020.03) - see [`gef-legacy`](https://github.com/hugsy/gef-legacy)). - * Built around an architecture abstraction layer, so all commands work in any GDB-supported architecture such as x86-32/64, ARMv5/6/7, AARCH64, SPARC, MIPS, PowerPC, etc. - * Suited for real-life apps debugging, exploit development, just as much as CTF - -Check out the [Screenshot page](docs/screenshots.md) for more or [try it online](https://demo.gef.blah.cat) (user:`gef`/password:`gef-demo`) +* **One** single GDB script +* Entirely **architecture agnostic**, **NO** dependencies: `GEF` is battery-included and [is + installable instantly](https://hugsy.github.io/gef/#setup) +* **Fast** limiting the number of dependencies and optimizing code to make the commands as fast as + possible +* Provides a great variety of commands to drastically change your experience in GDB. +* [**Easily** extensible](https://hugsy.github.io/gef/api/) to create other commands by providing +d more comprehensible layout to GDB Python API. +* Full Python3 support ([Python2 support was + dropped](https://github.com/hugsy/gef/releases/tag/2020.03) - see + [`gef-legacy`](https://github.com/hugsy/gef-legacy)). +* Built around an architecture abstraction layer, so all commands work in any GDB-supported + architecture such as x86-32/64, ARMv5/6/7, AARCH64, SPARC, MIPS, PowerPC, etc. +* Suited for real-life apps debugging, exploit development, just as much as CTF + +Check out the [Screenshot page](docs/screenshots.md) for more or [try it +online](https://demo.gef.blah.cat) (user:`gef`/password:`gef-demo`) ## Documentation ## -Unlike other GDB plugins, GEF has an extensive and up-to-date [documentation](https://hugsy.github.io/gef/). Users are recommended to refer to it as it may help them in their attempts to use GEF. In particular, new users should navigate through it (see the [FAQ](https://hugsy.github.io/gef/faq/) for common installation problems), and the problem persists, try to reach out for help on the Discord channel or submit an issue. +Unlike other GDB plugins, GEF has an extensive and up-to-date +[documentation](https://hugsy.github.io/gef/). Users are recommended to refer to it as it may help +them in their attempts to use GEF. In particular, new users should navigate through it (see the +[FAQ](https://hugsy.github.io/gef/faq/) for common installation problems), and the problem persists, +try to reach out for help on the Discord channel or submit an issue. ## Current status ## @@ -68,11 +84,15 @@ Unlike other GDB plugins, GEF has an extensive and up-to-date [documentation](ht ## Contribute ## -To get involved, refer to the [Contribution documentation](https://hugsy.github.io/gef/#contribution) and the [guidelines](https://github.com/hugsy/gef/blob/dev/.github/CONTRIBUTING.md) to start. +To get involved, refer to the [Contribution +documentation](https://hugsy.github.io/gef/#contribution) and the +[guidelines](https://github.com/hugsy/gef/blob/dev/.github/CONTRIBUTING.md) to start. ## Sponsors ## -Another way to contribute to keeping the project alive is by sponsoring it! Check out [the sponsoring documentation](https://hugsy.github.io/gef/#sponsors) for details so you can be part of the list of those [awesome sponsors](https://github.com/sponsors/hugsy). +Another way to contribute to keeping the project alive is by sponsoring it! Check out [the +sponsoring documentation](https://hugsy.github.io/gef/#sponsors) for details so you can be part of +the list of those [awesome sponsors](https://github.com/sponsors/hugsy). ## Happy Hacking 🍻 ## From b57e174deb79ebac7914be75c886974409a7b9ef Mon Sep 17 00:00:00 2001 From: crazy hugsy Date: Mon, 31 Jul 2023 20:09:52 -0700 Subject: [PATCH 18/21] Minor additions to the documentation (#975) * added more references to gef-extras * adding a note about required common bins (issue #973) * applied `markdownlint` * manual markdownl formatting --- README.md | 2 ++ docs/index.md | 1 + docs/install.md | 8 ++++++++ mkdocs.yml | 3 ++- 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7985bd718..e8d014228 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,8 @@ d more comprehensible layout to GDB Python API. * Built around an architecture abstraction layer, so all commands work in any GDB-supported architecture such as x86-32/64, ARMv5/6/7, AARCH64, SPARC, MIPS, PowerPC, etc. * Suited for real-life apps debugging, exploit development, just as much as CTF +* And a lot more commands contributed by the community available on + [GEF-Extras](https://github.com/hugsy/gef-extras) !! Check out the [Screenshot page](docs/screenshots.md) for more or [try it online](https://demo.gef.blah.cat) (user:`gef`/password:`gef-demo`) diff --git a/docs/index.md b/docs/index.md index f063bd161..6785805e5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -29,6 +29,7 @@ It requires Python 3, but [`gef-legacy`](https://github.com/hugsy/gef-legacy) ca * Built around an architecture abstraction layer, so all commands work in any GDB-supported architecture such as x86-32/64, ARMv5/6/7, AARCH64, SPARC, MIPS, PowerPC, etc. * Suited for real-life debugging, exploit development, just as much as for CTFs +* And a lot more commands contributed by the community available on [GEF-Extras](https://github.com/hugsy/gef-extras) !! Check out the [showroom page](https://hugsy.github.io/gef/screenshots/) for more | or [try it online yourself!](https://demo.gef.blah.cat) (user:`gef`/password:`gef-demo`) diff --git a/docs/install.md b/docs/install.md index eac4d8fad..37937b051 100644 --- a/docs/install.md +++ b/docs/install.md @@ -2,6 +2,14 @@ ## Prerequisites +Specific GEF commands rely on commonly used Unix commands to extract additional information. Therefore it requires the following binaries to be present: + * `file` + * `readelf` + * `ps` + * `python3` + +Those tools are included by default in many modern distributions. If they're missing, you can use your OS package manager to install them. + ### GDB Only [GDB 8 and higher](https://www.gnu.org/s/gdb) is required. It must be compiled with Python 3.6 diff --git a/mkdocs.yml b/mkdocs.yml index 140f56a64..5e209372f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -11,7 +11,6 @@ theme: nav: - Home: index.md -- Coverage: https://hugsy.github.io/gef/coverage/ - Showroom: screenshots.md - Setup: - Installation: install.md @@ -22,6 +21,7 @@ nav: - Testing: testing.md - Write extensions: api.md - API: api/gef.md + - Coverage: https://hugsy.github.io/gef/coverage/ - Commands: - aliases: commands/aliases.md - aslr: commands/aslr.md @@ -76,4 +76,5 @@ nav: - got: functions/got.md - heap: functions/heap.md - stack: functions/stack.md +- GEF-Extras: https://hugsy.github.io/gef-extras/ - Deprecated: deprecated.md From 5e237393629d861def1809b4bcbe4302ab31b726 Mon Sep 17 00:00:00 2001 From: crazy hugsy Date: Tue, 1 Aug 2023 20:14:57 -0700 Subject: [PATCH 19/21] [Docs] Added linting for markdown files (#977) * adding a note about required common bins (issue #973) * added markdownlint policy * applied markdownlint * customized mdlint config --- .editorconfig | 2 +- docs/.markdownlint.yaml | 259 ++++++++++++++++++++++++++ docs/api.md | 34 ++-- docs/commands/aslr.md | 3 + docs/commands/canary.md | 1 + docs/commands/checksec.md | 3 +- docs/commands/config.md | 6 + docs/commands/context.md | 19 +- docs/commands/dereference.md | 3 +- docs/commands/edit-flags.md | 3 + docs/commands/format-string-helper.md | 2 +- docs/commands/functions.md | 6 +- docs/commands/gef-remote.md | 6 +- docs/commands/gef.md | 4 +- docs/commands/got.md | 3 + docs/commands/heap-analysis-helper.md | 8 +- docs/commands/heap.md | 1 - docs/commands/highlight.md | 1 - docs/commands/hijack-fd.md | 8 +- docs/commands/memory.md | 8 +- docs/commands/name-break.md | 2 +- docs/commands/nop.md | 21 ++- docs/commands/pcustom.md | 31 +-- docs/commands/print-format.md | 1 - docs/commands/process-search.md | 2 +- docs/commands/reset-cache.md | 2 +- docs/commands/search-pattern.md | 3 + docs/commands/shellcode.md | 1 - docs/commands/skipi.md | 10 +- docs/commands/trace-run.md | 1 - docs/commands/xor-memory.md | 1 + docs/compat.md | 2 - docs/faq.md | 19 +- docs/functions/base.md | 1 + docs/functions/bss.md | 1 + docs/functions/got.md | 1 + docs/functions/heap.md | 1 + docs/functions/stack.md | 1 + docs/index.md | 13 +- docs/install.md | 30 +-- docs/obsolete/docs/index.md | 1 - docs/testing.md | 2 - 42 files changed, 410 insertions(+), 117 deletions(-) create mode 100644 docs/.markdownlint.yaml diff --git a/.editorconfig b/.editorconfig index afce7e399..be8ec9af6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -21,4 +21,4 @@ indent_style = space indent_size = 2 [*.md] -max_line_length=100 +max_line_length = 100 diff --git a/docs/.markdownlint.yaml b/docs/.markdownlint.yaml new file mode 100644 index 000000000..8e74f3862 --- /dev/null +++ b/docs/.markdownlint.yaml @@ -0,0 +1,259 @@ +# Default state for all rules +default: true + +# Path to configuration file to extend +extends: null + +# MD001/heading-increment/header-increment - Heading levels should only increment by one level at a time +MD001: true + +# MD002/first-heading-h1/first-header-h1 - First heading should be a top-level heading +MD002: + # Heading level + level: 1 + +# MD003/heading-style/header-style - Heading style +MD003: + # Heading style + style: "consistent" + +# MD004/ul-style - Unordered list style +MD004: + # List style + style: "consistent" + +# MD005/list-indent - Inconsistent indentation for list items at the same level +MD005: true + +# MD006/ul-start-left - Consider starting bulleted lists at the beginning of the line +MD006: true + +# MD007/ul-indent - Unordered list indentation +MD007: + # Spaces for indent + indent: 2 + # Whether to indent the first level of the list + start_indented: false + # Spaces for first level indent (when start_indented is set) + start_indent: 2 + +# MD009/no-trailing-spaces - Trailing spaces +MD009: + # Spaces for line break + br_spaces: 2 + # Allow spaces for empty lines in list items + list_item_empty_lines: false + # Include unnecessary breaks + strict: false + +# MD010/no-hard-tabs - Hard tabs +MD010: + # Include code blocks + code_blocks: false + # Fenced code languages to ignore + ignore_code_languages: [] + # Number of spaces for each hard tab + spaces_per_tab: 4 + +# MD011/no-reversed-links - Reversed link syntax +MD011: true + +# MD012/no-multiple-blanks - Multiple consecutive blank lines +MD012: + # Consecutive blank lines + maximum: 2 + +# MD013/line-length - Line length +MD013: + # Number of characters + line_length: 100 + # Number of characters for headings + heading_line_length: 100 + # Number of characters for code blocks + code_block_line_length: 100 + # Include code blocks + code_blocks: false + # Include tables + tables: false + # Include headings + headings: true + # Include headings + headers: true + # Strict length checking + strict: false + # Stern length checking + stern: false + +# MD014/commands-show-output - Dollar signs used before commands without showing output +MD014: true + +# MD018/no-missing-space-atx - No space after hash on atx style heading +MD018: true + +# MD019/no-multiple-space-atx - Multiple spaces after hash on atx style heading +MD019: true + +# MD020/no-missing-space-closed-atx - No space inside hashes on closed atx style heading +MD020: true + +# MD021/no-multiple-space-closed-atx - Multiple spaces inside hashes on closed atx style heading +MD021: true + +# MD022/blanks-around-headings/blanks-around-headers - Headings should be surrounded by blank lines +MD022: + # Blank lines above heading + lines_above: 1 + # Blank lines below heading + lines_below: 1 + +# MD023/heading-start-left/header-start-left - Headings must start at the beginning of the line +MD023: true + +# MD024/no-duplicate-heading/no-duplicate-header - Multiple headings with the same content +MD024: + # Only check sibling headings + allow_different_nesting: false + # Only check sibling headings + siblings_only: false + +# MD025/single-title/single-h1 - Multiple top-level headings in the same document +MD025: + # Heading level + level: 1 + # RegExp for matching title in front matter + front_matter_title: "^\\s*title\\s*[:=]" + +# MD026/no-trailing-punctuation - Trailing punctuation in heading +MD026: + # Punctuation characters not allowed at end of headings + punctuation: ".,;:!。,;:!" + +# MD027/no-multiple-space-blockquote - Multiple spaces after blockquote symbol +MD027: true + +# MD028/no-blanks-blockquote - Blank line inside blockquote +MD028: true + +# MD029/ol-prefix - Ordered list item prefix +MD029: + # List style + style: "one_or_ordered" + +# MD030/list-marker-space - Spaces after list markers +MD030: + # Spaces for single-line unordered list items + ul_single: 2 + # Spaces for single-line ordered list items + ol_single: 2 + # Spaces for multi-line unordered list items + ul_multi: 2 + # Spaces for multi-line ordered list items + ol_multi: 2 + +# MD031/blanks-around-fences - Fenced code blocks should be surrounded by blank lines +MD031: + # Include list items + list_items: true + +# MD032/blanks-around-lists - Lists should be surrounded by blank lines +MD032: true + +# MD033/no-inline-html - Inline HTML +MD033: + # Allowed elements + allowed_elements: [] + +# MD034/no-bare-urls - Bare URL used +MD034: true + +# MD035/hr-style - Horizontal rule style +MD035: + # Horizontal rule style + style: "consistent" + +# MD036/no-emphasis-as-heading/no-emphasis-as-header - Emphasis used instead of a heading +MD036: + # Punctuation characters + punctuation: ".,;:!?。,;:!?" + +# MD037/no-space-in-emphasis - Spaces inside emphasis markers +MD037: true + +# MD038/no-space-in-code - Spaces inside code span elements +MD038: true + +# MD039/no-space-in-links - Spaces inside link text +MD039: true + +# MD040/fenced-code-language - Fenced code blocks should have a language specified +MD040: + # List of languages + allowed_languages: [] + # Require language only + language_only: false + +# MD041/first-line-heading/first-line-h1 - First line in a file should be a top-level heading +MD041: + # Heading level + level: 1 + # RegExp for matching title in front matter + front_matter_title: "^\\s*title\\s*[:=]" + +# MD042/no-empty-links - No empty links +MD042: true + +# MD043/required-headings/required-headers - Required heading structure +MD043: + # List of headings + headings: [] + # List of headings + headers: [] + # Match case of headings + match_case: false + +# MD044/proper-names - Proper names should have the correct capitalization +MD044: + # List of proper names + names: [] + # Include code blocks + code_blocks: false + # Include HTML elements + html_elements: false + +# MD045/no-alt-text - Images should have alternate text (alt text) +MD045: true + +# MD046/code-block-style - Code block style +MD046: + # Block style + style: "consistent" + +# MD047/single-trailing-newline - Files should end with a single newline character +MD047: true + +# MD048/code-fence-style - Code fence style +MD048: + # Code fence style + style: "consistent" + +# MD049/emphasis-style - Emphasis style should be consistent +MD049: + # Emphasis style should be consistent + style: "consistent" + +# MD050/strong-style - Strong style should be consistent +MD050: + # Strong style should be consistent + style: "consistent" + +# MD051/link-fragments - Link fragments should be valid +MD051: true + +# MD052/reference-links-images - Reference links and images should use a label that is defined +MD052: true + +# MD053/link-image-reference-definitions - Link and image reference definitions should be needed +MD053: + # Ignored definitions + ignored_definitions: + - "//" diff --git a/docs/api.md b/docs/api.md index 3b23b4500..34dfc1353 100644 --- a/docs/api.md +++ b/docs/api.md @@ -33,6 +33,7 @@ register_external_command(NewCommand()) ``` Loading it in `GEF` is as easy as + ``` gef➤ source /path/to/newcmd.py [+] Loading 'NewCommand' @@ -61,15 +62,17 @@ We make GEF aware of this new command by registering it in the `__main__` sectio invoking the global function `register_external_command()`. Now you have a new GEF command which you can load, either from cli: + ```bash gef➤ source /path/to/newcmd.py ``` + or add to your `~/.gdbinit`: + ```bash -$ echo source /path/to/newcmd.py >> ~/.gdbinit +echo source /path/to/newcmd.py >> ~/.gdbinit ``` - ## Customizing context panes Sometimes you want something similar to a command to run on each break-like event and display itself @@ -119,20 +122,22 @@ gef➤ pi help(Architecture) or even from outside GDB: ```bash -$ gdb -q -ex 'pi help(hexdump)' -ex quit +gdb -q -ex 'pi help(hexdump)' -ex quit ``` The GEF API aims to provide a simpler and more Pythonic approach to GDB's. Some basic examples: -- read the memory -```python +* read the memory + +```text gef ➤ pi print(hexdump( gef.memory.read(parse_address("$pc"), length=0x20 ))) 0x0000000000000000 f3 0f 1e fa 31 ed 49 89 d1 5e 48 89 e2 48 83 e4 ....1.I..^H..H.. 0x0000000000000010 f0 50 54 4c 8d 05 66 0d 01 00 48 8d 0d ef 0c 01 .PTL..f...H..... ``` -- get access to the memory layout +* get access to the memory layout + ``` gef ➤ pi print('\n'.join([ f"{x.page_start:#x} -> {x.page_end:#x}" for x in gef.memory.maps])) 0x555555554000 -> 0x555555558000 @@ -148,18 +153,15 @@ gef ➤ pi print('\n'.join([ f"{x.page_start:#x} -> {x.page_end:#x}" for x in ge [...] ``` - The API also offers a number of decorators to simplify the creation of new/existing commands, such as: -- `@only_if_gdb_running` to execute only if a GDB session is running. -- `@only_if_gdb_target_local` to check if the target is local i.e. not debugging using GDB `remote`. -- and many more... - +* `@only_if_gdb_running` to execute only if a GDB session is running. +* `@only_if_gdb_target_local` to check if the target is local i.e. not debugging using GDB `remote`. +* and many more... ### Reference For a complete reference of the API offered by GEF, visit [`docs/api/gef.md`](api/gef.md). - ### Parsing command arguments ```python @@ -179,12 +181,10 @@ using a type of `tuple` or `list` for the default value. `parse_arguments` will of what to expect based on the first default value of the iterable, so make sure it's not empty. For instance: - ```python @parse_arguments( {"instructions": ["nop", "int3", "hlt"], }, {"--arch": "x64", } ) ``` - Argument flags are also supported, allowing to write simpler version of the flag such as ```python @@ -227,11 +227,11 @@ Sometimes architectures can more precisely determine whether they apply to the c looking at the architecture determined by gdb. For these cases the custom architecture may implement the `supports_gdb_arch()` static function to signal that they should be used instead of the default. The function receives only one argument: -- `gdb_str` (of type `str`) which is the architecture name as reported by GDB. +* `gdb_str` (of type `str`) which is the architecture name as reported by GDB. The function **must** return: -- `True` if the current `Architecture` class supports the target binary; `False` otherwise. -- `None` to simply ignore this check and let GEF try to determine the architecture. +* `True` if the current `Architecture` class supports the target binary; `False` otherwise. +* `None` to simply ignore this check and let GEF try to determine the architecture. One example is the ARM Cortex-M architecture which in some cases should be used over the generic ARM one: diff --git a/docs/commands/aslr.md b/docs/commands/aslr.md index 54e4c9e5c..3fc3fa7bf 100644 --- a/docs/commands/aslr.md +++ b/docs/commands/aslr.md @@ -3,12 +3,14 @@ Easily check, enable or disable ASLR on the debugged binary. Check the status: + ``` gef➤ aslr ASLR is currently disabled ``` Activate ASLR: + ``` gef➤ aslr on [+] Enabling ASLR @@ -17,6 +19,7 @@ ASLR is currently enabled ``` De-activate ASLR: + ``` gef➤ aslr off [+] Disabling ASLR diff --git a/docs/commands/canary.md b/docs/commands/canary.md index 9bbbd2755..c190d5205 100644 --- a/docs/commands/canary.md +++ b/docs/commands/canary.md @@ -5,6 +5,7 @@ If the currently debugged process was compiled with the Smash Stack Protector (S canary. This makes it convenient to avoid manually searching for this value in memory. The command `canary` does not take any arguments. + ``` gef➤ canary ``` diff --git a/docs/commands/checksec.md b/docs/commands/checksec.md index a1aa97a9c..1fa14714f 100644 --- a/docs/commands/checksec.md +++ b/docs/commands/checksec.md @@ -4,6 +4,7 @@ The `checksec` command is inspired from [`checksec.sh`](https://www.trapkit.de/t It provides a convenient way to determine which security protections are enabled in a binary. You can use the command on the currently debugged process: + ``` gef➤ checksec [+] checksec for '/vagrant/test-bin' @@ -19,5 +20,5 @@ Full RelRO: No Or specify directly the binary to check, for example: ```bash -$ gdb -ex "checksec ./tests/test-x86" +gdb -ex "checksec ./tests/test-x86" ``` diff --git a/docs/commands/config.md b/docs/commands/config.md index b10cf8670..ba2a15c65 100644 --- a/docs/commands/config.md +++ b/docs/commands/config.md @@ -5,24 +5,29 @@ specified via the `GEF_RC` environment variable. In addition, `gef` can also be runtime with the `gef config` command. To view all settings for all commands loaded: + ``` gef➤ gef config ``` + ![gef-config](https://i.imgur.com/bd2ZqsU.png) Or to get one setting value: + ``` gef➤ gef config pcustom.struct_path ``` Of course you can edit the values. For example, if you want the screen to be cleared before displaying the current context when reaching a breakpoing: + ``` gef➤ gef config context.clear_screen 1 ``` To save the current settings for `GEF` to the file system to have those options persist across all your future `GEF` sessions, simply run: + ``` gef➤ gef save [+] Configuration saved to '/home/vagrant/.gef.rc' @@ -32,6 +37,7 @@ Upon startup, if `$GEF_RC` points to an existing file, or otherwise if `${HOME}/ `gef` will automatically load its values. To reload the settings during the session, just run: + ``` gef➤ gef restore [+] Configuration from '/home/hugsy/.gef.rc' restored diff --git a/docs/commands/context.md b/docs/commands/context.md index 7c08eac05..ea3e047cc 100644 --- a/docs/commands/context.md +++ b/docs/commands/context.md @@ -2,7 +2,6 @@ ![gef-context](https://i.imgur.com/aZiG8Yb.png) - `gef` (not unlike `PEDA` or `fG! famous gdbinit`) provides comprehensive context menu when hitting a breakpoint. @@ -54,6 +53,7 @@ just omit it. ``` gef➤ gef config context.layout "-legend regs stack code args -source -threads -trace extra memory" ``` + This configuration will not display the `legend`, `source`, `threads`, and `trace` sections. The `memory` pane will display the content of all locations specified by the @@ -80,12 +80,14 @@ The size of most sections are also customizable: To have the stack displayed with the largest stack addresses on top (i.e., grow the stack downward), enable the following setting: + ``` gef➤ gef config context.grow_stack_down True ``` If the saved instruction pointer is not within the portion of the stack being displayed, then a section is created that includes the saved ip and depending on the architecture the frame pointer. + ``` 0x00007fffffffc9e8│+0x00: 0x00007ffff7a2d830 → <__main+240> mov edi, eax ($current_frame_savedip) 0x00007fffffffc9e0│+0x00: 0x00000000004008c0 → <__init+0> push r15 ← $rbp @@ -108,12 +110,14 @@ setting `context.redirect` variable to have the context sent to another section. To do so, select the TTY/file/socket/etc. you want the context redirected to with `gef config`. Enter the command `tty` in the prompt: + ``` $ tty /dev/pts/0 ``` Then tell `gef` about it! + ``` gef➤ gef config context.redirect /dev/pts/0 ``` @@ -121,8 +125,8 @@ gef➤ gef config context.redirect /dev/pts/0 Enjoy: ![gef-context-redirect-section](https://i.imgur.com/sWlX37q.png) - To go back to normal, remove the value: + ``` gef➤ gef config context.redirect "" ``` @@ -130,11 +134,13 @@ gef➤ gef config context.redirect "" ### Display individual sections ### You can display a single section by specifying it as an argument: + ``` gef➤ context regs ``` Multiple sections can be provided, even if they are not part of the current layout: + ``` gef➤ context regs stack ``` @@ -142,46 +148,55 @@ gef➤ context regs stack ### Examples ### * Display the code section first, then register, and stack, hiding everything else: + ``` gef➤ gef config context.layout "code regs stack" ``` * Stop showing the context sections when breaking: + ``` gef➤ gef config context.enable 0 ``` * Clear the screen before showing the context sections when breaking: + ``` gef➤ gef config context.clear_screen 1 ``` * Don't dereference the registers in the `regs` section (more compact): + ``` gef➤ gef config context.show_registers_raw 1 ``` * Number of bytes of opcodes to display next to the disassembly. + ``` gef➤ gef config context.show_opcodes_size 4 ``` * Don't 'peek' into the start of functions that are called. + ``` gef➤ gef config context.peek_calls False ``` * Hide specific registers from the registers view. + ``` gef➤ gef config context.ignore_registers "$cs $ds $gs" ``` * Hide the extra pc context info from the source code view. + ``` gef➤ gef config context.show_source_code_variable_values 0 ``` * Show better definitions for call to libc functions. + ``` gef➤ gef config context.libc_args True gef➤ gef config context.libc_args_path /path/to/gef-extras/libc_args diff --git a/docs/commands/dereference.md b/docs/commands/dereference.md index 69e528cc8..bc815f158 100644 --- a/docs/commands/dereference.md +++ b/docs/commands/dereference.md @@ -12,7 +12,7 @@ dereference (by default, `$sp`), the number of consecutive addresses to derefere ``` gef➤ dereference -0x00007fffffffdec0│+0x0000: 0x00007ffff7ffe190 → 0x0000555555554000 → jg 0x555555554047 ← $rsp, $r13 +0x00007fffffffdec0│+0x0000: 0x00007ffff7ffe190 → 0x0000555555554000 → jg 0x555555554047 ← $rsp, $r13 0x00007fffffffdec8│+0x0008: 0x00007ffff7ffe730 → 0x00007ffff7fd3000 → 0x00010102464c457f 0x00007fffffffded0│+0x0010: 0x00007ffff7faa000 → 0x00007ffff7de9000 → 0x03010102464c457f 0x00007fffffffded8│+0x0018: 0x00007ffff7ffd9f0 → 0x00007ffff7fd5000 → 0x00010102464c457f @@ -70,6 +70,7 @@ gef➤ dereference $sp -l 7 -r $rbp Just like with `x`, you can pass a negative number of addresses to dereference, to examine memory backwards from the start address: + ``` gef➤ dereference $sp -l 3 0x00007fffffffcf90│+0x0010: 0x00007ffff7f5aaa0 → 0x0000000000000000 diff --git a/docs/commands/edit-flags.md b/docs/commands/edit-flags.md index e507cc0b1..70d3faec2 100644 --- a/docs/commands/edit-flags.md +++ b/docs/commands/edit-flags.md @@ -5,9 +5,11 @@ the flag register for the architectures that support it. Without argument, the c return a human-friendly display of the register flags. One or many arguments can be provided, following the syntax below: + ``` gef➤ flags [(+|-|~)FLAGNAME ...] ``` + Where `FLAGNAME` is the name of the flag (case insensitive), and `+|-|~` indicates the action on whether to set, unset, or toggle the flag. @@ -17,4 +19,5 @@ instruction), but we want to have the Carry flag set, simply go with: ``` gef➤ flags -ZERO +CARRY ``` + ![flags](https://i.imgur.com/ro7iC5m.png) diff --git a/docs/commands/format-string-helper.md b/docs/commands/format-string-helper.md index 17d7164e5..a23df368a 100644 --- a/docs/commands/format-string-helper.md +++ b/docs/commands/format-string-helper.md @@ -20,6 +20,7 @@ gef➤ fmtstr-helper ``` Then start the binary execution. + ``` gef➤ r ``` @@ -28,4 +29,3 @@ If a potentially insecure entry is found, the breakpoint will trigger, stop the display the reason for trigger and the associated context. ![fmtstr-helper-example](https://i.imgur.com/INU3KGn.png) - diff --git a/docs/commands/functions.md b/docs/commands/functions.md index c13562436..2d367262f 100644 --- a/docs/commands/functions.md +++ b/docs/commands/functions.md @@ -14,12 +14,12 @@ These functions can be used as arguments to other commands to dynamically calcul ``` gef➤ deref -l 4 $_heap() -0x0000000000602000│+0x00: 0x0000000000000000 ← $r8 +0x0000000000602000│+0x00: 0x0000000000000000 ← $r8 0x0000000000602008│+0x08: 0x0000000000000021 ("!"?) -0x0000000000602010│+0x10: 0x0000000000000000 ← $rax, $rdx +0x0000000000602010│+0x10: 0x0000000000000000 ← $rax, $rdx 0x0000000000602018│+0x18: 0x0000000000000000 gef➤ deref -l 4 $_heap(0x20) -0x0000000000602020│+0x00: 0x0000000000000000 ← $rsi +0x0000000000602020│+0x00: 0x0000000000000000 ← $rsi 0x0000000000602028│+0x08: 0x0000000000020fe1 0x0000000000602030│+0x10: 0x0000000000000000 0x0000000000602038│+0x18: 0x0000000000000000 diff --git a/docs/commands/gef-remote.md b/docs/commands/gef-remote.md index 756cf8d68..7a5615c5e 100644 --- a/docs/commands/gef-remote.md +++ b/docs/commands/gef-remote.md @@ -10,6 +10,7 @@ process of debugging more cumbersome. GEF greatly improves that state with the ` `target remote` command. For many reasons, you **cannot** use `target remote` alone with GEF. `gef-remote` can function in 2 ways: + - `remote` which is meant to enrich use of GDB `target remote` command, when connecting to a "real" gdbserver instance - `qemu-mode` when connecting to GDB stab of either `qemu-user` or `qemu-system`. @@ -79,14 +80,12 @@ that, all of GEF features are available: ![gef-remote-command](https://i.imgur.com/05epyX6.png) - #### `remote-extended` Extended mode works the same as `remote`. Being an extended session, gdbserver has not spawned or attached to any process. Therefore, all that's required is to add the `--pid` flag when calling `gef-remote`, along with the process ID of the process to debug. - ### Qemu mode Qemu mode of `gef-remote` allows to connect to the [Qemu GDB @@ -101,13 +100,12 @@ makes now even more sense 😉 And using it is very straight forward. ![qemu-user](https://user-images.githubusercontent.com/590234/175072835-e276ab6c-4f75-4313-9e66-9fe5a3fd220e.png) - #### `qemu-system` To test locally, you can use the mini image linux x64 vm [here](https://mega.nz/file/ldQCDQiR#yJWJ8RXAHTxREKVmR7Hnfr70tIAQDFeWSYj96SvPO1k). + 1. Run `./run.sh` 2. Use `--qemu-user` and `--qemu-binary vmlinuz` when starting `gef-remote` - ![qemu-system](https://user-images.githubusercontent.com/590234/175071351-8e06aa27-dc61-4fd7-9215-c345dcebcd67.png) diff --git a/docs/commands/gef.md b/docs/commands/gef.md index 5f687786d..6d781c11d 100644 --- a/docs/commands/gef.md +++ b/docs/commands/gef.md @@ -29,7 +29,6 @@ gef➤ gef missing [*] Command `XXXX` is missing, reason → YYYYY. ``` - ### GEF Config Command Allows the user to set/view settings for the current debugging session. For making the changes @@ -111,7 +110,6 @@ within the command. gef➤ gef run ./binary ``` - ### GEF Install Command `gef install` allows to install one (or more) specific script(s) from `gef-extras`. The new scripts @@ -124,7 +122,6 @@ gef➤ gef install SCRIPTNAME1 [SCRIPTNAME2...] Where `SCRIPTNAME1` ... are the names of script from the [`gef-extras` repository](https://github.com/hugsy/gef-extras/tree/main/scripts/). - ``` gef➤ gef install remote windbg stack [+] Searching for 'remote.py' in `gef-extras@main`... @@ -139,6 +136,7 @@ gef➤ This makes it easier to deploy new functionalities in limited environment. By default, the command looks up for script names in the `main` branch of `gef-extras`. However you can change specify a different branch through the `gef.default_branch` configuration setting: + ``` gef➤ gef config gef.default_branch dev ``` diff --git a/docs/commands/got.md b/docs/commands/got.md index 25b129a84..746784a52 100644 --- a/docs/commands/got.md +++ b/docs/commands/got.md @@ -4,6 +4,7 @@ Display the current state of GOT table of the running process. The `got` command optionally takes function names and filters the output displaying only the matching functions. + ``` gef➤ got ``` @@ -11,6 +12,7 @@ gef➤ got ![gef-got](https://i.imgur.com/554ebM3.png) The applied filter partially matches the name of the functions, so you can do something like this. + ``` gef➤ got str gef➤ got print @@ -20,6 +22,7 @@ gef➤ got read ![gef-got-one-filter](https://i.imgur.com/IU715CG.png) Example of multiple partial filters: + ``` gef➤ got str get ``` diff --git a/docs/commands/heap-analysis-helper.md b/docs/commands/heap-analysis-helper.md index 65a74fbd4..bf9bfd870 100644 --- a/docs/commands/heap-analysis-helper.md +++ b/docs/commands/heap-analysis-helper.md @@ -30,13 +30,13 @@ enable/disable manually punctual checks via the `gef config` command. The following settings are accepted: -* `check_null_free`: to break execution when a free(NULL) is encountered (disabled by default); -* `check_double_free`: to break execution when a double free is encountered; +- `check_null_free`: to break execution when a free(NULL) is encountered (disabled by default); +- `check_double_free`: to break execution when a double free is encountered; ![double-free](https://i.imgur.com/S7b4FJa.png) -* `check_weird_free`: to execution when `free()` is called against a non-tracked pointer; -* `check_uaf`: to break execution when a possible Use-after-Free condition is found. +- `check_weird_free`: to execution when `free()` is called against a non-tracked pointer; +- `check_uaf`: to break execution when a possible Use-after-Free condition is found. ![uaf](https://i.imgur.com/NfV5Cu9.png) diff --git a/docs/commands/heap.md b/docs/commands/heap.md index ab85fb6e0..e5447d4f7 100644 --- a/docs/commands/heap.md +++ b/docs/commands/heap.md @@ -30,7 +30,6 @@ gef➤ gef config gef.bruteforce_main_arena True Note that this might take a few seconds to complete. If GEF does find the symbol you can then calculate the offset to the libc base address and save it in the config. - ### `heap chunks` command ### Displays all the chunks from the `heap` section of the current arena. diff --git a/docs/commands/highlight.md b/docs/commands/highlight.md index 81b8989c0..bf45a848e 100644 --- a/docs/commands/highlight.md +++ b/docs/commands/highlight.md @@ -77,4 +77,3 @@ support._ ## Colors To find a list of supported colors, check the [theme](./theme.md#changing-colors) documentation. - diff --git a/docs/commands/hijack-fd.md b/docs/commands/hijack-fd.md index 7b4fd9222..0998e6135 100644 --- a/docs/commands/hijack-fd.md +++ b/docs/commands/hijack-fd.md @@ -4,27 +4,29 @@ file descriptor can point to a file, a pipe, a socket, a device etc. To use it, simply run + ``` gef➤ hijack-fd FDNUM NEWFILE ``` For instance, + ``` gef➤ hijack-fd 1 /dev/null ``` + Will modify the current process file descriptors to redirect STDOUT to `/dev/null`. - This command also supports connecting to an ip:port if it is provided as an argument. For example + ``` gef➤ hijack-fd 0 localhost:8888 ``` -Will redirect STDIN to localhost:8888 +Will redirect STDIN to localhost:8888 Check out the tutorial on GEF's YouTube channel: [![yt-tuto-hijack-fd](https://img.youtube.com/vi/Ss_QFeYkEvk/0.jpg)](https://www.youtube.com/watch?v=Ss_QFeYkEvk) - diff --git a/docs/commands/memory.md b/docs/commands/memory.md index 676065629..61a539cb9 100644 --- a/docs/commands/memory.md +++ b/docs/commands/memory.md @@ -9,12 +9,12 @@ _Note_: this command **shoud NOT** be mistaken with the [GDB `watch` command](https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Watchpoints.html) meant to set breakpoints on memory access (read,write,exec). - ### Adding a watch Specify a location to watch and display with the context, along with their optional size and format: Syntax: + ``` memory watch
[SIZE] [(qword|dword|word|byte|pointers)] ``` @@ -39,34 +39,34 @@ Which, when the `context` is displayed, will show something like: ![](https://i.imgur.com/3YabwYv.png) - ### Removing a watch Remove a watched address. To list all the addresses being watched, use `memory list`. Syntax: + ``` memory unwatch
``` - ### Listing watches Enumerate all the addresses currently watched by the `memory` command. Syntax: + ``` memory list ``` The command will output a list of all the addresses watched, along with the size and format to display them as. - ### Resetting watches Empties the list of addresses to watch. Syntax: + ``` memory reset ``` diff --git a/docs/commands/name-break.md b/docs/commands/name-break.md index c0c6175f4..9201f34f5 100644 --- a/docs/commands/name-break.md +++ b/docs/commands/name-break.md @@ -32,7 +32,7 @@ Example output: 0x400e18 mov QWORD PTR [rbp-0x50], rsi 0x400e1c mov rax, QWORD PTR fs:0x28 ───────────────────────────────────────────────────────────────────────────────── stack ──── -0x00007fffffffe288│+0x0000: 0x0000000000401117 → movzx ecx, al ← $rsp +0x00007fffffffe288│+0x0000: 0x0000000000401117 → movzx ecx, al ← $rsp 0x00007fffffffe290│+0x0008: 0x00007fffffffe4b8 → 0x00007fffffffe71d → "/ctf/t19/srv_copy" 0x00007fffffffe298│+0x0010: 0x0000000100000000 0x00007fffffffe2a0│+0x0018: 0x0000000000000000 diff --git a/docs/commands/nop.md b/docs/commands/nop.md index 7c3ab011b..74917d2af 100644 --- a/docs/commands/nop.md +++ b/docs/commands/nop.md @@ -18,36 +18,43 @@ instructions it overwrites `--b` Instead of replacing whole instructions, fill ITEMS bytes with nops nop the current instruction ($pc): + ```bash -gef➤ nop +gef➤ nop ``` nop an instruction at $pc+3 address: + ```bash -gef➤ nop $pc+3 +gef➤ nop $pc+3 ``` nop two instructions at address $pc+3: + ```bash -gef➤ nop --i 2 $pc+3 +gef➤ nop --i 2 $pc+3 ``` Replace 1 byte with nop at current instruction ($pc): + ```bash -gef➤ nop --b +gef➤ nop --b ``` Replace 1 byte with nop at address $pc+3: + ```bash -gef➤ nop --b $pc+3 +gef➤ nop --b $pc+3 ``` Replace 2 bytes with nop(s) (breaking the last instruction) at address $pc+3: + ```bash -gef➤ nop --f --b --i 2 $pc+3 +gef➤ nop --f --b --i 2 $pc+3 ``` Patch 2 nops at address $pc+3: + ```bash -gef➤ nop --n --i 2 $pc+3 +gef➤ nop --n --i 2 $pc+3 ``` diff --git a/docs/commands/pcustom.md b/docs/commands/pcustom.md index d7d3a4666..b2387ff32 100644 --- a/docs/commands/pcustom.md +++ b/docs/commands/pcustom.md @@ -9,30 +9,34 @@ This is achieved via the command `pcustom` (for `print custom`), or you can use reference to the WinDBG command) as provided by the [`WinDbg compatibility extension`](https://github.com/hugsy/gef-extras/blob/main/scripts/windbg.py) - ### Configuration New structures can be stored in the location given by the configuration setting: + ``` gef➤ gef config pcustom.struct_path ``` + By default, this location is in `$TEMP/gef/structs` (e.g. `/tmp/user/1000/gef/structs`). The structure can be created as a simple `ctypes` structure, in a file called `.py`. You can naturally set this path to a new location + ``` gef➤ gef config pcustom.struct_path /my/new/location ``` + And save this change so you can re-use it directly next time you use `gdb` + ``` gef➤ gef save [+] Configuration saved to '~/.gef.rc' ``` - ### Using user-defined structures You can list existing custom structures via + ``` gef➤ pcustom list [+] Listing custom structures from '/tmp/structs' @@ -82,14 +86,14 @@ class person_t(Structure): ] _values_ = [ - # You can define a function to substitute the value - ("age", lambda age: "Old" if age > 40 else "Young"), - # Or alternatively a list of 2-tuples - ("id", [ - (0, "root"), - (1, "normal user"), - (None, "Invalid person") - ]) + # You can define a function to substitute the value + ("age", lambda age: "Old" if age > 40 else "Young"), + # Or alternatively a list of 2-tuples + ("id", [ + (0, "root"), + (1, "normal user"), + (None, "Invalid person") + ]) ] ``` @@ -118,7 +122,6 @@ Additionally, if you have successfully configured your IDA settings, you can als the structure(s) that was(were) reverse-engineered in IDA directly in your GDB session: ![ida-structure-examples](https://i.imgur.com/Tnsf6nt.png) - (see `gef-extras/ida-rpyc`, which is the new improved version of `ida-interact`) - #### Dynamic `ctypes.Structure`-like classes `pcustom` also supports the use of class factories to create a `ctypes.Structure` class whose @@ -127,6 +130,7 @@ currently debugged binary, the architecture, the size of a pointer and more). The syntax is relatively close to the way we use to create static classes (see above), but instead we define a function that will generate the class. The requirements for this class factory are: + - take a single [`Gef`](https://github.com/hugsy/gef/blob/dev/docs/api/gef.md#class-gef) positional argument - End the function name with `_t` @@ -179,18 +183,19 @@ def person_t(gef: Optional["Gef"]==None): return person_cls ``` - ### Public repository of structures A community contributed repository of structures can be found in [`gef-extras`](https://github.com/hugsy/gef-extras). To deploy it: In bash: + ``` -$ git clone https://github.com/hugsy/gef-extras +git clone https://github.com/hugsy/gef-extras ``` In GEF: + ``` gef➤ gef config pcustom.struct_path /path/to/gef-extras/structs gef➤ gef save diff --git a/docs/commands/print-format.md b/docs/commands/print-format.md index 1401e3992..bcb449222 100644 --- a/docs/commands/print-format.md +++ b/docs/commands/print-format.md @@ -10,7 +10,6 @@ following the format specified. Currently, the output formats supported are - Hex string (`hex`) - For patch byte command or GDB $_gef[N] byte access (`bytearray`) - ``` gef➤ print-format -h [+] print-format [--lang LANG] [--bitlen SIZE] [(--length,-l) LENGTH] [--clip] LOCATION diff --git a/docs/commands/process-search.md b/docs/commands/process-search.md index 62a24e675..96d585e4d 100644 --- a/docs/commands/process-search.md +++ b/docs/commands/process-search.md @@ -41,7 +41,7 @@ So, for example, if your targeted process is called `/home/foobar/plop`, but the is used through `socat`, like ``` -$ socat tcp-l:1234,fork,reuseaddr exec:/home/foobar/plop +socat tcp-l:1234,fork,reuseaddr exec:/home/foobar/plop ``` Then every time a new connection is opened to tcp/1234, `plop` will be forked, and GEF can easily diff --git a/docs/commands/reset-cache.md b/docs/commands/reset-cache.md index f1d1924cf..be5db7de2 100644 --- a/docs/commands/reset-cache.md +++ b/docs/commands/reset-cache.md @@ -1,3 +1,3 @@ ## Command `reset-cache` -This command is only useful for debugging `GEF` itself. \ No newline at end of file +This command is only useful for debugging `GEF` itself. diff --git a/docs/commands/search-pattern.md b/docs/commands/search-pattern.md index dc5044a82..0e587468c 100644 --- a/docs/commands/search-pattern.md +++ b/docs/commands/search-pattern.md @@ -2,6 +2,7 @@ `gef` allows you to search for a specific pattern at runtime in all the segments of your process memory layout. The command `search-pattern`, alias `grep`, aims to be straight-forward to use: + ``` gef➤ search-pattern MyPattern ``` @@ -25,6 +26,7 @@ For this reason, the alias `xref` also points to the command `search-pattern`. command above is equivalent to `xref 0x4005f6` which makes it more intuitive to use. ### Searching in a specific range ### + Sometimes, you may need to search for a very common pattern. To limit the search space, you can also specify an address range or the section to be checked. @@ -34,6 +36,7 @@ gef➤ search-pattern 0x4005f6 little 0x603100-0x603200 ``` ### Searching in a specific range using regex ### + Sometimes, you may need an advanced search using regex. Just use --regex arg. Example: how to find null-end-printable(from x20-x7e) C strings (min size >=2 bytes) with a regex: diff --git a/docs/commands/shellcode.md b/docs/commands/shellcode.md index f2d70b47b..56996ac9c 100644 --- a/docs/commands/shellcode.md +++ b/docs/commands/shellcode.md @@ -29,4 +29,3 @@ shell-storm.org Shellcode ARM without 0x20, 0x0a and 0x00 [...] ``` - diff --git a/docs/commands/skipi.md b/docs/commands/skipi.md index 68ca46243..a7565c2e1 100644 --- a/docs/commands/skipi.md +++ b/docs/commands/skipi.md @@ -11,8 +11,8 @@ skipi [LOCATION] [--n NUM_INSTRUCTIONS] `--n NUM_INSTRUCTIONS` Skip the specified number of instructions instead of the default 1. ```bash -gef➤ skipi -gef➤ skipi --n 3 -gef➤ skipi 0x69696969 -gef➤ skipi 0x69696969 --n 6 -``` \ No newline at end of file +gef➤ skipi +gef➤ skipi --n 3 +gef➤ skipi 0x69696969 +gef➤ skipi 0x69696969 --n 6 +``` diff --git a/docs/commands/trace-run.md b/docs/commands/trace-run.md index 1b30977dd..c9261f417 100644 --- a/docs/commands/trace-run.md +++ b/docs/commands/trace-run.md @@ -17,4 +17,3 @@ By using the script `ida_color_gdb_trace.py` on the text file generated, it will taken: ![trace-run-2](https://i.imgur.com/oAGoSMQ.png) - diff --git a/docs/commands/xor-memory.md b/docs/commands/xor-memory.md index 3c252611a..851a09278 100644 --- a/docs/commands/xor-memory.md +++ b/docs/commands/xor-memory.md @@ -3,6 +3,7 @@ This command is used to XOR a block of memory. Its syntax is: + ``` xor-memory
``` diff --git a/docs/compat.md b/docs/compat.md index 7b0d9b065..473414190 100644 --- a/docs/compat.md +++ b/docs/compat.md @@ -9,6 +9,4 @@ This matrix indicates the version of Python and/or GDB | [2022.01](https://github.com/hugsy/gef/releases/tag/2021.01) | 7.7 | Python 3.4+ | | [Current](https://github.com/hugsy/gef/tree/main) | 8.0+ | Python 3.6+ | - - * Up to - included diff --git a/docs/faq.md b/docs/faq.md index b065907cf..4c895fbf3 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,6 +1,5 @@ # Frequently Asked Questions # - ## Why use GEF over PEDA? ## [PEDA](https://github.com/longld/peda) is a fantastic tool that provides similar commands to make @@ -35,8 +34,7 @@ If you are running an obsolete version, GEF will show a error and message and ex Some pre-compiled static binaries for both recent GDB and GDBServer can be downloaded from the [`gdb-static`](https://github.com/hugsy/gdb-static) repository. - -## I cannot get GEF setup!! ## +## I cannot get GEF setup ## GEF will work on any GDB 8+ compiled with Python 3.6+ support. You can view that commands that failed to load using `gef missing`, but this will not affect GEF generally. @@ -79,7 +77,6 @@ readline_compat = True You can now use all features of `gef` even on versions of GDB compiled against old `readline` library. - ## Does GEF prevent the use of other GDB plugins? ## Definitely not! You can use any other GDB plugin on top of it for an even better debugging @@ -93,8 +90,6 @@ Some interesting plugins highly recommended too: ![voltron](https://i.imgur.com/bfTIjNi.jpg) Src: [@rick2600: terminator + gdb + gef + voltron cc: @snare @_hugsy_](https://twitter.com/rick2600/status/775926070566490113) - - ## I want to contribute, where should I head first? ## I would suggest thoroughly reading this documentation, just having a look to the @@ -104,7 +99,6 @@ give you pointers. Also a good thing would be to join our [Discord channel](https://discord.gg/HCS8Hg7) to get in touch with the people involved/using it. - ## I think I've found a bug, how can I help fixing it? ## `gef` is only getting better through people (like you!) using it, but most importantly reporting @@ -116,9 +110,11 @@ happens, you'll only get to see a message like this: ![gef-exception](https://i.imgur.com/J7dUnXV.png) By switching to debug mode, `gef` will give much more information: + ``` gef➤ gef config gef.debug 1 ``` + ![gef-debug](https://i.imgur.com/SGe8oFF.png) If you think fixing it is in your skills, then send a [Pull @@ -128,7 +124,6 @@ what was your solution for it. Otherwise, you can open an [issue](https://github.com/hugsy/gef/issues), give a thorough description of your bug and copy/paste the content from above. This will greatly help for solving the issue. - ## I get weird issues/characters using GDB + Python3, what's up? ## Chances are you are not using UTF-8. Python3 is [highly relying on @@ -141,7 +136,7 @@ In addition, some unexpected results were observed when your local is not set to aren't sure, simply run `gdb` like this: ``` -$ LC_ALL=en_US.UTF-8 gdb /path/to/your/binary +LC_ALL=en_US.UTF-8 gdb /path/to/your/binary ``` ## GDB crashes on ARM memory corruption with `gdb_exception_RETURN_MASK_ERROR` ## @@ -160,7 +155,7 @@ Debian/Kali for ARM > simple ARM assembly program (noted above) when instead of exiting cleanly, > gdb's disassembly failed with a SIGABRT and threw an exception: > -> `gdb_exception_RETURN_MASK_ERROR` +> `gdb_exception_RETURN_MASK_ERROR` > > This turns out to be a known problem (regression) with gdb, and affects > gef users running the ARM platform (Raspberry Pi). @@ -174,7 +169,7 @@ Therefore, there is nothing GEF's developers can do about that. The correct solu above is to recompile your GDB with a newer (better) version. The whole topic was already internally discussed, so please refer to the [issue -#206](https://github.com/hugsy/gef/issues/206) for the whole story. +# 206](https://github.com/hugsy/gef/issues/206) for the whole story. ## I still don't have my answer... Where can I go? @@ -189,7 +184,7 @@ can! ## How can I use GEF to debug a process in a container? GEF can attach to a process running in a container using `gdb --pid=$PID`, where `$PID` is the ID of -the running process *on the host*. To find this, you can use `docker top -o pid | awk +the running process _on the host_. To find this, you can use `docker top -o pid | awk '!/PID/' | xargs -I'{}' pstree -psa {}` to view the process tree for the container. `sudo` may be required to attach to the process, which will depend on your system's security diff --git a/docs/functions/base.md b/docs/functions/base.md index ec442adef..eadc98a27 100644 --- a/docs/functions/base.md +++ b/docs/functions/base.md @@ -10,6 +10,7 @@ $_base([filepath]) ``` Example: + ``` gef➤ p $_base(\"/usr/lib/ld-2.33.so\") ``` diff --git a/docs/functions/bss.md b/docs/functions/bss.md index 055f34d7a..ac9c67fc8 100644 --- a/docs/functions/bss.md +++ b/docs/functions/bss.md @@ -9,6 +9,7 @@ $_bss([offset]) ``` Example: + ``` gef➤ p $_bss(0x20) ``` diff --git a/docs/functions/got.md b/docs/functions/got.md index cb2ff95d7..9070df006 100644 --- a/docs/functions/got.md +++ b/docs/functions/got.md @@ -9,6 +9,7 @@ $_got([offset]) ``` Example: + ``` gef➤ p $_got(0x20) ``` diff --git a/docs/functions/heap.md b/docs/functions/heap.md index a7ae27269..7dd365205 100644 --- a/docs/functions/heap.md +++ b/docs/functions/heap.md @@ -9,6 +9,7 @@ $_heap([offset]) ``` Example: + ``` gef➤ p $_heap(0x20) ``` diff --git a/docs/functions/stack.md b/docs/functions/stack.md index de825136d..374bdb979 100644 --- a/docs/functions/stack.md +++ b/docs/functions/stack.md @@ -9,6 +9,7 @@ $_stack([offset]) ``` Example: + ``` gef➤ p $_stack(0x20) ``` diff --git a/docs/index.md b/docs/index.md index 6785805e5..ec7dbf234 100644 --- a/docs/index.md +++ b/docs/index.md @@ -34,7 +34,6 @@ It requires Python 3, but [`gef-legacy`](https://github.com/hugsy/gef-legacy) ca Check out the [showroom page](https://hugsy.github.io/gef/screenshots/) for more | or [try it online yourself!](https://demo.gef.blah.cat) (user:`gef`/password:`gef-demo`) - ## Quick start ### Automated installation @@ -49,7 +48,6 @@ bash -c "$(curl -fsSL https://gef.blah.cat/sh)" For more details and other ways to install GEF please see [installation page](https://hugsy.github.io/gef/install/). - ### Run Then just start playing (for local files): @@ -73,7 +71,6 @@ local:~ $ gdb -q gef➤ gef-remote -t your.ip.address:1234 -p 666 ``` - ## Bugs & Feedbacks ## To discuss `gef`, `gdb`, exploitation or other topics, feel free to join our [Discord @@ -91,9 +88,9 @@ systems such as GrSec. `gef` was created and maintained by myself, [`@_hugsy_`](https://twitter.com/_hugsy_), but kept fresh thanks to [all the contributors](https://github.com/hugsy/gef/graphs/contributors). -[ ![contributors-img](https://contrib.rocks/image?repo=hugsy/gef) ](https://github.com/hugsy/gef/graphs/contributors) +[![contributors-img](https://contrib.rocks/image?repo=hugsy/gef)](https://github.com/hugsy/gef/graphs/contributors) -Or if you just like the tool, feel free to drop a simple *"thanks"* on Discord, Twitter or other, it +Or if you just like the tool, feel free to drop a simple _"thanks"_ on Discord, Twitter or other, it is **always** very appreciated. ## Sponsors ## @@ -110,10 +107,8 @@ dedicate more time and resources to the project: [](https://github.com/therealdreg) [](https://github.com/mikesart) - ## Extra Credits -- The GEF logo was designed by [TheZakMan](https://twitter.com/thezakman) - +* The GEF logo was designed by [TheZakMan](https://twitter.com/thezakman) -## 🍺 Happy hacking ! +## 🍺 Happy hacking diff --git a/docs/install.md b/docs/install.md index 37937b051..a23eb2132 100644 --- a/docs/install.md +++ b/docs/install.md @@ -2,11 +2,13 @@ ## Prerequisites -Specific GEF commands rely on commonly used Unix commands to extract additional information. Therefore it requires the following binaries to be present: - * `file` - * `readelf` - * `ps` - * `python3` +Specific GEF commands rely on commonly used Unix commands to extract additional information. +Therefore it requires the following binaries to be present: + +* `file` +* `readelf` +* `ps` +* `python3` Those tools are included by default in many modern distributions. If they're missing, you can use your OS package manager to install them. @@ -25,7 +27,7 @@ features, and only functional bugs will be handled. You can verify it with the following command: ```bash -$ gdb -nx -ex 'pi print(sys.version)' -ex quit +gdb -nx -ex 'pi print(sys.version)' -ex quit ``` This should display your version of Python compiled with `gdb`. @@ -42,10 +44,9 @@ There are **none**: `GEF` works out of the box! GEF itself provides most (if not all 🤯) features required for typical sessions. However, GEF can be easily extended via -- community-built scripts, functions and architectures in the repo +* community-built scripts, functions and architectures in the repo `gef-extras` (see below) -- your own script which can leverage the GEF API for the heavy lifting - +* your own script which can leverage the GEF API for the heavy lifting ## Standalone @@ -60,6 +61,7 @@ bash -c "$(curl -fsSL https://gef.blah.cat/sh)" ``` Or if you prefer `wget` + ```bash bash -c "$(wget https://gef.blah.cat/sh -O -)" ``` @@ -79,7 +81,6 @@ $ cat ~/.gdbinit source ~/.gdbinit-gef.py ``` - ### Update If your host/VM is connected to the Internet, you can update `gef` easily to the latest version @@ -98,8 +99,8 @@ updates are available, `gef` will respond `No update` instead. To contribute to GEF, you might prefer using git directly. ```bash -$ git clone --branch dev https://github.com/hugsy/gef.git -$ echo source `pwd`/gef/gef.py >> ~/.gdbinit +git clone --branch dev https://github.com/hugsy/gef.git +echo source `pwd`/gef/gef.py >> ~/.gdbinit ``` GEF is in very active development, so the default branch is `dev`. This is the @@ -109,7 +110,7 @@ However if you prefer a more stable life, you can then switch to the `main` branch: ```bash -$ git checkout main +git checkout main ``` The `main` branch gets only updated for new releases, or also when critical @@ -122,6 +123,7 @@ GEF was built to also provide a solid base for external scripts. The repository anyone can freely submit their own commands to extend GDB via GEF's API. To benefit from it: + ```bash # using the automated way ## via the install script @@ -145,7 +147,6 @@ $ gdb -ex 'gef config pcustom.struct_path "/path/to/gef-extras/structs"' -ex 'ge There, you're now fully equipped epic pwnage with **all** GEF's goodness!! - # Uninstalling GEF ## Prevent script loading @@ -170,6 +171,7 @@ source /my/path/to/gef.py ``` Will become: + ```text $ cat ~/.gdbinit # source /my/path/to/gef.py diff --git a/docs/obsolete/docs/index.md b/docs/obsolete/docs/index.md index e568da80e..7fe850a97 100644 --- a/docs/obsolete/docs/index.md +++ b/docs/obsolete/docs/index.md @@ -6,4 +6,3 @@ --- ![redirect](https://i.imgflip.com/1f0lcn.jpg) - diff --git a/docs/testing.md b/docs/testing.md index 3f21625dd..6ebd2163a 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -44,7 +44,6 @@ FAILED tests/commands/heap.py::HeapCommand::test_cmd_heap_bins_unsorted - Assert You can then use `pytest` directly to help you fix each error specifically. - #### Using `pytest` GEF entirely relies on [`pytest`](https://pytest.org) for its testing. Refer to the project @@ -85,7 +84,6 @@ environment to help you get more information about the reason of failure. One of the most convenient ways to test `gef` properly is using the `pytest` integration of modern editors such as VisualStudio Code or PyCharm. Without proper tests, new code will not be integrated. - ### Linting GEF You can use the Makefile at the root of the project to get the proper linting settings. For most From ea7ed49daa8ac1e79dde7af7ca142ab6bb7301e4 Mon Sep 17 00:00:00 2001 From: Dreg Date: Wed, 2 Aug 2023 16:49:51 +0200 Subject: [PATCH 20/21] Fix link in testing docs (#979) --- docs/faq.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index 4c895fbf3..471338c1c 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -168,8 +168,8 @@ Debian/Kali for ARM Therefore, there is nothing GEF's developers can do about that. The correct solution as mentioned above is to recompile your GDB with a newer (better) version. -The whole topic was already internally discussed, so please refer to the [issue -# 206](https://github.com/hugsy/gef/issues/206) for the whole story. +The whole topic was already internally discussed, so please refer to the +[issue 206](https://github.com/hugsy/gef/issues/206) for the whole story. ## I still don't have my answer... Where can I go? From a825c8413d8a432b09f75132fe1d83803c2b906f Mon Sep 17 00:00:00 2001 From: crazy hugsy Date: Sat, 5 Aug 2023 13:31:56 -0700 Subject: [PATCH 21/21] [ci] Upgrade notification actions (#981) This PR modifies the content of Discord notification generated by the GActions. It also adds minor formatting additions. --- .../{discord-notify.yml => notify.yml} | 53 ++++++++++--------- 1 file changed, 28 insertions(+), 25 deletions(-) rename .github/workflows/{discord-notify.yml => notify.yml} (55%) diff --git a/.github/workflows/discord-notify.yml b/.github/workflows/notify.yml similarity index 55% rename from .github/workflows/discord-notify.yml rename to .github/workflows/notify.yml index 516c597ad..ca35c1ab1 100644 --- a/.github/workflows/discord-notify.yml +++ b/.github/workflows/notify.yml @@ -1,13 +1,19 @@ -name: "Discord Notification" - +name: "Notifications" on: + issues: + types: + - opened + - reopened push: branches: - main - dev pull_request: + types: + - opened + - closed branches: - main - dev @@ -16,56 +22,53 @@ env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} jobs: - notify: + discord: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - - name: GEF Push Notification + - name: Notify/Push if: github.event_name == 'push' && github.repository_owner == 'hugsy' - uses: sarisia/actions-status-discord@v1 + uses: sarisia/actions-status-discord@v1.12 with: nodetail: true - title: "[${{ github.repository }}] ${{ github.actor }} pushed to `${{ github.ref }}`" + title: "[${{ github.repository }}] ${{ github.actor }} pushed to `${{ github.ref_name }}`" description: | **Commits**: ● ${{ join(github.event.commits.*.message, ' ● ') }} --- - **Link**: ${{ github.event.compare }} - - color: 0x0000ff + [Open Diff View](${{ github.event.compare }}) + color: 0x00ff00 username: ${{ github.actor }} via GithubBot avatar_url: ${{ github.actor.avatar_url }} - - name: GEF Pull Request Notification - if: github.event_name == 'pull_request' && github.event.action == 'opened' - uses: sarisia/actions-status-discord@v1 + - name: Notify/Pull Request + if: github.event_name == 'pull_request' + uses: sarisia/actions-status-discord@v1.12 with: nodetail: true - title: "[${{ github.repository }}] ${{ github.actor }} created a new Pull Request (`#${{ github.event.pull_request.number }}`)" + title: "[${{ github.repository }}] ${{ github.actor }} ${{ github.event.action }} PR #${{ github.event.pull_request.number }}" description: | - **${{ github.event.pull_request.title }}** - + **Title**: ${{ github.event.pull_request.title }} --- - **Link**: ${{ github.event.pull_request.html_url }} - color: 0x00ff00 + [Goto PR](${{ github.event.pull_request.html_url }}) + color: 0x0000ff username: ${{ github.actor }} via GithubBot avatar_url: ${{ github.actor.avatar_url }} - - name: GEF Issue Notification - if: github.event_name == 'issues' && github.event.action == 'opened' && github.repository_owner == 'hugsy' - uses: sarisia/actions-status-discord@v1 + - name: Notify/Issue + if: github.event_name == 'issues' && github.repository_owner == 'hugsy' + uses: sarisia/actions-status-discord@v1.12 with: nodetail: true - title: "[${{ github.repository }}] ${{ github.actor }} created a new Issue (`#${{ github.event.issue.number }}`)" + title: "[${{ github.repository }}] ${{ github.actor }} ${{ github.event.action}} issue #${{ github.event.issue.number }}" description: | - **${{ github.event.issue.title }}** - + **Title**: ${{ github.event.issue.title }} --- - **Link**: ${{ github.event.issue.html_url }} + [Goto issue](${{ github.event.issue.html_url }}) color: 0xff0000 username: ${{ github.actor }} via GithubBot avatar_url: ${{ github.actor.avatar_url }}