From bc3551874f793af66f2c08fb3541bedd82992b8d Mon Sep 17 00:00:00 2001 From: hugsy Date: Tue, 1 Aug 2023 03:12:58 +0000 Subject: [PATCH] Deployed b57e174 with MkDocs version: 1.5.1 --- .nojekyll | 0 404.html | 1685 + api/gef/index.html | 39580 ++++++++++++++++ api/index.html | 2055 + assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.220ee61c.min.js | 29 + assets/javascripts/bundle.220ee61c.min.js.map | 8 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++ .../workers/search.74e28a9f.min.js | 42 + .../workers/search.74e28a9f.min.js.map | 8 + assets/stylesheets/main.eebd395e.min.css | 1 + assets/stylesheets/main.eebd395e.min.css.map | 1 + assets/stylesheets/palette.ecc896b0.min.css | 1 + .../stylesheets/palette.ecc896b0.min.css.map | 1 + commands/aliases/index.html | 1919 + commands/aslr/index.html | 1778 + commands/canary/index.html | 1767 + commands/checksec/index.html | 1776 + commands/config/index.html | 1786 + commands/context/index.html | 1990 + commands/dereference/index.html | 1824 + commands/edit-flags/index.html | 1773 + commands/elf-info/index.html | 1825 + commands/entry-break/index.html | 1772 + commands/eval/index.html | 1796 + commands/format-string-helper/index.html | 1780 + commands/functions/index.html | 1787 + commands/gef-remote/index.html | 1962 + commands/gef/index.html | 1982 + commands/got/index.html | 1776 + commands/heap-analysis-helper/index.html | 1810 + commands/heap/index.html | 2026 + commands/help/index.html | 1763 + commands/hexdump/index.html | 1804 + commands/highlight/index.html | 1904 + commands/hijack-fd/index.html | 1777 + commands/ksymaddr/index.html | 1775 + commands/memory/index.html | 1868 + commands/name-break/index.html | 1797 + commands/nop/index.html | 1790 + commands/patch/index.html | 1770 + commands/pattern/index.html | 1842 + commands/pcustom/index.html | 2007 + commands/pie/index.html | 1901 + commands/print-format/index.html | 1791 + commands/process-search/index.html | 1797 + commands/process-status/index.html | 1788 + commands/registers/index.html | 1838 + commands/reset-cache/index.html | 1761 + commands/scan/index.html | 1807 + commands/search-pattern/index.html | 1827 + commands/shellcode/index.html | 1787 + commands/skipi/index.html | 1725 + commands/stub/index.html | 1807 + commands/theme/index.html | 1825 + commands/tmux-setup/index.html | 1808 + commands/trace-run/index.html | 1771 + commands/version/index.html | 1808 + commands/vmmap/index.html | 1770 + commands/xfiles/index.html | 1764 + commands/xinfo/index.html | 1767 + commands/xor-memory/index.html | 1786 + compat/index.html | 1753 + config/index.html | 1783 + coverage/coverage.json | 1 + coverage/coverage.xml | 7591 +++ coverage/coverage_html.js | 624 + coverage/favicon_32.png | Bin 0 -> 1732 bytes coverage/gef_py.html | 11304 +++++ coverage/index.html | 110 + coverage/keybd_closed.png | Bin 0 -> 9004 bytes coverage/keybd_open.png | Bin 0 -> 9003 bytes coverage/status.json | 1 + coverage/style.css | 309 + deprecated/index.html | 1802 + faq/index.html | 2009 + functions/base/index.html | 1726 + functions/bss/index.html | 1725 + functions/got/index.html | 1725 + functions/heap/index.html | 1725 + functions/stack/index.html | 1725 + index.html | 1964 + install/index.html | 2010 + obsolete/docs/index.html | 1718 + obsolete/mkdocs.yml | 6 + obsolete/requirements.txt | 1 + requirements.txt | 2 + screenshots/index.html | 2038 + search/search_index.json | 1 + settings/context/index.html | 2130 + settings/dereference/index.html | 1769 + settings/entry-break/index.html | 1769 + settings/gef/index.html | 1959 + settings/got/index.html | 1788 + settings/heap-analysis-helper/index.html | 1845 + settings/heap-chunks/index.html | 1769 + settings/hexdump/index.html | 1769 + settings/highlight/index.html | 1769 + settings/pattern/index.html | 1769 + settings/pcustom/index.html | 1845 + settings/print-format/index.html | 1769 + settings/process-search/index.html | 1769 + settings/search-pattern/index.html | 1788 + settings/theme/index.html | 2073 + settings/trace-run/index.html | 1786 + sitemap.xml | 3 + sitemap.xml.gz | Bin 0 -> 127 bytes testing/index.html | 1959 + 139 files changed, 212945 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 api/gef/index.html create mode 100644 api/index.html create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.220ee61c.min.js create mode 100644 assets/javascripts/bundle.220ee61c.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.74e28a9f.min.js create mode 100644 assets/javascripts/workers/search.74e28a9f.min.js.map create mode 100644 assets/stylesheets/main.eebd395e.min.css create mode 100644 assets/stylesheets/main.eebd395e.min.css.map create mode 100644 assets/stylesheets/palette.ecc896b0.min.css create mode 100644 assets/stylesheets/palette.ecc896b0.min.css.map create mode 100644 commands/aliases/index.html create mode 100644 commands/aslr/index.html create mode 100644 commands/canary/index.html create mode 100644 commands/checksec/index.html create mode 100644 commands/config/index.html create mode 100644 commands/context/index.html create mode 100644 commands/dereference/index.html create mode 100644 commands/edit-flags/index.html create mode 100644 commands/elf-info/index.html create mode 100644 commands/entry-break/index.html create mode 100644 commands/eval/index.html create mode 100644 commands/format-string-helper/index.html create mode 100644 commands/functions/index.html create mode 100644 commands/gef-remote/index.html create mode 100644 commands/gef/index.html create mode 100644 commands/got/index.html create mode 100644 commands/heap-analysis-helper/index.html create mode 100644 commands/heap/index.html create mode 100644 commands/help/index.html create mode 100644 commands/hexdump/index.html create mode 100644 commands/highlight/index.html create mode 100644 commands/hijack-fd/index.html create mode 100644 commands/ksymaddr/index.html create mode 100644 commands/memory/index.html create mode 100644 commands/name-break/index.html create mode 100644 commands/nop/index.html create mode 100644 commands/patch/index.html create mode 100644 commands/pattern/index.html create mode 100644 commands/pcustom/index.html create mode 100644 commands/pie/index.html create mode 100644 commands/print-format/index.html create mode 100644 commands/process-search/index.html create mode 100644 commands/process-status/index.html create mode 100644 commands/registers/index.html create mode 100644 commands/reset-cache/index.html create mode 100644 commands/scan/index.html create mode 100644 commands/search-pattern/index.html create mode 100644 commands/shellcode/index.html create mode 100644 commands/skipi/index.html create mode 100644 commands/stub/index.html create mode 100644 commands/theme/index.html create mode 100644 commands/tmux-setup/index.html create mode 100644 commands/trace-run/index.html create mode 100644 commands/version/index.html create mode 100644 commands/vmmap/index.html create mode 100644 commands/xfiles/index.html create mode 100644 commands/xinfo/index.html create mode 100644 commands/xor-memory/index.html create mode 100644 compat/index.html create mode 100644 config/index.html create mode 100644 coverage/coverage.json create mode 100644 coverage/coverage.xml create mode 100644 coverage/coverage_html.js create mode 100644 coverage/favicon_32.png create mode 100644 coverage/gef_py.html create mode 100644 coverage/index.html create mode 100644 coverage/keybd_closed.png create mode 100644 coverage/keybd_open.png create mode 100644 coverage/status.json create mode 100644 coverage/style.css create mode 100644 deprecated/index.html create mode 100644 faq/index.html create mode 100644 functions/base/index.html create mode 100644 functions/bss/index.html create mode 100644 functions/got/index.html create mode 100644 functions/heap/index.html create mode 100644 functions/stack/index.html create mode 100644 index.html create mode 100644 install/index.html create mode 100644 obsolete/docs/index.html create mode 100644 obsolete/mkdocs.yml create mode 100644 obsolete/requirements.txt create mode 100644 requirements.txt create mode 100644 screenshots/index.html create mode 100644 search/search_index.json create mode 100644 settings/context/index.html create mode 100644 settings/dereference/index.html create mode 100644 settings/entry-break/index.html create mode 100644 settings/gef/index.html create mode 100644 settings/got/index.html create mode 100644 settings/heap-analysis-helper/index.html create mode 100644 settings/heap-chunks/index.html create mode 100644 settings/hexdump/index.html create mode 100644 settings/highlight/index.html create mode 100644 settings/pattern/index.html create mode 100644 settings/pcustom/index.html create mode 100644 settings/print-format/index.html create mode 100644 settings/process-search/index.html create mode 100644 settings/search-pattern/index.html create mode 100644 settings/theme/index.html create mode 100644 settings/trace-run/index.html create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz create mode 100644 testing/index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..37d25bbc6 --- /dev/null +++ b/404.html @@ -0,0 +1,1685 @@ + + + + + + + + + + + + + + + + + + GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/gef/index.html b/api/gef/index.html new file mode 100644 index 000000000..efae365c1 --- /dev/null +++ b/api/gef/index.html @@ -0,0 +1,39580 @@ + + + + + + + + + + + + + + + + + + + + + + API - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + +

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
  • +
  • progspace
  • +
  • errmsg
  • +
+
+

+

function http_get

+
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

+
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

+
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

+
reset() → None
+
+
+

+

function highlight_text

+
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

+
gef_print(*args: str, end='\n', sep=' ', **kwargs: Any) → None
+
+

Wrapper around print(), using string buffering feature.

+
+

+

function bufferize

+
bufferize(f: Callable) → Callable
+
+

Store the content to be printed for a function in memory, and flush it on function exit.

+
+

+

function p8

+
p8(
+    x: int,
+    s: bool = False,
+    e: Optional[ForwardRef('Endianness')] = None
+) → bytes
+
+

Pack one byte respecting the current architecture endianness.

+
+

+

function p16

+
p16(
+    x: int,
+    s: bool = False,
+    e: Optional[ForwardRef('Endianness')] = None
+) → bytes
+
+

Pack one word respecting the current architecture endianness.

+
+

+

function p32

+
p32(
+    x: int,
+    s: bool = False,
+    e: Optional[ForwardRef('Endianness')] = None
+) → bytes
+
+

Pack one dword respecting the current architecture endianness.

+
+

+

function p64

+
p64(
+    x: int,
+    s: bool = False,
+    e: Optional[ForwardRef('Endianness')] = None
+) → bytes
+
+

Pack one qword respecting the current architecture endianness.

+
+

+

function u8

+
u8(
+    x: bytes,
+    s: bool = False,
+    e: Optional[ForwardRef('Endianness')] = None
+) → int
+
+

Unpack one byte respecting the current architecture endianness.

+
+

+

function u16

+
u16(
+    x: bytes,
+    s: bool = False,
+    e: Optional[ForwardRef('Endianness')] = None
+) → int
+
+

Unpack one word respecting the current architecture endianness.

+
+

+

function u32

+
u32(
+    x: bytes,
+    s: bool = False,
+    e: Optional[ForwardRef('Endianness')] = None
+) → int
+
+

Unpack one dword respecting the current architecture endianness.

+
+

+

function u64

+
u64(
+    x: bytes,
+    s: bool = False,
+    e: Optional[ForwardRef('Endianness')] = None
+) → int
+
+

Unpack one qword respecting the current architecture endianness.

+
+

+

function is_ascii_string

+
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

+
is_alive() → bool
+
+

Check if GDB is running.

+
+

+

function calling_function

+
calling_function() → Optional[str]
+
+

Return the name of the calling function

+
+

+

function only_if_gdb_running

+
only_if_gdb_running(f: Callable) → Callable
+
+

Decorator wrapper to check if GDB is running.

+
+

+

function only_if_gdb_target_local

+
only_if_gdb_target_local(f: Callable) → Callable
+
+

Decorator wrapper to check if GDB is running locally (target not remote).

+
+

+

function deprecated

+
deprecated(solution: str = '') → Callable
+
+

Decorator to add a warning when a command is obsolete and will be removed.

+
+

+

function experimental_feature

+
experimental_feature(f: Callable) → Callable
+
+

Decorator to add a warning when a feature is experimental.

+
+

+

function only_if_events_supported

+
only_if_events_supported(event_type: str) → Callable
+
+

Checks if GDB supports events without crashing.

+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function wrapped_f

+
wrapped_f(*args: Any, **kwargs: Any) → Any
+
+
+

+

function FakeExit

+
FakeExit(*args: Any, **kwargs: Any) → NoReturn
+
+
+

+

function parse_arguments

+
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

+
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

+
get_libc_version() → Tuple[int, ...]
+
+

get_libc_version is DEPRECATED and will be removed in the future. + Use GefLibcManager.find_libc_version()

+
+

+

function titlify

+
titlify(
+    text: str,
+    color: Optional[str] = None,
+    msg_color: Optional[str] = None
+) → str
+
+

Print a centered title.

+
+

+

function dbg

+
dbg(msg: str) → None
+
+
+

+

function err

+
err(msg: str) → None
+
+
+

+

function warn

+
warn(msg: str) → None
+
+
+

+

function ok

+
ok(msg: str) → None
+
+
+

+

function info

+
info(msg: str) → None
+
+
+

+

function push_context_message

+
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

+
show_last_exception() → None
+
+

Display the last Python exception.

+
+

+

function gef_pystring

+
gef_pystring(x: bytes) → str
+
+

Returns a sanitized version as string of the bytes list given in input.

+
+

+

function gef_pybytes

+
gef_pybytes(x: str) → bytes
+
+

Returns an immutable bytes list from the string given as input.

+
+

+

function style_byte

+
style_byte(b: int, color: bool = True) → str
+
+
+

+

function hexdump

+
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

+
is_debug() → bool
+
+

Check if debug mode is enabled.

+
+

+

function buffer_output

+
buffer_output() → bool
+
+

Check if output should be buffered until command completion.

+
+

+

function hide_context

+
hide_context() → bool
+
+

Helper function to hide the context pane.

+
+

+

function unhide_context

+
unhide_context() → bool
+
+

Helper function to unhide the context pane.

+
+

+

function enable_redirect_output

+
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

+
disable_redirect_output() → None
+
+

Disable the output redirection, if any.

+
+

+

function gef_makedirs

+
gef_makedirs(path: str, mode: int = 493) → Path
+
+

Recursive mkdir() creation. If successful, return the absolute path of the directory created.

+
+

+

function gdb_disassemble

+
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

+
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

+
gdb_get_nth_next_instruction_address(addr: int, n: int) → int
+
+

Return the address of the n-th instruction after addr. + gdb_get_nth_next_instruction_address is DEPRECATED and will be removed in the future. + Use gef_instruction_n().address

+
+

+

function gef_instruction_n

+
gef_instruction_n(addr: int, n: int) → Instruction
+
+

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)

+
+

+

function gef_get_instruction_at

+
gef_get_instruction_at(addr: int) → Instruction
+
+

Return the full Instruction found at the specified address.

+
+

+

function gef_current_instruction

+
gef_current_instruction(addr: int) → Instruction
+
+

Return the current instruction as an Instruction object.

+
+

+

function gef_next_instruction

+
gef_next_instruction(addr: int) → Instruction
+
+

Return the next instruction as an Instruction object.

+
+

+

function gef_disassemble

+
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

+
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

+
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

+
checksec(filename: str) → Dict[str, bool]
+
+

checksec is DEPRECATED and will be removed in the future. + Use Elf(fname).checksec()

+
+

+

function get_entry_point

+
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

+
is_pie(fpath: str) → bool
+
+
+

+

function is_big_endian

+
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

+
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

+
flags_to_human(reg_value: int, value_table: Dict[int, str]) → str
+
+

Return a human readable string showing the flag states.

+
+

+

function register_architecture

+
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

+
copy_to_clipboard(data: bytes) → None
+
+

Helper function to submit data to the clipboard

+
+

+

function use_stdtype

+
use_stdtype() → str
+
+
+

+

function use_default_type

+
use_default_type() → str
+
+
+

+

function use_golang_type

+
use_golang_type() → str
+
+
+

+

function use_rust_type

+
use_rust_type() → str
+
+
+

+

function to_unsigned_long

+
to_unsigned_long(v: gdb.Value) → int
+
+

Cast a gdb.Value to unsigned long.

+
+

+

function get_path_from_info_proc

+
get_path_from_info_proc() → Optional[str]
+
+
+

+

function get_os

+
get_os() → str
+
+

get_os is DEPRECATED and will be removed in the future. + Use gef.session.os

+
+

+

function get_filepath

+
get_filepath() → Optional[str]
+
+

Return the local absolute path of the file currently debugged.

+
+

+

function get_function_length

+
get_function_length(sym: str) → int
+
+

Attempt to get the length of the raw bytes of a function.

+
+

+

function process_lookup_address

+
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

+
xor(data: ByteString, key: str) → bytearray
+
+

Return data xor-ed with key.

+
+

+

function is_hex

+
is_hex(pattern: str) → bool
+
+

Return whether provided string is a hexadecimal value.

+
+

+

function continue_handler

+
continue_handler(_: 'gdb.ContinueEvent') → None
+
+

GDB event handler for new object continue cases.

+
+

+

function hook_stop_handler

+
hook_stop_handler(_: 'gdb.StopEvent') → None
+
+

GDB event handler for stop cases.

+
+

+

function new_objfile_handler

+
new_objfile_handler(evt: Optional[ForwardRef('gdb.NewObjFileEvent')]) → None
+
+

GDB event handler for new object file cases.

+
+

+

function exit_handler

+
exit_handler(_: 'gdb.ExitedEvent') → None
+
+

GDB event handler for exit cases.

+
+

+

function memchanged_handler

+
memchanged_handler(_: 'gdb.MemoryChangedEvent') → None
+
+

GDB event handler for mem changes cases.

+
+

+

function regchanged_handler

+
regchanged_handler(_: 'gdb.RegisterChangedEvent') → None
+
+

GDB event handler for reg changes cases.

+
+

+

function get_terminal_size

+
get_terminal_size() → Tuple[int, int]
+
+

Return the current terminal size.

+
+

+

function reset_architecture

+
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

+
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

+
clear_screen(tty: str = '') → None
+
+

Clear the screen.

+
+

+

function format_address

+
format_address(addr: int) → str
+
+

Format the address according to its size.

+
+

+

function format_address_spaces

+
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

+
align_address(address: int) → int
+
+

Align the provided address to the process's native length.

+
+

+

function align_address_to_size

+
align_address_to_size(address: int, align: int) → int
+
+

Align the address to the given size.

+
+

+

function align_address_to_page

+
align_address_to_page(address: int) → int
+
+

Align the address to a page.

+
+

+

function parse_address

+
parse_address(address: str) → int
+
+

Parse an address and return it as an Integer.

+
+

+

function is_in_x86_kernel

+
is_in_x86_kernel(address: int) → bool
+
+
+

+

function is_remote_debug

+
is_remote_debug() → bool
+
+

"Return True is the current debugging session is running through GDB remote session.

+
+

+

function de_bruijn

+
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

+
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

+
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

+
gef_convenience(value: Union[str, bytes]) → str
+
+

Defines a new convenience value.

+
+

+

function parse_string_range

+
parse_string_range(s: str) → Iterator[int]
+
+

Parses an address range (e.g. 0x400000-0x401000)

+
+

+

function gef_get_pie_breakpoint

+
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

+
endian_str() → str
+
+

endian_str is DEPRECATED and will be removed in the future. + Use str(gef.arch.endianness) instead

+
+

+

function get_gef_setting

+
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

+
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

+
gef_getpagesize() → int
+
+

gef_getpagesize is DEPRECATED and will be removed in the future. + Use gef.session.pagesize

+
+

+

function gef_read_canary

+
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

+
get_pid() → int
+
+

get_pid is DEPRECATED and will be removed in the future. + Use gef.session.pid

+
+

+

function get_filename

+
get_filename() → str
+
+

get_filename is DEPRECATED and will be removed in the future. + Use gef.session.file.name

+
+

+

function get_glibc_arena

+
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

+
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

+
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

+
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

+
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

+
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

+
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

+
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

+
register(
+    cls: Union[Type[ForwardRef('GenericCommand')], Type[ForwardRef('GenericFunction')]]
+) → Union[Type[ForwardRef('GenericCommand')], Type[ForwardRef('GenericFunction')]]
+
+
+

+

function register_function

+
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

+
canary_address() → int
+
+
+

+

function AARCH64.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function AARCH64.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → int
+
+
+

+

function AARCH64.is_aarch32

+
is_aarch32() → bool
+
+

Determine if the CPU is currently in AARCH32 mode from runtime.

+
+

+

function AARCH64.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function AARCH64.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function AARCH64.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function AARCH64.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function AARCH64.is_thumb

+
is_thumb() → bool
+
+

Determine if the machine is currently in THUMB mode.

+
+

+

function AARCH64.is_thumb32

+
is_thumb32() → bool
+
+

Determine if the CPU is currently in THUMB32 mode from runtime.

+
+

+

function AARCH64.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function AARCH64.register

+
register(name: str) → int
+
+
+

+

function AARCH64.reset_caches

+
reset_caches() → None
+
+
+

+

function AARCH64.supports_gdb_arch

+
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

+
canary_address() → int
+
+
+

+

function ARM.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function ARM.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → int
+
+
+

+

function ARM.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function ARM.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function ARM.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function ARM.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function ARM.is_thumb

+
is_thumb() → bool
+
+

Determine if the machine is currently in THUMB mode.

+
+

+

function ARM.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function ARM.register

+
register(name: str) → int
+
+
+

+

function ARM.reset_caches

+
reset_caches() → None
+
+
+

+

function ARM.supports_gdb_arch

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property ASLRCommand.settings

+

Return the list of settings for this command.

+
+

+

function ASLRCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function ASLRCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ASLRCommand.post_load

+
post_load() → None
+
+
+

+

function ASLRCommand.pre_load

+
pre_load() → None
+
+
+

+

function ASLRCommand.usage

+
usage() → None
+
+
+

class Address

+

GEF representation of memory addresses.

+

+

function Address.__init__

+
__init__(**kwargs: Any) → None
+
+
+

property Address.valid

+
+

+

function Address.dereference

+
dereference() → Optional[int]
+
+
+

+

function Address.is_in_heap_segment

+
is_in_heap_segment() → bool
+
+
+

+

function Address.is_in_stack_segment

+
is_in_stack_segment() → bool
+
+
+

+

function Address.is_in_text_segment

+
is_in_text_segment() → bool
+
+
+

class AliasesAddCommand

+

Command to add aliases.

+

+

function AliasesAddCommand.__init__

+
__init__() → None
+
+
+

property AliasesAddCommand.settings

+

Return the list of settings for this command.

+
+

+

function AliasesAddCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function AliasesAddCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function AliasesAddCommand.post_load

+
post_load() → None
+
+
+

+

function AliasesAddCommand.pre_load

+
pre_load() → None
+
+
+

+

function AliasesAddCommand.usage

+
usage() → None
+
+
+

class AliasesCommand

+

Base command to add, remove, or list aliases.

+

+

function AliasesCommand.__init__

+
__init__() → None
+
+
+

property AliasesCommand.settings

+

Return the list of settings for this command.

+
+

+

function AliasesCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function AliasesCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function AliasesCommand.post_load

+
post_load() → None
+
+
+

+

function AliasesCommand.pre_load

+
pre_load() → None
+
+
+

+

function AliasesCommand.usage

+
usage() → None
+
+
+

class AliasesListCommand

+

Command to list aliases.

+

+

function AliasesListCommand.__init__

+
__init__() → None
+
+
+

property AliasesListCommand.settings

+

Return the list of settings for this command.

+
+

+

function AliasesListCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function AliasesListCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function AliasesListCommand.post_load

+
post_load() → None
+
+
+

+

function AliasesListCommand.pre_load

+
pre_load() → None
+
+
+

+

function AliasesListCommand.usage

+
usage() → None
+
+
+

class AliasesRmCommand

+

Command to remove aliases.

+

+

function AliasesRmCommand.__init__

+
__init__() → None
+
+
+

property AliasesRmCommand.settings

+

Return the list of settings for this command.

+
+

+

function AliasesRmCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function AliasesRmCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function AliasesRmCommand.post_load

+
post_load() → None
+
+
+

+

function AliasesRmCommand.pre_load

+
pre_load() → None
+
+
+

+

function AliasesRmCommand.usage

+
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

+
canary_address() → int
+
+
+

+

function Architecture.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function Architecture.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int]
+
+
+

+

function Architecture.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function Architecture.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function Architecture.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function Architecture.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function Architecture.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function Architecture.register

+
register(name: str) → int
+
+
+

+

function Architecture.reset_caches

+
reset_caches() → None
+
+
+

+

function Architecture.supports_gdb_arch

+
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__

+
__init__() → None
+
+
+

+

function BssBaseFunction.arg_to_long

+
arg_to_long(args: List, index: int, default: int = 0) → int
+
+
+

+

function BssBaseFunction.do_invoke

+
do_invoke(args: List) → int
+
+
+

+

function BssBaseFunction.invoke

+
invoke(*args: Any) → int
+
+
+

class CanaryCommand

+

Shows the canary value of the current process.

+

+

function CanaryCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property CanaryCommand.settings

+

Return the list of settings for this command.

+
+

+

function CanaryCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function CanaryCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function CanaryCommand.post_load

+
post_load() → None
+
+
+

+

function CanaryCommand.pre_load

+
pre_load() → None
+
+
+

+

function CanaryCommand.usage

+
usage() → None
+
+
+

class ChangeFdCommand

+

ChangeFdCommand: redirect file descriptor during runtime.

+

+

function ChangeFdCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property ChangeFdCommand.settings

+

Return the list of settings for this command.

+
+

+

function ChangeFdCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function ChangeFdCommand.get_fd_from_result

+
get_fd_from_result(res: str) → int
+
+
+

+

function ChangeFdCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ChangeFdCommand.post_load

+
post_load() → None
+
+
+

+

function ChangeFdCommand.pre_load

+
pre_load() → None
+
+
+

+

function ChangeFdCommand.usage

+
usage() → None
+
+
+

class ChangePermissionBreakpoint

+

When hit, this temporary breakpoint will restore the original code, and position $pc correctly.

+

+

function ChangePermissionBreakpoint.__init__

+
__init__(loc: str, code: ByteString, pc: int) → None
+
+
+

+

function ChangePermissionBreakpoint.stop

+
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__

+
__init__() → None
+
+
+

property ChecksecCommand.settings

+

Return the list of settings for this command.

+
+

+

function ChecksecCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function ChecksecCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ChecksecCommand.post_load

+
post_load() → None
+
+
+

+

function ChecksecCommand.pre_load

+
pre_load() → None
+
+
+

+

function ChecksecCommand.print_security_properties

+
print_security_properties(filename: str) → None
+
+
+

+

function ChecksecCommand.usage

+
usage() → None
+
+
+

class Color

+

Used to colorify terminal output.

+
+

+

function Color.blinkify

+
blinkify(msg: str) → str
+
+
+

+

function Color.blueify

+
blueify(msg: str) → str
+
+
+

+

function Color.boldify

+
boldify(msg: str) → str
+
+
+

+

function Color.colorify

+
colorify(text: str, attrs: str) → str
+
+

Color text according to the given attributes.

+
+

+

function Color.cyanify

+
cyanify(msg: str) → str
+
+
+

+

function Color.grayify

+
grayify(msg: str) → str
+
+
+

+

function Color.greenify

+
greenify(msg: str) → str
+
+
+

+

function Color.highlightify

+
highlightify(msg: str) → str
+
+
+

+

function Color.light_grayify

+
light_grayify(msg: str) → str
+
+
+

+

function Color.pinkify

+
pinkify(msg: str) → str
+
+
+

+

function Color.redify

+
redify(msg: str) → str
+
+
+

+

function Color.underlinify

+
underlinify(msg: str) → str
+
+
+

+

function Color.yellowify

+
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__

+
__init__() → None
+
+
+

property ContextCommand.settings

+

Return the list of settings for this command.

+
+

+

function ContextCommand.add_setting

+
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

+
addr_has_breakpoint(address: int, bp_locations: List[str]) → bool
+
+
+

+

function ContextCommand.context_additional_information

+
context_additional_information() → None
+
+
+

+

function ContextCommand.context_args

+
context_args() → None
+
+
+

+

function ContextCommand.context_code

+
context_code() → None
+
+
+

+

function ContextCommand.context_memory

+
context_memory() → None
+
+
+

+

function ContextCommand.context_regs

+
context_regs() → None
+
+
+

+

function ContextCommand.context_source

+
context_source() → None
+
+
+

+

function ContextCommand.context_stack

+
context_stack() → None
+
+
+

+

function ContextCommand.context_threads

+
context_threads() → None
+
+
+

+

function ContextCommand.context_title

+
context_title(m: Optional[str]) → None
+
+
+

+

function ContextCommand.context_trace

+
context_trace() → None
+
+
+

+

function ContextCommand.del_setting

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function ContextCommand.empty_extra_messages

+
empty_extra_messages(_) → None
+
+
+

+

function ContextCommand.get_pc_context_info

+
get_pc_context_info(pc: int, line: str) → str
+
+
+

+

function ContextCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ContextCommand.line_has_breakpoint

+
line_has_breakpoint(
+    file_name: str,
+    line_number: int,
+    bp_locations: List[str]
+) → bool
+
+
+

+

function ContextCommand.post_load

+
post_load() → None
+
+
+

+

function ContextCommand.pre_load

+
pre_load() → None
+
+
+

+

function ContextCommand.print_arguments_from_symbol

+
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

+
print_guessed_arguments(function_name: str) → None
+
+

When no symbol, read the current basic block and look for "interesting" instructions.

+
+

+

function ContextCommand.show_legend

+
show_legend() → None
+
+
+

+

function ContextCommand.update_registers

+
update_registers(_) → None
+
+
+

+

function ContextCommand.usage

+
usage() → None
+
+
+

class DereferenceCommand

+

Dereference recursively from an address and display information. This acts like WinDBG dps command.

+

+

function DereferenceCommand.__init__

+
__init__() → None
+
+
+

property DereferenceCommand.settings

+

Return the list of settings for this command.

+
+

+

function DereferenceCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function DereferenceCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function DereferenceCommand.post_load

+
post_load() → None
+
+
+

+

function DereferenceCommand.pprint_dereferenced

+
pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) → str
+
+
+

+

function DereferenceCommand.pre_load

+
pre_load() → None
+
+
+

+

function DereferenceCommand.usage

+
usage() → None
+
+
+

class DetailRegistersCommand

+

Display full details on one, many or all registers value from current architecture.

+

+

function DetailRegistersCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property DetailRegistersCommand.settings

+

Return the list of settings for this command.

+
+

+

function DetailRegistersCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function DetailRegistersCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function DetailRegistersCommand.post_load

+
post_load() → None
+
+
+

+

function DetailRegistersCommand.pre_load

+
pre_load() → None
+
+
+

+

function DetailRegistersCommand.usage

+
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__

+
__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

+
is_valid(path: pathlib.Path) → bool
+
+
+

+

function Elf.read

+
read(size: int) → bytes
+
+
+

+

function Elf.read_and_unpack

+
read_and_unpack(fmt: str) → Tuple[Any, ...]
+
+
+

+

function Elf.seek

+
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__

+
__init__() → None
+
+
+

property ElfInfoCommand.settings

+

Return the list of settings for this command.

+
+

+

function ElfInfoCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function ElfInfoCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ElfInfoCommand.post_load

+
post_load() → None
+
+
+

+

function ElfInfoCommand.pre_load

+
pre_load() → None
+
+
+

+

function ElfInfoCommand.usage

+
usage() → None
+
+
+

class Endianness

+

An enumeration.

+
+

class EntryBreakBreakpoint

+

Breakpoint used internally to stop execution at the most convenient entry point.

+

+

function EntryBreakBreakpoint.__init__

+
__init__(location: str) → None
+
+
+

+

function EntryBreakBreakpoint.stop

+
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__

+
__init__() → None
+
+
+

property EntryPointBreakCommand.settings

+

Return the list of settings for this command.

+
+

+

function EntryPointBreakCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function EntryPointBreakCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function EntryPointBreakCommand.post_load

+
post_load() → None
+
+
+

+

function EntryPointBreakCommand.pre_load

+
pre_load() → None
+
+
+

+

function EntryPointBreakCommand.set_init_tbreak

+
set_init_tbreak(addr: int) → EntryBreakBreakpoint
+
+
+

+

function EntryPointBreakCommand.set_init_tbreak_pie

+
set_init_tbreak_pie(addr: int, argv: List[str]) → EntryBreakBreakpoint
+
+
+

+

function EntryPointBreakCommand.usage

+
usage() → None
+
+
+

class ExternalStructureManager

+

+

function ExternalStructureManager.__init__

+
__init__() → None
+
+
+

property ExternalStructureManager.modules

+
+

property ExternalStructureManager.path

+
+

property ExternalStructureManager.structures

+
+

handler ExternalStructureManager.find

+
+

+

function ExternalStructureManager.clear_caches

+
clear_caches() → None
+
+
+

class FileFormat

+

+

function FileFormat.__init__

+
__init__(path: Union[str, pathlib.Path]) → None
+
+
+

+

function FileFormat.is_valid

+
is_valid(path: pathlib.Path) → bool
+
+
+

class FileFormatSection

+
+

class FlagsCommand

+

Edit flags in a human friendly way.

+

+

function FlagsCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property FlagsCommand.settings

+

Return the list of settings for this command.

+
+

+

function FlagsCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function FlagsCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function FlagsCommand.post_load

+
post_load() → None
+
+
+

+

function FlagsCommand.pre_load

+
pre_load() → None
+
+
+

+

function FlagsCommand.usage

+
usage() → None
+
+
+

class FormatStringBreakpoint

+

Inspect stack for format string.

+

+

function FormatStringBreakpoint.__init__

+
__init__(spec: str, num_args: int) → None
+
+
+

+

function FormatStringBreakpoint.stop

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property FormatStringSearchCommand.settings

+

Return the list of settings for this command.

+
+

+

function FormatStringSearchCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function FormatStringSearchCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function FormatStringSearchCommand.post_load

+
post_load() → None
+
+
+

+

function FormatStringSearchCommand.pre_load

+
pre_load() → None
+
+
+

+

function FormatStringSearchCommand.usage

+
usage() → None
+
+
+

class GdbRemoveReadlineFinder

+
+

+

function GdbRemoveReadlineFinder.find_module

+
find_module(fullname, path=None)
+
+
+

+

function GdbRemoveReadlineFinder.load_module

+
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__

+
__init__() → None
+
+
+

+

function Gef.reinitialize_managers

+
reinitialize_managers() → None
+
+

Reinitialize the managers. Avoid calling this function directly, using pi reset() is preferred

+
+

+

function Gef.reset_caches

+
reset_caches() → None
+
+

Recursively clean the cache of all the managers. Avoid calling this function directly, using reset-cache is preferred

+
+

+

function Gef.setup

+
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__

+
__init__(
+    alias: str,
+    command: str,
+    completer_class: int = 0,
+    command_class: int = -1
+) → None
+
+
+

+

function GefAlias.invoke

+
invoke(args: Any, from_tty: bool) → None
+
+
+

+

function GefAlias.lookup_command

+
lookup_command(cmd: str) → Optional[Tuple[str, __main__.GenericCommand]]
+
+
+

class GefCommand

+

GEF main command: view all new commands by typing gef.

+

+

function GefCommand.__init__

+
__init__() → None
+
+
+

property GefCommand.loaded_command_names

+
+

property GefCommand.loaded_commands

+
+

property GefCommand.loaded_functions

+
+

property GefCommand.missing_commands

+
+

+

function GefCommand.add_context_pane

+
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

+
invoke(args: Any, from_tty: bool) → None
+
+
+

+

function GefCommand.load

+
load() → None
+
+

Load all the commands and functions defined by GEF into GDB.

+
+

+

function GefCommand.load_extra_plugins

+
load_extra_plugins() → int
+
+
+

+

function GefCommand.setup

+
setup() → None
+
+
+

+

function GefCommand.show_banner

+
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__

+
__init__() → None
+
+
+

+

function GefConfigCommand.complete

+
complete(text: str, word: str) → List[str]
+
+
+

+

function GefConfigCommand.invoke

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GefConfigCommand.print_setting

+
print_setting(plugin_name: str, verbose: bool = False) → None
+
+
+

+

function GefConfigCommand.print_settings

+
print_settings() → None
+
+
+

+

function GefConfigCommand.set_setting

+
set_setting(argv: Tuple[str, Any]) → None
+
+
+

class GefFunctionsCommand

+

List the convenience functions provided by GEF.

+

+

function GefFunctionsCommand.__init__

+
__init__() → None
+
+
+

property GefFunctionsCommand.settings

+

Return the list of settings for this command.

+
+

+

function GefFunctionsCommand.add_setting

+
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

+
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

+
do_invoke(argv) → None
+
+
+

+

function GefFunctionsCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GefFunctionsCommand.post_load

+
post_load() → None
+
+
+

+

function GefFunctionsCommand.pre_load

+
pre_load() → None
+
+
+

+

function GefFunctionsCommand.usage

+
usage() → None
+
+
+

class GefHeapManager

+

Class managing session heap.

+

+

function GefHeapManager.__init__

+
__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

+
csize2tidx(size: int) → int
+
+
+

+

function GefHeapManager.malloc_align_address

+
malloc_align_address(address: int) → int
+
+

Align addresses according to glibc's MALLOC_ALIGNMENT. See also Issue #689 on Github

+
+

+

function GefHeapManager.reset_caches

+
reset_caches() → None
+
+
+

+

function GefHeapManager.tidx2size

+
tidx2size(idx: int) → int
+
+
+

class GefHelpCommand

+

GEF help sub-command.

+

+

function GefHelpCommand.__init__

+
__init__() → None
+
+
+

+

function GefHelpCommand.invoke

+
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__

+
__init__() → None
+
+
+

+

function GefInstallExtraScriptCommand.invoke

+
invoke(argv: str, from_tty: bool) → None
+
+
+

class GefLibcManager

+

Class managing everything libc-related (except heap).

+

+

function GefLibcManager.__init__

+
__init__() → None
+
+
+

property GefLibcManager.version

+
+

handler GefLibcManager.find_libc_version

+
+

+

function GefLibcManager.reset_caches

+
reset_caches() → None
+
+

Reset the LRU-cached attributes

+
+

class GefManager

+
+

+

function GefManager.reset_caches

+
reset_caches() → None
+
+

Reset the LRU-cached attributes

+
+

class GefMemoryManager

+

Class that manages memory access for gef.

+

+

function GefMemoryManager.__init__

+
__init__() → None
+
+
+

property GefMemoryManager.maps

+
+

+

function GefMemoryManager.read

+
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

+
read_ascii_string(address: int) → Optional[str]
+
+

Read an ASCII string from memory

+
+

+

function GefMemoryManager.read_cstring

+
read_cstring(
+    address: int,
+    max_length: int = 50,
+    encoding: Optional[str] = None
+) → str
+
+

Return a C-string read from memory.

+
+

+

function GefMemoryManager.read_integer

+
read_integer(addr: int) → int
+
+

Return an integer read from memory.

+
+

+

function GefMemoryManager.reset_caches

+
reset_caches() → None
+
+
+

+

function GefMemoryManager.write

+
write(address: int, buffer: ByteString, length: Optional[int] = None) → 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__

+
__init__() → None
+
+
+

+

function GefMissingCommand.invoke

+
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__

+
__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

+
close() → None
+
+
+

+

function GefRemoteSessionManager.connect

+
connect(pid: int) → bool
+
+

Connect to remote target. If in extended mode, also attach to the given PID.

+
+

+

function GefRemoteSessionManager.in_qemu_user

+
in_qemu_user() → bool
+
+
+

+

function GefRemoteSessionManager.remote_objfile_event_handler

+
remote_objfile_event_handler(evt: 'gdb.NewObjFileEvent') → None
+
+
+

+

function GefRemoteSessionManager.reset_caches

+
reset_caches() → None
+
+
+

+

function GefRemoteSessionManager.setup

+
setup() → bool
+
+
+

+

function GefRemoteSessionManager.sync

+
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__

+
__init__() → None
+
+
+

+

function GefRestoreCommand.invoke

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GefRestoreCommand.reload

+
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__

+
__init__() → None
+
+
+

+

function GefRunCommand.invoke

+
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__

+
__init__() → None
+
+
+

+

function GefSaveCommand.invoke

+
invoke(args: Any, from_tty: bool) → None
+
+
+

class GefSessionManager

+

Class managing the runtime properties of GEF.

+

+

function GefSessionManager.__init__

+
__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

+
reset_caches() → None
+
+
+

class GefSetCommand

+

Override GDB set commands with the context from GEF.

+

+

function GefSetCommand.__init__

+
__init__() → None
+
+
+

+

function GefSetCommand.invoke

+
invoke(args: Any, from_tty: bool) → None
+
+
+

class GefSetting

+

Basic class for storing gef settings as objects

+

+

function GefSetting.__init__

+
__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

+
raw_entry(name: str) → GefSetting
+
+
+

class GefThemeCommand

+

Customize GEF appearance.

+

+

function GefThemeCommand.__init__

+
__init__() → None
+
+
+

property GefThemeCommand.settings

+

Return the list of settings for this command.

+
+

+

function GefThemeCommand.add_setting

+
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

+
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

+
do_invoke(args: List[str]) → None
+
+
+

+

function GefThemeCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GefThemeCommand.post_load

+
post_load() → None
+
+
+

+

function GefThemeCommand.pre_load

+
pre_load() → None
+
+
+

+

function GefThemeCommand.usage

+
usage() → None
+
+
+

class GefTmuxSetup

+

Setup a confortable tmux debugging environment.

+

+

function GefTmuxSetup.__init__

+
__init__() → None
+
+
+

+

function GefTmuxSetup.invoke

+
invoke(args: Any, from_tty: bool) → None
+
+
+

+

function GefTmuxSetup.screen_setup

+
screen_setup() → None
+
+

Hackish equivalent of the tmux_setup() function for screen.

+
+

+

function GefTmuxSetup.tmux_setup

+
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__

+
__init__() → None
+
+
+

+

function GefUiManager.reset_caches

+
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

+
canary_address() → int
+
+
+

+

function GenericArchitecture.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function GenericArchitecture.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int]
+
+
+

+

function GenericArchitecture.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function GenericArchitecture.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function GenericArchitecture.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function GenericArchitecture.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function GenericArchitecture.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function GenericArchitecture.register

+
register(name: str) → int
+
+
+

+

function GenericArchitecture.reset_caches

+
reset_caches() → None
+
+
+

+

function GenericArchitecture.supports_gdb_arch

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property GenericCommand.settings

+

Return the list of settings for this command.

+
+

+

function GenericCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function GenericCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GenericCommand.post_load

+
post_load() → None
+
+
+

+

function GenericCommand.pre_load

+
pre_load() → None
+
+
+

+

function GenericCommand.usage

+
usage() → None
+
+
+

class GenericFunction

+

This is an abstract class for invoking convenience functions, should not be instantiated.

+

+

function GenericFunction.__init__

+
__init__() → None
+
+
+

+

function GenericFunction.arg_to_long

+
arg_to_long(args: List, index: int, default: int = 0) → int
+
+
+

+

function GenericFunction.do_invoke

+
do_invoke(args: Any) → int
+
+
+

+

function GenericFunction.invoke

+
invoke(*args: Any) → int
+
+
+

class GlibcArena

+

Glibc arena class

+

+

function GlibcArena.__init__

+
__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

+
bin(i: int) → Tuple[int, int]
+
+
+

+

function GlibcArena.bin_at

+
bin_at(i) → int
+
+
+

+

function GlibcArena.fastbin

+
fastbin(i: int) → Optional[ForwardRef('GlibcFastChunk')]
+
+

Return head chunk in fastbinsY[i].

+
+

+

function GlibcArena.get_heap_for_ptr

+
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

+
get_heap_info_list() → Optional[List[__main__.GlibcHeapInfo]]
+
+
+

+

function GlibcArena.heap_addr

+
heap_addr(allow_unaligned: bool = False) → Optional[int]
+
+
+

+

function GlibcArena.is_main_arena

+
is_main_arena() → bool
+
+
+

+

function GlibcArena.malloc_state_t

+
malloc_state_t() → Type[_ctypes.Structure]
+
+
+

+

function GlibcArena.reset

+
reset()
+
+
+

+

function GlibcArena.verify

+
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__

+
__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

+
get_next_chunk(allow_unaligned: bool = False) → GlibcChunk
+
+
+

+

function GlibcChunk.get_next_chunk_addr

+
get_next_chunk_addr() → int
+
+
+

+

function GlibcChunk.get_prev_chunk_size

+
get_prev_chunk_size() → int
+
+
+

+

function GlibcChunk.get_usable_size

+
get_usable_size() → int
+
+
+

+

function GlibcChunk.has_m_bit

+
has_m_bit() → bool
+
+
+

+

function GlibcChunk.has_n_bit

+
has_n_bit() → bool
+
+
+

+

function GlibcChunk.has_p_bit

+
has_p_bit() → bool
+
+
+

+

function GlibcChunk.is_used

+
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

+
malloc_chunk_t() → Type[_ctypes.Structure]
+
+
+

+

function GlibcChunk.psprint

+
psprint() → str
+
+
+

+

function GlibcChunk.reset

+
reset()
+
+
+

class GlibcFastChunk

+

+

function GlibcFastChunk.__init__

+
__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

+
get_next_chunk(allow_unaligned: bool = False) → GlibcChunk
+
+
+

+

function GlibcFastChunk.get_next_chunk_addr

+
get_next_chunk_addr() → int
+
+
+

+

function GlibcFastChunk.get_prev_chunk_size

+
get_prev_chunk_size() → int
+
+
+

+

function GlibcFastChunk.get_usable_size

+
get_usable_size() → int
+
+
+

+

function GlibcFastChunk.has_m_bit

+
has_m_bit() → bool
+
+
+

+

function GlibcFastChunk.has_n_bit

+
has_n_bit() → bool
+
+
+

+

function GlibcFastChunk.has_p_bit

+
has_p_bit() → bool
+
+
+

+

function GlibcFastChunk.is_used

+
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

+
malloc_chunk_t() → Type[_ctypes.Structure]
+
+
+

+

function GlibcFastChunk.protect_ptr

+
protect_ptr(pos: int, pointer: int) → int
+
+

https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L339

+
+

+

function GlibcFastChunk.psprint

+
psprint() → str
+
+
+

+

function GlibcFastChunk.reset

+
reset()
+
+
+

+

function GlibcFastChunk.reveal_ptr

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property GlibcHeapArenaCommand.settings

+

Return the list of settings for this command.

+
+

+

function GlibcHeapArenaCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function GlibcHeapArenaCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GlibcHeapArenaCommand.post_load

+
post_load() → None
+
+
+

+

function GlibcHeapArenaCommand.pre_load

+
pre_load() → None
+
+
+

+

function GlibcHeapArenaCommand.usage

+
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__

+
__init__() → None
+
+
+

property GlibcHeapBinsCommand.settings

+

Return the list of settings for this command.

+
+

+

function GlibcHeapBinsCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function GlibcHeapBinsCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GlibcHeapBinsCommand.post_load

+
post_load() → None
+
+
+

+

function GlibcHeapBinsCommand.pprint_bin

+
pprint_bin(arena_addr: str, index: int, _type: str = '') → int
+
+
+

+

function GlibcHeapBinsCommand.pre_load

+
pre_load() → None
+
+
+

+

function GlibcHeapBinsCommand.usage

+
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__

+
__init__() → None
+
+
+

property GlibcHeapChunkCommand.settings

+

Return the list of settings for this command.

+
+

+

function GlibcHeapChunkCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function GlibcHeapChunkCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GlibcHeapChunkCommand.post_load

+
post_load() → None
+
+
+

+

function GlibcHeapChunkCommand.pre_load

+
pre_load() → None
+
+
+

+

function GlibcHeapChunkCommand.usage

+
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__

+
__init__() → None
+
+
+

property GlibcHeapChunksCommand.settings

+

Return the list of settings for this command.

+
+

+

function GlibcHeapChunksCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function GlibcHeapChunksCommand.dump_chunks_arena

+
dump_chunks_arena(
+    arena: __main__.GlibcArena,
+    print_arena: bool = False,
+    allow_unaligned: bool = False
+) → None
+
+
+

+

function GlibcHeapChunksCommand.dump_chunks_heap

+
dump_chunks_heap(
+    start: int,
+    end: int,
+    arena: __main__.GlibcArena,
+    allow_unaligned: bool = False
+) → bool
+
+
+

+

function GlibcHeapChunksCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GlibcHeapChunksCommand.post_load

+
post_load() → None
+
+
+

+

function GlibcHeapChunksCommand.pre_load

+
pre_load() → None
+
+
+

+

function GlibcHeapChunksCommand.usage

+
usage() → None
+
+
+

class GlibcHeapCommand

+

Base command to get information about the Glibc heap structure.

+

+

function GlibcHeapCommand.__init__

+
__init__() → None
+
+
+

property GlibcHeapCommand.settings

+

Return the list of settings for this command.

+
+

+

function GlibcHeapCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function GlibcHeapCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GlibcHeapCommand.post_load

+
post_load() → None
+
+
+

+

function GlibcHeapCommand.pre_load

+
pre_load() → None
+
+
+

+

function GlibcHeapCommand.usage

+
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__

+
__init__() → None
+
+
+

property GlibcHeapFastbinsYCommand.settings

+

Return the list of settings for this command.

+
+

+

function GlibcHeapFastbinsYCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function GlibcHeapFastbinsYCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GlibcHeapFastbinsYCommand.post_load

+
post_load() → None
+
+
+

+

function GlibcHeapFastbinsYCommand.pre_load

+
pre_load() → None
+
+
+

+

function GlibcHeapFastbinsYCommand.usage

+
usage() → None
+
+
+

class GlibcHeapInfo

+

Glibc heap_info struct

+

+

function GlibcHeapInfo.__init__

+
__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

+
heap_info_t() → Type[_ctypes.Structure]
+
+
+

+

function GlibcHeapInfo.reset

+
reset()
+
+
+

class GlibcHeapLargeBinsCommand

+

Convenience command for viewing large bins.

+

+

function GlibcHeapLargeBinsCommand.__init__

+
__init__() → None
+
+
+

property GlibcHeapLargeBinsCommand.settings

+

Return the list of settings for this command.

+
+

+

function GlibcHeapLargeBinsCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function GlibcHeapLargeBinsCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GlibcHeapLargeBinsCommand.post_load

+
post_load() → None
+
+
+

+

function GlibcHeapLargeBinsCommand.pre_load

+
pre_load() → None
+
+
+

+

function GlibcHeapLargeBinsCommand.usage

+
usage() → None
+
+
+

class GlibcHeapSetArenaCommand

+

Set the address of the main_arena or the currently selected arena.

+

+

function GlibcHeapSetArenaCommand.__init__

+
__init__() → None
+
+
+

property GlibcHeapSetArenaCommand.settings

+

Return the list of settings for this command.

+
+

+

function GlibcHeapSetArenaCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function GlibcHeapSetArenaCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GlibcHeapSetArenaCommand.post_load

+
post_load() → None
+
+
+

+

function GlibcHeapSetArenaCommand.pre_load

+
pre_load() → None
+
+
+

+

function GlibcHeapSetArenaCommand.usage

+
usage() → None
+
+
+

class GlibcHeapSmallBinsCommand

+

Convenience command for viewing small bins.

+

+

function GlibcHeapSmallBinsCommand.__init__

+
__init__() → None
+
+
+

property GlibcHeapSmallBinsCommand.settings

+

Return the list of settings for this command.

+
+

+

function GlibcHeapSmallBinsCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function GlibcHeapSmallBinsCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GlibcHeapSmallBinsCommand.post_load

+
post_load() → None
+
+
+

+

function GlibcHeapSmallBinsCommand.pre_load

+
pre_load() → None
+
+
+

+

function GlibcHeapSmallBinsCommand.usage

+
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__

+
__init__() → None
+
+
+

property GlibcHeapTcachebinsCommand.settings

+

Return the list of settings for this command.

+
+

+

function GlibcHeapTcachebinsCommand.add_setting

+
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

+
check_thread_ids(tids: List[int]) → List[int]
+
+

Return the subset of tids that are currently valid.

+
+

+

function GlibcHeapTcachebinsCommand.del_setting

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function GlibcHeapTcachebinsCommand.find_tcache

+
find_tcache() → int
+
+

Return the location of the current thread's tcache.

+
+

+

function GlibcHeapTcachebinsCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GlibcHeapTcachebinsCommand.post_load

+
post_load() → None
+
+
+

+

function GlibcHeapTcachebinsCommand.pre_load

+
pre_load() → None
+
+
+

+

function GlibcHeapTcachebinsCommand.tcachebin

+
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

+
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__

+
__init__() → None
+
+
+

property GlibcHeapUnsortedBinsCommand.settings

+

Return the list of settings for this command.

+
+

+

function GlibcHeapUnsortedBinsCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function GlibcHeapUnsortedBinsCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GlibcHeapUnsortedBinsCommand.post_load

+
post_load() → None
+
+
+

+

function GlibcHeapUnsortedBinsCommand.pre_load

+
pre_load() → None
+
+
+

+

function GlibcHeapUnsortedBinsCommand.usage

+
usage() → None
+
+
+

class GlibcTcacheChunk

+

+

function GlibcTcacheChunk.__init__

+
__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

+
get_next_chunk(allow_unaligned: bool = False) → GlibcChunk
+
+
+

+

function GlibcTcacheChunk.get_next_chunk_addr

+
get_next_chunk_addr() → int
+
+
+

+

function GlibcTcacheChunk.get_prev_chunk_size

+
get_prev_chunk_size() → int
+
+
+

+

function GlibcTcacheChunk.get_usable_size

+
get_usable_size() → int
+
+
+

+

function GlibcTcacheChunk.has_m_bit

+
has_m_bit() → bool
+
+
+

+

function GlibcTcacheChunk.has_n_bit

+
has_n_bit() → bool
+
+
+

+

function GlibcTcacheChunk.has_p_bit

+
has_p_bit() → bool
+
+
+

+

function GlibcTcacheChunk.is_used

+
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

+
malloc_chunk_t() → Type[_ctypes.Structure]
+
+
+

+

function GlibcTcacheChunk.protect_ptr

+
protect_ptr(pos: int, pointer: int) → int
+
+

https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L339

+
+

+

function GlibcTcacheChunk.psprint

+
psprint() → str
+
+
+

+

function GlibcTcacheChunk.reset

+
reset()
+
+
+

+

function GlibcTcacheChunk.reveal_ptr

+
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__

+
__init__() → None
+
+
+

+

function GotBaseFunction.arg_to_long

+
arg_to_long(args: List, index: int, default: int = 0) → int
+
+
+

+

function GotBaseFunction.do_invoke

+
do_invoke(args: List) → int
+
+
+

+

function GotBaseFunction.invoke

+
invoke(*args: Any) → int
+
+
+

class GotCommand

+

Display current status of the got inside the process.

+

+

function GotCommand.__init__

+
__init__()
+
+
+

property GotCommand.settings

+

Return the list of settings for this command.

+
+

+

function GotCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function GotCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function GotCommand.post_load

+
post_load() → None
+
+
+

+

function GotCommand.pre_load

+
pre_load() → None
+
+
+

+

function GotCommand.usage

+
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__

+
__init__() → None
+
+
+

property HeapAnalysisCommand.settings

+

Return the list of settings for this command.

+
+

+

function HeapAnalysisCommand.add_setting

+
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

+
clean(_: 'gdb.Event') → None
+
+
+

+

function HeapAnalysisCommand.del_setting

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function HeapAnalysisCommand.dump_tracked_allocations

+
dump_tracked_allocations() → None
+
+
+

+

function HeapAnalysisCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function HeapAnalysisCommand.post_load

+
post_load() → None
+
+
+

+

function HeapAnalysisCommand.pre_load

+
pre_load() → None
+
+
+

+

function HeapAnalysisCommand.setup

+
setup() → None
+
+
+

+

function HeapAnalysisCommand.usage

+
usage() → None
+
+
+

class HeapBaseFunction

+

Return the current heap base address plus an optional offset.

+

+

function HeapBaseFunction.__init__

+
__init__() → None
+
+
+

+

function HeapBaseFunction.arg_to_long

+
arg_to_long(args: List, index: int, default: int = 0) → int
+
+
+

+

function HeapBaseFunction.do_invoke

+
do_invoke(args: List) → int
+
+
+

+

function HeapBaseFunction.invoke

+
invoke(*args: Any) → int
+
+
+

class HexdumpByteCommand

+

Display SIZE lines of hexdump as BYTE from the memory location pointed by ADDRESS.

+

+

function HexdumpByteCommand.__init__

+
__init__() → None
+
+
+

property HexdumpByteCommand.settings

+

Return the list of settings for this command.

+
+

+

function HexdumpByteCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function HexdumpByteCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function HexdumpByteCommand.post_load

+
post_load() → None
+
+
+

+

function HexdumpByteCommand.pre_load

+
pre_load() → None
+
+
+

+

function HexdumpByteCommand.usage

+
usage() → None
+
+
+

class HexdumpCommand

+

Display SIZE lines of hexdump from the memory location pointed by LOCATION.

+

+

function HexdumpCommand.__init__

+
__init__() → None
+
+
+

property HexdumpCommand.settings

+

Return the list of settings for this command.

+
+

+

function HexdumpCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function HexdumpCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function HexdumpCommand.post_load

+
post_load() → None
+
+
+

+

function HexdumpCommand.pre_load

+
pre_load() → None
+
+
+

+

function HexdumpCommand.usage

+
usage() → None
+
+
+

class HexdumpDwordCommand

+

Display SIZE lines of hexdump as DWORD from the memory location pointed by ADDRESS.

+

+

function HexdumpDwordCommand.__init__

+
__init__() → None
+
+
+

property HexdumpDwordCommand.settings

+

Return the list of settings for this command.

+
+

+

function HexdumpDwordCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function HexdumpDwordCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function HexdumpDwordCommand.post_load

+
post_load() → None
+
+
+

+

function HexdumpDwordCommand.pre_load

+
pre_load() → None
+
+
+

+

function HexdumpDwordCommand.usage

+
usage() → None
+
+
+

class HexdumpQwordCommand

+

Display SIZE lines of hexdump as QWORD from the memory location pointed by ADDRESS.

+

+

function HexdumpQwordCommand.__init__

+
__init__() → None
+
+
+

property HexdumpQwordCommand.settings

+

Return the list of settings for this command.

+
+

+

function HexdumpQwordCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function HexdumpQwordCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function HexdumpQwordCommand.post_load

+
post_load() → None
+
+
+

+

function HexdumpQwordCommand.pre_load

+
pre_load() → None
+
+
+

+

function HexdumpQwordCommand.usage

+
usage() → None
+
+
+

class HexdumpWordCommand

+

Display SIZE lines of hexdump as WORD from the memory location pointed by ADDRESS.

+

+

function HexdumpWordCommand.__init__

+
__init__() → None
+
+
+

property HexdumpWordCommand.settings

+

Return the list of settings for this command.

+
+

+

function HexdumpWordCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function HexdumpWordCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function HexdumpWordCommand.post_load

+
post_load() → None
+
+
+

+

function HexdumpWordCommand.pre_load

+
pre_load() → None
+
+
+

+

function HexdumpWordCommand.usage

+
usage() → None
+
+
+

class HighlightAddCommand

+

Add a match to the highlight table.

+

+

function HighlightAddCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property HighlightAddCommand.settings

+

Return the list of settings for this command.

+
+

+

function HighlightAddCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function HighlightAddCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function HighlightAddCommand.post_load

+
post_load() → None
+
+
+

+

function HighlightAddCommand.pre_load

+
pre_load() → None
+
+
+

+

function HighlightAddCommand.usage

+
usage() → None
+
+
+

class HighlightClearCommand

+

Clear the highlight table, remove all matches.

+

+

function HighlightClearCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property HighlightClearCommand.settings

+

Return the list of settings for this command.

+
+

+

function HighlightClearCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function HighlightClearCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function HighlightClearCommand.post_load

+
post_load() → None
+
+
+

+

function HighlightClearCommand.pre_load

+
pre_load() → None
+
+
+

+

function HighlightClearCommand.usage

+
usage() → None
+
+
+

class HighlightCommand

+

Highlight user-defined text matches in GEF output universally.

+

+

function HighlightCommand.__init__

+
__init__() → None
+
+
+

property HighlightCommand.settings

+

Return the list of settings for this command.

+
+

+

function HighlightCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function HighlightCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function HighlightCommand.post_load

+
post_load() → None
+
+
+

+

function HighlightCommand.pre_load

+
pre_load() → None
+
+
+

+

function HighlightCommand.usage

+
usage() → None
+
+
+

class HighlightListCommand

+

Show the current highlight table with matches to colors.

+

+

function HighlightListCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property HighlightListCommand.settings

+

Return the list of settings for this command.

+
+

+

function HighlightListCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function HighlightListCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function HighlightListCommand.post_load

+
post_load() → None
+
+
+

+

function HighlightListCommand.pre_load

+
pre_load() → None
+
+
+

+

function HighlightListCommand.print_highlight_table

+
print_highlight_table() → None
+
+
+

+

function HighlightListCommand.usage

+
usage() → None
+
+
+

class HighlightRemoveCommand

+

Remove a match in the highlight table.

+

+

function HighlightRemoveCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property HighlightRemoveCommand.settings

+

Return the list of settings for this command.

+
+

+

function HighlightRemoveCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function HighlightRemoveCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function HighlightRemoveCommand.post_load

+
post_load() → None
+
+
+

+

function HighlightRemoveCommand.pre_load

+
pre_load() → None
+
+
+

+

function HighlightRemoveCommand.usage

+
usage() → None
+
+
+

class Instruction

+

GEF representation of a CPU instruction.

+

+

function Instruction.__init__

+
__init__(
+    address: int,
+    location: str,
+    mnemo: str,
+    operands: List[str],
+    opcodes: bytes
+) → None
+
+
+

+

function Instruction.is_valid

+
is_valid() → bool
+
+
+

+

function Instruction.next

+
next() → Instruction
+
+
+

+

function Instruction.size

+
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

+
canary_address() → int
+
+
+

+

function MIPS.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function MIPS.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int]
+
+
+

+

function MIPS.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function MIPS.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function MIPS.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function MIPS.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function MIPS.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function MIPS.register

+
register(name: str) → int
+
+
+

+

function MIPS.reset_caches

+
reset_caches() → None
+
+
+

+

function MIPS.supports_gdb_arch

+
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

+
canary_address() → int
+
+
+

+

function MIPS64.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function MIPS64.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int]
+
+
+

+

function MIPS64.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function MIPS64.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function MIPS64.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function MIPS64.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function MIPS64.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function MIPS64.register

+
register(name: str) → int
+
+
+

+

function MIPS64.reset_caches

+
reset_caches() → None
+
+
+

+

function MIPS64.supports_gdb_arch

+
supports_gdb_arch(gdb_arch: str) → Optional[bool]
+
+
+

class MemoryCommand

+

Add or remove address ranges to the memory view.

+

+

function MemoryCommand.__init__

+
__init__() → None
+
+
+

property MemoryCommand.settings

+

Return the list of settings for this command.

+
+

+

function MemoryCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function MemoryCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function MemoryCommand.post_load

+
post_load() → None
+
+
+

+

function MemoryCommand.pre_load

+
pre_load() → None
+
+
+

+

function MemoryCommand.usage

+
usage() → None
+
+
+

class MemoryUnwatchCommand

+

Removes address ranges to the memory view.

+

+

function MemoryUnwatchCommand.__init__

+
__init__() → None
+
+
+

property MemoryUnwatchCommand.settings

+

Return the list of settings for this command.

+
+

+

function MemoryUnwatchCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function MemoryUnwatchCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function MemoryUnwatchCommand.post_load

+
post_load() → None
+
+
+

+

function MemoryUnwatchCommand.pre_load

+
pre_load() → None
+
+
+

+

function MemoryUnwatchCommand.usage

+
usage() → None
+
+
+

class MemoryWatchCommand

+

Adds address ranges to the memory view.

+

+

function MemoryWatchCommand.__init__

+
__init__() → None
+
+
+

property MemoryWatchCommand.settings

+

Return the list of settings for this command.

+
+

+

function MemoryWatchCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function MemoryWatchCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function MemoryWatchCommand.post_load

+
post_load() → None
+
+
+

+

function MemoryWatchCommand.pre_load

+
pre_load() → None
+
+
+

+

function MemoryWatchCommand.usage

+
usage() → None
+
+
+

class MemoryWatchListCommand

+

Lists all watchpoints to display in context layout.

+

+

function MemoryWatchListCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property MemoryWatchListCommand.settings

+

Return the list of settings for this command.

+
+

+

function MemoryWatchListCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function MemoryWatchListCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function MemoryWatchListCommand.post_load

+
post_load() → None
+
+
+

+

function MemoryWatchListCommand.pre_load

+
pre_load() → None
+
+
+

+

function MemoryWatchListCommand.usage

+
usage() → None
+
+
+

class MemoryWatchResetCommand

+

Removes all watchpoints.

+

+

function MemoryWatchResetCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property MemoryWatchResetCommand.settings

+

Return the list of settings for this command.

+
+

+

function MemoryWatchResetCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function MemoryWatchResetCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function MemoryWatchResetCommand.post_load

+
post_load() → None
+
+
+

+

function MemoryWatchResetCommand.pre_load

+
pre_load() → None
+
+
+

+

function MemoryWatchResetCommand.usage

+
usage() → None
+
+
+

class NamedBreakpoint

+

Breakpoint which shows a specified name, when hit.

+

+

function NamedBreakpoint.__init__

+
__init__(location: str, name: str) → None
+
+
+

+

function NamedBreakpoint.stop

+
stop() → bool
+
+
+

class NamedBreakpointCommand

+

Sets a breakpoint and assigns a name to it, which will be shown, when it's hit.

+

+

function NamedBreakpointCommand.__init__

+
__init__() → None
+
+
+

property NamedBreakpointCommand.settings

+

Return the list of settings for this command.

+
+

+

function NamedBreakpointCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function NamedBreakpointCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function NamedBreakpointCommand.post_load

+
post_load() → None
+
+
+

+

function NamedBreakpointCommand.pre_load

+
pre_load() → None
+
+
+

+

function NamedBreakpointCommand.usage

+
usage() → None
+
+
+

class NopCommand

+

Patch the instruction(s) pointed by parameters with NOP. Note: this command is architecture aware.

+

+

function NopCommand.__init__

+
__init__() → None
+
+
+

property NopCommand.settings

+

Return the list of settings for this command.

+
+

+

function NopCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function NopCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function NopCommand.post_load

+
post_load() → None
+
+
+

+

function NopCommand.pre_load

+
pre_load() → None
+
+
+

+

function NopCommand.usage

+
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__

+
__init__() → None
+
+
+

property PCustomCommand.settings

+

Return the list of settings for this command.

+
+

+

function PCustomCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PCustomCommand.explode_type

+
explode_type(arg: str) → Tuple[str, str]
+
+
+

+

function PCustomCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PCustomCommand.post_load

+
post_load() → None
+
+
+

+

function PCustomCommand.pre_load

+
pre_load() → None
+
+
+

+

function PCustomCommand.usage

+
usage() → None
+
+
+

class PCustomEditCommand

+

PCustom: edit the content of a given structure

+

+

function PCustomEditCommand.__init__

+
__init__() → None
+
+
+

property PCustomEditCommand.settings

+

Return the list of settings for this command.

+
+

+

function PCustomEditCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function PCustomEditCommand.explode_type

+
explode_type(arg: str) → Tuple[str, str]
+
+
+

+

function PCustomEditCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PCustomEditCommand.post_load

+
post_load() → None
+
+
+

+

function PCustomEditCommand.pre_load

+
pre_load() → None
+
+
+

+

function PCustomEditCommand.usage

+
usage() → None
+
+
+

class PCustomListCommand

+

PCustom: list available structures

+

+

function PCustomListCommand.__init__

+
__init__() → None
+
+
+

property PCustomListCommand.settings

+

Return the list of settings for this command.

+
+

+

function PCustomListCommand.add_setting

+
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

+
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

+
do_invoke(_: List) → None
+
+

Dump the list of all the structures and their respective.

+
+

+

function PCustomListCommand.explode_type

+
explode_type(arg: str) → Tuple[str, str]
+
+
+

+

function PCustomListCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PCustomListCommand.post_load

+
post_load() → None
+
+
+

+

function PCustomListCommand.pre_load

+
pre_load() → None
+
+
+

+

function PCustomListCommand.usage

+
usage() → None
+
+
+

class PCustomShowCommand

+

PCustom: show the content of a given structure

+

+

function PCustomShowCommand.__init__

+
__init__() → None
+
+
+

property PCustomShowCommand.settings

+

Return the list of settings for this command.

+
+

+

function PCustomShowCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function PCustomShowCommand.explode_type

+
explode_type(arg: str) → Tuple[str, str]
+
+
+

+

function PCustomShowCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PCustomShowCommand.post_load

+
post_load() → None
+
+
+

+

function PCustomShowCommand.pre_load

+
pre_load() → None
+
+
+

+

function PCustomShowCommand.usage

+
usage() → None
+
+
+

class PatchByteCommand

+

Write specified BYTE to the specified address.

+

+

function PatchByteCommand.__init__

+
__init__() → None
+
+
+

property PatchByteCommand.settings

+

Return the list of settings for this command.

+
+

+

function PatchByteCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PatchByteCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PatchByteCommand.post_load

+
post_load() → None
+
+
+

+

function PatchByteCommand.pre_load

+
pre_load() → None
+
+
+

+

function PatchByteCommand.usage

+
usage() → None
+
+
+

class PatchCommand

+

Write specified values to the specified address.

+

+

function PatchCommand.__init__

+
__init__() → None
+
+
+

property PatchCommand.settings

+

Return the list of settings for this command.

+
+

+

function PatchCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PatchCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PatchCommand.post_load

+
post_load() → None
+
+
+

+

function PatchCommand.pre_load

+
pre_load() → None
+
+
+

+

function PatchCommand.usage

+
usage() → None
+
+
+

class PatchDwordCommand

+

Write specified DWORD to the specified address.

+

+

function PatchDwordCommand.__init__

+
__init__() → None
+
+
+

property PatchDwordCommand.settings

+

Return the list of settings for this command.

+
+

+

function PatchDwordCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PatchDwordCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PatchDwordCommand.post_load

+
post_load() → None
+
+
+

+

function PatchDwordCommand.pre_load

+
pre_load() → None
+
+
+

+

function PatchDwordCommand.usage

+
usage() → None
+
+
+

class PatchQwordCommand

+

Write specified QWORD to the specified address.

+

+

function PatchQwordCommand.__init__

+
__init__() → None
+
+
+

property PatchQwordCommand.settings

+

Return the list of settings for this command.

+
+

+

function PatchQwordCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PatchQwordCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PatchQwordCommand.post_load

+
post_load() → None
+
+
+

+

function PatchQwordCommand.pre_load

+
pre_load() → None
+
+
+

+

function PatchQwordCommand.usage

+
usage() → None
+
+
+

class PatchStringCommand

+

Write specified string to the specified memory location pointed by ADDRESS.

+

+

function PatchStringCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property PatchStringCommand.settings

+

Return the list of settings for this command.

+
+

+

function PatchStringCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function PatchStringCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PatchStringCommand.post_load

+
post_load() → None
+
+
+

+

function PatchStringCommand.pre_load

+
pre_load() → None
+
+
+

+

function PatchStringCommand.usage

+
usage() → None
+
+
+

class PatchWordCommand

+

Write specified WORD to the specified address.

+

+

function PatchWordCommand.__init__

+
__init__() → None
+
+
+

property PatchWordCommand.settings

+

Return the list of settings for this command.

+
+

+

function PatchWordCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PatchWordCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PatchWordCommand.post_load

+
post_load() → None
+
+
+

+

function PatchWordCommand.pre_load

+
pre_load() → None
+
+
+

+

function PatchWordCommand.usage

+
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__

+
__init__() → None
+
+
+

property PatternCommand.settings

+

Return the list of settings for this command.

+
+

+

function PatternCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function PatternCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PatternCommand.post_load

+
post_load() → None
+
+
+

+

function PatternCommand.pre_load

+
pre_load() → None
+
+
+

+

function PatternCommand.usage

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property PatternCreateCommand.settings

+

Return the list of settings for this command.

+
+

+

function PatternCreateCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PatternCreateCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PatternCreateCommand.post_load

+
post_load() → None
+
+
+

+

function PatternCreateCommand.pre_load

+
pre_load() → None
+
+
+

+

function PatternCreateCommand.usage

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property PatternSearchCommand.settings

+

Return the list of settings for this command.

+
+

+

function PatternSearchCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PatternSearchCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PatternSearchCommand.post_load

+
post_load() → None
+
+
+

+

function PatternSearchCommand.pre_load

+
pre_load() → None
+
+
+

+

function PatternSearchCommand.search

+
search(pattern: str, size: int, period: int) → None
+
+
+

+

function PatternSearchCommand.usage

+
usage() → None
+
+
+

class Permission

+

GEF representation of Linux permission.

+
+

class Phdr

+

+

function Phdr.__init__

+
__init__(elf: __main__.Elf, off: int) → None
+
+
+

class PieAttachCommand

+

Do attach with PIE breakpoint support.

+

+

function PieAttachCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property PieAttachCommand.settings

+

Return the list of settings for this command.

+
+

+

function PieAttachCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function PieAttachCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PieAttachCommand.post_load

+
post_load() → None
+
+
+

+

function PieAttachCommand.pre_load

+
pre_load() → None
+
+
+

+

function PieAttachCommand.usage

+
usage() → None
+
+
+

class PieBreakpointCommand

+

Set a PIE breakpoint at an offset from the target binaries base address.

+

+

function PieBreakpointCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property PieBreakpointCommand.settings

+

Return the list of settings for this command.

+
+

+

function PieBreakpointCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PieBreakpointCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PieBreakpointCommand.post_load

+
post_load() → None
+
+
+

+

function PieBreakpointCommand.pre_load

+
pre_load() → None
+
+
+

+

function PieBreakpointCommand.set_pie_breakpoint

+
set_pie_breakpoint(set_func: Callable[[int], str], addr: int) → None
+
+
+

+

function PieBreakpointCommand.usage

+
usage() → None
+
+
+

class PieCommand

+

PIE breakpoint support.

+

+

function PieCommand.__init__

+
__init__() → None
+
+
+

property PieCommand.settings

+

Return the list of settings for this command.

+
+

+

function PieCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function PieCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PieCommand.post_load

+
post_load() → None
+
+
+

+

function PieCommand.pre_load

+
pre_load() → None
+
+
+

+

function PieCommand.usage

+
usage() → None
+
+
+

class PieDeleteCommand

+

Delete a PIE breakpoint.

+

+

function PieDeleteCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property PieDeleteCommand.settings

+

Return the list of settings for this command.

+
+

+

function PieDeleteCommand.add_setting

+
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

+
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

+
delete_bp(breakpoints: List[__main__.PieVirtualBreakpoint]) → None
+
+
+

+

function PieDeleteCommand.wrapper

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PieDeleteCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PieDeleteCommand.post_load

+
post_load() → None
+
+
+

+

function PieDeleteCommand.pre_load

+
pre_load() → None
+
+
+

+

function PieDeleteCommand.usage

+
usage() → None
+
+
+

class PieInfoCommand

+

Display breakpoint info.

+

+

function PieInfoCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property PieInfoCommand.settings

+

Return the list of settings for this command.

+
+

+

function PieInfoCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PieInfoCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PieInfoCommand.post_load

+
post_load() → None
+
+
+

+

function PieInfoCommand.pre_load

+
pre_load() → None
+
+
+

+

function PieInfoCommand.usage

+
usage() → None
+
+
+

class PieRemoteCommand

+

Attach to a remote connection with PIE breakpoint support.

+

+

function PieRemoteCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property PieRemoteCommand.settings

+

Return the list of settings for this command.

+
+

+

function PieRemoteCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function PieRemoteCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PieRemoteCommand.post_load

+
post_load() → None
+
+
+

+

function PieRemoteCommand.pre_load

+
pre_load() → None
+
+
+

+

function PieRemoteCommand.usage

+
usage() → None
+
+
+

class PieRunCommand

+

Run process with PIE breakpoint support.

+

+

function PieRunCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property PieRunCommand.settings

+

Return the list of settings for this command.

+
+

+

function PieRunCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function PieRunCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PieRunCommand.post_load

+
post_load() → None
+
+
+

+

function PieRunCommand.pre_load

+
pre_load() → None
+
+
+

+

function PieRunCommand.usage

+
usage() → None
+
+
+

class PieVirtualBreakpoint

+

PIE virtual breakpoint (not real breakpoint).

+

+

function PieVirtualBreakpoint.__init__

+
__init__(set_func: Callable[[int], str], vbp_num: int, addr: int) → None
+
+
+

+

function PieVirtualBreakpoint.destroy

+
destroy() → None
+
+
+

+

function PieVirtualBreakpoint.instantiate

+
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

+
canary_address() → int
+
+
+

+

function PowerPC.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function PowerPC.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int]
+
+
+

+

function PowerPC.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function PowerPC.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function PowerPC.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function PowerPC.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function PowerPC.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function PowerPC.register

+
register(name: str) → int
+
+
+

+

function PowerPC.reset_caches

+
reset_caches() → None
+
+
+

+

function PowerPC.supports_gdb_arch

+
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

+
canary_address() → int
+
+
+

+

function PowerPC64.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function PowerPC64.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int]
+
+
+

+

function PowerPC64.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function PowerPC64.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function PowerPC64.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function PowerPC64.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function PowerPC64.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function PowerPC64.register

+
register(name: str) → int
+
+
+

+

function PowerPC64.reset_caches

+
reset_caches() → None
+
+
+

+

function PowerPC64.supports_gdb_arch

+
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__

+
__init__() → None
+
+
+

property PrintFormatCommand.format_matrix

+
+

property PrintFormatCommand.settings

+

Return the list of settings for this command.

+
+

+

function PrintFormatCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function PrintFormatCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function PrintFormatCommand.post_load

+
post_load() → None
+
+
+

+

function PrintFormatCommand.pre_load

+
pre_load() → None
+
+
+

+

function PrintFormatCommand.usage

+
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__

+
__init__() → None
+
+
+

property ProcessListingCommand.settings

+

Return the list of settings for this command.

+
+

+

function ProcessListingCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function ProcessListingCommand.get_processes

+
get_processes() → Generator[Dict[str, str], NoneType, NoneType]
+
+
+

+

function ProcessListingCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ProcessListingCommand.post_load

+
post_load() → None
+
+
+

+

function ProcessListingCommand.pre_load

+
pre_load() → None
+
+
+

+

function ProcessListingCommand.usage

+
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__

+
__init__() → None
+
+
+

property ProcessStatusCommand.settings

+

Return the list of settings for this command.

+
+

+

function ProcessStatusCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function ProcessStatusCommand.get_children_pids

+
get_children_pids(pid: int) → List[int]
+
+
+

+

function ProcessStatusCommand.get_cmdline_of

+
get_cmdline_of(pid: int) → str
+
+
+

+

function ProcessStatusCommand.get_process_path_of

+
get_process_path_of(pid: int) → str
+
+
+

+

function ProcessStatusCommand.get_setting

+
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

+
get_state_of(pid: int) → Dict[str, str]
+
+
+

+

function ProcessStatusCommand.has_setting

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ProcessStatusCommand.list_sockets

+
list_sockets(pid: int) → List[int]
+
+
+

+

function ProcessStatusCommand.parse_ip_port

+
parse_ip_port(addr: str) → Tuple[str, int]
+
+
+

+

function ProcessStatusCommand.post_load

+
post_load() → None
+
+
+

+

function ProcessStatusCommand.pre_load

+
pre_load() → None
+
+
+

+

function ProcessStatusCommand.show_ancestor

+
show_ancestor() → None
+
+
+

+

function ProcessStatusCommand.show_connections

+
show_connections() → None
+
+
+

+

function ProcessStatusCommand.show_descendants

+
show_descendants() → None
+
+
+

+

function ProcessStatusCommand.show_fds

+
show_fds() → None
+
+
+

+

function ProcessStatusCommand.show_info_proc

+
show_info_proc() → None
+
+
+

+

function ProcessStatusCommand.usage

+
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

+
canary_address() → int
+
+
+

+

function RISCV.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function RISCV.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int]
+
+
+

+

function RISCV.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function RISCV.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function RISCV.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function RISCV.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function RISCV.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function RISCV.register

+
register(name: str) → int
+
+
+

+

function RISCV.reset_caches

+
reset_caches() → None
+
+
+

+

function RISCV.supports_gdb_arch

+
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__

+
__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__

+
__init__() → None
+
+
+

property RemoteCommand.settings

+

Return the list of settings for this command.

+
+

+

function RemoteCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function RemoteCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function RemoteCommand.post_load

+
post_load() → None
+
+
+

+

function RemoteCommand.pre_load

+
pre_load() → None
+
+
+

+

function RemoteCommand.usage

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property ResetCacheCommand.settings

+

Return the list of settings for this command.

+
+

+

function ResetCacheCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function ResetCacheCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ResetCacheCommand.post_load

+
post_load() → None
+
+
+

+

function ResetCacheCommand.pre_load

+
pre_load() → None
+
+
+

+

function ResetCacheCommand.usage

+
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

+
canary_address() → int
+
+
+

+

function SPARC.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function SPARC.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int]
+
+
+

+

function SPARC.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function SPARC.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function SPARC.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function SPARC.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function SPARC.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function SPARC.register

+
register(name: str) → int
+
+
+

+

function SPARC.reset_caches

+
reset_caches() → None
+
+
+

+

function SPARC.supports_gdb_arch

+
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

+
canary_address() → int
+
+
+

+

function SPARC64.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function SPARC64.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int]
+
+
+

+

function SPARC64.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function SPARC64.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function SPARC64.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function SPARC64.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function SPARC64.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function SPARC64.register

+
register(name: str) → int
+
+
+

+

function SPARC64.reset_caches

+
reset_caches() → None
+
+
+

+

function SPARC64.supports_gdb_arch

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property ScanSectionCommand.settings

+

Return the list of settings for this command.

+
+

+

function ScanSectionCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function ScanSectionCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ScanSectionCommand.post_load

+
post_load() → None
+
+
+

+

function ScanSectionCommand.pre_load

+
pre_load() → None
+
+
+

+

function ScanSectionCommand.usage

+
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__

+
__init__() → None
+
+
+

property SearchPatternCommand.settings

+

Return the list of settings for this command.

+
+

+

function SearchPatternCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function SearchPatternCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function SearchPatternCommand.post_load

+
post_load() → None
+
+
+

+

function SearchPatternCommand.pre_load

+
pre_load() → None
+
+
+

+

function SearchPatternCommand.print_loc

+
print_loc(loc: Tuple[int, int, str]) → None
+
+
+

+

function SearchPatternCommand.print_section

+
print_section(section: __main__.Section) → None
+
+
+

+

function SearchPatternCommand.search_binpattern_by_address

+
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

+
search_pattern(pattern: str, section_name: str) → None
+
+

Search a pattern within the whole userland memory.

+
+

+

function SearchPatternCommand.search_pattern_by_address

+
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

+
usage() → None
+
+
+

class Section

+

GEF representation of process memory sections.

+

+

function Section.__init__

+
__init__(**kwargs: Any) → None
+
+
+

property Section.realpath

+
+

property Section.size

+
+

+

function Section.is_executable

+
is_executable() → bool
+
+
+

+

function Section.is_readable

+
is_readable() → bool
+
+
+

+

function Section.is_writable

+
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__

+
__init__() → None
+
+
+

+

function SectionBaseFunction.arg_to_long

+
arg_to_long(args: List, index: int, default: int = 0) → int
+
+
+

+

function SectionBaseFunction.do_invoke

+
do_invoke(args: List) → int
+
+
+

+

function SectionBaseFunction.invoke

+
invoke(*args: Any) → int
+
+
+

class Shdr

+

+

function Shdr.__init__

+
__init__(elf: Optional[__main__.Elf], off: int) → None
+
+
+

class ShellcodeCommand

+

ShellcodeCommand uses @JonathanSalwan simple-yet-awesome shellcode API to download shellcodes.

+

+

function ShellcodeCommand.__init__

+
__init__() → None
+
+
+

property ShellcodeCommand.settings

+

Return the list of settings for this command.

+
+

+

function ShellcodeCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function ShellcodeCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ShellcodeCommand.post_load

+
post_load() → None
+
+
+

+

function ShellcodeCommand.pre_load

+
pre_load() → None
+
+
+

+

function ShellcodeCommand.usage

+
usage() → None
+
+
+

class ShellcodeGetCommand

+

Download shellcode from shell-storm's shellcode database.

+

+

function ShellcodeGetCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property ShellcodeGetCommand.settings

+

Return the list of settings for this command.

+
+

+

function ShellcodeGetCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function ShellcodeGetCommand.get_setting

+
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

+
get_shellcode(sid: int) → None
+
+
+

+

function ShellcodeGetCommand.has_setting

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ShellcodeGetCommand.post_load

+
post_load() → None
+
+
+

+

function ShellcodeGetCommand.pre_load

+
pre_load() → None
+
+
+

+

function ShellcodeGetCommand.usage

+
usage() → None
+
+
+

class ShellcodeSearchCommand

+

Search pattern in shell-storm's shellcode database.

+

+

function ShellcodeSearchCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property ShellcodeSearchCommand.settings

+

Return the list of settings for this command.

+
+

+

function ShellcodeSearchCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function ShellcodeSearchCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function ShellcodeSearchCommand.post_load

+
post_load() → None
+
+
+

+

function ShellcodeSearchCommand.pre_load

+
pre_load() → None
+
+
+

+

function ShellcodeSearchCommand.search_shellcode

+
search_shellcode(search_options: List) → None
+
+
+

+

function ShellcodeSearchCommand.usage

+
usage() → None
+
+
+

class SkipiCommand

+

Skip N instruction(s) execution

+

+

function SkipiCommand.__init__

+
__init__() → None
+
+
+

property SkipiCommand.settings

+

Return the list of settings for this command.

+
+

+

function SkipiCommand.add_setting

+
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 SkipiCommand.del_setting

+
del_setting(name: str) → None
+
+

del_setting is DEPRECATED and will be removed in the future. + Use del self[setting_name] instead

+
+

+

function SkipiCommand.wrapper

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function SkipiCommand.get_setting

+
get_setting(name: str) → Any
+
+

get_setting is DEPRECATED and will be removed in the future. + Use self[setting_name] instead

+
+

+

function SkipiCommand.has_setting

+
has_setting(name: str) → bool
+
+

has_setting is DEPRECATED and will be removed in the future. + Use setting_name in self instead

+
+

+

function SkipiCommand.invoke

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function SkipiCommand.post_load

+
post_load() → None
+
+
+

+

function SkipiCommand.pre_load

+
pre_load() → None
+
+
+

+

function SkipiCommand.usage

+
usage() → None
+
+
+

class SmartEvalCommand

+

SmartEval: Smart eval (vague approach to mimic WinDBG ?).

+

+

function SmartEvalCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property SmartEvalCommand.settings

+

Return the list of settings for this command.

+
+

+

function SmartEvalCommand.add_setting

+
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

+
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

+
distance(args: Tuple[str, str]) → None
+
+
+

+

function SmartEvalCommand.do_invoke

+
do_invoke(argv: List[str]) → None
+
+
+

+

function SmartEvalCommand.evaluate

+
evaluate(expr: List[str]) → None
+
+
+

+

function SmartEvalCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function SmartEvalCommand.post_load

+
post_load() → None
+
+
+

+

function SmartEvalCommand.pre_load

+
pre_load() → None
+
+
+

+

function SmartEvalCommand.usage

+
usage() → None
+
+
+

class SolveKernelSymbolCommand

+

Solve kernel symbols from kallsyms table.

+

+

function SolveKernelSymbolCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property SolveKernelSymbolCommand.settings

+

Return the list of settings for this command.

+
+

+

function SolveKernelSymbolCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function SolveKernelSymbolCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function SolveKernelSymbolCommand.post_load

+
post_load() → None
+
+
+

+

function SolveKernelSymbolCommand.pre_load

+
pre_load() → None
+
+
+

+

function SolveKernelSymbolCommand.usage

+
usage() → None
+
+
+

class StackOffsetFunction

+

Return the current stack base address plus an optional offset.

+

+

function StackOffsetFunction.__init__

+
__init__() → None
+
+
+

+

function StackOffsetFunction.arg_to_long

+
arg_to_long(args: List, index: int, default: int = 0) → int
+
+
+

+

function StackOffsetFunction.do_invoke

+
do_invoke(args: List) → int
+
+
+

+

function StackOffsetFunction.invoke

+
invoke(*args: Any) → int
+
+
+

class StubBreakpoint

+

Create a breakpoint to permanently disable a call (fork/alarm/signal/etc.).

+

+

function StubBreakpoint.__init__

+
__init__(func: str, retval: Optional[int]) → None
+
+
+

+

function StubBreakpoint.stop

+
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__

+
__init__() → None
+
+
+

property StubCommand.settings

+

Return the list of settings for this command.

+
+

+

function StubCommand.add_setting

+
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

+
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

+
wrapper(*args: Any, **kwargs: Any) → Callable
+
+
+

+

function StubCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function StubCommand.post_load

+
post_load() → None
+
+
+

+

function StubCommand.pre_load

+
pre_load() → None
+
+
+

+

function StubCommand.usage

+
usage() → None
+
+
+

class TraceFreeBreakpoint

+

Track calls to free() and attempts to detect inconsistencies.

+

+

function TraceFreeBreakpoint.__init__

+
__init__() → None
+
+
+

+

function TraceFreeBreakpoint.stop

+
stop() → bool
+
+
+

class TraceFreeRetBreakpoint

+

Internal temporary breakpoint to track free()d values.

+

+

function TraceFreeRetBreakpoint.__init__

+
__init__(addr: int) → None
+
+
+

+

function TraceFreeRetBreakpoint.stop

+
stop() → bool
+
+
+

class TraceMallocBreakpoint

+

Track allocations done with malloc() or calloc().

+

+

function TraceMallocBreakpoint.__init__

+
__init__(name: str) → None
+
+
+

+

function TraceMallocBreakpoint.stop

+
stop() → bool
+
+
+

class TraceMallocRetBreakpoint

+

Internal temporary breakpoint to retrieve the return value of malloc().

+

+

function TraceMallocRetBreakpoint.__init__

+
__init__(size: int, name: str) → None
+
+
+

+

function TraceMallocRetBreakpoint.stop

+
stop() → bool
+
+
+

class TraceReallocBreakpoint

+

Track re-allocations done with realloc().

+

+

function TraceReallocBreakpoint.__init__

+
__init__() → None
+
+
+

+

function TraceReallocBreakpoint.stop

+
stop() → bool
+
+
+

class TraceReallocRetBreakpoint

+

Internal temporary breakpoint to retrieve the return value of realloc().

+

+

function TraceReallocRetBreakpoint.__init__

+
__init__(ptr: int, size: int) → None
+
+
+

+

function TraceReallocRetBreakpoint.stop

+
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__

+
__init__() → None
+
+
+

property TraceRunCommand.settings

+

Return the list of settings for this command.

+
+

+

function TraceRunCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function TraceRunCommand.get_frames_size

+
get_frames_size() → int
+
+
+

+

function TraceRunCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function TraceRunCommand.post_load

+
post_load() → None
+
+
+

+

function TraceRunCommand.pre_load

+
pre_load() → None
+
+
+

+

function TraceRunCommand.start_tracing

+
start_tracing(loc_start: int, loc_end: int, depth: int) → None
+
+
+

+

function TraceRunCommand.trace

+
trace(loc_start: int, loc_end: int, depth: int) → None
+
+
+

+

function TraceRunCommand.usage

+
usage() → None
+
+
+

class UafWatchpoint

+

Custom watchpoints set TraceFreeBreakpoint() to monitor free()d pointers being used.

+

+

function UafWatchpoint.__init__

+
__init__(addr: int) → None
+
+
+

+

function UafWatchpoint.stop

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property VMMapCommand.settings

+

Return the list of settings for this command.

+
+

+

function VMMapCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function VMMapCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function VMMapCommand.is_integer

+
is_integer(n: str) → bool
+
+
+

+

function VMMapCommand.post_load

+
post_load() → None
+
+
+

+

function VMMapCommand.pre_load

+
pre_load() → None
+
+
+

+

function VMMapCommand.print_entry

+
print_entry(entry: __main__.Section) → None
+
+
+

+

function VMMapCommand.show_legend

+
show_legend() → None
+
+
+

+

function VMMapCommand.usage

+
usage() → None
+
+
+

class VersionCommand

+

Display GEF version info.

+

+

function VersionCommand.__init__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property VersionCommand.settings

+

Return the list of settings for this command.

+
+

+

function VersionCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function VersionCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function VersionCommand.post_load

+
post_load() → None
+
+
+

+

function VersionCommand.pre_load

+
pre_load() → None
+
+
+

+

function VersionCommand.usage

+
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

+
canary_address() → int
+
+
+

+

function X86.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function X86.get_ith_parameter

+
get_ith_parameter(i: int, in_func: bool = True) → Tuple[str, Optional[int]]
+
+
+

+

function X86.get_ra

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int]
+
+
+

+

function X86.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function X86.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function X86.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function X86.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function X86.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function X86.register

+
register(name: str) → int
+
+
+

+

function X86.reset_caches

+
reset_caches() → None
+
+
+

+

function X86.supports_gdb_arch

+
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

+
canary_address() → int
+
+
+

+

function X86_64.flag_register_to_human

+
flag_register_to_human(val: Optional[int] = None) → str
+
+
+

+

function X86_64.get_ith_parameter

+
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

+
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') → Optional[int]
+
+
+

+

function X86_64.is_branch_taken

+
is_branch_taken(insn: __main__.Instruction) → Tuple[bool, str]
+
+
+

+

function X86_64.is_call

+
is_call(insn: __main__.Instruction) → bool
+
+
+

+

function X86_64.is_conditional_branch

+
is_conditional_branch(insn: __main__.Instruction) → bool
+
+
+

+

function X86_64.is_ret

+
is_ret(insn: __main__.Instruction) → bool
+
+
+

+

function X86_64.mprotect_asm

+
mprotect_asm(addr: int, size: int, perm: __main__.Permission) → str
+
+
+

+

function X86_64.register

+
register(name: str) → int
+
+
+

+

function X86_64.reset_caches

+
reset_caches() → None
+
+
+

+

function X86_64.supports_gdb_arch

+
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__

+
__init__() → None
+
+
+

property XAddressInfoCommand.settings

+

Return the list of settings for this command.

+
+

+

function XAddressInfoCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function XAddressInfoCommand.get_setting

+
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

+
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

+
infos(address: int) → None
+
+
+

+

function XAddressInfoCommand.invoke

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function XAddressInfoCommand.post_load

+
post_load() → None
+
+
+

+

function XAddressInfoCommand.pre_load

+
pre_load() → None
+
+
+

+

function XAddressInfoCommand.usage

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property XFilesCommand.settings

+

Return the list of settings for this command.

+
+

+

function XFilesCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function XFilesCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function XFilesCommand.post_load

+
post_load() → None
+
+
+

+

function XFilesCommand.pre_load

+
pre_load() → None
+
+
+

+

function XFilesCommand.usage

+
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__

+
__init__() → None
+
+
+

property XorMemoryCommand.settings

+

Return the list of settings for this command.

+
+

+

function XorMemoryCommand.add_setting

+
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

+
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

+
do_invoke(_: List[str]) → None
+
+
+

+

function XorMemoryCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function XorMemoryCommand.post_load

+
post_load() → None
+
+
+

+

function XorMemoryCommand.pre_load

+
pre_load() → None
+
+
+

+

function XorMemoryCommand.usage

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property XorMemoryDisplayCommand.settings

+

Return the list of settings for this command.

+
+

+

function XorMemoryDisplayCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function XorMemoryDisplayCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function XorMemoryDisplayCommand.post_load

+
post_load() → None
+
+
+

+

function XorMemoryDisplayCommand.pre_load

+
pre_load() → None
+
+
+

+

function XorMemoryDisplayCommand.usage

+
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__

+
__init__(*args: Any, **kwargs: Any) → None
+
+
+

property XorMemoryPatchCommand.settings

+

Return the list of settings for this command.

+
+

+

function XorMemoryPatchCommand.add_setting

+
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

+
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

+
do_invoke(argv: List[str]) → None
+
+
+

+

function XorMemoryPatchCommand.get_setting

+
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

+
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

+
invoke(args: str, from_tty: bool) → None
+
+
+

+

function XorMemoryPatchCommand.post_load

+
post_load() → None
+
+
+

+

function XorMemoryPatchCommand.pre_load

+
pre_load() → None
+
+
+

+

function XorMemoryPatchCommand.usage

+
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.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/index.html b/api/index.html new file mode 100644 index 000000000..719fa2214 --- /dev/null +++ b/api/index.html @@ -0,0 +1,2055 @@ + + + + + + + + + + + + + + + + + + + + + + Write extensions - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Extending GEF

+

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.

+

A dedicated repository was born to host external +scripts. This repo is open to all for +contributions, no restrictions and the most valuable ones will be integrated into gef.py.

+

Quick start

+

Here is the most basic skeleton for creating a new GEF command named newcmd:

+
class NewCommand(GenericCommand):
+    """Dummy new command."""
+    _cmdline_ = "newcmd"
+    _syntax_  = f"{_cmdline_}"
+
+    @only_if_gdb_running         # not required, ensures that the debug session is started
+    def do_invoke(self, argv):
+        # let's say we want to print some info about the architecture of the current binary
+        print(f"gef.arch={gef.arch}")
+        # or showing the current $pc
+        print(f"gef.arch.pc={gef.arch.pc:#x}")
+        return
+
+register_external_command(NewCommand())
+
+

Loading it in GEF is as easy as

+
gef➤  source /path/to/newcmd.py
+[+] Loading 'NewCommand'
+
+

We can call it:

+
gef➤  newcmd
+gef.arch=<__main__.X86_64 object at 0x7fd5583571c0>
+gef.arch.pc=0x55555555a7d0
+
+

Yes, that's it! Check out the complete API to see what else GEF offers.

+

Detailed explanation

+

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.
  • +
+

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:

+
gef➤  source /path/to/newcmd.py
+
+

or add to your ~/.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 +as a part of the GEF context. Here is a simple example of how to make a custom context pane:

+
__start_time__ = int(time.time())
+def wasted_time_debugging():
+    gef_print("You have wasted {} seconds!".format(int(time.time()) - __start_time__))
+
+def wasted_time_debugging_title():
+    return "wasted:time:debugging:{}".format(int(time.time()) - __start_time__)
+
+register_external_context_pane("wasted_time_debugging", wasted_time_debugging, wasted_time_debugging_title)
+
+

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.

+

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
  • +
+

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:

+
gef➤  pi help(Architecture)
+
+

or even from outside GDB:

+
$ 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

+
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
  • +
+
gef ➤ pi print('\n'.join([ f"{x.page_start:#x} -> {x.page_end:#x}" for x in gef.memory.maps]))
+0x555555554000 -> 0x555555558000
+0x555555558000 -> 0x55555556c000
+0x55555556c000 -> 0x555555575000
+0x555555576000 -> 0x555555577000
+0x555555577000 -> 0x555555578000
+0x555555578000 -> 0x55555559a000
+0x7ffff7cd8000 -> 0x7ffff7cda000
+0x7ffff7cda000 -> 0x7ffff7ce1000
+0x7ffff7ce1000 -> 0x7ffff7cf2000
+0x7ffff7cf2000 -> 0x7ffff7cf7000
+[...]
+
+

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

+

Reference

+

For a complete reference of the API offered by GEF, visit docs/api/gef.md.

+

Parsing command arguments

+
@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.

+

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:

+
@parse_arguments( {"instructions": ["nop", "int3", "hlt"], }, {"--arch": "x64", } )
+
+

Argument flags are also supported, allowing to write simpler version of the flag such as

+
@parse_arguments( {}, {("--long-argument", "-l"): value, } )
+
+

A basic example would be as follow:

+
class MyCommand(GenericCommand):
+    [...]
+
+    @parse_arguments({"foo": [1,]}, {"--bleh": "", ("--blah", "-l): True})
+    def do_invoke(self, argv, *args, **kwargs):
+      args = kwargs["arguments"]
+      if args.foo == 1: ...
+      if args.blah == True: ...
+
+

When the user enters the following command:

+
gef➤ mycommand --blah 3 14 159 2653
+
+

The function MyCommand!do_invoke() can use the command line argument value

+
args.foo --> [3, 14, 159, 2653] # a List(int) from user input
+args.bleh --> "" # the default value
+args.blah --> True # set to True because user input declared the option (would have been False otherwise)
+
+

Adding new architectures

+

Support for new architectures can be added by inheriting from the Architecture class. Examples can +be found in gef-extras.

+

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 be used over the generic ARM +one:

+
@staticmethod
+def supports_gdb_arch(gdb_arch: str) -> Optional[bool]:
+    return bool(re.search("^armv.*-m$", gdb_arch))
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..1cf13b9f9d978896599290a74f77d5dbe7d1655c GIT binary patch literal 1870 zcmV-U2eJ5xP)Gc)JR9QMau)O=X#!i9;T z37kk-upj^(fsR36MHs_+1RCI)NNu9}lD0S{B^g8PN?Ww(5|~L#Ng*g{WsqleV}|#l zz8@ri&cTzw_h33bHI+12+kK6WN$h#n5cD8OQt`5kw6p~9H3()bUQ8OS4Q4HTQ=1Ol z_JAocz`fLbT2^{`8n~UAo=#AUOf=SOq4pYkt;XbC&f#7lb$*7=$na!mWCQ`dBQsO0 zLFBSPj*N?#u5&pf2t4XjEGH|=pPQ8xh7tpx;US5Cx_Ju;!O`ya-yF`)b%TEt5>eP1ZX~}sjjA%FJF?h7cX8=b!DZl<6%Cv z*G0uvvU+vmnpLZ2paivG-(cd*y3$hCIcsZcYOGh{$&)A6*XX&kXZd3G8m)G$Zz-LV z^GF3VAW^Mdv!)4OM8EgqRiz~*Cji;uzl2uC9^=8I84vNp;ltJ|q-*uQwGp2ma6cY7 z;`%`!9UXO@fr&Ebapfs34OmS9^u6$)bJxrucutf>`dKPKT%%*d3XlFVKunp9 zasduxjrjs>f8V=D|J=XNZp;_Zy^WgQ$9WDjgY=z@stwiEBm9u5*|34&1Na8BMjjgf3+SHcr`5~>oz1Y?SW^=K z^bTyO6>Gar#P_W2gEMwq)ot3; zREHn~U&Dp0l6YT0&k-wLwYjb?5zGK`W6S2v+K>AM(95m2C20L|3m~rN8dprPr@t)5lsk9Hu*W z?pS990s;Ez=+Rj{x7p``4>+c0G5^pYnB1^!TL=(?HLHZ+HicG{~4F1d^5Awl_2!1jICM-!9eoLhbbT^;yHcefyTAaqRcY zmuctDopPT!%k+}x%lZRKnzykr2}}XfG_ne?nRQO~?%hkzo;@RN{P6o`&mMUWBYMTe z6i8ChtjX&gXl`nvrU>jah)2iNM%JdjqoaeaU%yVn!^70x-flljp6Q5tK}5}&X8&&G zX3fpb3E(!rH=zVI_9Gjl45w@{(ITqngWFe7@9{mX;tO25Z_8 zQHEpI+FkTU#4xu>RkN>b3Tnc3UpWzPXWm#o55GKF09j^Mh~)K7{QqbO_~(@CVq! zS<8954|P8mXN2MRs86xZ&Q4EfM@JB94b=(YGuk)s&^jiSF=t3*oNK3`rD{H`yQ?d; ztE=laAUoZx5?RC8*WKOj`%LXEkgDd>&^Q4M^z`%u0rg-It=hLCVsq!Z%^6eB-OvOT zFZ28TN&cRmgU}Elrnk43)!>Z1FCPL2K$7}gwzIc48NX}#!A1BpJP?#v5wkNprhV** z?Cpalt1oH&{r!o3eSKc&ap)iz2BTn_VV`4>9M^b3;(YY}4>#ML6{~(4mH+?%07*qo IM6N<$f(jP3KmY&$ literal 0 HcmV?d00001 diff --git a/assets/javascripts/bundle.220ee61c.min.js b/assets/javascripts/bundle.220ee61c.min.js new file mode 100644 index 000000000..116072a11 --- /dev/null +++ b/assets/javascripts/bundle.220ee61c.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var Ci=Object.create;var gr=Object.defineProperty;var Ri=Object.getOwnPropertyDescriptor;var ki=Object.getOwnPropertyNames,Ht=Object.getOwnPropertySymbols,Hi=Object.getPrototypeOf,yr=Object.prototype.hasOwnProperty,nn=Object.prototype.propertyIsEnumerable;var rn=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,P=(e,t)=>{for(var r in t||(t={}))yr.call(t,r)&&rn(e,r,t[r]);if(Ht)for(var r of Ht(t))nn.call(t,r)&&rn(e,r,t[r]);return e};var on=(e,t)=>{var r={};for(var n in e)yr.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&Ht)for(var n of Ht(e))t.indexOf(n)<0&&nn.call(e,n)&&(r[n]=e[n]);return r};var Pt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Pi=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ki(t))!yr.call(e,o)&&o!==r&&gr(e,o,{get:()=>t[o],enumerable:!(n=Ri(t,o))||n.enumerable});return e};var yt=(e,t,r)=>(r=e!=null?Ci(Hi(e)):{},Pi(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var sn=Pt((xr,an)=>{(function(e,t){typeof xr=="object"&&typeof an!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(xr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(O){return!!(O&&O!==document&&O.nodeName!=="HTML"&&O.nodeName!=="BODY"&&"classList"in O&&"contains"in O.classList)}function f(O){var Qe=O.type,De=O.tagName;return!!(De==="INPUT"&&s[Qe]&&!O.readOnly||De==="TEXTAREA"&&!O.readOnly||O.isContentEditable)}function c(O){O.classList.contains("focus-visible")||(O.classList.add("focus-visible"),O.setAttribute("data-focus-visible-added",""))}function u(O){O.hasAttribute("data-focus-visible-added")&&(O.classList.remove("focus-visible"),O.removeAttribute("data-focus-visible-added"))}function p(O){O.metaKey||O.altKey||O.ctrlKey||(a(r.activeElement)&&c(r.activeElement),n=!0)}function m(O){n=!1}function d(O){a(O.target)&&(n||f(O.target))&&c(O.target)}function h(O){a(O.target)&&(O.target.classList.contains("focus-visible")||O.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),u(O.target))}function v(O){document.visibilityState==="hidden"&&(o&&(n=!0),Y())}function Y(){document.addEventListener("mousemove",N),document.addEventListener("mousedown",N),document.addEventListener("mouseup",N),document.addEventListener("pointermove",N),document.addEventListener("pointerdown",N),document.addEventListener("pointerup",N),document.addEventListener("touchmove",N),document.addEventListener("touchstart",N),document.addEventListener("touchend",N)}function B(){document.removeEventListener("mousemove",N),document.removeEventListener("mousedown",N),document.removeEventListener("mouseup",N),document.removeEventListener("pointermove",N),document.removeEventListener("pointerdown",N),document.removeEventListener("pointerup",N),document.removeEventListener("touchmove",N),document.removeEventListener("touchstart",N),document.removeEventListener("touchend",N)}function N(O){O.target.nodeName&&O.target.nodeName.toLowerCase()==="html"||(n=!1,B())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",m,!0),document.addEventListener("pointerdown",m,!0),document.addEventListener("touchstart",m,!0),document.addEventListener("visibilitychange",v,!0),Y(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var cn=Pt(Er=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(c){return!1}},r=t(),n=function(c){var u={next:function(){var p=c.shift();return{done:p===void 0,value:p}}};return r&&(u[Symbol.iterator]=function(){return u}),u},o=function(c){return encodeURIComponent(c).replace(/%20/g,"+")},i=function(c){return decodeURIComponent(String(c).replace(/\+/g," "))},s=function(){var c=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var m=typeof p;if(m!=="undefined")if(m==="string")p!==""&&this._fromString(p);else if(p instanceof c){var d=this;p.forEach(function(B,N){d.append(N,B)})}else if(p!==null&&m==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),c._entries&&(c._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(f,c){typeof f!="string"&&(f=String(f)),c&&typeof c!="string"&&(c=String(c));var u=document,p;if(c&&(e.location===void 0||c!==e.location.href)){c=c.toLowerCase(),u=document.implementation.createHTMLDocument(""),p=u.createElement("base"),p.href=c,u.head.appendChild(p);try{if(p.href.indexOf(c)!==0)throw new Error(p.href)}catch(O){throw new Error("URL unable to set base "+c+" due to "+O)}}var m=u.createElement("a");m.href=f,p&&(u.body.appendChild(m),m.href=m.href);var d=u.createElement("input");if(d.type="url",d.value=f,m.protocol===":"||!/:/.test(m.href)||!d.checkValidity()&&!c)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:m});var h=new e.URLSearchParams(this.search),v=!0,Y=!0,B=this;["append","delete","set"].forEach(function(O){var Qe=h[O];h[O]=function(){Qe.apply(h,arguments),v&&(Y=!1,B.search=h.toString(),Y=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var N=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==N&&(N=this.search,Y&&(v=!1,this.searchParams._fromString(this.search),v=!0))}})},s=i.prototype,a=function(f){Object.defineProperty(s,f,{get:function(){return this._anchorElement[f]},set:function(c){this._anchorElement[f]=c},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(f){a(f)}),Object.defineProperty(s,"search",{get:function(){return this._anchorElement.search},set:function(f){this._anchorElement.search=f,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(s,{toString:{get:function(){var f=this;return function(){return f.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(f){this._anchorElement.href=f,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(f){this._anchorElement.pathname=f},enumerable:!0},origin:{get:function(){var f={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],c=this._anchorElement.port!=f&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(c?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(f){},enumerable:!0},username:{get:function(){return""},set:function(f){},enumerable:!0}}),i.createObjectURL=function(f){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(f){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er)});var qr=Pt((Mt,Nr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Mt=="object"&&typeof Nr=="object"?Nr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Mt=="object"?Mt.ClipboardJS=r():t.ClipboardJS=r()})(Mt,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return Ai}});var s=i(279),a=i.n(s),f=i(370),c=i.n(f),u=i(817),p=i.n(u);function m(j){try{return document.execCommand(j)}catch(T){return!1}}var d=function(T){var E=p()(T);return m("cut"),E},h=d;function v(j){var T=document.documentElement.getAttribute("dir")==="rtl",E=document.createElement("textarea");E.style.fontSize="12pt",E.style.border="0",E.style.padding="0",E.style.margin="0",E.style.position="absolute",E.style[T?"right":"left"]="-9999px";var H=window.pageYOffset||document.documentElement.scrollTop;return E.style.top="".concat(H,"px"),E.setAttribute("readonly",""),E.value=j,E}var Y=function(T,E){var H=v(T);E.container.appendChild(H);var I=p()(H);return m("copy"),H.remove(),I},B=function(T){var E=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},H="";return typeof T=="string"?H=Y(T,E):T instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(T==null?void 0:T.type)?H=Y(T.value,E):(H=p()(T),m("copy")),H},N=B;function O(j){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?O=function(E){return typeof E}:O=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},O(j)}var Qe=function(){var T=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},E=T.action,H=E===void 0?"copy":E,I=T.container,q=T.target,Me=T.text;if(H!=="copy"&&H!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(q!==void 0)if(q&&O(q)==="object"&&q.nodeType===1){if(H==="copy"&&q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(H==="cut"&&(q.hasAttribute("readonly")||q.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Me)return N(Me,{container:I});if(q)return H==="cut"?h(q):N(q,{container:I})},De=Qe;function $e(j){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?$e=function(E){return typeof E}:$e=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},$e(j)}function Ei(j,T){if(!(j instanceof T))throw new TypeError("Cannot call a class as a function")}function tn(j,T){for(var E=0;E0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof I.action=="function"?I.action:this.defaultAction,this.target=typeof I.target=="function"?I.target:this.defaultTarget,this.text=typeof I.text=="function"?I.text:this.defaultText,this.container=$e(I.container)==="object"?I.container:document.body}},{key:"listenClick",value:function(I){var q=this;this.listener=c()(I,"click",function(Me){return q.onClick(Me)})}},{key:"onClick",value:function(I){var q=I.delegateTarget||I.currentTarget,Me=this.action(q)||"copy",kt=De({action:Me,container:this.container,target:this.target(q),text:this.text(q)});this.emit(kt?"success":"error",{action:Me,text:kt,trigger:q,clearSelection:function(){q&&q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(I){return vr("action",I)}},{key:"defaultTarget",value:function(I){var q=vr("target",I);if(q)return document.querySelector(q)}},{key:"defaultText",value:function(I){return vr("text",I)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(I){var q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return N(I,q)}},{key:"cut",value:function(I){return h(I)}},{key:"isSupported",value:function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],q=typeof I=="string"?[I]:I,Me=!!document.queryCommandSupported;return q.forEach(function(kt){Me=Me&&!!document.queryCommandSupported(kt)}),Me}}]),E}(a()),Ai=Li},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,f){for(;a&&a.nodeType!==o;){if(typeof a.matches=="function"&&a.matches(f))return a;a=a.parentNode}}n.exports=s},438:function(n,o,i){var s=i(828);function a(u,p,m,d,h){var v=c.apply(this,arguments);return u.addEventListener(m,v,h),{destroy:function(){u.removeEventListener(m,v,h)}}}function f(u,p,m,d,h){return typeof u.addEventListener=="function"?a.apply(null,arguments):typeof m=="function"?a.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(v){return a(v,p,m,d,h)}))}function c(u,p,m,d){return function(h){h.delegateTarget=s(h.target,p),h.delegateTarget&&d.call(u,h)}}n.exports=f},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(n,o,i){var s=i(879),a=i(438);function f(m,d,h){if(!m&&!d&&!h)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(h))throw new TypeError("Third argument must be a Function");if(s.node(m))return c(m,d,h);if(s.nodeList(m))return u(m,d,h);if(s.string(m))return p(m,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(m,d,h){return m.addEventListener(d,h),{destroy:function(){m.removeEventListener(d,h)}}}function u(m,d,h){return Array.prototype.forEach.call(m,function(v){v.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(m,function(v){v.removeEventListener(d,h)})}}}function p(m,d,h){return a(document.body,m,d,h)}n.exports=f},817:function(n){function o(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var f=window.getSelection(),c=document.createRange();c.selectNodeContents(i),f.removeAllRanges(),f.addRange(c),s=f.toString()}return s}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,s,a){var f=this.e||(this.e={});return(f[i]||(f[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var f=this;function c(){f.off(i,c),s.apply(a,arguments)}return c._=s,this.on(i,c,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),f=0,c=a.length;for(f;f{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var rs=/["'&<>]/;Yo.exports=ns;function ns(e){var t=""+e,r=rs.exec(t);if(!r)return t;var n,o="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function W(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var n=r.call(e),o,i=[],s;try{for(;(t===void 0||t-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(a){s={error:a}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(s)throw s.error}}return i}function D(e,t,r){if(r||arguments.length===2)for(var n=0,o=t.length,i;n1||a(m,d)})})}function a(m,d){try{f(n[m](d))}catch(h){p(i[0][3],h)}}function f(m){m.value instanceof et?Promise.resolve(m.value.v).then(c,u):p(i[0][2],m)}function c(m){a("next",m)}function u(m){a("throw",m)}function p(m,d){m(d),i.shift(),i.length&&a(i[0][0],i[0][1])}}function pn(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof Ee=="function"?Ee(e):e[Symbol.iterator](),r={},n("next"),n("throw"),n("return"),r[Symbol.asyncIterator]=function(){return this},r);function n(i){r[i]=e[i]&&function(s){return new Promise(function(a,f){s=e[i](s),o(a,f,s.done,s.value)})}}function o(i,s,a,f){Promise.resolve(f).then(function(c){i({value:c,done:a})},s)}}function C(e){return typeof e=="function"}function at(e){var t=function(n){Error.call(n),n.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var It=at(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(n,o){return o+1+") "+n.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Ve(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Ie=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,n,o,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=Ee(s),f=a.next();!f.done;f=a.next()){var c=f.value;c.remove(this)}}catch(v){t={error:v}}finally{try{f&&!f.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var u=this.initialTeardown;if(C(u))try{u()}catch(v){i=v instanceof It?v.errors:[v]}var p=this._finalizers;if(p){this._finalizers=null;try{for(var m=Ee(p),d=m.next();!d.done;d=m.next()){var h=d.value;try{ln(h)}catch(v){i=i!=null?i:[],v instanceof It?i=D(D([],W(i)),W(v.errors)):i.push(v)}}}catch(v){n={error:v}}finally{try{d&&!d.done&&(o=m.return)&&o.call(m)}finally{if(n)throw n.error}}}if(i)throw new It(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)ln(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Ve(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Ve(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Sr=Ie.EMPTY;function jt(e){return e instanceof Ie||e&&"closed"in e&&C(e.remove)&&C(e.add)&&C(e.unsubscribe)}function ln(e){C(e)?e():e.unsubscribe()}var Le={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var st={setTimeout:function(e,t){for(var r=[],n=2;n0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,s=o.isStopped,a=o.observers;return i||s?Sr:(this.currentObservers=null,a.push(r),new Ie(function(){n.currentObservers=null,Ve(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,s=n.isStopped;o?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,n){return new xn(r,n)},t}(F);var xn=function(e){ie(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Sr},t}(x);var Et={now:function(){return(Et.delegate||Date).now()},delegate:void 0};var wt=function(e){ie(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=Et);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,s=n._infiniteTimeWindow,a=n._timestampProvider,f=n._windowTime;o||(i.push(r),!s&&i.push(a.now()+f)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,s=o._buffer,a=s.slice(),f=0;f0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){var i;if(o===void 0&&(o=0),o!=null?o>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);var s=r.actions;n!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==n&&(ut.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Wt);var Sn=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Dt);var Oe=new Sn(wn);var M=new F(function(e){return e.complete()});function Vt(e){return e&&C(e.schedule)}function Cr(e){return e[e.length-1]}function Ye(e){return C(Cr(e))?e.pop():void 0}function Te(e){return Vt(Cr(e))?e.pop():void 0}function zt(e,t){return typeof Cr(e)=="number"?e.pop():t}var pt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Nt(e){return C(e==null?void 0:e.then)}function qt(e){return C(e[ft])}function Kt(e){return Symbol.asyncIterator&&C(e==null?void 0:e[Symbol.asyncIterator])}function Qt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function zi(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Yt=zi();function Gt(e){return C(e==null?void 0:e[Yt])}function Bt(e){return un(this,arguments,function(){var r,n,o,i;return $t(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,et(r.read())];case 3:return n=s.sent(),o=n.value,i=n.done,i?[4,et(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,et(o)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Jt(e){return C(e==null?void 0:e.getReader)}function U(e){if(e instanceof F)return e;if(e!=null){if(qt(e))return Ni(e);if(pt(e))return qi(e);if(Nt(e))return Ki(e);if(Kt(e))return On(e);if(Gt(e))return Qi(e);if(Jt(e))return Yi(e)}throw Qt(e)}function Ni(e){return new F(function(t){var r=e[ft]();if(C(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function qi(e){return new F(function(t){for(var r=0;r=2;return function(n){return n.pipe(e?A(function(o,i){return e(o,i,n)}):de,ge(1),r?He(t):Dn(function(){return new Zt}))}}function Vn(){for(var e=[],t=0;t=2,!0))}function pe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new x}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,f=a===void 0?!0:a;return function(c){var u,p,m,d=0,h=!1,v=!1,Y=function(){p==null||p.unsubscribe(),p=void 0},B=function(){Y(),u=m=void 0,h=v=!1},N=function(){var O=u;B(),O==null||O.unsubscribe()};return y(function(O,Qe){d++,!v&&!h&&Y();var De=m=m!=null?m:r();Qe.add(function(){d--,d===0&&!v&&!h&&(p=$r(N,f))}),De.subscribe(Qe),!u&&d>0&&(u=new rt({next:function($e){return De.next($e)},error:function($e){v=!0,Y(),p=$r(B,o,$e),De.error($e)},complete:function(){h=!0,Y(),p=$r(B,s),De.complete()}}),U(O).subscribe(u))})(c)}}function $r(e,t){for(var r=[],n=2;ne.next(document)),e}function K(e,t=document){return Array.from(t.querySelectorAll(e))}function z(e,t=document){let r=ce(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ce(e,t=document){return t.querySelector(e)||void 0}function _e(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function tr(e){return L(b(document.body,"focusin"),b(document.body,"focusout")).pipe(ke(1),l(()=>{let t=_e();return typeof t!="undefined"?e.contains(t):!1}),V(e===_e()),J())}function Xe(e){return{x:e.offsetLeft,y:e.offsetTop}}function Kn(e){return L(b(window,"load"),b(window,"resize")).pipe(Ce(0,Oe),l(()=>Xe(e)),V(Xe(e)))}function rr(e){return{x:e.scrollLeft,y:e.scrollTop}}function dt(e){return L(b(e,"scroll"),b(window,"resize")).pipe(Ce(0,Oe),l(()=>rr(e)),V(rr(e)))}var Yn=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!Wr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),va?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!Wr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=ba.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Gn=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),Jn=typeof WeakMap!="undefined"?new WeakMap:new Yn,Xn=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=ga.getInstance(),n=new La(t,r,this);Jn.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){Xn.prototype[e]=function(){var t;return(t=Jn.get(this))[e].apply(t,arguments)}});var Aa=function(){return typeof nr.ResizeObserver!="undefined"?nr.ResizeObserver:Xn}(),Zn=Aa;var eo=new x,Ca=$(()=>k(new Zn(e=>{for(let t of e)eo.next(t)}))).pipe(g(e=>L(ze,k(e)).pipe(R(()=>e.disconnect()))),X(1));function he(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ye(e){return Ca.pipe(S(t=>t.observe(e)),g(t=>eo.pipe(A(({target:r})=>r===e),R(()=>t.unobserve(e)),l(()=>he(e)))),V(he(e)))}function bt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function ar(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var to=new x,Ra=$(()=>k(new IntersectionObserver(e=>{for(let t of e)to.next(t)},{threshold:0}))).pipe(g(e=>L(ze,k(e)).pipe(R(()=>e.disconnect()))),X(1));function sr(e){return Ra.pipe(S(t=>t.observe(e)),g(t=>to.pipe(A(({target:r})=>r===e),R(()=>t.unobserve(e)),l(({isIntersecting:r})=>r))))}function ro(e,t=16){return dt(e).pipe(l(({y:r})=>{let n=he(e),o=bt(e);return r>=o.height-n.height-t}),J())}var cr={drawer:z("[data-md-toggle=drawer]"),search:z("[data-md-toggle=search]")};function no(e){return cr[e].checked}function Ke(e,t){cr[e].checked!==t&&cr[e].click()}function Ue(e){let t=cr[e];return b(t,"change").pipe(l(()=>t.checked),V(t.checked))}function ka(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ha(){return L(b(window,"compositionstart").pipe(l(()=>!0)),b(window,"compositionend").pipe(l(()=>!1))).pipe(V(!1))}function oo(){let e=b(window,"keydown").pipe(A(t=>!(t.metaKey||t.ctrlKey)),l(t=>({mode:no("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),A(({mode:t,type:r})=>{if(t==="global"){let n=_e();if(typeof n!="undefined")return!ka(n,r)}return!0}),pe());return Ha().pipe(g(t=>t?M:e))}function le(){return new URL(location.href)}function ot(e){location.href=e.href}function io(){return new x}function ao(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)ao(e,r)}function _(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)ao(n,o);return n}function fr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function so(){return location.hash.substring(1)}function Dr(e){let t=_("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Pa(e){return L(b(window,"hashchange"),e).pipe(l(so),V(so()),A(t=>t.length>0),X(1))}function co(e){return Pa(e).pipe(l(t=>ce(`[id="${t}"]`)),A(t=>typeof t!="undefined"))}function Vr(e){let t=matchMedia(e);return er(r=>t.addListener(()=>r(t.matches))).pipe(V(t.matches))}function fo(){let e=matchMedia("print");return L(b(window,"beforeprint").pipe(l(()=>!0)),b(window,"afterprint").pipe(l(()=>!1))).pipe(V(e.matches))}function zr(e,t){return e.pipe(g(r=>r?t():M))}function ur(e,t={credentials:"same-origin"}){return ue(fetch(`${e}`,t)).pipe(fe(()=>M),g(r=>r.status!==200?Ot(()=>new Error(r.statusText)):k(r)))}function We(e,t){return ur(e,t).pipe(g(r=>r.json()),X(1))}function uo(e,t){let r=new DOMParser;return ur(e,t).pipe(g(n=>n.text()),l(n=>r.parseFromString(n,"text/xml")),X(1))}function pr(e){let t=_("script",{src:e});return $(()=>(document.head.appendChild(t),L(b(t,"load"),b(t,"error").pipe(g(()=>Ot(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(l(()=>{}),R(()=>document.head.removeChild(t)),ge(1))))}function po(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function lo(){return L(b(window,"scroll",{passive:!0}),b(window,"resize",{passive:!0})).pipe(l(po),V(po()))}function mo(){return{width:innerWidth,height:innerHeight}}function ho(){return b(window,"resize",{passive:!0}).pipe(l(mo),V(mo()))}function bo(){return G([lo(),ho()]).pipe(l(([e,t])=>({offset:e,size:t})),X(1))}function lr(e,{viewport$:t,header$:r}){let n=t.pipe(ee("size")),o=G([n,r]).pipe(l(()=>Xe(e)));return G([r,t,o]).pipe(l(([{height:i},{offset:s,size:a},{x:f,y:c}])=>({offset:{x:s.x-f,y:s.y-c+i},size:a})))}(()=>{function e(n,o){parent.postMessage(n,o||"*")}function t(...n){return n.reduce((o,i)=>o.then(()=>new Promise(s=>{let a=document.createElement("script");a.src=i,a.onload=s,document.body.appendChild(a)})),Promise.resolve())}var r=class extends EventTarget{constructor(n){super(),this.url=n,this.m=i=>{i.source===this.w&&(this.dispatchEvent(new MessageEvent("message",{data:i.data})),this.onmessage&&this.onmessage(i))},this.e=(i,s,a,f,c)=>{if(s===`${this.url}`){let u=new ErrorEvent("error",{message:i,filename:s,lineno:a,colno:f,error:c});this.dispatchEvent(u),this.onerror&&this.onerror(u)}};let o=document.createElement("iframe");o.hidden=!0,document.body.appendChild(this.iframe=o),this.w.document.open(),this.w.document.write(` + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

aliases

+ +

Command aliases

+

Base command to add, remove, and list GEF defined aliases.

+
gef➤  aliases
+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.

+
aliases add [alias] [command]
+
+

To remove an alias, simply use the aliases rm command.

+
aliases rm [alias]
+
+

Listing Aliases

+

One can list aliases by using the aliases ls command. Some sample output of this command is seen +below.

+
[+] Aliases defined:
+fmtstr-helper                   →  format-string-helper
+telescope                       →  dereference
+dps                             →  dereference
+dq                              →  hexdump qword
+dd                              →  hexdump dword
+dw                              →  hexdump word
+dc                              →  hexdump byte
+cs-dis                          →  capstone-disassemble
+ctx                             →  context
+start-break                     →  entry-break
+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.

+

Creating a new alias is as simple as creating a new entry in this section:

+
$ nano ~/.gef.rc
+[...]
+[aliases]
+my-new-alias = gdb-or-gef-command <arg1> <arg2> <etc...>
+
+

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:

+
$ nano ~/.gef.rc
+[...]
+[aliases]
+# some windbg aliases
+dps = dereference
+dq = hexdump qword
+dd = hexdump dword
+dw = hexdump word
+dc = hexdump byte
+dt = pcustom
+bl = info breakpoints
+bp = break
+be = enable breakpoints
+bd = disable breakpoints
+bc = delete breakpoints
+tbp = tbreak
+tba = thbreak
+pa = advance
+ptc = finish
+t = stepi
+p = nexti
+g = gef run
+uf = disassemble
+
+

Or here are some PEDA aliases for people used to using PEDA who made the smart move to GEF.

+
# some peda aliases
+telescope = dereference
+start = entry-break
+stack = dereference -l 10 $sp
+argv = show args
+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:

+
gef➤  gef restore
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/aslr/index.html b/commands/aslr/index.html new file mode 100644 index 000000000..501c0c2eb --- /dev/null +++ b/commands/aslr/index.html @@ -0,0 +1,1778 @@ + + + + + + + + + + + + + + + + + + + + + + aslr - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

aslr

+ +

Command aslr

+

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
+gef➤  aslr
+ASLR is currently enabled
+
+

De-activate ASLR:

+
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..

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/canary/index.html b/commands/canary/index.html new file mode 100644 index 000000000..9b7847586 --- /dev/null +++ b/commands/canary/index.html @@ -0,0 +1,1767 @@ + + + + + + + + + + + + + + + + + + + + + + canary - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

canary

+ +

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.

+

The command canary does not take any arguments.

+
gef➤ canary
+
+

gef-canary

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/checksec/index.html b/commands/checksec/index.html new file mode 100644 index 000000000..0e7f42ace --- /dev/null +++ b/commands/checksec/index.html @@ -0,0 +1,1776 @@ + + + + + + + + + + + + + + + + + + + + + + checksec - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

checksec

+ +

Command checksec

+

The checksec command is inspired from checksec.sh. +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'
+Canary:                                           No
+NX Support:                                       Yes
+PIE Support:                                      No
+No RPATH:                                         Yes
+No RUNPATH:                                       Yes
+Partial RelRO:                                    Yes
+Full RelRO:                                       No
+
+

Or specify directly the binary to check, for example:

+
$ gdb -ex "checksec ./tests/test-x86"
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/config/index.html b/commands/config/index.html new file mode 100644 index 000000000..50a2d6ab8 --- /dev/null +++ b/commands/config/index.html @@ -0,0 +1,1786 @@ + + + + + + + + + + + + + + + + + + + + + + config - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

config

+ +

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.

+

To view all settings for all commands loaded:

+
gef➤  gef config
+
+

gef-config

+

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'
+
+

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:

+
gef➤  gef restore
+[+] Configuration from '/home/hugsy/.gef.rc' restored
+
+

You can tweak this configuration file outside your gdb session to suit your needs.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/context/index.html b/commands/context/index.html new file mode 100644 index 000000000..3bc8e3e26 --- /dev/null +++ b/commands/context/index.html @@ -0,0 +1,1990 @@ + + + + + + + + + + + + + + + + + + + + + + context - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+ + + +
+
+ + + + +

context

+ +

Command context

+

gef-context

+

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.
  • +
+

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:

+
register_external_context_pane(pane_name, display_pane_function, pane_title_function)
+
+

Check the API 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➤ 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
  • +
+

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"
+
+

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 +memory command. For instance,

+
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.

+

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.
  • +
+

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
+. . . (440 bytes skipped)
+0x00007fffffffc7e8│+0x38: 0x0000000000000000
+0x00007fffffffc7e0│+0x30: 0x0000000000000026 ("&"?)
+0x00007fffffffc7d8│+0x28: 0x0000000001958ac0
+0x00007fffffffc7d0│+0x20: 0x00007ffff7ffa2b0  →  0x5f6f7364765f5f00
+0x00007fffffffc7c8│+0x18: 0x00007fff00000000
+0x00007fffffffc7c0│+0x10: 0x00007fffffffc950  →  0x0000000000000000
+0x00007fffffffc7b8│+0x08: 0x0000000000000000
+0x00007fffffffc7b0│+0x00: 0x00007fffffffc7e4  →  0x0000000000000000      ← $rsp
+
+

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.

+

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

Enjoy: +gef-context-redirect-section

+

To go back to normal, remove the value:

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

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
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/dereference/index.html b/commands/dereference/index.html new file mode 100644 index 000000000..a7070af82 --- /dev/null +++ b/commands/dereference/index.html @@ -0,0 +1,1824 @@ + + + + + + + + + + + + + + + + + + + + + + dereference - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

dereference

+ +

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.

+

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

+
gef➤  dereference
+0x00007fffffffdec0│+0x0000: 0x00007ffff7ffe190  →  0x0000555555554000  →   jg 0x555555554047     ← $rsp, $r13
+0x00007fffffffdec8│+0x0008: 0x00007ffff7ffe730  →  0x00007ffff7fd3000  →  0x00010102464c457f
+0x00007fffffffded0│+0x0010: 0x00007ffff7faa000  →  0x00007ffff7de9000  →  0x03010102464c457f
+0x00007fffffffded8│+0x0018: 0x00007ffff7ffd9f0  →  0x00007ffff7fd5000  →  0x00010102464c457f
+0x00007fffffffdee0│+0x0020: 0x00007fffffffdee0  →  [loop detected]
+0x00007fffffffdee8│+0x0028: 0x00007fffffffdee0  →  0x00007fffffffdee0  →  [loop detected]
+0x00007fffffffdef0│+0x0030: 0x00000000f7fa57e3
+0x00007fffffffdef8│+0x0038: 0x0000555555755d60  →  0x0000555555554a40  →   cmp BYTE PTR [rip+0x201601], 0x0        # 0x555555756048
+0x00007fffffffdf00│+0x0040: 0x0000000000000004
+0x00007fffffffdf08│+0x0048: 0x0000000000000001
+
+

Here is an example with arguments:

+
gef➤  telescope $rbp+0x10 -l 8
+0x00007fffffffdf40│+0x0000: 0x00007ffff7fa5760  →  0x00000000fbad2887
+0x00007fffffffdf48│+0x0008: 0x00000001f7e65b63
+0x00007fffffffdf50│+0x0010: 0x0000000000000004
+0x00007fffffffdf58│+0x0018: 0x0000000000000000
+0x00007fffffffdf60│+0x0020: 0x00007fffffffdfa0  →  0x0000555555554fd0  →   push r15
+0x00007fffffffdf68│+0x0028: 0x0000555555554980  →   xor ebp, ebp
+0x00007fffffffdf70│+0x0030: 0x00007fffffffe080  →  0x0000000000000001
+0x00007fffffffdf78│+0x0038: 0x0000000000000000
+
+

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

+
gef➤  p ($rbp - $rsp)/8
+$3 = 4
+gef➤  dereference -l 5
+0x00007fffffffe170│+0x0000: 0x0000000000400690  →  push r15        ← $rsp
+0x00007fffffffe178│+0x0008: 0x0000000000400460  →  xor ebp, ebp
+0x00007fffffffe180│+0x0010: 0x00007fffffffe270  →  0x1
+0x00007fffffffe188│+0x0018: 0x1
+0x00007fffffffe190│+0x0020: 0x0000000000400690  →  push r15        ← $rbp
+
+

It is possible to change the offset calculation to use a different address than the start address:

+
gef➤  dereference $sp -l 7 -r $rbp
+0x00007ffe6ddaa3e0│-0x0030: 0x0000000000000000    ← $rsp
+0x00007ffe6ddaa3e8│-0x0028: 0x0000000000400970  →  <__libc_csu_init+0> push r15
+0x00007ffe6ddaa3f0│-0x0020: 0x0000000000000000
+0x00007ffe6ddaa3f8│-0x0018: 0x00000000004006e0  →  <_start+0> xor ebp, ebp
+0x00007ffe6ddaa400│-0x0010: 0x00007ffe6ddaa500  →  0x0000000000000001
+0x00007ffe6ddaa408│-0x0008: 0xa42456b3ee465800
+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:

+
gef➤  dereference $sp -l 3
+0x00007fffffffcf90│+0x0010: 0x00007ffff7f5aaa0  →  0x0000000000000000
+0x00007fffffffcf88│+0x0008: 0x00000000000204a0
+0x00007fffffffcf80│+0x0000: 0x00005555555a6b60  →  0x0000000000000000    ← $rsp
+gef➤  dereference $sp -l -3
+0x00007fffffffcf80│+0x0000: 0x00005555555a6b60  →  0x0000000000000000    ← $rsp
+0x00007fffffffcf78│-0x0008: 0x0000000000000020 (" "?)
+0x00007fffffffcf70│-0x0010: 0x000000000000000a ("\n"?)
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/edit-flags/index.html b/commands/edit-flags/index.html new file mode 100644 index 000000000..10b6d737f --- /dev/null +++ b/commands/edit-flags/index.html @@ -0,0 +1,1773 @@ + + + + + + + + + + + + + + + + + + + + + + edit-flags - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

edit-flags

+ +

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.

+

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.

+

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

flags

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/elf-info/index.html b/commands/elf-info/index.html new file mode 100644 index 000000000..5e914eb1e --- /dev/null +++ b/commands/elf-info/index.html @@ -0,0 +1,1825 @@ + + + + + + + + + + + + + + + + + + + + + + elf-info - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

elf-info

+ +

Command elf-info

+

elf-info (alias elf) provides some basic information on the currently loaded ELF binary:

+
gef➤  elf
+Magic                 : 7f 45 4c 46
+Class                 : 0x2 - 64-bit
+Endianness            : 0x1 - Little-Endian
+Version               : 0x1
+OS ABI                : 0x0 - System V
+ABI Version           : 0x0
+Type                  : 0x2 - Executable
+Machine               : 0x3e - x86-64
+Program Header Table  : 0x0000000000000040
+Section Header Table  : 0x00000000000021a8
+Header Table          : 0x0000000000000040
+ELF Version           : 0x1
+Header size           : 64 (0x40)
+Entry point           : 0x0000000000400750
+
+────────────────────────────────────────── Program Header ──────────────────────────────────────────
+  [ #] Type           Offset Virtaddr Physaddr  FileSiz   MemSiz Flags    Align
+  [ 0] PHDR             0x40 0x400040 0x400040    0x1f8    0x1f8 R-X        0x8
+  [ 1] INTERP          0x238 0x400238 0x400238     0x1c     0x1c R--        0x1
+  [ 2] LOAD              0x0 0x400000 0x400000   0x1414   0x1414 R-X   0x200000
+  [ 3] LOAD           0x1e10 0x601e10 0x601e10    0x268    0x330 RW-   0x200000
+  [ 4] DYNAMIC        0x1e28 0x601e28 0x601e28    0x1d0    0x1d0 RW-        0x8
+  [ 5] NOTE            0x254 0x400254 0x400254     0x44     0x44 R--        0x4
+  [ 6] GNU_EH_FLAME   0x11a0 0x4011a0 0x4011a0     0x74     0x74 R--        0x4
+  [ 7] GNU_STACK         0x0      0x0      0x0      0x0      0x0 RW-       0x10
+  [ 8] GNU_RELRO      0x1e10 0x601e10 0x601e10    0x1f0    0x1f0 R--        0x1
+
+────────────────────────────────────────── Section Header ──────────────────────────────────────────
+  [ #] Name                            Type  Address   Offset     Size   EntSiz Flags Link Info    Align
+  [ 0]                                 NULL      0x0      0x0      0x0      0x0        0x0  0x0      0x0
+  [ 1] .interp                     PROGBITS 0x400238    0x238     0x1c      0x0 A      0x0  0x0      0x1
+  [ 2] .note.ABI-tag                   NOTE 0x400254    0x254     0x20      0x0 A      0x0  0x0      0x4
+  [ 3] .note.gnu.build-id              NOTE 0x400274    0x274     0x24      0x0 A      0x0  0x0      0x4
+  [ 4] .gnu.hash                   GNU_HASH 0x400298    0x298     0x30      0x0 A      0x5  0x0      0x8
+  [ 5] .dynsym                       DYNSYM 0x4002c8    0x2c8    0x168     0x18 A      0x6  0x1      0x8
+  [ 6] .dynstr                       STRTAB 0x400430    0x430     0x96      0x0 A      0x0  0x0      0x1
+  [ 7] .gnu.version                    HIOS 0x4004c6    0x4c6     0x1e      0x2 A      0x5  0x0      0x2
+  [ 8] .gnu.version_r           GNU_verneed 0x4004e8    0x4e8     0x30      0x0 A      0x6  0x1      0x8
+  [ 9] .rela.dyn                       RELA 0x400518    0x518     0x60     0x18 A      0x5  0x0      0x8
+  [10] .rela.plt                       RELA 0x400578    0x578     0xf0     0x18 AI     0x5 0x18      0x8
+  [11] .init                       PROGBITS 0x400668    0x668     0x1a      0x0 AX     0x0  0x0      0x4
+  [12] .plt                        PROGBITS 0x400690    0x690     0xb0     0x10 AX     0x0  0x0     0x10
+  [13] .plt.got                    PROGBITS 0x400740    0x740      0x8      0x0 AX     0x0  0x0      0x8
+  [14] .text                       PROGBITS 0x400750    0x750    0x842      0x0 AX     0x0  0x0     0x10
+  [15] .fini                       PROGBITS 0x400f94    0xf94      0x9      0x0 AX     0x0  0x0      0x4
+  [16] .rodata                     PROGBITS 0x400fa0    0xfa0    0x200      0x0 A      0x0  0x0      0x8
+  [17] .eh_frame_hdr               PROGBITS 0x4011a0   0x11a0     0x74      0x0 A      0x0  0x0      0x4
+  [18] .eh_frame                   PROGBITS 0x401218   0x1218    0x1fc      0x0 A      0x0  0x0      0x8
+  [19] .init_array               INIT_ARRAY 0x601e10   0x1e10      0x8      0x0 WA     0x0  0x0      0x8
+  [20] .fini_array               FINI_ARRAY 0x601e18   0x1e18      0x8      0x0 WA     0x0  0x0      0x8
+  [21] .jcr                        PROGBITS 0x601e20   0x1e20      0x8      0x0 WA     0x0  0x0      0x8
+  [22] .dynamic                     DYNAMIC 0x601e28   0x1e28    0x1d0     0x10 WA     0x6  0x0      0x8
+  [23] .got                        PROGBITS 0x601ff8   0x1ff8      0x8      0x8 WA     0x0  0x0      0x8
+  [24] .got.plt                    PROGBITS 0x602000   0x2000     0x68      0x8 WA     0x0  0x0      0x8
+  [25] .data                       PROGBITS 0x602068   0x2068     0x10      0x0 WA     0x0  0x0      0x8
+  [26] .bss                          NOBITS 0x602080   0x2078     0xc0      0x0 WA     0x0  0x0     0x20
+  [27] .comment                    PROGBITS      0x0   0x2078     0x34      0x1 MS     0x0  0x0      0x1
+  [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.

+
gef➤ elf-info --filename /path/to/elf/executable
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/entry-break/index.html b/commands/entry-break/index.html new file mode 100644 index 000000000..58fe6c2ba --- /dev/null +++ b/commands/entry-break/index.html @@ -0,0 +1,1772 @@ + + + + + + + + + + + + + + + + + + + + + + entry-break - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

entry-break

+ +

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.

+

It will perform the following actions:

+
    +
  1. Look up a main symbol. If found, set a temporary breakpoint and go.
  2. +
  3. Otherwise, it will look up for __libc_start_main. If found, set a temporary breakpoint and go.
  4. +
  5. 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.
  6. +
+

entry-break-example

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/eval/index.html b/commands/eval/index.html new file mode 100644 index 000000000..aa6e4dad4 --- /dev/null +++ b/commands/eval/index.html @@ -0,0 +1,1796 @@ + + + + + + + + + + + + + + + + + + + + + + eval - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

eval

+ +

Command $

+

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:

+
gef➤  $ $pc+1
+93824992252977
+0x555555559431
+0b10101010101010101010101010101011001010000110001
+b'UUUU\x941'
+b'1\x94UUUU'
+
+gef➤  $ -0x1000
+-4096
+0xfffffffffffff000
+0b1111111111111111111111111111111111111111111111111111000000000000
+b'\xff\xff\xff\xff\xff\xff\xf0\x00'
+b'\x00\xf0\xff\xff\xff\xff\xff\xff'
+
+

With two arguments, it will simply compute the delta between them:

+
gef➤  vmmap libc
+Start              End                Offset             Perm
+0x00007ffff7812000 0x00007ffff79a7000 0x0000000000000000 r-x /lib/x86_64-linux-gnu/libc-2.24.so
+0x00007ffff79a7000 0x00007ffff7ba7000 0x0000000000195000 --- /lib/x86_64-linux-gnu/libc-2.24.so
+0x00007ffff7ba7000 0x00007ffff7bab000 0x0000000000195000 r-- /lib/x86_64-linux-gnu/libc-2.24.so
+0x00007ffff7bab000 0x00007ffff7bad000 0x0000000000199000 rw- /lib/x86_64-linux-gnu/libc-2.24.so
+
+gef➤  $ 0x00007ffff7812000 0x00007ffff79a7000
+-1658880
+1658880
+
+gef➤  $ 1658880
+1658880
+0x195000
+0b110010101000000000000
+b'\x19P\x00'
+b'\x00P\x19'
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/format-string-helper/index.html b/commands/format-string-helper/index.html new file mode 100644 index 000000000..1aea36e7e --- /dev/null +++ b/commands/format-string-helper/index.html @@ -0,0 +1,1780 @@ + + + + + + + + + + + + + + + + + + + + + + format-string-helper - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

format-string-helper

+ +

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.

+

It will use this new breakpoint against several targets, including:

+
    +
  • printf()
  • +
  • sprintf()
  • +
  • fprintf()
  • +
  • snprintf()
  • +
  • vsnprintf()
  • +
+

Just call the command to enable this functionality.

+

fmtstr-helper is a shorter alias.

+
gef➤ fmtstr-helper
+
+

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.

+

fmtstr-helper-example

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/functions/index.html b/commands/functions/index.html new file mode 100644 index 000000000..b95957249 --- /dev/null +++ b/commands/functions/index.html @@ -0,0 +1,1787 @@ + + + + + + + + + + + + + + + + + + + + + + functions - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

functions

+ +

Command functions

+

The functions command will list all of the convenience +functions 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.
  • +
+

These functions can be used as arguments to other commands to dynamically calculate values.

+
gef➤  deref -l 4 $_heap()
+0x0000000000602000│+0x00: 0x0000000000000000     ← $r8
+0x0000000000602008│+0x08: 0x0000000000000021 ("!"?)
+0x0000000000602010│+0x10: 0x0000000000000000     ← $rax, $rdx
+0x0000000000602018│+0x18: 0x0000000000000000
+gef➤  deref -l 4 $_heap(0x20)
+0x0000000000602020│+0x00: 0x0000000000000000     ← $rsi
+0x0000000000602028│+0x08: 0x0000000000020fe1
+0x0000000000602030│+0x10: 0x0000000000000000
+0x0000000000602038│+0x18: 0x0000000000000000
+gef➤  deref -l 4 $_base(\"libc\")
+0x00007ffff7da9000│+0x0000: 0x03010102464c457f
+0x00007ffff7da9008│+0x0008: 0x0000000000000000
+0x00007ffff7da9010│+0x0010: 0x00000001003e0003
+0x00007ffff7da9018│+0x0018: 0x0000000000027c60
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/gef-remote/index.html b/commands/gef-remote/index.html new file mode 100644 index 000000000..bd111e1b5 --- /dev/null +++ b/commands/gef-remote/index.html @@ -0,0 +1,1962 @@ + + + + + + + + + + + + + + + + + + + + + + gef-remote - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

gef-remote

+ +

Command gef-remote

+

target remote +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.

+

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.

+

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.

+

For example, if we want to debug uname, we do on the server:

+
$ gdbserver  :1234 /tmp/default.out
+Process /tmp/default.out created; pid = 258932
+Listening on port 1234
+
+

gef-remote-1

+

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'
+GEF for linux ready, type `gef' to start, `gef config' to configure
+90 commands loaded and 5 functions added for GDB 10.2 using Python engine 3.8
+gef➤ gef-remote localhost 1234
+[=] [remote] initializing remote session with localhost:1234 under /tmp/tmp8qd0r7iw
+[=] [remote] Installing new objfile handlers
+[=] [remote] Enabling extended remote: False
+[=] [remote] Executing 'target remote localhost:1234'
+Reading /tmp/default.out from remote target...
+warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
+Reading /tmp/default.out from remote target...
+Reading symbols from target:/tmp/default.out...
+[=] [remote] in remote_objfile_handler(target:/tmp/default.out))
+[=] [remote] downloading '/tmp/default.out' -> '/tmp/tmp8qd0r7iw/tmp/default.out'
+Reading /lib64/ld-linux-x86-64.so.2 from remote target...
+Reading /lib64/ld-linux-x86-64.so.2 from remote target...
+[=] [remote] in remote_objfile_handler(/usr/lib/debug/.build-id/45/87364908de169dec62ffa538170118c1c3a078.debug))
+[=] [remote] in remote_objfile_handler(target:/lib64/ld-linux-x86-64.so.2))
+[=] [remote] downloading '/lib64/ld-linux-x86-64.so.2' -> '/tmp/tmp8qd0r7iw/lib64/ld-linux-x86-64.so.2'
+[=] [remote] in remote_objfile_handler(system-supplied DSO at 0x7ffff7fcd000))
+[*] [remote] skipping 'system-supplied DSO at 0x7ffff7fcd000'
+0x00007ffff7fd0100 in _start () from target:/lib64/ld-linux-x86-64.so.2
+[=] Setting up as remote session
+[=] [remote] downloading '/proc/258932/maps' -> '/tmp/tmp8qd0r7iw/proc/258932/maps'
+[=] [remote] downloading '/proc/258932/environ' -> '/tmp/tmp8qd0r7iw/proc/258932/environ'
+[=] [remote] downloading '/proc/258932/cmdline' -> '/tmp/tmp8qd0r7iw/proc/258932/cmdline'
+[...]
+
+

And finally breaking into the program, showing the current context:

+

gef-remote

+

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

+

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 +stub 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

+
    +
  1. Run qemu-x86_64 :1234 /bin/ls
  2. +
  3. Use --qemu-user and --qemu-binary /bin/ls when starting gef-remote
  4. +
+

qemu-user

+

qemu-system

+

To test locally, you can use the mini image linux x64 vm +here. + 1. Run ./run.sh + 2. Use --qemu-user and --qemu-binary vmlinuz when starting gef-remote

+

qemu-system

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/gef/index.html b/commands/gef/index.html new file mode 100644 index 000000000..ab5931db9 --- /dev/null +++ b/commands/gef/index.html @@ -0,0 +1,1982 @@ + + + + + + + + + + + + + + + + + + + + + + gef - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

gef

+ +

Command gef

+

GEF Base Command

+

Displays a list of GEF commands and their descriptions.

+
gef➤  gef
+─────────────────────────────────── GEF - GDB Enhanced Features ───────────────────────────────────
+$                         -- SmartEval: Smart eval (vague approach to mimic WinDBG `?`).
+aslr                      -- 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.
+assemble                  -- Inline code assemble. Architecture can be set in GEF runtime config (default x86-32).  (alias: asm)
+bincompare                -- BincompareCommand: compare an binary file with the memory position looking for badchars.
+bytearray                 -- BytearrayCommand: Generate a bytearray to be compared with possible badchars.
+
+[...snip...]
+
+
+

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➤  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 +persistent see the gef save entry.

+

Using gef config by itself just shows all of the available settings and their values.

+
gef➤  gef config
+──────────────────────────────────── GEF configuration settings ────────────────────────────────────
+context.clear_screen (bool) = False
+context.enable (bool) = True
+context.grow_stack_down (bool) = False
+context.ignore_registers (str) = ""
+context.layout (str) = "-code -stack"
+context.libc_args (bool) = False
+
+[...snip...]
+
+
+

To filter the config settings you can use gef config [setting].

+
gef➤  gef config theme
+─────────────────────────── GEF configuration settings matching 'theme' ───────────────────────────
+theme.context_title_line (str) = "gray"
+theme.context_title_message (str) = "cyan"
+theme.default_title_line (str) = "gray"
+theme.default_title_message (str) = "cyan"
+
+[...snip...]
+
+
+

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

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

+
gef➤  gef save
+[+] Configuration saved to '/home/michael/.gef.rc'
+
+

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.

+
gef➤  gef restore
+[+] Configuration from '/home/michael/.gef.rc' restored
+
+

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.

+
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.

+
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➤  gef install SCRIPTNAME1 [SCRIPTNAME2...]
+
+

Where SCRIPTNAME1 ... are the names of script from the gef-extras +repository.

+
gef➤  gef install remote windbg stack
+[+] Searching for 'remote.py' in `gef-extras@main`...
+[+] Installed file '/tmp/gef/remote.py', new command(s) available: `rpyc-remote`
+[+] Searching for 'windbg.py' in `gef-extras@main`...
+[+] Installed file '/tmp/gef/windbg.py', new command(s) available: `pt`, `hh`, `tt`, `ptc`, `sxe`, `u`, `xs`, `tc`, `pc`, `g`, `r`
+[+] Searching for 'stack.py' in `gef-extras@main`...
+[+] Installed file '/tmp/gef/stack.py', new command(s) available: `current-stack-frame`
+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
+
+

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.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/got/index.html b/commands/got/index.html new file mode 100644 index 000000000..d51c2a8a3 --- /dev/null +++ b/commands/got/index.html @@ -0,0 +1,1776 @@ + + + + + + + + + + + + + + + + + + + + + + got - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

got

+ +

Command got

+

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

gef-got

+

The applied filter partially matches the name of the functions, so you can do something like this.

+
gef➤ got str
+gef➤ got print
+gef➤ got read
+
+

gef-got-one-filter

+

Example of multiple partial filters:

+
gef➤ got str get
+
+

gef-got-multi-filter

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/heap-analysis-helper/index.html b/commands/heap-analysis-helper/index.html new file mode 100644 index 000000000..d535c37b1 --- /dev/null +++ b/commands/heap-analysis-helper/index.html @@ -0,0 +1,1810 @@ + + + + + + + + + + + + + + + + + + + + + + heap-analysis-helper - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

heap-analysis-helper

+ +

Command heap-analysis-helper

+

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.

+

Currently, the following issues can be tracked:

+
    +
  • NULL free
  • +
  • Use-after-Free
  • +
  • Double Free
  • +
  • Heap overlap
  • +
+

The helper can simply be activated by running the command heap-analysis-helper.

+
gef➤ heap-analysis
+[+] Tracking malloc()
+[+] Tracking free()
+[+] Disabling hardware watchpoints (this may increase the latency)
+[+] Dynamic breakpoints correctly setup, GEF will break execution if a possible vulnerabity is found.
+[+] 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 +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;
  • +
+

double-free

+
    +
  • 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

+

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:

+
gef➤  gef config heap-analysis-helper.check_double_free False
+gef➤  gef config heap-analysis-helper.check_free_null False
+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.

+

heap-track

+

To get information regarding the currently tracked chunks, use the show subcommand:

+
gef➤  heap-analysis-helper show
+
+

heap-analysis-helper-show

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/heap/index.html b/commands/heap/index.html new file mode 100644 index 000000000..730ca17b1 --- /dev/null +++ b/commands/heap/index.html @@ -0,0 +1,2026 @@ + + + + + + + + + + + + + + + + + + + + + + heap - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+ + + +
+
+ + + + +

heap

+ +

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 for malloc +structure information). Syntax to the subcommands is straight forward:

+
gef➤ heap <sub_commands>
+
+

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:

+
gef➤ gef config gef.main_arena_offset <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:

+
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.

+
gef➤ heap chunks
+
+

heap-chunks

+

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]
+
+

heap-chunks-arena

+

In order to display the chunks of all the available arenas at once use

+
gef➤ heap chunks -a
+
+

heap-chunks-all

+

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:

+
gef➤ heap chunk [address]
+
+

heap-chunk

+

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:

+
gef➤ heap chunk --number 6 0x4e5400
+Chunk(addr=0x4e5400, size=0xd0, flags=PREV_INUSE)
+Chunk(addr=0x4e54d0, size=0x1a0, flags=PREV_INUSE)
+Chunk(addr=0x4e5670, size=0x200, flags=PREV_INUSE)
+Chunk(addr=0x4e5870, size=0xbc0, flags=PREV_INUSE)
+Chunk(addr=0x4e6430, size=0x330, flags=PREV_INUSE)
+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.

+

heap-arenas

+

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:

+
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.

+

heap bins command

+

Glibc uses bins for keeping tracks of freed 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
  • +
  • unsorted
  • +
  • small bins
  • +
  • large bins
  • +
  • tcachebins
  • +
+

heap bins fast command

+

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

+
gef➤ heap bins fast
+──────────────────────── Fastbins for arena 0x7ffff7fb8b80 ────────────────────────
+Fastbins[idx=0, size=0x20]  ←  Chunk(addr=0x555555559380, size=0x20, flags=PREV_INUSE)
+Fastbins[idx=1, size=0x30] 0x00
+Fastbins[idx=2, size=0x40] 0x00
+Fastbins[idx=3, size=0x50] 0x00
+Fastbins[idx=4, size=0x60] 0x00
+Fastbins[idx=5, size=0x70] 0x00
+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.

+

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.

+
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 tcaches 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
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/help/index.html b/commands/help/index.html new file mode 100644 index 000000000..a338728bf --- /dev/null +++ b/commands/help/index.html @@ -0,0 +1,1763 @@ + + + + + + + + + + + + + + + + + + + + + + help - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

help

+ +

Command gef help

+

Displays the help menu for the loaded GEF commands.

+
gef➤ gef help
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/hexdump/index.html b/commands/hexdump/index.html new file mode 100644 index 000000000..ab2e23431 --- /dev/null +++ b/commands/hexdump/index.html @@ -0,0 +1,1804 @@ + + + + + + + + + + + + + + + + + + + + + + hexdump - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

hexdump

+ +

Command hexdump

+

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)
  • +
  • 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).

+

The syntax is as following:

+
hexdump (qword|dword|word|byte) [-h] [--reverse] [--size SIZE] [address]
+
+

Examples:

+
    +
  • Display 4 QWORDs from $pc:
  • +
+
gef➤  hexdump qword $pc --size 4
+0x7ffff7a5c1c0+0000 │ 0x4855544155415641
+0x7ffff7a5c1c0+0008 │ 0x0090ec814853cd89
+0x7ffff7a5c1c0+0010 │ 0x377d6f058b480000
+0x7ffff7a5c1c0+0018 │ 0x748918247c894800
+
+
    +
  • Display 32 bytes from a location in the stack:
  • +
+
gef➤  hexdump byte 0x00007fffffffe5e5 --size 32
+0x00007fffffffe5e5     2f 68 6f 6d 65 2f 68 75 67 73 79 2f 63 6f 64 65     /home/hugsy/code
+0x00007fffffffe5f5     2f 67 65 66 2f 74 65 73 74 73 2f 77 69 6e 00 41     /gef/tests/win.A
+
+
    +
  • Display 8 WORDs from $sp in reverse order:
  • +
+
gef➤  hexdump word 8 --reverse
+0x00007fffffffe0ee│+0x000e   0x0000
+0x00007fffffffe0ec│+0x000c   0x7fff
+0x00007fffffffe0ea│+0x000a   0xffff
+0x00007fffffffe0e8│+0x0008   0xe3f5
+0x00007fffffffe0e6│+0x0006   0x0000
+0x00007fffffffe0e4│+0x0004   0x0000
+0x00007fffffffe0e2│+0x0002   0x0000
+0x00007fffffffe0e0│+0x0000   0x0001
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/highlight/index.html b/commands/highlight/index.html new file mode 100644 index 000000000..75998d518 --- /dev/null +++ b/commands/highlight/index.html @@ -0,0 +1,1904 @@ + + + + + + + + + + + + + + + + + + + + + + highlight - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

highlight

+ +

Command highlight

+

This command sets up custom highlighting for user set strings.

+

Syntax:

+
highlight (add|remove|list|clear)
+
+

Alias:

+
    +
  • hl
  • +
+

Adding matches

+

The following will add 41414141/'AAAA' as yellow, and 42424242/'BBBB' +as blue:

+
gef➤  hl add 41414141 yellow
+gef➤  hl add 42424242 blue
+gef➤  hl add AAAA yellow
+gef➤  hl add BBBB blue
+
+

Removing matches

+

To remove a match, target it by the original string used, ex.:

+
gef➤  hl rm 41414141
+
+

Listing matches

+

To list all matches with their colors:

+
gef➤  hl list
+41414141 | yellow
+42424242 | blue
+AAAA     | yellow
+BBBB     | blue
+
+

Clearing all matches

+

To clear all matches currently setup:

+
gef➤  hl clear
+
+

RegEx support

+

RegEx support is disabled by default, this is done for performance reasons.

+

To enable regular expressions on text matches:

+
gef➤  gef config highlight.regex True
+
+

To check the current status:

+
gef➤  gef config highlight.regex
+highlight.regex (bool) = True
+
+

Performance

+

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 documentation.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/hijack-fd/index.html b/commands/hijack-fd/index.html new file mode 100644 index 000000000..d5114c60d --- /dev/null +++ b/commands/hijack-fd/index.html @@ -0,0 +1,1777 @@ + + + + + + + + + + + + + + + + + + + + + + hijack-fd - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

hijack-fd

+ +

Command hijack-fd

+

gef can be used to modify file descriptors of the debugged process. The new +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

+

Check out the tutorial on GEF's YouTube channel:

+

yt-tuto-hijack-fd

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/ksymaddr/index.html b/commands/ksymaddr/index.html new file mode 100644 index 000000000..d85e004b0 --- /dev/null +++ b/commands/ksymaddr/index.html @@ -0,0 +1,1775 @@ + + + + + + + + + + + + + + + + + + + + + + ksymaddr - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

ksymaddr

+ +

Command ksymaddr

+

ksymaddr helps locate a kernel symbol by its name.

+

The syntax is straight forward:

+
ksymaddr <PATTERN>
+
+

For example,

+
gef➤  ksymaddr commit_creds
+[+] Found matching symbol for 'commit_creds' at 0xffffffff8f495740 (type=T)
+[*] Found partial match for 'commit_creds' at 0xffffffff8f495740 (type=T): commit_creds
+[*] Found partial match for 'commit_creds' at 0xffffffff8fc71ee0 (type=R): __ksymtab_commit_creds
+[*] Found partial match for 'commit_creds' at 0xffffffff8fc8d008 (type=r): __kcrctab_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.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/memory/index.html b/commands/memory/index.html new file mode 100644 index 000000000..e53423478 --- /dev/null +++ b/commands/memory/index.html @@ -0,0 +1,1868 @@ + + + + + + + + + + + + + + + + + + + + + + memory - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

memory

+ +

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.

+

memory watch

+

Note: this command shoud NOT be mistaken with the GDB watch +command 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 <ADDRESS> [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.

+

Note that the address format is a GDB therefore a symbol can be passed to it. It also supports GEF +functions +format +allowing to easily track commonly used addresses:

+

For example, to watch the first 5 entries of the GOT as pointers:

+
gef ➤ memory watch $_got()+0x18 5
+[+] Adding memwatch to 0x555555773c50
+
+

Which, when the context is displayed, will show something like:

+

+

Removing a watch

+

Remove a watched address. To list all the addresses being watched, use memory list.

+

Syntax:

+
memory unwatch <ADDRESS>
+
+

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
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/name-break/index.html b/commands/name-break/index.html new file mode 100644 index 000000000..23d9c7eee --- /dev/null +++ b/commands/name-break/index.html @@ -0,0 +1,1797 @@ + + + + + + + + + + + + + + + + + + + + + + name-break - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

name-break

+ +

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.

+

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.

+

Examples:

+
    +
  • nb first *0x400ec0
  • +
  • nb "main func" main
  • +
  • nb read_secret *main+149
  • +
  • nb check_heap
  • +
+

Example output:

+
─────────────────────────────────────────────────────────────────────────── code:x86:64 ────
+     0x400e04                  add    eax, 0xfffbe6e8
+     0x400e09                  dec    ecx
+     0x400e0b                  ret
+ →   0x400e0c                  push   rbp
+     0x400e0d                  mov    rbp, rsp
+     0x400e10                  sub    rsp, 0x50
+     0x400e14                  mov    QWORD PTR [rbp-0x48], rdi
+     0x400e18                  mov    QWORD PTR [rbp-0x50], rsi
+     0x400e1c                  mov    rax, QWORD PTR fs:0x28
+───────────────────────────────────────────────────────────────────────────────── stack ────
+0x00007fffffffe288│+0x0000: 0x0000000000401117  →   movzx ecx, al    ← $rsp
+0x00007fffffffe290│+0x0008: 0x00007fffffffe4b8  →  0x00007fffffffe71d  →  "/ctf/t19/srv_copy"
+0x00007fffffffe298│+0x0010: 0x0000000100000000
+0x00007fffffffe2a0│+0x0018: 0x0000000000000000
+0x00007fffffffe2a8│+0x0020: 0x0000000000000004
+0x00007fffffffe2b0│+0x0028: 0x0000000000000000
+───────────────────────────────────────────────────────────────────────────────── extra ────
+[+] Hit breakpoint *0x400e0c (check_entry)
+────────────────────────────────────────────────────────────────────────────────────────────
+gef➤
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/nop/index.html b/commands/nop/index.html new file mode 100644 index 000000000..0da3bc2a2 --- /dev/null +++ b/commands/nop/index.html @@ -0,0 +1,1790 @@ + + + + + + + + + + + + + + + + + + + + + + nop - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

nop

+ +

Command nop

+

The nop command allows you to easily patch instructions with nops.

+
nop [LOCATION] [--i ITEMS] [--f] [--n] [--b]
+
+

LOCATION address/symbol to patch (by default this command replaces whole instructions)

+

--i ITEMS number of items to insert (default 1)

+

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

+
gef➤    nop
+
+

nop an instruction at $pc+3 address:

+
gef➤    nop $pc+3
+
+

nop two instructions at address $pc+3:

+
gef➤    nop --i 2 $pc+3
+
+

Replace 1 byte with nop at current instruction ($pc):

+
gef➤    nop --b
+
+

Replace 1 byte with nop at address $pc+3:

+
gef➤    nop --b $pc+3
+
+

Replace 2 bytes with nop(s) (breaking the last instruction) at address $pc+3:

+
gef➤    nop --f --b --i 2 $pc+3
+
+

Patch 2 nops at address $pc+3:

+
gef➤    nop --n --i 2 $pc+3
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/patch/index.html b/commands/patch/index.html new file mode 100644 index 000000000..400c02877 --- /dev/null +++ b/commands/patch/index.html @@ -0,0 +1,1770 @@ + + + + + + + + + + + + + + + + + + + + + + patch - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

patch

+ +

Command patch

+

patch lets you easily patch the specified values to the specified address.

+
gef➤ patch byte $eip 0x90
+gef➤ patch string $eip "cool!"
+
+

These commands copy the first 10 bytes of $rsp+8 to $rip:

+
gef➤  print-format --lang bytearray -l 10 $rsp+8
+Saved data b'\xcb\xe3\xff\xff\xff\x7f\x00\x00\x00\x00'... in '$_gef0'
+gef➤  patch byte $rip $_gef0
+
+

Very handy to copy-paste-execute shellcodes/data from different memory regions.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/pattern/index.html b/commands/pattern/index.html new file mode 100644 index 000000000..a5fb63295 --- /dev/null +++ b/commands/pattern/index.html @@ -0,0 +1,1842 @@ + + + + + + + + + + + + + + + + + + + + + + pattern - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

pattern

+ +

Command pattern

+

This command will create or search a De Bruijn +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.

+

pattern create

+
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.

+
gef➤  pattern create -n 4 128
+[+] Generating a pattern of 128 bytes (n=4)
+aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaab
+[+] Saved as '$_gef0'
+
+

The equivalent command with pwntools is

+
from pwn import *
+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.

+

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
+[+] Searching '0x6161616161616167'
+[+] Found at offset 48 (little-endian search) likely
+[+] Found at offset 41 (big-endian search)
+gef➤  pattern search $rbp
+[+] Searching '$rbp'
+[+] Found at offset 32 (little-endian search) likely
+[+] Found at offset 25 (big-endian search)
+gef➤  pattern search aaaaaaac
+[+] Searching for 'aaaaaaac'
+[+] Found at offset 16 (little-endian search) likely
+[+] Found at offset 9 (big-endian search)
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/pcustom/index.html b/commands/pcustom/index.html new file mode 100644 index 000000000..ed5635531 --- /dev/null +++ b/commands/pcustom/index.html @@ -0,0 +1,2007 @@ + + + + + + + + + + + + + + + + + + + + + + pcustom - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+ +
+
+ + + +
+
+ + + + +

pcustom

+ +

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

+

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 <struct_name>.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'
+ →  /tmp/structs/A.py (A, B)
+ →  /tmp/structs/elf32_t.py (elf32_t)
+ →  /tmp/structs/elf64_t.py (elf64_t)
+[...]
+
+

To create or edit a structure, use pcustom edit <struct_name> 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:

+
gef➤  pcustom edit elf32_t
+[+] Editing '/home/hugsy/code/gef-extras/structs/elf32_t.py'
+
+

Static ctypes.Structure-like classes

+

The code can be defined just as any Python (using ctypes) code.

+
from ctypes import *
+
+'''
+typedef struct {
+  int age;
+  char name[256];
+  int id;
+} person_t;
+'''
+
+class person_t(Structure):
+    _fields_ = [
+        ("age",  c_int),
+        ("name", c_char * 256),
+        ("id", c_int),
+    ]
+
+    _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")
+        ])
+    ]
+
+

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
++0000   age          c_int   /* size=0x4 */
++0004   name         c_char_Array_256   /* size=0x100 */
++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:

+

gef-pcustom-with-address

+

This means that we can now create very easily new user-defined structures

+

For a full demo, watch the following tutorial:

+

yt-gef-pcustom

+

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

+

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

+
import ctypes
+from typing import Optional
+
+def person_t(gef: Optional["Gef"]=None):
+    fields = [
+        ("age",  ctypes.c_int),
+        ("name", ctypes.c_char * 256),
+        ("id", ctypes.c_int),
+    ]
+
+    class person_cls(ctypes.Structure):
+      _fields_ = fields
+
+    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:

+
import ctypes
+from typing import Optional
+
+def person_t(gef: Optional["Gef"]==None):
+    fields = [
+        ("age",  ctypes.c_uint8),
+        ("name", ctypes.c_char * 256),
+        ("id", ctypes.c_uint8),
+    ]
+
+    # constraint on the libc version
+    if gef.libc.version > (2, 27):
+      # or on the pointer size
+      pointer_type = ctypes.c_uint64 if gef.arch.ptrsize == 8 else ctypes.c_uint32
+      fields += [
+        ("new_field", pointer_size)
+      ]
+
+    class person_cls(ctypes.Structure):
+      _fields_ = fields
+
+    return person_cls
+
+

Public repository of structures

+

A community contributed repository of structures can be found in +gef-extras. To deploy it:

+

In bash:

+
$ git clone https://github.com/hugsy/gef-extras
+
+

In GEF:

+
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:

+
gef➤ pcustom list
+
+

Should return several entries.

+

And remember this is collaborative repository, so feel free to contribute too!

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/pie/index.html b/commands/pie/index.html new file mode 100644 index 000000000..cda7e4e81 --- /dev/null +++ b/commands/pie/index.html @@ -0,0 +1,1901 @@ + + + + + + + + + + + + + + + + + + + + + + pie - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

pie

+ +

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.

+

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.

+

Usage:

+
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.

+

This works just like info breakpoint in gdb.

+
gef➤  pie info
+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.

+

You can omit the VNum argument to get info on all PIE breakpoints.

+

Usage:

+
gef➤  pie info [VNum]
+
+
+

pie delete command

+

This command deletes a PIE breakpoint given its VNum.

+

Usage:

+
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.

+

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.

+

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.

+

The usage is just the same as run.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/print-format/index.html b/commands/print-format/index.html new file mode 100644 index 000000000..753db1c3f --- /dev/null +++ b/commands/print-format/index.html @@ -0,0 +1,1791 @@ + + + + + + + + + + + + + + + + + + + + + + print-format - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

print-format

+ +

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)
  • +
+
gef➤  print-format -h
+[+] print-format [--lang LANG] [--bitlen SIZE] [(--length,-l) LENGTH] [--clip] LOCATION
+    --lang LANG specifies the output format for programming language (available: ['py', 'c', 'js', 'asm', 'hex'], default 'py').
+    --bitlen SIZE specifies size of bit (possible values: [8, 16, 32, 64], default is 8).
+    --length LENGTH specifies length of array (default is 256).
+    --clip The output data will be copied to clipboard
+    LOCATION specifies where the address of bytes is stored.
+
+

For example this command will dump 10 bytes from $rsp and copy the result to the clipboard.

+
gef➤  print-format --lang py --bitlen 8 -l 10 --clip $rsp
+[+] Copied to clipboard
+buf = [0x87, 0xfa, 0xa3, 0xf7, 0xff, 0x7f, 0x0, 0x0, 0x30, 0xe6]
+
+

These commands copy the first 10 bytes of $rsp+8 to $rip:

+
gef➤  print-format --lang bytearray -l 10 $rsp+8
+Saved data b'\xcb\xe3\xff\xff\xff\x7f\x00\x00\x00\x00'... in '$_gef0'
+gef➤  display/x $_gef0[5]
+4: /x $_gef0[5] = 0x7f
+gef➤  patch byte $rip $_gef0
+
+

Very handy to copy-paste-execute shellcodes/data from different memory regions.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/process-search/index.html b/commands/process-search/index.html new file mode 100644 index 000000000..4f6428b4c --- /dev/null +++ b/commands/process-search/index.html @@ -0,0 +1,1797 @@ + + + + + + + + + + + + + + + + + + + + + + process-search - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

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

+

Without argument, it will return all processes reachable by user:

+
gef➤  ps
+1               root            0.0             0.4             ?           /sbin/init
+2               root            0.0             0.0             ?           [kthreadd]
+3               root            0.0             0.0             ?           [ksoftirqd/0]
+4               root            0.0             0.0             ?           [kworker/0:0]
+5               root            0.0             0.0             ?           [kworker/0:0H]
+6               root            0.0             0.0             ?           [kworker/u2:0]
+7               root            0.0             0.0             ?           [rcu_sched]
+8               root            0.0             0.0             ?           [rcuos/0]
+9               root            0.0             0.0             ?           [rcu_bh]
+10              root            0.0             0.0             ?           [rcuob/0]
+11              root            0.0             0.0             ?           [migration/0]
+[...]
+
+

Or to filter with pattern:

+
gef➤  ps bash
+22590           vagrant         0.0             0.8             pts/0       -bash
+
+

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.)
  • +
  • --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

+
$ 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

+
gef➤  ps --attach --smart-scan plop
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/process-status/index.html b/commands/process-status/index.html new file mode 100644 index 000000000..5cc068a69 --- /dev/null +++ b/commands/process-status/index.html @@ -0,0 +1,1788 @@ + + + + + + + + + + + + + + + + + + + + + + process-status - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

process-status

+ +

Command process-status

+
+

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.

+
gef➤ ps --smart-scan zsh
+22879
+gef➤ attach 22879
+[...]
+gef➤ status
+[+] Process Information
+        PID  →  22879
+        Executable  →  /bin/zsh
+        Command line  →  '-zsh'
+[+] Parent Process Information
+        Parent PID  →  4475
+        Command line  →  'tmux new -s cool vibe
+[+] Children Process Information
+        PID  →  26190 (Name: '/bin/sleep', CmdLine: 'sleep 100000')
+[+] File Descriptors:
+        /proc/22879/fd/0  →  /dev/pts/4
+        /proc/22879/fd/1  →  /dev/pts/4
+        /proc/22879/fd/2  →  /dev/pts/4
+        /proc/22879/fd/10  →  /dev/pts/4
+[+] File Descriptors:
+        No TCP connections
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/registers/index.html b/commands/registers/index.html new file mode 100644 index 000000000..366cf7da6 --- /dev/null +++ b/commands/registers/index.html @@ -0,0 +1,1838 @@ + + + + + + + + + + + + + + + + + + + + + + registers - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

registers

+ +

Command registers

+

The registers command will print all the registers and dereference any pointers.

+

Example on a MIPS host:

+
gef➤ reg
+$zero     : 0x00000000
+$at       : 0x00000001
+$v0       : 0x7fff6cd8 -> 0x77e5e7f8 -> <__libc_start_main+200>: bnez v0,0x77e5e8a8
+$v1       : 0x77ff4490
+$a0       : 0x00000001
+$a1       : 0x7fff6d94 -> 0x7fff6e85 -> "/root/demo-mips"
+$a2       : 0x7fff6d9c -> 0x7fff6e91 -> "SHELL=/bin/bash"
+$a3       : 0x00000000
+$t0       : 0x77fc26a0 -> 0x0
+$t1       : 0x77fc26a0 -> 0x0
+$t2       : 0x77fe5000 -> "_dl_fini"
+$t3       : 0x77fe5000 -> "_dl_fini"
+$t4       : 0xf0000000
+$t5       : 0x00000070
+$t6       : 0x00000020
+$t7       : 0x7fff6bc8 -> 0x0
+$s0       : 0x00000000
+$s1       : 0x00000000
+$s2       : 0x00000000
+$s3       : 0x00500000
+$s4       : 0x00522f48
+$s5       : 0x00522608
+$s6       : 0x00000000
+$s7       : 0x00000000
+$t8       : 0x0000000b
+$t9       : 0x004008b0 -> <main>: addiu sp,sp,-32
+$k0       : 0x00000000
+$k1       : 0x00000000
+$s8       : 0x00000000
+$status   : 0x0000a413
+$badvaddr : 0x77e7a874 -> <__cxa_atexit>: lui gp,0x15
+$cause    : 0x10800024
+$pc       : 0x004008c4 -> <main+20>: li v0,2
+$sp       : 0x7fff6ca0 -> 0x77e4a834 -> 0x29bd
+$hi       : 0x000001a5
+$lo       : 0x00005e17
+$fir      : 0x00739300
+$fcsr     : 0x00000000
+$ra       : 0x77e5e834 -> <__libc_start_main+260>: lw gp,16(sp)
+$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:

+
gef➤ reg $rax $rip $rsp
+$rax   : 0x0000555555555169  →  <main+0> endbr64
+$rsp   : 0x00007fffffffe3e8  →  0x00007ffff7df40b3  →  <__libc_start_main+243> mov edi, eax
+$rip   : 0x0000555555555169  →  <main+0> endbr64
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/reset-cache/index.html b/commands/reset-cache/index.html new file mode 100644 index 000000000..634de0105 --- /dev/null +++ b/commands/reset-cache/index.html @@ -0,0 +1,1761 @@ + + + + + + + + + + + + + + + + + + + + + + reset-cache - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

reset-cache

+ +

Command reset-cache

+

This command is only useful for debugging GEF itself.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/scan/index.html b/commands/scan/index.html new file mode 100644 index 000000000..de3c604b4 --- /dev/null +++ b/commands/scan/index.html @@ -0,0 +1,1807 @@ + + + + + + + + + + + + + + + + + + + + + + scan - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

scan

+ +

Command scan

+

scan searches for addresses of one memory region (needle) inside another region (haystack) and +lists all results.

+

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) to determine the memory ranges to search.

+
gef➤  scan stack libc
+[+] Searching for addresses in 'stack' that point to 'libc'
+[stack]: 0x00007fffffffd6a8│+0x1f6a8: 0x00007ffff77cf482  →  "__tunable_get_val"
+[stack]: 0x00007fffffffd6b0│+0x1f6b0: 0x00007ffff77bff78  →  0x0000001200001ab2
+[stack]: 0x00007fffffffd758│+0x1f758: 0x00007ffff77cd9d0  →  0x6c5f755f72647800
+[stack]: 0x00007fffffffd778│+0x1f778: 0x00007ffff77bda6c  →  0x0000090900000907
+[stack]: 0x00007fffffffd7d8│+0x1f7d8: 0x00007ffff77cd9d0  →  0x6c5f755f72647800
+[...]
+
+

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.

+

scan-address

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/search-pattern/index.html b/commands/search-pattern/index.html new file mode 100644 index 000000000..fd6796c3e --- /dev/null +++ b/commands/search-pattern/index.html @@ -0,0 +1,1827 @@ + + + + + + + + + + + + + + + + + + + + + + search-pattern - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

search-pattern

+ +

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➤  search-pattern MyPattern
+
+

grep

+

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:

+
gef➤  search-pattern 0x4005f6
+
+

grep-address

+

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.

+
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.

+

Example: how to find null-end-printable(from x20-x7e) C strings (min size >=2 bytes) with a regex:

+
gef➤  search-pattern --regex 0x401000 0x401500 ([\\x20-\\x7E]{2,})(?=\\x00)
+
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/shellcode/index.html b/commands/shellcode/index.html new file mode 100644 index 000000000..b74b482c2 --- /dev/null +++ b/commands/shellcode/index.html @@ -0,0 +1,1787 @@ + + + + + + + + + + + + + + + + + + + + + + shellcode - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

shellcode

+ +

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

+
gef➤ shellcode search arm
+[+] Showing matching shellcodes
+901     Linux/ARM       Add map in /etc/hosts file - 79 bytes
+853     Linux/ARM       chmod("/etc/passwd", 0777) - 39 bytes
+854     Linux/ARM       creat("/root/pwned", 0777) - 39 bytes
+855     Linux/ARM       execve("/bin/sh", [], [0 vars]) - 35 bytes
+729     Linux/ARM       Bind Connect UDP Port 68
+730     Linux/ARM       Bindshell port 0x1337
+[...]
+gef➤ shellcode get 698
+[+] Downloading shellcode id=698
+[+] Shellcode written as '/tmp/sc-EfcWtM.txt'
+gef➤ system cat /tmp/sc-EfcWtM.txt
+/*
+Title:     Linux/ARM - execve("/bin/sh", [0], [0 vars]) - 27 bytes
+Date:      2010-09-05
+Tested on: ARM926EJ-S rev 5 (v5l)
+Author:    Jonathan Salwan - twitter: @jonathansalwan
+
+shell-storm.org
+
+Shellcode ARM without 0x20, 0x0a and 0x00
+[...]
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/skipi/index.html b/commands/skipi/index.html new file mode 100644 index 000000000..be77da2e4 --- /dev/null +++ b/commands/skipi/index.html @@ -0,0 +1,1725 @@ + + + + + + + + + + + + + + + + + + Skipi - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Skipi

+ +

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.

+
gef➤    skipi
+gef➤    skipi --n 3
+gef➤    skipi 0x69696969
+gef➤    skipi 0x69696969 --n 6
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/stub/index.html b/commands/stub/index.html new file mode 100644 index 000000000..296115411 --- /dev/null +++ b/commands/stub/index.html @@ -0,0 +1,1807 @@ + + + + + + + + + + + + + + + + + + + + + + stub - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

stub

+ +

Command stub

+

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.

+

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.

+

Example

+

Patching fork() calls:

+
    +
  • Without stub:
  • +
+

fork execution

+
    +
  • With stub:
  • +
+

stubbed fork

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/theme/index.html b/commands/theme/index.html new file mode 100644 index 000000000..924d959ea --- /dev/null +++ b/commands/theme/index.html @@ -0,0 +1,1825 @@ + + + + + + + + + + + + + + + + + + + + + + theme - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

theme

+ +

Command theme

+

Customize GEF by changing its color scheme.

+
gef➤  theme
+context_title_message                   : red bold
+default_title_message                   : red bold
+default_title_line                      : green bold
+context_title_line                      : green bold
+disable_color                           : 0
+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.

+

Colors can be one of the following:

+
    +
  • red
  • +
  • green
  • +
  • blue
  • +
  • yellow
  • +
  • gray
  • +
  • pink
  • +
+

Color also accepts the following attributes:

+
    +
  • bold
  • +
  • underline
  • +
  • highlight
  • +
  • blink
  • +
+

Any other will value simply be ignored.

+
gef➤  theme context_title_message blue bold foobar
+gef➤  theme
+context_title_message                   : blue bold
+default_title_message                   : red bold
+default_title_line                      : green bold
+context_title_line                      : green bold
+disable_color                           : 0
+xinfo_title_message                     : blue bold
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/tmux-setup/index.html b/commands/tmux-setup/index.html new file mode 100644 index 000000000..ab42806fd --- /dev/null +++ b/commands/tmux-setup/index.html @@ -0,0 +1,1808 @@ + + + + + + + + + + + + + + + + + + + + + + tmux-setup - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

tmux-setup

+ +

Command tmux-setup

+

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:

+

+

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.

+

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.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/trace-run/index.html b/commands/trace-run/index.html new file mode 100644 index 000000000..9a8366cc1 --- /dev/null +++ b/commands/trace-run/index.html @@ -0,0 +1,1771 @@ + + + + + + + + + + + + + + + + + + + + + + trace-run - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

trace-run

+ +

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 +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.

+
gef> trace-run <address_of_last_instruction_to_trace>
+
+

trace-run-1

+

By using the script ida_color_gdb_trace.py on the text file generated, it will color the path +taken:

+

trace-run-2

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/version/index.html b/commands/version/index.html new file mode 100644 index 000000000..18bebd0b2 --- /dev/null +++ b/commands/version/index.html @@ -0,0 +1,1808 @@ + + + + + + + + + + + + + + + + + + + + + + version - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

version

+ +

Command version

+

Print out version information about your current gdb environment.

+

Usage Examples

+

When GEF is located in a directory tracked with git:

+
gef➤  version
+GEF: rev:48a9fd74dd39db524fb395e7db528f85cc49d081 (Git - clean)
+SHA1(/gef/rules/gef.py): 848cdc87ba7c3e99e8129ad820c9fcc0973b1e99
+GDB: 9.2
+GDB-Python: 3.8
+
+

Otherwise the command shows the standalone information:

+
gef➤  version
+GEF: (Standalone)
+Blob Hash(/gef/rules/gef.py): f0aef0f481e8157006b26690bd121585d3befee0
+SHA1(/gef/rules/gef.py): 4b26a1175abcd8314d4816f97fdf908b3837c779
+GDB: 9.2
+GDB-Python: 3.8
+
+

The Blob Hash can be used to easily find the git commit(s) matching this file revision.

+
git log --oneline --find-object <BLOB_HASH>
+
+

If this command does not return anything then the file was most likely modified and cannot be +matched to a specific git commit.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/vmmap/index.html b/commands/vmmap/index.html new file mode 100644 index 000000000..ce09a77fc --- /dev/null +++ b/commands/vmmap/index.html @@ -0,0 +1,1770 @@ + + + + + + + + + + + + + + + + + + + + + + vmmap - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

vmmap

+ +

Command vmmap

+

vmmap displays the target process's entire memory space mapping.

+

vmmap

+

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

+

vmmap-address

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/xfiles/index.html b/commands/xfiles/index.html new file mode 100644 index 000000000..5ab59617b --- /dev/null +++ b/commands/xfiles/index.html @@ -0,0 +1,1764 @@ + + + + + + + + + + + + + + + + + + + + + + xfiles - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

xfiles

+ +

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

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/xinfo/index.html b/commands/xinfo/index.html new file mode 100644 index 000000000..dbf436bc7 --- /dev/null +++ b/commands/xinfo/index.html @@ -0,0 +1,1767 @@ + + + + + + + + + + + + + + + + + + + + + + xinfo - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

xinfo

+ +

Command xinfo

+

xinfo displays all the information known to gef about the specific address given as argument:

+

xinfo-example

+

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.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/commands/xor-memory/index.html b/commands/xor-memory/index.html new file mode 100644 index 000000000..80fe19e0d --- /dev/null +++ b/commands/xor-memory/index.html @@ -0,0 +1,1786 @@ + + + + + + + + + + + + + + + + + + + + + + xor-memory - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

xor-memory

+ +

Command xor-memory

+

This command is used to XOR a block of memory.

+

Its syntax is:

+
xor-memory <display|patch> <address> <size_to_read> <xor_key>
+
+

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.

    +
    gef➤  xor display $rsp 16 1337
    +[+] Displaying XOR-ing 0x7fff589b67f8-0x7fff589b6808 with '1337'
    +────────────────────────────────[ Original block ]────────────────────────────────────
    +0x00007fff589b67f8     46 4e 40 00 00 00 00 00 00 00 00 00 00 00 00 00     FN@.............
    +────────────────────────────────[ XOR-ed block ]──────────────────────────────────────
    +0x00007fff589b67f8     55 79 53 37 13 37 13 37 13 37 13 37 13 37 13 37     UyS7.7.7.7.7.7.7
    +
    +
  2. +
  3. +

    patch will overwrite the memory with the xor-ed content.

    +
    gef➤  xor patch $rsp 16 1337
    +[+] Patching XOR-ing 0x7fff589b67f8-0x7fff589b6808 with '1337'
    +gef➤  hexdump byte $rsp 16
    +0x00007fff589b67f8     55 79 53 37 13 37 13 37 13 37     UyS7.7.7.7
    +
    +
  4. +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/compat/index.html b/compat/index.html new file mode 100644 index 000000000..35635fa8d --- /dev/null +++ b/compat/index.html @@ -0,0 +1,1753 @@ + + + + + + + + + + + + + + + + + + + + + + Compatibility - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

GEF Compatibility

+

This matrix indicates the version of Python and/or GDB

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
GEF versionGDB Python compatibility*Python compatibility*
2018.027.2Python 2.7, Python 3.4+
2020.037.4Python 2.7, Python 3.4+
2022.017.7Python 3.4+
Current8.0+Python 3.6+
+
    +
  • Up to - included
  • +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/config/index.html b/config/index.html new file mode 100644 index 000000000..d9c7782b0 --- /dev/null +++ b/config/index.html @@ -0,0 +1,1783 @@ + + + + + + + + + + + + + + + + + + + + + + Configuration - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Configuration

+ +

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.

+

The configuration file is a Python +configparser. To +create a basic file with all settings and their default values, simply run

+
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. Without argument the command +will simply dump all known settings:

+

gef-config

+

To update, follow the syntax

+
gef➤  gef config <Module>.<ModuleSetting>  <Value>
+
+

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 for +complete explanation.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/coverage/coverage.json b/coverage/coverage.json new file mode 100644 index 000000000..034a4d3c9 --- /dev/null +++ b/coverage/coverage.json @@ -0,0 +1 @@ +{"meta": {"version": "7.2.7", "timestamp": "2023-08-01T03:12:41.071746", "branch_coverage": true, "show_contexts": false}, "files": {"gef.py": {"executed_lines": [52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 89, 91, 92, 94, 97, 98, 99, 100, 101, 104, 120, 121, 130, 131, 132, 133, 135, 136, 138, 141, 142, 144, 145, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 159, 161, 162, 163, 164, 165, 168, 172, 173, 174, 175, 177, 178, 181, 184, 185, 190, 191, 193, 195, 198, 211, 212, 214, 219, 221, 222, 223, 224, 225, 226, 227, 228, 230, 233, 235, 236, 240, 241, 244, 247, 248, 251, 252, 254, 255, 256, 258, 259, 273, 274, 276, 282, 283, 284, 285, 287, 294, 300, 302, 303, 306, 308, 309, 312, 314, 315, 318, 320, 321, 324, 326, 327, 330, 332, 333, 336, 338, 339, 342, 344, 345, 350, 352, 353, 358, 360, 361, 362, 370, 373, 374, 375, 376, 378, 380, 383, 386, 387, 388, 389, 393, 396, 398, 399, 400, 401, 402, 403, 404, 405, 407, 408, 409, 410, 411, 413, 414, 415, 416, 417, 420, 423, 424, 425, 426, 428, 431, 433, 434, 435, 436, 438, 439, 442, 443, 444, 445, 448, 452, 455, 459, 461, 462, 463, 464, 465, 466, 467, 468, 470, 471, 472, 479, 480, 481, 483, 485, 487, 488, 491, 492, 493, 494, 495, 496, 497, 498, 500, 502, 503, 504, 505, 506, 509, 510, 511, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 555, 556, 558, 560, 561, 562, 563, 564, 565, 566, 567, 570, 571, 572, 573, 574, 575, 576, 578, 579, 580, 581, 582, 583, 584, 585, 587, 588, 589, 591, 594, 595, 598, 599, 601, 602, 604, 605, 606, 607, 609, 610, 611, 614, 615, 616, 617, 618, 619, 620, 622, 623, 624, 625, 626, 627, 629, 630, 631, 632, 633, 634, 635, 636, 638, 639, 640, 641, 642, 643, 644, 646, 647, 648, 651, 652, 653, 656, 657, 659, 660, 661, 662, 663, 664, 665, 666, 668, 671, 672, 674, 675, 677, 678, 683, 684, 688, 693, 696, 697, 698, 700, 701, 703, 706, 710, 711, 714, 715, 716, 717, 718, 719, 721, 724, 726, 727, 728, 729, 731, 732, 734, 735, 738, 742, 743, 749, 750, 751, 753, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 769, 770, 771, 772, 773, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 807, 808, 809, 810, 812, 814, 817, 818, 819, 820, 824, 827, 829, 831, 832, 836, 838, 841, 844, 845, 848, 851, 852, 855, 856, 860, 861, 863, 864, 865, 867, 868, 869, 870, 872, 873, 875, 876, 877, 878, 880, 881, 883, 884, 886, 889, 890, 893, 894, 895, 897, 898, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 918, 919, 920, 921, 922, 923, 926, 927, 928, 929, 930, 932, 933, 934, 936, 937, 938, 940, 941, 942, 944, 945, 946, 948, 949, 950, 952, 953, 954, 956, 957, 958, 960, 961, 962, 964, 965, 966, 968, 969, 970, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 998, 999, 1002, 1003, 1004, 1005, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1016, 1017, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1031, 1032, 1034, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1083, 1084, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1105, 1106, 1107, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1121, 1122, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1137, 1138, 1139, 1141, 1142, 1143, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1156, 1162, 1163, 1165, 1166, 1168, 1172, 1173, 1176, 1179, 1181, 1182, 1183, 1184, 1187, 1188, 1190, 1191, 1193, 1194, 1196, 1201, 1202, 1203, 1205, 1206, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1220, 1221, 1224, 1225, 1226, 1229, 1230, 1233, 1234, 1236, 1237, 1238, 1239, 1241, 1242, 1243, 1244, 1245, 1247, 1248, 1249, 1252, 1255, 1258, 1259, 1260, 1262, 1263, 1266, 1267, 1270, 1271, 1273, 1278, 1279, 1280, 1281, 1287, 1288, 1289, 1292, 1293, 1295, 1296, 1297, 1298, 1299, 1300, 1302, 1303, 1304, 1305, 1309, 1311, 1315, 1324, 1326, 1329, 1333, 1334, 1335, 1337, 1338, 1339, 1344, 1345, 1347, 1348, 1349, 1350, 1351, 1353, 1356, 1357, 1359, 1360, 1362, 1363, 1365, 1366, 1367, 1369, 1370, 1371, 1373, 1374, 1376, 1377, 1379, 1381, 1384, 1385, 1386, 1388, 1389, 1390, 1392, 1393, 1394, 1396, 1397, 1398, 1400, 1401, 1402, 1404, 1405, 1406, 1408, 1409, 1410, 1412, 1413, 1416, 1417, 1418, 1420, 1421, 1424, 1425, 1428, 1429, 1432, 1433, 1436, 1438, 1439, 1440, 1441, 1443, 1444, 1445, 1446, 1447, 1449, 1454, 1455, 1457, 1458, 1459, 1460, 1462, 1463, 1464, 1466, 1468, 1469, 1471, 1472, 1473, 1477, 1479, 1480, 1483, 1486, 1487, 1488, 1490, 1491, 1505, 1506, 1510, 1511, 1512, 1513, 1515, 1516, 1522, 1523, 1524, 1525, 1526, 1528, 1536, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1549, 1550, 1551, 1553, 1554, 1556, 1557, 1560, 1561, 1562, 1564, 1565, 1566, 1568, 1569, 1570, 1572, 1573, 1576, 1577, 1580, 1581, 1584, 1586, 1587, 1588, 1589, 1590, 1592, 1593, 1594, 1596, 1597, 1599, 1600, 1601, 1603, 1604, 1606, 1609, 1612, 1614, 1617, 1618, 1621, 1624, 1625, 1626, 1628, 1629, 1631, 1632, 1634, 1635, 1637, 1640, 1644, 1647, 1648, 1650, 1651, 1652, 1654, 1655, 1656, 1657, 1661, 1662, 1663, 1667, 1668, 1670, 1672, 1689, 1690, 1693, 1694, 1698, 1700, 1703, 1705, 1706, 1707, 1708, 1710, 1712, 1719, 1721, 1722, 1724, 1726, 1728, 1730, 1731, 1734, 1736, 1737, 1738, 1739, 1741, 1744, 1747, 1748, 1749, 1750, 1753, 1754, 1755, 1758, 1759, 1760, 1763, 1764, 1765, 1768, 1769, 1770, 1773, 1775, 1778, 1779, 1782, 1785, 1791, 1792, 1794, 1795, 1796, 1798, 1799, 1801, 1804, 1805, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1816, 1817, 1818, 1822, 1823, 1824, 1827, 1829, 1830, 1831, 1832, 1835, 1837, 1840, 1841, 1843, 1844, 1845, 1846, 1847, 1849, 1852, 1853, 1860, 1861, 1862, 1864, 1865, 1866, 1867, 1869, 1870, 1871, 1872, 1875, 1883, 1884, 1886, 1887, 1888, 1890, 1891, 1892, 1894, 1895, 1896, 1897, 1901, 1902, 1905, 1907, 1910, 1912, 1915, 1917, 1918, 1921, 1923, 1924, 1927, 1928, 1929, 1930, 1932, 1933, 1934, 1937, 1938, 1939, 1940, 1942, 1944, 1945, 1946, 1947, 1948, 1950, 1952, 1953, 1954, 1957, 1966, 1973, 1975, 1976, 1977, 1978, 1981, 1982, 1990, 1991, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2017, 2018, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2030, 2032, 2033, 2035, 2037, 2040, 2043, 2047, 2051, 2052, 2053, 2054, 2056, 2059, 2064, 2067, 2071, 2072, 2074, 2077, 2078, 2083, 2086, 2089, 2091, 2092, 2095, 2097, 2100, 2102, 2105, 2108, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2121, 2122, 2125, 2127, 2128, 2131, 2146, 2147, 2151, 2152, 2154, 2155, 2156, 2158, 2159, 2160, 2164, 2165, 2168, 2169, 2171, 2172, 2179, 2180, 2185, 2189, 2190, 2194, 2195, 2199, 2201, 2202, 2203, 2204, 2207, 2208, 2209, 2210, 2213, 2214, 2215, 2216, 2222, 2223, 2226, 2227, 2228, 2230, 2232, 2233, 2234, 2235, 2236, 2239, 2240, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2256, 2257, 2258, 2260, 2261, 2262, 2265, 2268, 2271, 2272, 2276, 2278, 2281, 2284, 2287, 2290, 2293, 2296, 2297, 2299, 2300, 2303, 2304, 2305, 2307, 2309, 2310, 2311, 2313, 2314, 2316, 2317, 2318, 2319, 2322, 2323, 2324, 2326, 2327, 2328, 2329, 2331, 2332, 2335, 2336, 2337, 2339, 2340, 2341, 2343, 2344, 2347, 2348, 2349, 2355, 2357, 2358, 2359, 2360, 2361, 2362, 2367, 2369, 2371, 2372, 2373, 2374, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2392, 2393, 2394, 2395, 2396, 2401, 2402, 2403, 2404, 2405, 2407, 2408, 2410, 2411, 2414, 2417, 2428, 2429, 2432, 2433, 2441, 2444, 2500, 2509, 2510, 2511, 2512, 2516, 2517, 2518, 2519, 2528, 2529, 2530, 2531, 2533, 2537, 2538, 2544, 2545, 2550, 2551, 2554, 2555, 2559, 2560, 2563, 2568, 2580, 2587, 2591, 2624, 2639, 2640, 2657, 2658, 2659, 2660, 2662, 2668, 2669, 2670, 2681, 2682, 2683, 2684, 2686, 2691, 2698, 2702, 2706, 2707, 2717, 2718, 2741, 2748, 2779, 2780, 2781, 2782, 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, 2792, 2806, 2807, 2808, 2809, 2811, 2812, 2813, 2814, 2815, 2817, 2818, 2819, 2820, 2822, 2823, 2825, 2826, 2827, 2833, 2835, 2880, 2881, 2882, 2883, 2884, 2885, 2887, 2889, 2890, 2905, 2916, 2917, 2918, 2919, 2921, 2924, 2925, 2926, 2927, 2928, 2930, 2931, 2933, 2934, 2959, 2960, 2962, 2963, 2964, 2965, 2967, 2973, 2974, 2975, 2976, 2977, 2988, 2989, 2990, 2991, 2994, 3001, 3004, 3007, 3012, 3025, 3033, 3034, 3059, 3060, 3061, 3062, 3063, 3066, 3067, 3070, 3071, 3072, 3074, 3080, 3081, 3082, 3083, 3084, 3092, 3093, 3094, 3096, 3103, 3106, 3109, 3118, 3142, 3150, 3151, 3170, 3171, 3175, 3176, 3177, 3179, 3186, 3187, 3194, 3196, 3197, 3216, 3217, 3218, 3219, 3222, 3228, 3229, 3230, 3231, 3232, 3233, 3234, 3235, 3236, 3238, 3241, 3244, 3247, 3252, 3274, 3282, 3283, 3299, 3300, 3301, 3302, 3303, 3305, 3306, 3307, 3310, 3328, 3329, 3330, 3334, 3335, 3336, 3340, 3346, 3352, 3354, 3355, 3358, 3365, 3366, 3370, 3371, 3372, 3373, 3374, 3375, 3378, 3379, 3386, 3387, 3388, 3389, 3390, 3391, 3394, 3396, 3397, 3398, 3399, 3403, 3411, 3412, 3414, 3415, 3416, 3417, 3418, 3421, 3422, 3424, 3425, 3426, 3427, 3429, 3430, 3432, 3434, 3435, 3438, 3441, 3445, 3446, 3449, 3450, 3451, 3453, 3456, 3457, 3460, 3464, 3465, 3466, 3471, 3472, 3475, 3476, 3477, 3481, 3482, 3485, 3486, 3487, 3488, 3491, 3492, 3495, 3496, 3497, 3499, 3500, 3503, 3505, 3506, 3509, 3511, 3512, 3513, 3516, 3518, 3521, 3523, 3524, 3525, 3528, 3530, 3531, 3532, 3533, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3545, 3546, 3550, 3554, 3557, 3561, 3564, 3565, 3566, 3567, 3568, 3569, 3572, 3573, 3574, 3588, 3590, 3591, 3594, 3596, 3597, 3600, 3602, 3603, 3628, 3629, 3631, 3634, 3635, 3637, 3640, 3641, 3643, 3646, 3647, 3649, 3652, 3653, 3654, 3657, 3658, 3662, 3670, 3673, 3680, 3682, 3683, 3688, 3689, 3690, 3693, 3696, 3697, 3698, 3699, 3700, 3701, 3704, 3705, 3724, 3727, 3728, 3729, 3742, 3744, 3745, 3747, 3750, 3753, 3755, 3756, 3758, 3761, 3764, 3766, 3769, 3772, 3777, 3783, 3785, 3786, 3787, 3790, 3791, 3792, 3793, 3796, 3798, 3801, 3803, 3804, 3806, 3807, 3808, 3809, 3810, 3812, 3813, 3815, 3816, 3817, 3819, 3822, 3824, 3825, 3828, 3831, 3832, 3833, 3834, 3835, 3838, 3839, 3841, 3842, 3846, 3847, 3849, 3850, 3851, 3852, 3853, 3856, 3859, 3860, 3861, 3862, 3863, 3864, 3865, 3868, 3871, 3873, 3874, 3877, 3878, 3892, 3893, 3897, 3898, 3902, 3903, 3907, 3908, 3913, 3914, 3918, 3919, 3923, 3924, 3928, 3929, 3933, 3934, 3938, 3939, 3943, 3944, 3948, 3949, 3956, 3957, 3958, 3961, 3962, 3966, 3967, 3968, 3971, 3972, 3976, 3977, 3978, 3981, 3982, 3983, 3986, 3987, 3988, 3991, 3992, 3993, 3996, 3997, 4001, 4002, 4006, 4007, 4008, 4011, 4012, 4016, 4017, 4018, 4021, 4022, 4030, 4031, 4033, 4036, 4037, 4039, 4040, 4042, 4043, 4046, 4048, 4049, 4052, 4053, 4058, 4061, 4062, 4063, 4064, 4066, 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4087, 4088, 4089, 4090, 4091, 4093, 4096, 4097, 4098, 4099, 4100, 4101, 4103, 4104, 4109, 4110, 4112, 4113, 4114, 4115, 4117, 4118, 4119, 4120, 4121, 4123, 4124, 4125, 4127, 4130, 4131, 4134, 4140, 4148, 4149, 4151, 4152, 4153, 4154, 4155, 4157, 4158, 4159, 4160, 4161, 4164, 4165, 4167, 4168, 4169, 4170, 4171, 4172, 4174, 4175, 4176, 4180, 4181, 4182, 4185, 4195, 4205, 4207, 4209, 4210, 4211, 4212, 4213, 4215, 4229, 4230, 4233, 4234, 4236, 4237, 4238, 4239, 4241, 4242, 4243, 4244, 4245, 4248, 4249, 4251, 4252, 4253, 4254, 4255, 4256, 4258, 4259, 4260, 4264, 4265, 4273, 4275, 4277, 4279, 4285, 4287, 4290, 4291, 4293, 4294, 4295, 4296, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4305, 4307, 4308, 4317, 4328, 4330, 4331, 4343, 4345, 4346, 4348, 4349, 4352, 4353, 4355, 4356, 4357, 4358, 4359, 4361, 4362, 4363, 4364, 4365, 4368, 4369, 4371, 4372, 4373, 4374, 4375, 4376, 4378, 4398, 4399, 4401, 4402, 4403, 4404, 4406, 4407, 4408, 4411, 4412, 4414, 4415, 4416, 4417, 4418, 4420, 4430, 4455, 4456, 4458, 4460, 4461, 4465, 4466, 4472, 4474, 4475, 4476, 4477, 4478, 4479, 4481, 4482, 4483, 4484, 4485, 4486, 4491, 4492, 4494, 4495, 4496, 4498, 4499, 4500, 4501, 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4519, 4520, 4521, 4523, 4524, 4525, 4526, 4527, 4528, 4531, 4532, 4535, 4537, 4538, 4539, 4541, 4544, 4545, 4547, 4548, 4550, 4551, 4552, 4554, 4555, 4556, 4557, 4559, 4560, 4562, 4564, 4565, 4568, 4569, 4570, 4572, 4573, 4576, 4577, 4579, 4580, 4583, 4585, 4586, 4587, 4588, 4589, 4590, 4592, 4594, 4595, 4596, 4598, 4599, 4602, 4606, 4607, 4608, 4609, 4610, 4612, 4613, 4614, 4615, 4616, 4619, 4620, 4621, 4623, 4624, 4625, 4627, 4628, 4629, 4630, 4631, 4633, 4634, 4635, 4636, 4641, 4642, 4643, 4644, 4646, 4647, 4648, 4651, 4652, 4653, 4655, 4656, 4658, 4659, 4660, 4666, 4668, 4669, 4670, 4671, 4673, 4674, 4676, 4683, 4684, 4685, 4687, 4688, 4690, 4691, 4695, 4696, 4697, 4699, 4700, 4701, 4702, 4703, 4705, 4706, 4707, 4708, 4709, 4711, 4713, 4714, 4715, 4716, 4717, 4718, 4719, 4722, 4723, 4724, 4727, 4728, 4732, 4738, 4739, 4742, 4743, 4744, 4746, 4747, 4749, 4750, 4751, 4753, 4754, 4755, 4756, 4759, 4760, 4761, 4763, 4764, 4766, 4767, 4768, 4769, 4773, 4774, 4777, 4782, 4784, 4785, 4786, 4787, 4788, 4791, 4792, 4793, 4795, 4796, 4798, 4799, 4800, 4801, 4803, 4805, 4809, 4810, 4813, 4814, 4817, 4818, 4819, 4821, 4822, 4824, 4825, 4827, 4828, 4833, 4836, 4839, 4840, 4842, 4844, 4847, 4848, 4851, 4852, 4853, 4855, 4856, 4858, 4860, 4861, 4865, 4869, 4873, 4874, 4875, 4876, 4877, 4878, 4879, 4880, 4883, 4884, 4886, 4887, 4891, 4894, 4895, 4896, 4898, 4899, 4901, 4918, 4919, 4920, 4922, 4923, 4925, 4942, 4943, 4944, 4946, 4947, 4948, 4951, 4952, 4953, 4954, 4955, 4957, 4958, 4959, 4961, 4962, 4963, 4964, 4965, 4967, 4968, 4969, 4970, 4971, 4972, 4973, 4974, 4977, 4979, 4980, 4981, 4982, 4983, 4984, 4988, 4989, 4990, 4991, 4996, 4998, 4999, 5000, 5001, 5002, 5005, 5008, 5009, 5010, 5012, 5013, 5015, 5016, 5017, 5019, 5020, 5024, 5025, 5029, 5030, 5031, 5034, 5035, 5036, 5039, 5040, 5041, 5043, 5044, 5045, 5047, 5048, 5049, 5050, 5051, 5052, 5053, 5054, 5055, 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, 5066, 5067, 5068, 5070, 5071, 5073, 5074, 5075, 5076, 5077, 5078, 5080, 5081, 5082, 5083, 5084, 5087, 5089, 5090, 5091, 5092, 5093, 5094, 5096, 5098, 5099, 5100, 5101, 5102, 5103, 5111, 5112, 5113, 5115, 5116, 5117, 5121, 5122, 5123, 5124, 5125, 5127, 5128, 5129, 5130, 5131, 5132, 5133, 5136, 5138, 5142, 5144, 5159, 5163, 5164, 5165, 5166, 5167, 5168, 5190, 5191, 5192, 5194, 5195, 5197, 5198, 5199, 5200, 5201, 5202, 5203, 5204, 5205, 5206, 5207, 5208, 5209, 5210, 5211, 5212, 5213, 5214, 5215, 5216, 5218, 5219, 5220, 5222, 5223, 5224, 5225, 5226, 5227, 5229, 5230, 5231, 5232, 5234, 5235, 5236, 5237, 5239, 5240, 5241, 5244, 5245, 5246, 5247, 5248, 5249, 5250, 5252, 5254, 5256, 5257, 5259, 5260, 5261, 5262, 5263, 5264, 5265, 5266, 5267, 5268, 5269, 5271, 5273, 5274, 5275, 5276, 5277, 5278, 5279, 5281, 5283, 5288, 5289, 5291, 5292, 5298, 5299, 5302, 5303, 5304, 5305, 5306, 5307, 5309, 5315, 5316, 5317, 5318, 5319, 5321, 5323, 5325, 5327, 5328, 5329, 5330, 5331, 5332, 5333, 5335, 5336, 5350, 5351, 5352, 5353, 5354, 5355, 5357, 5358, 5359, 5360, 5362, 5364, 5365, 5366, 5367, 5368, 5369, 5371, 5374, 5375, 5376, 5377, 5378, 5381, 5382, 5383, 5386, 5389, 5391, 5392, 5393, 5394, 5396, 5397, 5398, 5399, 5400, 5401, 5402, 5404, 5411, 5412, 5413, 5415, 5416, 5417, 5418, 5420, 5421, 5422, 5423, 5424, 5426, 5427, 5428, 5429, 5430, 5432, 5433, 5439, 5440, 5442, 5443, 5444, 5445, 5448, 5449, 5450, 5457, 5458, 5460, 5461, 5462, 5463, 5464, 5465, 5466, 5467, 5469, 5470, 5471, 5472, 5473, 5474, 5476, 5478, 5479, 5480, 5482, 5483, 5484, 5486, 5487, 5488, 5489, 5490, 5491, 5493, 5494, 5495, 5497, 5498, 5499, 5500, 5503, 5504, 5505, 5507, 5508, 5510, 5511, 5512, 5514, 5516, 5517, 5518, 5519, 5520, 5521, 5522, 5523, 5524, 5527, 5528, 5529, 5531, 5532, 5533, 5535, 5536, 5537, 5539, 5540, 5544, 5545, 5546, 5547, 5548, 5549, 5551, 5552, 5555, 5556, 5557, 5559, 5560, 5561, 5563, 5564, 5565, 5567, 5576, 5588, 5601, 5602, 5603, 5605, 5606, 5607, 5609, 5610, 5611, 5666, 5672, 5673, 5674, 5677, 5678, 5679, 5680, 5682, 5683, 5684, 5688, 5689, 5691, 5694, 5695, 5697, 5700, 5701, 5703, 5707, 5711, 5712, 5713, 5714, 5715, 5717, 5718, 5720, 5721, 5722, 5726, 5727, 5728, 5729, 5730, 5731, 5732, 5733, 5737, 5740, 5741, 5742, 5745, 5746, 5747, 5748, 5753, 5754, 5755, 5756, 5757, 5759, 5760, 5761, 5762, 5764, 5765, 5766, 5767, 5769, 5770, 5771, 5773, 5775, 5776, 5777, 5779, 5780, 5781, 5785, 5786, 5790, 5791, 5792, 5793, 5794, 5796, 5797, 5798, 5800, 5802, 5804, 5807, 5808, 5810, 5811, 5812, 5816, 5817, 5820, 5821, 5822, 5823, 5824, 5825, 5826, 5827, 5829, 5831, 5833, 5835, 5837, 5838, 5839, 5840, 5842, 5843, 5844, 5846, 5847, 5848, 5849, 5850, 5851, 5853, 5854, 5856, 5857, 5858, 5859, 5863, 5864, 5865, 5867, 5868, 5870, 5871, 5873, 5875, 5876, 5878, 5882, 5888, 5907, 5908, 5909, 5912, 5913, 5914, 5916, 5917, 5918, 5919, 5922, 5923, 5927, 5928, 5931, 5932, 5934, 5938, 5942, 5943, 5944, 5945, 5946, 5947, 5948, 5950, 5952, 5954, 5955, 5958, 5959, 5960, 5966, 5967, 5968, 5972, 5973, 5974, 5976, 5977, 5978, 5983, 5984, 5989, 5990, 5991, 5992, 5993, 6003, 6004, 6005, 6006, 6007, 6008, 6011, 6012, 6013, 6015, 6016, 6020, 6025, 6026, 6027, 6029, 6030, 6031, 6032, 6033, 6034, 6036, 6037, 6038, 6040, 6041, 6042, 6045, 6046, 6047, 6050, 6051, 6057, 6065, 6066, 6067, 6069, 6070, 6071, 6072, 6073, 6074, 6075, 6076, 6077, 6078, 6080, 6081, 6082, 6084, 6085, 6086, 6087, 6088, 6090, 6091, 6092, 6093, 6094, 6095, 6096, 6098, 6099, 6102, 6103, 6104, 6106, 6107, 6108, 6109, 6110, 6111, 6112, 6114, 6116, 6117, 6120, 6121, 6122, 6124, 6125, 6126, 6131, 6132, 6134, 6137, 6138, 6139, 6142, 6143, 6146, 6148, 6149, 6150, 6152, 6153, 6154, 6155, 6156, 6157, 6158, 6161, 6162, 6163, 6165, 6166, 6168, 6169, 6170, 6172, 6173, 6178, 6179, 6180, 6182, 6183, 6184, 6186, 6187, 6188, 6190, 6191, 6192, 6195, 6197, 6201, 6205, 6206, 6211, 6212, 6214, 6218, 6221, 6222, 6223, 6225, 6226, 6228, 6229, 6230, 6231, 6232, 6235, 6236, 6237, 6240, 6241, 6243, 6244, 6245, 6247, 6248, 6249, 6250, 6251, 6256, 6257, 6259, 6260, 6261, 6264, 6265, 6266, 6267, 6269, 6270, 6273, 6275, 6276, 6279, 6280, 6281, 6284, 6285, 6286, 6289, 6290, 6291, 6292, 6294, 6295, 6296, 6297, 6298, 6299, 6300, 6301, 6302, 6303, 6304, 6305, 6306, 6311, 6312, 6313, 6316, 6318, 6319, 6320, 6322, 6323, 6324, 6326, 6328, 6329, 6330, 6331, 6332, 6333, 6335, 6337, 6341, 6342, 6343, 6344, 6345, 6348, 6349, 6350, 6353, 6354, 6355, 6357, 6358, 6359, 6361, 6362, 6376, 6377, 6378, 6380, 6381, 6385, 6387, 6390, 6392, 6393, 6394, 6395, 6397, 6399, 6400, 6401, 6402, 6403, 6404, 6406, 6407, 6408, 6411, 6412, 6413, 6416, 6417, 6419, 6421, 6422, 6423, 6425, 6426, 6428, 6432, 6433, 6438, 6439, 6440, 6441, 6445, 6447, 6448, 6449, 6451, 6453, 6454, 6458, 6459, 6460, 6461, 6462, 6463, 6464, 6467, 6468, 6469, 6471, 6472, 6473, 6474, 6476, 6480, 6482, 6483, 6484, 6486, 6491, 6492, 6493, 6494, 6495, 6496, 6497, 6499, 6500, 6502, 6503, 6505, 6506, 6508, 6511, 6522, 6524, 6525, 6530, 6531, 6533, 6537, 6548, 6552, 6556, 6557, 6559, 6560, 6561, 6564, 6565, 6566, 6569, 6570, 6572, 6573, 6574, 6576, 6577, 6578, 6579, 6580, 6582, 6583, 6587, 6588, 6589, 6591, 6592, 6596, 6597, 6598, 6599, 6600, 6602, 6603, 6604, 6605, 6607, 6608, 6609, 6613, 6616, 6618, 6619, 6620, 6626, 6627, 6630, 6631, 6632, 6635, 6636, 6638, 6639, 6640, 6642, 6643, 6644, 6645, 6646, 6649, 6650, 6651, 6652, 6653, 6654, 6657, 6658, 6659, 6661, 6662, 6664, 6665, 6666, 6668, 6669, 6670, 6671, 6672, 6676, 6677, 6678, 6679, 6680, 6681, 6683, 6684, 6685, 6686, 6689, 6690, 6691, 6693, 6694, 6696, 6697, 6698, 6700, 6701, 6702, 6703, 6704, 6708, 6709, 6710, 6711, 6712, 6713, 6715, 6716, 6717, 6718, 6721, 6722, 6723, 6725, 6726, 6727, 6729, 6730, 6731, 6732, 6733, 6736, 6737, 6740, 6741, 6742, 6743, 6744, 6745, 6746, 6748, 6749, 6751, 6752, 6753, 6756, 6757, 6758, 6760, 6761, 6762, 6765, 6766, 6767, 6768, 6769, 6770, 6771, 6773, 6774, 6775, 6776, 6777, 6778, 6779, 6780, 6783, 6784, 6785, 6786, 6787, 6789, 6790, 6791, 6794, 6796, 6801, 6802, 6803, 6804, 6806, 6809, 6810, 6811, 6812, 6814, 6816, 6817, 6818, 6819, 6821, 6822, 6823, 6825, 6826, 6828, 6829, 6830, 6831, 6834, 6835, 6836, 6837, 6838, 6839, 6840, 6841, 6843, 6845, 6846, 6847, 6850, 6851, 6852, 6855, 6856, 6858, 6859, 6860, 6862, 6863, 6864, 6865, 6868, 6869, 6870, 6872, 6873, 6874, 6876, 6877, 6879, 6880, 6885, 6886, 6888, 6890, 6892, 6893, 6897, 6900, 6901, 6903, 6904, 6905, 6906, 6907, 6908, 6909, 6910, 6911, 6913, 6914, 6917, 6918, 6919, 6921, 6922, 6923, 6925, 6926, 6928, 6929, 6934, 6939, 6940, 6942, 6943, 6944, 6945, 6946, 6947, 6949, 6950, 6951, 6952, 6953, 6954, 6955, 6958, 6959, 6960, 6963, 6964, 6965, 6966, 6968, 6969, 6970, 6971, 6973, 6974, 6975, 6976, 6977, 6978, 6979, 6981, 6982, 6983, 6985, 6986, 6988, 6989, 6990, 6991, 6992, 6994, 6999, 7000, 7002, 7004, 7005, 7006, 7008, 7009, 7010, 7012, 7013, 7014, 7016, 7018, 7020, 7023, 7024, 7025, 7028, 7029, 7030, 7032, 7033, 7034, 7036, 7037, 7038, 7040, 7044, 7045, 7048, 7049, 7054, 7071, 7072, 7074, 7075, 7077, 7080, 7081, 7082, 7084, 7087, 7088, 7089, 7092, 7093, 7094, 7096, 7098, 7101, 7102, 7103, 7107, 7108, 7109, 7111, 7112, 7113, 7114, 7116, 7117, 7118, 7122, 7126, 7127, 7128, 7130, 7131, 7133, 7134, 7135, 7136, 7137, 7138, 7139, 7164, 7169, 7181, 7182, 7183, 7185, 7186, 7187, 7188, 7190, 7191, 7192, 7194, 7195, 7196, 7197, 7202, 7203, 7206, 7207, 7208, 7213, 7214, 7215, 7217, 7219, 7220, 7221, 7222, 7223, 7224, 7225, 7226, 7227, 7228, 7229, 7230, 7231, 7232, 7233, 7234, 7235, 7236, 7237, 7238, 7239, 7240, 7242, 7255, 7256, 7258, 7259, 7260, 7261, 7263, 7264, 7266, 7267, 7268, 7269, 7270, 7272, 7277, 7279, 7280, 7281, 7282, 7284, 7288, 7291, 7293, 7296, 7298, 7299, 7302, 7303, 7304, 7306, 7307, 7308, 7311, 7313, 7321, 7323, 7324, 7326, 7328, 7330, 7332, 7335, 7336, 7339, 7340, 7341, 7343, 7344, 7345, 7349, 7350, 7352, 7353, 7355, 7356, 7357, 7359, 7360, 7361, 7362, 7363, 7425, 7426, 7428, 7429, 7431, 7432, 7433, 7437, 7442, 7444, 7445, 7447, 7448, 7449, 7450, 7451, 7452, 7453, 7454, 7455, 7457, 7458, 7460, 7462, 7465, 7466, 7467, 7468, 7469, 7471, 7472, 7474, 7475, 7477, 7478, 7480, 7481, 7483, 7492, 7494, 7495, 7498, 7500, 7502, 7503, 7504, 7508, 7513, 7514, 7515, 7517, 7518, 7519, 7520, 7555, 7575, 7637, 7638, 7639, 7641, 7642, 7643, 7644, 7645, 7647, 7648, 7651, 7652, 7653, 7655, 7656, 7658, 7659, 7660, 7661, 7663, 7664, 7665, 7666, 7667, 7668, 7669, 7670, 7672, 7673, 7676, 7678, 7679, 7681, 7682, 7683, 7684, 7685, 7686, 7687, 7688, 7690, 7691, 7692, 7693, 7694, 7695, 7697, 7698, 7699, 7700, 7701, 7702, 7703, 7704, 7705, 7706, 7707, 7715, 7716, 7720, 7721, 7722, 7724, 7725, 7728, 7730, 7731, 7733, 7734, 7738, 7742, 7743, 7744, 7745, 7749, 7750, 7751, 7753, 7754, 7755, 7758, 7759, 7760, 7761, 7762, 7763, 7764, 7767, 7769, 7770, 7771, 7772, 7775, 7776, 7777, 7781, 7783, 7785, 7786, 7787, 7788, 7791, 7792, 7794, 7795, 7796, 7797, 7800, 7801, 7802, 7803, 7804, 7806, 7808, 7809, 7810, 7815, 7817, 7818, 7819, 7822, 7825, 7829, 7830, 7832, 7833, 7834, 7835, 7836, 7838, 7839, 7840, 7841, 7842, 7845, 7846, 7847, 7851, 7856, 7857, 7859, 7860, 7861, 7863, 7864, 7865, 7867, 7868, 7869, 7870, 7873, 7875, 7876, 7877, 7878, 7879, 7882, 7884, 7885, 7886, 7887, 7888, 7889, 7890, 7891, 7893, 7894, 7895, 7898, 7899, 7900, 7901, 7902, 7904, 7905, 7906, 7908, 7909, 7914, 7915, 7916, 7917, 7918, 7919, 7922, 7923, 7924, 7926, 7927, 7928, 7932, 7933, 7934, 7936, 7937, 7938, 7943, 7945, 7946, 7948, 7949, 7950, 7953, 7954, 7955, 7956, 7957, 7958, 7961, 7962, 7963, 7965, 7966, 7967, 7971, 7972, 7973, 7974, 7977, 7980, 7981, 7982, 7983, 7984, 7986, 7987, 7988, 7989, 7990, 7993, 7994, 7995, 7996, 7997, 7999, 8000, 8001, 8002, 8003, 8011, 8012, 8013, 8015, 8016, 8017, 8019, 8020, 8021, 8022, 8023, 8024, 8026, 8027, 8028, 8029, 8030, 8034, 8035, 8036, 8037, 8039, 8040, 8041, 8042, 8043, 8045, 8046, 8048, 8049, 8051, 8052, 8053, 8055, 8056, 8058, 8059, 8061, 8067, 8068, 8069, 8070, 8072, 8073, 8074, 8075, 8076, 8077, 8078, 8079, 8080, 8082, 8084, 8086, 8089, 8090, 8091, 8093, 8094, 8095, 8097, 8098, 8099, 8100, 8103, 8104, 8105, 8107, 8108, 8109, 8111, 8112, 8113, 8114, 8117, 8118, 8119, 8121, 8122, 8123, 8125, 8126, 8127, 8128, 8131, 8132, 8133, 8135, 8136, 8137, 8139, 8140, 8141, 8142, 8145, 8146, 8147, 8149, 8150, 8152, 8159, 8160, 8161, 8162, 8164, 8165, 8166, 8167, 8168, 8172, 8176, 8177, 8178, 8180, 8181, 8182, 8183, 8184, 8189, 8190, 8191, 8192, 8193, 8194, 8195, 8198, 8199, 8200, 8202, 8203, 8204, 8206, 8207, 8208, 8209, 8212, 8213, 8214, 8216, 8217, 8218, 8220, 8221, 8222, 8223, 8226, 8227, 8228, 8230, 8231, 8232, 8234, 8235, 8236, 8237, 8240, 8241, 8242, 8244, 8245, 8246, 8248, 8249, 8250, 8251, 8254, 8255, 8256, 8258, 8259, 8260, 8262, 8263, 8264, 8265, 8269, 8270, 8272, 8273, 8278, 8279, 8282, 8283, 8284, 8287, 8288, 8289, 8290, 8291, 8292, 8294, 8295, 8296, 8297, 8298, 8300, 8304, 8305, 8307, 8308, 8310, 8311, 8312, 8313, 8314, 8317, 8318, 8319, 8320, 8321, 8322, 8324, 8325, 8326, 8327, 8328, 8329, 8330, 8332, 8334, 8335, 8338, 8339, 8340, 8342, 8345, 8346, 8347, 8350, 8351, 8352, 8353, 8355, 8356, 8357, 8358, 8360, 8361, 8362, 8363, 8365, 8366, 8368, 8369, 8370, 8371, 8372, 8373, 8377, 8379, 8380, 8381, 8382, 8384, 8385, 8386, 8388, 8389, 8391, 8392, 8393, 8394, 8395, 8397, 8398, 8400, 8401, 8403, 8404, 8405, 8407, 8411, 8420, 8421, 8422, 8423, 8425, 8426, 8428, 8429, 8431, 8432, 8434, 8437, 8438, 8439, 8442, 8443, 8445, 8446, 8448, 8449, 8450, 8451, 8454, 8455, 8456, 8458, 8460, 8461, 8463, 8464, 8465, 8466, 8467, 8479, 8480, 8481, 8484, 8485, 8487, 8488, 8489, 8492, 8493, 8494, 8497, 8498, 8499, 8501, 8502, 8503, 8504, 8508, 8509, 8511, 8513, 8514, 8516, 8517, 8518, 8519, 8520, 8521, 8522, 8526, 8528, 8529, 8530, 8531, 8532, 8534, 8535, 8537, 8542, 8545, 8547, 8548, 8550, 8551, 8553, 8554, 8555, 8556, 8558, 8562, 8564, 8565, 8566, 8567, 8568, 8572, 8573, 8574, 8579, 8580, 8581, 8583, 8584, 8585, 8586, 8587, 8589, 8590, 8592, 8593, 8599, 8605, 8606, 8609, 8610, 8611, 8613, 8614, 8615, 8617, 8618, 8619, 8621, 8622, 8623, 8624, 8625, 8626, 8628, 8629, 8630, 8631, 8632, 8636, 8638, 8639, 8640, 8644, 8645, 8647, 8648, 8655, 8660, 8661, 8668, 8671, 8672, 8673, 8676, 8677, 8679, 8680, 8681, 8683, 8688, 8689, 8690, 8693, 8694, 8695, 8697, 8698, 8699, 8703, 8704, 8705, 8706, 8707, 8709, 8710, 8712, 8713, 8714, 8717, 8718, 8719, 8722, 8723, 8724, 8726, 8727, 8728, 8732, 8733, 8734, 8735, 8736, 8737, 8738, 8739, 8742, 8743, 8744, 8748, 8749, 8750, 8752, 8753, 8754, 8755, 8756, 8758, 8759, 8760, 8764, 8767, 8769, 8770, 8771, 8776, 8777, 8779, 8780, 8781, 8782, 8783, 8784, 8785, 8787, 8788, 8789, 8790, 8791, 8792, 8793, 8794, 8795, 8796, 8798, 8799, 8800, 8802, 8810, 8811, 8812, 8814, 8815, 8817, 8819, 8820, 8822, 8823, 8827, 8829, 8832, 8833, 8834, 8838, 8839, 8841, 8842, 8843, 8844, 8846, 8851, 8852, 8853, 8857, 8858, 8859, 8861, 8862, 8863, 8864, 8865, 8866, 8867, 8868, 8869, 8870, 8873, 8874, 8875, 8880, 8881, 8882, 8885, 8887, 8888, 8889, 8890, 8891, 8895, 8896, 8897, 8900, 8901, 8903, 8904, 8907, 8908, 8909, 8910, 8911, 8913, 8914, 8915, 8916, 8919, 8920, 8922, 8923, 8924, 8925, 8926, 8928, 8930, 8931, 8936, 8937, 8940, 8941, 8942, 8950, 8951, 8952, 8954, 8955, 8956, 8958, 8959, 8961, 8962, 8963, 8975, 8976, 8977, 8979, 8980, 8981, 8982, 8983, 8984, 8985, 8989, 8991, 8992, 8993, 8994, 8997, 9000, 9001, 9002, 9004, 9005, 9006, 9008, 9009, 9010, 9012, 9014, 9016, 9017, 9018, 9020, 9024, 9025, 9027, 9028, 9029, 9030, 9033, 9034, 9035, 9036, 9038, 9046, 9047, 9049, 9051, 9052, 9055, 9056, 9057, 9059, 9062, 9063, 9066, 9069, 9072, 9074, 9075, 9076, 9077, 9080, 9081, 9082, 9083, 9084, 9085, 9087, 9088, 9089, 9091, 9095, 9096, 9097, 9098, 9099, 9100, 9102, 9113, 9117, 9118, 9119, 9120, 9121, 9122, 9124, 9128, 9129, 9130, 9131, 9132, 9133, 9134, 9136, 9137, 9140, 9141, 9142, 9145, 9146, 9147, 9148, 9149, 9150, 9157, 9159, 9167, 9168, 9169, 9173, 9174, 9175, 9177, 9178, 9186, 9188, 9189, 9190, 9191, 9192, 9194, 9196, 9199, 9200, 9201, 9208, 9209, 9211, 9212, 9213, 9214, 9215, 9216, 9217, 9219, 9220, 9221, 9222, 9223, 9225, 9226, 9227, 9228, 9229, 9230, 9236, 9237, 9238, 9239, 9240, 9241, 9242, 9243, 9245, 9246, 9248, 9250, 9254, 9255, 9257, 9275, 9278, 9279, 9280, 9281, 9282, 9283, 9286, 9288, 9290, 9291, 9293, 9294, 9295, 9297, 9298, 9300, 9301, 9307, 9308, 9313, 9314, 9316, 9317, 9318, 9320, 9321, 9323, 9324, 9325, 9326, 9328, 9329, 9330, 9331, 9332, 9333, 9335, 9339, 9340, 9341, 9342, 9343, 9345, 9346, 9347, 9350, 9353, 9354, 9355, 9356, 9357, 9359, 9360, 9361, 9365, 9368, 9369, 9370, 9372, 9373, 9374, 9376, 9377, 9378, 9379, 9380, 9381, 9386, 9387, 9388, 9389, 9393, 9396, 9397, 9398, 9399, 9400, 9401, 9403, 9404, 9405, 9407, 9410, 9411, 9412, 9413, 9414, 9415, 9417, 9418, 9419, 9421, 9424, 9425, 9426, 9427, 9428, 9430, 9431, 9432, 9433, 9434, 9436, 9438, 9439, 9441, 9442, 9443, 9444, 9445, 9446, 9447, 9449, 9452, 9453, 9454, 9455, 9457, 9459, 9460, 9462, 9463, 9464, 9465, 9466, 9467, 9469, 9470, 9471, 9472, 9474, 9475, 9481, 9482, 9484, 9485, 9487, 9488, 9489, 9490, 9491, 9492, 9493, 9494, 9495, 9496, 9497, 9498, 9499, 9501, 9502, 9503, 9504, 9506, 9507, 9511, 9512, 9516, 9517, 9521, 9522, 9524, 9525, 9526, 9527, 9528, 9529, 9530, 9533, 9534, 9536, 9537, 9546, 9547, 9548, 9549, 9550, 9551, 9552, 9553, 9566, 9567, 9580, 9582, 9583, 9584, 9585, 9587, 9588, 9589, 9590, 9592, 9609, 9611, 9612, 9613, 9614, 9615, 9616, 9619, 9620, 9621, 9622, 9623, 9626, 9627, 9628, 9629, 9630, 9633, 9634, 9635, 9636, 9638, 9639, 9644, 9645, 9648, 9649, 9653, 9654, 9659, 9660, 9664, 9667, 9668, 9669, 9670, 9672, 9673, 9674, 9675, 9676, 9677, 9679, 9680, 9681, 9682, 9683, 9685, 9687, 9688, 9690, 9691, 9692, 9693, 9694, 9695, 9697, 9699, 9700, 9702, 9703, 9704, 9705, 9706, 9707, 9709, 9712, 9715, 9716, 9717, 9720, 9721, 9727, 9728, 9730, 9731, 9732, 9734, 9735, 9736, 9737, 9739, 9743, 9744, 9745, 9746, 9748, 9749, 9750, 9751, 9752, 9753, 9754, 9758, 9760, 9761, 9763, 9764, 9765, 9766, 9768, 9771, 9772, 9773, 9774, 9776, 9778, 9780, 9781, 9782, 9783, 9785, 9786, 9787, 9788, 9790, 9792, 9794, 9798, 9799, 9800, 9804, 9808, 9809, 9810, 9811, 9813, 9815, 9820, 9821, 9823, 9838, 9839, 9841, 9842, 9844, 9845, 9846, 9848, 9849, 9850, 9851, 9854, 9855, 9856, 9858, 9859, 9860, 9862, 9865, 9866, 9867, 9869, 9870, 9872, 9873, 9876, 9877, 9879, 9880, 9882, 9883, 9884, 9885, 9887, 9894, 9895, 9896, 9898, 9899, 9901, 9902, 9903, 9906, 9909, 9910, 9911, 9912, 9915, 9916, 9917, 9918, 9920, 9922, 9925, 9926, 9930, 9931, 9933, 9934, 9935, 9937, 9949, 9950, 9951, 9952, 9954, 9955, 9956, 9958, 9959, 9960, 9961, 9962, 9963, 9964, 9965, 9969, 9970, 9973, 9974, 9976, 9977, 9979, 9980, 9981, 9983, 9995, 9996, 9998, 9999, 10000, 10003, 10004, 10006, 10007, 10008, 10009, 10010, 10011, 10012, 10013, 10015, 10018, 10019, 10020, 10022, 10023, 10024, 10026, 10028, 10029, 10030, 10032, 10035, 10036, 10037, 10039, 10040, 10042, 10043, 10044, 10046, 10051, 10052, 10053, 10055, 10056, 10057, 10059, 10060, 10061, 10063, 10064, 10067, 10068, 10071, 10072, 10073, 10075, 10076, 10078, 10079, 10080, 10082, 10084, 10087, 10088, 10089, 10093, 10094, 10097, 10098, 10099, 10101, 10102, 10104, 10105, 10106, 10108, 10109, 10110, 10111, 10112, 10115, 10116, 10118, 10119, 10120, 10121, 10123, 10139, 10156, 10185, 10186, 10188, 10189, 10191, 10192, 10193, 10194, 10196, 10197, 10198, 10202, 10204, 10208, 10209, 10213, 10214, 10215, 10217, 10220, 10221, 10222, 10223, 10224, 10225, 10226, 10230, 10231, 10232, 10234, 10235, 10236, 10237, 10238, 10239, 10246, 10257, 10258, 10260, 10261, 10262, 10263, 10264, 10266, 10267, 10268, 10271, 10272, 10273, 10274, 10275, 10277, 10278, 10279, 10280, 10282, 10284, 10285, 10287, 10289, 10291, 10293, 10294, 10295, 10296, 10298, 10303, 10304, 10306, 10307, 10311, 10312, 10314, 10315, 10320, 10321, 10322, 10323, 10324, 10326, 10328, 10329, 10330, 10331, 10333, 10334, 10335, 10336, 10337, 10339, 10341, 10342, 10347, 10348, 10349, 10350, 10352, 10354, 10355, 10356, 10357, 10358, 10359, 10360, 10361, 10362, 10363, 10364, 10365, 10367, 10368, 10370, 10371, 10372, 10373, 10374, 10380, 10382, 10384, 10386, 10387, 10390, 10391, 10392, 10393, 10394, 10395, 10396, 10405, 10407, 10408, 10409, 10411, 10433, 10434, 10435, 10436, 10437, 10439, 10440, 10441, 10442, 10443, 10445, 10446, 10447, 10448, 10449, 10450, 10453, 10457, 10459, 10460, 10464, 10465, 10466, 10467, 10468, 10471, 10486, 10487, 10539, 10540, 10541, 10544, 10546, 10547, 10548, 10549, 10551, 10552, 10553, 10555, 10557, 10558, 10559, 10560, 10561, 10562, 10563, 10567, 10569, 10570, 10572, 10573, 10578, 10579, 10580, 10582, 10583, 10584, 10585, 10586, 10592, 10594, 10595, 10597, 10598, 10600, 10602, 10603, 10604, 10607, 10608, 10609, 10610, 10612, 10613, 10614, 10615, 10616, 10617, 10618, 10619, 10621, 10622, 10625, 10627, 10628, 10630, 10635, 10636, 10640, 10641, 10642, 10643, 10645, 10647, 10649, 10650, 10651, 10654, 10655, 10656, 10657, 10658, 10659, 10660, 10662, 10666, 10667, 10669, 10670, 10671, 10673, 10674, 10675, 10677, 10678, 10680, 10681, 10682, 10683, 10684, 10687, 10688, 10689, 10690, 10691, 10692, 10693, 10694, 10695, 10696, 10697, 10698, 10699, 10700, 10701, 10702, 10703, 10704, 10705, 10707, 10708, 10709, 10710, 10711, 10712, 10713, 10714, 10715, 10716, 10718, 10721, 10722, 10723, 10724, 10725, 10727, 10728, 10729, 10730, 10733, 10734, 10735, 10736, 10738, 10739, 10740, 10741, 10742, 10744, 10745, 10747, 10748, 10749, 10751, 10752, 10754, 10755, 10756, 10757, 10758, 10759, 10761, 10762, 10764, 10765, 10766, 10767, 10768, 10769, 10771, 10772, 10773, 10774, 10775, 10777, 10778, 10780, 10781, 10782, 10783, 10784, 10786, 10787, 10791, 10792, 10793, 10794, 10797, 10798, 10800, 10801, 10804, 10805, 10806, 10807, 10808, 10809, 10810, 10813, 10814, 10816, 10817, 10818, 10819, 10820, 10822, 10823, 10825, 10826, 10828, 10829, 10830, 10831, 10832, 10834, 10835, 10837, 10838, 10839, 10840, 10841, 10842, 10843, 10844, 10845, 10847, 10849, 10851, 10852, 10853, 10854, 10855, 10858, 10860, 10861, 10863, 10864, 10866, 10867, 10868, 10870, 10871, 10872, 10874, 10875, 10877, 10878, 10879, 10881, 10882, 10883, 10885, 10886, 10888, 10890, 10891, 10892, 10893, 10894, 10896, 10899, 10900, 10901, 10902, 10904, 10905, 10906, 10907, 10909, 10912, 10913, 10914, 10917, 10918, 10919, 10920, 10921, 10922, 10923, 10924, 10926, 10933, 10935, 10936, 10937, 10939, 10940, 10943, 10944, 10945, 10946, 10948, 10950, 10951, 10952, 10953, 10954, 10955, 10958, 10959, 10962, 10963, 10964, 10965, 10968, 10969, 10970, 10971, 10974, 10975, 10976, 10977, 10978, 10979, 10980, 10982, 10984, 10985, 10990, 10991, 10992, 10997, 10998, 11003, 11005, 11006, 11007, 11009, 11010, 11011, 11012, 11013, 11014, 11016, 11019, 11020, 11021, 11022, 11023, 11024, 11025, 11026, 11027, 11028, 11031, 11032, 11033, 11034, 11035, 11037, 11040, 11041, 11042, 11044, 11045, 11046, 11048, 11049, 11050, 11051, 11052, 11053, 11054, 11056, 11057, 11058, 11059, 11062, 11063, 11064, 11070, 11071, 11073, 11074, 11075, 11076, 11077, 11078, 11079, 11080, 11081, 11083, 11084, 11085, 11086, 11087, 11088, 11089, 11091, 11094, 11096, 11097, 11098, 11099, 11101, 11103, 11104, 11105, 11106, 11107, 11108, 11109, 11111, 11114, 11115, 11116, 11119, 11120, 11125, 11131, 11132, 11138, 11139, 11145, 11146, 11147, 11153, 11165, 11166, 11167, 11172, 11173, 11174, 11177, 11180, 11183, 11184, 11185, 11186, 11187, 11188, 11190, 11191, 11193, 11195, 11198, 11199, 11200, 11203, 11204], "summary": {"covered_lines": 5745, "num_statements": 7572, "percent_covered": 71.5684335443038, "percent_covered_display": "72", "missing_lines": 1827, "excluded_lines": 0, "num_branches": 2540, "num_partial_branches": 418, "covered_branches": 1492, "missing_branches": 1048}, "missing_lines": [107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 122, 124, 125, 126, 127, 186, 187, 188, 194, 215, 216, 217, 237, 238, 260, 262, 263, 264, 266, 267, 268, 271, 278, 279, 280, 296, 297, 346, 347, 354, 355, 363, 364, 391, 406, 437, 449, 474, 475, 477, 490, 586, 592, 669, 679, 680, 681, 686, 689, 704, 707, 722, 730, 736, 739, 822, 825, 834, 839, 858, 887, 891, 925, 1000, 1018, 1027, 1028, 1029, 1035, 1085, 1123, 1132, 1133, 1134, 1135, 1145, 1146, 1157, 1174, 1177, 1197, 1198, 1250, 1253, 1256, 1264, 1268, 1283, 1284, 1285, 1340, 1341, 1354, 1382, 1414, 1422, 1426, 1430, 1434, 1450, 1451, 1452, 1461, 1465, 1470, 1474, 1475, 1476, 1484, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1558, 1574, 1578, 1582, 1607, 1610, 1615, 1619, 1622, 1638, 1645, 1658, 1659, 1664, 1665, 1673, 1674, 1676, 1677, 1678, 1679, 1680, 1682, 1683, 1684, 1685, 1687, 1699, 1709, 1714, 1715, 1716, 1717, 1723, 1732, 1776, 1777, 1786, 1787, 1788, 1789, 1802, 1819, 1820, 1899, 1959, 1960, 1961, 1962, 1963, 1968, 1969, 1970, 1984, 1985, 1986, 1987, 2044, 2060, 2068, 2080, 2117, 2119, 2134, 2135, 2136, 2137, 2139, 2140, 2141, 2142, 2143, 2148, 2161, 2162, 2166, 2173, 2176, 2182, 2186, 2191, 2196, 2224, 2266, 2269, 2279, 2282, 2285, 2288, 2291, 2294, 2301, 2333, 2345, 2350, 2351, 2352, 2354, 2363, 2364, 2366, 2412, 2415, 2418, 2419, 2420, 2421, 2423, 2424, 2425, 2426, 2430, 2434, 2435, 2436, 2437, 2438, 2439, 2442, 2445, 2447, 2448, 2449, 2450, 2451, 2452, 2454, 2455, 2457, 2458, 2460, 2462, 2463, 2464, 2465, 2467, 2468, 2470, 2474, 2475, 2476, 2478, 2480, 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, 2491, 2492, 2493, 2494, 2496, 2498, 2501, 2502, 2503, 2504, 2505, 2506, 2535, 2539, 2540, 2541, 2542, 2546, 2547, 2548, 2552, 2557, 2561, 2564, 2565, 2566, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2577, 2578, 2582, 2583, 2584, 2585, 2588, 2589, 2592, 2594, 2595, 2596, 2598, 2599, 2600, 2601, 2602, 2603, 2605, 2606, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2625, 2626, 2628, 2629, 2630, 2631, 2632, 2634, 2635, 2636, 2637, 2641, 2642, 2654, 2687, 2688, 2689, 2693, 2694, 2695, 2696, 2700, 2704, 2709, 2710, 2711, 2712, 2713, 2714, 2715, 2719, 2720, 2739, 2744, 2745, 2746, 2749, 2750, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2760, 2761, 2764, 2765, 2766, 2767, 2770, 2771, 2772, 2774, 2775, 2776, 2836, 2838, 2839, 2841, 2843, 2844, 2845, 2846, 2847, 2848, 2849, 2850, 2851, 2852, 2853, 2854, 2855, 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863, 2864, 2865, 2866, 2867, 2868, 2869, 2870, 2871, 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2891, 2892, 2903, 2906, 2907, 2908, 2909, 2910, 2911, 2912, 2913, 2935, 2936, 2957, 2996, 2997, 2998, 2999, 3002, 3005, 3008, 3009, 3010, 3013, 3014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3026, 3027, 3028, 3029, 3030, 3031, 3036, 3037, 3056, 3098, 3099, 3100, 3101, 3104, 3107, 3110, 3112, 3116, 3119, 3120, 3121, 3122, 3124, 3125, 3126, 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134, 3135, 3136, 3137, 3138, 3139, 3140, 3143, 3144, 3145, 3146, 3147, 3148, 3152, 3153, 3154, 3155, 3167, 3198, 3199, 3200, 3201, 3213, 3239, 3242, 3245, 3248, 3249, 3250, 3253, 3254, 3256, 3257, 3258, 3259, 3260, 3261, 3262, 3263, 3264, 3265, 3266, 3267, 3268, 3269, 3270, 3271, 3272, 3275, 3276, 3277, 3278, 3279, 3280, 3284, 3285, 3296, 3312, 3313, 3314, 3315, 3316, 3317, 3319, 3321, 3322, 3323, 3324, 3325, 3331, 3337, 3341, 3342, 3343, 3347, 3348, 3349, 3359, 3360, 3361, 3362, 3367, 3380, 3381, 3382, 3383, 3400, 3405, 3406, 3407, 3408, 3419, 3442, 3443, 3447, 3461, 3462, 3468, 3478, 3536, 3551, 3552, 3553, 3576, 3577, 3578, 3580, 3581, 3582, 3583, 3584, 3585, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3617, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3659, 3674, 3675, 3676, 3677, 3678, 3684, 3685, 3691, 3692, 3712, 3713, 3714, 3716, 3717, 3718, 3719, 3721, 3733, 3734, 3735, 3736, 3737, 3738, 3739, 3748, 3759, 3767, 3774, 3779, 3780, 3867, 3880, 3881, 3882, 3883, 3884, 3885, 3894, 3899, 3904, 3909, 3910, 3915, 3920, 3925, 3930, 3935, 3940, 3945, 3950, 3963, 3973, 3998, 4003, 4013, 4023, 4045, 4050, 4054, 4055, 4056, 4059, 4060, 4067, 4068, 4069, 4070, 4071, 4072, 4094, 4106, 4135, 4136, 4137, 4138, 4141, 4142, 4143, 4144, 4145, 4178, 4186, 4187, 4188, 4189, 4190, 4191, 4192, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, 4216, 4217, 4219, 4220, 4221, 4222, 4223, 4224, 4225, 4226, 4262, 4269, 4280, 4281, 4282, 4309, 4310, 4311, 4312, 4313, 4314, 4315, 4318, 4319, 4320, 4321, 4322, 4323, 4324, 4333, 4334, 4335, 4336, 4337, 4338, 4339, 4340, 4380, 4381, 4382, 4383, 4387, 4388, 4389, 4390, 4391, 4393, 4394, 4395, 4421, 4422, 4423, 4448, 4449, 4463, 4469, 4488, 4502, 4534, 4542, 4566, 4574, 4581, 4593, 4600, 4603, 4604, 4638, 4639, 4640, 4692, 4693, 4720, 4721, 4725, 4726, 4730, 4733, 4734, 4736, 4770, 4771, 4778, 4779, 4780, 4781, 4830, 4831, 4845, 4862, 4863, 4866, 4867, 4870, 4888, 4889, 4890, 4902, 4903, 4904, 4905, 4906, 4909, 4910, 4912, 4913, 4914, 4915, 4926, 4927, 4928, 4929, 4930, 4933, 4934, 4936, 4937, 4938, 4939, 4975, 4976, 4985, 4986, 4993, 4994, 4995, 5003, 5004, 5021, 5022, 5026, 5027, 5105, 5106, 5107, 5108, 5109, 5118, 5119, 5134, 5135, 5139, 5140, 5170, 5171, 5172, 5173, 5174, 5176, 5177, 5178, 5179, 5180, 5181, 5182, 5183, 5184, 5186, 5187, 5253, 5284, 5285, 5293, 5294, 5295, 5313, 5320, 5324, 5337, 5338, 5339, 5340, 5341, 5342, 5343, 5344, 5345, 5346, 5347, 5348, 5372, 5387, 5388, 5406, 5407, 5408, 5409, 5434, 5435, 5436, 5437, 5541, 5542, 5568, 5569, 5570, 5572, 5573, 5574, 5577, 5578, 5579, 5581, 5582, 5584, 5585, 5586, 5589, 5596, 5597, 5598, 5612, 5613, 5614, 5616, 5617, 5618, 5620, 5621, 5623, 5624, 5625, 5627, 5628, 5629, 5630, 5634, 5635, 5636, 5638, 5639, 5640, 5642, 5643, 5646, 5648, 5649, 5650, 5651, 5653, 5655, 5656, 5658, 5659, 5660, 5661, 5662, 5663, 5664, 5668, 5669, 5685, 5686, 5698, 5704, 5705, 5708, 5709, 5723, 5724, 5735, 5783, 5787, 5788, 5814, 5818, 5819, 5860, 5861, 5879, 5880, 5883, 5884, 5886, 5889, 5891, 5892, 5894, 5895, 5896, 5898, 5899, 5901, 5902, 5903, 5905, 5924, 5925, 5929, 5935, 5936, 5939, 5940, 5979, 5980, 5985, 5986, 5994, 5995, 5996, 5997, 6127, 6129, 6174, 6175, 6198, 6199, 6202, 6203, 6207, 6208, 6209, 6217, 6252, 6253, 6254, 6262, 6271, 6307, 6308, 6309, 6314, 6315, 6317, 6325, 6338, 6339, 6363, 6364, 6365, 6366, 6368, 6369, 6370, 6371, 6373, 6374, 6382, 6383, 6386, 6388, 6429, 6430, 6434, 6435, 6443, 6455, 6456, 6477, 6478, 6487, 6488, 6489, 6512, 6517, 6518, 6519, 6520, 6521, 6527, 6528, 6534, 6535, 6553, 6554, 6584, 6585, 6593, 6594, 6610, 6611, 6614, 6622, 6623, 6624, 6625, 6647, 6648, 6673, 6674, 6682, 6705, 6706, 6714, 6734, 6735, 6738, 6739, 6750, 6781, 6792, 6797, 6799, 6881, 6882, 6883, 6894, 6895, 6930, 6931, 6932, 6935, 6936, 6937, 6995, 6996, 6997, 7041, 7042, 7046, 7050, 7051, 7052, 7119, 7120, 7123, 7124, 7141, 7142, 7144, 7145, 7146, 7149, 7150, 7153, 7155, 7156, 7157, 7158, 7160, 7161, 7162, 7165, 7166, 7167, 7170, 7171, 7172, 7173, 7174, 7175, 7176, 7177, 7178, 7198, 7199, 7200, 7265, 7285, 7286, 7289, 7294, 7300, 7309, 7310, 7312, 7314, 7316, 7317, 7319, 7327, 7333, 7365, 7366, 7367, 7368, 7369, 7370, 7371, 7372, 7374, 7375, 7376, 7378, 7379, 7380, 7381, 7383, 7384, 7386, 7389, 7390, 7392, 7393, 7394, 7396, 7398, 7399, 7400, 7401, 7402, 7404, 7405, 7406, 7408, 7409, 7410, 7412, 7414, 7415, 7416, 7417, 7419, 7420, 7422, 7423, 7434, 7435, 7439, 7440, 7484, 7485, 7486, 7487, 7488, 7490, 7491, 7493, 7505, 7507, 7509, 7510, 7511, 7522, 7529, 7530, 7531, 7532, 7535, 7536, 7538, 7541, 7543, 7544, 7545, 7546, 7548, 7549, 7550, 7552, 7553, 7557, 7559, 7560, 7561, 7562, 7563, 7564, 7566, 7568, 7569, 7570, 7572, 7573, 7578, 7579, 7580, 7581, 7582, 7583, 7584, 7585, 7587, 7588, 7589, 7590, 7591, 7593, 7594, 7596, 7597, 7598, 7600, 7601, 7602, 7604, 7605, 7606, 7608, 7610, 7615, 7616, 7617, 7619, 7620, 7622, 7624, 7625, 7626, 7627, 7628, 7630, 7631, 7632, 7633, 7634, 7635, 7649, 7674, 7708, 7709, 7710, 7711, 7713, 7714, 7718, 7726, 7727, 7735, 7739, 7740, 7746, 7747, 7756, 7778, 7779, 7789, 7798, 7805, 7807, 7811, 7813, 7820, 7823, 7826, 7827, 7837, 7848, 7849, 7854, 7855, 7871, 7872, 7880, 7910, 7911, 7929, 7930, 7939, 7940, 7941, 7944, 7968, 7969, 7976, 8005, 8006, 8007, 8008, 8031, 8032, 8081, 8169, 8170, 8173, 8174, 8185, 8186, 8187, 8266, 8267, 8274, 8275, 8276, 8285, 8408, 8409, 8412, 8413, 8414, 8415, 8417, 8418, 8452, 8468, 8469, 8470, 8471, 8473, 8475, 8476, 8505, 8506, 8523, 8524, 8525, 8533, 8543, 8569, 8594, 8595, 8596, 8597, 8634, 8635, 8641, 8642, 8656, 8662, 8663, 8664, 8665, 8666, 8684, 8685, 8700, 8701, 8729, 8730, 8761, 8762, 8765, 8772, 8773, 8774, 8847, 8848, 8892, 8893, 8898, 8899, 8912, 8932, 8934, 8964, 8965, 8966, 8967, 8968, 8969, 8970, 8972, 8973, 8986, 8987, 8996, 9021, 9022, 9039, 9040, 9042, 9043, 9070, 9092, 9103, 9104, 9105, 9107, 9108, 9109, 9111, 9114, 9125, 9138, 9160, 9161, 9163, 9164, 9232, 9233, 9234, 9260, 9261, 9262, 9263, 9265, 9267, 9268, 9269, 9270, 9272, 9273, 9310, 9336, 9348, 9362, 9363, 9364, 9382, 9383, 9384, 9390, 9391, 9392, 9406, 9420, 9440, 9450, 9508, 9509, 9513, 9514, 9518, 9519, 9538, 9539, 9540, 9541, 9542, 9543, 9544, 9554, 9555, 9556, 9557, 9558, 9559, 9560, 9562, 9563, 9564, 9568, 9569, 9570, 9571, 9572, 9574, 9575, 9578, 9579, 9594, 9595, 9596, 9597, 9599, 9600, 9603, 9604, 9607, 9641, 9642, 9661, 9710, 9740, 9741, 9756, 9757, 9769, 9795, 9796, 9801, 9802, 9805, 9806, 9816, 9817, 9818, 9824, 9826, 9828, 9830, 9832, 9835, 9888, 9889, 9890, 9891, 9892, 9904, 9905, 9913, 9914, 9921, 9938, 9939, 9940, 9941, 9942, 9944, 9945, 9946, 9967, 9984, 9985, 9986, 9987, 9989, 9990, 9991, 9992, 10001, 10016, 10047, 10048, 10065, 10066, 10085, 10086, 10090, 10091, 10092, 10124, 10126, 10127, 10128, 10129, 10131, 10132, 10133, 10134, 10136, 10137, 10142, 10143, 10145, 10146, 10148, 10149, 10151, 10152, 10153, 10154, 10158, 10159, 10160, 10161, 10162, 10163, 10165, 10166, 10167, 10168, 10169, 10170, 10172, 10174, 10175, 10176, 10177, 10178, 10179, 10180, 10181, 10182, 10199, 10200, 10205, 10206, 10210, 10211, 10216, 10227, 10228, 10248, 10249, 10250, 10251, 10252, 10253, 10254, 10265, 10308, 10309, 10310, 10316, 10318, 10343, 10344, 10346, 10388, 10406, 10413, 10414, 10415, 10416, 10417, 10418, 10419, 10420, 10421, 10423, 10424, 10454, 10456, 10461, 10462, 10472, 10473, 10474, 10475, 10476, 10477, 10480, 10481, 10482, 10483, 10488, 10489, 10492, 10493, 10494, 10496, 10498, 10499, 10500, 10501, 10502, 10503, 10505, 10508, 10509, 10511, 10512, 10515, 10516, 10517, 10518, 10520, 10521, 10522, 10524, 10525, 10526, 10527, 10528, 10529, 10530, 10533, 10534, 10535, 10536, 10537, 10543, 10554, 10564, 10566, 10568, 10574, 10575, 10576, 10589, 10620, 10624, 10626, 10631, 10663, 10664, 10679, 10719, 10726, 10731, 10732, 10737, 10846, 10848, 10856, 10857, 10880, 10903, 10925, 10927, 10928, 10931, 10986, 10987, 10993, 10994, 10999, 11000, 11001, 11002, 11008, 11015, 11038, 11043, 11055, 11060, 11061, 11065, 11092, 11121, 11122, 11123, 11126, 11129, 11133, 11134, 11135, 11137, 11148, 11150, 11168, 11169, 11205], "excluded_lines": [], "executed_branches": [[172, 173], [172, 177], [174, 172], [174, 175], [185, 190], [193, 195], [211, 212], [211, 214], [214, 219], [221, 222], [221, 230], [222, 223], [224, 222], [224, 225], [235, -235], [235, 235], [235, 236], [236, 240], [251, 252], [251, 254], [259, 273], [276, 282], [375, 376], [375, 378], [388, 389], [405, 407], [407, 408], [408, 409], [413, 414], [413, 415], [435, 436], [459, -459], [459, 461], [464, 465], [464, 487], [467, 468], [467, 470], [472, 479], [479, 480], [479, 483], [487, 488], [487, 502], [488, 491], [493, 494], [493, 495], [495, 496], [495, 497], [497, 498], [497, 500], [531, -530], [531, 532], [533, -532], [533, 534], [535, -534], [535, 536], [537, -536], [537, 538], [539, 540], [541, 542], [543, -542], [543, 544], [545, 546], [547, -546], [547, 548], [549, 550], [551, 552], [553, 555], [558, 560], [561, -561], [561, 561], [561, 562], [583, 584], [583, 585], [585, 587], [587, 588], [587, 589], [611, -611], [611, -609], [632, 633], [632, 636], [728, 729], [728, 731], [729, 728], [817, 818], [817, 819], [819, 820], [824, 827], [829, 831], [829, 870], [832, 836], [838, 841], [855, 856], [864, 865], [864, 867], [868, 829], [868, 869], [907, 908], [913, 914], [913, 916], [914, 913], [914, 915], [922, 923], [934, -932], [934, 936], [938, -936], [938, 940], [942, -940], [942, 944], [946, -944], [946, 948], [950, -948], [950, 952], [954, -952], [954, 956], [958, -956], [958, 960], [962, -960], [962, 964], [966, -964], [966, 968], [970, -968], [970, -742], [1017, 1019], [1022, 1023], [1122, 1124], [1126, 1127], [1141, 1142], [1151, 1152], [1151, 1153], [1173, 1176], [1176, 1179], [1181, -1181], [1181, 1181], [1181, 1182], [1182, 1183], [1182, 1184], [1220, 1221], [1225, 1226], [1248, 1249], [1273, 1278], [1280, 1281], [1309, 1311], [1324, 1326], [1366, 1367], [1366, 1369], [1439, 1440], [1439, 1441], [1458, 1459], [1458, 1463], [1460, 1462], [1464, 1466], [1469, 1471], [1473, 1477], [1483, 1486], [1542, 1543], [1542, 1544], [1588, 1589], [1589, 1590], [1606, 1609], [1609, 1612], [1614, 1617], [1618, 1621], [1644, 1647], [1667, 1668], [1698, 1700], [1708, 1710], [1722, 1724], [1748, 1749], [1775, 1778], [1798, 1799], [1798, 1807], [1801, 1804], [1843, 1844], [1843, 1849], [1846, 1843], [1846, 1847], [1861, 1862], [1861, 1864], [1864, 1865], [1864, 1866], [1866, 1867], [1866, 1869], [1870, 1871], [1886, 1887], [1886, 1902], [1888, -1888], [1888, 1888], [1888, 1890], [1890, 1891], [1890, 1894], [1894, -1894], [1894, 1894], [1894, 1895], [1895, 1896], [1976, 1977], [1976, 1978], [1997, 1998], [1997, 2000], [2003, 2004], [2003, 2005], [2020, -2008], [2020, 2021], [2026, 2027], [2026, 2030], [2043, 2047], [2051, 2052], [2059, 2064], [2067, 2071], [2071, -2071], [2071, 2071], [2071, 2072], [2110, 2111], [2110, 2121], [2113, 2114], [2113, 2121], [2114, 2115], [2114, 2121], [2115, 2116], [2121, -2105], [2121, 2122], [2128, -2128], [2128, -2125], [2128, 2128], [2154, 2155], [2154, 2158], [2160, 2164], [2165, 2168], [2169, 2171], [2171, 2172], [2202, 2203], [2202, 2204], [2233, 2234], [2233, 2236], [2234, 2235], [2265, -2265], [2265, -2260], [2327, 2328], [2327, 2329], [2349, 2355], [2359, 2360], [2359, 2367], [2361, 2362], [2813, 2814], [2882, 2883], [2884, 2885], [3329, 3330], [3330, -3328], [3335, 3336], [3336, -3334], [3372, 3373], [3372, 3374], [3388, -3386], [3388, 3389], [3388, 3390], [3396, 3397], [3396, 3398], [3398, 3399], [3416, 3417], [3416, 3435], [3418, 3421], [3421, 3422], [3421, 3424], [3424, -3424], [3424, 3424], [3424, 3425], [3429, 3430], [3429, 3432], [3441, 3445], [3445, 3446], [3446, 3449], [3449, 3450], [3449, 3453], [3450, 3449], [3450, 3451], [3460, 3464], [3464, 3465], [3465, 3464], [3465, 3466], [3475, 3476], [3476, 3475], [3476, 3477], [3485, 3486], [3485, 3488], [3486, 3485], [3486, 3487], [3497, 3499], [3497, 3500], [3506, -3506], [3506, -3503], [3506, 3506], [3511, 3512], [3511, 3513], [3513, -3513], [3513, -3509], [3513, 3513], [3533, 3537], [3538, -3538], [3538, 3539], [3538, 3546], [3541, 3542], [3541, 3545], [3546, 3550], [3550, 3554], [3565, 3566], [3565, 3572], [3573, 3574], [3602, 3603], [3673, 3680], [3682, -3682], [3682, 3682], [3682, 3683], [3683, 3688], [3727, 3728], [3747, 3750], [3758, 3761], [3766, 3769], [3785, 3786], [3785, 3787], [3807, 3808], [3807, 3812], [3808, -3806], [3808, 3809], [3809, -3806], [3809, 3810], [3815, -3806], [3815, 3816], [3861, 3862], [3861, 3863], [3863, 3864], [3864, -3864], [3864, 3864], [3864, 3865], [3874, -3874], [3874, -3871], [4042, 4043], [4049, 4052], [4058, 4061], [4093, 4096], [4096, 4097], [4118, 4119], [4175, 4176], [4185, 4195], [4195, 4205], [4207, 4209], [4211, 4212], [4211, 4229], [4215, 4211], [4259, 4260], [4264, 4265], [4277, -4277], [4277, 4277], [4277, 4279], [4308, 4317], [4317, -4317], [4317, 4328], [4330, -4330], [4330, 4330], [4330, 4331], [4346, 4348], [4474, 4475], [4474, 4481], [4477, -4477], [4477, 4478], [4481, 4482], [4484, -4484], [4484, 4485], [4501, -4501], [4501, -4498], [4508, 4509], [4508, 4510], [4510, 4511], [4531, 4532], [4555, -4554], [4555, 4556], [4556, 4555], [4556, 4557], [4585, -4585], [4585, 4585], [4585, 4586], [4585, 4587], [4588, 4589], [4588, 4592], [4592, 4594], [4594, 4595], [4607, 4608], [4607, 4612], [4619, 4620], [4619, 4621], [4630, 4631], [4630, 4633], [4633, 4634], [4646, 4647], [4646, 4648], [4651, 4652], [4651, 4653], [4691, 4695], [4695, 4696], [4695, 4699], [4705, 4706], [4705, 4711], [4706, 4707], [4706, 4709], [4713, 4714], [4713, 4717], [4717, 4718], [4717, 4719], [4719, 4722], [4722, 4723], [4722, 4724], [4724, 4727], [4727, 4728], [4732, 4738], [4742, 4743], [4742, 4744], [4754, 4755], [4759, 4760], [4759, 4761], [4769, 4773], [4774, -4774], [4774, 4777], [4777, 4782], [4791, 4792], [4791, 4793], [4801, 4803], [4801, 4805], [4805, -4805], [4805, 4805], [4805, 4809], [4810, -4810], [4810, 4810], [4810, 4813], [4817, 4818], [4817, 4819], [4828, 4833], [4833, -4833], [4833, 4833], [4833, 4836], [4842, 4844], [4842, 4848], [4844, 4847], [4851, 4852], [4851, 4853], [4861, 4865], [4865, 4869], [4869, 4873], [4879, -4879], [4879, 4879], [4879, 4880], [4883, 4884], [4883, 4886], [4894, 4895], [4894, 4896], [4918, 4919], [4918, 4920], [4942, 4943], [4942, 4944], [4953, 4954], [4953, 4957], [4957, 4958], [4964, -4964], [4964, 4965], [4965, -4965], [4965, 4967], [4980, 4981], [4980, 4988], [4990, 4991], [5008, 5009], [5008, 5010], [5020, 5024], [5025, 5029], [5034, 5035], [5034, 5036], [5059, 5060], [5059, 5061], [5061, 5062], [5061, 5064], [5067, -5066], [5067, 5068], [5076, 5077], [5101, 5102], [5117, 5121], [5121, 5122], [5121, 5125], [5123, 5124], [5131, 5132], [5131, 5136], [5133, 5131], [5166, 5167], [5190, 5191], [5190, 5192], [5222, 5223], [5222, 5229], [5223, 5224], [5223, 5227], [5230, 5231], [5230, 5234], [5234, 5235], [5234, 5239], [5239, -5239], [5239, 5239], [5239, 5240], [5252, 5254], [5261, 5262], [5261, 5268], [5283, 5288], [5304, 5305], [5304, 5333], [5309, 5309], [5309, 5315], [5319, 5321], [5323, 5325], [5325, 5304], [5325, 5327], [5329, 5330], [5336, -5335], [5357, 5358], [5357, 5360], [5376, 5377], [5376, 5389], [5377, 5376], [5377, 5378], [5381, 5382], [5381, 5386], [5386, 5376], [5396, 5397], [5396, 5402], [5397, 5396], [5397, 5398], [5398, 5399], [5399, 5400], [5422, 5423], [5422, 5424], [5428, 5429], [5428, 5430], [5442, 5443], [5442, 5445], [5443, 5442], [5443, 5444], [5448, 5449], [5448, 5450], [5472, 5473], [5472, 5476], [5478, 5479], [5478, 5482], [5482, 5483], [5482, 5486], [5489, 5490], [5489, 5493], [5503, 5504], [5503, 5505], [5520, 5521], [5520, 5524], [5521, -5521], [5521, 5521], [5521, 5522], [5527, 5528], [5527, 5529], [5540, 5544], [5547, 5548], [5547, 5551], [5555, 5556], [5555, 5557], [5601, 5602], [5601, 5603], [5672, 5673], [5672, 5674], [5684, 5688], [5694, 5695], [5694, 5697], [5697, 5700], [5703, 5707], [5707, 5711], [5711, 5712], [5711, 5717], [5712, 5713], [5712, 5714], [5714, 5711], [5714, 5715], [5720, 5721], [5720, 5737], [5726, 5720], [5726, 5727], [5728, 5726], [5728, 5729], [5729, 5728], [5729, 5730], [5731, 5732], [5740, 5741], [5740, 5742], [5761, 5762], [5779, 5780], [5779, 5802], [5780, 5781], [5790, 5791], [5790, 5800], [5792, 5793], [5792, 5796], [5810, 5811], [5810, 5833], [5811, 5812], [5821, 5822], [5821, 5831], [5825, 5826], [5837, 5838], [5837, 5854], [5838, 5837], [5838, 5839], [5839, 5837], [5839, 5840], [5840, 5842], [5846, 5837], [5846, 5847], [5848, 5849], [5849, 5850], [5859, 5863], [5863, 5864], [5863, 5875], [5870, 5871], [5870, 5873], [5878, 5882], [5882, 5888], [5888, 5907], [5912, 5913], [5912, 5914], [5923, 5927], [5927, 5928], [5927, 5954], [5928, 5931], [5934, 5938], [5938, 5942], [5942, 5927], [5942, 5943], [5943, 5942], [5943, 5944], [5945, 5946], [5945, 5947], [5947, 5948], [5947, 5950], [5958, 5959], [5958, 5960], [5978, 5983], [5984, 5989], [5991, 5992], [5991, 6003], [5993, 6003], [6011, 6012], [6011, 6013], [6045, 6046], [6045, 6047], [6080, 6081], [6080, 6084], [6085, 6086], [6085, 6087], [6087, 6088], [6087, 6090], [6098, 6099], [6098, 6106], [6102, 6103], [6102, 6106], [6108, 6109], [6108, 6114], [6109, 6110], [6109, 6112], [6116, 6117], [6116, 6124], [6120, 6121], [6120, 6124], [6126, 6131], [6137, 6138], [6137, 6139], [6161, 6162], [6161, 6163], [6178, 6179], [6178, 6180], [6197, 6201], [6201, 6205], [6212, 6214], [6221, 6222], [6221, 6223], [6230, 6231], [6230, 6232], [6235, 6236], [6235, 6237], [6251, 6256], [6259, 6260], [6259, 6275], [6260, 6261], [6261, 6264], [6266, 6267], [6266, 6269], [6270, 6273], [6279, 6280], [6279, 6281], [6298, 6299], [6298, 6303], [6299, 6300], [6301, 6302], [6313, 6316], [6316, 6318], [6318, 6319], [6318, 6322], [6323, 6324], [6323, 6326], [6324, 6323], [6331, 6332], [6332, 6333], [6332, 6337], [6337, 6341], [6342, 6343], [6348, 6349], [6348, 6350], [6381, 6385], [6385, 6387], [6387, 6390], [6394, 6395], [6394, 6397], [6400, 6401], [6400, 6406], [6406, 6407], [6411, 6412], [6411, 6413], [6428, 6432], [6433, 6438], [6438, -6438], [6438, 6439], [6439, 6440], [6439, 6445], [6440, 6441], [6441, -6441], [6441, 6441], [6441, 6447], [6447, 6448], [6447, 6502], [6448, 6449], [6448, 6451], [6454, 6458], [6460, 6461], [6460, 6499], [6468, 6469], [6468, 6471], [6473, 6474], [6473, 6476], [6476, 6480], [6483, 6484], [6483, 6486], [6491, 6460], [6491, 6492], [6499, 6447], [6499, 6500], [6533, 6537], [6552, 6556], [6564, 6565], [6564, 6566], [6583, 6587], [6592, 6596], [6597, 6598], [6597, 6627], [6603, 6604], [6603, 6607], [6609, 6613], [6613, 6616], [6619, 6620], [6630, 6631], [6630, 6632], [6646, 6649], [6652, 6653], [6657, 6658], [6657, 6659], [6672, 6676], [6679, 6680], [6679, 6685], [6681, 6683], [6683, 6679], [6683, 6684], [6689, 6690], [6689, 6691], [6704, 6708], [6711, 6712], [6711, 6717], [6713, 6715], [6715, 6711], [6715, 6716], [6721, 6722], [6721, 6723], [6737, 6740], [6741, 6742], [6741, 6743], [6742, -6742], [6742, 6741], [6742, 6742], [6743, -6743], [6743, 6743], [6743, 6744], [6744, 6745], [6744, 6749], [6745, 6746], [6745, 6748], [6749, 6751], [6751, 6752], [6756, 6757], [6756, 6758], [6774, 6775], [6774, 6783], [6777, 6778], [6780, 6783], [6789, 6790], [6789, 6845], [6791, 6794], [6796, 6801], [6803, 6804], [6803, 6806], [6809, 6810], [6809, 6814], [6816, 6817], [6816, 6821], [6822, 6823], [6822, 6825], [6828, 6829], [6828, 6834], [6838, -6838], [6838, 6838], [6838, 6839], [6838, 6843], [6845, 6846], [6850, 6851], [6850, 6852], [6868, 6869], [6868, 6870], [6880, 6885], [6893, 6897], [6901, -6901], [6901, 6901], [6901, 6903], [6903, 6904], [6906, 6907], [6906, 6913], [6917, 6918], [6917, 6919], [6929, 6934], [6934, 6939], [6945, 6946], [6945, 6949], [6950, 6951], [6950, 6955], [6958, 6959], [6958, 6960], [6981, 6982], [6981, 7002], [6985, 6986], [6985, 6988], [6988, 6989], [6988, 6994], [6989, 6990], [6990, 6991], [6991, 6992], [6992, 6981], [6994, 6999], [6999, -6999], [6999, 6999], [6999, 7000], [7006, -7006], [7006, 7006], [7006, 7008], [7008, 7009], [7008, 7020], [7012, 7013], [7012, 7018], [7013, 7014], [7013, 7016], [7023, 7024], [7023, 7025], [7040, 7044], [7045, 7048], [7071, 7072], [7071, 7074], [7080, 7081], [7080, 7087], [7092, 7093], [7092, 7098], [7101, 7102], [7101, 7103], [7118, 7122], [7122, 7126], [7126, 7127], [7126, 7130], [7133, 7134], [7181, 7182], [7181, 7183], [7197, 7202], [7206, 7207], [7206, 7208], [7264, 7266], [7281, 7282], [7281, 7284], [7284, -7284], [7284, 7288], [7288, 7291], [7293, 7296], [7299, 7302], [7302, 7303], [7302, 7321], [7303, 7304], [7303, 7306], [7308, 7311], [7311, 7313], [7323, 7324], [7323, 7326], [7326, 7328], [7332, 7335], [7339, 7340], [7339, 7343], [7359, 7360], [7433, 7437], [7445, -7445], [7445, -7444], [7445, 7445], [7455, -7455], [7455, 7455], [7455, 7457], [7465, 7466], [7465, 7515], [7471, 7472], [7471, 7474], [7477, 7478], [7477, 7480], [7480, 7481], [7480, 7498], [7483, 7492], [7492, 7494], [7494, 7495], [7494, 7500], [7502, 7465], [7502, 7503], [7508, 7513], [7519, 7520], [7639, -7639], [7639, -7637], [7648, 7651], [7648, 7655], [7652, 7653], [7652, 7655], [7652, 7658], [7653, -7653], [7653, 7652], [7653, 7653], [7660, -7660], [7660, 7660], [7660, 7661], [7665, 7666], [7665, 7667], [7672, 7673], [7672, 7695], [7673, 7676], [7678, 7679], [7678, 7681], [7681, 7682], [7681, 7690], [7684, 7685], [7686, 7687], [7686, 7688], [7690, 7672], [7690, 7691], [7700, 7701], [7702, 7703], [7702, 7724], [7703, 7704], [7703, 7722], [7705, 7703], [7705, 7706], [7707, 7715], [7715, 7716], [7720, 7721], [7724, 7725], [7724, 7728], [7725, -7725], [7725, -7697], [7725, 7725], [7734, 7738], [7738, 7742], [7745, 7749], [7753, 7754], [7753, 7791], [7755, 7758], [7762, 7763], [7762, 7769], [7764, -7764], [7764, 7764], [7764, 7767], [7777, 7781], [7788, 7753], [7797, 7800], [7800, 7801], [7802, 7803], [7802, 7804], [7804, 7806], [7806, 7808], [7808, 7809], [7808, 7810], [7810, 7800], [7819, 7822], [7822, 7825], [7825, 7829], [7832, 7833], [7832, 7859], [7834, 7835], [7834, 7836], [7836, 7838], [7838, 7839], [7845, 7846], [7845, 7851], [7847, 7851], [7864, 7865], [7864, 7867], [7868, 7869], [7868, 7873], [7869, 7870], [7870, 7868], [7876, -7875], [7876, 7877], [7879, 7882], [7886, 7887], [7886, 7891], [7898, 7899], [7898, 7900], [7914, 7915], [7914, 7916], [7928, 7932], [7936, 7937], [7936, 7943], [7938, 7948], [7943, 7945], [7945, 7946], [7953, 7954], [7953, 7955], [7967, 7971], [7973, 7974], [7980, 7981], [7980, 7982], [7993, 7994], [7993, 7995], [8001, 8002], [8011, 8012], [8011, 8013], [8030, 8034], [8039, 8040], [8039, 8045], [8048, 8049], [8048, 8051], [8074, 8075], [8074, 8086], [8080, 8082], [8089, 8090], [8089, 8091], [8103, 8104], [8103, 8105], [8117, 8118], [8117, 8119], [8131, 8132], [8131, 8133], [8145, 8146], [8145, 8147], [8168, 8172], [8172, 8176], [8180, 8181], [8180, 8189], [8181, 8182], [8181, 8189], [8190, 8191], [8190, 8195], [8198, 8199], [8198, 8200], [8212, 8213], [8212, 8214], [8226, 8227], [8226, 8228], [8240, 8241], [8240, 8242], [8254, 8255], [8254, 8256], [8265, 8269], [8284, 8287], [8294, 8295], [8294, 8342], [8295, 8296], [8295, 8298], [8305, 8307], [8305, 8310], [8311, 8312], [8311, 8317], [8317, 8318], [8318, 8319], [8318, 8324], [8324, 8325], [8325, 8326], [8325, 8338], [8327, 8328], [8327, 8329], [8329, 8330], [8329, 8332], [8345, 8346], [8345, 8347], [8379, 8380], [8379, 8384], [8381, 8379], [8381, 8382], [8384, 8385], [8384, 8388], [8403, 8404], [8403, 8407], [8407, 8411], [8411, 8420], [8421, 8422], [8421, 8425], [8431, 8432], [8431, 8434], [8437, 8438], [8437, 8439], [8448, 8449], [8448, 8463], [8451, 8454], [8455, 8456], [8455, 8458], [8463, 8464], [8464, 8465], [8479, 8480], [8479, 8481], [8492, 8493], [8492, 8494], [8504, 8508], [8508, 8509], [8516, 8517], [8516, 8526], [8517, 8518], [8517, 8520], [8520, 8521], [8520, 8522], [8522, 8516], [8530, 8531], [8530, 8532], [8532, 8534], [8534, 8535], [8534, 8537], [8542, 8545], [8572, 8573], [8572, 8574], [8592, 8593], [8592, 8606], [8593, 8599], [8609, 8610], [8609, 8611], [8623, 8624], [8623, 8628], [8628, 8629], [8628, 8636], [8640, 8644], [8647, 8648], [8655, 8660], [8661, 8668], [8671, 8672], [8671, 8673], [8688, 8689], [8688, 8690], [8699, 8703], [8717, 8718], [8717, 8719], [8728, 8732], [8742, 8743], [8742, 8744], [8760, 8764], [8764, 8767], [8782, 8783], [8782, 8785], [8790, 8791], [8790, 8794], [8810, 8811], [8814, 8815], [8814, 8817], [8832, 8833], [8832, 8834], [8851, 8852], [8851, 8853], [8873, 8874], [8873, 8875], [8891, 8895], [8897, 8900], [8908, 8909], [8908, 8919], [8911, 8913], [8925, 8926], [8925, 8930], [8931, 8936], [8940, 8941], [8940, 8942], [8961, 8962], [8963, 8975], [8981, 8982], [8981, 8991], [8982, 8981], [8982, 8983], [8985, 8989], [8991, 8992], [8991, 8993], [8993, 8994], [9000, 9001], [9000, 9002], [9020, 9024], [9029, -9029], [9029, 9029], [9029, 9030], [9030, -9030], [9030, 9030], [9030, 9033], [9038, 9046], [9047, -9047], [9047, 9047], [9047, 9049], [9051, 9052], [9051, 9077], [9055, 9056], [9055, 9059], [9056, -9056], [9056, 9057], [9056, 9059], [9062, 9063], [9069, 9072], [9080, 9081], [9080, 9082], [9095, 9096], [9095, 9097], [9117, 9118], [9117, 9119], [9128, 9129], [9128, 9130], [9137, 9140], [9145, 9146], [9145, 9147], [9167, 9168], [9167, 9169], [9188, 9189], [9188, 9194], [9189, 9188], [9189, 9190], [9199, 9200], [9199, 9201], [9228, 9229], [9279, 9280], [9279, 9290], [9280, 9281], [9290, 9291], [9290, 9293], [9324, 9325], [9324, 9326], [9339, 9340], [9339, 9341], [9347, 9350], [9353, 9354], [9353, 9355], [9361, 9365], [9368, 9369], [9368, 9370], [9380, 9381], [9388, 9389], [9396, 9397], [9396, 9398], [9405, 9407], [9410, 9411], [9410, 9412], [9419, 9421], [9424, 9425], [9424, 9426], [9439, 9441], [9444, 9445], [9444, 9446], [9453, 9454], [9459, 9460], [9459, 9462], [9551, 9552], [9551, 9566], [9553, 9551], [9567, 9580], [9612, -9612], [9612, 9612], [9612, 9613], [9614, -9614], [9614, 9614], [9614, 9615], [9619, 9620], [9619, 9626], [9620, 9621], [9621, 9620], [9621, 9622], [9626, 9627], [9626, 9644], [9628, 9629], [9629, 9628], [9629, 9630], [9633, 9634], [9633, 9638], [9635, 9636], [9635, 9638], [9660, 9664], [9687, 9688], [9687, 9690], [9700, 9702], [9700, 9703], [9715, 9716], [9739, 9743], [9743, 9744], [9743, 9748], [9748, 9749], [9748, 9760], [9750, -9750], [9750, 9750], [9750, 9751], [9751, 9752], [9752, 9753], [9768, 9771], [9773, 9774], [9773, 9776], [9780, 9781], [9780, 9783], [9786, 9787], [9786, 9788], [9794, 9798], [9800, 9804], [9804, 9808], [9810, 9811], [9810, 9813], [9854, 9855], [9854, 9865], [9858, 9859], [9858, 9862], [9866, 9867], [9866, 9869], [9869, 9870], [9869, 9872], [9898, 9899], [9898, 9920], [9899, 9901], [9899, 9909], [9901, 9902], [9901, 9906], [9909, 9898], [9909, 9910], [9916, 9917], [9916, 9918], [9920, 9922], [9962, 9963], [9962, 9969], [9963, 9964], [10000, 10003], [10003, -10003], [10003, 10003], [10003, 10004], [10003, 10006], [10011, 10012], [10011, 10018], [10015, 10018], [10028, 10029], [10028, 10032], [10029, 10028], [10029, 10030], [10035, 10036], [10035, 10037], [10051, 10052], [10051, 10053], [10064, 10067], [10071, 10072], [10071, 10073], [10084, 10087], [10088, -10088], [10088, 10089], [10097, 10098], [10097, 10099], [10110, 10111], [10110, 10112], [10198, 10202], [10204, 10208], [10209, 10213], [10213, 10214], [10213, 10217], [10215, 10213], [10222, 10223], [10226, 10230], [10230, 10231], [10230, 10234], [10237, -10237], [10237, 10238], [10260, 10261], [10260, 10268], [10263, 10264], [10312, 10314], [10312, 10320], [10322, 10323], [10322, 10324], [10329, -10329], [10329, 10329], [10329, 10330], [10329, 10331], [10335, -10333], [10335, 10336], [10335, 10337], [10342, 10347], [10355, 10356], [10355, 10358], [10358, -10352], [10358, 10359], [10358, 10380], [10359, 10358], [10359, 10360], [10363, 10364], [10363, 10367], [10386, 10387], [10386, 10409], [10387, 10390], [10391, -10391], [10391, 10391], [10391, 10392], [10392, -10392], [10392, 10392], [10392, 10393], [10392, 10405], [10405, 10407], [10447, 10448], [10447, 10457], [10471, 10486], [10541, 10544], [10553, 10555], [10559, 10560], [10559, 10570], [10567, 10569], [10586, 10592], [10603, -10603], [10603, 10604], [10617, 10618], [10617, 10628], [10618, 10619], [10618, 10628], [10619, 10621], [10621, 10622], [10625, 10627], [10647, 10649], [10647, 10654], [10650, 10651], [10654, 10655], [10655, 10656], [10656, 10657], [10678, 10680], [10681, 10682], [10681, 10684], [10682, 10683], [10682, 10684], [10703, 10704], [10703, 10705], [10723, 10724], [10723, 10725], [10725, -10721], [10725, 10727], [10727, 10728], [10727, 10742], [10730, 10733], [10733, 10734], [10733, 10741], [10736, 10738], [10747, -10744], [10747, 10748], [10747, 10749], [10754, -10751], [10754, 10755], [10754, 10759], [10756, 10757], [10756, 10758], [10764, -10761], [10764, 10765], [10764, 10766], [10767, 10768], [10767, 10769], [10773, -10771], [10773, 10774], [10773, 10775], [10781, 10782], [10781, 10783], [10805, 10806], [10805, 10807], [10816, 10817], [10816, 10818], [10818, 10819], [10818, 10823], [10819, 10820], [10819, 10822], [10828, 10829], [10828, 10830], [10830, 10831], [10830, 10832], [10845, 10847], [10847, 10849], [10877, -10874], [10877, 10878], [10877, 10883], [10879, 10881], [10892, -10890], [10892, 10893], [10892, 10894], [10899, 10900], [10899, 10901], [10902, 10904], [10920, 10921], [10920, 10926], [10924, 10920], [10935, 10936], [10935, 10939], [10963, 10964], [10964, 10965], [10964, 10968], [10969, 10970], [10970, 10971], [10970, 10974], [10975, 10976], [10976, 10977], [10976, 10980], [10985, 10990], [10990, 10991], [10990, 10997], [10992, 10990], [10998, 11003], [11007, 11009], [11009, 11010], [11009, 11012], [11012, 11013], [11012, 11016], [11014, 11016], [11042, 11044], [11044, 11045], [11044, 11046], [11052, 11053], [11054, 11056], [11056, 11052], [11056, 11057], [11058, 11059], [11058, 11062], [11063, 11064], [11064, -11064], [11064, -11048], [11064, 11064], [11114, 11115], [11114, 11116], [11119, 11120], [11120, 11125], [11125, 11131], [11147, 11153], [11165, 11166], [11165, 11172], [11191, 11193], [11204, -52]], "missing_branches": [[109, 110], [109, 112], [112, -104], [112, 113], [124, 125], [124, 126], [185, 186], [193, 194], [214, 215], [215, 216], [215, 217], [222, 227], [236, 237], [259, 260], [260, 262], [260, 264], [264, 266], [264, 271], [276, 278], [388, 391], [405, 406], [407, 411], [408, 410], [435, 437], [472, 474], [474, 475], [474, 477], [488, 490], [539, -538], [541, -540], [545, -544], [549, -548], [551, -550], [553, -552], [558, -555], [585, 586], [679, 680], [679, 681], [729, 730], [819, 822], [824, 825], [832, 834], [838, 839], [855, 858], [907, 930], [922, 925], [1017, 1018], [1022, 1027], [1122, 1123], [1126, 1132], [1141, 1145], [1173, 1174], [1176, 1177], [1220, 1225], [1225, 1230], [1248, 1250], [1273, 1285], [1280, 1283], [1309, 1315], [1324, 1329], [1460, 1461], [1464, 1465], [1469, 1470], [1473, 1474], [1483, 1484], [1496, 1497], [1496, 1502], [1497, 1498], [1497, 1499], [1588, -1584], [1589, -1584], [1606, 1607], [1609, 1610], [1614, 1615], [1618, 1619], [1644, 1645], [1667, 1670], [1698, 1699], [1708, 1709], [1715, 1716], [1715, 1717], [1722, 1723], [1748, 1750], [1775, 1776], [1787, 1788], [1787, 1789], [1801, 1802], [1870, 1872], [1895, 1899], [2043, 2044], [2051, 2074], [2059, 2060], [2067, 2068], [2071, 2051], [2115, 2121], [2135, 2136], [2135, 2139], [2140, 2141], [2140, 2143], [2160, 2161], [2165, 2166], [2169, 2176], [2171, 2173], [2234, 2233], [2265, 2266], [2349, 2350], [2351, 2352], [2351, 2354], [2361, 2363], [2363, 2364], [2363, 2366], [2419, 2420], [2419, 2421], [2421, 2423], [2421, 2424], [2424, 2425], [2424, 2426], [2434, 2435], [2434, 2436], [2436, 2437], [2436, 2439], [2447, 2448], [2447, 2450], [2448, 2449], [2448, 2455], [2450, 2451], [2450, 2454], [2451, 2452], [2451, 2455], [2460, 2462], [2460, 2465], [2465, 2467], [2465, 2470], [2474, 2475], [2474, 2478], [2480, 2481], [2480, 2483], [2481, 2482], [2481, 2498], [2483, 2484], [2483, 2486], [2484, 2485], [2484, 2498], [2486, 2487], [2486, 2489], [2487, 2488], [2487, 2498], [2489, 2490], [2489, 2492], [2490, 2491], [2490, 2498], [2492, 2493], [2492, 2496], [2493, 2494], [2493, 2498], [2502, 2503], [2502, 2504], [2504, 2505], [2504, 2506], [2540, 2541], [2540, 2542], [2546, 2547], [2546, 2548], [2572, 2573], [2572, 2574], [2574, 2575], [2574, 2576], [2576, 2577], [2576, 2578], [2582, 2583], [2582, 2585], [2594, -2594], [2594, 2595], [2598, 2599], [2598, 2622], [2599, 2600], [2599, 2622], [2600, 2601], [2600, 2602], [2602, 2603], [2602, 2605], [2605, 2606], [2605, 2608], [2608, 2609], [2608, 2610], [2610, 2611], [2610, 2622], [2611, 2612], [2611, 2622], [2612, 2613], [2612, 2614], [2614, 2615], [2614, 2616], [2616, 2617], [2616, 2618], [2618, 2619], [2618, 2620], [2620, 2621], [2620, 2622], [2626, 2628], [2626, 2635], [2628, 2629], [2628, 2631], [2631, 2632], [2631, 2634], [2635, 2636], [2635, 2637], [2694, 2695], [2694, 2696], [2709, 2710], [2709, 2711], [2711, 2712], [2711, 2713], [2713, 2714], [2713, 2715], [2752, 2753], [2752, 2774], [2755, 2756], [2755, 2758], [2756, 2757], [2756, 2774], [2758, 2759], [2758, 2761], [2759, 2760], [2759, 2774], [2761, 2764], [2761, 2767], [2765, 2766], [2765, 2774], [2767, 2770], [2767, 2774], [2771, 2772], [2771, 2774], [2774, 2775], [2774, 2776], [2813, 2815], [2838, -2838], [2838, 2839], [2843, 2844], [2843, 2845], [2845, 2846], [2845, 2847], [2847, 2848], [2847, 2849], [2849, 2850], [2849, 2851], [2851, 2852], [2851, 2854], [2854, 2855], [2854, 2856], [2856, 2857], [2856, 2858], [2858, 2859], [2858, 2860], [2860, 2861], [2860, 2862], [2862, 2863], [2862, 2864], [2864, 2865], [2864, 2866], [2866, 2867], [2866, 2868], [2868, 2869], [2868, 2870], [2870, 2871], [2870, 2872], [2872, 2873], [2872, 2874], [2874, 2875], [2874, 2876], [2876, 2877], [2876, 2878], [2882, 2884], [2884, 2887], [2906, 2907], [2906, 2908], [2996, 2997], [2996, 2999], [3014, -3014], [3014, 3015], [3017, 3018], [3017, 3023], [3018, 3019], [3018, 3023], [3019, 3020], [3019, 3023], [3020, 3021], [3020, 3023], [3021, 3022], [3021, 3023], [3027, 3028], [3027, 3029], [3029, 3030], [3029, 3031], [3099, 3100], [3099, 3101], [3120, -3120], [3120, 3121], [3124, 3125], [3124, 3140], [3125, 3126], [3125, 3140], [3126, 3127], [3126, 3140], [3127, 3128], [3127, 3140], [3128, 3129], [3128, 3140], [3129, 3130], [3129, 3140], [3130, 3131], [3130, 3140], [3131, 3132], [3131, 3140], [3132, 3133], [3132, 3140], [3133, 3134], [3133, 3140], [3134, 3135], [3134, 3140], [3135, 3136], [3135, 3140], [3136, 3137], [3136, 3140], [3137, 3138], [3137, 3140], [3138, 3139], [3138, 3140], [3144, 3145], [3144, 3146], [3146, 3147], [3146, 3148], [3256, 3257], [3256, 3258], [3258, 3259], [3258, 3260], [3260, 3261], [3260, 3262], [3262, 3263], [3262, 3264], [3264, 3265], [3264, 3266], [3266, 3267], [3266, 3268], [3268, 3269], [3268, 3270], [3270, 3271], [3270, 3272], [3276, 3277], [3276, 3278], [3278, 3279], [3278, 3280], [3312, 3313], [3312, 3315], [3315, 3316], [3315, 3319], [3321, 3322], [3321, 3325], [3329, -3328], [3330, 3331], [3335, -3334], [3336, 3337], [3341, -3340], [3341, 3342], [3342, -3340], [3342, 3343], [3347, -3346], [3347, 3348], [3348, -3346], [3348, 3349], [3359, 3360], [3359, 3362], [3360, 3359], [3360, 3361], [3380, 3381], [3380, 3382], [3398, 3400], [3418, 3419], [3441, 3442], [3445, 3449], [3446, 3447], [3460, 3461], [3464, 3468], [3475, 3478], [3533, 3536], [3546, 3552], [3550, 3551], [3573, 3576], [3577, 3578], [3577, 3580], [3580, 3581], [3580, 3585], [3581, 3580], [3581, 3582], [3582, 3583], [3582, 3584], [3602, 3605], [3605, 3606], [3605, 3619], [3611, 3612], [3611, 3617], [3673, 3674], [3683, 3684], [3713, 3714], [3713, 3716], [3727, 3733], [3734, 3735], [3734, 3739], [3747, 3748], [3758, 3759], [3766, 3767], [3863, 3867], [3880, 3881], [3880, 3882], [3883, 3884], [3883, 3885], [4042, 4045], [4049, 4050], [4058, 4059], [4067, 4068], [4067, 4070], [4093, 4094], [4096, 4106], [4118, 4120], [4175, 4178], [4185, 4186], [4187, 4188], [4187, 4195], [4189, 4190], [4189, 4192], [4195, 4196], [4197, 4198], [4197, 4205], [4199, 4200], [4199, 4203], [4207, 4229], [4215, 4216], [4217, 4211], [4217, 4219], [4259, 4262], [4264, 4269], [4281, 4282], [4281, 4285], [4308, 4309], [4309, 4310], [4309, 4315], [4317, 4318], [4318, 4319], [4318, 4324], [4334, 4335], [4334, 4340], [4346, 4349], [4382, 4383], [4382, 4387], [4481, 4488], [4501, 4502], [4510, 4512], [4531, 4534], [4592, 4593], [4594, 4596], [4633, 4638], [4691, 4692], [4719, 4720], [4724, 4725], [4727, 4730], [4732, 4733], [4733, 4734], [4733, 4736], [4754, 4756], [4769, 4770], [4777, 4778], [4779, -4779], [4779, 4780], [4780, 4781], [4780, 4782], [4828, 4830], [4844, 4845], [4861, 4862], [4865, 4866], [4869, 4870], [4910, -4910], [4910, 4912], [4912, 4913], [4912, 4914], [4934, -4934], [4934, 4936], [4936, 4937], [4936, 4938], [4957, 4959], [4990, 4993], [5020, 5021], [5025, 5026], [5076, -5076], [5076, -5073], [5101, 5105], [5105, -5098], [5105, 5106], [5117, 5118], [5123, 5121], [5133, 5134], [5166, 5170], [5171, 5172], [5171, 5173], [5172, -5172], [5172, 5171], [5173, 5174], [5173, 5176], [5174, -5174], [5174, 5173], [5176, 5177], [5176, 5187], [5177, 5176], [5177, 5178], [5180, 5177], [5180, 5181], [5252, 5253], [5283, 5284], [5309, 5313], [5319, 5320], [5323, 5324], [5329, 5304], [5336, 5337], [5338, 5339], [5338, 5348], [5339, 5338], [5339, 5340], [5340, 5341], [5340, 5342], [5343, 5338], [5343, 5344], [5344, -5335], [5344, 5345], [5386, 5387], [5398, 5396], [5399, 5396], [5406, 5407], [5406, 5409], [5407, 5406], [5407, 5408], [5434, 5435], [5434, 5437], [5435, 5434], [5435, 5436], [5540, 5541], [5568, 5569], [5568, 5572], [5578, 5579], [5578, 5581], [5596, 5597], [5596, 5598], [5612, 5613], [5612, 5616], [5616, 5617], [5616, 5620], [5623, 5624], [5623, 5655], [5635, -5635], [5635, 5636], [5649, 5650], [5649, 5653], [5684, 5685], [5697, 5698], [5703, 5704], [5707, 5708], [5731, 5735], [5761, 5764], [5780, 5783], [5811, 5814], [5825, 5827], [5840, 5837], [5848, 5853], [5849, 5853], [5859, 5860], [5878, 5879], [5879, 5880], [5879, 5882], [5882, 5883], [5883, 5884], [5883, 5886], [5884, -5884], [5884, 5888], [5886, -5886], [5886, 5888], [5888, 5889], [5891, 5892], [5891, 5901], [5895, 5896], [5895, 5898], [5898, 5899], [5898, 5909], [5902, 5903], [5902, 5905], [5923, 5924], [5928, 5929], [5934, 5935], [5938, 5939], [5978, 5979], [5984, 5985], [5993, 5994], [6126, 6127], [6197, 6198], [6201, 6202], [6212, 6217], [6251, 6252], [6260, 6276], [6261, 6262], [6270, 6271], [6299, 6303], [6301, 6299], [6313, 6314], [6316, 6317], [6324, 6325], [6331, 6345], [6337, 6338], [6342, 6344], [6363, 6364], [6363, 6368], [6364, 6365], [6364, 6366], [6369, 6370], [6369, 6373], [6381, 6382], [6385, 6386], [6387, 6388], [6406, 6408], [6428, 6429], [6433, 6434], [6440, 6443], [6443, -6443], [6443, 6447], [6454, 6455], [6476, 6477], [6518, 6519], [6518, 6521], [6527, -6527], [6527, 6528], [6533, 6534], [6552, 6553], [6583, 6584], [6592, 6593], [6609, 6610], [6613, 6614], [6619, 6622], [6646, 6647], [6652, 6654], [6672, 6673], [6681, 6682], [6704, 6705], [6713, 6714], [6737, 6738], [6749, 6750], [6751, 6753], [6777, 6779], [6780, 6781], [6791, 6792], [6796, 6797], [6845, 6847], [6880, 6881], [6893, 6894], [6903, 6914], [6929, 6930], [6934, 6935], [6989, 6981], [6990, 6981], [6991, 6981], [6992, 6994], [6994, 6995], [7040, 7041], [7045, 7046], [7118, 7119], [7122, 7123], [7133, 7149], [7142, 7144], [7142, 7146], [7149, 7150], [7149, 7153], [7155, 7156], [7155, 7160], [7177, -7177], [7177, 7178], [7197, 7198], [7264, 7265], [7284, 7285], [7288, 7289], [7293, 7294], [7299, 7300], [7308, 7309], [7309, 7310], [7309, 7311], [7311, 7312], [7314, 7316], [7314, 7317], [7326, 7327], [7332, 7333], [7359, 7365], [7374, 7375], [7374, 7419], [7375, 7376], [7375, 7378], [7380, 7381], [7380, 7383], [7386, 7389], [7386, 7392], [7401, 7402], [7401, 7404], [7405, 7406], [7405, 7408], [7409, 7410], [7409, 7412], [7414, 7415], [7414, 7417], [7419, 7420], [7419, 7422], [7433, 7434], [7483, 7484], [7485, 7486], [7485, 7490], [7492, 7493], [7508, 7509], [7508, 7511], [7519, 7522], [7529, 7530], [7529, 7531], [7531, 7532], [7531, 7535], [7536, 7538], [7536, 7541], [7544, 7545], [7544, 7548], [7548, 7549], [7548, 7552], [7559, 7560], [7559, 7566], [7568, 7569], [7568, 7572], [7590, 7591], [7590, 7593], [7596, 7597], [7596, 7619], [7597, 7598], [7597, 7600], [7600, 7601], [7600, 7604], [7601, 7596], [7601, 7602], [7605, 7606], [7605, 7608], [7608, 7596], [7608, 7610], [7615, 7596], [7615, 7616], [7616, 7615], [7616, 7617], [7619, 7620], [7619, 7622], [7622, -7622], [7622, 7624], [7625, 7626], [7625, 7630], [7632, 7633], [7632, 7634], [7648, 7649], [7673, 7674], [7684, 7688], [7700, -7697], [7707, 7708], [7710, 7711], [7710, 7713], [7715, 7718], [7720, 7703], [7734, 7735], [7738, 7739], [7745, 7746], [7755, 7756], [7777, 7778], [7788, 7789], [7797, 7798], [7800, 7813], [7804, 7805], [7806, 7807], [7810, 7811], [7819, 7820], [7822, 7823], [7825, 7826], [7836, 7837], [7838, 7854], [7847, 7848], [7854, 7855], [7854, 7856], [7869, 7868], [7870, 7871], [7871, 7868], [7871, 7872], [7879, 7880], [7928, 7929], [7938, 7939], [7943, 7944], [7945, 7948], [7967, 7968], [7973, 7976], [8001, 8005], [8006, 8007], [8006, 8008], [8030, 8031], [8080, 8081], [8081, -8081], [8081, 8082], [8168, 8169], [8172, 8173], [8265, 8266], [8284, 8285], [8317, 8338], [8324, 8338], [8407, 8408], [8411, 8412], [8413, 8414], [8413, 8417], [8451, 8452], [8463, 8475], [8464, 8468], [8468, 8469], [8468, 8473], [8504, 8505], [8508, 8511], [8522, 8523], [8524, 8516], [8524, 8525], [8532, 8533], [8542, 8543], [8593, 8594], [8594, 8595], [8594, 8596], [8596, 8597], [8596, 8599], [8640, 8641], [8647, 8655], [8655, 8656], [8661, 8662], [8664, 8665], [8664, 8666], [8699, 8700], [8728, 8729], [8760, 8761], [8764, 8765], [8810, 8829], [8891, 8892], [8897, 8898], [8911, 8912], [8931, 8932], [8961, 8966], [8963, 8964], [8966, 8967], [8966, 8972], [8968, 8969], [8968, 8975], [8985, 8986], [8993, 8996], [9020, 9021], [9038, 9039], [9042, 9043], [9042, 9046], [9062, 9066], [9069, 9070], [9103, 9104], [9103, 9107], [9108, 9109], [9108, 9111], [9137, 9138], [9160, 9161], [9160, 9163], [9228, 9232], [9232, 9233], [9232, 9234], [9260, 9261], [9260, 9265], [9262, 9263], [9262, 9267], [9267, 9268], [9267, 9272], [9269, 9270], [9269, 9273], [9280, 9288], [9347, 9348], [9361, 9362], [9363, 9364], [9363, 9365], [9380, 9382], [9388, 9393], [9405, 9406], [9419, 9420], [9439, 9440], [9453, 9455], [9553, 9554], [9555, 9551], [9555, 9556], [9557, 9551], [9557, 9558], [9558, 9559], [9558, 9562], [9559, 9557], [9559, 9560], [9562, 9557], [9562, 9563], [9563, 9557], [9563, 9564], [9567, 9568], [9574, 9575], [9574, 9580], [9594, 9595], [9594, 9599], [9595, 9594], [9595, 9596], [9620, 9619], [9628, 9626], [9660, 9661], [9715, 9717], [9739, 9740], [9751, 9758], [9752, 9756], [9768, 9769], [9794, 9795], [9800, 9801], [9804, 9805], [9826, 9828], [9826, 9830], [9828, -9828], [9828, -9823], [9830, 9832], [9830, 9835], [9832, -9832], [9832, -9823], [9835, -9835], [9835, -9823], [9889, 9890], [9889, 9892], [9920, 9921], [9940, 9941], [9940, 9944], [9944, 9945], [9944, 9946], [9963, 9967], [9985, 9986], [9985, 9989], [10000, 10001], [10015, 10016], [10064, 10065], [10084, 10085], [10127, 10128], [10127, 10131], [10132, 10133], [10132, 10136], [10146, -10146], [10146, 10148], [10165, 10166], [10165, 10172], [10175, 10176], [10175, 10177], [10198, 10199], [10204, 10205], [10209, 10210], [10215, 10216], [10222, 10234], [10226, 10227], [10248, -10246], [10248, 10249], [10249, -10246], [10249, 10250], [10251, 10252], [10251, 10253], [10263, 10265], [10342, 10343], [10387, 10388], [10405, 10406], [10413, -10411], [10413, 10414], [10414, 10415], [10414, 10416], [10419, -10419], [10419, 10423], [10471, 10472], [10475, 10476], [10475, 10486], [10480, 10481], [10480, 10486], [10492, 10493], [10492, 10515], [10498, 10499], [10498, 10500], [10500, 10501], [10500, 10502], [10502, 10503], [10502, 10505], [10508, 10509], [10508, 10515], [10515, 10516], [10515, 10533], [10520, -10520], [10520, 10521], [10524, 10525], [10524, 10528], [10525, 10524], [10525, 10526], [10534, 10535], [10534, 10536], [10541, 10543], [10553, 10554], [10567, 10568], [10574, 10575], [10574, 10576], [10586, 10589], [10619, 10620], [10621, 10624], [10625, 10626], [10650, -10645], [10654, -10645], [10655, -10645], [10656, -10645], [10678, 10679], [10725, 10726], [10730, 10731], [10736, 10737], [10845, 10846], [10847, 10848], [10879, 10880], [10902, 10903], [10924, 10925], [10963, 10968], [10969, 10974], [10975, 10980], [10985, 10986], [10992, 10993], [10998, 10999], [10999, 11000], [10999, 11003], [11007, 11008], [11014, 11015], [11042, 11043], [11052, 11065], [11054, 11055], [11055, -11055], [11055, -11048], [11063, 11052], [11119, -52], [11120, 11121], [11125, 11126], [11147, 11148], [11191, 11195], [11204, 11205]]}}, "totals": {"covered_lines": 5745, "num_statements": 7572, "percent_covered": 71.5684335443038, "percent_covered_display": "72", "missing_lines": 1827, "excluded_lines": 0, "num_branches": 2540, "num_partial_branches": 418, "covered_branches": 1492, "missing_branches": 1048}} \ No newline at end of file diff --git a/coverage/coverage.xml b/coverage/coverage.xml new file mode 100644 index 000000000..fad2a1a72 --- /dev/null +++ b/coverage/coverage.xml @@ -0,0 +1,7591 @@ + + + + + + /home/runner/work/gef/gef + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coverage/coverage_html.js b/coverage/coverage_html.js new file mode 100644 index 000000000..4c321182c --- /dev/null +++ b/coverage/coverage_html.js @@ -0,0 +1,624 @@ +// Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 +// For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt + +// Coverage.py HTML report browser code. +/*jslint browser: true, sloppy: true, vars: true, plusplus: true, maxerr: 50, indent: 4 */ +/*global coverage: true, document, window, $ */ + +coverage = {}; + +// General helpers +function debounce(callback, wait) { + let timeoutId = null; + return function(...args) { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + callback.apply(this, args); + }, wait); + }; +}; + +function checkVisible(element) { + const rect = element.getBoundingClientRect(); + const viewBottom = Math.max(document.documentElement.clientHeight, window.innerHeight); + const viewTop = 30; + return !(rect.bottom < viewTop || rect.top >= viewBottom); +} + +function on_click(sel, fn) { + const elt = document.querySelector(sel); + if (elt) { + elt.addEventListener("click", fn); + } +} + +// Helpers for table sorting +function getCellValue(row, column = 0) { + const cell = row.cells[column] + if (cell.childElementCount == 1) { + const child = cell.firstElementChild + if (child instanceof HTMLTimeElement && child.dateTime) { + return child.dateTime + } else if (child instanceof HTMLDataElement && child.value) { + return child.value + } + } + return cell.innerText || cell.textContent; +} + +function rowComparator(rowA, rowB, column = 0) { + let valueA = getCellValue(rowA, column); + let valueB = getCellValue(rowB, column); + if (!isNaN(valueA) && !isNaN(valueB)) { + return valueA - valueB + } + return valueA.localeCompare(valueB, undefined, {numeric: true}); +} + +function sortColumn(th) { + // Get the current sorting direction of the selected header, + // clear state on other headers and then set the new sorting direction + const currentSortOrder = th.getAttribute("aria-sort"); + [...th.parentElement.cells].forEach(header => header.setAttribute("aria-sort", "none")); + if (currentSortOrder === "none") { + th.setAttribute("aria-sort", th.dataset.defaultSortOrder || "ascending"); + } else { + th.setAttribute("aria-sort", currentSortOrder === "ascending" ? "descending" : "ascending"); + } + + const column = [...th.parentElement.cells].indexOf(th) + + // Sort all rows and afterwards append them in order to move them in the DOM + Array.from(th.closest("table").querySelectorAll("tbody tr")) + .sort((rowA, rowB) => rowComparator(rowA, rowB, column) * (th.getAttribute("aria-sort") === "ascending" ? 1 : -1)) + .forEach(tr => tr.parentElement.appendChild(tr) ); +} + +// Find all the elements with data-shortcut attribute, and use them to assign a shortcut key. +coverage.assign_shortkeys = function () { + document.querySelectorAll("[data-shortcut]").forEach(element => { + document.addEventListener("keypress", event => { + if (event.target.tagName.toLowerCase() === "input") { + return; // ignore keypress from search filter + } + if (event.key === element.dataset.shortcut) { + element.click(); + } + }); + }); +}; + +// Create the events for the filter box. +coverage.wire_up_filter = function () { + // Cache elements. + const table = document.querySelector("table.index"); + const table_body_rows = table.querySelectorAll("tbody tr"); + const no_rows = document.getElementById("no_rows"); + + // Observe filter keyevents. + document.getElementById("filter").addEventListener("input", debounce(event => { + // Keep running total of each metric, first index contains number of shown rows + const totals = new Array(table.rows[0].cells.length).fill(0); + // Accumulate the percentage as fraction + totals[totals.length - 1] = { "numer": 0, "denom": 0 }; + + // Hide / show elements. + table_body_rows.forEach(row => { + if (!row.cells[0].textContent.includes(event.target.value)) { + // hide + row.classList.add("hidden"); + return; + } + + // show + row.classList.remove("hidden"); + totals[0]++; + + for (let column = 1; column < totals.length; column++) { + // Accumulate dynamic totals + cell = row.cells[column] + if (column === totals.length - 1) { + // Last column contains percentage + const [numer, denom] = cell.dataset.ratio.split(" "); + totals[column]["numer"] += parseInt(numer, 10); + totals[column]["denom"] += parseInt(denom, 10); + } else { + totals[column] += parseInt(cell.textContent, 10); + } + } + }); + + // Show placeholder if no rows will be displayed. + if (!totals[0]) { + // Show placeholder, hide table. + no_rows.style.display = "block"; + table.style.display = "none"; + return; + } + + // Hide placeholder, show table. + no_rows.style.display = null; + table.style.display = null; + + const footer = table.tFoot.rows[0]; + // Calculate new dynamic sum values based on visible rows. + for (let column = 1; column < totals.length; column++) { + // Get footer cell element. + const cell = footer.cells[column]; + + // Set value into dynamic footer cell element. + if (column === totals.length - 1) { + // Percentage column uses the numerator and denominator, + // and adapts to the number of decimal places. + const match = /\.([0-9]+)/.exec(cell.textContent); + const places = match ? match[1].length : 0; + const { numer, denom } = totals[column]; + cell.dataset.ratio = `${numer} ${denom}`; + // Check denom to prevent NaN if filtered files contain no statements + cell.textContent = denom + ? `${(numer * 100 / denom).toFixed(places)}%` + : `${(100).toFixed(places)}%`; + } else { + cell.textContent = totals[column]; + } + } + })); + + // Trigger change event on setup, to force filter on page refresh + // (filter value may still be present). + document.getElementById("filter").dispatchEvent(new Event("input")); +}; + +coverage.INDEX_SORT_STORAGE = "COVERAGE_INDEX_SORT_2"; + +// Loaded on index.html +coverage.index_ready = function () { + coverage.assign_shortkeys(); + coverage.wire_up_filter(); + document.querySelectorAll("[data-sortable] th[aria-sort]").forEach( + th => th.addEventListener("click", e => sortColumn(e.target)) + ); + + // Look for a localStorage item containing previous sort settings: + const stored_list = localStorage.getItem(coverage.INDEX_SORT_STORAGE); + + if (stored_list) { + const {column, direction} = JSON.parse(stored_list); + const th = document.querySelector("[data-sortable]").tHead.rows[0].cells[column]; + th.setAttribute("aria-sort", direction === "ascending" ? "descending" : "ascending"); + th.click() + } + + // Watch for page unload events so we can save the final sort settings: + window.addEventListener("unload", function () { + const th = document.querySelector('[data-sortable] th[aria-sort="ascending"], [data-sortable] [aria-sort="descending"]'); + if (!th) { + return; + } + localStorage.setItem(coverage.INDEX_SORT_STORAGE, JSON.stringify({ + column: [...th.parentElement.cells].indexOf(th), + direction: th.getAttribute("aria-sort"), + })); + }); + + on_click(".button_prev_file", coverage.to_prev_file); + on_click(".button_next_file", coverage.to_next_file); + + on_click(".button_show_hide_help", coverage.show_hide_help); +}; + +// -- pyfile stuff -- + +coverage.LINE_FILTERS_STORAGE = "COVERAGE_LINE_FILTERS"; + +coverage.pyfile_ready = function () { + // If we're directed to a particular line number, highlight the line. + var frag = location.hash; + if (frag.length > 2 && frag[1] === "t") { + document.querySelector(frag).closest(".n").classList.add("highlight"); + coverage.set_sel(parseInt(frag.substr(2), 10)); + } else { + coverage.set_sel(0); + } + + on_click(".button_toggle_run", coverage.toggle_lines); + on_click(".button_toggle_mis", coverage.toggle_lines); + on_click(".button_toggle_exc", coverage.toggle_lines); + on_click(".button_toggle_par", coverage.toggle_lines); + + on_click(".button_next_chunk", coverage.to_next_chunk_nicely); + on_click(".button_prev_chunk", coverage.to_prev_chunk_nicely); + on_click(".button_top_of_page", coverage.to_top); + on_click(".button_first_chunk", coverage.to_first_chunk); + + on_click(".button_prev_file", coverage.to_prev_file); + on_click(".button_next_file", coverage.to_next_file); + on_click(".button_to_index", coverage.to_index); + + on_click(".button_show_hide_help", coverage.show_hide_help); + + coverage.filters = undefined; + try { + coverage.filters = localStorage.getItem(coverage.LINE_FILTERS_STORAGE); + } catch(err) {} + + if (coverage.filters) { + coverage.filters = JSON.parse(coverage.filters); + } + else { + coverage.filters = {run: false, exc: true, mis: true, par: true}; + } + + for (cls in coverage.filters) { + coverage.set_line_visibilty(cls, coverage.filters[cls]); + } + + coverage.assign_shortkeys(); + coverage.init_scroll_markers(); + coverage.wire_up_sticky_header(); + + document.querySelectorAll("[id^=ctxs]").forEach( + cbox => cbox.addEventListener("click", coverage.expand_contexts) + ); + + // Rebuild scroll markers when the window height changes. + window.addEventListener("resize", coverage.build_scroll_markers); +}; + +coverage.toggle_lines = function (event) { + const btn = event.target.closest("button"); + const category = btn.value + const show = !btn.classList.contains("show_" + category); + coverage.set_line_visibilty(category, show); + coverage.build_scroll_markers(); + coverage.filters[category] = show; + try { + localStorage.setItem(coverage.LINE_FILTERS_STORAGE, JSON.stringify(coverage.filters)); + } catch(err) {} +}; + +coverage.set_line_visibilty = function (category, should_show) { + const cls = "show_" + category; + const btn = document.querySelector(".button_toggle_" + category); + if (btn) { + if (should_show) { + document.querySelectorAll("#source ." + category).forEach(e => e.classList.add(cls)); + btn.classList.add(cls); + } + else { + document.querySelectorAll("#source ." + category).forEach(e => e.classList.remove(cls)); + btn.classList.remove(cls); + } + } +}; + +// Return the nth line div. +coverage.line_elt = function (n) { + return document.getElementById("t" + n)?.closest("p"); +}; + +// Set the selection. b and e are line numbers. +coverage.set_sel = function (b, e) { + // The first line selected. + coverage.sel_begin = b; + // The next line not selected. + coverage.sel_end = (e === undefined) ? b+1 : e; +}; + +coverage.to_top = function () { + coverage.set_sel(0, 1); + coverage.scroll_window(0); +}; + +coverage.to_first_chunk = function () { + coverage.set_sel(0, 1); + coverage.to_next_chunk(); +}; + +coverage.to_prev_file = function () { + window.location = document.getElementById("prevFileLink").href; +} + +coverage.to_next_file = function () { + window.location = document.getElementById("nextFileLink").href; +} + +coverage.to_index = function () { + location.href = document.getElementById("indexLink").href; +} + +coverage.show_hide_help = function () { + const helpCheck = document.getElementById("help_panel_state") + helpCheck.checked = !helpCheck.checked; +} + +// Return a string indicating what kind of chunk this line belongs to, +// or null if not a chunk. +coverage.chunk_indicator = function (line_elt) { + const classes = line_elt?.className; + if (!classes) { + return null; + } + const match = classes.match(/\bshow_\w+\b/); + if (!match) { + return null; + } + return match[0]; +}; + +coverage.to_next_chunk = function () { + const c = coverage; + + // Find the start of the next colored chunk. + var probe = c.sel_end; + var chunk_indicator, probe_line; + while (true) { + probe_line = c.line_elt(probe); + if (!probe_line) { + return; + } + chunk_indicator = c.chunk_indicator(probe_line); + if (chunk_indicator) { + break; + } + probe++; + } + + // There's a next chunk, `probe` points to it. + var begin = probe; + + // Find the end of this chunk. + var next_indicator = chunk_indicator; + while (next_indicator === chunk_indicator) { + probe++; + probe_line = c.line_elt(probe); + next_indicator = c.chunk_indicator(probe_line); + } + c.set_sel(begin, probe); + c.show_selection(); +}; + +coverage.to_prev_chunk = function () { + const c = coverage; + + // Find the end of the prev colored chunk. + var probe = c.sel_begin-1; + var probe_line = c.line_elt(probe); + if (!probe_line) { + return; + } + var chunk_indicator = c.chunk_indicator(probe_line); + while (probe > 1 && !chunk_indicator) { + probe--; + probe_line = c.line_elt(probe); + if (!probe_line) { + return; + } + chunk_indicator = c.chunk_indicator(probe_line); + } + + // There's a prev chunk, `probe` points to its last line. + var end = probe+1; + + // Find the beginning of this chunk. + var prev_indicator = chunk_indicator; + while (prev_indicator === chunk_indicator) { + probe--; + if (probe <= 0) { + return; + } + probe_line = c.line_elt(probe); + prev_indicator = c.chunk_indicator(probe_line); + } + c.set_sel(probe+1, end); + c.show_selection(); +}; + +// Returns 0, 1, or 2: how many of the two ends of the selection are on +// the screen right now? +coverage.selection_ends_on_screen = function () { + if (coverage.sel_begin === 0) { + return 0; + } + + const begin = coverage.line_elt(coverage.sel_begin); + const end = coverage.line_elt(coverage.sel_end-1); + + return ( + (checkVisible(begin) ? 1 : 0) + + (checkVisible(end) ? 1 : 0) + ); +}; + +coverage.to_next_chunk_nicely = function () { + if (coverage.selection_ends_on_screen() === 0) { + // The selection is entirely off the screen: + // Set the top line on the screen as selection. + + // This will select the top-left of the viewport + // As this is most likely the span with the line number we take the parent + const line = document.elementFromPoint(0, 0).parentElement; + if (line.parentElement !== document.getElementById("source")) { + // The element is not a source line but the header or similar + coverage.select_line_or_chunk(1); + } else { + // We extract the line number from the id + coverage.select_line_or_chunk(parseInt(line.id.substring(1), 10)); + } + } + coverage.to_next_chunk(); +}; + +coverage.to_prev_chunk_nicely = function () { + if (coverage.selection_ends_on_screen() === 0) { + // The selection is entirely off the screen: + // Set the lowest line on the screen as selection. + + // This will select the bottom-left of the viewport + // As this is most likely the span with the line number we take the parent + const line = document.elementFromPoint(document.documentElement.clientHeight-1, 0).parentElement; + if (line.parentElement !== document.getElementById("source")) { + // The element is not a source line but the header or similar + coverage.select_line_or_chunk(coverage.lines_len); + } else { + // We extract the line number from the id + coverage.select_line_or_chunk(parseInt(line.id.substring(1), 10)); + } + } + coverage.to_prev_chunk(); +}; + +// Select line number lineno, or if it is in a colored chunk, select the +// entire chunk +coverage.select_line_or_chunk = function (lineno) { + var c = coverage; + var probe_line = c.line_elt(lineno); + if (!probe_line) { + return; + } + var the_indicator = c.chunk_indicator(probe_line); + if (the_indicator) { + // The line is in a highlighted chunk. + // Search backward for the first line. + var probe = lineno; + var indicator = the_indicator; + while (probe > 0 && indicator === the_indicator) { + probe--; + probe_line = c.line_elt(probe); + if (!probe_line) { + break; + } + indicator = c.chunk_indicator(probe_line); + } + var begin = probe + 1; + + // Search forward for the last line. + probe = lineno; + indicator = the_indicator; + while (indicator === the_indicator) { + probe++; + probe_line = c.line_elt(probe); + indicator = c.chunk_indicator(probe_line); + } + + coverage.set_sel(begin, probe); + } + else { + coverage.set_sel(lineno); + } +}; + +coverage.show_selection = function () { + // Highlight the lines in the chunk + document.querySelectorAll("#source .highlight").forEach(e => e.classList.remove("highlight")); + for (let probe = coverage.sel_begin; probe < coverage.sel_end; probe++) { + coverage.line_elt(probe).querySelector(".n").classList.add("highlight"); + } + + coverage.scroll_to_selection(); +}; + +coverage.scroll_to_selection = function () { + // Scroll the page if the chunk isn't fully visible. + if (coverage.selection_ends_on_screen() < 2) { + const element = coverage.line_elt(coverage.sel_begin); + coverage.scroll_window(element.offsetTop - 60); + } +}; + +coverage.scroll_window = function (to_pos) { + window.scroll({top: to_pos, behavior: "smooth"}); +}; + +coverage.init_scroll_markers = function () { + // Init some variables + coverage.lines_len = document.querySelectorAll("#source > p").length; + + // Build html + coverage.build_scroll_markers(); +}; + +coverage.build_scroll_markers = function () { + const temp_scroll_marker = document.getElementById("scroll_marker") + if (temp_scroll_marker) temp_scroll_marker.remove(); + // Don't build markers if the window has no scroll bar. + if (document.body.scrollHeight <= window.innerHeight) { + return; + } + + const marker_scale = window.innerHeight / document.body.scrollHeight; + const line_height = Math.min(Math.max(3, window.innerHeight / coverage.lines_len), 10); + + let previous_line = -99, last_mark, last_top; + + const scroll_marker = document.createElement("div"); + scroll_marker.id = "scroll_marker"; + document.getElementById("source").querySelectorAll( + "p.show_run, p.show_mis, p.show_exc, p.show_exc, p.show_par" + ).forEach(element => { + const line_top = Math.floor(element.offsetTop * marker_scale); + const line_number = parseInt(element.querySelector(".n a").id.substr(1)); + + if (line_number === previous_line + 1) { + // If this solid missed block just make previous mark higher. + last_mark.style.height = `${line_top + line_height - last_top}px`; + } else { + // Add colored line in scroll_marker block. + last_mark = document.createElement("div"); + last_mark.id = `m${line_number}`; + last_mark.classList.add("marker"); + last_mark.style.height = `${line_height}px`; + last_mark.style.top = `${line_top}px`; + scroll_marker.append(last_mark); + last_top = line_top; + } + + previous_line = line_number; + }); + + // Append last to prevent layout calculation + document.body.append(scroll_marker); +}; + +coverage.wire_up_sticky_header = function () { + const header = document.querySelector("header"); + const header_bottom = ( + header.querySelector(".content h2").getBoundingClientRect().top - + header.getBoundingClientRect().top + ); + + function updateHeader() { + if (window.scrollY > header_bottom) { + header.classList.add("sticky"); + } else { + header.classList.remove("sticky"); + } + } + + window.addEventListener("scroll", updateHeader); + updateHeader(); +}; + +coverage.expand_contexts = function (e) { + var ctxs = e.target.parentNode.querySelector(".ctxs"); + + if (!ctxs.classList.contains("expanded")) { + var ctxs_text = ctxs.textContent; + var width = Number(ctxs_text[0]); + ctxs.textContent = ""; + for (var i = 1; i < ctxs_text.length; i += width) { + key = ctxs_text.substring(i, i + width).trim(); + ctxs.appendChild(document.createTextNode(contexts[key])); + ctxs.appendChild(document.createElement("br")); + } + ctxs.classList.add("expanded"); + } +}; + +document.addEventListener("DOMContentLoaded", () => { + if (document.body.classList.contains("indexfile")) { + coverage.index_ready(); + } else { + coverage.pyfile_ready(); + } +}); diff --git a/coverage/favicon_32.png b/coverage/favicon_32.png new file mode 100644 index 0000000000000000000000000000000000000000..8649f0475d8d20793b2ec431fe25a186a414cf10 GIT binary patch literal 1732 zcmV;#20QtQP)K2KOkBOVxIZChq#W-v7@TU%U6P(wycKT1hUJUToW3ke1U1ONa4 z000000000000000bb)GRa9mqwR9|UWHy;^RUrt?IT__Y0JUcxmBP0(51q1>E00030 z|NrOz)aw7%8sJzM<5^g%z7^qE`}_Ot|JUUG(NUkWzR|7K?Zo%@_v-8G-1N%N=D$;; zw;keH4dGY$`1t4M=HK_s*zm^0#KgqfwWhe3qO_HtvXYvtjgX>;-~C$L`&k>^R)9)7 zdPh2TL^pCnHC#0+_4D)M`p?qp!pq{jO_{8;$fbaflbx`Tn52n|n}8VFRTA1&ugOP< zPd{uvFjz7t*Vot1&d$l-xWCk}s;sQL&#O(Bskh6gqNJv>#iB=ypG1e3K!K4yc7!~M zfj4S*g^zZ7eP$+_Sl07Z646l;%urinP#D8a6TwRtnLIRcI!r4f@bK~9-`~;E(N?Lv zSEst7s;rcxsi~}{Nsytfz@MtUoR*iFc8!#vvx}Umhm4blk(_~MdVD-@dW&>!Nn~ro z_E~-ESVQAj6Wmn;(olz(O&_{U2*pZBc1aYjMh>Dq3z|6`jW`RDHV=t3I6yRKJ~LOX zz_z!!vbVXPqob#=pj3^VMT?x6t(irRmSKsMo1~LLkB&=#j!=M%NP35mfqim$drWb9 zYIb>no_LUwc!r^NkDzs4YHu@=ZHRzrafWDZd1EhEVq=tGX?tK$pIa)DTh#bkvh!J- z?^%@YS!U*0E8$q$_*aOTQ&)Ra64g>ep;BdcQgvlg8qQHrP*E$;P{-m=A*@axn@$bO zO-Y4JzS&EAi%YG}N?cn?YFS7ivPY=EMV6~YH;+Xxu|tefLS|Aza)Cg6us#)=JW!uH zQa?H>d^j+YHCtyjL^LulF*05|F$RG!AX_OHVI&MtA~_@=5_lU|0000rbW%=J06GH4 z^5LD8b8apw8vNh1ua1mF{{Hy)_U`NA;Nacc+sCpuHXa-V{r&yz?c(9#+}oX+NmiRW z+W-IqK1oDDR5;6GfCDCOP5}iL5fK(cB~ET81`MFgF2kGa9AjhSIk~-E-4&*tPPKdiilQJ11k_J082ZS z>@TvivP!5ZFG?t@{t+GpR3XR&@*hA_VE1|Lo8@L@)l*h(Z@=?c-NS$Fk&&61IzUU9 z*nPqBM=OBZ-6ka1SJgGAS-Us5EN)r#dUX%>wQZLa2ytPCtMKp)Ob z*xcu38Z&d5<-NBS)@jRD+*!W*cf-m_wmxDEqBf?czI%3U0J$Xik;lA`jg}VH?(S(V zE!M3;X2B8w0TnnW&6(8;_Uc)WD;Ms6PKP+s(sFgO!}B!^ES~GDt4qLPxwYB)^7)XA zZwo9zDy-B0B+jT6V=!=bo(zs_8{eBA78gT9GH$(DVhz;4VAYwz+bOIdZ-PNb|I&rl z^XG=vFLF)1{&nT2*0vMz#}7^9hXzzf&ZdKlEj{LihP;|;Ywqn35ajP?H?7t|i-Un% z&&kxee@9B{nwgv1+S-~0)E1{ob1^Wn`F2isurqThKK=3%&;`@{0{!D- z&CSj80t;uPu&FaJFtSXKH#ajgGj}=sEad7US6jP0|Db@0j)?(5@sf<7`~a9>s;wCa zm^)spe{uxGFmrJYI9cOh7s$>8Npkt-5EWB1UKc`{W{y5Ce$1+nM9Cr;);=Ju#N^62OSlJMn7omiUgP&ErsYzT~iGxcW aE(`!K@+CXylaC4j0000 + + + + Coverage for gef.py: 71.5684% + + + + + +
+
+

+ Coverage for gef.py: + 71.5684% +

+ +

+ 7572 statements   + + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.2.7, + created at 2023-08-01 03:12 +0000 +

+ +
+
+
+

1####################################################################################### 

+

2# GEF - Multi-Architecture GDB Enhanced Features for Exploiters & Reverse-Engineers 

+

3# 

+

4# by @_hugsy_ 

+

5####################################################################################### 

+

6# 

+

7# GEF is a kick-ass set of commands for X86, ARM, MIPS, PowerPC and SPARC to 

+

8# make GDB cool again for exploit dev. It is aimed to be used mostly by exploit 

+

9# devs and reversers, to provides additional features to GDB using the Python 

+

10# API to assist during the process of dynamic analysis. 

+

11# 

+

12# GEF fully relies on GDB API and other Linux-specific sources of information 

+

13# (such as /proc/<pid>). As a consequence, some of the features might not work 

+

14# on custom or hardened systems such as GrSec. 

+

15# 

+

16# Since January 2020, GEF solely support GDB compiled with Python3 and was tested on 

+

17# * x86-32 & x86-64 

+

18# * arm v5,v6,v7 

+

19# * aarch64 (armv8) 

+

20# * mips & mips64 

+

21# * powerpc & powerpc64 

+

22# * sparc & sparc64(v9) 

+

23# 

+

24# For GEF with Python2 (only) support was moved to the GEF-Legacy 

+

25# (https://github.com/hugsy/gef-legacy) 

+

26# 

+

27# To start: in gdb, type `source /path/to/gef.py` 

+

28# 

+

29####################################################################################### 

+

30# 

+

31# gef is distributed under the MIT License (MIT) 

+

32# Copyright (c) 2013-2023 crazy rabbidz 

+

33# 

+

34# Permission is hereby granted, free of charge, to any person obtaining a copy 

+

35# of this software and associated documentation files (the "Software"), to deal 

+

36# in the Software without restriction, including without limitation the rights 

+

37# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 

+

38# copies of the Software, and to permit persons to whom the Software is 

+

39# furnished to do so, subject to the following conditions: 

+

40# 

+

41# The above copyright notice and this permission notice shall be included in all 

+

42# copies or substantial portions of the Software. 

+

43# 

+

44# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 

+

45# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 

+

46# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 

+

47# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 

+

48# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 

+

49# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 

+

50# SOFTWARE. 

+

51 

+

52import abc 

+

53import argparse 

+

54import ast 

+

55import atexit 

+

56import binascii 

+

57import codecs 

+

58import collections 

+

59import configparser 

+

60import ctypes 

+

61import enum 

+

62import functools 

+

63import hashlib 

+

64import importlib 

+

65import importlib.util 

+

66import inspect 

+

67import itertools 

+

68import os 

+

69import pathlib 

+

70import platform 

+

71import re 

+

72import shutil 

+

73import site 

+

74import socket 

+

75import string 

+

76import struct 

+

77import subprocess 

+

78import sys 

+

79import tempfile 

+

80import time 

+

81import traceback 

+

82import warnings 

+

83from functools import lru_cache 

+

84from io import StringIO, TextIOWrapper 

+

85from types import ModuleType 

+

86from typing import (Any, ByteString, Callable, Dict, Generator, Iterable, 

+

87 Iterator, List, NoReturn, Optional, Sequence, Set, Tuple, Type, 

+

88 Union) 

+

89from urllib.request import urlopen 

+

90 

+

91GEF_DEFAULT_BRANCH = "main" 

+

92GEF_EXTRAS_DEFAULT_BRANCH = "main" 

+

93 

+

94def http_get(url: str) -> Optional[bytes]: 

+

95 """Basic HTTP wrapper for GET request. Return the body of the page if HTTP code is OK, 

+

96 otherwise return None.""" 

+

97 try: 

+

98 http = urlopen(url) 

+

99 return http.read() if http.getcode() == 200 else None 

+

100 except Exception: 

+

101 return None 

+

102 

+

103 

+

104def update_gef(argv: List[str]) -> int: 

+

105 """Try to update `gef` to the latest version pushed on GitHub main branch. 

+

106 Return 0 on success, 1 on failure. """ 

+

107 ver = "dev" if "--dev" in argv else GEF_DEFAULT_BRANCH 

+

108 latest_gef_data = http_get(f"https://raw.githubusercontent.com/hugsy/gef/{ver}/scripts/gef.sh") 

+

109 if not latest_gef_data: 

+

110 print("[-] Failed to get remote gef") 

+

111 return 1 

+

112 with tempfile.NamedTemporaryFile(suffix=".sh") as fd: 

+

113 fd.write(latest_gef_data) 

+

114 fd.flush() 

+

115 fpath = pathlib.Path(fd.name) 

+

116 return subprocess.run(["bash", fpath, ver], stdout=subprocess.DEVNULL, 

+

117 stderr=subprocess.DEVNULL).returncode 

+

118 

+

119 

+

120try: 

+

121 import gdb # type:ignore 

+

122except ImportError: 

+

123 # if out of gdb, the only action allowed is to update gef.py 

+

124 if len(sys.argv) >= 2 and sys.argv[1].lower() in ("--update", "--upgrade"): 

+

125 sys.exit(update_gef(sys.argv[2:])) 

+

126 print("[-] gef cannot run as standalone") 

+

127 sys.exit(0) 

+

128 

+

129 

+

130GDB_MIN_VERSION = (8, 0) 

+

131GDB_VERSION = tuple(map(int, re.search(r"(\d+)[^\d]+(\d+)", gdb.VERSION).groups())) 

+

132PYTHON_MIN_VERSION = (3, 6) 

+

133PYTHON_VERSION = sys.version_info[0:2] 

+

134 

+

135DEFAULT_PAGE_ALIGN_SHIFT = 12 

+

136DEFAULT_PAGE_SIZE = 1 << DEFAULT_PAGE_ALIGN_SHIFT 

+

137 

+

138GEF_RC = (pathlib.Path(os.getenv("GEF_RC", "")).absolute() 

+

139 if os.getenv("GEF_RC") 

+

140 else pathlib.Path().home() / ".gef.rc") 

+

141GEF_TEMP_DIR = os.path.join(tempfile.gettempdir(), "gef") 

+

142GEF_MAX_STRING_LENGTH = 50 

+

143 

+

144LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME = "main_arena" 

+

145ANSI_SPLIT_RE = r"(\033\[[\d;]*m)" 

+

146 

+

147LEFT_ARROW = " ← " 

+

148RIGHT_ARROW = " → " 

+

149DOWN_ARROW = "↳" 

+

150HORIZONTAL_LINE = "─" 

+

151VERTICAL_LINE = "│" 

+

152CROSS = "✘ " 

+

153TICK = "✓ " 

+

154BP_GLYPH = "●" 

+

155GEF_PROMPT = "gef➤ " 

+

156GEF_PROMPT_ON = f"\001\033[1;32m\002{GEF_PROMPT}\001\033[0m\002" 

+

157GEF_PROMPT_OFF = f"\001\033[1;31m\002{GEF_PROMPT}\001\033[0m\002" 

+

158 

+

159PATTERN_LIBC_VERSION = re.compile(rb"glibc (\d+)\.(\d+)") 

+

160 

+

161gef : "Gef" 

+

162__registered_commands__ : Set[Type["GenericCommand"]] = set() 

+

163__registered_functions__ : Set[Type["GenericFunction"]] = set() 

+

164__registered_architectures__ : Dict[Union["Elf.Abi", str], Type["Architecture"]] = {} 

+

165__registered_file_formats__ : Set[ Type["FileFormat"] ] = set() 

+

166 

+

167 

+

168def reset_all_caches() -> None: 

+

169 """Free all caches. If an object is cached, it will have a callable attribute `cache_clear` 

+

170 which will be invoked to purge the function cache.""" 

+

171 

+

172 for mod in dir(sys.modules["__main__"]): 

+

173 obj = getattr(sys.modules["__main__"], mod) 

+

174 if hasattr(obj, "cache_clear"): 

+

175 obj.cache_clear() 

+

176 

+

177 gef.reset_caches() 

+

178 return 

+

179 

+

180 

+

181def reset() -> None: 

+

182 global gef 

+

183 

+

184 arch = None 

+

185 if "gef" in locals().keys(): 185 ↛ 186line 185 didn't jump to line 186, because the condition on line 185 was never true

+

186 reset_all_caches() 

+

187 arch = gef.arch 

+

188 del gef 

+

189 

+

190 gef = Gef() 

+

191 gef.setup() 

+

192 

+

193 if arch: 193 ↛ 194line 193 didn't jump to line 194, because the condition on line 193 was never true

+

194 gef.arch = arch 

+

195 return 

+

196 

+

197 

+

198def highlight_text(text: str) -> str: 

+

199 """ 

+

200 Highlight text using `gef.ui.highlight_table` { match -> color } settings. 

+

201 

+

202 If RegEx is enabled it will create a match group around all items in the 

+

203 `gef.ui.highlight_table` and wrap the specified color in the `gef.ui.highlight_table` 

+

204 around those matches. 

+

205 

+

206 If RegEx is disabled, split by ANSI codes and 'colorify' each match found 

+

207 within the specified string. 

+

208 """ 

+

209 global gef 

+

210 

+

211 if not gef.ui.highlight_table: 

+

212 return text 

+

213 

+

214 if gef.config["highlight.regex"]: 214 ↛ 215line 214 didn't jump to line 215, because the condition on line 214 was never true

+

215 for match, color in gef.ui.highlight_table.items(): 

+

216 text = re.sub("(" + match + ")", Color.colorify("\\1", color), text) 

+

217 return text 

+

218 

+

219 ansiSplit = re.split(ANSI_SPLIT_RE, text) 

+

220 

+

221 for match, color in gef.ui.highlight_table.items(): 

+

222 for index, val in enumerate(ansiSplit): 222 ↛ 227line 222 didn't jump to line 227, because the loop on line 222 didn't complete

+

223 found = val.find(match) 

+

224 if found > -1: 

+

225 ansiSplit[index] = val.replace(match, Color.colorify(match, color)) 

+

226 break 

+

227 text = "".join(ansiSplit) 

+

228 ansiSplit = re.split(ANSI_SPLIT_RE, text) 

+

229 

+

230 return "".join(ansiSplit) 

+

231 

+

232 

+

233def gef_print(*args: str, end="\n", sep=" ", **kwargs: Any) -> None: 

+

234 """Wrapper around print(), using string buffering feature.""" 

+

235 parts = [highlight_text(a) for a in args] 

+

236 if buffer_output() and gef.ui.stream_buffer and not is_debug(): 236 ↛ 237line 236 didn't jump to line 237, because the condition on line 236 was never true

+

237 gef.ui.stream_buffer.write(sep.join(parts) + end) 

+

238 return 

+

239 

+

240 print(*parts, sep=sep, end=end, **kwargs) 

+

241 return 

+

242 

+

243 

+

244def bufferize(f: Callable) -> Callable: 

+

245 """Store the content to be printed for a function in memory, and flush it on function exit.""" 

+

246 

+

247 @functools.wraps(f) 

+

248 def wrapper(*args: Any, **kwargs: Any) -> Any: 

+

249 global gef 

+

250 

+

251 if gef.ui.stream_buffer: 

+

252 return f(*args, **kwargs) 

+

253 

+

254 gef.ui.stream_buffer = StringIO() 

+

255 try: 

+

256 rv = f(*args, **kwargs) 

+

257 finally: 

+

258 redirect = gef.config["context.redirect"] 

+

259 if redirect.startswith("/dev/pts/"): 259 ↛ 260line 259 didn't jump to line 260, because the condition on line 259 was never true

+

260 if not gef.ui.redirect_fd: 

+

261 # if the FD has never been open, open it 

+

262 fd = open(redirect, "wt") 

+

263 gef.ui.redirect_fd = fd 

+

264 elif redirect != gef.ui.redirect_fd.name: 

+

265 # if the user has changed the redirect setting during runtime, update the state 

+

266 gef.ui.redirect_fd.close() 

+

267 fd = open(redirect, "wt") 

+

268 gef.ui.redirect_fd = fd 

+

269 else: 

+

270 # otherwise, keep using it 

+

271 fd = gef.ui.redirect_fd 

+

272 else: 

+

273 fd = sys.stdout 

+

274 gef.ui.redirect_fd = None 

+

275 

+

276 if gef.ui.redirect_fd and fd.closed: 276 ↛ 278line 276 didn't jump to line 278, because the condition on line 276 was never true

+

277 # if the tty was closed, revert back to stdout 

+

278 fd = sys.stdout 

+

279 gef.ui.redirect_fd = None 

+

280 gef.config["context.redirect"] = "" 

+

281 

+

282 fd.write(gef.ui.stream_buffer.getvalue()) 

+

283 fd.flush() 

+

284 gef.ui.stream_buffer = None 

+

285 return rv 

+

286 

+

287 return wrapper 

+

288 

+

289 

+

290# 

+

291# Helpers 

+

292# 

+

293 

+

294def p8(x: int, s: bool = False, e: Optional["Endianness"] = None) -> bytes: 

+

295 """Pack one byte respecting the current architecture endianness.""" 

+

296 endian = e or gef.arch.endianness 

+

297 return struct.pack(f"{endian}B", x) if not s else struct.pack(f"{endian:s}b", x) 

+

298 

+

299 

+

300def p16(x: int, s: bool = False, e: Optional["Endianness"] = None) -> bytes: 

+

301 """Pack one word respecting the current architecture endianness.""" 

+

302 endian = e or gef.arch.endianness 

+

303 return struct.pack(f"{endian}H", x) if not s else struct.pack(f"{endian:s}h", x) 

+

304 

+

305 

+

306def p32(x: int, s: bool = False, e: Optional["Endianness"] = None) -> bytes: 

+

307 """Pack one dword respecting the current architecture endianness.""" 

+

308 endian = e or gef.arch.endianness 

+

309 return struct.pack(f"{endian}I", x) if not s else struct.pack(f"{endian:s}i", x) 

+

310 

+

311 

+

312def p64(x: int, s: bool = False, e: Optional["Endianness"] = None) -> bytes: 

+

313 """Pack one qword respecting the current architecture endianness.""" 

+

314 endian = e or gef.arch.endianness 

+

315 return struct.pack(f"{endian}Q", x) if not s else struct.pack(f"{endian:s}q", x) 

+

316 

+

317 

+

318def u8(x: bytes, s: bool = False, e: Optional["Endianness"] = None) -> int: 

+

319 """Unpack one byte respecting the current architecture endianness.""" 

+

320 endian = e or gef.arch.endianness 

+

321 return struct.unpack(f"{endian}B", x)[0] if not s else struct.unpack(f"{endian:s}b", x)[0] 

+

322 

+

323 

+

324def u16(x: bytes, s: bool = False, e: Optional["Endianness"] = None) -> int: 

+

325 """Unpack one word respecting the current architecture endianness.""" 

+

326 endian = e or gef.arch.endianness 

+

327 return struct.unpack(f"{endian}H", x)[0] if not s else struct.unpack(f"{endian:s}h", x)[0] 

+

328 

+

329 

+

330def u32(x: bytes, s: bool = False, e: Optional["Endianness"] = None) -> int: 

+

331 """Unpack one dword respecting the current architecture endianness.""" 

+

332 endian = e or gef.arch.endianness 

+

333 return struct.unpack(f"{endian}I", x)[0] if not s else struct.unpack(f"{endian:s}i", x)[0] 

+

334 

+

335 

+

336def u64(x: bytes, s: bool = False, e: Optional["Endianness"] = None) -> int: 

+

337 """Unpack one qword respecting the current architecture endianness.""" 

+

338 endian = e or gef.arch.endianness 

+

339 return struct.unpack(f"{endian}Q", x)[0] if not s else struct.unpack(f"{endian:s}q", x)[0] 

+

340 

+

341 

+

342def is_ascii_string(address: int) -> bool: 

+

343 """Helper function to determine if the buffer pointed by `address` is an ASCII string (in GDB)""" 

+

344 try: 

+

345 return gef.memory.read_ascii_string(address) is not None 

+

346 except Exception: 

+

347 return False 

+

348 

+

349 

+

350def is_alive() -> bool: 

+

351 """Check if GDB is running.""" 

+

352 try: 

+

353 return gdb.selected_inferior().pid > 0 

+

354 except Exception: 

+

355 return False 

+

356 

+

357 

+

358def calling_function() -> Optional[str]: 

+

359 """Return the name of the calling function""" 

+

360 try: 

+

361 stack_info = traceback.extract_stack()[-3] 

+

362 return stack_info.name 

+

363 except: 

+

364 return None 

+

365 

+

366 

+

367# 

+

368# Decorators 

+

369# 

+

370def only_if_gdb_running(f: Callable) -> Callable: 

+

371 """Decorator wrapper to check if GDB is running.""" 

+

372 

+

373 @functools.wraps(f) 

+

374 def wrapper(*args: Any, **kwargs: Any) -> Any: 

+

375 if is_alive(): 

+

376 return f(*args, **kwargs) 

+

377 else: 

+

378 warn("No debugging session active") 

+

379 

+

380 return wrapper 

+

381 

+

382 

+

383def only_if_gdb_target_local(f: Callable) -> Callable: 

+

384 """Decorator wrapper to check if GDB is running locally (target not remote).""" 

+

385 

+

386 @functools.wraps(f) 

+

387 def wrapper(*args: Any, **kwargs: Any) -> Any: 

+

388 if not is_remote_debug(): 388 ↛ 391line 388 didn't jump to line 391, because the condition on line 388 was never false

+

389 return f(*args, **kwargs) 

+

390 else: 

+

391 warn("This command cannot work for remote sessions.") 

+

392 

+

393 return wrapper 

+

394 

+

395 

+

396def deprecated(solution: str = "") -> Callable: 

+

397 """Decorator to add a warning when a command is obsolete and will be removed.""" 

+

398 def decorator(f: Callable) -> Callable: 

+

399 @functools.wraps(f) 

+

400 def wrapper(*args: Any, **kwargs: Any) -> Any: 

+

401 caller = inspect.stack()[1] 

+

402 caller_file = pathlib.Path(caller.filename) 

+

403 caller_loc = caller.lineno 

+

404 msg = f"{caller_file.name}:L{caller_loc} '{f.__name__}' is deprecated and will be removed in a feature release. " 

+

405 if not gef: 405 ↛ 406line 405 didn't jump to line 406, because the condition on line 405 was never true

+

406 print(msg) 

+

407 elif gef.config["gef.show_deprecation_warnings"] is True: 407 ↛ 411line 407 didn't jump to line 411, because the condition on line 407 was never false

+

408 if solution: 408 ↛ 410line 408 didn't jump to line 410, because the condition on line 408 was never false

+

409 msg += solution 

+

410 warn(msg) 

+

411 return f(*args, **kwargs) 

+

412 

+

413 if not wrapper.__doc__: 

+

414 wrapper.__doc__ = "" 

+

415 wrapper.__doc__ += f"\r\n`{f.__name__}` is **DEPRECATED** and will be removed in the future.\r\n{solution}" 

+

416 return wrapper 

+

417 return decorator 

+

418 

+

419 

+

420def experimental_feature(f: Callable) -> Callable: 

+

421 """Decorator to add a warning when a feature is experimental.""" 

+

422 

+

423 @functools.wraps(f) 

+

424 def wrapper(*args: Any, **kwargs: Any) -> Any: 

+

425 warn("This feature is under development, expect bugs and unstability...") 

+

426 return f(*args, **kwargs) 

+

427 

+

428 return wrapper 

+

429 

+

430 

+

431def only_if_events_supported(event_type: str) -> Callable: 

+

432 """Checks if GDB supports events without crashing.""" 

+

433 def wrap(f: Callable) -> Callable: 

+

434 def wrapped_f(*args: Any, **kwargs: Any) -> Any: 

+

435 if getattr(gdb, "events") and getattr(gdb.events, event_type): 435 ↛ 437line 435 didn't jump to line 437, because the condition on line 435 was never false

+

436 return f(*args, **kwargs) 

+

437 warn("GDB events cannot be set") 

+

438 return wrapped_f 

+

439 return wrap 

+

440 

+

441 

+

442class classproperty(property): 

+

443 """Make the attribute a `classproperty`.""" 

+

444 def __get__(self, cls, owner): 

+

445 return classmethod(self.fget).__get__(None, owner)() 

+

446 

+

447 

+

448def FakeExit(*args: Any, **kwargs: Any) -> NoReturn: 

+

449 raise RuntimeWarning 

+

450 

+

451 

+

452sys.exit = FakeExit 

+

453 

+

454 

+

455def parse_arguments(required_arguments: Dict[Union[str, Tuple[str, str]], Any], 

+

456 optional_arguments: Dict[Union[str, Tuple[str, str]], Any]) -> Callable: 

+

457 """Argument parsing decorator.""" 

+

458 

+

459 def int_wrapper(x: str) -> int: return int(x, 0) 

+

460 

+

461 def decorator(f: Callable) -> Optional[Callable]: 

+

462 def wrapper(*args: Any, **kwargs: Any) -> Callable: 

+

463 parser = argparse.ArgumentParser(prog=args[0]._cmdline_, add_help=True) 

+

464 for argname in required_arguments: 

+

465 argvalue = required_arguments[argname] 

+

466 argtype = type(argvalue) 

+

467 if argtype is int: 

+

468 argtype = int_wrapper 

+

469 

+

470 argname_is_list = not isinstance(argname, str) 

+

471 assert not argname_is_list and isinstance(argname, str) 

+

472 if not argname_is_list and argname.startswith("-"): 472 ↛ 474line 472 didn't jump to line 474, because the condition on line 472 was never true

+

473 # optional args 

+

474 if argtype is bool: 

+

475 parser.add_argument(argname, action="store_true" if argvalue else "store_false") 

+

476 else: 

+

477 parser.add_argument(argname, type=argtype, required=True, default=argvalue) 

+

478 else: 

+

479 if argtype in (list, tuple): 

+

480 nargs = "*" 

+

481 argtype = type(argvalue[0]) 

+

482 else: 

+

483 nargs = "?" 

+

484 # positional args 

+

485 parser.add_argument(argname, type=argtype, default=argvalue, nargs=nargs) 

+

486 

+

487 for argname in optional_arguments: 

+

488 if isinstance(argname, str) and not argname.startswith("-"): 488 ↛ 490line 488 didn't jump to line 490, because the condition on line 488 was never true

+

489 # refuse positional arguments 

+

490 continue 

+

491 argvalue = optional_arguments[argname] 

+

492 argtype = type(argvalue) 

+

493 if isinstance(argname, str): 

+

494 argname = [argname,] 

+

495 if argtype is int: 

+

496 argtype = int_wrapper 

+

497 if argtype is bool: 

+

498 parser.add_argument(*argname, action="store_true" if argvalue else "store_false") 

+

499 else: 

+

500 parser.add_argument(*argname, type=argtype, default=argvalue) 

+

501 

+

502 parsed_args = parser.parse_args(*(args[1:])) 

+

503 kwargs["arguments"] = parsed_args 

+

504 return f(*args, **kwargs) 

+

505 return wrapper 

+

506 return decorator 

+

507 

+

508 

+

509class Color: 

+

510 """Used to colorify terminal output.""" 

+

511 colors = { 

+

512 "normal" : "\033[0m", 

+

513 "gray" : "\033[1;38;5;240m", 

+

514 "light_gray" : "\033[0;37m", 

+

515 "red" : "\033[31m", 

+

516 "green" : "\033[32m", 

+

517 "yellow" : "\033[33m", 

+

518 "blue" : "\033[34m", 

+

519 "pink" : "\033[35m", 

+

520 "cyan" : "\033[36m", 

+

521 "bold" : "\033[1m", 

+

522 "underline" : "\033[4m", 

+

523 "underline_off" : "\033[24m", 

+

524 "highlight" : "\033[3m", 

+

525 "highlight_off" : "\033[23m", 

+

526 "blink" : "\033[5m", 

+

527 "blink_off" : "\033[25m", 

+

528 } 

+

529 

+

530 @staticmethod 

+

531 def redify(msg: str) -> str: return Color.colorify(msg, "red") 

+

532 @staticmethod 

+

533 def greenify(msg: str) -> str: return Color.colorify(msg, "green") 

+

534 @staticmethod 

+

535 def blueify(msg: str) -> str: return Color.colorify(msg, "blue") 

+

536 @staticmethod 

+

537 def yellowify(msg: str) -> str: return Color.colorify(msg, "yellow") 

+

538 @staticmethod 

+

539 def grayify(msg: str) -> str: return Color.colorify(msg, "gray") 539 ↛ exitline 539 didn't return from function 'grayify', because the return on line 539 wasn't executed

+

540 @staticmethod 

+

541 def light_grayify(msg: str) -> str: return Color.colorify(msg, "light_gray") 541 ↛ exitline 541 didn't return from function 'light_grayify', because the return on line 541 wasn't executed

+

542 @staticmethod 

+

543 def pinkify(msg: str) -> str: return Color.colorify(msg, "pink") 

+

544 @staticmethod 

+

545 def cyanify(msg: str) -> str: return Color.colorify(msg, "cyan") 545 ↛ exitline 545 didn't return from function 'cyanify', because the return on line 545 wasn't executed

+

546 @staticmethod 

+

547 def boldify(msg: str) -> str: return Color.colorify(msg, "bold") 

+

548 @staticmethod 

+

549 def underlinify(msg: str) -> str: return Color.colorify(msg, "underline") 549 ↛ exitline 549 didn't return from function 'underlinify', because the return on line 549 wasn't executed

+

550 @staticmethod 

+

551 def highlightify(msg: str) -> str: return Color.colorify(msg, "highlight") 551 ↛ exitline 551 didn't return from function 'highlightify', because the return on line 551 wasn't executed

+

552 @staticmethod 

+

553 def blinkify(msg: str) -> str: return Color.colorify(msg, "blink") 553 ↛ exitline 553 didn't return from function 'blinkify', because the return on line 553 wasn't executed

+

554 

+

555 @staticmethod 

+

556 def colorify(text: str, attrs: str) -> str: 

+

557 """Color text according to the given attributes.""" 

+

558 if gef.config["gef.disable_color"] is True: return text 558 ↛ exitline 558 didn't return from function 'colorify', because the return on line 558 wasn't executed

+

559 

+

560 colors = Color.colors 

+

561 msg = [colors[attr] for attr in attrs.split() if attr in colors] 

+

562 msg.append(str(text)) 

+

563 if colors["highlight"] in msg: msg.append(colors["highlight_off"]) 

+

564 if colors["underline"] in msg: msg.append(colors["underline_off"]) 

+

565 if colors["blink"] in msg: msg.append(colors["blink_off"]) 

+

566 msg.append(colors["normal"]) 

+

567 return "".join(msg) 

+

568 

+

569 

+

570class Address: 

+

571 """GEF representation of memory addresses.""" 

+

572 def __init__(self, **kwargs: Any) -> None: 

+

573 self.value: int = kwargs.get("value", 0) 

+

574 self.section: "Section" = kwargs.get("section", None) 

+

575 self.info: "Zone" = kwargs.get("info", None) 

+

576 return 

+

577 

+

578 def __str__(self) -> str: 

+

579 value = format_address(self.value) 

+

580 code_color = gef.config["theme.address_code"] 

+

581 stack_color = gef.config["theme.address_stack"] 

+

582 heap_color = gef.config["theme.address_heap"] 

+

583 if self.is_in_text_segment(): 

+

584 return Color.colorify(value, code_color) 

+

585 if self.is_in_heap_segment(): 585 ↛ 586line 585 didn't jump to line 586, because the condition on line 585 was never true

+

586 return Color.colorify(value, heap_color) 

+

587 if self.is_in_stack_segment(): 

+

588 return Color.colorify(value, stack_color) 

+

589 return value 

+

590 

+

591 def __int__(self) -> int: 

+

592 return self.value 

+

593 

+

594 def is_in_text_segment(self) -> bool: 

+

595 return (hasattr(self.info, "name") and ".text" in self.info.name) or \ 

+

596 (hasattr(self.section, "path") and get_filepath() == self.section.path and self.section.is_executable()) 

+

597 

+

598 def is_in_stack_segment(self) -> bool: 

+

599 return hasattr(self.section, "path") and "[stack]" == self.section.path 

+

600 

+

601 def is_in_heap_segment(self) -> bool: 

+

602 return hasattr(self.section, "path") and "[heap]" == self.section.path 

+

603 

+

604 def dereference(self) -> Optional[int]: 

+

605 addr = align_address(int(self.value)) 

+

606 derefed = dereference(addr) 

+

607 return None if derefed is None else int(derefed) 

+

608 

+

609 @property 

+

610 def valid(self) -> bool: 

+

611 return any(map(lambda x: x.page_start <= self.value < x.page_end, gef.memory.maps)) 

+

612 

+

613 

+

614class Permission(enum.Flag): 

+

615 """GEF representation of Linux permission.""" 

+

616 NONE = 0 

+

617 EXECUTE = 1 

+

618 WRITE = 2 

+

619 READ = 4 

+

620 ALL = 7 

+

621 

+

622 def __str__(self) -> str: 

+

623 perm_str = "" 

+

624 perm_str += "r" if self & Permission.READ else "-" 

+

625 perm_str += "w" if self & Permission.WRITE else "-" 

+

626 perm_str += "x" if self & Permission.EXECUTE else "-" 

+

627 return perm_str 

+

628 

+

629 @classmethod 

+

630 def from_info_sections(cls, *args: str) -> "Permission": 

+

631 perm = cls(0) 

+

632 for arg in args: 

+

633 if "READONLY" in arg: perm |= Permission.READ 

+

634 if "DATA" in arg: perm |= Permission.WRITE 

+

635 if "CODE" in arg: perm |= Permission.EXECUTE 

+

636 return perm 

+

637 

+

638 @classmethod 

+

639 def from_process_maps(cls, perm_str: str) -> "Permission": 

+

640 perm = cls(0) 

+

641 if perm_str[0] == "r": perm |= Permission.READ 

+

642 if perm_str[1] == "w": perm |= Permission.WRITE 

+

643 if perm_str[2] == "x": perm |= Permission.EXECUTE 

+

644 return perm 

+

645 

+

646 @classmethod 

+

647 def from_info_mem(cls, perm_str: str) -> "Permission": 

+

648 perm = cls(0) 

+

649 # perm_str[0] shows if this is a user page, which 

+

650 # we don't track 

+

651 if perm_str[1] == "r": perm |= Permission.READ 

+

652 if perm_str[2] == "w": perm |= Permission.WRITE 

+

653 return perm 

+

654 

+

655 

+

656class Section: 

+

657 """GEF representation of process memory sections.""" 

+

658 

+

659 def __init__(self, **kwargs: Any) -> None: 

+

660 self.page_start: int = kwargs.get("page_start", 0) 

+

661 self.page_end: int = kwargs.get("page_end", 0) 

+

662 self.offset: int = kwargs.get("offset", 0) 

+

663 self.permission: Permission = kwargs.get("permission", Permission(0)) 

+

664 self.inode: int = kwargs.get("inode", 0) 

+

665 self.path: str = kwargs.get("path", "") 

+

666 return 

+

667 

+

668 def is_readable(self) -> bool: 

+

669 return (self.permission & Permission.READ) != 0 

+

670 

+

671 def is_writable(self) -> bool: 

+

672 return (self.permission & Permission.WRITE) != 0 

+

673 

+

674 def is_executable(self) -> bool: 

+

675 return (self.permission & Permission.EXECUTE) != 0 

+

676 

+

677 @property 

+

678 def size(self) -> int: 

+

679 if self.page_end is None or self.page_start is None: 

+

680 return -1 

+

681 return self.page_end - self.page_start 

+

682 

+

683 @property 

+

684 def realpath(self) -> str: 

+

685 # when in a `gef-remote` session, realpath returns the path to the binary on the local disk, not remote 

+

686 return self.path if gef.session.remote is None else f"/tmp/gef/{gef.session.remote:d}/{self.path}" 

+

687 

+

688 def __str__(self) -> str: 

+

689 return (f"Section(page_start={self.page_start:#x}, page_end={self.page_end:#x}, " 

+

690 f"permissions={self.permission!s})") 

+

691 

+

692 

+

693Zone = collections.namedtuple("Zone", ["name", "zone_start", "zone_end", "filename"]) 

+

694 

+

695 

+

696class Endianness(enum.Enum): 

+

697 LITTLE_ENDIAN = 1 

+

698 BIG_ENDIAN = 2 

+

699 

+

700 def __str__(self) -> str: 

+

701 return "<" if self == Endianness.LITTLE_ENDIAN else ">" 

+

702 

+

703 def __repr__(self) -> str: 

+

704 return self.name 

+

705 

+

706 def __int__(self) -> int: 

+

707 return self.value 

+

708 

+

709 

+

710class FileFormatSection: 

+

711 misc: Any 

+

712 

+

713 

+

714class FileFormat: 

+

715 name: str 

+

716 path: pathlib.Path 

+

717 entry_point: int 

+

718 checksec: Dict[str, bool] 

+

719 sections: List[FileFormatSection] 

+

720 

+

721 def __init__(self, path: Union[str, pathlib.Path]) -> None: 

+

722 raise NotImplemented 

+

723 

+

724 def __init_subclass__(cls: Type["FileFormat"], **kwargs): 

+

725 global __registered_file_formats__ 

+

726 super().__init_subclass__(**kwargs) 

+

727 required_attributes = ("name", "entry_point", "is_valid", "checksec",) 

+

728 for attr in required_attributes: 

+

729 if not hasattr(cls, attr): 729 ↛ 730line 729 didn't jump to line 730, because the condition on line 729 was never true

+

730 raise NotImplementedError(f"File format '{cls.__name__}' is invalid: missing attribute '{attr}'") 

+

731 __registered_file_formats__.add(cls) 

+

732 return 

+

733 

+

734 @classmethod 

+

735 def is_valid(cls, path: pathlib.Path) -> bool: 

+

736 raise NotImplemented 

+

737 

+

738 def __str__(self) -> str: 

+

739 return f"{self.name}('{self.path.absolute()}', entry @ {self.entry_point:#x})" 

+

740 

+

741 

+

742class Elf(FileFormat): 

+

743 """Basic ELF parsing. 

+

744 Ref: 

+

745 - http://www.skyfree.org/linux/references/ELF_Format.pdf 

+

746 - https://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf 

+

747 - https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html 

+

748 """ 

+

749 class Class(enum.Enum): 

+

750 ELF_32_BITS = 0x01 

+

751 ELF_64_BITS = 0x02 

+

752 

+

753 ELF_MAGIC = 0x7f454c46 

+

754 

+

755 class Abi(enum.Enum): 

+

756 X86_64 = 0x3e 

+

757 X86_32 = 0x03 

+

758 ARM = 0x28 

+

759 MIPS = 0x08 

+

760 POWERPC = 0x14 

+

761 POWERPC64 = 0x15 

+

762 SPARC = 0x02 

+

763 SPARC64 = 0x2b 

+

764 AARCH64 = 0xb7 

+

765 RISCV = 0xf3 

+

766 IA64 = 0x32 

+

767 M68K = 0x04 

+

768 

+

769 class Type(enum.Enum): 

+

770 ET_RELOC = 1 

+

771 ET_EXEC = 2 

+

772 ET_DYN = 3 

+

773 ET_CORE = 4 

+

774 

+

775 class OsAbi(enum.Enum): 

+

776 SYSTEMV = 0x00 

+

777 HPUX = 0x01 

+

778 NETBSD = 0x02 

+

779 LINUX = 0x03 

+

780 SOLARIS = 0x06 

+

781 AIX = 0x07 

+

782 IRIX = 0x08 

+

783 FREEBSD = 0x09 

+

784 OPENBSD = 0x0C 

+

785 

+

786 e_magic: int = ELF_MAGIC 

+

787 e_class: "Elf.Class" = Class.ELF_32_BITS 

+

788 e_endianness: Endianness = Endianness.LITTLE_ENDIAN 

+

789 e_eiversion: int 

+

790 e_osabi: "Elf.OsAbi" 

+

791 e_abiversion: int 

+

792 e_pad: bytes 

+

793 e_type: "Elf.Type" = Type.ET_EXEC 

+

794 e_machine: Abi = Abi.X86_32 

+

795 e_version: int 

+

796 e_entry: int 

+

797 e_phoff: int 

+

798 e_shoff: int 

+

799 e_flags: int 

+

800 e_ehsize: int 

+

801 e_phentsize: int 

+

802 e_phnum: int 

+

803 e_shentsize: int 

+

804 e_shnum: int 

+

805 e_shstrndx: int 

+

806 

+

807 path: pathlib.Path 

+

808 phdrs : List["Phdr"] 

+

809 shdrs : List["Shdr"] 

+

810 name: str = "ELF" 

+

811 

+

812 __checksec : Dict[str, bool] 

+

813 

+

814 def __init__(self, path: Union[str, pathlib.Path]) -> None: 

+

815 """Instantiate an ELF object. A valid ELF must be provided, or an exception will be thrown.""" 

+

816 

+

817 if isinstance(path, str): 

+

818 self.path = pathlib.Path(path).expanduser() 

+

819 elif isinstance(path, pathlib.Path): 819 ↛ 822line 819 didn't jump to line 822, because the condition on line 819 was never false

+

820 self.path = path 

+

821 else: 

+

822 raise TypeError 

+

823 

+

824 if not self.path.exists(): 824 ↛ 825line 824 didn't jump to line 825, because the condition on line 824 was never true

+

825 raise FileNotFoundError(f"'{self.path}' not found/readable, most gef features will not work") 

+

826 

+

827 self.__checksec = {} 

+

828 

+

829 with self.path.open("rb") as self.fd: 

+

830 # off 0x0 

+

831 self.e_magic, e_class, e_endianness, self.e_eiversion = self.read_and_unpack(">IBBB") 

+

832 if self.e_magic != Elf.ELF_MAGIC: 832 ↛ 834line 832 didn't jump to line 834, because the condition on line 832 was never true

+

833 # The ELF is corrupted, GDB won't handle it, no point going further 

+

834 raise RuntimeError("Not a valid ELF file (magic)") 

+

835 

+

836 self.e_class, self.e_endianness = Elf.Class(e_class), Endianness(e_endianness) 

+

837 

+

838 if self.e_endianness != gef.arch.endianness: 838 ↛ 839line 838 didn't jump to line 839, because the condition on line 838 was never true

+

839 warn("Unexpected endianness for architecture") 

+

840 

+

841 endian = self.e_endianness 

+

842 

+

843 # off 0x7 

+

844 e_osabi, self.e_abiversion = self.read_and_unpack(f"{endian}BB") 

+

845 self.e_osabi = Elf.OsAbi(e_osabi) 

+

846 

+

847 # off 0x9 

+

848 self.e_pad = self.read(7) 

+

849 

+

850 # off 0x10 

+

851 e_type, e_machine, self.e_version = self.read_and_unpack(f"{endian}HHI") 

+

852 self.e_type, self.e_machine = Elf.Type(e_type), Elf.Abi(e_machine) 

+

853 

+

854 # off 0x18 

+

855 if self.e_class == Elf.Class.ELF_64_BITS: 855 ↛ 858line 855 didn't jump to line 858, because the condition on line 855 was never false

+

856 self.e_entry, self.e_phoff, self.e_shoff = self.read_and_unpack(f"{endian}QQQ") 

+

857 else: 

+

858 self.e_entry, self.e_phoff, self.e_shoff = self.read_and_unpack(f"{endian}III") 

+

859 

+

860 self.e_flags, self.e_ehsize, self.e_phentsize, self.e_phnum = self.read_and_unpack(f"{endian}IHHH") 

+

861 self.e_shentsize, self.e_shnum, self.e_shstrndx = self.read_and_unpack(f"{endian}HHH") 

+

862 

+

863 self.phdrs = [] 

+

864 for i in range(self.e_phnum): 

+

865 self.phdrs.append(Phdr(self, self.e_phoff + self.e_phentsize * i)) 

+

866 

+

867 self.shdrs = [] 

+

868 for i in range(self.e_shnum): 

+

869 self.shdrs.append(Shdr(self, self.e_shoff + self.e_shentsize * i)) 

+

870 return 

+

871 

+

872 def read(self, size: int) -> bytes: 

+

873 return self.fd.read(size) 

+

874 

+

875 def read_and_unpack(self, fmt: str) -> Tuple[Any, ...]: 

+

876 size = struct.calcsize(fmt) 

+

877 data = self.fd.read(size) 

+

878 return struct.unpack(fmt, data) 

+

879 

+

880 def seek(self, off: int) -> None: 

+

881 self.fd.seek(off, 0) 

+

882 

+

883 def __str__(self) -> str: 

+

884 return f"ELF('{self.path.absolute()}', {self.e_class.name}, {self.e_machine.name})" 

+

885 

+

886 def __repr__(self) -> str: 

+

887 return f"ELF('{self.path.absolute()}', {self.e_class.name}, {self.e_machine.name})" 

+

888 

+

889 @property 

+

890 def entry_point(self) -> int: 

+

891 return self.e_entry 

+

892 

+

893 @classmethod 

+

894 def is_valid(cls, path: pathlib.Path) -> bool: 

+

895 return u32(path.open("rb").read(4), e = Endianness.BIG_ENDIAN) == Elf.ELF_MAGIC 

+

896 

+

897 @property 

+

898 def checksec(self) -> Dict[str, bool]: 

+

899 """Check the security property of the ELF binary. The following properties are: 

+

900 - Canary 

+

901 - NX 

+

902 - PIE 

+

903 - Fortify 

+

904 - Partial/Full RelRO. 

+

905 Return a dict() with the different keys mentioned above, and the boolean 

+

906 associated whether the protection was found.""" 

+

907 if not self.__checksec: 907 ↛ 930line 907 didn't jump to line 930, because the condition on line 907 was never false

+

908 def __check_security_property(opt: str, filename: str, pattern: str) -> bool: 

+

909 cmd = [readelf,] 

+

910 cmd += opt.split() 

+

911 cmd += [filename,] 

+

912 lines = gef_execute_external(cmd, as_list=True) 

+

913 for line in lines: 

+

914 if re.search(pattern, line): 

+

915 return True 

+

916 return False 

+

917 

+

918 abspath = str(self.path.absolute()) 

+

919 readelf = gef.session.constants["readelf"] 

+

920 self.__checksec["Canary"] = __check_security_property("-rs", abspath, r"__stack_chk_fail") is True 

+

921 has_gnu_stack = __check_security_property("-W -l", abspath, r"GNU_STACK") is True 

+

922 if has_gnu_stack: 922 ↛ 925line 922 didn't jump to line 925, because the condition on line 922 was never false

+

923 self.__checksec["NX"] = __check_security_property("-W -l", abspath, r"GNU_STACK.*RWE") is False 

+

924 else: 

+

925 self.__checksec["NX"] = False 

+

926 self.__checksec["PIE"] = __check_security_property("-h", abspath, r":.*EXEC") is False 

+

927 self.__checksec["Fortify"] = __check_security_property("-s", abspath, r"_chk@GLIBC") is True 

+

928 self.__checksec["Partial RelRO"] = __check_security_property("-l", abspath, r"GNU_RELRO") is True 

+

929 self.__checksec["Full RelRO"] = self.__checksec["Partial RelRO"] and __check_security_property("-d", abspath, r"BIND_NOW") is True 

+

930 return self.__checksec 

+

931 

+

932 @classproperty 

+

933 @deprecated("use `Elf.Abi.X86_64`") 

+

934 def X86_64(cls) -> int: return Elf.Abi.X86_64.value # pylint: disable=no-self-argument 

+

935 

+

936 @classproperty 

+

937 @deprecated("use `Elf.Abi.X86_32`") 

+

938 def X86_32(cls) -> int : return Elf.Abi.X86_32.value # pylint: disable=no-self-argument 

+

939 

+

940 @classproperty 

+

941 @deprecated("use `Elf.Abi.ARM`") 

+

942 def ARM(cls) -> int : return Elf.Abi.ARM.value # pylint: disable=no-self-argument 

+

943 

+

944 @classproperty 

+

945 @deprecated("use `Elf.Abi.MIPS`") 

+

946 def MIPS(cls) -> int : return Elf.Abi.MIPS.value # pylint: disable=no-self-argument 

+

947 

+

948 @classproperty 

+

949 @deprecated("use `Elf.Abi.POWERPC`") 

+

950 def POWERPC(cls) -> int : return Elf.Abi.POWERPC.value # pylint: disable=no-self-argument 

+

951 

+

952 @classproperty 

+

953 @deprecated("use `Elf.Abi.POWERPC64`") 

+

954 def POWERPC64(cls) -> int : return Elf.Abi.POWERPC64.value # pylint: disable=no-self-argument 

+

955 

+

956 @classproperty 

+

957 @deprecated("use `Elf.Abi.SPARC`") 

+

958 def SPARC(cls) -> int : return Elf.Abi.SPARC.value # pylint: disable=no-self-argument 

+

959 

+

960 @classproperty 

+

961 @deprecated("use `Elf.Abi.SPARC64`") 

+

962 def SPARC64(cls) -> int : return Elf.Abi.SPARC64.value # pylint: disable=no-self-argument 

+

963 

+

964 @classproperty 

+

965 @deprecated("use `Elf.Abi.AARCH64`") 

+

966 def AARCH64(cls) -> int : return Elf.Abi.AARCH64.value # pylint: disable=no-self-argument 

+

967 

+

968 @classproperty 

+

969 @deprecated("use `Elf.Abi.RISCV`") 

+

970 def RISCV(cls) -> int : return Elf.Abi.RISCV.value # pylint: disable=no-self-argument 

+

971 

+

972 

+

973class Phdr: 

+

974 class Type(enum.IntEnum): 

+

975 PT_NULL = 0 

+

976 PT_LOAD = 1 

+

977 PT_DYNAMIC = 2 

+

978 PT_INTERP = 3 

+

979 PT_NOTE = 4 

+

980 PT_SHLIB = 5 

+

981 PT_PHDR = 6 

+

982 PT_TLS = 7 

+

983 PT_LOOS = 0x60000000 

+

984 PT_GNU_EH_FRAME = 0x6474e550 

+

985 PT_GNU_STACK = 0x6474e551 

+

986 PT_GNU_RELRO = 0x6474e552 

+

987 PT_GNU_PROPERTY = 0x6474e553 

+

988 PT_LOSUNW = 0x6ffffffa 

+

989 PT_SUNWBSS = 0x6ffffffa 

+

990 PT_SUNWSTACK = 0x6ffffffb 

+

991 PT_HISUNW = PT_HIOS = 0x6fffffff 

+

992 PT_LOPROC = 0x70000000 

+

993 PT_ARM_EIDX = 0x70000001 

+

994 PT_MIPS_ABIFLAGS= 0x70000003 

+

995 PT_HIPROC = 0x7fffffff 

+

996 UNKNOWN_PHDR = 0xffffffff 

+

997 

+

998 @classmethod 

+

999 def _missing_(cls, _:int) -> Type: 

+

1000 return cls.UNKNOWN_PHDR 

+

1001 

+

1002 class Flags(enum.IntFlag): 

+

1003 PF_X = 1 

+

1004 PF_W = 2 

+

1005 PF_R = 4 

+

1006 

+

1007 p_type: "Phdr.Type" 

+

1008 p_flags: "Phdr.Flags" 

+

1009 p_offset: int 

+

1010 p_vaddr: int 

+

1011 p_paddr: int 

+

1012 p_filesz: int 

+

1013 p_memsz: int 

+

1014 p_align: int 

+

1015 

+

1016 def __init__(self, elf: Elf, off: int) -> None: 

+

1017 if not elf: 1017 ↛ 1018line 1017 didn't jump to line 1018, because the condition on line 1017 was never true

+

1018 return 

+

1019 elf.seek(off) 

+

1020 self.offset = off 

+

1021 endian = elf.e_endianness 

+

1022 if elf.e_class == Elf.Class.ELF_64_BITS: 1022 ↛ 1027line 1022 didn't jump to line 1027, because the condition on line 1022 was never false

+

1023 p_type, p_flags, self.p_offset = elf.read_and_unpack(f"{endian}IIQ") 

+

1024 self.p_vaddr, self.p_paddr = elf.read_and_unpack(f"{endian}QQ") 

+

1025 self.p_filesz, self.p_memsz, self.p_align = elf.read_and_unpack(f"{endian}QQQ") 

+

1026 else: 

+

1027 p_type, self.p_offset = elf.read_and_unpack(f"{endian}II") 

+

1028 self.p_vaddr, self.p_paddr = elf.read_and_unpack(f"{endian}II") 

+

1029 self.p_filesz, self.p_memsz, p_flags, self.p_align = elf.read_and_unpack(f"{endian}IIII") 

+

1030 

+

1031 self.p_type, self.p_flags = Phdr.Type(p_type), Phdr.Flags(p_flags) 

+

1032 return 

+

1033 

+

1034 def __str__(self) -> str: 

+

1035 return (f"Phdr(offset={self.offset}, type={self.p_type.name}, flags={self.p_flags.name}, " 

+

1036 f"vaddr={self.p_vaddr}, paddr={self.p_paddr}, filesz={self.p_filesz}, " 

+

1037 f"memsz={self.p_memsz}, align={self.p_align})") 

+

1038 

+

1039 

+

1040class Shdr: 

+

1041 class Type(enum.IntEnum): 

+

1042 SHT_NULL = 0 

+

1043 SHT_PROGBITS = 1 

+

1044 SHT_SYMTAB = 2 

+

1045 SHT_STRTAB = 3 

+

1046 SHT_RELA = 4 

+

1047 SHT_HASH = 5 

+

1048 SHT_DYNAMIC = 6 

+

1049 SHT_NOTE = 7 

+

1050 SHT_NOBITS = 8 

+

1051 SHT_REL = 9 

+

1052 SHT_SHLIB = 10 

+

1053 SHT_DYNSYM = 11 

+

1054 SHT_NUM = 12 

+

1055 SHT_INIT_ARRAY = 14 

+

1056 SHT_FINI_ARRAY = 15 

+

1057 SHT_PREINIT_ARRAY = 16 

+

1058 SHT_GROUP = 17 

+

1059 SHT_SYMTAB_SHNDX = 18 

+

1060 SHT_LOOS = 0x60000000 

+

1061 SHT_GNU_ATTRIBUTES = 0x6ffffff5 

+

1062 SHT_GNU_HASH = 0x6ffffff6 

+

1063 SHT_GNU_LIBLIST = 0x6ffffff7 

+

1064 SHT_CHECKSUM = 0x6ffffff8 

+

1065 SHT_LOSUNW = 0x6ffffffa 

+

1066 SHT_SUNW_move = 0x6ffffffa 

+

1067 SHT_SUNW_COMDAT = 0x6ffffffb 

+

1068 SHT_SUNW_syminfo = 0x6ffffffc 

+

1069 SHT_GNU_verdef = 0x6ffffffd 

+

1070 SHT_GNU_verneed = 0x6ffffffe 

+

1071 SHT_GNU_versym = 0x6fffffff 

+

1072 SHT_LOPROC = 0x70000000 

+

1073 SHT_ARM_EXIDX = 0x70000001 

+

1074 SHT_X86_64_UNWIND = 0x70000001 

+

1075 SHT_ARM_ATTRIBUTES = 0x70000003 

+

1076 SHT_MIPS_OPTIONS = 0x7000000d 

+

1077 DT_MIPS_INTERFACE = 0x7000002a 

+

1078 SHT_HIPROC = 0x7fffffff 

+

1079 SHT_LOUSER = 0x80000000 

+

1080 SHT_HIUSER = 0x8fffffff 

+

1081 UNKNOWN_SHDR = 0xffffffff 

+

1082 

+

1083 @classmethod 

+

1084 def _missing_(cls, _:int) -> Type: 

+

1085 return cls.UNKNOWN_SHDR 

+

1086 

+

1087 class Flags(enum.IntFlag): 

+

1088 WRITE = 1 

+

1089 ALLOC = 2 

+

1090 EXECINSTR = 4 

+

1091 MERGE = 0x10 

+

1092 STRINGS = 0x20 

+

1093 INFO_LINK = 0x40 

+

1094 LINK_ORDER = 0x80 

+

1095 OS_NONCONFORMING = 0x100 

+

1096 GROUP = 0x200 

+

1097 TLS = 0x400 

+

1098 COMPRESSED = 0x800 

+

1099 RELA_LIVEPATCH = 0x00100000 

+

1100 RO_AFTER_INIT = 0x00200000 

+

1101 ORDERED = 0x40000000 

+

1102 EXCLUDE = 0x80000000 

+

1103 UNKNOWN_FLAG = 0xffffffff 

+

1104 

+

1105 @classmethod 

+

1106 def _missing_(cls, _:int): 

+

1107 return cls.UNKNOWN_FLAG 

+

1108 

+

1109 sh_name: int 

+

1110 sh_type: "Shdr.Type" 

+

1111 sh_flags: "Shdr.Flags" 

+

1112 sh_addr: int 

+

1113 sh_offset: int 

+

1114 sh_size: int 

+

1115 sh_link: int 

+

1116 sh_info: int 

+

1117 sh_addralign: int 

+

1118 sh_entsize: int 

+

1119 name: str 

+

1120 

+

1121 def __init__(self, elf: Optional[Elf], off: int) -> None: 

+

1122 if elf is None: 1122 ↛ 1123line 1122 didn't jump to line 1123, because the condition on line 1122 was never true

+

1123 return 

+

1124 elf.seek(off) 

+

1125 endian = elf.e_endianness 

+

1126 if elf.e_class == Elf.Class.ELF_64_BITS: 1126 ↛ 1132line 1126 didn't jump to line 1132, because the condition on line 1126 was never false

+

1127 self.sh_name, sh_type, sh_flags = elf.read_and_unpack(f"{endian}IIQ") 

+

1128 self.sh_addr, self.sh_offset = elf.read_and_unpack(f"{endian}QQ") 

+

1129 self.sh_size, self.sh_link, self.sh_info = elf.read_and_unpack(f"{endian}QII") 

+

1130 self.sh_addralign, self.sh_entsize = elf.read_and_unpack(f"{endian}QQ") 

+

1131 else: 

+

1132 self.sh_name, sh_type, sh_flags = elf.read_and_unpack(f"{endian}III") 

+

1133 self.sh_addr, self.sh_offset = elf.read_and_unpack(f"{endian}II") 

+

1134 self.sh_size, self.sh_link, self.sh_info = elf.read_and_unpack(f"{endian}III") 

+

1135 self.sh_addralign, self.sh_entsize = elf.read_and_unpack(f"{endian}II") 

+

1136 

+

1137 self.sh_type = Shdr.Type(sh_type) 

+

1138 self.sh_flags = Shdr.Flags(sh_flags) 

+

1139 stroff = elf.e_shoff + elf.e_shentsize * elf.e_shstrndx 

+

1140 

+

1141 if elf.e_class == Elf.Class.ELF_64_BITS: 1141 ↛ 1145line 1141 didn't jump to line 1145, because the condition on line 1141 was never false

+

1142 elf.seek(stroff + 16 + 8) 

+

1143 offset = u64(elf.read(8)) 

+

1144 else: 

+

1145 elf.seek(stroff + 12 + 4) 

+

1146 offset = u32(elf.read(4)) 

+

1147 elf.seek(offset + self.sh_name) 

+

1148 self.name = "" 

+

1149 while True: 

+

1150 c = u8(elf.read(1)) 

+

1151 if c == 0: 

+

1152 break 

+

1153 self.name += chr(c) 

+

1154 return 

+

1155 

+

1156 def __str__(self) -> str: 

+

1157 return (f"Shdr(name={self.name}, type={self.sh_type.name}, flags={self.sh_flags.name}, " 

+

1158 f"addr={self.sh_addr:#x}, offset={self.sh_offset}, size={self.sh_size}, link={self.sh_link}, " 

+

1159 f"info={self.sh_info}, addralign={self.sh_addralign}, entsize={self.sh_entsize})") 

+

1160 

+

1161 

+

1162class Instruction: 

+

1163 """GEF representation of a CPU instruction.""" 

+

1164 

+

1165 def __init__(self, address: int, location: str, mnemo: str, operands: List[str], opcodes: bytes) -> None: 

+

1166 self.address, self.location, self.mnemonic, self.operands, self.opcodes = \ 

+

1167 address, location, mnemo, operands, opcodes 

+

1168 return 

+

1169 

+

1170 # Allow formatting an instruction with {:o} to show opcodes. 

+

1171 # The number of bytes to display can be configured, e.g. {:4o} to only show 4 bytes of the opcodes 

+

1172 def __format__(self, format_spec: str) -> str: 

+

1173 if len(format_spec) == 0 or format_spec[-1] != "o": 1173 ↛ 1174line 1173 didn't jump to line 1174, because the condition on line 1173 was never true

+

1174 return str(self) 

+

1175 

+

1176 if format_spec == "o": 1176 ↛ 1177line 1176 didn't jump to line 1177, because the condition on line 1176 was never true

+

1177 opcodes_len = len(self.opcodes) 

+

1178 else: 

+

1179 opcodes_len = int(format_spec[:-1]) 

+

1180 

+

1181 opcodes_text = "".join(f"{b:02x}" for b in self.opcodes[:opcodes_len]) 

+

1182 if opcodes_len < len(self.opcodes): 

+

1183 opcodes_text += "..." 

+

1184 return (f"{self.address:#10x} {opcodes_text:{opcodes_len * 2 + 3:d}s} {self.location:16} " 

+

1185 f"{self.mnemonic:6} {', '.join(self.operands)}") 

+

1186 

+

1187 def __str__(self) -> str: 

+

1188 return f"{self.address:#10x} {self.location:16} {self.mnemonic:6} {', '.join(self.operands)}" 

+

1189 

+

1190 def is_valid(self) -> bool: 

+

1191 return "(bad)" not in self.mnemonic 

+

1192 

+

1193 def size(self) -> int: 

+

1194 return len(self.opcodes) 

+

1195 

+

1196 def next(self) -> "Instruction": 

+

1197 address = self.address + self.size() 

+

1198 return gef_get_instruction_at(address) 

+

1199 

+

1200 

+

1201@deprecated("Use GefHeapManager.find_main_arena_addr()") 

+

1202def search_for_main_arena() -> int: 

+

1203 return GefHeapManager.find_main_arena_addr() 

+

1204 

+

1205class GlibcHeapInfo: 

+

1206 """Glibc heap_info struct""" 

+

1207 

+

1208 @staticmethod 

+

1209 def heap_info_t() -> Type[ctypes.Structure]: 

+

1210 assert gef.libc.version 

+

1211 class heap_info_cls(ctypes.Structure): 

+

1212 pass 

+

1213 pointer = ctypes.c_uint64 if gef.arch.ptrsize == 8 else ctypes.c_uint32 

+

1214 pad_size = -5 * gef.arch.ptrsize & (gef.heap.malloc_alignment - 1) 

+

1215 fields = [ 

+

1216 ("ar_ptr", ctypes.POINTER(GlibcArena.malloc_state_t())), 

+

1217 ("prev", ctypes.POINTER(heap_info_cls)), 

+

1218 ("size", pointer) 

+

1219 ] 

+

1220 if gef.libc.version >= (2, 5): 1220 ↛ 1225line 1220 didn't jump to line 1225, because the condition on line 1220 was never false

+

1221 fields += [ 

+

1222 ("mprotect_size", pointer) 

+

1223 ] 

+

1224 pad_size = -6 * gef.arch.ptrsize & (gef.heap.malloc_alignment - 1) 

+

1225 if gef.libc.version >= (2, 34): 1225 ↛ 1230line 1225 didn't jump to line 1230, because the condition on line 1225 was never false

+

1226 fields += [ 

+

1227 ("pagesize", pointer) 

+

1228 ] 

+

1229 pad_size = -3 * gef.arch.ptrsize & (gef.heap.malloc_alignment - 1) 

+

1230 fields += [ 

+

1231 ("pad", ctypes.c_uint8*pad_size) 

+

1232 ] 

+

1233 heap_info_cls._fields_ = fields 

+

1234 return heap_info_cls 

+

1235 

+

1236 def __init__(self, addr: Union[str, int]) -> None: 

+

1237 self.__address : int = parse_address(f"&{addr}") if isinstance(addr, str) else addr 

+

1238 self.reset() 

+

1239 return 

+

1240 

+

1241 def reset(self): 

+

1242 self._sizeof = ctypes.sizeof(GlibcHeapInfo.heap_info_t()) 

+

1243 self._data = gef.memory.read(self.__address, ctypes.sizeof(GlibcHeapInfo.heap_info_t())) 

+

1244 self._heap_info = GlibcHeapInfo.heap_info_t().from_buffer_copy(self._data) 

+

1245 return 

+

1246 

+

1247 def __getattr__(self, item: Any) -> Any: 

+

1248 if item in dir(self._heap_info): 1248 ↛ 1250line 1248 didn't jump to line 1250, because the condition on line 1248 was never false

+

1249 return ctypes.cast(getattr(self._heap_info, item), ctypes.c_void_p).value 

+

1250 return getattr(self, item) 

+

1251 

+

1252 def __abs__(self) -> int: 

+

1253 return self.__address 

+

1254 

+

1255 def __int__(self) -> int: 

+

1256 return self.__address 

+

1257 

+

1258 @property 

+

1259 def address(self) -> int: 

+

1260 return self.__address 

+

1261 

+

1262 @property 

+

1263 def sizeof(self) -> int: 

+

1264 return self._sizeof 

+

1265 

+

1266 @property 

+

1267 def addr(self) -> int: 

+

1268 return int(self) 

+

1269 

+

1270 @property 

+

1271 def heap_start(self) -> int: 

+

1272 # check special case: first heap of non-main-arena 

+

1273 if self.ar_ptr - self.address < 0x60: 1273 ↛ 1285line 1273 didn't jump to line 1285, because the condition on line 1273 was never false

+

1274 # the first heap of a non-main-arena starts with a `heap_info` 

+

1275 # struct, which should fit easily into 0x60 bytes throughout 

+

1276 # all architectures and glibc versions. If this check succeeds 

+

1277 # then we are currently looking at such a "first heap" 

+

1278 arena = GlibcArena(f"*{self.ar_ptr:#x}") 

+

1279 heap_addr = arena.heap_addr() 

+

1280 if heap_addr: 1280 ↛ 1283line 1280 didn't jump to line 1283, because the condition on line 1280 was never false

+

1281 return heap_addr 

+

1282 else: 

+

1283 err(f"Cannot find heap address for arena {self.ar_ptr:#x}") 

+

1284 return 0 

+

1285 return self.address + self.sizeof 

+

1286 

+

1287 @property 

+

1288 def heap_end(self) -> int: 

+

1289 return self.address + self.size 

+

1290 

+

1291 

+

1292class GlibcArena: 

+

1293 """Glibc arena class""" 

+

1294 

+

1295 NFASTBINS = 10 

+

1296 NBINS = 128 

+

1297 NSMALLBINS = 64 

+

1298 BINMAPSHIFT = 5 

+

1299 BITSPERMAP = 1 << BINMAPSHIFT 

+

1300 BINMAPSIZE = NBINS // BITSPERMAP 

+

1301 

+

1302 @staticmethod 

+

1303 def malloc_state_t() -> Type[ctypes.Structure]: 

+

1304 pointer = ctypes.c_uint64 if gef and gef.arch.ptrsize == 8 else ctypes.c_uint32 

+

1305 fields = [ 

+

1306 ("mutex", ctypes.c_uint32), 

+

1307 ("flags", ctypes.c_uint32), 

+

1308 ] 

+

1309 if gef and gef.libc.version and gef.libc.version >= (2, 27): 1309 ↛ 1315line 1309 didn't jump to line 1315, because the condition on line 1309 was never false

+

1310 # https://elixir.bootlin.com/glibc/glibc-2.27/source/malloc/malloc.c#L1684 

+

1311 fields += [ 

+

1312 ("have_fastchunks", ctypes.c_uint32), 

+

1313 ("UNUSED_c", ctypes.c_uint32), # padding to align to 0x10 

+

1314 ] 

+

1315 fields += [ 

+

1316 ("fastbinsY", GlibcArena.NFASTBINS * pointer), 

+

1317 ("top", pointer), 

+

1318 ("last_remainder", pointer), 

+

1319 ("bins", (GlibcArena.NBINS * 2 - 2) * pointer), 

+

1320 ("binmap", GlibcArena.BINMAPSIZE * ctypes.c_uint32), 

+

1321 ("next", pointer), 

+

1322 ("next_free", pointer) 

+

1323 ] 

+

1324 if gef and gef.libc.version and gef.libc.version >= (2, 23): 1324 ↛ 1329line 1324 didn't jump to line 1329, because the condition on line 1324 was never false

+

1325 # https://elixir.bootlin.com/glibc/glibc-2.23/source/malloc/malloc.c#L1719 

+

1326 fields += [ 

+

1327 ("attached_threads", pointer) 

+

1328 ] 

+

1329 fields += [ 

+

1330 ("system_mem", pointer), 

+

1331 ("max_system_mem", pointer), 

+

1332 ] 

+

1333 class malloc_state_cls(ctypes.Structure): 

+

1334 _fields_ = fields 

+

1335 return malloc_state_cls 

+

1336 

+

1337 def __init__(self, addr: str) -> None: 

+

1338 try: 

+

1339 self.__address : int = parse_address(f"&{addr}") 

+

1340 except gdb.error: 

+

1341 self.__address : int = GefHeapManager.find_main_arena_addr() 

+

1342 # if `find_main_arena_addr` throws `gdb.error` on symbol lookup: 

+

1343 # it means the session is not started, so just propagate the exception 

+

1344 self.reset() 

+

1345 return 

+

1346 

+

1347 def reset(self): 

+

1348 self._sizeof = ctypes.sizeof(GlibcArena.malloc_state_t()) 

+

1349 self._data = gef.memory.read(self.__address, ctypes.sizeof(GlibcArena.malloc_state_t())) 

+

1350 self.__arena = GlibcArena.malloc_state_t().from_buffer_copy(self._data) 

+

1351 return 

+

1352 

+

1353 def __abs__(self) -> int: 

+

1354 return self.__address 

+

1355 

+

1356 def __int__(self) -> int: 

+

1357 return self.__address 

+

1358 

+

1359 def __iter__(self) -> Generator["GlibcArena", None, None]: 

+

1360 main_arena = int(gef.heap.main_arena) 

+

1361 

+

1362 current_arena = self 

+

1363 yield current_arena 

+

1364 

+

1365 while True: 

+

1366 if current_arena.next == 0 or current_arena.next == main_arena: 

+

1367 break 

+

1368 

+

1369 current_arena = GlibcArena(f"*{current_arena.next:#x} ") 

+

1370 yield current_arena 

+

1371 return 

+

1372 

+

1373 def __eq__(self, other: "GlibcArena") -> bool: 

+

1374 return self.__address == int(other) 

+

1375 

+

1376 def __str__(self) -> str: 

+

1377 properties = f"base={self.__address:#x}, top={self.top:#x}, " \ 

+

1378 f"last_remainder={self.last_remainder:#x}, next={self.next:#x}" 

+

1379 return (f"{Color.colorify('Arena', 'blue bold underline')}({properties})") 

+

1380 

+

1381 def __repr__(self) -> str: 

+

1382 return f"GlibcArena(address={self.__address:#x}, size={self._sizeof})" 

+

1383 

+

1384 @property 

+

1385 def address(self) -> int: 

+

1386 return self.__address 

+

1387 

+

1388 @property 

+

1389 def sizeof(self) -> int: 

+

1390 return self._sizeof 

+

1391 

+

1392 @property 

+

1393 def addr(self) -> int: 

+

1394 return int(self) 

+

1395 

+

1396 @property 

+

1397 def top(self) -> int: 

+

1398 return self.__arena.top 

+

1399 

+

1400 @property 

+

1401 def last_remainder(self) -> int: 

+

1402 return self.__arena.last_remainder 

+

1403 

+

1404 @property 

+

1405 def fastbinsY(self) -> ctypes.Array: 

+

1406 return self.__arena.fastbinsY 

+

1407 

+

1408 @property 

+

1409 def bins(self) -> ctypes.Array: 

+

1410 return self.__arena.bins 

+

1411 

+

1412 @property 

+

1413 def binmap(self) -> ctypes.Array: 

+

1414 return self.__arena.binmap 

+

1415 

+

1416 @property 

+

1417 def next(self) -> int: 

+

1418 return self.__arena.next 

+

1419 

+

1420 @property 

+

1421 def next_free(self) -> int: 

+

1422 return self.__arena.next_free 

+

1423 

+

1424 @property 

+

1425 def attached_threads(self) -> int: 

+

1426 return self.__arena.attached_threads 

+

1427 

+

1428 @property 

+

1429 def system_mem(self) -> int: 

+

1430 return self.__arena.system_mem 

+

1431 

+

1432 @property 

+

1433 def max_system_mem(self) -> int: 

+

1434 return self.__arena.max_system_mem 

+

1435 

+

1436 def fastbin(self, i: int) -> Optional["GlibcFastChunk"]: 

+

1437 """Return head chunk in fastbinsY[i].""" 

+

1438 addr = int(self.fastbinsY[i]) 

+

1439 if addr == 0: 

+

1440 return None 

+

1441 return GlibcFastChunk(addr + 2 * gef.arch.ptrsize) 

+

1442 

+

1443 def bin(self, i: int) -> Tuple[int, int]: 

+

1444 idx = i * 2 

+

1445 fd = int(self.bins[idx]) 

+

1446 bk = int(self.bins[idx + 1]) 

+

1447 return fd, bk 

+

1448 

+

1449 def bin_at(self, i) -> int: 

+

1450 header_sz = 2 * gef.arch.ptrsize 

+

1451 offset = ctypes.addressof(self.__arena.bins) - ctypes.addressof(self.__arena) 

+

1452 return self.__address + offset + (i-1) * 2 * gef.arch.ptrsize + header_sz 

+

1453 

+

1454 def is_main_arena(self) -> bool: 

+

1455 return gef.heap.main_arena is not None and int(self) == int(gef.heap.main_arena) 

+

1456 

+

1457 def heap_addr(self, allow_unaligned: bool = False) -> Optional[int]: 

+

1458 if self.is_main_arena(): 

+

1459 heap_section = gef.heap.base_address 

+

1460 if not heap_section: 1460 ↛ 1461line 1460 didn't jump to line 1461, because the condition on line 1460 was never true

+

1461 return None 

+

1462 return heap_section 

+

1463 _addr = int(self) + self.sizeof 

+

1464 if allow_unaligned: 1464 ↛ 1465line 1464 didn't jump to line 1465, because the condition on line 1464 was never true

+

1465 return _addr 

+

1466 return gef.heap.malloc_align_address(_addr) 

+

1467 

+

1468 def get_heap_info_list(self) -> Optional[List[GlibcHeapInfo]]: 

+

1469 if self.is_main_arena(): 1469 ↛ 1470line 1469 didn't jump to line 1470, because the condition on line 1469 was never true

+

1470 return None 

+

1471 heap_addr = self.get_heap_for_ptr(self.top) 

+

1472 heap_infos = [GlibcHeapInfo(heap_addr)] 

+

1473 while heap_infos[-1].prev is not None: 1473 ↛ 1474line 1473 didn't jump to line 1474, because the condition on line 1473 was never true

+

1474 prev = int(heap_infos[-1].prev) 

+

1475 heap_info = GlibcHeapInfo(prev) 

+

1476 heap_infos.append(heap_info) 

+

1477 return heap_infos[::-1] 

+

1478 

+

1479 @staticmethod 

+

1480 def get_heap_for_ptr(ptr: int) -> int: 

+

1481 """Find the corresponding heap for a given pointer (int). 

+

1482 See https://github.com/bminor/glibc/blob/glibc-2.34/malloc/arena.c#L129""" 

+

1483 if is_32bit(): 1483 ↛ 1484line 1483 didn't jump to line 1484, because the condition on line 1483 was never true

+

1484 default_mmap_threshold_max = 512 * 1024 

+

1485 else: # 64bit 

+

1486 default_mmap_threshold_max = 4 * 1024 * 1024 * cached_lookup_type("long").sizeof 

+

1487 heap_max_size = 2 * default_mmap_threshold_max 

+

1488 return ptr & ~(heap_max_size - 1) 

+

1489 

+

1490 @staticmethod 

+

1491 def verify(addr: int) -> bool: 

+

1492 """Verify that the address matches a possible valid GlibcArena""" 

+

1493 try: 

+

1494 test_arena = GlibcArena(f"*{addr:#x}") 

+

1495 cur_arena = GlibcArena(f"*{test_arena.next:#x}") 

+

1496 while cur_arena != test_arena: 

+

1497 if cur_arena == 0: 

+

1498 return False 

+

1499 cur_arena = GlibcArena(f"*{cur_arena.next:#x}") 

+

1500 except Exception as e: 

+

1501 return False 

+

1502 return True 

+

1503 

+

1504 

+

1505class GlibcChunk: 

+

1506 """Glibc chunk class. The default behavior (from_base=False) is to interpret the data starting at the memory 

+

1507 address pointed to as the chunk data. Setting from_base to True instead treats that data as the chunk header. 

+

1508 Ref: https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/.""" 

+

1509 

+

1510 class ChunkFlags(enum.IntFlag): 

+

1511 PREV_INUSE = 1 

+

1512 IS_MMAPPED = 2 

+

1513 NON_MAIN_ARENA = 4 

+

1514 

+

1515 def __str__(self) -> str: 

+

1516 return f" | ".join([ 

+

1517 Color.greenify("PREV_INUSE") if self.value & self.PREV_INUSE else Color.redify("PREV_INUSE"), 

+

1518 Color.greenify("IS_MMAPPED") if self.value & self.IS_MMAPPED else Color.redify("IS_MMAPPED"), 

+

1519 Color.greenify("NON_MAIN_ARENA") if self.value & self.NON_MAIN_ARENA else Color.redify("NON_MAIN_ARENA") 

+

1520 ]) 

+

1521 

+

1522 @staticmethod 

+

1523 def malloc_chunk_t() -> Type[ctypes.Structure]: 

+

1524 pointer = ctypes.c_uint64 if gef and gef.arch.ptrsize == 8 else ctypes.c_uint32 

+

1525 class malloc_chunk_cls(ctypes.Structure): 

+

1526 pass 

+

1527 

+

1528 malloc_chunk_cls._fields_ = [ 

+

1529 ("prev_size", pointer), 

+

1530 ("size", pointer), 

+

1531 ("fd", pointer), 

+

1532 ("bk", pointer), 

+

1533 ("fd_nextsize", ctypes.POINTER(malloc_chunk_cls)), 

+

1534 ("bk_nextsize", ctypes.POINTER(malloc_chunk_cls)), 

+

1535 ] 

+

1536 return malloc_chunk_cls 

+

1537 

+

1538 def __init__(self, addr: int, from_base: bool = False, allow_unaligned: bool = True) -> None: 

+

1539 ptrsize = gef.arch.ptrsize 

+

1540 self.data_address = addr + 2 * ptrsize if from_base else addr 

+

1541 self.base_address = addr if from_base else addr - 2 * ptrsize 

+

1542 if not allow_unaligned: 

+

1543 self.data_address = gef.heap.malloc_align_address(self.data_address) 

+

1544 self.size_addr = int(self.data_address - ptrsize) 

+

1545 self.prev_size_addr = self.base_address 

+

1546 self.reset() 

+

1547 return 

+

1548 

+

1549 def reset(self): 

+

1550 self._sizeof = ctypes.sizeof(GlibcChunk.malloc_chunk_t()) 

+

1551 self._data = gef.memory.read( 

+

1552 self.base_address, ctypes.sizeof(GlibcChunk.malloc_chunk_t())) 

+

1553 self._chunk = GlibcChunk.malloc_chunk_t().from_buffer_copy(self._data) 

+

1554 return 

+

1555 

+

1556 @property 

+

1557 def prev_size(self) -> int: 

+

1558 return self._chunk.prev_size 

+

1559 

+

1560 @property 

+

1561 def size(self) -> int: 

+

1562 return self._chunk.size & (~0x07) 

+

1563 

+

1564 @property 

+

1565 def flags(self) -> ChunkFlags: 

+

1566 return GlibcChunk.ChunkFlags(self._chunk.size & 0x07) 

+

1567 

+

1568 @property 

+

1569 def fd(self) -> int: 

+

1570 return self._chunk.fd 

+

1571 

+

1572 @property 

+

1573 def bk(self) -> int: 

+

1574 return self._chunk.bk 

+

1575 

+

1576 @property 

+

1577 def fd_nextsize(self) -> int: 

+

1578 return self._chunk.fd_nextsize 

+

1579 

+

1580 @property 

+

1581 def bk_nextsize(self) -> int: 

+

1582 return self._chunk.bk_nextsize 

+

1583 

+

1584 def get_usable_size(self) -> int: 

+

1585 # https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L4537 

+

1586 ptrsz = gef.arch.ptrsize 

+

1587 cursz = self.size 

+

1588 if cursz == 0: return cursz 1588 ↛ exitline 1588 didn't return from function 'get_usable_size', because the return on line 1588 wasn't executed

+

1589 if self.has_m_bit(): return cursz - 2 * ptrsz 1589 ↛ exitline 1589 didn't return from function 'get_usable_size', because the return on line 1589 wasn't executed

+

1590 return cursz - ptrsz 

+

1591 

+

1592 @property 

+

1593 def usable_size(self) -> int: 

+

1594 return self.get_usable_size() 

+

1595 

+

1596 def get_prev_chunk_size(self) -> int: 

+

1597 return gef.memory.read_integer(self.prev_size_addr) 

+

1598 

+

1599 def __iter__(self) -> Generator["GlibcChunk", None, None]: 

+

1600 current_chunk = self 

+

1601 top = gef.heap.main_arena.top 

+

1602 

+

1603 while True: 

+

1604 yield current_chunk 

+

1605 

+

1606 if current_chunk.base_address == top: 1606 ↛ 1607line 1606 didn't jump to line 1607, because the condition on line 1606 was never true

+

1607 break 

+

1608 

+

1609 if current_chunk.size == 0: 1609 ↛ 1610line 1609 didn't jump to line 1610, because the condition on line 1609 was never true

+

1610 break 

+

1611 

+

1612 next_chunk_addr = current_chunk.get_next_chunk_addr() 

+

1613 

+

1614 if not Address(value=next_chunk_addr).valid: 1614 ↛ 1615line 1614 didn't jump to line 1615, because the condition on line 1614 was never true

+

1615 break 

+

1616 

+

1617 next_chunk = current_chunk.get_next_chunk() 

+

1618 if next_chunk is None: 1618 ↛ 1619line 1618 didn't jump to line 1619, because the condition on line 1618 was never true

+

1619 break 

+

1620 

+

1621 current_chunk = next_chunk 

+

1622 return 

+

1623 

+

1624 def get_next_chunk(self, allow_unaligned: bool = False) -> "GlibcChunk": 

+

1625 addr = self.get_next_chunk_addr() 

+

1626 return GlibcChunk(addr, allow_unaligned=allow_unaligned) 

+

1627 

+

1628 def get_next_chunk_addr(self) -> int: 

+

1629 return self.data_address + self.size 

+

1630 

+

1631 def has_p_bit(self) -> bool: 

+

1632 return bool(self.flags & GlibcChunk.ChunkFlags.PREV_INUSE) 

+

1633 

+

1634 def has_m_bit(self) -> bool: 

+

1635 return bool(self.flags & GlibcChunk.ChunkFlags.IS_MMAPPED) 

+

1636 

+

1637 def has_n_bit(self) -> bool: 

+

1638 return bool(self.flags & GlibcChunk.ChunkFlags.NON_MAIN_ARENA) 

+

1639 

+

1640 def is_used(self) -> bool: 

+

1641 """Check if the current block is used by: 

+

1642 - checking the M bit is true 

+

1643 - or checking that next chunk PREV_INUSE flag is true""" 

+

1644 if self.has_m_bit(): 1644 ↛ 1645line 1644 didn't jump to line 1645, because the condition on line 1644 was never true

+

1645 return True 

+

1646 

+

1647 next_chunk = self.get_next_chunk() 

+

1648 return True if next_chunk.has_p_bit() else False 

+

1649 

+

1650 def __str_sizes(self) -> str: 

+

1651 msg = [] 

+

1652 failed = False 

+

1653 

+

1654 try: 

+

1655 msg.append("Chunk size: {0:d} ({0:#x})".format(self.size)) 

+

1656 msg.append("Usable size: {0:d} ({0:#x})".format(self.usable_size)) 

+

1657 failed = True 

+

1658 except gdb.MemoryError: 

+

1659 msg.append(f"Chunk size: Cannot read at {self.size_addr:#x} (corrupted?)") 

+

1660 

+

1661 try: 

+

1662 msg.append("Previous chunk size: {0:d} ({0:#x})".format(self.get_prev_chunk_size())) 

+

1663 failed = True 

+

1664 except gdb.MemoryError: 

+

1665 msg.append(f"Previous chunk size: Cannot read at {self.base_address:#x} (corrupted?)") 

+

1666 

+

1667 if failed: 1667 ↛ 1670line 1667 didn't jump to line 1670, because the condition on line 1667 was never false

+

1668 msg.append(str(self.flags)) 

+

1669 

+

1670 return "\n".join(msg) 

+

1671 

+

1672 def _str_pointers(self) -> str: 

+

1673 fwd = self.data_address 

+

1674 bkw = self.data_address + gef.arch.ptrsize 

+

1675 

+

1676 msg = [] 

+

1677 try: 

+

1678 msg.append(f"Forward pointer: {self.fd:#x}") 

+

1679 except gdb.MemoryError: 

+

1680 msg.append(f"Forward pointer: {fwd:#x} (corrupted?)") 

+

1681 

+

1682 try: 

+

1683 msg.append(f"Backward pointer: {self.bk:#x}") 

+

1684 except gdb.MemoryError: 

+

1685 msg.append(f"Backward pointer: {bkw:#x} (corrupted?)") 

+

1686 

+

1687 return "\n".join(msg) 

+

1688 

+

1689 def __str__(self) -> str: 

+

1690 return (f"{Color.colorify('Chunk', 'yellow bold underline')}(addr={self.data_address:#x}, " 

+

1691 f"size={self.size:#x}, flags={self.flags!s})") 

+

1692 

+

1693 def psprint(self) -> str: 

+

1694 msg = [ 

+

1695 str(self), 

+

1696 self.__str_sizes(), 

+

1697 ] 

+

1698 if not self.is_used(): 1698 ↛ 1699line 1698 didn't jump to line 1699, because the condition on line 1698 was never true

+

1699 msg.append(f"\n\n{self._str_pointers()}") 

+

1700 return "\n".join(msg) + "\n" 

+

1701 

+

1702 

+

1703class GlibcFastChunk(GlibcChunk): 

+

1704 

+

1705 @property 

+

1706 def fd(self) -> int: 

+

1707 assert(gef and gef.libc.version) 

+

1708 if gef.libc.version < (2, 32): 1708 ↛ 1709line 1708 didn't jump to line 1709, because the condition on line 1708 was never true

+

1709 return self._chunk.fd 

+

1710 return self.reveal_ptr(self.data_address) 

+

1711 

+

1712 def protect_ptr(self, pos: int, pointer: int) -> int: 

+

1713 """https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L339""" 

+

1714 assert(gef and gef.libc.version) 

+

1715 if gef.libc.version < (2, 32): 

+

1716 return pointer 

+

1717 return (pos >> 12) ^ pointer 

+

1718 

+

1719 def reveal_ptr(self, pointer: int) -> int: 

+

1720 """https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L341""" 

+

1721 assert(gef and gef.libc.version) 

+

1722 if gef.libc.version < (2, 32): 1722 ↛ 1723line 1722 didn't jump to line 1723, because the condition on line 1722 was never true

+

1723 return pointer 

+

1724 return gef.memory.read_integer(pointer) ^ (pointer >> 12) 

+

1725 

+

1726class GlibcTcacheChunk(GlibcFastChunk): 

+

1727 

+

1728 pass 

+

1729 

+

1730@deprecated("Use GefLibcManager.find_libc_version()") 

+

1731def get_libc_version() -> Tuple[int, ...]: 

+

1732 return GefLibcManager.find_libc_version() 

+

1733 

+

1734def titlify(text: str, color: Optional[str] = None, msg_color: Optional[str] = None) -> str: 

+

1735 """Print a centered title.""" 

+

1736 _, cols = get_terminal_size() 

+

1737 nb = (cols - len(text) - 2) // 2 

+

1738 line_color = color or gef.config["theme.default_title_line"] 

+

1739 text_color = msg_color or gef.config["theme.default_title_message"] 

+

1740 

+

1741 msg = [Color.colorify(f"{HORIZONTAL_LINE * nb} ", line_color), 

+

1742 Color.colorify(text, text_color), 

+

1743 Color.colorify(f" {HORIZONTAL_LINE * nb}", line_color)] 

+

1744 return "".join(msg) 

+

1745 

+

1746 

+

1747def dbg(msg: str) -> None: 

+

1748 if gef.config["gef.debug"] is True: 1748 ↛ 1750line 1748 didn't jump to line 1750, because the condition on line 1748 was never false

+

1749 gef_print(f"{Color.colorify('[=]', 'bold cyan')} {msg}") 

+

1750 return 

+

1751 

+

1752 

+

1753def err(msg: str) -> None: 

+

1754 gef_print(f"{Color.colorify('[!]', 'bold red')} {msg}") 

+

1755 return 

+

1756 

+

1757 

+

1758def warn(msg: str) -> None: 

+

1759 gef_print(f"{Color.colorify('[*]', 'bold yellow')} {msg}") 

+

1760 return 

+

1761 

+

1762 

+

1763def ok(msg: str) -> None: 

+

1764 gef_print(f"{Color.colorify('[+]', 'bold green')} {msg}") 

+

1765 return 

+

1766 

+

1767 

+

1768def info(msg: str) -> None: 

+

1769 gef_print(f"{Color.colorify('[+]', 'bold blue')} {msg}") 

+

1770 return 

+

1771 

+

1772 

+

1773def push_context_message(level: str, message: str) -> None: 

+

1774 """Push the message to be displayed the next time the context is invoked.""" 

+

1775 if level not in ("error", "warn", "ok", "info"): 1775 ↛ 1776line 1775 didn't jump to line 1776, because the condition on line 1775 was never true

+

1776 err(f"Invalid level '{level}', discarding message") 

+

1777 return 

+

1778 gef.ui.context_messages.append((level, message)) 

+

1779 return 

+

1780 

+

1781 

+

1782def show_last_exception() -> None: 

+

1783 """Display the last Python exception.""" 

+

1784 

+

1785 def _show_code_line(fname: str, idx: int) -> str: 

+

1786 fname = os.path.expanduser(os.path.expandvars(fname)) 

+

1787 with open(fname, "r") as f: 

+

1788 _data = f.readlines() 

+

1789 return _data[idx - 1] if 0 < idx < len(_data) else "" 

+

1790 

+

1791 gef_print("") 

+

1792 exc_type, exc_value, exc_traceback = sys.exc_info() 

+

1793 

+

1794 gef_print(" Exception raised ".center(80, HORIZONTAL_LINE)) 

+

1795 gef_print(f"{Color.colorify(exc_type.__name__, 'bold underline red')}: {exc_value}") 

+

1796 gef_print(" Detailed stacktrace ".center(80, HORIZONTAL_LINE)) 

+

1797 

+

1798 for fs in traceback.extract_tb(exc_traceback)[::-1]: 

+

1799 filename, lineno, method, code = fs 

+

1800 

+

1801 if not code or not code.strip(): 1801 ↛ 1802line 1801 didn't jump to line 1802, because the condition on line 1801 was never true

+

1802 code = _show_code_line(filename, lineno) 

+

1803 

+

1804 gef_print(f"""{DOWN_ARROW} File "{Color.yellowify(filename)}", line {lineno:d}, in {Color.greenify(method)}()""") 

+

1805 gef_print(f" {RIGHT_ARROW} {code}") 

+

1806 

+

1807 gef_print(" Version ".center(80, HORIZONTAL_LINE)) 

+

1808 gdb.execute("version full") 

+

1809 gef_print(" Last 10 GDB commands ".center(80, HORIZONTAL_LINE)) 

+

1810 gdb.execute("show commands") 

+

1811 gef_print(" Runtime environment ".center(80, HORIZONTAL_LINE)) 

+

1812 gef_print(f"* GDB: {gdb.VERSION}") 

+

1813 gef_print(f"* Python: {sys.version_info.major:d}.{sys.version_info.minor:d}.{sys.version_info.micro:d} - {sys.version_info.releaselevel}") 

+

1814 gef_print(f"* OS: {platform.system()} - {platform.release()} ({platform.machine()})") 

+

1815 

+

1816 try: 

+

1817 lsb_release = which("lsb_release") 

+

1818 gdb.execute(f"!{lsb_release} -a") 

+

1819 except FileNotFoundError: 

+

1820 gef_print("lsb_release is missing, cannot collect additional debug information") 

+

1821 

+

1822 gef_print(HORIZONTAL_LINE*80) 

+

1823 gef_print("") 

+

1824 return 

+

1825 

+

1826 

+

1827def gef_pystring(x: bytes) -> str: 

+

1828 """Returns a sanitized version as string of the bytes list given in input.""" 

+

1829 res = str(x, encoding="utf-8") 

+

1830 substs = [("\n", "\\n"), ("\r", "\\r"), ("\t", "\\t"), ("\v", "\\v"), ("\b", "\\b"), ] 

+

1831 for x, y in substs: res = res.replace(x, y) 

+

1832 return res 

+

1833 

+

1834 

+

1835def gef_pybytes(x: str) -> bytes: 

+

1836 """Returns an immutable bytes list from the string given as input.""" 

+

1837 return bytes(str(x), encoding="utf-8") 

+

1838 

+

1839 

+

1840@lru_cache() 

+

1841def which(program: str) -> pathlib.Path: 

+

1842 """Locate a command on the filesystem.""" 

+

1843 for path in os.environ["PATH"].split(os.pathsep): 

+

1844 dirname = pathlib.Path(path) 

+

1845 fpath = dirname / program 

+

1846 if os.access(fpath, os.X_OK): 

+

1847 return fpath 

+

1848 

+

1849 raise FileNotFoundError(f"Missing file `{program}`") 

+

1850 

+

1851 

+

1852def style_byte(b: int, color: bool = True) -> str: 

+

1853 style = { 

+

1854 "nonprintable": "yellow", 

+

1855 "printable": "white", 

+

1856 "00": "gray", 

+

1857 "0a": "blue", 

+

1858 "ff": "green", 

+

1859 } 

+

1860 sbyte = f"{b:02x}" 

+

1861 if not color or gef.config["highlight.regex"]: 

+

1862 return sbyte 

+

1863 

+

1864 if sbyte in style: 

+

1865 st = style[sbyte] 

+

1866 elif chr(b) in (string.ascii_letters + string.digits + string.punctuation + " "): 

+

1867 st = style.get("printable") 

+

1868 else: 

+

1869 st = style.get("nonprintable") 

+

1870 if st: 1870 ↛ 1872line 1870 didn't jump to line 1872, because the condition on line 1870 was never false

+

1871 sbyte = Color.colorify(sbyte, st) 

+

1872 return sbyte 

+

1873 

+

1874 

+

1875def hexdump(source: ByteString, length: int = 0x10, separator: str = ".", show_raw: bool = False, show_symbol: bool = True, base: int = 0x00) -> str: 

+

1876 """Return the hexdump of `src` argument. 

+

1877 @param source *MUST* be of type bytes or bytearray 

+

1878 @param length is the length of items per line 

+

1879 @param separator is the default character to use if one byte is not printable 

+

1880 @param show_raw if True, do not add the line nor the text translation 

+

1881 @param base is the start address of the block being hexdump 

+

1882 @return a string with the hexdump""" 

+

1883 result = [] 

+

1884 align = gef.arch.ptrsize * 2 + 2 if is_alive() else 18 

+

1885 

+

1886 for i in range(0, len(source), length): 

+

1887 chunk = bytearray(source[i : i + length]) 

+

1888 hexa = " ".join([style_byte(b, color=not show_raw) for b in chunk]) 

+

1889 

+

1890 if show_raw: 

+

1891 result.append(hexa) 

+

1892 continue 

+

1893 

+

1894 text = "".join([chr(b) if 0x20 <= b < 0x7F else separator for b in chunk]) 

+

1895 if show_symbol: 1895 ↛ 1899line 1895 didn't jump to line 1899, because the condition on line 1895 was never false

+

1896 sym = gdb_get_location_from_symbol(base + i) 

+

1897 sym = "<{:s}+{:04x}>".format(*sym) if sym else "" 

+

1898 else: 

+

1899 sym = "" 

+

1900 

+

1901 result.append(f"{base + i:#0{align}x} {sym} {hexa:<{3 * length}} {text}") 

+

1902 return "\n".join(result) 

+

1903 

+

1904 

+

1905def is_debug() -> bool: 

+

1906 """Check if debug mode is enabled.""" 

+

1907 return gef.config["gef.debug"] is True 

+

1908 

+

1909 

+

1910def buffer_output() -> bool: 

+

1911 """Check if output should be buffered until command completion.""" 

+

1912 return gef.config["gef.buffer"] is True 

+

1913 

+

1914 

+

1915def hide_context() -> bool: 

+

1916 """Helper function to hide the context pane.""" 

+

1917 gef.ui.context_hidden = True 

+

1918 return True 

+

1919 

+

1920 

+

1921def unhide_context() -> bool: 

+

1922 """Helper function to unhide the context pane.""" 

+

1923 gef.ui.context_hidden = False 

+

1924 return True 

+

1925 

+

1926 

+

1927class DisableContextOutputContext: 

+

1928 def __enter__(self) -> None: 

+

1929 hide_context() 

+

1930 return 

+

1931 

+

1932 def __exit__(self, *exc: Any) -> None: 

+

1933 unhide_context() 

+

1934 return 

+

1935 

+

1936 

+

1937class RedirectOutputContext: 

+

1938 def __init__(self, to: str = "/dev/null") -> None: 

+

1939 self.redirection_target_file = to 

+

1940 return 

+

1941 

+

1942 def __enter__(self) -> None: 

+

1943 """Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`.""" 

+

1944 gdb.execute("set logging overwrite") 

+

1945 gdb.execute(f"set logging file {self.redirection_target_file}") 

+

1946 gdb.execute("set logging redirect on") 

+

1947 gdb.execute("set logging on") 

+

1948 return 

+

1949 

+

1950 def __exit__(self, *exc: Any) -> None: 

+

1951 """Disable the output redirection, if any.""" 

+

1952 gdb.execute("set logging off") 

+

1953 gdb.execute("set logging redirect off") 

+

1954 return 

+

1955 

+

1956 

+

1957def enable_redirect_output(to_file: str = "/dev/null") -> None: 

+

1958 """Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`.""" 

+

1959 gdb.execute("set logging overwrite") 

+

1960 gdb.execute(f"set logging file {to_file}") 

+

1961 gdb.execute("set logging redirect on") 

+

1962 gdb.execute("set logging on") 

+

1963 return 

+

1964 

+

1965 

+

1966def disable_redirect_output() -> None: 

+

1967 """Disable the output redirection, if any.""" 

+

1968 gdb.execute("set logging off") 

+

1969 gdb.execute("set logging redirect off") 

+

1970 return 

+

1971 

+

1972 

+

1973def gef_makedirs(path: str, mode: int = 0o755) -> pathlib.Path: 

+

1974 """Recursive mkdir() creation. If successful, return the absolute path of the directory created.""" 

+

1975 fpath = pathlib.Path(path) 

+

1976 if not fpath.is_dir(): 

+

1977 fpath.mkdir(mode=mode, exist_ok=True, parents=True) 

+

1978 return fpath.absolute() 

+

1979 

+

1980 

+

1981@lru_cache() 

+

1982def gdb_lookup_symbol(sym: str) -> Optional[Tuple[Optional[str], Optional[Tuple[gdb.Symtab_and_line, ...]]]]: 

+

1983 """Fetch the proper symbol or None if not defined.""" 

+

1984 try: 

+

1985 return gdb.decode_line(sym)[1] 

+

1986 except gdb.error: 

+

1987 return None 

+

1988 

+

1989 

+

1990@lru_cache(maxsize=512) 

+

1991def gdb_get_location_from_symbol(address: int) -> Optional[Tuple[str, int]]: 

+

1992 """Retrieve the location of the `address` argument from the symbol table. 

+

1993 Return a tuple with the name and offset if found, None otherwise.""" 

+

1994 # this is horrible, ugly hack and shitty perf... 

+

1995 # find a *clean* way to get gdb.Location from an address 

+

1996 sym = str(gdb.execute(f"info symbol {address:#x}", to_string=True)) 

+

1997 if sym.startswith("No symbol matches"): 

+

1998 return None 

+

1999 

+

2000 i = sym.find(" in section ") 

+

2001 sym = sym[:i].split() 

+

2002 name, offset = sym[0], 0 

+

2003 if len(sym) == 3 and sym[2].isdigit(): 

+

2004 offset = int(sym[2]) 

+

2005 return name, offset 

+

2006 

+

2007 

+

2008def gdb_disassemble(start_pc: int, **kwargs: int) -> Generator[Instruction, None, None]: 

+

2009 """Disassemble instructions from `start_pc` (Integer). Accepts the following named 

+

2010 parameters: 

+

2011 - `end_pc` (Integer) only instructions whose start address fall in the interval from 

+

2012 start_pc to end_pc are returned. 

+

2013 - `count` (Integer) list at most this many disassembled instructions 

+

2014 If `end_pc` and `count` are not provided, the function will behave as if `count=1`. 

+

2015 Return an iterator of Instruction objects 

+

2016 """ 

+

2017 frame = gdb.selected_frame() 

+

2018 arch = frame.architecture() 

+

2019 

+

2020 for insn in arch.disassemble(start_pc, **kwargs): 

+

2021 assert isinstance(insn["addr"], int) 

+

2022 assert isinstance(insn["length"], int) 

+

2023 assert isinstance(insn["asm"], str) 

+

2024 address = insn["addr"] 

+

2025 asm = insn["asm"].rstrip().split(None, 1) 

+

2026 if len(asm) > 1: 

+

2027 mnemo, operands = asm 

+

2028 operands = operands.split(",") 

+

2029 else: 

+

2030 mnemo, operands = asm[0], [] 

+

2031 

+

2032 loc = gdb_get_location_from_symbol(address) 

+

2033 location = "<{}+{}>".format(*loc) if loc else "" 

+

2034 

+

2035 opcodes = gef.memory.read(insn["addr"], insn["length"]) 

+

2036 

+

2037 yield Instruction(address, location, mnemo, operands, opcodes) 

+

2038 

+

2039 

+

2040def gdb_get_nth_previous_instruction_address(addr: int, n: int) -> Optional[int]: 

+

2041 """Return the address (Integer) of the `n`-th instruction before `addr`.""" 

+

2042 # fixed-length ABI 

+

2043 if gef.arch.instruction_length: 2043 ↛ 2044line 2043 didn't jump to line 2044, because the condition on line 2043 was never true

+

2044 return max(0, addr - n * gef.arch.instruction_length) 

+

2045 

+

2046 # variable-length ABI 

+

2047 cur_insn_addr = gef_current_instruction(addr).address 

+

2048 

+

2049 # we try to find a good set of previous instructions by "guessing" disassembling backwards 

+

2050 # the 15 comes from the longest instruction valid size 

+

2051 for i in range(15 * n, 0, -1): 2051 ↛ 2074line 2051 didn't jump to line 2074, because the loop on line 2051 didn't complete

+

2052 try: 

+

2053 insns = list(gdb_disassemble(addr - i, end_pc=cur_insn_addr)) 

+

2054 except gdb.MemoryError: 

+

2055 # this is because we can hit an unmapped page trying to read backward 

+

2056 break 

+

2057 

+

2058 # 1. check that the disassembled instructions list size can satisfy 

+

2059 if len(insns) < n + 1: # we expect the current instruction plus the n before it 2059 ↛ 2060line 2059 didn't jump to line 2060, because the condition on line 2059 was never true

+

2060 continue 

+

2061 

+

2062 # If the list of instructions is longer than what we need, then we 

+

2063 # could get lucky and already have more than what we need, so slice down 

+

2064 insns = insns[-n - 1 :] 

+

2065 

+

2066 # 2. check that the sequence ends with the current address 

+

2067 if insns[-1].address != cur_insn_addr: 2067 ↛ 2068line 2067 didn't jump to line 2068, because the condition on line 2067 was never true

+

2068 continue 

+

2069 

+

2070 # 3. check all instructions are valid 

+

2071 if all(insn.is_valid() for insn in insns): 2071 ↛ 2051line 2071 didn't jump to line 2051, because the condition on line 2071 was never false

+

2072 return insns[0].address 

+

2073 

+

2074 return None 

+

2075 

+

2076 

+

2077@deprecated(solution="Use `gef_instruction_n().address`") 

+

2078def gdb_get_nth_next_instruction_address(addr: int, n: int) -> int: 

+

2079 """Return the address of the `n`-th instruction after `addr`. """ 

+

2080 return gef_instruction_n(addr, n).address 

+

2081 

+

2082 

+

2083def gef_instruction_n(addr: int, n: int) -> Instruction: 

+

2084 """Return the `n`-th instruction after `addr` as an Instruction object. Note that `n` is treated as 

+

2085 an positive index, starting from 0 (current instruction address)""" 

+

2086 return list(gdb_disassemble(addr, count=n + 1))[n] 

+

2087 

+

2088 

+

2089def gef_get_instruction_at(addr: int) -> Instruction: 

+

2090 """Return the full Instruction found at the specified address.""" 

+

2091 insn = next(gef_disassemble(addr, 1)) 

+

2092 return insn 

+

2093 

+

2094 

+

2095def gef_current_instruction(addr: int) -> Instruction: 

+

2096 """Return the current instruction as an Instruction object.""" 

+

2097 return gef_instruction_n(addr, 0) 

+

2098 

+

2099 

+

2100def gef_next_instruction(addr: int) -> Instruction: 

+

2101 """Return the next instruction as an Instruction object.""" 

+

2102 return gef_instruction_n(addr, 1) 

+

2103 

+

2104 

+

2105def gef_disassemble(addr: int, nb_insn: int, nb_prev: int = 0) -> Generator[Instruction, None, None]: 

+

2106 """Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr`. 

+

2107 Return an iterator of Instruction objects.""" 

+

2108 nb_insn = max(1, nb_insn) 

+

2109 

+

2110 if nb_prev: 

+

2111 try: 

+

2112 start_addr = gdb_get_nth_previous_instruction_address(addr, nb_prev) 

+

2113 if start_addr: 

+

2114 for insn in gdb_disassemble(start_addr, count=nb_prev): 

+

2115 if insn.address == addr: break 2115 ↛ 2121line 2115 didn't jump to line 2121, because the break on line 2115 wasn't executed

+

2116 yield insn 

+

2117 except gdb.MemoryError: 

+

2118 # If the address pointing to the previous instruction(s) is not mapped, simply skip them 

+

2119 pass 

+

2120 

+

2121 for insn in gdb_disassemble(addr, count=nb_insn): 

+

2122 yield insn 

+

2123 

+

2124 

+

2125def gef_execute_external(command: Sequence[str], as_list: bool = False, **kwargs: Any) -> Union[str, List[str]]: 

+

2126 """Execute an external command and return the result.""" 

+

2127 res = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=kwargs.get("shell", False)) 

+

2128 return [gef_pystring(_) for _ in res.splitlines()] if as_list else gef_pystring(res) 

+

2129 

+

2130 

+

2131def gef_execute_gdb_script(commands: str) -> None: 

+

2132 """Execute the parameter `source` as GDB command. This is done by writing `commands` to 

+

2133 a temporary file, which is then executed via GDB `source` command. The tempfile is then deleted.""" 

+

2134 fd, fname = tempfile.mkstemp(suffix=".gdb", prefix="gef_") 

+

2135 with os.fdopen(fd, "w") as f: 

+

2136 f.write(commands) 

+

2137 f.flush() 

+

2138 

+

2139 fname = pathlib.Path(fname) 

+

2140 if fname.is_file() and os.access(fname, os.R_OK): 

+

2141 gdb.execute(f"source {fname}") 

+

2142 fname.unlink() 

+

2143 return 

+

2144 

+

2145 

+

2146@deprecated("Use Elf(fname).checksec()") 

+

2147def checksec(filename: str) -> Dict[str, bool]: 

+

2148 return Elf(filename).checksec 

+

2149 

+

2150 

+

2151@lru_cache() 

+

2152def get_arch() -> str: 

+

2153 """Return the binary's architecture.""" 

+

2154 if is_alive(): 

+

2155 arch = gdb.selected_frame().architecture() 

+

2156 return arch.name() 

+

2157 

+

2158 arch_str = gdb.execute("show architecture", to_string=True).strip() 

+

2159 pat = "The target architecture is set automatically (currently " 

+

2160 if arch_str.startswith(pat): 2160 ↛ 2161line 2160 didn't jump to line 2161, because the condition on line 2160 was never true

+

2161 arch_str = arch_str[len(pat):].rstrip(")") 

+

2162 return arch_str 

+

2163 

+

2164 pat = "The target architecture is assumed to be " 

+

2165 if arch_str.startswith(pat): 2165 ↛ 2166line 2165 didn't jump to line 2166, because the condition on line 2165 was never true

+

2166 return arch_str[len(pat):] 

+

2167 

+

2168 pat = "The target architecture is set to " 

+

2169 if arch_str.startswith(pat): 2169 ↛ 2176line 2169 didn't jump to line 2176, because the condition on line 2169 was never false

+

2170 # GDB version >= 10.1 

+

2171 if '"auto"' in arch_str: 2171 ↛ 2173line 2171 didn't jump to line 2173, because the condition on line 2171 was never false

+

2172 return re.findall(r"currently \"(.+)\"", arch_str)[0] 

+

2173 return re.findall(r"\"(.+)\"", arch_str)[0] 

+

2174 

+

2175 # Unknown, we throw an exception to be safe 

+

2176 raise RuntimeError(f"Unknown architecture: {arch_str}") 

+

2177 

+

2178 

+

2179@deprecated("Use `gef.binary.entry_point` instead") 

+

2180def get_entry_point() -> Optional[int]: 

+

2181 """Return the binary entry point.""" 

+

2182 return gef.binary.entry_point if gef.binary else None 

+

2183 

+

2184 

+

2185def is_pie(fpath: str) -> bool: 

+

2186 return Elf(fpath).checksec["PIE"] 

+

2187 

+

2188 

+

2189@deprecated("Prefer `gef.arch.endianness == Endianness.BIG_ENDIAN`") 

+

2190def is_big_endian() -> bool: 

+

2191 return gef.arch.endianness == Endianness.BIG_ENDIAN 

+

2192 

+

2193 

+

2194@deprecated("gef.arch.endianness == Endianness.LITTLE_ENDIAN") 

+

2195def is_little_endian() -> bool: 

+

2196 return gef.arch.endianness == Endianness.LITTLE_ENDIAN 

+

2197 

+

2198 

+

2199def flags_to_human(reg_value: int, value_table: Dict[int, str]) -> str: 

+

2200 """Return a human readable string showing the flag states.""" 

+

2201 flags = [] 

+

2202 for bit_index, name in value_table.items(): 

+

2203 flags.append(Color.boldify(name.upper()) if reg_value & (1<<bit_index) != 0 else name.lower()) 

+

2204 return f"[{' '.join(flags)}]" 

+

2205 

+

2206 

+

2207@lru_cache() 

+

2208def get_section_base_address(name: str) -> Optional[int]: 

+

2209 section = process_lookup_path(name) 

+

2210 return section.page_start if section else None 

+

2211 

+

2212 

+

2213@lru_cache() 

+

2214def get_zone_base_address(name: str) -> Optional[int]: 

+

2215 zone = file_lookup_name_path(name, get_filepath()) 

+

2216 return zone.zone_start if zone else None 

+

2217 

+

2218 

+

2219# 

+

2220# Architecture classes 

+

2221# 

+

2222@deprecated("Using the decorator `register_architecture` is unecessary") 

+

2223def register_architecture(cls: Type["Architecture"]) -> Type["Architecture"]: 

+

2224 return cls 

+

2225 

+

2226class ArchitectureBase: 

+

2227 """Class decorator for declaring an architecture to GEF.""" 

+

2228 aliases: Union[Tuple[()], Tuple[Union[str, Elf.Abi], ...]] = () 

+

2229 

+

2230 def __init_subclass__(cls: Type["ArchitectureBase"], **kwargs): 

+

2231 global __registered_architectures__ 

+

2232 super().__init_subclass__(**kwargs) 

+

2233 for key in getattr(cls, "aliases"): 

+

2234 if issubclass(cls, Architecture): 2234 ↛ 2233line 2234 didn't jump to line 2233, because the condition on line 2234 was never false

+

2235 __registered_architectures__[key] = cls 

+

2236 return 

+

2237 

+

2238 

+

2239class Architecture(ArchitectureBase): 

+

2240 """Generic metaclass for the architecture supported by GEF.""" 

+

2241 

+

2242 # Mandatory defined attributes by inheriting classes 

+

2243 arch: str 

+

2244 mode: str 

+

2245 all_registers: Union[Tuple[()], Tuple[str, ...]] 

+

2246 nop_insn: bytes 

+

2247 return_register: str 

+

2248 flag_register: Optional[str] 

+

2249 instruction_length: Optional[int] 

+

2250 flags_table: Dict[int, str] 

+

2251 syscall_register: Optional[str] 

+

2252 syscall_instructions: Union[Tuple[()], Tuple[str, ...]] 

+

2253 function_parameters: Union[Tuple[()], Tuple[str, ...]] 

+

2254 

+

2255 # Optionally defined attributes 

+

2256 _ptrsize: Optional[int] = None 

+

2257 _endianness: Optional[Endianness] = None 

+

2258 special_registers: Union[Tuple[()], Tuple[str, ...]] = () 

+

2259 

+

2260 def __init_subclass__(cls, **kwargs): 

+

2261 super().__init_subclass__(**kwargs) 

+

2262 attributes = ("arch", "mode", "aliases", "all_registers", "nop_insn", 

+

2263 "return_register", "flag_register", "instruction_length", "flags_table", 

+

2264 "function_parameters",) 

+

2265 if not all(map(lambda x: hasattr(cls, x), attributes)): 2265 ↛ 2266line 2265 didn't jump to line 2266, because the condition on line 2265 was never true

+

2266 raise NotImplementedError 

+

2267 

+

2268 def __str__(self) -> str: 

+

2269 return f"Architecture({self.arch}, {self.mode or 'None'}, {repr(self.endianness)})" 

+

2270 

+

2271 @staticmethod 

+

2272 def supports_gdb_arch(gdb_arch: str) -> Optional[bool]: 

+

2273 """If implemented by a child `Architecture`, this function dictates if the current class 

+

2274 supports the loaded ELF file (which can be accessed via `gef.binary`). This callback 

+

2275 function will override any assumption made by GEF to determine the architecture.""" 

+

2276 return None 

+

2277 

+

2278 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

2279 raise NotImplementedError 

+

2280 

+

2281 def is_call(self, insn: Instruction) -> bool: 

+

2282 raise NotImplementedError 

+

2283 

+

2284 def is_ret(self, insn: Instruction) -> bool: 

+

2285 raise NotImplementedError 

+

2286 

+

2287 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

2288 raise NotImplementedError 

+

2289 

+

2290 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

2291 raise NotImplementedError 

+

2292 

+

2293 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

2294 raise NotImplementedError 

+

2295 

+

2296 def canary_address(self) -> int: 

+

2297 raise NotImplementedError 

+

2298 

+

2299 @classmethod 

+

2300 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2301 raise NotImplementedError 

+

2302 

+

2303 def reset_caches(self) -> None: 

+

2304 self.__get_register_for_selected_frame.cache_clear() 

+

2305 return 

+

2306 

+

2307 def __get_register(self, regname: str) -> int: 

+

2308 """Return a register's value.""" 

+

2309 curframe = gdb.selected_frame() 

+

2310 key = curframe.pc() ^ int(curframe.read_register('sp')) # todo: check when/if gdb.Frame implements `level()` 

+

2311 return self.__get_register_for_selected_frame(regname, key) 

+

2312 

+

2313 @lru_cache() 

+

2314 def __get_register_for_selected_frame(self, regname: str, hash_key: int) -> int: 

+

2315 # 1st chance 

+

2316 try: 

+

2317 return parse_address(regname) 

+

2318 except gdb.error: 

+

2319 pass 

+

2320 

+

2321 # 2nd chance - if an exception, propagate it 

+

2322 regname = regname.lstrip("$") 

+

2323 value = gdb.selected_frame().read_register(regname) 

+

2324 return int(value) 

+

2325 

+

2326 def register(self, name: str) -> int: 

+

2327 if not is_alive(): 

+

2328 raise gdb.error("No debugging session active") 

+

2329 return self.__get_register(name) 

+

2330 

+

2331 @property 

+

2332 def registers(self) -> Generator[str, None, None]: 

+

2333 yield from self.all_registers 

+

2334 

+

2335 @property 

+

2336 def pc(self) -> int: 

+

2337 return self.register("$pc") 

+

2338 

+

2339 @property 

+

2340 def sp(self) -> int: 

+

2341 return self.register("$sp") 

+

2342 

+

2343 @property 

+

2344 def fp(self) -> int: 

+

2345 return self.register("$fp") 

+

2346 

+

2347 @property 

+

2348 def ptrsize(self) -> int: 

+

2349 if not self._ptrsize: 2349 ↛ 2350line 2349 didn't jump to line 2350, because the condition on line 2349 was never true

+

2350 res = cached_lookup_type("size_t") 

+

2351 if res is not None: 

+

2352 self._ptrsize = res.sizeof 

+

2353 else: 

+

2354 self._ptrsize = gdb.parse_and_eval("$pc").type.sizeof 

+

2355 return self._ptrsize 

+

2356 

+

2357 @property 

+

2358 def endianness(self) -> Endianness: 

+

2359 if not self._endianness: 

+

2360 output = gdb.execute("show endian", to_string=True).strip().lower() 

+

2361 if "little endian" in output: 2361 ↛ 2363line 2361 didn't jump to line 2363, because the condition on line 2361 was never false

+

2362 self._endianness = Endianness.LITTLE_ENDIAN 

+

2363 elif "big endian" in output: 

+

2364 self._endianness = Endianness.BIG_ENDIAN 

+

2365 else: 

+

2366 raise OSError(f"No valid endianess found in '{output}'") 

+

2367 return self._endianness 

+

2368 

+

2369 def get_ith_parameter(self, i: int, in_func: bool = True) -> Tuple[str, Optional[int]]: 

+

2370 """Retrieves the correct parameter used for the current function call.""" 

+

2371 reg = self.function_parameters[i] 

+

2372 val = self.register(reg) 

+

2373 key = reg 

+

2374 return key, val 

+

2375 

+

2376 

+

2377class GenericArchitecture(Architecture): 

+

2378 arch = "Generic" 

+

2379 mode = "" 

+

2380 aliases = ("GenericArchitecture",) 

+

2381 all_registers = () 

+

2382 instruction_length = 0 

+

2383 return_register = "" 

+

2384 function_parameters = () 

+

2385 syscall_register = "" 

+

2386 syscall_instructions = () 

+

2387 nop_insn = b"" 

+

2388 flag_register = None 

+

2389 flags_table = {} 

+

2390 

+

2391 

+

2392class RISCV(Architecture): 

+

2393 arch = "RISCV" 

+

2394 mode = "RISCV" 

+

2395 aliases = ("RISCV", Elf.Abi.RISCV) 

+

2396 all_registers = ("$zero", "$ra", "$sp", "$gp", "$tp", "$t0", "$t1", 

+

2397 "$t2", "$fp", "$s1", "$a0", "$a1", "$a2", "$a3", 

+

2398 "$a4", "$a5", "$a6", "$a7", "$s2", "$s3", "$s4", 

+

2399 "$s5", "$s6", "$s7", "$s8", "$s9", "$s10", "$s11", 

+

2400 "$t3", "$t4", "$t5", "$t6",) 

+

2401 return_register = "$a0" 

+

2402 function_parameters = ("$a0", "$a1", "$a2", "$a3", "$a4", "$a5", "$a6", "$a7") 

+

2403 syscall_register = "$a7" 

+

2404 syscall_instructions = ("ecall",) 

+

2405 nop_insn = b"\x00\x00\x00\x13" 

+

2406 # RISC-V has no flags registers 

+

2407 flag_register = None 

+

2408 flags_table = {} 

+

2409 

+

2410 @property 

+

2411 def instruction_length(self) -> int: 

+

2412 return 4 

+

2413 

+

2414 def is_call(self, insn: Instruction) -> bool: 

+

2415 return insn.mnemonic == "call" 

+

2416 

+

2417 def is_ret(self, insn: Instruction) -> bool: 

+

2418 mnemo = insn.mnemonic 

+

2419 if mnemo == "ret": 

+

2420 return True 

+

2421 elif (mnemo == "jalr" and insn.operands[0] == "zero" and 

+

2422 insn.operands[1] == "ra" and insn.operands[2] == 0): 

+

2423 return True 

+

2424 elif (mnemo == "c.jalr" and insn.operands[0] == "ra"): 

+

2425 return True 

+

2426 return False 

+

2427 

+

2428 @classmethod 

+

2429 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2430 raise OSError(f"Architecture {cls.arch} not supported yet") 

+

2431 

+

2432 @property 

+

2433 def ptrsize(self) -> int: 

+

2434 if self._ptrsize is not None: 

+

2435 return self._ptrsize 

+

2436 if is_alive(): 

+

2437 self._ptrsize = gdb.parse_and_eval("$pc").type.sizeof 

+

2438 return self._ptrsize 

+

2439 return 4 

+

2440 

+

2441 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

2442 return insn.mnemonic.startswith("b") 

+

2443 

+

2444 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

2445 def long_to_twos_complement(v: int) -> int: 

+

2446 """Convert a python long value to its two's complement.""" 

+

2447 if is_32bit(): 

+

2448 if v & 0x80000000: 

+

2449 return v - 0x100000000 

+

2450 elif is_64bit(): 

+

2451 if v & 0x8000000000000000: 

+

2452 return v - 0x10000000000000000 

+

2453 else: 

+

2454 raise OSError("RISC-V: ELF file is not ELF32 or ELF64. This is not currently supported") 

+

2455 return v 

+

2456 

+

2457 mnemo = insn.mnemonic 

+

2458 condition = mnemo[1:] 

+

2459 

+

2460 if condition.endswith("z"): 

+

2461 # r2 is the zero register if we are comparing to 0 

+

2462 rs1 = gef.arch.register(insn.operands[0]) 

+

2463 rs2 = gef.arch.register("$zero") 

+

2464 condition = condition[:-1] 

+

2465 elif len(insn.operands) > 2: 

+

2466 # r2 is populated with the second operand 

+

2467 rs1 = gef.arch.register(insn.operands[0]) 

+

2468 rs2 = gef.arch.register(insn.operands[1]) 

+

2469 else: 

+

2470 raise OSError(f"RISC-V: Failed to get rs1 and rs2 for instruction: `{insn}`") 

+

2471 

+

2472 # If the conditional operation is not unsigned, convert the python long into 

+

2473 # its two's complement 

+

2474 if not condition.endswith("u"): 

+

2475 rs2 = long_to_twos_complement(rs2) 

+

2476 rs1 = long_to_twos_complement(rs1) 

+

2477 else: 

+

2478 condition = condition[:-1] 

+

2479 

+

2480 if condition == "eq": 

+

2481 if rs1 == rs2: taken, reason = True, f"{rs1}={rs2}" 

+

2482 else: taken, reason = False, f"{rs1}!={rs2}" 

+

2483 elif condition == "ne": 

+

2484 if rs1 != rs2: taken, reason = True, f"{rs1}!={rs2}" 

+

2485 else: taken, reason = False, f"{rs1}={rs2}" 

+

2486 elif condition == "lt": 

+

2487 if rs1 < rs2: taken, reason = True, f"{rs1}<{rs2}" 

+

2488 else: taken, reason = False, f"{rs1}>={rs2}" 

+

2489 elif condition == "le": 

+

2490 if rs1 <= rs2: taken, reason = True, f"{rs1}<={rs2}" 

+

2491 else: taken, reason = False, f"{rs1}>{rs2}" 

+

2492 elif condition == "ge": 

+

2493 if rs1 < rs2: taken, reason = True, f"{rs1}>={rs2}" 

+

2494 else: taken, reason = False, f"{rs1}<{rs2}" 

+

2495 else: 

+

2496 raise OSError(f"RISC-V: Conditional instruction `{insn}` not supported yet") 

+

2497 

+

2498 return taken, reason 

+

2499 

+

2500 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

2501 ra = None 

+

2502 if self.is_ret(insn): 

+

2503 ra = gef.arch.register("$ra") 

+

2504 elif frame.older(): 

+

2505 ra = frame.older().pc() 

+

2506 return ra 

+

2507 

+

2508 

+

2509class ARM(Architecture): 

+

2510 aliases = ("ARM", Elf.Abi.ARM) 

+

2511 arch = "ARM" 

+

2512 all_registers = ("$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", 

+

2513 "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$sp", 

+

2514 "$lr", "$pc", "$cpsr",) 

+

2515 

+

2516 nop_insn = b"\x00\xf0\x20\xe3" # hint #0 

+

2517 return_register = "$r0" 

+

2518 flag_register: str = "$cpsr" 

+

2519 flags_table = { 

+

2520 31: "negative", 

+

2521 30: "zero", 

+

2522 29: "carry", 

+

2523 28: "overflow", 

+

2524 7: "interrupt", 

+

2525 6: "fast", 

+

2526 5: "thumb", 

+

2527 } 

+

2528 function_parameters = ("$r0", "$r1", "$r2", "$r3") 

+

2529 syscall_register = "$r7" 

+

2530 syscall_instructions = ("swi 0x0", "swi NR") 

+

2531 _endianness = Endianness.LITTLE_ENDIAN 

+

2532 

+

2533 def is_thumb(self) -> bool: 

+

2534 """Determine if the machine is currently in THUMB mode.""" 

+

2535 return is_alive() and (self.cpsr & (1 << 5) == 1) 

+

2536 

+

2537 @property 

+

2538 def pc(self) -> Optional[int]: 

+

2539 pc = gef.arch.register("$pc") 

+

2540 if self.is_thumb(): 

+

2541 pc += 1 

+

2542 return pc 

+

2543 

+

2544 @property 

+

2545 def cpsr(self) -> int: 

+

2546 if not is_alive(): 

+

2547 raise RuntimeError("Cannot get CPSR, program not started?") 

+

2548 return gef.arch.register(self.flag_register) 

+

2549 

+

2550 @property 

+

2551 def mode(self) -> str: 

+

2552 return "THUMB" if self.is_thumb() else "ARM" 

+

2553 

+

2554 @property 

+

2555 def instruction_length(self) -> Optional[int]: 

+

2556 # Thumb instructions have variable-length (2 or 4-byte) 

+

2557 return None if self.is_thumb() else 4 

+

2558 

+

2559 @property 

+

2560 def ptrsize(self) -> int: 

+

2561 return 4 

+

2562 

+

2563 def is_call(self, insn: Instruction) -> bool: 

+

2564 mnemo = insn.mnemonic 

+

2565 call_mnemos = {"bl", "blx"} 

+

2566 return mnemo in call_mnemos 

+

2567 

+

2568 def is_ret(self, insn: Instruction) -> bool: 

+

2569 pop_mnemos = {"pop"} 

+

2570 branch_mnemos = {"bl", "bx"} 

+

2571 write_mnemos = {"ldr", "add"} 

+

2572 if insn.mnemonic in pop_mnemos: 

+

2573 return insn.operands[-1] == " pc}" 

+

2574 if insn.mnemonic in branch_mnemos: 

+

2575 return insn.operands[-1] == "lr" 

+

2576 if insn.mnemonic in write_mnemos: 

+

2577 return insn.operands[0] == "pc" 

+

2578 return False 

+

2579 

+

2580 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

2581 # https://www.botskool.com/user-pages/tutorials/electronics/arm-7-tutorial-part-1 

+

2582 if val is None: 

+

2583 reg = self.flag_register 

+

2584 val = gef.arch.register(reg) 

+

2585 return flags_to_human(val, self.flags_table) 

+

2586 

+

2587 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

2588 conditions = {"eq", "ne", "lt", "le", "gt", "ge", "vs", "vc", "mi", "pl", "hi", "ls", "cc", "cs"} 

+

2589 return insn.mnemonic[-2:] in conditions 

+

2590 

+

2591 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

2592 mnemo = insn.mnemonic 

+

2593 # ref: https://www.davespace.co.uk/arm/introduction-to-arm/conditional.html 

+

2594 flags = dict((self.flags_table[k], k) for k in self.flags_table) 

+

2595 val = gef.arch.register(self.flag_register) 

+

2596 taken, reason = False, "" 

+

2597 

+

2598 if mnemo.endswith("eq"): taken, reason = bool(val&(1<<flags["zero"])), "Z" 

+

2599 elif mnemo.endswith("ne"): taken, reason = not bool(val&(1<<flags["zero"])), "!Z" 

+

2600 elif mnemo.endswith("lt"): 

+

2601 taken, reason = bool(val&(1<<flags["negative"])) != bool(val&(1<<flags["overflow"])), "N!=V" 

+

2602 elif mnemo.endswith("le"): 

+

2603 taken, reason = bool(val&(1<<flags["zero"])) or \ 

+

2604 bool(val&(1<<flags["negative"])) != bool(val&(1<<flags["overflow"])), "Z || N!=V" 

+

2605 elif mnemo.endswith("gt"): 

+

2606 taken, reason = bool(val&(1<<flags["zero"])) == 0 and \ 

+

2607 bool(val&(1<<flags["negative"])) == bool(val&(1<<flags["overflow"])), "!Z && N==V" 

+

2608 elif mnemo.endswith("ge"): 

+

2609 taken, reason = bool(val&(1<<flags["negative"])) == bool(val&(1<<flags["overflow"])), "N==V" 

+

2610 elif mnemo.endswith("vs"): taken, reason = bool(val&(1<<flags["overflow"])), "V" 

+

2611 elif mnemo.endswith("vc"): taken, reason = not val&(1<<flags["overflow"]), "!V" 

+

2612 elif mnemo.endswith("mi"): 

+

2613 taken, reason = bool(val&(1<<flags["negative"])), "N" 

+

2614 elif mnemo.endswith("pl"): 

+

2615 taken, reason = not val&(1<<flags["negative"]), "N==0" 

+

2616 elif mnemo.endswith("hi"): 

+

2617 taken, reason = bool(val&(1<<flags["carry"])) and not bool(val&(1<<flags["zero"])), "C && !Z" 

+

2618 elif mnemo.endswith("ls"): 

+

2619 taken, reason = not val&(1<<flags["carry"]) or bool(val&(1<<flags["zero"])), "!C || Z" 

+

2620 elif mnemo.endswith("cs"): taken, reason = bool(val&(1<<flags["carry"])), "C" 

+

2621 elif mnemo.endswith("cc"): taken, reason = not val&(1<<flags["carry"]), "!C" 

+

2622 return taken, reason 

+

2623 

+

2624 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> int: 

+

2625 ra = None 

+

2626 if self.is_ret(insn): 

+

2627 # If it's a pop, we have to peek into the stack, otherwise use lr 

+

2628 if insn.mnemonic == "pop": 

+

2629 ra_addr = gef.arch.sp + (len(insn.operands)-1) * self.ptrsize 

+

2630 ra = to_unsigned_long(dereference(ra_addr)) 

+

2631 elif insn.mnemonic == "ldr": 

+

2632 return to_unsigned_long(dereference(gef.arch.sp)) 

+

2633 else: # 'bx lr' or 'add pc, lr, #0' 

+

2634 return gef.arch.register("$lr") 

+

2635 elif frame.older(): 

+

2636 ra = frame.older().pc() 

+

2637 return ra 

+

2638 

+

2639 @classmethod 

+

2640 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2641 _NR_mprotect = 125 

+

2642 insns = [ 

+

2643 "push {r0-r2, r7}", 

+

2644 f"mov r1, {addr & 0xffff:d}", 

+

2645 f"mov r0, {(addr & 0xffff0000) >> 16:d}", 

+

2646 "lsl r0, r0, 16", 

+

2647 "add r0, r0, r1", 

+

2648 f"mov r1, {size & 0xffff:d}", 

+

2649 f"mov r2, {perm.value & 0xff:d}", 

+

2650 f"mov r7, {_NR_mprotect:d}", 

+

2651 "svc 0", 

+

2652 "pop {r0-r2, r7}", 

+

2653 ] 

+

2654 return "; ".join(insns) 

+

2655 

+

2656 

+

2657class AARCH64(ARM): 

+

2658 aliases = ("ARM64", "AARCH64", Elf.Abi.AARCH64) 

+

2659 arch = "ARM64" 

+

2660 mode: str = "" 

+

2661 

+

2662 all_registers = ( 

+

2663 "$x0", "$x1", "$x2", "$x3", "$x4", "$x5", "$x6", "$x7", 

+

2664 "$x8", "$x9", "$x10", "$x11", "$x12", "$x13", "$x14","$x15", 

+

2665 "$x16", "$x17", "$x18", "$x19", "$x20", "$x21", "$x22", "$x23", 

+

2666 "$x24", "$x25", "$x26", "$x27", "$x28", "$x29", "$x30", "$sp", 

+

2667 "$pc", "$cpsr", "$fpsr", "$fpcr",) 

+

2668 return_register = "$x0" 

+

2669 flag_register = "$cpsr" 

+

2670 flags_table = { 

+

2671 31: "negative", 

+

2672 30: "zero", 

+

2673 29: "carry", 

+

2674 28: "overflow", 

+

2675 7: "interrupt", 

+

2676 9: "endian", 

+

2677 6: "fast", 

+

2678 5: "t32", 

+

2679 4: "m[4]", 

+

2680 } 

+

2681 nop_insn = b"\x1f\x20\x03\xd5" # hint #0 

+

2682 function_parameters = ("$x0", "$x1", "$x2", "$x3", "$x4", "$x5", "$x6", "$x7",) 

+

2683 syscall_register = "$x8" 

+

2684 syscall_instructions = ("svc $x0",) 

+

2685 

+

2686 def is_call(self, insn: Instruction) -> bool: 

+

2687 mnemo = insn.mnemonic 

+

2688 call_mnemos = {"bl", "blr"} 

+

2689 return mnemo in call_mnemos 

+

2690 

+

2691 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

2692 # https://events.linuxfoundation.org/sites/events/files/slides/KoreaLinuxForum-2014.pdf 

+

2693 reg = self.flag_register 

+

2694 if not val: 

+

2695 val = gef.arch.register(reg) 

+

2696 return flags_to_human(val, self.flags_table) 

+

2697 

+

2698 def is_aarch32(self) -> bool: 

+

2699 """Determine if the CPU is currently in AARCH32 mode from runtime.""" 

+

2700 return (self.cpsr & (1 << 4) != 0) and (self.cpsr & (1 << 5) == 0) 

+

2701 

+

2702 def is_thumb32(self) -> bool: 

+

2703 """Determine if the CPU is currently in THUMB32 mode from runtime.""" 

+

2704 return (self.cpsr & (1 << 4) == 1) and (self.cpsr & (1 << 5) == 1) 

+

2705 

+

2706 @property 

+

2707 def ptrsize(self) -> int: 

+

2708 """Determine the size of pointer from the current CPU mode""" 

+

2709 if not is_alive(): 

+

2710 return 8 

+

2711 if self.is_aarch32(): 

+

2712 return 4 

+

2713 if self.is_thumb32(): 

+

2714 return 2 

+

2715 return 8 

+

2716 

+

2717 @classmethod 

+

2718 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2719 _NR_mprotect = 226 

+

2720 insns = [ 

+

2721 "str x8, [sp, -16]!", 

+

2722 "str x0, [sp, -16]!", 

+

2723 "str x1, [sp, -16]!", 

+

2724 "str x2, [sp, -16]!", 

+

2725 f"mov x8, {_NR_mprotect:d}", 

+

2726 f"movz x0, {addr & 0xFFFF:#x}", 

+

2727 f"movk x0, {(addr >> 16) & 0xFFFF:#x}, lsl 16", 

+

2728 f"movk x0, {(addr >> 32) & 0xFFFF:#x}, lsl 32", 

+

2729 f"movk x0, {(addr >> 48) & 0xFFFF:#x}, lsl 48", 

+

2730 f"movz x1, {size & 0xFFFF:#x}", 

+

2731 f"movk x1, {(size >> 16) & 0xFFFF:#x}, lsl 16", 

+

2732 f"mov x2, {perm.value:d}", 

+

2733 "svc 0", 

+

2734 "ldr x2, [sp], 16", 

+

2735 "ldr x1, [sp], 16", 

+

2736 "ldr x0, [sp], 16", 

+

2737 "ldr x8, [sp], 16", 

+

2738 ] 

+

2739 return "; ".join(insns) 

+

2740 

+

2741 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

2742 # https://www.element14.com/community/servlet/JiveServlet/previewBody/41836-102-1-229511/ARM.Reference_Manual.pdf 

+

2743 # sect. 5.1.1 

+

2744 mnemo = insn.mnemonic 

+

2745 branch_mnemos = {"cbnz", "cbz", "tbnz", "tbz"} 

+

2746 return mnemo.startswith("b.") or mnemo in branch_mnemos 

+

2747 

+

2748 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

2749 mnemo, operands = insn.mnemonic, insn.operands 

+

2750 taken, reason = False, "" 

+

2751 

+

2752 if mnemo in {"cbnz", "cbz", "tbnz", "tbz"}: 

+

2753 reg = f"${operands[0]}" 

+

2754 op = gef.arch.register(reg) 

+

2755 if mnemo == "cbnz": 

+

2756 if op!=0: taken, reason = True, f"{reg}!=0" 

+

2757 else: taken, reason = False, f"{reg}==0" 

+

2758 elif mnemo == "cbz": 

+

2759 if op == 0: taken, reason = True, f"{reg}==0" 

+

2760 else: taken, reason = False, f"{reg}!=0" 

+

2761 elif mnemo == "tbnz": 

+

2762 # operands[1] has one or more white spaces in front, then a #, then the number 

+

2763 # so we need to eliminate them 

+

2764 i = int(operands[1].strip().lstrip("#")) 

+

2765 if (op & 1<<i) != 0: taken, reason = True, f"{reg}&1<<{i}!=0" 

+

2766 else: taken, reason = False, f"{reg}&1<<{i}==0" 

+

2767 elif mnemo == "tbz": 

+

2768 # operands[1] has one or more white spaces in front, then a #, then the number 

+

2769 # so we need to eliminate them 

+

2770 i = int(operands[1].strip().lstrip("#")) 

+

2771 if (op & 1<<i) == 0: taken, reason = True, f"{reg}&1<<{i}==0" 

+

2772 else: taken, reason = False, f"{reg}&1<<{i}!=0" 

+

2773 

+

2774 if not reason: 

+

2775 taken, reason = super().is_branch_taken(insn) 

+

2776 return taken, reason 

+

2777 

+

2778 

+

2779class X86(Architecture): 

+

2780 aliases: Tuple[Union[str, Elf.Abi], ...] = ("X86", Elf.Abi.X86_32) 

+

2781 arch = "X86" 

+

2782 mode = "32" 

+

2783 

+

2784 nop_insn = b"\x90" 

+

2785 flag_register: str = "$eflags" 

+

2786 special_registers = ("$cs", "$ss", "$ds", "$es", "$fs", "$gs", ) 

+

2787 gpr_registers = ("$eax", "$ebx", "$ecx", "$edx", "$esp", "$ebp", "$esi", "$edi", "$eip", ) 

+

2788 all_registers = gpr_registers + ( flag_register,) + special_registers 

+

2789 instruction_length = None 

+

2790 return_register = "$eax" 

+

2791 function_parameters = ("$esp", ) 

+

2792 flags_table = { 

+

2793 6: "zero", 

+

2794 0: "carry", 

+

2795 2: "parity", 

+

2796 4: "adjust", 

+

2797 7: "sign", 

+

2798 8: "trap", 

+

2799 9: "interrupt", 

+

2800 10: "direction", 

+

2801 11: "overflow", 

+

2802 16: "resume", 

+

2803 17: "virtualx86", 

+

2804 21: "identification", 

+

2805 } 

+

2806 syscall_register = "$eax" 

+

2807 syscall_instructions = ("sysenter", "int 0x80") 

+

2808 _ptrsize = 4 

+

2809 _endianness = Endianness.LITTLE_ENDIAN 

+

2810 

+

2811 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

2812 reg = self.flag_register 

+

2813 if not val: 2813 ↛ 2815line 2813 didn't jump to line 2815, because the condition on line 2813 was never false

+

2814 val = gef.arch.register(reg) 

+

2815 return flags_to_human(val, self.flags_table) 

+

2816 

+

2817 def is_call(self, insn: Instruction) -> bool: 

+

2818 mnemo = insn.mnemonic 

+

2819 call_mnemos = {"call", "callq"} 

+

2820 return mnemo in call_mnemos 

+

2821 

+

2822 def is_ret(self, insn: Instruction) -> bool: 

+

2823 return insn.mnemonic == "ret" 

+

2824 

+

2825 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

2826 mnemo = insn.mnemonic 

+

2827 branch_mnemos = { 

+

2828 "ja", "jnbe", "jae", "jnb", "jnc", "jb", "jc", "jnae", "jbe", "jna", 

+

2829 "jcxz", "jecxz", "jrcxz", "je", "jz", "jg", "jnle", "jge", "jnl", 

+

2830 "jl", "jnge", "jle", "jng", "jne", "jnz", "jno", "jnp", "jpo", "jns", 

+

2831 "jo", "jp", "jpe", "js" 

+

2832 } 

+

2833 return mnemo in branch_mnemos 

+

2834 

+

2835 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

2836 mnemo = insn.mnemonic 

+

2837 # all kudos to fG! (https://github.com/gdbinit/Gdbinit/blob/master/gdbinit#L1654) 

+

2838 flags = dict((self.flags_table[k], k) for k in self.flags_table) 

+

2839 val = gef.arch.register(self.flag_register) 

+

2840 

+

2841 taken, reason = False, "" 

+

2842 

+

2843 if mnemo in ("ja", "jnbe"): 

+

2844 taken, reason = not val&(1<<flags["carry"]) and not bool(val&(1<<flags["zero"])), "!C && !Z" 

+

2845 elif mnemo in ("jae", "jnb", "jnc"): 

+

2846 taken, reason = not val&(1<<flags["carry"]), "!C" 

+

2847 elif mnemo in ("jb", "jc", "jnae"): 

+

2848 taken, reason = bool(val&(1<<flags["carry"])) != 0, "C" 

+

2849 elif mnemo in ("jbe", "jna"): 

+

2850 taken, reason = bool(val&(1<<flags["carry"])) or bool(val&(1<<flags["zero"])), "C || Z" 

+

2851 elif mnemo in ("jcxz", "jecxz", "jrcxz"): 

+

2852 cx = gef.arch.register("$rcx") if is_x86_64() else gef.arch.register("$ecx") 

+

2853 taken, reason = cx == 0, "!$CX" 

+

2854 elif mnemo in ("je", "jz"): 

+

2855 taken, reason = bool(val&(1<<flags["zero"])), "Z" 

+

2856 elif mnemo in ("jne", "jnz"): 

+

2857 taken, reason = not bool(val&(1<<flags["zero"])), "!Z" 

+

2858 elif mnemo in ("jg", "jnle"): 

+

2859 taken, reason = not bool(val&(1<<flags["zero"])) and bool(val&(1<<flags["overflow"])) == bool(val&(1<<flags["sign"])), "!Z && S==O" 

+

2860 elif mnemo in ("jge", "jnl"): 

+

2861 taken, reason = bool(val&(1<<flags["sign"])) == bool(val&(1<<flags["overflow"])), "S==O" 

+

2862 elif mnemo in ("jl", "jnge"): 

+

2863 taken, reason = bool(val&(1<<flags["overflow"]) != val&(1<<flags["sign"])), "S!=O" 

+

2864 elif mnemo in ("jle", "jng"): 

+

2865 taken, reason = bool(val&(1<<flags["zero"])) or bool(val&(1<<flags["overflow"])) != bool(val&(1<<flags["sign"])), "Z || S!=O" 

+

2866 elif mnemo in ("jo",): 

+

2867 taken, reason = bool(val&(1<<flags["overflow"])), "O" 

+

2868 elif mnemo in ("jno",): 

+

2869 taken, reason = not val&(1<<flags["overflow"]), "!O" 

+

2870 elif mnemo in ("jpe", "jp"): 

+

2871 taken, reason = bool(val&(1<<flags["parity"])), "P" 

+

2872 elif mnemo in ("jnp", "jpo"): 

+

2873 taken, reason = not val&(1<<flags["parity"]), "!P" 

+

2874 elif mnemo in ("js",): 

+

2875 taken, reason = bool(val&(1<<flags["sign"])) != 0, "S" 

+

2876 elif mnemo in ("jns",): 

+

2877 taken, reason = not val&(1<<flags["sign"]), "!S" 

+

2878 return taken, reason 

+

2879 

+

2880 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

2881 ra = None 

+

2882 if self.is_ret(insn): 2882 ↛ 2884line 2882 didn't jump to line 2884, because the condition on line 2882 was never false

+

2883 ra = to_unsigned_long(dereference(gef.arch.sp)) 

+

2884 if frame.older(): 2884 ↛ 2887line 2884 didn't jump to line 2887, because the condition on line 2884 was never false

+

2885 ra = frame.older().pc() 

+

2886 

+

2887 return ra 

+

2888 

+

2889 @classmethod 

+

2890 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2891 _NR_mprotect = 125 

+

2892 insns = [ 

+

2893 "pushad", 

+

2894 "pushfd", 

+

2895 f"mov eax, {_NR_mprotect:d}", 

+

2896 f"mov ebx, {addr:d}", 

+

2897 f"mov ecx, {size:d}", 

+

2898 f"mov edx, {perm.value:d}", 

+

2899 "int 0x80", 

+

2900 "popfd", 

+

2901 "popad", 

+

2902 ] 

+

2903 return "; ".join(insns) 

+

2904 

+

2905 def get_ith_parameter(self, i: int, in_func: bool = True) -> Tuple[str, Optional[int]]: 

+

2906 if in_func: 

+

2907 i += 1 # Account for RA being at the top of the stack 

+

2908 sp = gef.arch.sp 

+

2909 sz = gef.arch.ptrsize 

+

2910 loc = sp + (i * sz) 

+

2911 val = gef.memory.read_integer(loc) 

+

2912 key = f"[sp + {i * sz:#x}]" 

+

2913 return key, val 

+

2914 

+

2915 

+

2916class X86_64(X86): 

+

2917 aliases = ("X86_64", Elf.Abi.X86_64, "i386:x86-64") 

+

2918 arch = "X86" 

+

2919 mode = "64" 

+

2920 

+

2921 gpr_registers = ( 

+

2922 "$rax", "$rbx", "$rcx", "$rdx", "$rsp", "$rbp", "$rsi", "$rdi", "$rip", 

+

2923 "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15", ) 

+

2924 all_registers = gpr_registers + ( X86.flag_register, ) + X86.special_registers 

+

2925 return_register = "$rax" 

+

2926 function_parameters = ["$rdi", "$rsi", "$rdx", "$rcx", "$r8", "$r9"] 

+

2927 syscall_register = "$rax" 

+

2928 syscall_instructions = ["syscall"] 

+

2929 # We don't want to inherit x86's stack based param getter 

+

2930 get_ith_parameter = Architecture.get_ith_parameter 

+

2931 _ptrsize = 8 

+

2932 

+

2933 @classmethod 

+

2934 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2935 _NR_mprotect = 10 

+

2936 insns = [ 

+

2937 "pushfq", 

+

2938 "push rax", 

+

2939 "push rdi", 

+

2940 "push rsi", 

+

2941 "push rdx", 

+

2942 "push rcx", 

+

2943 "push r11", 

+

2944 f"mov rax, {_NR_mprotect:d}", 

+

2945 f"mov rdi, {addr:d}", 

+

2946 f"mov rsi, {size:d}", 

+

2947 f"mov rdx, {perm.value:d}", 

+

2948 "syscall", 

+

2949 "pop r11", 

+

2950 "pop rcx", 

+

2951 "pop rdx", 

+

2952 "pop rsi", 

+

2953 "pop rdi", 

+

2954 "pop rax", 

+

2955 "popfq", 

+

2956 ] 

+

2957 return "; ".join(insns) 

+

2958 

+

2959 def canary_address(self) -> int: 

+

2960 return self.register("fs_base") + 0x28 

+

2961 

+

2962class PowerPC(Architecture): 

+

2963 aliases = ("PowerPC", Elf.Abi.POWERPC, "PPC") 

+

2964 arch = "PPC" 

+

2965 mode = "PPC32" 

+

2966 

+

2967 all_registers = ( 

+

2968 "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", 

+

2969 "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15", 

+

2970 "$r16", "$r17", "$r18", "$r19", "$r20", "$r21", "$r22", "$r23", 

+

2971 "$r24", "$r25", "$r26", "$r27", "$r28", "$r29", "$r30", "$r31", 

+

2972 "$pc", "$msr", "$cr", "$lr", "$ctr", "$xer", "$trap",) 

+

2973 instruction_length = 4 

+

2974 nop_insn = b"\x60\x00\x00\x00" # https://developer.ibm.com/articles/l-ppc/ 

+

2975 return_register = "$r0" 

+

2976 flag_register: str = "$cr" 

+

2977 flags_table = { 

+

2978 3: "negative[0]", 

+

2979 2: "positive[0]", 

+

2980 1: "equal[0]", 

+

2981 0: "overflow[0]", 

+

2982 # cr7 

+

2983 31: "less[7]", 

+

2984 30: "greater[7]", 

+

2985 29: "equal[7]", 

+

2986 28: "overflow[7]", 

+

2987 } 

+

2988 function_parameters = ("$i0", "$i1", "$i2", "$i3", "$i4", "$i5") 

+

2989 syscall_register = "$r0" 

+

2990 syscall_instructions = ("sc",) 

+

2991 ptrsize = 4 

+

2992 

+

2993 

+

2994 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

2995 # https://www.cebix.net/downloads/bebox/pem32b.pdf (% 2.1.3) 

+

2996 if not val: 

+

2997 reg = self.flag_register 

+

2998 val = gef.arch.register(reg) 

+

2999 return flags_to_human(val, self.flags_table) 

+

3000 

+

3001 def is_call(self, insn: Instruction) -> bool: 

+

3002 return False 

+

3003 

+

3004 def is_ret(self, insn: Instruction) -> bool: 

+

3005 return insn.mnemonic == "blr" 

+

3006 

+

3007 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

3008 mnemo = insn.mnemonic 

+

3009 branch_mnemos = {"beq", "bne", "ble", "blt", "bgt", "bge"} 

+

3010 return mnemo in branch_mnemos 

+

3011 

+

3012 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

3013 mnemo = insn.mnemonic 

+

3014 flags = dict((self.flags_table[k], k) for k in self.flags_table) 

+

3015 val = gef.arch.register(self.flag_register) 

+

3016 taken, reason = False, "" 

+

3017 if mnemo == "beq": taken, reason = bool(val&(1<<flags["equal[7]"])), "E" 

+

3018 elif mnemo == "bne": taken, reason = val&(1<<flags["equal[7]"]) == 0, "!E" 

+

3019 elif mnemo == "ble": taken, reason = bool(val&(1<<flags["equal[7]"])) or bool(val&(1<<flags["less[7]"])), "E || L" 

+

3020 elif mnemo == "blt": taken, reason = bool(val&(1<<flags["less[7]"])), "L" 

+

3021 elif mnemo == "bge": taken, reason = bool(val&(1<<flags["equal[7]"])) or bool(val&(1<<flags["greater[7]"])), "E || G" 

+

3022 elif mnemo == "bgt": taken, reason = bool(val&(1<<flags["greater[7]"])), "G" 

+

3023 return taken, reason 

+

3024 

+

3025 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

3026 ra = None 

+

3027 if self.is_ret(insn): 

+

3028 ra = gef.arch.register("$lr") 

+

3029 elif frame.older(): 

+

3030 ra = frame.older().pc() 

+

3031 return ra 

+

3032 

+

3033 @classmethod 

+

3034 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

3035 # Ref: https://developer.ibm.com/articles/l-ppc/ 

+

3036 _NR_mprotect = 125 

+

3037 insns = [ 

+

3038 "addi 1, 1, -16", # 1 = r1 = sp 

+

3039 "stw 0, 0(1)", 

+

3040 "stw 3, 4(1)", # r0 = syscall_code | r3, r4, r5 = args 

+

3041 "stw 4, 8(1)", 

+

3042 "stw 5, 12(1)", 

+

3043 f"li 0, {_NR_mprotect:d}", 

+

3044 f"lis 3, {addr:#x}@h", 

+

3045 f"ori 3, 3, {addr:#x}@l", 

+

3046 f"lis 4, {size:#x}@h", 

+

3047 f"ori 4, 4, {size:#x}@l", 

+

3048 f"li 5, {perm.value:d}", 

+

3049 "sc", 

+

3050 "lwz 0, 0(1)", 

+

3051 "lwz 3, 4(1)", 

+

3052 "lwz 4, 8(1)", 

+

3053 "lwz 5, 12(1)", 

+

3054 "addi 1, 1, 16", 

+

3055 ] 

+

3056 return ";".join(insns) 

+

3057 

+

3058 

+

3059class PowerPC64(PowerPC): 

+

3060 aliases = ("PowerPC64", Elf.Abi.POWERPC64, "PPC64") 

+

3061 arch = "PPC" 

+

3062 mode = "PPC64" 

+

3063 ptrsize = 8 

+

3064 

+

3065 

+

3066class SPARC(Architecture): 

+

3067 """ Refs: 

+

3068 - https://www.cse.scu.edu/~atkinson/teaching/sp05/259/sparc.pdf 

+

3069 """ 

+

3070 aliases = ("SPARC", Elf.Abi.SPARC) 

+

3071 arch = "SPARC" 

+

3072 mode = "" 

+

3073 

+

3074 all_registers = ( 

+

3075 "$g0", "$g1", "$g2", "$g3", "$g4", "$g5", "$g6", "$g7", 

+

3076 "$o0", "$o1", "$o2", "$o3", "$o4", "$o5", "$o7", 

+

3077 "$l0", "$l1", "$l2", "$l3", "$l4", "$l5", "$l6", "$l7", 

+

3078 "$i0", "$i1", "$i2", "$i3", "$i4", "$i5", "$i7", 

+

3079 "$pc", "$npc", "$sp ", "$fp ", "$psr",) 

+

3080 instruction_length = 4 

+

3081 nop_insn = b"\x00\x00\x00\x00" # sethi 0, %g0 

+

3082 return_register = "$i0" 

+

3083 flag_register: str = "$psr" 

+

3084 flags_table = { 

+

3085 23: "negative", 

+

3086 22: "zero", 

+

3087 21: "overflow", 

+

3088 20: "carry", 

+

3089 7: "supervisor", 

+

3090 5: "trap", 

+

3091 } 

+

3092 function_parameters = ("$o0 ", "$o1 ", "$o2 ", "$o3 ", "$o4 ", "$o5 ", "$o7 ",) 

+

3093 syscall_register = "%g1" 

+

3094 syscall_instructions = ("t 0x10",) 

+

3095 

+

3096 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

3097 # https://www.gaisler.com/doc/sparcv8.pdf 

+

3098 reg = self.flag_register 

+

3099 if not val: 

+

3100 val = gef.arch.register(reg) 

+

3101 return flags_to_human(val, self.flags_table) 

+

3102 

+

3103 def is_call(self, insn: Instruction) -> bool: 

+

3104 return False 

+

3105 

+

3106 def is_ret(self, insn: Instruction) -> bool: 

+

3107 return insn.mnemonic == "ret" 

+

3108 

+

3109 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

3110 mnemo = insn.mnemonic 

+

3111 # http://moss.csc.ncsu.edu/~mueller/codeopt/codeopt00/notes/condbranch.html 

+

3112 branch_mnemos = { 

+

3113 "be", "bne", "bg", "bge", "bgeu", "bgu", "bl", "ble", "blu", "bleu", 

+

3114 "bneg", "bpos", "bvs", "bvc", "bcs", "bcc" 

+

3115 } 

+

3116 return mnemo in branch_mnemos 

+

3117 

+

3118 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

3119 mnemo = insn.mnemonic 

+

3120 flags = dict((self.flags_table[k], k) for k in self.flags_table) 

+

3121 val = gef.arch.register(self.flag_register) 

+

3122 taken, reason = False, "" 

+

3123 

+

3124 if mnemo == "be": taken, reason = bool(val&(1<<flags["zero"])), "Z" 

+

3125 elif mnemo == "bne": taken, reason = bool(val&(1<<flags["zero"])) == 0, "!Z" 

+

3126 elif mnemo == "bg": taken, reason = bool(val&(1<<flags["zero"])) == 0 and (val&(1<<flags["negative"]) == 0 or val&(1<<flags["overflow"]) == 0), "!Z && (!N || !O)" 

+

3127 elif mnemo == "bge": taken, reason = val&(1<<flags["negative"]) == 0 or val&(1<<flags["overflow"]) == 0, "!N || !O" 

+

3128 elif mnemo == "bgu": taken, reason = val&(1<<flags["carry"]) == 0 and val&(1<<flags["zero"]) == 0, "!C && !Z" 

+

3129 elif mnemo == "bgeu": taken, reason = val&(1<<flags["carry"]) == 0, "!C" 

+

3130 elif mnemo == "bl": taken, reason = bool(val&(1<<flags["negative"])) and bool(val&(1<<flags["overflow"])), "N && O" 

+

3131 elif mnemo == "blu": taken, reason = bool(val&(1<<flags["carry"])), "C" 

+

3132 elif mnemo == "ble": taken, reason = bool(val&(1<<flags["zero"])) or bool(val&(1<<flags["negative"]) or val&(1<<flags["overflow"])), "Z || (N || O)" 

+

3133 elif mnemo == "bleu": taken, reason = bool(val&(1<<flags["carry"])) or bool(val&(1<<flags["zero"])), "C || Z" 

+

3134 elif mnemo == "bneg": taken, reason = bool(val&(1<<flags["negative"])), "N" 

+

3135 elif mnemo == "bpos": taken, reason = val&(1<<flags["negative"]) == 0, "!N" 

+

3136 elif mnemo == "bvs": taken, reason = bool(val&(1<<flags["overflow"])), "O" 

+

3137 elif mnemo == "bvc": taken, reason = val&(1<<flags["overflow"]) == 0, "!O" 

+

3138 elif mnemo == "bcs": taken, reason = bool(val&(1<<flags["carry"])), "C" 

+

3139 elif mnemo == "bcc": taken, reason = val&(1<<flags["carry"]) == 0, "!C" 

+

3140 return taken, reason 

+

3141 

+

3142 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

3143 ra = None 

+

3144 if self.is_ret(insn): 

+

3145 ra = gef.arch.register("$o7") 

+

3146 elif frame.older(): 

+

3147 ra = frame.older().pc() 

+

3148 return ra 

+

3149 

+

3150 @classmethod 

+

3151 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

3152 hi = (addr & 0xffff0000) >> 16 

+

3153 lo = (addr & 0x0000ffff) 

+

3154 _NR_mprotect = 125 

+

3155 insns = ["add %sp, -16, %sp", 

+

3156 "st %g1, [ %sp ]", "st %o0, [ %sp + 4 ]", 

+

3157 "st %o1, [ %sp + 8 ]", "st %o2, [ %sp + 12 ]", 

+

3158 f"sethi %hi({hi}), %o0", 

+

3159 f"or %o0, {lo}, %o0", 

+

3160 "clr %o1", 

+

3161 "clr %o2", 

+

3162 f"mov {_NR_mprotect}, %g1", 

+

3163 "t 0x10", 

+

3164 "ld [ %sp ], %g1", "ld [ %sp + 4 ], %o0", 

+

3165 "ld [ %sp + 8 ], %o1", "ld [ %sp + 12 ], %o2", 

+

3166 "add %sp, 16, %sp",] 

+

3167 return "; ".join(insns) 

+

3168 

+

3169 

+

3170class SPARC64(SPARC): 

+

3171 """Refs: 

+

3172 - http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_sparc.pdf 

+

3173 - https://cr.yp.to/2005-590/sparcv9.pdf 

+

3174 """ 

+

3175 aliases = ("SPARC64", Elf.Abi.SPARC64) 

+

3176 arch = "SPARC" 

+

3177 mode = "V9" 

+

3178 

+

3179 all_registers = [ 

+

3180 "$g0", "$g1", "$g2", "$g3", "$g4", "$g5", "$g6", "$g7", 

+

3181 "$o0", "$o1", "$o2", "$o3", "$o4", "$o5", "$o7", 

+

3182 "$l0", "$l1", "$l2", "$l3", "$l4", "$l5", "$l6", "$l7", 

+

3183 "$i0", "$i1", "$i2", "$i3", "$i4", "$i5", "$i7", 

+

3184 "$pc", "$npc", "$sp", "$fp", "$state", ] 

+

3185 

+

3186 flag_register = "$state" # sparcv9.pdf, 5.1.5.1 (ccr) 

+

3187 flags_table = { 

+

3188 35: "negative", 

+

3189 34: "zero", 

+

3190 33: "overflow", 

+

3191 32: "carry", 

+

3192 } 

+

3193 

+

3194 syscall_instructions = ["t 0x6d"] 

+

3195 

+

3196 @classmethod 

+

3197 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

3198 hi = (addr & 0xffff0000) >> 16 

+

3199 lo = (addr & 0x0000ffff) 

+

3200 _NR_mprotect = 125 

+

3201 insns = ["add %sp, -16, %sp", 

+

3202 "st %g1, [ %sp ]", "st %o0, [ %sp + 4 ]", 

+

3203 "st %o1, [ %sp + 8 ]", "st %o2, [ %sp + 12 ]", 

+

3204 f"sethi %hi({hi}), %o0", 

+

3205 f"or %o0, {lo}, %o0", 

+

3206 "clr %o1", 

+

3207 "clr %o2", 

+

3208 f"mov {_NR_mprotect}, %g1", 

+

3209 "t 0x6d", 

+

3210 "ld [ %sp ], %g1", "ld [ %sp + 4 ], %o0", 

+

3211 "ld [ %sp + 8 ], %o1", "ld [ %sp + 12 ], %o2", 

+

3212 "add %sp, 16, %sp",] 

+

3213 return "; ".join(insns) 

+

3214 

+

3215 

+

3216class MIPS(Architecture): 

+

3217 aliases: Tuple[Union[str, Elf.Abi], ...] = ("MIPS", Elf.Abi.MIPS) 

+

3218 arch = "MIPS" 

+

3219 mode = "MIPS32" 

+

3220 

+

3221 # https://vhouten.home.xs4all.nl/mipsel/r3000-isa.html 

+

3222 all_registers = ( 

+

3223 "$zero", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3", 

+

3224 "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", 

+

3225 "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7", 

+

3226 "$t8", "$t9", "$k0", "$k1", "$s8", "$pc", "$sp", "$hi", 

+

3227 "$lo", "$fir", "$ra", "$gp", ) 

+

3228 instruction_length = 4 

+

3229 _ptrsize = 4 

+

3230 nop_insn = b"\x00\x00\x00\x00" # sll $0,$0,0 

+

3231 return_register = "$v0" 

+

3232 flag_register = "$fcsr" 

+

3233 flags_table = {} 

+

3234 function_parameters = ("$a0", "$a1", "$a2", "$a3") 

+

3235 syscall_register = "$v0" 

+

3236 syscall_instructions = ("syscall",) 

+

3237 

+

3238 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

3239 return Color.colorify("No flag register", "yellow underline") 

+

3240 

+

3241 def is_call(self, insn: Instruction) -> bool: 

+

3242 return False 

+

3243 

+

3244 def is_ret(self, insn: Instruction) -> bool: 

+

3245 return insn.mnemonic == "jr" and insn.operands[0] == "ra" 

+

3246 

+

3247 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

3248 mnemo = insn.mnemonic 

+

3249 branch_mnemos = {"beq", "bne", "beqz", "bnez", "bgtz", "bgez", "bltz", "blez"} 

+

3250 return mnemo in branch_mnemos 

+

3251 

+

3252 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

3253 mnemo, ops = insn.mnemonic, insn.operands 

+

3254 taken, reason = False, "" 

+

3255 

+

3256 if mnemo == "beq": 

+

3257 taken, reason = gef.arch.register(ops[0]) == gef.arch.register(ops[1]), "{0[0]} == {0[1]}".format(ops) 

+

3258 elif mnemo == "bne": 

+

3259 taken, reason = gef.arch.register(ops[0]) != gef.arch.register(ops[1]), "{0[0]} != {0[1]}".format(ops) 

+

3260 elif mnemo == "beqz": 

+

3261 taken, reason = gef.arch.register(ops[0]) == 0, "{0[0]} == 0".format(ops) 

+

3262 elif mnemo == "bnez": 

+

3263 taken, reason = gef.arch.register(ops[0]) != 0, "{0[0]} != 0".format(ops) 

+

3264 elif mnemo == "bgtz": 

+

3265 taken, reason = gef.arch.register(ops[0]) > 0, "{0[0]} > 0".format(ops) 

+

3266 elif mnemo == "bgez": 

+

3267 taken, reason = gef.arch.register(ops[0]) >= 0, "{0[0]} >= 0".format(ops) 

+

3268 elif mnemo == "bltz": 

+

3269 taken, reason = gef.arch.register(ops[0]) < 0, "{0[0]} < 0".format(ops) 

+

3270 elif mnemo == "blez": 

+

3271 taken, reason = gef.arch.register(ops[0]) <= 0, "{0[0]} <= 0".format(ops) 

+

3272 return taken, reason 

+

3273 

+

3274 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

3275 ra = None 

+

3276 if self.is_ret(insn): 

+

3277 ra = gef.arch.register("$ra") 

+

3278 elif frame.older(): 

+

3279 ra = frame.older().pc() 

+

3280 return ra 

+

3281 

+

3282 @classmethod 

+

3283 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

3284 _NR_mprotect = 4125 

+

3285 insns = ["addi $sp, $sp, -16", 

+

3286 "sw $v0, 0($sp)", "sw $a0, 4($sp)", 

+

3287 "sw $a3, 8($sp)", "sw $a3, 12($sp)", 

+

3288 f"li $v0, {_NR_mprotect:d}", 

+

3289 f"li $a0, {addr:d}", 

+

3290 f"li $a1, {size:d}", 

+

3291 f"li $a2, {perm.value:d}", 

+

3292 "syscall", 

+

3293 "lw $v0, 0($sp)", "lw $a1, 4($sp)", 

+

3294 "lw $a3, 8($sp)", "lw $a3, 12($sp)", 

+

3295 "addi $sp, $sp, 16",] 

+

3296 return "; ".join(insns) 

+

3297 

+

3298 

+

3299class MIPS64(MIPS): 

+

3300 aliases = ("MIPS64",) 

+

3301 arch = "MIPS" 

+

3302 mode = "MIPS64" 

+

3303 _ptrsize = 8 

+

3304 

+

3305 @staticmethod 

+

3306 def supports_gdb_arch(gdb_arch: str) -> Optional[bool]: 

+

3307 return gdb_arch.startswith("mips") and gef.binary.e_class == Elf.Class.ELF_64_BITS 

+

3308 

+

3309 

+

3310def copy_to_clipboard(data: bytes) -> None: 

+

3311 """Helper function to submit data to the clipboard""" 

+

3312 if sys.platform == "linux": 

+

3313 xclip = which("xclip") 

+

3314 prog = [xclip, "-selection", "clipboard", "-i"] 

+

3315 elif sys.platform == "darwin": 

+

3316 pbcopy = which("pbcopy") 

+

3317 prog = [pbcopy] 

+

3318 else: 

+

3319 raise NotImplementedError("copy: Unsupported OS") 

+

3320 

+

3321 with subprocess.Popen(prog, stdin=subprocess.PIPE) as p: 

+

3322 p.stdin.write(data) 

+

3323 p.stdin.close() 

+

3324 p.wait() 

+

3325 return 

+

3326 

+

3327 

+

3328def use_stdtype() -> str: 

+

3329 if is_32bit(): return "uint32_t" 3329 ↛ exitline 3329 didn't return from function 'use_stdtype', because the return on line 3329 wasn't executed

+

3330 elif is_64bit(): return "uint64_t" 3330 ↛ 3331line 3330 didn't jump to line 3331, because the condition on line 3330 was never false

+

3331 return "uint16_t" 

+

3332 

+

3333 

+

3334def use_default_type() -> str: 

+

3335 if is_32bit(): return "unsigned int" 3335 ↛ exitline 3335 didn't return from function 'use_default_type', because the return on line 3335 wasn't executed

+

3336 elif is_64bit(): return "unsigned long" 3336 ↛ 3337line 3336 didn't jump to line 3337, because the condition on line 3336 was never false

+

3337 return "unsigned short" 

+

3338 

+

3339 

+

3340def use_golang_type() -> str: 

+

3341 if is_32bit(): return "uint32" 

+

3342 elif is_64bit(): return "uint64" 

+

3343 return "uint16" 

+

3344 

+

3345 

+

3346def use_rust_type() -> str: 

+

3347 if is_32bit(): return "u32" 

+

3348 elif is_64bit(): return "u64" 

+

3349 return "u16" 

+

3350 

+

3351 

+

3352def to_unsigned_long(v: gdb.Value) -> int: 

+

3353 """Cast a gdb.Value to unsigned long.""" 

+

3354 mask = (1 << 64) - 1 

+

3355 return int(v.cast(gdb.Value(mask).type)) & mask 

+

3356 

+

3357 

+

3358def get_path_from_info_proc() -> Optional[str]: 

+

3359 for x in gdb.execute("info proc", to_string=True).splitlines(): 

+

3360 if x.startswith("exe = "): 

+

3361 return x.split(" = ")[1].replace("'", "") 

+

3362 return None 

+

3363 

+

3364 

+

3365@deprecated("Use `gef.session.os`") 

+

3366def get_os() -> str: 

+

3367 return gef.session.os 

+

3368 

+

3369 

+

3370@lru_cache() 

+

3371def is_qemu() -> bool: 

+

3372 if not is_remote_debug(): 

+

3373 return False 

+

3374 response = gdb.execute("maintenance packet Qqemu.sstepbits", to_string=True, from_tty=False) 

+

3375 return "ENABLE=" in response 

+

3376 

+

3377 

+

3378@lru_cache() 

+

3379def is_qemu_usermode() -> bool: 

+

3380 if not is_qemu(): 

+

3381 return False 

+

3382 response = gdb.execute("maintenance packet qOffsets", to_string=True, from_tty=False) 

+

3383 return "Text=" in response 

+

3384 

+

3385 

+

3386@lru_cache() 

+

3387def is_qemu_system() -> bool: 

+

3388 if not is_qemu(): 

+

3389 return False 

+

3390 response = gdb.execute("maintenance packet qOffsets", to_string=True, from_tty=False) 

+

3391 return "received: \"\"" in response 

+

3392 

+

3393 

+

3394def get_filepath() -> Optional[str]: 

+

3395 """Return the local absolute path of the file currently debugged.""" 

+

3396 if gef.session.remote: 

+

3397 return str(gef.session.remote.lfile.absolute()) 

+

3398 if gef.session.file: 3398 ↛ 3400line 3398 didn't jump to line 3400, because the condition on line 3398 was never false

+

3399 return str(gef.session.file.absolute()) 

+

3400 return None 

+

3401 

+

3402 

+

3403def get_function_length(sym: str) -> int: 

+

3404 """Attempt to get the length of the raw bytes of a function.""" 

+

3405 dis = gdb.execute(f"disassemble {sym}", to_string=True).splitlines() 

+

3406 start_addr = int(dis[1].split()[0], 16) 

+

3407 end_addr = int(dis[-2].split()[0], 16) 

+

3408 return end_addr - start_addr 

+

3409 

+

3410 

+

3411@lru_cache() 

+

3412def get_info_files() -> List[Zone]: 

+

3413 """Retrieve all the files loaded by debuggee.""" 

+

3414 lines = gdb.execute("info files", to_string=True).splitlines() 

+

3415 infos = [] 

+

3416 for line in lines: 

+

3417 line = line.strip() 

+

3418 if not line: 3418 ↛ 3419line 3418 didn't jump to line 3419, because the condition on line 3418 was never true

+

3419 break 

+

3420 

+

3421 if not line.startswith("0x"): 

+

3422 continue 

+

3423 

+

3424 blobs = [x.strip() for x in line.split(" ")] 

+

3425 addr_start = int(blobs[0], 16) 

+

3426 addr_end = int(blobs[2], 16) 

+

3427 section_name = blobs[4] 

+

3428 

+

3429 if len(blobs) == 7: 

+

3430 filename = blobs[6] 

+

3431 else: 

+

3432 filename = get_filepath() 

+

3433 

+

3434 infos.append(Zone(section_name, addr_start, addr_end, filename)) 

+

3435 return infos 

+

3436 

+

3437 

+

3438def process_lookup_address(address: int) -> Optional[Section]: 

+

3439 """Look up for an address in memory. 

+

3440 Return an Address object if found, None otherwise.""" 

+

3441 if not is_alive(): 3441 ↛ 3442line 3441 didn't jump to line 3442, because the condition on line 3441 was never true

+

3442 err("Process is not running") 

+

3443 return None 

+

3444 

+

3445 if is_x86(): 3445 ↛ 3449line 3445 didn't jump to line 3449, because the condition on line 3445 was never false

+

3446 if is_in_x86_kernel(address): 3446 ↛ 3447line 3446 didn't jump to line 3447, because the condition on line 3446 was never true

+

3447 return None 

+

3448 

+

3449 for sect in gef.memory.maps: 

+

3450 if sect.page_start <= address < sect.page_end: 

+

3451 return sect 

+

3452 

+

3453 return None 

+

3454 

+

3455 

+

3456@lru_cache() 

+

3457def process_lookup_path(name: str, perm: Permission = Permission.ALL) -> Optional[Section]: 

+

3458 """Look up for a path in the process memory mapping. 

+

3459 Return a Section object if found, None otherwise.""" 

+

3460 if not is_alive(): 3460 ↛ 3461line 3460 didn't jump to line 3461, because the condition on line 3460 was never true

+

3461 err("Process is not running") 

+

3462 return None 

+

3463 

+

3464 for sect in gef.memory.maps: 3464 ↛ 3468line 3464 didn't jump to line 3468, because the loop on line 3464 didn't complete

+

3465 if name in sect.path and sect.permission & perm: 

+

3466 return sect 

+

3467 

+

3468 return None 

+

3469 

+

3470 

+

3471@lru_cache() 

+

3472def file_lookup_name_path(name: str, path: str) -> Optional[Zone]: 

+

3473 """Look up a file by name and path. 

+

3474 Return a Zone object if found, None otherwise.""" 

+

3475 for xfile in get_info_files(): 3475 ↛ 3478line 3475 didn't jump to line 3478, because the loop on line 3475 didn't complete

+

3476 if path == xfile.filename and name == xfile.name: 

+

3477 return xfile 

+

3478 return None 

+

3479 

+

3480 

+

3481@lru_cache() 

+

3482def file_lookup_address(address: int) -> Optional[Zone]: 

+

3483 """Look up for a file by its address. 

+

3484 Return a Zone object if found, None otherwise.""" 

+

3485 for info in get_info_files(): 

+

3486 if info.zone_start <= address < info.zone_end: 

+

3487 return info 

+

3488 return None 

+

3489 

+

3490 

+

3491@lru_cache() 

+

3492def lookup_address(address: int) -> Address: 

+

3493 """Try to find the address in the process address space. 

+

3494 Return an Address object, with validity flag set based on success.""" 

+

3495 sect = process_lookup_address(address) 

+

3496 info = file_lookup_address(address) 

+

3497 if sect is None and info is None: 

+

3498 # i.e. there is no info on this address 

+

3499 return Address(value=address, valid=False) 

+

3500 return Address(value=address, section=sect, info=info) 

+

3501 

+

3502 

+

3503def xor(data: ByteString, key: str) -> bytearray: 

+

3504 """Return `data` xor-ed with `key`.""" 

+

3505 key_raw = binascii.unhexlify(key.lstrip("0x")) 

+

3506 return bytearray(x ^ y for x, y in zip(data, itertools.cycle(key_raw))) 

+

3507 

+

3508 

+

3509def is_hex(pattern: str) -> bool: 

+

3510 """Return whether provided string is a hexadecimal value.""" 

+

3511 if not pattern.lower().startswith("0x"): 

+

3512 return False 

+

3513 return len(pattern) % 2 == 0 and all(c in string.hexdigits for c in pattern[2:]) 

+

3514 

+

3515 

+

3516def continue_handler(_: "gdb.ContinueEvent") -> None: 

+

3517 """GDB event handler for new object continue cases.""" 

+

3518 return 

+

3519 

+

3520 

+

3521def hook_stop_handler(_: "gdb.StopEvent") -> None: 

+

3522 """GDB event handler for stop cases.""" 

+

3523 reset_all_caches() 

+

3524 gdb.execute("context") 

+

3525 return 

+

3526 

+

3527 

+

3528def new_objfile_handler(evt: Optional["gdb.NewObjFileEvent"]) -> None: 

+

3529 """GDB event handler for new object file cases.""" 

+

3530 reset_all_caches() 

+

3531 path = evt.new_objfile.filename if evt else gdb.current_progspace().filename 

+

3532 try: 

+

3533 if gef.session.root and path.startswith("target:"): 3533 ↛ 3536line 3533 didn't jump to line 3536, because the condition on line 3533 was never true

+

3534 # If the process is in a container, replace the "target:" prefix 

+

3535 # with the actual root directory of the process. 

+

3536 path = path.replace("target:", str(gef.session.root), 1) 

+

3537 target = pathlib.Path(path) 

+

3538 FileFormatClasses = list(filter(lambda fmtcls: fmtcls.is_valid(target), __registered_file_formats__)) 

+

3539 GuessedFileFormatClass : Type[FileFormat] = FileFormatClasses.pop() if len(FileFormatClasses) else Elf 

+

3540 binary = GuessedFileFormatClass(target) 

+

3541 if not gef.binary: 

+

3542 gef.binary = binary 

+

3543 reset_architecture() 

+

3544 else: 

+

3545 gef.session.modules.append(binary) 

+

3546 except FileNotFoundError as fne: 3546 ↛ 3552line 3546 didn't jump to line 3552

+

3547 # Linux automatically maps the vDSO into our process, and GDB 

+

3548 # will give us the string 'system-supplied DSO' as a path. 

+

3549 # This is normal, so we shouldn't warn the user about it 

+

3550 if "system-supplied DSO" not in path: 3550 ↛ 3551line 3550 didn't jump to line 3551, because the condition on line 3550 was never true

+

3551 warn(f"Failed to find objfile or not a valid file format: {str(fne)}") 

+

3552 except RuntimeError as re: 

+

3553 warn(f"Not a valid file format: {str(re)}") 

+

3554 return 

+

3555 

+

3556 

+

3557def exit_handler(_: "gdb.ExitedEvent") -> None: 

+

3558 """GDB event handler for exit cases.""" 

+

3559 global gef 

+

3560 # flush the caches 

+

3561 reset_all_caches() 

+

3562 

+

3563 # disconnect properly the remote session 

+

3564 gef.session.qemu_mode = False 

+

3565 if gef.session.remote: 

+

3566 gef.session.remote.close() 

+

3567 del gef.session.remote 

+

3568 gef.session.remote = None 

+

3569 gef.session.remote_initializing = False 

+

3570 

+

3571 # if `autosave_breakpoints_file` setting is configured, save the breakpoints to disk 

+

3572 setting = (gef.config["gef.autosave_breakpoints_file"] or "").strip() 

+

3573 if not setting: 3573 ↛ 3576line 3573 didn't jump to line 3576, because the condition on line 3573 was never false

+

3574 return 

+

3575 

+

3576 bkp_fpath = pathlib.Path(setting).expanduser().absolute() 

+

3577 if bkp_fpath.exists(): 

+

3578 warn(f"{bkp_fpath} exists, content will be overwritten") 

+

3579 

+

3580 with bkp_fpath.open("w") as fd: 

+

3581 for bp in gdb.breakpoints(): 

+

3582 if not bp.enabled or not bp.is_valid: 

+

3583 continue 

+

3584 fd.write(f"{'t' if bp.temporary else ''}break {bp.location}\n") 

+

3585 return 

+

3586 

+

3587 

+

3588def memchanged_handler(_: "gdb.MemoryChangedEvent") -> None: 

+

3589 """GDB event handler for mem changes cases.""" 

+

3590 reset_all_caches() 

+

3591 return 

+

3592 

+

3593 

+

3594def regchanged_handler(_: "gdb.RegisterChangedEvent") -> None: 

+

3595 """GDB event handler for reg changes cases.""" 

+

3596 reset_all_caches() 

+

3597 return 

+

3598 

+

3599 

+

3600def get_terminal_size() -> Tuple[int, int]: 

+

3601 """Return the current terminal size.""" 

+

3602 if is_debug(): 3602 ↛ 3605line 3602 didn't jump to line 3605, because the condition on line 3602 was never false

+

3603 return 600, 100 

+

3604 

+

3605 if platform.system() == "Windows": 

+

3606 from ctypes import create_string_buffer, windll 

+

3607 hStdErr = -12 

+

3608 herr = windll.kernel32.GetStdHandle(hStdErr) 

+

3609 csbi = create_string_buffer(22) 

+

3610 res = windll.kernel32.GetConsoleScreenBufferInfo(herr, csbi) 

+

3611 if res: 

+

3612 _, _, _, _, _, left, top, right, bottom, _, _ = struct.unpack("hhhhHhhhhhh", csbi.raw) 

+

3613 tty_columns = right - left + 1 

+

3614 tty_rows = bottom - top + 1 

+

3615 return tty_rows, tty_columns 

+

3616 else: 

+

3617 return 600, 100 

+

3618 else: 

+

3619 import fcntl 

+

3620 import termios 

+

3621 try: 

+

3622 tty_rows, tty_columns = struct.unpack("hh", fcntl.ioctl(1, termios.TIOCGWINSZ, "1234")) # type: ignore 

+

3623 return tty_rows, tty_columns 

+

3624 except OSError: 

+

3625 return 600, 100 

+

3626 

+

3627 

+

3628@lru_cache() 

+

3629def is_64bit() -> bool: 

+

3630 """Checks if current target is 64bit.""" 

+

3631 return gef.arch.ptrsize == 8 

+

3632 

+

3633 

+

3634@lru_cache() 

+

3635def is_32bit() -> bool: 

+

3636 """Checks if current target is 32bit.""" 

+

3637 return gef.arch.ptrsize == 4 

+

3638 

+

3639 

+

3640@lru_cache() 

+

3641def is_x86_64() -> bool: 

+

3642 """Checks if current target is x86-64""" 

+

3643 return Elf.Abi.X86_64 in gef.arch.aliases 

+

3644 

+

3645 

+

3646@lru_cache() 

+

3647def is_x86_32(): 

+

3648 """Checks if current target is an x86-32""" 

+

3649 return Elf.Abi.X86_32 in gef.arch.aliases 

+

3650 

+

3651 

+

3652@lru_cache() 

+

3653def is_x86() -> bool: 

+

3654 return is_x86_32() or is_x86_64() 

+

3655 

+

3656 

+

3657@lru_cache() 

+

3658def is_arch(arch: Elf.Abi) -> bool: 

+

3659 return arch in gef.arch.aliases 

+

3660 

+

3661 

+

3662def reset_architecture(arch: Optional[str] = None) -> None: 

+

3663 """Sets the current architecture. 

+

3664 If an architecture is explicitly specified by parameter, try to use that one. If this fails, an `OSError` 

+

3665 exception will occur. 

+

3666 If no architecture is specified, then GEF will attempt to determine automatically based on the current 

+

3667 ELF target. If this fails, an `OSError` exception will occur. 

+

3668 """ 

+

3669 global gef 

+

3670 arches = __registered_architectures__ 

+

3671 

+

3672 # check if the architecture is forced by parameter 

+

3673 if arch: 3673 ↛ 3674line 3673 didn't jump to line 3674, because the condition on line 3673 was never true

+

3674 try: 

+

3675 gef.arch = arches[arch]() 

+

3676 except KeyError: 

+

3677 raise OSError(f"Specified arch {arch.upper()} is not supported") 

+

3678 return 

+

3679 

+

3680 gdb_arch = get_arch() 

+

3681 

+

3682 preciser_arch = next((a for a in arches.values() if a.supports_gdb_arch(gdb_arch)), None) 

+

3683 if preciser_arch: 3683 ↛ 3684line 3683 didn't jump to line 3684, because the condition on line 3683 was never true

+

3684 gef.arch = preciser_arch() 

+

3685 return 

+

3686 

+

3687 # last resort, use the info from elf header to find it from the known architectures 

+

3688 try: 

+

3689 arch_name = gef.binary.e_machine if gef.binary else gdb_arch 

+

3690 gef.arch = arches[arch_name]() 

+

3691 except KeyError: 

+

3692 raise OSError(f"CPU type is currently not supported: {get_arch()}") 

+

3693 return 

+

3694 

+

3695 

+

3696@lru_cache() 

+

3697def cached_lookup_type(_type: str) -> Optional[gdb.Type]: 

+

3698 try: 

+

3699 return gdb.lookup_type(_type).strip_typedefs() 

+

3700 except RuntimeError: 

+

3701 return None 

+

3702 

+

3703 

+

3704@deprecated("Use `gef.arch.ptrsize` instead") 

+

3705def get_memory_alignment(in_bits: bool = False) -> int: 

+

3706 """Try to determine the size of a pointer on this system. 

+

3707 First, try to parse it out of the ELF header. 

+

3708 Next, use the size of `size_t`. 

+

3709 Finally, try the size of $pc. 

+

3710 If `in_bits` is set to True, the result is returned in bits, otherwise in 

+

3711 bytes.""" 

+

3712 res = cached_lookup_type("size_t") 

+

3713 if res is not None: 

+

3714 return res.sizeof if not in_bits else res.sizeof * 8 

+

3715 

+

3716 try: 

+

3717 return gdb.parse_and_eval("$pc").type.sizeof 

+

3718 except: 

+

3719 pass 

+

3720 

+

3721 raise OSError("GEF is running under an unsupported mode") 

+

3722 

+

3723 

+

3724def clear_screen(tty: str = "") -> None: 

+

3725 """Clear the screen.""" 

+

3726 global gef 

+

3727 if not tty: 3727 ↛ 3733line 3727 didn't jump to line 3733, because the condition on line 3727 was never false

+

3728 gdb.execute("shell clear -x") 

+

3729 return 

+

3730 

+

3731 # Since the tty can be closed at any time, a PermissionError exception can 

+

3732 # occur when `clear_screen` is called. We handle this scenario properly 

+

3733 try: 

+

3734 with open(tty, "wt") as f: 

+

3735 f.write("\x1b[H\x1b[J") 

+

3736 except PermissionError: 

+

3737 gef.ui.redirect_fd = None 

+

3738 gef.config["context.redirect"] = "" 

+

3739 return 

+

3740 

+

3741 

+

3742def format_address(addr: int) -> str: 

+

3743 """Format the address according to its size.""" 

+

3744 memalign_size = gef.arch.ptrsize 

+

3745 addr = align_address(addr) 

+

3746 

+

3747 if memalign_size == 4: 3747 ↛ 3748line 3747 didn't jump to line 3748, because the condition on line 3747 was never true

+

3748 return f"0x{addr:08x}" 

+

3749 

+

3750 return f"0x{addr:016x}" 

+

3751 

+

3752 

+

3753def format_address_spaces(addr: int, left: bool = True) -> str: 

+

3754 """Format the address according to its size, but with spaces instead of zeroes.""" 

+

3755 width = gef.arch.ptrsize * 2 + 2 

+

3756 addr = align_address(addr) 

+

3757 

+

3758 if not left: 3758 ↛ 3759line 3758 didn't jump to line 3759, because the condition on line 3758 was never true

+

3759 return f"{addr:#x}".rjust(width) 

+

3760 

+

3761 return f"{addr:#x}".ljust(width) 

+

3762 

+

3763 

+

3764def align_address(address: int) -> int: 

+

3765 """Align the provided address to the process's native length.""" 

+

3766 if gef.arch.ptrsize == 4: 3766 ↛ 3767line 3766 didn't jump to line 3767, because the condition on line 3766 was never true

+

3767 return address & 0xFFFFFFFF 

+

3768 

+

3769 return address & 0xFFFFFFFFFFFFFFFF 

+

3770 

+

3771 

+

3772def align_address_to_size(address: int, align: int) -> int: 

+

3773 """Align the address to the given size.""" 

+

3774 return address + ((align - (address % align)) % align) 

+

3775 

+

3776 

+

3777def align_address_to_page(address: int) -> int: 

+

3778 """Align the address to a page.""" 

+

3779 a = align_address(address) >> DEFAULT_PAGE_ALIGN_SHIFT 

+

3780 return a << DEFAULT_PAGE_ALIGN_SHIFT 

+

3781 

+

3782 

+

3783def parse_address(address: str) -> int: 

+

3784 """Parse an address and return it as an Integer.""" 

+

3785 if is_hex(address): 

+

3786 return int(address, 16) 

+

3787 return to_unsigned_long(gdb.parse_and_eval(address)) 

+

3788 

+

3789 

+

3790def is_in_x86_kernel(address: int) -> bool: 

+

3791 address = align_address(address) 

+

3792 memalign = gef.arch.ptrsize*8 - 1 

+

3793 return (address >> memalign) == 0xF 

+

3794 

+

3795 

+

3796def is_remote_debug() -> bool: 

+

3797 """"Return True is the current debugging session is running through GDB remote session.""" 

+

3798 return gef.session.remote_initializing or gef.session.remote is not None 

+

3799 

+

3800 

+

3801def de_bruijn(alphabet: bytes, n: int) -> Generator[str, None, None]: 

+

3802 """De Bruijn sequence for alphabet and subsequences of length n (for compat. w/ pwnlib).""" 

+

3803 k = len(alphabet) 

+

3804 a = [0] * k * n 

+

3805 

+

3806 def db(t: int, p: int) -> Generator[str, None, None]: 

+

3807 if t > n: 

+

3808 if n % p == 0: 

+

3809 for j in range(1, p + 1): 

+

3810 yield alphabet[a[j]] 

+

3811 else: 

+

3812 a[t] = a[t - p] 

+

3813 yield from db(t + 1, p) 

+

3814 

+

3815 for j in range(a[t - p] + 1, k): 

+

3816 a[t] = j 

+

3817 yield from db(t + 1, t) 

+

3818 

+

3819 return db(1, 1) 

+

3820 

+

3821 

+

3822def generate_cyclic_pattern(length: int, cycle: int = 4) -> bytearray: 

+

3823 """Create a `length` byte bytearray of a de Bruijn cyclic pattern.""" 

+

3824 charset = bytearray(b"abcdefghijklmnopqrstuvwxyz") 

+

3825 return bytearray(itertools.islice(de_bruijn(charset, cycle), length)) 

+

3826 

+

3827 

+

3828def safe_parse_and_eval(value: str) -> Optional["gdb.Value"]: 

+

3829 """GEF wrapper for gdb.parse_and_eval(): this function returns None instead of raising 

+

3830 gdb.error if the eval failed.""" 

+

3831 try: 

+

3832 return gdb.parse_and_eval(value) 

+

3833 except gdb.error: 

+

3834 pass 

+

3835 return None 

+

3836 

+

3837 

+

3838@lru_cache() 

+

3839def dereference(addr: int) -> Optional["gdb.Value"]: 

+

3840 """GEF wrapper for gdb dereference function.""" 

+

3841 try: 

+

3842 ulong_t = cached_lookup_type(use_stdtype()) or \ 

+

3843 cached_lookup_type(use_default_type()) or \ 

+

3844 cached_lookup_type(use_golang_type()) or \ 

+

3845 cached_lookup_type(use_rust_type()) 

+

3846 unsigned_long_type = ulong_t.pointer() 

+

3847 res = gdb.Value(addr).cast(unsigned_long_type).dereference() 

+

3848 # GDB does lazy fetch by default so we need to force access to the value 

+

3849 res.fetch_lazy() 

+

3850 return res 

+

3851 except gdb.MemoryError: 

+

3852 pass 

+

3853 return None 

+

3854 

+

3855 

+

3856def gef_convenience(value: Union[str, bytes]) -> str: 

+

3857 """Defines a new convenience value.""" 

+

3858 global gef 

+

3859 var_name = f"$_gef{gef.session.convenience_vars_index:d}" 

+

3860 gef.session.convenience_vars_index += 1 

+

3861 if isinstance(value, str): 

+

3862 gdb.execute(f"""set {var_name} = "{value}" """) 

+

3863 elif isinstance(value, bytes): 3863 ↛ 3867line 3863 didn't jump to line 3867, because the condition on line 3863 was never false

+

3864 value_as_array = "{" + ", ".join(["%#.02x" % x for x in value]) + "}" 

+

3865 gdb.execute(f"""set {var_name} = {value_as_array} """) 

+

3866 else: 

+

3867 raise TypeError 

+

3868 return var_name 

+

3869 

+

3870 

+

3871def parse_string_range(s: str) -> Iterator[int]: 

+

3872 """Parses an address range (e.g. 0x400000-0x401000)""" 

+

3873 addrs = s.split("-") 

+

3874 return map(lambda x: int(x, 16), addrs) 

+

3875 

+

3876 

+

3877@lru_cache() 

+

3878def is_syscall(instruction: Union[Instruction,int]) -> bool: 

+

3879 """Checks whether an instruction or address points to a system call.""" 

+

3880 if isinstance(instruction, int): 

+

3881 instruction = gef_current_instruction(instruction) 

+

3882 insn_str = instruction.mnemonic 

+

3883 if len(instruction.operands): 

+

3884 insn_str += f" {', '.join(instruction.operands)}" 

+

3885 return insn_str in gef.arch.syscall_instructions 

+

3886 

+

3887 

+

3888# 

+

3889# Deprecated API 

+

3890# 

+

3891 

+

3892@deprecated("Use `gef.session.pie_breakpoints[num]`") 

+

3893def gef_get_pie_breakpoint(num: int) -> "PieVirtualBreakpoint": 

+

3894 return gef.session.pie_breakpoints[num] 

+

3895 

+

3896 

+

3897@deprecated("Use `str(gef.arch.endianness)` instead") 

+

3898def endian_str() -> str: 

+

3899 return str(gef.arch.endianness) 

+

3900 

+

3901 

+

3902@deprecated("Use `gef.config[key]`") 

+

3903def get_gef_setting(name: str) -> Any: 

+

3904 return gef.config[name] 

+

3905 

+

3906 

+

3907@deprecated("Use `gef.config[key] = value`") 

+

3908def set_gef_setting(name: str, value: Any) -> None: 

+

3909 gef.config[name] = value 

+

3910 return 

+

3911 

+

3912 

+

3913@deprecated("Use `gef.session.pagesize`") 

+

3914def gef_getpagesize() -> int: 

+

3915 return gef.session.pagesize 

+

3916 

+

3917 

+

3918@deprecated("Use `gef.session.canary`") 

+

3919def gef_read_canary() -> Optional[Tuple[int, int]]: 

+

3920 return gef.session.canary 

+

3921 

+

3922 

+

3923@deprecated("Use `gef.session.pid`") 

+

3924def get_pid() -> int: 

+

3925 return gef.session.pid 

+

3926 

+

3927 

+

3928@deprecated("Use `gef.session.file.name`") 

+

3929def get_filename() -> str: 

+

3930 return gef.session.file.name 

+

3931 

+

3932 

+

3933@deprecated("Use `gef.heap.main_arena`") 

+

3934def get_glibc_arena() -> Optional[GlibcArena]: 

+

3935 return gef.heap.main_arena 

+

3936 

+

3937 

+

3938@deprecated("Use `gef.arch.register(regname)`") 

+

3939def get_register(regname) -> Optional[int]: 

+

3940 return gef.arch.register(regname) 

+

3941 

+

3942 

+

3943@deprecated("Use `gef.memory.maps`") 

+

3944def get_process_maps() -> List[Section]: 

+

3945 return gef.memory.maps 

+

3946 

+

3947 

+

3948@deprecated("Use `reset_architecture`") 

+

3949def set_arch(arch: Optional[str] = None, _: Optional[str] = None) -> None: 

+

3950 return reset_architecture(arch) 

+

3951 

+

3952# 

+

3953# GDB event hooking 

+

3954# 

+

3955 

+

3956@only_if_events_supported("cont") 

+

3957def gef_on_continue_hook(func: Callable[["gdb.ContinueEvent"], None]) -> None: 

+

3958 gdb.events.cont.connect(func) 

+

3959 

+

3960 

+

3961@only_if_events_supported("cont") 

+

3962def gef_on_continue_unhook(func: Callable[["gdb.ThreadEvent"], None]) -> None: 

+

3963 gdb.events.cont.disconnect(func) 

+

3964 

+

3965 

+

3966@only_if_events_supported("stop") 

+

3967def gef_on_stop_hook(func: Callable[["gdb.StopEvent"], None]) -> None: 

+

3968 gdb.events.stop.connect(func) 

+

3969 

+

3970 

+

3971@only_if_events_supported("stop") 

+

3972def gef_on_stop_unhook(func: Callable[["gdb.StopEvent"], None]) -> None: 

+

3973 gdb.events.stop.disconnect(func) 

+

3974 

+

3975 

+

3976@only_if_events_supported("exited") 

+

3977def gef_on_exit_hook(func: Callable[["gdb.ExitedEvent"], None]) -> None: 

+

3978 gdb.events.exited.connect(func) 

+

3979 

+

3980 

+

3981@only_if_events_supported("exited") 

+

3982def gef_on_exit_unhook(func: Callable[["gdb.ExitedEvent"], None]) -> None: 

+

3983 gdb.events.exited.disconnect(func) 

+

3984 

+

3985 

+

3986@only_if_events_supported("new_objfile") 

+

3987def gef_on_new_hook(func: Callable[["gdb.NewObjFileEvent"], None]) -> None: 

+

3988 gdb.events.new_objfile.connect(func) 

+

3989 

+

3990 

+

3991@only_if_events_supported("new_objfile") 

+

3992def gef_on_new_unhook(func: Callable[["gdb.NewObjFileEvent"], None]) -> None: 

+

3993 gdb.events.new_objfile.disconnect(func) 

+

3994 

+

3995 

+

3996@only_if_events_supported("clear_objfiles") 

+

3997def gef_on_unload_objfile_hook(func: Callable[["gdb.ClearObjFilesEvent"], None]) -> None: 

+

3998 gdb.events.clear_objfiles.connect(func) 

+

3999 

+

4000 

+

4001@only_if_events_supported("clear_objfiles") 

+

4002def gef_on_unload_objfile_unhook(func: Callable[["gdb.ClearObjFilesEvent"], None]) -> None: 

+

4003 gdb.events.clear_objfiles.disconnect(func) 

+

4004 

+

4005 

+

4006@only_if_events_supported("memory_changed") 

+

4007def gef_on_memchanged_hook(func: Callable[["gdb.MemoryChangedEvent"], None]) -> None: 

+

4008 gdb.events.memory_changed.connect(func) 

+

4009 

+

4010 

+

4011@only_if_events_supported("memory_changed") 

+

4012def gef_on_memchanged_unhook(func: Callable[["gdb.MemoryChangedEvent"], None]) -> None: 

+

4013 gdb.events.memory_changed.disconnect(func) 

+

4014 

+

4015 

+

4016@only_if_events_supported("register_changed") 

+

4017def gef_on_regchanged_hook(func: Callable[["gdb.RegisterChangedEvent"], None]) -> None: 

+

4018 gdb.events.register_changed.connect(func) 

+

4019 

+

4020 

+

4021@only_if_events_supported("register_changed") 

+

4022def gef_on_regchanged_unhook(func: Callable[["gdb.RegisterChangedEvent"], None]) -> None: 

+

4023 gdb.events.register_changed.disconnect(func) 

+

4024 

+

4025 

+

4026# 

+

4027# Virtual breakpoints 

+

4028# 

+

4029 

+

4030class PieVirtualBreakpoint: 

+

4031 """PIE virtual breakpoint (not real breakpoint).""" 

+

4032 

+

4033 def __init__(self, set_func: Callable[[int], str], vbp_num: int, addr: int) -> None: 

+

4034 # set_func(base): given a base address return a 

+

4035 # "set breakpoint" gdb command string 

+

4036 self.set_func = set_func 

+

4037 self.vbp_num = vbp_num 

+

4038 # breakpoint num, 0 represents not instantiated yet 

+

4039 self.bp_num = 0 

+

4040 self.bp_addr = 0 

+

4041 # this address might be a symbol, just to know where to break 

+

4042 if isinstance(addr, int): 4042 ↛ 4045line 4042 didn't jump to line 4045, because the condition on line 4042 was never false

+

4043 self.addr: Union[int, str] = hex(addr) 

+

4044 else: 

+

4045 self.addr = addr 

+

4046 return 

+

4047 

+

4048 def instantiate(self, base: int) -> None: 

+

4049 if self.bp_num: 4049 ↛ 4050line 4049 didn't jump to line 4050, because the condition on line 4049 was never true

+

4050 self.destroy() 

+

4051 

+

4052 try: 

+

4053 res = gdb.execute(self.set_func(base), to_string=True) 

+

4054 except gdb.error as e: 

+

4055 err(e) 

+

4056 return 

+

4057 

+

4058 if "Breakpoint" not in res: 4058 ↛ 4059line 4058 didn't jump to line 4059, because the condition on line 4058 was never true

+

4059 err(res) 

+

4060 return 

+

4061 res_list = res.split() 

+

4062 self.bp_num = res_list[1] 

+

4063 self.bp_addr = res_list[3] 

+

4064 return 

+

4065 

+

4066 def destroy(self) -> None: 

+

4067 if not self.bp_num: 

+

4068 err("Destroy PIE breakpoint not even set") 

+

4069 return 

+

4070 gdb.execute(f"delete {self.bp_num}") 

+

4071 self.bp_num = 0 

+

4072 return 

+

4073 

+

4074 

+

4075# 

+

4076# Breakpoints 

+

4077# 

+

4078 

+

4079class FormatStringBreakpoint(gdb.Breakpoint): 

+

4080 """Inspect stack for format string.""" 

+

4081 def __init__(self, spec: str, num_args: int) -> None: 

+

4082 super().__init__(spec, type=gdb.BP_BREAKPOINT, internal=False) 

+

4083 self.num_args = num_args 

+

4084 self.enabled = True 

+

4085 return 

+

4086 

+

4087 def stop(self) -> bool: 

+

4088 reset_all_caches() 

+

4089 msg = [] 

+

4090 ptr, addr = gef.arch.get_ith_parameter(self.num_args) 

+

4091 addr = lookup_address(addr) 

+

4092 

+

4093 if not addr.valid: 4093 ↛ 4094line 4093 didn't jump to line 4094, because the condition on line 4093 was never true

+

4094 return False 

+

4095 

+

4096 if addr.section.is_writable(): 4096 ↛ 4106line 4096 didn't jump to line 4106, because the condition on line 4096 was never false

+

4097 content = gef.memory.read_cstring(addr.value) 

+

4098 name = addr.info.name if addr.info else addr.section.path 

+

4099 msg.append(Color.colorify("Format string helper", "yellow bold")) 

+

4100 msg.append(f"Possible insecure format string: {self.location}('{ptr}' {RIGHT_ARROW} {addr.value:#x}: '{content}')") 

+

4101 msg.append(f"Reason: Call to '{self.location}()' with format string argument in position " 

+

4102 f"#{self.num_args:d} is in page {addr.section.page_start:#x} ({name}) that has write permission") 

+

4103 push_context_message("warn", "\n".join(msg)) 

+

4104 return True 

+

4105 

+

4106 return False 

+

4107 

+

4108 

+

4109class StubBreakpoint(gdb.Breakpoint): 

+

4110 """Create a breakpoint to permanently disable a call (fork/alarm/signal/etc.).""" 

+

4111 

+

4112 def __init__(self, func: str, retval: Optional[int]) -> None: 

+

4113 super().__init__(func, gdb.BP_BREAKPOINT, internal=False) 

+

4114 self.func = func 

+

4115 self.retval = retval 

+

4116 

+

4117 m = f"All calls to '{self.func}' will be skipped" 

+

4118 if self.retval is not None: 4118 ↛ 4120line 4118 didn't jump to line 4120, because the condition on line 4118 was never false

+

4119 m += f" (with return value set to {self.retval:#x})" 

+

4120 info(m) 

+

4121 return 

+

4122 

+

4123 def stop(self) -> bool: 

+

4124 gdb.execute(f"return (unsigned int){self.retval:#x}") 

+

4125 ok(f"Ignoring call to '{self.func}' " 

+

4126 f"(setting return value to {self.retval:#x})") 

+

4127 return False 

+

4128 

+

4129 

+

4130class ChangePermissionBreakpoint(gdb.Breakpoint): 

+

4131 """When hit, this temporary breakpoint will restore the original code, and position 

+

4132 $pc correctly.""" 

+

4133 

+

4134 def __init__(self, loc: str, code: ByteString, pc: int) -> None: 

+

4135 super().__init__(loc, gdb.BP_BREAKPOINT, internal=False) 

+

4136 self.original_code = code 

+

4137 self.original_pc = pc 

+

4138 return 

+

4139 

+

4140 def stop(self) -> bool: 

+

4141 info("Restoring original context") 

+

4142 gef.memory.write(self.original_pc, self.original_code, len(self.original_code)) 

+

4143 info("Restoring $pc") 

+

4144 gdb.execute(f"set $pc = {self.original_pc:#x}") 

+

4145 return True 

+

4146 

+

4147 

+

4148class TraceMallocBreakpoint(gdb.Breakpoint): 

+

4149 """Track allocations done with malloc() or calloc().""" 

+

4150 

+

4151 def __init__(self, name: str) -> None: 

+

4152 super().__init__(name, gdb.BP_BREAKPOINT, internal=True) 

+

4153 self.silent = True 

+

4154 self.name = name 

+

4155 return 

+

4156 

+

4157 def stop(self) -> bool: 

+

4158 reset_all_caches() 

+

4159 _, size = gef.arch.get_ith_parameter(0) 

+

4160 self.retbp = TraceMallocRetBreakpoint(size, self.name) 

+

4161 return False 

+

4162 

+

4163 

+

4164class TraceMallocRetBreakpoint(gdb.FinishBreakpoint): 

+

4165 """Internal temporary breakpoint to retrieve the return value of malloc().""" 

+

4166 

+

4167 def __init__(self, size: int, name: str) -> None: 

+

4168 super().__init__(gdb.newest_frame(), internal=True) 

+

4169 self.size = size 

+

4170 self.name = name 

+

4171 self.silent = True 

+

4172 return 

+

4173 

+

4174 def stop(self) -> bool: 

+

4175 if self.return_value: 4175 ↛ 4178line 4175 didn't jump to line 4178, because the condition on line 4175 was never false

+

4176 loc = int(self.return_value) 

+

4177 else: 

+

4178 loc = parse_address(gef.arch.return_register) 

+

4179 

+

4180 size = self.size 

+

4181 ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - {self.name}({size})={loc:#x}") 

+

4182 check_heap_overlap = gef.config["heap-analysis-helper.check_heap_overlap"] 

+

4183 

+

4184 # pop from free-ed list if it was in it 

+

4185 if gef.session.heap_freed_chunks: 4185 ↛ 4186line 4185 didn't jump to line 4186, because the condition on line 4185 was never true

+

4186 idx = 0 

+

4187 for item in gef.session.heap_freed_chunks: 

+

4188 addr = item[0] 

+

4189 if addr == loc: 

+

4190 gef.session.heap_freed_chunks.remove(item) 

+

4191 continue 

+

4192 idx += 1 

+

4193 

+

4194 # pop from uaf watchlist 

+

4195 if gef.session.heap_uaf_watchpoints: 4195 ↛ 4196line 4195 didn't jump to line 4196, because the condition on line 4195 was never true

+

4196 idx = 0 

+

4197 for wp in gef.session.heap_uaf_watchpoints: 

+

4198 wp_addr = wp.address 

+

4199 if loc <= wp_addr < loc + size: 

+

4200 gef.session.heap_uaf_watchpoints.remove(wp) 

+

4201 wp.enabled = False 

+

4202 continue 

+

4203 idx += 1 

+

4204 

+

4205 item = (loc, size) 

+

4206 

+

4207 if check_heap_overlap: 4207 ↛ 4229line 4207 didn't jump to line 4229, because the condition on line 4207 was never false

+

4208 # seek all the currently allocated chunks, read their effective size and check for overlap 

+

4209 msg = [] 

+

4210 align = gef.arch.ptrsize 

+

4211 for chunk_addr, _ in gef.session.heap_allocated_chunks: 

+

4212 current_chunk = GlibcChunk(chunk_addr) 

+

4213 current_chunk_size = current_chunk.size 

+

4214 

+

4215 if chunk_addr <= loc < chunk_addr + current_chunk_size: 4215 ↛ 4216line 4215 didn't jump to line 4216, because the condition on line 4215 was never true

+

4216 offset = loc - chunk_addr - 2*align 

+

4217 if offset < 0: continue # false positive, discard 

+

4218 

+

4219 msg.append(Color.colorify("Heap-Analysis", "yellow bold")) 

+

4220 msg.append("Possible heap overlap detected") 

+

4221 msg.append(f"Reason {RIGHT_ARROW} new allocated chunk {loc:#x} (of size {size:d}) overlaps in-used chunk {chunk_addr:#x} (of size {current_chunk_size:#x})") 

+

4222 msg.append(f"Writing {offset:d} bytes from {chunk_addr:#x} will reach chunk {loc:#x}") 

+

4223 msg.append(f"Payload example for chunk {chunk_addr:#x} (to overwrite {loc:#x} headers):") 

+

4224 msg.append(" data = 'A'*{0:d} + 'B'*{1:d} + 'C'*{1:d}".format(offset, align)) 

+

4225 push_context_message("warn", "\n".join(msg)) 

+

4226 return True 

+

4227 

+

4228 # add it to alloc-ed list 

+

4229 gef.session.heap_allocated_chunks.append(item) 

+

4230 return False 

+

4231 

+

4232 

+

4233class TraceReallocBreakpoint(gdb.Breakpoint): 

+

4234 """Track re-allocations done with realloc().""" 

+

4235 

+

4236 def __init__(self) -> None: 

+

4237 super().__init__("__libc_realloc", gdb.BP_BREAKPOINT, internal=True) 

+

4238 self.silent = True 

+

4239 return 

+

4240 

+

4241 def stop(self) -> bool: 

+

4242 _, ptr = gef.arch.get_ith_parameter(0) 

+

4243 _, size = gef.arch.get_ith_parameter(1) 

+

4244 self.retbp = TraceReallocRetBreakpoint(ptr, size) 

+

4245 return False 

+

4246 

+

4247 

+

4248class TraceReallocRetBreakpoint(gdb.FinishBreakpoint): 

+

4249 """Internal temporary breakpoint to retrieve the return value of realloc().""" 

+

4250 

+

4251 def __init__(self, ptr: int, size: int) -> None: 

+

4252 super().__init__(gdb.newest_frame(), internal=True) 

+

4253 self.ptr = ptr 

+

4254 self.size = size 

+

4255 self.silent = True 

+

4256 return 

+

4257 

+

4258 def stop(self) -> bool: 

+

4259 if self.return_value: 4259 ↛ 4262line 4259 didn't jump to line 4262, because the condition on line 4259 was never false

+

4260 newloc = int(self.return_value) 

+

4261 else: 

+

4262 newloc = parse_address(gef.arch.return_register) 

+

4263 

+

4264 if newloc != self: 4264 ↛ 4269line 4264 didn't jump to line 4269, because the condition on line 4264 was never false

+

4265 ok("{} - realloc({:#x}, {})={}".format(Color.colorify("Heap-Analysis", "yellow bold"), 

+

4266 self.ptr, self.size, 

+

4267 Color.colorify(f"{newloc:#x}", "green"),)) 

+

4268 else: 

+

4269 ok("{} - realloc({:#x}, {})={}".format(Color.colorify("Heap-Analysis", "yellow bold"), 

+

4270 self.ptr, self.size, 

+

4271 Color.colorify(f"{newloc:#x}", "red"),)) 

+

4272 

+

4273 item = (newloc, self.size) 

+

4274 

+

4275 try: 

+

4276 # check if item was in alloc-ed list 

+

4277 idx = [x for x, y in gef.session.heap_allocated_chunks].index(self.ptr) 

+

4278 # if so pop it out 

+

4279 item = gef.session.heap_allocated_chunks.pop(idx) 

+

4280 except ValueError: 

+

4281 if is_debug(): 

+

4282 warn(f"Chunk {self.ptr:#x} was not in tracking list") 

+

4283 finally: 

+

4284 # add new item to alloc-ed list 

+

4285 gef.session.heap_allocated_chunks.append(item) 

+

4286 

+

4287 return False 

+

4288 

+

4289 

+

4290class TraceFreeBreakpoint(gdb.Breakpoint): 

+

4291 """Track calls to free() and attempts to detect inconsistencies.""" 

+

4292 

+

4293 def __init__(self) -> None: 

+

4294 super().__init__("__libc_free", gdb.BP_BREAKPOINT, internal=True) 

+

4295 self.silent = True 

+

4296 return 

+

4297 

+

4298 def stop(self) -> bool: 

+

4299 reset_all_caches() 

+

4300 _, addr = gef.arch.get_ith_parameter(0) 

+

4301 msg = [] 

+

4302 check_free_null = gef.config["heap-analysis-helper.check_free_null"] 

+

4303 check_double_free = gef.config["heap-analysis-helper.check_double_free"] 

+

4304 check_weird_free = gef.config["heap-analysis-helper.check_weird_free"] 

+

4305 check_uaf = gef.config["heap-analysis-helper.check_uaf"] 

+

4306 

+

4307 ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - free({addr:#x})") 

+

4308 if addr == 0: 4308 ↛ 4309line 4308 didn't jump to line 4309, because the condition on line 4308 was never true

+

4309 if check_free_null: 

+

4310 msg.append(Color.colorify("Heap-Analysis", "yellow bold")) 

+

4311 msg.append(f"Attempting to free(NULL) at {gef.arch.pc:#x}") 

+

4312 msg.append("Reason: if NULL page is allocatable, this can lead to code execution.") 

+

4313 push_context_message("warn", "\n".join(msg)) 

+

4314 return True 

+

4315 return False 

+

4316 

+

4317 if addr in [x for (x, y) in gef.session.heap_freed_chunks]: 4317 ↛ 4318line 4317 didn't jump to line 4318, because the condition on line 4317 was never true

+

4318 if check_double_free: 

+

4319 msg.append(Color.colorify("Heap-Analysis", "yellow bold")) 

+

4320 msg.append(f"Double-free detected {RIGHT_ARROW} free({addr:#x}) is called at {gef.arch.pc:#x} but is already in the free-ed list") 

+

4321 msg.append("Execution will likely crash...") 

+

4322 push_context_message("warn", "\n".join(msg)) 

+

4323 return True 

+

4324 return False 

+

4325 

+

4326 # if here, no error 

+

4327 # 1. move alloc-ed item to free list 

+

4328 try: 

+

4329 # pop from alloc-ed list 

+

4330 idx = [x for x, y in gef.session.heap_allocated_chunks].index(addr) 

+

4331 item = gef.session.heap_allocated_chunks.pop(idx) 

+

4332 

+

4333 except ValueError: 

+

4334 if check_weird_free: 

+

4335 msg.append(Color.colorify("Heap-Analysis", "yellow bold")) 

+

4336 msg.append("Heap inconsistency detected:") 

+

4337 msg.append(f"Attempting to free an unknown value: {addr:#x}") 

+

4338 push_context_message("warn", "\n".join(msg)) 

+

4339 return True 

+

4340 return False 

+

4341 

+

4342 # 2. add it to free-ed list 

+

4343 gef.session.heap_freed_chunks.append(item) 

+

4344 

+

4345 self.retbp = None 

+

4346 if check_uaf: 4346 ↛ 4349line 4346 didn't jump to line 4349, because the condition on line 4346 was never false

+

4347 # 3. (opt.) add a watchpoint on pointer 

+

4348 self.retbp = TraceFreeRetBreakpoint(addr) 

+

4349 return False 

+

4350 

+

4351 

+

4352class TraceFreeRetBreakpoint(gdb.FinishBreakpoint): 

+

4353 """Internal temporary breakpoint to track free()d values.""" 

+

4354 

+

4355 def __init__(self, addr: int) -> None: 

+

4356 super().__init__(gdb.newest_frame(), internal=True) 

+

4357 self.silent = True 

+

4358 self.addr = addr 

+

4359 return 

+

4360 

+

4361 def stop(self) -> bool: 

+

4362 reset_all_caches() 

+

4363 wp = UafWatchpoint(self.addr) 

+

4364 gef.session.heap_uaf_watchpoints.append(wp) 

+

4365 return False 

+

4366 

+

4367 

+

4368class UafWatchpoint(gdb.Breakpoint): 

+

4369 """Custom watchpoints set TraceFreeBreakpoint() to monitor free()d pointers being used.""" 

+

4370 

+

4371 def __init__(self, addr: int) -> None: 

+

4372 super().__init__(f"*{addr:#x}", gdb.BP_WATCHPOINT, internal=True) 

+

4373 self.address = addr 

+

4374 self.silent = True 

+

4375 self.enabled = True 

+

4376 return 

+

4377 

+

4378 def stop(self) -> bool: 

+

4379 """If this method is triggered, we likely have a UaF. Break the execution and report it.""" 

+

4380 reset_all_caches() 

+

4381 frame = gdb.selected_frame() 

+

4382 if frame.name() in ("_int_malloc", "malloc_consolidate", "__libc_calloc", ): 

+

4383 return False 

+

4384 

+

4385 # software watchpoints stop after the next statement (see 

+

4386 # https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html) 

+

4387 pc = gdb_get_nth_previous_instruction_address(gef.arch.pc, 2) 

+

4388 insn = gef_current_instruction(pc) 

+

4389 msg = [] 

+

4390 msg.append(Color.colorify("Heap-Analysis", "yellow bold")) 

+

4391 msg.append(f"Possible Use-after-Free in '{get_filepath()}': " 

+

4392 f"pointer {self.address:#x} was freed, but is attempted to be used at {pc:#x}") 

+

4393 msg.append(f"{insn.address:#x} {insn.mnemonic} {Color.yellowify(', '.join(insn.operands))}") 

+

4394 push_context_message("warn", "\n".join(msg)) 

+

4395 return True 

+

4396 

+

4397 

+

4398class EntryBreakBreakpoint(gdb.Breakpoint): 

+

4399 """Breakpoint used internally to stop execution at the most convenient entry point.""" 

+

4400 

+

4401 def __init__(self, location: str) -> None: 

+

4402 super().__init__(location, gdb.BP_BREAKPOINT, internal=True, temporary=True) 

+

4403 self.silent = True 

+

4404 return 

+

4405 

+

4406 def stop(self) -> bool: 

+

4407 reset_all_caches() 

+

4408 return True 

+

4409 

+

4410 

+

4411class NamedBreakpoint(gdb.Breakpoint): 

+

4412 """Breakpoint which shows a specified name, when hit.""" 

+

4413 

+

4414 def __init__(self, location: str, name: str) -> None: 

+

4415 super().__init__(spec=location, type=gdb.BP_BREAKPOINT, internal=False, temporary=False) 

+

4416 self.name = name 

+

4417 self.loc = location 

+

4418 return 

+

4419 

+

4420 def stop(self) -> bool: 

+

4421 reset_all_caches() 

+

4422 push_context_message("info", f"Hit breakpoint {self.loc} ({Color.colorify(self.name, 'red bold')})") 

+

4423 return True 

+

4424 

+

4425 

+

4426# 

+

4427# Context Panes 

+

4428# 

+

4429 

+

4430def register_external_context_pane(pane_name: str, display_pane_function: Callable[[], None], pane_title_function: Callable[[], Optional[str]], condition : Optional[Callable[[], bool]] = None) -> None: 

+

4431 """ 

+

4432 Registering function for new GEF Context View. 

+

4433 pane_name: a string that has no spaces (used in settings) 

+

4434 display_pane_function: a function that uses gef_print() to print strings 

+

4435 pane_title_function: a function that returns a string or None, which will be displayed as the title. 

+

4436 If None, no title line is displayed. 

+

4437 condition: an optional callback: if not None, the callback will be executed first. If it returns true, 

+

4438 then only the pane title and content will displayed. Otherwise, it's simply skipped. 

+

4439 

+

4440 Example usage for a simple text to show when we hit a syscall: 

+

4441 def only_syscall(): return gef_current_instruction(gef.arch.pc).is_syscall() 

+

4442 def display_pane(): 

+

4443 gef_print("Wow, I am a context pane!") 

+

4444 def pane_title(): 

+

4445 return "example:pane" 

+

4446 register_external_context_pane("example_pane", display_pane, pane_title, only_syscall) 

+

4447 """ 

+

4448 gef.gdb.add_context_pane(pane_name, display_pane_function, pane_title_function, condition) 

+

4449 return 

+

4450 

+

4451 

+

4452# 

+

4453# Commands 

+

4454# 

+

4455@deprecated("Use `register()`, and inherit from `GenericCommand` instead") 

+

4456def register_external_command(cls: Type["GenericCommand"]) -> Type["GenericCommand"]: 

+

4457 """Registering function for new GEF (sub-)command to GDB.""" 

+

4458 return cls 

+

4459 

+

4460@deprecated("Use `register()`, and inherit from `GenericCommand` instead") 

+

4461def register_command(cls: Type["GenericCommand"]) -> Type["GenericCommand"]: 

+

4462 """Decorator for registering new GEF (sub-)command to GDB.""" 

+

4463 return cls 

+

4464 

+

4465@deprecated("") 

+

4466def register_priority_command(cls: Type["GenericCommand"]) -> Type["GenericCommand"]: 

+

4467 """Decorator for registering new command with priority, meaning that it must 

+

4468 loaded before the other generic commands.""" 

+

4469 return cls 

+

4470 

+

4471 

+

4472def register(cls: Union[Type["GenericCommand"], Type["GenericFunction"]]) -> Union[Type["GenericCommand"], Type["GenericFunction"]]: 

+

4473 global __registered_commands__, __registered_functions__ 

+

4474 if issubclass(cls, GenericCommand): 

+

4475 assert( hasattr(cls, "_cmdline_")) 

+

4476 assert( hasattr(cls, "do_invoke")) 

+

4477 assert( all(map(lambda x: x._cmdline_ != cls._cmdline_, __registered_commands__))) 

+

4478 __registered_commands__.add(cls) 

+

4479 return cls 

+

4480 

+

4481 if issubclass(cls, GenericFunction): 4481 ↛ 4488line 4481 didn't jump to line 4488, because the condition on line 4481 was never false

+

4482 assert( hasattr(cls, "_function_")) 

+

4483 assert( hasattr(cls, "invoke")) 

+

4484 assert( all(map(lambda x: x._function_ != cls._function_, __registered_functions__))) 

+

4485 __registered_functions__.add(cls) 

+

4486 return cls 

+

4487 

+

4488 raise TypeError(f"`{cls.__class__}` is an illegal class for `register`") 

+

4489 

+

4490 

+

4491class GenericCommand(gdb.Command): 

+

4492 """This is an abstract class for invoking commands, should not be instantiated.""" 

+

4493 

+

4494 _cmdline_: str 

+

4495 _syntax_: str 

+

4496 _example_: Union[str, List[str]] = "" 

+

4497 

+

4498 def __init_subclass__(cls, **kwargs): 

+

4499 super().__init_subclass__(**kwargs) 

+

4500 attributes = ("_cmdline_", "_syntax_", ) 

+

4501 if not all(map(lambda x: hasattr(cls, x), attributes)): 4501 ↛ 4502line 4501 didn't jump to line 4502, because the condition on line 4501 was never true

+

4502 raise NotImplementedError 

+

4503 

+

4504 def __init__(self, *args: Any, **kwargs: Any) -> None: 

+

4505 self.pre_load() 

+

4506 syntax = Color.yellowify("\nSyntax: ") + self._syntax_ 

+

4507 example = Color.yellowify("\nExamples: \n\t") 

+

4508 if isinstance(self._example_, list): 

+

4509 example += "\n\t".join(self._example_) 

+

4510 elif isinstance(self._example_, str): 4510 ↛ 4512line 4510 didn't jump to line 4512, because the condition on line 4510 was never false

+

4511 example += self._example_ 

+

4512 self.__doc__ = self.__doc__.replace(" "*4, "") + syntax + example 

+

4513 self.repeat = False 

+

4514 self.repeat_count = 0 

+

4515 self.__last_command = None 

+

4516 command_type = kwargs.setdefault("command", gdb.COMMAND_OBSCURE) 

+

4517 complete_type = kwargs.setdefault("complete", gdb.COMPLETE_NONE) 

+

4518 prefix = kwargs.setdefault("prefix", False) 

+

4519 super().__init__(self._cmdline_, command_type, complete_type, prefix) 

+

4520 self.post_load() 

+

4521 return 

+

4522 

+

4523 def invoke(self, args: str, from_tty: bool) -> None: 

+

4524 try: 

+

4525 argv = gdb.string_to_argv(args) 

+

4526 self.__set_repeat_count(argv, from_tty) 

+

4527 bufferize(self.do_invoke)(argv) 

+

4528 except Exception as e: 

+

4529 # Note: since we are intercepting cleaning exceptions here, commands preferably should avoid 

+

4530 # catching generic Exception, but rather specific ones. This is allows a much cleaner use. 

+

4531 if is_debug(): 4531 ↛ 4534line 4531 didn't jump to line 4534, because the condition on line 4531 was never false

+

4532 show_last_exception() 

+

4533 else: 

+

4534 err(f"Command '{self._cmdline_}' failed to execute properly, reason: {e}") 

+

4535 return 

+

4536 

+

4537 def usage(self) -> None: 

+

4538 err(f"Syntax\n{self._syntax_}") 

+

4539 return 

+

4540 

+

4541 def do_invoke(self, argv: List[str]) -> None: 

+

4542 raise NotImplementedError 

+

4543 

+

4544 def pre_load(self) -> None: 

+

4545 return 

+

4546 

+

4547 def post_load(self) -> None: 

+

4548 return 

+

4549 

+

4550 def __get_setting_name(self, name: str) -> str: 

+

4551 clsname = self.__class__._cmdline_.replace(" ", "-") 

+

4552 return f"{clsname}.{name}" 

+

4553 

+

4554 def __iter__(self) -> Generator[str, None, None]: 

+

4555 for key in gef.config.keys(): 

+

4556 if key.startswith(self._cmdline_): 

+

4557 yield key.replace(f"{self._cmdline_}.", "", 1) 

+

4558 

+

4559 @property 

+

4560 def settings(self) -> List[str]: 

+

4561 """Return the list of settings for this command.""" 

+

4562 return list(iter(self)) 

+

4563 

+

4564 @deprecated(f"Use `self[setting_name]` instead") 

+

4565 def get_setting(self, name: str) -> Any: 

+

4566 return self.__getitem__(name) 

+

4567 

+

4568 def __getitem__(self, name: str) -> Any: 

+

4569 key = self.__get_setting_name(name) 

+

4570 return gef.config[key] 

+

4571 

+

4572 @deprecated(f"Use `setting_name in self` instead") 

+

4573 def has_setting(self, name: str) -> bool: 

+

4574 return self.__contains__(name) 

+

4575 

+

4576 def __contains__(self, name: str) -> bool: 

+

4577 return self.__get_setting_name(name) in gef.config 

+

4578 

+

4579 @deprecated(f"Use `self[setting_name] = value` instead") 

+

4580 def add_setting(self, name: str, value: Tuple[Any, type, str], description: str = "") -> None: 

+

4581 return self.__setitem__(name, (value, type(value), description)) 

+

4582 

+

4583 def __setitem__(self, name: str, value: Union[Any, Tuple[Any, str]]) -> None: 

+

4584 # make sure settings are always associated to the root command (which derives from GenericCommand) 

+

4585 if "GenericCommand" not in [x.__name__ for x in self.__class__.__bases__]: 

+

4586 return 

+

4587 key = self.__get_setting_name(name) 

+

4588 if key in gef.config: 

+

4589 setting = gef.config.raw_entry(key) 

+

4590 setting.value = value 

+

4591 else: 

+

4592 if len(value) == 1: 4592 ↛ 4593line 4592 didn't jump to line 4593, because the condition on line 4592 was never true

+

4593 gef.config[key] = GefSetting(value[0]) 

+

4594 elif len(value) == 2: 4594 ↛ 4596line 4594 didn't jump to line 4596, because the condition on line 4594 was never false

+

4595 gef.config[key] = GefSetting(value[0], description=value[1]) 

+

4596 return 

+

4597 

+

4598 @deprecated(f"Use `del self[setting_name]` instead") 

+

4599 def del_setting(self, name: str) -> None: 

+

4600 return self.__delitem__(name) 

+

4601 

+

4602 def __delitem__(self, name: str) -> None: 

+

4603 del gef.config[self.__get_setting_name(name)] 

+

4604 return 

+

4605 

+

4606 def __set_repeat_count(self, argv: List[str], from_tty: bool) -> None: 

+

4607 if not from_tty: 

+

4608 self.repeat = False 

+

4609 self.repeat_count = 0 

+

4610 return 

+

4611 

+

4612 command = gdb.execute("show commands", to_string=True).strip().split("\n")[-1] 

+

4613 self.repeat = self.__last_command == command 

+

4614 self.repeat_count = self.repeat_count + 1 if self.repeat else 0 

+

4615 self.__last_command = command 

+

4616 return 

+

4617 

+

4618 

+

4619@register 

+

4620class VersionCommand(GenericCommand): 

+

4621 """Display GEF version info.""" 

+

4622 

+

4623 _cmdline_ = "version" 

+

4624 _syntax_ = f"{_cmdline_}" 

+

4625 _example_ = f"{_cmdline_}" 

+

4626 

+

4627 def do_invoke(self, argv: List[str]) -> None: 

+

4628 gef_fpath = pathlib.Path(inspect.stack()[0][1]).expanduser().absolute() 

+

4629 gef_dir = gef_fpath.parent 

+

4630 with gef_fpath.open("rb") as f: 

+

4631 gef_hash = hashlib.sha256(f.read()).hexdigest() 

+

4632 

+

4633 if os.access(f"{gef_dir}/.git", os.X_OK): 4633 ↛ 4638line 4633 didn't jump to line 4638, because the condition on line 4633 was never false

+

4634 ver = subprocess.check_output("git log --format='%H' -n 1 HEAD", cwd=gef_dir, shell=True).decode("utf8").strip() 

+

4635 extra = "dirty" if len(subprocess.check_output("git ls-files -m", cwd=gef_dir, shell=True).decode("utf8").strip()) else "clean" 

+

4636 gef_print(f"GEF: rev:{ver} (Git - {extra})") 

+

4637 else: 

+

4638 gef_blob_hash = subprocess.check_output(f"git hash-object {gef_fpath}", shell=True).decode().strip() 

+

4639 gef_print("GEF: (Standalone)") 

+

4640 gef_print(f"Blob Hash({gef_fpath}): {gef_blob_hash}") 

+

4641 gef_print(f"SHA256({gef_fpath}): {gef_hash}") 

+

4642 gef_print(f"GDB: {gdb.VERSION}") 

+

4643 py_ver = f"{sys.version_info.major:d}.{sys.version_info.minor:d}" 

+

4644 gef_print(f"GDB-Python: {py_ver}") 

+

4645 

+

4646 if "full" in argv: 

+

4647 gef_print(f"Loaded commands: {', '.join(gef.gdb.loaded_command_names)}") 

+

4648 return 

+

4649 

+

4650 

+

4651@register 

+

4652class PrintFormatCommand(GenericCommand): 

+

4653 """Print bytes format in commonly used formats, such as literals in high level languages.""" 

+

4654 

+

4655 valid_formats = ("py", "c", "js", "asm", "hex", "bytearray") 

+

4656 valid_bitness = (8, 16, 32, 64) 

+

4657 

+

4658 _cmdline_ = "print-format" 

+

4659 _aliases_ = ["pf",] 

+

4660 _syntax_ = (f"{_cmdline_} [--lang LANG] [--bitlen SIZE] [(--length,-l) LENGTH] [--clip] LOCATION" 

+

4661 f"\t--lang LANG specifies the output format for programming language (available: {valid_formats!s}, default 'py')." 

+

4662 f"\t--bitlen SIZE specifies size of bit (possible values: {valid_bitness!s}, default is 8)." 

+

4663 "\t--length LENGTH specifies length of array (default is 256)." 

+

4664 "\t--clip The output data will be copied to clipboard" 

+

4665 "\tLOCATION specifies where the address of bytes is stored.") 

+

4666 _example_ = f"{_cmdline_} --lang py -l 16 $rsp" 

+

4667 

+

4668 def __init__(self) -> None: 

+

4669 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

4670 self["max_size_preview"] = (10, "max size preview of bytes") 

+

4671 return 

+

4672 

+

4673 @property 

+

4674 def format_matrix(self) -> Dict[int, Tuple[str, str, str]]: 

+

4675 # `gef.arch.endianness` is a runtime property, should not be defined as a class property 

+

4676 return { 

+

4677 8: (f"{gef.arch.endianness}B", "char", "db"), 

+

4678 16: (f"{gef.arch.endianness}H", "short", "dw"), 

+

4679 32: (f"{gef.arch.endianness}I", "int", "dd"), 

+

4680 64: (f"{gef.arch.endianness}Q", "long long", "dq"), 

+

4681 } 

+

4682 

+

4683 @only_if_gdb_running 

+

4684 @parse_arguments({"location": "$pc", }, {("--length", "-l"): 256, "--bitlen": 0, "--lang": "py", "--clip": True,}) 

+

4685 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

4686 """Default value for print-format command.""" 

+

4687 args: argparse.Namespace = kwargs["arguments"] 

+

4688 args.bitlen = args.bitlen or gef.arch.ptrsize * 2 

+

4689 

+

4690 valid_bitlens = self.format_matrix.keys() 

+

4691 if args.bitlen not in valid_bitlens: 4691 ↛ 4692line 4691 didn't jump to line 4692, because the condition on line 4691 was never true

+

4692 err(f"Size of bit must be in: {valid_bitlens!s}") 

+

4693 return 

+

4694 

+

4695 if args.lang not in self.valid_formats: 

+

4696 err(f"Language must be in: {self.valid_formats!s}") 

+

4697 return 

+

4698 

+

4699 start_addr = parse_address(args.location) 

+

4700 size = int(args.bitlen / 8) 

+

4701 end_addr = start_addr + args.length * size 

+

4702 fmt = self.format_matrix[args.bitlen][0] 

+

4703 data = [] 

+

4704 

+

4705 if args.lang != "bytearray": 

+

4706 for addr in range(start_addr, end_addr, size): 

+

4707 value = struct.unpack(fmt, gef.memory.read(addr, size))[0] 

+

4708 data += [value] 

+

4709 sdata = ", ".join(map(hex, data)) 

+

4710 else: 

+

4711 sdata = "" 

+

4712 

+

4713 if args.lang == "bytearray": 

+

4714 data = gef.memory.read(start_addr, args.length) 

+

4715 preview = str(data[0:self["max_size_preview"]]) 

+

4716 out = f"Saved data {preview}... in '{gef_convenience(data)}'" 

+

4717 elif args.lang == "py": 

+

4718 out = f"buf = [{sdata}]" 

+

4719 elif args.lang == "c": 4719 ↛ 4720line 4719 didn't jump to line 4720, because the condition on line 4719 was never true

+

4720 c_type = self.format_matrix[args.bitlen][1] 

+

4721 out = f"unsigned {c_type} buf[{args.length}] = {{{sdata}}};" 

+

4722 elif args.lang == "js": 

+

4723 out = f"var buf = [{sdata}]" 

+

4724 elif args.lang == "asm": 4724 ↛ 4725line 4724 didn't jump to line 4725, because the condition on line 4724 was never true

+

4725 asm_type = self.format_matrix[args.bitlen][2] 

+

4726 out = "buf {0} {1}".format(asm_type, sdata) 

+

4727 elif args.lang == "hex": 4727 ↛ 4730line 4727 didn't jump to line 4730, because the condition on line 4727 was never false

+

4728 out = binascii.hexlify(gef.memory.read(start_addr, end_addr-start_addr)).decode() 

+

4729 else: 

+

4730 raise ValueError(f"Invalid format: {args.lang}") 

+

4731 

+

4732 if args.clip: 4732 ↛ 4733line 4732 didn't jump to line 4733, because the condition on line 4732 was never true

+

4733 if copy_to_clipboard(gef_pybytes(out)): 

+

4734 info("Copied to clipboard") 

+

4735 else: 

+

4736 warn("There's a problem while copying") 

+

4737 

+

4738 gef_print(out) 

+

4739 return 

+

4740 

+

4741 

+

4742@register 

+

4743class PieCommand(GenericCommand): 

+

4744 """PIE breakpoint support.""" 

+

4745 

+

4746 _cmdline_ = "pie" 

+

4747 _syntax_ = f"{_cmdline_} (breakpoint|info|delete|run|attach|remote)" 

+

4748 

+

4749 def __init__(self) -> None: 

+

4750 super().__init__(prefix=True) 

+

4751 return 

+

4752 

+

4753 def do_invoke(self, argv: List[str]) -> None: 

+

4754 if not argv: 4754 ↛ 4756line 4754 didn't jump to line 4756, because the condition on line 4754 was never false

+

4755 self.usage() 

+

4756 return 

+

4757 

+

4758 

+

4759@register 

+

4760class PieBreakpointCommand(GenericCommand): 

+

4761 """Set a PIE breakpoint at an offset from the target binaries base address.""" 

+

4762 

+

4763 _cmdline_ = "pie breakpoint" 

+

4764 _syntax_ = f"{_cmdline_} OFFSET" 

+

4765 

+

4766 @parse_arguments({"offset": ""}, {}) 

+

4767 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

4768 args : argparse.Namespace = kwargs["arguments"] 

+

4769 if not args.offset: 4769 ↛ 4770line 4769 didn't jump to line 4770, because the condition on line 4769 was never true

+

4770 self.usage() 

+

4771 return 

+

4772 

+

4773 addr = parse_address(args.offset) 

+

4774 self.set_pie_breakpoint(lambda base: f"b *{base + addr}", addr) 

+

4775 

+

4776 # When the process is already on, set real breakpoints immediately 

+

4777 if is_alive(): 4777 ↛ 4778line 4777 didn't jump to line 4778, because the condition on line 4777 was never true

+

4778 vmmap = gef.memory.maps 

+

4779 base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] 

+

4780 for bp_ins in gef.session.pie_breakpoints.values(): 

+

4781 bp_ins.instantiate(base_address) 

+

4782 return 

+

4783 

+

4784 @staticmethod 

+

4785 def set_pie_breakpoint(set_func: Callable[[int], str], addr: int) -> None: 

+

4786 gef.session.pie_breakpoints[gef.session.pie_counter] = PieVirtualBreakpoint(set_func, gef.session.pie_counter, addr) 

+

4787 gef.session.pie_counter += 1 

+

4788 return 

+

4789 

+

4790 

+

4791@register 

+

4792class PieInfoCommand(GenericCommand): 

+

4793 """Display breakpoint info.""" 

+

4794 

+

4795 _cmdline_ = "pie info" 

+

4796 _syntax_ = f"{_cmdline_} BREAKPOINT" 

+

4797 

+

4798 @parse_arguments({"breakpoints": [-1,]}, {}) 

+

4799 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

4800 args : argparse.Namespace = kwargs["arguments"] 

+

4801 if args.breakpoints[0] == -1: 

+

4802 # No breakpoint info needed 

+

4803 bps = gef.session.pie_breakpoints.values() 

+

4804 else: 

+

4805 bps = [gef.session.pie_breakpoints[x] 

+

4806 for x in args.breakpoints 

+

4807 if x in gef.session.pie_breakpoints] 

+

4808 

+

4809 lines = ["{:6s} {:6s} {:18s}".format("VNum","Num","Addr")] 

+

4810 lines += [ 

+

4811 f"{x.vbp_num:6d} {str(x.bp_num) if x.bp_num else 'N/A':6s} {x.addr:18s}" for x in bps 

+

4812 ] 

+

4813 gef_print("\n".join(lines)) 

+

4814 return 

+

4815 

+

4816 

+

4817@register 

+

4818class PieDeleteCommand(GenericCommand): 

+

4819 """Delete a PIE breakpoint.""" 

+

4820 

+

4821 _cmdline_ = "pie delete" 

+

4822 _syntax_ = f"{_cmdline_} [BREAKPOINT]" 

+

4823 

+

4824 @parse_arguments({"breakpoints": [-1,]}, {}) 

+

4825 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

4826 global gef 

+

4827 args : argparse.Namespace = kwargs["arguments"] 

+

4828 if args.breakpoints[0] == -1: 4828 ↛ 4830line 4828 didn't jump to line 4830, because the condition on line 4828 was never true

+

4829 # no arg, delete all 

+

4830 to_delete = list(gef.session.pie_breakpoints.values()) 

+

4831 self.delete_bp(to_delete) 

+

4832 else: 

+

4833 self.delete_bp([gef.session.pie_breakpoints[x] 

+

4834 for x in args.breakpoints 

+

4835 if x in gef.session.pie_breakpoints]) 

+

4836 return 

+

4837 

+

4838 

+

4839 @staticmethod 

+

4840 def delete_bp(breakpoints: List[PieVirtualBreakpoint]) -> None: 

+

4841 global gef 

+

4842 for bp in breakpoints: 

+

4843 # delete current real breakpoints if exists 

+

4844 if bp.bp_num: 4844 ↛ 4845line 4844 didn't jump to line 4845, because the condition on line 4844 was never true

+

4845 gdb.execute(f"delete {bp.bp_num}") 

+

4846 # delete virtual breakpoints 

+

4847 del gef.session.pie_breakpoints[bp.vbp_num] 

+

4848 return 

+

4849 

+

4850 

+

4851@register 

+

4852class PieRunCommand(GenericCommand): 

+

4853 """Run process with PIE breakpoint support.""" 

+

4854 

+

4855 _cmdline_ = "pie run" 

+

4856 _syntax_ = _cmdline_ 

+

4857 

+

4858 def do_invoke(self, argv: List[str]) -> None: 

+

4859 global gef 

+

4860 fpath = get_filepath() 

+

4861 if not fpath: 4861 ↛ 4862line 4861 didn't jump to line 4862, because the condition on line 4861 was never true

+

4862 warn("No executable to debug, use `file` to load a binary") 

+

4863 return 

+

4864 

+

4865 if not os.access(fpath, os.X_OK): 4865 ↛ 4866line 4865 didn't jump to line 4866, because the condition on line 4865 was never true

+

4866 warn(f"The file '{fpath}' is not executable.") 

+

4867 return 

+

4868 

+

4869 if is_alive(): 4869 ↛ 4870line 4869 didn't jump to line 4870, because the condition on line 4869 was never true

+

4870 warn("gdb is already running. Restart process.") 

+

4871 

+

4872 # get base address 

+

4873 gdb.execute("set stop-on-solib-events 1") 

+

4874 hide_context() 

+

4875 gdb.execute(f"run {' '.join(argv)}") 

+

4876 unhide_context() 

+

4877 gdb.execute("set stop-on-solib-events 0") 

+

4878 vmmap = gef.memory.maps 

+

4879 base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] 

+

4880 info(f"base address {hex(base_address)}") 

+

4881 

+

4882 # modify all breakpoints 

+

4883 for bp_ins in gef.session.pie_breakpoints.values(): 

+

4884 bp_ins.instantiate(base_address) 

+

4885 

+

4886 try: 

+

4887 gdb.execute("continue") 

+

4888 except gdb.error as e: 

+

4889 err(e) 

+

4890 gdb.execute("kill") 

+

4891 return 

+

4892 

+

4893 

+

4894@register 

+

4895class PieAttachCommand(GenericCommand): 

+

4896 """Do attach with PIE breakpoint support.""" 

+

4897 

+

4898 _cmdline_ = "pie attach" 

+

4899 _syntax_ = f"{_cmdline_} PID" 

+

4900 

+

4901 def do_invoke(self, argv: List[str]) -> None: 

+

4902 try: 

+

4903 gdb.execute(f"attach {' '.join(argv)}", to_string=True) 

+

4904 except gdb.error as e: 

+

4905 err(e) 

+

4906 return 

+

4907 # after attach, we are stopped so that we can 

+

4908 # get base address to modify our breakpoint 

+

4909 vmmap = gef.memory.maps 

+

4910 base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] 

+

4911 

+

4912 for bp_ins in gef.session.pie_breakpoints.values(): 

+

4913 bp_ins.instantiate(base_address) 

+

4914 gdb.execute("context") 

+

4915 return 

+

4916 

+

4917 

+

4918@register 

+

4919class PieRemoteCommand(GenericCommand): 

+

4920 """Attach to a remote connection with PIE breakpoint support.""" 

+

4921 

+

4922 _cmdline_ = "pie remote" 

+

4923 _syntax_ = f"{_cmdline_} REMOTE" 

+

4924 

+

4925 def do_invoke(self, argv: List[str]) -> None: 

+

4926 try: 

+

4927 gdb.execute(f"gef-remote {' '.join(argv)}") 

+

4928 except gdb.error as e: 

+

4929 err(e) 

+

4930 return 

+

4931 # after remote attach, we are stopped so that we can 

+

4932 # get base address to modify our breakpoint 

+

4933 vmmap = gef.memory.maps 

+

4934 base_address = [x.page_start for x in vmmap if x.realpath == get_filepath()][0] 

+

4935 

+

4936 for bp_ins in gef.session.pie_breakpoints.values(): 

+

4937 bp_ins.instantiate(base_address) 

+

4938 gdb.execute("context") 

+

4939 return 

+

4940 

+

4941 

+

4942@register 

+

4943class SmartEvalCommand(GenericCommand): 

+

4944 """SmartEval: Smart eval (vague approach to mimic WinDBG `?`).""" 

+

4945 

+

4946 _cmdline_ = "$" 

+

4947 _syntax_ = f"{_cmdline_} EXPR\n{_cmdline_} ADDRESS1 ADDRESS2" 

+

4948 _example_ = (f"\n{_cmdline_} $pc+1" 

+

4949 f"\n{_cmdline_} 0x00007ffff7a10000 0x00007ffff7bce000") 

+

4950 

+

4951 def do_invoke(self, argv: List[str]) -> None: 

+

4952 argc = len(argv) 

+

4953 if argc == 1: 

+

4954 self.evaluate(argv) 

+

4955 return 

+

4956 

+

4957 if argc == 2: 4957 ↛ 4959line 4957 didn't jump to line 4959, because the condition on line 4957 was never false

+

4958 self.distance(argv) 

+

4959 return 

+

4960 

+

4961 def evaluate(self, expr: List[str]) -> None: 

+

4962 def show_as_int(i: int) -> None: 

+

4963 off = gef.arch.ptrsize*8 

+

4964 def comp2_x(x: Any) -> str: return f"{(x + (1 << off)) % (1 << off):x}" 

+

4965 def comp2_b(x: Any) -> str: return f"{(x + (1 << off)) % (1 << off):b}" 

+

4966 

+

4967 try: 

+

4968 s_i = comp2_x(res) 

+

4969 s_i = s_i.rjust(len(s_i)+1, "0") if len(s_i)%2 else s_i 

+

4970 gef_print(f"{i:d}") 

+

4971 gef_print("0x" + comp2_x(res)) 

+

4972 gef_print("0b" + comp2_b(res)) 

+

4973 gef_print(f"{binascii.unhexlify(s_i)}") 

+

4974 gef_print(f"{binascii.unhexlify(s_i)[::-1]}") 

+

4975 except: 

+

4976 pass 

+

4977 return 

+

4978 

+

4979 parsed_expr = [] 

+

4980 for xp in expr: 

+

4981 try: 

+

4982 xp = gdb.parse_and_eval(xp) 

+

4983 xp = int(xp) 

+

4984 parsed_expr.append(f"{xp:d}") 

+

4985 except gdb.error: 

+

4986 parsed_expr.append(str(xp)) 

+

4987 

+

4988 try: 

+

4989 res = eval(" ".join(parsed_expr)) 

+

4990 if isinstance(res, int): 4990 ↛ 4993line 4990 didn't jump to line 4993, because the condition on line 4990 was never false

+

4991 show_as_int(res) 

+

4992 else: 

+

4993 gef_print(f"{res}") 

+

4994 except SyntaxError: 

+

4995 gef_print(" ".join(parsed_expr)) 

+

4996 return 

+

4997 

+

4998 def distance(self, args: Tuple[str, str]) -> None: 

+

4999 try: 

+

5000 x = int(args[0], 16) if is_hex(args[0]) else int(args[0]) 

+

5001 y = int(args[1], 16) if is_hex(args[1]) else int(args[1]) 

+

5002 gef_print(f"{abs(x - y)}") 

+

5003 except ValueError: 

+

5004 warn(f"Distance requires 2 numbers: {self._cmdline_} 0 0xffff") 

+

5005 return 

+

5006 

+

5007 

+

5008@register 

+

5009class CanaryCommand(GenericCommand): 

+

5010 """Shows the canary value of the current process.""" 

+

5011 

+

5012 _cmdline_ = "canary" 

+

5013 _syntax_ = _cmdline_ 

+

5014 

+

5015 @only_if_gdb_running 

+

5016 def do_invoke(self, argv: List[str]) -> None: 

+

5017 self.dont_repeat() 

+

5018 

+

5019 has_canary = Elf(get_filepath()).checksec["Canary"] 

+

5020 if not has_canary: 5020 ↛ 5021line 5020 didn't jump to line 5021, because the condition on line 5020 was never true

+

5021 warn("This binary was not compiled with SSP.") 

+

5022 return 

+

5023 

+

5024 res = gef.session.canary 

+

5025 if not res: 5025 ↛ 5026line 5025 didn't jump to line 5026, because the condition on line 5025 was never true

+

5026 err("Failed to get the canary") 

+

5027 return 

+

5028 

+

5029 canary, location = res 

+

5030 info(f"The canary of process {gef.session.pid} is at {location:#x}, value is {canary:#x}") 

+

5031 return 

+

5032 

+

5033 

+

5034@register 

+

5035class ProcessStatusCommand(GenericCommand): 

+

5036 """Extends the info given by GDB `info proc`, by giving an exhaustive description of the 

+

5037 process status (file descriptors, ancestor, descendants, etc.).""" 

+

5038 

+

5039 _cmdline_ = "process-status" 

+

5040 _syntax_ = _cmdline_ 

+

5041 _aliases_ = ["status", ] 

+

5042 

+

5043 def __init__(self) -> None: 

+

5044 super().__init__(complete=gdb.COMPLETE_NONE) 

+

5045 return 

+

5046 

+

5047 @only_if_gdb_running 

+

5048 @only_if_gdb_target_local 

+

5049 def do_invoke(self, argv: List[str]) -> None: 

+

5050 self.show_info_proc() 

+

5051 self.show_ancestor() 

+

5052 self.show_descendants() 

+

5053 self.show_fds() 

+

5054 self.show_connections() 

+

5055 return 

+

5056 

+

5057 def get_state_of(self, pid: int) -> Dict[str, str]: 

+

5058 res = {} 

+

5059 with open(f"/proc/{pid}/status", "r") as f: 

+

5060 file = f.readlines() 

+

5061 for line in file: 

+

5062 key, value = line.split(":", 1) 

+

5063 res[key.strip()] = value.strip() 

+

5064 return res 

+

5065 

+

5066 def get_cmdline_of(self, pid: int) -> str: 

+

5067 with open(f"/proc/{pid}/cmdline", "r") as f: 

+

5068 return f.read().replace("\x00", "\x20").strip() 

+

5069 

+

5070 def get_process_path_of(self, pid: int) -> str: 

+

5071 return os.readlink(f"/proc/{pid}/exe") 

+

5072 

+

5073 def get_children_pids(self, pid: int) -> List[int]: 

+

5074 cmd = [gef.session.constants["ps"], "-o", "pid", "--ppid", f"{pid}", "--noheaders"] 

+

5075 try: 

+

5076 return [int(x) for x in gef_execute_external(cmd, as_list=True)] 5076 ↛ exit,   5076 ↛ exit2 missed branches: 1) line 5076 didn't run the list comprehension on line 5076, 2) line 5076 didn't return from function 'get_children_pids', because the return on line 5076 wasn't executed

+

5077 except Exception: 

+

5078 return [] 

+

5079 

+

5080 def show_info_proc(self) -> None: 

+

5081 info("Process Information") 

+

5082 pid = gef.session.pid 

+

5083 cmdline = self.get_cmdline_of(pid) 

+

5084 gef_print(f"\tPID {RIGHT_ARROW} {pid}", 

+

5085 f"\tExecutable {RIGHT_ARROW} {self.get_process_path_of(pid)}", 

+

5086 f"\tCommand line {RIGHT_ARROW} '{cmdline}'", sep="\n") 

+

5087 return 

+

5088 

+

5089 def show_ancestor(self) -> None: 

+

5090 info("Parent Process Information") 

+

5091 ppid = int(self.get_state_of(gef.session.pid)["PPid"]) 

+

5092 state = self.get_state_of(ppid) 

+

5093 cmdline = self.get_cmdline_of(ppid) 

+

5094 gef_print(f"\tParent PID {RIGHT_ARROW} {state['Pid']}", 

+

5095 f"\tCommand line {RIGHT_ARROW} '{cmdline}'", sep="\n") 

+

5096 return 

+

5097 

+

5098 def show_descendants(self) -> None: 

+

5099 info("Children Process Information") 

+

5100 children = self.get_children_pids(gef.session.pid) 

+

5101 if not children: 5101 ↛ 5105line 5101 didn't jump to line 5105, because the condition on line 5101 was never false

+

5102 gef_print("\tNo child process") 

+

5103 return 

+

5104 

+

5105 for child_pid in children: 

+

5106 state = self.get_state_of(child_pid) 

+

5107 pid = state["Pid"] 

+

5108 gef_print(f"\tPID {RIGHT_ARROW} {pid} (Name: '{self.get_process_path_of(pid)}', CmdLine: '{self.get_cmdline_of(pid)}')") 

+

5109 return 

+

5110 

+

5111 def show_fds(self) -> None: 

+

5112 pid = gef.session.pid 

+

5113 path = f"/proc/{pid:d}/fd" 

+

5114 

+

5115 info("File Descriptors:") 

+

5116 items = os.listdir(path) 

+

5117 if not items: 5117 ↛ 5118line 5117 didn't jump to line 5118, because the condition on line 5117 was never true

+

5118 gef_print("\tNo FD opened") 

+

5119 return 

+

5120 

+

5121 for fname in items: 

+

5122 fullpath = os.path.join(path, fname) 

+

5123 if os.path.islink(fullpath): 5123 ↛ 5121line 5123 didn't jump to line 5121, because the condition on line 5123 was never false

+

5124 gef_print(f"\t{fullpath} {RIGHT_ARROW} {os.readlink(fullpath)}") 

+

5125 return 

+

5126 

+

5127 def list_sockets(self, pid: int) -> List[int]: 

+

5128 sockets = [] 

+

5129 path = f"/proc/{pid:d}/fd" 

+

5130 items = os.listdir(path) 

+

5131 for fname in items: 

+

5132 fullpath = os.path.join(path, fname) 

+

5133 if os.path.islink(fullpath) and os.readlink(fullpath).startswith("socket:"): 5133 ↛ 5134line 5133 didn't jump to line 5134, because the condition on line 5133 was never true

+

5134 p = os.readlink(fullpath).replace("socket:", "")[1:-1] 

+

5135 sockets.append(int(p)) 

+

5136 return sockets 

+

5137 

+

5138 def parse_ip_port(self, addr: str) -> Tuple[str, int]: 

+

5139 ip, port = addr.split(":") 

+

5140 return socket.inet_ntoa(struct.pack("<I", int(ip, 16))), int(port, 16) 

+

5141 

+

5142 def show_connections(self) -> None: 

+

5143 # https://github.com/torvalds/linux/blob/v4.7/include/net/tcp_states.h#L16 

+

5144 tcp_states_str = { 

+

5145 0x01: "TCP_ESTABLISHED", 

+

5146 0x02: "TCP_SYN_SENT", 

+

5147 0x03: "TCP_SYN_RECV", 

+

5148 0x04: "TCP_FIN_WAIT1", 

+

5149 0x05: "TCP_FIN_WAIT2", 

+

5150 0x06: "TCP_TIME_WAIT", 

+

5151 0x07: "TCP_CLOSE", 

+

5152 0x08: "TCP_CLOSE_WAIT", 

+

5153 0x09: "TCP_LAST_ACK", 

+

5154 0x0A: "TCP_LISTEN", 

+

5155 0x0B: "TCP_CLOSING", 

+

5156 0x0C: "TCP_NEW_SYN_RECV", 

+

5157 } 

+

5158 

+

5159 udp_states_str = { 

+

5160 0x07: "UDP_LISTEN", 

+

5161 } 

+

5162 

+

5163 info("Network Connections") 

+

5164 pid = gef.session.pid 

+

5165 sockets = self.list_sockets(pid) 

+

5166 if not sockets: 5166 ↛ 5170line 5166 didn't jump to line 5170, because the condition on line 5166 was never false

+

5167 gef_print("\tNo open connections") 

+

5168 return 

+

5169 

+

5170 entries = dict() 

+

5171 with open(f"/proc/{pid:d}/net/tcp", "r") as tcp: 

+

5172 entries["TCP"] = [x.split() for x in tcp.readlines()[1:]] 

+

5173 with open(f"/proc/{pid:d}/net/udp", "r") as udp: 

+

5174 entries["UDP"] = [x.split() for x in udp.readlines()[1:]] 

+

5175 

+

5176 for proto in entries: 

+

5177 for entry in entries[proto]: 

+

5178 local, remote, state = entry[1:4] 

+

5179 inode = int(entry[9]) 

+

5180 if inode in sockets: 

+

5181 local = self.parse_ip_port(local) 

+

5182 remote = self.parse_ip_port(remote) 

+

5183 state = int(state, 16) 

+

5184 state_str = tcp_states_str[state] if proto == "TCP" else udp_states_str[state] 

+

5185 

+

5186 gef_print(f"\t{local[0]}:{local[1]} {RIGHT_ARROW} {remote[0]}:{remote[1]} ({state_str})") 

+

5187 return 

+

5188 

+

5189 

+

5190@register 

+

5191class GefThemeCommand(GenericCommand): 

+

5192 """Customize GEF appearance.""" 

+

5193 

+

5194 _cmdline_ = "theme" 

+

5195 _syntax_ = f"{_cmdline_} [KEY [VALUE]]" 

+

5196 

+

5197 def __init__(self) -> None: 

+

5198 super().__init__(self._cmdline_) 

+

5199 self["context_title_line"] = ("gray", "Color of the borders in context window") 

+

5200 self["context_title_message"] = ("cyan", "Color of the title in context window") 

+

5201 self["default_title_line"] = ("gray", "Default color of borders") 

+

5202 self["default_title_message"] = ("cyan", "Default color of title") 

+

5203 self["table_heading"] = ("blue", "Color of the column headings to tables (e.g. vmmap)") 

+

5204 self["old_context"] = ("gray", "Color to use to show things such as code that is not immediately relevant") 

+

5205 self["disassemble_current_instruction"] = ("green", "Color to use to highlight the current $pc when disassembling") 

+

5206 self["dereference_string"] = ("yellow", "Color of dereferenced string") 

+

5207 self["dereference_code"] = ("gray", "Color of dereferenced code") 

+

5208 self["dereference_base_address"] = ("cyan", "Color of dereferenced address") 

+

5209 self["dereference_register_value"] = ("bold blue", "Color of dereferenced register") 

+

5210 self["registers_register_name"] = ("blue", "Color of the register name in the register window") 

+

5211 self["registers_value_changed"] = ("bold red", "Color of the changed register in the register window") 

+

5212 self["address_stack"] = ("pink", "Color to use when a stack address is found") 

+

5213 self["address_heap"] = ("green", "Color to use when a heap address is found") 

+

5214 self["address_code"] = ("red", "Color to use when a code address is found") 

+

5215 self["source_current_line"] = ("green", "Color to use for the current code line in the source window") 

+

5216 return 

+

5217 

+

5218 def do_invoke(self, args: List[str]) -> None: 

+

5219 self.dont_repeat() 

+

5220 argc = len(args) 

+

5221 

+

5222 if argc == 0: 

+

5223 for key in self.settings: 

+

5224 setting = self[key] 

+

5225 value = Color.colorify(setting, setting) 

+

5226 gef_print(f"{key:40s}: {value}") 

+

5227 return 

+

5228 

+

5229 setting_name = args[0] 

+

5230 if not setting_name in self: 

+

5231 err("Invalid key") 

+

5232 return 

+

5233 

+

5234 if argc == 1: 

+

5235 value = self[setting_name] 

+

5236 gef_print(f"{setting_name:40s}: {Color.colorify(value, value)}") 

+

5237 return 

+

5238 

+

5239 colors = [color for color in args[1:] if color in Color.colors] 

+

5240 self[setting_name] = " ".join(colors) 

+

5241 return 

+

5242 

+

5243 

+

5244class ExternalStructureManager: 

+

5245 class Structure: 

+

5246 def __init__(self, manager: "ExternalStructureManager", mod_path: pathlib.Path, struct_name: str) -> None: 

+

5247 self.manager = manager 

+

5248 self.module_path = mod_path 

+

5249 self.name = struct_name 

+

5250 self.class_type = self.__get_structure_class() 

+

5251 # if the symbol points to a class factory method and not a class 

+

5252 if not hasattr(self.class_type, "_fields_") and callable(self.class_type): 5252 ↛ 5253line 5252 didn't jump to line 5253, because the condition on line 5252 was never true

+

5253 self.class_type = self.class_type(gef) 

+

5254 return 

+

5255 

+

5256 def __str__(self) -> str: 

+

5257 return self.name 

+

5258 

+

5259 def pprint(self) -> None: 

+

5260 res = [] 

+

5261 for _name, _type in self.class_type._fields_: 

+

5262 size = ctypes.sizeof(_type) 

+

5263 name = Color.colorify(_name, gef.config["pcustom.structure_name"]) 

+

5264 type = Color.colorify(_type.__name__, gef.config["pcustom.structure_type"]) 

+

5265 size = Color.colorify(hex(size), gef.config["pcustom.structure_size"]) 

+

5266 offset = Color.boldify(f"{getattr(self.class_type, _name).offset:04x}") 

+

5267 res.append(f"{offset} {name:32s} {type:16s} /* size={size} */") 

+

5268 gef_print("\n".join(res)) 

+

5269 return 

+

5270 

+

5271 def __get_structure_class(self) -> Type: 

+

5272 """Returns a tuple of (class, instance) if modname!classname exists""" 

+

5273 fpath = self.module_path 

+

5274 spec = importlib.util.spec_from_file_location(fpath.stem, fpath) 

+

5275 module = importlib.util.module_from_spec(spec) 

+

5276 sys.modules[fpath.stem] = module 

+

5277 spec.loader.exec_module(module) 

+

5278 _class = getattr(module, self.name) 

+

5279 return _class 

+

5280 

+

5281 def apply_at(self, address: int, max_depth: int, depth: int = 0) -> None: 

+

5282 """Apply (recursively if possible) the structure format to the given address.""" 

+

5283 if depth >= max_depth: 5283 ↛ 5284line 5283 didn't jump to line 5284, because the condition on line 5283 was never true

+

5284 warn("maximum recursion level reached") 

+

5285 return 

+

5286 

+

5287 # read the data at the specified address 

+

5288 _structure = self.class_type() 

+

5289 _sizeof_structure = ctypes.sizeof(_structure) 

+

5290 

+

5291 try: 

+

5292 data = gef.memory.read(address, _sizeof_structure) 

+

5293 except gdb.MemoryError: 

+

5294 err(f"{' ' * depth}Cannot read memory {address:#x}") 

+

5295 return 

+

5296 

+

5297 # deserialize the data 

+

5298 length = min(len(data), _sizeof_structure) 

+

5299 ctypes.memmove(ctypes.addressof(_structure), data, length) 

+

5300 

+

5301 # pretty print all the fields (and call recursively if possible) 

+

5302 ptrsize = gef.arch.ptrsize 

+

5303 unpack = u32 if ptrsize == 4 else u64 

+

5304 for field in _structure._fields_: 

+

5305 _name, _type = field 

+

5306 _value = getattr(_structure, _name) 

+

5307 _offset = getattr(self.class_type, _name).offset 

+

5308 

+

5309 if ((ptrsize == 4 and _type is ctypes.c_uint32) 5309 ↛ 5313line 5309 didn't jump to line 5313, because the condition on line 5309 was never true

+

5310 or (ptrsize == 8 and _type is ctypes.c_uint64) 

+

5311 or (ptrsize == ctypes.sizeof(ctypes.c_void_p) and _type is ctypes.c_void_p)): 

+

5312 # try to dereference pointers 

+

5313 _value = RIGHT_ARROW.join(dereference_from(_value)) 

+

5314 

+

5315 line = f"{' ' * depth}" 

+

5316 line += f"{address:#x}+{_offset:#04x} {_name} : ".ljust(40) 

+

5317 line += f"{_value} ({_type.__name__})" 

+

5318 parsed_value = self.__get_ctypes_value(_structure, _name, _value) 

+

5319 if parsed_value: 5319 ↛ 5320line 5319 didn't jump to line 5320, because the condition on line 5319 was never true

+

5320 line += f"{RIGHT_ARROW} {parsed_value}" 

+

5321 gef_print(line) 

+

5322 

+

5323 if issubclass(_type, ctypes.Structure): 5323 ↛ 5324line 5323 didn't jump to line 5324, because the condition on line 5323 was never true

+

5324 self.apply_at(address + _offset, max_depth, depth + 1) 

+

5325 elif _type.__name__.startswith("LP_"): 

+

5326 # Pointer to a structure of a different type 

+

5327 __sub_type_name = _type.__name__.lstrip("LP_") 

+

5328 result = self.manager.find(__sub_type_name) 

+

5329 if result: 5329 ↛ 5304line 5329 didn't jump to line 5304, because the condition on line 5329 was never false

+

5330 _, __structure = result 

+

5331 __address = unpack(gef.memory.read(address + _offset, ptrsize)) 

+

5332 __structure.apply_at(__address, max_depth, depth + 1) 

+

5333 return 

+

5334 

+

5335 def __get_ctypes_value(self, struct, item, value) -> str: 

+

5336 if not hasattr(struct, "_values_"): return "" 5336 ↛ 5337line 5336 didn't jump to line 5337, because the condition on line 5336 was never false

+

5337 default = "" 

+

5338 for name, values in struct._values_: 

+

5339 if name != item: continue 

+

5340 if callable(values): 

+

5341 return values(value) 

+

5342 try: 

+

5343 for val, desc in values: 

+

5344 if value == val: return desc 

+

5345 if val is None: default = desc 

+

5346 except Exception as e: 

+

5347 err(f"Error parsing '{name}': {e}") 

+

5348 return default 

+

5349 

+

5350 class Module(dict): 

+

5351 def __init__(self, manager: "ExternalStructureManager", path: pathlib.Path) -> None: 

+

5352 self.manager = manager 

+

5353 self.path = path 

+

5354 self.name = path.stem 

+

5355 self.raw = self.__load() 

+

5356 

+

5357 for entry in self: 

+

5358 structure = ExternalStructureManager.Structure(manager, self.path, entry) 

+

5359 self[structure.name] = structure 

+

5360 return 

+

5361 

+

5362 def __load(self) -> ModuleType: 

+

5363 """Load a custom module, and return it.""" 

+

5364 fpath = self.path 

+

5365 spec = importlib.util.spec_from_file_location(fpath.stem, fpath) 

+

5366 module = importlib.util.module_from_spec(spec) 

+

5367 sys.modules[fpath.stem] = module 

+

5368 spec.loader.exec_module(module) 

+

5369 return module 

+

5370 

+

5371 def __str__(self) -> str: 

+

5372 return self.name 

+

5373 

+

5374 def __iter__(self) -> Generator[str, None, None]: 

+

5375 _invalid = {"BigEndianStructure", "LittleEndianStructure", "Structure"} 

+

5376 for x in dir(self.raw): 

+

5377 if x in _invalid: continue 

+

5378 _attr = getattr(self.raw, x) 

+

5379 

+

5380 # if it's a ctypes.Structure class, add it 

+

5381 if inspect.isclass(_attr) and issubclass(_attr, ctypes.Structure): 

+

5382 yield x 

+

5383 continue 

+

5384 

+

5385 # also accept class factory functions 

+

5386 if callable(_attr) and _attr.__module__ == self.name and x.endswith("_t"): 5386 ↛ 5387line 5386 didn't jump to line 5387, because the condition on line 5386 was never true

+

5387 yield x 

+

5388 continue 

+

5389 return 

+

5390 

+

5391 class Modules(dict): 

+

5392 def __init__(self, manager: "ExternalStructureManager") -> None: 

+

5393 self.manager: "ExternalStructureManager" = manager 

+

5394 self.root: pathlib.Path = manager.path 

+

5395 

+

5396 for entry in self.root.iterdir(): 

+

5397 if not entry.is_file(): continue 

+

5398 if entry.suffix != ".py": continue 5398 ↛ 5396line 5398 didn't jump to line 5396, because the continue on line 5398 wasn't executed

+

5399 if entry.name == "__init__.py": continue 5399 ↛ 5396line 5399 didn't jump to line 5396, because the continue on line 5399 wasn't executed

+

5400 module = ExternalStructureManager.Module(manager, entry) 

+

5401 self[module.name] = module 

+

5402 return 

+

5403 

+

5404 def __contains__(self, structure_name: str) -> bool: 

+

5405 """Return True if the structure name is found in any of the modules""" 

+

5406 for module in self.values(): 

+

5407 if structure_name in module: 

+

5408 return True 

+

5409 return False 

+

5410 

+

5411 def __init__(self) -> None: 

+

5412 self.clear_caches() 

+

5413 return 

+

5414 

+

5415 def clear_caches(self) -> None: 

+

5416 self._path = None 

+

5417 self._modules = None 

+

5418 return 

+

5419 

+

5420 @property 

+

5421 def modules(self) -> "ExternalStructureManager.Modules": 

+

5422 if not self._modules: 

+

5423 self._modules = ExternalStructureManager.Modules(self) 

+

5424 return self._modules 

+

5425 

+

5426 @property 

+

5427 def path(self) -> pathlib.Path: 

+

5428 if not self._path: 

+

5429 self._path = pathlib.Path(gef.config["pcustom.struct_path"]).expanduser().absolute() 

+

5430 return self._path 

+

5431 

+

5432 @property 

+

5433 def structures(self) -> Generator[Tuple["ExternalStructureManager.Module", "ExternalStructureManager.Structure"], None, None]: 

+

5434 for module in self.modules.values(): 

+

5435 for structure in module.values(): 

+

5436 yield module, structure 

+

5437 return 

+

5438 

+

5439 @lru_cache() 

+

5440 def find(self, structure_name: str) -> Optional[Tuple["ExternalStructureManager.Module", "ExternalStructureManager.Structure"]]: 

+

5441 """Return the module and structure for the given structure name; `None` if the structure name was not found.""" 

+

5442 for module in self.modules.values(): 

+

5443 if structure_name in module: 

+

5444 return module, module[structure_name] 

+

5445 return None 

+

5446 

+

5447 

+

5448@register 

+

5449class PCustomCommand(GenericCommand): 

+

5450 """Dump user defined structure. 

+

5451 This command attempts to reproduce WinDBG awesome `dt` command for GDB and allows 

+

5452 to apply structures (from symbols or custom) directly to an address. 

+

5453 Custom structures can be defined in pure Python using ctypes, and should be stored 

+

5454 in a specific directory, whose path must be stored in the `pcustom.struct_path` 

+

5455 configuration setting.""" 

+

5456 

+

5457 _cmdline_ = "pcustom" 

+

5458 _syntax_ = f"{_cmdline_} [list|edit <StructureName>|show <StructureName>]|<StructureName> 0xADDRESS]" 

+

5459 

+

5460 def __init__(self) -> None: 

+

5461 super().__init__(prefix=True) 

+

5462 self["struct_path"] = (str(pathlib.Path(gef.config["gef.tempdir"]) / "structs"), "Path to store/load the structure ctypes files") 

+

5463 self["max_depth"] = (4, "Maximum level of recursion supported") 

+

5464 self["structure_name"] = ("bold blue", "Color of the structure name") 

+

5465 self["structure_type"] = ("bold red", "Color of the attribute type") 

+

5466 self["structure_size"] = ("green", "Color of the attribute size") 

+

5467 return 

+

5468 

+

5469 @parse_arguments({"type": "", "address": ""}, {}) 

+

5470 def do_invoke(self, *_: Any, **kwargs: Dict[str, Any]) -> None: 

+

5471 args : argparse.Namespace = kwargs["arguments"] 

+

5472 if not args.type: 

+

5473 gdb.execute("pcustom list") 

+

5474 return 

+

5475 

+

5476 _, structname = self.explode_type(args.type) 

+

5477 

+

5478 if not args.address: 

+

5479 gdb.execute(f"pcustom show {structname}") 

+

5480 return 

+

5481 

+

5482 if not is_alive(): 

+

5483 err("Session is not active") 

+

5484 return 

+

5485 

+

5486 manager = ExternalStructureManager() 

+

5487 address = parse_address(args.address) 

+

5488 result = manager.find(structname) 

+

5489 if not result: 

+

5490 err(f"No structure named '{structname}' found") 

+

5491 return 

+

5492 

+

5493 _, structure = result 

+

5494 structure.apply_at(address, self["max_depth"]) 

+

5495 return 

+

5496 

+

5497 def explode_type(self, arg: str) -> Tuple[str, str]: 

+

5498 modname, structname = arg.split(":", 1) if ":" in arg else (arg, arg) 

+

5499 structname = structname.split(".", 1)[0] if "." in structname else structname 

+

5500 return modname, structname 

+

5501 

+

5502 

+

5503@register 

+

5504class PCustomListCommand(PCustomCommand): 

+

5505 """PCustom: list available structures""" 

+

5506 

+

5507 _cmdline_ = "pcustom list" 

+

5508 _syntax_ = f"{_cmdline_}" 

+

5509 

+

5510 def __init__(self) -> None: 

+

5511 super().__init__() 

+

5512 return 

+

5513 

+

5514 def do_invoke(self, _: List) -> None: 

+

5515 """Dump the list of all the structures and their respective.""" 

+

5516 manager = ExternalStructureManager() 

+

5517 info(f"Listing custom structures from '{manager.path}'") 

+

5518 struct_color = gef.config["pcustom.structure_type"] 

+

5519 filename_color = gef.config["pcustom.structure_name"] 

+

5520 for module in manager.modules.values(): 

+

5521 __modules = ", ".join([Color.colorify(structure_name, struct_color) for structure_name in module.values()]) 

+

5522 __filename = Color.colorify(str(module.path), filename_color) 

+

5523 gef_print(f"{RIGHT_ARROW} {__filename} ({__modules})") 

+

5524 return 

+

5525 

+

5526 

+

5527@register 

+

5528class PCustomShowCommand(PCustomCommand): 

+

5529 """PCustom: show the content of a given structure""" 

+

5530 

+

5531 _cmdline_ = "pcustom show" 

+

5532 _syntax_ = f"{_cmdline_} StructureName" 

+

5533 __aliases__ = ["pcustom create", "pcustom update"] 

+

5534 

+

5535 def __init__(self) -> None: 

+

5536 super().__init__() 

+

5537 return 

+

5538 

+

5539 def do_invoke(self, argv: List[str]) -> None: 

+

5540 if len(argv) == 0: 5540 ↛ 5541line 5540 didn't jump to line 5541, because the condition on line 5540 was never true

+

5541 self.usage() 

+

5542 return 

+

5543 

+

5544 _, structname = self.explode_type(argv[0]) 

+

5545 manager = ExternalStructureManager() 

+

5546 result = manager.find(structname) 

+

5547 if result: 

+

5548 _, structure = result 

+

5549 structure.pprint() 

+

5550 else: 

+

5551 err(f"No structure named '{structname}' found") 

+

5552 return 

+

5553 

+

5554 

+

5555@register 

+

5556class PCustomEditCommand(PCustomCommand): 

+

5557 """PCustom: edit the content of a given structure""" 

+

5558 

+

5559 _cmdline_ = "pcustom edit" 

+

5560 _syntax_ = f"{_cmdline_} StructureName" 

+

5561 __aliases__ = ["pcustom create", "pcustom new", "pcustom update"] 

+

5562 

+

5563 def __init__(self) -> None: 

+

5564 super().__init__() 

+

5565 return 

+

5566 

+

5567 def do_invoke(self, argv: List[str]) -> None: 

+

5568 if len(argv) == 0: 

+

5569 self.usage() 

+

5570 return 

+

5571 

+

5572 modname, structname = self.explode_type(argv[0]) 

+

5573 self.__create_or_edit_structure(modname, structname) 

+

5574 return 

+

5575 

+

5576 def __create_or_edit_structure(self, mod_name: str, struct_name: str) -> int: 

+

5577 path = pathlib.Path(gef.config["pcustom.struct_path"]).expanduser() / f"{mod_name}.py" 

+

5578 if path.is_file(): 

+

5579 info(f"Editing '{path}'") 

+

5580 else: 

+

5581 ok(f"Creating '{path}' from template") 

+

5582 self.__create_template(struct_name, path) 

+

5583 

+

5584 cmd = (os.getenv("EDITOR") or "nano").split() 

+

5585 cmd.append(str(path.absolute())) 

+

5586 return subprocess.call(cmd) 

+

5587 

+

5588 def __create_template(self, structname: str, fpath: pathlib.Path) -> None: 

+

5589 template = f"""from ctypes import * 

+

5590 

+

5591class {structname}(Structure): 

+

5592 _fields_ = [] 

+

5593 

+

5594 _values_ = [] 

+

5595""" 

+

5596 with fpath.open("w") as f: 

+

5597 f.write(template) 

+

5598 return 

+

5599 

+

5600 

+

5601@register 

+

5602class ChangeFdCommand(GenericCommand): 

+

5603 """ChangeFdCommand: redirect file descriptor during runtime.""" 

+

5604 

+

5605 _cmdline_ = "hijack-fd" 

+

5606 _syntax_ = f"{_cmdline_} FD_NUM NEW_OUTPUT" 

+

5607 _example_ = f"{_cmdline_} 2 /tmp/stderr_output.txt" 

+

5608 

+

5609 @only_if_gdb_running 

+

5610 @only_if_gdb_target_local 

+

5611 def do_invoke(self, argv: List[str]) -> None: 

+

5612 if len(argv) != 2: 

+

5613 self.usage() 

+

5614 return 

+

5615 

+

5616 if not os.access(f"/proc/{gef.session.pid:d}/fd/{argv[0]}", os.R_OK): 

+

5617 self.usage() 

+

5618 return 

+

5619 

+

5620 old_fd = int(argv[0]) 

+

5621 new_output = argv[1] 

+

5622 

+

5623 if ":" in new_output: 

+

5624 address = socket.gethostbyname(new_output.split(":")[0]) 

+

5625 port = int(new_output.split(":")[1]) 

+

5626 

+

5627 AF_INET = 2 

+

5628 SOCK_STREAM = 1 

+

5629 res = gdb.execute(f"""call (int)socket({AF_INET}, {SOCK_STREAM}, 0)""", to_string=True) 

+

5630 new_fd = self.get_fd_from_result(res) 

+

5631 

+

5632 # fill in memory with sockaddr_in struct contents 

+

5633 # we will do this in the stack, since connect() wants a pointer to a struct 

+

5634 vmmap = gef.memory.maps 

+

5635 stack_addr = [entry.page_start for entry in vmmap if entry.path == "[stack]"][0] 

+

5636 original_contents = gef.memory.read(stack_addr, 8) 

+

5637 

+

5638 gef.memory.write(stack_addr, b"\x02\x00", 2) 

+

5639 gef.memory.write(stack_addr + 0x2, struct.pack("<H", socket.htons(port)), 2) 

+

5640 gef.memory.write(stack_addr + 0x4, socket.inet_aton(address), 4) 

+

5641 

+

5642 info(f"Trying to connect to {new_output}") 

+

5643 res = gdb.execute(f"""call (int)connect({new_fd}, {stack_addr}, {16})""", to_string=True) 

+

5644 

+

5645 # recover stack state 

+

5646 gef.memory.write(stack_addr, original_contents, 8) 

+

5647 

+

5648 res = self.get_fd_from_result(res) 

+

5649 if res == -1: 

+

5650 err(f"Failed to connect to {address}:{port}") 

+

5651 return 

+

5652 

+

5653 info(f"Connected to {new_output}") 

+

5654 else: 

+

5655 res = gdb.execute(f"""call (int)open("{new_output}", 66, 0666)""", to_string=True) 

+

5656 new_fd = self.get_fd_from_result(res) 

+

5657 

+

5658 info(f"Opened '{new_output}' as fd #{new_fd:d}") 

+

5659 gdb.execute(f"""call (int)dup2({new_fd:d}, {old_fd:d})""", to_string=True) 

+

5660 info(f"Duplicated fd #{new_fd:d}{RIGHT_ARROW}#{old_fd:d}") 

+

5661 gdb.execute(f"""call (int)close({new_fd:d})""", to_string=True) 

+

5662 info(f"Closed extra fd #{new_fd:d}") 

+

5663 ok("Success") 

+

5664 return 

+

5665 

+

5666 def get_fd_from_result(self, res: str) -> int: 

+

5667 # Output example: $1 = 3 

+

5668 res = gdb.execute(f"""p/d {int(res.split()[2], 0)}""", to_string=True) 

+

5669 return int(res.split()[2], 0) 

+

5670 

+

5671 

+

5672@register 

+

5673class ScanSectionCommand(GenericCommand): 

+

5674 """Search for addresses that are located in a memory mapping (haystack) that belonging 

+

5675 to another (needle).""" 

+

5676 

+

5677 _cmdline_ = "scan" 

+

5678 _syntax_ = f"{_cmdline_} HAYSTACK NEEDLE" 

+

5679 _aliases_ = ["lookup",] 

+

5680 _example_ = f"\n{_cmdline_} stack libc" 

+

5681 

+

5682 @only_if_gdb_running 

+

5683 def do_invoke(self, argv: List[str]) -> None: 

+

5684 if len(argv) != 2: 5684 ↛ 5685line 5684 didn't jump to line 5685, because the condition on line 5684 was never true

+

5685 self.usage() 

+

5686 return 

+

5687 

+

5688 haystack = argv[0] 

+

5689 needle = argv[1] 

+

5690 

+

5691 info(f"Searching for addresses in '{Color.yellowify(haystack)}' " 

+

5692 f"that point to '{Color.yellowify(needle)}'") 

+

5693 

+

5694 if haystack == "binary": 

+

5695 haystack = get_filepath() 

+

5696 

+

5697 if needle == "binary": 5697 ↛ 5698line 5697 didn't jump to line 5698, because the condition on line 5697 was never true

+

5698 needle = get_filepath() 

+

5699 

+

5700 needle_sections = [] 

+

5701 haystack_sections = [] 

+

5702 

+

5703 if "0x" in haystack: 5703 ↛ 5704line 5703 didn't jump to line 5704, because the condition on line 5703 was never true

+

5704 start, end = parse_string_range(haystack) 

+

5705 haystack_sections.append((start, end, "")) 

+

5706 

+

5707 if "0x" in needle: 5707 ↛ 5708line 5707 didn't jump to line 5708, because the condition on line 5707 was never true

+

5708 start, end = parse_string_range(needle) 

+

5709 needle_sections.append((start, end)) 

+

5710 

+

5711 for sect in gef.memory.maps: 

+

5712 if haystack in sect.path: 

+

5713 haystack_sections.append((sect.page_start, sect.page_end, os.path.basename(sect.path))) 

+

5714 if needle in sect.path: 

+

5715 needle_sections.append((sect.page_start, sect.page_end)) 

+

5716 

+

5717 step = gef.arch.ptrsize 

+

5718 unpack = u32 if step == 4 else u64 

+

5719 

+

5720 for hstart, hend, hname in haystack_sections: 

+

5721 try: 

+

5722 mem = gef.memory.read(hstart, hend - hstart) 

+

5723 except gdb.MemoryError: 

+

5724 continue 

+

5725 

+

5726 for i in range(0, len(mem), step): 

+

5727 target = unpack(mem[i:i+step]) 

+

5728 for nstart, nend in needle_sections: 

+

5729 if target >= nstart and target < nend: 

+

5730 deref = DereferenceCommand.pprint_dereferenced(hstart, int(i / step)) 

+

5731 if hname != "": 5731 ↛ 5735line 5731 didn't jump to line 5735, because the condition on line 5731 was never false

+

5732 name = Color.colorify(hname, "yellow") 

+

5733 gef_print(f"{name}: {deref}") 

+

5734 else: 

+

5735 gef_print(f" {deref}") 

+

5736 

+

5737 return 

+

5738 

+

5739 

+

5740@register 

+

5741class SearchPatternCommand(GenericCommand): 

+

5742 """SearchPatternCommand: search a pattern in memory. If given an hex value (starting with 0x) 

+

5743 the command will also try to look for upwards cross-references to this address.""" 

+

5744 

+

5745 _cmdline_ = "search-pattern" 

+

5746 _syntax_ = f"{_cmdline_} PATTERN [little|big] [section]" 

+

5747 _aliases_ = ["grep", "xref"] 

+

5748 _example_ = [f"{_cmdline_} AAAAAAAA", 

+

5749 f"{_cmdline_} 0x555555554000 little stack", 

+

5750 f"{_cmdline_} AAAA 0x600000-0x601000", 

+

5751 f"{_cmdline_} --regex 0x401000 0x401500 ([\\\\x20-\\\\x7E]{{2,}})(?=\\\\x00) <-- It matchs null-end-printable(from x20-x7e) C strings (min size 2 bytes)"] 

+

5752 

+

5753 def __init__(self) -> None: 

+

5754 super().__init__() 

+

5755 self["max_size_preview"] = (10, "max size preview of bytes") 

+

5756 self["nr_pages_chunk"] = (0x400, "number of pages readed for each memory read chunk") 

+

5757 return 

+

5758 

+

5759 def print_section(self, section: Section) -> None: 

+

5760 title = "In " 

+

5761 if section.path: 5761 ↛ 5764line 5761 didn't jump to line 5764, because the condition on line 5761 was never false

+

5762 title += f"'{Color.blueify(section.path)}'" 

+

5763 

+

5764 title += f"({section.page_start:#x}-{section.page_end:#x})" 

+

5765 title += f", permission={section.permission}" 

+

5766 ok(title) 

+

5767 return 

+

5768 

+

5769 def print_loc(self, loc: Tuple[int, int, str]) -> None: 

+

5770 gef_print(f""" {loc[0]:#x} - {loc[1]:#x} {RIGHT_ARROW} "{Color.pinkify(loc[2])}" """) 

+

5771 return 

+

5772 

+

5773 def search_pattern_by_address(self, pattern: str, start_address: int, end_address: int) -> List[Tuple[int, int, Optional[str]]]: 

+

5774 """Search a pattern within a range defined by arguments.""" 

+

5775 _pattern = gef_pybytes(pattern) 

+

5776 step = self["nr_pages_chunk"] * gef.session.pagesize 

+

5777 locations = [] 

+

5778 

+

5779 for chunk_addr in range(start_address, end_address, step): 

+

5780 if chunk_addr + step > end_address: 5780 ↛ 5783line 5780 didn't jump to line 5783, because the condition on line 5780 was never false

+

5781 chunk_size = end_address - chunk_addr 

+

5782 else: 

+

5783 chunk_size = step 

+

5784 

+

5785 try: 

+

5786 mem = gef.memory.read(chunk_addr, chunk_size) 

+

5787 except gdb.MemoryError as e: 

+

5788 return [] 

+

5789 

+

5790 for match in re.finditer(_pattern, mem): 

+

5791 start = chunk_addr + match.start() 

+

5792 if is_ascii_string(start): 

+

5793 ustr = gef.memory.read_ascii_string(start) or "" 

+

5794 end = start + len(ustr) 

+

5795 else: 

+

5796 ustr = gef_pystring(_pattern) + "[...]" 

+

5797 end = start + len(_pattern) 

+

5798 locations.append((start, end, ustr)) 

+

5799 

+

5800 del mem 

+

5801 

+

5802 return locations 

+

5803 

+

5804 def search_binpattern_by_address(self, binpattern: bytes, start_address: int, end_address: int) -> List[Tuple[int, int, Optional[str]]]: 

+

5805 """Search a binary pattern within a range defined by arguments.""" 

+

5806 

+

5807 step = self["nr_pages_chunk"] * gef.session.pagesize 

+

5808 locations = [] 

+

5809 

+

5810 for chunk_addr in range(start_address, end_address, step): 

+

5811 if chunk_addr + step > end_address: 5811 ↛ 5814line 5811 didn't jump to line 5814, because the condition on line 5811 was never false

+

5812 chunk_size = end_address - chunk_addr 

+

5813 else: 

+

5814 chunk_size = step 

+

5815 

+

5816 try: 

+

5817 mem = gef.memory.read(chunk_addr, chunk_size) 

+

5818 except gdb.MemoryError as e: 

+

5819 return [] 

+

5820 preview_size = self["max_size_preview"] 

+

5821 for match in re.finditer(binpattern, mem): 

+

5822 start = chunk_addr + match.start() 

+

5823 preview = str(mem[slice(*match.span())][0:preview_size]) + "..." 

+

5824 size_match = match.span()[1] - match.span()[0] 

+

5825 if size_match > 0: 5825 ↛ 5827line 5825 didn't jump to line 5827, because the condition on line 5825 was never false

+

5826 size_match -= 1 

+

5827 end = start + size_match 

+

5828 

+

5829 locations.append((start, end, preview)) 

+

5830 

+

5831 del mem 

+

5832 

+

5833 return locations 

+

5834 

+

5835 def search_pattern(self, pattern: str, section_name: str) -> None: 

+

5836 """Search a pattern within the whole userland memory.""" 

+

5837 for section in gef.memory.maps: 

+

5838 if not section.permission & Permission.READ: continue 

+

5839 if section.path == "[vvar]": continue 

+

5840 if not section_name in section.path: continue 5840 ↛ 5837line 5840 didn't jump to line 5837, because the continue on line 5840 wasn't executed

+

5841 

+

5842 start = section.page_start 

+

5843 end = section.page_end - 1 

+

5844 old_section = None 

+

5845 

+

5846 for loc in self.search_pattern_by_address(pattern, start, end): 

+

5847 addr_loc_start = lookup_address(loc[0]) 

+

5848 if addr_loc_start and addr_loc_start.section: 5848 ↛ 5853line 5848 didn't jump to line 5853, because the condition on line 5848 was never false

+

5849 if old_section != addr_loc_start.section: 5849 ↛ 5853line 5849 didn't jump to line 5853, because the condition on line 5849 was never false

+

5850 self.print_section(addr_loc_start.section) 

+

5851 old_section = addr_loc_start.section 

+

5852 

+

5853 self.print_loc(loc) 

+

5854 return 

+

5855 

+

5856 @only_if_gdb_running 

+

5857 def do_invoke(self, argv: List[str]) -> None: 

+

5858 argc = len(argv) 

+

5859 if argc < 1: 5859 ↛ 5860line 5859 didn't jump to line 5860, because the condition on line 5859 was never true

+

5860 self.usage() 

+

5861 return 

+

5862 

+

5863 if argc > 3 and argv[0].startswith("--regex"): 

+

5864 pattern = ' '.join(argv[3:]) 

+

5865 pattern = ast.literal_eval("b'" + pattern + "'") 

+

5866 

+

5867 addr_start = parse_address(argv[1]) 

+

5868 addr_end = parse_address(argv[2]) 

+

5869 

+

5870 for loc in self.search_binpattern_by_address(pattern, addr_start, addr_end): 

+

5871 self.print_loc(loc) 

+

5872 

+

5873 return 

+

5874 

+

5875 pattern = argv[0] 

+

5876 endian = gef.arch.endianness 

+

5877 

+

5878 if argc >= 2: 5878 ↛ 5879line 5878 didn't jump to line 5879, because the condition on line 5878 was never true

+

5879 if argv[1].lower() == "big": endian = Endianness.BIG_ENDIAN 

+

5880 elif argv[1].lower() == "little": endian = Endianness.LITTLE_ENDIAN 

+

5881 

+

5882 if is_hex(pattern): 5882 ↛ 5883line 5882 didn't jump to line 5883, because the condition on line 5882 was never true

+

5883 if endian == Endianness.BIG_ENDIAN: 

+

5884 pattern = "".join(["\\x" + pattern[i:i + 2] for i in range(2, len(pattern), 2)]) 

+

5885 else: 

+

5886 pattern = "".join(["\\x" + pattern[i:i + 2] for i in range(len(pattern) - 2, 0, -2)]) 

+

5887 

+

5888 if argc == 3: 5888 ↛ 5889line 5888 didn't jump to line 5889, because the condition on line 5888 was never true

+

5889 info(f"Searching '{Color.yellowify(pattern)}' in {argv[2]}") 

+

5890 

+

5891 if "0x" in argv[2]: 

+

5892 start, end = parse_string_range(argv[2]) 

+

5893 

+

5894 loc = lookup_address(start) 

+

5895 if loc.valid: 

+

5896 self.print_section(loc.section) 

+

5897 

+

5898 for loc in self.search_pattern_by_address(pattern, start, end): 

+

5899 self.print_loc(loc) 

+

5900 else: 

+

5901 section_name = argv[2] 

+

5902 if section_name == "binary": 

+

5903 section_name = get_filepath() or "" 

+

5904 

+

5905 self.search_pattern(pattern, section_name) 

+

5906 else: 

+

5907 info(f"Searching '{Color.yellowify(pattern)}' in memory") 

+

5908 self.search_pattern(pattern, "") 

+

5909 return 

+

5910 

+

5911 

+

5912@register 

+

5913class FlagsCommand(GenericCommand): 

+

5914 """Edit flags in a human friendly way.""" 

+

5915 

+

5916 _cmdline_ = "edit-flags" 

+

5917 _syntax_ = f"{_cmdline_} [(+|-|~)FLAGNAME ...]" 

+

5918 _aliases_ = ["flags",] 

+

5919 _example_ = (f"\n{_cmdline_}" 

+

5920 f"\n{_cmdline_} +zero # sets ZERO flag") 

+

5921 

+

5922 def do_invoke(self, argv: List[str]) -> None: 

+

5923 if not gef.arch.flag_register: 5923 ↛ 5924line 5923 didn't jump to line 5924, because the condition on line 5923 was never true

+

5924 warn(f"The architecture {gef.arch.arch}:{gef.arch.mode} doesn't have flag register.") 

+

5925 return 

+

5926 

+

5927 for flag in argv: 

+

5928 if len(flag) < 2: 5928 ↛ 5929line 5928 didn't jump to line 5929, because the condition on line 5928 was never true

+

5929 continue 

+

5930 

+

5931 action = flag[0] 

+

5932 name = flag[1:].lower() 

+

5933 

+

5934 if action not in ("+", "-", "~"): 5934 ↛ 5935line 5934 didn't jump to line 5935, because the condition on line 5934 was never true

+

5935 err(f"Invalid action for flag '{flag}'") 

+

5936 continue 

+

5937 

+

5938 if name not in gef.arch.flags_table.values(): 5938 ↛ 5939line 5938 didn't jump to line 5939, because the condition on line 5938 was never true

+

5939 err(f"Invalid flag name '{flag[1:]}'") 

+

5940 continue 

+

5941 

+

5942 for off in gef.arch.flags_table: 

+

5943 if gef.arch.flags_table[off] == name: 

+

5944 old_flag = gef.arch.register(gef.arch.flag_register) 

+

5945 if action == "+": 

+

5946 new_flags = old_flag | (1 << off) 

+

5947 elif action == "-": 

+

5948 new_flags = old_flag & ~(1 << off) 

+

5949 else: 

+

5950 new_flags = old_flag ^ (1 << off) 

+

5951 

+

5952 gdb.execute(f"set ({gef.arch.flag_register}) = {new_flags:#x}") 

+

5953 

+

5954 gef_print(gef.arch.flag_register_to_human()) 

+

5955 return 

+

5956 

+

5957 

+

5958@register 

+

5959class RemoteCommand(GenericCommand): 

+

5960 """GDB `target remote` command on steroids. This command will use the remote procfs to create 

+

5961 a local copy of the execution environment, including the target binary and its libraries 

+

5962 in the local temporary directory (the value by default is in `gef.config.tempdir`). Additionally, it 

+

5963 will fetch all the /proc/PID/maps and loads all its information. If procfs is not available remotely, the command 

+

5964 will likely fail. You can however still use the limited command provided by GDB `target remote`.""" 

+

5965 

+

5966 _cmdline_ = "gef-remote" 

+

5967 _syntax_ = f"{_cmdline_} [OPTIONS] TARGET" 

+

5968 _example_ = [f"{_cmdline_} localhost 1234", 

+

5969 f"{_cmdline_} --pid 6789 localhost 1234", 

+

5970 f"{_cmdline_} --qemu-user --qemu-binary /bin/debugme localhost 4444 "] 

+

5971 

+

5972 def __init__(self) -> None: 

+

5973 super().__init__(prefix=False) 

+

5974 return 

+

5975 

+

5976 @parse_arguments({"host": "", "port": 0}, {"--pid": -1, "--qemu-user": True, "--qemu-binary": ""}) 

+

5977 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

5978 if gef.session.remote is not None: 5978 ↛ 5979line 5978 didn't jump to line 5979, because the condition on line 5978 was never true

+

5979 err("You already are in remote session. Close it first before opening a new one...") 

+

5980 return 

+

5981 

+

5982 # argument check 

+

5983 args : argparse.Namespace = kwargs["arguments"] 

+

5984 if not args.host or not args.port: 5984 ↛ 5985line 5984 didn't jump to line 5985, because the condition on line 5984 was never true

+

5985 err("Missing parameters") 

+

5986 return 

+

5987 

+

5988 # qemu-user support 

+

5989 qemu_binary: Optional[pathlib.Path] = None 

+

5990 try: 

+

5991 if args.qemu_user: 

+

5992 qemu_binary = pathlib.Path(args.qemu_binary).expanduser().absolute() if args.qemu_binary else gef.session.file 

+

5993 if not qemu_binary or not qemu_binary.exists(): 5993 ↛ 5994line 5993 didn't jump to line 5994, because the condition on line 5993 was never true

+

5994 raise FileNotFoundError(f"{qemu_binary} does not exist") 

+

5995 except Exception as e: 

+

5996 err(f"Failed to initialize qemu-user mode, reason: {str(e)}") 

+

5997 return 

+

5998 

+

5999 # try to establish the remote session, throw on error 

+

6000 # Set `.remote_initializing` to True here - `GefRemoteSessionManager` invokes code which 

+

6001 # calls `is_remote_debug` which checks if `remote_initializing` is True or `.remote` is None 

+

6002 # This prevents some spurious errors being thrown during startup 

+

6003 gef.session.remote_initializing = True 

+

6004 gef.session.remote = GefRemoteSessionManager(args.host, args.port, args.pid, qemu_binary) 

+

6005 gef.session.remote_initializing = False 

+

6006 reset_all_caches() 

+

6007 gdb.execute("context") 

+

6008 return 

+

6009 

+

6010 

+

6011@register 

+

6012class SkipiCommand(GenericCommand): 

+

6013 """Skip N instruction(s) execution""" 

+

6014 

+

6015 _cmdline_ = "skipi" 

+

6016 _syntax_ = ("{_cmdline_} [LOCATION] [--n NUM_INSTRUCTIONS]" 

+

6017 "\n\tLOCATION\taddress/symbol from where to skip" 

+

6018 "\t--n NUM_INSTRUCTIONS\tSkip the specified number of instructions instead of the default 1.") 

+

6019 

+

6020 _example_ = [f"{_cmdline_}", 

+

6021 f"{_cmdline_} --n 3", 

+

6022 f"{_cmdline_} 0x69696969", 

+

6023 f"{_cmdline_} 0x69696969 --n 6",] 

+

6024 

+

6025 def __init__(self) -> None: 

+

6026 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6027 return 

+

6028 

+

6029 @only_if_gdb_running 

+

6030 @parse_arguments({"address": "$pc"}, {"--n": 1}) 

+

6031 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6032 args : argparse.Namespace = kwargs["arguments"] 

+

6033 address = parse_address(args.address) 

+

6034 num_instructions = args.n 

+

6035 

+

6036 last_insn = gef_instruction_n(address, num_instructions-1) 

+

6037 total_bytes = (last_insn.address - address) + last_insn.size() 

+

6038 target_addr = address + total_bytes 

+

6039 

+

6040 info(f"skipping {num_instructions} instructions ({total_bytes} bytes) from {address:#x} to {target_addr:#x}") 

+

6041 gdb.execute(f"set $pc = {target_addr:#x}") 

+

6042 return 

+

6043 

+

6044 

+

6045@register 

+

6046class NopCommand(GenericCommand): 

+

6047 """Patch the instruction(s) pointed by parameters with NOP. Note: this command is architecture 

+

6048 aware.""" 

+

6049 

+

6050 _cmdline_ = "nop" 

+

6051 _syntax_ = ("{_cmdline_} [LOCATION] [--i ITEMS] [--f] [--n] [--b]" 

+

6052 "\n\tLOCATION\taddress/symbol to patch (by default this command replaces whole instructions)" 

+

6053 "\t--i ITEMS\tnumber of items to insert (default 1)" 

+

6054 "\t--f\tForce patch even when the selected settings could overwrite partial instructions" 

+

6055 "\t--n\tInstead of replacing whole instructions, insert ITEMS nop instructions, no matter how many instructions it overwrites" 

+

6056 "\t--b\tInstead of replacing whole instructions, fill ITEMS bytes with nops") 

+

6057 _example_ = [f"{_cmdline_}", 

+

6058 f"{_cmdline_} $pc+3", 

+

6059 f"{_cmdline_} --i 2 $pc+3", 

+

6060 f"{_cmdline_} --b", 

+

6061 f"{_cmdline_} --b $pc+3", 

+

6062 f"{_cmdline_} --f --b --i 2 $pc+3" 

+

6063 f"{_cmdline_} --n --i 2 $pc+3",] 

+

6064 

+

6065 def __init__(self) -> None: 

+

6066 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6067 return 

+

6068 

+

6069 @only_if_gdb_running 

+

6070 @parse_arguments({"address": "$pc"}, {"--i": 1, "--b": True, "--f": True, "--n": True}) 

+

6071 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6072 args : argparse.Namespace = kwargs["arguments"] 

+

6073 address = parse_address(args.address) 

+

6074 nop = gef.arch.nop_insn 

+

6075 num_items = int(args.i) or 1 

+

6076 fill_bytes = bool(args.b) 

+

6077 fill_nops = bool(args.n) 

+

6078 force_flag = bool(args.f) or False 

+

6079 

+

6080 if fill_nops and fill_bytes: 

+

6081 err("--b and --n cannot be specified at the same time.") 

+

6082 return 

+

6083 

+

6084 total_bytes = 0 

+

6085 if fill_bytes: 

+

6086 total_bytes = num_items 

+

6087 elif fill_nops: 

+

6088 total_bytes = num_items * len(nop) 

+

6089 else: 

+

6090 try: 

+

6091 last_insn = gef_instruction_n(address, num_items-1) 

+

6092 last_addr = last_insn.address 

+

6093 except: 

+

6094 err(f"Cannot patch instruction at {address:#x} reaching unmapped area") 

+

6095 return 

+

6096 total_bytes = (last_addr - address) + gef_get_instruction_at(last_addr).size() 

+

6097 

+

6098 if len(nop) > total_bytes or total_bytes % len(nop): 

+

6099 warn(f"Patching {total_bytes} bytes at {address:#x} will result in LAST-NOP " 

+

6100 f"(byte nr {total_bytes % len(nop):#x}) broken and may cause a crash or " 

+

6101 "break disassembly.") 

+

6102 if not force_flag: 

+

6103 warn("Use --f (force) to ignore this warning.") 

+

6104 return 

+

6105 

+

6106 target_end_address = address + total_bytes 

+

6107 curr_ins = gef_current_instruction(address) 

+

6108 while curr_ins.address + curr_ins.size() < target_end_address: 

+

6109 if not Address(value=curr_ins.address + 1).valid: 

+

6110 err(f"Cannot patch instruction at {address:#x}: reaching unmapped area") 

+

6111 return 

+

6112 curr_ins = gef_next_instruction(curr_ins.address) 

+

6113 

+

6114 final_ins_end_addr = curr_ins.address + curr_ins.size() 

+

6115 

+

6116 if final_ins_end_addr != target_end_address: 

+

6117 warn(f"Patching {total_bytes} bytes at {address:#x} will result in LAST-INSTRUCTION " 

+

6118 f"({curr_ins.address:#x}) being partial overwritten and may cause a crash or " 

+

6119 "break disassembly.") 

+

6120 if not force_flag: 

+

6121 warn("Use --f (force) to ignore this warning.") 

+

6122 return 

+

6123 

+

6124 nops = bytearray(nop * total_bytes) 

+

6125 end_address = Address(value=address + total_bytes - 1) 

+

6126 if not end_address.valid: 6126 ↛ 6127line 6126 didn't jump to line 6127, because the condition on line 6126 was never true

+

6127 err(f"Cannot patch instruction at {address:#x}: reaching unmapped " 

+

6128 f"area: {end_address:#x}") 

+

6129 return 

+

6130 

+

6131 ok(f"Patching {total_bytes} bytes from {address:#x}") 

+

6132 gef.memory.write(address, nops, total_bytes) 

+

6133 

+

6134 return 

+

6135 

+

6136 

+

6137@register 

+

6138class StubCommand(GenericCommand): 

+

6139 """Stub out the specified function. This function is useful when needing to skip one 

+

6140 function to be called and disrupt your runtime flow (ex. fork).""" 

+

6141 

+

6142 _cmdline_ = "stub" 

+

6143 _syntax_ = (f"{_cmdline_} [--retval RETVAL] [address]" 

+

6144 "\taddress\taddress/symbol to stub out" 

+

6145 "\t--retval RETVAL\tSet the return value") 

+

6146 _example_ = f"{_cmdline_} --retval 0 fork" 

+

6147 

+

6148 def __init__(self) -> None: 

+

6149 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6150 return 

+

6151 

+

6152 @only_if_gdb_running 

+

6153 @parse_arguments({"address": ""}, {("-r", "--retval"): 0}) 

+

6154 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6155 args : argparse.Namespace = kwargs["arguments"] 

+

6156 loc = args.address if args.address else f"*{gef.arch.pc:#x}" 

+

6157 StubBreakpoint(loc, args.retval) 

+

6158 return 

+

6159 

+

6160 

+

6161@register 

+

6162class GlibcHeapCommand(GenericCommand): 

+

6163 """Base command to get information about the Glibc heap structure.""" 

+

6164 

+

6165 _cmdline_ = "heap" 

+

6166 _syntax_ = f"{_cmdline_} (chunk|chunks|bins|arenas|set-arena)" 

+

6167 

+

6168 def __init__(self) -> None: 

+

6169 super().__init__(prefix=True) 

+

6170 return 

+

6171 

+

6172 @only_if_gdb_running 

+

6173 def do_invoke(self, _: List[str]) -> None: 

+

6174 self.usage() 

+

6175 return 

+

6176 

+

6177 

+

6178@register 

+

6179class GlibcHeapSetArenaCommand(GenericCommand): 

+

6180 """Set the address of the main_arena or the currently selected arena.""" 

+

6181 

+

6182 _cmdline_ = "heap set-arena" 

+

6183 _syntax_ = f"{_cmdline_} [address|&symbol]" 

+

6184 _example_ = f"{_cmdline_} 0x001337001337" 

+

6185 

+

6186 def __init__(self) -> None: 

+

6187 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6188 return 

+

6189 

+

6190 @only_if_gdb_running 

+

6191 @parse_arguments({"addr": ""}, {"--reset": True}) 

+

6192 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6193 global gef 

+

6194 

+

6195 args: argparse.Namespace = kwargs["arguments"] 

+

6196 

+

6197 if args.reset: 6197 ↛ 6198line 6197 didn't jump to line 6198, because the condition on line 6197 was never true

+

6198 gef.heap.reset_caches() 

+

6199 return 

+

6200 

+

6201 if not args.addr: 6201 ↛ 6202line 6201 didn't jump to line 6202, because the condition on line 6201 was never true

+

6202 ok(f"Current arena set to: '{gef.heap.selected_arena}'") 

+

6203 return 

+

6204 

+

6205 try: 

+

6206 new_arena_address = parse_address(args.addr) 

+

6207 except gdb.error: 

+

6208 err("Invalid symbol for arena") 

+

6209 return 

+

6210 

+

6211 new_arena = GlibcArena( f"*{new_arena_address:#x}") 

+

6212 if new_arena in gef.heap.arenas: 6212 ↛ 6217line 6212 didn't jump to line 6217, because the condition on line 6212 was never false

+

6213 # if entered arena is in arena list then just select it 

+

6214 gef.heap.selected_arena = new_arena 

+

6215 else: 

+

6216 # otherwise set the main arena to the entered arena 

+

6217 gef.heap.main_arena = new_arena 

+

6218 return 

+

6219 

+

6220 

+

6221@register 

+

6222class GlibcHeapArenaCommand(GenericCommand): 

+

6223 """Display information on a heap chunk.""" 

+

6224 

+

6225 _cmdline_ = "heap arenas" 

+

6226 _syntax_ = _cmdline_ 

+

6227 

+

6228 @only_if_gdb_running 

+

6229 def do_invoke(self, _: List[str]) -> None: 

+

6230 for arena in gef.heap.arenas: 

+

6231 gef_print(str(arena)) 

+

6232 return 

+

6233 

+

6234 

+

6235@register 

+

6236class GlibcHeapChunkCommand(GenericCommand): 

+

6237 """Display information on a heap chunk. 

+

6238 See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123.""" 

+

6239 

+

6240 _cmdline_ = "heap chunk" 

+

6241 _syntax_ = f"{_cmdline_} [-h] [--allow-unaligned] [--number] address" 

+

6242 

+

6243 def __init__(self) -> None: 

+

6244 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6245 return 

+

6246 

+

6247 @parse_arguments({"address": ""}, {"--allow-unaligned": True, "--number": 1}) 

+

6248 @only_if_gdb_running 

+

6249 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6250 args : argparse.Namespace = kwargs["arguments"] 

+

6251 if not args.address: 6251 ↛ 6252line 6251 didn't jump to line 6252, because the condition on line 6251 was never true

+

6252 err("Missing chunk address") 

+

6253 self.usage() 

+

6254 return 

+

6255 

+

6256 addr = parse_address(args.address) 

+

6257 current_chunk = GlibcChunk(addr, allow_unaligned=args.allow_unaligned) 

+

6258 

+

6259 if args.number > 1: 

+

6260 for _i in range(args.number): 6260 ↛ 6276line 6260 didn't jump to line 6276, because the loop on line 6260 didn't complete

+

6261 if current_chunk.size == 0: 6261 ↛ 6262line 6261 didn't jump to line 6262, because the condition on line 6261 was never true

+

6262 break 

+

6263 

+

6264 gef_print(str(current_chunk)) 

+

6265 next_chunk_addr = current_chunk.get_next_chunk_addr() 

+

6266 if not Address(value=next_chunk_addr).valid: 

+

6267 break 

+

6268 

+

6269 next_chunk = current_chunk.get_next_chunk() 

+

6270 if next_chunk is None: 6270 ↛ 6271line 6270 didn't jump to line 6271, because the condition on line 6270 was never true

+

6271 break 

+

6272 

+

6273 current_chunk = next_chunk 

+

6274 else: 

+

6275 gef_print(current_chunk.psprint()) 

+

6276 return 

+

6277 

+

6278 

+

6279@register 

+

6280class GlibcHeapChunksCommand(GenericCommand): 

+

6281 """Display all heap chunks for the current arena. As an optional argument 

+

6282 the base address of a different arena can be passed""" 

+

6283 

+

6284 _cmdline_ = "heap chunks" 

+

6285 _syntax_ = f"{_cmdline_} [-h] [--all] [--allow-unaligned] [arena_address]" 

+

6286 _example_ = (f"\n{_cmdline_}" 

+

6287 f"\n{_cmdline_} 0x555555775000") 

+

6288 

+

6289 def __init__(self) -> None: 

+

6290 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6291 self["peek_nb_byte"] = (16, "Hexdump N first byte(s) inside the chunk data (0 to disable)") 

+

6292 return 

+

6293 

+

6294 @parse_arguments({"arena_address": ""}, {("--all", "-a"): True, "--allow-unaligned": True}) 

+

6295 @only_if_gdb_running 

+

6296 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6297 args = kwargs["arguments"] 

+

6298 if args.all or not args.arena_address: 

+

6299 for arena in gef.heap.arenas: 6299 ↛ 6303line 6299 didn't jump to line 6303, because the loop on line 6299 didn't complete

+

6300 self.dump_chunks_arena(arena, print_arena=args.all, allow_unaligned=args.allow_unaligned) 

+

6301 if not args.all: 6301 ↛ 6299line 6301 didn't jump to line 6299, because the condition on line 6301 was never false

+

6302 return 

+

6303 try: 

+

6304 arena_addr = parse_address(args.arena_address) 

+

6305 arena = GlibcArena(f"*{arena_addr:#x}") 

+

6306 self.dump_chunks_arena(arena, allow_unaligned=args.allow_unaligned) 

+

6307 except gdb.error: 

+

6308 err("Invalid arena") 

+

6309 return 

+

6310 

+

6311 def dump_chunks_arena(self, arena: GlibcArena, print_arena: bool = False, allow_unaligned: bool = False) -> None: 

+

6312 heap_addr = arena.heap_addr(allow_unaligned=allow_unaligned) 

+

6313 if heap_addr is None: 6313 ↛ 6314line 6313 didn't jump to line 6314, because the condition on line 6313 was never true

+

6314 err("Could not find heap for arena") 

+

6315 return 

+

6316 if print_arena: 6316 ↛ 6317line 6316 didn't jump to line 6317, because the condition on line 6316 was never true

+

6317 gef_print(str(arena)) 

+

6318 if arena.is_main_arena(): 

+

6319 heap_end = arena.top + GlibcChunk(arena.top, from_base=True).size 

+

6320 self.dump_chunks_heap(heap_addr, heap_end, arena, allow_unaligned=allow_unaligned) 

+

6321 else: 

+

6322 heap_info_structs = arena.get_heap_info_list() or [] 

+

6323 for heap_info in heap_info_structs: 

+

6324 if not self.dump_chunks_heap(heap_info.heap_start, heap_info.heap_end, arena, allow_unaligned=allow_unaligned): 6324 ↛ 6325line 6324 didn't jump to line 6325, because the condition on line 6324 was never true

+

6325 break 

+

6326 return 

+

6327 

+

6328 def dump_chunks_heap(self, start: int, end: int, arena: GlibcArena, allow_unaligned: bool = False) -> bool: 

+

6329 nb = self["peek_nb_byte"] 

+

6330 chunk_iterator = GlibcChunk(start, from_base=True, allow_unaligned=allow_unaligned) 

+

6331 for chunk in chunk_iterator: 6331 ↛ 6345line 6331 didn't jump to line 6345, because the loop on line 6331 didn't complete

+

6332 if chunk.base_address == arena.top: 

+

6333 gef_print( 

+

6334 f"{chunk!s} {LEFT_ARROW} {Color.greenify('top chunk')}") 

+

6335 break 

+

6336 

+

6337 if chunk.base_address > end: 6337 ↛ 6338line 6337 didn't jump to line 6338, because the condition on line 6337 was never true

+

6338 err("Corrupted heap, cannot continue.") 

+

6339 return False 

+

6340 

+

6341 line = str(chunk) 

+

6342 if nb: 6342 ↛ 6344line 6342 didn't jump to line 6344, because the condition on line 6342 was never false

+

6343 line += f"\n [{hexdump(gef.memory.read(chunk.data_address, nb), nb, base=chunk.data_address)}]" 

+

6344 gef_print(line) 

+

6345 return True 

+

6346 

+

6347 

+

6348@register 

+

6349class GlibcHeapBinsCommand(GenericCommand): 

+

6350 """Display information on the bins on an arena (default: main_arena). 

+

6351 See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123.""" 

+

6352 

+

6353 _bin_types_ = ("tcache", "fast", "unsorted", "small", "large") 

+

6354 _cmdline_ = "heap bins" 

+

6355 _syntax_ = f"{_cmdline_} [{'|'.join(_bin_types_)}]" 

+

6356 

+

6357 def __init__(self) -> None: 

+

6358 super().__init__(prefix=True, complete=gdb.COMPLETE_LOCATION) 

+

6359 return 

+

6360 

+

6361 @only_if_gdb_running 

+

6362 def do_invoke(self, argv: List[str]) -> None: 

+

6363 if not argv: 

+

6364 for bin_t in self._bin_types_: 

+

6365 gdb.execute(f"heap bins {bin_t}") 

+

6366 return 

+

6367 

+

6368 bin_t = argv[0] 

+

6369 if bin_t not in self._bin_types_: 

+

6370 self.usage() 

+

6371 return 

+

6372 

+

6373 gdb.execute(f"heap bins {bin_t}") 

+

6374 return 

+

6375 

+

6376 @staticmethod 

+

6377 def pprint_bin(arena_addr: str, index: int, _type: str = "") -> int: 

+

6378 arena = GlibcArena(arena_addr) 

+

6379 

+

6380 fd, bk = arena.bin(index) 

+

6381 if (fd, bk) == (0x00, 0x00): 6381 ↛ 6382line 6381 didn't jump to line 6382, because the condition on line 6381 was never true

+

6382 warn("Invalid backward and forward bin pointers(fw==bk==NULL)") 

+

6383 return -1 

+

6384 

+

6385 if _type == "tcache": 6385 ↛ 6386line 6385 didn't jump to line 6386, because the condition on line 6385 was never true

+

6386 chunkClass = GlibcTcacheChunk 

+

6387 elif _type == "fast": 6387 ↛ 6388line 6387 didn't jump to line 6388, because the condition on line 6387 was never true

+

6388 chunkClass = GlibcFastChunk 

+

6389 else: 

+

6390 chunkClass = GlibcChunk 

+

6391 

+

6392 nb_chunk = 0 

+

6393 head = chunkClass(bk, from_base=True).fd 

+

6394 if fd == head: 

+

6395 return nb_chunk 

+

6396 

+

6397 ok(f"{_type}bins[{index:d}]: fw={fd:#x}, bk={bk:#x}") 

+

6398 

+

6399 m = [] 

+

6400 while fd != head: 

+

6401 chunk = chunkClass(fd, from_base=True) 

+

6402 m.append(f"{RIGHT_ARROW} {chunk!s}") 

+

6403 fd = chunk.fd 

+

6404 nb_chunk += 1 

+

6405 

+

6406 if m: 6406 ↛ 6408line 6406 didn't jump to line 6408, because the condition on line 6406 was never false

+

6407 gef_print(" ".join(m)) 

+

6408 return nb_chunk 

+

6409 

+

6410 

+

6411@register 

+

6412class GlibcHeapTcachebinsCommand(GenericCommand): 

+

6413 """Display information on the Tcachebins on an arena (default: main_arena). 

+

6414 See https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc.""" 

+

6415 

+

6416 _cmdline_ = "heap bins tcache" 

+

6417 _syntax_ = f"{_cmdline_} [all] [thread_ids...]" 

+

6418 

+

6419 TCACHE_MAX_BINS = 0x40 

+

6420 

+

6421 def __init__(self) -> None: 

+

6422 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6423 return 

+

6424 

+

6425 @only_if_gdb_running 

+

6426 def do_invoke(self, argv: List[str]) -> None: 

+

6427 # Determine if we are using libc with tcache built in (2.26+) 

+

6428 if gef.libc.version and gef.libc.version < (2, 26): 6428 ↛ 6429line 6428 didn't jump to line 6429, because the condition on line 6428 was never true

+

6429 info("No Tcache in this version of libc") 

+

6430 return 

+

6431 

+

6432 current_thread = gdb.selected_thread() 

+

6433 if current_thread is None: 6433 ↛ 6434line 6433 didn't jump to line 6434, because the condition on line 6433 was never true

+

6434 err("Couldn't find current thread") 

+

6435 return 

+

6436 

+

6437 # As a nicety, we want to display threads in ascending order by gdb number 

+

6438 threads = sorted(gdb.selected_inferior().threads(), key=lambda t: t.num) 

+

6439 if argv: 

+

6440 if "all" in argv: 6440 ↛ 6443line 6440 didn't jump to line 6443, because the condition on line 6440 was never false

+

6441 tids = [t.num for t in threads] 

+

6442 else: 

+

6443 tids = self.check_thread_ids([int(a) for a in argv]) 

+

6444 else: 

+

6445 tids = [current_thread.num] 

+

6446 

+

6447 for thread in threads: 

+

6448 if thread.num not in tids: 

+

6449 continue 

+

6450 

+

6451 thread.switch() 

+

6452 

+

6453 tcache_addr = self.find_tcache() 

+

6454 if tcache_addr == 0: 6454 ↛ 6455line 6454 didn't jump to line 6455, because the condition on line 6454 was never true

+

6455 info(f"Uninitialized tcache for thread {thread.num:d}") 

+

6456 continue 

+

6457 

+

6458 gef_print(titlify(f"Tcachebins for thread {thread.num:d}")) 

+

6459 tcache_empty = True 

+

6460 for i in range(self.TCACHE_MAX_BINS): 

+

6461 chunk, count = self.tcachebin(tcache_addr, i) 

+

6462 chunks = set() 

+

6463 msg = [] 

+

6464 chunk_size = 0 

+

6465 

+

6466 # Only print the entry if there are valid chunks. Don't trust count 

+

6467 while True: 

+

6468 if chunk is None: 

+

6469 break 

+

6470 

+

6471 try: 

+

6472 msg.append(f"{LEFT_ARROW} {chunk!s} ") 

+

6473 if not chunk_size: 

+

6474 chunk_size = chunk.usable_size 

+

6475 

+

6476 if chunk.data_address in chunks: 6476 ↛ 6477line 6476 didn't jump to line 6477, because the condition on line 6476 was never true

+

6477 msg.append(f"{RIGHT_ARROW} [loop detected]") 

+

6478 break 

+

6479 

+

6480 chunks.add(chunk.data_address) 

+

6481 

+

6482 next_chunk = chunk.fd 

+

6483 if next_chunk == 0: 

+

6484 break 

+

6485 

+

6486 chunk = GlibcTcacheChunk(next_chunk) 

+

6487 except gdb.MemoryError: 

+

6488 msg.append(f"{LEFT_ARROW} [Corrupted chunk at {chunk.data_address:#x}]") 

+

6489 break 

+

6490 

+

6491 if msg: 

+

6492 tcache_empty = False 

+

6493 tidx = gef.heap.csize2tidx(chunk_size) 

+

6494 size = gef.heap.tidx2size(tidx) 

+

6495 count = len(chunks) 

+

6496 gef_print(f"Tcachebins[idx={tidx:d}, size={size:#x}, count={count}]", end="") 

+

6497 gef_print("".join(msg)) 

+

6498 

+

6499 if tcache_empty: 

+

6500 gef_print("All tcachebins are empty") 

+

6501 

+

6502 current_thread.switch() 

+

6503 return 

+

6504 

+

6505 @staticmethod 

+

6506 def find_tcache() -> int: 

+

6507 """Return the location of the current thread's tcache.""" 

+

6508 try: 

+

6509 # For multithreaded binaries, the tcache symbol (in thread local 

+

6510 # storage) will give us the correct address. 

+

6511 tcache_addr = parse_address("(void *) tcache") 

+

6512 except gdb.error: 

+

6513 # In binaries not linked with pthread (and therefore there is only 

+

6514 # one thread), we can't use the tcache symbol, but we can guess the 

+

6515 # correct address because the tcache is consistently the first 

+

6516 # allocation in the main arena. 

+

6517 heap_base = gef.heap.base_address 

+

6518 if heap_base is None: 

+

6519 err("No heap section") 

+

6520 return 0x0 

+

6521 tcache_addr = heap_base + 0x10 

+

6522 return tcache_addr 

+

6523 

+

6524 @staticmethod 

+

6525 def check_thread_ids(tids: List[int]) -> List[int]: 

+

6526 """Return the subset of tids that are currently valid.""" 

+

6527 existing_tids = set(t.num for t in gdb.selected_inferior().threads()) 

+

6528 return list(set(tids) & existing_tids) 

+

6529 

+

6530 @staticmethod 

+

6531 def tcachebin(tcache_base: int, i: int) -> Tuple[Optional[GlibcTcacheChunk], int]: 

+

6532 """Return the head chunk in tcache[i] and the number of chunks in the bin.""" 

+

6533 if i >= GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS: 6533 ↛ 6534line 6533 didn't jump to line 6534, because the condition on line 6533 was never true

+

6534 err("Incorrect index value, index value must be between 0 and {}-1, given {}".format(GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS, i)) 

+

6535 return None, 0 

+

6536 

+

6537 tcache_chunk = GlibcTcacheChunk(tcache_base) 

+

6538 

+

6539 # Glibc changed the size of the tcache in version 2.30; this fix has 

+

6540 # been backported inconsistently between distributions. We detect the 

+

6541 # difference by checking the size of the allocated chunk for the 

+

6542 # tcache. 

+

6543 # Minimum usable size of allocated tcache chunk = ? 

+

6544 # For new tcache: 

+

6545 # TCACHE_MAX_BINS * _2_ + TCACHE_MAX_BINS * ptrsize 

+

6546 # For old tcache: 

+

6547 # TCACHE_MAX_BINS * _1_ + TCACHE_MAX_BINS * ptrsize 

+

6548 new_tcache_min_size = ( 

+

6549 GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS * 2 + 

+

6550 GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS * gef.arch.ptrsize) 

+

6551 

+

6552 if tcache_chunk.usable_size < new_tcache_min_size: 6552 ↛ 6553line 6552 didn't jump to line 6553, because the condition on line 6552 was never true

+

6553 tcache_count_size = 1 

+

6554 count = ord(gef.memory.read(tcache_base + tcache_count_size*i, 1)) 

+

6555 else: 

+

6556 tcache_count_size = 2 

+

6557 count = u16(gef.memory.read(tcache_base + tcache_count_size*i, 2)) 

+

6558 

+

6559 chunk = dereference(tcache_base + tcache_count_size*GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS + i*gef.arch.ptrsize) 

+

6560 chunk = GlibcTcacheChunk(int(chunk)) if chunk else None 

+

6561 return chunk, count 

+

6562 

+

6563 

+

6564@register 

+

6565class GlibcHeapFastbinsYCommand(GenericCommand): 

+

6566 """Display information on the fastbinsY on an arena (default: main_arena). 

+

6567 See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123.""" 

+

6568 

+

6569 _cmdline_ = "heap bins fast" 

+

6570 _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" 

+

6571 

+

6572 def __init__(self) -> None: 

+

6573 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6574 return 

+

6575 

+

6576 @parse_arguments({"arena_address": ""}, {}) 

+

6577 @only_if_gdb_running 

+

6578 def do_invoke(self, *_: Any, **kwargs: Any) -> None: 

+

6579 def fastbin_index(sz: int) -> int: 

+

6580 return (sz >> 4) - 2 if SIZE_SZ == 8 else (sz >> 3) - 2 

+

6581 

+

6582 args : argparse.Namespace = kwargs["arguments"] 

+

6583 if not gef.heap.main_arena: 6583 ↛ 6584line 6583 didn't jump to line 6584, because the condition on line 6583 was never true

+

6584 err("Heap not initialized") 

+

6585 return 

+

6586 

+

6587 SIZE_SZ = gef.arch.ptrsize 

+

6588 MAX_FAST_SIZE = 80 * SIZE_SZ // 4 

+

6589 NFASTBINS = fastbin_index(MAX_FAST_SIZE) - 1 

+

6590 

+

6591 arena = GlibcArena(f"*{args.arena_address}") if args.arena_address else gef.heap.selected_arena 

+

6592 if arena is None: 6592 ↛ 6593line 6592 didn't jump to line 6593, because the condition on line 6592 was never true

+

6593 err("Invalid Glibc arena") 

+

6594 return 

+

6595 

+

6596 gef_print(titlify(f"Fastbins for arena at {arena.addr:#x}")) 

+

6597 for i in range(NFASTBINS): 

+

6598 gef_print(f"Fastbins[idx={i:d}, size={(i+2)*SIZE_SZ*2:#x}] ", end="") 

+

6599 chunk = arena.fastbin(i) 

+

6600 chunks = set() 

+

6601 

+

6602 while True: 

+

6603 if chunk is None: 

+

6604 gef_print("0x00", end="") 

+

6605 break 

+

6606 

+

6607 try: 

+

6608 gef_print(f"{LEFT_ARROW} {chunk!s} ", end="") 

+

6609 if chunk.data_address in chunks: 6609 ↛ 6610line 6609 didn't jump to line 6610, because the condition on line 6609 was never true

+

6610 gef_print(f"{RIGHT_ARROW} [loop detected]", end="") 

+

6611 break 

+

6612 

+

6613 if fastbin_index(chunk.size) != i: 6613 ↛ 6614line 6613 didn't jump to line 6614, because the condition on line 6613 was never true

+

6614 gef_print("[incorrect fastbin_index] ", end="") 

+

6615 

+

6616 chunks.add(chunk.data_address) 

+

6617 

+

6618 next_chunk = chunk.fd 

+

6619 if next_chunk == 0: 6619 ↛ 6622line 6619 didn't jump to line 6622, because the condition on line 6619 was never false

+

6620 break 

+

6621 

+

6622 chunk = GlibcFastChunk(next_chunk, from_base=True) 

+

6623 except gdb.MemoryError: 

+

6624 gef_print(f"{LEFT_ARROW} [Corrupted chunk at {chunk.data_address:#x}]", end="") 

+

6625 break 

+

6626 gef_print() 

+

6627 return 

+

6628 

+

6629 

+

6630@register 

+

6631class GlibcHeapUnsortedBinsCommand(GenericCommand): 

+

6632 """Display information on the Unsorted Bins of an arena (default: main_arena). 

+

6633 See: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1689.""" 

+

6634 

+

6635 _cmdline_ = "heap bins unsorted" 

+

6636 _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" 

+

6637 

+

6638 def __init__(self) -> None: 

+

6639 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6640 return 

+

6641 

+

6642 @parse_arguments({"arena_address": ""}, {}) 

+

6643 @only_if_gdb_running 

+

6644 def do_invoke(self, *_: Any, **kwargs: Any) -> None: 

+

6645 args : argparse.Namespace = kwargs["arguments"] 

+

6646 if gef.heap.main_arena is None: 6646 ↛ 6647line 6646 didn't jump to line 6647, because the condition on line 6646 was never true

+

6647 err("Heap not initialized") 

+

6648 return 

+

6649 arena_addr = args.arena_address if args.arena_address else f"{gef.heap.selected_arena.addr:#x}" 

+

6650 gef_print(titlify(f"Unsorted Bin for arena at {arena_addr}")) 

+

6651 nb_chunk = GlibcHeapBinsCommand.pprint_bin(f"*{arena_addr}", 0, "unsorted_") 

+

6652 if nb_chunk >= 0: 6652 ↛ 6654line 6652 didn't jump to line 6654, because the condition on line 6652 was never false

+

6653 info(f"Found {nb_chunk:d} chunks in unsorted bin.") 

+

6654 return 

+

6655 

+

6656 

+

6657@register 

+

6658class GlibcHeapSmallBinsCommand(GenericCommand): 

+

6659 """Convenience command for viewing small bins.""" 

+

6660 

+

6661 _cmdline_ = "heap bins small" 

+

6662 _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" 

+

6663 

+

6664 def __init__(self) -> None: 

+

6665 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6666 return 

+

6667 

+

6668 @parse_arguments({"arena_address": ""}, {}) 

+

6669 @only_if_gdb_running 

+

6670 def do_invoke(self, *_: Any, **kwargs: Any) -> None: 

+

6671 args : argparse.Namespace = kwargs["arguments"] 

+

6672 if not gef.heap.main_arena: 6672 ↛ 6673line 6672 didn't jump to line 6673, because the condition on line 6672 was never true

+

6673 err("Heap not initialized") 

+

6674 return 

+

6675 

+

6676 arena_address = args.arena_address or f"{gef.heap.selected_arena.address:#x}" 

+

6677 gef_print(titlify(f"Small Bins for arena at {arena_address}")) 

+

6678 bins = {} 

+

6679 for i in range(1, 63): 

+

6680 nb_chunk = GlibcHeapBinsCommand.pprint_bin(f"*{arena_address}", i, "small_") 

+

6681 if nb_chunk < 0: 6681 ↛ 6682line 6681 didn't jump to line 6682, because the condition on line 6681 was never true

+

6682 break 

+

6683 if nb_chunk > 0: 

+

6684 bins[i] = nb_chunk 

+

6685 info(f"Found {sum(bins.values()):d} chunks in {len(bins):d} small non-empty bins.") 

+

6686 return 

+

6687 

+

6688 

+

6689@register 

+

6690class GlibcHeapLargeBinsCommand(GenericCommand): 

+

6691 """Convenience command for viewing large bins.""" 

+

6692 

+

6693 _cmdline_ = "heap bins large" 

+

6694 _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" 

+

6695 

+

6696 def __init__(self) -> None: 

+

6697 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6698 return 

+

6699 

+

6700 @parse_arguments({"arena_address": ""}, {}) 

+

6701 @only_if_gdb_running 

+

6702 def do_invoke(self, *_: Any, **kwargs: Any) -> None: 

+

6703 args : argparse.Namespace = kwargs["arguments"] 

+

6704 if gef.heap.main_arena is None: 6704 ↛ 6705line 6704 didn't jump to line 6705, because the condition on line 6704 was never true

+

6705 err("Heap not initialized") 

+

6706 return 

+

6707 

+

6708 arena_addr = args.arena_address if args.arena_address else f"{gef.heap.selected_arena.addr:#x}" 

+

6709 gef_print(titlify(f"Large Bins for arena at {arena_addr}")) 

+

6710 bins = {} 

+

6711 for i in range(63, 126): 

+

6712 nb_chunk = GlibcHeapBinsCommand.pprint_bin(f"*{arena_addr}", i, "large_") 

+

6713 if nb_chunk < 0: 6713 ↛ 6714line 6713 didn't jump to line 6714, because the condition on line 6713 was never true

+

6714 break 

+

6715 if nb_chunk > 0: 

+

6716 bins[i] = nb_chunk 

+

6717 info(f"Found {sum(bins.values()):d} chunks in {len(bins):d} large non-empty bins.") 

+

6718 return 

+

6719 

+

6720 

+

6721@register 

+

6722class SolveKernelSymbolCommand(GenericCommand): 

+

6723 """Solve kernel symbols from kallsyms table.""" 

+

6724 

+

6725 _cmdline_ = "ksymaddr" 

+

6726 _syntax_ = f"{_cmdline_} SymbolToSearch" 

+

6727 _example_ = f"{_cmdline_} prepare_creds" 

+

6728 

+

6729 @parse_arguments({"symbol": ""}, {}) 

+

6730 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6731 def hex_to_int(num): 

+

6732 try: 

+

6733 return int(num, 16) 

+

6734 except ValueError: 

+

6735 return 0 

+

6736 args : argparse.Namespace = kwargs["arguments"] 

+

6737 if not args.symbol: 6737 ↛ 6738line 6737 didn't jump to line 6738, because the condition on line 6737 was never true

+

6738 self.usage() 

+

6739 return 

+

6740 sym = args.symbol 

+

6741 with open("/proc/kallsyms", "r") as f: 

+

6742 syms = [line.strip().split(" ", 2) for line in f] 

+

6743 matches = [(hex_to_int(addr), sym_t, " ".join(name.split())) for addr, sym_t, name in syms if sym in name] 

+

6744 for addr, sym_t, name in matches: 

+

6745 if sym == name.split()[0]: 

+

6746 ok(f"Found matching symbol for '{name}' at {addr:#x} (type={sym_t})") 

+

6747 else: 

+

6748 warn(f"Found partial match for '{sym}' at {addr:#x} (type={sym_t}): {name}") 

+

6749 if not matches: 6749 ↛ 6750line 6749 didn't jump to line 6750, because the condition on line 6749 was never true

+

6750 err(f"No match for '{sym}'") 

+

6751 elif matches[0][0] == 0: 6751 ↛ 6753line 6751 didn't jump to line 6753, because the condition on line 6751 was never false

+

6752 err("Check that you have the correct permissions to view kernel symbol addresses") 

+

6753 return 

+

6754 

+

6755 

+

6756@register 

+

6757class DetailRegistersCommand(GenericCommand): 

+

6758 """Display full details on one, many or all registers value from current architecture.""" 

+

6759 

+

6760 _cmdline_ = "registers" 

+

6761 _syntax_ = f"{_cmdline_} [[Register1][Register2] ... [RegisterN]]" 

+

6762 _example_ = (f"\n{_cmdline_}" 

+

6763 f"\n{_cmdline_} $eax $eip $esp") 

+

6764 

+

6765 @only_if_gdb_running 

+

6766 @parse_arguments({"registers": [""]}, {}) 

+

6767 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6768 unchanged_color = gef.config["theme.registers_register_name"] 

+

6769 changed_color = gef.config["theme.registers_value_changed"] 

+

6770 string_color = gef.config["theme.dereference_string"] 

+

6771 regs = gef.arch.all_registers 

+

6772 

+

6773 args : argparse.Namespace = kwargs["arguments"] 

+

6774 if args.registers and args.registers[0]: 

+

6775 requested_regs = set(args.registers) 

+

6776 valid_regs = set(gef.arch.all_registers) & requested_regs 

+

6777 if valid_regs: 6777 ↛ 6779line 6777 didn't jump to line 6779, because the condition on line 6777 was never false

+

6778 regs = valid_regs 

+

6779 invalid_regs = requested_regs - valid_regs 

+

6780 if invalid_regs: 6780 ↛ 6781line 6780 didn't jump to line 6781, because the condition on line 6780 was never true

+

6781 err(f"invalid registers for architecture: {', '.join(invalid_regs)}") 

+

6782 

+

6783 memsize = gef.arch.ptrsize 

+

6784 endian = str(gef.arch.endianness) 

+

6785 charset = string.printable 

+

6786 widest = max(map(len, gef.arch.all_registers)) 

+

6787 special_line = "" 

+

6788 

+

6789 for regname in regs: 

+

6790 reg = gdb.parse_and_eval(regname) 

+

6791 if reg.type.code == gdb.TYPE_CODE_VOID: 6791 ↛ 6792line 6791 didn't jump to line 6792, because the condition on line 6791 was never true

+

6792 continue 

+

6793 

+

6794 padreg = regname.ljust(widest, " ") 

+

6795 

+

6796 if str(reg) == "<unavailable>": 6796 ↛ 6797line 6796 didn't jump to line 6797, because the condition on line 6796 was never true

+

6797 gef_print(f"{Color.colorify(padreg, unchanged_color)}: " 

+

6798 f"{Color.colorify('no value', 'yellow underline')}") 

+

6799 continue 

+

6800 

+

6801 value = align_address(int(reg)) 

+

6802 old_value = ContextCommand.old_registers.get(regname, 0) 

+

6803 if value == old_value: 

+

6804 color = unchanged_color 

+

6805 else: 

+

6806 color = changed_color 

+

6807 

+

6808 # Special (e.g. segment) registers go on their own line 

+

6809 if regname in gef.arch.special_registers: 

+

6810 special_line += f"{Color.colorify(regname, color)}: " 

+

6811 special_line += f"{gef.arch.register(regname):#04x} " 

+

6812 continue 

+

6813 

+

6814 line = f"{Color.colorify(padreg, color)}: " 

+

6815 

+

6816 if regname == gef.arch.flag_register: 

+

6817 line += gef.arch.flag_register_to_human() 

+

6818 gef_print(line) 

+

6819 continue 

+

6820 

+

6821 addr = lookup_address(align_address(int(value))) 

+

6822 if addr.valid: 

+

6823 line += str(addr) 

+

6824 else: 

+

6825 line += format_address_spaces(value) 

+

6826 addrs = dereference_from(value) 

+

6827 

+

6828 if len(addrs) > 1: 

+

6829 sep = f" {RIGHT_ARROW} " 

+

6830 line += sep 

+

6831 line += sep.join(addrs[1:]) 

+

6832 

+

6833 # check to see if reg value is ascii 

+

6834 try: 

+

6835 fmt = f"{endian}{'I' if memsize == 4 else 'Q'}" 

+

6836 last_addr = int(addrs[-1], 16) 

+

6837 val = gef_pystring(struct.pack(fmt, last_addr)) 

+

6838 if all([_ in charset for _ in val]): 

+

6839 line += f" (\"{Color.colorify(val, string_color)}\"?)" 

+

6840 except ValueError: 

+

6841 pass 

+

6842 

+

6843 gef_print(line) 

+

6844 

+

6845 if special_line: 6845 ↛ 6847line 6845 didn't jump to line 6847, because the condition on line 6845 was never false

+

6846 gef_print(special_line) 

+

6847 return 

+

6848 

+

6849 

+

6850@register 

+

6851class ShellcodeCommand(GenericCommand): 

+

6852 """ShellcodeCommand uses @JonathanSalwan simple-yet-awesome shellcode API to 

+

6853 download shellcodes.""" 

+

6854 

+

6855 _cmdline_ = "shellcode" 

+

6856 _syntax_ = f"{_cmdline_} (search|get)" 

+

6857 

+

6858 def __init__(self) -> None: 

+

6859 super().__init__(prefix=True) 

+

6860 return 

+

6861 

+

6862 def do_invoke(self, _: List[str]) -> None: 

+

6863 err("Missing sub-command (search|get)") 

+

6864 self.usage() 

+

6865 return 

+

6866 

+

6867 

+

6868@register 

+

6869class ShellcodeSearchCommand(GenericCommand): 

+

6870 """Search pattern in shell-storm's shellcode database.""" 

+

6871 

+

6872 _cmdline_ = "shellcode search" 

+

6873 _syntax_ = f"{_cmdline_} PATTERN1 PATTERN2" 

+

6874 _aliases_ = ["sc-search",] 

+

6875 

+

6876 api_base = "http://shell-storm.org" 

+

6877 search_url = f"{api_base}/api/?s=" 

+

6878 

+

6879 def do_invoke(self, argv: List[str]) -> None: 

+

6880 if not argv: 6880 ↛ 6881line 6880 didn't jump to line 6881, because the condition on line 6880 was never true

+

6881 err("Missing pattern to search") 

+

6882 self.usage() 

+

6883 return 

+

6884 

+

6885 self.search_shellcode(argv) 

+

6886 return 

+

6887 

+

6888 def search_shellcode(self, search_options: List) -> None: 

+

6889 # API : http://shell-storm.org/shellcode/ 

+

6890 args = "*".join(search_options) 

+

6891 

+

6892 res = http_get(self.search_url + args) 

+

6893 if res is None: 6893 ↛ 6894line 6893 didn't jump to line 6894, because the condition on line 6893 was never true

+

6894 err("Could not query search page") 

+

6895 return 

+

6896 

+

6897 ret = gef_pystring(res) 

+

6898 

+

6899 # format: [author, OS/arch, cmd, id, link] 

+

6900 lines = ret.split("\\n") 

+

6901 refs = [line.split("::::") for line in lines] 

+

6902 

+

6903 if refs: 6903 ↛ 6914line 6903 didn't jump to line 6914, because the condition on line 6903 was never false

+

6904 info("Showing matching shellcodes") 

+

6905 info("\t".join(["Id", "Platform", "Description"])) 

+

6906 for ref in refs: 

+

6907 try: 

+

6908 _, arch, cmd, sid, _ = ref 

+

6909 gef_print("\t".join([sid, arch, cmd])) 

+

6910 except ValueError: 

+

6911 continue 

+

6912 

+

6913 info("Use `shellcode get <id>` to fetch shellcode") 

+

6914 return 

+

6915 

+

6916 

+

6917@register 

+

6918class ShellcodeGetCommand(GenericCommand): 

+

6919 """Download shellcode from shell-storm's shellcode database.""" 

+

6920 

+

6921 _cmdline_ = "shellcode get" 

+

6922 _syntax_ = f"{_cmdline_} SHELLCODE_ID" 

+

6923 _aliases_ = ["sc-get",] 

+

6924 

+

6925 api_base = "http://shell-storm.org" 

+

6926 get_url = f"{api_base}/shellcode/files/shellcode-{{:d}}.html" 

+

6927 

+

6928 def do_invoke(self, argv: List[str]) -> None: 

+

6929 if len(argv) != 1: 6929 ↛ 6930line 6929 didn't jump to line 6930, because the condition on line 6929 was never true

+

6930 err("Missing ID to download") 

+

6931 self.usage() 

+

6932 return 

+

6933 

+

6934 if not argv[0].isdigit(): 6934 ↛ 6935line 6934 didn't jump to line 6935, because the condition on line 6934 was never true

+

6935 err("ID is not a number") 

+

6936 self.usage() 

+

6937 return 

+

6938 

+

6939 self.get_shellcode(int(argv[0])) 

+

6940 return 

+

6941 

+

6942 def get_shellcode(self, sid: int) -> None: 

+

6943 info(f"Downloading shellcode id={sid}") 

+

6944 res = http_get(self.get_url.format(sid)) 

+

6945 if res is None: 

+

6946 err(f"Failed to fetch shellcode #{sid}") 

+

6947 return 

+

6948 

+

6949 ok("Downloaded, written to disk...") 

+

6950 with tempfile.NamedTemporaryFile(prefix="sc-", suffix=".txt", mode='w+b', delete=False, dir=gef.config["gef.tempdir"]) as fd: 

+

6951 shellcode = res.split(b"<pre>")[1].split(b"</pre>")[0] 

+

6952 shellcode = shellcode.replace(b"&quot;", b'"') 

+

6953 fd.write(shellcode) 

+

6954 ok(f"Shellcode written to '{fd.name}'") 

+

6955 return 

+

6956 

+

6957 

+

6958@register 

+

6959class ProcessListingCommand(GenericCommand): 

+

6960 """List and filter process. If a PATTERN is given as argument, results shown will be grepped 

+

6961 by this pattern.""" 

+

6962 

+

6963 _cmdline_ = "process-search" 

+

6964 _syntax_ = f"{_cmdline_} [-h] [--attach] [--smart-scan] [REGEX_PATTERN]" 

+

6965 _aliases_ = ["ps"] 

+

6966 _example_ = f"{_cmdline_} gdb.*" 

+

6967 

+

6968 def __init__(self) -> None: 

+

6969 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6970 self["ps_command"] = (f"{gef.session.constants['ps']} auxww", "`ps` command to get process information") 

+

6971 return 

+

6972 

+

6973 @parse_arguments({"pattern": ""}, {"--attach": True, "--smart-scan": True}) 

+

6974 def do_invoke(self, _: List, **kwargs: Any) -> None: 

+

6975 args : argparse.Namespace = kwargs["arguments"] 

+

6976 do_attach = args.attach 

+

6977 smart_scan = args.smart_scan 

+

6978 pattern = args.pattern 

+

6979 pattern = re.compile("^.*$") if not args else re.compile(pattern) 

+

6980 

+

6981 for process in self.get_processes(): 

+

6982 pid = int(process["pid"]) 

+

6983 command = process["command"] 

+

6984 

+

6985 if not re.search(pattern, command): 

+

6986 continue 

+

6987 

+

6988 if smart_scan: 

+

6989 if command.startswith("[") and command.endswith("]"): continue 6989 ↛ 6981line 6989 didn't jump to line 6981, because the continue on line 6989 wasn't executed

+

6990 if command.startswith("socat "): continue 6990 ↛ 6981line 6990 didn't jump to line 6981, because the continue on line 6990 wasn't executed

+

6991 if command.startswith("grep "): continue 6991 ↛ 6981line 6991 didn't jump to line 6981, because the continue on line 6991 wasn't executed

+

6992 if command.startswith("gdb "): continue 6992 ↛ 6994line 6992 didn't jump to line 6994, because the condition on line 6992 was never false

+

6993 

+

6994 if args and do_attach: 6994 ↛ 6995line 6994 didn't jump to line 6995, because the condition on line 6994 was never true

+

6995 ok(f"Attaching to process='{process['command']}' pid={pid:d}") 

+

6996 gdb.execute(f"attach {pid:d}") 

+

6997 return None 

+

6998 

+

6999 line = [process[i] for i in ("pid", "user", "cpu", "mem", "tty", "command")] 

+

7000 gef_print("\t\t".join(line)) 

+

7001 

+

7002 return None 

+

7003 

+

7004 def get_processes(self) -> Generator[Dict[str, str], None, None]: 

+

7005 output = gef_execute_external(self["ps_command"].split(), True) 

+

7006 names = [x.lower().replace("%", "") for x in output[0].split()] 

+

7007 

+

7008 for line in output[1:]: 

+

7009 fields = line.split() 

+

7010 t = {} 

+

7011 

+

7012 for i, name in enumerate(names): 

+

7013 if i == len(names) - 1: 

+

7014 t[name] = " ".join(fields[i:]) 

+

7015 else: 

+

7016 t[name] = fields[i] 

+

7017 

+

7018 yield t 

+

7019 

+

7020 return 

+

7021 

+

7022 

+

7023@register 

+

7024class ElfInfoCommand(GenericCommand): 

+

7025 """Display a limited subset of ELF header information. If no argument is provided, the command will 

+

7026 show information about the current ELF being debugged.""" 

+

7027 

+

7028 _cmdline_ = "elf-info" 

+

7029 _syntax_ = f"{_cmdline_} [FILE]" 

+

7030 _example_ = f"{_cmdline_} /bin/ls" 

+

7031 

+

7032 def __init__(self) -> None: 

+

7033 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

7034 return 

+

7035 

+

7036 @parse_arguments({}, {"--filename": ""}) 

+

7037 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

7038 args : argparse.Namespace = kwargs["arguments"] 

+

7039 

+

7040 if is_qemu_system(): 7040 ↛ 7041line 7040 didn't jump to line 7041, because the condition on line 7040 was never true

+

7041 err("Unsupported") 

+

7042 return 

+

7043 

+

7044 filename = args.filename or get_filepath() 

+

7045 if filename is None: 7045 ↛ 7046line 7045 didn't jump to line 7046, because the condition on line 7045 was never true

+

7046 return 

+

7047 

+

7048 try: 

+

7049 elf = Elf(filename) 

+

7050 except ValueError as ve: 

+

7051 err(f"`{filename}` is an invalid value for ELF file") 

+

7052 return 

+

7053 

+

7054 data = [ 

+

7055 ("Magic", f"{hexdump(struct.pack('>I', elf.e_magic), show_raw=True)}"), 

+

7056 ("Class", f"{elf.e_class.value:#x} - {elf.e_class.name}"), 

+

7057 ("Endianness", f"{elf.e_endianness.value:#x} - {Endianness(elf.e_endianness).name}"), 

+

7058 ("Version", f"{elf.e_eiversion:#x}"), 

+

7059 ("OS ABI", f"{elf.e_osabi.value:#x} - {elf.e_osabi.name if elf.e_osabi else ''}"), 

+

7060 ("ABI Version", f"{elf.e_abiversion:#x}"), 

+

7061 ("Type", f"{elf.e_type.value:#x} - {elf.e_type.name}"), 

+

7062 ("Machine", f"{elf.e_machine.value:#x} - {elf.e_machine.name}"), 

+

7063 ("Program Header Table", f"{format_address(elf.e_phoff)}"), 

+

7064 ("Section Header Table", f"{format_address(elf.e_shoff)}"), 

+

7065 ("Header Table", f"{format_address(elf.e_phoff)}"), 

+

7066 ("ELF Version", f"{elf.e_version:#x}"), 

+

7067 ("Header size", "{0} ({0:#x})".format(elf.e_ehsize)), 

+

7068 ("Entry point", f"{format_address(elf.e_entry)}"), 

+

7069 ] 

+

7070 

+

7071 for title, content in data: 

+

7072 gef_print(f"{Color.boldify(f'{title:<22}')}: {content}") 

+

7073 

+

7074 gef_print("") 

+

7075 gef_print(titlify("Program Header")) 

+

7076 

+

7077 gef_print(" [{:>2s}] {:12s} {:>8s} {:>10s} {:>10s} {:>8s} {:>8s} {:5s} {:>8s}".format( 

+

7078 "#", "Type", "Offset", "Virtaddr", "Physaddr", "FileSiz", "MemSiz", "Flags", "Align")) 

+

7079 

+

7080 for i, p in enumerate(elf.phdrs): 

+

7081 p_type = p.p_type.name if p.p_type else "" 

+

7082 p_flags = str(p.p_flags.name).lstrip("Flag.") if p.p_flags else "???" 

+

7083 

+

7084 gef_print(" [{:2d}] {:12s} {:#8x} {:#10x} {:#10x} {:#8x} {:#8x} {:5s} {:#8x}".format( 

+

7085 i, p_type, p.p_offset, p.p_vaddr, p.p_paddr, p.p_filesz, p.p_memsz, p_flags, p.p_align)) 

+

7086 

+

7087 gef_print("") 

+

7088 gef_print(titlify("Section Header")) 

+

7089 gef_print(" [{:>2s}] {:20s} {:>15s} {:>10s} {:>8s} {:>8s} {:>8s} {:5s} {:4s} {:4s} {:>8s}".format( 

+

7090 "#", "Name", "Type", "Address", "Offset", "Size", "EntSiz", "Flags", "Link", "Info", "Align")) 

+

7091 

+

7092 for i, s in enumerate(elf.shdrs): 

+

7093 sh_type = s.sh_type.name if s.sh_type else "UNKN" 

+

7094 sh_flags = str(s.sh_flags).lstrip("Flags.") if s.sh_flags else "UNKN" 

+

7095 

+

7096 gef_print(f" [{i:2d}] {s.name:20s} {sh_type:>15s} {s.sh_addr:#10x} {s.sh_offset:#8x} " 

+

7097 f"{s.sh_size:#8x} {s.sh_entsize:#8x} {sh_flags:5s} {s.sh_link:#4x} {s.sh_info:#4x} {s.sh_addralign:#8x}") 

+

7098 return 

+

7099 

+

7100 

+

7101@register 

+

7102class EntryPointBreakCommand(GenericCommand): 

+

7103 """Tries to find best entry point and sets a temporary breakpoint on it. The command will test for 

+

7104 well-known symbols for entry points, such as `main`, `_main`, `__libc_start_main`, etc. defined by 

+

7105 the setting `entrypoint_symbols`.""" 

+

7106 

+

7107 _cmdline_ = "entry-break" 

+

7108 _syntax_ = _cmdline_ 

+

7109 _aliases_ = ["start",] 

+

7110 

+

7111 def __init__(self) -> None: 

+

7112 super().__init__() 

+

7113 self["entrypoint_symbols"] = ("main _main __libc_start_main __uClibc_main start _start", "Possible symbols for entry points") 

+

7114 return 

+

7115 

+

7116 def do_invoke(self, argv: List[str]) -> None: 

+

7117 fpath = get_filepath() 

+

7118 if fpath is None: 7118 ↛ 7119line 7118 didn't jump to line 7119, because the condition on line 7118 was never true

+

7119 warn("No executable to debug, use `file` to load a binary") 

+

7120 return 

+

7121 

+

7122 if not os.access(fpath, os.X_OK): 7122 ↛ 7123line 7122 didn't jump to line 7123, because the condition on line 7122 was never true

+

7123 warn(f"The file '{fpath}' is not executable.") 

+

7124 return 

+

7125 

+

7126 if is_alive() and not gef.session.qemu_mode: 

+

7127 warn("gdb is already running") 

+

7128 return 

+

7129 

+

7130 bp = None 

+

7131 entrypoints = self["entrypoint_symbols"].split() 

+

7132 

+

7133 for sym in entrypoints: 7133 ↛ 7149line 7133 didn't jump to line 7149, because the loop on line 7133 didn't complete

+

7134 try: 

+

7135 value = parse_address(sym) 

+

7136 info(f"Breaking at '{value:#x}'") 

+

7137 bp = EntryBreakBreakpoint(sym) 

+

7138 gdb.execute(f"run {' '.join(argv)}") 

+

7139 return 

+

7140 

+

7141 except gdb.error as gdb_error: 

+

7142 if 'The "remote" target does not support "run".' in str(gdb_error): 

+

7143 # this case can happen when doing remote debugging 

+

7144 gdb.execute("continue") 

+

7145 return 

+

7146 continue 

+

7147 

+

7148 # if here, clear the breakpoint if any set 

+

7149 if bp: 

+

7150 bp.delete() 

+

7151 

+

7152 # break at entry point 

+

7153 entry = gef.binary.entry_point 

+

7154 

+

7155 if is_pie(fpath): 

+

7156 self.set_init_tbreak_pie(entry, argv) 

+

7157 gdb.execute("continue") 

+

7158 return 

+

7159 

+

7160 self.set_init_tbreak(entry) 

+

7161 gdb.execute(f"run {' '.join(argv)}") 

+

7162 return 

+

7163 

+

7164 def set_init_tbreak(self, addr: int) -> EntryBreakBreakpoint: 

+

7165 info(f"Breaking at entry-point: {addr:#x}") 

+

7166 bp = EntryBreakBreakpoint(f"*{addr:#x}") 

+

7167 return bp 

+

7168 

+

7169 def set_init_tbreak_pie(self, addr: int, argv: List[str]) -> EntryBreakBreakpoint: 

+

7170 warn("PIC binary detected, retrieving text base address") 

+

7171 gdb.execute("set stop-on-solib-events 1") 

+

7172 hide_context() 

+

7173 gdb.execute(f"run {' '.join(argv)}") 

+

7174 unhide_context() 

+

7175 gdb.execute("set stop-on-solib-events 0") 

+

7176 vmmap = gef.memory.maps 

+

7177 base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] 

+

7178 return self.set_init_tbreak(base_address + addr) 

+

7179 

+

7180 

+

7181@register 

+

7182class NamedBreakpointCommand(GenericCommand): 

+

7183 """Sets a breakpoint and assigns a name to it, which will be shown, when it's hit.""" 

+

7184 

+

7185 _cmdline_ = "name-break" 

+

7186 _syntax_ = f"{_cmdline_} name [address]" 

+

7187 _aliases_ = ["nb",] 

+

7188 _example = f"{_cmdline_} main *0x4008a9" 

+

7189 

+

7190 def __init__(self) -> None: 

+

7191 super().__init__() 

+

7192 return 

+

7193 

+

7194 @parse_arguments({"name": "", "address": "*$pc"}, {}) 

+

7195 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

7196 args : argparse.Namespace = kwargs["arguments"] 

+

7197 if not args.name: 7197 ↛ 7198line 7197 didn't jump to line 7198, because the condition on line 7197 was never true

+

7198 err("Missing name for breakpoint") 

+

7199 self.usage() 

+

7200 return 

+

7201 

+

7202 NamedBreakpoint(args.address, args.name) 

+

7203 return 

+

7204 

+

7205 

+

7206@register 

+

7207class ContextCommand(GenericCommand): 

+

7208 """Displays a comprehensive and modular summary of runtime context. Unless setting `enable` is 

+

7209 set to False, this command will be spawned automatically every time GDB hits a breakpoint, a 

+

7210 watchpoint, or any kind of interrupt. By default, it will show panes that contain the register 

+

7211 states, the stack, and the disassembly code around $pc.""" 

+

7212 

+

7213 _cmdline_ = "context" 

+

7214 _syntax_ = f"{_cmdline_} [legend|regs|stack|code|args|memory|source|trace|threads|extra]" 

+

7215 _aliases_ = ["ctx",] 

+

7216 

+

7217 old_registers: Dict[str, Optional[int]] = {} 

+

7218 

+

7219 def __init__(self) -> None: 

+

7220 super().__init__() 

+

7221 self["enable"] = (True, "Enable/disable printing the context when breaking") 

+

7222 self["show_source_code_variable_values"] = (True, "Show extra PC context info in the source code") 

+

7223 self["show_stack_raw"] = (False, "Show the stack pane as raw hexdump (no dereference)") 

+

7224 self["show_registers_raw"] = (False, "Show the registers pane with raw values (no dereference)") 

+

7225 self["show_opcodes_size"] = (0, "Number of bytes of opcodes to display next to the disassembly") 

+

7226 self["peek_calls"] = (True, "Peek into calls") 

+

7227 self["peek_ret"] = (True, "Peek at return address") 

+

7228 self["nb_lines_stack"] = (8, "Number of line in the stack pane") 

+

7229 self["grow_stack_down"] = (False, "Order of stack downward starts at largest down to stack pointer") 

+

7230 self["nb_lines_backtrace"] = (10, "Number of line in the backtrace pane") 

+

7231 self["nb_lines_backtrace_before"] = (2, "Number of line in the backtrace pane before selected frame") 

+

7232 self["nb_lines_threads"] = (-1, "Number of line in the threads pane") 

+

7233 self["nb_lines_code"] = (6, "Number of instruction after $pc") 

+

7234 self["nb_lines_code_prev"] = (3, "Number of instruction before $pc") 

+

7235 self["ignore_registers"] = ("", "Space-separated list of registers not to display (e.g. '$cs $ds $gs')") 

+

7236 self["clear_screen"] = (True, "Clear the screen before printing the context") 

+

7237 self["layout"] = ("legend regs stack code args source memory threads trace extra", "Change the order/presence of the context sections") 

+

7238 self["redirect"] = ("", "Redirect the context information to another TTY") 

+

7239 self["libc_args"] = (False, "[DEPRECATED - Unused] Show libc function call args description") 

+

7240 self["libc_args_path"] = ("", "[DEPRECATED - Unused] Path to libc function call args json files, provided via gef-extras") 

+

7241 

+

7242 self.layout_mapping = { 

+

7243 "legend": (self.show_legend, None, None), 

+

7244 "regs": (self.context_regs, None, None), 

+

7245 "stack": (self.context_stack, None, None), 

+

7246 "code": (self.context_code, None, None), 

+

7247 "args": (self.context_args, None, None), 

+

7248 "memory": (self.context_memory, None, None), 

+

7249 "source": (self.context_source, None, None), 

+

7250 "trace": (self.context_trace, None, None), 

+

7251 "threads": (self.context_threads, None, None), 

+

7252 "extra": (self.context_additional_information, None, None), 

+

7253 } 

+

7254 

+

7255 self.instruction_iterator = gef_disassemble 

+

7256 return 

+

7257 

+

7258 def post_load(self) -> None: 

+

7259 gef_on_continue_hook(self.update_registers) 

+

7260 gef_on_continue_hook(self.empty_extra_messages) 

+

7261 return 

+

7262 

+

7263 def show_legend(self) -> None: 

+

7264 if gef.config["gef.disable_color"] is True: 7264 ↛ 7265line 7264 didn't jump to line 7265, because the condition on line 7264 was never true

+

7265 return 

+

7266 str_color = gef.config["theme.dereference_string"] 

+

7267 code_addr_color = gef.config["theme.address_code"] 

+

7268 stack_addr_color = gef.config["theme.address_stack"] 

+

7269 heap_addr_color = gef.config["theme.address_heap"] 

+

7270 changed_register_color = gef.config["theme.registers_value_changed"] 

+

7271 

+

7272 gef_print("[ Legend: {} | {} | {} | {} | {} ]".format(Color.colorify("Modified register", changed_register_color), 

+

7273 Color.colorify("Code", code_addr_color), 

+

7274 Color.colorify("Heap", heap_addr_color), 

+

7275 Color.colorify("Stack", stack_addr_color), 

+

7276 Color.colorify("String", str_color))) 

+

7277 return 

+

7278 

+

7279 @only_if_gdb_running 

+

7280 def do_invoke(self, argv: List[str]) -> None: 

+

7281 if not self["enable"] or gef.ui.context_hidden: 

+

7282 return 

+

7283 

+

7284 if not all(_ in self.layout_mapping for _ in argv): 7284 ↛ 7285line 7284 didn't jump to line 7285, because the condition on line 7284 was never true

+

7285 self.usage() 

+

7286 return 

+

7287 

+

7288 if len(argv) > 0: 7288 ↛ 7289line 7288 didn't jump to line 7289, because the condition on line 7288 was never true

+

7289 current_layout = argv 

+

7290 else: 

+

7291 current_layout = self["layout"].strip().split() 

+

7292 

+

7293 if not current_layout: 7293 ↛ 7294line 7293 didn't jump to line 7294, because the condition on line 7293 was never true

+

7294 return 

+

7295 

+

7296 self.tty_rows, self.tty_columns = get_terminal_size() 

+

7297 

+

7298 redirect = self["redirect"] 

+

7299 if redirect and os.access(redirect, os.W_OK): 7299 ↛ 7300line 7299 didn't jump to line 7300, because the condition on line 7299 was never true

+

7300 enable_redirect_output(to_file=redirect) 

+

7301 

+

7302 for section in current_layout: 

+

7303 if section[0] == "-": 

+

7304 continue 

+

7305 

+

7306 try: 

+

7307 display_pane_function, pane_title_function, condition = self.layout_mapping[section] 

+

7308 if condition: 7308 ↛ 7309line 7308 didn't jump to line 7309, because the condition on line 7308 was never true

+

7309 if not condition(): 

+

7310 continue 

+

7311 if pane_title_function: 7311 ↛ 7312line 7311 didn't jump to line 7312, because the condition on line 7311 was never true

+

7312 self.context_title(pane_title_function()) 

+

7313 display_pane_function() 

+

7314 except gdb.MemoryError as e: 

+

7315 # a MemoryError will happen when $pc is corrupted (invalid address) 

+

7316 err(str(e)) 

+

7317 except IndexError: 

+

7318 # the `section` is not present, just skip 

+

7319 pass 

+

7320 

+

7321 self.context_title("") 

+

7322 

+

7323 if self["clear_screen"] and len(argv) == 0: 

+

7324 clear_screen(redirect) 

+

7325 

+

7326 if redirect and os.access(redirect, os.W_OK): 7326 ↛ 7327line 7326 didn't jump to line 7327, because the condition on line 7326 was never true

+

7327 disable_redirect_output() 

+

7328 return 

+

7329 

+

7330 def context_title(self, m: Optional[str]) -> None: 

+

7331 # allow for not displaying a title line 

+

7332 if m is None: 7332 ↛ 7333line 7332 didn't jump to line 7333, because the condition on line 7332 was never true

+

7333 return 

+

7334 

+

7335 line_color = gef.config["theme.context_title_line"] 

+

7336 msg_color = gef.config["theme.context_title_message"] 

+

7337 

+

7338 # print an empty line in case of "" 

+

7339 if not m: 

+

7340 gef_print(Color.colorify(HORIZONTAL_LINE * self.tty_columns, line_color)) 

+

7341 return 

+

7342 

+

7343 trail_len = len(m) + 6 

+

7344 title = "" 

+

7345 title += Color.colorify("{:{padd}<{width}} ".format("", 

+

7346 width=max(self.tty_columns - trail_len, 0), 

+

7347 padd=HORIZONTAL_LINE), 

+

7348 line_color) 

+

7349 title += Color.colorify(m, msg_color) 

+

7350 title += Color.colorify(" {:{padd}<4}".format("", padd=HORIZONTAL_LINE), 

+

7351 line_color) 

+

7352 gef_print(title) 

+

7353 return 

+

7354 

+

7355 def context_regs(self) -> None: 

+

7356 self.context_title("registers") 

+

7357 ignored_registers = set(self["ignore_registers"].split()) 

+

7358 

+

7359 if self["show_registers_raw"] is False: 7359 ↛ 7365line 7359 didn't jump to line 7365, because the condition on line 7359 was never false

+

7360 regs = set(gef.arch.all_registers) 

+

7361 printable_registers = " ".join(regs - ignored_registers) 

+

7362 gdb.execute(f"registers {printable_registers}") 

+

7363 return 

+

7364 

+

7365 widest = l = max(map(len, gef.arch.all_registers)) 

+

7366 l += 5 

+

7367 l += gef.arch.ptrsize * 2 

+

7368 nb = get_terminal_size()[1] // l 

+

7369 i = 1 

+

7370 line = "" 

+

7371 changed_color = gef.config["theme.registers_value_changed"] 

+

7372 regname_color = gef.config["theme.registers_register_name"] 

+

7373 

+

7374 for reg in gef.arch.all_registers: 

+

7375 if reg in ignored_registers: 

+

7376 continue 

+

7377 

+

7378 try: 

+

7379 r = gdb.parse_and_eval(reg) 

+

7380 if r.type.code == gdb.TYPE_CODE_VOID: 

+

7381 continue 

+

7382 

+

7383 new_value_type_flag = r.type.code == gdb.TYPE_CODE_FLAGS 

+

7384 new_value = int(r) 

+

7385 

+

7386 except (gdb.MemoryError, gdb.error): 

+

7387 # If this exception is triggered, it means that the current register 

+

7388 # is corrupted. Just use the register "raw" value (not eval-ed) 

+

7389 new_value = gef.arch.register(reg) 

+

7390 new_value_type_flag = False 

+

7391 

+

7392 except Exception: 

+

7393 new_value = 0 

+

7394 new_value_type_flag = False 

+

7395 

+

7396 old_value = self.old_registers.get(reg, 0) 

+

7397 

+

7398 padreg = reg.ljust(widest, " ") 

+

7399 value = align_address(new_value) 

+

7400 old_value = align_address(old_value or 0) 

+

7401 if value == old_value: 

+

7402 line += f"{Color.colorify(padreg, regname_color)}: " 

+

7403 else: 

+

7404 line += f"{Color.colorify(padreg, changed_color)}: " 

+

7405 if new_value_type_flag: 

+

7406 line += f"{format_address_spaces(value)} " 

+

7407 else: 

+

7408 addr = lookup_address(align_address(int(value))) 

+

7409 if addr.valid: 

+

7410 line += f"{addr!s} " 

+

7411 else: 

+

7412 line += f"{format_address_spaces(value)} " 

+

7413 

+

7414 if i % nb == 0: 

+

7415 gef_print(line) 

+

7416 line = "" 

+

7417 i += 1 

+

7418 

+

7419 if line: 

+

7420 gef_print(line) 

+

7421 

+

7422 gef_print(f"Flags: {gef.arch.flag_register_to_human()}") 

+

7423 return 

+

7424 

+

7425 def context_stack(self) -> None: 

+

7426 self.context_title("stack") 

+

7427 

+

7428 show_raw = self["show_stack_raw"] 

+

7429 nb_lines = self["nb_lines_stack"] 

+

7430 

+

7431 try: 

+

7432 sp = gef.arch.sp 

+

7433 if show_raw is True: 7433 ↛ 7434line 7433 didn't jump to line 7434, because the condition on line 7433 was never true

+

7434 mem = gef.memory.read(sp, 0x10 * nb_lines) 

+

7435 gef_print(hexdump(mem, base=sp)) 

+

7436 else: 

+

7437 gdb.execute(f"dereference -l {nb_lines:d} {sp:#x}") 

+

7438 

+

7439 except gdb.MemoryError: 

+

7440 err("Cannot read memory from $SP (corrupted stack pointer?)") 

+

7441 

+

7442 return 

+

7443 

+

7444 def addr_has_breakpoint(self, address: int, bp_locations: List[str]) -> bool: 

+

7445 return any(hex(address) in b for b in bp_locations) 

+

7446 

+

7447 def context_code(self) -> None: 

+

7448 nb_insn = self["nb_lines_code"] 

+

7449 nb_insn_prev = self["nb_lines_code_prev"] 

+

7450 show_opcodes_size = "show_opcodes_size" in self and self["show_opcodes_size"] 

+

7451 past_insns_color = gef.config["theme.old_context"] 

+

7452 cur_insn_color = gef.config["theme.disassemble_current_instruction"] 

+

7453 pc = gef.arch.pc 

+

7454 breakpoints = gdb.breakpoints() or [] 

+

7455 bp_locations = [b.location for b in breakpoints if b.location and b.location.startswith("*")] 

+

7456 

+

7457 frame = gdb.selected_frame() 

+

7458 arch_name = f"{gef.arch.arch.lower()}:{gef.arch.mode}" 

+

7459 

+

7460 self.context_title(f"code:{arch_name}") 

+

7461 

+

7462 try: 

+

7463 

+

7464 

+

7465 for insn in self.instruction_iterator(pc, nb_insn, nb_prev=nb_insn_prev): 

+

7466 line = [] 

+

7467 is_taken = False 

+

7468 target = None 

+

7469 bp_prefix = Color.redify(BP_GLYPH) if self.addr_has_breakpoint(insn.address, bp_locations) else " " 

+

7470 

+

7471 if show_opcodes_size == 0: 

+

7472 text = str(insn) 

+

7473 else: 

+

7474 insn_fmt = f"{{:{show_opcodes_size}o}}" 

+

7475 text = insn_fmt.format(insn) 

+

7476 

+

7477 if insn.address < pc: 

+

7478 line += f"{bp_prefix} {Color.colorify(text, past_insns_color)}" 

+

7479 

+

7480 elif insn.address == pc: 

+

7481 line += f"{bp_prefix}{Color.colorify(f'{RIGHT_ARROW[1:]}{text}', cur_insn_color)}" 

+

7482 

+

7483 if gef.arch.is_conditional_branch(insn): 7483 ↛ 7484line 7483 didn't jump to line 7484, because the condition on line 7483 was never true

+

7484 is_taken, reason = gef.arch.is_branch_taken(insn) 

+

7485 if is_taken: 

+

7486 target = insn.operands[-1].split()[0] 

+

7487 reason = f"[Reason: {reason}]" if reason else "" 

+

7488 line += Color.colorify(f"\tTAKEN {reason}", "bold green") 

+

7489 else: 

+

7490 reason = f"[Reason: !({reason})]" if reason else "" 

+

7491 line += Color.colorify(f"\tNOT taken {reason}", "bold red") 

+

7492 elif gef.arch.is_call(insn) and self["peek_calls"] is True: 7492 ↛ 7493line 7492 didn't jump to line 7493, because the condition on line 7492 was never true

+

7493 target = insn.operands[-1].split()[0] 

+

7494 elif gef.arch.is_ret(insn) and self["peek_ret"] is True: 

+

7495 target = gef.arch.get_ra(insn, frame) 

+

7496 

+

7497 else: 

+

7498 line += f"{bp_prefix} {text}" 

+

7499 

+

7500 gef_print("".join(line)) 

+

7501 

+

7502 if target: 

+

7503 try: 

+

7504 address = int(target, 0) if isinstance(target, str) else target 

+

7505 except ValueError: 

+

7506 # If the operand isn't an address right now we can't parse it 

+

7507 continue 

+

7508 for i, tinsn in enumerate(self.instruction_iterator(address, nb_insn)): 7508 ↛ 7509,   7508 ↛ 75112 missed branches: 1) line 7508 didn't jump to line 7509, because the loop on line 7508 never started, 2) line 7508 didn't jump to line 7511, because the loop on line 7508 didn't complete

+

7509 text= f" {DOWN_ARROW if i == 0 else ' '} {tinsn!s}" 

+

7510 gef_print(text) 

+

7511 break 

+

7512 

+

7513 except gdb.MemoryError: 

+

7514 err("Cannot disassemble from $PC") 

+

7515 return 

+

7516 

+

7517 def context_args(self) -> None: 

+

7518 insn = gef_current_instruction(gef.arch.pc) 

+

7519 if not gef.arch.is_call(insn): 7519 ↛ 7522line 7519 didn't jump to line 7522

+

7520 return 

+

7521 

+

7522 self.size2type = { 

+

7523 1: "BYTE", 

+

7524 2: "WORD", 

+

7525 4: "DWORD", 

+

7526 8: "QWORD", 

+

7527 } 

+

7528 

+

7529 if insn.operands[-1].startswith(self.size2type[gef.arch.ptrsize]+" PTR"): 

+

7530 target = "*" + insn.operands[-1].split()[-1] 

+

7531 elif "$"+insn.operands[0] in gef.arch.all_registers: 

+

7532 target = f"*{gef.arch.register('$' + insn.operands[0]):#x}" 

+

7533 else: 

+

7534 # is there a symbol? 

+

7535 ops = " ".join(insn.operands) 

+

7536 if "<" in ops and ">" in ops: 

+

7537 # extract it 

+

7538 target = re.sub(r".*<([^\(> ]*).*", r"\1", ops) 

+

7539 else: 

+

7540 # it's an address, just use as is 

+

7541 target = re.sub(r".*(0x[a-fA-F0-9]*).*", r"\1", ops) 

+

7542 

+

7543 sym = gdb.lookup_global_symbol(target) 

+

7544 if sym is None: 

+

7545 self.print_guessed_arguments(target) 

+

7546 return 

+

7547 

+

7548 if sym.type.code != gdb.TYPE_CODE_FUNC: 

+

7549 err(f"Symbol '{target}' is not a function: type={sym.type.code}") 

+

7550 return 

+

7551 

+

7552 self.print_arguments_from_symbol(target, sym) 

+

7553 return 

+

7554 

+

7555 def print_arguments_from_symbol(self, function_name: str, symbol: "gdb.Symbol") -> None: 

+

7556 """If symbols were found, parse them and print the argument adequately.""" 

+

7557 args = [] 

+

7558 

+

7559 for i, f in enumerate(symbol.type.fields()): 

+

7560 _value = gef.arch.get_ith_parameter(i, in_func=False)[1] 

+

7561 _value = RIGHT_ARROW.join(dereference_from(_value)) 

+

7562 _name = f.name or f"var_{i}" 

+

7563 _type = f.type.name or self.size2type[f.type.sizeof] 

+

7564 args.append(f"{_type} {_name} = {_value}") 

+

7565 

+

7566 self.context_title("arguments") 

+

7567 

+

7568 if not args: 

+

7569 gef_print(f"{function_name} (<void>)") 

+

7570 return 

+

7571 

+

7572 gef_print(f"{function_name} (\n "+",\n ".join(args)+"\n)") 

+

7573 return 

+

7574 

+

7575 def print_guessed_arguments(self, function_name: str) -> None: 

+

7576 """When no symbol, read the current basic block and look for "interesting" instructions.""" 

+

7577 

+

7578 def __get_current_block_start_address() -> Optional[int]: 

+

7579 pc = gef.arch.pc 

+

7580 try: 

+

7581 block = gdb.block_for_pc(pc) 

+

7582 block_start = block.start if block else gdb_get_nth_previous_instruction_address(pc, 5) 

+

7583 except RuntimeError: 

+

7584 block_start = gdb_get_nth_previous_instruction_address(pc, 5) 

+

7585 return block_start 

+

7586 

+

7587 parameter_set = set() 

+

7588 pc = gef.arch.pc 

+

7589 block_start = __get_current_block_start_address() 

+

7590 if not block_start: 

+

7591 return 

+

7592 

+

7593 function_parameters = gef.arch.function_parameters 

+

7594 arg_key_color = gef.config["theme.registers_register_name"] 

+

7595 

+

7596 for insn in self.instruction_iterator(block_start, pc - block_start): 

+

7597 if not insn.operands: 

+

7598 continue 

+

7599 

+

7600 if is_x86_32(): 

+

7601 if insn.mnemonic == "push": 

+

7602 parameter_set.add(insn.operands[0]) 

+

7603 else: 

+

7604 op = "$" + insn.operands[0] 

+

7605 if op in function_parameters: 

+

7606 parameter_set.add(op) 

+

7607 

+

7608 if is_x86_64(): 

+

7609 # also consider extended registers 

+

7610 extended_registers = {"$rdi": ["$edi", "$di"], 

+

7611 "$rsi": ["$esi", "$si"], 

+

7612 "$rdx": ["$edx", "$dx"], 

+

7613 "$rcx": ["$ecx", "$cx"], 

+

7614 } 

+

7615 for exreg in extended_registers: 

+

7616 if op in extended_registers[exreg]: 

+

7617 parameter_set.add(exreg) 

+

7618 

+

7619 if is_x86_32(): 

+

7620 nb_argument = len(parameter_set) 

+

7621 else: 

+

7622 nb_argument = max([function_parameters.index(p)+1 for p in parameter_set], default=0) 

+

7623 

+

7624 args = [] 

+

7625 for i in range(nb_argument): 

+

7626 _key, _values = gef.arch.get_ith_parameter(i, in_func=False) 

+

7627 _values = RIGHT_ARROW.join(dereference_from(_values)) 

+

7628 args.append(f"{Color.colorify(_key, arg_key_color)} = {_values}") 

+

7629 

+

7630 self.context_title("arguments (guessed)") 

+

7631 gef_print(f"{function_name} (") 

+

7632 if args: 

+

7633 gef_print(" " + ",\n ".join(args)) 

+

7634 gef_print(")") 

+

7635 return 

+

7636 

+

7637 def line_has_breakpoint(self, file_name: str, line_number: int, bp_locations: List[str]) -> bool: 

+

7638 filename_line = f"{file_name}:{line_number}" 

+

7639 return any(filename_line in loc for loc in bp_locations) 

+

7640 

+

7641 def context_source(self) -> None: 

+

7642 try: 

+

7643 pc = gef.arch.pc 

+

7644 symtabline = gdb.find_pc_line(pc) 

+

7645 symtab = symtabline.symtab 

+

7646 # we subtract one because the line number returned by gdb start at 1 

+

7647 line_num = symtabline.line - 1 

+

7648 if not symtab.is_valid(): 7648 ↛ 7649line 7648 didn't jump to line 7649, because the condition on line 7648 was never true

+

7649 return 

+

7650 

+

7651 fpath = symtab.fullname() 

+

7652 with open(fpath, "r") as f: 

+

7653 lines = [l.rstrip() for l in f.readlines()] 

+

7654 

+

7655 except Exception: 

+

7656 return 

+

7657 

+

7658 file_base_name = os.path.basename(symtab.filename) 

+

7659 breakpoints = gdb.breakpoints() or [] 

+

7660 bp_locations = [b.location for b in breakpoints if b.location and file_base_name in b.location] 

+

7661 past_lines_color = gef.config["theme.old_context"] 

+

7662 

+

7663 nb_line = self["nb_lines_code"] 

+

7664 fn = symtab.filename 

+

7665 if len(fn) > 20: 

+

7666 fn = f"{fn[:15]}[...]{os.path.splitext(fn)[1]}" 

+

7667 title = f"source:{fn}+{line_num + 1}" 

+

7668 cur_line_color = gef.config["theme.source_current_line"] 

+

7669 self.context_title(title) 

+

7670 show_extra_info = self["show_source_code_variable_values"] 

+

7671 

+

7672 for i in range(line_num - nb_line + 1, line_num + nb_line): 

+

7673 if i < 0: 7673 ↛ 7674line 7673 didn't jump to line 7674, because the condition on line 7673 was never true

+

7674 continue 

+

7675 

+

7676 bp_prefix = Color.redify(BP_GLYPH) if self.line_has_breakpoint(file_base_name, i + 1, bp_locations) else " " 

+

7677 

+

7678 if i < line_num: 

+

7679 gef_print("{}{}".format(bp_prefix, Color.colorify(f" {i + 1:4d}\t {lines[i]}", past_lines_color))) 

+

7680 

+

7681 if i == line_num: 

+

7682 prefix = f"{bp_prefix}{RIGHT_ARROW[1:]}{i + 1:4d}\t " 

+

7683 leading = len(lines[i]) - len(lines[i].lstrip()) 

+

7684 if show_extra_info: 7684 ↛ 7688line 7684 didn't jump to line 7688, because the condition on line 7684 was never false

+

7685 extra_info = self.get_pc_context_info(pc, lines[i]) 

+

7686 if extra_info: 

+

7687 gef_print(f"{' ' * (len(prefix) + leading)}{extra_info}") 

+

7688 gef_print(Color.colorify(f"{prefix}{lines[i]}", cur_line_color)) 

+

7689 

+

7690 if i > line_num: 

+

7691 try: 

+

7692 gef_print(f"{bp_prefix} {i + 1:4d}\t {lines[i]}") 

+

7693 except IndexError: 

+

7694 break 

+

7695 return 

+

7696 

+

7697 def get_pc_context_info(self, pc: int, line: str) -> str: 

+

7698 try: 

+

7699 current_block = gdb.block_for_pc(pc) 

+

7700 if not current_block or not current_block.is_valid(): return "" 7700 ↛ exitline 7700 didn't return from function 'get_pc_context_info', because the return on line 7700 wasn't executed

+

7701 m = collections.OrderedDict() 

+

7702 while current_block and not current_block.is_static: 

+

7703 for sym in current_block: 

+

7704 symbol = sym.name 

+

7705 if not sym.is_function and re.search(fr"\W{symbol}\W", line): 

+

7706 val = gdb.parse_and_eval(symbol) 

+

7707 if val.type.code in (gdb.TYPE_CODE_PTR, gdb.TYPE_CODE_ARRAY): 7707 ↛ 7708line 7707 didn't jump to line 7708, because the condition on line 7707 was never true

+

7708 addr = int(val.address) 

+

7709 addrs = dereference_from(addr) 

+

7710 if len(addrs) > 2: 

+

7711 addrs = [addrs[0], "[...]", addrs[-1]] 

+

7712 

+

7713 f = f" {RIGHT_ARROW} " 

+

7714 val = f.join(addrs) 

+

7715 elif val.type.code == gdb.TYPE_CODE_INT: 7715 ↛ 7718line 7715 didn't jump to line 7718, because the condition on line 7715 was never false

+

7716 val = hex(int(val)) 

+

7717 else: 

+

7718 continue 

+

7719 

+

7720 if symbol not in m: 7720 ↛ 7703line 7720 didn't jump to line 7703, because the condition on line 7720 was never false

+

7721 m[symbol] = val 

+

7722 current_block = current_block.superblock 

+

7723 

+

7724 if m: 

+

7725 return "// " + ", ".join([f"{Color.yellowify(a)}={b}" for a, b in m.items()]) 

+

7726 except Exception: 

+

7727 pass 

+

7728 return "" 

+

7729 

+

7730 def context_trace(self) -> None: 

+

7731 self.context_title("trace") 

+

7732 

+

7733 nb_backtrace = self["nb_lines_backtrace"] 

+

7734 if nb_backtrace <= 0: 7734 ↛ 7735line 7734 didn't jump to line 7735, because the condition on line 7734 was never true

+

7735 return 

+

7736 

+

7737 # backward compat for gdb (gdb < 7.10) 

+

7738 if not hasattr(gdb, "FrameDecorator"): 7738 ↛ 7739line 7738 didn't jump to line 7739, because the condition on line 7738 was never true

+

7739 gdb.execute(f"backtrace {nb_backtrace:d}") 

+

7740 return 

+

7741 

+

7742 orig_frame = gdb.selected_frame() 

+

7743 current_frame = gdb.newest_frame() 

+

7744 frames = [current_frame] 

+

7745 while current_frame != orig_frame: 7745 ↛ 7746line 7745 didn't jump to line 7746, because the condition on line 7745 was never true

+

7746 current_frame = current_frame.older() 

+

7747 frames.append(current_frame) 

+

7748 

+

7749 nb_backtrace_before = self["nb_lines_backtrace_before"] 

+

7750 level = max(len(frames) - nb_backtrace_before - 1, 0) 

+

7751 current_frame = frames[level] 

+

7752 

+

7753 while current_frame: 

+

7754 current_frame.select() 

+

7755 if not current_frame.is_valid(): 7755 ↛ 7756line 7755 didn't jump to line 7756, because the condition on line 7755 was never true

+

7756 continue 

+

7757 

+

7758 pc = current_frame.pc() 

+

7759 name = current_frame.name() 

+

7760 items = [] 

+

7761 items.append(f"{pc:#x}") 

+

7762 if name: 

+

7763 frame_args = gdb.FrameDecorator.FrameDecorator(current_frame).frame_args() or [] 

+

7764 m = "{}({})".format(Color.greenify(name), 

+

7765 ", ".join(["{}={!s}".format(Color.yellowify(x.sym), 

+

7766 x.sym.value(current_frame)) for x in frame_args])) 

+

7767 items.append(m) 

+

7768 else: 

+

7769 try: 

+

7770 insn = next(gef_disassemble(pc, 1)) 

+

7771 except gdb.MemoryError: 

+

7772 break 

+

7773 

+

7774 # check if the gdb symbol table may know the address 

+

7775 sym_found = gdb_get_location_from_symbol(pc) 

+

7776 symbol = "" 

+

7777 if sym_found: 7777 ↛ 7778line 7777 didn't jump to line 7778, because the condition on line 7777 was never true

+

7778 sym_name, offset = sym_found 

+

7779 symbol = f" <{sym_name}+{offset:x}> " 

+

7780 

+

7781 items.append(Color.redify(f"{symbol}{insn.mnemonic} {', '.join(insn.operands)}")) 

+

7782 

+

7783 gef_print("[{}] {}".format(Color.colorify(f"#{level}", "bold green" if current_frame == orig_frame else "bold pink"), 

+

7784 RIGHT_ARROW.join(items))) 

+

7785 current_frame = current_frame.older() 

+

7786 level += 1 

+

7787 nb_backtrace -= 1 

+

7788 if nb_backtrace == 0: 7788 ↛ 7789line 7788 didn't jump to line 7789, because the condition on line 7788 was never true

+

7789 break 

+

7790 

+

7791 orig_frame.select() 

+

7792 return 

+

7793 

+

7794 def context_threads(self) -> None: 

+

7795 def reason() -> str: 

+

7796 res = gdb.execute("info program", to_string=True) 

+

7797 if not res: 7797 ↛ 7798line 7797 didn't jump to line 7798, because the condition on line 7797 was never true

+

7798 return "NOT RUNNING" 

+

7799 

+

7800 for line in res.splitlines(): 7800 ↛ 7813line 7800 didn't jump to line 7813, because the loop on line 7800 didn't complete

+

7801 line = line.strip() 

+

7802 if line.startswith("It stopped with signal "): 

+

7803 return line.replace("It stopped with signal ", "").split(",", 1)[0] 

+

7804 if line == "The program being debugged is not being run.": 7804 ↛ 7805line 7804 didn't jump to line 7805, because the condition on line 7804 was never true

+

7805 return "NOT RUNNING" 

+

7806 if line == "It stopped at a breakpoint that has since been deleted.": 7806 ↛ 7807line 7806 didn't jump to line 7807, because the condition on line 7806 was never true

+

7807 return "TEMPORARY BREAKPOINT" 

+

7808 if line.startswith("It stopped at breakpoint "): 

+

7809 return "BREAKPOINT" 

+

7810 if line == "It stopped after being stepped.": 7810 ↛ 7811line 7810 didn't jump to line 7811, because the condition on line 7810 was never true

+

7811 return "SINGLE STEP" 

+

7812 

+

7813 return "STOPPED" 

+

7814 

+

7815 self.context_title("threads") 

+

7816 

+

7817 threads = gdb.selected_inferior().threads()[::-1] 

+

7818 idx = self["nb_lines_threads"] 

+

7819 if idx > 0: 7819 ↛ 7820line 7819 didn't jump to line 7820, because the condition on line 7819 was never true

+

7820 threads = threads[0:idx] 

+

7821 

+

7822 if idx == 0: 7822 ↛ 7823line 7822 didn't jump to line 7823, because the condition on line 7822 was never true

+

7823 return 

+

7824 

+

7825 if not threads: 7825 ↛ 7826line 7825 didn't jump to line 7826, because the condition on line 7825 was never true

+

7826 err("No thread selected") 

+

7827 return 

+

7828 

+

7829 selected_thread = gdb.selected_thread() 

+

7830 selected_frame = gdb.selected_frame() 

+

7831 

+

7832 for i, thread in enumerate(threads): 

+

7833 line = f"[{Color.colorify(f'#{i:d}', 'bold green' if thread == selected_thread else 'bold pink')}] Id {thread.num:d}, " 

+

7834 if thread.name: 

+

7835 line += f"""Name: "{thread.name}", """ 

+

7836 if thread.is_running(): 7836 ↛ 7837line 7836 didn't jump to line 7837, because the condition on line 7836 was never true

+

7837 line += Color.colorify("running", "bold green") 

+

7838 elif thread.is_stopped(): 7838 ↛ 7854line 7838 didn't jump to line 7854, because the condition on line 7838 was never false

+

7839 line += Color.colorify("stopped", "bold red") 

+

7840 thread.switch() 

+

7841 frame = gdb.selected_frame() 

+

7842 frame_name = frame.name() 

+

7843 

+

7844 # check if the gdb symbol table may know the address 

+

7845 if not frame_name: 

+

7846 sym_found = gdb_get_location_from_symbol(frame.pc()) 

+

7847 if sym_found: 7847 ↛ 7848line 7847 didn't jump to line 7848, because the condition on line 7847 was never true

+

7848 sym_name, offset = sym_found 

+

7849 frame_name = f"<{sym_name}+{offset:x}>" 

+

7850 

+

7851 line += (f" {Color.colorify(f'{frame.pc():#x}', 'blue')} in " 

+

7852 f"{Color.colorify(frame_name or '??', 'bold yellow')} (), " 

+

7853 f"reason: {Color.colorify(reason(), 'bold pink')}") 

+

7854 elif thread.is_exited(): 

+

7855 line += Color.colorify("exited", "bold yellow") 

+

7856 gef_print(line) 

+

7857 i += 1 

+

7858 

+

7859 selected_thread.switch() 

+

7860 selected_frame.select() 

+

7861 return 

+

7862 

+

7863 def context_additional_information(self) -> None: 

+

7864 if not gef.ui.context_messages: 

+

7865 return 

+

7866 

+

7867 self.context_title("extra") 

+

7868 for level, text in gef.ui.context_messages: 

+

7869 if level == "error": err(text) 7869 ↛ 7868line 7869 didn't jump to line 7868

+

7870 elif level == "warn": warn(text) 7870 ↛ 7871line 7870 didn't jump to line 7871, because the condition on line 7870 was never false

+

7871 elif level == "success": ok(text) 

+

7872 else: info(text) 

+

7873 return 

+

7874 

+

7875 def context_memory(self) -> None: 

+

7876 for address, opt in sorted(gef.ui.watches.items()): 

+

7877 sz, fmt = opt[0:2] 

+

7878 self.context_title(f"memory:{address:#x}") 

+

7879 if fmt == "pointers": 7879 ↛ 7880line 7879 didn't jump to line 7880, because the condition on line 7879 was never true

+

7880 gdb.execute(f"dereference -l {sz:d} {address:#x}") 

+

7881 else: 

+

7882 gdb.execute(f"hexdump {fmt} -s {sz:d} {address:#x}") 

+

7883 

+

7884 @classmethod 

+

7885 def update_registers(cls, _) -> None: 

+

7886 for reg in gef.arch.all_registers: 

+

7887 try: 

+

7888 cls.old_registers[reg] = gef.arch.register(reg) 

+

7889 except Exception: 

+

7890 cls.old_registers[reg] = 0 

+

7891 return 

+

7892 

+

7893 def empty_extra_messages(self, _) -> None: 

+

7894 gef.ui.context_messages.clear() 

+

7895 return 

+

7896 

+

7897 

+

7898@register 

+

7899class MemoryCommand(GenericCommand): 

+

7900 """Add or remove address ranges to the memory view.""" 

+

7901 _cmdline_ = "memory" 

+

7902 _syntax_ = f"{_cmdline_} (watch|unwatch|reset|list)" 

+

7903 

+

7904 def __init__(self) -> None: 

+

7905 super().__init__(prefix=True) 

+

7906 return 

+

7907 

+

7908 @only_if_gdb_running 

+

7909 def do_invoke(self, argv: List[str]) -> None: 

+

7910 self.usage() 

+

7911 return 

+

7912 

+

7913 

+

7914@register 

+

7915class MemoryWatchCommand(GenericCommand): 

+

7916 """Adds address ranges to the memory view.""" 

+

7917 _cmdline_ = "memory watch" 

+

7918 _syntax_ = f"{_cmdline_} ADDRESS [SIZE] [(qword|dword|word|byte|pointers)]" 

+

7919 _example_ = (f"\n{_cmdline_} 0x603000 0x100 byte" 

+

7920 f"\n{_cmdline_} $sp") 

+

7921 

+

7922 def __init__(self) -> None: 

+

7923 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

7924 return 

+

7925 

+

7926 @only_if_gdb_running 

+

7927 def do_invoke(self, argv: List[str]) -> None: 

+

7928 if len(argv) not in (1, 2, 3): 7928 ↛ 7929line 7928 didn't jump to line 7929, because the condition on line 7928 was never true

+

7929 self.usage() 

+

7930 return 

+

7931 

+

7932 address = parse_address(argv[0]) 

+

7933 size = parse_address(argv[1]) if len(argv) > 1 else 0x10 

+

7934 group = "byte" 

+

7935 

+

7936 if len(argv) == 3: 

+

7937 group = argv[2].lower() 

+

7938 if group not in ("qword", "dword", "word", "byte", "pointers"): 7938 ↛ 7939line 7938 didn't jump to line 7939, because the condition on line 7938 was never true

+

7939 warn(f"Unexpected grouping '{group}'") 

+

7940 self.usage() 

+

7941 return 

+

7942 else: 

+

7943 if gef.arch.ptrsize == 4: 7943 ↛ 7944line 7943 didn't jump to line 7944, because the condition on line 7943 was never true

+

7944 group = "dword" 

+

7945 elif gef.arch.ptrsize == 8: 7945 ↛ 7948line 7945 didn't jump to line 7948, because the condition on line 7945 was never false

+

7946 group = "qword" 

+

7947 

+

7948 gef.ui.watches[address] = (size, group) 

+

7949 ok(f"Adding memwatch to {address:#x}") 

+

7950 return 

+

7951 

+

7952 

+

7953@register 

+

7954class MemoryUnwatchCommand(GenericCommand): 

+

7955 """Removes address ranges to the memory view.""" 

+

7956 _cmdline_ = "memory unwatch" 

+

7957 _syntax_ = f"{_cmdline_} ADDRESS" 

+

7958 _example_ = (f"\n{_cmdline_} 0x603000" 

+

7959 f"\n{_cmdline_} $sp") 

+

7960 

+

7961 def __init__(self) -> None: 

+

7962 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

7963 return 

+

7964 

+

7965 @only_if_gdb_running 

+

7966 def do_invoke(self, argv: List[str]) -> None: 

+

7967 if not argv: 7967 ↛ 7968line 7967 didn't jump to line 7968, because the condition on line 7967 was never true

+

7968 self.usage() 

+

7969 return 

+

7970 

+

7971 address = parse_address(argv[0]) 

+

7972 res = gef.ui.watches.pop(address, None) 

+

7973 if not res: 7973 ↛ 7976line 7973 didn't jump to line 7976, because the condition on line 7973 was never false

+

7974 warn(f"You weren't watching {address:#x}") 

+

7975 else: 

+

7976 ok(f"Removed memwatch of {address:#x}") 

+

7977 return 

+

7978 

+

7979 

+

7980@register 

+

7981class MemoryWatchResetCommand(GenericCommand): 

+

7982 """Removes all watchpoints.""" 

+

7983 _cmdline_ = "memory reset" 

+

7984 _syntax_ = f"{_cmdline_}" 

+

7985 

+

7986 @only_if_gdb_running 

+

7987 def do_invoke(self, _: List[str]) -> None: 

+

7988 gef.ui.watches.clear() 

+

7989 ok("Memory watches cleared") 

+

7990 return 

+

7991 

+

7992 

+

7993@register 

+

7994class MemoryWatchListCommand(GenericCommand): 

+

7995 """Lists all watchpoints to display in context layout.""" 

+

7996 _cmdline_ = "memory list" 

+

7997 _syntax_ = f"{_cmdline_}" 

+

7998 

+

7999 @only_if_gdb_running 

+

8000 def do_invoke(self, _: List[str]) -> None: 

+

8001 if not gef.ui.watches: 8001 ↛ 8005line 8001 didn't jump to line 8005, because the condition on line 8001 was never false

+

8002 info("No memory watches") 

+

8003 return 

+

8004 

+

8005 info("Memory watches:") 

+

8006 for address, opt in sorted(gef.ui.watches.items()): 

+

8007 gef_print(f"- {address:#x} ({opt[0]}, {opt[1]})") 

+

8008 return 

+

8009 

+

8010 

+

8011@register 

+

8012class HexdumpCommand(GenericCommand): 

+

8013 """Display SIZE lines of hexdump from the memory location pointed by LOCATION.""" 

+

8014 

+

8015 _cmdline_ = "hexdump" 

+

8016 _syntax_ = f"{_cmdline_} (qword|dword|word|byte) [LOCATION] [--size SIZE] [--reverse]" 

+

8017 _example_ = f"{_cmdline_} byte $rsp --size 16 --reverse" 

+

8018 

+

8019 def __init__(self) -> None: 

+

8020 super().__init__(complete=gdb.COMPLETE_LOCATION, prefix=True) 

+

8021 self["always_show_ascii"] = (False, "If true, hexdump will always display the ASCII dump") 

+

8022 self.format: Optional[str] = None 

+

8023 self.__last_target = "$sp" 

+

8024 return 

+

8025 

+

8026 @only_if_gdb_running 

+

8027 @parse_arguments({"address": "",}, {("--reverse", "-r"): True, ("--size", "-s"): 0}) 

+

8028 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

8029 valid_formats = ["byte", "word", "dword", "qword"] 

+

8030 if not self.format or self.format not in valid_formats: 8030 ↛ 8031line 8030 didn't jump to line 8031, because the condition on line 8030 was never true

+

8031 err("Invalid command") 

+

8032 return 

+

8033 

+

8034 args : argparse.Namespace = kwargs["arguments"] 

+

8035 target = args.address or self.__last_target 

+

8036 start_addr = parse_address(target) 

+

8037 read_from = align_address(start_addr) 

+

8038 

+

8039 if self.format == "byte": 

+

8040 read_len = args.size or 0x40 

+

8041 read_from += self.repeat_count * read_len 

+

8042 mem = gef.memory.read(read_from, read_len) 

+

8043 lines = hexdump(mem, base=read_from).splitlines() 

+

8044 else: 

+

8045 read_len = args.size or 0x10 

+

8046 lines = self._hexdump(read_from, read_len, self.format, self.repeat_count * read_len) 

+

8047 

+

8048 if args.reverse: 

+

8049 lines.reverse() 

+

8050 

+

8051 self.__last_target = target 

+

8052 gef_print("\n".join(lines)) 

+

8053 return 

+

8054 

+

8055 def _hexdump(self, start_addr: int, length: int, arrange_as: str, offset: int = 0) -> List[str]: 

+

8056 endianness = gef.arch.endianness 

+

8057 

+

8058 base_address_color = gef.config["theme.dereference_base_address"] 

+

8059 show_ascii = gef.config["hexdump.always_show_ascii"] 

+

8060 

+

8061 formats = { 

+

8062 "qword": ("Q", 8), 

+

8063 "dword": ("I", 4), 

+

8064 "word": ("H", 2), 

+

8065 } 

+

8066 

+

8067 r, l = formats[arrange_as] 

+

8068 fmt_str = f"{{base}}{VERTICAL_LINE}+{{offset:#06x}} {{sym}}{{val:#0{l*2+2}x}} {{text}}" 

+

8069 fmt_pack = f"{endianness!s}{r}" 

+

8070 lines = [] 

+

8071 

+

8072 i = 0 

+

8073 text = "" 

+

8074 while i < length: 

+

8075 cur_addr = start_addr + (i + offset) * l 

+

8076 sym = gdb_get_location_from_symbol(cur_addr) 

+

8077 sym = "<{:s}+{:04x}> ".format(*sym) if sym else "" 

+

8078 mem = gef.memory.read(cur_addr, l) 

+

8079 val = struct.unpack(fmt_pack, mem)[0] 

+

8080 if show_ascii: 8080 ↛ 8081line 8080 didn't jump to line 8081, because the condition on line 8080 was never true

+

8081 text = "".join([chr(b) if 0x20 <= b < 0x7F else "." for b in mem]) 

+

8082 lines.append(fmt_str.format(base=Color.colorify(format_address(cur_addr), base_address_color), 

+

8083 offset=(i + offset) * l, sym=sym, val=val, text=text)) 

+

8084 i += 1 

+

8085 

+

8086 return lines 

+

8087 

+

8088 

+

8089@register 

+

8090class HexdumpQwordCommand(HexdumpCommand): 

+

8091 """Display SIZE lines of hexdump as QWORD from the memory location pointed by ADDRESS.""" 

+

8092 

+

8093 _cmdline_ = "hexdump qword" 

+

8094 _syntax_ = f"{_cmdline_} [ADDRESS] [[L][SIZE]] [REVERSE]" 

+

8095 _example_ = f"{_cmdline_} qword $rsp L16 REVERSE" 

+

8096 

+

8097 def __init__(self) -> None: 

+

8098 super().__init__() 

+

8099 self.format = "qword" 

+

8100 return 

+

8101 

+

8102 

+

8103@register 

+

8104class HexdumpDwordCommand(HexdumpCommand): 

+

8105 """Display SIZE lines of hexdump as DWORD from the memory location pointed by ADDRESS.""" 

+

8106 

+

8107 _cmdline_ = "hexdump dword" 

+

8108 _syntax_ = f"{_cmdline_} [ADDRESS] [[L][SIZE]] [REVERSE]" 

+

8109 _example_ = f"{_cmdline_} $esp L16 REVERSE" 

+

8110 

+

8111 def __init__(self) -> None: 

+

8112 super().__init__() 

+

8113 self.format = "dword" 

+

8114 return 

+

8115 

+

8116 

+

8117@register 

+

8118class HexdumpWordCommand(HexdumpCommand): 

+

8119 """Display SIZE lines of hexdump as WORD from the memory location pointed by ADDRESS.""" 

+

8120 

+

8121 _cmdline_ = "hexdump word" 

+

8122 _syntax_ = f"{_cmdline_} [ADDRESS] [[L][SIZE]] [REVERSE]" 

+

8123 _example_ = f"{_cmdline_} $esp L16 REVERSE" 

+

8124 

+

8125 def __init__(self) -> None: 

+

8126 super().__init__() 

+

8127 self.format = "word" 

+

8128 return 

+

8129 

+

8130 

+

8131@register 

+

8132class HexdumpByteCommand(HexdumpCommand): 

+

8133 """Display SIZE lines of hexdump as BYTE from the memory location pointed by ADDRESS.""" 

+

8134 

+

8135 _cmdline_ = "hexdump byte" 

+

8136 _syntax_ = f"{_cmdline_} [ADDRESS] [[L][SIZE]] [REVERSE]" 

+

8137 _example_ = f"{_cmdline_} $rsp L16" 

+

8138 

+

8139 def __init__(self) -> None: 

+

8140 super().__init__() 

+

8141 self.format = "byte" 

+

8142 return 

+

8143 

+

8144 

+

8145@register 

+

8146class PatchCommand(GenericCommand): 

+

8147 """Write specified values to the specified address.""" 

+

8148 

+

8149 _cmdline_ = "patch" 

+

8150 _syntax_ = (f"{_cmdline_} (qword|dword|word|byte) LOCATION VALUES\n" 

+

8151 f"{_cmdline_} string LOCATION \"double-escaped string\"") 

+

8152 SUPPORTED_SIZES = { 

+

8153 "qword": (8, "Q"), 

+

8154 "dword": (4, "L"), 

+

8155 "word": (2, "H"), 

+

8156 "byte": (1, "B"), 

+

8157 } 

+

8158 

+

8159 def __init__(self) -> None: 

+

8160 super().__init__(prefix=True, complete=gdb.COMPLETE_LOCATION) 

+

8161 self.format: Optional[str] = None 

+

8162 return 

+

8163 

+

8164 @only_if_gdb_running 

+

8165 @parse_arguments({"location": "", "values": ["", ]}, {}) 

+

8166 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

8167 args : argparse.Namespace = kwargs["arguments"] 

+

8168 if not self.format or self.format not in self.SUPPORTED_SIZES: 8168 ↛ 8169line 8168 didn't jump to line 8169, because the condition on line 8168 was never true

+

8169 self.usage() 

+

8170 return 

+

8171 

+

8172 if not args.location or not args.values: 8172 ↛ 8173line 8172 didn't jump to line 8173, because the condition on line 8172 was never true

+

8173 self.usage() 

+

8174 return 

+

8175 

+

8176 addr = align_address(parse_address(args.location)) 

+

8177 size, fcode = self.SUPPORTED_SIZES[self.format] 

+

8178 values = args.values 

+

8179 

+

8180 if size == 1: 

+

8181 if values[0].startswith("$_gef"): 

+

8182 var_name = values[0] 

+

8183 try: 

+

8184 values = str(gdb.parse_and_eval(var_name)).lstrip("{").rstrip("}").replace(",","").split(" ") 

+

8185 except: 

+

8186 gef_print(f"Bad variable specified, check value with command: p {var_name}") 

+

8187 return 

+

8188 

+

8189 d = str(gef.arch.endianness) 

+

8190 for value in values: 

+

8191 value = parse_address(value) & ((1 << size * 8) - 1) 

+

8192 vstr = struct.pack(d + fcode, value) 

+

8193 gef.memory.write(addr, vstr, length=size) 

+

8194 addr += size 

+

8195 return 

+

8196 

+

8197 

+

8198@register 

+

8199class PatchQwordCommand(PatchCommand): 

+

8200 """Write specified QWORD to the specified address.""" 

+

8201 

+

8202 _cmdline_ = "patch qword" 

+

8203 _syntax_ = f"{_cmdline_} LOCATION QWORD1 [QWORD2 [QWORD3..]]" 

+

8204 _example_ = f"{_cmdline_} $rip 0x4141414141414141" 

+

8205 

+

8206 def __init__(self) -> None: 

+

8207 super().__init__() 

+

8208 self.format = "qword" 

+

8209 return 

+

8210 

+

8211 

+

8212@register 

+

8213class PatchDwordCommand(PatchCommand): 

+

8214 """Write specified DWORD to the specified address.""" 

+

8215 

+

8216 _cmdline_ = "patch dword" 

+

8217 _syntax_ = f"{_cmdline_} LOCATION DWORD1 [DWORD2 [DWORD3..]]" 

+

8218 _example_ = f"{_cmdline_} $rip 0x41414141" 

+

8219 

+

8220 def __init__(self) -> None: 

+

8221 super().__init__() 

+

8222 self.format = "dword" 

+

8223 return 

+

8224 

+

8225 

+

8226@register 

+

8227class PatchWordCommand(PatchCommand): 

+

8228 """Write specified WORD to the specified address.""" 

+

8229 

+

8230 _cmdline_ = "patch word" 

+

8231 _syntax_ = f"{_cmdline_} LOCATION WORD1 [WORD2 [WORD3..]]" 

+

8232 _example_ = f"{_cmdline_} $rip 0x4141" 

+

8233 

+

8234 def __init__(self) -> None: 

+

8235 super().__init__() 

+

8236 self.format = "word" 

+

8237 return 

+

8238 

+

8239 

+

8240@register 

+

8241class PatchByteCommand(PatchCommand): 

+

8242 """Write specified BYTE to the specified address.""" 

+

8243 

+

8244 _cmdline_ = "patch byte" 

+

8245 _syntax_ = f"{_cmdline_} LOCATION BYTE1 [BYTE2 [BYTE3..]]" 

+

8246 _example_ = f"{_cmdline_} $pc 0x41 0x41 0x41 0x41 0x41" 

+

8247 

+

8248 def __init__(self) -> None: 

+

8249 super().__init__() 

+

8250 self.format = "byte" 

+

8251 return 

+

8252 

+

8253 

+

8254@register 

+

8255class PatchStringCommand(GenericCommand): 

+

8256 """Write specified string to the specified memory location pointed by ADDRESS.""" 

+

8257 

+

8258 _cmdline_ = "patch string" 

+

8259 _syntax_ = f"{_cmdline_} ADDRESS \"double backslash-escaped string\"" 

+

8260 _example_ = f"{_cmdline_} $sp \"GEFROCKS\"" 

+

8261 

+

8262 @only_if_gdb_running 

+

8263 def do_invoke(self, argv: List[str]) -> None: 

+

8264 argc = len(argv) 

+

8265 if argc != 2: 8265 ↛ 8266line 8265 didn't jump to line 8266, because the condition on line 8265 was never true

+

8266 self.usage() 

+

8267 return 

+

8268 

+

8269 location, s = argv[0:2] 

+

8270 addr = align_address(parse_address(location)) 

+

8271 

+

8272 try: 

+

8273 s = codecs.escape_decode(s)[0] 

+

8274 except binascii.Error: 

+

8275 gef_print(f"Could not decode '\\xXX' encoded string \"{s}\"") 

+

8276 return 

+

8277 

+

8278 gef.memory.write(addr, s, len(s)) 

+

8279 return 

+

8280 

+

8281 

+

8282@lru_cache() 

+

8283def dereference_from(address: int) -> List[str]: 

+

8284 if not is_alive(): 8284 ↛ 8285line 8284 didn't jump to line 8285, because the condition on line 8284 was never true

+

8285 return [format_address(address),] 

+

8286 

+

8287 code_color = gef.config["theme.dereference_code"] 

+

8288 string_color = gef.config["theme.dereference_string"] 

+

8289 max_recursion = gef.config["dereference.max_recursion"] or 10 

+

8290 addr = lookup_address(align_address(address)) 

+

8291 msg = [format_address(addr.value),] 

+

8292 seen_addrs = set() 

+

8293 

+

8294 while addr.section and max_recursion: 

+

8295 if addr.value in seen_addrs: 

+

8296 msg.append("[loop detected]") 

+

8297 break 

+

8298 seen_addrs.add(addr.value) 

+

8299 

+

8300 max_recursion -= 1 

+

8301 

+

8302 # Is this value a pointer or a value? 

+

8303 # -- If it's a pointer, dereference 

+

8304 deref = addr.dereference() 

+

8305 if deref is None: 

+

8306 # if here, dereferencing addr has triggered a MemoryError, no need to go further 

+

8307 msg.append(str(addr)) 

+

8308 break 

+

8309 

+

8310 new_addr = lookup_address(deref) 

+

8311 if new_addr.valid: 

+

8312 addr = new_addr 

+

8313 msg.append(str(addr)) 

+

8314 continue 

+

8315 

+

8316 # -- Otherwise try to parse the value 

+

8317 if addr.section: 8317 ↛ 8338line 8317 didn't jump to line 8338, because the condition on line 8317 was never false

+

8318 if addr.section.is_executable() and addr.is_in_text_segment() and not is_ascii_string(addr.value): 

+

8319 insn = gef_current_instruction(addr.value) 

+

8320 insn_str = f"{insn.location} {insn.mnemonic} {', '.join(insn.operands)}" 

+

8321 msg.append(Color.colorify(insn_str, code_color)) 

+

8322 break 

+

8323 

+

8324 elif addr.section.permission & Permission.READ: 8324 ↛ 8338line 8324 didn't jump to line 8338, because the condition on line 8324 was never false

+

8325 if is_ascii_string(addr.value): 

+

8326 s = gef.memory.read_cstring(addr.value) 

+

8327 if len(s) < gef.arch.ptrsize: 

+

8328 txt = f'{format_address(deref)} ("{Color.colorify(s, string_color)}"?)' 

+

8329 elif len(s) > 50: 

+

8330 txt = Color.colorify(f'"{s[:50]}[...]"', string_color) 

+

8331 else: 

+

8332 txt = Color.colorify(f'"{s}"', string_color) 

+

8333 

+

8334 msg.append(txt) 

+

8335 break 

+

8336 

+

8337 # if not able to parse cleanly, simply display and break 

+

8338 val = "{:#0{ma}x}".format(int(deref & 0xFFFFFFFFFFFFFFFF), ma=(gef.arch.ptrsize * 2 + 2)) 

+

8339 msg.append(val) 

+

8340 break 

+

8341 

+

8342 return msg 

+

8343 

+

8344 

+

8345@register 

+

8346class DereferenceCommand(GenericCommand): 

+

8347 """Dereference recursively from an address and display information. This acts like WinDBG `dps` 

+

8348 command.""" 

+

8349 

+

8350 _cmdline_ = "dereference" 

+

8351 _syntax_ = f"{_cmdline_} [-h] [--length LENGTH] [--reference REFERENCE] [address]" 

+

8352 _aliases_ = ["telescope", ] 

+

8353 _example_ = f"{_cmdline_} --length 20 --reference $sp+0x10 $sp" 

+

8354 

+

8355 def __init__(self) -> None: 

+

8356 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

8357 self["max_recursion"] = (7, "Maximum level of pointer recursion") 

+

8358 return 

+

8359 

+

8360 @staticmethod 

+

8361 def pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) -> str: 

+

8362 base_address_color = gef.config["theme.dereference_base_address"] 

+

8363 registers_color = gef.config["theme.dereference_register_value"] 

+

8364 

+

8365 sep = f" {RIGHT_ARROW} " 

+

8366 memalign = gef.arch.ptrsize 

+

8367 

+

8368 offset = idx * memalign 

+

8369 current_address = align_address(addr + offset) 

+

8370 addrs = dereference_from(current_address) 

+

8371 l = "" 

+

8372 addr_l = format_address(int(addrs[0], 16)) 

+

8373 l += "{}{}{:+#07x}: {:{ma}s}".format(Color.colorify(addr_l, base_address_color), 

+

8374 VERTICAL_LINE, base_offset+offset, 

+

8375 sep.join(addrs[1:]), ma=(memalign*2 + 2)) 

+

8376 

+

8377 register_hints = [] 

+

8378 

+

8379 for regname in gef.arch.all_registers: 

+

8380 regvalue = gef.arch.register(regname) 

+

8381 if current_address == regvalue: 

+

8382 register_hints.append(regname) 

+

8383 

+

8384 if register_hints: 

+

8385 m = f"\t{LEFT_ARROW}{', '.join(list(register_hints))}" 

+

8386 l += Color.colorify(m, registers_color) 

+

8387 

+

8388 offset += memalign 

+

8389 return l 

+

8390 

+

8391 @only_if_gdb_running 

+

8392 @parse_arguments({"address": "$sp"}, {("-r", "--reference"): "", ("-l", "--length"): 10}) 

+

8393 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

8394 args : argparse.Namespace = kwargs["arguments"] 

+

8395 nb = args.length 

+

8396 

+

8397 target = args.address 

+

8398 target_addr = parse_address(target) 

+

8399 

+

8400 reference = args.reference or target 

+

8401 ref_addr = parse_address(reference) 

+

8402 

+

8403 if process_lookup_address(target_addr) is None: 

+

8404 err(f"Unmapped address: '{target}'") 

+

8405 return 

+

8406 

+

8407 if process_lookup_address(ref_addr) is None: 8407 ↛ 8408line 8407 didn't jump to line 8408, because the condition on line 8407 was never true

+

8408 err(f"Unmapped address: '{reference}'") 

+

8409 return 

+

8410 

+

8411 if gef.config["context.grow_stack_down"] is True: 8411 ↛ 8412line 8411 didn't jump to line 8412, because the condition on line 8411 was never true

+

8412 insnum_step = -1 

+

8413 if nb > 0: 

+

8414 from_insnum = nb * (self.repeat_count + 1) - 1 

+

8415 to_insnum = self.repeat_count * nb - 1 

+

8416 else: 

+

8417 from_insnum = self.repeat_count * nb 

+

8418 to_insnum = nb * (self.repeat_count + 1) 

+

8419 else: 

+

8420 insnum_step = 1 

+

8421 if nb > 0: 

+

8422 from_insnum = self.repeat_count * nb 

+

8423 to_insnum = nb * (self.repeat_count + 1) 

+

8424 else: 

+

8425 from_insnum = nb * (self.repeat_count + 1) + 1 

+

8426 to_insnum = (self.repeat_count * nb) + 1 

+

8427 

+

8428 start_address = align_address(target_addr) 

+

8429 base_offset = start_address - align_address(ref_addr) 

+

8430 

+

8431 for i in range(from_insnum, to_insnum, insnum_step): 

+

8432 gef_print(DereferenceCommand.pprint_dereferenced(start_address, i, base_offset)) 

+

8433 

+

8434 return 

+

8435 

+

8436 

+

8437@register 

+

8438class ASLRCommand(GenericCommand): 

+

8439 """View/modify the ASLR setting of GDB. By default, GDB will disable ASLR when it starts the process. (i.e. not 

+

8440 attached). This command allows to change that setting.""" 

+

8441 

+

8442 _cmdline_ = "aslr" 

+

8443 _syntax_ = f"{_cmdline_} [(on|off)]" 

+

8444 

+

8445 def do_invoke(self, argv: List[str]) -> None: 

+

8446 argc = len(argv) 

+

8447 

+

8448 if argc == 0: 

+

8449 ret = gdb.execute("show disable-randomization", to_string=True) or "" 

+

8450 i = ret.find("virtual address space is ") 

+

8451 if i < 0: 8451 ↛ 8452line 8451 didn't jump to line 8452, because the condition on line 8451 was never true

+

8452 return 

+

8453 

+

8454 msg = "ASLR is currently " 

+

8455 if ret[i + 25:].strip() == "on.": 

+

8456 msg += Color.redify("disabled") 

+

8457 else: 

+

8458 msg += Color.greenify("enabled") 

+

8459 

+

8460 gef_print(msg) 

+

8461 return 

+

8462 

+

8463 elif argc == 1: 8463 ↛ 8475line 8463 didn't jump to line 8475, because the condition on line 8463 was never false

+

8464 if argv[0] == "on": 8464 ↛ 8468line 8464 didn't jump to line 8468, because the condition on line 8464 was never false

+

8465 info("Enabling ASLR") 

+

8466 gdb.execute("set disable-randomization off") 

+

8467 return 

+

8468 elif argv[0] == "off": 

+

8469 info("Disabling ASLR") 

+

8470 gdb.execute("set disable-randomization on") 

+

8471 return 

+

8472 

+

8473 warn("Invalid command") 

+

8474 

+

8475 self.usage() 

+

8476 return 

+

8477 

+

8478 

+

8479@register 

+

8480class ResetCacheCommand(GenericCommand): 

+

8481 """Reset cache of all stored data. This command is here for debugging and test purposes, GEF 

+

8482 handles properly the cache reset under "normal" scenario.""" 

+

8483 

+

8484 _cmdline_ = "reset-cache" 

+

8485 _syntax_ = _cmdline_ 

+

8486 

+

8487 def do_invoke(self, _: List[str]) -> None: 

+

8488 reset_all_caches() 

+

8489 return 

+

8490 

+

8491 

+

8492@register 

+

8493class VMMapCommand(GenericCommand): 

+

8494 """Display a comprehensive layout of the virtual memory mapping. If a filter argument, GEF will 

+

8495 filter out the mapping whose pathname do not match that filter.""" 

+

8496 

+

8497 _cmdline_ = "vmmap" 

+

8498 _syntax_ = f"{_cmdline_} [FILTER]" 

+

8499 _example_ = f"{_cmdline_} libc" 

+

8500 

+

8501 @only_if_gdb_running 

+

8502 def do_invoke(self, argv: List[str]) -> None: 

+

8503 vmmap = gef.memory.maps 

+

8504 if not vmmap: 8504 ↛ 8505line 8504 didn't jump to line 8505, because the condition on line 8504 was never true

+

8505 err("No address mapping information found") 

+

8506 return 

+

8507 

+

8508 if not gef.config["gef.disable_color"]: 8508 ↛ 8511line 8508 didn't jump to line 8511, because the condition on line 8508 was never false

+

8509 self.show_legend() 

+

8510 

+

8511 color = gef.config["theme.table_heading"] 

+

8512 

+

8513 headers = ["Start", "End", "Offset", "Perm", "Path"] 

+

8514 gef_print(Color.colorify("{:<{w}s}{:<{w}s}{:<{w}s}{:<4s} {:s}".format(*headers, w=gef.arch.ptrsize*2+3), color)) 

+

8515 

+

8516 for entry in vmmap: 

+

8517 if not argv: 

+

8518 self.print_entry(entry) 

+

8519 continue 

+

8520 if argv[0] in entry.path: 

+

8521 self.print_entry(entry) 

+

8522 elif self.is_integer(argv[0]): 8522 ↛ 8523line 8522 didn't jump to line 8523, because the condition on line 8522 was never true

+

8523 addr = int(argv[0], 0) 

+

8524 if addr >= entry.page_start and addr < entry.page_end: 

+

8525 self.print_entry(entry) 

+

8526 return 

+

8527 

+

8528 def print_entry(self, entry: Section) -> None: 

+

8529 line_color = "" 

+

8530 if entry.path == "[stack]": 

+

8531 line_color = gef.config["theme.address_stack"] 

+

8532 elif entry.path == "[heap]": 8532 ↛ 8533line 8532 didn't jump to line 8533, because the condition on line 8532 was never true

+

8533 line_color = gef.config["theme.address_heap"] 

+

8534 elif entry.permission & Permission.READ and entry.permission & Permission.EXECUTE: 

+

8535 line_color = gef.config["theme.address_code"] 

+

8536 

+

8537 l = [ 

+

8538 Color.colorify(format_address(entry.page_start), line_color), 

+

8539 Color.colorify(format_address(entry.page_end), line_color), 

+

8540 Color.colorify(format_address(entry.offset), line_color), 

+

8541 ] 

+

8542 if entry.permission == Permission.ALL: 8542 ↛ 8543line 8542 didn't jump to line 8543, because the condition on line 8542 was never true

+

8543 l.append(Color.colorify(str(entry.permission), "underline " + line_color)) 

+

8544 else: 

+

8545 l.append(Color.colorify(str(entry.permission), line_color)) 

+

8546 

+

8547 l.append(Color.colorify(entry.path, line_color)) 

+

8548 line = " ".join(l) 

+

8549 

+

8550 gef_print(line) 

+

8551 return 

+

8552 

+

8553 def show_legend(self) -> None: 

+

8554 code_addr_color = gef.config["theme.address_code"] 

+

8555 stack_addr_color = gef.config["theme.address_stack"] 

+

8556 heap_addr_color = gef.config["theme.address_heap"] 

+

8557 

+

8558 gef_print("[ Legend: {} | {} | {} ]".format(Color.colorify("Code", code_addr_color), 

+

8559 Color.colorify("Heap", heap_addr_color), 

+

8560 Color.colorify("Stack", stack_addr_color) 

+

8561 )) 

+

8562 return 

+

8563 

+

8564 def is_integer(self, n: str) -> bool: 

+

8565 try: 

+

8566 int(n, 0) 

+

8567 except ValueError: 

+

8568 return False 

+

8569 return True 

+

8570 

+

8571 

+

8572@register 

+

8573class XFilesCommand(GenericCommand): 

+

8574 """Shows all libraries (and sections) loaded by binary. This command extends the GDB command 

+

8575 `info files`, by retrieving more information from extra sources, and providing a better 

+

8576 display. If an argument FILE is given, the output will grep information related to only that file. 

+

8577 If an argument name is also given, the output will grep to the name within FILE.""" 

+

8578 

+

8579 _cmdline_ = "xfiles" 

+

8580 _syntax_ = f"{_cmdline_} [FILE [NAME]]" 

+

8581 _example_ = f"\n{_cmdline_} libc\n{_cmdline_} libc IO_vtables" 

+

8582 

+

8583 @only_if_gdb_running 

+

8584 def do_invoke(self, argv: List[str]) -> None: 

+

8585 color = gef.config["theme.table_heading"] 

+

8586 headers = ["Start", "End", "Name", "File"] 

+

8587 gef_print(Color.colorify("{:<{w}s}{:<{w}s}{:<21s} {:s}".format(*headers, w=gef.arch.ptrsize*2+3), color)) 

+

8588 

+

8589 filter_by_file = argv[0] if argv and argv[0] else None 

+

8590 filter_by_name = argv[1] if len(argv) > 1 and argv[1] else None 

+

8591 

+

8592 for xfile in get_info_files(): 

+

8593 if filter_by_file: 8593 ↛ 8594line 8593 didn't jump to line 8594, because the condition on line 8593 was never true

+

8594 if filter_by_file not in xfile.filename: 

+

8595 continue 

+

8596 if filter_by_name and filter_by_name not in xfile.name: 

+

8597 continue 

+

8598 

+

8599 l = [ 

+

8600 format_address(xfile.zone_start), 

+

8601 format_address(xfile.zone_end), 

+

8602 f"{xfile.name:<21s}", 

+

8603 xfile.filename, 

+

8604 ] 

+

8605 gef_print(" ".join(l)) 

+

8606 return 

+

8607 

+

8608 

+

8609@register 

+

8610class XAddressInfoCommand(GenericCommand): 

+

8611 """Retrieve and display runtime information for the location(s) given as parameter.""" 

+

8612 

+

8613 _cmdline_ = "xinfo" 

+

8614 _syntax_ = f"{_cmdline_} LOCATION" 

+

8615 _example_ = f"{_cmdline_} $pc" 

+

8616 

+

8617 def __init__(self) -> None: 

+

8618 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

8619 return 

+

8620 

+

8621 @only_if_gdb_running 

+

8622 def do_invoke(self, argv: List[str]) -> None: 

+

8623 if not argv: 

+

8624 err("At least one valid address must be specified") 

+

8625 self.usage() 

+

8626 return 

+

8627 

+

8628 for sym in argv: 

+

8629 try: 

+

8630 addr = align_address(parse_address(sym)) 

+

8631 gef_print(titlify(f"xinfo: {addr:#x}")) 

+

8632 self.infos(addr) 

+

8633 

+

8634 except gdb.error as gdb_err: 

+

8635 err(f"{gdb_err}") 

+

8636 return 

+

8637 

+

8638 def infos(self, address: int) -> None: 

+

8639 addr = lookup_address(address) 

+

8640 if not addr.valid: 8640 ↛ 8641line 8640 didn't jump to line 8641, because the condition on line 8640 was never true

+

8641 warn(f"Cannot reach {address:#x} in memory space") 

+

8642 return 

+

8643 

+

8644 sect = addr.section 

+

8645 info = addr.info 

+

8646 

+

8647 if sect: 8647 ↛ 8655line 8647 didn't jump to line 8655, because the condition on line 8647 was never false

+

8648 gef_print(f"Page: {format_address(sect.page_start)} {RIGHT_ARROW} " 

+

8649 f"{format_address(sect.page_end)} (size={sect.page_end-sect.page_start:#x})" 

+

8650 f"\nPermissions: {sect.permission}" 

+

8651 f"\nPathname: {sect.path}" 

+

8652 f"\nOffset (from page): {addr.value-sect.page_start:#x}" 

+

8653 f"\nInode: {sect.inode}") 

+

8654 

+

8655 if info: 8655 ↛ 8656line 8655 didn't jump to line 8656, because the condition on line 8655 was never true

+

8656 gef_print(f"Segment: {info.name} " 

+

8657 f"({format_address(info.zone_start)}-{format_address(info.zone_end)})" 

+

8658 f"\nOffset (from segment): {addr.value-info.zone_start:#x}") 

+

8659 

+

8660 sym = gdb_get_location_from_symbol(address) 

+

8661 if sym: 8661 ↛ 8662line 8661 didn't jump to line 8662, because the condition on line 8661 was never true

+

8662 name, offset = sym 

+

8663 msg = f"Symbol: {name}" 

+

8664 if offset: 

+

8665 msg += f"+{offset:d}" 

+

8666 gef_print(msg) 

+

8667 

+

8668 return 

+

8669 

+

8670 

+

8671@register 

+

8672class XorMemoryCommand(GenericCommand): 

+

8673 """XOR a block of memory. The command allows to simply display the result, or patch it 

+

8674 runtime at runtime.""" 

+

8675 

+

8676 _cmdline_ = "xor-memory" 

+

8677 _syntax_ = f"{_cmdline_} (display|patch) ADDRESS SIZE KEY" 

+

8678 

+

8679 def __init__(self) -> None: 

+

8680 super().__init__(prefix=True) 

+

8681 return 

+

8682 

+

8683 def do_invoke(self, _: List[str]) -> None: 

+

8684 self.usage() 

+

8685 return 

+

8686 

+

8687 

+

8688@register 

+

8689class XorMemoryDisplayCommand(GenericCommand): 

+

8690 """Display a block of memory pointed by ADDRESS by xor-ing each byte with KEY. The key must be 

+

8691 provided in hexadecimal format.""" 

+

8692 

+

8693 _cmdline_ = "xor-memory display" 

+

8694 _syntax_ = f"{_cmdline_} ADDRESS SIZE KEY" 

+

8695 _example_ = f"{_cmdline_} $sp 16 41414141" 

+

8696 

+

8697 @only_if_gdb_running 

+

8698 def do_invoke(self, argv: List[str]) -> None: 

+

8699 if len(argv) != 3: 8699 ↛ 8700line 8699 didn't jump to line 8700, because the condition on line 8699 was never true

+

8700 self.usage() 

+

8701 return 

+

8702 

+

8703 address = parse_address(argv[0]) 

+

8704 length = int(argv[1], 0) 

+

8705 key = argv[2] 

+

8706 block = gef.memory.read(address, length) 

+

8707 info(f"Displaying XOR-ing {address:#x}-{address + len(block):#x} with {key!r}") 

+

8708 

+

8709 gef_print(titlify("Original block")) 

+

8710 gef_print(hexdump(block, base=address)) 

+

8711 

+

8712 gef_print(titlify("XOR-ed block")) 

+

8713 gef_print(hexdump(xor(block, key), base=address)) 

+

8714 return 

+

8715 

+

8716 

+

8717@register 

+

8718class XorMemoryPatchCommand(GenericCommand): 

+

8719 """Patch a block of memory pointed by ADDRESS by xor-ing each byte with KEY. The key must be 

+

8720 provided in hexadecimal format.""" 

+

8721 

+

8722 _cmdline_ = "xor-memory patch" 

+

8723 _syntax_ = f"{_cmdline_} ADDRESS SIZE KEY" 

+

8724 _example_ = f"{_cmdline_} $sp 16 41414141" 

+

8725 

+

8726 @only_if_gdb_running 

+

8727 def do_invoke(self, argv: List[str]) -> None: 

+

8728 if len(argv) != 3: 8728 ↛ 8729line 8728 didn't jump to line 8729, because the condition on line 8728 was never true

+

8729 self.usage() 

+

8730 return 

+

8731 

+

8732 address = parse_address(argv[0]) 

+

8733 length = int(argv[1], 0) 

+

8734 key = argv[2] 

+

8735 block = gef.memory.read(address, length) 

+

8736 info(f"Patching XOR-ing {address:#x}-{address + len(block):#x} with {key!r}") 

+

8737 xored_block = xor(block, key) 

+

8738 gef.memory.write(address, xored_block, length) 

+

8739 return 

+

8740 

+

8741 

+

8742@register 

+

8743class TraceRunCommand(GenericCommand): 

+

8744 """Create a runtime trace of all instructions executed from $pc to LOCATION specified. The 

+

8745 trace is stored in a text file that can be next imported in IDA Pro to visualize the runtime 

+

8746 path.""" 

+

8747 

+

8748 _cmdline_ = "trace-run" 

+

8749 _syntax_ = f"{_cmdline_} LOCATION [MAX_CALL_DEPTH]" 

+

8750 _example_ = f"{_cmdline_} 0x555555554610" 

+

8751 

+

8752 def __init__(self) -> None: 

+

8753 super().__init__(self._cmdline_, complete=gdb.COMPLETE_LOCATION) 

+

8754 self["max_tracing_recursion"] = (1, "Maximum depth of tracing") 

+

8755 self["tracefile_prefix"] = ("./gef-trace-", "Specify the tracing output file prefix") 

+

8756 return 

+

8757 

+

8758 @only_if_gdb_running 

+

8759 def do_invoke(self, argv: List[str]) -> None: 

+

8760 if len(argv) not in (1, 2): 8760 ↛ 8761line 8760 didn't jump to line 8761, because the condition on line 8760 was never true

+

8761 self.usage() 

+

8762 return 

+

8763 

+

8764 if len(argv) == 2 and argv[1].isdigit(): 8764 ↛ 8765line 8764 didn't jump to line 8765, because the condition on line 8764 was never true

+

8765 depth = int(argv[1]) 

+

8766 else: 

+

8767 depth = 1 

+

8768 

+

8769 try: 

+

8770 loc_start = gef.arch.pc 

+

8771 loc_end = parse_address(argv[0]) 

+

8772 except gdb.error as e: 

+

8773 err(f"Invalid location: {e}") 

+

8774 return 

+

8775 

+

8776 self.trace(loc_start, loc_end, depth) 

+

8777 return 

+

8778 

+

8779 def get_frames_size(self) -> int: 

+

8780 n = 0 

+

8781 f = gdb.newest_frame() 

+

8782 while f: 

+

8783 n += 1 

+

8784 f = f.older() 

+

8785 return n 

+

8786 

+

8787 def trace(self, loc_start: int, loc_end: int, depth: int) -> None: 

+

8788 info(f"Tracing from {loc_start:#x} to {loc_end:#x} (max depth={depth:d})") 

+

8789 logfile = f"{self['tracefile_prefix']}{loc_start:#x}-{loc_end:#x}.txt" 

+

8790 with RedirectOutputContext(to=logfile): 

+

8791 hide_context() 

+

8792 self.start_tracing(loc_start, loc_end, depth) 

+

8793 unhide_context() 

+

8794 ok(f"Done, logfile stored as '{logfile}'") 

+

8795 info("Hint: import logfile with `ida_color_gdb_trace.py` script in IDA to visualize path") 

+

8796 return 

+

8797 

+

8798 def start_tracing(self, loc_start: int, loc_end: int, depth: int) -> None: 

+

8799 loc_cur = loc_start 

+

8800 frame_count_init = self.get_frames_size() 

+

8801 

+

8802 gef_print("#", 

+

8803 f"# Execution tracing of {get_filepath()}", 

+

8804 f"# Start address: {format_address(loc_start)}", 

+

8805 f"# End address: {format_address(loc_end)}", 

+

8806 f"# Recursion level: {depth:d}", 

+

8807 "# automatically generated by gef.py", 

+

8808 "#\n", sep="\n") 

+

8809 

+

8810 while loc_cur != loc_end: 8810 ↛ 8829line 8810 didn't jump to line 8829, because the condition on line 8810 was never false

+

8811 try: 

+

8812 delta = self.get_frames_size() - frame_count_init 

+

8813 

+

8814 if delta <= depth: 

+

8815 gdb.execute("stepi") 

+

8816 else: 

+

8817 gdb.execute("finish") 

+

8818 

+

8819 loc_cur = gef.arch.pc 

+

8820 gdb.flush() 

+

8821 

+

8822 except gdb.error as e: 

+

8823 gef_print("#", 

+

8824 f"# Execution interrupted at address {format_address(loc_cur)}", 

+

8825 f"# Exception: {e}", 

+

8826 "#\n", sep="\n") 

+

8827 break 

+

8828 

+

8829 return 

+

8830 

+

8831 

+

8832@register 

+

8833class PatternCommand(GenericCommand): 

+

8834 """Generate or Search a De Bruijn Sequence of unique substrings of length N 

+

8835 and a total length of LENGTH. The default value of N is set to match the 

+

8836 currently loaded architecture.""" 

+

8837 

+

8838 _cmdline_ = "pattern" 

+

8839 _syntax_ = f"{_cmdline_} (create|search) ARGS" 

+

8840 

+

8841 def __init__(self) -> None: 

+

8842 super().__init__(prefix=True) 

+

8843 self["length"] = (1024, "Default length of a cyclic buffer to generate") 

+

8844 return 

+

8845 

+

8846 def do_invoke(self, _: List[str]) -> None: 

+

8847 self.usage() 

+

8848 return 

+

8849 

+

8850 

+

8851@register 

+

8852class PatternCreateCommand(GenericCommand): 

+

8853 """Generate a De Bruijn Sequence of unique substrings of length N and a 

+

8854 total length of LENGTH. The default value of N is set to match the currently 

+

8855 loaded architecture.""" 

+

8856 

+

8857 _cmdline_ = "pattern create" 

+

8858 _syntax_ = f"{_cmdline_} [-h] [-n N] [length]" 

+

8859 _example_ = f"{_cmdline_} 4096" 

+

8860 

+

8861 @parse_arguments({"length": 0}, {("-n", "--n"): 0}) 

+

8862 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

8863 args : argparse.Namespace = kwargs["arguments"] 

+

8864 length = args.length or gef.config["pattern.length"] 

+

8865 n = args.n or gef.arch.ptrsize 

+

8866 info(f"Generating a pattern of {length:d} bytes (n={n:d})") 

+

8867 pattern_str = gef_pystring(generate_cyclic_pattern(length, n)) 

+

8868 gef_print(pattern_str) 

+

8869 ok(f"Saved as '{gef_convenience(pattern_str)}'") 

+

8870 return 

+

8871 

+

8872 

+

8873@register 

+

8874class PatternSearchCommand(GenericCommand): 

+

8875 """Search a De Bruijn Sequence of unique substrings of length N and a 

+

8876 maximum total length of MAX_LENGTH. The default value of N is set to match 

+

8877 the currently loaded architecture. The PATTERN argument can be a GDB symbol 

+

8878 (such as a register name), a string or a hexadecimal value""" 

+

8879 

+

8880 _cmdline_ = "pattern search" 

+

8881 _syntax_ = f"{_cmdline_} [-h] [-n N] [--max-length MAX_LENGTH] [pattern]" 

+

8882 _example_ = [f"{_cmdline_} $pc", 

+

8883 f"{_cmdline_} 0x61616164", 

+

8884 f"{_cmdline_} aaab"] 

+

8885 _aliases_ = ["pattern offset"] 

+

8886 

+

8887 @only_if_gdb_running 

+

8888 @parse_arguments({"pattern": ""}, {("--period", "-n"): 0, ("--max-length", "-l"): 0}) 

+

8889 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

8890 args = kwargs["arguments"] 

+

8891 if not args.pattern: 8891 ↛ 8892line 8891 didn't jump to line 8892, because the condition on line 8891 was never true

+

8892 warn("No pattern provided") 

+

8893 return 

+

8894 

+

8895 max_length = args.max_length or gef.config["pattern.length"] 

+

8896 n = args.period or gef.arch.ptrsize 

+

8897 if n not in (2, 4, 8) or n > gef.arch.ptrsize: 8897 ↛ 8898line 8897 didn't jump to line 8898, because the condition on line 8897 was never true

+

8898 err("Incorrect value for period") 

+

8899 return 

+

8900 self.search(args.pattern, max_length, n) 

+

8901 return 

+

8902 

+

8903 def search(self, pattern: str, size: int, period: int) -> None: 

+

8904 pattern_be, pattern_le = None, None 

+

8905 

+

8906 # 1. check if it's a symbol (like "$sp" or "0x1337") 

+

8907 symbol = safe_parse_and_eval(pattern) 

+

8908 if symbol: 

+

8909 addr = int(abs(symbol)) 

+

8910 dereferenced_value = dereference(addr) 

+

8911 if dereferenced_value: 8911 ↛ 8912line 8911 didn't jump to line 8912, because the condition on line 8911 was never true

+

8912 addr = int(abs(dereferenced_value)) 

+

8913 mask = (1<<(8 * period))-1 

+

8914 addr &= mask 

+

8915 pattern_le = addr.to_bytes(period, 'little') 

+

8916 pattern_be = addr.to_bytes(period, 'big') 

+

8917 else: 

+

8918 # 2. assume it's a plain string 

+

8919 pattern_be = gef_pybytes(pattern) 

+

8920 pattern_le = gef_pybytes(pattern[::-1]) 

+

8921 

+

8922 info(f"Searching for '{pattern_le.hex()}'/'{pattern_be.hex()}' with period={period}") 

+

8923 cyclic_pattern = generate_cyclic_pattern(size, period) 

+

8924 off = cyclic_pattern.find(pattern_le) 

+

8925 if off >= 0: 

+

8926 ok(f"Found at offset {off:d} (little-endian search) " 

+

8927 f"{Color.colorify('likely', 'bold red') if gef.arch.endianness == Endianness.LITTLE_ENDIAN else ''}") 

+

8928 return 

+

8929 

+

8930 off = cyclic_pattern.find(pattern_be) 

+

8931 if off >= 0: 8931 ↛ 8932line 8931 didn't jump to line 8932, because the condition on line 8931 was never true

+

8932 ok(f"Found at offset {off:d} (big-endian search) " 

+

8933 f"{Color.colorify('likely', 'bold green') if gef.arch.endianness == Endianness.BIG_ENDIAN else ''}") 

+

8934 return 

+

8935 

+

8936 err(f"Pattern '{pattern}' not found") 

+

8937 return 

+

8938 

+

8939 

+

8940@register 

+

8941class ChecksecCommand(GenericCommand): 

+

8942 """Checksec the security properties of the current executable or passed as argument. The 

+

8943 command checks for the following protections: 

+

8944 - PIE 

+

8945 - NX 

+

8946 - RelRO 

+

8947 - Glibc Stack Canaries 

+

8948 - Fortify Source""" 

+

8949 

+

8950 _cmdline_ = "checksec" 

+

8951 _syntax_ = f"{_cmdline_} [FILENAME]" 

+

8952 _example_ = f"{_cmdline_} /bin/ls" 

+

8953 

+

8954 def __init__(self) -> None: 

+

8955 super().__init__(complete=gdb.COMPLETE_FILENAME) 

+

8956 return 

+

8957 

+

8958 def do_invoke(self, argv: List[str]) -> None: 

+

8959 argc = len(argv) 

+

8960 

+

8961 if argc == 0: 8961 ↛ 8966line 8961 didn't jump to line 8966, because the condition on line 8961 was never false

+

8962 filename = get_filepath() 

+

8963 if filename is None: 8963 ↛ 8964line 8963 didn't jump to line 8964, because the condition on line 8963 was never true

+

8964 warn("No executable/library specified") 

+

8965 return 

+

8966 elif argc == 1: 

+

8967 filename = os.path.realpath(os.path.expanduser(argv[0])) 

+

8968 if not os.access(filename, os.R_OK): 

+

8969 err("Invalid filename") 

+

8970 return 

+

8971 else: 

+

8972 self.usage() 

+

8973 return 

+

8974 

+

8975 info(f"{self._cmdline_} for '{filename}'") 

+

8976 self.print_security_properties(filename) 

+

8977 return 

+

8978 

+

8979 def print_security_properties(self, filename: str) -> None: 

+

8980 sec = Elf(filename).checksec 

+

8981 for prop in sec: 

+

8982 if prop in ("Partial RelRO", "Full RelRO"): continue 

+

8983 val = sec[prop] 

+

8984 msg = Color.greenify(Color.boldify(TICK)) if val is True else Color.redify(Color.boldify(CROSS)) 

+

8985 if val and prop == "Canary" and is_alive(): 8985 ↛ 8986line 8985 didn't jump to line 8986, because the condition on line 8985 was never true

+

8986 canary = gef.session.canary[0] if gef.session.canary else 0 

+

8987 msg += f"(value: {canary:#x})" 

+

8988 

+

8989 gef_print(f"{prop:<30s}: {msg}") 

+

8990 

+

8991 if sec["Full RelRO"]: 

+

8992 gef_print(f"{'RelRO':<30s}: {Color.greenify('Full')}") 

+

8993 elif sec["Partial RelRO"]: 8993 ↛ 8996line 8993 didn't jump to line 8996, because the condition on line 8993 was never false

+

8994 gef_print(f"{'RelRO':<30s}: {Color.yellowify('Partial')}") 

+

8995 else: 

+

8996 gef_print(f"{'RelRO':<30s}: {Color.redify(Color.boldify(CROSS))}") 

+

8997 return 

+

8998 

+

8999 

+

9000@register 

+

9001class GotCommand(GenericCommand): 

+

9002 """Display current status of the got inside the process.""" 

+

9003 

+

9004 _cmdline_ = "got" 

+

9005 _syntax_ = f"{_cmdline_} [FUNCTION_NAME ...] " 

+

9006 _example_ = "got read printf exit" 

+

9007 

+

9008 def __init__(self): 

+

9009 super().__init__() 

+

9010 self["function_resolved"] = ("green", 

+

9011 "Line color of the got command output for resolved function") 

+

9012 self["function_not_resolved"] = ("yellow", 

+

9013 "Line color of the got command output for unresolved function") 

+

9014 return 

+

9015 

+

9016 @only_if_gdb_running 

+

9017 def do_invoke(self, argv: List[str]) -> None: 

+

9018 readelf = gef.session.constants["readelf"] 

+

9019 

+

9020 if is_remote_debug(): 9020 ↛ 9021line 9020 didn't jump to line 9021, because the condition on line 9020 was never true

+

9021 elf_file = str(gef.session.remote.lfile) 

+

9022 elf_virtual_path = str(gef.session.remote.file) 

+

9023 else: 

+

9024 elf_file = str(gef.session.file) 

+

9025 elf_virtual_path = str(gef.session.file) 

+

9026 

+

9027 func_names_filter = argv if argv else [] 

+

9028 vmmap = gef.memory.maps 

+

9029 base_address = min(x.page_start for x in vmmap if x.path == elf_virtual_path) 

+

9030 end_address = max(x.page_end for x in vmmap if x.path == elf_virtual_path) 

+

9031 

+

9032 # get the checksec output. 

+

9033 checksec_status = Elf(elf_file).checksec 

+

9034 relro_status = "Full RelRO" 

+

9035 full_relro = checksec_status["Full RelRO"] 

+

9036 pie = checksec_status["PIE"] # if pie we will have offset instead of abs address. 

+

9037 

+

9038 if not full_relro: 9038 ↛ 9039line 9038 didn't jump to line 9039, because the condition on line 9038 was never true

+

9039 relro_status = "Partial RelRO" 

+

9040 partial_relro = checksec_status["Partial RelRO"] 

+

9041 

+

9042 if not partial_relro: 

+

9043 relro_status = "No RelRO" 

+

9044 

+

9045 # retrieve jump slots using readelf 

+

9046 lines = gef_execute_external([readelf, "--relocs", elf_file], as_list=True) 

+

9047 jmpslots = [line for line in lines if "JUMP" in line] 

+

9048 

+

9049 gef_print(f"\nGOT protection: {relro_status} | GOT functions: {len(jmpslots)}\n ") 

+

9050 

+

9051 for line in jmpslots: 

+

9052 address, _, _, _, name = line.split()[:5] 

+

9053 

+

9054 # if we have a filter let's skip the entries that are not requested. 

+

9055 if func_names_filter: 

+

9056 if not any(map(lambda x: x in name, func_names_filter)): 

+

9057 continue 

+

9058 

+

9059 address_val = int(address, 16) 

+

9060 

+

9061 # address_val is an offset from the base_address if we have PIE. 

+

9062 if pie or is_remote_debug(): 9062 ↛ 9066line 9062 didn't jump to line 9066, because the condition on line 9062 was never false

+

9063 address_val = base_address + address_val 

+

9064 

+

9065 # read the address of the function. 

+

9066 got_address = gef.memory.read_integer(address_val) 

+

9067 

+

9068 # for the swag: different colors if the function has been resolved or not. 

+

9069 if base_address < got_address < end_address: 9069 ↛ 9070line 9069 didn't jump to line 9070, because the condition on line 9069 was never true

+

9070 color = self["function_not_resolved"] 

+

9071 else: 

+

9072 color = self["function_resolved"] 

+

9073 

+

9074 line = f"[{hex(address_val)}] " 

+

9075 line += Color.colorify(f"{name} {RIGHT_ARROW} {hex(got_address)}", color) 

+

9076 gef_print(line) 

+

9077 return 

+

9078 

+

9079 

+

9080@register 

+

9081class HighlightCommand(GenericCommand): 

+

9082 """Highlight user-defined text matches in GEF output universally.""" 

+

9083 _cmdline_ = "highlight" 

+

9084 _syntax_ = f"{_cmdline_} (add|remove|list|clear)" 

+

9085 _aliases_ = ["hl"] 

+

9086 

+

9087 def __init__(self) -> None: 

+

9088 super().__init__(prefix=True) 

+

9089 self["regex"] = (False, "Enable regex highlighting") 

+

9090 

+

9091 def do_invoke(self, _: List[str]) -> None: 

+

9092 return self.usage() 

+

9093 

+

9094 

+

9095@register 

+

9096class HighlightListCommand(GenericCommand): 

+

9097 """Show the current highlight table with matches to colors.""" 

+

9098 _cmdline_ = "highlight list" 

+

9099 _aliases_ = ["highlight ls", "hll"] 

+

9100 _syntax_ = _cmdline_ 

+

9101 

+

9102 def print_highlight_table(self) -> None: 

+

9103 if not gef.ui.highlight_table: 

+

9104 err("no matches found") 

+

9105 return 

+

9106 

+

9107 left_pad = max(map(len, gef.ui.highlight_table.keys())) 

+

9108 for match, color in sorted(gef.ui.highlight_table.items()): 

+

9109 print(f"{Color.colorify(match.ljust(left_pad), color)} {VERTICAL_LINE} " 

+

9110 f"{Color.colorify(color, color)}") 

+

9111 return 

+

9112 

+

9113 def do_invoke(self, _: List[str]) -> None: 

+

9114 return self.print_highlight_table() 

+

9115 

+

9116 

+

9117@register 

+

9118class HighlightClearCommand(GenericCommand): 

+

9119 """Clear the highlight table, remove all matches.""" 

+

9120 _cmdline_ = "highlight clear" 

+

9121 _aliases_ = ["hlc"] 

+

9122 _syntax_ = _cmdline_ 

+

9123 

+

9124 def do_invoke(self, _: List[str]) -> None: 

+

9125 return gef.ui.highlight_table.clear() 

+

9126 

+

9127 

+

9128@register 

+

9129class HighlightAddCommand(GenericCommand): 

+

9130 """Add a match to the highlight table.""" 

+

9131 _cmdline_ = "highlight add" 

+

9132 _syntax_ = f"{_cmdline_} MATCH COLOR" 

+

9133 _aliases_ = ["highlight set", "hla"] 

+

9134 _example_ = f"{_cmdline_} 41414141 yellow" 

+

9135 

+

9136 def do_invoke(self, argv: List[str]) -> None: 

+

9137 if len(argv) < 2: 9137 ↛ 9138line 9137 didn't jump to line 9138, because the condition on line 9137 was never true

+

9138 return self.usage() 

+

9139 

+

9140 match, color = argv 

+

9141 gef.ui.highlight_table[match] = color 

+

9142 return 

+

9143 

+

9144 

+

9145@register 

+

9146class HighlightRemoveCommand(GenericCommand): 

+

9147 """Remove a match in the highlight table.""" 

+

9148 _cmdline_ = "highlight remove" 

+

9149 _syntax_ = f"{_cmdline_} MATCH" 

+

9150 _aliases_ = [ 

+

9151 "highlight delete", 

+

9152 "highlight del", 

+

9153 "highlight unset", 

+

9154 "highlight rm", 

+

9155 "hlr", 

+

9156 ] 

+

9157 _example_ = f"{_cmdline_} remove 41414141" 

+

9158 

+

9159 def do_invoke(self, argv: List[str]) -> None: 

+

9160 if not argv: 

+

9161 return self.usage() 

+

9162 

+

9163 gef.ui.highlight_table.pop(argv[0], None) 

+

9164 return 

+

9165 

+

9166 

+

9167@register 

+

9168class FormatStringSearchCommand(GenericCommand): 

+

9169 """Exploitable format-string helper: this command will set up specific breakpoints 

+

9170 at well-known dangerous functions (printf, snprintf, etc.), and check if the pointer 

+

9171 holding the format string is writable, and therefore susceptible to format string 

+

9172 attacks if an attacker can control its content.""" 

+

9173 _cmdline_ = "format-string-helper" 

+

9174 _syntax_ = _cmdline_ 

+

9175 _aliases_ = ["fmtstr-helper",] 

+

9176 

+

9177 def do_invoke(self, _: List[str]) -> None: 

+

9178 dangerous_functions = { 

+

9179 "printf": 0, 

+

9180 "sprintf": 1, 

+

9181 "fprintf": 1, 

+

9182 "snprintf": 2, 

+

9183 "vsnprintf": 2, 

+

9184 } 

+

9185 

+

9186 nb_installed_breaks = 0 

+

9187 

+

9188 with RedirectOutputContext(to="/dev/null"): 

+

9189 for function_name in dangerous_functions: 

+

9190 argument_number = dangerous_functions[function_name] 

+

9191 FormatStringBreakpoint(function_name, argument_number) 

+

9192 nb_installed_breaks += 1 

+

9193 

+

9194 ok(f"Enabled {nb_installed_breaks} FormatString " 

+

9195 f"breakpoint{'s' if nb_installed_breaks > 1 else ''}") 

+

9196 return 

+

9197 

+

9198 

+

9199@register 

+

9200class HeapAnalysisCommand(GenericCommand): 

+

9201 """Heap vulnerability analysis helper: this command aims to track dynamic heap allocation 

+

9202 done through malloc()/free() to provide some insights on possible heap vulnerabilities. The 

+

9203 following vulnerabilities are checked: 

+

9204 - NULL free 

+

9205 - Use-after-Free 

+

9206 - Double Free 

+

9207 - Heap overlap""" 

+

9208 _cmdline_ = "heap-analysis-helper" 

+

9209 _syntax_ = _cmdline_ 

+

9210 

+

9211 def __init__(self) -> None: 

+

9212 super().__init__(complete=gdb.COMPLETE_NONE) 

+

9213 self["check_free_null"] = (False, "Break execution when a free(NULL) is encountered") 

+

9214 self["check_double_free"] = (True, "Break execution when a double free is encountered") 

+

9215 self["check_weird_free"] = (True, "Break execution when free() is called against a non-tracked pointer") 

+

9216 self["check_uaf"] = (True, "Break execution when a possible Use-after-Free condition is found") 

+

9217 self["check_heap_overlap"] = (True, "Break execution when a possible overlap in allocation is found") 

+

9218 

+

9219 self.bp_malloc = None 

+

9220 self.bp_calloc = None 

+

9221 self.bp_free = None 

+

9222 self.bp_realloc = None 

+

9223 return 

+

9224 

+

9225 @only_if_gdb_running 

+

9226 @experimental_feature 

+

9227 def do_invoke(self, argv: List[str]) -> None: 

+

9228 if not argv: 9228 ↛ 9232line 9228 didn't jump to line 9232, because the condition on line 9228 was never false

+

9229 self.setup() 

+

9230 return 

+

9231 

+

9232 if argv[0] == "show": 

+

9233 self.dump_tracked_allocations() 

+

9234 return 

+

9235 

+

9236 def setup(self) -> None: 

+

9237 ok("Tracking malloc() & calloc()") 

+

9238 self.bp_malloc = TraceMallocBreakpoint("__libc_malloc") 

+

9239 self.bp_calloc = TraceMallocBreakpoint("__libc_calloc") 

+

9240 ok("Tracking free()") 

+

9241 self.bp_free = TraceFreeBreakpoint() 

+

9242 ok("Tracking realloc()") 

+

9243 self.bp_realloc = TraceReallocBreakpoint() 

+

9244 

+

9245 ok("Disabling hardware watchpoints (this may increase the latency)") 

+

9246 gdb.execute("set can-use-hw-watchpoints 0") 

+

9247 

+

9248 info("Dynamic breakpoints correctly setup, " 

+

9249 "GEF will break execution if a possible vulnerabity is found.") 

+

9250 warn(f"{Color.colorify('Note', 'bold underline yellow')}: " 

+

9251 "The heap analysis slows down the execution noticeably.") 

+

9252 

+

9253 # when inferior quits, we need to clean everything for a next execution 

+

9254 gef_on_exit_hook(self.clean) 

+

9255 return 

+

9256 

+

9257 def dump_tracked_allocations(self) -> None: 

+

9258 global gef 

+

9259 

+

9260 if gef.session.heap_allocated_chunks: 

+

9261 ok("Tracked as in-use chunks:") 

+

9262 for addr, sz in gef.session.heap_allocated_chunks: 

+

9263 gef_print(f"{CROSS} malloc({sz:d}) = {addr:#x}") 

+

9264 else: 

+

9265 ok("No malloc() chunk tracked") 

+

9266 

+

9267 if gef.session.heap_freed_chunks: 

+

9268 ok("Tracked as free-ed chunks:") 

+

9269 for addr, sz in gef.session.heap_freed_chunks: 

+

9270 gef_print(f"{TICK} free({sz:d}) = {addr:#x}") 

+

9271 else: 

+

9272 ok("No free() chunk tracked") 

+

9273 return 

+

9274 

+

9275 def clean(self, _: "gdb.Event") -> None: 

+

9276 global gef 

+

9277 

+

9278 ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - Cleaning up") 

+

9279 for bp in [self.bp_malloc, self.bp_calloc, self.bp_free, self.bp_realloc]: 

+

9280 if hasattr(bp, "retbp") and bp.retbp: 9280 ↛ 9288line 9280 didn't jump to line 9288, because the condition on line 9280 was never false

+

9281 try: 

+

9282 bp.retbp.delete() 

+

9283 except RuntimeError: 

+

9284 # in some cases, gdb was found failing to correctly remove the retbp 

+

9285 # but they can be safely ignored since the debugging session is over 

+

9286 pass 

+

9287 

+

9288 bp.delete() 

+

9289 

+

9290 for wp in gef.session.heap_uaf_watchpoints: 

+

9291 wp.delete() 

+

9292 

+

9293 gef.session.heap_allocated_chunks = [] 

+

9294 gef.session.heap_freed_chunks = [] 

+

9295 gef.session.heap_uaf_watchpoints = [] 

+

9296 

+

9297 ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - Re-enabling hardware watchpoints") 

+

9298 gdb.execute("set can-use-hw-watchpoints 1") 

+

9299 

+

9300 gef_on_exit_unhook(self.clean) 

+

9301 return 

+

9302 

+

9303 

+

9304# 

+

9305# GDB Function declaration 

+

9306# 

+

9307@deprecated("") 

+

9308def register_function(cls: Type["GenericFunction"]) -> Type["GenericFunction"]: 

+

9309 """Decorator for registering a new convenience function to GDB.""" 

+

9310 return cls 

+

9311 

+

9312 

+

9313class GenericFunction(gdb.Function): 

+

9314 """This is an abstract class for invoking convenience functions, should not be instantiated.""" 

+

9315 

+

9316 _function_ : str 

+

9317 _syntax_: str = "" 

+

9318 _example_ : str = "" 

+

9319 

+

9320 def __init__(self) -> None: 

+

9321 super().__init__(self._function_) 

+

9322 

+

9323 def invoke(self, *args: Any) -> int: 

+

9324 if not is_alive(): 

+

9325 raise gdb.GdbError("No debugging session active") 

+

9326 return self.do_invoke(args) 

+

9327 

+

9328 def arg_to_long(self, args: List, index: int, default: int = 0) -> int: 

+

9329 try: 

+

9330 addr = args[index] 

+

9331 return int(addr) if addr.address is None else int(addr.address) 

+

9332 except IndexError: 

+

9333 return default 

+

9334 

+

9335 def do_invoke(self, args: Any) -> int: 

+

9336 raise NotImplementedError 

+

9337 

+

9338 

+

9339@register 

+

9340class StackOffsetFunction(GenericFunction): 

+

9341 """Return the current stack base address plus an optional offset.""" 

+

9342 _function_ = "_stack" 

+

9343 _syntax_ = f"${_function_}()" 

+

9344 

+

9345 def do_invoke(self, args: List) -> int: 

+

9346 base = get_section_base_address("[stack]") 

+

9347 if not base: 9347 ↛ 9348line 9347 didn't jump to line 9348, because the condition on line 9347 was never true

+

9348 raise gdb.GdbError("Stack not found") 

+

9349 

+

9350 return self.arg_to_long(args, 0) + base 

+

9351 

+

9352 

+

9353@register 

+

9354class HeapBaseFunction(GenericFunction): 

+

9355 """Return the current heap base address plus an optional offset.""" 

+

9356 _function_ = "_heap" 

+

9357 _syntax_ = f"${_function_}()" 

+

9358 

+

9359 def do_invoke(self, args: List) -> int: 

+

9360 base = gef.heap.base_address 

+

9361 if not base: 9361 ↛ 9362line 9361 didn't jump to line 9362, because the condition on line 9361 was never true

+

9362 base = get_section_base_address("[heap]") 

+

9363 if not base: 

+

9364 raise gdb.GdbError("Heap not found") 

+

9365 return self.arg_to_long(args, 0) + base 

+

9366 

+

9367 

+

9368@register 

+

9369class SectionBaseFunction(GenericFunction): 

+

9370 """Return the matching file's base address plus an optional offset. 

+

9371 Defaults to current file. Note that quotes need to be escaped""" 

+

9372 _function_ = "_base" 

+

9373 _syntax_ = "$_base([filepath])" 

+

9374 _example_ = "p $_base(\\\"/usr/lib/ld-2.33.so\\\")" 

+

9375 

+

9376 def do_invoke(self, args: List) -> int: 

+

9377 addr = 0 

+

9378 try: 

+

9379 name = args[0].string() 

+

9380 except IndexError: 9380 ↛ 9382line 9380 didn't jump to line 9382

+

9381 name = gef.session.file.name 

+

9382 except gdb.error: 

+

9383 err(f"Invalid arg: {args[0]}") 

+

9384 return 0 

+

9385 

+

9386 try: 

+

9387 base = get_section_base_address(name) 

+

9388 if base: 9388 ↛ 9393line 9388 didn't jump to line 9393, because the condition on line 9388 was never false

+

9389 addr = int(base) 

+

9390 except TypeError: 

+

9391 err(f"Cannot find section {name}") 

+

9392 return 0 

+

9393 return addr 

+

9394 

+

9395 

+

9396@register 

+

9397class BssBaseFunction(GenericFunction): 

+

9398 """Return the current bss base address plus the given offset.""" 

+

9399 _function_ = "_bss" 

+

9400 _syntax_ = f"${_function_}([OFFSET])" 

+

9401 _example_ = "deref $_bss(0x20)" 

+

9402 

+

9403 def do_invoke(self, args: List) -> int: 

+

9404 base = get_zone_base_address(".bss") 

+

9405 if not base: 9405 ↛ 9406line 9405 didn't jump to line 9406, because the condition on line 9405 was never true

+

9406 raise gdb.GdbError("BSS not found") 

+

9407 return self.arg_to_long(args, 0) + base 

+

9408 

+

9409 

+

9410@register 

+

9411class GotBaseFunction(GenericFunction): 

+

9412 """Return the current GOT base address plus the given offset.""" 

+

9413 _function_ = "_got" 

+

9414 _syntax_ = f"${_function_}([OFFSET])" 

+

9415 _example_ = "deref $_got(0x20)" 

+

9416 

+

9417 def do_invoke(self, args: List) -> int: 

+

9418 base = get_zone_base_address(".got") 

+

9419 if not base: 9419 ↛ 9420line 9419 didn't jump to line 9420, because the condition on line 9419 was never true

+

9420 raise gdb.GdbError("GOT not found") 

+

9421 return base + self.arg_to_long(args, 0) 

+

9422 

+

9423 

+

9424@register 

+

9425class GefFunctionsCommand(GenericCommand): 

+

9426 """List the convenience functions provided by GEF.""" 

+

9427 _cmdline_ = "functions" 

+

9428 _syntax_ = _cmdline_ 

+

9429 

+

9430 def __init__(self) -> None: 

+

9431 super().__init__() 

+

9432 self.docs = [] 

+

9433 self.should_refresh = True 

+

9434 return 

+

9435 

+

9436 def __add__(self, function: GenericFunction): 

+

9437 """Add function to documentation.""" 

+

9438 doc = getattr(function, "__doc__", "").lstrip() 

+

9439 if not hasattr(function, "_syntax_"): 9439 ↛ 9440line 9439 didn't jump to line 9440, because the condition on line 9439 was never true

+

9440 raise ValueError("Function is invalid") 

+

9441 syntax = getattr(function, "_syntax_").lstrip() 

+

9442 msg = f"{Color.colorify(syntax, 'bold cyan')}\n {doc}" 

+

9443 example = getattr(function, "_example_", "").strip() 

+

9444 if example: 

+

9445 msg += f"\n {Color.yellowify('Example:')} {example}" 

+

9446 self.docs.append(msg) 

+

9447 return self 

+

9448 

+

9449 def __radd__(self, function: GenericFunction): 

+

9450 return self.__add__(function) 

+

9451 

+

9452 def __str__(self) -> str: 

+

9453 if self.should_refresh: 9453 ↛ 9455line 9453 didn't jump to line 9455, because the condition on line 9453 was never false

+

9454 self.__rebuild() 

+

9455 return self.__doc__ or "" 

+

9456 

+

9457 def __rebuild(self) -> None: 

+

9458 """Rebuild the documentation for functions.""" 

+

9459 for function in gef.gdb.functions.values(): 

+

9460 self += function 

+

9461 

+

9462 self.command_size = len(gef.gdb.commands) 

+

9463 _, cols = get_terminal_size() 

+

9464 separator = HORIZONTAL_LINE*cols 

+

9465 self.__doc__ = f"\n{separator}\n".join(sorted(self.docs)) 

+

9466 self.should_refresh = False 

+

9467 return 

+

9468 

+

9469 def do_invoke(self, argv) -> None: 

+

9470 self.dont_repeat() 

+

9471 gef_print(titlify("GEF - Convenience Functions")) 

+

9472 gef_print("These functions can be used as arguments to other " 

+

9473 "commands to dynamically calculate values\n") 

+

9474 gef_print(str(self)) 

+

9475 return 

+

9476 

+

9477 

+

9478# 

+

9479# GEF internal command classes 

+

9480# 

+

9481class GefCommand(gdb.Command): 

+

9482 """GEF main command: view all new commands by typing `gef`.""" 

+

9483 

+

9484 _cmdline_ = "gef" 

+

9485 _syntax_ = f"{_cmdline_} (missing|config|save|restore|set|run)" 

+

9486 

+

9487 def __init__(self) -> None: 

+

9488 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, True) 

+

9489 gef.config["gef.follow_child"] = GefSetting(True, bool, "Automatically set GDB to follow child when forking") 

+

9490 gef.config["gef.readline_compat"] = GefSetting(False, bool, "Workaround for readline SOH/ETX issue (SEGV)") 

+

9491 gef.config["gef.debug"] = GefSetting(False, bool, "Enable debug mode for gef") 

+

9492 gef.config["gef.autosave_breakpoints_file"] = GefSetting("", str, "Automatically save and restore breakpoints") 

+

9493 gef.config["gef.extra_plugins_dir"] = GefSetting("", str, "Autoload additional GEF commands from external directory", hooks={"on_write": self.load_extra_plugins}) 

+

9494 gef.config["gef.disable_color"] = GefSetting(False, bool, "Disable all colors in GEF") 

+

9495 gef.config["gef.tempdir"] = GefSetting(GEF_TEMP_DIR, str, "Directory to use for temporary/cache content") 

+

9496 gef.config["gef.show_deprecation_warnings"] = GefSetting(True, bool, "Toggle the display of the `deprecated` warnings") 

+

9497 gef.config["gef.buffer"] = GefSetting(True, bool, "Internally buffer command output until completion") 

+

9498 gef.config["gef.bruteforce_main_arena"] = GefSetting(False, bool, "Allow bruteforcing main_arena symbol if everything else fails") 

+

9499 gef.config["gef.main_arena_offset"] = GefSetting("", str, "Offset from libc base address to main_arena symbol (int or hex). Set to empty string to disable.") 

+

9500 

+

9501 self.commands : Dict[str, GenericCommand] = collections.OrderedDict() 

+

9502 self.functions : Dict[str, GenericFunction] = collections.OrderedDict() 

+

9503 self.missing: Dict[str, Exception] = {} 

+

9504 return 

+

9505 

+

9506 @property 

+

9507 def loaded_commands(self) -> List[Tuple[str, Type[GenericCommand], Any]]: 

+

9508 print("Obsolete loaded_commands") 

+

9509 raise 

+

9510 

+

9511 @property 

+

9512 def loaded_functions(self) -> List[Type[GenericFunction]]: 

+

9513 print("Obsolete loaded_functions") 

+

9514 raise 

+

9515 

+

9516 @property 

+

9517 def missing_commands(self) -> Dict[str, Exception]: 

+

9518 print("Obsolete missing_commands") 

+

9519 raise 

+

9520 

+

9521 def setup(self) -> None: 

+

9522 self.load() 

+

9523 

+

9524 GefHelpCommand() 

+

9525 GefConfigCommand() 

+

9526 GefSaveCommand() 

+

9527 GefMissingCommand() 

+

9528 GefSetCommand() 

+

9529 GefRunCommand() 

+

9530 GefInstallExtraScriptCommand() 

+

9531 

+

9532 # restore the settings from config file if any 

+

9533 GefRestoreCommand() 

+

9534 return 

+

9535 

+

9536 def load_extra_plugins(self) -> int: 

+

9537 def load_plugin(fpath: pathlib.Path) -> bool: 

+

9538 try: 

+

9539 dbg(f"Loading '{fpath}'") 

+

9540 gdb.execute(f"source {fpath}") 

+

9541 except Exception as e: 

+

9542 warn(f"Exception while loading {fpath}: {str(e)}") 

+

9543 return False 

+

9544 return True 

+

9545 

+

9546 nb_added = -1 

+

9547 start_time = time.perf_counter() 

+

9548 try: 

+

9549 nb_inital = len(__registered_commands__) 

+

9550 directories: List[str] = gef.config["gef.extra_plugins_dir"].split(";") or [] 

+

9551 for d in directories: 

+

9552 d = d.strip() 

+

9553 if not d: continue 9553 ↛ 9554line 9553 didn't jump to line 9554, because the condition on line 9553 was never false

+

9554 directory = pathlib.Path(d).expanduser() 

+

9555 if not directory.is_dir(): continue 

+

9556 sys.path.append(str(directory.absolute())) 

+

9557 for entry in directory.iterdir(): 

+

9558 if entry.is_dir(): 

+

9559 if entry.name in ('gdb', 'gef', '__pycache__'): continue 

+

9560 load_plugin(entry / "__init__.py") 

+

9561 else: 

+

9562 if entry.suffix != ".py": continue 

+

9563 if entry.name == "__init__.py": continue 

+

9564 load_plugin(entry) 

+

9565 

+

9566 nb_added = len(__registered_commands__) - nb_inital 

+

9567 if nb_added > 0: 9567 ↛ 9568line 9567 didn't jump to line 9568, because the condition on line 9567 was never true

+

9568 self.load() 

+

9569 nb_failed = len(__registered_commands__) - len(self.commands) 

+

9570 end_time = time.perf_counter() 

+

9571 load_time = end_time - start_time 

+

9572 ok(f"{Color.colorify(str(nb_added), 'bold green')} extra commands added from " 

+

9573 f"'{Color.colorify(', '.join(directories), 'bold blue')}' in {load_time:.2f} seconds") 

+

9574 if nb_failed != 0: 

+

9575 warn(f"{Color.colorify(str(nb_failed), 'bold light_gray')} extra commands/functions failed to be added. " 

+

9576 "Check `gef missing` to know why") 

+

9577 

+

9578 except gdb.error as e: 

+

9579 err(f"failed: {e}") 

+

9580 return nb_added 

+

9581 

+

9582 @property 

+

9583 def loaded_command_names(self) -> Iterable[str]: 

+

9584 print("obsolete loaded_command_names") 

+

9585 return self.commands.keys() 

+

9586 

+

9587 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9588 self.dont_repeat() 

+

9589 gdb.execute("gef help") 

+

9590 return 

+

9591 

+

9592 def add_context_pane(self, pane_name: str, display_pane_function: Callable, pane_title_function: Callable, condition: Optional[Callable]) -> None: 

+

9593 """Add a new context pane to ContextCommand.""" 

+

9594 for _, class_instance in self.commands.items(): 

+

9595 if isinstance(class_instance, ContextCommand): 

+

9596 context = class_instance 

+

9597 break 

+

9598 else: 

+

9599 err("Cannot find ContextCommand") 

+

9600 return 

+

9601 

+

9602 # assure users can toggle the new context 

+

9603 corrected_settings_name = pane_name.replace(" ", "_") 

+

9604 gef.config["context.layout"] += f" {corrected_settings_name}" 

+

9605 

+

9606 # overload the printing of pane title 

+

9607 context.layout_mapping[corrected_settings_name] = (display_pane_function, pane_title_function, condition) 

+

9608 

+

9609 def load(self) -> None: 

+

9610 """Load all the commands and functions defined by GEF into GDB.""" 

+

9611 current_commands = set(self.commands.keys()) 

+

9612 new_commands = set(x._cmdline_ for x in __registered_commands__) - current_commands 

+

9613 current_functions = set(self.functions.keys()) 

+

9614 new_functions = set(x._function_ for x in __registered_functions__) - current_functions 

+

9615 self.missing.clear() 

+

9616 self.__load_time_ms = time.time()* 1000 

+

9617 

+

9618 # load all new functions 

+

9619 for name in sorted(new_functions): 

+

9620 for function_cls in __registered_functions__: 9620 ↛ 9619line 9620 didn't jump to line 9619, because the loop on line 9620 didn't complete

+

9621 if function_cls._function_ == name: 

+

9622 self.functions[name] = function_cls() 

+

9623 break 

+

9624 

+

9625 # load all new commands 

+

9626 for name in sorted(new_commands): 

+

9627 try: 

+

9628 for command_cls in __registered_commands__: 9628 ↛ 9626line 9628 didn't jump to line 9626, because the loop on line 9628 didn't complete

+

9629 if command_cls._cmdline_ == name: 

+

9630 command_instance = command_cls() 

+

9631 

+

9632 # create the aliases if any 

+

9633 if hasattr(command_instance, "_aliases_"): 

+

9634 aliases = getattr(command_instance, "_aliases_") 

+

9635 for alias in aliases: 

+

9636 GefAlias(alias, name) 

+

9637 

+

9638 self.commands[name] = command_instance 

+

9639 break 

+

9640 

+

9641 except Exception as reason: 

+

9642 self.missing[name] = reason 

+

9643 

+

9644 self.__load_time_ms = (time.time()* 1000) - self.__load_time_ms 

+

9645 return 

+

9646 

+

9647 

+

9648 def show_banner(self) -> None: 

+

9649 gef_print(f"{Color.greenify('GEF')} for {gef.session.os} ready, " 

+

9650 f"type `{Color.colorify('gef', 'underline yellow')}' to start, " 

+

9651 f"`{Color.colorify('gef config', 'underline pink')}' to configure") 

+

9652 

+

9653 ver = f"{sys.version_info.major:d}.{sys.version_info.minor:d}" 

+

9654 gef_print(f"{Color.colorify(str(len(self.commands)), 'bold green')} commands loaded " 

+

9655 f"and {Color.colorify(str(len(self.functions)), 'bold blue')} functions added for " 

+

9656 f"GDB {Color.colorify(gdb.VERSION, 'bold yellow')} in {self.__load_time_ms:.2f}ms " 

+

9657 f"using Python engine {Color.colorify(ver, 'bold red')}") 

+

9658 

+

9659 nb_missing = len(self.missing) 

+

9660 if nb_missing: 9660 ↛ 9661line 9660 didn't jump to line 9661, because the condition on line 9660 was never true

+

9661 warn(f"{Color.colorify(str(nb_missing), 'bold red')} " 

+

9662 f"command{'s' if nb_missing > 1 else ''} could not be loaded, " 

+

9663 f"run `{Color.colorify('gef missing', 'underline pink')}` to know why.") 

+

9664 return 

+

9665 

+

9666 

+

9667class GefHelpCommand(gdb.Command): 

+

9668 """GEF help sub-command.""" 

+

9669 _cmdline_ = "gef help" 

+

9670 _syntax_ = _cmdline_ 

+

9671 

+

9672 def __init__(self) -> None: 

+

9673 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) 

+

9674 self.docs = [] 

+

9675 self.should_refresh = True 

+

9676 self.command_size = 0 

+

9677 return 

+

9678 

+

9679 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9680 self.dont_repeat() 

+

9681 gef_print(titlify("GEF - GDB Enhanced Features")) 

+

9682 gef_print(str(self)) 

+

9683 return 

+

9684 

+

9685 def __rebuild(self) -> None: 

+

9686 """Rebuild the documentation.""" 

+

9687 for name, cmd in gef.gdb.commands.items(): 

+

9688 self += (name, cmd) 

+

9689 

+

9690 self.command_size = len(gef.gdb.commands) 

+

9691 _, cols = get_terminal_size() 

+

9692 separator = HORIZONTAL_LINE*cols 

+

9693 self.__doc__ = f"\n{separator}\n".join(sorted(self.docs)) 

+

9694 self.should_refresh = False 

+

9695 return 

+

9696 

+

9697 def __add__(self, command: Tuple[str, GenericCommand]): 

+

9698 """Add command to GEF documentation.""" 

+

9699 cmd, class_obj = command 

+

9700 if " " in cmd: 

+

9701 # do not print subcommands in gef help 

+

9702 return self 

+

9703 doc = getattr(class_obj, "__doc__", "").lstrip() 

+

9704 aliases = f"Aliases: {', '.join(class_obj._aliases_)}" if hasattr(class_obj, "_aliases_") else "" 

+

9705 msg = f"{Color.colorify(cmd, 'bold red')}\n{doc}\n{aliases}" 

+

9706 self.docs.append(msg) 

+

9707 return self 

+

9708 

+

9709 def __radd__(self, command: Tuple[str, GenericCommand]): 

+

9710 return self.__add__(command) 

+

9711 

+

9712 def __str__(self) -> str: 

+

9713 """Lazily regenerate the `gef help` object if it was modified""" 

+

9714 # quick check in case the docs have changed 

+

9715 if self.should_refresh or self.command_size != len(gef.gdb.commands): 9715 ↛ 9717line 9715 didn't jump to line 9717, because the condition on line 9715 was never false

+

9716 self.__rebuild() 

+

9717 return self.__doc__ or "" 

+

9718 

+

9719 

+

9720class GefConfigCommand(gdb.Command): 

+

9721 """GEF configuration sub-command 

+

9722 This command will help set/view GEF settings for the current debugging session. 

+

9723 It is possible to make those changes permanent by running `gef save` (refer 

+

9724 to this command help), and/or restore previously saved settings by running 

+

9725 `gef restore` (refer help). 

+

9726 """ 

+

9727 _cmdline_ = "gef config" 

+

9728 _syntax_ = f"{_cmdline_} [setting_name] [setting_value]" 

+

9729 

+

9730 def __init__(self) -> None: 

+

9731 super().__init__(self._cmdline_, gdb.COMMAND_NONE, prefix=False) 

+

9732 return 

+

9733 

+

9734 def invoke(self, args: str, from_tty: bool) -> None: 

+

9735 self.dont_repeat() 

+

9736 argv = gdb.string_to_argv(args) 

+

9737 argc = len(argv) 

+

9738 

+

9739 if not (0 <= argc <= 2): 9739 ↛ 9740line 9739 didn't jump to line 9740, because the condition on line 9739 was never true

+

9740 err("Invalid number of arguments") 

+

9741 return 

+

9742 

+

9743 if argc == 0: 

+

9744 gef_print(titlify("GEF configuration settings")) 

+

9745 self.print_settings() 

+

9746 return 

+

9747 

+

9748 if argc == 1: 

+

9749 prefix = argv[0] 

+

9750 names = [x for x in gef.config.keys() if x.startswith(prefix)] 

+

9751 if names: 9751 ↛ 9758line 9751 didn't jump to line 9758, because the condition on line 9751 was never false

+

9752 if len(names) == 1: 9752 ↛ 9756line 9752 didn't jump to line 9756, because the condition on line 9752 was never false

+

9753 gef_print(titlify(f"GEF configuration setting: {names[0]}")) 

+

9754 self.print_setting(names[0], verbose=True) 

+

9755 else: 

+

9756 gef_print(titlify(f"GEF configuration settings matching '{argv[0]}'")) 

+

9757 for name in names: self.print_setting(name) 

+

9758 return 

+

9759 

+

9760 self.set_setting(argv) 

+

9761 return 

+

9762 

+

9763 def print_setting(self, plugin_name: str, verbose: bool = False) -> None: 

+

9764 res = gef.config.raw_entry(plugin_name) 

+

9765 string_color = gef.config["theme.dereference_string"] 

+

9766 misc_color = gef.config["theme.dereference_base_address"] 

+

9767 

+

9768 if not res: 9768 ↛ 9769line 9768 didn't jump to line 9769, because the condition on line 9768 was never true

+

9769 return 

+

9770 

+

9771 _setting = Color.colorify(plugin_name, "green") 

+

9772 _type = res.type.__name__ 

+

9773 if _type == "str": 

+

9774 _value = f'"{Color.colorify(res.value, string_color)}"' 

+

9775 else: 

+

9776 _value = Color.colorify(res.value, misc_color) 

+

9777 

+

9778 gef_print(f"{_setting} ({_type}) = {_value}") 

+

9779 

+

9780 if verbose: 

+

9781 gef_print(Color.colorify("\nDescription:", "bold underline")) 

+

9782 gef_print(f"\t{res.description}") 

+

9783 return 

+

9784 

+

9785 def print_settings(self) -> None: 

+

9786 for x in sorted(gef.config): 

+

9787 self.print_setting(x) 

+

9788 return 

+

9789 

+

9790 def set_setting(self, argv: Tuple[str, Any]) -> None: 

+

9791 global gef 

+

9792 key, new_value = argv 

+

9793 

+

9794 if "." not in key: 9794 ↛ 9795line 9794 didn't jump to line 9795, because the condition on line 9794 was never true

+

9795 err("Invalid command format") 

+

9796 return 

+

9797 

+

9798 loaded_commands = list( gef.gdb.commands.keys()) + ["gef"] 

+

9799 plugin_name = key.split(".", 1)[0] 

+

9800 if plugin_name not in loaded_commands: 9800 ↛ 9801line 9800 didn't jump to line 9801, because the condition on line 9800 was never true

+

9801 err(f"Unknown plugin '{plugin_name}'") 

+

9802 return 

+

9803 

+

9804 if key not in gef.config: 9804 ↛ 9805line 9804 didn't jump to line 9805, because the condition on line 9804 was never true

+

9805 err(f"'{key}' is not a valid configuration setting") 

+

9806 return 

+

9807 

+

9808 _type = gef.config.raw_entry(key).type 

+

9809 try: 

+

9810 if _type == bool: 

+

9811 _newval = True if new_value.upper() in ("TRUE", "T", "1") else False 

+

9812 else: 

+

9813 _newval = new_value 

+

9814 

+

9815 gef.config[key] = _newval 

+

9816 except Exception as e: 

+

9817 err(f"'{key}' expects type '{_type.__name__}', got {type(new_value).__name__}: reason {str(e)}") 

+

9818 return 

+

9819 

+

9820 reset_all_caches() 

+

9821 return 

+

9822 

+

9823 def complete(self, text: str, word: str) -> List[str]: 

+

9824 settings = sorted(gef.config) 

+

9825 

+

9826 if text == "": 

+

9827 # no prefix: example: `gef config TAB` 

+

9828 return [s for s in settings if word in s] 

+

9829 

+

9830 if "." not in text: 

+

9831 # if looking for possible prefix 

+

9832 return [s for s in settings if s.startswith(text.strip())] 

+

9833 

+

9834 # finally, look for possible values for given prefix 

+

9835 return [s.split(".", 1)[1] for s in settings if s.startswith(text.strip())] 

+

9836 

+

9837 

+

9838class GefSaveCommand(gdb.Command): 

+

9839 """GEF save sub-command. 

+

9840 Saves the current configuration of GEF to disk (by default in file '~/.gef.rc').""" 

+

9841 _cmdline_ = "gef save" 

+

9842 _syntax_ = _cmdline_ 

+

9843 

+

9844 def __init__(self) -> None: 

+

9845 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) 

+

9846 return 

+

9847 

+

9848 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9849 self.dont_repeat() 

+

9850 cfg = configparser.RawConfigParser() 

+

9851 old_sect = None 

+

9852 

+

9853 # save the configuration 

+

9854 for key in sorted(gef.config): 

+

9855 sect, optname = key.split(".", 1) 

+

9856 value = gef.config[key] 

+

9857 

+

9858 if old_sect != sect: 

+

9859 cfg.add_section(sect) 

+

9860 old_sect = sect 

+

9861 

+

9862 cfg.set(sect, optname, value) 

+

9863 

+

9864 # save the aliases 

+

9865 cfg.add_section("aliases") 

+

9866 for alias in gef.session.aliases: 

+

9867 cfg.set("aliases", alias._alias, alias._command) 

+

9868 

+

9869 with GEF_RC.open("w") as fd: 

+

9870 cfg.write(fd) 

+

9871 

+

9872 ok(f"Configuration saved to '{GEF_RC}'") 

+

9873 return 

+

9874 

+

9875 

+

9876class GefRestoreCommand(gdb.Command): 

+

9877 """GEF restore sub-command. 

+

9878 Loads settings from file '~/.gef.rc' and apply them to the configuration of GEF.""" 

+

9879 _cmdline_ = "gef restore" 

+

9880 _syntax_ = _cmdline_ 

+

9881 

+

9882 def __init__(self) -> None: 

+

9883 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) 

+

9884 self.reload(True) 

+

9885 return 

+

9886 

+

9887 def invoke(self, args: str, from_tty: bool) -> None: 

+

9888 self.dont_repeat() 

+

9889 if GEF_RC.is_file(): 

+

9890 quiet = (args.lower() == "quiet") 

+

9891 self.reload(quiet) 

+

9892 return 

+

9893 

+

9894 def reload(self, quiet: bool): 

+

9895 cfg = configparser.ConfigParser() 

+

9896 cfg.read(GEF_RC) 

+

9897 

+

9898 for section in cfg.sections(): 

+

9899 if section == "aliases": 

+

9900 # load the aliases 

+

9901 for key in cfg.options(section): 

+

9902 try: 

+

9903 GefAlias(key, cfg.get(section, key)) 

+

9904 except: 

+

9905 pass 

+

9906 continue 

+

9907 

+

9908 # load the other options 

+

9909 for optname in cfg.options(section): 

+

9910 key = f"{section}.{optname}" 

+

9911 try: 

+

9912 setting = gef.config.raw_entry(key) 

+

9913 except Exception: 

+

9914 continue 

+

9915 new_value = cfg.get(section, optname) 

+

9916 if setting.type == bool: 

+

9917 new_value = True if new_value.upper() in ("TRUE", "T", "1") else False 

+

9918 setting.value = setting.type(new_value) 

+

9919 

+

9920 if not quiet: 9920 ↛ 9921line 9920 didn't jump to line 9921, because the condition on line 9920 was never true

+

9921 ok(f"Configuration from '{Color.colorify(str(GEF_RC), 'bold blue')}' restored") 

+

9922 return 

+

9923 

+

9924 

+

9925class GefMissingCommand(gdb.Command): 

+

9926 """GEF missing sub-command 

+

9927 Display the GEF commands that could not be loaded, along with the reason of why 

+

9928 they could not be loaded. 

+

9929 """ 

+

9930 _cmdline_ = "gef missing" 

+

9931 _syntax_ = _cmdline_ 

+

9932 

+

9933 def __init__(self) -> None: 

+

9934 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) 

+

9935 return 

+

9936 

+

9937 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9938 self.dont_repeat() 

+

9939 missing_commands = gef.gdb.missing 

+

9940 if not missing_commands: 

+

9941 ok("No missing command") 

+

9942 return 

+

9943 

+

9944 for missing_command, reason in missing_commands.items(): 

+

9945 warn(f"Command `{missing_command}` is missing, reason {RIGHT_ARROW} {reason}") 

+

9946 return 

+

9947 

+

9948 

+

9949class GefSetCommand(gdb.Command): 

+

9950 """Override GDB set commands with the context from GEF.""" 

+

9951 _cmdline_ = "gef set" 

+

9952 _syntax_ = f"{_cmdline_} [GDB_SET_ARGUMENTS]" 

+

9953 

+

9954 def __init__(self) -> None: 

+

9955 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_SYMBOL, False) 

+

9956 return 

+

9957 

+

9958 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9959 self.dont_repeat() 

+

9960 args = args.split() 

+

9961 cmd = ["set", args[0],] 

+

9962 for p in args[1:]: 

+

9963 if p.startswith("$_gef"): 9963 ↛ 9967line 9963 didn't jump to line 9967, because the condition on line 9963 was never false

+

9964 c = gdb.parse_and_eval(p) 

+

9965 cmd.append(c.string()) 

+

9966 else: 

+

9967 cmd.append(p) 

+

9968 

+

9969 gdb.execute(" ".join(cmd)) 

+

9970 return 

+

9971 

+

9972 

+

9973class GefRunCommand(gdb.Command): 

+

9974 """Override GDB run commands with the context from GEF. 

+

9975 Simple wrapper for GDB run command to use arguments set from `gef set args`.""" 

+

9976 _cmdline_ = "gef run" 

+

9977 _syntax_ = f"{_cmdline_} [GDB_RUN_ARGUMENTS]" 

+

9978 

+

9979 def __init__(self) -> None: 

+

9980 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_FILENAME, False) 

+

9981 return 

+

9982 

+

9983 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9984 self.dont_repeat() 

+

9985 if is_alive(): 

+

9986 gdb.execute("continue") 

+

9987 return 

+

9988 

+

9989 argv = args.split() 

+

9990 gdb.execute(f"gef set args {' '.join(argv)}") 

+

9991 gdb.execute("run") 

+

9992 return 

+

9993 

+

9994 

+

9995class GefAlias(gdb.Command): 

+

9996 """Simple aliasing wrapper because GDB doesn't do what it should.""" 

+

9997 

+

9998 def __init__(self, alias: str, command: str, completer_class: int = gdb.COMPLETE_NONE, command_class: int = gdb.COMMAND_NONE) -> None: 

+

9999 p = command.split() 

+

10000 if not p: 10000 ↛ 10001line 10000 didn't jump to line 10001, because the condition on line 10000 was never true

+

10001 return 

+

10002 

+

10003 if any(x for x in gef.session.aliases if x._alias == alias): 

+

10004 return 

+

10005 

+

10006 self._command = command 

+

10007 self._alias = alias 

+

10008 c = command.split()[0] 

+

10009 r = self.lookup_command(c) 

+

10010 self.__doc__ = f"Alias for '{Color.greenify(command)}'" 

+

10011 if r is not None: 

+

10012 _instance = r[1] 

+

10013 self.__doc__ += f": {_instance.__doc__}" 

+

10014 

+

10015 if hasattr(_instance, "complete"): 10015 ↛ 10016line 10015 didn't jump to line 10016, because the condition on line 10015 was never true

+

10016 self.complete = _instance.complete 

+

10017 

+

10018 super().__init__(alias, command_class, completer_class=completer_class) 

+

10019 gef.session.aliases.append(self) 

+

10020 return 

+

10021 

+

10022 def invoke(self, args: Any, from_tty: bool) -> None: 

+

10023 gdb.execute(f"{self._command} {args}", from_tty=from_tty) 

+

10024 return 

+

10025 

+

10026 def lookup_command(self, cmd: str) -> Optional[Tuple[str, GenericCommand]]: 

+

10027 global gef 

+

10028 for _name, _instance in gef.gdb.commands.items(): 

+

10029 if cmd == _name: 

+

10030 return _name, _instance 

+

10031 

+

10032 return None 

+

10033 

+

10034 

+

10035@register 

+

10036class AliasesCommand(GenericCommand): 

+

10037 """Base command to add, remove, or list aliases.""" 

+

10038 

+

10039 _cmdline_ = "aliases" 

+

10040 _syntax_ = f"{_cmdline_} (add|rm|ls)" 

+

10041 

+

10042 def __init__(self) -> None: 

+

10043 super().__init__(prefix=True) 

+

10044 return 

+

10045 

+

10046 def do_invoke(self, _: List[str]) -> None: 

+

10047 self.usage() 

+

10048 return 

+

10049 

+

10050 

+

10051@register 

+

10052class AliasesAddCommand(AliasesCommand): 

+

10053 """Command to add aliases.""" 

+

10054 

+

10055 _cmdline_ = "aliases add" 

+

10056 _syntax_ = f"{_cmdline_} [ALIAS] [COMMAND]" 

+

10057 _example_ = f"{_cmdline_} scope telescope" 

+

10058 

+

10059 def __init__(self) -> None: 

+

10060 super().__init__() 

+

10061 return 

+

10062 

+

10063 def do_invoke(self, argv: List[str]) -> None: 

+

10064 if len(argv) < 2: 10064 ↛ 10065line 10064 didn't jump to line 10065, because the condition on line 10064 was never true

+

10065 self.usage() 

+

10066 return 

+

10067 GefAlias(argv[0], " ".join(argv[1:])) 

+

10068 return 

+

10069 

+

10070 

+

10071@register 

+

10072class AliasesRmCommand(AliasesCommand): 

+

10073 """Command to remove aliases.""" 

+

10074 

+

10075 _cmdline_ = "aliases rm" 

+

10076 _syntax_ = f"{_cmdline_} [ALIAS]" 

+

10077 

+

10078 def __init__(self) -> None: 

+

10079 super().__init__() 

+

10080 return 

+

10081 

+

10082 def do_invoke(self, argv: List[str]) -> None: 

+

10083 global gef 

+

10084 if len(argv) != 1: 10084 ↛ 10085line 10084 didn't jump to line 10085, because the condition on line 10084 was never true

+

10085 self.usage() 

+

10086 return 

+

10087 try: 

+

10088 alias_to_remove = next(filter(lambda x: x._alias == argv[0], gef.session.aliases)) 

+

10089 gef.session.aliases.remove(alias_to_remove) 

+

10090 except (ValueError, StopIteration): 

+

10091 err(f"{argv[0]} not found in aliases.") 

+

10092 return 

+

10093 gef_print("You must reload GEF for alias removals to apply.") 

+

10094 return 

+

10095 

+

10096 

+

10097@register 

+

10098class AliasesListCommand(AliasesCommand): 

+

10099 """Command to list aliases.""" 

+

10100 

+

10101 _cmdline_ = "aliases ls" 

+

10102 _syntax_ = _cmdline_ 

+

10103 

+

10104 def __init__(self) -> None: 

+

10105 super().__init__() 

+

10106 return 

+

10107 

+

10108 def do_invoke(self, _: List[str]) -> None: 

+

10109 ok("Aliases defined:") 

+

10110 for a in gef.session.aliases: 

+

10111 gef_print(f"{a._alias:30s} {RIGHT_ARROW} {a._command}") 

+

10112 return 

+

10113 

+

10114 

+

10115class GefTmuxSetup(gdb.Command): 

+

10116 """Setup a confortable tmux debugging environment.""" 

+

10117 

+

10118 def __init__(self) -> None: 

+

10119 super().__init__("tmux-setup", gdb.COMMAND_NONE, gdb.COMPLETE_NONE) 

+

10120 GefAlias("screen-setup", "tmux-setup") 

+

10121 return 

+

10122 

+

10123 def invoke(self, args: Any, from_tty: bool) -> None: 

+

10124 self.dont_repeat() 

+

10125 

+

10126 tmux = os.getenv("TMUX") 

+

10127 if tmux: 

+

10128 self.tmux_setup() 

+

10129 return 

+

10130 

+

10131 screen = os.getenv("TERM") 

+

10132 if screen is not None and screen == "screen": 

+

10133 self.screen_setup() 

+

10134 return 

+

10135 

+

10136 warn("Not in a tmux/screen session") 

+

10137 return 

+

10138 

+

10139 def tmux_setup(self) -> None: 

+

10140 """Prepare the tmux environment by vertically splitting the current pane, and 

+

10141 forcing the context to be redirected there.""" 

+

10142 tmux = which("tmux") 

+

10143 ok("tmux session found, splitting window...") 

+

10144 

+

10145 pane, pty = subprocess.check_output([tmux, "splitw", "-h", '-F#{session_name}:#{window_index}.#{pane_index}-#{pane_tty}', "-P"]).decode().strip().split("-") 

+

10146 atexit.register(lambda : subprocess.run([tmux, "kill-pane", "-t", pane])) 

+

10147 # clear the screen and let it wait for input forever 

+

10148 gdb.execute(f"! {tmux} send-keys -t {pane} 'clear ; cat' C-m") 

+

10149 gdb.execute(f"! {tmux} select-pane -L") 

+

10150 

+

10151 ok(f"Setting `context.redirect` to '{pty}'...") 

+

10152 gdb.execute(f"gef config context.redirect {pty}") 

+

10153 ok("Done!") 

+

10154 return 

+

10155 

+

10156 def screen_setup(self) -> None: 

+

10157 """Hackish equivalent of the tmux_setup() function for screen.""" 

+

10158 screen = which("screen") 

+

10159 sty = os.getenv("STY") 

+

10160 ok("screen session found, splitting window...") 

+

10161 fd_script, script_path = tempfile.mkstemp() 

+

10162 fd_tty, tty_path = tempfile.mkstemp() 

+

10163 os.close(fd_tty) 

+

10164 

+

10165 with os.fdopen(fd_script, "w") as f: 

+

10166 f.write("startup_message off\n") 

+

10167 f.write("split -v\n") 

+

10168 f.write("focus right\n") 

+

10169 f.write(f"screen bash -c 'tty > {tty_path}; clear; cat'\n") 

+

10170 f.write("focus left\n") 

+

10171 

+

10172 gdb.execute(f"! {screen} -r {sty} -m -d -X source {script_path}") 

+

10173 # artificial delay to make sure `tty_path` is populated 

+

10174 time.sleep(0.25) 

+

10175 with open(tty_path, "r") as f: 

+

10176 pty = f.read().strip() 

+

10177 ok(f"Setting `context.redirect` to '{pty}'...") 

+

10178 gdb.execute(f"gef config context.redirect {pty}") 

+

10179 ok("Done!") 

+

10180 os.unlink(script_path) 

+

10181 os.unlink(tty_path) 

+

10182 return 

+

10183 

+

10184 

+

10185class GefInstallExtraScriptCommand(gdb.Command): 

+

10186 """`gef install` command: installs one or more scripts from the `gef-extras` script repo. Note that the command 

+

10187 doesn't check for external dependencies the script(s) might require.""" 

+

10188 _cmdline_ = "gef install" 

+

10189 _syntax_ = f"{_cmdline_} SCRIPTNAME [SCRIPTNAME [SCRIPTNAME...]]" 

+

10190 

+

10191 def __init__(self) -> None: 

+

10192 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) 

+

10193 self.branch = gef.config.get("gef.extras_default_branch", GEF_EXTRAS_DEFAULT_BRANCH) 

+

10194 return 

+

10195 

+

10196 def invoke(self, argv: str, from_tty: bool) -> None: 

+

10197 self.dont_repeat() 

+

10198 if not argv: 10198 ↛ 10199line 10198 didn't jump to line 10199, because the condition on line 10198 was never true

+

10199 err("No script name provided") 

+

10200 return 

+

10201 

+

10202 args = argv.split() 

+

10203 

+

10204 if "--list" in args or "-l" in args: 10204 ↛ 10205line 10204 didn't jump to line 10205, because the condition on line 10204 was never true

+

10205 subprocess.run(["xdg-open", f"https://github.com/hugsy/gef-extras/{self.branch}/"]) 

+

10206 return 

+

10207 

+

10208 self.dirpath = pathlib.Path(gef.config["gef.tempdir"]).expanduser().absolute() 

+

10209 if not self.dirpath.is_dir(): 10209 ↛ 10210line 10209 didn't jump to line 10210, because the condition on line 10209 was never true

+

10210 err("'gef.tempdir' is not a valid directory") 

+

10211 return 

+

10212 

+

10213 for script in args: 

+

10214 script = script.lower() 

+

10215 if not self.__install_extras_script(script): 10215 ↛ 10216line 10215 didn't jump to line 10216, because the condition on line 10215 was never true

+

10216 warn(f"Failed to install '{script}', skipping...") 

+

10217 return 

+

10218 

+

10219 

+

10220 def __install_extras_script(self, script: str) -> bool: 

+

10221 fpath = self.dirpath / f"{script}.py" 

+

10222 if not fpath.exists(): 10222 ↛ 10234line 10222 didn't jump to line 10234, because the condition on line 10222 was never false

+

10223 url = f"https://raw.githubusercontent.com/hugsy/gef-extras/{self.branch}/scripts/{script}.py" 

+

10224 info(f"Searching for '{script}.py' in `gef-extras@{self.branch}`...") 

+

10225 data = http_get(url) 

+

10226 if not data: 10226 ↛ 10227line 10226 didn't jump to line 10227, because the condition on line 10226 was never true

+

10227 warn("Not found") 

+

10228 return False 

+

10229 

+

10230 with fpath.open("wb") as fd: 

+

10231 fd.write(data) 

+

10232 fd.flush() 

+

10233 

+

10234 old_command_set = set(gef.gdb.commands) 

+

10235 gdb.execute(f"source {fpath}") 

+

10236 new_command_set = set(gef.gdb.commands) 

+

10237 new_commands = [f"`{c[0]}`" for c in (new_command_set - old_command_set)] 

+

10238 ok(f"Installed file '{fpath}', new command(s) available: {', '.join(new_commands)}") 

+

10239 return True 

+

10240 

+

10241 

+

10242# 

+

10243# GEF internal classes 

+

10244# 

+

10245 

+

10246def __gef_prompt__(current_prompt: Callable[[Callable], str]) -> str: 

+

10247 """GEF custom prompt function.""" 

+

10248 if gef.config["gef.readline_compat"] is True: return GEF_PROMPT 

+

10249 if gef.config["gef.disable_color"] is True: return GEF_PROMPT 

+

10250 prompt = "" 

+

10251 if gef.session.remote: 

+

10252 prompt += Color.boldify("(remote) ") 

+

10253 prompt += GEF_PROMPT_ON if is_alive() else GEF_PROMPT_OFF 

+

10254 return prompt 

+

10255 

+

10256 

+

10257class GefManager(metaclass=abc.ABCMeta): 

+

10258 def reset_caches(self) -> None: 

+

10259 """Reset the LRU-cached attributes""" 

+

10260 for attr in dir(self): 

+

10261 try: 

+

10262 obj = getattr(self, attr) 

+

10263 if not hasattr(obj, "cache_clear"): 10263 ↛ 10265line 10263 didn't jump to line 10265, because the condition on line 10263 was never false

+

10264 continue 

+

10265 obj.cache_clear() 

+

10266 except: # we're reseting the cache here, we don't care if (or which) exception triggers 

+

10267 continue 

+

10268 return 

+

10269 

+

10270 

+

10271class GefMemoryManager(GefManager): 

+

10272 """Class that manages memory access for gef.""" 

+

10273 def __init__(self) -> None: 

+

10274 self.reset_caches() 

+

10275 return 

+

10276 

+

10277 def reset_caches(self) -> None: 

+

10278 super().reset_caches() 

+

10279 self.__maps = None 

+

10280 return 

+

10281 

+

10282 def write(self, address: int, buffer: ByteString, length: Optional[int] = None) -> None: 

+

10283 """Write `buffer` at address `address`.""" 

+

10284 length = length or len(buffer) 

+

10285 gdb.selected_inferior().write_memory(address, buffer, length) 

+

10286 

+

10287 def read(self, addr: int, length: int = 0x10) -> bytes: 

+

10288 """Return a `length` long byte array with the copy of the process memory at `addr`.""" 

+

10289 return gdb.selected_inferior().read_memory(addr, length).tobytes() 

+

10290 

+

10291 def read_integer(self, addr: int) -> int: 

+

10292 """Return an integer read from memory.""" 

+

10293 sz = gef.arch.ptrsize 

+

10294 mem = self.read(addr, sz) 

+

10295 unpack = u32 if sz == 4 else u64 

+

10296 return unpack(mem) 

+

10297 

+

10298 def read_cstring(self, 

+

10299 address: int, 

+

10300 max_length: int = GEF_MAX_STRING_LENGTH, 

+

10301 encoding: Optional[str] = None) -> str: 

+

10302 """Return a C-string read from memory.""" 

+

10303 encoding = encoding or "unicode-escape" 

+

10304 length = min(address | (DEFAULT_PAGE_SIZE-1), max_length+1) 

+

10305 

+

10306 try: 

+

10307 res_bytes = self.read(address, length) 

+

10308 except gdb.error: 

+

10309 err(f"Can't read memory at '{address}'") 

+

10310 return "" 

+

10311 try: 

+

10312 with warnings.catch_warnings(): 

+

10313 # ignore DeprecationWarnings (see #735) 

+

10314 warnings.simplefilter("ignore") 

+

10315 res = res_bytes.decode(encoding, "strict") 

+

10316 except UnicodeDecodeError: 

+

10317 # latin-1 as fallback due to its single-byte to glyph mapping 

+

10318 res = res_bytes.decode("latin-1", "replace") 

+

10319 

+

10320 res = res.split("\x00", 1)[0] 

+

10321 ustr = res.replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t") 

+

10322 if max_length and len(res) > max_length: 

+

10323 return f"{ustr[:max_length]}[...]" 

+

10324 return ustr 

+

10325 

+

10326 def read_ascii_string(self, address: int) -> Optional[str]: 

+

10327 """Read an ASCII string from memory""" 

+

10328 cstr = self.read_cstring(address) 

+

10329 if isinstance(cstr, str) and cstr and all(x in string.printable for x in cstr): 

+

10330 return cstr 

+

10331 return None 

+

10332 

+

10333 @property 

+

10334 def maps(self) -> List[Section]: 

+

10335 if not self.__maps: 

+

10336 self.__maps = self.__parse_maps() 

+

10337 return self.__maps 

+

10338 

+

10339 def __parse_maps(self) -> List[Section]: 

+

10340 """Return the mapped memory sections""" 

+

10341 try: 

+

10342 if is_qemu_system(): 10342 ↛ 10343line 10342 didn't jump to line 10343, because the condition on line 10342 was never true

+

10343 return list(self.__parse_info_mem()) 

+

10344 except gdb.error: 

+

10345 # Target may not support this command 

+

10346 pass 

+

10347 try: 

+

10348 return list(self.__parse_procfs_maps()) 

+

10349 except FileNotFoundError: 

+

10350 return list(self.__parse_gdb_info_sections()) 

+

10351 

+

10352 def __parse_procfs_maps(self) -> Generator[Section, None, None]: 

+

10353 """Get the memory mapping from procfs.""" 

+

10354 procfs_mapfile = gef.session.maps 

+

10355 if not procfs_mapfile: 

+

10356 is_remote = gef.session.remote is not None 

+

10357 raise FileNotFoundError(f"Missing {'remote ' if is_remote else ''}procfs map file") 

+

10358 with procfs_mapfile.open("r") as fd: 

+

10359 for line in fd: 

+

10360 line = line.strip() 

+

10361 addr, perm, off, _, rest = line.split(" ", 4) 

+

10362 rest = rest.split(" ", 1) 

+

10363 if len(rest) == 1: 

+

10364 inode = rest[0] 

+

10365 pathname = "" 

+

10366 else: 

+

10367 inode = rest[0] 

+

10368 pathname = rest[1].lstrip() 

+

10369 

+

10370 addr_start, addr_end = parse_string_range(addr) 

+

10371 off = int(off, 16) 

+

10372 perm = Permission.from_process_maps(perm) 

+

10373 inode = int(inode) 

+

10374 yield Section(page_start=addr_start, 

+

10375 page_end=addr_end, 

+

10376 offset=off, 

+

10377 permission=perm, 

+

10378 inode=inode, 

+

10379 path=pathname) 

+

10380 return 

+

10381 

+

10382 def __parse_gdb_info_sections(self) -> Generator[Section, None, None]: 

+

10383 """Get the memory mapping from GDB's command `maintenance info sections` (limited info).""" 

+

10384 stream = StringIO(gdb.execute("maintenance info sections", to_string=True)) 

+

10385 

+

10386 for line in stream: 

+

10387 if not line: 10387 ↛ 10388line 10387 didn't jump to line 10388, because the condition on line 10387 was never true

+

10388 break 

+

10389 

+

10390 try: 

+

10391 parts = [x for x in line.split()] 

+

10392 addr_start, addr_end = [int(x, 16) for x in parts[1].split("->")] 

+

10393 off = int(parts[3][:-1], 16) 

+

10394 path = parts[4] 

+

10395 perm = Permission.from_info_sections(parts[5:]) 

+

10396 yield Section( 

+

10397 page_start=addr_start, 

+

10398 page_end=addr_end, 

+

10399 offset=off, 

+

10400 permission=perm, 

+

10401 inode="", 

+

10402 path=path 

+

10403 ) 

+

10404 

+

10405 except IndexError: 10405 ↛ 10406line 10405 didn't jump to line 10406, because the exception caught by line 10405 didn't happen

+

10406 continue 

+

10407 except ValueError: 

+

10408 continue 

+

10409 return 

+

10410 

+

10411 def __parse_info_mem(self) -> Generator[Section, None, None]: 

+

10412 """Get the memory mapping from GDB's command `monitor info mem`""" 

+

10413 for line in StringIO(gdb.execute("monitor info mem", to_string=True)): 

+

10414 if not line: 

+

10415 break 

+

10416 try: 

+

10417 ranges, off, perms = line.split() 

+

10418 off = int(off, 16) 

+

10419 start, end = [int(s, 16) for s in ranges.split("-")] 

+

10420 except ValueError as e: 

+

10421 continue 

+

10422 

+

10423 perm = Permission.from_info_mem(perms) 

+

10424 yield Section( 

+

10425 page_start=start, 

+

10426 page_end=end, 

+

10427 offset=off, 

+

10428 permission=perm, 

+

10429 inode="", 

+

10430 ) 

+

10431 

+

10432 

+

10433class GefHeapManager(GefManager): 

+

10434 """Class managing session heap.""" 

+

10435 def __init__(self) -> None: 

+

10436 self.reset_caches() 

+

10437 return 

+

10438 

+

10439 def reset_caches(self) -> None: 

+

10440 self.__libc_main_arena: Optional[GlibcArena] = None 

+

10441 self.__libc_selected_arena: Optional[GlibcArena] = None 

+

10442 self.__heap_base = None 

+

10443 return 

+

10444 

+

10445 @property 

+

10446 def main_arena(self) -> Optional[GlibcArena]: 

+

10447 if not self.__libc_main_arena: 

+

10448 try: 

+

10449 __main_arena_addr = GefHeapManager.find_main_arena_addr() 

+

10450 self.__libc_main_arena = GlibcArena(f"*{__main_arena_addr:#x}") 

+

10451 # the initialization of `main_arena` also defined `selected_arena`, so 

+

10452 # by default, `main_arena` == `selected_arena` 

+

10453 self.selected_arena = self.__libc_main_arena 

+

10454 except: 

+

10455 # the search for arena can fail when the session is not started 

+

10456 pass 

+

10457 return self.__libc_main_arena 

+

10458 

+

10459 @main_arena.setter 

+

10460 def main_arena(self, value: GlibcArena) -> None: 

+

10461 self.__libc_main_arena = value 

+

10462 return 

+

10463 

+

10464 @staticmethod 

+

10465 @lru_cache() 

+

10466 def find_main_arena_addr() -> int: 

+

10467 assert gef.libc.version 

+

10468 """A helper function to find the glibc `main_arena` address, either from 

+

10469 symbol, from its offset from `__malloc_hook` or by brute force.""" 

+

10470 # Before anything else, use libc offset from config if available 

+

10471 if gef.config["gef.main_arena_offset"]: 10471 ↛ 10472line 10471 didn't jump to line 10472, because the condition on line 10471 was never true

+

10472 try: 

+

10473 libc_base = get_section_base_address("libc") 

+

10474 offset = parse_address(gef.config["gef.main_arena_offset"]) 

+

10475 if libc_base: 

+

10476 dbg(f"Using main_arena_offset={offset:#x} from config") 

+

10477 addr = libc_base + offset 

+

10478 

+

10479 # Verify the found address before returning 

+

10480 if GlibcArena.verify(addr): 

+

10481 return addr 

+

10482 except gdb.error: 

+

10483 pass 

+

10484 

+

10485 # First, try to find `main_arena` symbol directly 

+

10486 try: 

+

10487 return parse_address(f"&{LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME}") 

+

10488 except gdb.error: 

+

10489 pass 

+

10490 

+

10491 # Second, try to find it by offset from `__malloc_hook` 

+

10492 if gef.libc.version < (2, 34): 

+

10493 try: 

+

10494 malloc_hook_addr = parse_address("(void *)&__malloc_hook") 

+

10495 

+

10496 struct_size = ctypes.sizeof(GlibcArena.malloc_state_t()) 

+

10497 

+

10498 if is_x86(): 

+

10499 addr = align_address_to_size(malloc_hook_addr + gef.arch.ptrsize, 0x20) 

+

10500 elif is_arch(Elf.Abi.AARCH64): 

+

10501 addr = malloc_hook_addr - gef.arch.ptrsize*2 - struct_size 

+

10502 elif is_arch(Elf.Abi.ARM): 

+

10503 addr = malloc_hook_addr - gef.arch.ptrsize - struct_size 

+

10504 else: 

+

10505 addr = None 

+

10506 

+

10507 # Verify the found address before returning 

+

10508 if addr and GlibcArena.verify(addr): 

+

10509 return addr 

+

10510 

+

10511 except gdb.error: 

+

10512 pass 

+

10513 

+

10514 # Last resort, try to find it via brute force if enabled in settings 

+

10515 if gef.config["gef.bruteforce_main_arena"]: 

+

10516 alignment = 0x8 

+

10517 try: 

+

10518 dbg("Trying to bruteforce main_arena address") 

+

10519 # setup search_range for `main_arena` to `.data` of glibc 

+

10520 search_filter = lambda f: "libc" in f.filename and f.name == ".data" 

+

10521 dotdata = list(filter(search_filter, get_info_files()))[0] 

+

10522 search_range = range(dotdata.zone_start, dotdata.zone_end, alignment) 

+

10523 # find first possible candidate 

+

10524 for addr in search_range: 

+

10525 if GlibcArena.verify(addr): 

+

10526 dbg(f"Found candidate at {addr:#x}") 

+

10527 return addr 

+

10528 dbg("Bruteforce not successful") 

+

10529 except Exception: 

+

10530 pass 

+

10531 

+

10532 # Nothing helped 

+

10533 err_msg = f"Cannot find main_arena for {gef.arch.arch}. You might want to set a manually found libc offset " 

+

10534 if not gef.config["gef.bruteforce_main_arena"]: 

+

10535 err_msg += "or allow bruteforcing " 

+

10536 err_msg += "through the GEF config." 

+

10537 raise OSError(err_msg) 

+

10538 

+

10539 @property 

+

10540 def selected_arena(self) -> Optional[GlibcArena]: 

+

10541 if not self.__libc_selected_arena: 10541 ↛ 10543line 10541 didn't jump to line 10543, because the condition on line 10541 was never true

+

10542 # `selected_arena` must default to `main_arena` 

+

10543 self.__libc_selected_arena = self.main_arena 

+

10544 return self.__libc_selected_arena 

+

10545 

+

10546 @selected_arena.setter 

+

10547 def selected_arena(self, value: GlibcArena) -> None: 

+

10548 self.__libc_selected_arena = value 

+

10549 return 

+

10550 

+

10551 @property 

+

10552 def arenas(self) -> Union[List, Iterator[GlibcArena]]: 

+

10553 if not self.main_arena: 10553 ↛ 10554line 10553 didn't jump to line 10554, because the condition on line 10553 was never true

+

10554 return [] 

+

10555 return iter(self.main_arena) 

+

10556 

+

10557 @property 

+

10558 def base_address(self) -> Optional[int]: 

+

10559 if not self.__heap_base: 

+

10560 base = 0 

+

10561 try: 

+

10562 base = parse_address("mp_->sbrk_base") 

+

10563 base = self.malloc_align_address(base) 

+

10564 except gdb.error: 

+

10565 # missing symbol, try again 

+

10566 base = 0 

+

10567 if not base: 10567 ↛ 10568line 10567 didn't jump to line 10568, because the condition on line 10567 was never true

+

10568 base = get_section_base_address("[heap]") 

+

10569 self.__heap_base = base 

+

10570 return self.__heap_base 

+

10571 

+

10572 @property 

+

10573 def chunks(self) -> Union[List, Iterator]: 

+

10574 if not self.base_address: 

+

10575 return [] 

+

10576 return iter(GlibcChunk(self.base_address, from_base=True)) 

+

10577 

+

10578 @property 

+

10579 def min_chunk_size(self) -> int: 

+

10580 return 4 * gef.arch.ptrsize 

+

10581 

+

10582 @property 

+

10583 def malloc_alignment(self) -> int: 

+

10584 assert gef.libc.version 

+

10585 __default_malloc_alignment = 0x10 

+

10586 if gef.libc.version >= (2, 26) and is_x86_32(): 10586 ↛ 10589line 10586 didn't jump to line 10589, because the condition on line 10586 was never true

+

10587 # Special case introduced in Glibc 2.26: 

+

10588 # https://elixir.bootlin.com/glibc/glibc-2.26/source/sysdeps/i386/malloc-alignment.h#L22 

+

10589 return __default_malloc_alignment 

+

10590 # Generic case: 

+

10591 # https://elixir.bootlin.com/glibc/glibc-2.26/source/sysdeps/generic/malloc-alignment.h#L22 

+

10592 return 2 * gef.arch.ptrsize 

+

10593 

+

10594 def csize2tidx(self, size: int) -> int: 

+

10595 return abs((size - self.min_chunk_size + self.malloc_alignment - 1)) // self.malloc_alignment 

+

10596 

+

10597 def tidx2size(self, idx: int) -> int: 

+

10598 return idx * self.malloc_alignment + self.min_chunk_size 

+

10599 

+

10600 def malloc_align_address(self, address: int) -> int: 

+

10601 """Align addresses according to glibc's MALLOC_ALIGNMENT. See also Issue #689 on Github""" 

+

10602 malloc_alignment = self.malloc_alignment 

+

10603 ceil = lambda n: int(-1 * n // 1 * -1) 

+

10604 return malloc_alignment * ceil((address / malloc_alignment)) 

+

10605 

+

10606 

+

10607class GefSetting: 

+

10608 """Basic class for storing gef settings as objects""" 

+

10609 READ_ACCESS = 0 

+

10610 WRITE_ACCESS = 1 

+

10611 

+

10612 def __init__(self, value: Any, cls: Optional[type] = None, description: Optional[str] = None, hooks: Optional[Dict[str, Callable]] = None) -> None: 

+

10613 self.value = value 

+

10614 self.type = cls or type(value) 

+

10615 self.description = description or "" 

+

10616 self.hooks: Tuple[List[Callable], List[Callable]] = ([], []) 

+

10617 if hooks: 

+

10618 for access, func in hooks.items(): 

+

10619 if access == "on_read": 10619 ↛ 10620line 10619 didn't jump to line 10620, because the condition on line 10619 was never true

+

10620 idx = GefSetting.READ_ACCESS 

+

10621 elif access == "on_write": 10621 ↛ 10624line 10621 didn't jump to line 10624, because the condition on line 10621 was never false

+

10622 idx = GefSetting.WRITE_ACCESS 

+

10623 else: 

+

10624 raise ValueError 

+

10625 if not callable(func): 10625 ↛ 10626line 10625 didn't jump to line 10626, because the condition on line 10625 was never true

+

10626 raise ValueError(f"hook is not callable") 

+

10627 self.hooks[idx].append(func) 

+

10628 return 

+

10629 

+

10630 def __str__(self) -> str: 

+

10631 return f"Setting(type={self.type.__name__}, value='{self.value}', desc='{self.description[:10]}...', "\ 

+

10632 f"read_hooks={len(self.hooks[GefSetting.READ_ACCESS])}, write_hooks={len(self.hooks[GefSetting.READ_ACCESS])})" 

+

10633 

+

10634 

+

10635class GefSettingsManager(dict): 

+

10636 """ 

+

10637 GefSettings acts as a dict where the global settings are stored and can be read, written or deleted as any other dict. 

+

10638 For instance, to read a specific command setting: `gef.config[mycommand.mysetting]` 

+

10639 """ 

+

10640 def __getitem__(self, name: str) -> Any: 

+

10641 setting : GefSetting = super().__getitem__(name) 

+

10642 self.__invoke_read_hooks(setting) 

+

10643 return setting.value 

+

10644 

+

10645 def __setitem__(self, name: str, value: Any) -> None: 

+

10646 # check if the key exists 

+

10647 if super().__contains__(name): 

+

10648 # if so, update its value directly 

+

10649 setting = super().__getitem__(name) 

+

10650 if not isinstance(setting, GefSetting): raise ValueError 10650 ↛ exitline 10650 didn't except from function '__setitem__', because the raise on line 10650 wasn't executed

+

10651 setting.value = setting.type(value) 

+

10652 else: 

+

10653 # if not, `value` must be a GefSetting 

+

10654 if not isinstance(value, GefSetting): raise Exception("Invalid argument") 10654 ↛ exitline 10654 didn't except from function '__setitem__', because the raise on line 10654 wasn't executed

+

10655 if not value.type: raise Exception("Invalid type") 10655 ↛ exitline 10655 didn't except from function '__setitem__', because the raise on line 10655 wasn't executed

+

10656 if not value.description: raise Exception("Invalid description") 10656 ↛ exitline 10656 didn't except from function '__setitem__', because the raise on line 10656 wasn't executed

+

10657 setting = value 

+

10658 super().__setitem__(name, setting) 

+

10659 self.__invoke_write_hooks(setting) 

+

10660 return 

+

10661 

+

10662 def __delitem__(self, name: str) -> None: 

+

10663 super().__delitem__(name) 

+

10664 return 

+

10665 

+

10666 def raw_entry(self, name: str) -> GefSetting: 

+

10667 return super().__getitem__(name) 

+

10668 

+

10669 def __invoke_read_hooks(self, setting: GefSetting) -> None: 

+

10670 self.__invoke_hooks(is_write=False, setting=setting) 

+

10671 return 

+

10672 

+

10673 def __invoke_write_hooks(self, setting: GefSetting) -> None: 

+

10674 self.__invoke_hooks(is_write=True, setting=setting) 

+

10675 return 

+

10676 

+

10677 def __invoke_hooks(self, is_write: bool, setting: GefSetting) -> None: 

+

10678 if not setting.hooks: 10678 ↛ 10679line 10678 didn't jump to line 10679, because the condition on line 10678 was never true

+

10679 return 

+

10680 idx = int(is_write) 

+

10681 if setting.hooks[idx]: 

+

10682 for callback in setting.hooks[idx]: 

+

10683 callback() 

+

10684 return 

+

10685 

+

10686 

+

10687class GefSessionManager(GefManager): 

+

10688 """Class managing the runtime properties of GEF. """ 

+

10689 def __init__(self) -> None: 

+

10690 self.reset_caches() 

+

10691 self.remote: Optional["GefRemoteSessionManager"] = None 

+

10692 self.remote_initializing: bool = False 

+

10693 self.qemu_mode: bool = False 

+

10694 self.convenience_vars_index: int = 0 

+

10695 self.heap_allocated_chunks: List[Tuple[int, int]] = [] 

+

10696 self.heap_freed_chunks: List[Tuple[int, int]] = [] 

+

10697 self.heap_uaf_watchpoints: List[UafWatchpoint] = [] 

+

10698 self.pie_breakpoints: Dict[int, PieVirtualBreakpoint] = {} 

+

10699 self.pie_counter: int = 1 

+

10700 self.aliases: List[GefAlias] = [] 

+

10701 self.modules: List[FileFormat] = [] 

+

10702 self.constants = {} # a dict for runtime constants (like 3rd party file paths) 

+

10703 for constant in ("python3", "readelf", "file", "ps"): 

+

10704 self.constants[constant] = which(constant) 

+

10705 return 

+

10706 

+

10707 def reset_caches(self) -> None: 

+

10708 super().reset_caches() 

+

10709 self._auxiliary_vector = None 

+

10710 self._pagesize = None 

+

10711 self._os = None 

+

10712 self._pid = None 

+

10713 self._file = None 

+

10714 self._maps: Optional[pathlib.Path] = None 

+

10715 self._root: Optional[pathlib.Path] = None 

+

10716 return 

+

10717 

+

10718 def __str__(self) -> str: 

+

10719 return f"Session({'Local' if self.remote is None else 'Remote'}, pid={self.pid or 'Not running'}, os='{self.os}')" 

+

10720 

+

10721 @property 

+

10722 def auxiliary_vector(self) -> Optional[Dict[str, int]]: 

+

10723 if not is_alive(): 

+

10724 return None 

+

10725 if is_qemu_system(): 10725 ↛ 10726line 10725 didn't jump to line 10726, because the condition on line 10725 was never true

+

10726 return None 

+

10727 if not self._auxiliary_vector: 

+

10728 auxiliary_vector = {} 

+

10729 auxv_info = gdb.execute("info auxv", to_string=True) 

+

10730 if not auxv_info or "failed" in auxv_info: 10730 ↛ 10731line 10730 didn't jump to line 10731, because the condition on line 10730 was never true

+

10731 err("Failed to query auxiliary variables") 

+

10732 return None 

+

10733 for line in auxv_info.splitlines(): 

+

10734 line = line.split('"')[0].strip() # remove the ending string (if any) 

+

10735 line = line.split() # split the string by whitespace(s) 

+

10736 if len(line) < 4: 10736 ↛ 10737line 10736 didn't jump to line 10737, because the condition on line 10736 was never true

+

10737 continue 

+

10738 __av_type = line[1] 

+

10739 __av_value = line[-1] 

+

10740 auxiliary_vector[__av_type] = int(__av_value, base=0) 

+

10741 self._auxiliary_vector = auxiliary_vector 

+

10742 return self._auxiliary_vector 

+

10743 

+

10744 @property 

+

10745 def os(self) -> str: 

+

10746 """Return the current OS.""" 

+

10747 if not self._os: 

+

10748 self._os = platform.system().lower() 

+

10749 return self._os 

+

10750 

+

10751 @property 

+

10752 def pid(self) -> int: 

+

10753 """Return the PID of the target process.""" 

+

10754 if not self._pid: 

+

10755 pid = gdb.selected_inferior().pid if not gef.session.qemu_mode else gdb.selected_thread().ptid[1] 

+

10756 if not pid: 

+

10757 raise RuntimeError("cannot retrieve PID for target process") 

+

10758 self._pid = pid 

+

10759 return self._pid 

+

10760 

+

10761 @property 

+

10762 def file(self) -> Optional[pathlib.Path]: 

+

10763 """Return a Path object of the target process.""" 

+

10764 if gef.session.remote is not None: 

+

10765 return gef.session.remote.file 

+

10766 fpath: str = gdb.current_progspace().filename 

+

10767 if fpath and not self._file: 

+

10768 self._file = pathlib.Path(fpath).expanduser() 

+

10769 return self._file 

+

10770 

+

10771 @property 

+

10772 def cwd(self) -> Optional[pathlib.Path]: 

+

10773 if gef.session.remote is not None: 

+

10774 return gef.session.remote.root 

+

10775 return self.file.parent if self.file else None 

+

10776 

+

10777 @property 

+

10778 def pagesize(self) -> int: 

+

10779 """Get the system page size""" 

+

10780 auxval = self.auxiliary_vector 

+

10781 if not auxval: 

+

10782 return DEFAULT_PAGE_SIZE 

+

10783 self._pagesize = auxval["AT_PAGESZ"] 

+

10784 return self._pagesize 

+

10785 

+

10786 @property 

+

10787 def canary(self) -> Optional[Tuple[int, int]]: 

+

10788 """Return a tuple of the canary address and value, read from the canonical 

+

10789 location if supported by the architecture. Otherwise, read from the auxiliary 

+

10790 vector.""" 

+

10791 try: 

+

10792 canary_location = gef.arch.canary_address() 

+

10793 canary = gef.memory.read_integer(canary_location) 

+

10794 except NotImplementedError: 

+

10795 # Fall back to `AT_RANDOM`, which is the original source 

+

10796 # of the canary value but not the canonical location 

+

10797 return self.original_canary 

+

10798 return canary, canary_location 

+

10799 

+

10800 @property 

+

10801 def original_canary(self) -> Optional[Tuple[int, int]]: 

+

10802 """Return a tuple of the initial canary address and value, read from the 

+

10803 auxiliary vector.""" 

+

10804 auxval = self.auxiliary_vector 

+

10805 if not auxval: 

+

10806 return None 

+

10807 canary_location = auxval["AT_RANDOM"] 

+

10808 canary = gef.memory.read_integer(canary_location) 

+

10809 canary &= ~0xFF 

+

10810 return canary, canary_location 

+

10811 

+

10812 

+

10813 @property 

+

10814 def maps(self) -> Optional[pathlib.Path]: 

+

10815 """Returns the Path to the procfs entry for the memory mapping.""" 

+

10816 if not is_alive(): 

+

10817 return None 

+

10818 if not self._maps: 

+

10819 if gef.session.remote is not None: 

+

10820 self._maps = gef.session.remote.maps 

+

10821 else: 

+

10822 self._maps = pathlib.Path(f"/proc/{self.pid}/maps") 

+

10823 return self._maps 

+

10824 

+

10825 @property 

+

10826 def root(self) -> Optional[pathlib.Path]: 

+

10827 """Returns the path to the process's root directory.""" 

+

10828 if not is_alive(): 

+

10829 return None 

+

10830 if not self._root: 

+

10831 self._root = pathlib.Path(f"/proc/{self.pid}/root") 

+

10832 return self._root 

+

10833 

+

10834class GefRemoteSessionManager(GefSessionManager): 

+

10835 """Class for managing remote sessions with GEF. It will create a temporary environment 

+

10836 designed to clone the remote one.""" 

+

10837 def __init__(self, host: str, port: int, pid: int =-1, qemu: Optional[pathlib.Path] = None) -> None: 

+

10838 super().__init__() 

+

10839 self.__host = host 

+

10840 self.__port = port 

+

10841 self.__local_root_fd = tempfile.TemporaryDirectory() 

+

10842 self.__local_root_path = pathlib.Path(self.__local_root_fd.name) 

+

10843 self.__qemu = qemu 

+

10844 dbg(f"[remote] initializing remote session with {self.target} under {self.root}") 

+

10845 if not self.connect(pid): 10845 ↛ 10846line 10845 didn't jump to line 10846, because the condition on line 10845 was never true

+

10846 raise EnvironmentError(f"Cannot connect to remote target {self.target}") 

+

10847 if not self.setup(): 10847 ↛ 10848line 10847 didn't jump to line 10848, because the condition on line 10847 was never true

+

10848 raise EnvironmentError(f"Failed to create a proper environment for {self.target}") 

+

10849 return 

+

10850 

+

10851 def close(self) -> None: 

+

10852 self.__local_root_fd.cleanup() 

+

10853 try: 

+

10854 gef_on_new_unhook(self.remote_objfile_event_handler) 

+

10855 gef_on_new_hook(new_objfile_handler) 

+

10856 except Exception as e: 

+

10857 warn(f"Exception while restoring local context: {str(e)}") 

+

10858 return 

+

10859 

+

10860 def in_qemu_user(self) -> bool: 

+

10861 return self.__qemu is not None 

+

10862 

+

10863 def __str__(self) -> str: 

+

10864 return f"RemoteSession(target='{self.target}', local='{self.root}', pid={self.pid}, qemu_user={bool(self.in_qemu_user())})" 

+

10865 

+

10866 @property 

+

10867 def target(self) -> str: 

+

10868 return f"{self.__host}:{self.__port}" 

+

10869 

+

10870 @property 

+

10871 def root(self) -> pathlib.Path: 

+

10872 return self.__local_root_path.absolute() 

+

10873 

+

10874 @property 

+

10875 def file(self) -> pathlib.Path: 

+

10876 """Path to the file being debugged as seen by the remote endpoint.""" 

+

10877 if not self._file: 

+

10878 filename = gdb.current_progspace().filename 

+

10879 if not filename: 10879 ↛ 10880line 10879 didn't jump to line 10880, because the condition on line 10879 was never true

+

10880 raise RuntimeError("No session started") 

+

10881 start_idx = len("target:") if filename.startswith("target:") else 0 

+

10882 self._file = pathlib.Path(filename[start_idx:]) 

+

10883 return self._file 

+

10884 

+

10885 @property 

+

10886 def lfile(self) -> pathlib.Path: 

+

10887 """Local path to the file being debugged.""" 

+

10888 return self.root / str(self.file).lstrip("/") 

+

10889 

+

10890 @property 

+

10891 def maps(self) -> pathlib.Path: 

+

10892 if not self._maps: 

+

10893 self._maps = self.root / f"proc/{self.pid}/maps" 

+

10894 return self._maps 

+

10895 

+

10896 def sync(self, src: str, dst: Optional[str] = None) -> bool: 

+

10897 """Copy the `src` into the temporary chroot. If `dst` is provided, that path will be 

+

10898 used instead of `src`.""" 

+

10899 if not dst: 

+

10900 dst = src 

+

10901 tgt = self.root / dst.lstrip("/") 

+

10902 if tgt.exists(): 10902 ↛ 10903line 10902 didn't jump to line 10903, because the condition on line 10902 was never true

+

10903 return True 

+

10904 tgt.parent.mkdir(parents=True, exist_ok=True) 

+

10905 dbg(f"[remote] downloading '{src}' -> '{tgt}'") 

+

10906 gdb.execute(f"remote get {src} {tgt.absolute()}") 

+

10907 return tgt.exists() 

+

10908 

+

10909 def connect(self, pid: int) -> bool: 

+

10910 """Connect to remote target. If in extended mode, also attach to the given PID.""" 

+

10911 # before anything, register our new hook to download files from the remote target 

+

10912 dbg(f"[remote] Installing new objfile handlers") 

+

10913 gef_on_new_unhook(new_objfile_handler) 

+

10914 gef_on_new_hook(self.remote_objfile_event_handler) 

+

10915 

+

10916 # then attempt to connect 

+

10917 is_extended_mode = (pid > -1) 

+

10918 dbg(f"[remote] Enabling extended remote: {bool(is_extended_mode)}") 

+

10919 try: 

+

10920 with DisableContextOutputContext(): 

+

10921 cmd = f"target {'extended-' if is_extended_mode else ''}remote {self.target}" 

+

10922 dbg(f"[remote] Executing '{cmd}'") 

+

10923 gdb.execute(cmd) 

+

10924 if is_extended_mode: 10924 ↛ 10925line 10924 didn't jump to line 10925, because the condition on line 10924 was never true

+

10925 gdb.execute(f"attach {pid:d}") 

+

10926 return True 

+

10927 except Exception as e: 

+

10928 err(f"Failed to connect to {self.target}: {e}") 

+

10929 

+

10930 # a failure will trigger the cleanup, deleting our hook anyway 

+

10931 return False 

+

10932 

+

10933 def setup(self) -> bool: 

+

10934 # setup remote adequately depending on remote or qemu mode 

+

10935 if self.in_qemu_user(): 

+

10936 dbg(f"Setting up as qemu session, target={self.__qemu}") 

+

10937 self.__setup_qemu() 

+

10938 else: 

+

10939 dbg(f"Setting up as remote session") 

+

10940 self.__setup_remote() 

+

10941 

+

10942 # refresh gef to consider the binary 

+

10943 reset_all_caches() 

+

10944 gef.binary = Elf(self.lfile) 

+

10945 reset_architecture() 

+

10946 return True 

+

10947 

+

10948 def __setup_qemu(self) -> bool: 

+

10949 # setup emulated file in the chroot 

+

10950 assert self.__qemu 

+

10951 target = self.root / str(self.__qemu.parent).lstrip("/") 

+

10952 target.mkdir(parents=True, exist_ok=False) 

+

10953 shutil.copy2(self.__qemu, target) 

+

10954 self._file = self.__qemu 

+

10955 assert self.lfile.exists() 

+

10956 

+

10957 # create a procfs 

+

10958 procfs = self.root / f"proc/{self.pid}/" 

+

10959 procfs.mkdir(parents=True, exist_ok=True) 

+

10960 

+

10961 ## /proc/pid/cmdline 

+

10962 cmdline = procfs / "cmdline" 

+

10963 if not cmdline.exists(): 10963 ↛ 10968line 10963 didn't jump to line 10968, because the condition on line 10963 was never false

+

10964 with cmdline.open("w") as fd: 

+

10965 fd.write("") 

+

10966 

+

10967 ## /proc/pid/environ 

+

10968 environ = procfs / "environ" 

+

10969 if not environ.exists(): 10969 ↛ 10974line 10969 didn't jump to line 10974, because the condition on line 10969 was never false

+

10970 with environ.open("wb") as fd: 

+

10971 fd.write(b"PATH=/bin\x00HOME=/tmp\x00") 

+

10972 

+

10973 ## /proc/pid/maps 

+

10974 maps = procfs / "maps" 

+

10975 if not maps.exists(): 10975 ↛ 10980line 10975 didn't jump to line 10980, because the condition on line 10975 was never false

+

10976 with maps.open("w") as fd: 

+

10977 fname = self.file.absolute() 

+

10978 mem_range = "00000000-ffffffff" if is_32bit() else "0000000000000000-ffffffffffffffff" 

+

10979 fd.write(f"{mem_range} rwxp 00000000 00:00 0 {fname}\n") 

+

10980 return True 

+

10981 

+

10982 def __setup_remote(self) -> bool: 

+

10983 # get the file 

+

10984 fpath = f"/proc/{self.pid}/exe" 

+

10985 if not self.sync(fpath, str(self.file)): 10985 ↛ 10986line 10985 didn't jump to line 10986, because the condition on line 10985 was never true

+

10986 err(f"'{fpath}' could not be fetched on the remote system.") 

+

10987 return False 

+

10988 

+

10989 # pseudo procfs 

+

10990 for _file in ("maps", "environ", "cmdline"): 

+

10991 fpath = f"/proc/{self.pid}/{_file}" 

+

10992 if not self.sync(fpath): 10992 ↛ 10993line 10992 didn't jump to line 10993, because the condition on line 10992 was never true

+

10993 err(f"'{fpath}' could not be fetched on the remote system.") 

+

10994 return False 

+

10995 

+

10996 # makeup a fake mem mapping in case we failed to retrieve it 

+

10997 maps = self.root / f"proc/{self.pid}/maps" 

+

10998 if not maps.exists(): 10998 ↛ 10999line 10998 didn't jump to line 10999, because the condition on line 10998 was never true

+

10999 with maps.open("w") as fd: 

+

11000 fname = self.file.absolute() 

+

11001 mem_range = "00000000-ffffffff" if is_32bit() else "0000000000000000-ffffffffffffffff" 

+

11002 fd.write(f"{mem_range} rwxp 00000000 00:00 0 {fname}\n") 

+

11003 return True 

+

11004 

+

11005 def remote_objfile_event_handler(self, evt: "gdb.NewObjFileEvent") -> None: 

+

11006 dbg(f"[remote] in remote_objfile_handler({evt.new_objfile.filename if evt else 'None'}))") 

+

11007 if not evt or not evt.new_objfile.filename: 11007 ↛ 11008line 11007 didn't jump to line 11008, because the condition on line 11007 was never true

+

11008 return 

+

11009 if not evt.new_objfile.filename.startswith("target:") and not evt.new_objfile.filename.startswith("/"): 

+

11010 warn(f"[remote] skipping '{evt.new_objfile.filename}'") 

+

11011 return 

+

11012 if evt.new_objfile.filename.startswith("target:"): 

+

11013 src: str = evt.new_objfile.filename[len("target:"):] 

+

11014 if not self.sync(src): 11014 ↛ 11015line 11014 didn't jump to line 11015, because the condition on line 11014 was never true

+

11015 raise FileNotFoundError(f"Failed to sync '{src}'") 

+

11016 return 

+

11017 

+

11018 

+

11019class GefUiManager(GefManager): 

+

11020 """Class managing UI settings.""" 

+

11021 def __init__(self) -> None: 

+

11022 self.redirect_fd : Optional[TextIOWrapper] = None 

+

11023 self.context_hidden = False 

+

11024 self.stream_buffer : Optional[StringIO] = None 

+

11025 self.highlight_table: Dict[str, str] = {} 

+

11026 self.watches: Dict[int, Tuple[int, str]] = {} 

+

11027 self.context_messages: List[Tuple[str, str]] = [] 

+

11028 return 

+

11029 

+

11030 

+

11031class GefLibcManager(GefManager): 

+

11032 """Class managing everything libc-related (except heap).""" 

+

11033 def __init__(self) -> None: 

+

11034 self._version : Optional[Tuple[int, int]] = None 

+

11035 return 

+

11036 

+

11037 def __str__(self) -> str: 

+

11038 return f"Libc(version='{self.version}')" 

+

11039 

+

11040 @property 

+

11041 def version(self) -> Optional[Tuple[int, int]]: 

+

11042 if not is_alive(): 11042 ↛ 11043line 11042 didn't jump to line 11043, because the condition on line 11042 was never true

+

11043 return None 

+

11044 if not self._version: 

+

11045 self._version = GefLibcManager.find_libc_version() 

+

11046 return self._version 

+

11047 

+

11048 @staticmethod 

+

11049 @lru_cache() 

+

11050 def find_libc_version() -> Tuple[int, ...]: 

+

11051 sections = gef.memory.maps 

+

11052 for section in sections: 11052 ↛ 11065line 11052 didn't jump to line 11065, because the loop on line 11052 didn't complete

+

11053 match = re.search(r"libc6?[-_](\d+)\.(\d+)\.so", section.path) 

+

11054 if match: 11054 ↛ 11055line 11054 didn't jump to line 11055, because the condition on line 11054 was never true

+

11055 return tuple(int(_) for _ in match.groups()) 

+

11056 if "libc" in section.path: 

+

11057 try: 

+

11058 with open(section.path, "rb") as f: 

+

11059 data = f.read() 

+

11060 except OSError: 

+

11061 continue 

+

11062 match = re.search(PATTERN_LIBC_VERSION, data) 

+

11063 if match: 11063 ↛ 11052line 11063 didn't jump to line 11052, because the condition on line 11063 was never false

+

11064 return tuple(int(_) for _ in match.groups()) 

+

11065 return 0, 0 

+

11066 

+

11067 

+

11068 

+

11069 

+

11070class Gef: 

+

11071 """The GEF root class, which serves as a entrypoint for all the debugging session attributes (architecture, 

+

11072 memory, settings, etc.).""" 

+

11073 binary: Optional[FileFormat] 

+

11074 arch: Architecture 

+

11075 config : GefSettingsManager 

+

11076 ui: GefUiManager 

+

11077 libc: GefLibcManager 

+

11078 memory : GefMemoryManager 

+

11079 heap : GefHeapManager 

+

11080 session : GefSessionManager 

+

11081 gdb: GefCommand 

+

11082 

+

11083 def __init__(self) -> None: 

+

11084 self.binary: Optional[FileFormat] = None 

+

11085 self.arch: Architecture = GenericArchitecture() # see PR #516, will be reset by `new_objfile_handler` 

+

11086 self.config = GefSettingsManager() 

+

11087 self.ui = GefUiManager() 

+

11088 self.libc = GefLibcManager() 

+

11089 return 

+

11090 

+

11091 def __str__(self) -> str: 

+

11092 return f"Gef(binary='{self.binary or 'None'}', arch={self.arch})" 

+

11093 

+

11094 def reinitialize_managers(self) -> None: 

+

11095 """Reinitialize the managers. Avoid calling this function directly, using `pi reset()` is preferred""" 

+

11096 self.memory = GefMemoryManager() 

+

11097 self.heap = GefHeapManager() 

+

11098 self.session = GefSessionManager() 

+

11099 return 

+

11100 

+

11101 def setup(self) -> None: 

+

11102 """Setup initialize the runtime setup, which may require for the `gef` to be not None.""" 

+

11103 self.reinitialize_managers() 

+

11104 self.gdb = GefCommand() 

+

11105 self.gdb.setup() 

+

11106 tempdir = self.config["gef.tempdir"] 

+

11107 gef_makedirs(tempdir) 

+

11108 gdb.execute(f"save gdb-index {tempdir}") 

+

11109 return 

+

11110 

+

11111 def reset_caches(self) -> None: 

+

11112 """Recursively clean the cache of all the managers. Avoid calling this function directly, using `reset-cache` 

+

11113 is preferred""" 

+

11114 for mgr in (self.memory, self.heap, self.session, self.arch): 

+

11115 mgr.reset_caches() 

+

11116 return 

+

11117 

+

11118 

+

11119if __name__ == "__main__": 11119 ↛ exitline 11119 didn't jump to the function exit

+

11120 if sys.version_info[0] == 2: 11120 ↛ 11121line 11120 didn't jump to line 11121, because the condition on line 11120 was never true

+

11121 err("GEF has dropped Python2 support for GDB when it reached EOL on 2020/01/01.") 

+

11122 err("If you require GEF for GDB+Python2, use https://github.com/hugsy/gef-legacy.") 

+

11123 exit(1) 

+

11124 

+

11125 if GDB_VERSION < GDB_MIN_VERSION or PYTHON_VERSION < PYTHON_MIN_VERSION: 11125 ↛ 11126line 11125 didn't jump to line 11126, because the condition on line 11125 was never true

+

11126 err("You're using an old version of GDB. GEF will not work correctly. " 

+

11127 f"Consider updating to GDB {'.'.join(map(str, GDB_MIN_VERSION))} or higher " 

+

11128 f"(with Python {'.'.join(map(str, PYTHON_MIN_VERSION))} or higher).") 

+

11129 exit(1) 

+

11130 

+

11131 try: 

+

11132 pyenv = which("pyenv") 

+

11133 PYENV_ROOT = gef_pystring(subprocess.check_output([pyenv, "root"]).strip()) 

+

11134 PYENV_VERSION = gef_pystring(subprocess.check_output([pyenv, "version-name"]).strip()) 

+

11135 site_packages_dir = os.path.join(PYENV_ROOT, "versions", PYENV_VERSION, "lib", 

+

11136 f"python{PYENV_VERSION[:3]}", "site-packages") 

+

11137 site.addsitedir(site_packages_dir) 

+

11138 except FileNotFoundError: 

+

11139 pass 

+

11140 

+

11141 # When using a Python virtual environment, GDB still loads the system-installed Python 

+

11142 # so GEF doesn't load site-packages dir from environment 

+

11143 # In order to fix it, from the shell with venv activated we run the python binary, 

+

11144 # take and parse its path, add the path to the current python process using sys.path.extend 

+

11145 PYTHONBIN = which("python3") 

+

11146 PREFIX = gef_pystring(subprocess.check_output([PYTHONBIN, '-c', 'import os, sys;print((sys.prefix))'])).strip("\\n") 

+

11147 if PREFIX != sys.base_prefix: 11147 ↛ 11148line 11147 didn't jump to line 11148, because the condition on line 11147 was never true

+

11148 SITE_PACKAGES_DIRS = subprocess.check_output( 

+

11149 [PYTHONBIN, "-c", "import os, sys;print(os.linesep.join(sys.path).strip())"]).decode("utf-8").split() 

+

11150 sys.path.extend(SITE_PACKAGES_DIRS) 

+

11151 

+

11152 # setup config 

+

11153 gdb_initial_settings = ( 

+

11154 "set confirm off", 

+

11155 "set verbose off", 

+

11156 "set pagination off", 

+

11157 "set print elements 0", 

+

11158 "set history save on", 

+

11159 f"set history filename {os.getenv('GDBHISTFILE', '~/.gdb_history')}", 

+

11160 "set output-radix 0x10", 

+

11161 "set print pretty on", 

+

11162 "set disassembly-flavor intel", 

+

11163 "handle SIGALRM print nopass", 

+

11164 ) 

+

11165 for cmd in gdb_initial_settings: 

+

11166 try: 

+

11167 gdb.execute(cmd) 

+

11168 except gdb.error: 

+

11169 pass 

+

11170 

+

11171 # load GEF, set up the managers and load the plugins, functions, 

+

11172 reset() 

+

11173 gef.gdb.load() 

+

11174 gef.gdb.show_banner() 

+

11175 

+

11176 # load config 

+

11177 gef.gdb.load_extra_plugins() 

+

11178 

+

11179 # setup gdb prompt 

+

11180 gdb.prompt_hook = __gef_prompt__ 

+

11181 

+

11182 # gdb events configuration 

+

11183 gef_on_continue_hook(continue_handler) 

+

11184 gef_on_stop_hook(hook_stop_handler) 

+

11185 gef_on_new_hook(new_objfile_handler) 

+

11186 gef_on_exit_hook(exit_handler) 

+

11187 gef_on_memchanged_hook(memchanged_handler) 

+

11188 gef_on_regchanged_hook(regchanged_handler) 

+

11189 

+

11190 progspace = gdb.current_progspace() 

+

11191 if progspace and progspace.filename: 11191 ↛ 11195line 11191 didn't jump to line 11195, because the condition on line 11191 was never false

+

11192 # if here, we are sourcing gef from a gdb session already attached, force call to new_objfile (see issue #278) 

+

11193 new_objfile_handler(None) 

+

11194 

+

11195 GefTmuxSetup() 

+

11196 

+

11197 # `target remote` commands cannot be disabled, so print a warning message instead 

+

11198 errmsg = "Using `target remote` with GEF does not work, use `gef-remote` instead. You've been warned." 

+

11199 gdb.execute(f"define target hook-remote\n pi if calling_function() != \"connect\": err(\"{errmsg}\") \nend") 

+

11200 gdb.execute(f"define target hook-extended-remote\n pi if calling_function() != \"connect\": err(\"{errmsg}\") \nend") 

+

11201 

+

11202 # restore saved breakpoints (if any) 

+

11203 bkp_fpath = pathlib.Path(gef.config["gef.autosave_breakpoints_file"]).expanduser().absolute() 

+

11204 if bkp_fpath.exists() and bkp_fpath.is_file(): 11204 ↛ 11205line 11204 didn't jump to line 11205, because the condition on line 11204 was never true

+

11205 gdb.execute(f"source {bkp_fpath}") 

+
+ + + diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 000000000..7693c3608 --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,110 @@ + + + + + Coverage report + + + + + +
+
+

Coverage report: + 71.5684% +

+ +
+ +
+

+ coverage.py v7.2.7, + created at 2023-08-01 03:12 +0000 +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Modulestatementsmissingexcludedbranchespartialcoverage
gef.py757218270254041871.5684%
Total757218270254041871.5684%
+

+ No items found using the specified filter. +

+
+ + + diff --git a/coverage/keybd_closed.png b/coverage/keybd_closed.png new file mode 100644 index 0000000000000000000000000000000000000000..ba119c47df81ed2bbd27a06988abf700139c4f99 GIT binary patch literal 9004 zcmeHLc{tSF+aIY=A^R4_poB4tZAN2XC;O7M(inrW3}(h&Q4}dl*&-65$i9^&vW6_# zcM4g`Qix=GhkBl;=lwnJ@Ap2}^}hc-b6vBXb3XUyzR%~}_c`-Dw+!?&>5p(90RRB> zXe~7($~PP3eT?=X<@3~Q1w84vX~IoSx~1#~02+TopXK(db;4v6!{+W`RHLkkHO zo;+s?)puc`+$yOwHv>I$5^8v^F3<|$44HA8AFnFB0cAP|C`p}aSMJK*-CUB{eQ!;K z-9Ju3OQ+xVPr3P#o4>_lNBT;M+1vgV&B~6!naOGHb-LFA9TkfHv1IFA1Y!Iz!Zl3) z%c#-^zNWPq7U_}6I7aHSmFWi125RZrNBKyvnV^?64)zviS;E!UD%LaGRl6@zn!3E{ zJ`B$5``cH_3a)t1#6I7d==JeB_IcSU%=I#DrRCBGm8GvCmA=+XHEvC2SIfsNa0(h9 z7P^C4U`W@@`9p>2f^zyb5B=lpc*RZMn-%%IqrxSWQF8{ec3i?-AB(_IVe z)XgT>Y^u41MwOMFvU=I4?!^#jaS-%bjnx@ zmL44yVEslR_ynm18F!u}Ru#moEn3EE?1=9@$B1Z5aLi5b8{&?V(IAYBzIar!SiY3< z`l0V)djHtrImy}(!7x-Pmq+njM)JFQ9mx*(C+9a3M)(_SW|lrN=gfxFhStu^zvynS zm@gl;>d8i8wpUkX42vS3BEzE3-yctH%t0#N%s+6-&_<*Fe7+h=`=FM?DOg1)eGL~~ zQvIFm$D*lqEh07XrXY=jb%hdyP4)`wyMCb$=-z9(lOme9=tirVkb)_GOl2MJn;=Ky z^0pV1owR7KP-BSxhI@@@+gG0roD-kXE1;!#R7KY1QiUbyDdTElm|ul7{mMdF1%UDJ z_vp=Vo!TCF?D*?u% zk~}4!xK2MSQd-QKC0${G=ZRv2x8%8ZqdfR!?Dv=5Mj^8WU)?iH;C?o6rSQy*^YwQb zf@5V)q=xah#a3UEIBC~N7on(p4jQd4K$|i7k`d8mw|M{Mxapl46Z^X^9U}JgqH#;T z`CTzafpMD+J-LjzF+3Xau>xM_sXisRj6m-287~i9g|%gHc}v77>n_+p7ZgmJszx!b zSmL4wV;&*5Z|zaCk`rOYFdOjZLLQr!WSV6AlaqYh_OE)>rYdtx`gk$yAMO=-E1b~J zIZY6gM*}1UWsJ)TW(pf1=h?lJy_0TFOr|nALGW>$IE1E7z+$`^2WJY+>$$nJo8Rs` z)xS>AH{N~X3+b=2+8Q_|n(1JoGv55r>TuwBV~MXE&9?3Zw>cIxnOPNs#gh~C4Zo=k z&!s;5)^6UG>!`?hh0Q|r|Qbm>}pgtOt23Vh!NSibozH$`#LSiYL)HR4bkfEJMa zBHwC3TaHx|BzD|MXAr>mm&FbZXeEX-=W}Ji&!pji4sO$#0Wk^Q7j%{8#bJPn$C=E% zPlB}0)@Ti^r_HMJrTMN?9~4LQbIiUiOKBVNm_QjABKY4;zC88yVjvB>ZETNzr%^(~ zI3U&Ont?P`r&4 z#Bp)jcVV_N_{c1_qW}_`dQm)D`NG?h{+S!YOaUgWna4i8SuoLcXAZ|#Jh&GNn7B}3 z?vZ8I{LpmCYT=@6)dLPd@|(;d<08ufov%+V?$mgUYQHYTrc%eA=CDUzK}v|G&9}yJ z)|g*=+RH1IQ>rvkY9UIam=fkxWDyGIKQ2RU{GqOQjD8nG#sl+$V=?wpzJdT=wlNWr z1%lw&+;kVs(z?e=YRWRA&jc75rQ~({*TS<( z8X!j>B}?Bxrrp%wEE7yBefQ?*nM20~+ZoQK(NO_wA`RNhsqVkXHy|sod@mqen=B#@ zmLi=x2*o9rWqTMWoB&qdZph$~qkJJTVNc*8^hU?gH_fY{GYPEBE8Q{j0Y$tvjMv%3 z)j#EyBf^7n)2d8IXDYX2O0S%ZTnGhg4Ss#sEIATKpE_E4TU=GimrD5F6K(%*+T-!o z?Se7^Vm`$ZKDwq+=~jf?w0qC$Kr&R-;IF#{iLF*8zKu8(=#chRO;>x zdM;h{i{RLpJgS!B-ueTFs8&4U4+D8|7nP~UZ@P`J;*0sj^#f_WqT#xpA?@qHonGB& zQ<^;OLtOG1w#)N~&@b0caUL7syAsAxV#R`n>-+eVL9aZwnlklzE>-6!1#!tVA`uNo z>Gv^P)sohc~g_1YMC;^f(N<{2y5C^;QCEXo;LQ^#$0 zr>jCrdoeXuff!dJ^`#=Wy2Gumo^Qt7BZrI~G+Pyl_kL>is3P0^JlE;Sjm-YfF~I>t z_KeNpK|5U&F4;v?WS&#l(jxUWDarfcIcl=-6!8>^S`57!M6;hZea5IFA@)2+*Rt85 zi-MBs_b^DU8LygXXQGkG+86N7<%M|baM(orG*ASffC`p!?@m{qd}IcYmZyi^d}#Q& zNjk-0@CajpUI-gPm20ERVDO!L8@p`tMJ69FD(ASIkdoLdiRV6h9TPKRz>2WK4upHd z6OZK33EP?`GoJkXh)S035}uLUO$;TlXwNdMg-WOhLB)7a`-%*a9lFmjf6n+4ZmIHN z-V@$ z8PXsoR4*`5RwXz=A8|5;aXKtSHFccj%dG7cO~UBJnt)61K>-uPX)`vu{7fcX6_>zZ zw_2V&Li+7mxbf!f7{Rk&VVyY!UtZywac%g!cH+xh#j$a`uf?XWl<``t`36W;p7=_* zO6uf~2{sAdkZn=Ts@p0>8N8rzw2ZLS@$ibV-c-QmG@%|3gUUrRxu=e*ekhTa+f?8q z3$JVGPr9w$VQG~QCq~Y=2ThLIH!T@(>{NihJ6nj*HA_C#Popv)CBa)+UI-bx8u8zfCT^*1|k z&N9oFYsZEijPn31Yx_yO5pFs>0tOAV=oRx~Wpy5ie&S_449m4R^{LWQMA~}vocV1O zIf#1ZV85E>tvZE4mz~zn{hs!pkIQM;EvZMimqiPAJu-9P@mId&nb$lsrICS=)zU3~ zn>a#9>}5*3N)9;PTMZ)$`5k} z?iG}Rwj$>Y*|(D3S3e&fxhaPHma8@vwu(cwdlaCjX+NIK6=$H4U`rfzcWQVOhp{fnzuZhgCCGpw|p zTi`>cv~xVzdx|^`C0vXdlMwPae3S?>3|7v$e*Bs6-5gS>>FMHk_r2M(ADOV{KV7+6 zA@5Q(mdx%7J}MY}K461iuQ}5GwDGI=Yc&g0MZHu)7gC3{5@QZj6SJl*o0MS2Cl_ia zyK?9QmC9tJ6yn{EA-erJ4wk$+!E#X(s~9h^HOmQ_|6V_s1)k;%9Q6Niw}SyT?jxl4 z;HYz2$Nj$8Q_*Xo`TWEUx^Q9b+ik@$o39`mlY&P}G8wnjdE+Dlj?uL;$aB$n;x zWoh-M_u>9}_Ok@d_uidMqz10zJc}RQijPW3Fs&~1am=j*+A$QWTvxf9)6n;n8zTQW z!Q_J1%apTsJzLF`#^P_#mRv2Ya_keUE7iMSP!ha-WQoo0vZZG?gyR;+4q8F6tL#u< zRj8Hu5f-p1$J;)4?WpGL{4@HmJ6&tF9A5Tc8Trp>;Y>{^s?Q1&bam}?OjsnKd?|Z82aix26wUOLxbEW~E)|CgJ#)MLf_me# zv4?F$o@A~Um)6>HlM0=3Bd-vc91EM}D+t6-@!}O%i*&Wl%@#C8X+?5+nv`oPu!!=5 znbL+Fk_#J_%8vOq^FIv~5N(nk03kyo1p@l|1c+rO^zCG3bk2?|%AF;*|4si1XM<`a z1NY0-8$wv?&129!(g_A1lXR!+pD*1*cF?T~e1d6*G1Fz)jcSaZoKpxtA%FNnKP2jo zLXn@OR#1z@6zuH%mMB98}-t zHJqClsZ!G5xMSgIs_=<8sBePXxfoXsuvy`|buON9BX%s-o>OVLA)k3W=wKnw1?so$ zEjm0aS=zu@Xu#;{A)QTjJ$a9_={++ACkRY*sk3jLk&Fu}RxR<-DXR<`5`$VNG*wJE zidM6VzaQ!M0gbQM98@x@;#0qUS8O)p6mrYwTk*;8J~!ovbY6jon^Ki}uggd3#J5G8 z>awvtF85Y<9yE{Iag}J7O7)1O=ylk^255@XmV5J06-{xaaSNASZoTKKp~$tSxdUI~ zU1RZ&UuW37Ro&_ryj^cSt$Jd&pt|+h!A&dwcr&`S=R5E`=6Tm`+(qGm@$YZ8(8@a$ zXfo@Rwtvm7N3RMmVCb7radAs-@QtCXx^CQ-<)V>QPLZy@jH{#dc4#(y zV)6Hp{ZMz!|NG8!>i01gZMy)G<8Hf2X7e&LH_gOaajW<<^Xi55@OnlY*|S|*TS8;u_nHbv7lgmmZ+Q<5 zi!*lLCJmdpyzl(L${$C?(pVo|oR%r~x_B_ocPePa_);27^=n4L=`toZ;xdBut9rSv z?wDQ7j2I3WQBdhz%X7`2YaG_y|wA!7|s?k;A&WNMLMTZEzCaE^d??E&u?f=ejQBR~|< z)=thyP2(p8r6mt?Ad}tXAP_GvF9|P630I;$1cpQ+Ay7C34hK^ZV3H4kjPV8&NP>G5 zKRDEIBrFl{M#j4mfP0)68&?mqJP1S?2mU0djAGTjDV;wZ?6vplNn~3Hn$nP>%!dMi zz@bnC7zzi&k&s{QDWkf&zgrVXKUJjY3Gv3bL0}S4h>OdgEJ$Q^&p-VAr3J}^a*+rz z!jW7(h*+GuCyqcC{MD(Ovj^!{pB^OKUe|uy&bD?CN>KZrf3?v>>l*xSvnQiH-o^ViN$%FRdm9url;%(*jf5H$*S)8;i0xWHdl>$p);nH9v0)YfW?Vz$! zNCeUbi9`NEg(i^57y=fzM@1o*z*Bf6?QCV>2p9}(BLlYsOCfMjFv1pw1mlo)Py{8v zppw{MDfEeWN+n>Ne~oI7%9cU}mz0r3!es2gNF0t5jkGipjIo2lz;-e)7}Ul_#!eDv zw;#>kI>;#-pyfeu3Fsd^2F@6=oh#8r9;A!G0`-mm7%{=S;Ec(bJ=I_`FodKGQVNEY zmXwr4{9*jpDl%4{ggQZ5Ac z%wYTdl*!1c5^)%^E78Q&)ma|27c6j(a=)g4sGrp$r{jv>>M2 z6y)E5|Aooe!PSfKzvKA>`a6pfK3=E8vL14ksP&f=>gOP?}rG6ye@9ZR3 zJF*vsh*P$w390i!FV~~_Hv6t2Zl<4VUi|rNja#boFt{%q~xGb z(2petq9A*_>~B*>?d?Olx^lmYg4)}sH2>G42RE; literal 0 HcmV?d00001 diff --git a/coverage/keybd_open.png b/coverage/keybd_open.png new file mode 100644 index 0000000000000000000000000000000000000000..a8bac6c9de256626c680f9e9e3f8ee81d9713ecd GIT binary patch literal 9003 zcmeHLc{tST+n?-2i>)FxMv|DtSZA{DOOu_57&BjtZI~H*ma;_1l4LIxB9dJQ*|TO# zN!sjLvQy+8>YUSgf9L)E-g8~=``>Y0!#wx%xj*;)e4hJ$zP?Ym-Z>3679JK52*jqP zscJy|%SHXLGSN|g3$@6f1Az_(`xu?47+^iYt|X!@!3h9Uyj=k>;6<(w94t$&Tmv4vUI0Y(72z4p-=52qQm)ibdMG{Lq zK-QAXj0ngGo#r{-=KfvMuhjI#;F3ml_v?vI<2-B3E&Sb83IPcet8E#VcMLMbDBXp( zietxGS0^|mhdOuNU*! z>lxhuyJ~5HC9jEu^6wu9yggaJEILLJFELe{&yOk3uY^_mY(J*EdTA{CbDHru&S*s5 zFHGCrim@r19P**ASiJAew_7dD+e>cSOtls3Z#(>lZx1iINjrV7NNt%PDNcMkXlA*W z`Bs*%ezf4U5NxJm__K5P?GEB7`Q`04T`~MTc=Sf&%qHuFd;!rn3}>8+-@yEidsy4J zwgV$+ymZ>vxo%s!H&}(*({B{M0j#!`Lt5GDbvmkji<_pajk9^n5DO(1Q=&m;TJ!?& z?dIZM5vQ>Gv(&EdlJNx^(v{pFFPfSP@r^ zUhRTD7bv*AYH`?Gq11M%nz2r;gHNp42jVLD`5tDqtqX8m!12pRUB0&T%w5?UN8u2$ z{33ra^&{S8?zu^Udrw+}HTUH(`Hi#oxx_~8z^KjV88Ir*uZL|Sg~!j^L_s$=4bBRW zop?W3)Xm?LO6n3E9KHt6XpGZ_HN~5oyARM_FU(4I%qcBvz8@9K>nRPh&##*Eoh-~w z_nj&&SNa->_^2rmZKKZTTsb8qBi7eZ+<|^m6k%kJZMtc45f~Vd$|>90cV@0+305_? z$}Q=5?!3a*rg#60fWtWf!9(Na58NEPqWSacwBi#FiX9R?*v-C&eMqb0k&TM0y0Va% zz~=|oCLbfUU9)b69enmUFXBy2)12vO`bS&kb^YOC0g}4%8d0@NbMm6<9C^4VY$)DE z97dE-HVFOL-)`t{@mQPechUcK@>Nbm7VqtmzZyM5U<`U@;RjksVMF8R*E>VhuI zkJSj=K$J!b9wLT59DZFvicVNQpWLaC2991nDs(piR8YcRq>puA}_3int5bZCnSnDDDBIyC`&DN%_Rawgsxlzfrw!$YU zk697D5ny@b5%eg+G2F&np#M_QkwT<~o z=20^H-;eo=m3|I#91GRY0$TY@>nd$|*Y@6PiI*+2I$KO&NY?@M466>Gt%~Lgowk~^JM_8wk%ghs}g}t}vM}#g;++DAjY#7oR5>!9Zb&%tZ@Av?{`s6b=pUPf& z`Ej0w!tuWT?VOSJ(s^!$)o|_8JY0RAMH30nz=QERTWUx%i6hBP9(PAp{ZQXvk!u}#Vab<|7#n z{maX?O+c&it?=GMZ6-mCiq1b`jrvnH%AIwV(c=)Y+Ng zV<#loBasaSDG>p~!~6DW%DmIwBgLM5kIpGHr(+-C2oq1L_i5|QlNU`n4xG_p4P3X+ zRb3J0k2659ugVF3jbY3g*#hm^+qFWErnuOPd#1_kH{$GKT=$ySdOG<2GJTTZieX8- z?SgdRq&e6K0~#g8LaMO>bF{p3>QU`28P6mcPxd#h%a3HMTriHT*5N2RdHdrvo)Hl( z`U&a1G+qKp7@qqMO*C~Dy@6-;0(yrivn$>oJm|n&YNs2%lFk?#rUv7N=CbY!26_#` zOwy)}i?Rp4nN$r%&5zU9O^|X|`}0gh4dooTajuqYy@fN0lYu~6li4||>k%x%XO;xj z5hh>P?#m$1I$s2gk=e^$N7Mm%F()PB*mBjl8#GTm}V z$n>4H{Zn?>tRb54D4BSNiH}riISvV^~kJ4Oqi-Q}*uV!1arYe1u@i3%->Aj(r zIL(E2nn^nhc3)1$LG?M!Z0P!8{kc7jVZ|z31Z9vW;zWG03+NwSV4)_v?8U zWzJng#k|hYcWf&`>pXSb$1J+|*RC+y0H1PLZGt#e5IB@{-e@rJo$|6ec*b&%(FN6?k>rN1-Nr$ z4m|s8prjrxoFseZy3M8c%nY<;8djgwW?!ntbr_BuPh)z_r$EZ(kbFfHIe-m~a@%)q zLHUZt{_ImXka>hsv7(tXD6IvCnD*Y9=OgFxoLemASErKGmb*^Vr}f(jx0bPl+I)E& zdgR_RtTV3aL1y$Y0L5%R`aCZ_j3{hDnOKUvJ-^B&r*-n!H1{M-gxge|1@AvCd1;LQ z&gyHGB7uzB5-;A*PN28V&l6{zV&ytnvv49kQD;x-Jcw{TPutVpBdI*~r2kQt;9y9} zrm;uL{ueR+pCY~(GsbF5WOLs1yA+{d^Nmfm{aCu^(uKBHuPP3>NOHZQeGCtO_(B6)e%e38$iS+A2@EuwaM3TExzF}i&|u$ zKssx-vZFF{(!fLzv#fm`hUWZG5W_HwZrHcibZGYIaTr8bF#XA~Yf^ke%h&0u3Dx%! z^ibu!hA$rmFDYFLiIR1*I%r`O?aUXua(z?Y&59c);yYe5&auIz#2%m$bF*Hyeb18q z{s%|D-an(}lltLeI1PH%zkvDJwfC);yKU+wq>Y~}`Wh1~1YKy!?;AbZMc?c-xx!ID zGU@t4XMu&;EzIlDe3)0mJ*~+gZ-I|7lWVH7XtQ^*7s@OAG%rXhF&W2i7^~4ZIjANP z)iqZodK~wkV=H<3sb9XbJmqa^_fu6Md2TL+@V@LjyB!gdKL)fcuy|X!v>b{(24;h6 zJWY9Lv8*x1KY;xnwHPyvsDJ@ za=nD?=lf8HdL|ib^6{~*M~Z^@X6f4_vccD5U;FmpEMP#m#3a{Hv(qAR7jbY4j^jmY1_kGt2jCr9Hcns@ad#dkAiH(87OC%{OL&%A8E67dds4 zUUa(por`Wt!CH3Hh4y+T!9&*HuNopp&DuC!EBsu2>zv#{TDK;p*zGdw3Q}{Qa3l3P z;iD#9LF=sx7%v`;5kM(4uz1BHUXiwju?VgYWB8vDMa+TeebP^R`85D{{ zc$n4X&Z!+bAB>Phr{s{sU9$^T=t{2+HO8<@oNBifmQ0|Km;F^;iwj#gXkI1ur>(!Z zG@-if3==No%Idh?cck)-zRX2RqlFtoV`vrn=qyc?4xL}sirUxBJ4r!#F?aOvj)juB z%{tu=P8ttd5+4}c=Ud{6@wDYv&cB^kki63NIG@ATX%<^s?;CRDcEa1`cD0Wo0dd{Y z6qjdr3O;ft)T>4e(3iLm_u`QvGhKad%P9zU^Lh8<(*A{x4mEG2wo)t&m&#+lvgmgT zX=0eA>sxXaMJ9`9ydOiNS4<9P-1gH31Wp9bo%!tP$g@wsOnW*#!un#WK&N2z$F93% z)7XXFa=YT;W;+I0qF=FN_Dr$}{`Q67WG7Phqm*HvlkJb*IdK?p`G_u_U_TMccM}%Z z9o(j&Lzg2plsL#1uY|kR zlIJvxnYMIcl8WJUtLEWZ=Jc)J-!GUhx*adO`KdDYV3eE|sbm38a(2si#4)I#TQ{ zu?Gg4M4z6{uc>!WZ(Z|4?1_ml(CD!lWvQIf+81z4K0o}Pq{RyyL8J8^KU+axA#4qy zQ_Hf5_NC-tOOi9sMZFnv)U{y8i$_y>bVIjd zYdd_eZZ%qsKW*^;2wxh(DlFXEIM5O>17AA*?E6crapNmn`L!Jn>AqbENHS$!E&q-T zFo+4DLWSrzdaYa`rye_*o~K22kByy4JzG;|#gQ7C@QCI9JkMy#2(2Fr`Ks(a7O@xQ zvrGC5UmLAPFdMG#Z`W+kDtZAXOA0bEMIr=*Q!fa#N06YRqNk;z^4on3^%f>IEv8Vr zL60-Ew)rk(`mRiv3IpS4>4mi@^GxX`R5ew(n60W&Syt}_o>A)pgE5&E8 zx78ULi@iR42{_udvF!_&adC>f`(&?{`S`^G4hsg;xq4oViQ6kITte;T!WM@^_k;-B zLpb!avBKI!QgmoYY?o2a^F?+Z#*eEd9ik7<*Uqk8Z`^Mqt=+4+d1B;xTx-$WS;2+I zO|PLhqWk+I$Zt%YKlF@o9>2ARqq#A@Bb52^a#Z=0)&8LgZP% zvLw7M+CWwPCk1sR2eGG6T+wj2r>7^(lX?k3vV)7EP$)P82}dHKR0Ndl?LxtNL0!lK zI}|@SQ~@%ML~x}Lh%VqAPOJ^logxQ;Q0Kuv$*HqAH7~01XMmmYE64doj z0dOP&Ap=Dqp-2?`SAXg(2J^eO3;CytR6XHdSXa0h3;}m`{*wopqUP~Oyub7y8&U5O z;RXPi=uW}`Y94?KMc~(#>9W6^Y0Fj&pS3( z&1F|tv?>wjz7teSRSvR~FB(t85%B2UuQo^=N&+ci3&lwQc&G#dB?U#Ha9F4<9xr7h zBPD@Dps>GCX}ORoSQi|yLq#Qr5vV*UoEQ=zjTM7RN}ch1}Yr4mQkNTZ}}B%l(~;?mS?Yyqf^gft3@K-mCDtb{mq zUTl|YXCKf?dRlT2Bn~8 zNJ`0wBY$x>0Z3$OmG6*>Az;WKS>thNbt)y6T5SYptQ`P%b+Oy!-Psp3bv0CFu{+H{ zW!|+@7lT$I0ayx=WJDx7$w79K1@BPq_7qt5XSblw5^=kZyI=sn({MjqP8n+l-yO=r z{~h>Wm<;WSo-Y48oj67^y5TwBJ4^92JfB%Xe{oB{A8>LfZyE$s*XRVaQ0XiJAiuJ z{_M5i?1aClV_U2g4k1M?Txn@MwF0GZQcxRdF#w7}NFk8o(kPUK)Q?*Eot;dyrFddV zfRY`x2B`Z??XBH?2A}#-e!_oF#?v0ysVxLj42qC|iisN`#nA|Hw73Lyh(;hFKeik! z3*R|qe_OKb&N+m^pnnxbcITWzYwc8{p}VWA69FLoS*+iR=YPQc;{UTy|C9T#upizk zL|1QWC)-nWJzf57_`d-DU^q*_0WM_Xzf1jB$PZb5c^FZ1{$Zm&;FtHmOoy*0T=2& zf1cErYE6u!67_|g#zsd&6|{Xdx}%mlVs_OuBZEMDId(pKK*_0xsYXVM7DkP6jBXz- zEd)lyY5I@OKCuXih+u*QN7paQfUw6wG;XcaW~qWCo?T2*0>x(MuCfDKSAqe7lXsSc7qm4=p(o#F8`bgRO G%6|bpD&^7u literal 0 HcmV?d00001 diff --git a/coverage/status.json b/coverage/status.json new file mode 100644 index 000000000..7df35ad02 --- /dev/null +++ b/coverage/status.json @@ -0,0 +1 @@ +{"format":2,"version":"7.2.7","globals":"2e60d5fd700cfe61484311c5480cde96","files":{"gef_py":{"hash":"398fee3e011c8f97d91757f640a015e5","index":{"nums":[4,1,7572,0,1827,2540,418,1048],"html_filename":"gef_py.html","relative_filename":"gef.py"}}}} \ No newline at end of file diff --git a/coverage/style.css b/coverage/style.css new file mode 100644 index 000000000..11b24c4e7 --- /dev/null +++ b/coverage/style.css @@ -0,0 +1,309 @@ +@charset "UTF-8"; +/* Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 */ +/* For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt */ +/* Don't edit this .css file. Edit the .scss file instead! */ +html, body, h1, h2, h3, p, table, td, th { margin: 0; padding: 0; border: 0; font-weight: inherit; font-style: inherit; font-size: 100%; font-family: inherit; vertical-align: baseline; } + +body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-size: 1em; background: #fff; color: #000; } + +@media (prefers-color-scheme: dark) { body { background: #1e1e1e; } } + +@media (prefers-color-scheme: dark) { body { color: #eee; } } + +html > body { font-size: 16px; } + +a:active, a:focus { outline: 2px dashed #007acc; } + +p { font-size: .875em; line-height: 1.4em; } + +table { border-collapse: collapse; } + +td { vertical-align: top; } + +table tr.hidden { display: none !important; } + +p#no_rows { display: none; font-size: 1.2em; } + +a.nav { text-decoration: none; color: inherit; } + +a.nav:hover { text-decoration: underline; color: inherit; } + +.hidden { display: none; } + +header { background: #f8f8f8; width: 100%; z-index: 2; border-bottom: 1px solid #ccc; } + +@media (prefers-color-scheme: dark) { header { background: black; } } + +@media (prefers-color-scheme: dark) { header { border-color: #333; } } + +header .content { padding: 1rem 3.5rem; } + +header h2 { margin-top: .5em; font-size: 1em; } + +header p.text { margin: .5em 0 -.5em; color: #666; font-style: italic; } + +@media (prefers-color-scheme: dark) { header p.text { color: #aaa; } } + +header.sticky { position: fixed; left: 0; right: 0; height: 2.5em; } + +header.sticky .text { display: none; } + +header.sticky h1, header.sticky h2 { font-size: 1em; margin-top: 0; display: inline-block; } + +header.sticky .content { padding: 0.5rem 3.5rem; } + +header.sticky .content p { font-size: 1em; } + +header.sticky ~ #source { padding-top: 6.5em; } + +main { position: relative; z-index: 1; } + +footer { margin: 1rem 3.5rem; } + +footer .content { padding: 0; color: #666; font-style: italic; } + +@media (prefers-color-scheme: dark) { footer .content { color: #aaa; } } + +#index { margin: 1rem 0 0 3.5rem; } + +h1 { font-size: 1.25em; display: inline-block; } + +#filter_container { float: right; margin: 0 2em 0 0; } + +#filter_container input { width: 10em; padding: 0.2em 0.5em; border: 2px solid #ccc; background: #fff; color: #000; } + +@media (prefers-color-scheme: dark) { #filter_container input { border-color: #444; } } + +@media (prefers-color-scheme: dark) { #filter_container input { background: #1e1e1e; } } + +@media (prefers-color-scheme: dark) { #filter_container input { color: #eee; } } + +#filter_container input:focus { border-color: #007acc; } + +header button { font-family: inherit; font-size: inherit; border: 1px solid; border-radius: .2em; color: inherit; padding: .1em .5em; margin: 1px calc(.1em + 1px); cursor: pointer; border-color: #ccc; } + +@media (prefers-color-scheme: dark) { header button { border-color: #444; } } + +header button:active, header button:focus { outline: 2px dashed #007acc; } + +header button.run { background: #eeffee; } + +@media (prefers-color-scheme: dark) { header button.run { background: #373d29; } } + +header button.run.show_run { background: #dfd; border: 2px solid #00dd00; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.run.show_run { background: #373d29; } } + +header button.mis { background: #ffeeee; } + +@media (prefers-color-scheme: dark) { header button.mis { background: #4b1818; } } + +header button.mis.show_mis { background: #fdd; border: 2px solid #ff0000; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.mis.show_mis { background: #4b1818; } } + +header button.exc { background: #f7f7f7; } + +@media (prefers-color-scheme: dark) { header button.exc { background: #333; } } + +header button.exc.show_exc { background: #eee; border: 2px solid #808080; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.exc.show_exc { background: #333; } } + +header button.par { background: #ffffd5; } + +@media (prefers-color-scheme: dark) { header button.par { background: #650; } } + +header button.par.show_par { background: #ffa; border: 2px solid #bbbb00; margin: 0 .1em; } + +@media (prefers-color-scheme: dark) { header button.par.show_par { background: #650; } } + +#help_panel, #source p .annotate.long { display: none; position: absolute; z-index: 999; background: #ffffcc; border: 1px solid #888; border-radius: .2em; color: #333; padding: .25em .5em; } + +#source p .annotate.long { white-space: normal; float: right; top: 1.75em; right: 1em; height: auto; } + +#help_panel_wrapper { float: right; position: relative; } + +#keyboard_icon { margin: 5px; } + +#help_panel_state { display: none; } + +#help_panel { top: 25px; right: 0; padding: .75em; border: 1px solid #883; color: #333; } + +#help_panel .keyhelp p { margin-top: .75em; } + +#help_panel .legend { font-style: italic; margin-bottom: 1em; } + +.indexfile #help_panel { width: 25em; } + +.pyfile #help_panel { width: 18em; } + +#help_panel_state:checked ~ #help_panel { display: block; } + +kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em .35em; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-weight: bold; background: #eee; border-radius: 3px; } + +#source { padding: 1em 0 1em 3.5rem; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; } + +#source p { position: relative; white-space: pre; } + +#source p * { box-sizing: border-box; } + +#source p .n { float: left; text-align: right; width: 3.5rem; box-sizing: border-box; margin-left: -3.5rem; padding-right: 1em; color: #999; } + +@media (prefers-color-scheme: dark) { #source p .n { color: #777; } } + +#source p .n.highlight { background: #ffdd00; } + +#source p .n a { margin-top: -4em; padding-top: 4em; text-decoration: none; color: #999; } + +@media (prefers-color-scheme: dark) { #source p .n a { color: #777; } } + +#source p .n a:hover { text-decoration: underline; color: #999; } + +@media (prefers-color-scheme: dark) { #source p .n a:hover { color: #777; } } + +#source p .t { display: inline-block; width: 100%; box-sizing: border-box; margin-left: -.5em; padding-left: 0.3em; border-left: 0.2em solid #fff; } + +@media (prefers-color-scheme: dark) { #source p .t { border-color: #1e1e1e; } } + +#source p .t:hover { background: #f2f2f2; } + +@media (prefers-color-scheme: dark) { #source p .t:hover { background: #282828; } } + +#source p .t:hover ~ .r .annotate.long { display: block; } + +#source p .t .com { color: #008000; font-style: italic; line-height: 1px; } + +@media (prefers-color-scheme: dark) { #source p .t .com { color: #6a9955; } } + +#source p .t .key { font-weight: bold; line-height: 1px; } + +#source p .t .str { color: #0451a5; } + +@media (prefers-color-scheme: dark) { #source p .t .str { color: #9cdcfe; } } + +#source p.mis .t { border-left: 0.2em solid #ff0000; } + +#source p.mis.show_mis .t { background: #fdd; } + +@media (prefers-color-scheme: dark) { #source p.mis.show_mis .t { background: #4b1818; } } + +#source p.mis.show_mis .t:hover { background: #f2d2d2; } + +@media (prefers-color-scheme: dark) { #source p.mis.show_mis .t:hover { background: #532323; } } + +#source p.run .t { border-left: 0.2em solid #00dd00; } + +#source p.run.show_run .t { background: #dfd; } + +@media (prefers-color-scheme: dark) { #source p.run.show_run .t { background: #373d29; } } + +#source p.run.show_run .t:hover { background: #d2f2d2; } + +@media (prefers-color-scheme: dark) { #source p.run.show_run .t:hover { background: #404633; } } + +#source p.exc .t { border-left: 0.2em solid #808080; } + +#source p.exc.show_exc .t { background: #eee; } + +@media (prefers-color-scheme: dark) { #source p.exc.show_exc .t { background: #333; } } + +#source p.exc.show_exc .t:hover { background: #e2e2e2; } + +@media (prefers-color-scheme: dark) { #source p.exc.show_exc .t:hover { background: #3c3c3c; } } + +#source p.par .t { border-left: 0.2em solid #bbbb00; } + +#source p.par.show_par .t { background: #ffa; } + +@media (prefers-color-scheme: dark) { #source p.par.show_par .t { background: #650; } } + +#source p.par.show_par .t:hover { background: #f2f2a2; } + +@media (prefers-color-scheme: dark) { #source p.par.show_par .t:hover { background: #6d5d0c; } } + +#source p .r { position: absolute; top: 0; right: 2.5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; } + +#source p .annotate { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; color: #666; padding-right: .5em; } + +@media (prefers-color-scheme: dark) { #source p .annotate { color: #ddd; } } + +#source p .annotate.short:hover ~ .long { display: block; } + +#source p .annotate.long { width: 30em; right: 2.5em; } + +#source p input { display: none; } + +#source p input ~ .r label.ctx { cursor: pointer; border-radius: .25em; } + +#source p input ~ .r label.ctx::before { content: "▶ "; } + +#source p input ~ .r label.ctx:hover { background: #e8f4ff; color: #666; } + +@media (prefers-color-scheme: dark) { #source p input ~ .r label.ctx:hover { background: #0f3a42; } } + +@media (prefers-color-scheme: dark) { #source p input ~ .r label.ctx:hover { color: #aaa; } } + +#source p input:checked ~ .r label.ctx { background: #d0e8ff; color: #666; border-radius: .75em .75em 0 0; padding: 0 .5em; margin: -.25em 0; } + +@media (prefers-color-scheme: dark) { #source p input:checked ~ .r label.ctx { background: #056; } } + +@media (prefers-color-scheme: dark) { #source p input:checked ~ .r label.ctx { color: #aaa; } } + +#source p input:checked ~ .r label.ctx::before { content: "▼ "; } + +#source p input:checked ~ .ctxs { padding: .25em .5em; overflow-y: scroll; max-height: 10.5em; } + +#source p label.ctx { color: #999; display: inline-block; padding: 0 .5em; font-size: .8333em; } + +@media (prefers-color-scheme: dark) { #source p label.ctx { color: #777; } } + +#source p .ctxs { display: block; max-height: 0; overflow-y: hidden; transition: all .2s; padding: 0 .5em; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; white-space: nowrap; background: #d0e8ff; border-radius: .25em; margin-right: 1.75em; text-align: right; } + +@media (prefers-color-scheme: dark) { #source p .ctxs { background: #056; } } + +#index { font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 0.875em; } + +#index table.index { margin-left: -.5em; } + +#index td, #index th { text-align: right; width: 5em; padding: .25em .5em; border-bottom: 1px solid #eee; } + +@media (prefers-color-scheme: dark) { #index td, #index th { border-color: #333; } } + +#index td.name, #index th.name { text-align: left; width: auto; } + +#index th { font-style: italic; color: #333; cursor: pointer; } + +@media (prefers-color-scheme: dark) { #index th { color: #ddd; } } + +#index th:hover { background: #eee; } + +@media (prefers-color-scheme: dark) { #index th:hover { background: #333; } } + +#index th[aria-sort="ascending"], #index th[aria-sort="descending"] { white-space: nowrap; background: #eee; padding-left: .5em; } + +@media (prefers-color-scheme: dark) { #index th[aria-sort="ascending"], #index th[aria-sort="descending"] { background: #333; } } + +#index th[aria-sort="ascending"]::after { font-family: sans-serif; content: " ↑"; } + +#index th[aria-sort="descending"]::after { font-family: sans-serif; content: " ↓"; } + +#index td.name a { text-decoration: none; color: inherit; } + +#index tr.total td, #index tr.total_dynamic td { font-weight: bold; border-top: 1px solid #ccc; border-bottom: none; } + +#index tr.file:hover { background: #eee; } + +@media (prefers-color-scheme: dark) { #index tr.file:hover { background: #333; } } + +#index tr.file:hover td.name { text-decoration: underline; color: inherit; } + +#scroll_marker { position: fixed; z-index: 3; right: 0; top: 0; width: 16px; height: 100%; background: #fff; border-left: 1px solid #eee; will-change: transform; } + +@media (prefers-color-scheme: dark) { #scroll_marker { background: #1e1e1e; } } + +@media (prefers-color-scheme: dark) { #scroll_marker { border-color: #333; } } + +#scroll_marker .marker { background: #ccc; position: absolute; min-height: 3px; width: 100%; } + +@media (prefers-color-scheme: dark) { #scroll_marker .marker { background: #444; } } diff --git a/deprecated/index.html b/deprecated/index.html new file mode 100644 index 000000000..10a194963 --- /dev/null +++ b/deprecated/index.html @@ -0,0 +1,1802 @@ + + + + + + + + + + + + + + + + + + + + + + Deprecated - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

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 or even simply removed. This +page aims to track those changes.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CommandStatusSinceLink (if Applicable)Notes
cs-disassembleMoved2022.06LinkDepends on capstone
assembleMoved2022.06LinkDepends on keystone
emulateMoved2022.06LinkDepends on unicorn and capstone
set-permissionMoved2022.06LinkDepends on keystone
ropperMoved2022.06LinkDepends on ropper
ida-interactMoved2022.06LinkDepends on rpyc
exploit-templateMovedc402900Link
windbgMoveda933a5aLink
is-syscallMoved3f79fb38Link
syscall-argsMoved3f79fb38Link
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/faq/index.html b/faq/index.html new file mode 100644 index 000000000..fba7af9ac --- /dev/null +++ b/faq/index.html @@ -0,0 +1,2009 @@ + + + + + + + + + + + + + + + + + + + + + + FAQ - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + + +
+
+ + + + +

Frequently Asked Questions

+

Why use GEF over PEDA?

+

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!

+

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.

+

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. For really older versions of GDB, you can +use 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 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 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.

+

If you experience problems setting it up on your host, first go to the Discord +channel 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.

+

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:

+
root@debian-aarch64:~# gdb -q ./test-bin-aarch64
+GEF ready, type `gef' to start, `gef config' to configure
+53 commands loaded, using Python engine 3.4
+[*] 5 commands could not be loaded, run `gef missing` to know why.
+[+] Configuration from '/root/.gef.rc' restored
+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:

+
root@debian-aarch64:~# nano ~/.gef.rc
+[...]
+[gef]
+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 +experience.

+

Some interesting plugins highly recommended too:

+ +

voltron +Src: @rick2600: terminator + gdb + gef + voltron cc: @snare @hugsy

+

I want to contribute, where should I head first?

+

I would suggest thoroughly reading this documentation, just having a look to the +CONTRIBUTE file of the project to +give you pointers.

+

Also a good thing would be to join our Discord channel 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.

+

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

+

By switching to debug mode, gef will give much more information:

+
gef➤  gef config gef.debug 1
+
+

gef-debug

+

If you think fixing it is in your skills, then send a Pull +Request with your patched version, explaining your bug, and +what was your solution for it.

+

Otherwise, you can open an issue, 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 to display correctly characters of any alphabet +and also some cool emojis. 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:

+
$ 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

+
+

Original Issue and Mitigation

+

gdb version 7.12, as distributed w/ Raspbian/Kali rolling (only distro's +tested,) throws an exception while disassembling ARM binaries when using gef. +This is not a gef problem, this is a gdb problem. gef is just the tool that +revealed the gdb dain bramage! (The issue was not observed using vanilla +gdb/peda/pwndbg) This issue was first noted when using si to step through a +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

+

This turns out to be a known problem (regression) with gdb, and affects +gef users running the ARM platform (Raspberry Pi).

+

The mitigation is for ARM users to compile gdb from source and run the latest +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.

+

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?

+

Discord is your answer: join and talk to us by clicking here

+

Discord

+

If you cannot find the answer to your problem here or on the Discord, then go to the project Issues +page 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 <container ID> -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 may +improve results.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/functions/base/index.html b/functions/base/index.html new file mode 100644 index 000000000..2ac571692 --- /dev/null +++ b/functions/base/index.html @@ -0,0 +1,1726 @@ + + + + + + + + + + + + + + + + + + + + + + base - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Function $_base()

+

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

+
$_base([filepath])
+
+

Example:

+
gef➤ p $_base(\"/usr/lib/ld-2.33.so\")
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/functions/bss/index.html b/functions/bss/index.html new file mode 100644 index 000000000..e0d390520 --- /dev/null +++ b/functions/bss/index.html @@ -0,0 +1,1725 @@ + + + + + + + + + + + + + + + + + + + + + + bss - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Function $_bss()

+

Return the current BSS base address plus the given offset.

+

Note: a debugging session must be active

+
$_bss([offset])
+
+

Example:

+
gef➤ p $_bss(0x20)
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/functions/got/index.html b/functions/got/index.html new file mode 100644 index 000000000..4fcf60e29 --- /dev/null +++ b/functions/got/index.html @@ -0,0 +1,1725 @@ + + + + + + + + + + + + + + + + + + + + + + got - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Function $_got()

+

Return the current GOT base address plus the given offset.

+

Note: a debugging session must be active

+
$_got([offset])
+
+

Example:

+
gef➤ p $_got(0x20)
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/functions/heap/index.html b/functions/heap/index.html new file mode 100644 index 000000000..68fc1fb8c --- /dev/null +++ b/functions/heap/index.html @@ -0,0 +1,1725 @@ + + + + + + + + + + + + + + + + + + + + + + heap - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Function $_heap()

+

Return the current heap base address plus the given offset.

+

Note: a debugging session must be active

+
$_heap([offset])
+
+

Example:

+
gef➤ p $_heap(0x20)
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/functions/stack/index.html b/functions/stack/index.html new file mode 100644 index 000000000..7dc78bcab --- /dev/null +++ b/functions/stack/index.html @@ -0,0 +1,1725 @@ + + + + + + + + + + + + + + + + + + + + + + stack - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Function $_stack()

+

Return the current stack base address plus the given offset.

+

Note: a debugging session must be active

+
$_stack([offset])
+
+

Example:

+
gef➤ p $_stack(0x20)
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 000000000..253b92548 --- /dev/null +++ b/index.html @@ -0,0 +1,1964 @@ + + + + + + + + + + + + + + + + + + + + GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

GEF - GDB Enhanced Features

+

Docs Coverage MIT Python 3 Discord

+

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 can be used if Python +2 support is needed.

+

gef-context

+

GDB Made Easy

+
    +
  • One single GDB script
  • +
  • Entirely architecture agnostic, NO dependencies: GEF is battery-included and is + installable instantly
  • +
  • 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 to create other commands by providing + more comprehensible layout to GDB Python API.
  • +
  • Full Python3 support (Python2 support was dropped in + 2020.03) - check out + gef-legacy for a Python2 compatible version, and the + compatibility matrix 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
  • +
  • And a lot more commands contributed by the community available on GEF-Extras !!
  • +
+

Check out the showroom page for more | or try it online +yourself! (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:

+
bash -c "$(curl -fsSL https://gef.blah.cat/sh)"
+
+

For more details and other ways to install GEF please see installation +page.

+

Run

+

Then just start playing (for local files):

+
$ gdb -q /path/to/my/bin
+gef➤  gef help
+
+

Or (for remote debugging):

+
remote:~ $ gdbserver 0.0.0.0:1234 /path/to/file
+Running as PID: 666
+
+

And:

+
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 +channel.

+

For bugs or feature requests, just go here 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/<pid>). 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_, but kept +fresh thanks to all the contributors.

+

contributors-img

+

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:

+

+ + + + + + +

+

Extra Credits

+ +

🍺 Happy hacking !

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/install/index.html b/install/index.html new file mode 100644 index 000000000..0daef6ddc --- /dev/null +++ b/install/index.html @@ -0,0 +1,2010 @@ + + + + + + + + + + + + + + + + + + + + + + Installation - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Installing GEF

+

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

+

GEF will then only work for Python 3. If you absolutely require GDB + Python 2, please use +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:

+
$ gdb -nx -ex 'pi print(sys.version)' -ex quit
+
+

This should display your version of Python compiled with gdb.

+
$ gdb -nx -ex 'pi print(sys.version)' -ex quit
+3.6.9 (default, Nov  7 2019, 10:44:02)
+[GCC 8.3.0]
+
+

Python dependencies

+

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

+

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, compiled with Python 3.6 or higher, +and run

+
bash -c "$(curl -fsSL https://gef.blah.cat/sh)"
+
+

Or if you prefer wget

+
bash -c "$(wget https://gef.blah.cat/sh -O -)"
+
+

Alternatively from inside gdb directly:

+
$ 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.

+
$ 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 +(even without git installed). with python /path/to/gef.py --update

+
$ 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.

+

Using git

+

To contribute to GEF, you might prefer using git directly.

+
$ 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.

+

However if you prefer a more stable life, you can then switch to the main +branch:

+
$ git checkout main
+
+

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 is an open repository where +anyone can freely submit their own commands to extend GDB via GEF's API.

+

To benefit from it:

+
# using the automated way
+## via the install script
+$ bash -c "$(wget https://github.com/hugsy/gef/raw/main/scripts/gef-extras.sh -O -)"
+
+# or manually
+## clone the repo
+$ git clone --branch main https://github.com/hugsy/gef-extras.git
+
+## then specify gef to load this directory
+$ gdb -ex 'gef config gef.extra_plugins_dir "/path/to/gef-extras/scripts"' -ex 'gef save' -ex quit
+[+] Configuration saved
+
+

You can also use the structures defined from this repository:

+
$ gdb -ex 'gef config pcustom.struct_path "/path/to/gef-extras/structs"' -ex 'gef save' -ex quit
+[+] Configuration saved
+
+

There, you're now fully equipped epic pwnage with all GEF's goodness!!

+

Uninstalling GEF

+

Prevent script loading

+

GDB provides the -nx command line flag to disable the commands from the +~/.gdbinit to be executed.

+
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:

+

So:

+
$ cat ~/.gdbinit
+source /my/path/to/gef.py
+
+

Will become:

+
$ 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:

+
$ gdb
+(gdb) source /my/path/to/gef.py
+
+

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:

+
$ cat ~/.gdbinit
+# source /my/path/to/gef.py
+$ rm /my/path/to/gef.py ~/.gef.rc
+
+

GEF is totally removed from your system.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/obsolete/docs/index.html b/obsolete/docs/index.html new file mode 100644 index 000000000..7688c73d7 --- /dev/null +++ b/obsolete/docs/index.html @@ -0,0 +1,1718 @@ + + + + + + + + + + + + + + + + + + Index - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Index

+ +
+

The latest version of the documentation is hosted on hugsy.github.io/gef

+
+

redirect

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/obsolete/mkdocs.yml b/obsolete/mkdocs.yml new file mode 100644 index 000000000..bc23baff7 --- /dev/null +++ b/obsolete/mkdocs.yml @@ -0,0 +1,6 @@ +site_name: GEF - GDB Enhanced Features documentation +repo_url: https://github.com/hugsy/gef/ +docs_dir: docs/ +theme: readthedocs +nav: +- Home: index.md diff --git a/obsolete/requirements.txt b/obsolete/requirements.txt new file mode 100644 index 000000000..ad4f88966 --- /dev/null +++ b/obsolete/requirements.txt @@ -0,0 +1 @@ +mkdocs>=1.2.3 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..204dd3ee1 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +mkdocs-material +lazydocs diff --git a/screenshots/index.html b/screenshots/index.html new file mode 100644 index 000000000..db2a0c7da --- /dev/null +++ b/screenshots/index.html @@ -0,0 +1,2038 @@ + + + + + + + + + + + + + + + + + + + + + + Showroom - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + + +
+
+ + + + +

Screenshots

+ + +

This page illustrates a few of the possibilities available to you when using GEF.

+

Multi-architecture support

+

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
  • +
+

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:

+

hexdump

+

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:

+

mipsel-deref-regs

+

Heap analysis

+

Detailed view of Glibc Chunks

+

x86-heap-chunks

+

Automatic detection of UaF during runtime

+

x86-heap-helper-uaf

+

Display ELF information

+

ELF structure

+

elf-info

+

Security settings

+

elf-checksec

+

Automatic vulnerable string detection

+

aarch64-fmtstr

+

Code emulation with Unicorn-Engine (x86-64)

+

emu

+

Comprehensive address space layout display

+

vmmap

+

Defining arbitrary custom structures

+

sparc-arb-struct

+

Highlight custom strings

+

highlight-command

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 000000000..5acbabfd3 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"GEF - GDB Enhanced Features","text":"

GEF (pronounced \u02a4\u025bf - \"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 can be used if Python 2 support is needed.

"},{"location":"#gdb-made-easy","title":"GDB Made Easy","text":"
  • One single GDB script
  • Entirely architecture agnostic, NO dependencies: GEF is battery-included and is installable instantly
  • 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 to create other commands by providing more comprehensible layout to GDB Python API.
  • Full Python3 support (Python2 support was dropped in 2020.03) - check out gef-legacy for a Python2 compatible version, and the compatibility matrix 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
  • And a lot more commands contributed by the community available on GEF-Extras !!

Check out the showroom page for more | or try it online yourself! (user:gef/password:gef-demo)

"},{"location":"#quick-start","title":"Quick start","text":""},{"location":"#automated-installation","title":"Automated installation","text":"

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 -c \"$(curl -fsSL https://gef.blah.cat/sh)\"\n

For more details and other ways to install GEF please see installation page.

"},{"location":"#run","title":"Run","text":"

Then just start playing (for local files):

$ gdb -q /path/to/my/bin\ngef\u27a4  gef help\n

Or (for remote debugging):

remote:~ $ gdbserver 0.0.0.0:1234 /path/to/file\nRunning as PID: 666\n

And:

local:~ $ gdb -q\ngef\u27a4  gef-remote -t your.ip.address:1234 -p 666\n
"},{"location":"#bugs-feedbacks","title":"Bugs & Feedbacks","text":"

To discuss gef, gdb, exploitation or other topics, feel free to join our Discord channel.

For bugs or feature requests, just go here 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/<pid>). As a consequence, some of the features might not work on custom or hardened systems such as GrSec.

"},{"location":"#contribution","title":"Contribution","text":"

gef was created and maintained by myself, @_hugsy_, but kept fresh thanks to all the 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.

"},{"location":"#sponsors","title":"Sponsors","text":"

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:

"},{"location":"#extra-credits","title":"Extra Credits","text":"
  • The GEF logo was designed by TheZakMan
"},{"location":"#happy-hacking","title":"\ud83c\udf7a Happy hacking !","text":""},{"location":"api/","title":"Extending GEF","text":"

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.

A dedicated repository was born to host external scripts. This repo is open to all for contributions, no restrictions and the most valuable ones will be integrated into gef.py.

"},{"location":"api/#quick-start","title":"Quick start","text":"

Here is the most basic skeleton for creating a new GEF command named newcmd:

class NewCommand(GenericCommand):\n    \"\"\"Dummy new command.\"\"\"\n    _cmdline_ = \"newcmd\"\n    _syntax_  = f\"{_cmdline_}\"\n\n    @only_if_gdb_running         # not required, ensures that the debug session is started\n    def do_invoke(self, argv):\n        # let's say we want to print some info about the architecture of the current binary\n        print(f\"gef.arch={gef.arch}\")\n        # or showing the current $pc\n        print(f\"gef.arch.pc={gef.arch.pc:#x}\")\n        return\n\nregister_external_command(NewCommand())\n

Loading it in GEF is as easy as

gef\u27a4  source /path/to/newcmd.py\n[+] Loading 'NewCommand'\n

We can call it:

gef\u27a4  newcmd\ngef.arch=<__main__.X86_64 object at 0x7fd5583571c0>\ngef.arch.pc=0x55555555a7d0\n

Yes, that's it! Check out the complete API to see what else GEF offers.

"},{"location":"api/#detailed-explanation","title":"Detailed explanation","text":"

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.

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:

gef\u27a4  source /path/to/newcmd.py\n

or add to your ~/.gdbinit:

$ echo source /path/to/newcmd.py >> ~/.gdbinit\n
"},{"location":"api/#customizing-context-panes","title":"Customizing context panes","text":"

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:

__start_time__ = int(time.time())\ndef wasted_time_debugging():\n    gef_print(\"You have wasted {} seconds!\".format(int(time.time()) - __start_time__))\n\ndef wasted_time_debugging_title():\n    return \"wasted:time:debugging:{}\".format(int(time.time()) - __start_time__)\n\nregister_external_context_pane(\"wasted_time_debugging\", wasted_time_debugging, wasted_time_debugging_title)\n

Loading it in GEF is as easy as loading a command

gef\u27a4  source /path/to/custom_context_pane.py\n

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.

"},{"location":"api/#context-pane-api","title":"Context Pane API","text":"

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
"},{"location":"api/#api","title":"API","text":"

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:

gef\u27a4  pi help(Architecture)\n

or even from outside GDB:

$ gdb -q -ex 'pi help(hexdump)' -ex quit\n

The GEF API aims to provide a simpler and more Pythonic approach to GDB's.

Some basic examples: - read the memory

gef \u27a4  pi print(hexdump( gef.memory.read(parse_address(\"$pc\"), length=0x20 )))\n0x0000000000000000     f3 0f 1e fa 31 ed 49 89 d1 5e 48 89 e2 48 83 e4    ....1.I..^H..H..\n0x0000000000000010     f0 50 54 4c 8d 05 66 0d 01 00 48 8d 0d ef 0c 01    .PTL..f...H.....\n
  • get access to the memory layout
gef \u27a4 pi print('\\n'.join([ f\"{x.page_start:#x} -> {x.page_end:#x}\" for x in gef.memory.maps]))\n0x555555554000 -> 0x555555558000\n0x555555558000 -> 0x55555556c000\n0x55555556c000 -> 0x555555575000\n0x555555576000 -> 0x555555577000\n0x555555577000 -> 0x555555578000\n0x555555578000 -> 0x55555559a000\n0x7ffff7cd8000 -> 0x7ffff7cda000\n0x7ffff7cda000 -> 0x7ffff7ce1000\n0x7ffff7ce1000 -> 0x7ffff7cf2000\n0x7ffff7cf2000 -> 0x7ffff7cf7000\n[...]\n

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

"},{"location":"api/#reference","title":"Reference","text":"

For a complete reference of the API offered by GEF, visit docs/api/gef.md.

"},{"location":"api/#parsing-command-arguments","title":"Parsing command arguments","text":"
@parse_arguments( {\"required_argument_1\": DefaultValue1, ...}, {\"--optional-argument-1\": DefaultValue1, ...} )\n

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:

@parse_arguments( {\"instructions\": [\"nop\", \"int3\", \"hlt\"], }, {\"--arch\": \"x64\", } )\n

Argument flags are also supported, allowing to write simpler version of the flag such as

@parse_arguments( {}, {(\"--long-argument\", \"-l\"): value, } )\n

A basic example would be as follow:

class MyCommand(GenericCommand):\n    [...]\n\n    @parse_arguments({\"foo\": [1,]}, {\"--bleh\": \"\", (\"--blah\", \"-l): True})\n    def do_invoke(self, argv, *args, **kwargs):\n      args = kwargs[\"arguments\"]\n      if args.foo == 1: ...\n      if args.blah == True: ...\n

When the user enters the following command:

gef\u27a4 mycommand --blah 3 14 159 2653\n

The function MyCommand!do_invoke() can use the command line argument value

args.foo --> [3, 14, 159, 2653] # a List(int) from user input\nargs.bleh --> \"\" # the default value\nargs.blah --> True # set to True because user input declared the option (would have been False otherwise)\n
"},{"location":"api/#adding-new-architectures","title":"Adding new architectures","text":"

Support for new architectures can be added by inheriting from the Architecture class. Examples can be found in gef-extras.

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 be used over the generic ARM one:

@staticmethod\ndef supports_gdb_arch(gdb_arch: str) -> Optional[bool]:\n    return bool(re.search(\"^armv.*-m$\", gdb_arch))\n
"},{"location":"compat/","title":"GEF Compatibility","text":"

This matrix indicates the version of Python and/or GDB

GEF version GDB Python compatibility* Python compatibility* 2018.02 7.2 Python 2.7, Python 3.4+ 2020.03 7.4 Python 2.7, Python 3.4+ 2022.01 7.7 Python 3.4+ Current 8.0+ Python 3.6+
  • Up to - included
"},{"location":"config/","title":"Configuration","text":""},{"location":"config/#configuring-gef","title":"Configuring GEF","text":"

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. To create a basic file with all settings and their default values, simply run

gdb -ex 'gef save' -ex quit\n

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. Without argument the command will simply dump all known settings:

To update, follow the syntax

gef\u27a4  gef config <Module>.<ModuleSetting>  <Value>\n

Any setting updated this way will be specific to the current GDB session. To make permanent, use the following command

gef\u27a4  gef save\n

Refer to the gef config command documentation for complete explanation.

"},{"location":"deprecated/","title":"Deprecated commands","text":"

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 or even simply removed. This page aims to track those changes.

Command Status Since Link (if Applicable) Notes cs-disassemble Moved 2022.06 Link Depends on capstone assemble Moved 2022.06 Link Depends on keystone emulate Moved 2022.06 Link Depends on unicorn and capstone set-permission Moved 2022.06 Link Depends on keystone ropper Moved 2022.06 Link Depends on ropper ida-interact Moved 2022.06 Link Depends on rpyc exploit-template Moved c402900 Link windbg Moved a933a5a Link is-syscall Moved 3f79fb38 Link syscall-args Moved 3f79fb38 Link"},{"location":"faq/","title":"Frequently Asked Questions","text":""},{"location":"faq/#why-use-gef-over-peda","title":"Why use GEF over PEDA?","text":"

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!

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.

"},{"location":"faq/#what-if-my-gdb-is-80","title":"What if my GDB is < 8.0 ?","text":"

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. For really older versions of GDB, you can use 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 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 repository.

"},{"location":"faq/#i-cannot-get-gef-setup","title":"I cannot get GEF setup!!","text":"

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

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.

"},{"location":"faq/#i-get-a-segfault-when-starting-gdb-with-gef","title":"I get a SegFault when starting GDB with GEF","text":"

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\nGEF ready, type `gef' to start, `gef config' to configure\n53 commands loaded, using Python engine 3.4\n[*] 5 commands could not be loaded, run `gef missing` to know why.\n[+] Configuration from '/root/.gef.rc' restored\nReading symbols from ./bof-aarch64...(no debugging symbols found)...done.\nSegmentation fault (core dumped)\n

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\n[...]\n[gef]\nreadline_compat = True\n

You can now use all features of gef even on versions of GDB compiled against old readline library.

"},{"location":"faq/#does-gef-prevent-the-use-of-other-gdb-plugins","title":"Does GEF prevent the use of other GDB plugins?","text":"

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:

  • !exploitable
  • Voltron

Src: @rick2600: terminator + gdb + gef + voltron cc: @snare @hugsy

"},{"location":"faq/#i-want-to-contribute-where-should-i-head-first","title":"I want to contribute, where should I head first?","text":"

I would suggest thoroughly reading this documentation, just having a look to the CONTRIBUTE file of the project to give you pointers.

Also a good thing would be to join our Discord channel to get in touch with the people involved/using it.

"},{"location":"faq/#i-think-ive-found-a-bug-how-can-i-help-fixing-it","title":"I think I've found a bug, how can I help fixing it?","text":"

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:

By switching to debug mode, gef will give much more information:

gef\u27a4  gef config gef.debug 1\n

If you think fixing it is in your skills, then send a Pull Request with your patched version, explaining your bug, and what was your solution for it.

Otherwise, you can open an issue, give a thorough description of your bug and copy/paste the content from above. This will greatly help for solving the issue.

"},{"location":"faq/#i-get-weird-issuescharacters-using-gdb-python3-whats-up","title":"I get weird issues/characters using GDB + Python3, what's up?","text":"

Chances are you are not using UTF-8. Python3 is highly relying on UTF-8 to display correctly characters of any alphabet and also some cool emojis. 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:

$ LC_ALL=en_US.UTF-8 gdb /path/to/your/binary\n
"},{"location":"faq/#gdb-crashes-on-arm-memory-corruption-with-gdb_exception_return_mask_error","title":"GDB crashes on ARM memory corruption with gdb_exception_RETURN_MASK_ERROR","text":"

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

gdb version 7.12, as distributed w/ Raspbian/Kali rolling (only distro's tested,) throws an exception while disassembling ARM binaries when using gef. This is not a gef problem, this is a gdb problem. gef is just the tool that revealed the gdb dain bramage! (The issue was not observed using vanilla gdb/peda/pwndbg) This issue was first noted when using si to step through a 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

This turns out to be a known problem (regression) with gdb, and affects gef users running the ARM platform (Raspberry Pi).

The mitigation is for ARM users to compile gdb from source and run the latest 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.

The whole topic was already internally discussed, so please refer to the [issue

"},{"location":"faq/#206httpsgithubcomhugsygefissues206-for-the-whole-story","title":"206](https://github.com/hugsy/gef/issues/206) for the whole story.","text":""},{"location":"faq/#i-still-dont-have-my-answer-where-can-i-go","title":"I still don't have my answer... Where can I go?","text":"

Discord is your answer: join and talk to us by clicking here

If you cannot find the answer to your problem here or on the Discord, then go to the project Issues page and fill up the forms with as much information as you can!

"},{"location":"faq/#how-can-i-use-gef-to-debug-a-process-in-a-container","title":"How can I use GEF to debug a process in a container?","text":"

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 <container ID> -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 may improve results.

"},{"location":"install/","title":"Installing GEF","text":""},{"location":"install/#prerequisites","title":"Prerequisites","text":"

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.

"},{"location":"install/#gdb","title":"GDB","text":"

Only GDB 8 and higher 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.

GEF will then only work for Python 3. If you absolutely require GDB + Python 2, please use 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:

$ gdb -nx -ex 'pi print(sys.version)' -ex quit\n

This should display your version of Python compiled with gdb.

$ gdb -nx -ex 'pi print(sys.version)' -ex quit\n3.6.9 (default, Nov  7 2019, 10:44:02)\n[GCC 8.3.0]\n
"},{"location":"install/#python-dependencies","title":"Python dependencies","text":"

There are none: GEF works out of the box!

GEF itself provides most (if not all \ud83e\udd2f) 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

"},{"location":"install/#standalone","title":"Standalone","text":""},{"location":"install/#quick-install","title":"Quick install","text":"

The quickest way to get started with GEF is through the installation script available. Simply make sure you have GDB 8.0 or higher, compiled with Python 3.6 or higher, and run

bash -c \"$(curl -fsSL https://gef.blah.cat/sh)\"\n

Or if you prefer wget

bash -c \"$(wget https://gef.blah.cat/sh -O -)\"\n

Alternatively from inside gdb directly:

$ gdb -q\n(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)\n

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.

$ cat ~/.gdbinit\nsource ~/.gdbinit-gef.py\n
"},{"location":"install/#update","title":"Update","text":"

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

$ python ~/.gdbinit-gef.py --update\nUpdated\n

This will deploy the latest version of gef's main branch from Github. If no updates are available, gef will respond No update instead.

"},{"location":"install/#using-git","title":"Using git","text":"

To contribute to GEF, you might prefer using git directly.

$ git clone --branch dev https://github.com/hugsy/gef.git\n$ echo source `pwd`/gef/gef.py >> ~/.gdbinit\n

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:

$ git checkout main\n

The main branch gets only updated for new releases, or also when critical fixes occur and need to be patched urgently.

"},{"location":"install/#community-repository-gef-extras","title":"Community repository: GEF-Extras","text":"

GEF was built to also provide a solid base for external scripts. The repository 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:

# using the automated way\n## via the install script\n$ bash -c \"$(wget https://github.com/hugsy/gef/raw/main/scripts/gef-extras.sh -O -)\"\n\n# or manually\n## clone the repo\n$ git clone --branch main https://github.com/hugsy/gef-extras.git\n\n## then specify gef to load this directory\n$ gdb -ex 'gef config gef.extra_plugins_dir \"/path/to/gef-extras/scripts\"' -ex 'gef save' -ex quit\n[+] Configuration saved\n

You can also use the structures defined from this repository:

$ gdb -ex 'gef config pcustom.struct_path \"/path/to/gef-extras/structs\"' -ex 'gef save' -ex quit\n[+] Configuration saved\n

There, you're now fully equipped epic pwnage with all GEF's goodness!!

"},{"location":"install/#uninstalling-gef","title":"Uninstalling GEF","text":""},{"location":"install/#prevent-script-loading","title":"Prevent script loading","text":"

GDB provides the -nx command line flag to disable the commands from the ~/.gdbinit to be executed.

gdb -nx\n
"},{"location":"install/#disable-gef","title":"Disable GEF","text":"

To disable GEF without removing it, go to editing ~/.gdbinit, spot the line that sources GEF, and comment / delete that line:

So:

$ cat ~/.gdbinit\nsource /my/path/to/gef.py\n

Will become:

$ cat ~/.gdbinit\n# source /my/path/to/gef.py\n

Restart GDB, GEF is gone. Note that you can also load GEF at any moment during your GDB session as such:

$ gdb\n(gdb) source /my/path/to/gef.py\n
"},{"location":"install/#remove-gef","title":"Remove GEF","text":"

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:

$ cat ~/.gdbinit\n# source /my/path/to/gef.py\n$ rm /my/path/to/gef.py ~/.gef.rc\n

GEF is totally removed from your system.

"},{"location":"screenshots/","title":"Screenshots","text":"

This page illustrates a few of the possibilities available to you when using GEF.

"},{"location":"screenshots/#multi-architecture-support","title":"Multi-architecture support","text":"

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
"},{"location":"screenshots/#features","title":"Features","text":""},{"location":"screenshots/#embedded-hexdump-view","title":"Embedded hexdump view","text":"

To this day, GDB doesn't come with a hexdump-like view. Well GEF fixes that for you via the hexdump command:

"},{"location":"screenshots/#dereferencing-data-or-registers","title":"Dereferencing data or registers","text":"

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:

"},{"location":"screenshots/#heap-analysis","title":"Heap analysis","text":""},{"location":"screenshots/#detailed-view-of-glibc-chunks","title":"Detailed view of Glibc Chunks","text":""},{"location":"screenshots/#automatic-detection-of-uaf-during-runtime","title":"Automatic detection of UaF during runtime","text":""},{"location":"screenshots/#display-elf-information","title":"Display ELF information","text":""},{"location":"screenshots/#elf-structure","title":"ELF structure","text":""},{"location":"screenshots/#security-settings","title":"Security settings","text":""},{"location":"screenshots/#automatic-vulnerable-string-detection","title":"Automatic vulnerable string detection","text":""},{"location":"screenshots/#code-emulation-with-unicorn-engine-x86-64","title":"Code emulation with Unicorn-Engine (x86-64)","text":""},{"location":"screenshots/#comprehensive-address-space-layout-display","title":"Comprehensive address space layout display","text":""},{"location":"screenshots/#defining-arbitrary-custom-structures","title":"Defining arbitrary custom structures","text":""},{"location":"screenshots/#highlight-custom-strings","title":"Highlight custom strings","text":""},{"location":"testing/","title":"Testing","text":""},{"location":"testing/#testing-gef","title":"Testing GEF","text":"

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.

"},{"location":"testing/#prerequisites","title":"Prerequisites","text":"

All the prerequisite packages are in requirements.txt file at the root of the project. So running

python -m pip install -r tests/requirements.txt --user -U\n

is enough to get started.

"},{"location":"testing/#running-tests","title":"Running tests","text":""},{"location":"testing/#basic-pytest","title":"Basic pytest","text":"

For testing GEF on the architecture on the host running the tests (most cases), simply run

cd /root/of/gef\npython3 -m pytest -v -k \"not benchmark\" tests\n

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:

gdb -q -nx -ex \"pi print('.'.join(map(str, sys.version_info[:2])))\" -ex quit\n

At the end, a summary of explanation will be shown, clearly indicating the tests that have failed, for instance:

=================================== short test summary info ==================================\nFAILED tests/commands/heap.py::HeapCommand::test_cmd_heap_bins_large - AssertionError: 'siz...\nFAILED tests/commands/heap.py::HeapCommand::test_cmd_heap_bins_small - AssertionError: 'siz...\nFAILED tests/commands/heap.py::HeapCommand::test_cmd_heap_bins_unsorted - AssertionError: '...\n======================== 3 failed, 4 passed, 113 deselected in 385.77s (0:06:25)==============\n

You can then use pytest directly to help you fix each error specifically.

"},{"location":"testing/#using-pytest","title":"Using pytest","text":"

GEF entirely relies on pytest 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

A skeleton of a test module would look something like:

\"\"\"\n`my-command` command test module\n\"\"\"\n\n\nfrom tests.utils import GefUnitTestGeneric, gdb_run_cmd, gdb_start_silent_cmd\n\n\nclass MyCommandCommand(GefUnitTestGeneric):\n    \"\"\"`my-command` command test module\"\"\"\n\n    def test_cmd_my_command(self):\n        # `my-command` is expected to fail if the session is not active\n        self.assertFailIfInactiveSession(gdb_run_cmd(\"my-command\"))\n\n        # `my-command` should never throw an exception in GDB when running\n        res = gdb_start_silent_cmd(\"my-command\")\n        self.assertNoException(res)\n\n        # it also must print out a \"Hello World\" message\n        self.assertIn(\"Hello World\", res)\n

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.

"},{"location":"testing/#linting-gef","title":"Linting GEF","text":"

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:

cd /root/of/gef\npython3 -m pylint --rcfile .pylintrc\n

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:

gdb -q -nx -ex \"pi print('.'.join(map(str, sys.version_info[:2])))\" -ex quit\n
"},{"location":"testing/#benchmarking-gef","title":"Benchmarking GEF","text":"

Benchmarking relies on pytest-benchmark and is experimental for now.

You can run all benchmark test cases as such:

cd /root/of/gef\npytest -k benchmark\n

which will return (after some time) an execution summary

tests/perf/benchmark.py ..                                                               [100%]\n\n\n---------------------------------------- benchmark: 3 tests -----------------------------------\nName (time in ms)          Min                 Max                Mean            StdDev              Median                IQR            Outliers     OPS            Rounds  Iterations\n-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\ntime_baseline         612.2325 (1.0)      630.3416 (1.01)     623.7984 (1.01)     7.2848 (1.64)     626.1485 (1.01)      9.9971 (1.81)          1;0  1.6031 (0.99)          5           1\ntime_cmd_context      613.8124 (1.00)     625.8964 (1.0)      620.1908 (1.0)      4.4532 (1.0)      619.8831 (1.0)       5.5109 (1.0)           2;0  1.6124 (1.0)           5           1\ntime_elf_parsing      616.5053 (1.01)     638.6965 (1.02)     628.1588 (1.01)     8.2465 (1.85)     629.0099 (1.01)     10.7885 (1.96)          2;0  1.5920 (0.99)          5           1\n-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n\nLegend:\n  Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile.\n  OPS: Operations Per Second, computed as 1 / Mean\n============================================== 3 passed, 117 deselected in 14.78s =============================================\n
"},{"location":"api/gef/","title":"API","text":""},{"location":"api/gef/#module-gef","title":"module GEF","text":""},{"location":"api/gef/#global-variables","title":"Global Variables","text":"
  • 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
  • progspace
  • errmsg
"},{"location":"api/gef/#function-http_get","title":"function http_get","text":"
http_get(url: str) \u2192 Optional[bytes]\n

Basic HTTP wrapper for GET request. Return the body of the page if HTTP code is OK, otherwise return None.

"},{"location":"api/gef/#function-update_gef","title":"function update_gef","text":"
update_gef(argv: List[str]) \u2192 int\n

Try to update gef to the latest version pushed on GitHub main branch. Return 0 on success, 1 on failure.

"},{"location":"api/gef/#function-reset_all_caches","title":"function reset_all_caches","text":"
reset_all_caches() \u2192 None\n

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.

"},{"location":"api/gef/#function-reset","title":"function reset","text":"
reset() \u2192 None\n
"},{"location":"api/gef/#function-highlight_text","title":"function highlight_text","text":"
highlight_text(text: str) \u2192 str\n

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.

"},{"location":"api/gef/#function-gef_print","title":"function gef_print","text":"
gef_print(*args: str, end='\\n', sep=' ', **kwargs: Any) \u2192 None\n

Wrapper around print(), using string buffering feature.

"},{"location":"api/gef/#function-bufferize","title":"function bufferize","text":"
bufferize(f: Callable) \u2192 Callable\n

Store the content to be printed for a function in memory, and flush it on function exit.

"},{"location":"api/gef/#function-p8","title":"function p8","text":"
p8(\n    x: int,\n    s: bool = False,\n    e: Optional[ForwardRef('Endianness')] = None\n) \u2192 bytes\n

Pack one byte respecting the current architecture endianness.

"},{"location":"api/gef/#function-p16","title":"function p16","text":"
p16(\n    x: int,\n    s: bool = False,\n    e: Optional[ForwardRef('Endianness')] = None\n) \u2192 bytes\n

Pack one word respecting the current architecture endianness.

"},{"location":"api/gef/#function-p32","title":"function p32","text":"
p32(\n    x: int,\n    s: bool = False,\n    e: Optional[ForwardRef('Endianness')] = None\n) \u2192 bytes\n

Pack one dword respecting the current architecture endianness.

"},{"location":"api/gef/#function-p64","title":"function p64","text":"
p64(\n    x: int,\n    s: bool = False,\n    e: Optional[ForwardRef('Endianness')] = None\n) \u2192 bytes\n

Pack one qword respecting the current architecture endianness.

"},{"location":"api/gef/#function-u8","title":"function u8","text":"
u8(\n    x: bytes,\n    s: bool = False,\n    e: Optional[ForwardRef('Endianness')] = None\n) \u2192 int\n

Unpack one byte respecting the current architecture endianness.

"},{"location":"api/gef/#function-u16","title":"function u16","text":"
u16(\n    x: bytes,\n    s: bool = False,\n    e: Optional[ForwardRef('Endianness')] = None\n) \u2192 int\n

Unpack one word respecting the current architecture endianness.

"},{"location":"api/gef/#function-u32","title":"function u32","text":"
u32(\n    x: bytes,\n    s: bool = False,\n    e: Optional[ForwardRef('Endianness')] = None\n) \u2192 int\n

Unpack one dword respecting the current architecture endianness.

"},{"location":"api/gef/#function-u64","title":"function u64","text":"
u64(\n    x: bytes,\n    s: bool = False,\n    e: Optional[ForwardRef('Endianness')] = None\n) \u2192 int\n

Unpack one qword respecting the current architecture endianness.

"},{"location":"api/gef/#function-is_ascii_string","title":"function is_ascii_string","text":"
is_ascii_string(address: int) \u2192 bool\n

Helper function to determine if the buffer pointed by address is an ASCII string (in GDB)

"},{"location":"api/gef/#function-is_alive","title":"function is_alive","text":"
is_alive() \u2192 bool\n

Check if GDB is running.

"},{"location":"api/gef/#function-calling_function","title":"function calling_function","text":"
calling_function() \u2192 Optional[str]\n

Return the name of the calling function

"},{"location":"api/gef/#function-only_if_gdb_running","title":"function only_if_gdb_running","text":"
only_if_gdb_running(f: Callable) \u2192 Callable\n

Decorator wrapper to check if GDB is running.

"},{"location":"api/gef/#function-only_if_gdb_target_local","title":"function only_if_gdb_target_local","text":"
only_if_gdb_target_local(f: Callable) \u2192 Callable\n

Decorator wrapper to check if GDB is running locally (target not remote).

"},{"location":"api/gef/#function-deprecated","title":"function deprecated","text":"
deprecated(solution: str = '') \u2192 Callable\n

Decorator to add a warning when a command is obsolete and will be removed.

"},{"location":"api/gef/#function-experimental_feature","title":"function experimental_feature","text":"
experimental_feature(f: Callable) \u2192 Callable\n

Decorator to add a warning when a feature is experimental.

"},{"location":"api/gef/#function-only_if_events_supported","title":"function only_if_events_supported","text":"
only_if_events_supported(event_type: str) \u2192 Callable\n

Checks if GDB supports events without crashing.

"},{"location":"api/gef/#function-wrapped_f","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_1","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_2","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_3","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_4","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_5","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_6","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_7","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_8","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_9","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_10","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_11","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_12","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-wrapped_f_13","title":"function wrapped_f","text":"
wrapped_f(*args: Any, **kwargs: Any) \u2192 Any\n
"},{"location":"api/gef/#function-fakeexit","title":"function FakeExit","text":"
FakeExit(*args: Any, **kwargs: Any) \u2192 NoReturn\n
"},{"location":"api/gef/#function-parse_arguments","title":"function parse_arguments","text":"
parse_arguments(\n    required_arguments: Dict[Union[str, Tuple[str, str]], Any],\n    optional_arguments: Dict[Union[str, Tuple[str, str]], Any]\n) \u2192 Callable\n

Argument parsing decorator.

"},{"location":"api/gef/#function-search_for_main_arena","title":"function search_for_main_arena","text":"
search_for_main_arena() \u2192 int\n

search_for_main_arena is DEPRECATED and will be removed in the future. Use GefHeapManager.find_main_arena_addr()

"},{"location":"api/gef/#function-get_libc_version","title":"function get_libc_version","text":"
get_libc_version() \u2192 Tuple[int, ...]\n

get_libc_version is DEPRECATED and will be removed in the future. Use GefLibcManager.find_libc_version()

"},{"location":"api/gef/#function-titlify","title":"function titlify","text":"
titlify(\n    text: str,\n    color: Optional[str] = None,\n    msg_color: Optional[str] = None\n) \u2192 str\n

Print a centered title.

"},{"location":"api/gef/#function-dbg","title":"function dbg","text":"
dbg(msg: str) \u2192 None\n
"},{"location":"api/gef/#function-err","title":"function err","text":"
err(msg: str) \u2192 None\n
"},{"location":"api/gef/#function-warn","title":"function warn","text":"
warn(msg: str) \u2192 None\n
"},{"location":"api/gef/#function-ok","title":"function ok","text":"
ok(msg: str) \u2192 None\n
"},{"location":"api/gef/#function-info","title":"function info","text":"
info(msg: str) \u2192 None\n
"},{"location":"api/gef/#function-push_context_message","title":"function push_context_message","text":"
push_context_message(level: str, message: str) \u2192 None\n

Push the message to be displayed the next time the context is invoked.

"},{"location":"api/gef/#function-show_last_exception","title":"function show_last_exception","text":"
show_last_exception() \u2192 None\n

Display the last Python exception.

"},{"location":"api/gef/#function-gef_pystring","title":"function gef_pystring","text":"
gef_pystring(x: bytes) \u2192 str\n

Returns a sanitized version as string of the bytes list given in input.

"},{"location":"api/gef/#function-gef_pybytes","title":"function gef_pybytes","text":"
gef_pybytes(x: str) \u2192 bytes\n

Returns an immutable bytes list from the string given as input.

"},{"location":"api/gef/#function-style_byte","title":"function style_byte","text":"
style_byte(b: int, color: bool = True) \u2192 str\n
"},{"location":"api/gef/#function-hexdump","title":"function hexdump","text":"
hexdump(\n    source: ByteString,\n    length: int = 16,\n    separator: str = '.',\n    show_raw: bool = False,\n    show_symbol: bool = True,\n    base: int = 0\n) \u2192 str\n

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

"},{"location":"api/gef/#function-is_debug","title":"function is_debug","text":"
is_debug() \u2192 bool\n

Check if debug mode is enabled.

"},{"location":"api/gef/#function-buffer_output","title":"function buffer_output","text":"
buffer_output() \u2192 bool\n

Check if output should be buffered until command completion.

"},{"location":"api/gef/#function-hide_context","title":"function hide_context","text":"
hide_context() \u2192 bool\n

Helper function to hide the context pane.

"},{"location":"api/gef/#function-unhide_context","title":"function unhide_context","text":"
unhide_context() \u2192 bool\n

Helper function to unhide the context pane.

"},{"location":"api/gef/#function-enable_redirect_output","title":"function enable_redirect_output","text":"
enable_redirect_output(to_file: str = '/dev/null') \u2192 None\n

Redirect all GDB output to to_file parameter. By default, to_file redirects to /dev/null.

"},{"location":"api/gef/#function-disable_redirect_output","title":"function disable_redirect_output","text":"
disable_redirect_output() \u2192 None\n

Disable the output redirection, if any.

"},{"location":"api/gef/#function-gef_makedirs","title":"function gef_makedirs","text":"
gef_makedirs(path: str, mode: int = 493) \u2192 Path\n

Recursive mkdir() creation. If successful, return the absolute path of the directory created.

"},{"location":"api/gef/#function-gdb_disassemble","title":"function gdb_disassemble","text":"
gdb_disassemble(\n    start_pc: int,\n    **kwargs: int\n) \u2192 Generator[__main__.Instruction, NoneType, NoneType]\n

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

"},{"location":"api/gef/#function-gdb_get_nth_previous_instruction_address","title":"function gdb_get_nth_previous_instruction_address","text":"
gdb_get_nth_previous_instruction_address(addr: int, n: int) \u2192 Optional[int]\n

Return the address (Integer) of the n-th instruction before addr.

"},{"location":"api/gef/#function-gdb_get_nth_next_instruction_address","title":"function gdb_get_nth_next_instruction_address","text":"
gdb_get_nth_next_instruction_address(addr: int, n: int) \u2192 int\n

Return the address of the n-th instruction after addr. gdb_get_nth_next_instruction_address is DEPRECATED and will be removed in the future. Use gef_instruction_n().address

"},{"location":"api/gef/#function-gef_instruction_n","title":"function gef_instruction_n","text":"
gef_instruction_n(addr: int, n: int) \u2192 Instruction\n

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)

"},{"location":"api/gef/#function-gef_get_instruction_at","title":"function gef_get_instruction_at","text":"
gef_get_instruction_at(addr: int) \u2192 Instruction\n

Return the full Instruction found at the specified address.

"},{"location":"api/gef/#function-gef_current_instruction","title":"function gef_current_instruction","text":"
gef_current_instruction(addr: int) \u2192 Instruction\n

Return the current instruction as an Instruction object.

"},{"location":"api/gef/#function-gef_next_instruction","title":"function gef_next_instruction","text":"
gef_next_instruction(addr: int) \u2192 Instruction\n

Return the next instruction as an Instruction object.

"},{"location":"api/gef/#function-gef_disassemble","title":"function gef_disassemble","text":"
gef_disassemble(\n    addr: int,\n    nb_insn: int,\n    nb_prev: int = 0\n) \u2192 Generator[__main__.Instruction, NoneType, NoneType]\n

Disassemble nb_insn instructions after addr and nb_prev before addr. Return an iterator of Instruction objects.

"},{"location":"api/gef/#function-gef_execute_external","title":"function gef_execute_external","text":"
gef_execute_external(\n    command: Sequence[str],\n    as_list: bool = False,\n    **kwargs: Any\n) \u2192 Union[str, List[str]]\n

Execute an external command and return the result.

"},{"location":"api/gef/#function-gef_execute_gdb_script","title":"function gef_execute_gdb_script","text":"
gef_execute_gdb_script(commands: str) \u2192 None\n

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.

"},{"location":"api/gef/#function-checksec","title":"function checksec","text":"
checksec(filename: str) \u2192 Dict[str, bool]\n

checksec is DEPRECATED and will be removed in the future. Use Elf(fname).checksec()

"},{"location":"api/gef/#function-get_entry_point","title":"function get_entry_point","text":"
get_entry_point() \u2192 Optional[int]\n

Return the binary entry point. get_entry_point is DEPRECATED and will be removed in the future. Use gef.binary.entry_point instead

"},{"location":"api/gef/#function-is_pie","title":"function is_pie","text":"
is_pie(fpath: str) \u2192 bool\n
"},{"location":"api/gef/#function-is_big_endian","title":"function is_big_endian","text":"
is_big_endian() \u2192 bool\n

is_big_endian is DEPRECATED and will be removed in the future. Prefer gef.arch.endianness == Endianness.BIG_ENDIAN

"},{"location":"api/gef/#function-is_little_endian","title":"function is_little_endian","text":"
is_little_endian() \u2192 bool\n

is_little_endian is DEPRECATED and will be removed in the future. gef.arch.endianness == Endianness.LITTLE_ENDIAN

"},{"location":"api/gef/#function-flags_to_human","title":"function flags_to_human","text":"
flags_to_human(reg_value: int, value_table: Dict[int, str]) \u2192 str\n

Return a human readable string showing the flag states.

"},{"location":"api/gef/#function-register_architecture","title":"function register_architecture","text":"
register_architecture(\n    cls: Type[ForwardRef('Architecture')]\n) \u2192 Type[ForwardRef('Architecture')]\n

register_architecture is DEPRECATED and will be removed in the future. Using the decorator register_architecture is unecessary

"},{"location":"api/gef/#function-copy_to_clipboard","title":"function copy_to_clipboard","text":"
copy_to_clipboard(data: bytes) \u2192 None\n

Helper function to submit data to the clipboard

"},{"location":"api/gef/#function-use_stdtype","title":"function use_stdtype","text":"
use_stdtype() \u2192 str\n
"},{"location":"api/gef/#function-use_default_type","title":"function use_default_type","text":"
use_default_type() \u2192 str\n
"},{"location":"api/gef/#function-use_golang_type","title":"function use_golang_type","text":"
use_golang_type() \u2192 str\n
"},{"location":"api/gef/#function-use_rust_type","title":"function use_rust_type","text":"
use_rust_type() \u2192 str\n
"},{"location":"api/gef/#function-to_unsigned_long","title":"function to_unsigned_long","text":"
to_unsigned_long(v: gdb.Value) \u2192 int\n

Cast a gdb.Value to unsigned long.

"},{"location":"api/gef/#function-get_path_from_info_proc","title":"function get_path_from_info_proc","text":"
get_path_from_info_proc() \u2192 Optional[str]\n
"},{"location":"api/gef/#function-get_os","title":"function get_os","text":"
get_os() \u2192 str\n

get_os is DEPRECATED and will be removed in the future. Use gef.session.os

"},{"location":"api/gef/#function-get_filepath","title":"function get_filepath","text":"
get_filepath() \u2192 Optional[str]\n

Return the local absolute path of the file currently debugged.

"},{"location":"api/gef/#function-get_function_length","title":"function get_function_length","text":"
get_function_length(sym: str) \u2192 int\n

Attempt to get the length of the raw bytes of a function.

"},{"location":"api/gef/#function-process_lookup_address","title":"function process_lookup_address","text":"
process_lookup_address(address: int) \u2192 Optional[__main__.Section]\n

Look up for an address in memory. Return an Address object if found, None otherwise.

"},{"location":"api/gef/#function-xor","title":"function xor","text":"
xor(data: ByteString, key: str) \u2192 bytearray\n

Return data xor-ed with key.

"},{"location":"api/gef/#function-is_hex","title":"function is_hex","text":"
is_hex(pattern: str) \u2192 bool\n

Return whether provided string is a hexadecimal value.

"},{"location":"api/gef/#function-continue_handler","title":"function continue_handler","text":"
continue_handler(_: 'gdb.ContinueEvent') \u2192 None\n

GDB event handler for new object continue cases.

"},{"location":"api/gef/#function-hook_stop_handler","title":"function hook_stop_handler","text":"
hook_stop_handler(_: 'gdb.StopEvent') \u2192 None\n

GDB event handler for stop cases.

"},{"location":"api/gef/#function-new_objfile_handler","title":"function new_objfile_handler","text":"
new_objfile_handler(evt: Optional[ForwardRef('gdb.NewObjFileEvent')]) \u2192 None\n

GDB event handler for new object file cases.

"},{"location":"api/gef/#function-exit_handler","title":"function exit_handler","text":"
exit_handler(_: 'gdb.ExitedEvent') \u2192 None\n

GDB event handler for exit cases.

"},{"location":"api/gef/#function-memchanged_handler","title":"function memchanged_handler","text":"
memchanged_handler(_: 'gdb.MemoryChangedEvent') \u2192 None\n

GDB event handler for mem changes cases.

"},{"location":"api/gef/#function-regchanged_handler","title":"function regchanged_handler","text":"
regchanged_handler(_: 'gdb.RegisterChangedEvent') \u2192 None\n

GDB event handler for reg changes cases.

"},{"location":"api/gef/#function-get_terminal_size","title":"function get_terminal_size","text":"
get_terminal_size() \u2192 Tuple[int, int]\n

Return the current terminal size.

"},{"location":"api/gef/#function-reset_architecture","title":"function reset_architecture","text":"
reset_architecture(arch: Optional[str] = None) \u2192 None\n

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.

"},{"location":"api/gef/#function-get_memory_alignment","title":"function get_memory_alignment","text":"
get_memory_alignment(in_bits: bool = False) \u2192 int\n

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

"},{"location":"api/gef/#function-clear_screen","title":"function clear_screen","text":"
clear_screen(tty: str = '') \u2192 None\n

Clear the screen.

"},{"location":"api/gef/#function-format_address","title":"function format_address","text":"
format_address(addr: int) \u2192 str\n

Format the address according to its size.

"},{"location":"api/gef/#function-format_address_spaces","title":"function format_address_spaces","text":"
format_address_spaces(addr: int, left: bool = True) \u2192 str\n

Format the address according to its size, but with spaces instead of zeroes.

"},{"location":"api/gef/#function-align_address","title":"function align_address","text":"
align_address(address: int) \u2192 int\n

Align the provided address to the process's native length.

"},{"location":"api/gef/#function-align_address_to_size","title":"function align_address_to_size","text":"
align_address_to_size(address: int, align: int) \u2192 int\n

Align the address to the given size.

"},{"location":"api/gef/#function-align_address_to_page","title":"function align_address_to_page","text":"
align_address_to_page(address: int) \u2192 int\n

Align the address to a page.

"},{"location":"api/gef/#function-parse_address","title":"function parse_address","text":"
parse_address(address: str) \u2192 int\n

Parse an address and return it as an Integer.

"},{"location":"api/gef/#function-is_in_x86_kernel","title":"function is_in_x86_kernel","text":"
is_in_x86_kernel(address: int) \u2192 bool\n
"},{"location":"api/gef/#function-is_remote_debug","title":"function is_remote_debug","text":"
is_remote_debug() \u2192 bool\n

\"Return True is the current debugging session is running through GDB remote session.

"},{"location":"api/gef/#function-de_bruijn","title":"function de_bruijn","text":"
de_bruijn(alphabet: bytes, n: int) \u2192 Generator[str, NoneType, NoneType]\n

De Bruijn sequence for alphabet and subsequences of length n (for compat. w/ pwnlib).

"},{"location":"api/gef/#function-generate_cyclic_pattern","title":"function generate_cyclic_pattern","text":"
generate_cyclic_pattern(length: int, cycle: int = 4) \u2192 bytearray\n

Create a length byte bytearray of a de Bruijn cyclic pattern.

"},{"location":"api/gef/#function-safe_parse_and_eval","title":"function safe_parse_and_eval","text":"
safe_parse_and_eval(value: str) \u2192 Optional[ForwardRef('gdb.Value')]\n

GEF wrapper for gdb.parse_and_eval(): this function returns None instead of raising gdb.error if the eval failed.

"},{"location":"api/gef/#function-gef_convenience","title":"function gef_convenience","text":"
gef_convenience(value: Union[str, bytes]) \u2192 str\n

Defines a new convenience value.

"},{"location":"api/gef/#function-parse_string_range","title":"function parse_string_range","text":"
parse_string_range(s: str) \u2192 Iterator[int]\n

Parses an address range (e.g. 0x400000-0x401000)

"},{"location":"api/gef/#function-gef_get_pie_breakpoint","title":"function gef_get_pie_breakpoint","text":"
gef_get_pie_breakpoint(num: int) \u2192 PieVirtualBreakpoint\n

gef_get_pie_breakpoint is DEPRECATED and will be removed in the future. Use gef.session.pie_breakpoints[num]

"},{"location":"api/gef/#function-endian_str","title":"function endian_str","text":"
endian_str() \u2192 str\n

endian_str is DEPRECATED and will be removed in the future. Use str(gef.arch.endianness) instead

"},{"location":"api/gef/#function-get_gef_setting","title":"function get_gef_setting","text":"
get_gef_setting(name: str) \u2192 Any\n

get_gef_setting is DEPRECATED and will be removed in the future. Use gef.config[key]

"},{"location":"api/gef/#function-set_gef_setting","title":"function set_gef_setting","text":"
set_gef_setting(name: str, value: Any) \u2192 None\n

set_gef_setting is DEPRECATED and will be removed in the future. Use gef.config[key] = value

"},{"location":"api/gef/#function-gef_getpagesize","title":"function gef_getpagesize","text":"
gef_getpagesize() \u2192 int\n

gef_getpagesize is DEPRECATED and will be removed in the future. Use gef.session.pagesize

"},{"location":"api/gef/#function-gef_read_canary","title":"function gef_read_canary","text":"
gef_read_canary() \u2192 Optional[Tuple[int, int]]\n

gef_read_canary is DEPRECATED and will be removed in the future. Use gef.session.canary

"},{"location":"api/gef/#function-get_pid","title":"function get_pid","text":"
get_pid() \u2192 int\n

get_pid is DEPRECATED and will be removed in the future. Use gef.session.pid

"},{"location":"api/gef/#function-get_filename","title":"function get_filename","text":"
get_filename() \u2192 str\n

get_filename is DEPRECATED and will be removed in the future. Use gef.session.file.name

"},{"location":"api/gef/#function-get_glibc_arena","title":"function get_glibc_arena","text":"
get_glibc_arena() \u2192 Optional[__main__.GlibcArena]\n

get_glibc_arena is DEPRECATED and will be removed in the future. Use gef.heap.main_arena

"},{"location":"api/gef/#function-get_register","title":"function get_register","text":"
get_register(regname) \u2192 Optional[int]\n

get_register is DEPRECATED and will be removed in the future. Use gef.arch.register(regname)

"},{"location":"api/gef/#function-get_process_maps","title":"function get_process_maps","text":"
get_process_maps() \u2192 List[__main__.Section]\n

get_process_maps is DEPRECATED and will be removed in the future. Use gef.memory.maps

"},{"location":"api/gef/#function-set_arch","title":"function set_arch","text":"
set_arch(arch: Optional[str] = None, _: Optional[str] = None) \u2192 None\n

set_arch is DEPRECATED and will be removed in the future. Use reset_architecture

"},{"location":"api/gef/#function-register_external_context_pane","title":"function register_external_context_pane","text":"
register_external_context_pane(\n    pane_name: str,\n    display_pane_function: Callable[[], NoneType],\n    pane_title_function: Callable[[], Optional[str]],\n    condition: Optional[Callable[[], bool]] = None\n) \u2192 None\n

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)

"},{"location":"api/gef/#function-register_external_command","title":"function register_external_command","text":"
register_external_command(\n    cls: Type[ForwardRef('GenericCommand')]\n) \u2192 Type[ForwardRef('GenericCommand')]\n

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

"},{"location":"api/gef/#function-register_command","title":"function register_command","text":"
register_command(\n    cls: Type[ForwardRef('GenericCommand')]\n) \u2192 Type[ForwardRef('GenericCommand')]\n

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

"},{"location":"api/gef/#function-register_priority_command","title":"function register_priority_command","text":"
register_priority_command(\n    cls: Type[ForwardRef('GenericCommand')]\n) \u2192 Type[ForwardRef('GenericCommand')]\n

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.

"},{"location":"api/gef/#function-register","title":"function register","text":"
register(\n    cls: Union[Type[ForwardRef('GenericCommand')], Type[ForwardRef('GenericFunction')]]\n) \u2192 Union[Type[ForwardRef('GenericCommand')], Type[ForwardRef('GenericFunction')]]\n
"},{"location":"api/gef/#function-register_function","title":"function register_function","text":"
register_function(\n    cls: Type[ForwardRef('GenericFunction')]\n) \u2192 Type[ForwardRef('GenericFunction')]\n

Decorator for registering a new convenience function to GDB. register_function is DEPRECATED and will be removed in the future.

"},{"location":"api/gef/#class-aarch64","title":"class AARCH64","text":""},{"location":"api/gef/#property-aarch64cpsr","title":"property AARCH64.cpsr","text":""},{"location":"api/gef/#property-aarch64endianness","title":"property AARCH64.endianness","text":""},{"location":"api/gef/#property-aarch64fp","title":"property AARCH64.fp","text":""},{"location":"api/gef/#property-aarch64instruction_length","title":"property AARCH64.instruction_length","text":""},{"location":"api/gef/#property-aarch64pc","title":"property AARCH64.pc","text":""},{"location":"api/gef/#property-aarch64ptrsize","title":"property AARCH64.ptrsize","text":"

Determine the size of pointer from the current CPU mode

"},{"location":"api/gef/#property-aarch64registers","title":"property AARCH64.registers","text":""},{"location":"api/gef/#property-aarch64sp","title":"property AARCH64.sp","text":""},{"location":"api/gef/#function-aarch64canary_address","title":"function AARCH64.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-aarch64flag_register_to_human","title":"function AARCH64.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-aarch64get_ith_parameter","title":"function AARCH64.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-aarch64get_ra","title":"function AARCH64.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 int\n
"},{"location":"api/gef/#function-aarch64is_aarch32","title":"function AARCH64.is_aarch32","text":"
is_aarch32() \u2192 bool\n

Determine if the CPU is currently in AARCH32 mode from runtime.

"},{"location":"api/gef/#function-aarch64is_branch_taken","title":"function AARCH64.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-aarch64is_call","title":"function AARCH64.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-aarch64is_conditional_branch","title":"function AARCH64.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-aarch64is_ret","title":"function AARCH64.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-aarch64is_thumb","title":"function AARCH64.is_thumb","text":"
is_thumb() \u2192 bool\n

Determine if the machine is currently in THUMB mode.

"},{"location":"api/gef/#function-aarch64is_thumb32","title":"function AARCH64.is_thumb32","text":"
is_thumb32() \u2192 bool\n

Determine if the CPU is currently in THUMB32 mode from runtime.

"},{"location":"api/gef/#function-aarch64mprotect_asm","title":"function AARCH64.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-aarch64register","title":"function AARCH64.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-aarch64reset_caches","title":"function AARCH64.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-aarch64supports_gdb_arch","title":"function AARCH64.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-arm","title":"class ARM","text":""},{"location":"api/gef/#property-armcpsr","title":"property ARM.cpsr","text":""},{"location":"api/gef/#property-armendianness","title":"property ARM.endianness","text":""},{"location":"api/gef/#property-armfp","title":"property ARM.fp","text":""},{"location":"api/gef/#property-arminstruction_length","title":"property ARM.instruction_length","text":""},{"location":"api/gef/#property-armmode","title":"property ARM.mode","text":""},{"location":"api/gef/#property-armpc","title":"property ARM.pc","text":""},{"location":"api/gef/#property-armptrsize","title":"property ARM.ptrsize","text":""},{"location":"api/gef/#property-armregisters","title":"property ARM.registers","text":""},{"location":"api/gef/#property-armsp","title":"property ARM.sp","text":""},{"location":"api/gef/#function-armcanary_address","title":"function ARM.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-armflag_register_to_human","title":"function ARM.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-armget_ith_parameter","title":"function ARM.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-armget_ra","title":"function ARM.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 int\n
"},{"location":"api/gef/#function-armis_branch_taken","title":"function ARM.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-armis_call","title":"function ARM.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-armis_conditional_branch","title":"function ARM.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-armis_ret","title":"function ARM.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-armis_thumb","title":"function ARM.is_thumb","text":"
is_thumb() \u2192 bool\n

Determine if the machine is currently in THUMB mode.

"},{"location":"api/gef/#function-armmprotect_asm","title":"function ARM.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-armregister","title":"function ARM.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-armreset_caches","title":"function ARM.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-armsupports_gdb_arch","title":"function ARM.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-aslrcommand","title":"class ASLRCommand","text":"

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.

"},{"location":"api/gef/#function-aslrcommand__init__","title":"function ASLRCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-aslrcommandsettings","title":"property ASLRCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-aslrcommandadd_setting","title":"function ASLRCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-aslrcommanddel_setting","title":"function ASLRCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-aslrcommanddo_invoke","title":"function ASLRCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-aslrcommandget_setting","title":"function ASLRCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-aslrcommandhas_setting","title":"function ASLRCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-aslrcommandinvoke","title":"function ASLRCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-aslrcommandpost_load","title":"function ASLRCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-aslrcommandpre_load","title":"function ASLRCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-aslrcommandusage","title":"function ASLRCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-address","title":"class Address","text":"

GEF representation of memory addresses.

"},{"location":"api/gef/#function-address__init__","title":"function Address.__init__","text":"
__init__(**kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-addressvalid","title":"property Address.valid","text":""},{"location":"api/gef/#function-addressdereference","title":"function Address.dereference","text":"
dereference() \u2192 Optional[int]\n
"},{"location":"api/gef/#function-addressis_in_heap_segment","title":"function Address.is_in_heap_segment","text":"
is_in_heap_segment() \u2192 bool\n
"},{"location":"api/gef/#function-addressis_in_stack_segment","title":"function Address.is_in_stack_segment","text":"
is_in_stack_segment() \u2192 bool\n
"},{"location":"api/gef/#function-addressis_in_text_segment","title":"function Address.is_in_text_segment","text":"
is_in_text_segment() \u2192 bool\n
"},{"location":"api/gef/#class-aliasesaddcommand","title":"class AliasesAddCommand","text":"

Command to add aliases.

"},{"location":"api/gef/#function-aliasesaddcommand__init__","title":"function AliasesAddCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-aliasesaddcommandsettings","title":"property AliasesAddCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-aliasesaddcommandadd_setting","title":"function AliasesAddCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-aliasesaddcommanddel_setting","title":"function AliasesAddCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-aliasesaddcommanddo_invoke","title":"function AliasesAddCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-aliasesaddcommandget_setting","title":"function AliasesAddCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-aliasesaddcommandhas_setting","title":"function AliasesAddCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-aliasesaddcommandinvoke","title":"function AliasesAddCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-aliasesaddcommandpost_load","title":"function AliasesAddCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-aliasesaddcommandpre_load","title":"function AliasesAddCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-aliasesaddcommandusage","title":"function AliasesAddCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-aliasescommand","title":"class AliasesCommand","text":"

Base command to add, remove, or list aliases.

"},{"location":"api/gef/#function-aliasescommand__init__","title":"function AliasesCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-aliasescommandsettings","title":"property AliasesCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-aliasescommandadd_setting","title":"function AliasesCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-aliasescommanddel_setting","title":"function AliasesCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-aliasescommanddo_invoke","title":"function AliasesCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-aliasescommandget_setting","title":"function AliasesCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-aliasescommandhas_setting","title":"function AliasesCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-aliasescommandinvoke","title":"function AliasesCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-aliasescommandpost_load","title":"function AliasesCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-aliasescommandpre_load","title":"function AliasesCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-aliasescommandusage","title":"function AliasesCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-aliaseslistcommand","title":"class AliasesListCommand","text":"

Command to list aliases.

"},{"location":"api/gef/#function-aliaseslistcommand__init__","title":"function AliasesListCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-aliaseslistcommandsettings","title":"property AliasesListCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-aliaseslistcommandadd_setting","title":"function AliasesListCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-aliaseslistcommanddel_setting","title":"function AliasesListCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-aliaseslistcommanddo_invoke","title":"function AliasesListCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-aliaseslistcommandget_setting","title":"function AliasesListCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-aliaseslistcommandhas_setting","title":"function AliasesListCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-aliaseslistcommandinvoke","title":"function AliasesListCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-aliaseslistcommandpost_load","title":"function AliasesListCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-aliaseslistcommandpre_load","title":"function AliasesListCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-aliaseslistcommandusage","title":"function AliasesListCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-aliasesrmcommand","title":"class AliasesRmCommand","text":"

Command to remove aliases.

"},{"location":"api/gef/#function-aliasesrmcommand__init__","title":"function AliasesRmCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-aliasesrmcommandsettings","title":"property AliasesRmCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-aliasesrmcommandadd_setting","title":"function AliasesRmCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-aliasesrmcommanddel_setting","title":"function AliasesRmCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-aliasesrmcommanddo_invoke","title":"function AliasesRmCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-aliasesrmcommandget_setting","title":"function AliasesRmCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-aliasesrmcommandhas_setting","title":"function AliasesRmCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-aliasesrmcommandinvoke","title":"function AliasesRmCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-aliasesrmcommandpost_load","title":"function AliasesRmCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-aliasesrmcommandpre_load","title":"function AliasesRmCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-aliasesrmcommandusage","title":"function AliasesRmCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-architecture","title":"class Architecture","text":"

Generic metaclass for the architecture supported by GEF.

"},{"location":"api/gef/#property-architectureendianness","title":"property Architecture.endianness","text":""},{"location":"api/gef/#property-architecturefp","title":"property Architecture.fp","text":""},{"location":"api/gef/#property-architecturepc","title":"property Architecture.pc","text":""},{"location":"api/gef/#property-architectureptrsize","title":"property Architecture.ptrsize","text":""},{"location":"api/gef/#property-architectureregisters","title":"property Architecture.registers","text":""},{"location":"api/gef/#property-architecturesp","title":"property Architecture.sp","text":""},{"location":"api/gef/#function-architecturecanary_address","title":"function Architecture.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-architectureflag_register_to_human","title":"function Architecture.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-architectureget_ith_parameter","title":"function Architecture.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-architectureget_ra","title":"function Architecture.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 Optional[int]\n
"},{"location":"api/gef/#function-architectureis_branch_taken","title":"function Architecture.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-architectureis_call","title":"function Architecture.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-architectureis_conditional_branch","title":"function Architecture.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-architectureis_ret","title":"function Architecture.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-architecturemprotect_asm","title":"function Architecture.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-architectureregister","title":"function Architecture.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-architecturereset_caches","title":"function Architecture.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-architecturesupports_gdb_arch","title":"function Architecture.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-architecturebase","title":"class ArchitectureBase","text":"

Class decorator for declaring an architecture to GEF.

"},{"location":"api/gef/#class-bssbasefunction","title":"class BssBaseFunction","text":"

Return the current bss base address plus the given offset.

"},{"location":"api/gef/#function-bssbasefunction__init__","title":"function BssBaseFunction.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-bssbasefunctionarg_to_long","title":"function BssBaseFunction.arg_to_long","text":"
arg_to_long(args: List, index: int, default: int = 0) \u2192 int\n
"},{"location":"api/gef/#function-bssbasefunctiondo_invoke","title":"function BssBaseFunction.do_invoke","text":"
do_invoke(args: List) \u2192 int\n
"},{"location":"api/gef/#function-bssbasefunctioninvoke","title":"function BssBaseFunction.invoke","text":"
invoke(*args: Any) \u2192 int\n
"},{"location":"api/gef/#class-canarycommand","title":"class CanaryCommand","text":"

Shows the canary value of the current process.

"},{"location":"api/gef/#function-canarycommand__init__","title":"function CanaryCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-canarycommandsettings","title":"property CanaryCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-canarycommandadd_setting","title":"function CanaryCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-canarycommanddel_setting","title":"function CanaryCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-canarycommanddo_invoke","title":"function CanaryCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-canarycommandget_setting","title":"function CanaryCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-canarycommandhas_setting","title":"function CanaryCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-canarycommandinvoke","title":"function CanaryCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-canarycommandpost_load","title":"function CanaryCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-canarycommandpre_load","title":"function CanaryCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-canarycommandusage","title":"function CanaryCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-changefdcommand","title":"class ChangeFdCommand","text":"

ChangeFdCommand: redirect file descriptor during runtime.

"},{"location":"api/gef/#function-changefdcommand__init__","title":"function ChangeFdCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-changefdcommandsettings","title":"property ChangeFdCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-changefdcommandadd_setting","title":"function ChangeFdCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-changefdcommanddel_setting","title":"function ChangeFdCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-changefdcommanddo_invoke","title":"function ChangeFdCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-changefdcommandget_fd_from_result","title":"function ChangeFdCommand.get_fd_from_result","text":"
get_fd_from_result(res: str) \u2192 int\n
"},{"location":"api/gef/#function-changefdcommandget_setting","title":"function ChangeFdCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-changefdcommandhas_setting","title":"function ChangeFdCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-changefdcommandinvoke","title":"function ChangeFdCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-changefdcommandpost_load","title":"function ChangeFdCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-changefdcommandpre_load","title":"function ChangeFdCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-changefdcommandusage","title":"function ChangeFdCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-changepermissionbreakpoint","title":"class ChangePermissionBreakpoint","text":"

When hit, this temporary breakpoint will restore the original code, and position $pc correctly.

"},{"location":"api/gef/#function-changepermissionbreakpoint__init__","title":"function ChangePermissionBreakpoint.__init__","text":"
__init__(loc: str, code: ByteString, pc: int) \u2192 None\n
"},{"location":"api/gef/#function-changepermissionbreakpointstop","title":"function ChangePermissionBreakpoint.stop","text":"
stop() \u2192 bool\n
"},{"location":"api/gef/#class-checkseccommand","title":"class ChecksecCommand","text":"

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

"},{"location":"api/gef/#function-checkseccommand__init__","title":"function ChecksecCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-checkseccommandsettings","title":"property ChecksecCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-checkseccommandadd_setting","title":"function ChecksecCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-checkseccommanddel_setting","title":"function ChecksecCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-checkseccommanddo_invoke","title":"function ChecksecCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-checkseccommandget_setting","title":"function ChecksecCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-checkseccommandhas_setting","title":"function ChecksecCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-checkseccommandinvoke","title":"function ChecksecCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-checkseccommandpost_load","title":"function ChecksecCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-checkseccommandpre_load","title":"function ChecksecCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-checkseccommandprint_security_properties","title":"function ChecksecCommand.print_security_properties","text":"
print_security_properties(filename: str) \u2192 None\n
"},{"location":"api/gef/#function-checkseccommandusage","title":"function ChecksecCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-color","title":"class Color","text":"

Used to colorify terminal output.

"},{"location":"api/gef/#function-colorblinkify","title":"function Color.blinkify","text":"
blinkify(msg: str) \u2192 str\n
"},{"location":"api/gef/#function-colorblueify","title":"function Color.blueify","text":"
blueify(msg: str) \u2192 str\n
"},{"location":"api/gef/#function-colorboldify","title":"function Color.boldify","text":"
boldify(msg: str) \u2192 str\n
"},{"location":"api/gef/#function-colorcolorify","title":"function Color.colorify","text":"
colorify(text: str, attrs: str) \u2192 str\n

Color text according to the given attributes.

"},{"location":"api/gef/#function-colorcyanify","title":"function Color.cyanify","text":"
cyanify(msg: str) \u2192 str\n
"},{"location":"api/gef/#function-colorgrayify","title":"function Color.grayify","text":"
grayify(msg: str) \u2192 str\n
"},{"location":"api/gef/#function-colorgreenify","title":"function Color.greenify","text":"
greenify(msg: str) \u2192 str\n
"},{"location":"api/gef/#function-colorhighlightify","title":"function Color.highlightify","text":"
highlightify(msg: str) \u2192 str\n
"},{"location":"api/gef/#function-colorlight_grayify","title":"function Color.light_grayify","text":"
light_grayify(msg: str) \u2192 str\n
"},{"location":"api/gef/#function-colorpinkify","title":"function Color.pinkify","text":"
pinkify(msg: str) \u2192 str\n
"},{"location":"api/gef/#function-colorredify","title":"function Color.redify","text":"
redify(msg: str) \u2192 str\n
"},{"location":"api/gef/#function-colorunderlinify","title":"function Color.underlinify","text":"
underlinify(msg: str) \u2192 str\n
"},{"location":"api/gef/#function-coloryellowify","title":"function Color.yellowify","text":"
yellowify(msg: str) \u2192 str\n
"},{"location":"api/gef/#class-contextcommand","title":"class ContextCommand","text":"

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.

"},{"location":"api/gef/#function-contextcommand__init__","title":"function ContextCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-contextcommandsettings","title":"property ContextCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-contextcommandadd_setting","title":"function ContextCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-contextcommandaddr_has_breakpoint","title":"function ContextCommand.addr_has_breakpoint","text":"
addr_has_breakpoint(address: int, bp_locations: List[str]) \u2192 bool\n
"},{"location":"api/gef/#function-contextcommandcontext_additional_information","title":"function ContextCommand.context_additional_information","text":"
context_additional_information() \u2192 None\n
"},{"location":"api/gef/#function-contextcommandcontext_args","title":"function ContextCommand.context_args","text":"
context_args() \u2192 None\n
"},{"location":"api/gef/#function-contextcommandcontext_code","title":"function ContextCommand.context_code","text":"
context_code() \u2192 None\n
"},{"location":"api/gef/#function-contextcommandcontext_memory","title":"function ContextCommand.context_memory","text":"
context_memory() \u2192 None\n
"},{"location":"api/gef/#function-contextcommandcontext_regs","title":"function ContextCommand.context_regs","text":"
context_regs() \u2192 None\n
"},{"location":"api/gef/#function-contextcommandcontext_source","title":"function ContextCommand.context_source","text":"
context_source() \u2192 None\n
"},{"location":"api/gef/#function-contextcommandcontext_stack","title":"function ContextCommand.context_stack","text":"
context_stack() \u2192 None\n
"},{"location":"api/gef/#function-contextcommandcontext_threads","title":"function ContextCommand.context_threads","text":"
context_threads() \u2192 None\n
"},{"location":"api/gef/#function-contextcommandcontext_title","title":"function ContextCommand.context_title","text":"
context_title(m: Optional[str]) \u2192 None\n
"},{"location":"api/gef/#function-contextcommandcontext_trace","title":"function ContextCommand.context_trace","text":"
context_trace() \u2192 None\n
"},{"location":"api/gef/#function-contextcommanddel_setting","title":"function ContextCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-contextcommanddo_invoke","title":"function ContextCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-contextcommandempty_extra_messages","title":"function ContextCommand.empty_extra_messages","text":"
empty_extra_messages(_) \u2192 None\n
"},{"location":"api/gef/#function-contextcommandget_pc_context_info","title":"function ContextCommand.get_pc_context_info","text":"
get_pc_context_info(pc: int, line: str) \u2192 str\n
"},{"location":"api/gef/#function-contextcommandget_setting","title":"function ContextCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-contextcommandhas_setting","title":"function ContextCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-contextcommandinvoke","title":"function ContextCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-contextcommandline_has_breakpoint","title":"function ContextCommand.line_has_breakpoint","text":"
line_has_breakpoint(\n    file_name: str,\n    line_number: int,\n    bp_locations: List[str]\n) \u2192 bool\n
"},{"location":"api/gef/#function-contextcommandpost_load","title":"function ContextCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-contextcommandpre_load","title":"function ContextCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-contextcommandprint_arguments_from_symbol","title":"function ContextCommand.print_arguments_from_symbol","text":"
print_arguments_from_symbol(function_name: str, symbol: 'gdb.Symbol') \u2192 None\n

If symbols were found, parse them and print the argument adequately.

"},{"location":"api/gef/#function-contextcommandprint_guessed_arguments","title":"function ContextCommand.print_guessed_arguments","text":"
print_guessed_arguments(function_name: str) \u2192 None\n

When no symbol, read the current basic block and look for \"interesting\" instructions.

"},{"location":"api/gef/#function-contextcommandshow_legend","title":"function ContextCommand.show_legend","text":"
show_legend() \u2192 None\n
"},{"location":"api/gef/#function-contextcommandupdate_registers","title":"function ContextCommand.update_registers","text":"
update_registers(_) \u2192 None\n
"},{"location":"api/gef/#function-contextcommandusage","title":"function ContextCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-dereferencecommand","title":"class DereferenceCommand","text":"

Dereference recursively from an address and display information. This acts like WinDBG dps command.

"},{"location":"api/gef/#function-dereferencecommand__init__","title":"function DereferenceCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-dereferencecommandsettings","title":"property DereferenceCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-dereferencecommandadd_setting","title":"function DereferenceCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-dereferencecommanddel_setting","title":"function DereferenceCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-dereferencecommandwrapper","title":"function DereferenceCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-dereferencecommandget_setting","title":"function DereferenceCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-dereferencecommandhas_setting","title":"function DereferenceCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-dereferencecommandinvoke","title":"function DereferenceCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-dereferencecommandpost_load","title":"function DereferenceCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-dereferencecommandpprint_dereferenced","title":"function DereferenceCommand.pprint_dereferenced","text":"
pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) \u2192 str\n
"},{"location":"api/gef/#function-dereferencecommandpre_load","title":"function DereferenceCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-dereferencecommandusage","title":"function DereferenceCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-detailregisterscommand","title":"class DetailRegistersCommand","text":"

Display full details on one, many or all registers value from current architecture.

"},{"location":"api/gef/#function-detailregisterscommand__init__","title":"function DetailRegistersCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-detailregisterscommandsettings","title":"property DetailRegistersCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-detailregisterscommandadd_setting","title":"function DetailRegistersCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-detailregisterscommanddel_setting","title":"function DetailRegistersCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-detailregisterscommandwrapper","title":"function DetailRegistersCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-detailregisterscommandget_setting","title":"function DetailRegistersCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-detailregisterscommandhas_setting","title":"function DetailRegistersCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-detailregisterscommandinvoke","title":"function DetailRegistersCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-detailregisterscommandpost_load","title":"function DetailRegistersCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-detailregisterscommandpre_load","title":"function DetailRegistersCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-detailregisterscommandusage","title":"function DetailRegistersCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-disablecontextoutputcontext","title":"class DisableContextOutputContext","text":""},{"location":"api/gef/#class-elf","title":"class Elf","text":"

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

"},{"location":"api/gef/#function-elf__init__","title":"function Elf.__init__","text":"
__init__(path: Union[str, pathlib.Path]) \u2192 None\n

Instantiate an ELF object. A valid ELF must be provided, or an exception will be thrown.

"},{"location":"api/gef/#property-elfchecksec","title":"property Elf.checksec","text":"

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.

"},{"location":"api/gef/#property-elfentry_point","title":"property Elf.entry_point","text":""},{"location":"api/gef/#function-elfis_valid","title":"function Elf.is_valid","text":"
is_valid(path: pathlib.Path) \u2192 bool\n
"},{"location":"api/gef/#function-elfread","title":"function Elf.read","text":"
read(size: int) \u2192 bytes\n
"},{"location":"api/gef/#function-elfread_and_unpack","title":"function Elf.read_and_unpack","text":"
read_and_unpack(fmt: str) \u2192 Tuple[Any, ...]\n
"},{"location":"api/gef/#function-elfseek","title":"function Elf.seek","text":"
seek(off: int) \u2192 None\n
"},{"location":"api/gef/#class-elfinfocommand","title":"class ElfInfoCommand","text":"

Display a limited subset of ELF header information. If no argument is provided, the command will show information about the current ELF being debugged.

"},{"location":"api/gef/#function-elfinfocommand__init__","title":"function ElfInfoCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-elfinfocommandsettings","title":"property ElfInfoCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-elfinfocommandadd_setting","title":"function ElfInfoCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-elfinfocommanddel_setting","title":"function ElfInfoCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-elfinfocommandwrapper","title":"function ElfInfoCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-elfinfocommandget_setting","title":"function ElfInfoCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-elfinfocommandhas_setting","title":"function ElfInfoCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-elfinfocommandinvoke","title":"function ElfInfoCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-elfinfocommandpost_load","title":"function ElfInfoCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-elfinfocommandpre_load","title":"function ElfInfoCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-elfinfocommandusage","title":"function ElfInfoCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-endianness","title":"class Endianness","text":"

An enumeration.

"},{"location":"api/gef/#class-entrybreakbreakpoint","title":"class EntryBreakBreakpoint","text":"

Breakpoint used internally to stop execution at the most convenient entry point.

"},{"location":"api/gef/#function-entrybreakbreakpoint__init__","title":"function EntryBreakBreakpoint.__init__","text":"
__init__(location: str) \u2192 None\n
"},{"location":"api/gef/#function-entrybreakbreakpointstop","title":"function EntryBreakBreakpoint.stop","text":"
stop() \u2192 bool\n
"},{"location":"api/gef/#class-entrypointbreakcommand","title":"class EntryPointBreakCommand","text":"

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.

"},{"location":"api/gef/#function-entrypointbreakcommand__init__","title":"function EntryPointBreakCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-entrypointbreakcommandsettings","title":"property EntryPointBreakCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-entrypointbreakcommandadd_setting","title":"function EntryPointBreakCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-entrypointbreakcommanddel_setting","title":"function EntryPointBreakCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-entrypointbreakcommanddo_invoke","title":"function EntryPointBreakCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-entrypointbreakcommandget_setting","title":"function EntryPointBreakCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-entrypointbreakcommandhas_setting","title":"function EntryPointBreakCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-entrypointbreakcommandinvoke","title":"function EntryPointBreakCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-entrypointbreakcommandpost_load","title":"function EntryPointBreakCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-entrypointbreakcommandpre_load","title":"function EntryPointBreakCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-entrypointbreakcommandset_init_tbreak","title":"function EntryPointBreakCommand.set_init_tbreak","text":"
set_init_tbreak(addr: int) \u2192 EntryBreakBreakpoint\n
"},{"location":"api/gef/#function-entrypointbreakcommandset_init_tbreak_pie","title":"function EntryPointBreakCommand.set_init_tbreak_pie","text":"
set_init_tbreak_pie(addr: int, argv: List[str]) \u2192 EntryBreakBreakpoint\n
"},{"location":"api/gef/#function-entrypointbreakcommandusage","title":"function EntryPointBreakCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-externalstructuremanager","title":"class ExternalStructureManager","text":""},{"location":"api/gef/#function-externalstructuremanager__init__","title":"function ExternalStructureManager.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-externalstructuremanagermodules","title":"property ExternalStructureManager.modules","text":""},{"location":"api/gef/#property-externalstructuremanagerpath","title":"property ExternalStructureManager.path","text":""},{"location":"api/gef/#property-externalstructuremanagerstructures","title":"property ExternalStructureManager.structures","text":""},{"location":"api/gef/#handler-externalstructuremanagerfind","title":"handler ExternalStructureManager.find","text":""},{"location":"api/gef/#function-externalstructuremanagerclear_caches","title":"function ExternalStructureManager.clear_caches","text":"
clear_caches() \u2192 None\n
"},{"location":"api/gef/#class-fileformat","title":"class FileFormat","text":""},{"location":"api/gef/#function-fileformat__init__","title":"function FileFormat.__init__","text":"
__init__(path: Union[str, pathlib.Path]) \u2192 None\n
"},{"location":"api/gef/#function-fileformatis_valid","title":"function FileFormat.is_valid","text":"
is_valid(path: pathlib.Path) \u2192 bool\n
"},{"location":"api/gef/#class-fileformatsection","title":"class FileFormatSection","text":""},{"location":"api/gef/#class-flagscommand","title":"class FlagsCommand","text":"

Edit flags in a human friendly way.

"},{"location":"api/gef/#function-flagscommand__init__","title":"function FlagsCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-flagscommandsettings","title":"property FlagsCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-flagscommandadd_setting","title":"function FlagsCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-flagscommanddel_setting","title":"function FlagsCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-flagscommanddo_invoke","title":"function FlagsCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-flagscommandget_setting","title":"function FlagsCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-flagscommandhas_setting","title":"function FlagsCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-flagscommandinvoke","title":"function FlagsCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-flagscommandpost_load","title":"function FlagsCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-flagscommandpre_load","title":"function FlagsCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-flagscommandusage","title":"function FlagsCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-formatstringbreakpoint","title":"class FormatStringBreakpoint","text":"

Inspect stack for format string.

"},{"location":"api/gef/#function-formatstringbreakpoint__init__","title":"function FormatStringBreakpoint.__init__","text":"
__init__(spec: str, num_args: int) \u2192 None\n
"},{"location":"api/gef/#function-formatstringbreakpointstop","title":"function FormatStringBreakpoint.stop","text":"
stop() \u2192 bool\n
"},{"location":"api/gef/#class-formatstringsearchcommand","title":"class FormatStringSearchCommand","text":"

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.

"},{"location":"api/gef/#function-formatstringsearchcommand__init__","title":"function FormatStringSearchCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-formatstringsearchcommandsettings","title":"property FormatStringSearchCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-formatstringsearchcommandadd_setting","title":"function FormatStringSearchCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-formatstringsearchcommanddel_setting","title":"function FormatStringSearchCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-formatstringsearchcommanddo_invoke","title":"function FormatStringSearchCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-formatstringsearchcommandget_setting","title":"function FormatStringSearchCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-formatstringsearchcommandhas_setting","title":"function FormatStringSearchCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-formatstringsearchcommandinvoke","title":"function FormatStringSearchCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-formatstringsearchcommandpost_load","title":"function FormatStringSearchCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-formatstringsearchcommandpre_load","title":"function FormatStringSearchCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-formatstringsearchcommandusage","title":"function FormatStringSearchCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-gdbremovereadlinefinder","title":"class GdbRemoveReadlineFinder","text":""},{"location":"api/gef/#function-gdbremovereadlinefinderfind_module","title":"function GdbRemoveReadlineFinder.find_module","text":"
find_module(fullname, path=None)\n
"},{"location":"api/gef/#function-gdbremovereadlinefinderload_module","title":"function GdbRemoveReadlineFinder.load_module","text":"
load_module(fullname)\n
"},{"location":"api/gef/#class-gef","title":"class Gef","text":"

The GEF root class, which serves as a entrypoint for all the debugging session attributes (architecture, memory, settings, etc.).

"},{"location":"api/gef/#function-gef__init__","title":"function Gef.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-gefreinitialize_managers","title":"function Gef.reinitialize_managers","text":"
reinitialize_managers() \u2192 None\n

Reinitialize the managers. Avoid calling this function directly, using pi reset() is preferred

"},{"location":"api/gef/#function-gefreset_caches","title":"function Gef.reset_caches","text":"
reset_caches() \u2192 None\n

Recursively clean the cache of all the managers. Avoid calling this function directly, using reset-cache is preferred

"},{"location":"api/gef/#function-gefsetup","title":"function Gef.setup","text":"
setup() \u2192 None\n

Setup initialize the runtime setup, which may require for the gef to be not None.

"},{"location":"api/gef/#class-gefalias","title":"class GefAlias","text":"

Simple aliasing wrapper because GDB doesn't do what it should.

"},{"location":"api/gef/#function-gefalias__init__","title":"function GefAlias.__init__","text":"
__init__(\n    alias: str,\n    command: str,\n    completer_class: int = 0,\n    command_class: int = -1\n) \u2192 None\n
"},{"location":"api/gef/#function-gefaliasinvoke","title":"function GefAlias.invoke","text":"
invoke(args: Any, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-gefaliaslookup_command","title":"function GefAlias.lookup_command","text":"
lookup_command(cmd: str) \u2192 Optional[Tuple[str, __main__.GenericCommand]]\n
"},{"location":"api/gef/#class-gefcommand","title":"class GefCommand","text":"

GEF main command: view all new commands by typing gef.

"},{"location":"api/gef/#function-gefcommand__init__","title":"function GefCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-gefcommandloaded_command_names","title":"property GefCommand.loaded_command_names","text":""},{"location":"api/gef/#property-gefcommandloaded_commands","title":"property GefCommand.loaded_commands","text":""},{"location":"api/gef/#property-gefcommandloaded_functions","title":"property GefCommand.loaded_functions","text":""},{"location":"api/gef/#property-gefcommandmissing_commands","title":"property GefCommand.missing_commands","text":""},{"location":"api/gef/#function-gefcommandadd_context_pane","title":"function GefCommand.add_context_pane","text":"
add_context_pane(\n    pane_name: str,\n    display_pane_function: Callable,\n    pane_title_function: Callable,\n    condition: Optional[Callable]\n) \u2192 None\n

Add a new context pane to ContextCommand.

"},{"location":"api/gef/#function-gefcommandinvoke","title":"function GefCommand.invoke","text":"
invoke(args: Any, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-gefcommandload","title":"function GefCommand.load","text":"
load() \u2192 None\n

Load all the commands and functions defined by GEF into GDB.

"},{"location":"api/gef/#function-gefcommandload_extra_plugins","title":"function GefCommand.load_extra_plugins","text":"
load_extra_plugins() \u2192 int\n
"},{"location":"api/gef/#function-gefcommandsetup","title":"function GefCommand.setup","text":"
setup() \u2192 None\n
"},{"location":"api/gef/#function-gefcommandshow_banner","title":"function GefCommand.show_banner","text":"
show_banner() \u2192 None\n
"},{"location":"api/gef/#class-gefconfigcommand","title":"class GefConfigCommand","text":"

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

"},{"location":"api/gef/#function-gefconfigcommand__init__","title":"function GefConfigCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-gefconfigcommandcomplete","title":"function GefConfigCommand.complete","text":"
complete(text: str, word: str) \u2192 List[str]\n
"},{"location":"api/gef/#function-gefconfigcommandinvoke","title":"function GefConfigCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-gefconfigcommandprint_setting","title":"function GefConfigCommand.print_setting","text":"
print_setting(plugin_name: str, verbose: bool = False) \u2192 None\n
"},{"location":"api/gef/#function-gefconfigcommandprint_settings","title":"function GefConfigCommand.print_settings","text":"
print_settings() \u2192 None\n
"},{"location":"api/gef/#function-gefconfigcommandset_setting","title":"function GefConfigCommand.set_setting","text":"
set_setting(argv: Tuple[str, Any]) \u2192 None\n
"},{"location":"api/gef/#class-geffunctionscommand","title":"class GefFunctionsCommand","text":"

List the convenience functions provided by GEF.

"},{"location":"api/gef/#function-geffunctionscommand__init__","title":"function GefFunctionsCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-geffunctionscommandsettings","title":"property GefFunctionsCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-geffunctionscommandadd_setting","title":"function GefFunctionsCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-geffunctionscommanddel_setting","title":"function GefFunctionsCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-geffunctionscommanddo_invoke","title":"function GefFunctionsCommand.do_invoke","text":"
do_invoke(argv) \u2192 None\n
"},{"location":"api/gef/#function-geffunctionscommandget_setting","title":"function GefFunctionsCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-geffunctionscommandhas_setting","title":"function GefFunctionsCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-geffunctionscommandinvoke","title":"function GefFunctionsCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-geffunctionscommandpost_load","title":"function GefFunctionsCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-geffunctionscommandpre_load","title":"function GefFunctionsCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-geffunctionscommandusage","title":"function GefFunctionsCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-gefheapmanager","title":"class GefHeapManager","text":"

Class managing session heap.

"},{"location":"api/gef/#function-gefheapmanager__init__","title":"function GefHeapManager.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-gefheapmanagerarenas","title":"property GefHeapManager.arenas","text":""},{"location":"api/gef/#property-gefheapmanagerbase_address","title":"property GefHeapManager.base_address","text":""},{"location":"api/gef/#property-gefheapmanagerchunks","title":"property GefHeapManager.chunks","text":""},{"location":"api/gef/#property-gefheapmanagermain_arena","title":"property GefHeapManager.main_arena","text":""},{"location":"api/gef/#property-gefheapmanagermalloc_alignment","title":"property GefHeapManager.malloc_alignment","text":""},{"location":"api/gef/#property-gefheapmanagermin_chunk_size","title":"property GefHeapManager.min_chunk_size","text":""},{"location":"api/gef/#property-gefheapmanagerselected_arena","title":"property GefHeapManager.selected_arena","text":""},{"location":"api/gef/#handler-gefheapmanagerfind_main_arena_addr","title":"handler GefHeapManager.find_main_arena_addr","text":""},{"location":"api/gef/#function-gefheapmanagercsize2tidx","title":"function GefHeapManager.csize2tidx","text":"
csize2tidx(size: int) \u2192 int\n
"},{"location":"api/gef/#function-gefheapmanagermalloc_align_address","title":"function GefHeapManager.malloc_align_address","text":"
malloc_align_address(address: int) \u2192 int\n

Align addresses according to glibc's MALLOC_ALIGNMENT. See also Issue #689 on Github

"},{"location":"api/gef/#function-gefheapmanagerreset_caches","title":"function GefHeapManager.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-gefheapmanagertidx2size","title":"function GefHeapManager.tidx2size","text":"
tidx2size(idx: int) \u2192 int\n
"},{"location":"api/gef/#class-gefhelpcommand","title":"class GefHelpCommand","text":"

GEF help sub-command.

"},{"location":"api/gef/#function-gefhelpcommand__init__","title":"function GefHelpCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-gefhelpcommandinvoke","title":"function GefHelpCommand.invoke","text":"
invoke(args: Any, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#class-gefinstallextrascriptcommand","title":"class GefInstallExtraScriptCommand","text":"

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.

"},{"location":"api/gef/#function-gefinstallextrascriptcommand__init__","title":"function GefInstallExtraScriptCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-gefinstallextrascriptcommandinvoke","title":"function GefInstallExtraScriptCommand.invoke","text":"
invoke(argv: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#class-geflibcmanager","title":"class GefLibcManager","text":"

Class managing everything libc-related (except heap).

"},{"location":"api/gef/#function-geflibcmanager__init__","title":"function GefLibcManager.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-geflibcmanagerversion","title":"property GefLibcManager.version","text":""},{"location":"api/gef/#handler-geflibcmanagerfind_libc_version","title":"handler GefLibcManager.find_libc_version","text":""},{"location":"api/gef/#function-geflibcmanagerreset_caches","title":"function GefLibcManager.reset_caches","text":"
reset_caches() \u2192 None\n

Reset the LRU-cached attributes

"},{"location":"api/gef/#class-gefmanager","title":"class GefManager","text":""},{"location":"api/gef/#function-gefmanagerreset_caches","title":"function GefManager.reset_caches","text":"
reset_caches() \u2192 None\n

Reset the LRU-cached attributes

"},{"location":"api/gef/#class-gefmemorymanager","title":"class GefMemoryManager","text":"

Class that manages memory access for gef.

"},{"location":"api/gef/#function-gefmemorymanager__init__","title":"function GefMemoryManager.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-gefmemorymanagermaps","title":"property GefMemoryManager.maps","text":""},{"location":"api/gef/#function-gefmemorymanagerread","title":"function GefMemoryManager.read","text":"
read(addr: int, length: int = 16) \u2192 bytes\n

Return a length long byte array with the copy of the process memory at addr.

"},{"location":"api/gef/#function-gefmemorymanagerread_ascii_string","title":"function GefMemoryManager.read_ascii_string","text":"
read_ascii_string(address: int) \u2192 Optional[str]\n

Read an ASCII string from memory

"},{"location":"api/gef/#function-gefmemorymanagerread_cstring","title":"function GefMemoryManager.read_cstring","text":"
read_cstring(\n    address: int,\n    max_length: int = 50,\n    encoding: Optional[str] = None\n) \u2192 str\n

Return a C-string read from memory.

"},{"location":"api/gef/#function-gefmemorymanagerread_integer","title":"function GefMemoryManager.read_integer","text":"
read_integer(addr: int) \u2192 int\n

Return an integer read from memory.

"},{"location":"api/gef/#function-gefmemorymanagerreset_caches","title":"function GefMemoryManager.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-gefmemorymanagerwrite","title":"function GefMemoryManager.write","text":"
write(address: int, buffer: ByteString, length: Optional[int] = None) \u2192 None\n

Write buffer at address address.

"},{"location":"api/gef/#class-gefmissingcommand","title":"class GefMissingCommand","text":"

GEF missing sub-command Display the GEF commands that could not be loaded, along with the reason of why they could not be loaded.

"},{"location":"api/gef/#function-gefmissingcommand__init__","title":"function GefMissingCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-gefmissingcommandinvoke","title":"function GefMissingCommand.invoke","text":"
invoke(args: Any, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#class-gefremotesessionmanager","title":"class GefRemoteSessionManager","text":"

Class for managing remote sessions with GEF. It will create a temporary environment designed to clone the remote one.

"},{"location":"api/gef/#function-gefremotesessionmanager__init__","title":"function GefRemoteSessionManager.__init__","text":"
__init__(\n    host: str,\n    port: int,\n    pid: int = -1,\n    qemu: Optional[pathlib.Path] = None\n) \u2192 None\n
"},{"location":"api/gef/#property-gefremotesessionmanagerauxiliary_vector","title":"property GefRemoteSessionManager.auxiliary_vector","text":""},{"location":"api/gef/#property-gefremotesessionmanagercanary","title":"property GefRemoteSessionManager.canary","text":"

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.

"},{"location":"api/gef/#property-gefremotesessionmanagercwd","title":"property GefRemoteSessionManager.cwd","text":""},{"location":"api/gef/#property-gefremotesessionmanagerfile","title":"property GefRemoteSessionManager.file","text":"

Path to the file being debugged as seen by the remote endpoint.

"},{"location":"api/gef/#property-gefremotesessionmanagerlfile","title":"property GefRemoteSessionManager.lfile","text":"

Local path to the file being debugged.

"},{"location":"api/gef/#property-gefremotesessionmanagermaps","title":"property GefRemoteSessionManager.maps","text":""},{"location":"api/gef/#property-gefremotesessionmanageroriginal_canary","title":"property GefRemoteSessionManager.original_canary","text":"

Return a tuple of the initial canary address and value, read from the auxiliary vector.

"},{"location":"api/gef/#property-gefremotesessionmanageros","title":"property GefRemoteSessionManager.os","text":"

Return the current OS.

"},{"location":"api/gef/#property-gefremotesessionmanagerpagesize","title":"property GefRemoteSessionManager.pagesize","text":"

Get the system page size

"},{"location":"api/gef/#property-gefremotesessionmanagerpid","title":"property GefRemoteSessionManager.pid","text":"

Return the PID of the target process.

"},{"location":"api/gef/#property-gefremotesessionmanagerroot","title":"property GefRemoteSessionManager.root","text":""},{"location":"api/gef/#property-gefremotesessionmanagertarget","title":"property GefRemoteSessionManager.target","text":""},{"location":"api/gef/#function-gefremotesessionmanagerclose","title":"function GefRemoteSessionManager.close","text":"
close() \u2192 None\n
"},{"location":"api/gef/#function-gefremotesessionmanagerconnect","title":"function GefRemoteSessionManager.connect","text":"
connect(pid: int) \u2192 bool\n

Connect to remote target. If in extended mode, also attach to the given PID.

"},{"location":"api/gef/#function-gefremotesessionmanagerin_qemu_user","title":"function GefRemoteSessionManager.in_qemu_user","text":"
in_qemu_user() \u2192 bool\n
"},{"location":"api/gef/#function-gefremotesessionmanagerremote_objfile_event_handler","title":"function GefRemoteSessionManager.remote_objfile_event_handler","text":"
remote_objfile_event_handler(evt: 'gdb.NewObjFileEvent') \u2192 None\n
"},{"location":"api/gef/#function-gefremotesessionmanagerreset_caches","title":"function GefRemoteSessionManager.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-gefremotesessionmanagersetup","title":"function GefRemoteSessionManager.setup","text":"
setup() \u2192 bool\n
"},{"location":"api/gef/#function-gefremotesessionmanagersync","title":"function GefRemoteSessionManager.sync","text":"
sync(src: str, dst: Optional[str] = None) \u2192 bool\n

Copy the src into the temporary chroot. If dst is provided, that path will be used instead of src.

"},{"location":"api/gef/#class-gefrestorecommand","title":"class GefRestoreCommand","text":"

GEF restore sub-command. Loads settings from file '~/.gef.rc' and apply them to the configuration of GEF.

"},{"location":"api/gef/#function-gefrestorecommand__init__","title":"function GefRestoreCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-gefrestorecommandinvoke","title":"function GefRestoreCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-gefrestorecommandreload","title":"function GefRestoreCommand.reload","text":"
reload(quiet: bool)\n
"},{"location":"api/gef/#class-gefruncommand","title":"class GefRunCommand","text":"

Override GDB run commands with the context from GEF. Simple wrapper for GDB run command to use arguments set from gef set args.

"},{"location":"api/gef/#function-gefruncommand__init__","title":"function GefRunCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-gefruncommandinvoke","title":"function GefRunCommand.invoke","text":"
invoke(args: Any, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#class-gefsavecommand","title":"class GefSaveCommand","text":"

GEF save sub-command. Saves the current configuration of GEF to disk (by default in file '~/.gef.rc').

"},{"location":"api/gef/#function-gefsavecommand__init__","title":"function GefSaveCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-gefsavecommandinvoke","title":"function GefSaveCommand.invoke","text":"
invoke(args: Any, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#class-gefsessionmanager","title":"class GefSessionManager","text":"

Class managing the runtime properties of GEF.

"},{"location":"api/gef/#function-gefsessionmanager__init__","title":"function GefSessionManager.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-gefsessionmanagerauxiliary_vector","title":"property GefSessionManager.auxiliary_vector","text":""},{"location":"api/gef/#property-gefsessionmanagercanary","title":"property GefSessionManager.canary","text":"

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.

"},{"location":"api/gef/#property-gefsessionmanagercwd","title":"property GefSessionManager.cwd","text":""},{"location":"api/gef/#property-gefsessionmanagerfile","title":"property GefSessionManager.file","text":"

Return a Path object of the target process.

"},{"location":"api/gef/#property-gefsessionmanagermaps","title":"property GefSessionManager.maps","text":"

Returns the Path to the procfs entry for the memory mapping.

"},{"location":"api/gef/#property-gefsessionmanageroriginal_canary","title":"property GefSessionManager.original_canary","text":"

Return a tuple of the initial canary address and value, read from the auxiliary vector.

"},{"location":"api/gef/#property-gefsessionmanageros","title":"property GefSessionManager.os","text":"

Return the current OS.

"},{"location":"api/gef/#property-gefsessionmanagerpagesize","title":"property GefSessionManager.pagesize","text":"

Get the system page size

"},{"location":"api/gef/#property-gefsessionmanagerpid","title":"property GefSessionManager.pid","text":"

Return the PID of the target process.

"},{"location":"api/gef/#property-gefsessionmanagerroot","title":"property GefSessionManager.root","text":"

Returns the path to the process's root directory.

"},{"location":"api/gef/#function-gefsessionmanagerreset_caches","title":"function GefSessionManager.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#class-gefsetcommand","title":"class GefSetCommand","text":"

Override GDB set commands with the context from GEF.

"},{"location":"api/gef/#function-gefsetcommand__init__","title":"function GefSetCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-gefsetcommandinvoke","title":"function GefSetCommand.invoke","text":"
invoke(args: Any, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#class-gefsetting","title":"class GefSetting","text":"

Basic class for storing gef settings as objects

"},{"location":"api/gef/#function-gefsetting__init__","title":"function GefSetting.__init__","text":"
__init__(\n    value: Any,\n    cls: Optional[type] = None,\n    description: Optional[str] = None,\n    hooks: Optional[Dict[str, Callable]] = None\n) \u2192 None\n
"},{"location":"api/gef/#class-gefsettingsmanager","title":"class GefSettingsManager","text":"

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]

"},{"location":"api/gef/#function-gefsettingsmanagerraw_entry","title":"function GefSettingsManager.raw_entry","text":"
raw_entry(name: str) \u2192 GefSetting\n
"},{"location":"api/gef/#class-gefthemecommand","title":"class GefThemeCommand","text":"

Customize GEF appearance.

"},{"location":"api/gef/#function-gefthemecommand__init__","title":"function GefThemeCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-gefthemecommandsettings","title":"property GefThemeCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-gefthemecommandadd_setting","title":"function GefThemeCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-gefthemecommanddel_setting","title":"function GefThemeCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-gefthemecommanddo_invoke","title":"function GefThemeCommand.do_invoke","text":"
do_invoke(args: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-gefthemecommandget_setting","title":"function GefThemeCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-gefthemecommandhas_setting","title":"function GefThemeCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-gefthemecommandinvoke","title":"function GefThemeCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-gefthemecommandpost_load","title":"function GefThemeCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-gefthemecommandpre_load","title":"function GefThemeCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-gefthemecommandusage","title":"function GefThemeCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-geftmuxsetup","title":"class GefTmuxSetup","text":"

Setup a confortable tmux debugging environment.

"},{"location":"api/gef/#function-geftmuxsetup__init__","title":"function GefTmuxSetup.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-geftmuxsetupinvoke","title":"function GefTmuxSetup.invoke","text":"
invoke(args: Any, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-geftmuxsetupscreen_setup","title":"function GefTmuxSetup.screen_setup","text":"
screen_setup() \u2192 None\n

Hackish equivalent of the tmux_setup() function for screen.

"},{"location":"api/gef/#function-geftmuxsetuptmux_setup","title":"function GefTmuxSetup.tmux_setup","text":"
tmux_setup() \u2192 None\n

Prepare the tmux environment by vertically splitting the current pane, and forcing the context to be redirected there.

"},{"location":"api/gef/#class-gefuimanager","title":"class GefUiManager","text":"

Class managing UI settings.

"},{"location":"api/gef/#function-gefuimanager__init__","title":"function GefUiManager.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-gefuimanagerreset_caches","title":"function GefUiManager.reset_caches","text":"
reset_caches() \u2192 None\n

Reset the LRU-cached attributes

"},{"location":"api/gef/#class-genericarchitecture","title":"class GenericArchitecture","text":""},{"location":"api/gef/#property-genericarchitectureendianness","title":"property GenericArchitecture.endianness","text":""},{"location":"api/gef/#property-genericarchitecturefp","title":"property GenericArchitecture.fp","text":""},{"location":"api/gef/#property-genericarchitecturepc","title":"property GenericArchitecture.pc","text":""},{"location":"api/gef/#property-genericarchitectureptrsize","title":"property GenericArchitecture.ptrsize","text":""},{"location":"api/gef/#property-genericarchitectureregisters","title":"property GenericArchitecture.registers","text":""},{"location":"api/gef/#property-genericarchitecturesp","title":"property GenericArchitecture.sp","text":""},{"location":"api/gef/#function-genericarchitecturecanary_address","title":"function GenericArchitecture.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-genericarchitectureflag_register_to_human","title":"function GenericArchitecture.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-genericarchitectureget_ith_parameter","title":"function GenericArchitecture.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-genericarchitectureget_ra","title":"function GenericArchitecture.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 Optional[int]\n
"},{"location":"api/gef/#function-genericarchitectureis_branch_taken","title":"function GenericArchitecture.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-genericarchitectureis_call","title":"function GenericArchitecture.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-genericarchitectureis_conditional_branch","title":"function GenericArchitecture.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-genericarchitectureis_ret","title":"function GenericArchitecture.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-genericarchitecturemprotect_asm","title":"function GenericArchitecture.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-genericarchitectureregister","title":"function GenericArchitecture.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-genericarchitecturereset_caches","title":"function GenericArchitecture.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-genericarchitecturesupports_gdb_arch","title":"function GenericArchitecture.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-genericcommand","title":"class GenericCommand","text":"

This is an abstract class for invoking commands, should not be instantiated.

"},{"location":"api/gef/#function-genericcommand__init__","title":"function GenericCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-genericcommandsettings","title":"property GenericCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-genericcommandadd_setting","title":"function GenericCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-genericcommanddel_setting","title":"function GenericCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-genericcommanddo_invoke","title":"function GenericCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-genericcommandget_setting","title":"function GenericCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-genericcommandhas_setting","title":"function GenericCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-genericcommandinvoke","title":"function GenericCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-genericcommandpost_load","title":"function GenericCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-genericcommandpre_load","title":"function GenericCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-genericcommandusage","title":"function GenericCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-genericfunction","title":"class GenericFunction","text":"

This is an abstract class for invoking convenience functions, should not be instantiated.

"},{"location":"api/gef/#function-genericfunction__init__","title":"function GenericFunction.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-genericfunctionarg_to_long","title":"function GenericFunction.arg_to_long","text":"
arg_to_long(args: List, index: int, default: int = 0) \u2192 int\n
"},{"location":"api/gef/#function-genericfunctiondo_invoke","title":"function GenericFunction.do_invoke","text":"
do_invoke(args: Any) \u2192 int\n
"},{"location":"api/gef/#function-genericfunctioninvoke","title":"function GenericFunction.invoke","text":"
invoke(*args: Any) \u2192 int\n
"},{"location":"api/gef/#class-glibcarena","title":"class GlibcArena","text":"

Glibc arena class

"},{"location":"api/gef/#function-glibcarena__init__","title":"function GlibcArena.__init__","text":"
__init__(addr: str) \u2192 None\n
"},{"location":"api/gef/#property-glibcarenaaddr","title":"property GlibcArena.addr","text":""},{"location":"api/gef/#property-glibcarenaaddress","title":"property GlibcArena.address","text":""},{"location":"api/gef/#property-glibcarenaattached_threads","title":"property GlibcArena.attached_threads","text":""},{"location":"api/gef/#property-glibcarenabinmap","title":"property GlibcArena.binmap","text":""},{"location":"api/gef/#property-glibcarenabins","title":"property GlibcArena.bins","text":""},{"location":"api/gef/#property-glibcarenafastbinsy","title":"property GlibcArena.fastbinsY","text":""},{"location":"api/gef/#property-glibcarenalast_remainder","title":"property GlibcArena.last_remainder","text":""},{"location":"api/gef/#property-glibcarenamax_system_mem","title":"property GlibcArena.max_system_mem","text":""},{"location":"api/gef/#property-glibcarenanext","title":"property GlibcArena.next","text":""},{"location":"api/gef/#property-glibcarenanext_free","title":"property GlibcArena.next_free","text":""},{"location":"api/gef/#property-glibcarenasizeof","title":"property GlibcArena.sizeof","text":""},{"location":"api/gef/#property-glibcarenasystem_mem","title":"property GlibcArena.system_mem","text":""},{"location":"api/gef/#property-glibcarenatop","title":"property GlibcArena.top","text":""},{"location":"api/gef/#function-glibcarenabin","title":"function GlibcArena.bin","text":"
bin(i: int) \u2192 Tuple[int, int]\n
"},{"location":"api/gef/#function-glibcarenabin_at","title":"function GlibcArena.bin_at","text":"
bin_at(i) \u2192 int\n
"},{"location":"api/gef/#function-glibcarenafastbin","title":"function GlibcArena.fastbin","text":"
fastbin(i: int) \u2192 Optional[ForwardRef('GlibcFastChunk')]\n

Return head chunk in fastbinsY[i].

"},{"location":"api/gef/#function-glibcarenaget_heap_for_ptr","title":"function GlibcArena.get_heap_for_ptr","text":"
get_heap_for_ptr(ptr: int) \u2192 int\n

Find the corresponding heap for a given pointer (int). See https://github.com/bminor/glibc/blob/glibc-2.34/malloc/arena.c#L129

"},{"location":"api/gef/#function-glibcarenaget_heap_info_list","title":"function GlibcArena.get_heap_info_list","text":"
get_heap_info_list() \u2192 Optional[List[__main__.GlibcHeapInfo]]\n
"},{"location":"api/gef/#function-glibcarenaheap_addr","title":"function GlibcArena.heap_addr","text":"
heap_addr(allow_unaligned: bool = False) \u2192 Optional[int]\n
"},{"location":"api/gef/#function-glibcarenais_main_arena","title":"function GlibcArena.is_main_arena","text":"
is_main_arena() \u2192 bool\n
"},{"location":"api/gef/#function-glibcarenamalloc_state_t","title":"function GlibcArena.malloc_state_t","text":"
malloc_state_t() \u2192 Type[_ctypes.Structure]\n
"},{"location":"api/gef/#function-glibcarenareset","title":"function GlibcArena.reset","text":"
reset()\n
"},{"location":"api/gef/#function-glibcarenaverify","title":"function GlibcArena.verify","text":"
verify(addr: int) \u2192 bool\n

Verify that the address matches a possible valid GlibcArena

"},{"location":"api/gef/#class-glibcchunk","title":"class GlibcChunk","text":"

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/.

"},{"location":"api/gef/#function-glibcchunk__init__","title":"function GlibcChunk.__init__","text":"
__init__(\n    addr: int,\n    from_base: bool = False,\n    allow_unaligned: bool = True\n) \u2192 None\n
"},{"location":"api/gef/#property-glibcchunkbk","title":"property GlibcChunk.bk","text":""},{"location":"api/gef/#property-glibcchunkbk_nextsize","title":"property GlibcChunk.bk_nextsize","text":""},{"location":"api/gef/#property-glibcchunkfd","title":"property GlibcChunk.fd","text":""},{"location":"api/gef/#property-glibcchunkfd_nextsize","title":"property GlibcChunk.fd_nextsize","text":""},{"location":"api/gef/#property-glibcchunkflags","title":"property GlibcChunk.flags","text":""},{"location":"api/gef/#property-glibcchunkprev_size","title":"property GlibcChunk.prev_size","text":""},{"location":"api/gef/#property-glibcchunksize","title":"property GlibcChunk.size","text":""},{"location":"api/gef/#property-glibcchunkusable_size","title":"property GlibcChunk.usable_size","text":""},{"location":"api/gef/#function-glibcchunkget_next_chunk","title":"function GlibcChunk.get_next_chunk","text":"
get_next_chunk(allow_unaligned: bool = False) \u2192 GlibcChunk\n
"},{"location":"api/gef/#function-glibcchunkget_next_chunk_addr","title":"function GlibcChunk.get_next_chunk_addr","text":"
get_next_chunk_addr() \u2192 int\n
"},{"location":"api/gef/#function-glibcchunkget_prev_chunk_size","title":"function GlibcChunk.get_prev_chunk_size","text":"
get_prev_chunk_size() \u2192 int\n
"},{"location":"api/gef/#function-glibcchunkget_usable_size","title":"function GlibcChunk.get_usable_size","text":"
get_usable_size() \u2192 int\n
"},{"location":"api/gef/#function-glibcchunkhas_m_bit","title":"function GlibcChunk.has_m_bit","text":"
has_m_bit() \u2192 bool\n
"},{"location":"api/gef/#function-glibcchunkhas_n_bit","title":"function GlibcChunk.has_n_bit","text":"
has_n_bit() \u2192 bool\n
"},{"location":"api/gef/#function-glibcchunkhas_p_bit","title":"function GlibcChunk.has_p_bit","text":"
has_p_bit() \u2192 bool\n
"},{"location":"api/gef/#function-glibcchunkis_used","title":"function GlibcChunk.is_used","text":"
is_used() \u2192 bool\n

Check if the current block is used by: - checking the M bit is true - or checking that next chunk PREV_INUSE flag is true

"},{"location":"api/gef/#function-glibcchunkmalloc_chunk_t","title":"function GlibcChunk.malloc_chunk_t","text":"
malloc_chunk_t() \u2192 Type[_ctypes.Structure]\n
"},{"location":"api/gef/#function-glibcchunkpsprint","title":"function GlibcChunk.psprint","text":"
psprint() \u2192 str\n
"},{"location":"api/gef/#function-glibcchunkreset","title":"function GlibcChunk.reset","text":"
reset()\n
"},{"location":"api/gef/#class-glibcfastchunk","title":"class GlibcFastChunk","text":""},{"location":"api/gef/#function-glibcfastchunk__init__","title":"function GlibcFastChunk.__init__","text":"
__init__(\n    addr: int,\n    from_base: bool = False,\n    allow_unaligned: bool = True\n) \u2192 None\n
"},{"location":"api/gef/#property-glibcfastchunkbk","title":"property GlibcFastChunk.bk","text":""},{"location":"api/gef/#property-glibcfastchunkbk_nextsize","title":"property GlibcFastChunk.bk_nextsize","text":""},{"location":"api/gef/#property-glibcfastchunkfd","title":"property GlibcFastChunk.fd","text":""},{"location":"api/gef/#property-glibcfastchunkfd_nextsize","title":"property GlibcFastChunk.fd_nextsize","text":""},{"location":"api/gef/#property-glibcfastchunkflags","title":"property GlibcFastChunk.flags","text":""},{"location":"api/gef/#property-glibcfastchunkprev_size","title":"property GlibcFastChunk.prev_size","text":""},{"location":"api/gef/#property-glibcfastchunksize","title":"property GlibcFastChunk.size","text":""},{"location":"api/gef/#property-glibcfastchunkusable_size","title":"property GlibcFastChunk.usable_size","text":""},{"location":"api/gef/#function-glibcfastchunkget_next_chunk","title":"function GlibcFastChunk.get_next_chunk","text":"
get_next_chunk(allow_unaligned: bool = False) \u2192 GlibcChunk\n
"},{"location":"api/gef/#function-glibcfastchunkget_next_chunk_addr","title":"function GlibcFastChunk.get_next_chunk_addr","text":"
get_next_chunk_addr() \u2192 int\n
"},{"location":"api/gef/#function-glibcfastchunkget_prev_chunk_size","title":"function GlibcFastChunk.get_prev_chunk_size","text":"
get_prev_chunk_size() \u2192 int\n
"},{"location":"api/gef/#function-glibcfastchunkget_usable_size","title":"function GlibcFastChunk.get_usable_size","text":"
get_usable_size() \u2192 int\n
"},{"location":"api/gef/#function-glibcfastchunkhas_m_bit","title":"function GlibcFastChunk.has_m_bit","text":"
has_m_bit() \u2192 bool\n
"},{"location":"api/gef/#function-glibcfastchunkhas_n_bit","title":"function GlibcFastChunk.has_n_bit","text":"
has_n_bit() \u2192 bool\n
"},{"location":"api/gef/#function-glibcfastchunkhas_p_bit","title":"function GlibcFastChunk.has_p_bit","text":"
has_p_bit() \u2192 bool\n
"},{"location":"api/gef/#function-glibcfastchunkis_used","title":"function GlibcFastChunk.is_used","text":"
is_used() \u2192 bool\n

Check if the current block is used by: - checking the M bit is true - or checking that next chunk PREV_INUSE flag is true

"},{"location":"api/gef/#function-glibcfastchunkmalloc_chunk_t","title":"function GlibcFastChunk.malloc_chunk_t","text":"
malloc_chunk_t() \u2192 Type[_ctypes.Structure]\n
"},{"location":"api/gef/#function-glibcfastchunkprotect_ptr","title":"function GlibcFastChunk.protect_ptr","text":"
protect_ptr(pos: int, pointer: int) \u2192 int\n

https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L339

"},{"location":"api/gef/#function-glibcfastchunkpsprint","title":"function GlibcFastChunk.psprint","text":"
psprint() \u2192 str\n
"},{"location":"api/gef/#function-glibcfastchunkreset","title":"function GlibcFastChunk.reset","text":"
reset()\n
"},{"location":"api/gef/#function-glibcfastchunkreveal_ptr","title":"function GlibcFastChunk.reveal_ptr","text":"
reveal_ptr(pointer: int) \u2192 int\n

https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L341

"},{"location":"api/gef/#class-glibcheaparenacommand","title":"class GlibcHeapArenaCommand","text":"

Display information on a heap chunk.

"},{"location":"api/gef/#function-glibcheaparenacommand__init__","title":"function GlibcHeapArenaCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-glibcheaparenacommandsettings","title":"property GlibcHeapArenaCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-glibcheaparenacommandadd_setting","title":"function GlibcHeapArenaCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-glibcheaparenacommanddel_setting","title":"function GlibcHeapArenaCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-glibcheaparenacommanddo_invoke","title":"function GlibcHeapArenaCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-glibcheaparenacommandget_setting","title":"function GlibcHeapArenaCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-glibcheaparenacommandhas_setting","title":"function GlibcHeapArenaCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-glibcheaparenacommandinvoke","title":"function GlibcHeapArenaCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-glibcheaparenacommandpost_load","title":"function GlibcHeapArenaCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheaparenacommandpre_load","title":"function GlibcHeapArenaCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheaparenacommandusage","title":"function GlibcHeapArenaCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-glibcheapbinscommand","title":"class GlibcHeapBinsCommand","text":"

Display information on the bins on an arena (default: main_arena). See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123.

"},{"location":"api/gef/#function-glibcheapbinscommand__init__","title":"function GlibcHeapBinsCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-glibcheapbinscommandsettings","title":"property GlibcHeapBinsCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-glibcheapbinscommandadd_setting","title":"function GlibcHeapBinsCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-glibcheapbinscommanddel_setting","title":"function GlibcHeapBinsCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapbinscommanddo_invoke","title":"function GlibcHeapBinsCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-glibcheapbinscommandget_setting","title":"function GlibcHeapBinsCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapbinscommandhas_setting","title":"function GlibcHeapBinsCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-glibcheapbinscommandinvoke","title":"function GlibcHeapBinsCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-glibcheapbinscommandpost_load","title":"function GlibcHeapBinsCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapbinscommandpprint_bin","title":"function GlibcHeapBinsCommand.pprint_bin","text":"
pprint_bin(arena_addr: str, index: int, _type: str = '') \u2192 int\n
"},{"location":"api/gef/#function-glibcheapbinscommandpre_load","title":"function GlibcHeapBinsCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapbinscommandusage","title":"function GlibcHeapBinsCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-glibcheapchunkcommand","title":"class GlibcHeapChunkCommand","text":"

Display information on a heap chunk. See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123.

"},{"location":"api/gef/#function-glibcheapchunkcommand__init__","title":"function GlibcHeapChunkCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-glibcheapchunkcommandsettings","title":"property GlibcHeapChunkCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-glibcheapchunkcommandadd_setting","title":"function GlibcHeapChunkCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-glibcheapchunkcommanddel_setting","title":"function GlibcHeapChunkCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapchunkcommandwrapper","title":"function GlibcHeapChunkCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-glibcheapchunkcommandget_setting","title":"function GlibcHeapChunkCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapchunkcommandhas_setting","title":"function GlibcHeapChunkCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-glibcheapchunkcommandinvoke","title":"function GlibcHeapChunkCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-glibcheapchunkcommandpost_load","title":"function GlibcHeapChunkCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapchunkcommandpre_load","title":"function GlibcHeapChunkCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapchunkcommandusage","title":"function GlibcHeapChunkCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-glibcheapchunkscommand","title":"class GlibcHeapChunksCommand","text":"

Display all heap chunks for the current arena. As an optional argument the base address of a different arena can be passed

"},{"location":"api/gef/#function-glibcheapchunkscommand__init__","title":"function GlibcHeapChunksCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-glibcheapchunkscommandsettings","title":"property GlibcHeapChunksCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-glibcheapchunkscommandadd_setting","title":"function GlibcHeapChunksCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-glibcheapchunkscommanddel_setting","title":"function GlibcHeapChunksCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapchunkscommandwrapper","title":"function GlibcHeapChunksCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-glibcheapchunkscommanddump_chunks_arena","title":"function GlibcHeapChunksCommand.dump_chunks_arena","text":"
dump_chunks_arena(\n    arena: __main__.GlibcArena,\n    print_arena: bool = False,\n    allow_unaligned: bool = False\n) \u2192 None\n
"},{"location":"api/gef/#function-glibcheapchunkscommanddump_chunks_heap","title":"function GlibcHeapChunksCommand.dump_chunks_heap","text":"
dump_chunks_heap(\n    start: int,\n    end: int,\n    arena: __main__.GlibcArena,\n    allow_unaligned: bool = False\n) \u2192 bool\n
"},{"location":"api/gef/#function-glibcheapchunkscommandget_setting","title":"function GlibcHeapChunksCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapchunkscommandhas_setting","title":"function GlibcHeapChunksCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-glibcheapchunkscommandinvoke","title":"function GlibcHeapChunksCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-glibcheapchunkscommandpost_load","title":"function GlibcHeapChunksCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapchunkscommandpre_load","title":"function GlibcHeapChunksCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapchunkscommandusage","title":"function GlibcHeapChunksCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-glibcheapcommand","title":"class GlibcHeapCommand","text":"

Base command to get information about the Glibc heap structure.

"},{"location":"api/gef/#function-glibcheapcommand__init__","title":"function GlibcHeapCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-glibcheapcommandsettings","title":"property GlibcHeapCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-glibcheapcommandadd_setting","title":"function GlibcHeapCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-glibcheapcommanddel_setting","title":"function GlibcHeapCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapcommanddo_invoke","title":"function GlibcHeapCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-glibcheapcommandget_setting","title":"function GlibcHeapCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapcommandhas_setting","title":"function GlibcHeapCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-glibcheapcommandinvoke","title":"function GlibcHeapCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-glibcheapcommandpost_load","title":"function GlibcHeapCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapcommandpre_load","title":"function GlibcHeapCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapcommandusage","title":"function GlibcHeapCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-glibcheapfastbinsycommand","title":"class GlibcHeapFastbinsYCommand","text":"

Display information on the fastbinsY on an arena (default: main_arena). See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123.

"},{"location":"api/gef/#function-glibcheapfastbinsycommand__init__","title":"function GlibcHeapFastbinsYCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-glibcheapfastbinsycommandsettings","title":"property GlibcHeapFastbinsYCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-glibcheapfastbinsycommandadd_setting","title":"function GlibcHeapFastbinsYCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-glibcheapfastbinsycommanddel_setting","title":"function GlibcHeapFastbinsYCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapfastbinsycommandwrapper","title":"function GlibcHeapFastbinsYCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-glibcheapfastbinsycommandget_setting","title":"function GlibcHeapFastbinsYCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapfastbinsycommandhas_setting","title":"function GlibcHeapFastbinsYCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-glibcheapfastbinsycommandinvoke","title":"function GlibcHeapFastbinsYCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-glibcheapfastbinsycommandpost_load","title":"function GlibcHeapFastbinsYCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapfastbinsycommandpre_load","title":"function GlibcHeapFastbinsYCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapfastbinsycommandusage","title":"function GlibcHeapFastbinsYCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-glibcheapinfo","title":"class GlibcHeapInfo","text":"

Glibc heap_info struct

"},{"location":"api/gef/#function-glibcheapinfo__init__","title":"function GlibcHeapInfo.__init__","text":"
__init__(addr: Union[str, int]) \u2192 None\n
"},{"location":"api/gef/#property-glibcheapinfoaddr","title":"property GlibcHeapInfo.addr","text":""},{"location":"api/gef/#property-glibcheapinfoaddress","title":"property GlibcHeapInfo.address","text":""},{"location":"api/gef/#property-glibcheapinfoheap_end","title":"property GlibcHeapInfo.heap_end","text":""},{"location":"api/gef/#property-glibcheapinfoheap_start","title":"property GlibcHeapInfo.heap_start","text":""},{"location":"api/gef/#property-glibcheapinfosizeof","title":"property GlibcHeapInfo.sizeof","text":""},{"location":"api/gef/#function-glibcheapinfoheap_info_t","title":"function GlibcHeapInfo.heap_info_t","text":"
heap_info_t() \u2192 Type[_ctypes.Structure]\n
"},{"location":"api/gef/#function-glibcheapinforeset","title":"function GlibcHeapInfo.reset","text":"
reset()\n
"},{"location":"api/gef/#class-glibcheaplargebinscommand","title":"class GlibcHeapLargeBinsCommand","text":"

Convenience command for viewing large bins.

"},{"location":"api/gef/#function-glibcheaplargebinscommand__init__","title":"function GlibcHeapLargeBinsCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-glibcheaplargebinscommandsettings","title":"property GlibcHeapLargeBinsCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-glibcheaplargebinscommandadd_setting","title":"function GlibcHeapLargeBinsCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-glibcheaplargebinscommanddel_setting","title":"function GlibcHeapLargeBinsCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-glibcheaplargebinscommandwrapper","title":"function GlibcHeapLargeBinsCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-glibcheaplargebinscommandget_setting","title":"function GlibcHeapLargeBinsCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-glibcheaplargebinscommandhas_setting","title":"function GlibcHeapLargeBinsCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-glibcheaplargebinscommandinvoke","title":"function GlibcHeapLargeBinsCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-glibcheaplargebinscommandpost_load","title":"function GlibcHeapLargeBinsCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheaplargebinscommandpre_load","title":"function GlibcHeapLargeBinsCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheaplargebinscommandusage","title":"function GlibcHeapLargeBinsCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-glibcheapsetarenacommand","title":"class GlibcHeapSetArenaCommand","text":"

Set the address of the main_arena or the currently selected arena.

"},{"location":"api/gef/#function-glibcheapsetarenacommand__init__","title":"function GlibcHeapSetArenaCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-glibcheapsetarenacommandsettings","title":"property GlibcHeapSetArenaCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-glibcheapsetarenacommandadd_setting","title":"function GlibcHeapSetArenaCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-glibcheapsetarenacommanddel_setting","title":"function GlibcHeapSetArenaCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapsetarenacommandwrapper","title":"function GlibcHeapSetArenaCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-glibcheapsetarenacommandget_setting","title":"function GlibcHeapSetArenaCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapsetarenacommandhas_setting","title":"function GlibcHeapSetArenaCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-glibcheapsetarenacommandinvoke","title":"function GlibcHeapSetArenaCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-glibcheapsetarenacommandpost_load","title":"function GlibcHeapSetArenaCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapsetarenacommandpre_load","title":"function GlibcHeapSetArenaCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapsetarenacommandusage","title":"function GlibcHeapSetArenaCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-glibcheapsmallbinscommand","title":"class GlibcHeapSmallBinsCommand","text":"

Convenience command for viewing small bins.

"},{"location":"api/gef/#function-glibcheapsmallbinscommand__init__","title":"function GlibcHeapSmallBinsCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-glibcheapsmallbinscommandsettings","title":"property GlibcHeapSmallBinsCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-glibcheapsmallbinscommandadd_setting","title":"function GlibcHeapSmallBinsCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-glibcheapsmallbinscommanddel_setting","title":"function GlibcHeapSmallBinsCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapsmallbinscommandwrapper","title":"function GlibcHeapSmallBinsCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-glibcheapsmallbinscommandget_setting","title":"function GlibcHeapSmallBinsCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapsmallbinscommandhas_setting","title":"function GlibcHeapSmallBinsCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-glibcheapsmallbinscommandinvoke","title":"function GlibcHeapSmallBinsCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-glibcheapsmallbinscommandpost_load","title":"function GlibcHeapSmallBinsCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapsmallbinscommandpre_load","title":"function GlibcHeapSmallBinsCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapsmallbinscommandusage","title":"function GlibcHeapSmallBinsCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-glibcheaptcachebinscommand","title":"class GlibcHeapTcachebinsCommand","text":"

Display information on the Tcachebins on an arena (default: main_arena). See https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc.

"},{"location":"api/gef/#function-glibcheaptcachebinscommand__init__","title":"function GlibcHeapTcachebinsCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-glibcheaptcachebinscommandsettings","title":"property GlibcHeapTcachebinsCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-glibcheaptcachebinscommandadd_setting","title":"function GlibcHeapTcachebinsCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-glibcheaptcachebinscommandcheck_thread_ids","title":"function GlibcHeapTcachebinsCommand.check_thread_ids","text":"
check_thread_ids(tids: List[int]) \u2192 List[int]\n

Return the subset of tids that are currently valid.

"},{"location":"api/gef/#function-glibcheaptcachebinscommanddel_setting","title":"function GlibcHeapTcachebinsCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-glibcheaptcachebinscommanddo_invoke","title":"function GlibcHeapTcachebinsCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-glibcheaptcachebinscommandfind_tcache","title":"function GlibcHeapTcachebinsCommand.find_tcache","text":"
find_tcache() \u2192 int\n

Return the location of the current thread's tcache.

"},{"location":"api/gef/#function-glibcheaptcachebinscommandget_setting","title":"function GlibcHeapTcachebinsCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-glibcheaptcachebinscommandhas_setting","title":"function GlibcHeapTcachebinsCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-glibcheaptcachebinscommandinvoke","title":"function GlibcHeapTcachebinsCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-glibcheaptcachebinscommandpost_load","title":"function GlibcHeapTcachebinsCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheaptcachebinscommandpre_load","title":"function GlibcHeapTcachebinsCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheaptcachebinscommandtcachebin","title":"function GlibcHeapTcachebinsCommand.tcachebin","text":"
tcachebin(\n    tcache_base: int,\n    i: int\n) \u2192 Tuple[Optional[__main__.GlibcTcacheChunk], int]\n

Return the head chunk in tcache[i] and the number of chunks in the bin.

"},{"location":"api/gef/#function-glibcheaptcachebinscommandusage","title":"function GlibcHeapTcachebinsCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-glibcheapunsortedbinscommand","title":"class GlibcHeapUnsortedBinsCommand","text":"

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.

"},{"location":"api/gef/#function-glibcheapunsortedbinscommand__init__","title":"function GlibcHeapUnsortedBinsCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-glibcheapunsortedbinscommandsettings","title":"property GlibcHeapUnsortedBinsCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-glibcheapunsortedbinscommandadd_setting","title":"function GlibcHeapUnsortedBinsCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-glibcheapunsortedbinscommanddel_setting","title":"function GlibcHeapUnsortedBinsCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapunsortedbinscommandwrapper","title":"function GlibcHeapUnsortedBinsCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-glibcheapunsortedbinscommandget_setting","title":"function GlibcHeapUnsortedBinsCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-glibcheapunsortedbinscommandhas_setting","title":"function GlibcHeapUnsortedBinsCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-glibcheapunsortedbinscommandinvoke","title":"function GlibcHeapUnsortedBinsCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-glibcheapunsortedbinscommandpost_load","title":"function GlibcHeapUnsortedBinsCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapunsortedbinscommandpre_load","title":"function GlibcHeapUnsortedBinsCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-glibcheapunsortedbinscommandusage","title":"function GlibcHeapUnsortedBinsCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-glibctcachechunk","title":"class GlibcTcacheChunk","text":""},{"location":"api/gef/#function-glibctcachechunk__init__","title":"function GlibcTcacheChunk.__init__","text":"
__init__(\n    addr: int,\n    from_base: bool = False,\n    allow_unaligned: bool = True\n) \u2192 None\n
"},{"location":"api/gef/#property-glibctcachechunkbk","title":"property GlibcTcacheChunk.bk","text":""},{"location":"api/gef/#property-glibctcachechunkbk_nextsize","title":"property GlibcTcacheChunk.bk_nextsize","text":""},{"location":"api/gef/#property-glibctcachechunkfd","title":"property GlibcTcacheChunk.fd","text":""},{"location":"api/gef/#property-glibctcachechunkfd_nextsize","title":"property GlibcTcacheChunk.fd_nextsize","text":""},{"location":"api/gef/#property-glibctcachechunkflags","title":"property GlibcTcacheChunk.flags","text":""},{"location":"api/gef/#property-glibctcachechunkprev_size","title":"property GlibcTcacheChunk.prev_size","text":""},{"location":"api/gef/#property-glibctcachechunksize","title":"property GlibcTcacheChunk.size","text":""},{"location":"api/gef/#property-glibctcachechunkusable_size","title":"property GlibcTcacheChunk.usable_size","text":""},{"location":"api/gef/#function-glibctcachechunkget_next_chunk","title":"function GlibcTcacheChunk.get_next_chunk","text":"
get_next_chunk(allow_unaligned: bool = False) \u2192 GlibcChunk\n
"},{"location":"api/gef/#function-glibctcachechunkget_next_chunk_addr","title":"function GlibcTcacheChunk.get_next_chunk_addr","text":"
get_next_chunk_addr() \u2192 int\n
"},{"location":"api/gef/#function-glibctcachechunkget_prev_chunk_size","title":"function GlibcTcacheChunk.get_prev_chunk_size","text":"
get_prev_chunk_size() \u2192 int\n
"},{"location":"api/gef/#function-glibctcachechunkget_usable_size","title":"function GlibcTcacheChunk.get_usable_size","text":"
get_usable_size() \u2192 int\n
"},{"location":"api/gef/#function-glibctcachechunkhas_m_bit","title":"function GlibcTcacheChunk.has_m_bit","text":"
has_m_bit() \u2192 bool\n
"},{"location":"api/gef/#function-glibctcachechunkhas_n_bit","title":"function GlibcTcacheChunk.has_n_bit","text":"
has_n_bit() \u2192 bool\n
"},{"location":"api/gef/#function-glibctcachechunkhas_p_bit","title":"function GlibcTcacheChunk.has_p_bit","text":"
has_p_bit() \u2192 bool\n
"},{"location":"api/gef/#function-glibctcachechunkis_used","title":"function GlibcTcacheChunk.is_used","text":"
is_used() \u2192 bool\n

Check if the current block is used by: - checking the M bit is true - or checking that next chunk PREV_INUSE flag is true

"},{"location":"api/gef/#function-glibctcachechunkmalloc_chunk_t","title":"function GlibcTcacheChunk.malloc_chunk_t","text":"
malloc_chunk_t() \u2192 Type[_ctypes.Structure]\n
"},{"location":"api/gef/#function-glibctcachechunkprotect_ptr","title":"function GlibcTcacheChunk.protect_ptr","text":"
protect_ptr(pos: int, pointer: int) \u2192 int\n

https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L339

"},{"location":"api/gef/#function-glibctcachechunkpsprint","title":"function GlibcTcacheChunk.psprint","text":"
psprint() \u2192 str\n
"},{"location":"api/gef/#function-glibctcachechunkreset","title":"function GlibcTcacheChunk.reset","text":"
reset()\n
"},{"location":"api/gef/#function-glibctcachechunkreveal_ptr","title":"function GlibcTcacheChunk.reveal_ptr","text":"
reveal_ptr(pointer: int) \u2192 int\n

https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L341

"},{"location":"api/gef/#class-gotbasefunction","title":"class GotBaseFunction","text":"

Return the current GOT base address plus the given offset.

"},{"location":"api/gef/#function-gotbasefunction__init__","title":"function GotBaseFunction.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-gotbasefunctionarg_to_long","title":"function GotBaseFunction.arg_to_long","text":"
arg_to_long(args: List, index: int, default: int = 0) \u2192 int\n
"},{"location":"api/gef/#function-gotbasefunctiondo_invoke","title":"function GotBaseFunction.do_invoke","text":"
do_invoke(args: List) \u2192 int\n
"},{"location":"api/gef/#function-gotbasefunctioninvoke","title":"function GotBaseFunction.invoke","text":"
invoke(*args: Any) \u2192 int\n
"},{"location":"api/gef/#class-gotcommand","title":"class GotCommand","text":"

Display current status of the got inside the process.

"},{"location":"api/gef/#function-gotcommand__init__","title":"function GotCommand.__init__","text":"
__init__()\n
"},{"location":"api/gef/#property-gotcommandsettings","title":"property GotCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-gotcommandadd_setting","title":"function GotCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-gotcommanddel_setting","title":"function GotCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-gotcommanddo_invoke","title":"function GotCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-gotcommandget_setting","title":"function GotCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-gotcommandhas_setting","title":"function GotCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-gotcommandinvoke","title":"function GotCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-gotcommandpost_load","title":"function GotCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-gotcommandpre_load","title":"function GotCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-gotcommandusage","title":"function GotCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-heapanalysiscommand","title":"class HeapAnalysisCommand","text":"

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

"},{"location":"api/gef/#function-heapanalysiscommand__init__","title":"function HeapAnalysisCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-heapanalysiscommandsettings","title":"property HeapAnalysisCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-heapanalysiscommandadd_setting","title":"function HeapAnalysisCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-heapanalysiscommandclean","title":"function HeapAnalysisCommand.clean","text":"
clean(_: 'gdb.Event') \u2192 None\n
"},{"location":"api/gef/#function-heapanalysiscommanddel_setting","title":"function HeapAnalysisCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-heapanalysiscommanddo_invoke","title":"function HeapAnalysisCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-heapanalysiscommanddump_tracked_allocations","title":"function HeapAnalysisCommand.dump_tracked_allocations","text":"
dump_tracked_allocations() \u2192 None\n
"},{"location":"api/gef/#function-heapanalysiscommandget_setting","title":"function HeapAnalysisCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-heapanalysiscommandhas_setting","title":"function HeapAnalysisCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-heapanalysiscommandinvoke","title":"function HeapAnalysisCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-heapanalysiscommandpost_load","title":"function HeapAnalysisCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-heapanalysiscommandpre_load","title":"function HeapAnalysisCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-heapanalysiscommandsetup","title":"function HeapAnalysisCommand.setup","text":"
setup() \u2192 None\n
"},{"location":"api/gef/#function-heapanalysiscommandusage","title":"function HeapAnalysisCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-heapbasefunction","title":"class HeapBaseFunction","text":"

Return the current heap base address plus an optional offset.

"},{"location":"api/gef/#function-heapbasefunction__init__","title":"function HeapBaseFunction.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-heapbasefunctionarg_to_long","title":"function HeapBaseFunction.arg_to_long","text":"
arg_to_long(args: List, index: int, default: int = 0) \u2192 int\n
"},{"location":"api/gef/#function-heapbasefunctiondo_invoke","title":"function HeapBaseFunction.do_invoke","text":"
do_invoke(args: List) \u2192 int\n
"},{"location":"api/gef/#function-heapbasefunctioninvoke","title":"function HeapBaseFunction.invoke","text":"
invoke(*args: Any) \u2192 int\n
"},{"location":"api/gef/#class-hexdumpbytecommand","title":"class HexdumpByteCommand","text":"

Display SIZE lines of hexdump as BYTE from the memory location pointed by ADDRESS.

"},{"location":"api/gef/#function-hexdumpbytecommand__init__","title":"function HexdumpByteCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-hexdumpbytecommandsettings","title":"property HexdumpByteCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-hexdumpbytecommandadd_setting","title":"function HexdumpByteCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-hexdumpbytecommanddel_setting","title":"function HexdumpByteCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-hexdumpbytecommandwrapper","title":"function HexdumpByteCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-hexdumpbytecommandget_setting","title":"function HexdumpByteCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-hexdumpbytecommandhas_setting","title":"function HexdumpByteCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-hexdumpbytecommandinvoke","title":"function HexdumpByteCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-hexdumpbytecommandpost_load","title":"function HexdumpByteCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-hexdumpbytecommandpre_load","title":"function HexdumpByteCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-hexdumpbytecommandusage","title":"function HexdumpByteCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-hexdumpcommand","title":"class HexdumpCommand","text":"

Display SIZE lines of hexdump from the memory location pointed by LOCATION.

"},{"location":"api/gef/#function-hexdumpcommand__init__","title":"function HexdumpCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-hexdumpcommandsettings","title":"property HexdumpCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-hexdumpcommandadd_setting","title":"function HexdumpCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-hexdumpcommanddel_setting","title":"function HexdumpCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-hexdumpcommandwrapper","title":"function HexdumpCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-hexdumpcommandget_setting","title":"function HexdumpCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-hexdumpcommandhas_setting","title":"function HexdumpCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-hexdumpcommandinvoke","title":"function HexdumpCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-hexdumpcommandpost_load","title":"function HexdumpCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-hexdumpcommandpre_load","title":"function HexdumpCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-hexdumpcommandusage","title":"function HexdumpCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-hexdumpdwordcommand","title":"class HexdumpDwordCommand","text":"

Display SIZE lines of hexdump as DWORD from the memory location pointed by ADDRESS.

"},{"location":"api/gef/#function-hexdumpdwordcommand__init__","title":"function HexdumpDwordCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-hexdumpdwordcommandsettings","title":"property HexdumpDwordCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-hexdumpdwordcommandadd_setting","title":"function HexdumpDwordCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-hexdumpdwordcommanddel_setting","title":"function HexdumpDwordCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-hexdumpdwordcommandwrapper","title":"function HexdumpDwordCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-hexdumpdwordcommandget_setting","title":"function HexdumpDwordCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-hexdumpdwordcommandhas_setting","title":"function HexdumpDwordCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-hexdumpdwordcommandinvoke","title":"function HexdumpDwordCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-hexdumpdwordcommandpost_load","title":"function HexdumpDwordCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-hexdumpdwordcommandpre_load","title":"function HexdumpDwordCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-hexdumpdwordcommandusage","title":"function HexdumpDwordCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-hexdumpqwordcommand","title":"class HexdumpQwordCommand","text":"

Display SIZE lines of hexdump as QWORD from the memory location pointed by ADDRESS.

"},{"location":"api/gef/#function-hexdumpqwordcommand__init__","title":"function HexdumpQwordCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-hexdumpqwordcommandsettings","title":"property HexdumpQwordCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-hexdumpqwordcommandadd_setting","title":"function HexdumpQwordCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-hexdumpqwordcommanddel_setting","title":"function HexdumpQwordCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-hexdumpqwordcommandwrapper","title":"function HexdumpQwordCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-hexdumpqwordcommandget_setting","title":"function HexdumpQwordCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-hexdumpqwordcommandhas_setting","title":"function HexdumpQwordCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-hexdumpqwordcommandinvoke","title":"function HexdumpQwordCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-hexdumpqwordcommandpost_load","title":"function HexdumpQwordCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-hexdumpqwordcommandpre_load","title":"function HexdumpQwordCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-hexdumpqwordcommandusage","title":"function HexdumpQwordCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-hexdumpwordcommand","title":"class HexdumpWordCommand","text":"

Display SIZE lines of hexdump as WORD from the memory location pointed by ADDRESS.

"},{"location":"api/gef/#function-hexdumpwordcommand__init__","title":"function HexdumpWordCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-hexdumpwordcommandsettings","title":"property HexdumpWordCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-hexdumpwordcommandadd_setting","title":"function HexdumpWordCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-hexdumpwordcommanddel_setting","title":"function HexdumpWordCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-hexdumpwordcommandwrapper","title":"function HexdumpWordCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-hexdumpwordcommandget_setting","title":"function HexdumpWordCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-hexdumpwordcommandhas_setting","title":"function HexdumpWordCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-hexdumpwordcommandinvoke","title":"function HexdumpWordCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-hexdumpwordcommandpost_load","title":"function HexdumpWordCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-hexdumpwordcommandpre_load","title":"function HexdumpWordCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-hexdumpwordcommandusage","title":"function HexdumpWordCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-highlightaddcommand","title":"class HighlightAddCommand","text":"

Add a match to the highlight table.

"},{"location":"api/gef/#function-highlightaddcommand__init__","title":"function HighlightAddCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-highlightaddcommandsettings","title":"property HighlightAddCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-highlightaddcommandadd_setting","title":"function HighlightAddCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-highlightaddcommanddel_setting","title":"function HighlightAddCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-highlightaddcommanddo_invoke","title":"function HighlightAddCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-highlightaddcommandget_setting","title":"function HighlightAddCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-highlightaddcommandhas_setting","title":"function HighlightAddCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-highlightaddcommandinvoke","title":"function HighlightAddCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-highlightaddcommandpost_load","title":"function HighlightAddCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-highlightaddcommandpre_load","title":"function HighlightAddCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-highlightaddcommandusage","title":"function HighlightAddCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-highlightclearcommand","title":"class HighlightClearCommand","text":"

Clear the highlight table, remove all matches.

"},{"location":"api/gef/#function-highlightclearcommand__init__","title":"function HighlightClearCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-highlightclearcommandsettings","title":"property HighlightClearCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-highlightclearcommandadd_setting","title":"function HighlightClearCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-highlightclearcommanddel_setting","title":"function HighlightClearCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-highlightclearcommanddo_invoke","title":"function HighlightClearCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-highlightclearcommandget_setting","title":"function HighlightClearCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-highlightclearcommandhas_setting","title":"function HighlightClearCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-highlightclearcommandinvoke","title":"function HighlightClearCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-highlightclearcommandpost_load","title":"function HighlightClearCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-highlightclearcommandpre_load","title":"function HighlightClearCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-highlightclearcommandusage","title":"function HighlightClearCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-highlightcommand","title":"class HighlightCommand","text":"

Highlight user-defined text matches in GEF output universally.

"},{"location":"api/gef/#function-highlightcommand__init__","title":"function HighlightCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-highlightcommandsettings","title":"property HighlightCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-highlightcommandadd_setting","title":"function HighlightCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-highlightcommanddel_setting","title":"function HighlightCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-highlightcommanddo_invoke","title":"function HighlightCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-highlightcommandget_setting","title":"function HighlightCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-highlightcommandhas_setting","title":"function HighlightCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-highlightcommandinvoke","title":"function HighlightCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-highlightcommandpost_load","title":"function HighlightCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-highlightcommandpre_load","title":"function HighlightCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-highlightcommandusage","title":"function HighlightCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-highlightlistcommand","title":"class HighlightListCommand","text":"

Show the current highlight table with matches to colors.

"},{"location":"api/gef/#function-highlightlistcommand__init__","title":"function HighlightListCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-highlightlistcommandsettings","title":"property HighlightListCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-highlightlistcommandadd_setting","title":"function HighlightListCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-highlightlistcommanddel_setting","title":"function HighlightListCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-highlightlistcommanddo_invoke","title":"function HighlightListCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-highlightlistcommandget_setting","title":"function HighlightListCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-highlightlistcommandhas_setting","title":"function HighlightListCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-highlightlistcommandinvoke","title":"function HighlightListCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-highlightlistcommandpost_load","title":"function HighlightListCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-highlightlistcommandpre_load","title":"function HighlightListCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-highlightlistcommandprint_highlight_table","title":"function HighlightListCommand.print_highlight_table","text":"
print_highlight_table() \u2192 None\n
"},{"location":"api/gef/#function-highlightlistcommandusage","title":"function HighlightListCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-highlightremovecommand","title":"class HighlightRemoveCommand","text":"

Remove a match in the highlight table.

"},{"location":"api/gef/#function-highlightremovecommand__init__","title":"function HighlightRemoveCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-highlightremovecommandsettings","title":"property HighlightRemoveCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-highlightremovecommandadd_setting","title":"function HighlightRemoveCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-highlightremovecommanddel_setting","title":"function HighlightRemoveCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-highlightremovecommanddo_invoke","title":"function HighlightRemoveCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-highlightremovecommandget_setting","title":"function HighlightRemoveCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-highlightremovecommandhas_setting","title":"function HighlightRemoveCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-highlightremovecommandinvoke","title":"function HighlightRemoveCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-highlightremovecommandpost_load","title":"function HighlightRemoveCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-highlightremovecommandpre_load","title":"function HighlightRemoveCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-highlightremovecommandusage","title":"function HighlightRemoveCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-instruction","title":"class Instruction","text":"

GEF representation of a CPU instruction.

"},{"location":"api/gef/#function-instruction__init__","title":"function Instruction.__init__","text":"
__init__(\n    address: int,\n    location: str,\n    mnemo: str,\n    operands: List[str],\n    opcodes: bytes\n) \u2192 None\n
"},{"location":"api/gef/#function-instructionis_valid","title":"function Instruction.is_valid","text":"
is_valid() \u2192 bool\n
"},{"location":"api/gef/#function-instructionnext","title":"function Instruction.next","text":"
next() \u2192 Instruction\n
"},{"location":"api/gef/#function-instructionsize","title":"function Instruction.size","text":"
size() \u2192 int\n
"},{"location":"api/gef/#class-mips","title":"class MIPS","text":""},{"location":"api/gef/#property-mipsendianness","title":"property MIPS.endianness","text":""},{"location":"api/gef/#property-mipsfp","title":"property MIPS.fp","text":""},{"location":"api/gef/#property-mipspc","title":"property MIPS.pc","text":""},{"location":"api/gef/#property-mipsptrsize","title":"property MIPS.ptrsize","text":""},{"location":"api/gef/#property-mipsregisters","title":"property MIPS.registers","text":""},{"location":"api/gef/#property-mipssp","title":"property MIPS.sp","text":""},{"location":"api/gef/#function-mipscanary_address","title":"function MIPS.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-mipsflag_register_to_human","title":"function MIPS.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-mipsget_ith_parameter","title":"function MIPS.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-mipsget_ra","title":"function MIPS.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 Optional[int]\n
"},{"location":"api/gef/#function-mipsis_branch_taken","title":"function MIPS.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-mipsis_call","title":"function MIPS.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-mipsis_conditional_branch","title":"function MIPS.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-mipsis_ret","title":"function MIPS.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-mipsmprotect_asm","title":"function MIPS.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-mipsregister","title":"function MIPS.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-mipsreset_caches","title":"function MIPS.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-mipssupports_gdb_arch","title":"function MIPS.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-mips64","title":"class MIPS64","text":""},{"location":"api/gef/#property-mips64endianness","title":"property MIPS64.endianness","text":""},{"location":"api/gef/#property-mips64fp","title":"property MIPS64.fp","text":""},{"location":"api/gef/#property-mips64pc","title":"property MIPS64.pc","text":""},{"location":"api/gef/#property-mips64ptrsize","title":"property MIPS64.ptrsize","text":""},{"location":"api/gef/#property-mips64registers","title":"property MIPS64.registers","text":""},{"location":"api/gef/#property-mips64sp","title":"property MIPS64.sp","text":""},{"location":"api/gef/#function-mips64canary_address","title":"function MIPS64.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-mips64flag_register_to_human","title":"function MIPS64.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-mips64get_ith_parameter","title":"function MIPS64.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-mips64get_ra","title":"function MIPS64.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 Optional[int]\n
"},{"location":"api/gef/#function-mips64is_branch_taken","title":"function MIPS64.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-mips64is_call","title":"function MIPS64.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-mips64is_conditional_branch","title":"function MIPS64.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-mips64is_ret","title":"function MIPS64.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-mips64mprotect_asm","title":"function MIPS64.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-mips64register","title":"function MIPS64.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-mips64reset_caches","title":"function MIPS64.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-mips64supports_gdb_arch","title":"function MIPS64.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n
"},{"location":"api/gef/#class-memorycommand","title":"class MemoryCommand","text":"

Add or remove address ranges to the memory view.

"},{"location":"api/gef/#function-memorycommand__init__","title":"function MemoryCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-memorycommandsettings","title":"property MemoryCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-memorycommandadd_setting","title":"function MemoryCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-memorycommanddel_setting","title":"function MemoryCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-memorycommanddo_invoke","title":"function MemoryCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-memorycommandget_setting","title":"function MemoryCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-memorycommandhas_setting","title":"function MemoryCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-memorycommandinvoke","title":"function MemoryCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-memorycommandpost_load","title":"function MemoryCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-memorycommandpre_load","title":"function MemoryCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-memorycommandusage","title":"function MemoryCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-memoryunwatchcommand","title":"class MemoryUnwatchCommand","text":"

Removes address ranges to the memory view.

"},{"location":"api/gef/#function-memoryunwatchcommand__init__","title":"function MemoryUnwatchCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-memoryunwatchcommandsettings","title":"property MemoryUnwatchCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-memoryunwatchcommandadd_setting","title":"function MemoryUnwatchCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-memoryunwatchcommanddel_setting","title":"function MemoryUnwatchCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-memoryunwatchcommanddo_invoke","title":"function MemoryUnwatchCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-memoryunwatchcommandget_setting","title":"function MemoryUnwatchCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-memoryunwatchcommandhas_setting","title":"function MemoryUnwatchCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-memoryunwatchcommandinvoke","title":"function MemoryUnwatchCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-memoryunwatchcommandpost_load","title":"function MemoryUnwatchCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-memoryunwatchcommandpre_load","title":"function MemoryUnwatchCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-memoryunwatchcommandusage","title":"function MemoryUnwatchCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-memorywatchcommand","title":"class MemoryWatchCommand","text":"

Adds address ranges to the memory view.

"},{"location":"api/gef/#function-memorywatchcommand__init__","title":"function MemoryWatchCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-memorywatchcommandsettings","title":"property MemoryWatchCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-memorywatchcommandadd_setting","title":"function MemoryWatchCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-memorywatchcommanddel_setting","title":"function MemoryWatchCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-memorywatchcommanddo_invoke","title":"function MemoryWatchCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-memorywatchcommandget_setting","title":"function MemoryWatchCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-memorywatchcommandhas_setting","title":"function MemoryWatchCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-memorywatchcommandinvoke","title":"function MemoryWatchCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-memorywatchcommandpost_load","title":"function MemoryWatchCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-memorywatchcommandpre_load","title":"function MemoryWatchCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-memorywatchcommandusage","title":"function MemoryWatchCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-memorywatchlistcommand","title":"class MemoryWatchListCommand","text":"

Lists all watchpoints to display in context layout.

"},{"location":"api/gef/#function-memorywatchlistcommand__init__","title":"function MemoryWatchListCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-memorywatchlistcommandsettings","title":"property MemoryWatchListCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-memorywatchlistcommandadd_setting","title":"function MemoryWatchListCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-memorywatchlistcommanddel_setting","title":"function MemoryWatchListCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-memorywatchlistcommanddo_invoke","title":"function MemoryWatchListCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-memorywatchlistcommandget_setting","title":"function MemoryWatchListCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-memorywatchlistcommandhas_setting","title":"function MemoryWatchListCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-memorywatchlistcommandinvoke","title":"function MemoryWatchListCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-memorywatchlistcommandpost_load","title":"function MemoryWatchListCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-memorywatchlistcommandpre_load","title":"function MemoryWatchListCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-memorywatchlistcommandusage","title":"function MemoryWatchListCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-memorywatchresetcommand","title":"class MemoryWatchResetCommand","text":"

Removes all watchpoints.

"},{"location":"api/gef/#function-memorywatchresetcommand__init__","title":"function MemoryWatchResetCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-memorywatchresetcommandsettings","title":"property MemoryWatchResetCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-memorywatchresetcommandadd_setting","title":"function MemoryWatchResetCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-memorywatchresetcommanddel_setting","title":"function MemoryWatchResetCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-memorywatchresetcommanddo_invoke","title":"function MemoryWatchResetCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-memorywatchresetcommandget_setting","title":"function MemoryWatchResetCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-memorywatchresetcommandhas_setting","title":"function MemoryWatchResetCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-memorywatchresetcommandinvoke","title":"function MemoryWatchResetCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-memorywatchresetcommandpost_load","title":"function MemoryWatchResetCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-memorywatchresetcommandpre_load","title":"function MemoryWatchResetCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-memorywatchresetcommandusage","title":"function MemoryWatchResetCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-namedbreakpoint","title":"class NamedBreakpoint","text":"

Breakpoint which shows a specified name, when hit.

"},{"location":"api/gef/#function-namedbreakpoint__init__","title":"function NamedBreakpoint.__init__","text":"
__init__(location: str, name: str) \u2192 None\n
"},{"location":"api/gef/#function-namedbreakpointstop","title":"function NamedBreakpoint.stop","text":"
stop() \u2192 bool\n
"},{"location":"api/gef/#class-namedbreakpointcommand","title":"class NamedBreakpointCommand","text":"

Sets a breakpoint and assigns a name to it, which will be shown, when it's hit.

"},{"location":"api/gef/#function-namedbreakpointcommand__init__","title":"function NamedBreakpointCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-namedbreakpointcommandsettings","title":"property NamedBreakpointCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-namedbreakpointcommandadd_setting","title":"function NamedBreakpointCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-namedbreakpointcommanddel_setting","title":"function NamedBreakpointCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-namedbreakpointcommandwrapper","title":"function NamedBreakpointCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-namedbreakpointcommandget_setting","title":"function NamedBreakpointCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-namedbreakpointcommandhas_setting","title":"function NamedBreakpointCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-namedbreakpointcommandinvoke","title":"function NamedBreakpointCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-namedbreakpointcommandpost_load","title":"function NamedBreakpointCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-namedbreakpointcommandpre_load","title":"function NamedBreakpointCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-namedbreakpointcommandusage","title":"function NamedBreakpointCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-nopcommand","title":"class NopCommand","text":"

Patch the instruction(s) pointed by parameters with NOP. Note: this command is architecture aware.

"},{"location":"api/gef/#function-nopcommand__init__","title":"function NopCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-nopcommandsettings","title":"property NopCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-nopcommandadd_setting","title":"function NopCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-nopcommanddel_setting","title":"function NopCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-nopcommandwrapper","title":"function NopCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-nopcommandget_setting","title":"function NopCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-nopcommandhas_setting","title":"function NopCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-nopcommandinvoke","title":"function NopCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-nopcommandpost_load","title":"function NopCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-nopcommandpre_load","title":"function NopCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-nopcommandusage","title":"function NopCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-pcustomcommand","title":"class PCustomCommand","text":"

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.

"},{"location":"api/gef/#function-pcustomcommand__init__","title":"function PCustomCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-pcustomcommandsettings","title":"property PCustomCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-pcustomcommandadd_setting","title":"function PCustomCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-pcustomcommanddel_setting","title":"function PCustomCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-pcustomcommandwrapper","title":"function PCustomCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-pcustomcommandexplode_type","title":"function PCustomCommand.explode_type","text":"
explode_type(arg: str) \u2192 Tuple[str, str]\n
"},{"location":"api/gef/#function-pcustomcommandget_setting","title":"function PCustomCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-pcustomcommandhas_setting","title":"function PCustomCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-pcustomcommandinvoke","title":"function PCustomCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-pcustomcommandpost_load","title":"function PCustomCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-pcustomcommandpre_load","title":"function PCustomCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-pcustomcommandusage","title":"function PCustomCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-pcustomeditcommand","title":"class PCustomEditCommand","text":"

PCustom: edit the content of a given structure

"},{"location":"api/gef/#function-pcustomeditcommand__init__","title":"function PCustomEditCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-pcustomeditcommandsettings","title":"property PCustomEditCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-pcustomeditcommandadd_setting","title":"function PCustomEditCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-pcustomeditcommanddel_setting","title":"function PCustomEditCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-pcustomeditcommanddo_invoke","title":"function PCustomEditCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-pcustomeditcommandexplode_type","title":"function PCustomEditCommand.explode_type","text":"
explode_type(arg: str) \u2192 Tuple[str, str]\n
"},{"location":"api/gef/#function-pcustomeditcommandget_setting","title":"function PCustomEditCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-pcustomeditcommandhas_setting","title":"function PCustomEditCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-pcustomeditcommandinvoke","title":"function PCustomEditCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-pcustomeditcommandpost_load","title":"function PCustomEditCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-pcustomeditcommandpre_load","title":"function PCustomEditCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-pcustomeditcommandusage","title":"function PCustomEditCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-pcustomlistcommand","title":"class PCustomListCommand","text":"

PCustom: list available structures

"},{"location":"api/gef/#function-pcustomlistcommand__init__","title":"function PCustomListCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-pcustomlistcommandsettings","title":"property PCustomListCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-pcustomlistcommandadd_setting","title":"function PCustomListCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-pcustomlistcommanddel_setting","title":"function PCustomListCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-pcustomlistcommanddo_invoke","title":"function PCustomListCommand.do_invoke","text":"
do_invoke(_: List) \u2192 None\n

Dump the list of all the structures and their respective.

"},{"location":"api/gef/#function-pcustomlistcommandexplode_type","title":"function PCustomListCommand.explode_type","text":"
explode_type(arg: str) \u2192 Tuple[str, str]\n
"},{"location":"api/gef/#function-pcustomlistcommandget_setting","title":"function PCustomListCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-pcustomlistcommandhas_setting","title":"function PCustomListCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-pcustomlistcommandinvoke","title":"function PCustomListCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-pcustomlistcommandpost_load","title":"function PCustomListCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-pcustomlistcommandpre_load","title":"function PCustomListCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-pcustomlistcommandusage","title":"function PCustomListCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-pcustomshowcommand","title":"class PCustomShowCommand","text":"

PCustom: show the content of a given structure

"},{"location":"api/gef/#function-pcustomshowcommand__init__","title":"function PCustomShowCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-pcustomshowcommandsettings","title":"property PCustomShowCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-pcustomshowcommandadd_setting","title":"function PCustomShowCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-pcustomshowcommanddel_setting","title":"function PCustomShowCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-pcustomshowcommanddo_invoke","title":"function PCustomShowCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-pcustomshowcommandexplode_type","title":"function PCustomShowCommand.explode_type","text":"
explode_type(arg: str) \u2192 Tuple[str, str]\n
"},{"location":"api/gef/#function-pcustomshowcommandget_setting","title":"function PCustomShowCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-pcustomshowcommandhas_setting","title":"function PCustomShowCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-pcustomshowcommandinvoke","title":"function PCustomShowCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-pcustomshowcommandpost_load","title":"function PCustomShowCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-pcustomshowcommandpre_load","title":"function PCustomShowCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-pcustomshowcommandusage","title":"function PCustomShowCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-patchbytecommand","title":"class PatchByteCommand","text":"

Write specified BYTE to the specified address.

"},{"location":"api/gef/#function-patchbytecommand__init__","title":"function PatchByteCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-patchbytecommandsettings","title":"property PatchByteCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-patchbytecommandadd_setting","title":"function PatchByteCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-patchbytecommanddel_setting","title":"function PatchByteCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-patchbytecommandwrapper","title":"function PatchByteCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-patchbytecommandget_setting","title":"function PatchByteCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-patchbytecommandhas_setting","title":"function PatchByteCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-patchbytecommandinvoke","title":"function PatchByteCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-patchbytecommandpost_load","title":"function PatchByteCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-patchbytecommandpre_load","title":"function PatchByteCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-patchbytecommandusage","title":"function PatchByteCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-patchcommand","title":"class PatchCommand","text":"

Write specified values to the specified address.

"},{"location":"api/gef/#function-patchcommand__init__","title":"function PatchCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-patchcommandsettings","title":"property PatchCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-patchcommandadd_setting","title":"function PatchCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-patchcommanddel_setting","title":"function PatchCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-patchcommandwrapper","title":"function PatchCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-patchcommandget_setting","title":"function PatchCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-patchcommandhas_setting","title":"function PatchCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-patchcommandinvoke","title":"function PatchCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-patchcommandpost_load","title":"function PatchCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-patchcommandpre_load","title":"function PatchCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-patchcommandusage","title":"function PatchCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-patchdwordcommand","title":"class PatchDwordCommand","text":"

Write specified DWORD to the specified address.

"},{"location":"api/gef/#function-patchdwordcommand__init__","title":"function PatchDwordCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-patchdwordcommandsettings","title":"property PatchDwordCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-patchdwordcommandadd_setting","title":"function PatchDwordCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-patchdwordcommanddel_setting","title":"function PatchDwordCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-patchdwordcommandwrapper","title":"function PatchDwordCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-patchdwordcommandget_setting","title":"function PatchDwordCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-patchdwordcommandhas_setting","title":"function PatchDwordCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-patchdwordcommandinvoke","title":"function PatchDwordCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-patchdwordcommandpost_load","title":"function PatchDwordCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-patchdwordcommandpre_load","title":"function PatchDwordCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-patchdwordcommandusage","title":"function PatchDwordCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-patchqwordcommand","title":"class PatchQwordCommand","text":"

Write specified QWORD to the specified address.

"},{"location":"api/gef/#function-patchqwordcommand__init__","title":"function PatchQwordCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-patchqwordcommandsettings","title":"property PatchQwordCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-patchqwordcommandadd_setting","title":"function PatchQwordCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-patchqwordcommanddel_setting","title":"function PatchQwordCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-patchqwordcommandwrapper","title":"function PatchQwordCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-patchqwordcommandget_setting","title":"function PatchQwordCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-patchqwordcommandhas_setting","title":"function PatchQwordCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-patchqwordcommandinvoke","title":"function PatchQwordCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-patchqwordcommandpost_load","title":"function PatchQwordCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-patchqwordcommandpre_load","title":"function PatchQwordCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-patchqwordcommandusage","title":"function PatchQwordCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-patchstringcommand","title":"class PatchStringCommand","text":"

Write specified string to the specified memory location pointed by ADDRESS.

"},{"location":"api/gef/#function-patchstringcommand__init__","title":"function PatchStringCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-patchstringcommandsettings","title":"property PatchStringCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-patchstringcommandadd_setting","title":"function PatchStringCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-patchstringcommanddel_setting","title":"function PatchStringCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-patchstringcommanddo_invoke","title":"function PatchStringCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-patchstringcommandget_setting","title":"function PatchStringCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-patchstringcommandhas_setting","title":"function PatchStringCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-patchstringcommandinvoke","title":"function PatchStringCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-patchstringcommandpost_load","title":"function PatchStringCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-patchstringcommandpre_load","title":"function PatchStringCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-patchstringcommandusage","title":"function PatchStringCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-patchwordcommand","title":"class PatchWordCommand","text":"

Write specified WORD to the specified address.

"},{"location":"api/gef/#function-patchwordcommand__init__","title":"function PatchWordCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-patchwordcommandsettings","title":"property PatchWordCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-patchwordcommandadd_setting","title":"function PatchWordCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-patchwordcommanddel_setting","title":"function PatchWordCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-patchwordcommandwrapper","title":"function PatchWordCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-patchwordcommandget_setting","title":"function PatchWordCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-patchwordcommandhas_setting","title":"function PatchWordCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-patchwordcommandinvoke","title":"function PatchWordCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-patchwordcommandpost_load","title":"function PatchWordCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-patchwordcommandpre_load","title":"function PatchWordCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-patchwordcommandusage","title":"function PatchWordCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-patterncommand","title":"class PatternCommand","text":"

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.

"},{"location":"api/gef/#function-patterncommand__init__","title":"function PatternCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-patterncommandsettings","title":"property PatternCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-patterncommandadd_setting","title":"function PatternCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-patterncommanddel_setting","title":"function PatternCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-patterncommanddo_invoke","title":"function PatternCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-patterncommandget_setting","title":"function PatternCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-patterncommandhas_setting","title":"function PatternCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-patterncommandinvoke","title":"function PatternCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-patterncommandpost_load","title":"function PatternCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-patterncommandpre_load","title":"function PatternCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-patterncommandusage","title":"function PatternCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-patterncreatecommand","title":"class PatternCreateCommand","text":"

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.

"},{"location":"api/gef/#function-patterncreatecommand__init__","title":"function PatternCreateCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-patterncreatecommandsettings","title":"property PatternCreateCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-patterncreatecommandadd_setting","title":"function PatternCreateCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-patterncreatecommanddel_setting","title":"function PatternCreateCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-patterncreatecommandwrapper","title":"function PatternCreateCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-patterncreatecommandget_setting","title":"function PatternCreateCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-patterncreatecommandhas_setting","title":"function PatternCreateCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-patterncreatecommandinvoke","title":"function PatternCreateCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-patterncreatecommandpost_load","title":"function PatternCreateCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-patterncreatecommandpre_load","title":"function PatternCreateCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-patterncreatecommandusage","title":"function PatternCreateCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-patternsearchcommand","title":"class PatternSearchCommand","text":"

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

"},{"location":"api/gef/#function-patternsearchcommand__init__","title":"function PatternSearchCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-patternsearchcommandsettings","title":"property PatternSearchCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-patternsearchcommandadd_setting","title":"function PatternSearchCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-patternsearchcommanddel_setting","title":"function PatternSearchCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-patternsearchcommandwrapper","title":"function PatternSearchCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-patternsearchcommandget_setting","title":"function PatternSearchCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-patternsearchcommandhas_setting","title":"function PatternSearchCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-patternsearchcommandinvoke","title":"function PatternSearchCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-patternsearchcommandpost_load","title":"function PatternSearchCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-patternsearchcommandpre_load","title":"function PatternSearchCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-patternsearchcommandsearch","title":"function PatternSearchCommand.search","text":"
search(pattern: str, size: int, period: int) \u2192 None\n
"},{"location":"api/gef/#function-patternsearchcommandusage","title":"function PatternSearchCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-permission","title":"class Permission","text":"

GEF representation of Linux permission.

"},{"location":"api/gef/#class-phdr","title":"class Phdr","text":""},{"location":"api/gef/#function-phdr__init__","title":"function Phdr.__init__","text":"
__init__(elf: __main__.Elf, off: int) \u2192 None\n
"},{"location":"api/gef/#class-pieattachcommand","title":"class PieAttachCommand","text":"

Do attach with PIE breakpoint support.

"},{"location":"api/gef/#function-pieattachcommand__init__","title":"function PieAttachCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-pieattachcommandsettings","title":"property PieAttachCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-pieattachcommandadd_setting","title":"function PieAttachCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-pieattachcommanddel_setting","title":"function PieAttachCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-pieattachcommanddo_invoke","title":"function PieAttachCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-pieattachcommandget_setting","title":"function PieAttachCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-pieattachcommandhas_setting","title":"function PieAttachCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-pieattachcommandinvoke","title":"function PieAttachCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-pieattachcommandpost_load","title":"function PieAttachCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-pieattachcommandpre_load","title":"function PieAttachCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-pieattachcommandusage","title":"function PieAttachCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-piebreakpointcommand","title":"class PieBreakpointCommand","text":"

Set a PIE breakpoint at an offset from the target binaries base address.

"},{"location":"api/gef/#function-piebreakpointcommand__init__","title":"function PieBreakpointCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-piebreakpointcommandsettings","title":"property PieBreakpointCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-piebreakpointcommandadd_setting","title":"function PieBreakpointCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-piebreakpointcommanddel_setting","title":"function PieBreakpointCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-piebreakpointcommandwrapper","title":"function PieBreakpointCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-piebreakpointcommandget_setting","title":"function PieBreakpointCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-piebreakpointcommandhas_setting","title":"function PieBreakpointCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-piebreakpointcommandinvoke","title":"function PieBreakpointCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-piebreakpointcommandpost_load","title":"function PieBreakpointCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-piebreakpointcommandpre_load","title":"function PieBreakpointCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-piebreakpointcommandset_pie_breakpoint","title":"function PieBreakpointCommand.set_pie_breakpoint","text":"
set_pie_breakpoint(set_func: Callable[[int], str], addr: int) \u2192 None\n
"},{"location":"api/gef/#function-piebreakpointcommandusage","title":"function PieBreakpointCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-piecommand","title":"class PieCommand","text":"

PIE breakpoint support.

"},{"location":"api/gef/#function-piecommand__init__","title":"function PieCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-piecommandsettings","title":"property PieCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-piecommandadd_setting","title":"function PieCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-piecommanddel_setting","title":"function PieCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-piecommanddo_invoke","title":"function PieCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-piecommandget_setting","title":"function PieCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-piecommandhas_setting","title":"function PieCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-piecommandinvoke","title":"function PieCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-piecommandpost_load","title":"function PieCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-piecommandpre_load","title":"function PieCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-piecommandusage","title":"function PieCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-piedeletecommand","title":"class PieDeleteCommand","text":"

Delete a PIE breakpoint.

"},{"location":"api/gef/#function-piedeletecommand__init__","title":"function PieDeleteCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-piedeletecommandsettings","title":"property PieDeleteCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-piedeletecommandadd_setting","title":"function PieDeleteCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-piedeletecommanddel_setting","title":"function PieDeleteCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-piedeletecommanddelete_bp","title":"function PieDeleteCommand.delete_bp","text":"
delete_bp(breakpoints: List[__main__.PieVirtualBreakpoint]) \u2192 None\n
"},{"location":"api/gef/#function-piedeletecommandwrapper","title":"function PieDeleteCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-piedeletecommandget_setting","title":"function PieDeleteCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-piedeletecommandhas_setting","title":"function PieDeleteCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-piedeletecommandinvoke","title":"function PieDeleteCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-piedeletecommandpost_load","title":"function PieDeleteCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-piedeletecommandpre_load","title":"function PieDeleteCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-piedeletecommandusage","title":"function PieDeleteCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-pieinfocommand","title":"class PieInfoCommand","text":"

Display breakpoint info.

"},{"location":"api/gef/#function-pieinfocommand__init__","title":"function PieInfoCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-pieinfocommandsettings","title":"property PieInfoCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-pieinfocommandadd_setting","title":"function PieInfoCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-pieinfocommanddel_setting","title":"function PieInfoCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-pieinfocommandwrapper","title":"function PieInfoCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-pieinfocommandget_setting","title":"function PieInfoCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-pieinfocommandhas_setting","title":"function PieInfoCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-pieinfocommandinvoke","title":"function PieInfoCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-pieinfocommandpost_load","title":"function PieInfoCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-pieinfocommandpre_load","title":"function PieInfoCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-pieinfocommandusage","title":"function PieInfoCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-pieremotecommand","title":"class PieRemoteCommand","text":"

Attach to a remote connection with PIE breakpoint support.

"},{"location":"api/gef/#function-pieremotecommand__init__","title":"function PieRemoteCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-pieremotecommandsettings","title":"property PieRemoteCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-pieremotecommandadd_setting","title":"function PieRemoteCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-pieremotecommanddel_setting","title":"function PieRemoteCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-pieremotecommanddo_invoke","title":"function PieRemoteCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-pieremotecommandget_setting","title":"function PieRemoteCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-pieremotecommandhas_setting","title":"function PieRemoteCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-pieremotecommandinvoke","title":"function PieRemoteCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-pieremotecommandpost_load","title":"function PieRemoteCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-pieremotecommandpre_load","title":"function PieRemoteCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-pieremotecommandusage","title":"function PieRemoteCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-pieruncommand","title":"class PieRunCommand","text":"

Run process with PIE breakpoint support.

"},{"location":"api/gef/#function-pieruncommand__init__","title":"function PieRunCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-pieruncommandsettings","title":"property PieRunCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-pieruncommandadd_setting","title":"function PieRunCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-pieruncommanddel_setting","title":"function PieRunCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-pieruncommanddo_invoke","title":"function PieRunCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-pieruncommandget_setting","title":"function PieRunCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-pieruncommandhas_setting","title":"function PieRunCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-pieruncommandinvoke","title":"function PieRunCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-pieruncommandpost_load","title":"function PieRunCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-pieruncommandpre_load","title":"function PieRunCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-pieruncommandusage","title":"function PieRunCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-pievirtualbreakpoint","title":"class PieVirtualBreakpoint","text":"

PIE virtual breakpoint (not real breakpoint).

"},{"location":"api/gef/#function-pievirtualbreakpoint__init__","title":"function PieVirtualBreakpoint.__init__","text":"
__init__(set_func: Callable[[int], str], vbp_num: int, addr: int) \u2192 None\n
"},{"location":"api/gef/#function-pievirtualbreakpointdestroy","title":"function PieVirtualBreakpoint.destroy","text":"
destroy() \u2192 None\n
"},{"location":"api/gef/#function-pievirtualbreakpointinstantiate","title":"function PieVirtualBreakpoint.instantiate","text":"
instantiate(base: int) \u2192 None\n
"},{"location":"api/gef/#class-powerpc","title":"class PowerPC","text":""},{"location":"api/gef/#property-powerpcendianness","title":"property PowerPC.endianness","text":""},{"location":"api/gef/#property-powerpcfp","title":"property PowerPC.fp","text":""},{"location":"api/gef/#property-powerpcpc","title":"property PowerPC.pc","text":""},{"location":"api/gef/#property-powerpcregisters","title":"property PowerPC.registers","text":""},{"location":"api/gef/#property-powerpcsp","title":"property PowerPC.sp","text":""},{"location":"api/gef/#function-powerpccanary_address","title":"function PowerPC.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-powerpcflag_register_to_human","title":"function PowerPC.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-powerpcget_ith_parameter","title":"function PowerPC.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-powerpcget_ra","title":"function PowerPC.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 Optional[int]\n
"},{"location":"api/gef/#function-powerpcis_branch_taken","title":"function PowerPC.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-powerpcis_call","title":"function PowerPC.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-powerpcis_conditional_branch","title":"function PowerPC.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-powerpcis_ret","title":"function PowerPC.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-powerpcmprotect_asm","title":"function PowerPC.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-powerpcregister","title":"function PowerPC.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-powerpcreset_caches","title":"function PowerPC.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-powerpcsupports_gdb_arch","title":"function PowerPC.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-powerpc64","title":"class PowerPC64","text":""},{"location":"api/gef/#property-powerpc64endianness","title":"property PowerPC64.endianness","text":""},{"location":"api/gef/#property-powerpc64fp","title":"property PowerPC64.fp","text":""},{"location":"api/gef/#property-powerpc64pc","title":"property PowerPC64.pc","text":""},{"location":"api/gef/#property-powerpc64registers","title":"property PowerPC64.registers","text":""},{"location":"api/gef/#property-powerpc64sp","title":"property PowerPC64.sp","text":""},{"location":"api/gef/#function-powerpc64canary_address","title":"function PowerPC64.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-powerpc64flag_register_to_human","title":"function PowerPC64.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-powerpc64get_ith_parameter","title":"function PowerPC64.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-powerpc64get_ra","title":"function PowerPC64.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 Optional[int]\n
"},{"location":"api/gef/#function-powerpc64is_branch_taken","title":"function PowerPC64.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-powerpc64is_call","title":"function PowerPC64.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-powerpc64is_conditional_branch","title":"function PowerPC64.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-powerpc64is_ret","title":"function PowerPC64.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-powerpc64mprotect_asm","title":"function PowerPC64.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-powerpc64register","title":"function PowerPC64.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-powerpc64reset_caches","title":"function PowerPC64.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-powerpc64supports_gdb_arch","title":"function PowerPC64.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-printformatcommand","title":"class PrintFormatCommand","text":"

Print bytes format in commonly used formats, such as literals in high level languages.

"},{"location":"api/gef/#function-printformatcommand__init__","title":"function PrintFormatCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-printformatcommandformat_matrix","title":"property PrintFormatCommand.format_matrix","text":""},{"location":"api/gef/#property-printformatcommandsettings","title":"property PrintFormatCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-printformatcommandadd_setting","title":"function PrintFormatCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-printformatcommanddel_setting","title":"function PrintFormatCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-printformatcommandwrapper","title":"function PrintFormatCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-printformatcommandget_setting","title":"function PrintFormatCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-printformatcommandhas_setting","title":"function PrintFormatCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-printformatcommandinvoke","title":"function PrintFormatCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-printformatcommandpost_load","title":"function PrintFormatCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-printformatcommandpre_load","title":"function PrintFormatCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-printformatcommandusage","title":"function PrintFormatCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-processlistingcommand","title":"class ProcessListingCommand","text":"

List and filter process. If a PATTERN is given as argument, results shown will be grepped by this pattern.

"},{"location":"api/gef/#function-processlistingcommand__init__","title":"function ProcessListingCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-processlistingcommandsettings","title":"property ProcessListingCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-processlistingcommandadd_setting","title":"function ProcessListingCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-processlistingcommanddel_setting","title":"function ProcessListingCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-processlistingcommandwrapper","title":"function ProcessListingCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-processlistingcommandget_processes","title":"function ProcessListingCommand.get_processes","text":"
get_processes() \u2192 Generator[Dict[str, str], NoneType, NoneType]\n
"},{"location":"api/gef/#function-processlistingcommandget_setting","title":"function ProcessListingCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-processlistingcommandhas_setting","title":"function ProcessListingCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-processlistingcommandinvoke","title":"function ProcessListingCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-processlistingcommandpost_load","title":"function ProcessListingCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-processlistingcommandpre_load","title":"function ProcessListingCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-processlistingcommandusage","title":"function ProcessListingCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-processstatuscommand","title":"class ProcessStatusCommand","text":"

Extends the info given by GDB info proc, by giving an exhaustive description of the process status (file descriptors, ancestor, descendants, etc.).

"},{"location":"api/gef/#function-processstatuscommand__init__","title":"function ProcessStatusCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-processstatuscommandsettings","title":"property ProcessStatusCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-processstatuscommandadd_setting","title":"function ProcessStatusCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-processstatuscommanddel_setting","title":"function ProcessStatusCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-processstatuscommanddo_invoke","title":"function ProcessStatusCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-processstatuscommandget_children_pids","title":"function ProcessStatusCommand.get_children_pids","text":"
get_children_pids(pid: int) \u2192 List[int]\n
"},{"location":"api/gef/#function-processstatuscommandget_cmdline_of","title":"function ProcessStatusCommand.get_cmdline_of","text":"
get_cmdline_of(pid: int) \u2192 str\n
"},{"location":"api/gef/#function-processstatuscommandget_process_path_of","title":"function ProcessStatusCommand.get_process_path_of","text":"
get_process_path_of(pid: int) \u2192 str\n
"},{"location":"api/gef/#function-processstatuscommandget_setting","title":"function ProcessStatusCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-processstatuscommandget_state_of","title":"function ProcessStatusCommand.get_state_of","text":"
get_state_of(pid: int) \u2192 Dict[str, str]\n
"},{"location":"api/gef/#function-processstatuscommandhas_setting","title":"function ProcessStatusCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-processstatuscommandinvoke","title":"function ProcessStatusCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-processstatuscommandlist_sockets","title":"function ProcessStatusCommand.list_sockets","text":"
list_sockets(pid: int) \u2192 List[int]\n
"},{"location":"api/gef/#function-processstatuscommandparse_ip_port","title":"function ProcessStatusCommand.parse_ip_port","text":"
parse_ip_port(addr: str) \u2192 Tuple[str, int]\n
"},{"location":"api/gef/#function-processstatuscommandpost_load","title":"function ProcessStatusCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-processstatuscommandpre_load","title":"function ProcessStatusCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-processstatuscommandshow_ancestor","title":"function ProcessStatusCommand.show_ancestor","text":"
show_ancestor() \u2192 None\n
"},{"location":"api/gef/#function-processstatuscommandshow_connections","title":"function ProcessStatusCommand.show_connections","text":"
show_connections() \u2192 None\n
"},{"location":"api/gef/#function-processstatuscommandshow_descendants","title":"function ProcessStatusCommand.show_descendants","text":"
show_descendants() \u2192 None\n
"},{"location":"api/gef/#function-processstatuscommandshow_fds","title":"function ProcessStatusCommand.show_fds","text":"
show_fds() \u2192 None\n
"},{"location":"api/gef/#function-processstatuscommandshow_info_proc","title":"function ProcessStatusCommand.show_info_proc","text":"
show_info_proc() \u2192 None\n
"},{"location":"api/gef/#function-processstatuscommandusage","title":"function ProcessStatusCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-riscv","title":"class RISCV","text":""},{"location":"api/gef/#property-riscvendianness","title":"property RISCV.endianness","text":""},{"location":"api/gef/#property-riscvfp","title":"property RISCV.fp","text":""},{"location":"api/gef/#property-riscvinstruction_length","title":"property RISCV.instruction_length","text":""},{"location":"api/gef/#property-riscvpc","title":"property RISCV.pc","text":""},{"location":"api/gef/#property-riscvptrsize","title":"property RISCV.ptrsize","text":""},{"location":"api/gef/#property-riscvregisters","title":"property RISCV.registers","text":""},{"location":"api/gef/#property-riscvsp","title":"property RISCV.sp","text":""},{"location":"api/gef/#function-riscvcanary_address","title":"function RISCV.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-riscvflag_register_to_human","title":"function RISCV.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-riscvget_ith_parameter","title":"function RISCV.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-riscvget_ra","title":"function RISCV.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 Optional[int]\n
"},{"location":"api/gef/#function-riscvis_branch_taken","title":"function RISCV.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-riscvis_call","title":"function RISCV.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-riscvis_conditional_branch","title":"function RISCV.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-riscvis_ret","title":"function RISCV.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-riscvmprotect_asm","title":"function RISCV.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-riscvregister","title":"function RISCV.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-riscvreset_caches","title":"function RISCV.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-riscvsupports_gdb_arch","title":"function RISCV.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-redirectoutputcontext","title":"class RedirectOutputContext","text":""},{"location":"api/gef/#function-redirectoutputcontext__init__","title":"function RedirectOutputContext.__init__","text":"
__init__(to: str = '/dev/null') \u2192 None\n
"},{"location":"api/gef/#class-remotecommand","title":"class RemoteCommand","text":"

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.

"},{"location":"api/gef/#function-remotecommand__init__","title":"function RemoteCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-remotecommandsettings","title":"property RemoteCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-remotecommandadd_setting","title":"function RemoteCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-remotecommanddel_setting","title":"function RemoteCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-remotecommandwrapper","title":"function RemoteCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-remotecommandget_setting","title":"function RemoteCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-remotecommandhas_setting","title":"function RemoteCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-remotecommandinvoke","title":"function RemoteCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-remotecommandpost_load","title":"function RemoteCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-remotecommandpre_load","title":"function RemoteCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-remotecommandusage","title":"function RemoteCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-resetcachecommand","title":"class ResetCacheCommand","text":"

Reset cache of all stored data. This command is here for debugging and test purposes, GEF handles properly the cache reset under \"normal\" scenario.

"},{"location":"api/gef/#function-resetcachecommand__init__","title":"function ResetCacheCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-resetcachecommandsettings","title":"property ResetCacheCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-resetcachecommandadd_setting","title":"function ResetCacheCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-resetcachecommanddel_setting","title":"function ResetCacheCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-resetcachecommanddo_invoke","title":"function ResetCacheCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-resetcachecommandget_setting","title":"function ResetCacheCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-resetcachecommandhas_setting","title":"function ResetCacheCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-resetcachecommandinvoke","title":"function ResetCacheCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-resetcachecommandpost_load","title":"function ResetCacheCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-resetcachecommandpre_load","title":"function ResetCacheCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-resetcachecommandusage","title":"function ResetCacheCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-sparc","title":"class SPARC","text":"

Refs: - https://www.cse.scu.edu/~atkinson/teaching/sp05/259/sparc.pdf

"},{"location":"api/gef/#property-sparcendianness","title":"property SPARC.endianness","text":""},{"location":"api/gef/#property-sparcfp","title":"property SPARC.fp","text":""},{"location":"api/gef/#property-sparcpc","title":"property SPARC.pc","text":""},{"location":"api/gef/#property-sparcptrsize","title":"property SPARC.ptrsize","text":""},{"location":"api/gef/#property-sparcregisters","title":"property SPARC.registers","text":""},{"location":"api/gef/#property-sparcsp","title":"property SPARC.sp","text":""},{"location":"api/gef/#function-sparccanary_address","title":"function SPARC.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-sparcflag_register_to_human","title":"function SPARC.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-sparcget_ith_parameter","title":"function SPARC.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-sparcget_ra","title":"function SPARC.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 Optional[int]\n
"},{"location":"api/gef/#function-sparcis_branch_taken","title":"function SPARC.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-sparcis_call","title":"function SPARC.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-sparcis_conditional_branch","title":"function SPARC.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-sparcis_ret","title":"function SPARC.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-sparcmprotect_asm","title":"function SPARC.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-sparcregister","title":"function SPARC.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-sparcreset_caches","title":"function SPARC.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-sparcsupports_gdb_arch","title":"function SPARC.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-sparc64","title":"class SPARC64","text":"

Refs: - http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_sparc.pdf - https://cr.yp.to/2005-590/sparcv9.pdf

"},{"location":"api/gef/#property-sparc64endianness","title":"property SPARC64.endianness","text":""},{"location":"api/gef/#property-sparc64fp","title":"property SPARC64.fp","text":""},{"location":"api/gef/#property-sparc64pc","title":"property SPARC64.pc","text":""},{"location":"api/gef/#property-sparc64ptrsize","title":"property SPARC64.ptrsize","text":""},{"location":"api/gef/#property-sparc64registers","title":"property SPARC64.registers","text":""},{"location":"api/gef/#property-sparc64sp","title":"property SPARC64.sp","text":""},{"location":"api/gef/#function-sparc64canary_address","title":"function SPARC64.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-sparc64flag_register_to_human","title":"function SPARC64.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-sparc64get_ith_parameter","title":"function SPARC64.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-sparc64get_ra","title":"function SPARC64.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 Optional[int]\n
"},{"location":"api/gef/#function-sparc64is_branch_taken","title":"function SPARC64.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-sparc64is_call","title":"function SPARC64.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-sparc64is_conditional_branch","title":"function SPARC64.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-sparc64is_ret","title":"function SPARC64.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-sparc64mprotect_asm","title":"function SPARC64.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-sparc64register","title":"function SPARC64.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-sparc64reset_caches","title":"function SPARC64.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-sparc64supports_gdb_arch","title":"function SPARC64.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-scansectioncommand","title":"class ScanSectionCommand","text":"

Search for addresses that are located in a memory mapping (haystack) that belonging to another (needle).

"},{"location":"api/gef/#function-scansectioncommand__init__","title":"function ScanSectionCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-scansectioncommandsettings","title":"property ScanSectionCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-scansectioncommandadd_setting","title":"function ScanSectionCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-scansectioncommanddel_setting","title":"function ScanSectionCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-scansectioncommanddo_invoke","title":"function ScanSectionCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-scansectioncommandget_setting","title":"function ScanSectionCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-scansectioncommandhas_setting","title":"function ScanSectionCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-scansectioncommandinvoke","title":"function ScanSectionCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-scansectioncommandpost_load","title":"function ScanSectionCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-scansectioncommandpre_load","title":"function ScanSectionCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-scansectioncommandusage","title":"function ScanSectionCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-searchpatterncommand","title":"class SearchPatternCommand","text":"

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.

"},{"location":"api/gef/#function-searchpatterncommand__init__","title":"function SearchPatternCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-searchpatterncommandsettings","title":"property SearchPatternCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-searchpatterncommandadd_setting","title":"function SearchPatternCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-searchpatterncommanddel_setting","title":"function SearchPatternCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-searchpatterncommanddo_invoke","title":"function SearchPatternCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-searchpatterncommandget_setting","title":"function SearchPatternCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-searchpatterncommandhas_setting","title":"function SearchPatternCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-searchpatterncommandinvoke","title":"function SearchPatternCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-searchpatterncommandpost_load","title":"function SearchPatternCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-searchpatterncommandpre_load","title":"function SearchPatternCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-searchpatterncommandprint_loc","title":"function SearchPatternCommand.print_loc","text":"
print_loc(loc: Tuple[int, int, str]) \u2192 None\n
"},{"location":"api/gef/#function-searchpatterncommandprint_section","title":"function SearchPatternCommand.print_section","text":"
print_section(section: __main__.Section) \u2192 None\n
"},{"location":"api/gef/#function-searchpatterncommandsearch_binpattern_by_address","title":"function SearchPatternCommand.search_binpattern_by_address","text":"
search_binpattern_by_address(\n    binpattern: bytes,\n    start_address: int,\n    end_address: int\n) \u2192 List[Tuple[int, int, Optional[str]]]\n

Search a binary pattern within a range defined by arguments.

"},{"location":"api/gef/#function-searchpatterncommandsearch_pattern","title":"function SearchPatternCommand.search_pattern","text":"
search_pattern(pattern: str, section_name: str) \u2192 None\n

Search a pattern within the whole userland memory.

"},{"location":"api/gef/#function-searchpatterncommandsearch_pattern_by_address","title":"function SearchPatternCommand.search_pattern_by_address","text":"
search_pattern_by_address(\n    pattern: str,\n    start_address: int,\n    end_address: int\n) \u2192 List[Tuple[int, int, Optional[str]]]\n

Search a pattern within a range defined by arguments.

"},{"location":"api/gef/#function-searchpatterncommandusage","title":"function SearchPatternCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-section","title":"class Section","text":"

GEF representation of process memory sections.

"},{"location":"api/gef/#function-section__init__","title":"function Section.__init__","text":"
__init__(**kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-sectionrealpath","title":"property Section.realpath","text":""},{"location":"api/gef/#property-sectionsize","title":"property Section.size","text":""},{"location":"api/gef/#function-sectionis_executable","title":"function Section.is_executable","text":"
is_executable() \u2192 bool\n
"},{"location":"api/gef/#function-sectionis_readable","title":"function Section.is_readable","text":"
is_readable() \u2192 bool\n
"},{"location":"api/gef/#function-sectionis_writable","title":"function Section.is_writable","text":"
is_writable() \u2192 bool\n
"},{"location":"api/gef/#class-sectionbasefunction","title":"class SectionBaseFunction","text":"

Return the matching file's base address plus an optional offset. Defaults to current file. Note that quotes need to be escaped

"},{"location":"api/gef/#function-sectionbasefunction__init__","title":"function SectionBaseFunction.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-sectionbasefunctionarg_to_long","title":"function SectionBaseFunction.arg_to_long","text":"
arg_to_long(args: List, index: int, default: int = 0) \u2192 int\n
"},{"location":"api/gef/#function-sectionbasefunctiondo_invoke","title":"function SectionBaseFunction.do_invoke","text":"
do_invoke(args: List) \u2192 int\n
"},{"location":"api/gef/#function-sectionbasefunctioninvoke","title":"function SectionBaseFunction.invoke","text":"
invoke(*args: Any) \u2192 int\n
"},{"location":"api/gef/#class-shdr","title":"class Shdr","text":""},{"location":"api/gef/#function-shdr__init__","title":"function Shdr.__init__","text":"
__init__(elf: Optional[__main__.Elf], off: int) \u2192 None\n
"},{"location":"api/gef/#class-shellcodecommand","title":"class ShellcodeCommand","text":"

ShellcodeCommand uses @JonathanSalwan simple-yet-awesome shellcode API to download shellcodes.

"},{"location":"api/gef/#function-shellcodecommand__init__","title":"function ShellcodeCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-shellcodecommandsettings","title":"property ShellcodeCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-shellcodecommandadd_setting","title":"function ShellcodeCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-shellcodecommanddel_setting","title":"function ShellcodeCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-shellcodecommanddo_invoke","title":"function ShellcodeCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-shellcodecommandget_setting","title":"function ShellcodeCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-shellcodecommandhas_setting","title":"function ShellcodeCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-shellcodecommandinvoke","title":"function ShellcodeCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-shellcodecommandpost_load","title":"function ShellcodeCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-shellcodecommandpre_load","title":"function ShellcodeCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-shellcodecommandusage","title":"function ShellcodeCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-shellcodegetcommand","title":"class ShellcodeGetCommand","text":"

Download shellcode from shell-storm's shellcode database.

"},{"location":"api/gef/#function-shellcodegetcommand__init__","title":"function ShellcodeGetCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-shellcodegetcommandsettings","title":"property ShellcodeGetCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-shellcodegetcommandadd_setting","title":"function ShellcodeGetCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-shellcodegetcommanddel_setting","title":"function ShellcodeGetCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-shellcodegetcommanddo_invoke","title":"function ShellcodeGetCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-shellcodegetcommandget_setting","title":"function ShellcodeGetCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-shellcodegetcommandget_shellcode","title":"function ShellcodeGetCommand.get_shellcode","text":"
get_shellcode(sid: int) \u2192 None\n
"},{"location":"api/gef/#function-shellcodegetcommandhas_setting","title":"function ShellcodeGetCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-shellcodegetcommandinvoke","title":"function ShellcodeGetCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-shellcodegetcommandpost_load","title":"function ShellcodeGetCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-shellcodegetcommandpre_load","title":"function ShellcodeGetCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-shellcodegetcommandusage","title":"function ShellcodeGetCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-shellcodesearchcommand","title":"class ShellcodeSearchCommand","text":"

Search pattern in shell-storm's shellcode database.

"},{"location":"api/gef/#function-shellcodesearchcommand__init__","title":"function ShellcodeSearchCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-shellcodesearchcommandsettings","title":"property ShellcodeSearchCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-shellcodesearchcommandadd_setting","title":"function ShellcodeSearchCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-shellcodesearchcommanddel_setting","title":"function ShellcodeSearchCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-shellcodesearchcommanddo_invoke","title":"function ShellcodeSearchCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-shellcodesearchcommandget_setting","title":"function ShellcodeSearchCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-shellcodesearchcommandhas_setting","title":"function ShellcodeSearchCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-shellcodesearchcommandinvoke","title":"function ShellcodeSearchCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-shellcodesearchcommandpost_load","title":"function ShellcodeSearchCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-shellcodesearchcommandpre_load","title":"function ShellcodeSearchCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-shellcodesearchcommandsearch_shellcode","title":"function ShellcodeSearchCommand.search_shellcode","text":"
search_shellcode(search_options: List) \u2192 None\n
"},{"location":"api/gef/#function-shellcodesearchcommandusage","title":"function ShellcodeSearchCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-skipicommand","title":"class SkipiCommand","text":"

Skip N instruction(s) execution

"},{"location":"api/gef/#function-skipicommand__init__","title":"function SkipiCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-skipicommandsettings","title":"property SkipiCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-skipicommandadd_setting","title":"function SkipiCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-skipicommanddel_setting","title":"function SkipiCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-skipicommandwrapper","title":"function SkipiCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-skipicommandget_setting","title":"function SkipiCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-skipicommandhas_setting","title":"function SkipiCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-skipicommandinvoke","title":"function SkipiCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-skipicommandpost_load","title":"function SkipiCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-skipicommandpre_load","title":"function SkipiCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-skipicommandusage","title":"function SkipiCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-smartevalcommand","title":"class SmartEvalCommand","text":"

SmartEval: Smart eval (vague approach to mimic WinDBG ?).

"},{"location":"api/gef/#function-smartevalcommand__init__","title":"function SmartEvalCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-smartevalcommandsettings","title":"property SmartEvalCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-smartevalcommandadd_setting","title":"function SmartEvalCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-smartevalcommanddel_setting","title":"function SmartEvalCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-smartevalcommanddistance","title":"function SmartEvalCommand.distance","text":"
distance(args: Tuple[str, str]) \u2192 None\n
"},{"location":"api/gef/#function-smartevalcommanddo_invoke","title":"function SmartEvalCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-smartevalcommandevaluate","title":"function SmartEvalCommand.evaluate","text":"
evaluate(expr: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-smartevalcommandget_setting","title":"function SmartEvalCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-smartevalcommandhas_setting","title":"function SmartEvalCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-smartevalcommandinvoke","title":"function SmartEvalCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-smartevalcommandpost_load","title":"function SmartEvalCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-smartevalcommandpre_load","title":"function SmartEvalCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-smartevalcommandusage","title":"function SmartEvalCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-solvekernelsymbolcommand","title":"class SolveKernelSymbolCommand","text":"

Solve kernel symbols from kallsyms table.

"},{"location":"api/gef/#function-solvekernelsymbolcommand__init__","title":"function SolveKernelSymbolCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-solvekernelsymbolcommandsettings","title":"property SolveKernelSymbolCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-solvekernelsymbolcommandadd_setting","title":"function SolveKernelSymbolCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-solvekernelsymbolcommanddel_setting","title":"function SolveKernelSymbolCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-solvekernelsymbolcommandwrapper","title":"function SolveKernelSymbolCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-solvekernelsymbolcommandget_setting","title":"function SolveKernelSymbolCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-solvekernelsymbolcommandhas_setting","title":"function SolveKernelSymbolCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-solvekernelsymbolcommandinvoke","title":"function SolveKernelSymbolCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-solvekernelsymbolcommandpost_load","title":"function SolveKernelSymbolCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-solvekernelsymbolcommandpre_load","title":"function SolveKernelSymbolCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-solvekernelsymbolcommandusage","title":"function SolveKernelSymbolCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-stackoffsetfunction","title":"class StackOffsetFunction","text":"

Return the current stack base address plus an optional offset.

"},{"location":"api/gef/#function-stackoffsetfunction__init__","title":"function StackOffsetFunction.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-stackoffsetfunctionarg_to_long","title":"function StackOffsetFunction.arg_to_long","text":"
arg_to_long(args: List, index: int, default: int = 0) \u2192 int\n
"},{"location":"api/gef/#function-stackoffsetfunctiondo_invoke","title":"function StackOffsetFunction.do_invoke","text":"
do_invoke(args: List) \u2192 int\n
"},{"location":"api/gef/#function-stackoffsetfunctioninvoke","title":"function StackOffsetFunction.invoke","text":"
invoke(*args: Any) \u2192 int\n
"},{"location":"api/gef/#class-stubbreakpoint","title":"class StubBreakpoint","text":"

Create a breakpoint to permanently disable a call (fork/alarm/signal/etc.).

"},{"location":"api/gef/#function-stubbreakpoint__init__","title":"function StubBreakpoint.__init__","text":"
__init__(func: str, retval: Optional[int]) \u2192 None\n
"},{"location":"api/gef/#function-stubbreakpointstop","title":"function StubBreakpoint.stop","text":"
stop() \u2192 bool\n
"},{"location":"api/gef/#class-stubcommand","title":"class StubCommand","text":"

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

"},{"location":"api/gef/#function-stubcommand__init__","title":"function StubCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-stubcommandsettings","title":"property StubCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-stubcommandadd_setting","title":"function StubCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-stubcommanddel_setting","title":"function StubCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-stubcommandwrapper","title":"function StubCommand.wrapper","text":"
wrapper(*args: Any, **kwargs: Any) \u2192 Callable\n
"},{"location":"api/gef/#function-stubcommandget_setting","title":"function StubCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-stubcommandhas_setting","title":"function StubCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-stubcommandinvoke","title":"function StubCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-stubcommandpost_load","title":"function StubCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-stubcommandpre_load","title":"function StubCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-stubcommandusage","title":"function StubCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-tracefreebreakpoint","title":"class TraceFreeBreakpoint","text":"

Track calls to free() and attempts to detect inconsistencies.

"},{"location":"api/gef/#function-tracefreebreakpoint__init__","title":"function TraceFreeBreakpoint.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-tracefreebreakpointstop","title":"function TraceFreeBreakpoint.stop","text":"
stop() \u2192 bool\n
"},{"location":"api/gef/#class-tracefreeretbreakpoint","title":"class TraceFreeRetBreakpoint","text":"

Internal temporary breakpoint to track free()d values.

"},{"location":"api/gef/#function-tracefreeretbreakpoint__init__","title":"function TraceFreeRetBreakpoint.__init__","text":"
__init__(addr: int) \u2192 None\n
"},{"location":"api/gef/#function-tracefreeretbreakpointstop","title":"function TraceFreeRetBreakpoint.stop","text":"
stop() \u2192 bool\n
"},{"location":"api/gef/#class-tracemallocbreakpoint","title":"class TraceMallocBreakpoint","text":"

Track allocations done with malloc() or calloc().

"},{"location":"api/gef/#function-tracemallocbreakpoint__init__","title":"function TraceMallocBreakpoint.__init__","text":"
__init__(name: str) \u2192 None\n
"},{"location":"api/gef/#function-tracemallocbreakpointstop","title":"function TraceMallocBreakpoint.stop","text":"
stop() \u2192 bool\n
"},{"location":"api/gef/#class-tracemallocretbreakpoint","title":"class TraceMallocRetBreakpoint","text":"

Internal temporary breakpoint to retrieve the return value of malloc().

"},{"location":"api/gef/#function-tracemallocretbreakpoint__init__","title":"function TraceMallocRetBreakpoint.__init__","text":"
__init__(size: int, name: str) \u2192 None\n
"},{"location":"api/gef/#function-tracemallocretbreakpointstop","title":"function TraceMallocRetBreakpoint.stop","text":"
stop() \u2192 bool\n
"},{"location":"api/gef/#class-tracereallocbreakpoint","title":"class TraceReallocBreakpoint","text":"

Track re-allocations done with realloc().

"},{"location":"api/gef/#function-tracereallocbreakpoint__init__","title":"function TraceReallocBreakpoint.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#function-tracereallocbreakpointstop","title":"function TraceReallocBreakpoint.stop","text":"
stop() \u2192 bool\n
"},{"location":"api/gef/#class-tracereallocretbreakpoint","title":"class TraceReallocRetBreakpoint","text":"

Internal temporary breakpoint to retrieve the return value of realloc().

"},{"location":"api/gef/#function-tracereallocretbreakpoint__init__","title":"function TraceReallocRetBreakpoint.__init__","text":"
__init__(ptr: int, size: int) \u2192 None\n
"},{"location":"api/gef/#function-tracereallocretbreakpointstop","title":"function TraceReallocRetBreakpoint.stop","text":"
stop() \u2192 bool\n
"},{"location":"api/gef/#class-traceruncommand","title":"class TraceRunCommand","text":"

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.

"},{"location":"api/gef/#function-traceruncommand__init__","title":"function TraceRunCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-traceruncommandsettings","title":"property TraceRunCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-traceruncommandadd_setting","title":"function TraceRunCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-traceruncommanddel_setting","title":"function TraceRunCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-traceruncommanddo_invoke","title":"function TraceRunCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-traceruncommandget_frames_size","title":"function TraceRunCommand.get_frames_size","text":"
get_frames_size() \u2192 int\n
"},{"location":"api/gef/#function-traceruncommandget_setting","title":"function TraceRunCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-traceruncommandhas_setting","title":"function TraceRunCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-traceruncommandinvoke","title":"function TraceRunCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-traceruncommandpost_load","title":"function TraceRunCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-traceruncommandpre_load","title":"function TraceRunCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-traceruncommandstart_tracing","title":"function TraceRunCommand.start_tracing","text":"
start_tracing(loc_start: int, loc_end: int, depth: int) \u2192 None\n
"},{"location":"api/gef/#function-traceruncommandtrace","title":"function TraceRunCommand.trace","text":"
trace(loc_start: int, loc_end: int, depth: int) \u2192 None\n
"},{"location":"api/gef/#function-traceruncommandusage","title":"function TraceRunCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-uafwatchpoint","title":"class UafWatchpoint","text":"

Custom watchpoints set TraceFreeBreakpoint() to monitor free()d pointers being used.

"},{"location":"api/gef/#function-uafwatchpoint__init__","title":"function UafWatchpoint.__init__","text":"
__init__(addr: int) \u2192 None\n
"},{"location":"api/gef/#function-uafwatchpointstop","title":"function UafWatchpoint.stop","text":"
stop() \u2192 bool\n

If this method is triggered, we likely have a UaF. Break the execution and report it.

"},{"location":"api/gef/#class-vmmapcommand","title":"class VMMapCommand","text":"

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.

"},{"location":"api/gef/#function-vmmapcommand__init__","title":"function VMMapCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-vmmapcommandsettings","title":"property VMMapCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-vmmapcommandadd_setting","title":"function VMMapCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-vmmapcommanddel_setting","title":"function VMMapCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-vmmapcommanddo_invoke","title":"function VMMapCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-vmmapcommandget_setting","title":"function VMMapCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-vmmapcommandhas_setting","title":"function VMMapCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-vmmapcommandinvoke","title":"function VMMapCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-vmmapcommandis_integer","title":"function VMMapCommand.is_integer","text":"
is_integer(n: str) \u2192 bool\n
"},{"location":"api/gef/#function-vmmapcommandpost_load","title":"function VMMapCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-vmmapcommandpre_load","title":"function VMMapCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-vmmapcommandprint_entry","title":"function VMMapCommand.print_entry","text":"
print_entry(entry: __main__.Section) \u2192 None\n
"},{"location":"api/gef/#function-vmmapcommandshow_legend","title":"function VMMapCommand.show_legend","text":"
show_legend() \u2192 None\n
"},{"location":"api/gef/#function-vmmapcommandusage","title":"function VMMapCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-versioncommand","title":"class VersionCommand","text":"

Display GEF version info.

"},{"location":"api/gef/#function-versioncommand__init__","title":"function VersionCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-versioncommandsettings","title":"property VersionCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-versioncommandadd_setting","title":"function VersionCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-versioncommanddel_setting","title":"function VersionCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-versioncommanddo_invoke","title":"function VersionCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-versioncommandget_setting","title":"function VersionCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-versioncommandhas_setting","title":"function VersionCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-versioncommandinvoke","title":"function VersionCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-versioncommandpost_load","title":"function VersionCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-versioncommandpre_load","title":"function VersionCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-versioncommandusage","title":"function VersionCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-x86","title":"class X86","text":""},{"location":"api/gef/#property-x86endianness","title":"property X86.endianness","text":""},{"location":"api/gef/#property-x86fp","title":"property X86.fp","text":""},{"location":"api/gef/#property-x86pc","title":"property X86.pc","text":""},{"location":"api/gef/#property-x86ptrsize","title":"property X86.ptrsize","text":""},{"location":"api/gef/#property-x86registers","title":"property X86.registers","text":""},{"location":"api/gef/#property-x86sp","title":"property X86.sp","text":""},{"location":"api/gef/#function-x86canary_address","title":"function X86.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-x86flag_register_to_human","title":"function X86.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-x86get_ith_parameter","title":"function X86.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n
"},{"location":"api/gef/#function-x86get_ra","title":"function X86.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 Optional[int]\n
"},{"location":"api/gef/#function-x86is_branch_taken","title":"function X86.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-x86is_call","title":"function X86.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-x86is_conditional_branch","title":"function X86.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-x86is_ret","title":"function X86.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-x86mprotect_asm","title":"function X86.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-x86register","title":"function X86.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-x86reset_caches","title":"function X86.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-x86supports_gdb_arch","title":"function X86.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-x86_64","title":"class X86_64","text":""},{"location":"api/gef/#property-x86_64endianness","title":"property X86_64.endianness","text":""},{"location":"api/gef/#property-x86_64fp","title":"property X86_64.fp","text":""},{"location":"api/gef/#property-x86_64pc","title":"property X86_64.pc","text":""},{"location":"api/gef/#property-x86_64ptrsize","title":"property X86_64.ptrsize","text":""},{"location":"api/gef/#property-x86_64registers","title":"property X86_64.registers","text":""},{"location":"api/gef/#property-x86_64sp","title":"property X86_64.sp","text":""},{"location":"api/gef/#function-x86_64canary_address","title":"function X86_64.canary_address","text":"
canary_address() \u2192 int\n
"},{"location":"api/gef/#function-x86_64flag_register_to_human","title":"function X86_64.flag_register_to_human","text":"
flag_register_to_human(val: Optional[int] = None) \u2192 str\n
"},{"location":"api/gef/#function-x86_64get_ith_parameter","title":"function X86_64.get_ith_parameter","text":"
get_ith_parameter(i: int, in_func: bool = True) \u2192 Tuple[str, Optional[int]]\n

Retrieves the correct parameter used for the current function call.

"},{"location":"api/gef/#function-x86_64get_ra","title":"function X86_64.get_ra","text":"
get_ra(insn: __main__.Instruction, frame: 'gdb.Frame') \u2192 Optional[int]\n
"},{"location":"api/gef/#function-x86_64is_branch_taken","title":"function X86_64.is_branch_taken","text":"
is_branch_taken(insn: __main__.Instruction) \u2192 Tuple[bool, str]\n
"},{"location":"api/gef/#function-x86_64is_call","title":"function X86_64.is_call","text":"
is_call(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-x86_64is_conditional_branch","title":"function X86_64.is_conditional_branch","text":"
is_conditional_branch(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-x86_64is_ret","title":"function X86_64.is_ret","text":"
is_ret(insn: __main__.Instruction) \u2192 bool\n
"},{"location":"api/gef/#function-x86_64mprotect_asm","title":"function X86_64.mprotect_asm","text":"
mprotect_asm(addr: int, size: int, perm: __main__.Permission) \u2192 str\n
"},{"location":"api/gef/#function-x86_64register","title":"function X86_64.register","text":"
register(name: str) \u2192 int\n
"},{"location":"api/gef/#function-x86_64reset_caches","title":"function X86_64.reset_caches","text":"
reset_caches() \u2192 None\n
"},{"location":"api/gef/#function-x86_64supports_gdb_arch","title":"function X86_64.supports_gdb_arch","text":"
supports_gdb_arch(gdb_arch: str) \u2192 Optional[bool]\n

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.

"},{"location":"api/gef/#class-xaddressinfocommand","title":"class XAddressInfoCommand","text":"

Retrieve and display runtime information for the location(s) given as parameter.

"},{"location":"api/gef/#function-xaddressinfocommand__init__","title":"function XAddressInfoCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-xaddressinfocommandsettings","title":"property XAddressInfoCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-xaddressinfocommandadd_setting","title":"function XAddressInfoCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-xaddressinfocommanddel_setting","title":"function XAddressInfoCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-xaddressinfocommanddo_invoke","title":"function XAddressInfoCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-xaddressinfocommandget_setting","title":"function XAddressInfoCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-xaddressinfocommandhas_setting","title":"function XAddressInfoCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-xaddressinfocommandinfos","title":"function XAddressInfoCommand.infos","text":"
infos(address: int) \u2192 None\n
"},{"location":"api/gef/#function-xaddressinfocommandinvoke","title":"function XAddressInfoCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-xaddressinfocommandpost_load","title":"function XAddressInfoCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-xaddressinfocommandpre_load","title":"function XAddressInfoCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-xaddressinfocommandusage","title":"function XAddressInfoCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-xfilescommand","title":"class XFilesCommand","text":"

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.

"},{"location":"api/gef/#function-xfilescommand__init__","title":"function XFilesCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-xfilescommandsettings","title":"property XFilesCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-xfilescommandadd_setting","title":"function XFilesCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-xfilescommanddel_setting","title":"function XFilesCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-xfilescommanddo_invoke","title":"function XFilesCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-xfilescommandget_setting","title":"function XFilesCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-xfilescommandhas_setting","title":"function XFilesCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-xfilescommandinvoke","title":"function XFilesCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-xfilescommandpost_load","title":"function XFilesCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-xfilescommandpre_load","title":"function XFilesCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-xfilescommandusage","title":"function XFilesCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-xormemorycommand","title":"class XorMemoryCommand","text":"

XOR a block of memory. The command allows to simply display the result, or patch it runtime at runtime.

"},{"location":"api/gef/#function-xormemorycommand__init__","title":"function XorMemoryCommand.__init__","text":"
__init__() \u2192 None\n
"},{"location":"api/gef/#property-xormemorycommandsettings","title":"property XorMemoryCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-xormemorycommandadd_setting","title":"function XorMemoryCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-xormemorycommanddel_setting","title":"function XorMemoryCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-xormemorycommanddo_invoke","title":"function XorMemoryCommand.do_invoke","text":"
do_invoke(_: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-xormemorycommandget_setting","title":"function XorMemoryCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-xormemorycommandhas_setting","title":"function XorMemoryCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-xormemorycommandinvoke","title":"function XorMemoryCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-xormemorycommandpost_load","title":"function XorMemoryCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-xormemorycommandpre_load","title":"function XorMemoryCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-xormemorycommandusage","title":"function XorMemoryCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-xormemorydisplaycommand","title":"class XorMemoryDisplayCommand","text":"

Display a block of memory pointed by ADDRESS by xor-ing each byte with KEY. The key must be provided in hexadecimal format.

"},{"location":"api/gef/#function-xormemorydisplaycommand__init__","title":"function XorMemoryDisplayCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-xormemorydisplaycommandsettings","title":"property XorMemoryDisplayCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-xormemorydisplaycommandadd_setting","title":"function XorMemoryDisplayCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-xormemorydisplaycommanddel_setting","title":"function XorMemoryDisplayCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-xormemorydisplaycommanddo_invoke","title":"function XorMemoryDisplayCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-xormemorydisplaycommandget_setting","title":"function XorMemoryDisplayCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-xormemorydisplaycommandhas_setting","title":"function XorMemoryDisplayCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-xormemorydisplaycommandinvoke","title":"function XorMemoryDisplayCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-xormemorydisplaycommandpost_load","title":"function XorMemoryDisplayCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-xormemorydisplaycommandpre_load","title":"function XorMemoryDisplayCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-xormemorydisplaycommandusage","title":"function XorMemoryDisplayCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-xormemorypatchcommand","title":"class XorMemoryPatchCommand","text":"

Patch a block of memory pointed by ADDRESS by xor-ing each byte with KEY. The key must be provided in hexadecimal format.

"},{"location":"api/gef/#function-xormemorypatchcommand__init__","title":"function XorMemoryPatchCommand.__init__","text":"
__init__(*args: Any, **kwargs: Any) \u2192 None\n
"},{"location":"api/gef/#property-xormemorypatchcommandsettings","title":"property XorMemoryPatchCommand.settings","text":"

Return the list of settings for this command.

"},{"location":"api/gef/#function-xormemorypatchcommandadd_setting","title":"function XorMemoryPatchCommand.add_setting","text":"
add_setting(\n    name: str,\n    value: Tuple[Any, type, str],\n    description: str = ''\n) \u2192 None\n

add_setting is DEPRECATED and will be removed in the future. Use self[setting_name] = value instead

"},{"location":"api/gef/#function-xormemorypatchcommanddel_setting","title":"function XorMemoryPatchCommand.del_setting","text":"
del_setting(name: str) \u2192 None\n

del_setting is DEPRECATED and will be removed in the future. Use del self[setting_name] instead

"},{"location":"api/gef/#function-xormemorypatchcommanddo_invoke","title":"function XorMemoryPatchCommand.do_invoke","text":"
do_invoke(argv: List[str]) \u2192 None\n
"},{"location":"api/gef/#function-xormemorypatchcommandget_setting","title":"function XorMemoryPatchCommand.get_setting","text":"
get_setting(name: str) \u2192 Any\n

get_setting is DEPRECATED and will be removed in the future. Use self[setting_name] instead

"},{"location":"api/gef/#function-xormemorypatchcommandhas_setting","title":"function XorMemoryPatchCommand.has_setting","text":"
has_setting(name: str) \u2192 bool\n

has_setting is DEPRECATED and will be removed in the future. Use setting_name in self instead

"},{"location":"api/gef/#function-xormemorypatchcommandinvoke","title":"function XorMemoryPatchCommand.invoke","text":"
invoke(args: str, from_tty: bool) \u2192 None\n
"},{"location":"api/gef/#function-xormemorypatchcommandpost_load","title":"function XorMemoryPatchCommand.post_load","text":"
post_load() \u2192 None\n
"},{"location":"api/gef/#function-xormemorypatchcommandpre_load","title":"function XorMemoryPatchCommand.pre_load","text":"
pre_load() \u2192 None\n
"},{"location":"api/gef/#function-xormemorypatchcommandusage","title":"function XorMemoryPatchCommand.usage","text":"
usage() \u2192 None\n
"},{"location":"api/gef/#class-zone","title":"class Zone","text":"

Zone(name, zone_start, zone_end, filename)

"},{"location":"api/gef/#class-classproperty","title":"class classproperty","text":"

Make the attribute a classproperty.

This file was automatically generated via lazydocs.

"},{"location":"commands/aliases/","title":"aliases","text":""},{"location":"commands/aliases/#command-aliases","title":"Command aliases","text":"

Base command to add, remove, and list GEF defined aliases.

gef\u27a4  aliases\naliases (add|rm|list)\n
"},{"location":"commands/aliases/#addingremoving-aliases","title":"Adding/Removing Aliases","text":"

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]\n

To remove an alias, simply use the aliases rm command.

aliases rm [alias]\n
"},{"location":"commands/aliases/#listing-aliases","title":"Listing Aliases","text":"

One can list aliases by using the aliases ls command. Some sample output of this command is seen below.

[+] Aliases defined:\nfmtstr-helper                   \u2192  format-string-helper\ntelescope                       \u2192  dereference\ndps                             \u2192  dereference\ndq                              \u2192  hexdump qword\ndd                              \u2192  hexdump dword\ndw                              \u2192  hexdump word\ndc                              \u2192  hexdump byte\ncs-dis                          \u2192  capstone-disassemble\nctx                             \u2192  context\nstart-break                     \u2192  entry-break\nps                              \u2192  process-search\n[...]\n
"},{"location":"commands/aliases/#using-the-configuration-file","title":"Using the Configuration File","text":"

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:

$ nano ~/.gef.rc\n[...]\n[aliases]\nmy-new-alias = gdb-or-gef-command <arg1> <arg2> <etc...>\n
"},{"location":"commands/aliases/#bringing-some-peda-and-windbg-flavours-into-gef","title":"Bringing some PEDA and WinDBG flavours into GEF","text":"

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\n[...]\n[aliases]\n# some windbg aliases\ndps = dereference\ndq = hexdump qword\ndd = hexdump dword\ndw = hexdump word\ndc = hexdump byte\ndt = pcustom\nbl = info breakpoints\nbp = break\nbe = enable breakpoints\nbd = disable breakpoints\nbc = delete breakpoints\ntbp = tbreak\ntba = thbreak\npa = advance\nptc = finish\nt = stepi\np = nexti\ng = gef run\nuf = disassemble\n

Or here are some PEDA aliases for people used to using PEDA who made the smart move to GEF.

# some peda aliases\ntelescope = dereference\nstart = entry-break\nstack = dereference -l 10 $sp\nargv = show args\nkp = info stack\nfindmem = search-pattern\n

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\u27a4  gef restore\n
"},{"location":"commands/aslr/","title":"aslr","text":""},{"location":"commands/aslr/#command-aslr","title":"Command aslr","text":"

Easily check, enable or disable ASLR on the debugged binary.

Check the status:

gef\u27a4  aslr\nASLR is currently disabled\n

Activate ASLR:

gef\u27a4  aslr on\n[+] Enabling ASLR\ngef\u27a4  aslr\nASLR is currently enabled\n

De-activate ASLR:

gef\u27a4  aslr off\n[+] Disabling ASLR\n

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

"},{"location":"commands/canary/","title":"canary","text":""},{"location":"commands/canary/#command-canary","title":"Command canary","text":"

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.

gef\u27a4 canary\n

"},{"location":"commands/checksec/","title":"checksec","text":""},{"location":"commands/checksec/#command-checksec","title":"Command checksec","text":"

The checksec command is inspired from checksec.sh. 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\u27a4  checksec\n[+] checksec for '/vagrant/test-bin'\nCanary:                                           No\nNX Support:                                       Yes\nPIE Support:                                      No\nNo RPATH:                                         Yes\nNo RUNPATH:                                       Yes\nPartial RelRO:                                    Yes\nFull RelRO:                                       No\n

Or specify directly the binary to check, for example:

$ gdb -ex \"checksec ./tests/test-x86\"\n
"},{"location":"commands/config/","title":"config","text":""},{"location":"commands/config/#command-gef-config","title":"Command gef config","text":"

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:

gef\u27a4  gef config\n

Or to get one setting value:

gef\u27a4  gef config pcustom.struct_path\n

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\u27a4  gef config context.clear_screen 1\n

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\u27a4  gef save\n[+] Configuration saved to '/home/vagrant/.gef.rc'\n

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:

gef\u27a4  gef restore\n[+] Configuration from '/home/hugsy/.gef.rc' restored\n

You can tweak this configuration file outside your gdb session to suit your needs.

"},{"location":"commands/context/","title":"context","text":""},{"location":"commands/context/#command-context","title":"Command context","text":"

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.
"},{"location":"commands/context/#adding-custom-context-panes","title":"Adding custom context panes","text":"

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:

register_external_context_pane(pane_name, display_pane_function, pane_title_function)\n

Check the API documentation to see a full usage of the registration API.

"},{"location":"commands/context/#editing-context-layout","title":"Editing context layout","text":"

gef allows you to configure your own setup for the display, by re-arranging the order with which contexts will be displayed.

gef\u27a4 gef config context.layout\n

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

To hide a section, simply use the context.layout setting, and prepend the section name with - or just omit it.

gef\u27a4 gef config context.layout \"-legend regs stack code args -source -threads -trace extra memory\"\n

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 memory command. For instance,

gef\u27a4 memory watch $sp 0x40 byte\n

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.

To have the stack displayed with the largest stack addresses on top (i.e., grow the stack downward), enable the following setting:

gef\u27a4 gef config context.grow_stack_down True\n

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\u2502+0x00: 0x00007ffff7a2d830  \u2192  <__main+240> mov edi, eax    ($current_frame_savedip)\n0x00007fffffffc9e0\u2502+0x00: 0x00000000004008c0  \u2192  <__init+0> push r15    \u2190 $rbp\n. . . (440 bytes skipped)\n0x00007fffffffc7e8\u2502+0x38: 0x0000000000000000\n0x00007fffffffc7e0\u2502+0x30: 0x0000000000000026 (\"&\"?)\n0x00007fffffffc7d8\u2502+0x28: 0x0000000001958ac0\n0x00007fffffffc7d0\u2502+0x20: 0x00007ffff7ffa2b0  \u2192  0x5f6f7364765f5f00\n0x00007fffffffc7c8\u2502+0x18: 0x00007fff00000000\n0x00007fffffffc7c0\u2502+0x10: 0x00007fffffffc950  \u2192  0x0000000000000000\n0x00007fffffffc7b8\u2502+0x08: 0x0000000000000000\n0x00007fffffffc7b0\u2502+0x00: 0x00007fffffffc7e4  \u2192  0x0000000000000000      \u2190 $rsp\n
"},{"location":"commands/context/#redirecting-context-output-to-another-ttyfile","title":"Redirecting context output to another tty/file","text":"

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.

Enter the command tty in the prompt:

$ tty\n/dev/pts/0\n

Then tell gef about it!

gef\u27a4 gef config context.redirect /dev/pts/0\n

Enjoy:

To go back to normal, remove the value:

gef\u27a4 gef config context.redirect \"\"\n
"},{"location":"commands/context/#display-individual-sections","title":"Display individual sections","text":"

You can display a single section by specifying it as an argument:

gef\u27a4 context regs\n

Multiple sections can be provided, even if they are not part of the current layout:

gef\u27a4 context regs stack\n
"},{"location":"commands/context/#examples","title":"Examples","text":"
  • Display the code section first, then register, and stack, hiding everything else:
gef\u27a4 gef config context.layout \"code regs stack\"\n
  • Stop showing the context sections when breaking:
gef\u27a4 gef config context.enable 0\n
  • Clear the screen before showing the context sections when breaking:
gef\u27a4 gef config context.clear_screen 1\n
  • Don't dereference the registers in the regs section (more compact):
gef\u27a4 gef config context.show_registers_raw 1\n
  • Number of bytes of opcodes to display next to the disassembly.
gef\u27a4 gef config context.show_opcodes_size 4\n
  • Don't 'peek' into the start of functions that are called.
gef\u27a4  gef config context.peek_calls False\n
  • Hide specific registers from the registers view.
gef\u27a4  gef config context.ignore_registers \"$cs $ds $gs\"\n
  • Hide the extra pc context info from the source code view.
gef\u27a4  gef config context.show_source_code_variable_values 0\n
  • Show better definitions for call to libc functions.
gef\u27a4  gef config context.libc_args True\ngef\u27a4  gef config context.libc_args_path /path/to/gef-extras/libc_args\n
"},{"location":"commands/dereference/","title":"dereference","text":""},{"location":"commands/dereference/#command-dereference","title":"Command dereference","text":"

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.

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\u27a4  dereference\n0x00007fffffffdec0\u2502+0x0000: 0x00007ffff7ffe190  \u2192  0x0000555555554000  \u2192   jg 0x555555554047     \u2190 $rsp, $r13\n0x00007fffffffdec8\u2502+0x0008: 0x00007ffff7ffe730  \u2192  0x00007ffff7fd3000  \u2192  0x00010102464c457f\n0x00007fffffffded0\u2502+0x0010: 0x00007ffff7faa000  \u2192  0x00007ffff7de9000  \u2192  0x03010102464c457f\n0x00007fffffffded8\u2502+0x0018: 0x00007ffff7ffd9f0  \u2192  0x00007ffff7fd5000  \u2192  0x00010102464c457f\n0x00007fffffffdee0\u2502+0x0020: 0x00007fffffffdee0  \u2192  [loop detected]\n0x00007fffffffdee8\u2502+0x0028: 0x00007fffffffdee0  \u2192  0x00007fffffffdee0  \u2192  [loop detected]\n0x00007fffffffdef0\u2502+0x0030: 0x00000000f7fa57e3\n0x00007fffffffdef8\u2502+0x0038: 0x0000555555755d60  \u2192  0x0000555555554a40  \u2192   cmp BYTE PTR [rip+0x201601], 0x0        # 0x555555756048\n0x00007fffffffdf00\u2502+0x0040: 0x0000000000000004\n0x00007fffffffdf08\u2502+0x0048: 0x0000000000000001\n

Here is an example with arguments:

gef\u27a4  telescope $rbp+0x10 -l 8\n0x00007fffffffdf40\u2502+0x0000: 0x00007ffff7fa5760  \u2192  0x00000000fbad2887\n0x00007fffffffdf48\u2502+0x0008: 0x00000001f7e65b63\n0x00007fffffffdf50\u2502+0x0010: 0x0000000000000004\n0x00007fffffffdf58\u2502+0x0018: 0x0000000000000000\n0x00007fffffffdf60\u2502+0x0020: 0x00007fffffffdfa0  \u2192  0x0000555555554fd0  \u2192   push r15\n0x00007fffffffdf68\u2502+0x0028: 0x0000555555554980  \u2192   xor ebp, ebp\n0x00007fffffffdf70\u2502+0x0030: 0x00007fffffffe080  \u2192  0x0000000000000001\n0x00007fffffffdf78\u2502+0x0038: 0x0000000000000000\n

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

gef\u27a4  p ($rbp - $rsp)/8\n$3 = 4\ngef\u27a4  dereference -l 5\n0x00007fffffffe170\u2502+0x0000: 0x0000000000400690  \u2192  push r15        \u2190 $rsp\n0x00007fffffffe178\u2502+0x0008: 0x0000000000400460  \u2192  xor ebp, ebp\n0x00007fffffffe180\u2502+0x0010: 0x00007fffffffe270  \u2192  0x1\n0x00007fffffffe188\u2502+0x0018: 0x1\n0x00007fffffffe190\u2502+0x0020: 0x0000000000400690  \u2192  push r15        \u2190 $rbp\n

It is possible to change the offset calculation to use a different address than the start address:

gef\u27a4  dereference $sp -l 7 -r $rbp\n0x00007ffe6ddaa3e0\u2502-0x0030: 0x0000000000000000    \u2190 $rsp\n0x00007ffe6ddaa3e8\u2502-0x0028: 0x0000000000400970  \u2192  <__libc_csu_init+0> push r15\n0x00007ffe6ddaa3f0\u2502-0x0020: 0x0000000000000000\n0x00007ffe6ddaa3f8\u2502-0x0018: 0x00000000004006e0  \u2192  <_start+0> xor ebp, ebp\n0x00007ffe6ddaa400\u2502-0x0010: 0x00007ffe6ddaa500  \u2192  0x0000000000000001\n0x00007ffe6ddaa408\u2502-0x0008: 0xa42456b3ee465800\n0x00007ffe6ddaa410\u2502+0x0000: 0x0000000000000000    \u2190 $rbp\n

Just like with x, you can pass a negative number of addresses to dereference, to examine memory backwards from the start address:

gef\u27a4  dereference $sp -l 3\n0x00007fffffffcf90\u2502+0x0010: 0x00007ffff7f5aaa0  \u2192  0x0000000000000000\n0x00007fffffffcf88\u2502+0x0008: 0x00000000000204a0\n0x00007fffffffcf80\u2502+0x0000: 0x00005555555a6b60  \u2192  0x0000000000000000    \u2190 $rsp\ngef\u27a4  dereference $sp -l -3\n0x00007fffffffcf80\u2502+0x0000: 0x00005555555a6b60  \u2192  0x0000000000000000    \u2190 $rsp\n0x00007fffffffcf78\u2502-0x0008: 0x0000000000000020 (\" \"?)\n0x00007fffffffcf70\u2502-0x0010: 0x000000000000000a (\"\\n\"?)\n
"},{"location":"commands/edit-flags/","title":"edit-flags","text":""},{"location":"commands/edit-flags/#command-edit-flags","title":"Command edit-flags","text":"

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\u27a4 flags [(+|-|~)FLAGNAME ...]\n

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:

gef\u27a4 flags -ZERO +CARRY\n

"},{"location":"commands/elf-info/","title":"elf-info","text":""},{"location":"commands/elf-info/#command-elf-info","title":"Command elf-info","text":"

elf-info (alias elf) provides some basic information on the currently loaded ELF binary:

gef\u27a4  elf\nMagic                 : 7f 45 4c 46\nClass                 : 0x2 - 64-bit\nEndianness            : 0x1 - Little-Endian\nVersion               : 0x1\nOS ABI                : 0x0 - System V\nABI Version           : 0x0\nType                  : 0x2 - Executable\nMachine               : 0x3e - x86-64\nProgram Header Table  : 0x0000000000000040\nSection Header Table  : 0x00000000000021a8\nHeader Table          : 0x0000000000000040\nELF Version           : 0x1\nHeader size           : 64 (0x40)\nEntry point           : 0x0000000000400750\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Program Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  [ #] Type           Offset Virtaddr Physaddr  FileSiz   MemSiz Flags    Align\n  [ 0] PHDR             0x40 0x400040 0x400040    0x1f8    0x1f8 R-X        0x8\n  [ 1] INTERP          0x238 0x400238 0x400238     0x1c     0x1c R--        0x1\n  [ 2] LOAD              0x0 0x400000 0x400000   0x1414   0x1414 R-X   0x200000\n  [ 3] LOAD           0x1e10 0x601e10 0x601e10    0x268    0x330 RW-   0x200000\n  [ 4] DYNAMIC        0x1e28 0x601e28 0x601e28    0x1d0    0x1d0 RW-        0x8\n  [ 5] NOTE            0x254 0x400254 0x400254     0x44     0x44 R--        0x4\n  [ 6] GNU_EH_FLAME   0x11a0 0x4011a0 0x4011a0     0x74     0x74 R--        0x4\n  [ 7] GNU_STACK         0x0      0x0      0x0      0x0      0x0 RW-       0x10\n  [ 8] GNU_RELRO      0x1e10 0x601e10 0x601e10    0x1f0    0x1f0 R--        0x1\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Section Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  [ #] Name                            Type  Address   Offset     Size   EntSiz Flags Link Info    Align\n  [ 0]                                 NULL      0x0      0x0      0x0      0x0        0x0  0x0      0x0\n  [ 1] .interp                     PROGBITS 0x400238    0x238     0x1c      0x0 A      0x0  0x0      0x1\n  [ 2] .note.ABI-tag                   NOTE 0x400254    0x254     0x20      0x0 A      0x0  0x0      0x4\n  [ 3] .note.gnu.build-id              NOTE 0x400274    0x274     0x24      0x0 A      0x0  0x0      0x4\n  [ 4] .gnu.hash                   GNU_HASH 0x400298    0x298     0x30      0x0 A      0x5  0x0      0x8\n  [ 5] .dynsym                       DYNSYM 0x4002c8    0x2c8    0x168     0x18 A      0x6  0x1      0x8\n  [ 6] .dynstr                       STRTAB 0x400430    0x430     0x96      0x0 A      0x0  0x0      0x1\n  [ 7] .gnu.version                    HIOS 0x4004c6    0x4c6     0x1e      0x2 A      0x5  0x0      0x2\n  [ 8] .gnu.version_r           GNU_verneed 0x4004e8    0x4e8     0x30      0x0 A      0x6  0x1      0x8\n  [ 9] .rela.dyn                       RELA 0x400518    0x518     0x60     0x18 A      0x5  0x0      0x8\n  [10] .rela.plt                       RELA 0x400578    0x578     0xf0     0x18 AI     0x5 0x18      0x8\n  [11] .init                       PROGBITS 0x400668    0x668     0x1a      0x0 AX     0x0  0x0      0x4\n  [12] .plt                        PROGBITS 0x400690    0x690     0xb0     0x10 AX     0x0  0x0     0x10\n  [13] .plt.got                    PROGBITS 0x400740    0x740      0x8      0x0 AX     0x0  0x0      0x8\n  [14] .text                       PROGBITS 0x400750    0x750    0x842      0x0 AX     0x0  0x0     0x10\n  [15] .fini                       PROGBITS 0x400f94    0xf94      0x9      0x0 AX     0x0  0x0      0x4\n  [16] .rodata                     PROGBITS 0x400fa0    0xfa0    0x200      0x0 A      0x0  0x0      0x8\n  [17] .eh_frame_hdr               PROGBITS 0x4011a0   0x11a0     0x74      0x0 A      0x0  0x0      0x4\n  [18] .eh_frame                   PROGBITS 0x401218   0x1218    0x1fc      0x0 A      0x0  0x0      0x8\n  [19] .init_array               INIT_ARRAY 0x601e10   0x1e10      0x8      0x0 WA     0x0  0x0      0x8\n  [20] .fini_array               FINI_ARRAY 0x601e18   0x1e18      0x8      0x0 WA     0x0  0x0      0x8\n  [21] .jcr                        PROGBITS 0x601e20   0x1e20      0x8      0x0 WA     0x0  0x0      0x8\n  [22] .dynamic                     DYNAMIC 0x601e28   0x1e28    0x1d0     0x10 WA     0x6  0x0      0x8\n  [23] .got                        PROGBITS 0x601ff8   0x1ff8      0x8      0x8 WA     0x0  0x0      0x8\n  [24] .got.plt                    PROGBITS 0x602000   0x2000     0x68      0x8 WA     0x0  0x0      0x8\n  [25] .data                       PROGBITS 0x602068   0x2068     0x10      0x0 WA     0x0  0x0      0x8\n  [26] .bss                          NOBITS 0x602080   0x2078     0xc0      0x0 WA     0x0  0x0     0x20\n  [27] .comment                    PROGBITS      0x0   0x2078     0x34      0x1 MS     0x0  0x0      0x1\n  [28] .shstrtab                     STRTAB      0x0   0x20ac     0xfc      0x0        0x0  0x0      0x1\n

Optionally a filepath to another ELF binary can be provided to view the basic information for that binary instead.

gef\u27a4 elf-info --filename /path/to/elf/executable\n
"},{"location":"commands/entry-break/","title":"entry-break","text":""},{"location":"commands/entry-break/#command-entry-break","title":"Command entry-break","text":"

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.

"},{"location":"commands/eval/","title":"eval","text":""},{"location":"commands/eval/#command","title":"Command $","text":"

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:

gef\u27a4  $ $pc+1\n93824992252977\n0x555555559431\n0b10101010101010101010101010101011001010000110001\nb'UUUU\\x941'\nb'1\\x94UUUU'\n\ngef\u27a4  $ -0x1000\n-4096\n0xfffffffffffff000\n0b1111111111111111111111111111111111111111111111111111000000000000\nb'\\xff\\xff\\xff\\xff\\xff\\xff\\xf0\\x00'\nb'\\x00\\xf0\\xff\\xff\\xff\\xff\\xff\\xff'\n

With two arguments, it will simply compute the delta between them:

gef\u27a4  vmmap libc\nStart              End                Offset             Perm\n0x00007ffff7812000 0x00007ffff79a7000 0x0000000000000000 r-x /lib/x86_64-linux-gnu/libc-2.24.so\n0x00007ffff79a7000 0x00007ffff7ba7000 0x0000000000195000 --- /lib/x86_64-linux-gnu/libc-2.24.so\n0x00007ffff7ba7000 0x00007ffff7bab000 0x0000000000195000 r-- /lib/x86_64-linux-gnu/libc-2.24.so\n0x00007ffff7bab000 0x00007ffff7bad000 0x0000000000199000 rw- /lib/x86_64-linux-gnu/libc-2.24.so\n\ngef\u27a4  $ 0x00007ffff7812000 0x00007ffff79a7000\n-1658880\n1658880\n\ngef\u27a4  $ 1658880\n1658880\n0x195000\n0b110010101000000000000\nb'\\x19P\\x00'\nb'\\x00P\\x19'\n
"},{"location":"commands/format-string-helper/","title":"format-string-helper","text":""},{"location":"commands/format-string-helper/#command-format-string-helper","title":"Command format-string-helper","text":"

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:

  • printf()
  • sprintf()
  • fprintf()
  • snprintf()
  • vsnprintf()

Just call the command to enable this functionality.

fmtstr-helper is a shorter alias.

gef\u27a4 fmtstr-helper\n

Then start the binary execution.

gef\u27a4 r\n

If a potentially insecure entry is found, the breakpoint will trigger, stop the process execution, display the reason for trigger and the associated context.

"},{"location":"commands/functions/","title":"functions","text":""},{"location":"commands/functions/#command-functions","title":"Command functions","text":"

The functions command will list all of the convenience functions 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.

These functions can be used as arguments to other commands to dynamically calculate values.

gef\u27a4  deref -l 4 $_heap()\n0x0000000000602000\u2502+0x00: 0x0000000000000000     \u2190 $r8\n0x0000000000602008\u2502+0x08: 0x0000000000000021 (\"!\"?)\n0x0000000000602010\u2502+0x10: 0x0000000000000000     \u2190 $rax, $rdx\n0x0000000000602018\u2502+0x18: 0x0000000000000000\ngef\u27a4  deref -l 4 $_heap(0x20)\n0x0000000000602020\u2502+0x00: 0x0000000000000000     \u2190 $rsi\n0x0000000000602028\u2502+0x08: 0x0000000000020fe1\n0x0000000000602030\u2502+0x10: 0x0000000000000000\n0x0000000000602038\u2502+0x18: 0x0000000000000000\ngef\u27a4  deref -l 4 $_base(\\\"libc\\\")\n0x00007ffff7da9000\u2502+0x0000: 0x03010102464c457f\n0x00007ffff7da9008\u2502+0x0008: 0x0000000000000000\n0x00007ffff7da9010\u2502+0x0010: 0x00000001003e0003\n0x00007ffff7da9018\u2502+0x0018: 0x0000000000027c60\n
"},{"location":"commands/gef-remote/","title":"gef-remote","text":""},{"location":"commands/gef-remote/#command-gef-remote","title":"Command gef-remote","text":"

target remote 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.

\ud83d\udcdd 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.

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.

"},{"location":"commands/gef-remote/#remote-mode","title":"Remote mode","text":""},{"location":"commands/gef-remote/#remote","title":"remote","text":"

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:

$ gdbserver  :1234 /tmp/default.out\nProcess /tmp/default.out created; pid = 258932\nListening on port 1234\n

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'\nGEF for linux ready, type `gef' to start, `gef config' to configure\n90 commands loaded and 5 functions added for GDB 10.2 using Python engine 3.8\ngef\u27a4 gef-remote localhost 1234\n[=] [remote] initializing remote session with localhost:1234 under /tmp/tmp8qd0r7iw\n[=] [remote] Installing new objfile handlers\n[=] [remote] Enabling extended remote: False\n[=] [remote] Executing 'target remote localhost:1234'\nReading /tmp/default.out from remote target...\nwarning: File transfers from remote targets can be slow. Use \"set sysroot\" to access files locally instead.\nReading /tmp/default.out from remote target...\nReading symbols from target:/tmp/default.out...\n[=] [remote] in remote_objfile_handler(target:/tmp/default.out))\n[=] [remote] downloading '/tmp/default.out' -> '/tmp/tmp8qd0r7iw/tmp/default.out'\nReading /lib64/ld-linux-x86-64.so.2 from remote target...\nReading /lib64/ld-linux-x86-64.so.2 from remote target...\n[=] [remote] in remote_objfile_handler(/usr/lib/debug/.build-id/45/87364908de169dec62ffa538170118c1c3a078.debug))\n[=] [remote] in remote_objfile_handler(target:/lib64/ld-linux-x86-64.so.2))\n[=] [remote] downloading '/lib64/ld-linux-x86-64.so.2' -> '/tmp/tmp8qd0r7iw/lib64/ld-linux-x86-64.so.2'\n[=] [remote] in remote_objfile_handler(system-supplied DSO at 0x7ffff7fcd000))\n[*] [remote] skipping 'system-supplied DSO at 0x7ffff7fcd000'\n0x00007ffff7fd0100 in _start () from target:/lib64/ld-linux-x86-64.so.2\n[=] Setting up as remote session\n[=] [remote] downloading '/proc/258932/maps' -> '/tmp/tmp8qd0r7iw/proc/258932/maps'\n[=] [remote] downloading '/proc/258932/environ' -> '/tmp/tmp8qd0r7iw/proc/258932/environ'\n[=] [remote] downloading '/proc/258932/cmdline' -> '/tmp/tmp8qd0r7iw/proc/258932/cmdline'\n[...]\n

And finally breaking into the program, showing the current context:

You will also notice the prompt has changed to indicate the debugging mode is now \"remote\". Besides that, all of GEF features are available:

"},{"location":"commands/gef-remote/#remote-extended","title":"remote-extended","text":"

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.

"},{"location":"commands/gef-remote/#qemu-mode","title":"Qemu mode","text":"

Qemu mode of gef-remote allows to connect to the Qemu GDB stub 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 \ud83d\ude09 And using it is very straight forward.

"},{"location":"commands/gef-remote/#qemu-user","title":"qemu-user","text":"
  1. Run qemu-x86_64 :1234 /bin/ls
  2. Use --qemu-user and --qemu-binary /bin/ls when starting gef-remote
"},{"location":"commands/gef-remote/#qemu-system","title":"qemu-system","text":"

To test locally, you can use the mini image linux x64 vm here. 1. Run ./run.sh 2. Use --qemu-user and --qemu-binary vmlinuz when starting gef-remote

"},{"location":"commands/gef/","title":"gef","text":""},{"location":"commands/gef/#command-gef","title":"Command gef","text":""},{"location":"commands/gef/#gef-base-command","title":"GEF Base Command","text":"

Displays a list of GEF commands and their descriptions.

gef\u27a4  gef\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 GEF - GDB Enhanced Features \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n$                         -- SmartEval: Smart eval (vague approach to mimic WinDBG `?`).\naslr                      -- View/modify the ASLR setting of GDB. By default, GDB will disable ASLR when it starts the process. (i.e. not\n                             attached). This command allows to change that setting.\nassemble                  -- Inline code assemble. Architecture can be set in GEF runtime config (default x86-32).  (alias: asm)\nbincompare                -- BincompareCommand: compare an binary file with the memory position looking for badchars.\nbytearray                 -- BytearrayCommand: Generate a bytearray to be compared with possible badchars.\n\n[...snip...]\n\n
"},{"location":"commands/gef/#gef-missing-command","title":"GEF Missing Command","text":"

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\u27a4  gef missing\n[*] Command `XXXX` is missing, reason  \u2192  YYYYY.\n
"},{"location":"commands/gef/#gef-config-command","title":"GEF Config Command","text":"

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.

gef\u27a4  gef config\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 GEF configuration settings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ncontext.clear_screen (bool) = False\ncontext.enable (bool) = True\ncontext.grow_stack_down (bool) = False\ncontext.ignore_registers (str) = \"\"\ncontext.layout (str) = \"-code -stack\"\ncontext.libc_args (bool) = False\n\n[...snip...]\n\n

To filter the config settings you can use gef config [setting].

gef\u27a4  gef config theme\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 GEF configuration settings matching 'theme' \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ntheme.context_title_line (str) = \"gray\"\ntheme.context_title_message (str) = \"cyan\"\ntheme.default_title_line (str) = \"gray\"\ntheme.default_title_message (str) = \"cyan\"\n\n[...snip...]\n\n

You can use gef config [setting] [value] to set a setting for the current session (see example below).

gef\u27a4  gef config theme.address_stack blue\n
"},{"location":"commands/gef/#gef-save-command","title":"GEF Save Command","text":"

The gef save command saves the current settings (set with gef config) to the user's ~/.gef.rc file (making the changes persistent).

gef\u27a4  gef save\n[+] Configuration saved to '/home/michael/.gef.rc'\n
"},{"location":"commands/gef/#gef-restore-command","title":"GEF Restore Command","text":"

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\u27a4  gef restore\n[+] Configuration from '/home/michael/.gef.rc' restored\n
"},{"location":"commands/gef/#gef-set-command","title":"GEF Set Command","text":"

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\u27a4  gef set $a=1\n
"},{"location":"commands/gef/#gef-run-command","title":"GEF Run Command","text":"

The GEF run command is a wrapper around GDB's run command, allowing the user to use GEF context within the command.

gef\u27a4  gef run ./binary\n
"},{"location":"commands/gef/#gef-install-command","title":"GEF Install Command","text":"

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\u27a4  gef install SCRIPTNAME1 [SCRIPTNAME2...]\n

Where SCRIPTNAME1 ... are the names of script from the gef-extras repository.

gef\u27a4  gef install remote windbg stack\n[+] Searching for 'remote.py' in `gef-extras@main`...\n[+] Installed file '/tmp/gef/remote.py', new command(s) available: `rpyc-remote`\n[+] Searching for 'windbg.py' in `gef-extras@main`...\n[+] Installed file '/tmp/gef/windbg.py', new command(s) available: `pt`, `hh`, `tt`, `ptc`, `sxe`, `u`, `xs`, `tc`, `pc`, `g`, `r`\n[+] Searching for 'stack.py' in `gef-extras@main`...\n[+] Installed file '/tmp/gef/stack.py', new command(s) available: `current-stack-frame`\ngef\u27a4\n

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\u27a4 gef config gef.default_branch dev\n

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.

"},{"location":"commands/got/","title":"got","text":""},{"location":"commands/got/#command-got","title":"Command got","text":"

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\u27a4 got\n

The applied filter partially matches the name of the functions, so you can do something like this.

gef\u27a4 got str\ngef\u27a4 got print\ngef\u27a4 got read\n

Example of multiple partial filters:

gef\u27a4 got str get\n

"},{"location":"commands/heap-analysis-helper/","title":"heap-analysis-helper","text":""},{"location":"commands/heap-analysis-helper/#command-heap-analysis-helper","title":"Command heap-analysis-helper","text":"

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.

Currently, the following issues can be tracked:

  • NULL free
  • Use-after-Free
  • Double Free
  • Heap overlap

The helper can simply be activated by running the command heap-analysis-helper.

gef\u27a4 heap-analysis\n[+] Tracking malloc()\n[+] Tracking free()\n[+] Disabling hardware watchpoints (this may increase the latency)\n[+] Dynamic breakpoints correctly setup, GEF will break execution if a possible vulnerabity is found.\n[+] To disable, clear the malloc/free breakpoints (`delete breakpoints`) and restore hardware breakpoints (`set can-use-hw-watchpoints 1`)\n

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_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.

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:

gef\u27a4  gef config heap-analysis-helper.check_double_free False\ngef\u27a4  gef config heap-analysis-helper.check_free_null False\ngef\u27a4  gef config heap-analysis-helper.check_weird_free False\ngef\u27a4  gef config heap-analysis-helper.check_uaf False\n

Then gef will not notify you of any inconsistency detected, but simply display a clear message when a chunk is allocated/freed.

To get information regarding the currently tracked chunks, use the show subcommand:

gef\u27a4  heap-analysis-helper show\n

"},{"location":"commands/heap/","title":"heap","text":""},{"location":"commands/heap/#command-heap","title":"Command heap","text":"

The heap command provides information on the heap chunk specified as argument. For the moment, it only supports GlibC heap format (see this link for malloc structure information). Syntax to the subcommands is straight forward:

gef\u27a4 heap <sub_commands>\n
"},{"location":"commands/heap/#main_arena-symbol","title":"main_arena symbol","text":"

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\u27a4 gef config gef.main_arena_offset <offset>\n

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\u27a4 gef config gef.bruteforce_main_arena True\n

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.

"},{"location":"commands/heap/#heap-chunks-command","title":"heap chunks command","text":"

Displays all the chunks from the heap section of the current arena.

gef\u27a4 heap chunks\n

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\u27a4 heap chunks [arena_address]\n

In order to display the chunks of all the available arenas at once use

gef\u27a4 heap chunks -a\n

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.

"},{"location":"commands/heap/#heap-chunk-command","title":"heap chunk command","text":"

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\u27a4 heap chunk [address]\n

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:

gef\u27a4 heap chunk --number 6 0x4e5400\nChunk(addr=0x4e5400, size=0xd0, flags=PREV_INUSE)\nChunk(addr=0x4e54d0, size=0x1a0, flags=PREV_INUSE)\nChunk(addr=0x4e5670, size=0x200, flags=PREV_INUSE)\nChunk(addr=0x4e5870, size=0xbc0, flags=PREV_INUSE)\nChunk(addr=0x4e6430, size=0x330, flags=PREV_INUSE)\nChunk(addr=0x4e6760, size=0x4c0, flags=PREV_INUSE)\n\n
"},{"location":"commands/heap/#heap-arenas-command","title":"heap arenas command","text":"

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.

"},{"location":"commands/heap/#heap-set-arena-command","title":"heap set-arena command","text":"

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\u27a4 heap set-arena [address]\n

If the arena address is correct, all heap commands will be functional, and use the specified address for main_arena.

"},{"location":"commands/heap/#heap-bins-command","title":"heap bins command","text":"

Glibc uses bins for keeping tracks of freed 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
  • unsorted
  • small bins
  • large bins
  • tcachebins
"},{"location":"commands/heap/#heap-bins-fast-command","title":"heap bins fast command","text":"

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

gef\u27a4 heap bins fast\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Fastbins for arena 0x7ffff7fb8b80 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nFastbins[idx=0, size=0x20]  \u2190  Chunk(addr=0x555555559380, size=0x20, flags=PREV_INUSE)\nFastbins[idx=1, size=0x30] 0x00\nFastbins[idx=2, size=0x40] 0x00\nFastbins[idx=3, size=0x50] 0x00\nFastbins[idx=4, size=0x60] 0x00\nFastbins[idx=5, size=0x70] 0x00\nFastbins[idx=6, size=0x80] 0x00\n
"},{"location":"commands/heap/#other-heap-bins-x-command","title":"Other heap bins X command","text":"

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.

"},{"location":"commands/heap/#heap-bins-tcache-command","title":"heap bins tcache command","text":"

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\u27a4 heap bins tcache [all] [thread_ids...]\n

Without any arguments, heap bins tcache will display the tcache for the current thread. heap bins tcache all will show the tcaches 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\u27a4 heap bins tcache 1 2\n
"},{"location":"commands/help/","title":"help","text":""},{"location":"commands/help/#command-gef-help","title":"Command gef help","text":"

Displays the help menu for the loaded GEF commands.

gef\u27a4 gef help\n
"},{"location":"commands/hexdump/","title":"hexdump","text":""},{"location":"commands/hexdump/#command-hexdump","title":"Command hexdump","text":"

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

The syntax is as following:

hexdump (qword|dword|word|byte) [-h] [--reverse] [--size SIZE] [address]\n

Examples:

  • Display 4 QWORDs from $pc:
gef\u27a4  hexdump qword $pc --size 4\n0x7ffff7a5c1c0+0000 \u2502 0x4855544155415641\n0x7ffff7a5c1c0+0008 \u2502 0x0090ec814853cd89\n0x7ffff7a5c1c0+0010 \u2502 0x377d6f058b480000\n0x7ffff7a5c1c0+0018 \u2502 0x748918247c894800\n
  • Display 32 bytes from a location in the stack:
gef\u27a4  hexdump byte 0x00007fffffffe5e5 --size 32\n0x00007fffffffe5e5     2f 68 6f 6d 65 2f 68 75 67 73 79 2f 63 6f 64 65     /home/hugsy/code\n0x00007fffffffe5f5     2f 67 65 66 2f 74 65 73 74 73 2f 77 69 6e 00 41     /gef/tests/win.A\n
  • Display 8 WORDs from $sp in reverse order:
gef\u27a4  hexdump word 8 --reverse\n0x00007fffffffe0ee\u2502+0x000e   0x0000\n0x00007fffffffe0ec\u2502+0x000c   0x7fff\n0x00007fffffffe0ea\u2502+0x000a   0xffff\n0x00007fffffffe0e8\u2502+0x0008   0xe3f5\n0x00007fffffffe0e6\u2502+0x0006   0x0000\n0x00007fffffffe0e4\u2502+0x0004   0x0000\n0x00007fffffffe0e2\u2502+0x0002   0x0000\n0x00007fffffffe0e0\u2502+0x0000   0x0001\n
"},{"location":"commands/highlight/","title":"highlight","text":""},{"location":"commands/highlight/#command-highlight","title":"Command highlight","text":"

This command sets up custom highlighting for user set strings.

Syntax:

highlight (add|remove|list|clear)\n

Alias:

  • hl
"},{"location":"commands/highlight/#adding-matches","title":"Adding matches","text":"

The following will add 41414141/'AAAA' as yellow, and 42424242/'BBBB' as blue:

gef\u27a4  hl add 41414141 yellow\ngef\u27a4  hl add 42424242 blue\ngef\u27a4  hl add AAAA yellow\ngef\u27a4  hl add BBBB blue\n
"},{"location":"commands/highlight/#removing-matches","title":"Removing matches","text":"

To remove a match, target it by the original string used, ex.:

gef\u27a4  hl rm 41414141\n
"},{"location":"commands/highlight/#listing-matches","title":"Listing matches","text":"

To list all matches with their colors:

gef\u27a4  hl list\n41414141 | yellow\n42424242 | blue\nAAAA     | yellow\nBBBB     | blue\n
"},{"location":"commands/highlight/#clearing-all-matches","title":"Clearing all matches","text":"

To clear all matches currently setup:

gef\u27a4  hl clear\n
"},{"location":"commands/highlight/#regex-support","title":"RegEx support","text":"

RegEx support is disabled by default, this is done for performance reasons.

To enable regular expressions on text matches:

gef\u27a4  gef config highlight.regex True\n

To check the current status:

gef\u27a4  gef config highlight.regex\nhighlight.regex (bool) = True\n
"},{"location":"commands/highlight/#performance","title":"Performance","text":"

NOTE: Adding many matches may slow down debugging while using GEF. This includes enabling RegEx support.

"},{"location":"commands/highlight/#colors","title":"Colors","text":"

To find a list of supported colors, check the theme documentation.

"},{"location":"commands/hijack-fd/","title":"hijack-fd","text":""},{"location":"commands/hijack-fd/#command-hijack-fd","title":"Command hijack-fd","text":"

gef can be used to modify file descriptors of the debugged process. The new file descriptor can point to a file, a pipe, a socket, a device etc.

To use it, simply run

gef\u27a4 hijack-fd FDNUM NEWFILE\n

For instance,

gef\u27a4 hijack-fd 1 /dev/null\n

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\u27a4 hijack-fd 0 localhost:8888\n

Will redirect STDIN to localhost:8888

Check out the tutorial on GEF's YouTube channel:

"},{"location":"commands/ksymaddr/","title":"ksymaddr","text":""},{"location":"commands/ksymaddr/#command-ksymaddr","title":"Command ksymaddr","text":"

ksymaddr helps locate a kernel symbol by its name.

The syntax is straight forward:

ksymaddr <PATTERN>\n

For example,

gef\u27a4  ksymaddr commit_creds\n[+] Found matching symbol for 'commit_creds' at 0xffffffff8f495740 (type=T)\n[*] Found partial match for 'commit_creds' at 0xffffffff8f495740 (type=T): commit_creds\n[*] Found partial match for 'commit_creds' at 0xffffffff8fc71ee0 (type=R): __ksymtab_commit_creds\n[*] Found partial match for 'commit_creds' at 0xffffffff8fc8d008 (type=r): __kcrctab_commit_creds\n[*] Found partial match for 'commit_creds' at 0xffffffff8fc9bfcd (type=r): __kstrtab_commit_creds\n

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.

"},{"location":"commands/memory/","title":"memory","text":""},{"location":"commands/memory/#command-memory","title":"Command memory","text":"

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.

Note: this command shoud NOT be mistaken with the GDB watch command meant to set breakpoints on memory access (read,write,exec).

"},{"location":"commands/memory/#adding-a-watch","title":"Adding a watch","text":"

Specify a location to watch and display with the context, along with their optional size and format:

Syntax:

memory watch <ADDRESS> [SIZE] [(qword|dword|word|byte|pointers)]\n

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 allowing to easily track commonly used addresses:

For example, to watch the first 5 entries of the GOT as pointers:

gef \u27a4 memory watch $_got()+0x18 5\n[+] Adding memwatch to 0x555555773c50\n

Which, when the context is displayed, will show something like:

"},{"location":"commands/memory/#removing-a-watch","title":"Removing a watch","text":"

Remove a watched address. To list all the addresses being watched, use memory list.

Syntax:

memory unwatch <ADDRESS>\n
"},{"location":"commands/memory/#listing-watches","title":"Listing watches","text":"

Enumerate all the addresses currently watched by the memory command.

Syntax:

memory list\n

The command will output a list of all the addresses watched, along with the size and format to display them as.

"},{"location":"commands/memory/#resetting-watches","title":"Resetting watches","text":"

Empties the list of addresses to watch.

Syntax:

memory reset\n
"},{"location":"commands/name-break/","title":"name-break","text":""},{"location":"commands/name-break/#command-name-break","title":"Command name-break","text":"

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.

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.

Examples:

  • nb first *0x400ec0
  • nb \"main func\" main
  • nb read_secret *main+149
  • nb check_heap

Example output:

\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 code:x86:64 \u2500\u2500\u2500\u2500\n     0x400e04                  add    eax, 0xfffbe6e8\n     0x400e09                  dec    ecx\n     0x400e0b                  ret\n \u2192   0x400e0c                  push   rbp\n     0x400e0d                  mov    rbp, rsp\n     0x400e10                  sub    rsp, 0x50\n     0x400e14                  mov    QWORD PTR [rbp-0x48], rdi\n     0x400e18                  mov    QWORD PTR [rbp-0x50], rsi\n     0x400e1c                  mov    rax, QWORD PTR fs:0x28\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 stack \u2500\u2500\u2500\u2500\n0x00007fffffffe288\u2502+0x0000: 0x0000000000401117  \u2192   movzx ecx, al    \u2190 $rsp\n0x00007fffffffe290\u2502+0x0008: 0x00007fffffffe4b8  \u2192  0x00007fffffffe71d  \u2192  \"/ctf/t19/srv_copy\"\n0x00007fffffffe298\u2502+0x0010: 0x0000000100000000\n0x00007fffffffe2a0\u2502+0x0018: 0x0000000000000000\n0x00007fffffffe2a8\u2502+0x0020: 0x0000000000000004\n0x00007fffffffe2b0\u2502+0x0028: 0x0000000000000000\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 extra \u2500\u2500\u2500\u2500\n[+] Hit breakpoint *0x400e0c (check_entry)\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ngef\u27a4\n
"},{"location":"commands/nop/","title":"nop","text":""},{"location":"commands/nop/#command-nop","title":"Command nop","text":"

The nop command allows you to easily patch instructions with nops.

nop [LOCATION] [--i ITEMS] [--f] [--n] [--b]\n

LOCATION address/symbol to patch (by default this command replaces whole instructions)

--i ITEMS number of items to insert (default 1)

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

gef\u27a4    nop\n

nop an instruction at $pc+3 address:

gef\u27a4    nop $pc+3\n

nop two instructions at address $pc+3:

gef\u27a4    nop --i 2 $pc+3\n

Replace 1 byte with nop at current instruction ($pc):

gef\u27a4    nop --b\n

Replace 1 byte with nop at address $pc+3:

gef\u27a4    nop --b $pc+3\n

Replace 2 bytes with nop(s) (breaking the last instruction) at address $pc+3:

gef\u27a4    nop --f --b --i 2 $pc+3\n

Patch 2 nops at address $pc+3:

gef\u27a4    nop --n --i 2 $pc+3\n
"},{"location":"commands/patch/","title":"patch","text":""},{"location":"commands/patch/#command-patch","title":"Command patch","text":"

patch lets you easily patch the specified values to the specified address.

gef\u27a4 patch byte $eip 0x90\ngef\u27a4 patch string $eip \"cool!\"\n

These commands copy the first 10 bytes of $rsp+8 to $rip:

gef\u27a4  print-format --lang bytearray -l 10 $rsp+8\nSaved data b'\\xcb\\xe3\\xff\\xff\\xff\\x7f\\x00\\x00\\x00\\x00'... in '$_gef0'\ngef\u27a4  patch byte $rip $_gef0\n

Very handy to copy-paste-execute shellcodes/data from different memory regions.

"},{"location":"commands/pattern/","title":"pattern","text":""},{"location":"commands/pattern/#command-pattern","title":"Command pattern","text":"

This command will create or search a De Bruijn 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.

"},{"location":"commands/pattern/#pattern-create","title":"pattern create","text":"
pattern create [-h] [-n N] [length]\n

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\u27a4  pattern create -n 4 128\n[+] Generating a pattern of 128 bytes (n=4)\naaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaab\n[+] Saved as '$_gef0'\n

The equivalent command with pwntools is

from pwn import *\np = cyclic(128, n=8)\n
"},{"location":"commands/pattern/#pattern-search","title":"pattern search","text":"
pattern search [-h] [-n N] [--max-length MAX_LENGTH] [pattern]\n

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

gef\u27a4  pattern search 0x6161616161616167\n[+] Searching '0x6161616161616167'\n[+] Found at offset 48 (little-endian search) likely\n[+] Found at offset 41 (big-endian search)\ngef\u27a4  pattern search $rbp\n[+] Searching '$rbp'\n[+] Found at offset 32 (little-endian search) likely\n[+] Found at offset 25 (big-endian search)\ngef\u27a4  pattern search aaaaaaac\n[+] Searching for 'aaaaaaac'\n[+] Found at offset 16 (little-endian search) likely\n[+] Found at offset 9 (big-endian search)\n
"},{"location":"commands/pcustom/","title":"pcustom","text":""},{"location":"commands/pcustom/#command-pcustom","title":"Command pcustom","text":"

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

"},{"location":"commands/pcustom/#configuration","title":"Configuration","text":"

New structures can be stored in the location given by the configuration setting:

gef\u27a4 gef config pcustom.struct_path\n

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 <struct_name>.py.

You can naturally set this path to a new location

gef\u27a4 gef config pcustom.struct_path /my/new/location\n

And save this change so you can re-use it directly next time you use gdb

gef\u27a4 gef save\n[+] Configuration saved to '~/.gef.rc'\n
"},{"location":"commands/pcustom/#using-user-defined-structures","title":"Using user-defined structures","text":"

You can list existing custom structures via

gef\u27a4  pcustom list\n[+] Listing custom structures from '/tmp/structs'\n \u2192  /tmp/structs/A.py (A, B)\n \u2192  /tmp/structs/elf32_t.py (elf32_t)\n \u2192  /tmp/structs/elf64_t.py (elf64_t)\n[...]\n

To create or edit a structure, use pcustom edit <struct_name> 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\u27a4  pcustom new mystruct_t\n[+] Creating '/tmp/gef/structs/mystruct_t.py' from template\n

If the structure already exists, GEF will open the text editor to edit the known structure. This is equivalent to:

gef\u27a4  pcustom edit elf32_t\n[+] Editing '/home/hugsy/code/gef-extras/structs/elf32_t.py'\n
"},{"location":"commands/pcustom/#static-ctypesstructure-like-classes","title":"Static ctypes.Structure-like classes","text":"

The code can be defined just as any Python (using ctypes) code.

from ctypes import *\n\n'''\ntypedef struct {\n  int age;\n  char name[256];\n  int id;\n} person_t;\n'''\n\nclass person_t(Structure):\n    _fields_ = [\n        (\"age\",  c_int),\n        (\"name\", c_char * 256),\n        (\"id\", c_int),\n    ]\n\n    _values_ = [\n        # You can define a function to substitute the value\n        (\"age\", lambda age: \"Old\" if age > 40 else \"Young\"),\n        # Or alternatively a list of 2-tuples\n        (\"id\", [\n            (0, \"root\"),\n            (1, \"normal user\"),\n            (None, \"Invalid person\")\n        ])\n    ]\n

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\u27a4  dt person_t\n+0000   age          c_int   /* size=0x4 */\n+0004   name         c_char_Array_256   /* size=0x100 */\n+0104   id           c_int   /* size=0x4 */\n

By providing an address or a GDB symbol, gef will apply this user-defined structure to the specified address:

This means that we can now create very easily new user-defined structures

For a full demo, watch the following tutorial:

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: - (see gef-extras/ida-rpyc, which is the new improved version of ida-interact)

"},{"location":"commands/pcustom/#dynamic-ctypesstructure-like-classes","title":"Dynamic ctypes.Structure-like classes","text":"

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

import ctypes\nfrom typing import Optional\n\ndef person_t(gef: Optional[\"Gef\"]=None):\n    fields = [\n        (\"age\",  ctypes.c_int),\n        (\"name\", ctypes.c_char * 256),\n        (\"id\", ctypes.c_int),\n    ]\n\n    class person_cls(ctypes.Structure):\n      _fields_ = fields\n\n    return person_cls\n

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:

import ctypes\nfrom typing import Optional\n\ndef person_t(gef: Optional[\"Gef\"]==None):\n    fields = [\n        (\"age\",  ctypes.c_uint8),\n        (\"name\", ctypes.c_char * 256),\n        (\"id\", ctypes.c_uint8),\n    ]\n\n    # constraint on the libc version\n    if gef.libc.version > (2, 27):\n      # or on the pointer size\n      pointer_type = ctypes.c_uint64 if gef.arch.ptrsize == 8 else ctypes.c_uint32\n      fields += [\n        (\"new_field\", pointer_size)\n      ]\n\n    class person_cls(ctypes.Structure):\n      _fields_ = fields\n\n    return person_cls\n
"},{"location":"commands/pcustom/#public-repository-of-structures","title":"Public repository of structures","text":"

A community contributed repository of structures can be found in gef-extras. To deploy it:

In bash:

$ git clone https://github.com/hugsy/gef-extras\n

In GEF:

gef\u27a4 gef config pcustom.struct_path /path/to/gef-extras/structs\ngef\u27a4 gef save\n

Then either close GDB or gef reload. You can confirm the structures were correctly loaded in GEF's prompt:

gef\u27a4 pcustom list\n

Should return several entries.

And remember this is collaborative repository, so feel free to contribute too!

"},{"location":"commands/pie/","title":"pie","text":""},{"location":"commands/pie/#command-pie","title":"Command pie","text":"

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.

"},{"location":"commands/pie/#pie-breakpoint-command","title":"pie breakpoint command","text":"

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:

gef\u27a4 pie breakpoint OFFSET\n
"},{"location":"commands/pie/#pie-info-command","title":"pie info command","text":"

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.

gef\u27a4  pie info\nVNum    Num     Addr\n1       N/A     0xdeadbeef\n

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.

Usage:

gef\u27a4  pie info [VNum]\n\n
"},{"location":"commands/pie/#pie-delete-command","title":"pie delete command","text":"

This command deletes a PIE breakpoint given its VNum.

Usage:

gef\u27a4  pie delete [VNum]\n
"},{"location":"commands/pie/#pie-attach-command","title":"pie attach command","text":"

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.

"},{"location":"commands/pie/#pie-remote-command","title":"pie remote command","text":"

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.

"},{"location":"commands/pie/#pie-run-command","title":"pie run command","text":"

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.

"},{"location":"commands/print-format/","title":"print-format","text":""},{"location":"commands/print-format/#command-print-format","title":"Command print-format","text":"

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)
gef\u27a4  print-format -h\n[+] print-format [--lang LANG] [--bitlen SIZE] [(--length,-l) LENGTH] [--clip] LOCATION\n    --lang LANG specifies the output format for programming language (available: ['py', 'c', 'js', 'asm', 'hex'], default 'py').\n    --bitlen SIZE specifies size of bit (possible values: [8, 16, 32, 64], default is 8).\n    --length LENGTH specifies length of array (default is 256).\n    --clip The output data will be copied to clipboard\n    LOCATION specifies where the address of bytes is stored.\n

For example this command will dump 10 bytes from $rsp and copy the result to the clipboard.

gef\u27a4  print-format --lang py --bitlen 8 -l 10 --clip $rsp\n[+] Copied to clipboard\nbuf = [0x87, 0xfa, 0xa3, 0xf7, 0xff, 0x7f, 0x0, 0x0, 0x30, 0xe6]\n

These commands copy the first 10 bytes of $rsp+8 to $rip:

gef\u27a4  print-format --lang bytearray -l 10 $rsp+8\nSaved data b'\\xcb\\xe3\\xff\\xff\\xff\\x7f\\x00\\x00\\x00\\x00'... in '$_gef0'\ngef\u27a4  display/x $_gef0[5]\n4: /x $_gef0[5] = 0x7f\ngef\u27a4  patch byte $rip $_gef0\n

Very handy to copy-paste-execute shellcodes/data from different memory regions.

"},{"location":"commands/process-search/","title":"process-search","text":""},{"location":"commands/process-search/#command-process-search","title":"Command process-search","text":"

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:

gef\u27a4  ps\n1               root            0.0             0.4             ?           /sbin/init\n2               root            0.0             0.0             ?           [kthreadd]\n3               root            0.0             0.0             ?           [ksoftirqd/0]\n4               root            0.0             0.0             ?           [kworker/0:0]\n5               root            0.0             0.0             ?           [kworker/0:0H]\n6               root            0.0             0.0             ?           [kworker/u2:0]\n7               root            0.0             0.0             ?           [rcu_sched]\n8               root            0.0             0.0             ?           [rcuos/0]\n9               root            0.0             0.0             ?           [rcu_bh]\n10              root            0.0             0.0             ?           [rcuob/0]\n11              root            0.0             0.0             ?           [migration/0]\n[...]\n

Or to filter with pattern:

gef\u27a4  ps bash\n22590           vagrant         0.0             0.8             pts/0       -bash\n

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

$ socat tcp-l:1234,fork,reuseaddr exec:/home/foobar/plop\n

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\u27a4  ps --attach --smart-scan plop\n
"},{"location":"commands/process-status/","title":"process-status","text":""},{"location":"commands/process-status/#command-process-status","title":"Command process-status","text":"

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.

gef\u27a4 ps --smart-scan zsh\n22879\ngef\u27a4 attach 22879\n[...]\ngef\u27a4 status\n[+] Process Information\n        PID  \u2192  22879\n        Executable  \u2192  /bin/zsh\n        Command line  \u2192  '-zsh'\n[+] Parent Process Information\n        Parent PID  \u2192  4475\n        Command line  \u2192  'tmux new -s cool vibe\n[+] Children Process Information\n        PID  \u2192  26190 (Name: '/bin/sleep', CmdLine: 'sleep 100000')\n[+] File Descriptors:\n        /proc/22879/fd/0  \u2192  /dev/pts/4\n        /proc/22879/fd/1  \u2192  /dev/pts/4\n        /proc/22879/fd/2  \u2192  /dev/pts/4\n        /proc/22879/fd/10  \u2192  /dev/pts/4\n[+] File Descriptors:\n        No TCP connections\n
"},{"location":"commands/registers/","title":"registers","text":""},{"location":"commands/registers/#command-registers","title":"Command registers","text":"

The registers command will print all the registers and dereference any pointers.

Example on a MIPS host:

gef\u27a4 reg\n$zero     : 0x00000000\n$at       : 0x00000001\n$v0       : 0x7fff6cd8 -> 0x77e5e7f8 -> <__libc_start_main+200>: bnez v0,0x77e5e8a8\n$v1       : 0x77ff4490\n$a0       : 0x00000001\n$a1       : 0x7fff6d94 -> 0x7fff6e85 -> \"/root/demo-mips\"\n$a2       : 0x7fff6d9c -> 0x7fff6e91 -> \"SHELL=/bin/bash\"\n$a3       : 0x00000000\n$t0       : 0x77fc26a0 -> 0x0\n$t1       : 0x77fc26a0 -> 0x0\n$t2       : 0x77fe5000 -> \"_dl_fini\"\n$t3       : 0x77fe5000 -> \"_dl_fini\"\n$t4       : 0xf0000000\n$t5       : 0x00000070\n$t6       : 0x00000020\n$t7       : 0x7fff6bc8 -> 0x0\n$s0       : 0x00000000\n$s1       : 0x00000000\n$s2       : 0x00000000\n$s3       : 0x00500000\n$s4       : 0x00522f48\n$s5       : 0x00522608\n$s6       : 0x00000000\n$s7       : 0x00000000\n$t8       : 0x0000000b\n$t9       : 0x004008b0 -> <main>: addiu sp,sp,-32\n$k0       : 0x00000000\n$k1       : 0x00000000\n$s8       : 0x00000000\n$status   : 0x0000a413\n$badvaddr : 0x77e7a874 -> <__cxa_atexit>: lui gp,0x15\n$cause    : 0x10800024\n$pc       : 0x004008c4 -> <main+20>: li v0,2\n$sp       : 0x7fff6ca0 -> 0x77e4a834 -> 0x29bd\n$hi       : 0x000001a5\n$lo       : 0x00005e17\n$fir      : 0x00739300\n$fcsr     : 0x00000000\n$ra       : 0x77e5e834 -> <__libc_start_main+260>: lw gp,16(sp)\n$gp       : 0x00418b20\n
"},{"location":"commands/registers/#filtering-registers","title":"Filtering registers","text":"

If one or more register names are passed to the registers command as optional arguments, then only those will be shown:

gef\u27a4 reg $rax $rip $rsp\n$rax   : 0x0000555555555169  \u2192  <main+0> endbr64\n$rsp   : 0x00007fffffffe3e8  \u2192  0x00007ffff7df40b3  \u2192  <__libc_start_main+243> mov edi, eax\n$rip   : 0x0000555555555169  \u2192  <main+0> endbr64\n
"},{"location":"commands/reset-cache/","title":"reset-cache","text":""},{"location":"commands/reset-cache/#command-reset-cache","title":"Command reset-cache","text":"

This command is only useful for debugging GEF itself.

"},{"location":"commands/scan/","title":"scan","text":""},{"location":"commands/scan/#command-scan","title":"Command scan","text":"

scan searches for addresses of one memory region (needle) inside another region (haystack) and lists all results.

Usage:

gef\u27a4  scan NEEDLE HAYSTACK\n

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) to determine the memory ranges to search.

gef\u27a4  scan stack libc\n[+] Searching for addresses in 'stack' that point to 'libc'\n[stack]: 0x00007fffffffd6a8\u2502+0x1f6a8: 0x00007ffff77cf482  \u2192  \"__tunable_get_val\"\n[stack]: 0x00007fffffffd6b0\u2502+0x1f6b0: 0x00007ffff77bff78  \u2192  0x0000001200001ab2\n[stack]: 0x00007fffffffd758\u2502+0x1f758: 0x00007ffff77cd9d0  \u2192  0x6c5f755f72647800\n[stack]: 0x00007fffffffd778\u2502+0x1f778: 0x00007ffff77bda6c  \u2192  0x0000090900000907\n[stack]: 0x00007fffffffd7d8\u2502+0x1f7d8: 0x00007ffff77cd9d0  \u2192  0x6c5f755f72647800\n[...]\n
"},{"location":"commands/scan/#advanced-needlehaystack-syntax","title":"Advanced Needle/Haystack syntax","text":"

To check mappings without a path associated, an address range (start-end) can be used. Note that ranges don't include whitespaces.

"},{"location":"commands/search-pattern/","title":"search-pattern","text":""},{"location":"commands/search-pattern/#command-search-pattern","title":"Command search-pattern","text":"

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\u27a4  search-pattern MyPattern\n

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:

gef\u27a4  search-pattern 0x4005f6\n

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.

"},{"location":"commands/search-pattern/#searching-in-a-specific-range","title":"Searching in a specific range","text":"

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\u27a4  search-pattern 0x4005f6 little libc\ngef\u27a4  search-pattern 0x4005f6 little 0x603100-0x603200\n
"},{"location":"commands/search-pattern/#searching-in-a-specific-range-using-regex","title":"Searching in a specific range using regex","text":"

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:

gef\u27a4  search-pattern --regex 0x401000 0x401500 ([\\\\x20-\\\\x7E]{2,})(?=\\\\x00)\n\n
"},{"location":"commands/shellcode/","title":"shellcode","text":""},{"location":"commands/shellcode/#command-shellcode","title":"Command shellcode","text":"

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\u27a4 shellcode search arm\n[+] Showing matching shellcodes\n901     Linux/ARM       Add map in /etc/hosts file - 79 bytes\n853     Linux/ARM       chmod(\"/etc/passwd\", 0777) - 39 bytes\n854     Linux/ARM       creat(\"/root/pwned\", 0777) - 39 bytes\n855     Linux/ARM       execve(\"/bin/sh\", [], [0 vars]) - 35 bytes\n729     Linux/ARM       Bind Connect UDP Port 68\n730     Linux/ARM       Bindshell port 0x1337\n[...]\ngef\u27a4 shellcode get 698\n[+] Downloading shellcode id=698\n[+] Shellcode written as '/tmp/sc-EfcWtM.txt'\ngef\u27a4 system cat /tmp/sc-EfcWtM.txt\n/*\nTitle:     Linux/ARM - execve(\"/bin/sh\", [0], [0 vars]) - 27 bytes\nDate:      2010-09-05\nTested on: ARM926EJ-S rev 5 (v5l)\nAuthor:    Jonathan Salwan - twitter: @jonathansalwan\n\nshell-storm.org\n\nShellcode ARM without 0x20, 0x0a and 0x00\n[...]\n
"},{"location":"commands/skipi/","title":"Skipi","text":""},{"location":"commands/skipi/#command-skipi","title":"Command skipi","text":"

The skipi command allows you to easily skip instructions execution.

skipi [LOCATION] [--n NUM_INSTRUCTIONS]\n

LOCATION address/symbol from where to skip (default is $pc)

--n NUM_INSTRUCTIONS Skip the specified number of instructions instead of the default 1.

gef\u27a4    skipi\ngef\u27a4    skipi --n 3\ngef\u27a4    skipi 0x69696969\ngef\u27a4    skipi 0x69696969 --n 6\n
"},{"location":"commands/stub/","title":"stub","text":""},{"location":"commands/stub/#command-stub","title":"Command stub","text":"

The stub command allows you stub out functions, optionally specifying the return value.

gef\u27a4  stub [-h] [--retval RETVAL] [address]\n

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.

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.

"},{"location":"commands/stub/#example","title":"Example","text":"

Patching fork() calls:

  • Without stub:

  • With stub:

"},{"location":"commands/theme/","title":"theme","text":""},{"location":"commands/theme/#command-theme","title":"Command theme","text":"

Customize GEF by changing its color scheme.

gef\u27a4  theme\ncontext_title_message                   : red bold\ndefault_title_message                   : red bold\ndefault_title_line                      : green bold\ncontext_title_line                      : green bold\ndisable_color                           : 0\nxinfo_title_message                     : blue bold\n
"},{"location":"commands/theme/#changing-colors","title":"Changing colors","text":"

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

Color also accepts the following attributes:

  • bold
  • underline
  • highlight
  • blink

Any other will value simply be ignored.

gef\u27a4  theme context_title_message blue bold foobar\ngef\u27a4  theme\ncontext_title_message                   : blue bold\ndefault_title_message                   : red bold\ndefault_title_line                      : green bold\ncontext_title_line                      : green bold\ndisable_color                           : 0\nxinfo_title_message                     : blue bold\n
"},{"location":"commands/tmux-setup/","title":"tmux-setup","text":""},{"location":"commands/tmux-setup/#command-tmux-setup","title":"Command tmux-setup","text":"

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:

To set it up, simply enter

gef\u27a4 tmux-setup\n

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.

"},{"location":"commands/tmux-setup/#possible-color-issues-with-tmux","title":"Possible color issues with tmux","text":"

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.

"},{"location":"commands/trace-run/","title":"trace-run","text":""},{"location":"commands/trace-run/#command-trace-run","title":"Command trace-run","text":"

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

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 <address_of_last_instruction_to_trace>\n

By using the script ida_color_gdb_trace.py on the text file generated, it will color the path taken:

"},{"location":"commands/version/","title":"version","text":""},{"location":"commands/version/#command-version","title":"Command version","text":"

Print out version information about your current gdb environment.

"},{"location":"commands/version/#usage-examples","title":"Usage Examples","text":"

When GEF is located in a directory tracked with git:

gef\u27a4  version\nGEF: rev:48a9fd74dd39db524fb395e7db528f85cc49d081 (Git - clean)\nSHA1(/gef/rules/gef.py): 848cdc87ba7c3e99e8129ad820c9fcc0973b1e99\nGDB: 9.2\nGDB-Python: 3.8\n

Otherwise the command shows the standalone information:

gef\u27a4  version\nGEF: (Standalone)\nBlob Hash(/gef/rules/gef.py): f0aef0f481e8157006b26690bd121585d3befee0\nSHA1(/gef/rules/gef.py): 4b26a1175abcd8314d4816f97fdf908b3837c779\nGDB: 9.2\nGDB-Python: 3.8\n

The Blob Hash can be used to easily find the git commit(s) matching this file revision.

git log --oneline --find-object <BLOB_HASH>\n

If this command does not return anything then the file was most likely modified and cannot be matched to a specific git commit.

"},{"location":"commands/vmmap/","title":"vmmap","text":""},{"location":"commands/vmmap/#command-vmmap","title":"Command vmmap","text":"

vmmap displays the target process's entire memory space mapping.

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.

"},{"location":"commands/xfiles/","title":"xfiles","text":""},{"location":"commands/xfiles/#command-xfiles","title":"Command xfiles","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):

"},{"location":"commands/xinfo/","title":"xinfo","text":""},{"location":"commands/xinfo/#command-xinfo","title":"Command xinfo","text":"

xinfo displays all the information known to gef about the specific address given as argument:

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.

"},{"location":"commands/xor-memory/","title":"xor-memory","text":""},{"location":"commands/xor-memory/#command-xor-memory","title":"Command xor-memory","text":"

This command is used to XOR a block of memory.

Its syntax is:

xor-memory <display|patch> <address> <size_to_read> <xor_key>\n

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.

    gef\u27a4  xor display $rsp 16 1337\n[+] Displaying XOR-ing 0x7fff589b67f8-0x7fff589b6808 with '1337'\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500[ Original block ]\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n0x00007fff589b67f8     46 4e 40 00 00 00 00 00 00 00 00 00 00 00 00 00     FN@.............\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500[ XOR-ed block ]\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n0x00007fff589b67f8     55 79 53 37 13 37 13 37 13 37 13 37 13 37 13 37     UyS7.7.7.7.7.7.7\n
  2. patch will overwrite the memory with the xor-ed content.

    gef\u27a4  xor patch $rsp 16 1337\n[+] Patching XOR-ing 0x7fff589b67f8-0x7fff589b6808 with '1337'\ngef\u27a4  hexdump byte $rsp 16\n0x00007fff589b67f8     55 79 53 37 13 37 13 37 13 37     UyS7.7.7.7\n
"},{"location":"functions/base/","title":"Function $_base()","text":"

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

$_base([filepath])\n

Example:

gef\u27a4 p $_base(\\\"/usr/lib/ld-2.33.so\\\")\n
"},{"location":"functions/bss/","title":"Function $_bss()","text":"

Return the current BSS base address plus the given offset.

Note: a debugging session must be active

$_bss([offset])\n

Example:

gef\u27a4 p $_bss(0x20)\n
"},{"location":"functions/got/","title":"Function $_got()","text":"

Return the current GOT base address plus the given offset.

Note: a debugging session must be active

$_got([offset])\n

Example:

gef\u27a4 p $_got(0x20)\n
"},{"location":"functions/heap/","title":"Function $_heap()","text":"

Return the current heap base address plus the given offset.

Note: a debugging session must be active

$_heap([offset])\n

Example:

gef\u27a4 p $_heap(0x20)\n
"},{"location":"functions/stack/","title":"Function $_stack()","text":"

Return the current stack base address plus the given offset.

Note: a debugging session must be active

$_stack([offset])\n

Example:

gef\u27a4 p $_stack(0x20)\n
"},{"location":"obsolete/docs/","title":"Index","text":""},{"location":"obsolete/docs/#the-latest-version-of-the-documentation-is-hosted-on-hugsygithubiogef","title":"The latest version of the documentation is hosted on hugsy.github.io/gef","text":""},{"location":"settings/context/","title":"Settings for command context","text":""},{"location":"settings/context/#enable","title":"enable","text":"

Name context.enable

Type bool

DefaultValue: True

Description Enable/disable printing the context when breaking

"},{"location":"settings/context/#show_source_code_variable_values","title":"show_source_code_variable_values","text":"

Name context.show_source_code_variable_values

Type bool

DefaultValue: True

Description Show extra PC context info in the source code

"},{"location":"settings/context/#show_stack_raw","title":"show_stack_raw","text":"

Name context.show_stack_raw

Type bool

DefaultValue: False

Description Show the stack pane as raw hexdump (no dereference)

"},{"location":"settings/context/#show_registers_raw","title":"show_registers_raw","text":"

Name context.show_registers_raw

Type bool

DefaultValue: False

Description Show the registers pane with raw values (no dereference)

"},{"location":"settings/context/#show_opcodes_size","title":"show_opcodes_size","text":"

Name context.show_opcodes_size

Type int

DefaultValue: 0

Description Number of bytes of opcodes to display next to the disassembly

"},{"location":"settings/context/#peek_calls","title":"peek_calls","text":"

Name context.peek_calls

Type bool

DefaultValue: True

Description Peek into calls

"},{"location":"settings/context/#peek_ret","title":"peek_ret","text":"

Name context.peek_ret

Type bool

DefaultValue: True

Description Peek at return address

"},{"location":"settings/context/#nb_lines_stack","title":"nb_lines_stack","text":"

Name context.nb_lines_stack

Type int

DefaultValue: 8

Description Number of line in the stack pane

"},{"location":"settings/context/#grow_stack_down","title":"grow_stack_down","text":"

Name context.grow_stack_down

Type bool

DefaultValue: False

Description Order of stack downward starts at largest down to stack pointer

"},{"location":"settings/context/#nb_lines_backtrace","title":"nb_lines_backtrace","text":"

Name context.nb_lines_backtrace

Type int

DefaultValue: 10

Description Number of line in the backtrace pane

"},{"location":"settings/context/#nb_lines_backtrace_before","title":"nb_lines_backtrace_before","text":"

Name context.nb_lines_backtrace_before

Type int

DefaultValue: 2

Description Number of line in the backtrace pane before selected frame

"},{"location":"settings/context/#nb_lines_threads","title":"nb_lines_threads","text":"

Name context.nb_lines_threads

Type int

DefaultValue: -1

Description Number of line in the threads pane

"},{"location":"settings/context/#nb_lines_code","title":"nb_lines_code","text":"

Name context.nb_lines_code

Type int

DefaultValue: 6

Description Number of instruction after $pc

"},{"location":"settings/context/#nb_lines_code_prev","title":"nb_lines_code_prev","text":"

Name context.nb_lines_code_prev

Type int

DefaultValue: 3

Description Number of instruction before $pc

"},{"location":"settings/context/#ignore_registers","title":"ignore_registers","text":"

Name context.ignore_registers

Type str

DefaultValue: ``

Description Space-separated list of registers not to display (e.g. '$cs $ds $gs')

"},{"location":"settings/context/#clear_screen","title":"clear_screen","text":"

Name context.clear_screen

Type bool

DefaultValue: True

Description Clear the screen before printing the context

"},{"location":"settings/context/#layout","title":"layout","text":"

Name context.layout

Type str

DefaultValue: legend regs stack code args source memory threads trace extra

Description Change the order/presence of the context sections

"},{"location":"settings/context/#redirect","title":"redirect","text":"

Name context.redirect

Type str

DefaultValue: ``

Description Redirect the context information to another TTY

"},{"location":"settings/context/#libc_args","title":"libc_args","text":"

Name context.libc_args

Type bool

DefaultValue: False

Description [DEPRECATED - Unused] Show libc function call args description

"},{"location":"settings/context/#libc_args_path","title":"libc_args_path","text":"

Name context.libc_args_path

Type str

DefaultValue: ``

Description [DEPRECATED - Unused] Path to libc function call args json files, provided via gef-extras

"},{"location":"settings/dereference/","title":"Settings for command dereference","text":""},{"location":"settings/dereference/#max_recursion","title":"max_recursion","text":"

Name dereference.max_recursion

Type int

DefaultValue: 7

Description Maximum level of pointer recursion

"},{"location":"settings/entry-break/","title":"Settings for command entry-break","text":""},{"location":"settings/entry-break/#entrypoint_symbols","title":"entrypoint_symbols","text":"

Name entry-break.entrypoint_symbols

Type str

DefaultValue: main _main __libc_start_main __uClibc_main start _start

Description Possible symbols for entry points

"},{"location":"settings/gef/","title":"Settings for command gef","text":""},{"location":"settings/gef/#follow_child","title":"follow_child","text":"

Name gef.follow_child

Type bool

DefaultValue: True

Description Automatically set GDB to follow child when forking

"},{"location":"settings/gef/#readline_compat","title":"readline_compat","text":"

Name gef.readline_compat

Type bool

DefaultValue: False

Description Workaround for readline SOH/ETX issue (SEGV)

"},{"location":"settings/gef/#debug","title":"debug","text":"

Name gef.debug

Type bool

DefaultValue: False

Description Enable debug mode for gef

"},{"location":"settings/gef/#autosave_breakpoints_file","title":"autosave_breakpoints_file","text":"

Name gef.autosave_breakpoints_file

Type str

DefaultValue: ``

Description Automatically save and restore breakpoints

"},{"location":"settings/gef/#extra_plugins_dir","title":"extra_plugins_dir","text":"

Name gef.extra_plugins_dir

Type str

DefaultValue: ``

Description Autoload additional GEF commands from external directory

"},{"location":"settings/gef/#disable_color","title":"disable_color","text":"

Name gef.disable_color

Type bool

DefaultValue: True

Description Disable all colors in GEF

"},{"location":"settings/gef/#tempdir","title":"tempdir","text":"

Name gef.tempdir

Type str

DefaultValue: /tmp/gef

Description Directory to use for temporary/cache content

"},{"location":"settings/gef/#show_deprecation_warnings","title":"show_deprecation_warnings","text":"

Name gef.show_deprecation_warnings

Type bool

DefaultValue: True

Description Toggle the display of the deprecated warnings

"},{"location":"settings/gef/#buffer","title":"buffer","text":"

Name gef.buffer

Type bool

DefaultValue: True

Description Internally buffer command output until completion

"},{"location":"settings/gef/#bruteforce_main_arena","title":"bruteforce_main_arena","text":"

Name gef.bruteforce_main_arena

Type bool

DefaultValue: False

Description Allow bruteforcing main_arena symbol if everything else fails

"},{"location":"settings/gef/#main_arena_offset","title":"main_arena_offset","text":"

Name gef.main_arena_offset

Type str

DefaultValue: ``

Description Offset from libc base address to main_arena symbol (int or hex). Set to empty string to disable.

"},{"location":"settings/got/","title":"Settings for command got","text":""},{"location":"settings/got/#function_resolved","title":"function_resolved","text":"

Name got.function_resolved

Type str

DefaultValue: green

Description Line color of the got command output for resolved function

"},{"location":"settings/got/#function_not_resolved","title":"function_not_resolved","text":"

Name got.function_not_resolved

Type str

DefaultValue: yellow

Description Line color of the got command output for unresolved function

"},{"location":"settings/heap-analysis-helper/","title":"Settings for command heap-analysis-helper","text":""},{"location":"settings/heap-analysis-helper/#check_free_null","title":"check_free_null","text":"

Name heap-analysis-helper.check_free_null

Type bool

DefaultValue: False

Description Break execution when a free(NULL) is encountered

"},{"location":"settings/heap-analysis-helper/#check_double_free","title":"check_double_free","text":"

Name heap-analysis-helper.check_double_free

Type bool

DefaultValue: True

Description Break execution when a double free is encountered

"},{"location":"settings/heap-analysis-helper/#check_weird_free","title":"check_weird_free","text":"

Name heap-analysis-helper.check_weird_free

Type bool

DefaultValue: True

Description Break execution when free() is called against a non-tracked pointer

"},{"location":"settings/heap-analysis-helper/#check_uaf","title":"check_uaf","text":"

Name heap-analysis-helper.check_uaf

Type bool

DefaultValue: True

Description Break execution when a possible Use-after-Free condition is found

"},{"location":"settings/heap-analysis-helper/#check_heap_overlap","title":"check_heap_overlap","text":"

Name heap-analysis-helper.check_heap_overlap

Type bool

DefaultValue: True

Description Break execution when a possible overlap in allocation is found

"},{"location":"settings/heap-chunks/","title":"Settings for command heap-chunks","text":""},{"location":"settings/heap-chunks/#peek_nb_byte","title":"peek_nb_byte","text":"

Name heap-chunks.peek_nb_byte

Type int

DefaultValue: 16

Description Hexdump N first byte(s) inside the chunk data (0 to disable)

"},{"location":"settings/hexdump/","title":"Settings for command hexdump","text":""},{"location":"settings/hexdump/#always_show_ascii","title":"always_show_ascii","text":"

Name hexdump.always_show_ascii

Type bool

DefaultValue: False

Description If true, hexdump will always display the ASCII dump

"},{"location":"settings/highlight/","title":"Settings for command highlight","text":""},{"location":"settings/highlight/#regex","title":"regex","text":"

Name highlight.regex

Type bool

DefaultValue: False

Description Enable regex highlighting

"},{"location":"settings/pattern/","title":"Settings for command pattern","text":""},{"location":"settings/pattern/#length","title":"length","text":"

Name pattern.length

Type int

DefaultValue: 1024

Description Default length of a cyclic buffer to generate

"},{"location":"settings/pcustom/","title":"Settings for command pcustom","text":""},{"location":"settings/pcustom/#struct_path","title":"struct_path","text":"

Name pcustom.struct_path

Type str

DefaultValue: /tmp/gef/structs

Description Path to store/load the structure ctypes files

"},{"location":"settings/pcustom/#max_depth","title":"max_depth","text":"

Name pcustom.max_depth

Type int

DefaultValue: 4

Description Maximum level of recursion supported

"},{"location":"settings/pcustom/#structure_name","title":"structure_name","text":"

Name pcustom.structure_name

Type str

DefaultValue: bold blue

Description Color of the structure name

"},{"location":"settings/pcustom/#structure_type","title":"structure_type","text":"

Name pcustom.structure_type

Type str

DefaultValue: bold red

Description Color of the attribute type

"},{"location":"settings/pcustom/#structure_size","title":"structure_size","text":"

Name pcustom.structure_size

Type str

DefaultValue: green

Description Color of the attribute size

"},{"location":"settings/print-format/","title":"Settings for command print-format","text":""},{"location":"settings/print-format/#max_size_preview","title":"max_size_preview","text":"

Name print-format.max_size_preview

Type int

DefaultValue: 10

Description max size preview of bytes

"},{"location":"settings/process-search/","title":"Settings for command process-search","text":""},{"location":"settings/process-search/#ps_command","title":"ps_command","text":"

Name process-search.ps_command

Type str

DefaultValue: /usr/bin/ps auxww

Description ps command to get process information

"},{"location":"settings/search-pattern/","title":"Settings for command search-pattern","text":""},{"location":"settings/search-pattern/#max_size_preview","title":"max_size_preview","text":"

Name search-pattern.max_size_preview

Type int

DefaultValue: 10

Description max size preview of bytes

"},{"location":"settings/search-pattern/#nr_pages_chunk","title":"nr_pages_chunk","text":"

Name search-pattern.nr_pages_chunk

Type int

DefaultValue: 1024

Description number of pages readed for each memory read chunk

"},{"location":"settings/theme/","title":"Settings for command theme","text":""},{"location":"settings/theme/#context_title_line","title":"context_title_line","text":"

Name theme.context_title_line

Type str

DefaultValue: gray

Description Color of the borders in context window

"},{"location":"settings/theme/#context_title_message","title":"context_title_message","text":"

Name theme.context_title_message

Type str

DefaultValue: cyan

Description Color of the title in context window

"},{"location":"settings/theme/#default_title_line","title":"default_title_line","text":"

Name theme.default_title_line

Type str

DefaultValue: gray

Description Default color of borders

"},{"location":"settings/theme/#default_title_message","title":"default_title_message","text":"

Name theme.default_title_message

Type str

DefaultValue: cyan

Description Default color of title

"},{"location":"settings/theme/#table_heading","title":"table_heading","text":"

Name theme.table_heading

Type str

DefaultValue: blue

Description Color of the column headings to tables (e.g. vmmap)

"},{"location":"settings/theme/#old_context","title":"old_context","text":"

Name theme.old_context

Type str

DefaultValue: gray

Description Color to use to show things such as code that is not immediately relevant

"},{"location":"settings/theme/#disassemble_current_instruction","title":"disassemble_current_instruction","text":"

Name theme.disassemble_current_instruction

Type str

DefaultValue: green

Description Color to use to highlight the current $pc when disassembling

"},{"location":"settings/theme/#dereference_string","title":"dereference_string","text":"

Name theme.dereference_string

Type str

DefaultValue: yellow

Description Color of dereferenced string

"},{"location":"settings/theme/#dereference_code","title":"dereference_code","text":"

Name theme.dereference_code

Type str

DefaultValue: gray

Description Color of dereferenced code

"},{"location":"settings/theme/#dereference_base_address","title":"dereference_base_address","text":"

Name theme.dereference_base_address

Type str

DefaultValue: cyan

Description Color of dereferenced address

"},{"location":"settings/theme/#dereference_register_value","title":"dereference_register_value","text":"

Name theme.dereference_register_value

Type str

DefaultValue: bold blue

Description Color of dereferenced register

"},{"location":"settings/theme/#registers_register_name","title":"registers_register_name","text":"

Name theme.registers_register_name

Type str

DefaultValue: blue

Description Color of the register name in the register window

"},{"location":"settings/theme/#registers_value_changed","title":"registers_value_changed","text":"

Name theme.registers_value_changed

Type str

DefaultValue: bold red

Description Color of the changed register in the register window

"},{"location":"settings/theme/#address_stack","title":"address_stack","text":"

Name theme.address_stack

Type str

DefaultValue: pink

Description Color to use when a stack address is found

"},{"location":"settings/theme/#address_heap","title":"address_heap","text":"

Name theme.address_heap

Type str

DefaultValue: green

Description Color to use when a heap address is found

"},{"location":"settings/theme/#address_code","title":"address_code","text":"

Name theme.address_code

Type str

DefaultValue: red

Description Color to use when a code address is found

"},{"location":"settings/theme/#source_current_line","title":"source_current_line","text":"

Name theme.source_current_line

Type str

DefaultValue: green

Description Color to use for the current code line in the source window

"},{"location":"settings/trace-run/","title":"Settings for command trace-run","text":""},{"location":"settings/trace-run/#max_tracing_recursion","title":"max_tracing_recursion","text":"

Name trace-run.max_tracing_recursion

Type int

DefaultValue: 1

Description Maximum depth of tracing

"},{"location":"settings/trace-run/#tracefile_prefix","title":"tracefile_prefix","text":"

Name trace-run.tracefile_prefix

Type str

DefaultValue: ./gef-trace-

Description Specify the tracing output file prefix

"}]} \ No newline at end of file diff --git a/settings/context/index.html b/settings/context/index.html new file mode 100644 index 000000000..b56bceb05 --- /dev/null +++ b/settings/context/index.html @@ -0,0 +1,2130 @@ + + + + + + + + + + + + + + + + + + + + + + context - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + + +
+
+ + + + +

Settings for command context

+

enable

+

Name context.enable

+

Type bool

+

DefaultValue: True

+

Description Enable/disable printing the context when breaking

+

show_source_code_variable_values

+

Name context.show_source_code_variable_values

+

Type bool

+

DefaultValue: True

+

Description Show extra PC context info in the source code

+

show_stack_raw

+

Name context.show_stack_raw

+

Type bool

+

DefaultValue: False

+

Description Show the stack pane as raw hexdump (no dereference)

+

show_registers_raw

+

Name context.show_registers_raw

+

Type bool

+

DefaultValue: False

+

Description Show the registers pane with raw values (no dereference)

+

show_opcodes_size

+

Name context.show_opcodes_size

+

Type int

+

DefaultValue: 0

+

Description Number of bytes of opcodes to display next to the disassembly

+

peek_calls

+

Name context.peek_calls

+

Type bool

+

DefaultValue: True

+

Description Peek into calls

+

peek_ret

+

Name context.peek_ret

+

Type bool

+

DefaultValue: True

+

Description Peek at return address

+

nb_lines_stack

+

Name context.nb_lines_stack

+

Type int

+

DefaultValue: 8

+

Description Number of line in the stack pane

+

grow_stack_down

+

Name context.grow_stack_down

+

Type bool

+

DefaultValue: False

+

Description Order of stack downward starts at largest down to stack pointer

+

nb_lines_backtrace

+

Name context.nb_lines_backtrace

+

Type int

+

DefaultValue: 10

+

Description Number of line in the backtrace pane

+

nb_lines_backtrace_before

+

Name context.nb_lines_backtrace_before

+

Type int

+

DefaultValue: 2

+

Description Number of line in the backtrace pane before selected frame

+

nb_lines_threads

+

Name context.nb_lines_threads

+

Type int

+

DefaultValue: -1

+

Description Number of line in the threads pane

+

nb_lines_code

+

Name context.nb_lines_code

+

Type int

+

DefaultValue: 6

+

Description Number of instruction after $pc

+

nb_lines_code_prev

+

Name context.nb_lines_code_prev

+

Type int

+

DefaultValue: 3

+

Description Number of instruction before $pc

+

ignore_registers

+

Name context.ignore_registers

+

Type str

+

DefaultValue: ``

+

Description Space-separated list of registers not to display (e.g. '$cs $ds $gs')

+

clear_screen

+

Name context.clear_screen

+

Type bool

+

DefaultValue: True

+

Description Clear the screen before printing the context

+

layout

+

Name context.layout

+

Type str

+

DefaultValue: legend regs stack code args source memory threads trace extra

+

Description Change the order/presence of the context sections

+

redirect

+

Name context.redirect

+

Type str

+

DefaultValue: ``

+

Description Redirect the context information to another TTY

+

libc_args

+

Name context.libc_args

+

Type bool

+

DefaultValue: False

+

Description [DEPRECATED - Unused] Show libc function call args description

+

libc_args_path

+

Name context.libc_args_path

+

Type str

+

DefaultValue: ``

+

Description [DEPRECATED - Unused] Path to libc function call args json files, provided via gef-extras

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/dereference/index.html b/settings/dereference/index.html new file mode 100644 index 000000000..9a481900f --- /dev/null +++ b/settings/dereference/index.html @@ -0,0 +1,1769 @@ + + + + + + + + + + + + + + + + + + + + + + dereference - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command dereference

+

max_recursion

+

Name dereference.max_recursion

+

Type int

+

DefaultValue: 7

+

Description Maximum level of pointer recursion

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/entry-break/index.html b/settings/entry-break/index.html new file mode 100644 index 000000000..eb100ad96 --- /dev/null +++ b/settings/entry-break/index.html @@ -0,0 +1,1769 @@ + + + + + + + + + + + + + + + + + + + + + + entry-break - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command entry-break

+

entrypoint_symbols

+

Name entry-break.entrypoint_symbols

+

Type str

+

DefaultValue: main _main __libc_start_main __uClibc_main start _start

+

Description Possible symbols for entry points

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/gef/index.html b/settings/gef/index.html new file mode 100644 index 000000000..cb554314c --- /dev/null +++ b/settings/gef/index.html @@ -0,0 +1,1959 @@ + + + + + + + + + + + + + + + + + + + + + + gef - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command gef

+

follow_child

+

Name gef.follow_child

+

Type bool

+

DefaultValue: True

+

Description Automatically set GDB to follow child when forking

+

readline_compat

+

Name gef.readline_compat

+

Type bool

+

DefaultValue: False

+

Description Workaround for readline SOH/ETX issue (SEGV)

+

debug

+

Name gef.debug

+

Type bool

+

DefaultValue: False

+

Description Enable debug mode for gef

+

autosave_breakpoints_file

+

Name gef.autosave_breakpoints_file

+

Type str

+

DefaultValue: ``

+

Description Automatically save and restore breakpoints

+

extra_plugins_dir

+

Name gef.extra_plugins_dir

+

Type str

+

DefaultValue: ``

+

Description Autoload additional GEF commands from external directory

+

disable_color

+

Name gef.disable_color

+

Type bool

+

DefaultValue: True

+

Description Disable all colors in GEF

+

tempdir

+

Name gef.tempdir

+

Type str

+

DefaultValue: /tmp/gef

+

Description Directory to use for temporary/cache content

+

show_deprecation_warnings

+

Name gef.show_deprecation_warnings

+

Type bool

+

DefaultValue: True

+

Description Toggle the display of the deprecated warnings

+

buffer

+

Name gef.buffer

+

Type bool

+

DefaultValue: True

+

Description Internally buffer command output until completion

+

bruteforce_main_arena

+

Name gef.bruteforce_main_arena

+

Type bool

+

DefaultValue: False

+

Description Allow bruteforcing main_arena symbol if everything else fails

+

main_arena_offset

+

Name gef.main_arena_offset

+

Type str

+

DefaultValue: ``

+

Description Offset from libc base address to main_arena symbol (int or hex). Set to empty string to disable.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/got/index.html b/settings/got/index.html new file mode 100644 index 000000000..c68d4ac7f --- /dev/null +++ b/settings/got/index.html @@ -0,0 +1,1788 @@ + + + + + + + + + + + + + + + + + + + + + + got - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command got

+

function_resolved

+

Name got.function_resolved

+

Type str

+

DefaultValue: green

+

Description Line color of the got command output for resolved function

+

function_not_resolved

+

Name got.function_not_resolved

+

Type str

+

DefaultValue: yellow

+

Description Line color of the got command output for unresolved function

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/heap-analysis-helper/index.html b/settings/heap-analysis-helper/index.html new file mode 100644 index 000000000..da50f3177 --- /dev/null +++ b/settings/heap-analysis-helper/index.html @@ -0,0 +1,1845 @@ + + + + + + + + + + + + + + + + + + + + + + heap-analysis-helper - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command heap-analysis-helper

+

check_free_null

+

Name heap-analysis-helper.check_free_null

+

Type bool

+

DefaultValue: False

+

Description Break execution when a free(NULL) is encountered

+

check_double_free

+

Name heap-analysis-helper.check_double_free

+

Type bool

+

DefaultValue: True

+

Description Break execution when a double free is encountered

+

check_weird_free

+

Name heap-analysis-helper.check_weird_free

+

Type bool

+

DefaultValue: True

+

Description Break execution when free() is called against a non-tracked pointer

+

check_uaf

+

Name heap-analysis-helper.check_uaf

+

Type bool

+

DefaultValue: True

+

Description Break execution when a possible Use-after-Free condition is found

+

check_heap_overlap

+

Name heap-analysis-helper.check_heap_overlap

+

Type bool

+

DefaultValue: True

+

Description Break execution when a possible overlap in allocation is found

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/heap-chunks/index.html b/settings/heap-chunks/index.html new file mode 100644 index 000000000..16ca362a3 --- /dev/null +++ b/settings/heap-chunks/index.html @@ -0,0 +1,1769 @@ + + + + + + + + + + + + + + + + + + + + + + heap-chunks - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command heap-chunks

+

peek_nb_byte

+

Name heap-chunks.peek_nb_byte

+

Type int

+

DefaultValue: 16

+

Description Hexdump N first byte(s) inside the chunk data (0 to disable)

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/hexdump/index.html b/settings/hexdump/index.html new file mode 100644 index 000000000..b41d86d9a --- /dev/null +++ b/settings/hexdump/index.html @@ -0,0 +1,1769 @@ + + + + + + + + + + + + + + + + + + + + + + hexdump - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command hexdump

+

always_show_ascii

+

Name hexdump.always_show_ascii

+

Type bool

+

DefaultValue: False

+

Description If true, hexdump will always display the ASCII dump

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/highlight/index.html b/settings/highlight/index.html new file mode 100644 index 000000000..6451a80b3 --- /dev/null +++ b/settings/highlight/index.html @@ -0,0 +1,1769 @@ + + + + + + + + + + + + + + + + + + + + + + highlight - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command highlight

+

regex

+

Name highlight.regex

+

Type bool

+

DefaultValue: False

+

Description Enable regex highlighting

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/pattern/index.html b/settings/pattern/index.html new file mode 100644 index 000000000..27cfdeeb0 --- /dev/null +++ b/settings/pattern/index.html @@ -0,0 +1,1769 @@ + + + + + + + + + + + + + + + + + + + + + + pattern - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command pattern

+

length

+

Name pattern.length

+

Type int

+

DefaultValue: 1024

+

Description Default length of a cyclic buffer to generate

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/pcustom/index.html b/settings/pcustom/index.html new file mode 100644 index 000000000..966ed9ce6 --- /dev/null +++ b/settings/pcustom/index.html @@ -0,0 +1,1845 @@ + + + + + + + + + + + + + + + + + + + + + + pcustom - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command pcustom

+

struct_path

+

Name pcustom.struct_path

+

Type str

+

DefaultValue: /tmp/gef/structs

+

Description Path to store/load the structure ctypes files

+

max_depth

+

Name pcustom.max_depth

+

Type int

+

DefaultValue: 4

+

Description Maximum level of recursion supported

+

structure_name

+

Name pcustom.structure_name

+

Type str

+

DefaultValue: bold blue

+

Description Color of the structure name

+

structure_type

+

Name pcustom.structure_type

+

Type str

+

DefaultValue: bold red

+

Description Color of the attribute type

+

structure_size

+

Name pcustom.structure_size

+

Type str

+

DefaultValue: green

+

Description Color of the attribute size

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/print-format/index.html b/settings/print-format/index.html new file mode 100644 index 000000000..295f7e531 --- /dev/null +++ b/settings/print-format/index.html @@ -0,0 +1,1769 @@ + + + + + + + + + + + + + + + + + + + + + + print-format - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command print-format

+

max_size_preview

+

Name print-format.max_size_preview

+

Type int

+

DefaultValue: 10

+

Description max size preview of bytes

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/process-search/index.html b/settings/process-search/index.html new file mode 100644 index 000000000..af913b4e7 --- /dev/null +++ b/settings/process-search/index.html @@ -0,0 +1,1769 @@ + + + + + + + + + + + + + + + + + + + + + + process-search - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command process-search

+

ps_command

+

Name process-search.ps_command

+

Type str

+

DefaultValue: /usr/bin/ps auxww

+

Description ps command to get process information

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/search-pattern/index.html b/settings/search-pattern/index.html new file mode 100644 index 000000000..93dea9c4c --- /dev/null +++ b/settings/search-pattern/index.html @@ -0,0 +1,1788 @@ + + + + + + + + + + + + + + + + + + + + + + search-pattern - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command search-pattern

+

max_size_preview

+

Name search-pattern.max_size_preview

+

Type int

+

DefaultValue: 10

+

Description max size preview of bytes

+

nr_pages_chunk

+

Name search-pattern.nr_pages_chunk

+

Type int

+

DefaultValue: 1024

+

Description number of pages readed for each memory read chunk

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/theme/index.html b/settings/theme/index.html new file mode 100644 index 000000000..9249f680d --- /dev/null +++ b/settings/theme/index.html @@ -0,0 +1,2073 @@ + + + + + + + + + + + + + + + + + + + + + + theme - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + + + + + +
+
+ + + + +

Settings for command theme

+

context_title_line

+

Name theme.context_title_line

+

Type str

+

DefaultValue: gray

+

Description Color of the borders in context window

+

context_title_message

+

Name theme.context_title_message

+

Type str

+

DefaultValue: cyan

+

Description Color of the title in context window

+

default_title_line

+

Name theme.default_title_line

+

Type str

+

DefaultValue: gray

+

Description Default color of borders

+

default_title_message

+

Name theme.default_title_message

+

Type str

+

DefaultValue: cyan

+

Description Default color of title

+

table_heading

+

Name theme.table_heading

+

Type str

+

DefaultValue: blue

+

Description Color of the column headings to tables (e.g. vmmap)

+

old_context

+

Name theme.old_context

+

Type str

+

DefaultValue: gray

+

Description Color to use to show things such as code that is not immediately relevant

+

disassemble_current_instruction

+

Name theme.disassemble_current_instruction

+

Type str

+

DefaultValue: green

+

Description Color to use to highlight the current $pc when disassembling

+

dereference_string

+

Name theme.dereference_string

+

Type str

+

DefaultValue: yellow

+

Description Color of dereferenced string

+

dereference_code

+

Name theme.dereference_code

+

Type str

+

DefaultValue: gray

+

Description Color of dereferenced code

+

dereference_base_address

+

Name theme.dereference_base_address

+

Type str

+

DefaultValue: cyan

+

Description Color of dereferenced address

+

dereference_register_value

+

Name theme.dereference_register_value

+

Type str

+

DefaultValue: bold blue

+

Description Color of dereferenced register

+

registers_register_name

+

Name theme.registers_register_name

+

Type str

+

DefaultValue: blue

+

Description Color of the register name in the register window

+

registers_value_changed

+

Name theme.registers_value_changed

+

Type str

+

DefaultValue: bold red

+

Description Color of the changed register in the register window

+

address_stack

+

Name theme.address_stack

+

Type str

+

DefaultValue: pink

+

Description Color to use when a stack address is found

+

address_heap

+

Name theme.address_heap

+

Type str

+

DefaultValue: green

+

Description Color to use when a heap address is found

+

address_code

+

Name theme.address_code

+

Type str

+

DefaultValue: red

+

Description Color to use when a code address is found

+

source_current_line

+

Name theme.source_current_line

+

Type str

+

DefaultValue: green

+

Description Color to use for the current code line in the source window

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/settings/trace-run/index.html b/settings/trace-run/index.html new file mode 100644 index 000000000..7aa242286 --- /dev/null +++ b/settings/trace-run/index.html @@ -0,0 +1,1786 @@ + + + + + + + + + + + + + + + + + + + + trace-run - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Settings for command trace-run

+

max_tracing_recursion

+

Name trace-run.max_tracing_recursion

+

Type int

+

DefaultValue: 1

+

Description Maximum depth of tracing

+

tracefile_prefix

+

Name trace-run.tracefile_prefix

+

Type str

+

DefaultValue: ./gef-trace-

+

Description Specify the tracing output file prefix

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 000000000..0f8724efd --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..f357a3d6cda9e6574b43a7ebdb3c25239e9a1054 GIT binary patch literal 127 zcmV-_0D%7=iwFofc*tY||8r?{Wo=<_E_iKh04<9_3V)_WXo8&M?ytk3HC}0~zlG)Vu + + + + + + + + + + + + + + + + + + + + Testing - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Testing

+ +

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.

+

Prerequisites

+

All the prerequisite packages are in requirements.txt file at the root of the project. So running

+
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

+
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:

+
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:

+
=================================== short test summary info ==================================
+FAILED tests/commands/heap.py::HeapCommand::test_cmd_heap_bins_large - AssertionError: 'siz...
+FAILED tests/commands/heap.py::HeapCommand::test_cmd_heap_bins_small - AssertionError: 'siz...
+FAILED tests/commands/heap.py::HeapCommand::test_cmd_heap_bins_unsorted - AssertionError: '...
+======================== 3 failed, 4 passed, 113 deselected in 385.77s (0:06:25)==============
+
+

You can then use pytest directly to help you fix each error specifically.

+

Using pytest

+

GEF entirely relies on pytest 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

+

A skeleton of a test module would look something like:

+
"""
+`my-command` command test module
+"""
+
+
+from tests.utils import GefUnitTestGeneric, gdb_run_cmd, gdb_start_silent_cmd
+
+
+class MyCommandCommand(GefUnitTestGeneric):
+    """`my-command` command test module"""
+
+    def test_cmd_my_command(self):
+        # `my-command` is expected to fail if the session is not active
+        self.assertFailIfInactiveSession(gdb_run_cmd("my-command"))
+
+        # `my-command` should never throw an exception in GDB when running
+        res = gdb_start_silent_cmd("my-command")
+        self.assertNoException(res)
+
+        # it also must print out a "Hello World" message
+        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.

+

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:

+
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:

+
gdb -q -nx -ex "pi print('.'.join(map(str, sys.version_info[:2])))" -ex quit
+
+

Benchmarking GEF

+

Benchmarking relies on pytest-benchmark and is experimental for now.

+

You can run all benchmark test cases as such:

+
cd /root/of/gef
+pytest -k benchmark
+
+

which will return (after some time) an execution summary

+
tests/perf/benchmark.py ..                                                               [100%]
+
+
+---------------------------------------- benchmark: 3 tests -----------------------------------
+Name (time in ms)          Min                 Max                Mean            StdDev              Median                IQR            Outliers     OPS            Rounds  Iterations
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+time_baseline         612.2325 (1.0)      630.3416 (1.01)     623.7984 (1.01)     7.2848 (1.64)     626.1485 (1.01)      9.9971 (1.81)          1;0  1.6031 (0.99)          5           1
+time_cmd_context      613.8124 (1.00)     625.8964 (1.0)      620.1908 (1.0)      4.4532 (1.0)      619.8831 (1.0)       5.5109 (1.0)           2;0  1.6124 (1.0)           5           1
+time_elf_parsing      616.5053 (1.01)     638.6965 (1.02)     628.1588 (1.01)     8.2465 (1.85)     629.0099 (1.01)     10.7885 (1.96)          2;0  1.5920 (0.99)          5           1
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Legend:
+  Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile.
+  OPS: Operations Per Second, computed as 1 / Mean
+============================================== 3 passed, 117 deselected in 14.78s =============================================
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file