From 8391d4ec0783f15606d1005dfb5ce3b451609084 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 21 Jul 2023 20:06:27 +0000 Subject: [PATCH] Deployed 99c59a9 with MkDocs version: 1.4.3 --- .nojekyll | 0 404.html | 1671 + api/gef/index.html | 39544 ++++++++++++++++ api/index.html | 2041 + 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 | 1905 + commands/aslr/index.html | 1764 + commands/canary/index.html | 1753 + commands/checksec/index.html | 1762 + commands/config/index.html | 1772 + commands/context/index.html | 1976 + commands/dereference/index.html | 1810 + commands/edit-flags/index.html | 1759 + commands/elf-info/index.html | 1811 + commands/entry-break/index.html | 1758 + commands/eval/index.html | 1782 + commands/format-string-helper/index.html | 1766 + commands/functions/index.html | 1773 + commands/gef-remote/index.html | 1948 + commands/gef/index.html | 1968 + commands/got/index.html | 1762 + commands/heap-analysis-helper/index.html | 1796 + commands/heap/index.html | 2012 + commands/help/index.html | 1749 + commands/hexdump/index.html | 1790 + commands/highlight/index.html | 1890 + commands/hijack-fd/index.html | 1763 + commands/ksymaddr/index.html | 1761 + commands/memory/index.html | 1854 + commands/name-break/index.html | 1783 + commands/nop/index.html | 1775 + commands/patch/index.html | 1756 + commands/pattern/index.html | 1828 + commands/pcustom/index.html | 1993 + commands/pie/index.html | 1887 + commands/print-format/index.html | 1777 + commands/process-search/index.html | 1783 + commands/process-status/index.html | 1774 + commands/registers/index.html | 1824 + commands/reset-cache/index.html | 1747 + commands/scan/index.html | 1793 + commands/search-pattern/index.html | 1813 + commands/shellcode/index.html | 1773 + commands/skipi/index.html | 1711 + commands/stub/index.html | 1793 + commands/theme/index.html | 1811 + commands/tmux-setup/index.html | 1794 + commands/trace-run/index.html | 1757 + commands/version/index.html | 1794 + commands/vmmap/index.html | 1756 + commands/xfiles/index.html | 1750 + commands/xinfo/index.html | 1753 + commands/xor-memory/index.html | 1772 + compat/index.html | 1739 + config/index.html | 1769 + coverage/coverage.json | 1 + coverage/coverage.xml | 7573 +++ coverage/coverage_html.js | 624 + coverage/favicon_32.png | Bin 0 -> 1732 bytes coverage/gef_py.html | 11281 +++++ 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 | 1788 + faq/index.html | 1995 + functions/base/index.html | 1712 + functions/bss/index.html | 1711 + functions/got/index.html | 1711 + functions/heap/index.html | 1711 + functions/stack/index.html | 1711 + index.html | 1949 + install/index.html | 1990 + obsolete/docs/index.html | 1704 + obsolete/mkdocs.yml | 6 + obsolete/requirements.txt | 1 + requirements.txt | 2 + screenshots/index.html | 2024 + search/search_index.json | 1 + settings/context/index.html | 2116 + settings/dereference/index.html | 1755 + settings/entry-break/index.html | 1755 + settings/gef/index.html | 1945 + settings/got/index.html | 1774 + settings/heap-analysis-helper/index.html | 1831 + settings/heap-chunks/index.html | 1755 + settings/hexdump/index.html | 1755 + settings/highlight/index.html | 1755 + settings/pattern/index.html | 1755 + settings/pcustom/index.html | 1831 + settings/print-format/index.html | 1755 + settings/process-search/index.html | 1755 + settings/search-pattern/index.html | 1774 + settings/theme/index.html | 2059 + settings/trace-run/index.html | 1772 + sitemap.xml | 3 + sitemap.xml.gz | Bin 0 -> 127 bytes testing/index.html | 1945 + 139 files changed, 211740 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..788a36a79 --- /dev/null +++ b/404.html @@ -0,0 +1,1671 @@ + + + + + + + + + + + + + + + + + + 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..972820458 --- /dev/null +++ b/api/gef/index.html @@ -0,0 +1,39544 @@ + + + + + + + + + + + + + + + + + + + + + + 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
  • +
  • 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 (Integer) of the n-th instruction after addr.

+
+

+

function gef_instruction_n

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

Return the n-th instruction after addr as an Instruction object.

+
+

+

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.Event') → 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: int = 16) → None
+
+

Write buffer at address address.

+
+

class GefMissingCommand

+

GEF missing sub-command Display the GEF commands that could not be loaded, along with the reason of why they could not be loaded.

+

+

function GefMissingCommand.__init__

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

Check the validity, dedup, and return all valid tids.

+
+

+

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.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..b6d8881dd --- /dev/null +++ b/api/index.html @@ -0,0 +1,2041 @@ + + + + + + + + + + + + + + + + + + + + + + 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..ceffd04be --- /dev/null +++ b/commands/aslr/index.html @@ -0,0 +1,1764 @@ + + + + + + + + + + + + + + + + + + + + + + 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..4282fabff --- /dev/null +++ b/commands/canary/index.html @@ -0,0 +1,1753 @@ + + + + + + + + + + + + + + + + + + + + + + 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..6ad400371 --- /dev/null +++ b/commands/checksec/index.html @@ -0,0 +1,1762 @@ + + + + + + + + + + + + + + + + + + + + + + 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..3687895e3 --- /dev/null +++ b/commands/config/index.html @@ -0,0 +1,1772 @@ + + + + + + + + + + + + + + + + + + + + + + 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..c15a7c378 --- /dev/null +++ b/commands/context/index.html @@ -0,0 +1,1976 @@ + + + + + + + + + + + + + + + + + + + + + + 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..b59010678 --- /dev/null +++ b/commands/dereference/index.html @@ -0,0 +1,1810 @@ + + + + + + + + + + + + + + + + + + + + + + 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..70ca0eba4 --- /dev/null +++ b/commands/edit-flags/index.html @@ -0,0 +1,1759 @@ + + + + + + + + + + + + + + + + + + + + + + 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..65b7985c3 --- /dev/null +++ b/commands/elf-info/index.html @@ -0,0 +1,1811 @@ + + + + + + + + + + + + + + + + + + + + + + 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..e012d6bf1 --- /dev/null +++ b/commands/entry-break/index.html @@ -0,0 +1,1758 @@ + + + + + + + + + + + + + + + + + + + + + + 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..fe8a13069 --- /dev/null +++ b/commands/eval/index.html @@ -0,0 +1,1782 @@ + + + + + + + + + + + + + + + + + + + + + + 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..1da3bd318 --- /dev/null +++ b/commands/format-string-helper/index.html @@ -0,0 +1,1766 @@ + + + + + + + + + + + + + + + + + + + + + + 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..7c8ba92dd --- /dev/null +++ b/commands/functions/index.html @@ -0,0 +1,1773 @@ + + + + + + + + + + + + + + + + + + + + + + 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..8e775207a --- /dev/null +++ b/commands/gef-remote/index.html @@ -0,0 +1,1948 @@ + + + + + + + + + + + + + + + + + + + + + + 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..057efeb86 --- /dev/null +++ b/commands/gef/index.html @@ -0,0 +1,1968 @@ + + + + + + + + + + + + + + + + + + + + + + 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..ba5ed8803 --- /dev/null +++ b/commands/got/index.html @@ -0,0 +1,1762 @@ + + + + + + + + + + + + + + + + + + + + + + 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..d7d7d6c8f --- /dev/null +++ b/commands/heap-analysis-helper/index.html @@ -0,0 +1,1796 @@ + + + + + + + + + + + + + + + + + + + + + + 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..b8fb5edd5 --- /dev/null +++ b/commands/heap/index.html @@ -0,0 +1,2012 @@ + + + + + + + + + + + + + + + + + + + + + + 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..efea30005 --- /dev/null +++ b/commands/help/index.html @@ -0,0 +1,1749 @@ + + + + + + + + + + + + + + + + + + + + + + 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..5c0a984de --- /dev/null +++ b/commands/hexdump/index.html @@ -0,0 +1,1790 @@ + + + + + + + + + + + + + + + + + + + + + + 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..ddf4db075 --- /dev/null +++ b/commands/highlight/index.html @@ -0,0 +1,1890 @@ + + + + + + + + + + + + + + + + + + + + + + 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..1c2ae938a --- /dev/null +++ b/commands/hijack-fd/index.html @@ -0,0 +1,1763 @@ + + + + + + + + + + + + + + + + + + + + + + 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..082e85593 --- /dev/null +++ b/commands/ksymaddr/index.html @@ -0,0 +1,1761 @@ + + + + + + + + + + + + + + + + + + + + + + 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..8495e3f88 --- /dev/null +++ b/commands/memory/index.html @@ -0,0 +1,1854 @@ + + + + + + + + + + + + + + + + + + + + + + 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..cd8b4fb4b --- /dev/null +++ b/commands/name-break/index.html @@ -0,0 +1,1783 @@ + + + + + + + + + + + + + + + + + + + + + + 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..a8ee4209a --- /dev/null +++ b/commands/nop/index.html @@ -0,0 +1,1775 @@ + + + + + + + + + + + + + + + + + + + + + + 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..95f8f4292 --- /dev/null +++ b/commands/patch/index.html @@ -0,0 +1,1756 @@ + + + + + + + + + + + + + + + + + + + + + + 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..fee7f0617 --- /dev/null +++ b/commands/pattern/index.html @@ -0,0 +1,1828 @@ + + + + + + + + + + + + + + + + + + + + + + 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..bc7b62e69 --- /dev/null +++ b/commands/pcustom/index.html @@ -0,0 +1,1993 @@ + + + + + + + + + + + + + + + + + + + + + + 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..47dc81e10 --- /dev/null +++ b/commands/pie/index.html @@ -0,0 +1,1887 @@ + + + + + + + + + + + + + + + + + + + + + + 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..d02d5706f --- /dev/null +++ b/commands/print-format/index.html @@ -0,0 +1,1777 @@ + + + + + + + + + + + + + + + + + + + + + + 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..02dedfbf6 --- /dev/null +++ b/commands/process-search/index.html @@ -0,0 +1,1783 @@ + + + + + + + + + + + + + + + + + + + + + + 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..0a972b014 --- /dev/null +++ b/commands/process-status/index.html @@ -0,0 +1,1774 @@ + + + + + + + + + + + + + + + + + + + + + + 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..505c34ca2 --- /dev/null +++ b/commands/registers/index.html @@ -0,0 +1,1824 @@ + + + + + + + + + + + + + + + + + + + + + + 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..b6f01f8ce --- /dev/null +++ b/commands/reset-cache/index.html @@ -0,0 +1,1747 @@ + + + + + + + + + + + + + + + + + + + + + + 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..ed4488d99 --- /dev/null +++ b/commands/scan/index.html @@ -0,0 +1,1793 @@ + + + + + + + + + + + + + + + + + + + + + + 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..af77cbc7f --- /dev/null +++ b/commands/search-pattern/index.html @@ -0,0 +1,1813 @@ + + + + + + + + + + + + + + + + + + + + + + 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..1a1cbab55 --- /dev/null +++ b/commands/shellcode/index.html @@ -0,0 +1,1773 @@ + + + + + + + + + + + + + + + + + + + + + + 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..06c7837b2 --- /dev/null +++ b/commands/skipi/index.html @@ -0,0 +1,1711 @@ + + + + + + + + + + + + + + + + + + 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..324b01724 --- /dev/null +++ b/commands/stub/index.html @@ -0,0 +1,1793 @@ + + + + + + + + + + + + + + + + + + + + + + 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..9cbb54a99 --- /dev/null +++ b/commands/theme/index.html @@ -0,0 +1,1811 @@ + + + + + + + + + + + + + + + + + + + + + + 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..7430e4687 --- /dev/null +++ b/commands/tmux-setup/index.html @@ -0,0 +1,1794 @@ + + + + + + + + + + + + + + + + + + + + + + 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..351faa5a5 --- /dev/null +++ b/commands/trace-run/index.html @@ -0,0 +1,1757 @@ + + + + + + + + + + + + + + + + + + + + + + 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..ab2184839 --- /dev/null +++ b/commands/version/index.html @@ -0,0 +1,1794 @@ + + + + + + + + + + + + + + + + + + + + + + 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..9e57d9a62 --- /dev/null +++ b/commands/vmmap/index.html @@ -0,0 +1,1756 @@ + + + + + + + + + + + + + + + + + + + + + + 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..600ab66f5 --- /dev/null +++ b/commands/xfiles/index.html @@ -0,0 +1,1750 @@ + + + + + + + + + + + + + + + + + + + + + + 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..0bdb3dec9 --- /dev/null +++ b/commands/xinfo/index.html @@ -0,0 +1,1753 @@ + + + + + + + + + + + + + + + + + + + + + + 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..a54cb12b9 --- /dev/null +++ b/commands/xor-memory/index.html @@ -0,0 +1,1772 @@ + + + + + + + + + + + + + + + + + + + + + + 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..10ad935c2 --- /dev/null +++ b/compat/index.html @@ -0,0 +1,1739 @@ + + + + + + + + + + + + + + + + + + + + + + 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..52bfb88f4 --- /dev/null +++ b/config/index.html @@ -0,0 +1,1769 @@ + + + + + + + + + + + + + + + + + + + + + + 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..a5d22a4bf --- /dev/null +++ b/coverage/coverage.json @@ -0,0 +1 @@ +{"meta": {"version": "7.2.7", "timestamp": "2023-07-21T20:06:10.659830", "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, 1197, 1198, 1200, 1201, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1214, 1215, 1218, 1219, 1220, 1223, 1224, 1227, 1228, 1230, 1231, 1232, 1233, 1235, 1236, 1237, 1238, 1239, 1241, 1242, 1243, 1246, 1249, 1252, 1253, 1254, 1256, 1257, 1260, 1261, 1264, 1265, 1267, 1272, 1273, 1274, 1275, 1281, 1282, 1283, 1286, 1287, 1289, 1290, 1291, 1292, 1293, 1294, 1296, 1297, 1298, 1299, 1303, 1305, 1309, 1318, 1320, 1323, 1327, 1328, 1329, 1331, 1332, 1333, 1338, 1339, 1341, 1342, 1343, 1344, 1345, 1347, 1350, 1351, 1353, 1354, 1356, 1357, 1359, 1360, 1361, 1363, 1364, 1365, 1367, 1368, 1370, 1371, 1373, 1375, 1378, 1379, 1380, 1382, 1383, 1384, 1386, 1387, 1388, 1390, 1391, 1392, 1394, 1395, 1396, 1398, 1399, 1400, 1402, 1403, 1404, 1406, 1407, 1410, 1411, 1412, 1414, 1415, 1418, 1419, 1422, 1423, 1426, 1427, 1430, 1432, 1433, 1434, 1435, 1437, 1438, 1439, 1440, 1441, 1443, 1448, 1449, 1451, 1452, 1453, 1454, 1456, 1457, 1458, 1460, 1462, 1463, 1465, 1466, 1467, 1471, 1473, 1474, 1477, 1480, 1481, 1482, 1484, 1485, 1499, 1500, 1504, 1505, 1506, 1507, 1509, 1510, 1516, 1517, 1518, 1519, 1520, 1522, 1530, 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1543, 1544, 1545, 1547, 1548, 1550, 1551, 1554, 1555, 1556, 1558, 1559, 1560, 1562, 1563, 1564, 1566, 1567, 1570, 1571, 1574, 1575, 1578, 1580, 1581, 1582, 1583, 1584, 1586, 1587, 1588, 1590, 1591, 1593, 1594, 1595, 1597, 1598, 1600, 1603, 1606, 1608, 1611, 1612, 1615, 1618, 1619, 1620, 1622, 1623, 1625, 1626, 1628, 1629, 1631, 1634, 1638, 1641, 1642, 1644, 1645, 1646, 1648, 1649, 1650, 1651, 1655, 1656, 1657, 1661, 1662, 1664, 1666, 1683, 1684, 1687, 1688, 1692, 1694, 1697, 1699, 1700, 1701, 1702, 1704, 1706, 1713, 1715, 1716, 1718, 1720, 1722, 1724, 1725, 1728, 1730, 1731, 1732, 1733, 1735, 1738, 1741, 1742, 1743, 1744, 1747, 1748, 1749, 1752, 1753, 1754, 1757, 1758, 1759, 1762, 1763, 1764, 1767, 1769, 1772, 1773, 1776, 1779, 1785, 1786, 1788, 1789, 1790, 1792, 1793, 1795, 1798, 1799, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1810, 1811, 1812, 1816, 1817, 1818, 1821, 1823, 1824, 1825, 1826, 1829, 1831, 1834, 1835, 1837, 1838, 1839, 1840, 1841, 1843, 1846, 1847, 1854, 1855, 1856, 1858, 1859, 1860, 1861, 1863, 1864, 1865, 1866, 1869, 1877, 1878, 1880, 1881, 1882, 1884, 1885, 1886, 1888, 1889, 1890, 1891, 1895, 1896, 1899, 1901, 1904, 1906, 1909, 1911, 1912, 1915, 1917, 1918, 1921, 1922, 1923, 1924, 1926, 1927, 1928, 1931, 1932, 1933, 1934, 1936, 1938, 1939, 1940, 1941, 1942, 1944, 1946, 1947, 1948, 1951, 1960, 1967, 1969, 1970, 1971, 1972, 1975, 1976, 1984, 1985, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2002, 2011, 2012, 2014, 2015, 2016, 2017, 2018, 2019, 2021, 2023, 2024, 2026, 2028, 2031, 2034, 2038, 2042, 2043, 2044, 2045, 2047, 2050, 2055, 2058, 2062, 2063, 2065, 2068, 2071, 2075, 2076, 2079, 2081, 2084, 2086, 2087, 2090, 2092, 2095, 2097, 2100, 2103, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2116, 2117, 2120, 2122, 2123, 2126, 2141, 2142, 2146, 2147, 2149, 2150, 2151, 2153, 2154, 2155, 2159, 2160, 2163, 2164, 2166, 2167, 2174, 2175, 2180, 2184, 2185, 2189, 2190, 2194, 2196, 2197, 2198, 2199, 2202, 2203, 2204, 2205, 2208, 2209, 2210, 2211, 2217, 2218, 2221, 2222, 2223, 2225, 2227, 2228, 2229, 2230, 2231, 2234, 2235, 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2251, 2252, 2253, 2255, 2256, 2257, 2260, 2263, 2266, 2267, 2271, 2273, 2276, 2279, 2282, 2285, 2288, 2291, 2292, 2294, 2295, 2298, 2299, 2300, 2302, 2304, 2305, 2306, 2308, 2309, 2311, 2312, 2313, 2314, 2317, 2318, 2319, 2321, 2322, 2323, 2324, 2326, 2327, 2330, 2331, 2332, 2334, 2335, 2336, 2338, 2339, 2342, 2343, 2344, 2350, 2352, 2353, 2354, 2355, 2356, 2357, 2362, 2364, 2366, 2367, 2368, 2369, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, 2387, 2388, 2389, 2390, 2391, 2396, 2397, 2398, 2399, 2400, 2402, 2403, 2405, 2406, 2409, 2412, 2423, 2424, 2427, 2428, 2436, 2439, 2495, 2504, 2505, 2506, 2507, 2512, 2513, 2514, 2515, 2524, 2525, 2526, 2527, 2529, 2533, 2534, 2540, 2541, 2546, 2547, 2550, 2551, 2555, 2556, 2559, 2564, 2576, 2583, 2587, 2620, 2635, 2636, 2653, 2654, 2655, 2656, 2658, 2664, 2665, 2666, 2677, 2678, 2679, 2681, 2686, 2693, 2697, 2701, 2702, 2712, 2713, 2736, 2743, 2774, 2775, 2776, 2777, 2779, 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2801, 2802, 2803, 2804, 2806, 2807, 2808, 2809, 2810, 2812, 2813, 2814, 2815, 2817, 2818, 2820, 2821, 2822, 2828, 2830, 2875, 2876, 2877, 2878, 2879, 2880, 2882, 2884, 2885, 2900, 2911, 2912, 2913, 2914, 2916, 2919, 2920, 2921, 2922, 2923, 2925, 2926, 2928, 2929, 2954, 2955, 2957, 2958, 2959, 2960, 2962, 2968, 2969, 2970, 2971, 2972, 2983, 2984, 2985, 2986, 2989, 2996, 2999, 3002, 3007, 3020, 3028, 3029, 3054, 3055, 3056, 3057, 3058, 3061, 3062, 3065, 3066, 3067, 3069, 3075, 3076, 3077, 3078, 3079, 3087, 3088, 3089, 3091, 3098, 3101, 3104, 3113, 3137, 3145, 3146, 3165, 3166, 3170, 3171, 3172, 3174, 3181, 3182, 3189, 3191, 3192, 3211, 3212, 3213, 3214, 3217, 3223, 3224, 3225, 3226, 3227, 3228, 3229, 3230, 3231, 3233, 3236, 3239, 3242, 3247, 3269, 3277, 3278, 3294, 3295, 3296, 3297, 3298, 3300, 3301, 3302, 3305, 3323, 3324, 3325, 3329, 3330, 3331, 3335, 3341, 3347, 3349, 3350, 3353, 3360, 3361, 3365, 3366, 3367, 3368, 3369, 3370, 3373, 3374, 3381, 3382, 3383, 3384, 3385, 3386, 3389, 3391, 3392, 3393, 3394, 3398, 3406, 3407, 3409, 3410, 3411, 3412, 3413, 3416, 3417, 3419, 3420, 3421, 3422, 3424, 3425, 3427, 3429, 3430, 3433, 3436, 3440, 3441, 3444, 3445, 3446, 3448, 3451, 3452, 3455, 3459, 3460, 3461, 3466, 3467, 3470, 3471, 3472, 3476, 3477, 3480, 3481, 3482, 3483, 3486, 3487, 3490, 3491, 3492, 3494, 3495, 3498, 3500, 3501, 3504, 3506, 3507, 3508, 3511, 3513, 3516, 3518, 3519, 3520, 3523, 3525, 3526, 3527, 3528, 3532, 3533, 3534, 3535, 3536, 3537, 3538, 3540, 3541, 3545, 3549, 3552, 3555, 3556, 3557, 3558, 3559, 3560, 3561, 3562, 3565, 3567, 3568, 3571, 3573, 3574, 3577, 3579, 3580, 3605, 3606, 3608, 3611, 3612, 3614, 3617, 3618, 3620, 3623, 3624, 3626, 3629, 3630, 3631, 3634, 3635, 3639, 3647, 3650, 3657, 3659, 3660, 3665, 3666, 3667, 3670, 3673, 3674, 3675, 3676, 3677, 3678, 3681, 3682, 3701, 3704, 3705, 3706, 3719, 3721, 3722, 3724, 3727, 3730, 3732, 3733, 3735, 3738, 3741, 3743, 3746, 3749, 3754, 3760, 3762, 3763, 3764, 3767, 3768, 3769, 3770, 3773, 3775, 3778, 3780, 3781, 3783, 3784, 3785, 3786, 3787, 3789, 3790, 3792, 3793, 3794, 3796, 3799, 3801, 3802, 3805, 3808, 3809, 3810, 3811, 3812, 3815, 3816, 3818, 3819, 3823, 3824, 3826, 3827, 3828, 3829, 3830, 3833, 3836, 3837, 3838, 3839, 3840, 3841, 3842, 3845, 3848, 3850, 3851, 3854, 3855, 3869, 3870, 3874, 3875, 3879, 3880, 3884, 3885, 3890, 3891, 3895, 3896, 3900, 3901, 3905, 3906, 3910, 3911, 3915, 3916, 3920, 3921, 3925, 3926, 3933, 3934, 3935, 3938, 3939, 3943, 3944, 3945, 3948, 3949, 3953, 3954, 3955, 3958, 3959, 3960, 3963, 3964, 3965, 3968, 3969, 3970, 3973, 3974, 3978, 3979, 3983, 3984, 3985, 3988, 3989, 3993, 3994, 3995, 3998, 3999, 4007, 4008, 4010, 4013, 4014, 4016, 4017, 4019, 4020, 4023, 4025, 4026, 4029, 4030, 4035, 4038, 4039, 4040, 4041, 4043, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4064, 4065, 4066, 4067, 4068, 4070, 4073, 4074, 4075, 4076, 4077, 4078, 4080, 4081, 4086, 4087, 4089, 4090, 4091, 4092, 4094, 4095, 4096, 4097, 4098, 4100, 4101, 4102, 4104, 4107, 4108, 4111, 4117, 4125, 4126, 4128, 4129, 4130, 4131, 4132, 4134, 4135, 4136, 4137, 4138, 4141, 4142, 4144, 4145, 4146, 4147, 4148, 4149, 4151, 4152, 4153, 4157, 4158, 4159, 4162, 4172, 4182, 4184, 4186, 4187, 4188, 4189, 4190, 4192, 4206, 4207, 4210, 4211, 4213, 4214, 4215, 4216, 4218, 4219, 4220, 4221, 4222, 4225, 4226, 4228, 4229, 4230, 4231, 4232, 4233, 4235, 4236, 4237, 4241, 4242, 4250, 4252, 4254, 4256, 4262, 4264, 4267, 4268, 4270, 4271, 4272, 4273, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4284, 4285, 4294, 4305, 4307, 4308, 4320, 4322, 4323, 4325, 4326, 4329, 4330, 4332, 4333, 4334, 4335, 4336, 4338, 4339, 4340, 4341, 4342, 4345, 4346, 4348, 4349, 4350, 4351, 4352, 4353, 4355, 4375, 4376, 4378, 4379, 4380, 4381, 4383, 4384, 4385, 4388, 4389, 4391, 4392, 4393, 4394, 4395, 4397, 4407, 4432, 4433, 4435, 4437, 4438, 4442, 4443, 4449, 4451, 4452, 4453, 4454, 4455, 4456, 4458, 4459, 4460, 4461, 4462, 4463, 4468, 4469, 4471, 4472, 4473, 4475, 4476, 4477, 4478, 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4491, 4492, 4493, 4494, 4495, 4496, 4497, 4498, 4500, 4501, 4502, 4503, 4504, 4505, 4508, 4509, 4512, 4514, 4515, 4516, 4518, 4521, 4522, 4524, 4525, 4527, 4528, 4529, 4531, 4532, 4533, 4534, 4536, 4537, 4539, 4541, 4542, 4545, 4546, 4547, 4549, 4550, 4553, 4554, 4556, 4557, 4560, 4562, 4563, 4564, 4565, 4566, 4567, 4569, 4571, 4572, 4573, 4575, 4576, 4579, 4583, 4584, 4585, 4586, 4587, 4589, 4590, 4591, 4592, 4593, 4596, 4597, 4598, 4600, 4601, 4602, 4604, 4605, 4606, 4607, 4608, 4610, 4611, 4612, 4613, 4618, 4619, 4620, 4621, 4623, 4624, 4625, 4628, 4629, 4630, 4632, 4633, 4635, 4636, 4637, 4643, 4645, 4646, 4647, 4648, 4650, 4651, 4653, 4660, 4661, 4662, 4664, 4665, 4667, 4668, 4672, 4673, 4674, 4676, 4677, 4678, 4679, 4680, 4682, 4683, 4684, 4685, 4686, 4688, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4699, 4700, 4701, 4704, 4705, 4709, 4715, 4716, 4719, 4720, 4721, 4723, 4724, 4726, 4727, 4728, 4730, 4731, 4732, 4733, 4736, 4737, 4738, 4740, 4741, 4743, 4744, 4745, 4746, 4750, 4751, 4754, 4759, 4761, 4762, 4763, 4764, 4765, 4768, 4769, 4770, 4772, 4773, 4775, 4776, 4777, 4778, 4780, 4782, 4786, 4787, 4790, 4791, 4794, 4795, 4796, 4798, 4799, 4801, 4802, 4804, 4805, 4810, 4813, 4816, 4817, 4819, 4821, 4824, 4825, 4828, 4829, 4830, 4832, 4833, 4835, 4837, 4838, 4842, 4846, 4850, 4851, 4852, 4853, 4854, 4855, 4856, 4857, 4860, 4861, 4863, 4864, 4868, 4871, 4872, 4873, 4875, 4876, 4878, 4895, 4896, 4897, 4899, 4900, 4902, 4919, 4920, 4921, 4923, 4924, 4925, 4928, 4929, 4930, 4931, 4932, 4934, 4935, 4936, 4938, 4939, 4940, 4941, 4942, 4944, 4945, 4946, 4947, 4948, 4949, 4950, 4951, 4954, 4956, 4957, 4958, 4959, 4960, 4961, 4965, 4966, 4967, 4968, 4973, 4975, 4976, 4977, 4978, 4979, 4982, 4985, 4986, 4987, 4989, 4990, 4992, 4993, 4994, 4996, 4997, 5001, 5002, 5006, 5007, 5008, 5011, 5012, 5013, 5016, 5017, 5018, 5020, 5021, 5022, 5024, 5025, 5026, 5027, 5028, 5029, 5030, 5031, 5032, 5034, 5035, 5036, 5037, 5038, 5039, 5040, 5041, 5043, 5044, 5045, 5047, 5048, 5050, 5051, 5052, 5053, 5054, 5055, 5057, 5058, 5059, 5060, 5061, 5064, 5066, 5067, 5068, 5069, 5070, 5071, 5073, 5075, 5076, 5077, 5078, 5079, 5080, 5088, 5089, 5090, 5092, 5093, 5094, 5098, 5099, 5100, 5101, 5102, 5104, 5105, 5106, 5107, 5108, 5109, 5110, 5113, 5115, 5119, 5121, 5136, 5140, 5141, 5142, 5143, 5144, 5145, 5167, 5168, 5169, 5171, 5172, 5174, 5175, 5176, 5177, 5178, 5179, 5180, 5181, 5182, 5183, 5184, 5185, 5186, 5187, 5188, 5189, 5190, 5191, 5192, 5193, 5195, 5196, 5197, 5199, 5200, 5201, 5202, 5203, 5204, 5206, 5207, 5208, 5209, 5211, 5212, 5213, 5214, 5216, 5217, 5218, 5221, 5222, 5223, 5224, 5225, 5226, 5227, 5229, 5231, 5233, 5234, 5236, 5237, 5238, 5239, 5240, 5241, 5242, 5243, 5244, 5245, 5246, 5248, 5250, 5251, 5252, 5253, 5254, 5255, 5256, 5258, 5260, 5265, 5266, 5268, 5269, 5275, 5276, 5279, 5280, 5281, 5282, 5283, 5284, 5286, 5292, 5293, 5294, 5295, 5296, 5298, 5300, 5302, 5304, 5305, 5306, 5307, 5308, 5309, 5310, 5312, 5313, 5327, 5328, 5329, 5330, 5331, 5332, 5334, 5335, 5336, 5337, 5339, 5341, 5342, 5343, 5344, 5345, 5346, 5348, 5351, 5352, 5353, 5354, 5355, 5358, 5359, 5360, 5363, 5366, 5368, 5369, 5370, 5371, 5373, 5374, 5375, 5376, 5377, 5378, 5379, 5381, 5388, 5389, 5390, 5392, 5393, 5394, 5395, 5397, 5398, 5399, 5400, 5401, 5403, 5404, 5405, 5406, 5407, 5409, 5410, 5416, 5417, 5419, 5420, 5421, 5422, 5425, 5426, 5427, 5434, 5435, 5437, 5438, 5439, 5440, 5441, 5442, 5443, 5444, 5446, 5447, 5448, 5449, 5450, 5451, 5453, 5455, 5456, 5457, 5459, 5460, 5461, 5463, 5464, 5465, 5466, 5467, 5468, 5470, 5471, 5472, 5474, 5475, 5476, 5477, 5480, 5481, 5482, 5484, 5485, 5487, 5488, 5489, 5491, 5493, 5494, 5495, 5496, 5497, 5498, 5499, 5500, 5501, 5504, 5505, 5506, 5508, 5509, 5510, 5512, 5513, 5514, 5516, 5517, 5521, 5522, 5523, 5524, 5525, 5526, 5528, 5529, 5532, 5533, 5534, 5536, 5537, 5538, 5540, 5541, 5542, 5544, 5553, 5565, 5578, 5579, 5580, 5582, 5583, 5584, 5586, 5587, 5588, 5643, 5649, 5650, 5651, 5654, 5655, 5656, 5657, 5659, 5660, 5661, 5665, 5666, 5668, 5671, 5672, 5674, 5677, 5678, 5680, 5684, 5688, 5689, 5690, 5691, 5692, 5694, 5695, 5697, 5698, 5699, 5703, 5704, 5705, 5706, 5707, 5708, 5709, 5710, 5714, 5717, 5718, 5719, 5722, 5723, 5724, 5725, 5730, 5731, 5732, 5733, 5734, 5736, 5737, 5738, 5739, 5741, 5742, 5743, 5744, 5746, 5747, 5748, 5750, 5752, 5753, 5754, 5756, 5757, 5758, 5762, 5763, 5767, 5768, 5769, 5770, 5771, 5773, 5774, 5775, 5777, 5779, 5781, 5784, 5785, 5787, 5788, 5789, 5793, 5794, 5797, 5798, 5799, 5800, 5801, 5802, 5803, 5804, 5806, 5808, 5810, 5812, 5814, 5815, 5816, 5817, 5819, 5820, 5821, 5823, 5824, 5825, 5826, 5827, 5828, 5830, 5831, 5833, 5834, 5835, 5836, 5840, 5841, 5842, 5844, 5845, 5847, 5848, 5850, 5852, 5853, 5855, 5859, 5865, 5884, 5885, 5886, 5889, 5890, 5891, 5893, 5894, 5895, 5896, 5899, 5900, 5904, 5905, 5908, 5909, 5911, 5915, 5919, 5920, 5921, 5922, 5923, 5924, 5925, 5927, 5929, 5931, 5932, 5935, 5936, 5937, 5943, 5944, 5945, 5949, 5950, 5951, 5953, 5954, 5955, 5960, 5961, 5966, 5967, 5968, 5969, 5970, 5980, 5981, 5982, 5983, 5984, 5985, 5988, 5989, 5990, 5992, 5993, 5997, 6002, 6003, 6004, 6006, 6007, 6008, 6009, 6010, 6011, 6013, 6014, 6015, 6017, 6018, 6019, 6022, 6023, 6024, 6027, 6028, 6034, 6042, 6043, 6044, 6046, 6047, 6048, 6049, 6050, 6051, 6052, 6053, 6054, 6055, 6057, 6058, 6059, 6061, 6062, 6063, 6064, 6065, 6067, 6068, 6069, 6070, 6071, 6072, 6074, 6075, 6078, 6079, 6081, 6082, 6083, 6084, 6085, 6086, 6087, 6089, 6091, 6092, 6095, 6096, 6098, 6099, 6100, 6105, 6106, 6108, 6111, 6112, 6113, 6116, 6117, 6120, 6122, 6123, 6124, 6126, 6127, 6128, 6129, 6130, 6131, 6132, 6135, 6136, 6137, 6139, 6140, 6142, 6143, 6144, 6146, 6147, 6152, 6153, 6154, 6156, 6157, 6158, 6160, 6161, 6162, 6164, 6165, 6166, 6169, 6171, 6175, 6179, 6180, 6185, 6186, 6188, 6192, 6195, 6196, 6197, 6199, 6200, 6202, 6203, 6204, 6205, 6206, 6209, 6210, 6211, 6214, 6215, 6217, 6218, 6219, 6221, 6222, 6223, 6224, 6225, 6230, 6231, 6233, 6234, 6235, 6238, 6239, 6240, 6241, 6243, 6244, 6247, 6249, 6250, 6253, 6254, 6255, 6258, 6259, 6260, 6263, 6264, 6265, 6266, 6268, 6269, 6270, 6271, 6272, 6273, 6274, 6275, 6276, 6277, 6278, 6279, 6280, 6285, 6286, 6287, 6290, 6292, 6293, 6294, 6296, 6297, 6298, 6300, 6302, 6303, 6304, 6305, 6306, 6307, 6309, 6311, 6315, 6316, 6317, 6318, 6319, 6322, 6323, 6324, 6327, 6328, 6329, 6331, 6332, 6333, 6335, 6336, 6350, 6351, 6352, 6354, 6355, 6359, 6361, 6364, 6366, 6367, 6368, 6369, 6371, 6373, 6374, 6375, 6376, 6377, 6378, 6380, 6381, 6382, 6385, 6386, 6387, 6390, 6391, 6393, 6395, 6396, 6397, 6399, 6400, 6402, 6406, 6407, 6412, 6413, 6414, 6415, 6419, 6421, 6422, 6423, 6425, 6427, 6428, 6432, 6433, 6434, 6435, 6436, 6437, 6438, 6441, 6442, 6443, 6445, 6446, 6447, 6448, 6450, 6454, 6456, 6457, 6458, 6460, 6465, 6466, 6467, 6468, 6469, 6470, 6471, 6473, 6474, 6476, 6477, 6479, 6480, 6482, 6485, 6496, 6498, 6499, 6516, 6517, 6519, 6523, 6534, 6538, 6542, 6543, 6545, 6546, 6547, 6550, 6551, 6552, 6555, 6556, 6558, 6559, 6560, 6562, 6563, 6564, 6565, 6566, 6568, 6569, 6573, 6574, 6575, 6577, 6578, 6582, 6583, 6584, 6585, 6586, 6588, 6589, 6590, 6591, 6593, 6594, 6595, 6599, 6602, 6604, 6605, 6606, 6612, 6613, 6616, 6617, 6618, 6621, 6622, 6624, 6625, 6626, 6628, 6629, 6630, 6631, 6632, 6635, 6636, 6637, 6638, 6639, 6640, 6643, 6644, 6645, 6647, 6648, 6650, 6651, 6652, 6654, 6655, 6656, 6657, 6658, 6662, 6663, 6664, 6665, 6666, 6667, 6669, 6670, 6671, 6672, 6675, 6676, 6677, 6679, 6680, 6682, 6683, 6684, 6686, 6687, 6688, 6689, 6690, 6694, 6695, 6696, 6697, 6698, 6699, 6701, 6702, 6703, 6704, 6707, 6708, 6709, 6711, 6712, 6713, 6715, 6716, 6717, 6718, 6719, 6722, 6723, 6726, 6727, 6728, 6729, 6730, 6731, 6732, 6734, 6735, 6737, 6738, 6739, 6742, 6743, 6744, 6746, 6747, 6748, 6751, 6752, 6753, 6754, 6755, 6756, 6757, 6759, 6760, 6761, 6762, 6763, 6764, 6765, 6766, 6769, 6770, 6771, 6772, 6773, 6775, 6776, 6777, 6780, 6782, 6787, 6788, 6789, 6790, 6792, 6795, 6796, 6797, 6798, 6800, 6802, 6803, 6804, 6805, 6807, 6808, 6809, 6811, 6812, 6814, 6815, 6816, 6817, 6820, 6821, 6822, 6823, 6824, 6825, 6826, 6827, 6829, 6831, 6832, 6833, 6836, 6837, 6838, 6841, 6842, 6844, 6845, 6846, 6848, 6849, 6850, 6851, 6854, 6855, 6856, 6858, 6859, 6860, 6862, 6863, 6865, 6866, 6871, 6872, 6874, 6876, 6878, 6879, 6883, 6886, 6887, 6889, 6890, 6891, 6892, 6893, 6894, 6895, 6896, 6897, 6899, 6900, 6903, 6904, 6905, 6907, 6908, 6909, 6911, 6912, 6914, 6915, 6920, 6925, 6926, 6928, 6929, 6930, 6931, 6932, 6933, 6935, 6936, 6937, 6938, 6939, 6940, 6941, 6944, 6945, 6946, 6949, 6950, 6951, 6952, 6954, 6955, 6956, 6957, 6959, 6960, 6961, 6962, 6963, 6964, 6965, 6967, 6968, 6969, 6971, 6972, 6974, 6975, 6976, 6977, 6978, 6980, 6985, 6986, 6988, 6990, 6991, 6992, 6994, 6995, 6996, 6998, 6999, 7000, 7002, 7004, 7006, 7009, 7010, 7011, 7014, 7015, 7016, 7018, 7019, 7020, 7022, 7023, 7024, 7026, 7030, 7031, 7034, 7035, 7040, 7057, 7058, 7060, 7061, 7063, 7066, 7067, 7068, 7070, 7073, 7074, 7075, 7078, 7079, 7080, 7082, 7084, 7087, 7088, 7089, 7093, 7094, 7095, 7097, 7098, 7099, 7100, 7102, 7103, 7104, 7108, 7112, 7113, 7114, 7116, 7117, 7119, 7120, 7121, 7122, 7123, 7124, 7125, 7150, 7155, 7167, 7168, 7169, 7171, 7172, 7173, 7174, 7176, 7177, 7178, 7180, 7181, 7182, 7183, 7188, 7189, 7192, 7193, 7194, 7199, 7200, 7201, 7203, 7205, 7206, 7207, 7208, 7209, 7210, 7211, 7212, 7213, 7214, 7215, 7216, 7217, 7218, 7219, 7220, 7221, 7222, 7223, 7224, 7225, 7226, 7228, 7241, 7242, 7244, 7245, 7246, 7247, 7249, 7250, 7252, 7253, 7254, 7255, 7256, 7258, 7263, 7265, 7266, 7267, 7268, 7270, 7274, 7277, 7279, 7282, 7284, 7285, 7288, 7289, 7290, 7292, 7293, 7294, 7297, 7299, 7307, 7309, 7310, 7312, 7314, 7316, 7318, 7321, 7322, 7325, 7326, 7327, 7329, 7330, 7331, 7335, 7336, 7338, 7339, 7341, 7342, 7343, 7345, 7346, 7347, 7348, 7349, 7411, 7412, 7414, 7415, 7417, 7418, 7419, 7423, 7428, 7430, 7431, 7433, 7434, 7435, 7436, 7437, 7438, 7439, 7440, 7441, 7443, 7444, 7446, 7448, 7451, 7452, 7453, 7454, 7455, 7457, 7458, 7460, 7461, 7463, 7464, 7466, 7467, 7469, 7478, 7480, 7481, 7484, 7486, 7488, 7489, 7490, 7494, 7499, 7500, 7501, 7503, 7504, 7505, 7506, 7541, 7561, 7623, 7624, 7625, 7627, 7628, 7629, 7630, 7631, 7633, 7634, 7637, 7638, 7639, 7641, 7642, 7644, 7645, 7646, 7647, 7649, 7650, 7651, 7652, 7653, 7654, 7655, 7656, 7658, 7659, 7662, 7664, 7665, 7667, 7668, 7669, 7670, 7671, 7672, 7673, 7674, 7676, 7677, 7678, 7679, 7680, 7681, 7683, 7684, 7685, 7686, 7687, 7688, 7689, 7690, 7691, 7692, 7693, 7701, 7702, 7706, 7707, 7708, 7710, 7711, 7714, 7716, 7717, 7719, 7720, 7724, 7728, 7729, 7730, 7731, 7735, 7736, 7737, 7739, 7740, 7741, 7744, 7745, 7746, 7747, 7748, 7749, 7750, 7753, 7755, 7756, 7757, 7758, 7761, 7762, 7763, 7767, 7769, 7771, 7772, 7773, 7774, 7777, 7778, 7780, 7781, 7782, 7783, 7786, 7787, 7788, 7789, 7790, 7792, 7794, 7795, 7796, 7801, 7803, 7804, 7805, 7808, 7811, 7815, 7816, 7818, 7819, 7820, 7821, 7822, 7824, 7825, 7826, 7827, 7828, 7831, 7832, 7833, 7837, 7842, 7843, 7845, 7846, 7847, 7849, 7850, 7851, 7853, 7854, 7855, 7856, 7859, 7861, 7862, 7863, 7864, 7865, 7868, 7870, 7871, 7872, 7873, 7874, 7875, 7876, 7877, 7879, 7880, 7881, 7884, 7885, 7886, 7887, 7888, 7890, 7891, 7892, 7894, 7895, 7900, 7901, 7902, 7903, 7904, 7905, 7908, 7909, 7910, 7912, 7913, 7914, 7918, 7919, 7920, 7922, 7923, 7924, 7929, 7931, 7932, 7934, 7935, 7936, 7939, 7940, 7941, 7942, 7943, 7944, 7947, 7948, 7949, 7951, 7952, 7953, 7957, 7958, 7959, 7960, 7963, 7966, 7967, 7968, 7969, 7970, 7972, 7973, 7974, 7975, 7976, 7979, 7980, 7981, 7982, 7983, 7985, 7986, 7987, 7988, 7989, 7997, 7998, 7999, 8001, 8002, 8003, 8005, 8006, 8007, 8008, 8009, 8010, 8012, 8013, 8014, 8015, 8016, 8020, 8021, 8022, 8023, 8025, 8026, 8027, 8028, 8029, 8031, 8032, 8034, 8035, 8037, 8038, 8039, 8041, 8042, 8044, 8045, 8047, 8053, 8054, 8055, 8056, 8058, 8059, 8060, 8061, 8062, 8063, 8064, 8065, 8066, 8068, 8070, 8072, 8075, 8076, 8077, 8079, 8080, 8081, 8083, 8084, 8085, 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, 8138, 8145, 8146, 8147, 8148, 8150, 8151, 8152, 8153, 8154, 8158, 8162, 8163, 8164, 8166, 8167, 8168, 8169, 8170, 8175, 8176, 8177, 8178, 8179, 8180, 8181, 8184, 8185, 8186, 8188, 8189, 8190, 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, 8255, 8256, 8258, 8259, 8264, 8265, 8268, 8269, 8270, 8273, 8274, 8275, 8276, 8277, 8278, 8280, 8281, 8282, 8283, 8284, 8286, 8290, 8291, 8293, 8294, 8296, 8297, 8298, 8299, 8300, 8303, 8304, 8305, 8306, 8307, 8308, 8310, 8311, 8312, 8313, 8314, 8315, 8316, 8318, 8320, 8321, 8324, 8325, 8326, 8328, 8331, 8332, 8333, 8336, 8337, 8338, 8339, 8341, 8342, 8343, 8344, 8346, 8347, 8348, 8349, 8351, 8352, 8354, 8355, 8356, 8357, 8358, 8359, 8363, 8365, 8366, 8367, 8368, 8370, 8371, 8372, 8374, 8375, 8377, 8378, 8379, 8380, 8381, 8383, 8384, 8386, 8387, 8389, 8390, 8391, 8393, 8397, 8406, 8407, 8408, 8409, 8411, 8412, 8414, 8415, 8417, 8418, 8420, 8423, 8424, 8425, 8428, 8429, 8431, 8432, 8434, 8435, 8436, 8437, 8440, 8441, 8442, 8444, 8446, 8447, 8449, 8450, 8451, 8452, 8453, 8465, 8466, 8467, 8470, 8471, 8473, 8474, 8475, 8478, 8479, 8480, 8483, 8484, 8485, 8487, 8488, 8489, 8490, 8494, 8495, 8497, 8499, 8500, 8502, 8503, 8504, 8505, 8506, 8507, 8508, 8512, 8514, 8515, 8516, 8517, 8518, 8520, 8521, 8523, 8528, 8531, 8533, 8534, 8536, 8537, 8539, 8540, 8541, 8542, 8544, 8548, 8550, 8551, 8552, 8553, 8554, 8558, 8559, 8560, 8565, 8566, 8567, 8569, 8570, 8571, 8572, 8573, 8575, 8576, 8578, 8579, 8585, 8591, 8592, 8595, 8596, 8597, 8599, 8600, 8601, 8603, 8604, 8605, 8607, 8608, 8609, 8610, 8611, 8612, 8614, 8615, 8616, 8617, 8618, 8622, 8624, 8625, 8626, 8630, 8631, 8633, 8634, 8641, 8646, 8647, 8654, 8657, 8658, 8659, 8662, 8663, 8665, 8666, 8667, 8669, 8674, 8675, 8676, 8679, 8680, 8681, 8683, 8684, 8685, 8689, 8690, 8691, 8692, 8693, 8695, 8696, 8698, 8699, 8700, 8703, 8704, 8705, 8708, 8709, 8710, 8712, 8713, 8714, 8718, 8719, 8720, 8721, 8722, 8723, 8724, 8725, 8728, 8729, 8730, 8734, 8735, 8736, 8738, 8739, 8740, 8741, 8742, 8744, 8745, 8746, 8750, 8753, 8755, 8756, 8757, 8762, 8763, 8765, 8766, 8767, 8768, 8769, 8770, 8771, 8773, 8774, 8775, 8776, 8777, 8778, 8779, 8780, 8781, 8782, 8784, 8785, 8786, 8788, 8796, 8797, 8798, 8800, 8801, 8803, 8805, 8806, 8808, 8809, 8813, 8815, 8818, 8819, 8820, 8824, 8825, 8827, 8828, 8829, 8830, 8832, 8837, 8838, 8839, 8843, 8844, 8845, 8847, 8848, 8849, 8850, 8851, 8852, 8853, 8854, 8855, 8856, 8859, 8860, 8861, 8866, 8867, 8868, 8871, 8873, 8874, 8875, 8876, 8877, 8881, 8882, 8883, 8886, 8887, 8889, 8890, 8893, 8894, 8895, 8896, 8897, 8899, 8900, 8901, 8902, 8905, 8906, 8908, 8909, 8910, 8911, 8912, 8914, 8916, 8917, 8922, 8923, 8926, 8927, 8928, 8936, 8937, 8938, 8940, 8941, 8942, 8944, 8945, 8947, 8948, 8949, 8961, 8962, 8963, 8965, 8966, 8967, 8968, 8969, 8970, 8971, 8975, 8977, 8978, 8979, 8980, 8983, 8986, 8987, 8988, 8990, 8991, 8992, 8994, 8995, 8996, 8998, 9000, 9002, 9003, 9004, 9006, 9010, 9011, 9013, 9014, 9015, 9016, 9019, 9020, 9021, 9022, 9024, 9032, 9033, 9035, 9037, 9038, 9041, 9042, 9043, 9045, 9048, 9049, 9052, 9055, 9058, 9060, 9061, 9062, 9063, 9066, 9067, 9068, 9069, 9070, 9071, 9073, 9074, 9075, 9077, 9081, 9082, 9083, 9084, 9085, 9086, 9088, 9099, 9103, 9104, 9105, 9106, 9107, 9108, 9110, 9114, 9115, 9116, 9117, 9118, 9119, 9120, 9122, 9123, 9126, 9127, 9128, 9131, 9132, 9133, 9134, 9135, 9136, 9143, 9145, 9153, 9154, 9155, 9159, 9160, 9161, 9163, 9164, 9172, 9174, 9175, 9176, 9177, 9178, 9180, 9182, 9185, 9186, 9187, 9194, 9195, 9197, 9198, 9199, 9200, 9201, 9202, 9203, 9205, 9206, 9207, 9208, 9209, 9211, 9212, 9213, 9214, 9215, 9216, 9222, 9223, 9224, 9225, 9226, 9227, 9228, 9229, 9231, 9232, 9234, 9236, 9240, 9241, 9243, 9261, 9264, 9265, 9266, 9267, 9268, 9269, 9272, 9274, 9276, 9277, 9279, 9280, 9281, 9283, 9284, 9286, 9287, 9293, 9294, 9299, 9300, 9302, 9303, 9304, 9306, 9307, 9309, 9310, 9311, 9312, 9314, 9315, 9316, 9317, 9318, 9319, 9321, 9325, 9326, 9327, 9328, 9329, 9331, 9332, 9333, 9336, 9339, 9340, 9341, 9342, 9343, 9345, 9346, 9347, 9351, 9354, 9355, 9356, 9358, 9359, 9360, 9362, 9363, 9364, 9365, 9366, 9367, 9372, 9373, 9374, 9375, 9379, 9382, 9383, 9384, 9385, 9386, 9387, 9389, 9390, 9391, 9393, 9396, 9397, 9398, 9399, 9400, 9401, 9403, 9404, 9405, 9407, 9410, 9411, 9412, 9413, 9414, 9416, 9417, 9418, 9419, 9420, 9422, 9424, 9425, 9427, 9428, 9429, 9430, 9431, 9432, 9433, 9435, 9438, 9439, 9440, 9441, 9443, 9445, 9446, 9448, 9449, 9450, 9451, 9452, 9453, 9455, 9456, 9457, 9458, 9460, 9461, 9467, 9468, 9470, 9471, 9473, 9474, 9475, 9476, 9477, 9478, 9479, 9480, 9481, 9482, 9483, 9484, 9485, 9487, 9488, 9489, 9490, 9492, 9493, 9497, 9498, 9502, 9503, 9507, 9508, 9510, 9511, 9512, 9513, 9514, 9515, 9516, 9519, 9520, 9522, 9523, 9532, 9533, 9534, 9535, 9536, 9537, 9538, 9539, 9552, 9553, 9566, 9568, 9569, 9570, 9571, 9573, 9574, 9575, 9576, 9578, 9595, 9597, 9598, 9599, 9600, 9601, 9602, 9605, 9606, 9607, 9608, 9609, 9612, 9613, 9614, 9615, 9616, 9619, 9620, 9621, 9622, 9624, 9625, 9630, 9631, 9634, 9635, 9639, 9640, 9645, 9646, 9650, 9653, 9654, 9655, 9656, 9658, 9659, 9660, 9661, 9662, 9663, 9665, 9666, 9667, 9668, 9669, 9671, 9673, 9674, 9676, 9677, 9678, 9679, 9680, 9681, 9683, 9685, 9686, 9688, 9689, 9690, 9691, 9692, 9693, 9695, 9698, 9701, 9702, 9703, 9706, 9707, 9713, 9714, 9716, 9717, 9718, 9720, 9721, 9722, 9723, 9725, 9729, 9730, 9731, 9732, 9734, 9735, 9736, 9737, 9738, 9739, 9740, 9744, 9746, 9747, 9749, 9750, 9751, 9752, 9754, 9757, 9758, 9759, 9760, 9762, 9764, 9766, 9767, 9768, 9769, 9771, 9772, 9773, 9774, 9776, 9778, 9780, 9784, 9785, 9786, 9790, 9794, 9795, 9796, 9797, 9799, 9801, 9806, 9807, 9809, 9824, 9825, 9827, 9828, 9830, 9831, 9832, 9834, 9835, 9836, 9837, 9840, 9841, 9842, 9844, 9845, 9846, 9848, 9851, 9852, 9853, 9855, 9856, 9858, 9859, 9862, 9863, 9865, 9866, 9868, 9869, 9870, 9871, 9873, 9880, 9881, 9882, 9884, 9885, 9887, 9888, 9889, 9892, 9895, 9896, 9897, 9898, 9901, 9902, 9903, 9904, 9906, 9908, 9911, 9912, 9916, 9917, 9919, 9920, 9921, 9923, 9935, 9936, 9937, 9938, 9940, 9941, 9942, 9944, 9945, 9946, 9947, 9948, 9949, 9950, 9951, 9955, 9956, 9959, 9960, 9962, 9963, 9965, 9966, 9967, 9969, 9981, 9982, 9984, 9985, 9986, 9989, 9990, 9992, 9993, 9994, 9995, 9996, 9997, 9998, 9999, 10001, 10004, 10005, 10006, 10008, 10009, 10010, 10012, 10014, 10015, 10016, 10018, 10021, 10022, 10023, 10025, 10026, 10028, 10029, 10030, 10032, 10037, 10038, 10039, 10041, 10042, 10043, 10045, 10046, 10047, 10049, 10050, 10053, 10054, 10057, 10058, 10059, 10061, 10062, 10064, 10065, 10066, 10068, 10070, 10073, 10074, 10075, 10079, 10080, 10083, 10084, 10085, 10087, 10088, 10090, 10091, 10092, 10094, 10095, 10096, 10097, 10098, 10101, 10102, 10104, 10105, 10106, 10107, 10109, 10125, 10142, 10171, 10172, 10174, 10175, 10177, 10178, 10179, 10180, 10182, 10183, 10184, 10188, 10190, 10194, 10195, 10199, 10200, 10201, 10203, 10206, 10207, 10208, 10209, 10210, 10211, 10212, 10216, 10217, 10218, 10220, 10221, 10222, 10223, 10224, 10225, 10232, 10243, 10244, 10246, 10247, 10248, 10249, 10250, 10252, 10253, 10254, 10257, 10258, 10259, 10260, 10261, 10263, 10264, 10265, 10266, 10268, 10270, 10272, 10274, 10276, 10278, 10279, 10280, 10281, 10283, 10288, 10289, 10291, 10292, 10296, 10297, 10299, 10300, 10305, 10306, 10307, 10308, 10309, 10311, 10313, 10314, 10315, 10316, 10318, 10319, 10320, 10321, 10322, 10324, 10326, 10327, 10332, 10333, 10334, 10335, 10337, 10339, 10340, 10341, 10342, 10343, 10344, 10345, 10346, 10347, 10348, 10349, 10350, 10352, 10353, 10355, 10356, 10357, 10358, 10359, 10365, 10367, 10369, 10371, 10372, 10375, 10376, 10377, 10378, 10379, 10380, 10381, 10390, 10392, 10393, 10394, 10396, 10418, 10419, 10420, 10421, 10422, 10424, 10425, 10426, 10427, 10428, 10430, 10431, 10432, 10433, 10434, 10435, 10438, 10442, 10444, 10445, 10449, 10450, 10451, 10455, 10470, 10471, 10523, 10524, 10525, 10528, 10530, 10531, 10532, 10533, 10535, 10536, 10537, 10539, 10541, 10542, 10543, 10544, 10545, 10546, 10547, 10551, 10553, 10554, 10556, 10557, 10562, 10563, 10564, 10566, 10567, 10568, 10569, 10575, 10577, 10578, 10580, 10581, 10583, 10585, 10586, 10587, 10590, 10591, 10592, 10593, 10595, 10596, 10597, 10598, 10599, 10600, 10601, 10602, 10604, 10605, 10608, 10610, 10611, 10613, 10618, 10619, 10623, 10624, 10625, 10626, 10628, 10630, 10632, 10633, 10634, 10637, 10638, 10639, 10640, 10641, 10642, 10643, 10645, 10649, 10650, 10652, 10653, 10654, 10656, 10657, 10658, 10660, 10661, 10663, 10664, 10665, 10666, 10667, 10670, 10671, 10672, 10673, 10674, 10675, 10676, 10677, 10678, 10679, 10680, 10681, 10682, 10683, 10684, 10685, 10686, 10687, 10688, 10690, 10691, 10692, 10693, 10694, 10695, 10696, 10697, 10698, 10699, 10701, 10704, 10705, 10706, 10707, 10708, 10710, 10711, 10712, 10713, 10716, 10717, 10718, 10719, 10721, 10722, 10723, 10724, 10725, 10727, 10728, 10730, 10731, 10732, 10734, 10735, 10737, 10738, 10739, 10740, 10741, 10742, 10744, 10745, 10747, 10748, 10749, 10750, 10751, 10752, 10754, 10755, 10756, 10757, 10758, 10760, 10761, 10763, 10764, 10765, 10766, 10767, 10769, 10770, 10774, 10775, 10776, 10777, 10780, 10781, 10783, 10784, 10787, 10788, 10789, 10790, 10791, 10792, 10793, 10796, 10797, 10799, 10800, 10801, 10802, 10803, 10805, 10806, 10808, 10809, 10811, 10812, 10813, 10814, 10815, 10817, 10818, 10820, 10821, 10822, 10823, 10824, 10825, 10826, 10827, 10828, 10830, 10832, 10834, 10835, 10836, 10837, 10838, 10841, 10843, 10844, 10846, 10847, 10849, 10850, 10851, 10853, 10854, 10855, 10857, 10858, 10860, 10861, 10862, 10864, 10865, 10866, 10868, 10869, 10871, 10873, 10874, 10875, 10876, 10877, 10879, 10882, 10883, 10884, 10885, 10887, 10888, 10889, 10890, 10892, 10895, 10896, 10897, 10900, 10901, 10902, 10903, 10904, 10905, 10906, 10907, 10909, 10916, 10918, 10919, 10920, 10922, 10923, 10926, 10927, 10928, 10929, 10931, 10933, 10934, 10935, 10936, 10937, 10938, 10941, 10942, 10945, 10946, 10947, 10948, 10951, 10952, 10953, 10954, 10957, 10958, 10959, 10960, 10961, 10962, 10963, 10965, 10967, 10968, 10973, 10974, 10975, 10980, 10981, 10986, 10988, 10989, 10990, 10992, 10993, 10994, 10995, 10996, 10997, 10999, 11002, 11003, 11004, 11005, 11006, 11007, 11008, 11009, 11010, 11011, 11014, 11015, 11016, 11017, 11018, 11020, 11023, 11024, 11025, 11027, 11028, 11029, 11031, 11032, 11033, 11034, 11035, 11036, 11037, 11039, 11040, 11041, 11042, 11045, 11046, 11047, 11053, 11054, 11056, 11057, 11058, 11059, 11060, 11061, 11062, 11063, 11064, 11066, 11067, 11068, 11069, 11070, 11071, 11072, 11074, 11077, 11079, 11080, 11081, 11082, 11084, 11086, 11087, 11088, 11089, 11090, 11091, 11092, 11094, 11097, 11098, 11099, 11102, 11103, 11108, 11114, 11115, 11121, 11122, 11128, 11129, 11130, 11136, 11148, 11149, 11150, 11155, 11156, 11157, 11160, 11163, 11166, 11167, 11168, 11169, 11170, 11171, 11173, 11175, 11177, 11180, 11181, 11182], "summary": {"covered_lines": 5729, "num_statements": 7554, "percent_covered": 71.59563924677899, "percent_covered_display": "72", "missing_lines": 1825, "excluded_lines": 0, "num_branches": 2536, "num_partial_branches": 417, "covered_branches": 1495, "missing_branches": 1041}, "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, 1244, 1247, 1250, 1258, 1262, 1277, 1278, 1279, 1334, 1335, 1348, 1376, 1408, 1416, 1420, 1424, 1428, 1444, 1445, 1446, 1455, 1459, 1464, 1468, 1469, 1470, 1478, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1552, 1568, 1572, 1576, 1601, 1604, 1609, 1613, 1616, 1632, 1639, 1652, 1653, 1658, 1659, 1667, 1668, 1670, 1671, 1672, 1673, 1674, 1676, 1677, 1678, 1679, 1681, 1693, 1703, 1708, 1709, 1710, 1711, 1717, 1726, 1770, 1771, 1780, 1781, 1782, 1783, 1796, 1813, 1814, 1893, 1953, 1954, 1955, 1956, 1957, 1962, 1963, 1964, 1978, 1979, 1980, 1981, 2035, 2051, 2059, 2072, 2112, 2114, 2129, 2130, 2131, 2132, 2134, 2135, 2136, 2137, 2138, 2143, 2156, 2157, 2161, 2168, 2171, 2177, 2181, 2186, 2191, 2219, 2261, 2264, 2274, 2277, 2280, 2283, 2286, 2289, 2296, 2328, 2340, 2345, 2346, 2347, 2349, 2358, 2359, 2361, 2407, 2410, 2413, 2414, 2415, 2416, 2418, 2419, 2420, 2421, 2425, 2429, 2430, 2431, 2432, 2433, 2434, 2437, 2440, 2442, 2443, 2444, 2445, 2446, 2447, 2449, 2450, 2452, 2453, 2455, 2457, 2458, 2459, 2460, 2462, 2463, 2465, 2469, 2470, 2471, 2473, 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2491, 2493, 2496, 2497, 2498, 2499, 2500, 2501, 2531, 2535, 2536, 2537, 2538, 2542, 2543, 2544, 2548, 2553, 2557, 2560, 2561, 2562, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2578, 2579, 2580, 2581, 2584, 2585, 2588, 2590, 2591, 2592, 2594, 2595, 2596, 2597, 2598, 2599, 2601, 2602, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2621, 2622, 2624, 2625, 2626, 2627, 2628, 2630, 2631, 2632, 2633, 2637, 2638, 2650, 2682, 2683, 2684, 2688, 2689, 2690, 2691, 2695, 2699, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2714, 2715, 2734, 2739, 2740, 2741, 2744, 2745, 2747, 2748, 2749, 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2759, 2760, 2761, 2762, 2765, 2766, 2767, 2769, 2770, 2771, 2831, 2833, 2834, 2836, 2838, 2839, 2840, 2841, 2842, 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, 2886, 2887, 2898, 2901, 2902, 2903, 2904, 2905, 2906, 2907, 2908, 2930, 2931, 2952, 2991, 2992, 2993, 2994, 2997, 3000, 3003, 3004, 3005, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3021, 3022, 3023, 3024, 3025, 3026, 3031, 3032, 3051, 3093, 3094, 3095, 3096, 3099, 3102, 3105, 3107, 3111, 3114, 3115, 3116, 3117, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134, 3135, 3138, 3139, 3140, 3141, 3142, 3143, 3147, 3148, 3149, 3150, 3162, 3193, 3194, 3195, 3196, 3208, 3234, 3237, 3240, 3243, 3244, 3245, 3248, 3249, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3260, 3261, 3262, 3263, 3264, 3265, 3266, 3267, 3270, 3271, 3272, 3273, 3274, 3275, 3279, 3280, 3291, 3307, 3308, 3309, 3310, 3311, 3312, 3314, 3316, 3317, 3318, 3319, 3320, 3326, 3332, 3336, 3337, 3338, 3342, 3343, 3344, 3354, 3355, 3356, 3357, 3362, 3375, 3376, 3377, 3378, 3395, 3400, 3401, 3402, 3403, 3414, 3437, 3438, 3442, 3456, 3457, 3463, 3473, 3531, 3546, 3547, 3548, 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3594, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3636, 3651, 3652, 3653, 3654, 3655, 3661, 3662, 3668, 3669, 3689, 3690, 3691, 3693, 3694, 3695, 3696, 3698, 3710, 3711, 3712, 3713, 3714, 3715, 3716, 3725, 3736, 3744, 3751, 3756, 3757, 3844, 3857, 3858, 3859, 3860, 3861, 3862, 3871, 3876, 3881, 3886, 3887, 3892, 3897, 3902, 3907, 3912, 3917, 3922, 3927, 3940, 3950, 3975, 3980, 3990, 4000, 4022, 4027, 4031, 4032, 4033, 4036, 4037, 4044, 4045, 4046, 4047, 4048, 4049, 4071, 4083, 4112, 4113, 4114, 4115, 4118, 4119, 4120, 4121, 4122, 4155, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4173, 4174, 4175, 4176, 4177, 4178, 4179, 4180, 4193, 4194, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, 4239, 4246, 4257, 4258, 4259, 4286, 4287, 4288, 4289, 4290, 4291, 4292, 4295, 4296, 4297, 4298, 4299, 4300, 4301, 4310, 4311, 4312, 4313, 4314, 4315, 4316, 4317, 4357, 4358, 4359, 4360, 4364, 4365, 4366, 4367, 4368, 4370, 4371, 4372, 4398, 4399, 4400, 4425, 4426, 4440, 4446, 4465, 4479, 4511, 4519, 4543, 4551, 4558, 4570, 4577, 4580, 4581, 4615, 4616, 4617, 4669, 4670, 4697, 4698, 4702, 4703, 4707, 4710, 4711, 4713, 4747, 4748, 4755, 4756, 4757, 4758, 4807, 4808, 4822, 4839, 4840, 4843, 4844, 4847, 4865, 4866, 4867, 4879, 4880, 4881, 4882, 4883, 4886, 4887, 4889, 4890, 4891, 4892, 4903, 4904, 4905, 4906, 4907, 4910, 4911, 4913, 4914, 4915, 4916, 4952, 4953, 4962, 4963, 4970, 4971, 4972, 4980, 4981, 4998, 4999, 5003, 5004, 5082, 5083, 5084, 5085, 5086, 5095, 5096, 5111, 5112, 5116, 5117, 5147, 5148, 5149, 5150, 5151, 5153, 5154, 5155, 5156, 5157, 5158, 5159, 5160, 5161, 5163, 5164, 5230, 5261, 5262, 5270, 5271, 5272, 5290, 5297, 5301, 5314, 5315, 5316, 5317, 5318, 5319, 5320, 5321, 5322, 5323, 5324, 5325, 5349, 5364, 5365, 5383, 5384, 5385, 5386, 5411, 5412, 5413, 5414, 5518, 5519, 5545, 5546, 5547, 5549, 5550, 5551, 5554, 5555, 5556, 5558, 5559, 5561, 5562, 5563, 5566, 5573, 5574, 5575, 5589, 5590, 5591, 5593, 5594, 5595, 5597, 5598, 5600, 5601, 5602, 5604, 5605, 5606, 5607, 5611, 5612, 5613, 5615, 5616, 5617, 5619, 5620, 5623, 5625, 5626, 5627, 5628, 5630, 5632, 5633, 5635, 5636, 5637, 5638, 5639, 5640, 5641, 5645, 5646, 5662, 5663, 5675, 5681, 5682, 5685, 5686, 5700, 5701, 5712, 5760, 5764, 5765, 5791, 5795, 5796, 5837, 5838, 5856, 5857, 5860, 5861, 5863, 5866, 5868, 5869, 5871, 5872, 5873, 5875, 5876, 5878, 5879, 5880, 5882, 5901, 5902, 5906, 5912, 5913, 5916, 5917, 5956, 5957, 5962, 5963, 5971, 5972, 5973, 5974, 6101, 6103, 6148, 6149, 6172, 6173, 6176, 6177, 6181, 6182, 6183, 6191, 6226, 6227, 6228, 6236, 6245, 6281, 6282, 6283, 6288, 6289, 6291, 6299, 6312, 6313, 6337, 6338, 6339, 6340, 6342, 6343, 6344, 6345, 6347, 6348, 6356, 6357, 6360, 6362, 6403, 6404, 6408, 6409, 6417, 6429, 6430, 6451, 6452, 6461, 6462, 6463, 6486, 6491, 6492, 6493, 6494, 6495, 6501, 6502, 6503, 6504, 6505, 6506, 6507, 6508, 6509, 6510, 6512, 6514, 6520, 6521, 6539, 6540, 6570, 6571, 6579, 6580, 6596, 6597, 6600, 6608, 6609, 6610, 6611, 6633, 6634, 6659, 6660, 6668, 6691, 6692, 6700, 6720, 6721, 6724, 6725, 6736, 6767, 6778, 6783, 6785, 6867, 6868, 6869, 6880, 6881, 6916, 6917, 6918, 6921, 6922, 6923, 6981, 6982, 6983, 7027, 7028, 7032, 7036, 7037, 7038, 7105, 7106, 7109, 7110, 7127, 7128, 7130, 7131, 7132, 7135, 7136, 7139, 7141, 7142, 7143, 7144, 7146, 7147, 7148, 7151, 7152, 7153, 7156, 7157, 7158, 7159, 7160, 7161, 7162, 7163, 7164, 7184, 7185, 7186, 7251, 7271, 7272, 7275, 7280, 7286, 7295, 7296, 7298, 7300, 7302, 7303, 7305, 7313, 7319, 7351, 7352, 7353, 7354, 7355, 7356, 7357, 7358, 7360, 7361, 7362, 7364, 7365, 7366, 7367, 7369, 7370, 7372, 7375, 7376, 7378, 7379, 7380, 7382, 7384, 7385, 7386, 7387, 7388, 7390, 7391, 7392, 7394, 7395, 7396, 7398, 7400, 7401, 7402, 7403, 7405, 7406, 7408, 7409, 7420, 7421, 7425, 7426, 7470, 7471, 7472, 7473, 7474, 7476, 7477, 7479, 7491, 7493, 7495, 7496, 7497, 7508, 7515, 7516, 7517, 7518, 7521, 7522, 7524, 7527, 7529, 7530, 7531, 7532, 7534, 7535, 7536, 7538, 7539, 7543, 7545, 7546, 7547, 7548, 7549, 7550, 7552, 7554, 7555, 7556, 7558, 7559, 7564, 7565, 7566, 7567, 7568, 7569, 7570, 7571, 7573, 7574, 7575, 7576, 7577, 7579, 7580, 7582, 7583, 7584, 7586, 7587, 7588, 7590, 7591, 7592, 7594, 7596, 7601, 7602, 7603, 7605, 7606, 7608, 7610, 7611, 7612, 7613, 7614, 7616, 7617, 7618, 7619, 7620, 7621, 7635, 7660, 7694, 7695, 7696, 7697, 7699, 7700, 7704, 7712, 7713, 7721, 7725, 7726, 7732, 7733, 7742, 7764, 7765, 7775, 7784, 7791, 7793, 7797, 7799, 7806, 7809, 7812, 7813, 7823, 7834, 7835, 7840, 7841, 7857, 7858, 7866, 7896, 7897, 7915, 7916, 7925, 7926, 7927, 7930, 7954, 7955, 7962, 7991, 7992, 7993, 7994, 8017, 8018, 8067, 8155, 8156, 8159, 8160, 8171, 8172, 8173, 8252, 8253, 8260, 8261, 8262, 8271, 8394, 8395, 8398, 8399, 8400, 8401, 8403, 8404, 8438, 8454, 8455, 8456, 8457, 8459, 8461, 8462, 8491, 8492, 8509, 8510, 8511, 8519, 8529, 8555, 8580, 8581, 8582, 8583, 8620, 8621, 8627, 8628, 8642, 8648, 8649, 8650, 8651, 8652, 8670, 8671, 8686, 8687, 8715, 8716, 8747, 8748, 8751, 8758, 8759, 8760, 8833, 8834, 8878, 8879, 8884, 8885, 8898, 8918, 8920, 8950, 8951, 8952, 8953, 8954, 8955, 8956, 8958, 8959, 8972, 8973, 8982, 9007, 9008, 9025, 9026, 9028, 9029, 9056, 9078, 9089, 9090, 9091, 9093, 9094, 9095, 9097, 9100, 9111, 9124, 9146, 9147, 9149, 9150, 9218, 9219, 9220, 9246, 9247, 9248, 9249, 9251, 9253, 9254, 9255, 9256, 9258, 9259, 9296, 9322, 9334, 9348, 9349, 9350, 9368, 9369, 9370, 9376, 9377, 9378, 9392, 9406, 9426, 9436, 9494, 9495, 9499, 9500, 9504, 9505, 9524, 9525, 9526, 9527, 9528, 9529, 9530, 9540, 9541, 9542, 9543, 9544, 9545, 9546, 9548, 9549, 9550, 9554, 9555, 9556, 9557, 9558, 9560, 9561, 9564, 9565, 9580, 9581, 9582, 9583, 9585, 9586, 9589, 9590, 9593, 9627, 9628, 9647, 9696, 9726, 9727, 9742, 9743, 9755, 9781, 9782, 9787, 9788, 9791, 9792, 9802, 9803, 9804, 9810, 9812, 9814, 9816, 9818, 9821, 9874, 9875, 9876, 9877, 9878, 9890, 9891, 9899, 9900, 9907, 9924, 9925, 9926, 9927, 9928, 9930, 9931, 9932, 9953, 9970, 9971, 9972, 9973, 9975, 9976, 9977, 9978, 9987, 10002, 10033, 10034, 10051, 10052, 10071, 10072, 10076, 10077, 10078, 10110, 10112, 10113, 10114, 10115, 10117, 10118, 10119, 10120, 10122, 10123, 10128, 10129, 10131, 10132, 10134, 10135, 10137, 10138, 10139, 10140, 10144, 10145, 10146, 10147, 10148, 10149, 10151, 10152, 10153, 10154, 10155, 10156, 10158, 10160, 10161, 10162, 10163, 10164, 10165, 10166, 10167, 10168, 10185, 10186, 10191, 10192, 10196, 10197, 10202, 10213, 10214, 10234, 10235, 10236, 10237, 10238, 10239, 10240, 10251, 10293, 10294, 10295, 10301, 10303, 10328, 10329, 10331, 10373, 10391, 10398, 10399, 10400, 10401, 10402, 10403, 10404, 10405, 10406, 10408, 10409, 10439, 10441, 10446, 10447, 10456, 10457, 10458, 10459, 10460, 10461, 10464, 10465, 10466, 10467, 10472, 10473, 10476, 10477, 10478, 10480, 10482, 10483, 10484, 10485, 10486, 10487, 10489, 10492, 10493, 10495, 10496, 10499, 10500, 10501, 10502, 10504, 10505, 10506, 10508, 10509, 10510, 10511, 10512, 10513, 10514, 10517, 10518, 10519, 10520, 10521, 10527, 10538, 10548, 10550, 10552, 10558, 10559, 10560, 10572, 10603, 10607, 10609, 10614, 10646, 10647, 10662, 10702, 10709, 10714, 10715, 10720, 10829, 10831, 10839, 10840, 10863, 10886, 10908, 10910, 10911, 10914, 10969, 10970, 10976, 10977, 10982, 10983, 10984, 10985, 10991, 10998, 11021, 11026, 11038, 11043, 11044, 11048, 11075, 11104, 11105, 11106, 11109, 11112, 11116, 11117, 11118, 11120, 11131, 11133, 11151, 11152], "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], [1214, 1215], [1219, 1220], [1242, 1243], [1267, 1272], [1274, 1275], [1303, 1305], [1318, 1320], [1360, 1361], [1360, 1363], [1433, 1434], [1433, 1435], [1452, 1453], [1452, 1457], [1454, 1456], [1458, 1460], [1463, 1465], [1467, 1471], [1477, 1480], [1536, 1537], [1536, 1538], [1582, 1583], [1583, 1584], [1600, 1603], [1603, 1606], [1608, 1611], [1612, 1615], [1638, 1641], [1661, 1662], [1692, 1694], [1702, 1704], [1716, 1718], [1742, 1743], [1769, 1772], [1792, 1793], [1792, 1801], [1795, 1798], [1837, 1838], [1837, 1843], [1840, 1837], [1840, 1841], [1855, 1856], [1855, 1858], [1858, 1859], [1858, 1860], [1860, 1861], [1860, 1863], [1864, 1865], [1880, 1881], [1880, 1896], [1882, -1882], [1882, 1882], [1882, 1884], [1884, 1885], [1884, 1888], [1888, -1888], [1888, 1888], [1888, 1889], [1889, 1890], [1970, 1971], [1970, 1972], [1991, 1992], [1991, 1994], [1997, 1998], [1997, 1999], [2014, -2002], [2014, 2015], [2017, 2018], [2017, 2021], [2034, 2038], [2042, 2043], [2050, 2055], [2058, 2062], [2062, -2062], [2062, 2062], [2062, 2063], [2071, 2075], [2105, 2106], [2105, 2116], [2108, 2109], [2108, 2116], [2109, 2110], [2109, 2116], [2110, 2111], [2116, -2100], [2116, 2117], [2123, -2123], [2123, -2120], [2123, 2123], [2149, 2150], [2149, 2153], [2155, 2159], [2160, 2163], [2164, 2166], [2166, 2167], [2197, 2198], [2197, 2199], [2228, 2229], [2228, 2231], [2229, 2230], [2260, -2260], [2260, -2255], [2322, 2323], [2322, 2324], [2344, 2350], [2354, 2355], [2354, 2362], [2356, 2357], [2808, 2809], [2877, 2878], [2879, 2880], [3324, 3325], [3325, -3323], [3330, 3331], [3331, -3329], [3367, 3368], [3367, 3369], [3383, -3381], [3383, 3384], [3383, 3385], [3391, 3392], [3391, 3393], [3393, 3394], [3411, 3412], [3411, 3430], [3413, 3416], [3416, 3417], [3416, 3419], [3419, -3419], [3419, 3419], [3419, 3420], [3424, 3425], [3424, 3427], [3436, 3440], [3440, 3441], [3441, 3444], [3444, 3445], [3444, 3448], [3445, 3444], [3445, 3446], [3455, 3459], [3459, 3460], [3460, 3459], [3460, 3461], [3470, 3471], [3471, 3470], [3471, 3472], [3480, 3481], [3480, 3483], [3481, 3480], [3481, 3482], [3492, 3494], [3492, 3495], [3501, -3501], [3501, -3498], [3501, 3501], [3506, 3507], [3506, 3508], [3508, -3508], [3508, -3504], [3508, 3508], [3528, 3532], [3533, -3533], [3533, 3534], [3533, 3541], [3536, 3537], [3536, 3540], [3541, 3545], [3545, 3549], [3557, 3558], [3557, 3562], [3579, 3580], [3650, 3657], [3659, -3659], [3659, 3659], [3659, 3660], [3660, 3665], [3704, 3705], [3724, 3727], [3735, 3738], [3743, 3746], [3762, 3763], [3762, 3764], [3784, 3785], [3784, 3789], [3785, -3783], [3785, 3786], [3786, -3783], [3786, 3787], [3792, -3783], [3792, 3793], [3838, 3839], [3838, 3840], [3840, 3841], [3841, -3841], [3841, 3841], [3841, 3842], [3851, -3851], [3851, -3848], [4019, 4020], [4026, 4029], [4035, 4038], [4070, 4073], [4073, 4074], [4095, 4096], [4152, 4153], [4162, 4172], [4172, 4182], [4184, 4186], [4188, 4189], [4188, 4206], [4192, 4188], [4236, 4237], [4241, 4242], [4254, -4254], [4254, 4254], [4254, 4256], [4285, 4294], [4294, -4294], [4294, 4305], [4307, -4307], [4307, 4307], [4307, 4308], [4323, 4325], [4451, 4452], [4451, 4458], [4454, -4454], [4454, 4455], [4458, 4459], [4461, -4461], [4461, 4462], [4478, -4478], [4478, -4475], [4485, 4486], [4485, 4487], [4487, 4488], [4508, 4509], [4532, -4531], [4532, 4533], [4533, 4532], [4533, 4534], [4562, -4562], [4562, 4562], [4562, 4563], [4562, 4564], [4565, 4566], [4565, 4569], [4569, 4571], [4571, 4572], [4584, 4585], [4584, 4589], [4596, 4597], [4596, 4598], [4607, 4608], [4607, 4610], [4610, 4611], [4623, 4624], [4623, 4625], [4628, 4629], [4628, 4630], [4668, 4672], [4672, 4673], [4672, 4676], [4682, 4683], [4682, 4688], [4683, 4684], [4683, 4686], [4690, 4691], [4690, 4694], [4694, 4695], [4694, 4696], [4696, 4699], [4699, 4700], [4699, 4701], [4701, 4704], [4704, 4705], [4709, 4715], [4719, 4720], [4719, 4721], [4731, 4732], [4736, 4737], [4736, 4738], [4746, 4750], [4751, -4751], [4751, 4754], [4754, 4759], [4768, 4769], [4768, 4770], [4778, 4780], [4778, 4782], [4782, -4782], [4782, 4782], [4782, 4786], [4787, -4787], [4787, 4787], [4787, 4790], [4794, 4795], [4794, 4796], [4805, 4810], [4810, -4810], [4810, 4810], [4810, 4813], [4819, 4821], [4819, 4825], [4821, 4824], [4828, 4829], [4828, 4830], [4838, 4842], [4842, 4846], [4846, 4850], [4856, -4856], [4856, 4856], [4856, 4857], [4860, 4861], [4860, 4863], [4871, 4872], [4871, 4873], [4895, 4896], [4895, 4897], [4919, 4920], [4919, 4921], [4930, 4931], [4930, 4934], [4934, 4935], [4941, -4941], [4941, 4942], [4942, -4942], [4942, 4944], [4957, 4958], [4957, 4965], [4967, 4968], [4985, 4986], [4985, 4987], [4997, 5001], [5002, 5006], [5011, 5012], [5011, 5013], [5036, 5037], [5036, 5038], [5038, 5039], [5038, 5041], [5044, -5043], [5044, 5045], [5053, 5054], [5078, 5079], [5094, 5098], [5098, 5099], [5098, 5102], [5100, 5101], [5108, 5109], [5108, 5113], [5110, 5108], [5143, 5144], [5167, 5168], [5167, 5169], [5199, 5200], [5199, 5206], [5200, 5201], [5200, 5204], [5207, 5208], [5207, 5211], [5211, 5212], [5211, 5216], [5216, -5216], [5216, 5216], [5216, 5217], [5229, 5231], [5238, 5239], [5238, 5245], [5260, 5265], [5281, 5282], [5281, 5310], [5286, 5286], [5286, 5292], [5296, 5298], [5300, 5302], [5302, 5281], [5302, 5304], [5306, 5307], [5313, -5312], [5334, 5335], [5334, 5337], [5353, 5354], [5353, 5366], [5354, 5353], [5354, 5355], [5358, 5359], [5358, 5363], [5363, 5353], [5373, 5374], [5373, 5379], [5374, 5373], [5374, 5375], [5375, 5376], [5376, 5377], [5399, 5400], [5399, 5401], [5405, 5406], [5405, 5407], [5419, 5420], [5419, 5422], [5420, 5419], [5420, 5421], [5425, 5426], [5425, 5427], [5449, 5450], [5449, 5453], [5455, 5456], [5455, 5459], [5459, 5460], [5459, 5463], [5466, 5467], [5466, 5470], [5480, 5481], [5480, 5482], [5497, 5498], [5497, 5501], [5498, -5498], [5498, 5498], [5498, 5499], [5504, 5505], [5504, 5506], [5517, 5521], [5524, 5525], [5524, 5528], [5532, 5533], [5532, 5534], [5578, 5579], [5578, 5580], [5649, 5650], [5649, 5651], [5661, 5665], [5671, 5672], [5671, 5674], [5674, 5677], [5680, 5684], [5684, 5688], [5688, 5689], [5688, 5694], [5689, 5690], [5689, 5691], [5691, 5688], [5691, 5692], [5697, 5698], [5697, 5714], [5703, 5697], [5703, 5704], [5705, 5703], [5705, 5706], [5706, 5705], [5706, 5707], [5708, 5709], [5717, 5718], [5717, 5719], [5738, 5739], [5756, 5757], [5756, 5779], [5757, 5758], [5767, 5768], [5767, 5777], [5769, 5770], [5769, 5773], [5787, 5788], [5787, 5810], [5788, 5789], [5798, 5799], [5798, 5808], [5802, 5803], [5814, 5815], [5814, 5831], [5815, 5814], [5815, 5816], [5816, 5814], [5816, 5817], [5817, 5819], [5823, 5814], [5823, 5824], [5825, 5826], [5826, 5827], [5836, 5840], [5840, 5841], [5840, 5852], [5847, 5848], [5847, 5850], [5855, 5859], [5859, 5865], [5865, 5884], [5889, 5890], [5889, 5891], [5900, 5904], [5904, 5905], [5904, 5931], [5905, 5908], [5911, 5915], [5915, 5919], [5919, 5904], [5919, 5920], [5920, 5919], [5920, 5921], [5922, 5923], [5922, 5924], [5924, 5925], [5924, 5927], [5935, 5936], [5935, 5937], [5955, 5960], [5961, 5966], [5968, 5969], [5968, 5980], [5970, 5980], [5988, 5989], [5988, 5990], [6022, 6023], [6022, 6024], [6057, 6058], [6057, 6061], [6062, 6063], [6062, 6064], [6064, 6065], [6064, 6067], [6074, 6075], [6074, 6081], [6078, 6079], [6078, 6081], [6083, 6084], [6083, 6089], [6084, 6085], [6084, 6087], [6091, 6092], [6091, 6098], [6095, 6096], [6095, 6098], [6100, 6105], [6111, 6112], [6111, 6113], [6135, 6136], [6135, 6137], [6152, 6153], [6152, 6154], [6171, 6175], [6175, 6179], [6186, 6188], [6195, 6196], [6195, 6197], [6204, 6205], [6204, 6206], [6209, 6210], [6209, 6211], [6225, 6230], [6233, 6234], [6233, 6249], [6234, 6235], [6235, 6238], [6240, 6241], [6240, 6243], [6244, 6247], [6253, 6254], [6253, 6255], [6272, 6273], [6272, 6277], [6273, 6274], [6275, 6276], [6287, 6290], [6290, 6292], [6292, 6293], [6292, 6296], [6297, 6298], [6297, 6300], [6298, 6297], [6305, 6306], [6306, 6307], [6306, 6311], [6311, 6315], [6316, 6317], [6322, 6323], [6322, 6324], [6355, 6359], [6359, 6361], [6361, 6364], [6368, 6369], [6368, 6371], [6374, 6375], [6374, 6380], [6380, 6381], [6385, 6386], [6385, 6387], [6402, 6406], [6407, 6412], [6412, -6412], [6412, 6413], [6413, 6414], [6413, 6419], [6414, 6415], [6415, -6415], [6415, 6415], [6415, 6421], [6421, 6422], [6421, 6476], [6422, 6423], [6422, 6425], [6428, 6432], [6434, 6435], [6434, 6473], [6442, 6443], [6442, 6445], [6447, 6448], [6447, 6450], [6450, 6454], [6457, 6458], [6457, 6460], [6465, 6434], [6465, 6466], [6473, 6421], [6473, 6474], [6519, 6523], [6538, 6542], [6550, 6551], [6550, 6552], [6569, 6573], [6578, 6582], [6583, 6584], [6583, 6613], [6589, 6590], [6589, 6593], [6595, 6599], [6599, 6602], [6605, 6606], [6616, 6617], [6616, 6618], [6632, 6635], [6638, 6639], [6643, 6644], [6643, 6645], [6658, 6662], [6665, 6666], [6665, 6671], [6667, 6669], [6669, 6665], [6669, 6670], [6675, 6676], [6675, 6677], [6690, 6694], [6697, 6698], [6697, 6703], [6699, 6701], [6701, 6697], [6701, 6702], [6707, 6708], [6707, 6709], [6723, 6726], [6727, 6728], [6727, 6729], [6728, -6728], [6728, 6727], [6728, 6728], [6729, -6729], [6729, 6729], [6729, 6730], [6730, 6731], [6730, 6735], [6731, 6732], [6731, 6734], [6735, 6737], [6737, 6738], [6742, 6743], [6742, 6744], [6760, 6761], [6760, 6769], [6762, -6762], [6762, 6762], [6762, 6763], [6763, 6764], [6765, -6765], [6765, 6765], [6765, 6766], [6766, 6769], [6775, 6776], [6775, 6831], [6777, 6780], [6782, 6787], [6789, 6790], [6789, 6792], [6795, 6796], [6795, 6800], [6802, 6803], [6802, 6807], [6808, 6809], [6808, 6811], [6814, 6815], [6814, 6820], [6824, -6824], [6824, 6824], [6824, 6825], [6824, 6829], [6831, 6832], [6836, 6837], [6836, 6838], [6854, 6855], [6854, 6856], [6866, 6871], [6879, 6883], [6887, -6887], [6887, 6887], [6887, 6889], [6889, 6890], [6892, 6893], [6892, 6899], [6903, 6904], [6903, 6905], [6915, 6920], [6920, 6925], [6931, 6932], [6931, 6935], [6936, 6937], [6936, 6941], [6944, 6945], [6944, 6946], [6967, 6968], [6967, 6988], [6971, 6972], [6971, 6974], [6974, 6975], [6974, 6980], [6975, 6976], [6976, 6977], [6977, 6978], [6978, 6967], [6980, 6985], [6985, -6985], [6985, 6985], [6985, 6986], [6992, -6992], [6992, 6992], [6992, 6994], [6994, 6995], [6994, 7006], [6998, 6999], [6998, 7004], [6999, 7000], [6999, 7002], [7009, 7010], [7009, 7011], [7026, 7030], [7031, 7034], [7057, 7058], [7057, 7060], [7066, 7067], [7066, 7073], [7078, 7079], [7078, 7084], [7087, 7088], [7087, 7089], [7104, 7108], [7108, 7112], [7112, 7113], [7112, 7116], [7119, 7120], [7167, 7168], [7167, 7169], [7183, 7188], [7192, 7193], [7192, 7194], [7250, 7252], [7267, 7268], [7267, 7270], [7270, -7270], [7270, 7274], [7274, 7277], [7279, 7282], [7285, 7288], [7288, 7289], [7288, 7307], [7289, 7290], [7289, 7292], [7294, 7297], [7297, 7299], [7309, 7310], [7309, 7312], [7312, 7314], [7318, 7321], [7325, 7326], [7325, 7329], [7345, 7346], [7419, 7423], [7431, -7431], [7431, -7430], [7431, 7431], [7441, -7441], [7441, 7441], [7441, 7443], [7451, 7452], [7451, 7501], [7457, 7458], [7457, 7460], [7463, 7464], [7463, 7466], [7466, 7467], [7466, 7484], [7469, 7478], [7478, 7480], [7480, 7481], [7480, 7486], [7488, 7451], [7488, 7489], [7494, 7499], [7505, 7506], [7625, -7625], [7625, -7623], [7634, 7637], [7634, 7641], [7638, 7639], [7638, 7641], [7638, 7644], [7639, -7639], [7639, 7638], [7639, 7639], [7646, -7646], [7646, 7646], [7646, 7647], [7651, 7652], [7651, 7653], [7658, 7659], [7658, 7681], [7659, 7662], [7664, 7665], [7664, 7667], [7667, 7668], [7667, 7676], [7670, 7671], [7672, 7673], [7672, 7674], [7676, 7658], [7676, 7677], [7686, 7687], [7688, 7689], [7688, 7710], [7689, 7690], [7689, 7708], [7691, 7689], [7691, 7692], [7693, 7701], [7701, 7702], [7706, 7707], [7710, 7711], [7710, 7714], [7711, -7711], [7711, -7683], [7711, 7711], [7720, 7724], [7724, 7728], [7731, 7735], [7739, 7740], [7739, 7777], [7741, 7744], [7748, 7749], [7748, 7755], [7750, -7750], [7750, 7750], [7750, 7753], [7763, 7767], [7774, 7739], [7783, 7786], [7786, 7787], [7788, 7789], [7788, 7790], [7790, 7792], [7792, 7794], [7794, 7795], [7794, 7796], [7796, 7786], [7805, 7808], [7808, 7811], [7811, 7815], [7818, 7819], [7818, 7845], [7820, 7821], [7820, 7822], [7822, 7824], [7824, 7825], [7831, 7832], [7831, 7837], [7833, 7837], [7850, 7851], [7850, 7853], [7854, 7855], [7854, 7859], [7855, 7856], [7856, 7854], [7862, -7861], [7862, 7863], [7865, 7868], [7872, 7873], [7872, 7877], [7884, 7885], [7884, 7886], [7900, 7901], [7900, 7902], [7914, 7918], [7922, 7923], [7922, 7929], [7924, 7934], [7929, 7931], [7931, 7932], [7939, 7940], [7939, 7941], [7953, 7957], [7959, 7960], [7966, 7967], [7966, 7968], [7979, 7980], [7979, 7981], [7987, 7988], [7997, 7998], [7997, 7999], [8016, 8020], [8025, 8026], [8025, 8031], [8034, 8035], [8034, 8037], [8060, 8061], [8060, 8072], [8066, 8068], [8075, 8076], [8075, 8077], [8089, 8090], [8089, 8091], [8103, 8104], [8103, 8105], [8117, 8118], [8117, 8119], [8131, 8132], [8131, 8133], [8154, 8158], [8158, 8162], [8166, 8167], [8166, 8175], [8167, 8168], [8167, 8175], [8176, 8177], [8176, 8181], [8184, 8185], [8184, 8186], [8198, 8199], [8198, 8200], [8212, 8213], [8212, 8214], [8226, 8227], [8226, 8228], [8240, 8241], [8240, 8242], [8251, 8255], [8270, 8273], [8280, 8281], [8280, 8328], [8281, 8282], [8281, 8284], [8291, 8293], [8291, 8296], [8297, 8298], [8297, 8303], [8303, 8304], [8304, 8305], [8304, 8310], [8310, 8311], [8311, 8312], [8311, 8324], [8313, 8314], [8313, 8315], [8315, 8316], [8315, 8318], [8331, 8332], [8331, 8333], [8365, 8366], [8365, 8370], [8367, 8365], [8367, 8368], [8370, 8371], [8370, 8374], [8389, 8390], [8389, 8393], [8393, 8397], [8397, 8406], [8407, 8408], [8407, 8411], [8417, 8418], [8417, 8420], [8423, 8424], [8423, 8425], [8434, 8435], [8434, 8449], [8437, 8440], [8441, 8442], [8441, 8444], [8449, 8450], [8450, 8451], [8465, 8466], [8465, 8467], [8478, 8479], [8478, 8480], [8490, 8494], [8494, 8495], [8502, 8503], [8502, 8512], [8503, 8504], [8503, 8506], [8506, 8507], [8506, 8508], [8508, 8502], [8516, 8517], [8516, 8518], [8518, 8520], [8520, 8521], [8520, 8523], [8528, 8531], [8558, 8559], [8558, 8560], [8578, 8579], [8578, 8592], [8579, 8585], [8595, 8596], [8595, 8597], [8609, 8610], [8609, 8614], [8614, 8615], [8614, 8622], [8626, 8630], [8633, 8634], [8641, 8646], [8647, 8654], [8657, 8658], [8657, 8659], [8674, 8675], [8674, 8676], [8685, 8689], [8703, 8704], [8703, 8705], [8714, 8718], [8728, 8729], [8728, 8730], [8746, 8750], [8750, 8753], [8768, 8769], [8768, 8771], [8776, 8777], [8776, 8780], [8796, 8797], [8800, 8801], [8800, 8803], [8818, 8819], [8818, 8820], [8837, 8838], [8837, 8839], [8859, 8860], [8859, 8861], [8877, 8881], [8883, 8886], [8894, 8895], [8894, 8905], [8897, 8899], [8911, 8912], [8911, 8916], [8917, 8922], [8926, 8927], [8926, 8928], [8947, 8948], [8949, 8961], [8967, 8968], [8967, 8977], [8968, 8967], [8968, 8969], [8971, 8975], [8977, 8978], [8977, 8979], [8979, 8980], [8986, 8987], [8986, 8988], [9006, 9010], [9015, -9015], [9015, 9015], [9015, 9016], [9016, -9016], [9016, 9016], [9016, 9019], [9024, 9032], [9033, -9033], [9033, 9033], [9033, 9035], [9037, 9038], [9037, 9063], [9041, 9042], [9041, 9045], [9042, -9042], [9042, 9043], [9042, 9045], [9048, 9049], [9055, 9058], [9066, 9067], [9066, 9068], [9081, 9082], [9081, 9083], [9103, 9104], [9103, 9105], [9114, 9115], [9114, 9116], [9123, 9126], [9131, 9132], [9131, 9133], [9153, 9154], [9153, 9155], [9174, 9175], [9174, 9180], [9175, 9174], [9175, 9176], [9185, 9186], [9185, 9187], [9214, 9215], [9265, 9266], [9265, 9276], [9266, 9267], [9276, 9277], [9276, 9279], [9310, 9311], [9310, 9312], [9325, 9326], [9325, 9327], [9333, 9336], [9339, 9340], [9339, 9341], [9347, 9351], [9354, 9355], [9354, 9356], [9366, 9367], [9374, 9375], [9382, 9383], [9382, 9384], [9391, 9393], [9396, 9397], [9396, 9398], [9405, 9407], [9410, 9411], [9410, 9412], [9425, 9427], [9430, 9431], [9430, 9432], [9439, 9440], [9445, 9446], [9445, 9448], [9537, 9538], [9537, 9552], [9539, 9537], [9553, 9566], [9598, -9598], [9598, 9598], [9598, 9599], [9600, -9600], [9600, 9600], [9600, 9601], [9605, 9606], [9605, 9612], [9606, 9607], [9607, 9606], [9607, 9608], [9612, 9613], [9612, 9630], [9614, 9615], [9615, 9614], [9615, 9616], [9619, 9620], [9619, 9624], [9621, 9622], [9621, 9624], [9646, 9650], [9673, 9674], [9673, 9676], [9686, 9688], [9686, 9689], [9701, 9702], [9725, 9729], [9729, 9730], [9729, 9734], [9734, 9735], [9734, 9746], [9736, -9736], [9736, 9736], [9736, 9737], [9737, 9738], [9738, 9739], [9754, 9757], [9759, 9760], [9759, 9762], [9766, 9767], [9766, 9769], [9772, 9773], [9772, 9774], [9780, 9784], [9786, 9790], [9790, 9794], [9796, 9797], [9796, 9799], [9840, 9841], [9840, 9851], [9844, 9845], [9844, 9848], [9852, 9853], [9852, 9855], [9855, 9856], [9855, 9858], [9884, 9885], [9884, 9906], [9885, 9887], [9885, 9895], [9887, 9888], [9887, 9892], [9895, 9884], [9895, 9896], [9902, 9903], [9902, 9904], [9906, 9908], [9948, 9949], [9948, 9955], [9949, 9950], [9986, 9989], [9989, -9989], [9989, 9989], [9989, 9990], [9989, 9992], [9997, 9998], [9997, 10004], [10001, 10004], [10014, 10015], [10014, 10018], [10015, 10014], [10015, 10016], [10021, 10022], [10021, 10023], [10037, 10038], [10037, 10039], [10050, 10053], [10057, 10058], [10057, 10059], [10070, 10073], [10074, -10074], [10074, 10075], [10083, 10084], [10083, 10085], [10096, 10097], [10096, 10098], [10184, 10188], [10190, 10194], [10195, 10199], [10199, 10200], [10199, 10203], [10201, 10199], [10208, 10209], [10212, 10216], [10216, 10217], [10216, 10220], [10223, -10223], [10223, 10224], [10246, 10247], [10246, 10254], [10249, 10250], [10297, 10299], [10297, 10305], [10307, 10308], [10307, 10309], [10314, -10314], [10314, 10314], [10314, 10315], [10314, 10316], [10320, -10318], [10320, 10321], [10320, 10322], [10327, 10332], [10340, 10341], [10340, 10343], [10343, -10337], [10343, 10344], [10343, 10365], [10344, 10343], [10344, 10345], [10348, 10349], [10348, 10352], [10371, 10372], [10371, 10394], [10372, 10375], [10376, -10376], [10376, 10376], [10376, 10377], [10377, -10377], [10377, 10377], [10377, 10378], [10377, 10390], [10390, 10392], [10432, 10433], [10432, 10442], [10455, 10470], [10525, 10528], [10537, 10539], [10543, 10544], [10543, 10554], [10551, 10553], [10569, 10575], [10586, -10586], [10586, 10587], [10600, 10601], [10600, 10611], [10601, 10602], [10601, 10611], [10602, 10604], [10604, 10605], [10608, 10610], [10630, 10632], [10630, 10637], [10633, 10634], [10637, 10638], [10638, 10639], [10639, 10640], [10661, 10663], [10664, 10665], [10664, 10667], [10665, 10666], [10665, 10667], [10686, 10687], [10686, 10688], [10706, 10707], [10706, 10708], [10708, -10704], [10708, 10710], [10710, 10711], [10710, 10725], [10713, 10716], [10716, 10717], [10716, 10724], [10719, 10721], [10730, -10727], [10730, 10731], [10730, 10732], [10737, -10734], [10737, 10738], [10737, 10742], [10739, 10740], [10739, 10741], [10747, -10744], [10747, 10748], [10747, 10749], [10750, 10751], [10750, 10752], [10756, -10754], [10756, 10757], [10756, 10758], [10764, 10765], [10764, 10766], [10788, 10789], [10788, 10790], [10799, 10800], [10799, 10801], [10801, 10802], [10801, 10806], [10802, 10803], [10802, 10805], [10811, 10812], [10811, 10813], [10813, 10814], [10813, 10815], [10828, 10830], [10830, 10832], [10860, -10857], [10860, 10861], [10860, 10866], [10862, 10864], [10875, -10873], [10875, 10876], [10875, 10877], [10882, 10883], [10882, 10884], [10885, 10887], [10903, 10904], [10903, 10909], [10907, 10903], [10918, 10919], [10918, 10922], [10946, 10947], [10947, 10948], [10947, 10951], [10952, 10953], [10953, 10954], [10953, 10957], [10958, 10959], [10959, 10960], [10959, 10963], [10968, 10973], [10973, 10974], [10973, 10980], [10975, 10973], [10981, 10986], [10990, 10992], [10992, 10993], [10992, 10995], [10995, 10996], [10995, 10999], [10997, 10999], [11025, 11027], [11027, 11028], [11027, 11029], [11035, 11036], [11037, 11039], [11039, 11035], [11039, 11040], [11041, 11042], [11041, 11045], [11046, 11047], [11047, -11047], [11047, -11031], [11047, 11047], [11097, 11098], [11097, 11099], [11102, 11103], [11103, 11108], [11108, 11114], [11130, 11136], [11148, 11149], [11148, 11155], [11173, 11175]], "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], [1214, 1219], [1219, 1224], [1242, 1244], [1267, 1279], [1274, 1277], [1303, 1309], [1318, 1323], [1454, 1455], [1458, 1459], [1463, 1464], [1467, 1468], [1477, 1478], [1490, 1491], [1490, 1496], [1491, 1492], [1491, 1493], [1582, -1578], [1583, -1578], [1600, 1601], [1603, 1604], [1608, 1609], [1612, 1613], [1638, 1639], [1661, 1664], [1692, 1693], [1702, 1703], [1709, 1710], [1709, 1711], [1716, 1717], [1742, 1744], [1769, 1770], [1781, 1782], [1781, 1783], [1795, 1796], [1864, 1866], [1889, 1893], [2034, 2035], [2042, 2065], [2050, 2051], [2058, 2059], [2062, 2042], [2071, 2072], [2110, 2116], [2130, 2131], [2130, 2134], [2135, 2136], [2135, 2138], [2155, 2156], [2160, 2161], [2164, 2171], [2166, 2168], [2229, 2228], [2260, 2261], [2344, 2345], [2346, 2347], [2346, 2349], [2356, 2358], [2358, 2359], [2358, 2361], [2414, 2415], [2414, 2416], [2416, 2418], [2416, 2419], [2419, 2420], [2419, 2421], [2429, 2430], [2429, 2431], [2431, 2432], [2431, 2434], [2442, 2443], [2442, 2445], [2443, 2444], [2443, 2450], [2445, 2446], [2445, 2449], [2446, 2447], [2446, 2450], [2455, 2457], [2455, 2460], [2460, 2462], [2460, 2465], [2469, 2470], [2469, 2473], [2475, 2476], [2475, 2478], [2476, 2477], [2476, 2493], [2478, 2479], [2478, 2481], [2479, 2480], [2479, 2493], [2481, 2482], [2481, 2484], [2482, 2483], [2482, 2493], [2484, 2485], [2484, 2487], [2485, 2486], [2485, 2493], [2487, 2488], [2487, 2491], [2488, 2489], [2488, 2493], [2497, 2498], [2497, 2499], [2499, 2500], [2499, 2501], [2536, 2537], [2536, 2538], [2542, 2543], [2542, 2544], [2568, 2569], [2568, 2570], [2570, 2571], [2570, 2572], [2572, 2573], [2572, 2574], [2578, 2579], [2578, 2581], [2590, -2590], [2590, 2591], [2594, 2595], [2594, 2618], [2595, 2596], [2595, 2618], [2596, 2597], [2596, 2598], [2598, 2599], [2598, 2601], [2601, 2602], [2601, 2604], [2604, 2605], [2604, 2606], [2606, 2607], [2606, 2618], [2607, 2608], [2607, 2618], [2608, 2609], [2608, 2610], [2610, 2611], [2610, 2612], [2612, 2613], [2612, 2614], [2614, 2615], [2614, 2616], [2616, 2617], [2616, 2618], [2622, 2624], [2622, 2631], [2624, 2625], [2624, 2627], [2627, 2628], [2627, 2630], [2631, 2632], [2631, 2633], [2689, 2690], [2689, 2691], [2704, 2705], [2704, 2706], [2706, 2707], [2706, 2708], [2708, 2709], [2708, 2710], [2747, 2748], [2747, 2769], [2750, 2751], [2750, 2753], [2751, 2752], [2751, 2769], [2753, 2754], [2753, 2756], [2754, 2755], [2754, 2769], [2756, 2759], [2756, 2762], [2760, 2761], [2760, 2769], [2762, 2765], [2762, 2769], [2766, 2767], [2766, 2769], [2769, 2770], [2769, 2771], [2808, 2810], [2833, -2833], [2833, 2834], [2838, 2839], [2838, 2840], [2840, 2841], [2840, 2842], [2842, 2843], [2842, 2844], [2844, 2845], [2844, 2846], [2846, 2847], [2846, 2849], [2849, 2850], [2849, 2851], [2851, 2852], [2851, 2853], [2853, 2854], [2853, 2855], [2855, 2856], [2855, 2857], [2857, 2858], [2857, 2859], [2859, 2860], [2859, 2861], [2861, 2862], [2861, 2863], [2863, 2864], [2863, 2865], [2865, 2866], [2865, 2867], [2867, 2868], [2867, 2869], [2869, 2870], [2869, 2871], [2871, 2872], [2871, 2873], [2877, 2879], [2879, 2882], [2901, 2902], [2901, 2903], [2991, 2992], [2991, 2994], [3009, -3009], [3009, 3010], [3012, 3013], [3012, 3018], [3013, 3014], [3013, 3018], [3014, 3015], [3014, 3018], [3015, 3016], [3015, 3018], [3016, 3017], [3016, 3018], [3022, 3023], [3022, 3024], [3024, 3025], [3024, 3026], [3094, 3095], [3094, 3096], [3115, -3115], [3115, 3116], [3119, 3120], [3119, 3135], [3120, 3121], [3120, 3135], [3121, 3122], [3121, 3135], [3122, 3123], [3122, 3135], [3123, 3124], [3123, 3135], [3124, 3125], [3124, 3135], [3125, 3126], [3125, 3135], [3126, 3127], [3126, 3135], [3127, 3128], [3127, 3135], [3128, 3129], [3128, 3135], [3129, 3130], [3129, 3135], [3130, 3131], [3130, 3135], [3131, 3132], [3131, 3135], [3132, 3133], [3132, 3135], [3133, 3134], [3133, 3135], [3139, 3140], [3139, 3141], [3141, 3142], [3141, 3143], [3251, 3252], [3251, 3253], [3253, 3254], [3253, 3255], [3255, 3256], [3255, 3257], [3257, 3258], [3257, 3259], [3259, 3260], [3259, 3261], [3261, 3262], [3261, 3263], [3263, 3264], [3263, 3265], [3265, 3266], [3265, 3267], [3271, 3272], [3271, 3273], [3273, 3274], [3273, 3275], [3307, 3308], [3307, 3310], [3310, 3311], [3310, 3314], [3316, 3317], [3316, 3320], [3324, -3323], [3325, 3326], [3330, -3329], [3331, 3332], [3336, -3335], [3336, 3337], [3337, -3335], [3337, 3338], [3342, -3341], [3342, 3343], [3343, -3341], [3343, 3344], [3354, 3355], [3354, 3357], [3355, 3354], [3355, 3356], [3375, 3376], [3375, 3377], [3393, 3395], [3413, 3414], [3436, 3437], [3440, 3444], [3441, 3442], [3455, 3456], [3459, 3463], [3470, 3473], [3528, 3531], [3541, 3547], [3545, 3546], [3579, 3582], [3582, 3583], [3582, 3596], [3588, 3589], [3588, 3594], [3650, 3651], [3660, 3661], [3690, 3691], [3690, 3693], [3704, 3710], [3711, 3712], [3711, 3716], [3724, 3725], [3735, 3736], [3743, 3744], [3840, 3844], [3857, 3858], [3857, 3859], [3860, 3861], [3860, 3862], [4019, 4022], [4026, 4027], [4035, 4036], [4044, 4045], [4044, 4047], [4070, 4071], [4073, 4083], [4095, 4097], [4152, 4155], [4162, 4163], [4164, 4165], [4164, 4172], [4166, 4167], [4166, 4169], [4172, 4173], [4174, 4175], [4174, 4182], [4176, 4177], [4176, 4180], [4184, 4206], [4192, 4193], [4194, 4188], [4194, 4196], [4236, 4239], [4241, 4246], [4258, 4259], [4258, 4262], [4285, 4286], [4286, 4287], [4286, 4292], [4294, 4295], [4295, 4296], [4295, 4301], [4311, 4312], [4311, 4317], [4323, 4326], [4359, 4360], [4359, 4364], [4458, 4465], [4478, 4479], [4487, 4489], [4508, 4511], [4569, 4570], [4571, 4573], [4610, 4615], [4668, 4669], [4696, 4697], [4701, 4702], [4704, 4707], [4709, 4710], [4710, 4711], [4710, 4713], [4731, 4733], [4746, 4747], [4754, 4755], [4756, -4756], [4756, 4757], [4757, 4758], [4757, 4759], [4805, 4807], [4821, 4822], [4838, 4839], [4842, 4843], [4846, 4847], [4887, -4887], [4887, 4889], [4889, 4890], [4889, 4891], [4911, -4911], [4911, 4913], [4913, 4914], [4913, 4915], [4934, 4936], [4967, 4970], [4997, 4998], [5002, 5003], [5053, -5053], [5053, -5050], [5078, 5082], [5082, -5075], [5082, 5083], [5094, 5095], [5100, 5098], [5110, 5111], [5143, 5147], [5148, 5149], [5148, 5150], [5149, -5149], [5149, 5148], [5150, 5151], [5150, 5153], [5151, -5151], [5151, 5150], [5153, 5154], [5153, 5164], [5154, 5153], [5154, 5155], [5157, 5154], [5157, 5158], [5229, 5230], [5260, 5261], [5286, 5290], [5296, 5297], [5300, 5301], [5306, 5281], [5313, 5314], [5315, 5316], [5315, 5325], [5316, 5315], [5316, 5317], [5317, 5318], [5317, 5319], [5320, 5315], [5320, 5321], [5321, -5312], [5321, 5322], [5363, 5364], [5375, 5373], [5376, 5373], [5383, 5384], [5383, 5386], [5384, 5383], [5384, 5385], [5411, 5412], [5411, 5414], [5412, 5411], [5412, 5413], [5517, 5518], [5545, 5546], [5545, 5549], [5555, 5556], [5555, 5558], [5573, 5574], [5573, 5575], [5589, 5590], [5589, 5593], [5593, 5594], [5593, 5597], [5600, 5601], [5600, 5632], [5612, -5612], [5612, 5613], [5626, 5627], [5626, 5630], [5661, 5662], [5674, 5675], [5680, 5681], [5684, 5685], [5708, 5712], [5738, 5741], [5757, 5760], [5788, 5791], [5802, 5804], [5817, 5814], [5825, 5830], [5826, 5830], [5836, 5837], [5855, 5856], [5856, 5857], [5856, 5859], [5859, 5860], [5860, 5861], [5860, 5863], [5861, -5861], [5861, 5865], [5863, -5863], [5863, 5865], [5865, 5866], [5868, 5869], [5868, 5878], [5872, 5873], [5872, 5875], [5875, 5876], [5875, 5886], [5879, 5880], [5879, 5882], [5900, 5901], [5905, 5906], [5911, 5912], [5915, 5916], [5955, 5956], [5961, 5962], [5970, 5971], [6100, 6101], [6171, 6172], [6175, 6176], [6186, 6191], [6225, 6226], [6234, 6250], [6235, 6236], [6244, 6245], [6273, 6277], [6275, 6273], [6287, 6288], [6290, 6291], [6298, 6299], [6305, 6319], [6311, 6312], [6316, 6318], [6337, 6338], [6337, 6342], [6338, 6339], [6338, 6340], [6343, 6344], [6343, 6347], [6355, 6356], [6359, 6360], [6361, 6362], [6380, 6382], [6402, 6403], [6407, 6408], [6414, 6417], [6428, 6429], [6450, 6451], [6492, 6493], [6492, 6495], [6501, -6501], [6501, 6502], [6503, 6504], [6503, 6514], [6509, 6510], [6509, 6512], [6519, 6520], [6538, 6539], [6569, 6570], [6578, 6579], [6595, 6596], [6599, 6600], [6605, 6608], [6632, 6633], [6638, 6640], [6658, 6659], [6667, 6668], [6690, 6691], [6699, 6700], [6723, 6724], [6735, 6736], [6737, 6739], [6763, 6765], [6766, 6767], [6777, 6778], [6782, 6783], [6831, 6833], [6866, 6867], [6879, 6880], [6889, 6900], [6915, 6916], [6920, 6921], [6975, 6967], [6976, 6967], [6977, 6967], [6978, 6980], [6980, 6981], [7026, 7027], [7031, 7032], [7104, 7105], [7108, 7109], [7119, 7135], [7128, 7130], [7128, 7132], [7135, 7136], [7135, 7139], [7141, 7142], [7141, 7146], [7163, -7163], [7163, 7164], [7183, 7184], [7250, 7251], [7270, 7271], [7274, 7275], [7279, 7280], [7285, 7286], [7294, 7295], [7295, 7296], [7295, 7297], [7297, 7298], [7300, 7302], [7300, 7303], [7312, 7313], [7318, 7319], [7345, 7351], [7360, 7361], [7360, 7405], [7361, 7362], [7361, 7364], [7366, 7367], [7366, 7369], [7372, 7375], [7372, 7378], [7387, 7388], [7387, 7390], [7391, 7392], [7391, 7394], [7395, 7396], [7395, 7398], [7400, 7401], [7400, 7403], [7405, 7406], [7405, 7408], [7419, 7420], [7469, 7470], [7471, 7472], [7471, 7476], [7478, 7479], [7494, 7495], [7494, 7497], [7505, 7508], [7515, 7516], [7515, 7517], [7517, 7518], [7517, 7521], [7522, 7524], [7522, 7527], [7530, 7531], [7530, 7534], [7534, 7535], [7534, 7538], [7545, 7546], [7545, 7552], [7554, 7555], [7554, 7558], [7576, 7577], [7576, 7579], [7582, 7583], [7582, 7605], [7583, 7584], [7583, 7586], [7586, 7587], [7586, 7590], [7587, 7582], [7587, 7588], [7591, 7592], [7591, 7594], [7594, 7582], [7594, 7596], [7601, 7582], [7601, 7602], [7602, 7601], [7602, 7603], [7605, 7606], [7605, 7608], [7608, -7608], [7608, 7610], [7611, 7612], [7611, 7616], [7618, 7619], [7618, 7620], [7634, 7635], [7659, 7660], [7670, 7674], [7686, -7683], [7693, 7694], [7696, 7697], [7696, 7699], [7701, 7704], [7706, 7689], [7720, 7721], [7724, 7725], [7731, 7732], [7741, 7742], [7763, 7764], [7774, 7775], [7783, 7784], [7786, 7799], [7790, 7791], [7792, 7793], [7796, 7797], [7805, 7806], [7808, 7809], [7811, 7812], [7822, 7823], [7824, 7840], [7833, 7834], [7840, 7841], [7840, 7842], [7855, 7854], [7856, 7857], [7857, 7854], [7857, 7858], [7865, 7866], [7914, 7915], [7924, 7925], [7929, 7930], [7931, 7934], [7953, 7954], [7959, 7962], [7987, 7991], [7992, 7993], [7992, 7994], [8016, 8017], [8066, 8067], [8067, -8067], [8067, 8068], [8154, 8155], [8158, 8159], [8251, 8252], [8270, 8271], [8303, 8324], [8310, 8324], [8393, 8394], [8397, 8398], [8399, 8400], [8399, 8403], [8437, 8438], [8449, 8461], [8450, 8454], [8454, 8455], [8454, 8459], [8490, 8491], [8494, 8497], [8508, 8509], [8510, 8502], [8510, 8511], [8518, 8519], [8528, 8529], [8579, 8580], [8580, 8581], [8580, 8582], [8582, 8583], [8582, 8585], [8626, 8627], [8633, 8641], [8641, 8642], [8647, 8648], [8650, 8651], [8650, 8652], [8685, 8686], [8714, 8715], [8746, 8747], [8750, 8751], [8796, 8815], [8877, 8878], [8883, 8884], [8897, 8898], [8917, 8918], [8947, 8952], [8949, 8950], [8952, 8953], [8952, 8958], [8954, 8955], [8954, 8961], [8971, 8972], [8979, 8982], [9006, 9007], [9024, 9025], [9028, 9029], [9028, 9032], [9048, 9052], [9055, 9056], [9089, 9090], [9089, 9093], [9094, 9095], [9094, 9097], [9123, 9124], [9146, 9147], [9146, 9149], [9214, 9218], [9218, 9219], [9218, 9220], [9246, 9247], [9246, 9251], [9248, 9249], [9248, 9253], [9253, 9254], [9253, 9258], [9255, 9256], [9255, 9259], [9266, 9274], [9333, 9334], [9347, 9348], [9349, 9350], [9349, 9351], [9366, 9368], [9374, 9379], [9391, 9392], [9405, 9406], [9425, 9426], [9439, 9441], [9539, 9540], [9541, 9537], [9541, 9542], [9543, 9537], [9543, 9544], [9544, 9545], [9544, 9548], [9545, 9543], [9545, 9546], [9548, 9543], [9548, 9549], [9549, 9543], [9549, 9550], [9553, 9554], [9560, 9561], [9560, 9566], [9580, 9581], [9580, 9585], [9581, 9580], [9581, 9582], [9606, 9605], [9614, 9612], [9646, 9647], [9701, 9703], [9725, 9726], [9737, 9744], [9738, 9742], [9754, 9755], [9780, 9781], [9786, 9787], [9790, 9791], [9812, 9814], [9812, 9816], [9814, -9814], [9814, -9809], [9816, 9818], [9816, 9821], [9818, -9818], [9818, -9809], [9821, -9821], [9821, -9809], [9875, 9876], [9875, 9878], [9906, 9907], [9926, 9927], [9926, 9930], [9930, 9931], [9930, 9932], [9949, 9953], [9971, 9972], [9971, 9975], [9986, 9987], [10001, 10002], [10050, 10051], [10070, 10071], [10113, 10114], [10113, 10117], [10118, 10119], [10118, 10122], [10132, -10132], [10132, 10134], [10151, 10152], [10151, 10158], [10161, 10162], [10161, 10163], [10184, 10185], [10190, 10191], [10195, 10196], [10201, 10202], [10208, 10220], [10212, 10213], [10234, -10232], [10234, 10235], [10235, -10232], [10235, 10236], [10237, 10238], [10237, 10239], [10249, 10251], [10327, 10328], [10372, 10373], [10390, 10391], [10398, -10396], [10398, 10399], [10399, 10400], [10399, 10401], [10404, -10404], [10404, 10408], [10455, 10456], [10459, 10460], [10459, 10470], [10464, 10465], [10464, 10470], [10476, 10477], [10476, 10499], [10482, 10483], [10482, 10484], [10484, 10485], [10484, 10486], [10486, 10487], [10486, 10489], [10492, 10493], [10492, 10499], [10499, 10500], [10499, 10517], [10504, -10504], [10504, 10505], [10508, 10509], [10508, 10512], [10509, 10508], [10509, 10510], [10518, 10519], [10518, 10520], [10525, 10527], [10537, 10538], [10551, 10552], [10558, 10559], [10558, 10560], [10569, 10572], [10602, 10603], [10604, 10607], [10608, 10609], [10633, -10628], [10637, -10628], [10638, -10628], [10639, -10628], [10661, 10662], [10708, 10709], [10713, 10714], [10719, 10720], [10828, 10829], [10830, 10831], [10862, 10863], [10885, 10886], [10907, 10908], [10946, 10951], [10952, 10957], [10958, 10963], [10968, 10969], [10975, 10976], [10981, 10982], [10982, 10983], [10982, 10986], [10990, 10991], [10997, 10998], [11025, 11026], [11035, 11048], [11037, 11038], [11038, -11038], [11038, -11031], [11046, 11035], [11102, -52], [11103, 11104], [11108, 11109], [11130, 11131], [11173, 11177]]}}, "totals": {"covered_lines": 5729, "num_statements": 7554, "percent_covered": 71.59563924677899, "percent_covered_display": "72", "missing_lines": 1825, "excluded_lines": 0, "num_branches": 2536, "num_partial_branches": 417, "covered_branches": 1495, "missing_branches": 1041}} \ No newline at end of file diff --git a/coverage/coverage.xml b/coverage/coverage.xml new file mode 100644 index 000000000..df7eab90f --- /dev/null +++ b/coverage/coverage.xml @@ -0,0 +1,7573 @@ + + + + + + /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.5956% + + + + + +
+
+

+ Coverage for gef.py: + 71.5956% +

+ +

+ 7554 statements   + + + + +

+

+ « prev     + ^ index     + » next +       + coverage.py v7.2.7, + created at 2023-07-21 20:06 +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-2022 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@deprecated("Use GefHeapManager.find_main_arena_addr()") 

+

1197def search_for_main_arena() -> int: 

+

1198 return GefHeapManager.find_main_arena_addr() 

+

1199 

+

1200class GlibcHeapInfo: 

+

1201 """Glibc heap_info struct""" 

+

1202 

+

1203 @staticmethod 

+

1204 def heap_info_t() -> Type[ctypes.Structure]: 

+

1205 class heap_info_cls(ctypes.Structure): 

+

1206 pass 

+

1207 pointer = ctypes.c_uint64 if gef.arch.ptrsize == 8 else ctypes.c_uint32 

+

1208 pad_size = -5 * gef.arch.ptrsize & (gef.heap.malloc_alignment - 1) 

+

1209 fields = [ 

+

1210 ("ar_ptr", ctypes.POINTER(GlibcArena.malloc_state_t())), 

+

1211 ("prev", ctypes.POINTER(heap_info_cls)), 

+

1212 ("size", pointer) 

+

1213 ] 

+

1214 if gef.libc.version >= (2, 5): 1214 ↛ 1219line 1214 didn't jump to line 1219, because the condition on line 1214 was never false

+

1215 fields += [ 

+

1216 ("mprotect_size", pointer) 

+

1217 ] 

+

1218 pad_size = -6 * gef.arch.ptrsize & (gef.heap.malloc_alignment - 1) 

+

1219 if gef.libc.version >= (2, 34): 1219 ↛ 1224line 1219 didn't jump to line 1224, because the condition on line 1219 was never false

+

1220 fields += [ 

+

1221 ("pagesize", pointer) 

+

1222 ] 

+

1223 pad_size = -3 * gef.arch.ptrsize & (gef.heap.malloc_alignment - 1) 

+

1224 fields += [ 

+

1225 ("pad", ctypes.c_uint8*pad_size) 

+

1226 ] 

+

1227 heap_info_cls._fields_ = fields 

+

1228 return heap_info_cls 

+

1229 

+

1230 def __init__(self, addr: Union[str, int]) -> None: 

+

1231 self.__address : int = parse_address(f"&{addr}") if isinstance(addr, str) else addr 

+

1232 self.reset() 

+

1233 return 

+

1234 

+

1235 def reset(self): 

+

1236 self._sizeof = ctypes.sizeof(GlibcHeapInfo.heap_info_t()) 

+

1237 self._data = gef.memory.read(self.__address, ctypes.sizeof(GlibcHeapInfo.heap_info_t())) 

+

1238 self._heap_info = GlibcHeapInfo.heap_info_t().from_buffer_copy(self._data) 

+

1239 return 

+

1240 

+

1241 def __getattr__(self, item: Any) -> Any: 

+

1242 if item in dir(self._heap_info): 1242 ↛ 1244line 1242 didn't jump to line 1244, because the condition on line 1242 was never false

+

1243 return ctypes.cast(getattr(self._heap_info, item), ctypes.c_void_p).value 

+

1244 return getattr(self, item) 

+

1245 

+

1246 def __abs__(self) -> int: 

+

1247 return self.__address 

+

1248 

+

1249 def __int__(self) -> int: 

+

1250 return self.__address 

+

1251 

+

1252 @property 

+

1253 def address(self) -> int: 

+

1254 return self.__address 

+

1255 

+

1256 @property 

+

1257 def sizeof(self) -> int: 

+

1258 return self._sizeof 

+

1259 

+

1260 @property 

+

1261 def addr(self) -> int: 

+

1262 return int(self) 

+

1263 

+

1264 @property 

+

1265 def heap_start(self) -> int: 

+

1266 # check special case: first heap of non-main-arena 

+

1267 if self.ar_ptr - self.address < 0x60: 1267 ↛ 1279line 1267 didn't jump to line 1279, because the condition on line 1267 was never false

+

1268 # the first heap of a non-main-arena starts with a `heap_info` 

+

1269 # struct, which should fit easily into 0x60 bytes throughout 

+

1270 # all architectures and glibc versions. If this check succeeds 

+

1271 # then we are currently looking at such a "first heap" 

+

1272 arena = GlibcArena(f"*{self.ar_ptr:#x}") 

+

1273 heap_addr = arena.heap_addr() 

+

1274 if heap_addr: 1274 ↛ 1277line 1274 didn't jump to line 1277, because the condition on line 1274 was never false

+

1275 return heap_addr 

+

1276 else: 

+

1277 err(f"Cannot find heap address for arena {self.ar_ptr:#x}") 

+

1278 return 0 

+

1279 return self.address + self.sizeof 

+

1280 

+

1281 @property 

+

1282 def heap_end(self) -> int: 

+

1283 return self.address + self.size 

+

1284 

+

1285 

+

1286class GlibcArena: 

+

1287 """Glibc arena class""" 

+

1288 

+

1289 NFASTBINS = 10 

+

1290 NBINS = 128 

+

1291 NSMALLBINS = 64 

+

1292 BINMAPSHIFT = 5 

+

1293 BITSPERMAP = 1 << BINMAPSHIFT 

+

1294 BINMAPSIZE = NBINS // BITSPERMAP 

+

1295 

+

1296 @staticmethod 

+

1297 def malloc_state_t() -> Type[ctypes.Structure]: 

+

1298 pointer = ctypes.c_uint64 if gef and gef.arch.ptrsize == 8 else ctypes.c_uint32 

+

1299 fields = [ 

+

1300 ("mutex", ctypes.c_uint32), 

+

1301 ("flags", ctypes.c_uint32), 

+

1302 ] 

+

1303 if gef and gef.libc.version and gef.libc.version >= (2, 27): 1303 ↛ 1309line 1303 didn't jump to line 1309, because the condition on line 1303 was never false

+

1304 # https://elixir.bootlin.com/glibc/glibc-2.27/source/malloc/malloc.c#L1684 

+

1305 fields += [ 

+

1306 ("have_fastchunks", ctypes.c_uint32), 

+

1307 ("UNUSED_c", ctypes.c_uint32), # padding to align to 0x10 

+

1308 ] 

+

1309 fields += [ 

+

1310 ("fastbinsY", GlibcArena.NFASTBINS * pointer), 

+

1311 ("top", pointer), 

+

1312 ("last_remainder", pointer), 

+

1313 ("bins", (GlibcArena.NBINS * 2 - 2) * pointer), 

+

1314 ("binmap", GlibcArena.BINMAPSIZE * ctypes.c_uint32), 

+

1315 ("next", pointer), 

+

1316 ("next_free", pointer) 

+

1317 ] 

+

1318 if gef and gef.libc.version and gef.libc.version >= (2, 23): 1318 ↛ 1323line 1318 didn't jump to line 1323, because the condition on line 1318 was never false

+

1319 # https://elixir.bootlin.com/glibc/glibc-2.23/source/malloc/malloc.c#L1719 

+

1320 fields += [ 

+

1321 ("attached_threads", pointer) 

+

1322 ] 

+

1323 fields += [ 

+

1324 ("system_mem", pointer), 

+

1325 ("max_system_mem", pointer), 

+

1326 ] 

+

1327 class malloc_state_cls(ctypes.Structure): 

+

1328 _fields_ = fields 

+

1329 return malloc_state_cls 

+

1330 

+

1331 def __init__(self, addr: str) -> None: 

+

1332 try: 

+

1333 self.__address : int = parse_address(f"&{addr}") 

+

1334 except gdb.error: 

+

1335 self.__address : int = GefHeapManager.find_main_arena_addr() 

+

1336 # if `find_main_arena_addr` throws `gdb.error` on symbol lookup: 

+

1337 # it means the session is not started, so just propagate the exception 

+

1338 self.reset() 

+

1339 return 

+

1340 

+

1341 def reset(self): 

+

1342 self._sizeof = ctypes.sizeof(GlibcArena.malloc_state_t()) 

+

1343 self._data = gef.memory.read(self.__address, ctypes.sizeof(GlibcArena.malloc_state_t())) 

+

1344 self.__arena = GlibcArena.malloc_state_t().from_buffer_copy(self._data) 

+

1345 return 

+

1346 

+

1347 def __abs__(self) -> int: 

+

1348 return self.__address 

+

1349 

+

1350 def __int__(self) -> int: 

+

1351 return self.__address 

+

1352 

+

1353 def __iter__(self) -> Generator["GlibcArena", None, None]: 

+

1354 main_arena = int(gef.heap.main_arena) 

+

1355 

+

1356 current_arena = self 

+

1357 yield current_arena 

+

1358 

+

1359 while True: 

+

1360 if current_arena.next == 0 or current_arena.next == main_arena: 

+

1361 break 

+

1362 

+

1363 current_arena = GlibcArena(f"*{current_arena.next:#x} ") 

+

1364 yield current_arena 

+

1365 return 

+

1366 

+

1367 def __eq__(self, other: "GlibcArena") -> bool: 

+

1368 return self.__address == int(other) 

+

1369 

+

1370 def __str__(self) -> str: 

+

1371 properties = f"base={self.__address:#x}, top={self.top:#x}, " \ 

+

1372 f"last_remainder={self.last_remainder:#x}, next={self.next:#x}" 

+

1373 return (f"{Color.colorify('Arena', 'blue bold underline')}({properties})") 

+

1374 

+

1375 def __repr__(self) -> str: 

+

1376 return f"GlibcArena(address={self.__address:#x}, size={self._sizeof})" 

+

1377 

+

1378 @property 

+

1379 def address(self) -> int: 

+

1380 return self.__address 

+

1381 

+

1382 @property 

+

1383 def sizeof(self) -> int: 

+

1384 return self._sizeof 

+

1385 

+

1386 @property 

+

1387 def addr(self) -> int: 

+

1388 return int(self) 

+

1389 

+

1390 @property 

+

1391 def top(self) -> int: 

+

1392 return self.__arena.top 

+

1393 

+

1394 @property 

+

1395 def last_remainder(self) -> int: 

+

1396 return self.__arena.last_remainder 

+

1397 

+

1398 @property 

+

1399 def fastbinsY(self) -> ctypes.Array: 

+

1400 return self.__arena.fastbinsY 

+

1401 

+

1402 @property 

+

1403 def bins(self) -> ctypes.Array: 

+

1404 return self.__arena.bins 

+

1405 

+

1406 @property 

+

1407 def binmap(self) -> ctypes.Array: 

+

1408 return self.__arena.binmap 

+

1409 

+

1410 @property 

+

1411 def next(self) -> int: 

+

1412 return self.__arena.next 

+

1413 

+

1414 @property 

+

1415 def next_free(self) -> int: 

+

1416 return self.__arena.next_free 

+

1417 

+

1418 @property 

+

1419 def attached_threads(self) -> int: 

+

1420 return self.__arena.attached_threads 

+

1421 

+

1422 @property 

+

1423 def system_mem(self) -> int: 

+

1424 return self.__arena.system_mem 

+

1425 

+

1426 @property 

+

1427 def max_system_mem(self) -> int: 

+

1428 return self.__arena.max_system_mem 

+

1429 

+

1430 def fastbin(self, i: int) -> Optional["GlibcFastChunk"]: 

+

1431 """Return head chunk in fastbinsY[i].""" 

+

1432 addr = int(self.fastbinsY[i]) 

+

1433 if addr == 0: 

+

1434 return None 

+

1435 return GlibcFastChunk(addr + 2 * gef.arch.ptrsize) 

+

1436 

+

1437 def bin(self, i: int) -> Tuple[int, int]: 

+

1438 idx = i * 2 

+

1439 fd = int(self.bins[idx]) 

+

1440 bk = int(self.bins[idx + 1]) 

+

1441 return fd, bk 

+

1442 

+

1443 def bin_at(self, i) -> int: 

+

1444 header_sz = 2 * gef.arch.ptrsize 

+

1445 offset = ctypes.addressof(self.__arena.bins) - ctypes.addressof(self.__arena) 

+

1446 return self.__address + offset + (i-1) * 2 * gef.arch.ptrsize + header_sz 

+

1447 

+

1448 def is_main_arena(self) -> bool: 

+

1449 return gef.heap.main_arena is not None and int(self) == int(gef.heap.main_arena) 

+

1450 

+

1451 def heap_addr(self, allow_unaligned: bool = False) -> Optional[int]: 

+

1452 if self.is_main_arena(): 

+

1453 heap_section = gef.heap.base_address 

+

1454 if not heap_section: 1454 ↛ 1455line 1454 didn't jump to line 1455, because the condition on line 1454 was never true

+

1455 return None 

+

1456 return heap_section 

+

1457 _addr = int(self) + self.sizeof 

+

1458 if allow_unaligned: 1458 ↛ 1459line 1458 didn't jump to line 1459, because the condition on line 1458 was never true

+

1459 return _addr 

+

1460 return gef.heap.malloc_align_address(_addr) 

+

1461 

+

1462 def get_heap_info_list(self) -> Optional[List[GlibcHeapInfo]]: 

+

1463 if self.is_main_arena(): 1463 ↛ 1464line 1463 didn't jump to line 1464, because the condition on line 1463 was never true

+

1464 return None 

+

1465 heap_addr = self.get_heap_for_ptr(self.top) 

+

1466 heap_infos = [GlibcHeapInfo(heap_addr)] 

+

1467 while heap_infos[-1].prev is not None: 1467 ↛ 1468line 1467 didn't jump to line 1468, because the condition on line 1467 was never true

+

1468 prev = int(heap_infos[-1].prev) 

+

1469 heap_info = GlibcHeapInfo(prev) 

+

1470 heap_infos.append(heap_info) 

+

1471 return heap_infos[::-1] 

+

1472 

+

1473 @staticmethod 

+

1474 def get_heap_for_ptr(ptr: int) -> int: 

+

1475 """Find the corresponding heap for a given pointer (int). 

+

1476 See https://github.com/bminor/glibc/blob/glibc-2.34/malloc/arena.c#L129""" 

+

1477 if is_32bit(): 1477 ↛ 1478line 1477 didn't jump to line 1478, because the condition on line 1477 was never true

+

1478 default_mmap_threshold_max = 512 * 1024 

+

1479 else: # 64bit 

+

1480 default_mmap_threshold_max = 4 * 1024 * 1024 * cached_lookup_type("long").sizeof 

+

1481 heap_max_size = 2 * default_mmap_threshold_max 

+

1482 return ptr & ~(heap_max_size - 1) 

+

1483 

+

1484 @staticmethod 

+

1485 def verify(addr: int) -> bool: 

+

1486 """Verify that the address matches a possible valid GlibcArena""" 

+

1487 try: 

+

1488 test_arena = GlibcArena(f"*{addr:#x}") 

+

1489 cur_arena = GlibcArena(f"*{test_arena.next:#x}") 

+

1490 while cur_arena != test_arena: 

+

1491 if cur_arena == 0: 

+

1492 return False 

+

1493 cur_arena = GlibcArena(f"*{cur_arena.next:#x}") 

+

1494 except Exception as e: 

+

1495 return False 

+

1496 return True 

+

1497 

+

1498 

+

1499class GlibcChunk: 

+

1500 """Glibc chunk class. The default behavior (from_base=False) is to interpret the data starting at the memory 

+

1501 address pointed to as the chunk data. Setting from_base to True instead treats that data as the chunk header. 

+

1502 Ref: https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/.""" 

+

1503 

+

1504 class ChunkFlags(enum.IntFlag): 

+

1505 PREV_INUSE = 1 

+

1506 IS_MMAPPED = 2 

+

1507 NON_MAIN_ARENA = 4 

+

1508 

+

1509 def __str__(self) -> str: 

+

1510 return f" | ".join([ 

+

1511 Color.greenify("PREV_INUSE") if self.value & self.PREV_INUSE else Color.redify("PREV_INUSE"), 

+

1512 Color.greenify("IS_MMAPPED") if self.value & self.IS_MMAPPED else Color.redify("IS_MMAPPED"), 

+

1513 Color.greenify("NON_MAIN_ARENA") if self.value & self.NON_MAIN_ARENA else Color.redify("NON_MAIN_ARENA") 

+

1514 ]) 

+

1515 

+

1516 @staticmethod 

+

1517 def malloc_chunk_t() -> Type[ctypes.Structure]: 

+

1518 pointer = ctypes.c_uint64 if gef and gef.arch.ptrsize == 8 else ctypes.c_uint32 

+

1519 class malloc_chunk_cls(ctypes.Structure): 

+

1520 pass 

+

1521 

+

1522 malloc_chunk_cls._fields_ = [ 

+

1523 ("prev_size", pointer), 

+

1524 ("size", pointer), 

+

1525 ("fd", pointer), 

+

1526 ("bk", pointer), 

+

1527 ("fd_nextsize", ctypes.POINTER(malloc_chunk_cls)), 

+

1528 ("bk_nextsize", ctypes.POINTER(malloc_chunk_cls)), 

+

1529 ] 

+

1530 return malloc_chunk_cls 

+

1531 

+

1532 def __init__(self, addr: int, from_base: bool = False, allow_unaligned: bool = True) -> None: 

+

1533 ptrsize = gef.arch.ptrsize 

+

1534 self.data_address = addr + 2 * ptrsize if from_base else addr 

+

1535 self.base_address = addr if from_base else addr - 2 * ptrsize 

+

1536 if not allow_unaligned: 

+

1537 self.data_address = gef.heap.malloc_align_address(self.data_address) 

+

1538 self.size_addr = int(self.data_address - ptrsize) 

+

1539 self.prev_size_addr = self.base_address 

+

1540 self.reset() 

+

1541 return 

+

1542 

+

1543 def reset(self): 

+

1544 self._sizeof = ctypes.sizeof(GlibcChunk.malloc_chunk_t()) 

+

1545 self._data = gef.memory.read( 

+

1546 self.base_address, ctypes.sizeof(GlibcChunk.malloc_chunk_t())) 

+

1547 self._chunk = GlibcChunk.malloc_chunk_t().from_buffer_copy(self._data) 

+

1548 return 

+

1549 

+

1550 @property 

+

1551 def prev_size(self) -> int: 

+

1552 return self._chunk.prev_size 

+

1553 

+

1554 @property 

+

1555 def size(self) -> int: 

+

1556 return self._chunk.size & (~0x07) 

+

1557 

+

1558 @property 

+

1559 def flags(self) -> ChunkFlags: 

+

1560 return GlibcChunk.ChunkFlags(self._chunk.size & 0x07) 

+

1561 

+

1562 @property 

+

1563 def fd(self) -> int: 

+

1564 return self._chunk.fd 

+

1565 

+

1566 @property 

+

1567 def bk(self) -> int: 

+

1568 return self._chunk.bk 

+

1569 

+

1570 @property 

+

1571 def fd_nextsize(self) -> int: 

+

1572 return self._chunk.fd_nextsize 

+

1573 

+

1574 @property 

+

1575 def bk_nextsize(self) -> int: 

+

1576 return self._chunk.bk_nextsize 

+

1577 

+

1578 def get_usable_size(self) -> int: 

+

1579 # https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L4537 

+

1580 ptrsz = gef.arch.ptrsize 

+

1581 cursz = self.size 

+

1582 if cursz == 0: return cursz 1582 ↛ exitline 1582 didn't return from function 'get_usable_size', because the return on line 1582 wasn't executed

+

1583 if self.has_m_bit(): return cursz - 2 * ptrsz 1583 ↛ exitline 1583 didn't return from function 'get_usable_size', because the return on line 1583 wasn't executed

+

1584 return cursz - ptrsz 

+

1585 

+

1586 @property 

+

1587 def usable_size(self) -> int: 

+

1588 return self.get_usable_size() 

+

1589 

+

1590 def get_prev_chunk_size(self) -> int: 

+

1591 return gef.memory.read_integer(self.prev_size_addr) 

+

1592 

+

1593 def __iter__(self) -> Generator["GlibcChunk", None, None]: 

+

1594 current_chunk = self 

+

1595 top = gef.heap.main_arena.top 

+

1596 

+

1597 while True: 

+

1598 yield current_chunk 

+

1599 

+

1600 if current_chunk.base_address == top: 1600 ↛ 1601line 1600 didn't jump to line 1601, because the condition on line 1600 was never true

+

1601 break 

+

1602 

+

1603 if current_chunk.size == 0: 1603 ↛ 1604line 1603 didn't jump to line 1604, because the condition on line 1603 was never true

+

1604 break 

+

1605 

+

1606 next_chunk_addr = current_chunk.get_next_chunk_addr() 

+

1607 

+

1608 if not Address(value=next_chunk_addr).valid: 1608 ↛ 1609line 1608 didn't jump to line 1609, because the condition on line 1608 was never true

+

1609 break 

+

1610 

+

1611 next_chunk = current_chunk.get_next_chunk() 

+

1612 if next_chunk is None: 1612 ↛ 1613line 1612 didn't jump to line 1613, because the condition on line 1612 was never true

+

1613 break 

+

1614 

+

1615 current_chunk = next_chunk 

+

1616 return 

+

1617 

+

1618 def get_next_chunk(self, allow_unaligned: bool = False) -> "GlibcChunk": 

+

1619 addr = self.get_next_chunk_addr() 

+

1620 return GlibcChunk(addr, allow_unaligned=allow_unaligned) 

+

1621 

+

1622 def get_next_chunk_addr(self) -> int: 

+

1623 return self.data_address + self.size 

+

1624 

+

1625 def has_p_bit(self) -> bool: 

+

1626 return bool(self.flags & GlibcChunk.ChunkFlags.PREV_INUSE) 

+

1627 

+

1628 def has_m_bit(self) -> bool: 

+

1629 return bool(self.flags & GlibcChunk.ChunkFlags.IS_MMAPPED) 

+

1630 

+

1631 def has_n_bit(self) -> bool: 

+

1632 return bool(self.flags & GlibcChunk.ChunkFlags.NON_MAIN_ARENA) 

+

1633 

+

1634 def is_used(self) -> bool: 

+

1635 """Check if the current block is used by: 

+

1636 - checking the M bit is true 

+

1637 - or checking that next chunk PREV_INUSE flag is true""" 

+

1638 if self.has_m_bit(): 1638 ↛ 1639line 1638 didn't jump to line 1639, because the condition on line 1638 was never true

+

1639 return True 

+

1640 

+

1641 next_chunk = self.get_next_chunk() 

+

1642 return True if next_chunk.has_p_bit() else False 

+

1643 

+

1644 def __str_sizes(self) -> str: 

+

1645 msg = [] 

+

1646 failed = False 

+

1647 

+

1648 try: 

+

1649 msg.append("Chunk size: {0:d} ({0:#x})".format(self.size)) 

+

1650 msg.append("Usable size: {0:d} ({0:#x})".format(self.usable_size)) 

+

1651 failed = True 

+

1652 except gdb.MemoryError: 

+

1653 msg.append(f"Chunk size: Cannot read at {self.size_addr:#x} (corrupted?)") 

+

1654 

+

1655 try: 

+

1656 msg.append("Previous chunk size: {0:d} ({0:#x})".format(self.get_prev_chunk_size())) 

+

1657 failed = True 

+

1658 except gdb.MemoryError: 

+

1659 msg.append(f"Previous chunk size: Cannot read at {self.base_address:#x} (corrupted?)") 

+

1660 

+

1661 if failed: 1661 ↛ 1664line 1661 didn't jump to line 1664, because the condition on line 1661 was never false

+

1662 msg.append(str(self.flags)) 

+

1663 

+

1664 return "\n".join(msg) 

+

1665 

+

1666 def _str_pointers(self) -> str: 

+

1667 fwd = self.data_address 

+

1668 bkw = self.data_address + gef.arch.ptrsize 

+

1669 

+

1670 msg = [] 

+

1671 try: 

+

1672 msg.append(f"Forward pointer: {self.fd:#x}") 

+

1673 except gdb.MemoryError: 

+

1674 msg.append(f"Forward pointer: {fwd:#x} (corrupted?)") 

+

1675 

+

1676 try: 

+

1677 msg.append(f"Backward pointer: {self.bk:#x}") 

+

1678 except gdb.MemoryError: 

+

1679 msg.append(f"Backward pointer: {bkw:#x} (corrupted?)") 

+

1680 

+

1681 return "\n".join(msg) 

+

1682 

+

1683 def __str__(self) -> str: 

+

1684 return (f"{Color.colorify('Chunk', 'yellow bold underline')}(addr={self.data_address:#x}, " 

+

1685 f"size={self.size:#x}, flags={self.flags!s})") 

+

1686 

+

1687 def psprint(self) -> str: 

+

1688 msg = [ 

+

1689 str(self), 

+

1690 self.__str_sizes(), 

+

1691 ] 

+

1692 if not self.is_used(): 1692 ↛ 1693line 1692 didn't jump to line 1693, because the condition on line 1692 was never true

+

1693 msg.append(f"\n\n{self._str_pointers()}") 

+

1694 return "\n".join(msg) + "\n" 

+

1695 

+

1696 

+

1697class GlibcFastChunk(GlibcChunk): 

+

1698 

+

1699 @property 

+

1700 def fd(self) -> int: 

+

1701 assert(gef and gef.libc.version) 

+

1702 if gef.libc.version < (2, 32): 1702 ↛ 1703line 1702 didn't jump to line 1703, because the condition on line 1702 was never true

+

1703 return self._chunk.fd 

+

1704 return self.reveal_ptr(self.data_address) 

+

1705 

+

1706 def protect_ptr(self, pos: int, pointer: int) -> int: 

+

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

+

1708 assert(gef and gef.libc.version) 

+

1709 if gef.libc.version < (2, 32): 

+

1710 return pointer 

+

1711 return (pos >> 12) ^ pointer 

+

1712 

+

1713 def reveal_ptr(self, pointer: int) -> int: 

+

1714 """https://elixir.bootlin.com/glibc/glibc-2.32/source/malloc/malloc.c#L341""" 

+

1715 assert(gef and gef.libc.version) 

+

1716 if gef.libc.version < (2, 32): 1716 ↛ 1717line 1716 didn't jump to line 1717, because the condition on line 1716 was never true

+

1717 return pointer 

+

1718 return gef.memory.read_integer(pointer) ^ (pointer >> 12) 

+

1719 

+

1720class GlibcTcacheChunk(GlibcFastChunk): 

+

1721 

+

1722 pass 

+

1723 

+

1724@deprecated("Use GefLibcManager.find_libc_version()") 

+

1725def get_libc_version() -> Tuple[int, ...]: 

+

1726 return GefLibcManager.find_libc_version() 

+

1727 

+

1728def titlify(text: str, color: Optional[str] = None, msg_color: Optional[str] = None) -> str: 

+

1729 """Print a centered title.""" 

+

1730 _, cols = get_terminal_size() 

+

1731 nb = (cols - len(text) - 2) // 2 

+

1732 line_color = color or gef.config["theme.default_title_line"] 

+

1733 text_color = msg_color or gef.config["theme.default_title_message"] 

+

1734 

+

1735 msg = [Color.colorify(f"{HORIZONTAL_LINE * nb} ", line_color), 

+

1736 Color.colorify(text, text_color), 

+

1737 Color.colorify(f" {HORIZONTAL_LINE * nb}", line_color)] 

+

1738 return "".join(msg) 

+

1739 

+

1740 

+

1741def dbg(msg: str) -> None: 

+

1742 if gef.config["gef.debug"] is True: 1742 ↛ 1744line 1742 didn't jump to line 1744, because the condition on line 1742 was never false

+

1743 gef_print(f"{Color.colorify('[=]', 'bold cyan')} {msg}") 

+

1744 return 

+

1745 

+

1746 

+

1747def err(msg: str) -> None: 

+

1748 gef_print(f"{Color.colorify('[!]', 'bold red')} {msg}") 

+

1749 return 

+

1750 

+

1751 

+

1752def warn(msg: str) -> None: 

+

1753 gef_print(f"{Color.colorify('[*]', 'bold yellow')} {msg}") 

+

1754 return 

+

1755 

+

1756 

+

1757def ok(msg: str) -> None: 

+

1758 gef_print(f"{Color.colorify('[+]', 'bold green')} {msg}") 

+

1759 return 

+

1760 

+

1761 

+

1762def info(msg: str) -> None: 

+

1763 gef_print(f"{Color.colorify('[+]', 'bold blue')} {msg}") 

+

1764 return 

+

1765 

+

1766 

+

1767def push_context_message(level: str, message: str) -> None: 

+

1768 """Push the message to be displayed the next time the context is invoked.""" 

+

1769 if level not in ("error", "warn", "ok", "info"): 1769 ↛ 1770line 1769 didn't jump to line 1770, because the condition on line 1769 was never true

+

1770 err(f"Invalid level '{level}', discarding message") 

+

1771 return 

+

1772 gef.ui.context_messages.append((level, message)) 

+

1773 return 

+

1774 

+

1775 

+

1776def show_last_exception() -> None: 

+

1777 """Display the last Python exception.""" 

+

1778 

+

1779 def _show_code_line(fname: str, idx: int) -> str: 

+

1780 fname = os.path.expanduser(os.path.expandvars(fname)) 

+

1781 with open(fname, "r") as f: 

+

1782 _data = f.readlines() 

+

1783 return _data[idx - 1] if 0 < idx < len(_data) else "" 

+

1784 

+

1785 gef_print("") 

+

1786 exc_type, exc_value, exc_traceback = sys.exc_info() 

+

1787 

+

1788 gef_print(" Exception raised ".center(80, HORIZONTAL_LINE)) 

+

1789 gef_print(f"{Color.colorify(exc_type.__name__, 'bold underline red')}: {exc_value}") 

+

1790 gef_print(" Detailed stacktrace ".center(80, HORIZONTAL_LINE)) 

+

1791 

+

1792 for fs in traceback.extract_tb(exc_traceback)[::-1]: 

+

1793 filename, lineno, method, code = fs 

+

1794 

+

1795 if not code or not code.strip(): 1795 ↛ 1796line 1795 didn't jump to line 1796, because the condition on line 1795 was never true

+

1796 code = _show_code_line(filename, lineno) 

+

1797 

+

1798 gef_print(f"""{DOWN_ARROW} File "{Color.yellowify(filename)}", line {lineno:d}, in {Color.greenify(method)}()""") 

+

1799 gef_print(f" {RIGHT_ARROW} {code}") 

+

1800 

+

1801 gef_print(" Version ".center(80, HORIZONTAL_LINE)) 

+

1802 gdb.execute("version full") 

+

1803 gef_print(" Last 10 GDB commands ".center(80, HORIZONTAL_LINE)) 

+

1804 gdb.execute("show commands") 

+

1805 gef_print(" Runtime environment ".center(80, HORIZONTAL_LINE)) 

+

1806 gef_print(f"* GDB: {gdb.VERSION}") 

+

1807 gef_print(f"* Python: {sys.version_info.major:d}.{sys.version_info.minor:d}.{sys.version_info.micro:d} - {sys.version_info.releaselevel}") 

+

1808 gef_print(f"* OS: {platform.system()} - {platform.release()} ({platform.machine()})") 

+

1809 

+

1810 try: 

+

1811 lsb_release = which("lsb_release") 

+

1812 gdb.execute(f"!{lsb_release} -a") 

+

1813 except FileNotFoundError: 

+

1814 gef_print("lsb_release is missing, cannot collect additional debug information") 

+

1815 

+

1816 gef_print(HORIZONTAL_LINE*80) 

+

1817 gef_print("") 

+

1818 return 

+

1819 

+

1820 

+

1821def gef_pystring(x: bytes) -> str: 

+

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

+

1823 res = str(x, encoding="utf-8") 

+

1824 substs = [("\n", "\\n"), ("\r", "\\r"), ("\t", "\\t"), ("\v", "\\v"), ("\b", "\\b"), ] 

+

1825 for x, y in substs: res = res.replace(x, y) 

+

1826 return res 

+

1827 

+

1828 

+

1829def gef_pybytes(x: str) -> bytes: 

+

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

+

1831 return bytes(str(x), encoding="utf-8") 

+

1832 

+

1833 

+

1834@lru_cache() 

+

1835def which(program: str) -> pathlib.Path: 

+

1836 """Locate a command on the filesystem.""" 

+

1837 for path in os.environ["PATH"].split(os.pathsep): 

+

1838 dirname = pathlib.Path(path) 

+

1839 fpath = dirname / program 

+

1840 if os.access(fpath, os.X_OK): 

+

1841 return fpath 

+

1842 

+

1843 raise FileNotFoundError(f"Missing file `{program}`") 

+

1844 

+

1845 

+

1846def style_byte(b: int, color: bool = True) -> str: 

+

1847 style = { 

+

1848 "nonprintable": "yellow", 

+

1849 "printable": "white", 

+

1850 "00": "gray", 

+

1851 "0a": "blue", 

+

1852 "ff": "green", 

+

1853 } 

+

1854 sbyte = f"{b:02x}" 

+

1855 if not color or gef.config["highlight.regex"]: 

+

1856 return sbyte 

+

1857 

+

1858 if sbyte in style: 

+

1859 st = style[sbyte] 

+

1860 elif chr(b) in (string.ascii_letters + string.digits + string.punctuation + " "): 

+

1861 st = style.get("printable") 

+

1862 else: 

+

1863 st = style.get("nonprintable") 

+

1864 if st: 1864 ↛ 1866line 1864 didn't jump to line 1866, because the condition on line 1864 was never false

+

1865 sbyte = Color.colorify(sbyte, st) 

+

1866 return sbyte 

+

1867 

+

1868 

+

1869def hexdump(source: ByteString, length: int = 0x10, separator: str = ".", show_raw: bool = False, show_symbol: bool = True, base: int = 0x00) -> str: 

+

1870 """Return the hexdump of `src` argument. 

+

1871 @param source *MUST* be of type bytes or bytearray 

+

1872 @param length is the length of items per line 

+

1873 @param separator is the default character to use if one byte is not printable 

+

1874 @param show_raw if True, do not add the line nor the text translation 

+

1875 @param base is the start address of the block being hexdump 

+

1876 @return a string with the hexdump""" 

+

1877 result = [] 

+

1878 align = gef.arch.ptrsize * 2 + 2 if is_alive() else 18 

+

1879 

+

1880 for i in range(0, len(source), length): 

+

1881 chunk = bytearray(source[i : i + length]) 

+

1882 hexa = " ".join([style_byte(b, color=not show_raw) for b in chunk]) 

+

1883 

+

1884 if show_raw: 

+

1885 result.append(hexa) 

+

1886 continue 

+

1887 

+

1888 text = "".join([chr(b) if 0x20 <= b < 0x7F else separator for b in chunk]) 

+

1889 if show_symbol: 1889 ↛ 1893line 1889 didn't jump to line 1893, because the condition on line 1889 was never false

+

1890 sym = gdb_get_location_from_symbol(base + i) 

+

1891 sym = "<{:s}+{:04x}>".format(*sym) if sym else "" 

+

1892 else: 

+

1893 sym = "" 

+

1894 

+

1895 result.append(f"{base + i:#0{align}x} {sym} {hexa:<{3 * length}} {text}") 

+

1896 return "\n".join(result) 

+

1897 

+

1898 

+

1899def is_debug() -> bool: 

+

1900 """Check if debug mode is enabled.""" 

+

1901 return gef.config["gef.debug"] is True 

+

1902 

+

1903 

+

1904def buffer_output() -> bool: 

+

1905 """Check if output should be buffered until command completion.""" 

+

1906 return gef.config["gef.buffer"] is True 

+

1907 

+

1908 

+

1909def hide_context() -> bool: 

+

1910 """Helper function to hide the context pane.""" 

+

1911 gef.ui.context_hidden = True 

+

1912 return True 

+

1913 

+

1914 

+

1915def unhide_context() -> bool: 

+

1916 """Helper function to unhide the context pane.""" 

+

1917 gef.ui.context_hidden = False 

+

1918 return True 

+

1919 

+

1920 

+

1921class DisableContextOutputContext: 

+

1922 def __enter__(self) -> None: 

+

1923 hide_context() 

+

1924 return 

+

1925 

+

1926 def __exit__(self, *exc: Any) -> None: 

+

1927 unhide_context() 

+

1928 return 

+

1929 

+

1930 

+

1931class RedirectOutputContext: 

+

1932 def __init__(self, to: str = "/dev/null") -> None: 

+

1933 self.redirection_target_file = to 

+

1934 return 

+

1935 

+

1936 def __enter__(self) -> None: 

+

1937 """Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`.""" 

+

1938 gdb.execute("set logging overwrite") 

+

1939 gdb.execute(f"set logging file {self.redirection_target_file}") 

+

1940 gdb.execute("set logging redirect on") 

+

1941 gdb.execute("set logging on") 

+

1942 return 

+

1943 

+

1944 def __exit__(self, *exc: Any) -> None: 

+

1945 """Disable the output redirection, if any.""" 

+

1946 gdb.execute("set logging off") 

+

1947 gdb.execute("set logging redirect off") 

+

1948 return 

+

1949 

+

1950 

+

1951def enable_redirect_output(to_file: str = "/dev/null") -> None: 

+

1952 """Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`.""" 

+

1953 gdb.execute("set logging overwrite") 

+

1954 gdb.execute(f"set logging file {to_file}") 

+

1955 gdb.execute("set logging redirect on") 

+

1956 gdb.execute("set logging on") 

+

1957 return 

+

1958 

+

1959 

+

1960def disable_redirect_output() -> None: 

+

1961 """Disable the output redirection, if any.""" 

+

1962 gdb.execute("set logging off") 

+

1963 gdb.execute("set logging redirect off") 

+

1964 return 

+

1965 

+

1966 

+

1967def gef_makedirs(path: str, mode: int = 0o755) -> pathlib.Path: 

+

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

+

1969 fpath = pathlib.Path(path) 

+

1970 if not fpath.is_dir(): 

+

1971 fpath.mkdir(mode=mode, exist_ok=True, parents=True) 

+

1972 return fpath.absolute() 

+

1973 

+

1974 

+

1975@lru_cache() 

+

1976def gdb_lookup_symbol(sym: str) -> Optional[Tuple[Optional[str], Optional[Tuple[gdb.Symtab_and_line, ...]]]]: 

+

1977 """Fetch the proper symbol or None if not defined.""" 

+

1978 try: 

+

1979 return gdb.decode_line(sym)[1] 

+

1980 except gdb.error: 

+

1981 return None 

+

1982 

+

1983 

+

1984@lru_cache(maxsize=512) 

+

1985def gdb_get_location_from_symbol(address: int) -> Optional[Tuple[str, int]]: 

+

1986 """Retrieve the location of the `address` argument from the symbol table. 

+

1987 Return a tuple with the name and offset if found, None otherwise.""" 

+

1988 # this is horrible, ugly hack and shitty perf... 

+

1989 # find a *clean* way to get gdb.Location from an address 

+

1990 sym = str(gdb.execute(f"info symbol {address:#x}", to_string=True)) 

+

1991 if sym.startswith("No symbol matches"): 

+

1992 return None 

+

1993 

+

1994 i = sym.find(" in section ") 

+

1995 sym = sym[:i].split() 

+

1996 name, offset = sym[0], 0 

+

1997 if len(sym) == 3 and sym[2].isdigit(): 

+

1998 offset = int(sym[2]) 

+

1999 return name, offset 

+

2000 

+

2001 

+

2002def gdb_disassemble(start_pc: int, **kwargs: int) -> Generator[Instruction, None, None]: 

+

2003 """Disassemble instructions from `start_pc` (Integer). Accepts the following named 

+

2004 parameters: 

+

2005 - `end_pc` (Integer) only instructions whose start address fall in the interval from 

+

2006 start_pc to end_pc are returned. 

+

2007 - `count` (Integer) list at most this many disassembled instructions 

+

2008 If `end_pc` and `count` are not provided, the function will behave as if `count=1`. 

+

2009 Return an iterator of Instruction objects 

+

2010 """ 

+

2011 frame = gdb.selected_frame() 

+

2012 arch = frame.architecture() 

+

2013 

+

2014 for insn in arch.disassemble(start_pc, **kwargs): 

+

2015 address = insn["addr"] 

+

2016 asm = insn["asm"].rstrip().split(None, 1) 

+

2017 if len(asm) > 1: 

+

2018 mnemo, operands = asm 

+

2019 operands = operands.split(",") 

+

2020 else: 

+

2021 mnemo, operands = asm[0], [] 

+

2022 

+

2023 loc = gdb_get_location_from_symbol(address) 

+

2024 location = "<{}+{}>".format(*loc) if loc else "" 

+

2025 

+

2026 opcodes = gef.memory.read(insn["addr"], insn["length"]) 

+

2027 

+

2028 yield Instruction(address, location, mnemo, operands, opcodes) 

+

2029 

+

2030 

+

2031def gdb_get_nth_previous_instruction_address(addr: int, n: int) -> Optional[int]: 

+

2032 """Return the address (Integer) of the `n`-th instruction before `addr`.""" 

+

2033 # fixed-length ABI 

+

2034 if gef.arch.instruction_length: 2034 ↛ 2035line 2034 didn't jump to line 2035, because the condition on line 2034 was never true

+

2035 return max(0, addr - n * gef.arch.instruction_length) 

+

2036 

+

2037 # variable-length ABI 

+

2038 cur_insn_addr = gef_current_instruction(addr).address 

+

2039 

+

2040 # we try to find a good set of previous instructions by "guessing" disassembling backwards 

+

2041 # the 15 comes from the longest instruction valid size 

+

2042 for i in range(15 * n, 0, -1): 2042 ↛ 2065line 2042 didn't jump to line 2065, because the loop on line 2042 didn't complete

+

2043 try: 

+

2044 insns = list(gdb_disassemble(addr - i, end_pc=cur_insn_addr)) 

+

2045 except gdb.MemoryError: 

+

2046 # this is because we can hit an unmapped page trying to read backward 

+

2047 break 

+

2048 

+

2049 # 1. check that the disassembled instructions list size can satisfy 

+

2050 if len(insns) < n + 1: # we expect the current instruction plus the n before it 2050 ↛ 2051line 2050 didn't jump to line 2051, because the condition on line 2050 was never true

+

2051 continue 

+

2052 

+

2053 # If the list of instructions is longer than what we need, then we 

+

2054 # could get lucky and already have more than what we need, so slice down 

+

2055 insns = insns[-n - 1 :] 

+

2056 

+

2057 # 2. check that the sequence ends with the current address 

+

2058 if insns[-1].address != cur_insn_addr: 2058 ↛ 2059line 2058 didn't jump to line 2059, because the condition on line 2058 was never true

+

2059 continue 

+

2060 

+

2061 # 3. check all instructions are valid 

+

2062 if all(insn.is_valid() for insn in insns): 2062 ↛ 2042line 2062 didn't jump to line 2042, because the condition on line 2062 was never false

+

2063 return insns[0].address 

+

2064 

+

2065 return None 

+

2066 

+

2067 

+

2068def gdb_get_nth_next_instruction_address(addr: int, n: int) -> int: 

+

2069 """Return the address (Integer) of the `n`-th instruction after `addr`.""" 

+

2070 # fixed-length ABI 

+

2071 if gef.arch.instruction_length: 2071 ↛ 2072line 2071 didn't jump to line 2072, because the condition on line 2071 was never true

+

2072 return addr + n * gef.arch.instruction_length 

+

2073 

+

2074 # variable-length ABI 

+

2075 insn = list(gdb_disassemble(addr, count=n))[-1] 

+

2076 return insn.address 

+

2077 

+

2078 

+

2079def gef_instruction_n(addr: int, n: int) -> Instruction: 

+

2080 """Return the `n`-th instruction after `addr` as an Instruction object.""" 

+

2081 return list(gdb_disassemble(addr, count=n + 1))[n] 

+

2082 

+

2083 

+

2084def gef_get_instruction_at(addr: int) -> Instruction: 

+

2085 """Return the full Instruction found at the specified address.""" 

+

2086 insn = next(gef_disassemble(addr, 1)) 

+

2087 return insn 

+

2088 

+

2089 

+

2090def gef_current_instruction(addr: int) -> Instruction: 

+

2091 """Return the current instruction as an Instruction object.""" 

+

2092 return gef_instruction_n(addr, 0) 

+

2093 

+

2094 

+

2095def gef_next_instruction(addr: int) -> Instruction: 

+

2096 """Return the next instruction as an Instruction object.""" 

+

2097 return gef_instruction_n(addr, 1) 

+

2098 

+

2099 

+

2100def gef_disassemble(addr: int, nb_insn: int, nb_prev: int = 0) -> Generator[Instruction, None, None]: 

+

2101 """Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr`. 

+

2102 Return an iterator of Instruction objects.""" 

+

2103 nb_insn = max(1, nb_insn) 

+

2104 

+

2105 if nb_prev: 

+

2106 try: 

+

2107 start_addr = gdb_get_nth_previous_instruction_address(addr, nb_prev) 

+

2108 if start_addr: 

+

2109 for insn in gdb_disassemble(start_addr, count=nb_prev): 

+

2110 if insn.address == addr: break 2110 ↛ 2116line 2110 didn't jump to line 2116, because the break on line 2110 wasn't executed

+

2111 yield insn 

+

2112 except gdb.MemoryError: 

+

2113 # If the address pointing to the previous instruction(s) is not mapped, simply skip them 

+

2114 pass 

+

2115 

+

2116 for insn in gdb_disassemble(addr, count=nb_insn): 

+

2117 yield insn 

+

2118 

+

2119 

+

2120def gef_execute_external(command: Sequence[str], as_list: bool = False, **kwargs: Any) -> Union[str, List[str]]: 

+

2121 """Execute an external command and return the result.""" 

+

2122 res = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=kwargs.get("shell", False)) 

+

2123 return [gef_pystring(_) for _ in res.splitlines()] if as_list else gef_pystring(res) 

+

2124 

+

2125 

+

2126def gef_execute_gdb_script(commands: str) -> None: 

+

2127 """Execute the parameter `source` as GDB command. This is done by writing `commands` to 

+

2128 a temporary file, which is then executed via GDB `source` command. The tempfile is then deleted.""" 

+

2129 fd, fname = tempfile.mkstemp(suffix=".gdb", prefix="gef_") 

+

2130 with os.fdopen(fd, "w") as f: 

+

2131 f.write(commands) 

+

2132 f.flush() 

+

2133 

+

2134 fname = pathlib.Path(fname) 

+

2135 if fname.is_file() and os.access(fname, os.R_OK): 

+

2136 gdb.execute(f"source {fname}") 

+

2137 fname.unlink() 

+

2138 return 

+

2139 

+

2140 

+

2141@deprecated("Use Elf(fname).checksec()") 

+

2142def checksec(filename: str) -> Dict[str, bool]: 

+

2143 return Elf(filename).checksec 

+

2144 

+

2145 

+

2146@lru_cache() 

+

2147def get_arch() -> str: 

+

2148 """Return the binary's architecture.""" 

+

2149 if is_alive(): 

+

2150 arch = gdb.selected_frame().architecture() 

+

2151 return arch.name() 

+

2152 

+

2153 arch_str = gdb.execute("show architecture", to_string=True).strip() 

+

2154 pat = "The target architecture is set automatically (currently " 

+

2155 if arch_str.startswith(pat): 2155 ↛ 2156line 2155 didn't jump to line 2156, because the condition on line 2155 was never true

+

2156 arch_str = arch_str[len(pat):].rstrip(")") 

+

2157 return arch_str 

+

2158 

+

2159 pat = "The target architecture is assumed to be " 

+

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 return arch_str[len(pat):] 

+

2162 

+

2163 pat = "The target architecture is set to " 

+

2164 if arch_str.startswith(pat): 2164 ↛ 2171line 2164 didn't jump to line 2171, because the condition on line 2164 was never false

+

2165 # GDB version >= 10.1 

+

2166 if '"auto"' in arch_str: 2166 ↛ 2168line 2166 didn't jump to line 2168, because the condition on line 2166 was never false

+

2167 return re.findall(r"currently \"(.+)\"", arch_str)[0] 

+

2168 return re.findall(r"\"(.+)\"", arch_str)[0] 

+

2169 

+

2170 # Unknown, we throw an exception to be safe 

+

2171 raise RuntimeError(f"Unknown architecture: {arch_str}") 

+

2172 

+

2173 

+

2174@deprecated("Use `gef.binary.entry_point` instead") 

+

2175def get_entry_point() -> Optional[int]: 

+

2176 """Return the binary entry point.""" 

+

2177 return gef.binary.entry_point if gef.binary else None 

+

2178 

+

2179 

+

2180def is_pie(fpath: str) -> bool: 

+

2181 return Elf(fpath).checksec["PIE"] 

+

2182 

+

2183 

+

2184@deprecated("Prefer `gef.arch.endianness == Endianness.BIG_ENDIAN`") 

+

2185def is_big_endian() -> bool: 

+

2186 return gef.arch.endianness == Endianness.BIG_ENDIAN 

+

2187 

+

2188 

+

2189@deprecated("gef.arch.endianness == Endianness.LITTLE_ENDIAN") 

+

2190def is_little_endian() -> bool: 

+

2191 return gef.arch.endianness == Endianness.LITTLE_ENDIAN 

+

2192 

+

2193 

+

2194def flags_to_human(reg_value: int, value_table: Dict[int, str]) -> str: 

+

2195 """Return a human readable string showing the flag states.""" 

+

2196 flags = [] 

+

2197 for bit_index, name in value_table.items(): 

+

2198 flags.append(Color.boldify(name.upper()) if reg_value & (1<<bit_index) != 0 else name.lower()) 

+

2199 return f"[{' '.join(flags)}]" 

+

2200 

+

2201 

+

2202@lru_cache() 

+

2203def get_section_base_address(name: str) -> Optional[int]: 

+

2204 section = process_lookup_path(name) 

+

2205 return section.page_start if section else None 

+

2206 

+

2207 

+

2208@lru_cache() 

+

2209def get_zone_base_address(name: str) -> Optional[int]: 

+

2210 zone = file_lookup_name_path(name, get_filepath()) 

+

2211 return zone.zone_start if zone else None 

+

2212 

+

2213 

+

2214# 

+

2215# Architecture classes 

+

2216# 

+

2217@deprecated("Using the decorator `register_architecture` is unecessary") 

+

2218def register_architecture(cls: Type["Architecture"]) -> Type["Architecture"]: 

+

2219 return cls 

+

2220 

+

2221class ArchitectureBase: 

+

2222 """Class decorator for declaring an architecture to GEF.""" 

+

2223 aliases: Union[Tuple[()], Tuple[Union[str, Elf.Abi], ...]] = () 

+

2224 

+

2225 def __init_subclass__(cls: Type["ArchitectureBase"], **kwargs): 

+

2226 global __registered_architectures__ 

+

2227 super().__init_subclass__(**kwargs) 

+

2228 for key in getattr(cls, "aliases"): 

+

2229 if issubclass(cls, Architecture): 2229 ↛ 2228line 2229 didn't jump to line 2228, because the condition on line 2229 was never false

+

2230 __registered_architectures__[key] = cls 

+

2231 return 

+

2232 

+

2233 

+

2234class Architecture(ArchitectureBase): 

+

2235 """Generic metaclass for the architecture supported by GEF.""" 

+

2236 

+

2237 # Mandatory defined attributes by inheriting classes 

+

2238 arch: str 

+

2239 mode: str 

+

2240 all_registers: Union[Tuple[()], Tuple[str, ...]] 

+

2241 nop_insn: bytes 

+

2242 return_register: str 

+

2243 flag_register: Optional[str] 

+

2244 instruction_length: Optional[int] 

+

2245 flags_table: Dict[int, str] 

+

2246 syscall_register: Optional[str] 

+

2247 syscall_instructions: Union[Tuple[()], Tuple[str, ...]] 

+

2248 function_parameters: Union[Tuple[()], Tuple[str, ...]] 

+

2249 

+

2250 # Optionally defined attributes 

+

2251 _ptrsize: Optional[int] = None 

+

2252 _endianness: Optional[Endianness] = None 

+

2253 special_registers: Union[Tuple[()], Tuple[str, ...]] = () 

+

2254 

+

2255 def __init_subclass__(cls, **kwargs): 

+

2256 super().__init_subclass__(**kwargs) 

+

2257 attributes = ("arch", "mode", "aliases", "all_registers", "nop_insn", 

+

2258 "return_register", "flag_register", "instruction_length", "flags_table", 

+

2259 "function_parameters",) 

+

2260 if not all(map(lambda x: hasattr(cls, x), attributes)): 2260 ↛ 2261line 2260 didn't jump to line 2261, because the condition on line 2260 was never true

+

2261 raise NotImplementedError 

+

2262 

+

2263 def __str__(self) -> str: 

+

2264 return f"Architecture({self.arch}, {self.mode or 'None'}, {repr(self.endianness)})" 

+

2265 

+

2266 @staticmethod 

+

2267 def supports_gdb_arch(gdb_arch: str) -> Optional[bool]: 

+

2268 """If implemented by a child `Architecture`, this function dictates if the current class 

+

2269 supports the loaded ELF file (which can be accessed via `gef.binary`). This callback 

+

2270 function will override any assumption made by GEF to determine the architecture.""" 

+

2271 return None 

+

2272 

+

2273 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

2274 raise NotImplementedError 

+

2275 

+

2276 def is_call(self, insn: Instruction) -> bool: 

+

2277 raise NotImplementedError 

+

2278 

+

2279 def is_ret(self, insn: Instruction) -> bool: 

+

2280 raise NotImplementedError 

+

2281 

+

2282 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

2283 raise NotImplementedError 

+

2284 

+

2285 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

2286 raise NotImplementedError 

+

2287 

+

2288 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

2289 raise NotImplementedError 

+

2290 

+

2291 def canary_address(self) -> int: 

+

2292 raise NotImplementedError 

+

2293 

+

2294 @classmethod 

+

2295 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2296 raise NotImplementedError 

+

2297 

+

2298 def reset_caches(self) -> None: 

+

2299 self.__get_register_for_selected_frame.cache_clear() 

+

2300 return 

+

2301 

+

2302 def __get_register(self, regname: str) -> int: 

+

2303 """Return a register's value.""" 

+

2304 curframe = gdb.selected_frame() 

+

2305 key = curframe.pc() ^ int(curframe.read_register('sp')) # todo: check when/if gdb.Frame implements `level()` 

+

2306 return self.__get_register_for_selected_frame(regname, key) 

+

2307 

+

2308 @lru_cache() 

+

2309 def __get_register_for_selected_frame(self, regname: str, hash_key: int) -> int: 

+

2310 # 1st chance 

+

2311 try: 

+

2312 return parse_address(regname) 

+

2313 except gdb.error: 

+

2314 pass 

+

2315 

+

2316 # 2nd chance - if an exception, propagate it 

+

2317 regname = regname.lstrip("$") 

+

2318 value = gdb.selected_frame().read_register(regname) 

+

2319 return int(value) 

+

2320 

+

2321 def register(self, name: str) -> int: 

+

2322 if not is_alive(): 

+

2323 raise gdb.error("No debugging session active") 

+

2324 return self.__get_register(name) 

+

2325 

+

2326 @property 

+

2327 def registers(self) -> Generator[str, None, None]: 

+

2328 yield from self.all_registers 

+

2329 

+

2330 @property 

+

2331 def pc(self) -> int: 

+

2332 return self.register("$pc") 

+

2333 

+

2334 @property 

+

2335 def sp(self) -> int: 

+

2336 return self.register("$sp") 

+

2337 

+

2338 @property 

+

2339 def fp(self) -> int: 

+

2340 return self.register("$fp") 

+

2341 

+

2342 @property 

+

2343 def ptrsize(self) -> int: 

+

2344 if not self._ptrsize: 2344 ↛ 2345line 2344 didn't jump to line 2345, because the condition on line 2344 was never true

+

2345 res = cached_lookup_type("size_t") 

+

2346 if res is not None: 

+

2347 self._ptrsize = res.sizeof 

+

2348 else: 

+

2349 self._ptrsize = gdb.parse_and_eval("$pc").type.sizeof 

+

2350 return self._ptrsize 

+

2351 

+

2352 @property 

+

2353 def endianness(self) -> Endianness: 

+

2354 if not self._endianness: 

+

2355 output = gdb.execute("show endian", to_string=True).strip().lower() 

+

2356 if "little endian" in output: 2356 ↛ 2358line 2356 didn't jump to line 2358, because the condition on line 2356 was never false

+

2357 self._endianness = Endianness.LITTLE_ENDIAN 

+

2358 elif "big endian" in output: 

+

2359 self._endianness = Endianness.BIG_ENDIAN 

+

2360 else: 

+

2361 raise OSError(f"No valid endianess found in '{output}'") 

+

2362 return self._endianness 

+

2363 

+

2364 def get_ith_parameter(self, i: int, in_func: bool = True) -> Tuple[str, Optional[int]]: 

+

2365 """Retrieves the correct parameter used for the current function call.""" 

+

2366 reg = self.function_parameters[i] 

+

2367 val = self.register(reg) 

+

2368 key = reg 

+

2369 return key, val 

+

2370 

+

2371 

+

2372class GenericArchitecture(Architecture): 

+

2373 arch = "Generic" 

+

2374 mode = "" 

+

2375 aliases = ("GenericArchitecture",) 

+

2376 all_registers = () 

+

2377 instruction_length = 0 

+

2378 return_register = "" 

+

2379 function_parameters = () 

+

2380 syscall_register = "" 

+

2381 syscall_instructions = () 

+

2382 nop_insn = b"" 

+

2383 flag_register = None 

+

2384 flags_table = {} 

+

2385 

+

2386 

+

2387class RISCV(Architecture): 

+

2388 arch = "RISCV" 

+

2389 mode = "RISCV" 

+

2390 aliases = ("RISCV", Elf.Abi.RISCV) 

+

2391 all_registers = ("$zero", "$ra", "$sp", "$gp", "$tp", "$t0", "$t1", 

+

2392 "$t2", "$fp", "$s1", "$a0", "$a1", "$a2", "$a3", 

+

2393 "$a4", "$a5", "$a6", "$a7", "$s2", "$s3", "$s4", 

+

2394 "$s5", "$s6", "$s7", "$s8", "$s9", "$s10", "$s11", 

+

2395 "$t3", "$t4", "$t5", "$t6",) 

+

2396 return_register = "$a0" 

+

2397 function_parameters = ("$a0", "$a1", "$a2", "$a3", "$a4", "$a5", "$a6", "$a7") 

+

2398 syscall_register = "$a7" 

+

2399 syscall_instructions = ("ecall",) 

+

2400 nop_insn = b"\x00\x00\x00\x13" 

+

2401 # RISC-V has no flags registers 

+

2402 flag_register = None 

+

2403 flags_table = {} 

+

2404 

+

2405 @property 

+

2406 def instruction_length(self) -> int: 

+

2407 return 4 

+

2408 

+

2409 def is_call(self, insn: Instruction) -> bool: 

+

2410 return insn.mnemonic == "call" 

+

2411 

+

2412 def is_ret(self, insn: Instruction) -> bool: 

+

2413 mnemo = insn.mnemonic 

+

2414 if mnemo == "ret": 

+

2415 return True 

+

2416 elif (mnemo == "jalr" and insn.operands[0] == "zero" and 

+

2417 insn.operands[1] == "ra" and insn.operands[2] == 0): 

+

2418 return True 

+

2419 elif (mnemo == "c.jalr" and insn.operands[0] == "ra"): 

+

2420 return True 

+

2421 return False 

+

2422 

+

2423 @classmethod 

+

2424 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2425 raise OSError(f"Architecture {cls.arch} not supported yet") 

+

2426 

+

2427 @property 

+

2428 def ptrsize(self) -> int: 

+

2429 if self._ptrsize is not None: 

+

2430 return self._ptrsize 

+

2431 if is_alive(): 

+

2432 self._ptrsize = gdb.parse_and_eval("$pc").type.sizeof 

+

2433 return self._ptrsize 

+

2434 return 4 

+

2435 

+

2436 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

2437 return insn.mnemonic.startswith("b") 

+

2438 

+

2439 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

2440 def long_to_twos_complement(v: int) -> int: 

+

2441 """Convert a python long value to its two's complement.""" 

+

2442 if is_32bit(): 

+

2443 if v & 0x80000000: 

+

2444 return v - 0x100000000 

+

2445 elif is_64bit(): 

+

2446 if v & 0x8000000000000000: 

+

2447 return v - 0x10000000000000000 

+

2448 else: 

+

2449 raise OSError("RISC-V: ELF file is not ELF32 or ELF64. This is not currently supported") 

+

2450 return v 

+

2451 

+

2452 mnemo = insn.mnemonic 

+

2453 condition = mnemo[1:] 

+

2454 

+

2455 if condition.endswith("z"): 

+

2456 # r2 is the zero register if we are comparing to 0 

+

2457 rs1 = gef.arch.register(insn.operands[0]) 

+

2458 rs2 = gef.arch.register("$zero") 

+

2459 condition = condition[:-1] 

+

2460 elif len(insn.operands) > 2: 

+

2461 # r2 is populated with the second operand 

+

2462 rs1 = gef.arch.register(insn.operands[0]) 

+

2463 rs2 = gef.arch.register(insn.operands[1]) 

+

2464 else: 

+

2465 raise OSError(f"RISC-V: Failed to get rs1 and rs2 for instruction: `{insn}`") 

+

2466 

+

2467 # If the conditional operation is not unsigned, convert the python long into 

+

2468 # its two's complement 

+

2469 if not condition.endswith("u"): 

+

2470 rs2 = long_to_twos_complement(rs2) 

+

2471 rs1 = long_to_twos_complement(rs1) 

+

2472 else: 

+

2473 condition = condition[:-1] 

+

2474 

+

2475 if condition == "eq": 

+

2476 if rs1 == rs2: taken, reason = True, f"{rs1}={rs2}" 

+

2477 else: taken, reason = False, f"{rs1}!={rs2}" 

+

2478 elif condition == "ne": 

+

2479 if rs1 != rs2: taken, reason = True, f"{rs1}!={rs2}" 

+

2480 else: taken, reason = False, f"{rs1}={rs2}" 

+

2481 elif condition == "lt": 

+

2482 if rs1 < rs2: taken, reason = True, f"{rs1}<{rs2}" 

+

2483 else: taken, reason = False, f"{rs1}>={rs2}" 

+

2484 elif condition == "le": 

+

2485 if rs1 <= rs2: taken, reason = True, f"{rs1}<={rs2}" 

+

2486 else: taken, reason = False, f"{rs1}>{rs2}" 

+

2487 elif condition == "ge": 

+

2488 if rs1 < rs2: taken, reason = True, f"{rs1}>={rs2}" 

+

2489 else: taken, reason = False, f"{rs1}<{rs2}" 

+

2490 else: 

+

2491 raise OSError(f"RISC-V: Conditional instruction `{insn}` not supported yet") 

+

2492 

+

2493 return taken, reason 

+

2494 

+

2495 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

2496 ra = None 

+

2497 if self.is_ret(insn): 

+

2498 ra = gef.arch.register("$ra") 

+

2499 elif frame.older(): 

+

2500 ra = frame.older().pc() 

+

2501 return ra 

+

2502 

+

2503 

+

2504class ARM(Architecture): 

+

2505 aliases = ("ARM", Elf.Abi.ARM) 

+

2506 arch = "ARM" 

+

2507 all_registers = ("$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", 

+

2508 "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$sp", 

+

2509 "$lr", "$pc", "$cpsr",) 

+

2510 

+

2511 # https://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0041c/Caccegih.html 

+

2512 nop_insn = b"\x01\x10\xa0\xe1" # mov r1, r1 

+

2513 return_register = "$r0" 

+

2514 flag_register: str = "$cpsr" 

+

2515 flags_table = { 

+

2516 31: "negative", 

+

2517 30: "zero", 

+

2518 29: "carry", 

+

2519 28: "overflow", 

+

2520 7: "interrupt", 

+

2521 6: "fast", 

+

2522 5: "thumb", 

+

2523 } 

+

2524 function_parameters = ("$r0", "$r1", "$r2", "$r3") 

+

2525 syscall_register = "$r7" 

+

2526 syscall_instructions = ("swi 0x0", "swi NR") 

+

2527 _endianness = Endianness.LITTLE_ENDIAN 

+

2528 

+

2529 def is_thumb(self) -> bool: 

+

2530 """Determine if the machine is currently in THUMB mode.""" 

+

2531 return is_alive() and (self.cpsr & (1 << 5) == 1) 

+

2532 

+

2533 @property 

+

2534 def pc(self) -> Optional[int]: 

+

2535 pc = gef.arch.register("$pc") 

+

2536 if self.is_thumb(): 

+

2537 pc += 1 

+

2538 return pc 

+

2539 

+

2540 @property 

+

2541 def cpsr(self) -> int: 

+

2542 if not is_alive(): 

+

2543 raise RuntimeError("Cannot get CPSR, program not started?") 

+

2544 return gef.arch.register(self.flag_register) 

+

2545 

+

2546 @property 

+

2547 def mode(self) -> str: 

+

2548 return "THUMB" if self.is_thumb() else "ARM" 

+

2549 

+

2550 @property 

+

2551 def instruction_length(self) -> Optional[int]: 

+

2552 # Thumb instructions have variable-length (2 or 4-byte) 

+

2553 return None if self.is_thumb() else 4 

+

2554 

+

2555 @property 

+

2556 def ptrsize(self) -> int: 

+

2557 return 4 

+

2558 

+

2559 def is_call(self, insn: Instruction) -> bool: 

+

2560 mnemo = insn.mnemonic 

+

2561 call_mnemos = {"bl", "blx"} 

+

2562 return mnemo in call_mnemos 

+

2563 

+

2564 def is_ret(self, insn: Instruction) -> bool: 

+

2565 pop_mnemos = {"pop"} 

+

2566 branch_mnemos = {"bl", "bx"} 

+

2567 write_mnemos = {"ldr", "add"} 

+

2568 if insn.mnemonic in pop_mnemos: 

+

2569 return insn.operands[-1] == " pc}" 

+

2570 if insn.mnemonic in branch_mnemos: 

+

2571 return insn.operands[-1] == "lr" 

+

2572 if insn.mnemonic in write_mnemos: 

+

2573 return insn.operands[0] == "pc" 

+

2574 return False 

+

2575 

+

2576 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

2577 # https://www.botskool.com/user-pages/tutorials/electronics/arm-7-tutorial-part-1 

+

2578 if val is None: 

+

2579 reg = self.flag_register 

+

2580 val = gef.arch.register(reg) 

+

2581 return flags_to_human(val, self.flags_table) 

+

2582 

+

2583 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

2584 conditions = {"eq", "ne", "lt", "le", "gt", "ge", "vs", "vc", "mi", "pl", "hi", "ls", "cc", "cs"} 

+

2585 return insn.mnemonic[-2:] in conditions 

+

2586 

+

2587 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

2588 mnemo = insn.mnemonic 

+

2589 # ref: https://www.davespace.co.uk/arm/introduction-to-arm/conditional.html 

+

2590 flags = dict((self.flags_table[k], k) for k in self.flags_table) 

+

2591 val = gef.arch.register(self.flag_register) 

+

2592 taken, reason = False, "" 

+

2593 

+

2594 if mnemo.endswith("eq"): taken, reason = bool(val&(1<<flags["zero"])), "Z" 

+

2595 elif mnemo.endswith("ne"): taken, reason = not bool(val&(1<<flags["zero"])), "!Z" 

+

2596 elif mnemo.endswith("lt"): 

+

2597 taken, reason = bool(val&(1<<flags["negative"])) != bool(val&(1<<flags["overflow"])), "N!=V" 

+

2598 elif mnemo.endswith("le"): 

+

2599 taken, reason = bool(val&(1<<flags["zero"])) or \ 

+

2600 bool(val&(1<<flags["negative"])) != bool(val&(1<<flags["overflow"])), "Z || N!=V" 

+

2601 elif mnemo.endswith("gt"): 

+

2602 taken, reason = bool(val&(1<<flags["zero"])) == 0 and \ 

+

2603 bool(val&(1<<flags["negative"])) == bool(val&(1<<flags["overflow"])), "!Z && N==V" 

+

2604 elif mnemo.endswith("ge"): 

+

2605 taken, reason = bool(val&(1<<flags["negative"])) == bool(val&(1<<flags["overflow"])), "N==V" 

+

2606 elif mnemo.endswith("vs"): taken, reason = bool(val&(1<<flags["overflow"])), "V" 

+

2607 elif mnemo.endswith("vc"): taken, reason = not val&(1<<flags["overflow"]), "!V" 

+

2608 elif mnemo.endswith("mi"): 

+

2609 taken, reason = bool(val&(1<<flags["negative"])), "N" 

+

2610 elif mnemo.endswith("pl"): 

+

2611 taken, reason = not val&(1<<flags["negative"]), "N==0" 

+

2612 elif mnemo.endswith("hi"): 

+

2613 taken, reason = bool(val&(1<<flags["carry"])) and not bool(val&(1<<flags["zero"])), "C && !Z" 

+

2614 elif mnemo.endswith("ls"): 

+

2615 taken, reason = not val&(1<<flags["carry"]) or bool(val&(1<<flags["zero"])), "!C || Z" 

+

2616 elif mnemo.endswith("cs"): taken, reason = bool(val&(1<<flags["carry"])), "C" 

+

2617 elif mnemo.endswith("cc"): taken, reason = not val&(1<<flags["carry"]), "!C" 

+

2618 return taken, reason 

+

2619 

+

2620 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> int: 

+

2621 ra = None 

+

2622 if self.is_ret(insn): 

+

2623 # If it's a pop, we have to peek into the stack, otherwise use lr 

+

2624 if insn.mnemonic == "pop": 

+

2625 ra_addr = gef.arch.sp + (len(insn.operands)-1) * self.ptrsize 

+

2626 ra = to_unsigned_long(dereference(ra_addr)) 

+

2627 elif insn.mnemonic == "ldr": 

+

2628 return to_unsigned_long(dereference(gef.arch.sp)) 

+

2629 else: # 'bx lr' or 'add pc, lr, #0' 

+

2630 return gef.arch.register("$lr") 

+

2631 elif frame.older(): 

+

2632 ra = frame.older().pc() 

+

2633 return ra 

+

2634 

+

2635 @classmethod 

+

2636 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2637 _NR_mprotect = 125 

+

2638 insns = [ 

+

2639 "push {r0-r2, r7}", 

+

2640 f"mov r1, {addr & 0xffff:d}", 

+

2641 f"mov r0, {(addr & 0xffff0000) >> 16:d}", 

+

2642 "lsl r0, r0, 16", 

+

2643 "add r0, r0, r1", 

+

2644 f"mov r1, {size & 0xffff:d}", 

+

2645 f"mov r2, {perm.value & 0xff:d}", 

+

2646 f"mov r7, {_NR_mprotect:d}", 

+

2647 "svc 0", 

+

2648 "pop {r0-r2, r7}", 

+

2649 ] 

+

2650 return "; ".join(insns) 

+

2651 

+

2652 

+

2653class AARCH64(ARM): 

+

2654 aliases = ("ARM64", "AARCH64", Elf.Abi.AARCH64) 

+

2655 arch = "ARM64" 

+

2656 mode: str = "" 

+

2657 

+

2658 all_registers = ( 

+

2659 "$x0", "$x1", "$x2", "$x3", "$x4", "$x5", "$x6", "$x7", 

+

2660 "$x8", "$x9", "$x10", "$x11", "$x12", "$x13", "$x14","$x15", 

+

2661 "$x16", "$x17", "$x18", "$x19", "$x20", "$x21", "$x22", "$x23", 

+

2662 "$x24", "$x25", "$x26", "$x27", "$x28", "$x29", "$x30", "$sp", 

+

2663 "$pc", "$cpsr", "$fpsr", "$fpcr",) 

+

2664 return_register = "$x0" 

+

2665 flag_register = "$cpsr" 

+

2666 flags_table = { 

+

2667 31: "negative", 

+

2668 30: "zero", 

+

2669 29: "carry", 

+

2670 28: "overflow", 

+

2671 7: "interrupt", 

+

2672 9: "endian", 

+

2673 6: "fast", 

+

2674 5: "t32", 

+

2675 4: "m[4]", 

+

2676 } 

+

2677 function_parameters = ("$x0", "$x1", "$x2", "$x3", "$x4", "$x5", "$x6", "$x7",) 

+

2678 syscall_register = "$x8" 

+

2679 syscall_instructions = ("svc $x0",) 

+

2680 

+

2681 def is_call(self, insn: Instruction) -> bool: 

+

2682 mnemo = insn.mnemonic 

+

2683 call_mnemos = {"bl", "blr"} 

+

2684 return mnemo in call_mnemos 

+

2685 

+

2686 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

2687 # https://events.linuxfoundation.org/sites/events/files/slides/KoreaLinuxForum-2014.pdf 

+

2688 reg = self.flag_register 

+

2689 if not val: 

+

2690 val = gef.arch.register(reg) 

+

2691 return flags_to_human(val, self.flags_table) 

+

2692 

+

2693 def is_aarch32(self) -> bool: 

+

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

+

2695 return (self.cpsr & (1 << 4) != 0) and (self.cpsr & (1 << 5) == 0) 

+

2696 

+

2697 def is_thumb32(self) -> bool: 

+

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

+

2699 return (self.cpsr & (1 << 4) == 1) and (self.cpsr & (1 << 5) == 1) 

+

2700 

+

2701 @property 

+

2702 def ptrsize(self) -> int: 

+

2703 """Determine the size of pointer from the current CPU mode""" 

+

2704 if not is_alive(): 

+

2705 return 8 

+

2706 if self.is_aarch32(): 

+

2707 return 4 

+

2708 if self.is_thumb32(): 

+

2709 return 2 

+

2710 return 8 

+

2711 

+

2712 @classmethod 

+

2713 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2714 _NR_mprotect = 226 

+

2715 insns = [ 

+

2716 "str x8, [sp, -16]!", 

+

2717 "str x0, [sp, -16]!", 

+

2718 "str x1, [sp, -16]!", 

+

2719 "str x2, [sp, -16]!", 

+

2720 f"mov x8, {_NR_mprotect:d}", 

+

2721 f"movz x0, {addr & 0xFFFF:#x}", 

+

2722 f"movk x0, {(addr >> 16) & 0xFFFF:#x}, lsl 16", 

+

2723 f"movk x0, {(addr >> 32) & 0xFFFF:#x}, lsl 32", 

+

2724 f"movk x0, {(addr >> 48) & 0xFFFF:#x}, lsl 48", 

+

2725 f"movz x1, {size & 0xFFFF:#x}", 

+

2726 f"movk x1, {(size >> 16) & 0xFFFF:#x}, lsl 16", 

+

2727 f"mov x2, {perm.value:d}", 

+

2728 "svc 0", 

+

2729 "ldr x2, [sp], 16", 

+

2730 "ldr x1, [sp], 16", 

+

2731 "ldr x0, [sp], 16", 

+

2732 "ldr x8, [sp], 16", 

+

2733 ] 

+

2734 return "; ".join(insns) 

+

2735 

+

2736 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

2737 # https://www.element14.com/community/servlet/JiveServlet/previewBody/41836-102-1-229511/ARM.Reference_Manual.pdf 

+

2738 # sect. 5.1.1 

+

2739 mnemo = insn.mnemonic 

+

2740 branch_mnemos = {"cbnz", "cbz", "tbnz", "tbz"} 

+

2741 return mnemo.startswith("b.") or mnemo in branch_mnemos 

+

2742 

+

2743 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

2744 mnemo, operands = insn.mnemonic, insn.operands 

+

2745 taken, reason = False, "" 

+

2746 

+

2747 if mnemo in {"cbnz", "cbz", "tbnz", "tbz"}: 

+

2748 reg = f"${operands[0]}" 

+

2749 op = gef.arch.register(reg) 

+

2750 if mnemo == "cbnz": 

+

2751 if op!=0: taken, reason = True, f"{reg}!=0" 

+

2752 else: taken, reason = False, f"{reg}==0" 

+

2753 elif mnemo == "cbz": 

+

2754 if op == 0: taken, reason = True, f"{reg}==0" 

+

2755 else: taken, reason = False, f"{reg}!=0" 

+

2756 elif mnemo == "tbnz": 

+

2757 # operands[1] has one or more white spaces in front, then a #, then the number 

+

2758 # so we need to eliminate them 

+

2759 i = int(operands[1].strip().lstrip("#")) 

+

2760 if (op & 1<<i) != 0: taken, reason = True, f"{reg}&1<<{i}!=0" 

+

2761 else: taken, reason = False, f"{reg}&1<<{i}==0" 

+

2762 elif mnemo == "tbz": 

+

2763 # operands[1] has one or more white spaces in front, then a #, then the number 

+

2764 # so we need to eliminate them 

+

2765 i = int(operands[1].strip().lstrip("#")) 

+

2766 if (op & 1<<i) == 0: taken, reason = True, f"{reg}&1<<{i}==0" 

+

2767 else: taken, reason = False, f"{reg}&1<<{i}!=0" 

+

2768 

+

2769 if not reason: 

+

2770 taken, reason = super().is_branch_taken(insn) 

+

2771 return taken, reason 

+

2772 

+

2773 

+

2774class X86(Architecture): 

+

2775 aliases: Tuple[Union[str, Elf.Abi], ...] = ("X86", Elf.Abi.X86_32) 

+

2776 arch = "X86" 

+

2777 mode = "32" 

+

2778 

+

2779 nop_insn = b"\x90" 

+

2780 flag_register: str = "$eflags" 

+

2781 special_registers = ("$cs", "$ss", "$ds", "$es", "$fs", "$gs", ) 

+

2782 gpr_registers = ("$eax", "$ebx", "$ecx", "$edx", "$esp", "$ebp", "$esi", "$edi", "$eip", ) 

+

2783 all_registers = gpr_registers + ( flag_register,) + special_registers 

+

2784 instruction_length = None 

+

2785 return_register = "$eax" 

+

2786 function_parameters = ("$esp", ) 

+

2787 flags_table = { 

+

2788 6: "zero", 

+

2789 0: "carry", 

+

2790 2: "parity", 

+

2791 4: "adjust", 

+

2792 7: "sign", 

+

2793 8: "trap", 

+

2794 9: "interrupt", 

+

2795 10: "direction", 

+

2796 11: "overflow", 

+

2797 16: "resume", 

+

2798 17: "virtualx86", 

+

2799 21: "identification", 

+

2800 } 

+

2801 syscall_register = "$eax" 

+

2802 syscall_instructions = ("sysenter", "int 0x80") 

+

2803 _ptrsize = 4 

+

2804 _endianness = Endianness.LITTLE_ENDIAN 

+

2805 

+

2806 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

2807 reg = self.flag_register 

+

2808 if not val: 2808 ↛ 2810line 2808 didn't jump to line 2810, because the condition on line 2808 was never false

+

2809 val = gef.arch.register(reg) 

+

2810 return flags_to_human(val, self.flags_table) 

+

2811 

+

2812 def is_call(self, insn: Instruction) -> bool: 

+

2813 mnemo = insn.mnemonic 

+

2814 call_mnemos = {"call", "callq"} 

+

2815 return mnemo in call_mnemos 

+

2816 

+

2817 def is_ret(self, insn: Instruction) -> bool: 

+

2818 return insn.mnemonic == "ret" 

+

2819 

+

2820 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

2821 mnemo = insn.mnemonic 

+

2822 branch_mnemos = { 

+

2823 "ja", "jnbe", "jae", "jnb", "jnc", "jb", "jc", "jnae", "jbe", "jna", 

+

2824 "jcxz", "jecxz", "jrcxz", "je", "jz", "jg", "jnle", "jge", "jnl", 

+

2825 "jl", "jnge", "jle", "jng", "jne", "jnz", "jno", "jnp", "jpo", "jns", 

+

2826 "jo", "jp", "jpe", "js" 

+

2827 } 

+

2828 return mnemo in branch_mnemos 

+

2829 

+

2830 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

2831 mnemo = insn.mnemonic 

+

2832 # all kudos to fG! (https://github.com/gdbinit/Gdbinit/blob/master/gdbinit#L1654) 

+

2833 flags = dict((self.flags_table[k], k) for k in self.flags_table) 

+

2834 val = gef.arch.register(self.flag_register) 

+

2835 

+

2836 taken, reason = False, "" 

+

2837 

+

2838 if mnemo in ("ja", "jnbe"): 

+

2839 taken, reason = not val&(1<<flags["carry"]) and not bool(val&(1<<flags["zero"])), "!C && !Z" 

+

2840 elif mnemo in ("jae", "jnb", "jnc"): 

+

2841 taken, reason = not val&(1<<flags["carry"]), "!C" 

+

2842 elif mnemo in ("jb", "jc", "jnae"): 

+

2843 taken, reason = bool(val&(1<<flags["carry"])) != 0, "C" 

+

2844 elif mnemo in ("jbe", "jna"): 

+

2845 taken, reason = bool(val&(1<<flags["carry"])) or bool(val&(1<<flags["zero"])), "C || Z" 

+

2846 elif mnemo in ("jcxz", "jecxz", "jrcxz"): 

+

2847 cx = gef.arch.register("$rcx") if is_x86_64() else gef.arch.register("$ecx") 

+

2848 taken, reason = cx == 0, "!$CX" 

+

2849 elif mnemo in ("je", "jz"): 

+

2850 taken, reason = bool(val&(1<<flags["zero"])), "Z" 

+

2851 elif mnemo in ("jne", "jnz"): 

+

2852 taken, reason = not bool(val&(1<<flags["zero"])), "!Z" 

+

2853 elif mnemo in ("jg", "jnle"): 

+

2854 taken, reason = not bool(val&(1<<flags["zero"])) and bool(val&(1<<flags["overflow"])) == bool(val&(1<<flags["sign"])), "!Z && S==O" 

+

2855 elif mnemo in ("jge", "jnl"): 

+

2856 taken, reason = bool(val&(1<<flags["sign"])) == bool(val&(1<<flags["overflow"])), "S==O" 

+

2857 elif mnemo in ("jl", "jnge"): 

+

2858 taken, reason = bool(val&(1<<flags["overflow"]) != val&(1<<flags["sign"])), "S!=O" 

+

2859 elif mnemo in ("jle", "jng"): 

+

2860 taken, reason = bool(val&(1<<flags["zero"])) or bool(val&(1<<flags["overflow"])) != bool(val&(1<<flags["sign"])), "Z || S!=O" 

+

2861 elif mnemo in ("jo",): 

+

2862 taken, reason = bool(val&(1<<flags["overflow"])), "O" 

+

2863 elif mnemo in ("jno",): 

+

2864 taken, reason = not val&(1<<flags["overflow"]), "!O" 

+

2865 elif mnemo in ("jpe", "jp"): 

+

2866 taken, reason = bool(val&(1<<flags["parity"])), "P" 

+

2867 elif mnemo in ("jnp", "jpo"): 

+

2868 taken, reason = not val&(1<<flags["parity"]), "!P" 

+

2869 elif mnemo in ("js",): 

+

2870 taken, reason = bool(val&(1<<flags["sign"])) != 0, "S" 

+

2871 elif mnemo in ("jns",): 

+

2872 taken, reason = not val&(1<<flags["sign"]), "!S" 

+

2873 return taken, reason 

+

2874 

+

2875 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

2876 ra = None 

+

2877 if self.is_ret(insn): 2877 ↛ 2879line 2877 didn't jump to line 2879, because the condition on line 2877 was never false

+

2878 ra = to_unsigned_long(dereference(gef.arch.sp)) 

+

2879 if frame.older(): 2879 ↛ 2882line 2879 didn't jump to line 2882, because the condition on line 2879 was never false

+

2880 ra = frame.older().pc() 

+

2881 

+

2882 return ra 

+

2883 

+

2884 @classmethod 

+

2885 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2886 _NR_mprotect = 125 

+

2887 insns = [ 

+

2888 "pushad", 

+

2889 "pushfd", 

+

2890 f"mov eax, {_NR_mprotect:d}", 

+

2891 f"mov ebx, {addr:d}", 

+

2892 f"mov ecx, {size:d}", 

+

2893 f"mov edx, {perm.value:d}", 

+

2894 "int 0x80", 

+

2895 "popfd", 

+

2896 "popad", 

+

2897 ] 

+

2898 return "; ".join(insns) 

+

2899 

+

2900 def get_ith_parameter(self, i: int, in_func: bool = True) -> Tuple[str, Optional[int]]: 

+

2901 if in_func: 

+

2902 i += 1 # Account for RA being at the top of the stack 

+

2903 sp = gef.arch.sp 

+

2904 sz = gef.arch.ptrsize 

+

2905 loc = sp + (i * sz) 

+

2906 val = gef.memory.read_integer(loc) 

+

2907 key = f"[sp + {i * sz:#x}]" 

+

2908 return key, val 

+

2909 

+

2910 

+

2911class X86_64(X86): 

+

2912 aliases = ("X86_64", Elf.Abi.X86_64, "i386:x86-64") 

+

2913 arch = "X86" 

+

2914 mode = "64" 

+

2915 

+

2916 gpr_registers = ( 

+

2917 "$rax", "$rbx", "$rcx", "$rdx", "$rsp", "$rbp", "$rsi", "$rdi", "$rip", 

+

2918 "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15", ) 

+

2919 all_registers = gpr_registers + ( X86.flag_register, ) + X86.special_registers 

+

2920 return_register = "$rax" 

+

2921 function_parameters = ["$rdi", "$rsi", "$rdx", "$rcx", "$r8", "$r9"] 

+

2922 syscall_register = "$rax" 

+

2923 syscall_instructions = ["syscall"] 

+

2924 # We don't want to inherit x86's stack based param getter 

+

2925 get_ith_parameter = Architecture.get_ith_parameter 

+

2926 _ptrsize = 8 

+

2927 

+

2928 @classmethod 

+

2929 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

2930 _NR_mprotect = 10 

+

2931 insns = [ 

+

2932 "pushfq", 

+

2933 "push rax", 

+

2934 "push rdi", 

+

2935 "push rsi", 

+

2936 "push rdx", 

+

2937 "push rcx", 

+

2938 "push r11", 

+

2939 f"mov rax, {_NR_mprotect:d}", 

+

2940 f"mov rdi, {addr:d}", 

+

2941 f"mov rsi, {size:d}", 

+

2942 f"mov rdx, {perm.value:d}", 

+

2943 "syscall", 

+

2944 "pop r11", 

+

2945 "pop rcx", 

+

2946 "pop rdx", 

+

2947 "pop rsi", 

+

2948 "pop rdi", 

+

2949 "pop rax", 

+

2950 "popfq", 

+

2951 ] 

+

2952 return "; ".join(insns) 

+

2953 

+

2954 def canary_address(self) -> int: 

+

2955 return self.register("fs_base") + 0x28 

+

2956 

+

2957class PowerPC(Architecture): 

+

2958 aliases = ("PowerPC", Elf.Abi.POWERPC, "PPC") 

+

2959 arch = "PPC" 

+

2960 mode = "PPC32" 

+

2961 

+

2962 all_registers = ( 

+

2963 "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", 

+

2964 "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15", 

+

2965 "$r16", "$r17", "$r18", "$r19", "$r20", "$r21", "$r22", "$r23", 

+

2966 "$r24", "$r25", "$r26", "$r27", "$r28", "$r29", "$r30", "$r31", 

+

2967 "$pc", "$msr", "$cr", "$lr", "$ctr", "$xer", "$trap",) 

+

2968 instruction_length = 4 

+

2969 nop_insn = b"\x60\x00\x00\x00" # https://developer.ibm.com/articles/l-ppc/ 

+

2970 return_register = "$r0" 

+

2971 flag_register: str = "$cr" 

+

2972 flags_table = { 

+

2973 3: "negative[0]", 

+

2974 2: "positive[0]", 

+

2975 1: "equal[0]", 

+

2976 0: "overflow[0]", 

+

2977 # cr7 

+

2978 31: "less[7]", 

+

2979 30: "greater[7]", 

+

2980 29: "equal[7]", 

+

2981 28: "overflow[7]", 

+

2982 } 

+

2983 function_parameters = ("$i0", "$i1", "$i2", "$i3", "$i4", "$i5") 

+

2984 syscall_register = "$r0" 

+

2985 syscall_instructions = ("sc",) 

+

2986 ptrsize = 4 

+

2987 

+

2988 

+

2989 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

2990 # https://www.cebix.net/downloads/bebox/pem32b.pdf (% 2.1.3) 

+

2991 if not val: 

+

2992 reg = self.flag_register 

+

2993 val = gef.arch.register(reg) 

+

2994 return flags_to_human(val, self.flags_table) 

+

2995 

+

2996 def is_call(self, insn: Instruction) -> bool: 

+

2997 return False 

+

2998 

+

2999 def is_ret(self, insn: Instruction) -> bool: 

+

3000 return insn.mnemonic == "blr" 

+

3001 

+

3002 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

3003 mnemo = insn.mnemonic 

+

3004 branch_mnemos = {"beq", "bne", "ble", "blt", "bgt", "bge"} 

+

3005 return mnemo in branch_mnemos 

+

3006 

+

3007 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

3008 mnemo = insn.mnemonic 

+

3009 flags = dict((self.flags_table[k], k) for k in self.flags_table) 

+

3010 val = gef.arch.register(self.flag_register) 

+

3011 taken, reason = False, "" 

+

3012 if mnemo == "beq": taken, reason = bool(val&(1<<flags["equal[7]"])), "E" 

+

3013 elif mnemo == "bne": taken, reason = val&(1<<flags["equal[7]"]) == 0, "!E" 

+

3014 elif mnemo == "ble": taken, reason = bool(val&(1<<flags["equal[7]"])) or bool(val&(1<<flags["less[7]"])), "E || L" 

+

3015 elif mnemo == "blt": taken, reason = bool(val&(1<<flags["less[7]"])), "L" 

+

3016 elif mnemo == "bge": taken, reason = bool(val&(1<<flags["equal[7]"])) or bool(val&(1<<flags["greater[7]"])), "E || G" 

+

3017 elif mnemo == "bgt": taken, reason = bool(val&(1<<flags["greater[7]"])), "G" 

+

3018 return taken, reason 

+

3019 

+

3020 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

3021 ra = None 

+

3022 if self.is_ret(insn): 

+

3023 ra = gef.arch.register("$lr") 

+

3024 elif frame.older(): 

+

3025 ra = frame.older().pc() 

+

3026 return ra 

+

3027 

+

3028 @classmethod 

+

3029 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

3030 # Ref: https://developer.ibm.com/articles/l-ppc/ 

+

3031 _NR_mprotect = 125 

+

3032 insns = [ 

+

3033 "addi 1, 1, -16", # 1 = r1 = sp 

+

3034 "stw 0, 0(1)", 

+

3035 "stw 3, 4(1)", # r0 = syscall_code | r3, r4, r5 = args 

+

3036 "stw 4, 8(1)", 

+

3037 "stw 5, 12(1)", 

+

3038 f"li 0, {_NR_mprotect:d}", 

+

3039 f"lis 3, {addr:#x}@h", 

+

3040 f"ori 3, 3, {addr:#x}@l", 

+

3041 f"lis 4, {size:#x}@h", 

+

3042 f"ori 4, 4, {size:#x}@l", 

+

3043 f"li 5, {perm.value:d}", 

+

3044 "sc", 

+

3045 "lwz 0, 0(1)", 

+

3046 "lwz 3, 4(1)", 

+

3047 "lwz 4, 8(1)", 

+

3048 "lwz 5, 12(1)", 

+

3049 "addi 1, 1, 16", 

+

3050 ] 

+

3051 return ";".join(insns) 

+

3052 

+

3053 

+

3054class PowerPC64(PowerPC): 

+

3055 aliases = ("PowerPC64", Elf.Abi.POWERPC64, "PPC64") 

+

3056 arch = "PPC" 

+

3057 mode = "PPC64" 

+

3058 ptrsize = 8 

+

3059 

+

3060 

+

3061class SPARC(Architecture): 

+

3062 """ Refs: 

+

3063 - https://www.cse.scu.edu/~atkinson/teaching/sp05/259/sparc.pdf 

+

3064 """ 

+

3065 aliases = ("SPARC", Elf.Abi.SPARC) 

+

3066 arch = "SPARC" 

+

3067 mode = "" 

+

3068 

+

3069 all_registers = ( 

+

3070 "$g0", "$g1", "$g2", "$g3", "$g4", "$g5", "$g6", "$g7", 

+

3071 "$o0", "$o1", "$o2", "$o3", "$o4", "$o5", "$o7", 

+

3072 "$l0", "$l1", "$l2", "$l3", "$l4", "$l5", "$l6", "$l7", 

+

3073 "$i0", "$i1", "$i2", "$i3", "$i4", "$i5", "$i7", 

+

3074 "$pc", "$npc", "$sp ", "$fp ", "$psr",) 

+

3075 instruction_length = 4 

+

3076 nop_insn = b"\x00\x00\x00\x00" # sethi 0, %g0 

+

3077 return_register = "$i0" 

+

3078 flag_register: str = "$psr" 

+

3079 flags_table = { 

+

3080 23: "negative", 

+

3081 22: "zero", 

+

3082 21: "overflow", 

+

3083 20: "carry", 

+

3084 7: "supervisor", 

+

3085 5: "trap", 

+

3086 } 

+

3087 function_parameters = ("$o0 ", "$o1 ", "$o2 ", "$o3 ", "$o4 ", "$o5 ", "$o7 ",) 

+

3088 syscall_register = "%g1" 

+

3089 syscall_instructions = ("t 0x10",) 

+

3090 

+

3091 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

3092 # https://www.gaisler.com/doc/sparcv8.pdf 

+

3093 reg = self.flag_register 

+

3094 if not val: 

+

3095 val = gef.arch.register(reg) 

+

3096 return flags_to_human(val, self.flags_table) 

+

3097 

+

3098 def is_call(self, insn: Instruction) -> bool: 

+

3099 return False 

+

3100 

+

3101 def is_ret(self, insn: Instruction) -> bool: 

+

3102 return insn.mnemonic == "ret" 

+

3103 

+

3104 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

3105 mnemo = insn.mnemonic 

+

3106 # http://moss.csc.ncsu.edu/~mueller/codeopt/codeopt00/notes/condbranch.html 

+

3107 branch_mnemos = { 

+

3108 "be", "bne", "bg", "bge", "bgeu", "bgu", "bl", "ble", "blu", "bleu", 

+

3109 "bneg", "bpos", "bvs", "bvc", "bcs", "bcc" 

+

3110 } 

+

3111 return mnemo in branch_mnemos 

+

3112 

+

3113 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

3114 mnemo = insn.mnemonic 

+

3115 flags = dict((self.flags_table[k], k) for k in self.flags_table) 

+

3116 val = gef.arch.register(self.flag_register) 

+

3117 taken, reason = False, "" 

+

3118 

+

3119 if mnemo == "be": taken, reason = bool(val&(1<<flags["zero"])), "Z" 

+

3120 elif mnemo == "bne": taken, reason = bool(val&(1<<flags["zero"])) == 0, "!Z" 

+

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

+

3122 elif mnemo == "bge": taken, reason = val&(1<<flags["negative"]) == 0 or val&(1<<flags["overflow"]) == 0, "!N || !O" 

+

3123 elif mnemo == "bgu": taken, reason = val&(1<<flags["carry"]) == 0 and val&(1<<flags["zero"]) == 0, "!C && !Z" 

+

3124 elif mnemo == "bgeu": taken, reason = val&(1<<flags["carry"]) == 0, "!C" 

+

3125 elif mnemo == "bl": taken, reason = bool(val&(1<<flags["negative"])) and bool(val&(1<<flags["overflow"])), "N && O" 

+

3126 elif mnemo == "blu": taken, reason = bool(val&(1<<flags["carry"])), "C" 

+

3127 elif mnemo == "ble": taken, reason = bool(val&(1<<flags["zero"])) or bool(val&(1<<flags["negative"]) or val&(1<<flags["overflow"])), "Z || (N || O)" 

+

3128 elif mnemo == "bleu": taken, reason = bool(val&(1<<flags["carry"])) or bool(val&(1<<flags["zero"])), "C || Z" 

+

3129 elif mnemo == "bneg": taken, reason = bool(val&(1<<flags["negative"])), "N" 

+

3130 elif mnemo == "bpos": taken, reason = val&(1<<flags["negative"]) == 0, "!N" 

+

3131 elif mnemo == "bvs": taken, reason = bool(val&(1<<flags["overflow"])), "O" 

+

3132 elif mnemo == "bvc": taken, reason = val&(1<<flags["overflow"]) == 0, "!O" 

+

3133 elif mnemo == "bcs": taken, reason = bool(val&(1<<flags["carry"])), "C" 

+

3134 elif mnemo == "bcc": taken, reason = val&(1<<flags["carry"]) == 0, "!C" 

+

3135 return taken, reason 

+

3136 

+

3137 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

3138 ra = None 

+

3139 if self.is_ret(insn): 

+

3140 ra = gef.arch.register("$o7") 

+

3141 elif frame.older(): 

+

3142 ra = frame.older().pc() 

+

3143 return ra 

+

3144 

+

3145 @classmethod 

+

3146 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

3147 hi = (addr & 0xffff0000) >> 16 

+

3148 lo = (addr & 0x0000ffff) 

+

3149 _NR_mprotect = 125 

+

3150 insns = ["add %sp, -16, %sp", 

+

3151 "st %g1, [ %sp ]", "st %o0, [ %sp + 4 ]", 

+

3152 "st %o1, [ %sp + 8 ]", "st %o2, [ %sp + 12 ]", 

+

3153 f"sethi %hi({hi}), %o0", 

+

3154 f"or %o0, {lo}, %o0", 

+

3155 "clr %o1", 

+

3156 "clr %o2", 

+

3157 f"mov {_NR_mprotect}, %g1", 

+

3158 "t 0x10", 

+

3159 "ld [ %sp ], %g1", "ld [ %sp + 4 ], %o0", 

+

3160 "ld [ %sp + 8 ], %o1", "ld [ %sp + 12 ], %o2", 

+

3161 "add %sp, 16, %sp",] 

+

3162 return "; ".join(insns) 

+

3163 

+

3164 

+

3165class SPARC64(SPARC): 

+

3166 """Refs: 

+

3167 - http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_sparc.pdf 

+

3168 - https://cr.yp.to/2005-590/sparcv9.pdf 

+

3169 """ 

+

3170 aliases = ("SPARC64", Elf.Abi.SPARC64) 

+

3171 arch = "SPARC" 

+

3172 mode = "V9" 

+

3173 

+

3174 all_registers = [ 

+

3175 "$g0", "$g1", "$g2", "$g3", "$g4", "$g5", "$g6", "$g7", 

+

3176 "$o0", "$o1", "$o2", "$o3", "$o4", "$o5", "$o7", 

+

3177 "$l0", "$l1", "$l2", "$l3", "$l4", "$l5", "$l6", "$l7", 

+

3178 "$i0", "$i1", "$i2", "$i3", "$i4", "$i5", "$i7", 

+

3179 "$pc", "$npc", "$sp", "$fp", "$state", ] 

+

3180 

+

3181 flag_register = "$state" # sparcv9.pdf, 5.1.5.1 (ccr) 

+

3182 flags_table = { 

+

3183 35: "negative", 

+

3184 34: "zero", 

+

3185 33: "overflow", 

+

3186 32: "carry", 

+

3187 } 

+

3188 

+

3189 syscall_instructions = ["t 0x6d"] 

+

3190 

+

3191 @classmethod 

+

3192 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

3193 hi = (addr & 0xffff0000) >> 16 

+

3194 lo = (addr & 0x0000ffff) 

+

3195 _NR_mprotect = 125 

+

3196 insns = ["add %sp, -16, %sp", 

+

3197 "st %g1, [ %sp ]", "st %o0, [ %sp + 4 ]", 

+

3198 "st %o1, [ %sp + 8 ]", "st %o2, [ %sp + 12 ]", 

+

3199 f"sethi %hi({hi}), %o0", 

+

3200 f"or %o0, {lo}, %o0", 

+

3201 "clr %o1", 

+

3202 "clr %o2", 

+

3203 f"mov {_NR_mprotect}, %g1", 

+

3204 "t 0x6d", 

+

3205 "ld [ %sp ], %g1", "ld [ %sp + 4 ], %o0", 

+

3206 "ld [ %sp + 8 ], %o1", "ld [ %sp + 12 ], %o2", 

+

3207 "add %sp, 16, %sp",] 

+

3208 return "; ".join(insns) 

+

3209 

+

3210 

+

3211class MIPS(Architecture): 

+

3212 aliases: Tuple[Union[str, Elf.Abi], ...] = ("MIPS", Elf.Abi.MIPS) 

+

3213 arch = "MIPS" 

+

3214 mode = "MIPS32" 

+

3215 

+

3216 # https://vhouten.home.xs4all.nl/mipsel/r3000-isa.html 

+

3217 all_registers = ( 

+

3218 "$zero", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3", 

+

3219 "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", 

+

3220 "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7", 

+

3221 "$t8", "$t9", "$k0", "$k1", "$s8", "$pc", "$sp", "$hi", 

+

3222 "$lo", "$fir", "$ra", "$gp", ) 

+

3223 instruction_length = 4 

+

3224 _ptrsize = 4 

+

3225 nop_insn = b"\x00\x00\x00\x00" # sll $0,$0,0 

+

3226 return_register = "$v0" 

+

3227 flag_register = "$fcsr" 

+

3228 flags_table = {} 

+

3229 function_parameters = ("$a0", "$a1", "$a2", "$a3") 

+

3230 syscall_register = "$v0" 

+

3231 syscall_instructions = ("syscall",) 

+

3232 

+

3233 def flag_register_to_human(self, val: Optional[int] = None) -> str: 

+

3234 return Color.colorify("No flag register", "yellow underline") 

+

3235 

+

3236 def is_call(self, insn: Instruction) -> bool: 

+

3237 return False 

+

3238 

+

3239 def is_ret(self, insn: Instruction) -> bool: 

+

3240 return insn.mnemonic == "jr" and insn.operands[0] == "ra" 

+

3241 

+

3242 def is_conditional_branch(self, insn: Instruction) -> bool: 

+

3243 mnemo = insn.mnemonic 

+

3244 branch_mnemos = {"beq", "bne", "beqz", "bnez", "bgtz", "bgez", "bltz", "blez"} 

+

3245 return mnemo in branch_mnemos 

+

3246 

+

3247 def is_branch_taken(self, insn: Instruction) -> Tuple[bool, str]: 

+

3248 mnemo, ops = insn.mnemonic, insn.operands 

+

3249 taken, reason = False, "" 

+

3250 

+

3251 if mnemo == "beq": 

+

3252 taken, reason = gef.arch.register(ops[0]) == gef.arch.register(ops[1]), "{0[0]} == {0[1]}".format(ops) 

+

3253 elif mnemo == "bne": 

+

3254 taken, reason = gef.arch.register(ops[0]) != gef.arch.register(ops[1]), "{0[0]} != {0[1]}".format(ops) 

+

3255 elif mnemo == "beqz": 

+

3256 taken, reason = gef.arch.register(ops[0]) == 0, "{0[0]} == 0".format(ops) 

+

3257 elif mnemo == "bnez": 

+

3258 taken, reason = gef.arch.register(ops[0]) != 0, "{0[0]} != 0".format(ops) 

+

3259 elif mnemo == "bgtz": 

+

3260 taken, reason = gef.arch.register(ops[0]) > 0, "{0[0]} > 0".format(ops) 

+

3261 elif mnemo == "bgez": 

+

3262 taken, reason = gef.arch.register(ops[0]) >= 0, "{0[0]} >= 0".format(ops) 

+

3263 elif mnemo == "bltz": 

+

3264 taken, reason = gef.arch.register(ops[0]) < 0, "{0[0]} < 0".format(ops) 

+

3265 elif mnemo == "blez": 

+

3266 taken, reason = gef.arch.register(ops[0]) <= 0, "{0[0]} <= 0".format(ops) 

+

3267 return taken, reason 

+

3268 

+

3269 def get_ra(self, insn: Instruction, frame: "gdb.Frame") -> Optional[int]: 

+

3270 ra = None 

+

3271 if self.is_ret(insn): 

+

3272 ra = gef.arch.register("$ra") 

+

3273 elif frame.older(): 

+

3274 ra = frame.older().pc() 

+

3275 return ra 

+

3276 

+

3277 @classmethod 

+

3278 def mprotect_asm(cls, addr: int, size: int, perm: Permission) -> str: 

+

3279 _NR_mprotect = 4125 

+

3280 insns = ["addi $sp, $sp, -16", 

+

3281 "sw $v0, 0($sp)", "sw $a0, 4($sp)", 

+

3282 "sw $a3, 8($sp)", "sw $a3, 12($sp)", 

+

3283 f"li $v0, {_NR_mprotect:d}", 

+

3284 f"li $a0, {addr:d}", 

+

3285 f"li $a1, {size:d}", 

+

3286 f"li $a2, {perm.value:d}", 

+

3287 "syscall", 

+

3288 "lw $v0, 0($sp)", "lw $a1, 4($sp)", 

+

3289 "lw $a3, 8($sp)", "lw $a3, 12($sp)", 

+

3290 "addi $sp, $sp, 16",] 

+

3291 return "; ".join(insns) 

+

3292 

+

3293 

+

3294class MIPS64(MIPS): 

+

3295 aliases = ("MIPS64",) 

+

3296 arch = "MIPS" 

+

3297 mode = "MIPS64" 

+

3298 _ptrsize = 8 

+

3299 

+

3300 @staticmethod 

+

3301 def supports_gdb_arch(gdb_arch: str) -> Optional[bool]: 

+

3302 return gdb_arch.startswith("mips") and gef.binary.e_class == Elf.Class.ELF_64_BITS 

+

3303 

+

3304 

+

3305def copy_to_clipboard(data: bytes) -> None: 

+

3306 """Helper function to submit data to the clipboard""" 

+

3307 if sys.platform == "linux": 

+

3308 xclip = which("xclip") 

+

3309 prog = [xclip, "-selection", "clipboard", "-i"] 

+

3310 elif sys.platform == "darwin": 

+

3311 pbcopy = which("pbcopy") 

+

3312 prog = [pbcopy] 

+

3313 else: 

+

3314 raise NotImplementedError("copy: Unsupported OS") 

+

3315 

+

3316 with subprocess.Popen(prog, stdin=subprocess.PIPE) as p: 

+

3317 p.stdin.write(data) 

+

3318 p.stdin.close() 

+

3319 p.wait() 

+

3320 return 

+

3321 

+

3322 

+

3323def use_stdtype() -> str: 

+

3324 if is_32bit(): return "uint32_t" 3324 ↛ exitline 3324 didn't return from function 'use_stdtype', because the return on line 3324 wasn't executed

+

3325 elif is_64bit(): return "uint64_t" 3325 ↛ 3326line 3325 didn't jump to line 3326, because the condition on line 3325 was never false

+

3326 return "uint16_t" 

+

3327 

+

3328 

+

3329def use_default_type() -> str: 

+

3330 if is_32bit(): return "unsigned int" 3330 ↛ exitline 3330 didn't return from function 'use_default_type', because the return on line 3330 wasn't executed

+

3331 elif is_64bit(): return "unsigned long" 3331 ↛ 3332line 3331 didn't jump to line 3332, because the condition on line 3331 was never false

+

3332 return "unsigned short" 

+

3333 

+

3334 

+

3335def use_golang_type() -> str: 

+

3336 if is_32bit(): return "uint32" 

+

3337 elif is_64bit(): return "uint64" 

+

3338 return "uint16" 

+

3339 

+

3340 

+

3341def use_rust_type() -> str: 

+

3342 if is_32bit(): return "u32" 

+

3343 elif is_64bit(): return "u64" 

+

3344 return "u16" 

+

3345 

+

3346 

+

3347def to_unsigned_long(v: gdb.Value) -> int: 

+

3348 """Cast a gdb.Value to unsigned long.""" 

+

3349 mask = (1 << 64) - 1 

+

3350 return int(v.cast(gdb.Value(mask).type)) & mask 

+

3351 

+

3352 

+

3353def get_path_from_info_proc() -> Optional[str]: 

+

3354 for x in gdb.execute("info proc", to_string=True).splitlines(): 

+

3355 if x.startswith("exe = "): 

+

3356 return x.split(" = ")[1].replace("'", "") 

+

3357 return None 

+

3358 

+

3359 

+

3360@deprecated("Use `gef.session.os`") 

+

3361def get_os() -> str: 

+

3362 return gef.session.os 

+

3363 

+

3364 

+

3365@lru_cache() 

+

3366def is_qemu() -> bool: 

+

3367 if not is_remote_debug(): 

+

3368 return False 

+

3369 response = gdb.execute("maintenance packet Qqemu.sstepbits", to_string=True, from_tty=False) 

+

3370 return "ENABLE=" in response 

+

3371 

+

3372 

+

3373@lru_cache() 

+

3374def is_qemu_usermode() -> bool: 

+

3375 if not is_qemu(): 

+

3376 return False 

+

3377 response = gdb.execute("maintenance packet qOffsets", to_string=True, from_tty=False) 

+

3378 return "Text=" in response 

+

3379 

+

3380 

+

3381@lru_cache() 

+

3382def is_qemu_system() -> bool: 

+

3383 if not is_qemu(): 

+

3384 return False 

+

3385 response = gdb.execute("maintenance packet qOffsets", to_string=True, from_tty=False) 

+

3386 return "received: \"\"" in response 

+

3387 

+

3388 

+

3389def get_filepath() -> Optional[str]: 

+

3390 """Return the local absolute path of the file currently debugged.""" 

+

3391 if gef.session.remote: 

+

3392 return str(gef.session.remote.lfile.absolute()) 

+

3393 if gef.session.file: 3393 ↛ 3395line 3393 didn't jump to line 3395, because the condition on line 3393 was never false

+

3394 return str(gef.session.file.absolute()) 

+

3395 return None 

+

3396 

+

3397 

+

3398def get_function_length(sym: str) -> int: 

+

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

+

3400 dis = gdb.execute(f"disassemble {sym}", to_string=True).splitlines() 

+

3401 start_addr = int(dis[1].split()[0], 16) 

+

3402 end_addr = int(dis[-2].split()[0], 16) 

+

3403 return end_addr - start_addr 

+

3404 

+

3405 

+

3406@lru_cache() 

+

3407def get_info_files() -> List[Zone]: 

+

3408 """Retrieve all the files loaded by debuggee.""" 

+

3409 lines = gdb.execute("info files", to_string=True).splitlines() 

+

3410 infos = [] 

+

3411 for line in lines: 

+

3412 line = line.strip() 

+

3413 if not line: 3413 ↛ 3414line 3413 didn't jump to line 3414, because the condition on line 3413 was never true

+

3414 break 

+

3415 

+

3416 if not line.startswith("0x"): 

+

3417 continue 

+

3418 

+

3419 blobs = [x.strip() for x in line.split(" ")] 

+

3420 addr_start = int(blobs[0], 16) 

+

3421 addr_end = int(blobs[2], 16) 

+

3422 section_name = blobs[4] 

+

3423 

+

3424 if len(blobs) == 7: 

+

3425 filename = blobs[6] 

+

3426 else: 

+

3427 filename = get_filepath() 

+

3428 

+

3429 infos.append(Zone(section_name, addr_start, addr_end, filename)) 

+

3430 return infos 

+

3431 

+

3432 

+

3433def process_lookup_address(address: int) -> Optional[Section]: 

+

3434 """Look up for an address in memory. 

+

3435 Return an Address object if found, None otherwise.""" 

+

3436 if not is_alive(): 3436 ↛ 3437line 3436 didn't jump to line 3437, because the condition on line 3436 was never true

+

3437 err("Process is not running") 

+

3438 return None 

+

3439 

+

3440 if is_x86(): 3440 ↛ 3444line 3440 didn't jump to line 3444, because the condition on line 3440 was never false

+

3441 if is_in_x86_kernel(address): 3441 ↛ 3442line 3441 didn't jump to line 3442, because the condition on line 3441 was never true

+

3442 return None 

+

3443 

+

3444 for sect in gef.memory.maps: 

+

3445 if sect.page_start <= address < sect.page_end: 

+

3446 return sect 

+

3447 

+

3448 return None 

+

3449 

+

3450 

+

3451@lru_cache() 

+

3452def process_lookup_path(name: str, perm: Permission = Permission.ALL) -> Optional[Section]: 

+

3453 """Look up for a path in the process memory mapping. 

+

3454 Return a Section object if found, None otherwise.""" 

+

3455 if not is_alive(): 3455 ↛ 3456line 3455 didn't jump to line 3456, because the condition on line 3455 was never true

+

3456 err("Process is not running") 

+

3457 return None 

+

3458 

+

3459 for sect in gef.memory.maps: 3459 ↛ 3463line 3459 didn't jump to line 3463, because the loop on line 3459 didn't complete

+

3460 if name in sect.path and sect.permission & perm: 

+

3461 return sect 

+

3462 

+

3463 return None 

+

3464 

+

3465 

+

3466@lru_cache() 

+

3467def file_lookup_name_path(name: str, path: str) -> Optional[Zone]: 

+

3468 """Look up a file by name and path. 

+

3469 Return a Zone object if found, None otherwise.""" 

+

3470 for xfile in get_info_files(): 3470 ↛ 3473line 3470 didn't jump to line 3473, because the loop on line 3470 didn't complete

+

3471 if path == xfile.filename and name == xfile.name: 

+

3472 return xfile 

+

3473 return None 

+

3474 

+

3475 

+

3476@lru_cache() 

+

3477def file_lookup_address(address: int) -> Optional[Zone]: 

+

3478 """Look up for a file by its address. 

+

3479 Return a Zone object if found, None otherwise.""" 

+

3480 for info in get_info_files(): 

+

3481 if info.zone_start <= address < info.zone_end: 

+

3482 return info 

+

3483 return None 

+

3484 

+

3485 

+

3486@lru_cache() 

+

3487def lookup_address(address: int) -> Address: 

+

3488 """Try to find the address in the process address space. 

+

3489 Return an Address object, with validity flag set based on success.""" 

+

3490 sect = process_lookup_address(address) 

+

3491 info = file_lookup_address(address) 

+

3492 if sect is None and info is None: 

+

3493 # i.e. there is no info on this address 

+

3494 return Address(value=address, valid=False) 

+

3495 return Address(value=address, section=sect, info=info) 

+

3496 

+

3497 

+

3498def xor(data: ByteString, key: str) -> bytearray: 

+

3499 """Return `data` xor-ed with `key`.""" 

+

3500 key_raw = binascii.unhexlify(key.lstrip("0x")) 

+

3501 return bytearray(x ^ y for x, y in zip(data, itertools.cycle(key_raw))) 

+

3502 

+

3503 

+

3504def is_hex(pattern: str) -> bool: 

+

3505 """Return whether provided string is a hexadecimal value.""" 

+

3506 if not pattern.lower().startswith("0x"): 

+

3507 return False 

+

3508 return len(pattern) % 2 == 0 and all(c in string.hexdigits for c in pattern[2:]) 

+

3509 

+

3510 

+

3511def continue_handler(_: "gdb.Event") -> None: 

+

3512 """GDB event handler for new object continue cases.""" 

+

3513 return 

+

3514 

+

3515 

+

3516def hook_stop_handler(_: "gdb.StopEvent") -> None: 

+

3517 """GDB event handler for stop cases.""" 

+

3518 reset_all_caches() 

+

3519 gdb.execute("context") 

+

3520 return 

+

3521 

+

3522 

+

3523def new_objfile_handler(evt: Optional["gdb.NewObjFileEvent"]) -> None: 

+

3524 """GDB event handler for new object file cases.""" 

+

3525 reset_all_caches() 

+

3526 path = evt.new_objfile.filename if evt else gdb.current_progspace().filename 

+

3527 try: 

+

3528 if gef.session.root and path.startswith("target:"): 3528 ↛ 3531line 3528 didn't jump to line 3531, because the condition on line 3528 was never true

+

3529 # If the process is in a container, replace the "target:" prefix 

+

3530 # with the actual root directory of the process. 

+

3531 path = path.replace("target:", str(gef.session.root), 1) 

+

3532 target = pathlib.Path(path) 

+

3533 FileFormatClasses = list(filter(lambda fmtcls: fmtcls.is_valid(target), __registered_file_formats__)) 

+

3534 GuessedFileFormatClass : Type[FileFormat] = FileFormatClasses.pop() if len(FileFormatClasses) else Elf 

+

3535 binary = GuessedFileFormatClass(target) 

+

3536 if not gef.binary: 

+

3537 gef.binary = binary 

+

3538 reset_architecture() 

+

3539 else: 

+

3540 gef.session.modules.append(binary) 

+

3541 except FileNotFoundError as fne: 3541 ↛ 3547line 3541 didn't jump to line 3547

+

3542 # Linux automatically maps the vDSO into our process, and GDB 

+

3543 # will give us the string 'system-supplied DSO' as a path. 

+

3544 # This is normal, so we shouldn't warn the user about it 

+

3545 if "system-supplied DSO" not in path: 3545 ↛ 3546line 3545 didn't jump to line 3546, because the condition on line 3545 was never true

+

3546 warn(f"Failed to find objfile or not a valid file format: {str(fne)}") 

+

3547 except RuntimeError as re: 

+

3548 warn(f"Not a valid file format: {str(re)}") 

+

3549 return 

+

3550 

+

3551 

+

3552def exit_handler(_: "gdb.ExitedEvent") -> None: 

+

3553 """GDB event handler for exit cases.""" 

+

3554 global gef 

+

3555 reset_all_caches() 

+

3556 gef.session.qemu_mode = False 

+

3557 if gef.session.remote: 

+

3558 gef.session.remote.close() 

+

3559 del gef.session.remote 

+

3560 gef.session.remote = None 

+

3561 gef.session.remote_initializing = False 

+

3562 return 

+

3563 

+

3564 

+

3565def memchanged_handler(_: "gdb.MemoryChangedEvent") -> None: 

+

3566 """GDB event handler for mem changes cases.""" 

+

3567 reset_all_caches() 

+

3568 return 

+

3569 

+

3570 

+

3571def regchanged_handler(_: "gdb.RegisterChangedEvent") -> None: 

+

3572 """GDB event handler for reg changes cases.""" 

+

3573 reset_all_caches() 

+

3574 return 

+

3575 

+

3576 

+

3577def get_terminal_size() -> Tuple[int, int]: 

+

3578 """Return the current terminal size.""" 

+

3579 if is_debug(): 3579 ↛ 3582line 3579 didn't jump to line 3582, because the condition on line 3579 was never false

+

3580 return 600, 100 

+

3581 

+

3582 if platform.system() == "Windows": 

+

3583 from ctypes import create_string_buffer, windll 

+

3584 hStdErr = -12 

+

3585 herr = windll.kernel32.GetStdHandle(hStdErr) 

+

3586 csbi = create_string_buffer(22) 

+

3587 res = windll.kernel32.GetConsoleScreenBufferInfo(herr, csbi) 

+

3588 if res: 

+

3589 _, _, _, _, _, left, top, right, bottom, _, _ = struct.unpack("hhhhHhhhhhh", csbi.raw) 

+

3590 tty_columns = right - left + 1 

+

3591 tty_rows = bottom - top + 1 

+

3592 return tty_rows, tty_columns 

+

3593 else: 

+

3594 return 600, 100 

+

3595 else: 

+

3596 import fcntl 

+

3597 import termios 

+

3598 try: 

+

3599 tty_rows, tty_columns = struct.unpack("hh", fcntl.ioctl(1, termios.TIOCGWINSZ, "1234")) # type: ignore 

+

3600 return tty_rows, tty_columns 

+

3601 except OSError: 

+

3602 return 600, 100 

+

3603 

+

3604 

+

3605@lru_cache() 

+

3606def is_64bit() -> bool: 

+

3607 """Checks if current target is 64bit.""" 

+

3608 return gef.arch.ptrsize == 8 

+

3609 

+

3610 

+

3611@lru_cache() 

+

3612def is_32bit() -> bool: 

+

3613 """Checks if current target is 32bit.""" 

+

3614 return gef.arch.ptrsize == 4 

+

3615 

+

3616 

+

3617@lru_cache() 

+

3618def is_x86_64() -> bool: 

+

3619 """Checks if current target is x86-64""" 

+

3620 return Elf.Abi.X86_64 in gef.arch.aliases 

+

3621 

+

3622 

+

3623@lru_cache() 

+

3624def is_x86_32(): 

+

3625 """Checks if current target is an x86-32""" 

+

3626 return Elf.Abi.X86_32 in gef.arch.aliases 

+

3627 

+

3628 

+

3629@lru_cache() 

+

3630def is_x86() -> bool: 

+

3631 return is_x86_32() or is_x86_64() 

+

3632 

+

3633 

+

3634@lru_cache() 

+

3635def is_arch(arch: Elf.Abi) -> bool: 

+

3636 return arch in gef.arch.aliases 

+

3637 

+

3638 

+

3639def reset_architecture(arch: Optional[str] = None) -> None: 

+

3640 """Sets the current architecture. 

+

3641 If an architecture is explicitly specified by parameter, try to use that one. If this fails, an `OSError` 

+

3642 exception will occur. 

+

3643 If no architecture is specified, then GEF will attempt to determine automatically based on the current 

+

3644 ELF target. If this fails, an `OSError` exception will occur. 

+

3645 """ 

+

3646 global gef 

+

3647 arches = __registered_architectures__ 

+

3648 

+

3649 # check if the architecture is forced by parameter 

+

3650 if arch: 3650 ↛ 3651line 3650 didn't jump to line 3651, because the condition on line 3650 was never true

+

3651 try: 

+

3652 gef.arch = arches[arch]() 

+

3653 except KeyError: 

+

3654 raise OSError(f"Specified arch {arch.upper()} is not supported") 

+

3655 return 

+

3656 

+

3657 gdb_arch = get_arch() 

+

3658 

+

3659 preciser_arch = next((a for a in arches.values() if a.supports_gdb_arch(gdb_arch)), None) 

+

3660 if preciser_arch: 3660 ↛ 3661line 3660 didn't jump to line 3661, because the condition on line 3660 was never true

+

3661 gef.arch = preciser_arch() 

+

3662 return 

+

3663 

+

3664 # last resort, use the info from elf header to find it from the known architectures 

+

3665 try: 

+

3666 arch_name = gef.binary.e_machine if gef.binary else gdb_arch 

+

3667 gef.arch = arches[arch_name]() 

+

3668 except KeyError: 

+

3669 raise OSError(f"CPU type is currently not supported: {get_arch()}") 

+

3670 return 

+

3671 

+

3672 

+

3673@lru_cache() 

+

3674def cached_lookup_type(_type: str) -> Optional[gdb.Type]: 

+

3675 try: 

+

3676 return gdb.lookup_type(_type).strip_typedefs() 

+

3677 except RuntimeError: 

+

3678 return None 

+

3679 

+

3680 

+

3681@deprecated("Use `gef.arch.ptrsize` instead") 

+

3682def get_memory_alignment(in_bits: bool = False) -> int: 

+

3683 """Try to determine the size of a pointer on this system. 

+

3684 First, try to parse it out of the ELF header. 

+

3685 Next, use the size of `size_t`. 

+

3686 Finally, try the size of $pc. 

+

3687 If `in_bits` is set to True, the result is returned in bits, otherwise in 

+

3688 bytes.""" 

+

3689 res = cached_lookup_type("size_t") 

+

3690 if res is not None: 

+

3691 return res.sizeof if not in_bits else res.sizeof * 8 

+

3692 

+

3693 try: 

+

3694 return gdb.parse_and_eval("$pc").type.sizeof 

+

3695 except: 

+

3696 pass 

+

3697 

+

3698 raise OSError("GEF is running under an unsupported mode") 

+

3699 

+

3700 

+

3701def clear_screen(tty: str = "") -> None: 

+

3702 """Clear the screen.""" 

+

3703 global gef 

+

3704 if not tty: 3704 ↛ 3710line 3704 didn't jump to line 3710, because the condition on line 3704 was never false

+

3705 gdb.execute("shell clear -x") 

+

3706 return 

+

3707 

+

3708 # Since the tty can be closed at any time, a PermissionError exception can 

+

3709 # occur when `clear_screen` is called. We handle this scenario properly 

+

3710 try: 

+

3711 with open(tty, "wt") as f: 

+

3712 f.write("\x1b[H\x1b[J") 

+

3713 except PermissionError: 

+

3714 gef.ui.redirect_fd = None 

+

3715 gef.config["context.redirect"] = "" 

+

3716 return 

+

3717 

+

3718 

+

3719def format_address(addr: int) -> str: 

+

3720 """Format the address according to its size.""" 

+

3721 memalign_size = gef.arch.ptrsize 

+

3722 addr = align_address(addr) 

+

3723 

+

3724 if memalign_size == 4: 3724 ↛ 3725line 3724 didn't jump to line 3725, because the condition on line 3724 was never true

+

3725 return f"0x{addr:08x}" 

+

3726 

+

3727 return f"0x{addr:016x}" 

+

3728 

+

3729 

+

3730def format_address_spaces(addr: int, left: bool = True) -> str: 

+

3731 """Format the address according to its size, but with spaces instead of zeroes.""" 

+

3732 width = gef.arch.ptrsize * 2 + 2 

+

3733 addr = align_address(addr) 

+

3734 

+

3735 if not left: 3735 ↛ 3736line 3735 didn't jump to line 3736, because the condition on line 3735 was never true

+

3736 return f"{addr:#x}".rjust(width) 

+

3737 

+

3738 return f"{addr:#x}".ljust(width) 

+

3739 

+

3740 

+

3741def align_address(address: int) -> int: 

+

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

+

3743 if gef.arch.ptrsize == 4: 3743 ↛ 3744line 3743 didn't jump to line 3744, because the condition on line 3743 was never true

+

3744 return address & 0xFFFFFFFF 

+

3745 

+

3746 return address & 0xFFFFFFFFFFFFFFFF 

+

3747 

+

3748 

+

3749def align_address_to_size(address: int, align: int) -> int: 

+

3750 """Align the address to the given size.""" 

+

3751 return address + ((align - (address % align)) % align) 

+

3752 

+

3753 

+

3754def align_address_to_page(address: int) -> int: 

+

3755 """Align the address to a page.""" 

+

3756 a = align_address(address) >> DEFAULT_PAGE_ALIGN_SHIFT 

+

3757 return a << DEFAULT_PAGE_ALIGN_SHIFT 

+

3758 

+

3759 

+

3760def parse_address(address: str) -> int: 

+

3761 """Parse an address and return it as an Integer.""" 

+

3762 if is_hex(address): 

+

3763 return int(address, 16) 

+

3764 return to_unsigned_long(gdb.parse_and_eval(address)) 

+

3765 

+

3766 

+

3767def is_in_x86_kernel(address: int) -> bool: 

+

3768 address = align_address(address) 

+

3769 memalign = gef.arch.ptrsize*8 - 1 

+

3770 return (address >> memalign) == 0xF 

+

3771 

+

3772 

+

3773def is_remote_debug() -> bool: 

+

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

+

3775 return gef.session.remote_initializing or gef.session.remote is not None 

+

3776 

+

3777 

+

3778def de_bruijn(alphabet: bytes, n: int) -> Generator[str, None, None]: 

+

3779 """De Bruijn sequence for alphabet and subsequences of length n (for compat. w/ pwnlib).""" 

+

3780 k = len(alphabet) 

+

3781 a = [0] * k * n 

+

3782 

+

3783 def db(t: int, p: int) -> Generator[str, None, None]: 

+

3784 if t > n: 

+

3785 if n % p == 0: 

+

3786 for j in range(1, p + 1): 

+

3787 yield alphabet[a[j]] 

+

3788 else: 

+

3789 a[t] = a[t - p] 

+

3790 yield from db(t + 1, p) 

+

3791 

+

3792 for j in range(a[t - p] + 1, k): 

+

3793 a[t] = j 

+

3794 yield from db(t + 1, t) 

+

3795 

+

3796 return db(1, 1) 

+

3797 

+

3798 

+

3799def generate_cyclic_pattern(length: int, cycle: int = 4) -> bytearray: 

+

3800 """Create a `length` byte bytearray of a de Bruijn cyclic pattern.""" 

+

3801 charset = bytearray(b"abcdefghijklmnopqrstuvwxyz") 

+

3802 return bytearray(itertools.islice(de_bruijn(charset, cycle), length)) 

+

3803 

+

3804 

+

3805def safe_parse_and_eval(value: str) -> Optional["gdb.Value"]: 

+

3806 """GEF wrapper for gdb.parse_and_eval(): this function returns None instead of raising 

+

3807 gdb.error if the eval failed.""" 

+

3808 try: 

+

3809 return gdb.parse_and_eval(value) 

+

3810 except gdb.error: 

+

3811 pass 

+

3812 return None 

+

3813 

+

3814 

+

3815@lru_cache() 

+

3816def dereference(addr: int) -> Optional["gdb.Value"]: 

+

3817 """GEF wrapper for gdb dereference function.""" 

+

3818 try: 

+

3819 ulong_t = cached_lookup_type(use_stdtype()) or \ 

+

3820 cached_lookup_type(use_default_type()) or \ 

+

3821 cached_lookup_type(use_golang_type()) or \ 

+

3822 cached_lookup_type(use_rust_type()) 

+

3823 unsigned_long_type = ulong_t.pointer() 

+

3824 res = gdb.Value(addr).cast(unsigned_long_type).dereference() 

+

3825 # GDB does lazy fetch by default so we need to force access to the value 

+

3826 res.fetch_lazy() 

+

3827 return res 

+

3828 except gdb.MemoryError: 

+

3829 pass 

+

3830 return None 

+

3831 

+

3832 

+

3833def gef_convenience(value: Union[str, bytes]) -> str: 

+

3834 """Defines a new convenience value.""" 

+

3835 global gef 

+

3836 var_name = f"$_gef{gef.session.convenience_vars_index:d}" 

+

3837 gef.session.convenience_vars_index += 1 

+

3838 if isinstance(value, str): 

+

3839 gdb.execute(f"""set {var_name} = "{value}" """) 

+

3840 elif isinstance(value, bytes): 3840 ↛ 3844line 3840 didn't jump to line 3844, because the condition on line 3840 was never false

+

3841 value_as_array = "{" + ", ".join(["%#.02x" % x for x in value]) + "}" 

+

3842 gdb.execute(f"""set {var_name} = {value_as_array} """) 

+

3843 else: 

+

3844 raise TypeError 

+

3845 return var_name 

+

3846 

+

3847 

+

3848def parse_string_range(s: str) -> Iterator[int]: 

+

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

+

3850 addrs = s.split("-") 

+

3851 return map(lambda x: int(x, 16), addrs) 

+

3852 

+

3853 

+

3854@lru_cache() 

+

3855def is_syscall(instruction: Union[Instruction,int]) -> bool: 

+

3856 """Checks whether an instruction or address points to a system call.""" 

+

3857 if isinstance(instruction, int): 

+

3858 instruction = gef_current_instruction(instruction) 

+

3859 insn_str = instruction.mnemonic 

+

3860 if len(instruction.operands): 

+

3861 insn_str += f" {', '.join(instruction.operands)}" 

+

3862 return insn_str in gef.arch.syscall_instructions 

+

3863 

+

3864 

+

3865# 

+

3866# Deprecated API 

+

3867# 

+

3868 

+

3869@deprecated("Use `gef.session.pie_breakpoints[num]`") 

+

3870def gef_get_pie_breakpoint(num: int) -> "PieVirtualBreakpoint": 

+

3871 return gef.session.pie_breakpoints[num] 

+

3872 

+

3873 

+

3874@deprecated("Use `str(gef.arch.endianness)` instead") 

+

3875def endian_str() -> str: 

+

3876 return str(gef.arch.endianness) 

+

3877 

+

3878 

+

3879@deprecated("Use `gef.config[key]`") 

+

3880def get_gef_setting(name: str) -> Any: 

+

3881 return gef.config[name] 

+

3882 

+

3883 

+

3884@deprecated("Use `gef.config[key] = value`") 

+

3885def set_gef_setting(name: str, value: Any) -> None: 

+

3886 gef.config[name] = value 

+

3887 return 

+

3888 

+

3889 

+

3890@deprecated("Use `gef.session.pagesize`") 

+

3891def gef_getpagesize() -> int: 

+

3892 return gef.session.pagesize 

+

3893 

+

3894 

+

3895@deprecated("Use `gef.session.canary`") 

+

3896def gef_read_canary() -> Optional[Tuple[int, int]]: 

+

3897 return gef.session.canary 

+

3898 

+

3899 

+

3900@deprecated("Use `gef.session.pid`") 

+

3901def get_pid() -> int: 

+

3902 return gef.session.pid 

+

3903 

+

3904 

+

3905@deprecated("Use `gef.session.file.name`") 

+

3906def get_filename() -> str: 

+

3907 return gef.session.file.name 

+

3908 

+

3909 

+

3910@deprecated("Use `gef.heap.main_arena`") 

+

3911def get_glibc_arena() -> Optional[GlibcArena]: 

+

3912 return gef.heap.main_arena 

+

3913 

+

3914 

+

3915@deprecated("Use `gef.arch.register(regname)`") 

+

3916def get_register(regname) -> Optional[int]: 

+

3917 return gef.arch.register(regname) 

+

3918 

+

3919 

+

3920@deprecated("Use `gef.memory.maps`") 

+

3921def get_process_maps() -> List[Section]: 

+

3922 return gef.memory.maps 

+

3923 

+

3924 

+

3925@deprecated("Use `reset_architecture`") 

+

3926def set_arch(arch: Optional[str] = None, _: Optional[str] = None) -> None: 

+

3927 return reset_architecture(arch) 

+

3928 

+

3929# 

+

3930# GDB event hooking 

+

3931# 

+

3932 

+

3933@only_if_events_supported("cont") 

+

3934def gef_on_continue_hook(func: Callable[["gdb.ThreadEvent"], None]) -> None: 

+

3935 gdb.events.cont.connect(func) 

+

3936 

+

3937 

+

3938@only_if_events_supported("cont") 

+

3939def gef_on_continue_unhook(func: Callable[["gdb.ThreadEvent"], None]) -> None: 

+

3940 gdb.events.cont.disconnect(func) 

+

3941 

+

3942 

+

3943@only_if_events_supported("stop") 

+

3944def gef_on_stop_hook(func: Callable[["gdb.StopEvent"], None]) -> None: 

+

3945 gdb.events.stop.connect(func) 

+

3946 

+

3947 

+

3948@only_if_events_supported("stop") 

+

3949def gef_on_stop_unhook(func: Callable[["gdb.StopEvent"], None]) -> None: 

+

3950 gdb.events.stop.disconnect(func) 

+

3951 

+

3952 

+

3953@only_if_events_supported("exited") 

+

3954def gef_on_exit_hook(func: Callable[["gdb.ExitedEvent"], None]) -> None: 

+

3955 gdb.events.exited.connect(func) 

+

3956 

+

3957 

+

3958@only_if_events_supported("exited") 

+

3959def gef_on_exit_unhook(func: Callable[["gdb.ExitedEvent"], None]) -> None: 

+

3960 gdb.events.exited.disconnect(func) 

+

3961 

+

3962 

+

3963@only_if_events_supported("new_objfile") 

+

3964def gef_on_new_hook(func: Callable[["gdb.NewObjFileEvent"], None]) -> None: 

+

3965 gdb.events.new_objfile.connect(func) 

+

3966 

+

3967 

+

3968@only_if_events_supported("new_objfile") 

+

3969def gef_on_new_unhook(func: Callable[["gdb.NewObjFileEvent"], None]) -> None: 

+

3970 gdb.events.new_objfile.disconnect(func) 

+

3971 

+

3972 

+

3973@only_if_events_supported("clear_objfiles") 

+

3974def gef_on_unload_objfile_hook(func: Callable[["gdb.ClearObjFilesEvent"], None]) -> None: 

+

3975 gdb.events.clear_objfiles.connect(func) 

+

3976 

+

3977 

+

3978@only_if_events_supported("clear_objfiles") 

+

3979def gef_on_unload_objfile_unhook(func: Callable[["gdb.ClearObjFilesEvent"], None]) -> None: 

+

3980 gdb.events.clear_objfiles.disconnect(func) 

+

3981 

+

3982 

+

3983@only_if_events_supported("memory_changed") 

+

3984def gef_on_memchanged_hook(func: Callable[["gdb.MemoryChangedEvent"], None]) -> None: 

+

3985 gdb.events.memory_changed.connect(func) 

+

3986 

+

3987 

+

3988@only_if_events_supported("memory_changed") 

+

3989def gef_on_memchanged_unhook(func: Callable[["gdb.MemoryChangedEvent"], None]) -> None: 

+

3990 gdb.events.memory_changed.disconnect(func) 

+

3991 

+

3992 

+

3993@only_if_events_supported("register_changed") 

+

3994def gef_on_regchanged_hook(func: Callable[["gdb.RegisterChangedEvent"], None]) -> None: 

+

3995 gdb.events.register_changed.connect(func) 

+

3996 

+

3997 

+

3998@only_if_events_supported("register_changed") 

+

3999def gef_on_regchanged_unhook(func: Callable[["gdb.RegisterChangedEvent"], None]) -> None: 

+

4000 gdb.events.register_changed.disconnect(func) 

+

4001 

+

4002 

+

4003# 

+

4004# Virtual breakpoints 

+

4005# 

+

4006 

+

4007class PieVirtualBreakpoint: 

+

4008 """PIE virtual breakpoint (not real breakpoint).""" 

+

4009 

+

4010 def __init__(self, set_func: Callable[[int], str], vbp_num: int, addr: int) -> None: 

+

4011 # set_func(base): given a base address return a 

+

4012 # "set breakpoint" gdb command string 

+

4013 self.set_func = set_func 

+

4014 self.vbp_num = vbp_num 

+

4015 # breakpoint num, 0 represents not instantiated yet 

+

4016 self.bp_num = 0 

+

4017 self.bp_addr = 0 

+

4018 # this address might be a symbol, just to know where to break 

+

4019 if isinstance(addr, int): 4019 ↛ 4022line 4019 didn't jump to line 4022, because the condition on line 4019 was never false

+

4020 self.addr: Union[int, str] = hex(addr) 

+

4021 else: 

+

4022 self.addr = addr 

+

4023 return 

+

4024 

+

4025 def instantiate(self, base: int) -> None: 

+

4026 if self.bp_num: 4026 ↛ 4027line 4026 didn't jump to line 4027, because the condition on line 4026 was never true

+

4027 self.destroy() 

+

4028 

+

4029 try: 

+

4030 res = gdb.execute(self.set_func(base), to_string=True) 

+

4031 except gdb.error as e: 

+

4032 err(e) 

+

4033 return 

+

4034 

+

4035 if "Breakpoint" not in res: 4035 ↛ 4036line 4035 didn't jump to line 4036, because the condition on line 4035 was never true

+

4036 err(res) 

+

4037 return 

+

4038 res_list = res.split() 

+

4039 self.bp_num = res_list[1] 

+

4040 self.bp_addr = res_list[3] 

+

4041 return 

+

4042 

+

4043 def destroy(self) -> None: 

+

4044 if not self.bp_num: 

+

4045 err("Destroy PIE breakpoint not even set") 

+

4046 return 

+

4047 gdb.execute(f"delete {self.bp_num}") 

+

4048 self.bp_num = 0 

+

4049 return 

+

4050 

+

4051 

+

4052# 

+

4053# Breakpoints 

+

4054# 

+

4055 

+

4056class FormatStringBreakpoint(gdb.Breakpoint): 

+

4057 """Inspect stack for format string.""" 

+

4058 def __init__(self, spec: str, num_args: int) -> None: 

+

4059 super().__init__(spec, type=gdb.BP_BREAKPOINT, internal=False) 

+

4060 self.num_args = num_args 

+

4061 self.enabled = True 

+

4062 return 

+

4063 

+

4064 def stop(self) -> bool: 

+

4065 reset_all_caches() 

+

4066 msg = [] 

+

4067 ptr, addr = gef.arch.get_ith_parameter(self.num_args) 

+

4068 addr = lookup_address(addr) 

+

4069 

+

4070 if not addr.valid: 4070 ↛ 4071line 4070 didn't jump to line 4071, because the condition on line 4070 was never true

+

4071 return False 

+

4072 

+

4073 if addr.section.is_writable(): 4073 ↛ 4083line 4073 didn't jump to line 4083, because the condition on line 4073 was never false

+

4074 content = gef.memory.read_cstring(addr.value) 

+

4075 name = addr.info.name if addr.info else addr.section.path 

+

4076 msg.append(Color.colorify("Format string helper", "yellow bold")) 

+

4077 msg.append(f"Possible insecure format string: {self.location}('{ptr}' {RIGHT_ARROW} {addr.value:#x}: '{content}')") 

+

4078 msg.append(f"Reason: Call to '{self.location}()' with format string argument in position " 

+

4079 f"#{self.num_args:d} is in page {addr.section.page_start:#x} ({name}) that has write permission") 

+

4080 push_context_message("warn", "\n".join(msg)) 

+

4081 return True 

+

4082 

+

4083 return False 

+

4084 

+

4085 

+

4086class StubBreakpoint(gdb.Breakpoint): 

+

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

+

4088 

+

4089 def __init__(self, func: str, retval: Optional[int]) -> None: 

+

4090 super().__init__(func, gdb.BP_BREAKPOINT, internal=False) 

+

4091 self.func = func 

+

4092 self.retval = retval 

+

4093 

+

4094 m = f"All calls to '{self.func}' will be skipped" 

+

4095 if self.retval is not None: 4095 ↛ 4097line 4095 didn't jump to line 4097, because the condition on line 4095 was never false

+

4096 m += f" (with return value set to {self.retval:#x})" 

+

4097 info(m) 

+

4098 return 

+

4099 

+

4100 def stop(self) -> bool: 

+

4101 gdb.execute(f"return (unsigned int){self.retval:#x}") 

+

4102 ok(f"Ignoring call to '{self.func}' " 

+

4103 f"(setting return value to {self.retval:#x})") 

+

4104 return False 

+

4105 

+

4106 

+

4107class ChangePermissionBreakpoint(gdb.Breakpoint): 

+

4108 """When hit, this temporary breakpoint will restore the original code, and position 

+

4109 $pc correctly.""" 

+

4110 

+

4111 def __init__(self, loc: str, code: ByteString, pc: int) -> None: 

+

4112 super().__init__(loc, gdb.BP_BREAKPOINT, internal=False) 

+

4113 self.original_code = code 

+

4114 self.original_pc = pc 

+

4115 return 

+

4116 

+

4117 def stop(self) -> bool: 

+

4118 info("Restoring original context") 

+

4119 gef.memory.write(self.original_pc, self.original_code, len(self.original_code)) 

+

4120 info("Restoring $pc") 

+

4121 gdb.execute(f"set $pc = {self.original_pc:#x}") 

+

4122 return True 

+

4123 

+

4124 

+

4125class TraceMallocBreakpoint(gdb.Breakpoint): 

+

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

+

4127 

+

4128 def __init__(self, name: str) -> None: 

+

4129 super().__init__(name, gdb.BP_BREAKPOINT, internal=True) 

+

4130 self.silent = True 

+

4131 self.name = name 

+

4132 return 

+

4133 

+

4134 def stop(self) -> bool: 

+

4135 reset_all_caches() 

+

4136 _, size = gef.arch.get_ith_parameter(0) 

+

4137 self.retbp = TraceMallocRetBreakpoint(size, self.name) 

+

4138 return False 

+

4139 

+

4140 

+

4141class TraceMallocRetBreakpoint(gdb.FinishBreakpoint): 

+

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

+

4143 

+

4144 def __init__(self, size: int, name: str) -> None: 

+

4145 super().__init__(gdb.newest_frame(), internal=True) 

+

4146 self.size = size 

+

4147 self.name = name 

+

4148 self.silent = True 

+

4149 return 

+

4150 

+

4151 def stop(self) -> bool: 

+

4152 if self.return_value: 4152 ↛ 4155line 4152 didn't jump to line 4155, because the condition on line 4152 was never false

+

4153 loc = int(self.return_value) 

+

4154 else: 

+

4155 loc = parse_address(gef.arch.return_register) 

+

4156 

+

4157 size = self.size 

+

4158 ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - {self.name}({size})={loc:#x}") 

+

4159 check_heap_overlap = gef.config["heap-analysis-helper.check_heap_overlap"] 

+

4160 

+

4161 # pop from free-ed list if it was in it 

+

4162 if gef.session.heap_freed_chunks: 4162 ↛ 4163line 4162 didn't jump to line 4163, because the condition on line 4162 was never true

+

4163 idx = 0 

+

4164 for item in gef.session.heap_freed_chunks: 

+

4165 addr = item[0] 

+

4166 if addr == loc: 

+

4167 gef.session.heap_freed_chunks.remove(item) 

+

4168 continue 

+

4169 idx += 1 

+

4170 

+

4171 # pop from uaf watchlist 

+

4172 if gef.session.heap_uaf_watchpoints: 4172 ↛ 4173line 4172 didn't jump to line 4173, because the condition on line 4172 was never true

+

4173 idx = 0 

+

4174 for wp in gef.session.heap_uaf_watchpoints: 

+

4175 wp_addr = wp.address 

+

4176 if loc <= wp_addr < loc + size: 

+

4177 gef.session.heap_uaf_watchpoints.remove(wp) 

+

4178 wp.enabled = False 

+

4179 continue 

+

4180 idx += 1 

+

4181 

+

4182 item = (loc, size) 

+

4183 

+

4184 if check_heap_overlap: 4184 ↛ 4206line 4184 didn't jump to line 4206, because the condition on line 4184 was never false

+

4185 # seek all the currently allocated chunks, read their effective size and check for overlap 

+

4186 msg = [] 

+

4187 align = gef.arch.ptrsize 

+

4188 for chunk_addr, _ in gef.session.heap_allocated_chunks: 

+

4189 current_chunk = GlibcChunk(chunk_addr) 

+

4190 current_chunk_size = current_chunk.size 

+

4191 

+

4192 if chunk_addr <= loc < chunk_addr + current_chunk_size: 4192 ↛ 4193line 4192 didn't jump to line 4193, because the condition on line 4192 was never true

+

4193 offset = loc - chunk_addr - 2*align 

+

4194 if offset < 0: continue # false positive, discard 

+

4195 

+

4196 msg.append(Color.colorify("Heap-Analysis", "yellow bold")) 

+

4197 msg.append("Possible heap overlap detected") 

+

4198 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})") 

+

4199 msg.append(f"Writing {offset:d} bytes from {chunk_addr:#x} will reach chunk {loc:#x}") 

+

4200 msg.append(f"Payload example for chunk {chunk_addr:#x} (to overwrite {loc:#x} headers):") 

+

4201 msg.append(" data = 'A'*{0:d} + 'B'*{1:d} + 'C'*{1:d}".format(offset, align)) 

+

4202 push_context_message("warn", "\n".join(msg)) 

+

4203 return True 

+

4204 

+

4205 # add it to alloc-ed list 

+

4206 gef.session.heap_allocated_chunks.append(item) 

+

4207 return False 

+

4208 

+

4209 

+

4210class TraceReallocBreakpoint(gdb.Breakpoint): 

+

4211 """Track re-allocations done with realloc().""" 

+

4212 

+

4213 def __init__(self) -> None: 

+

4214 super().__init__("__libc_realloc", gdb.BP_BREAKPOINT, internal=True) 

+

4215 self.silent = True 

+

4216 return 

+

4217 

+

4218 def stop(self) -> bool: 

+

4219 _, ptr = gef.arch.get_ith_parameter(0) 

+

4220 _, size = gef.arch.get_ith_parameter(1) 

+

4221 self.retbp = TraceReallocRetBreakpoint(ptr, size) 

+

4222 return False 

+

4223 

+

4224 

+

4225class TraceReallocRetBreakpoint(gdb.FinishBreakpoint): 

+

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

+

4227 

+

4228 def __init__(self, ptr: int, size: int) -> None: 

+

4229 super().__init__(gdb.newest_frame(), internal=True) 

+

4230 self.ptr = ptr 

+

4231 self.size = size 

+

4232 self.silent = True 

+

4233 return 

+

4234 

+

4235 def stop(self) -> bool: 

+

4236 if self.return_value: 4236 ↛ 4239line 4236 didn't jump to line 4239, because the condition on line 4236 was never false

+

4237 newloc = int(self.return_value) 

+

4238 else: 

+

4239 newloc = parse_address(gef.arch.return_register) 

+

4240 

+

4241 if newloc != self: 4241 ↛ 4246line 4241 didn't jump to line 4246, because the condition on line 4241 was never false

+

4242 ok("{} - realloc({:#x}, {})={}".format(Color.colorify("Heap-Analysis", "yellow bold"), 

+

4243 self.ptr, self.size, 

+

4244 Color.colorify(f"{newloc:#x}", "green"),)) 

+

4245 else: 

+

4246 ok("{} - realloc({:#x}, {})={}".format(Color.colorify("Heap-Analysis", "yellow bold"), 

+

4247 self.ptr, self.size, 

+

4248 Color.colorify(f"{newloc:#x}", "red"),)) 

+

4249 

+

4250 item = (newloc, self.size) 

+

4251 

+

4252 try: 

+

4253 # check if item was in alloc-ed list 

+

4254 idx = [x for x, y in gef.session.heap_allocated_chunks].index(self.ptr) 

+

4255 # if so pop it out 

+

4256 item = gef.session.heap_allocated_chunks.pop(idx) 

+

4257 except ValueError: 

+

4258 if is_debug(): 

+

4259 warn(f"Chunk {self.ptr:#x} was not in tracking list") 

+

4260 finally: 

+

4261 # add new item to alloc-ed list 

+

4262 gef.session.heap_allocated_chunks.append(item) 

+

4263 

+

4264 return False 

+

4265 

+

4266 

+

4267class TraceFreeBreakpoint(gdb.Breakpoint): 

+

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

+

4269 

+

4270 def __init__(self) -> None: 

+

4271 super().__init__("__libc_free", gdb.BP_BREAKPOINT, internal=True) 

+

4272 self.silent = True 

+

4273 return 

+

4274 

+

4275 def stop(self) -> bool: 

+

4276 reset_all_caches() 

+

4277 _, addr = gef.arch.get_ith_parameter(0) 

+

4278 msg = [] 

+

4279 check_free_null = gef.config["heap-analysis-helper.check_free_null"] 

+

4280 check_double_free = gef.config["heap-analysis-helper.check_double_free"] 

+

4281 check_weird_free = gef.config["heap-analysis-helper.check_weird_free"] 

+

4282 check_uaf = gef.config["heap-analysis-helper.check_uaf"] 

+

4283 

+

4284 ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - free({addr:#x})") 

+

4285 if addr == 0: 4285 ↛ 4286line 4285 didn't jump to line 4286, because the condition on line 4285 was never true

+

4286 if check_free_null: 

+

4287 msg.append(Color.colorify("Heap-Analysis", "yellow bold")) 

+

4288 msg.append(f"Attempting to free(NULL) at {gef.arch.pc:#x}") 

+

4289 msg.append("Reason: if NULL page is allocatable, this can lead to code execution.") 

+

4290 push_context_message("warn", "\n".join(msg)) 

+

4291 return True 

+

4292 return False 

+

4293 

+

4294 if addr in [x for (x, y) in gef.session.heap_freed_chunks]: 4294 ↛ 4295line 4294 didn't jump to line 4295, because the condition on line 4294 was never true

+

4295 if check_double_free: 

+

4296 msg.append(Color.colorify("Heap-Analysis", "yellow bold")) 

+

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

+

4298 msg.append("Execution will likely crash...") 

+

4299 push_context_message("warn", "\n".join(msg)) 

+

4300 return True 

+

4301 return False 

+

4302 

+

4303 # if here, no error 

+

4304 # 1. move alloc-ed item to free list 

+

4305 try: 

+

4306 # pop from alloc-ed list 

+

4307 idx = [x for x, y in gef.session.heap_allocated_chunks].index(addr) 

+

4308 item = gef.session.heap_allocated_chunks.pop(idx) 

+

4309 

+

4310 except ValueError: 

+

4311 if check_weird_free: 

+

4312 msg.append(Color.colorify("Heap-Analysis", "yellow bold")) 

+

4313 msg.append("Heap inconsistency detected:") 

+

4314 msg.append(f"Attempting to free an unknown value: {addr:#x}") 

+

4315 push_context_message("warn", "\n".join(msg)) 

+

4316 return True 

+

4317 return False 

+

4318 

+

4319 # 2. add it to free-ed list 

+

4320 gef.session.heap_freed_chunks.append(item) 

+

4321 

+

4322 self.retbp = None 

+

4323 if check_uaf: 4323 ↛ 4326line 4323 didn't jump to line 4326, because the condition on line 4323 was never false

+

4324 # 3. (opt.) add a watchpoint on pointer 

+

4325 self.retbp = TraceFreeRetBreakpoint(addr) 

+

4326 return False 

+

4327 

+

4328 

+

4329class TraceFreeRetBreakpoint(gdb.FinishBreakpoint): 

+

4330 """Internal temporary breakpoint to track free()d values.""" 

+

4331 

+

4332 def __init__(self, addr: int) -> None: 

+

4333 super().__init__(gdb.newest_frame(), internal=True) 

+

4334 self.silent = True 

+

4335 self.addr = addr 

+

4336 return 

+

4337 

+

4338 def stop(self) -> bool: 

+

4339 reset_all_caches() 

+

4340 wp = UafWatchpoint(self.addr) 

+

4341 gef.session.heap_uaf_watchpoints.append(wp) 

+

4342 return False 

+

4343 

+

4344 

+

4345class UafWatchpoint(gdb.Breakpoint): 

+

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

+

4347 

+

4348 def __init__(self, addr: int) -> None: 

+

4349 super().__init__(f"*{addr:#x}", gdb.BP_WATCHPOINT, internal=True) 

+

4350 self.address = addr 

+

4351 self.silent = True 

+

4352 self.enabled = True 

+

4353 return 

+

4354 

+

4355 def stop(self) -> bool: 

+

4356 """If this method is triggered, we likely have a UaF. Break the execution and report it.""" 

+

4357 reset_all_caches() 

+

4358 frame = gdb.selected_frame() 

+

4359 if frame.name() in ("_int_malloc", "malloc_consolidate", "__libc_calloc", ): 

+

4360 return False 

+

4361 

+

4362 # software watchpoints stop after the next statement (see 

+

4363 # https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html) 

+

4364 pc = gdb_get_nth_previous_instruction_address(gef.arch.pc, 2) 

+

4365 insn = gef_current_instruction(pc) 

+

4366 msg = [] 

+

4367 msg.append(Color.colorify("Heap-Analysis", "yellow bold")) 

+

4368 msg.append(f"Possible Use-after-Free in '{get_filepath()}': " 

+

4369 f"pointer {self.address:#x} was freed, but is attempted to be used at {pc:#x}") 

+

4370 msg.append(f"{insn.address:#x} {insn.mnemonic} {Color.yellowify(', '.join(insn.operands))}") 

+

4371 push_context_message("warn", "\n".join(msg)) 

+

4372 return True 

+

4373 

+

4374 

+

4375class EntryBreakBreakpoint(gdb.Breakpoint): 

+

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

+

4377 

+

4378 def __init__(self, location: str) -> None: 

+

4379 super().__init__(location, gdb.BP_BREAKPOINT, internal=True, temporary=True) 

+

4380 self.silent = True 

+

4381 return 

+

4382 

+

4383 def stop(self) -> bool: 

+

4384 reset_all_caches() 

+

4385 return True 

+

4386 

+

4387 

+

4388class NamedBreakpoint(gdb.Breakpoint): 

+

4389 """Breakpoint which shows a specified name, when hit.""" 

+

4390 

+

4391 def __init__(self, location: str, name: str) -> None: 

+

4392 super().__init__(spec=location, type=gdb.BP_BREAKPOINT, internal=False, temporary=False) 

+

4393 self.name = name 

+

4394 self.loc = location 

+

4395 return 

+

4396 

+

4397 def stop(self) -> bool: 

+

4398 reset_all_caches() 

+

4399 push_context_message("info", f"Hit breakpoint {self.loc} ({Color.colorify(self.name, 'red bold')})") 

+

4400 return True 

+

4401 

+

4402 

+

4403# 

+

4404# Context Panes 

+

4405# 

+

4406 

+

4407def register_external_context_pane(pane_name: str, display_pane_function: Callable[[], None], pane_title_function: Callable[[], Optional[str]], condition : Optional[Callable[[], bool]] = None) -> None: 

+

4408 """ 

+

4409 Registering function for new GEF Context View. 

+

4410 pane_name: a string that has no spaces (used in settings) 

+

4411 display_pane_function: a function that uses gef_print() to print strings 

+

4412 pane_title_function: a function that returns a string or None, which will be displayed as the title. 

+

4413 If None, no title line is displayed. 

+

4414 condition: an optional callback: if not None, the callback will be executed first. If it returns true, 

+

4415 then only the pane title and content will displayed. Otherwise, it's simply skipped. 

+

4416 

+

4417 Example usage for a simple text to show when we hit a syscall: 

+

4418 def only_syscall(): return gef_current_instruction(gef.arch.pc).is_syscall() 

+

4419 def display_pane(): 

+

4420 gef_print("Wow, I am a context pane!") 

+

4421 def pane_title(): 

+

4422 return "example:pane" 

+

4423 register_external_context_pane("example_pane", display_pane, pane_title, only_syscall) 

+

4424 """ 

+

4425 gef.gdb.add_context_pane(pane_name, display_pane_function, pane_title_function, condition) 

+

4426 return 

+

4427 

+

4428 

+

4429# 

+

4430# Commands 

+

4431# 

+

4432@deprecated("Use `register()`, and inherit from `GenericCommand` instead") 

+

4433def register_external_command(cls: Type["GenericCommand"]) -> Type["GenericCommand"]: 

+

4434 """Registering function for new GEF (sub-)command to GDB.""" 

+

4435 return cls 

+

4436 

+

4437@deprecated("Use `register()`, and inherit from `GenericCommand` instead") 

+

4438def register_command(cls: Type["GenericCommand"]) -> Type["GenericCommand"]: 

+

4439 """Decorator for registering new GEF (sub-)command to GDB.""" 

+

4440 return cls 

+

4441 

+

4442@deprecated("") 

+

4443def register_priority_command(cls: Type["GenericCommand"]) -> Type["GenericCommand"]: 

+

4444 """Decorator for registering new command with priority, meaning that it must 

+

4445 loaded before the other generic commands.""" 

+

4446 return cls 

+

4447 

+

4448 

+

4449def register(cls: Union[Type["GenericCommand"], Type["GenericFunction"]]) -> Union[Type["GenericCommand"], Type["GenericFunction"]]: 

+

4450 global __registered_commands__, __registered_functions__ 

+

4451 if issubclass(cls, GenericCommand): 

+

4452 assert( hasattr(cls, "_cmdline_")) 

+

4453 assert( hasattr(cls, "do_invoke")) 

+

4454 assert( all(map(lambda x: x._cmdline_ != cls._cmdline_, __registered_commands__))) 

+

4455 __registered_commands__.add(cls) 

+

4456 return cls 

+

4457 

+

4458 if issubclass(cls, GenericFunction): 4458 ↛ 4465line 4458 didn't jump to line 4465, because the condition on line 4458 was never false

+

4459 assert( hasattr(cls, "_function_")) 

+

4460 assert( hasattr(cls, "invoke")) 

+

4461 assert( all(map(lambda x: x._function_ != cls._function_, __registered_functions__))) 

+

4462 __registered_functions__.add(cls) 

+

4463 return cls 

+

4464 

+

4465 raise TypeError(f"`{cls.__class__}` is an illegal class for `register`") 

+

4466 

+

4467 

+

4468class GenericCommand(gdb.Command): 

+

4469 """This is an abstract class for invoking commands, should not be instantiated.""" 

+

4470 

+

4471 _cmdline_: str 

+

4472 _syntax_: str 

+

4473 _example_: Union[str, List[str]] = "" 

+

4474 

+

4475 def __init_subclass__(cls, **kwargs): 

+

4476 super().__init_subclass__(**kwargs) 

+

4477 attributes = ("_cmdline_", "_syntax_", ) 

+

4478 if not all(map(lambda x: hasattr(cls, x), attributes)): 4478 ↛ 4479line 4478 didn't jump to line 4479, because the condition on line 4478 was never true

+

4479 raise NotImplementedError 

+

4480 

+

4481 def __init__(self, *args: Any, **kwargs: Any) -> None: 

+

4482 self.pre_load() 

+

4483 syntax = Color.yellowify("\nSyntax: ") + self._syntax_ 

+

4484 example = Color.yellowify("\nExamples: \n\t") 

+

4485 if isinstance(self._example_, list): 

+

4486 example += "\n\t".join(self._example_) 

+

4487 elif isinstance(self._example_, str): 4487 ↛ 4489line 4487 didn't jump to line 4489, because the condition on line 4487 was never false

+

4488 example += self._example_ 

+

4489 self.__doc__ = self.__doc__.replace(" "*4, "") + syntax + example 

+

4490 self.repeat = False 

+

4491 self.repeat_count = 0 

+

4492 self.__last_command = None 

+

4493 command_type = kwargs.setdefault("command", gdb.COMMAND_OBSCURE) 

+

4494 complete_type = kwargs.setdefault("complete", gdb.COMPLETE_NONE) 

+

4495 prefix = kwargs.setdefault("prefix", False) 

+

4496 super().__init__(self._cmdline_, command_type, complete_type, prefix) 

+

4497 self.post_load() 

+

4498 return 

+

4499 

+

4500 def invoke(self, args: str, from_tty: bool) -> None: 

+

4501 try: 

+

4502 argv = gdb.string_to_argv(args) 

+

4503 self.__set_repeat_count(argv, from_tty) 

+

4504 bufferize(self.do_invoke)(argv) 

+

4505 except Exception as e: 

+

4506 # Note: since we are intercepting cleaning exceptions here, commands preferably should avoid 

+

4507 # catching generic Exception, but rather specific ones. This is allows a much cleaner use. 

+

4508 if is_debug(): 4508 ↛ 4511line 4508 didn't jump to line 4511, because the condition on line 4508 was never false

+

4509 show_last_exception() 

+

4510 else: 

+

4511 err(f"Command '{self._cmdline_}' failed to execute properly, reason: {e}") 

+

4512 return 

+

4513 

+

4514 def usage(self) -> None: 

+

4515 err(f"Syntax\n{self._syntax_}") 

+

4516 return 

+

4517 

+

4518 def do_invoke(self, argv: List[str]) -> None: 

+

4519 raise NotImplementedError 

+

4520 

+

4521 def pre_load(self) -> None: 

+

4522 return 

+

4523 

+

4524 def post_load(self) -> None: 

+

4525 return 

+

4526 

+

4527 def __get_setting_name(self, name: str) -> str: 

+

4528 clsname = self.__class__._cmdline_.replace(" ", "-") 

+

4529 return f"{clsname}.{name}" 

+

4530 

+

4531 def __iter__(self) -> Generator[str, None, None]: 

+

4532 for key in gef.config.keys(): 

+

4533 if key.startswith(self._cmdline_): 

+

4534 yield key.replace(f"{self._cmdline_}.", "", 1) 

+

4535 

+

4536 @property 

+

4537 def settings(self) -> List[str]: 

+

4538 """Return the list of settings for this command.""" 

+

4539 return list(iter(self)) 

+

4540 

+

4541 @deprecated(f"Use `self[setting_name]` instead") 

+

4542 def get_setting(self, name: str) -> Any: 

+

4543 return self.__getitem__(name) 

+

4544 

+

4545 def __getitem__(self, name: str) -> Any: 

+

4546 key = self.__get_setting_name(name) 

+

4547 return gef.config[key] 

+

4548 

+

4549 @deprecated(f"Use `setting_name in self` instead") 

+

4550 def has_setting(self, name: str) -> bool: 

+

4551 return self.__contains__(name) 

+

4552 

+

4553 def __contains__(self, name: str) -> bool: 

+

4554 return self.__get_setting_name(name) in gef.config 

+

4555 

+

4556 @deprecated(f"Use `self[setting_name] = value` instead") 

+

4557 def add_setting(self, name: str, value: Tuple[Any, type, str], description: str = "") -> None: 

+

4558 return self.__setitem__(name, (value, type(value), description)) 

+

4559 

+

4560 def __setitem__(self, name: str, value: Union[Any, Tuple[Any, str]]) -> None: 

+

4561 # make sure settings are always associated to the root command (which derives from GenericCommand) 

+

4562 if "GenericCommand" not in [x.__name__ for x in self.__class__.__bases__]: 

+

4563 return 

+

4564 key = self.__get_setting_name(name) 

+

4565 if key in gef.config: 

+

4566 setting = gef.config.raw_entry(key) 

+

4567 setting.value = value 

+

4568 else: 

+

4569 if len(value) == 1: 4569 ↛ 4570line 4569 didn't jump to line 4570, because the condition on line 4569 was never true

+

4570 gef.config[key] = GefSetting(value[0]) 

+

4571 elif len(value) == 2: 4571 ↛ 4573line 4571 didn't jump to line 4573, because the condition on line 4571 was never false

+

4572 gef.config[key] = GefSetting(value[0], description=value[1]) 

+

4573 return 

+

4574 

+

4575 @deprecated(f"Use `del self[setting_name]` instead") 

+

4576 def del_setting(self, name: str) -> None: 

+

4577 return self.__delitem__(name) 

+

4578 

+

4579 def __delitem__(self, name: str) -> None: 

+

4580 del gef.config[self.__get_setting_name(name)] 

+

4581 return 

+

4582 

+

4583 def __set_repeat_count(self, argv: List[str], from_tty: bool) -> None: 

+

4584 if not from_tty: 

+

4585 self.repeat = False 

+

4586 self.repeat_count = 0 

+

4587 return 

+

4588 

+

4589 command = gdb.execute("show commands", to_string=True).strip().split("\n")[-1] 

+

4590 self.repeat = self.__last_command == command 

+

4591 self.repeat_count = self.repeat_count + 1 if self.repeat else 0 

+

4592 self.__last_command = command 

+

4593 return 

+

4594 

+

4595 

+

4596@register 

+

4597class VersionCommand(GenericCommand): 

+

4598 """Display GEF version info.""" 

+

4599 

+

4600 _cmdline_ = "version" 

+

4601 _syntax_ = f"{_cmdline_}" 

+

4602 _example_ = f"{_cmdline_}" 

+

4603 

+

4604 def do_invoke(self, argv: List[str]) -> None: 

+

4605 gef_fpath = pathlib.Path(inspect.stack()[0][1]).expanduser().absolute() 

+

4606 gef_dir = gef_fpath.parent 

+

4607 with gef_fpath.open("rb") as f: 

+

4608 gef_hash = hashlib.sha256(f.read()).hexdigest() 

+

4609 

+

4610 if os.access(f"{gef_dir}/.git", os.X_OK): 4610 ↛ 4615line 4610 didn't jump to line 4615, because the condition on line 4610 was never false

+

4611 ver = subprocess.check_output("git log --format='%H' -n 1 HEAD", cwd=gef_dir, shell=True).decode("utf8").strip() 

+

4612 extra = "dirty" if len(subprocess.check_output("git ls-files -m", cwd=gef_dir, shell=True).decode("utf8").strip()) else "clean" 

+

4613 gef_print(f"GEF: rev:{ver} (Git - {extra})") 

+

4614 else: 

+

4615 gef_blob_hash = subprocess.check_output(f"git hash-object {gef_fpath}", shell=True).decode().strip() 

+

4616 gef_print("GEF: (Standalone)") 

+

4617 gef_print(f"Blob Hash({gef_fpath}): {gef_blob_hash}") 

+

4618 gef_print(f"SHA256({gef_fpath}): {gef_hash}") 

+

4619 gef_print(f"GDB: {gdb.VERSION}") 

+

4620 py_ver = f"{sys.version_info.major:d}.{sys.version_info.minor:d}" 

+

4621 gef_print(f"GDB-Python: {py_ver}") 

+

4622 

+

4623 if "full" in argv: 

+

4624 gef_print(f"Loaded commands: {', '.join(gef.gdb.loaded_command_names)}") 

+

4625 return 

+

4626 

+

4627 

+

4628@register 

+

4629class PrintFormatCommand(GenericCommand): 

+

4630 """Print bytes format in commonly used formats, such as literals in high level languages.""" 

+

4631 

+

4632 valid_formats = ("py", "c", "js", "asm", "hex", "bytearray") 

+

4633 valid_bitness = (8, 16, 32, 64) 

+

4634 

+

4635 _cmdline_ = "print-format" 

+

4636 _aliases_ = ["pf",] 

+

4637 _syntax_ = (f"{_cmdline_} [--lang LANG] [--bitlen SIZE] [(--length,-l) LENGTH] [--clip] LOCATION" 

+

4638 f"\t--lang LANG specifies the output format for programming language (available: {valid_formats!s}, default 'py')." 

+

4639 f"\t--bitlen SIZE specifies size of bit (possible values: {valid_bitness!s}, default is 8)." 

+

4640 "\t--length LENGTH specifies length of array (default is 256)." 

+

4641 "\t--clip The output data will be copied to clipboard" 

+

4642 "\tLOCATION specifies where the address of bytes is stored.") 

+

4643 _example_ = f"{_cmdline_} --lang py -l 16 $rsp" 

+

4644 

+

4645 def __init__(self) -> None: 

+

4646 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

4647 self["max_size_preview"] = (10, "max size preview of bytes") 

+

4648 return 

+

4649 

+

4650 @property 

+

4651 def format_matrix(self) -> Dict[int, Tuple[str, str, str]]: 

+

4652 # `gef.arch.endianness` is a runtime property, should not be defined as a class property 

+

4653 return { 

+

4654 8: (f"{gef.arch.endianness}B", "char", "db"), 

+

4655 16: (f"{gef.arch.endianness}H", "short", "dw"), 

+

4656 32: (f"{gef.arch.endianness}I", "int", "dd"), 

+

4657 64: (f"{gef.arch.endianness}Q", "long long", "dq"), 

+

4658 } 

+

4659 

+

4660 @only_if_gdb_running 

+

4661 @parse_arguments({"location": "$pc", }, {("--length", "-l"): 256, "--bitlen": 0, "--lang": "py", "--clip": True,}) 

+

4662 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

4663 """Default value for print-format command.""" 

+

4664 args: argparse.Namespace = kwargs["arguments"] 

+

4665 args.bitlen = args.bitlen or gef.arch.ptrsize * 2 

+

4666 

+

4667 valid_bitlens = self.format_matrix.keys() 

+

4668 if args.bitlen not in valid_bitlens: 4668 ↛ 4669line 4668 didn't jump to line 4669, because the condition on line 4668 was never true

+

4669 err(f"Size of bit must be in: {valid_bitlens!s}") 

+

4670 return 

+

4671 

+

4672 if args.lang not in self.valid_formats: 

+

4673 err(f"Language must be in: {self.valid_formats!s}") 

+

4674 return 

+

4675 

+

4676 start_addr = parse_address(args.location) 

+

4677 size = int(args.bitlen / 8) 

+

4678 end_addr = start_addr + args.length * size 

+

4679 fmt = self.format_matrix[args.bitlen][0] 

+

4680 data = [] 

+

4681 

+

4682 if args.lang != "bytearray": 

+

4683 for addr in range(start_addr, end_addr, size): 

+

4684 value = struct.unpack(fmt, gef.memory.read(addr, size))[0] 

+

4685 data += [value] 

+

4686 sdata = ", ".join(map(hex, data)) 

+

4687 else: 

+

4688 sdata = "" 

+

4689 

+

4690 if args.lang == "bytearray": 

+

4691 data = gef.memory.read(start_addr, args.length) 

+

4692 preview = str(data[0:self["max_size_preview"]]) 

+

4693 out = f"Saved data {preview}... in '{gef_convenience(data)}'" 

+

4694 elif args.lang == "py": 

+

4695 out = f"buf = [{sdata}]" 

+

4696 elif args.lang == "c": 4696 ↛ 4697line 4696 didn't jump to line 4697, because the condition on line 4696 was never true

+

4697 c_type = self.format_matrix[args.bitlen][1] 

+

4698 out = f"unsigned {c_type} buf[{args.length}] = {{{sdata}}};" 

+

4699 elif args.lang == "js": 

+

4700 out = f"var buf = [{sdata}]" 

+

4701 elif args.lang == "asm": 4701 ↛ 4702line 4701 didn't jump to line 4702, because the condition on line 4701 was never true

+

4702 asm_type = self.format_matrix[args.bitlen][2] 

+

4703 out = "buf {0} {1}".format(asm_type, sdata) 

+

4704 elif args.lang == "hex": 4704 ↛ 4707line 4704 didn't jump to line 4707, because the condition on line 4704 was never false

+

4705 out = binascii.hexlify(gef.memory.read(start_addr, end_addr-start_addr)).decode() 

+

4706 else: 

+

4707 raise ValueError(f"Invalid format: {args.lang}") 

+

4708 

+

4709 if args.clip: 4709 ↛ 4710line 4709 didn't jump to line 4710, because the condition on line 4709 was never true

+

4710 if copy_to_clipboard(gef_pybytes(out)): 

+

4711 info("Copied to clipboard") 

+

4712 else: 

+

4713 warn("There's a problem while copying") 

+

4714 

+

4715 gef_print(out) 

+

4716 return 

+

4717 

+

4718 

+

4719@register 

+

4720class PieCommand(GenericCommand): 

+

4721 """PIE breakpoint support.""" 

+

4722 

+

4723 _cmdline_ = "pie" 

+

4724 _syntax_ = f"{_cmdline_} (breakpoint|info|delete|run|attach|remote)" 

+

4725 

+

4726 def __init__(self) -> None: 

+

4727 super().__init__(prefix=True) 

+

4728 return 

+

4729 

+

4730 def do_invoke(self, argv: List[str]) -> None: 

+

4731 if not argv: 4731 ↛ 4733line 4731 didn't jump to line 4733, because the condition on line 4731 was never false

+

4732 self.usage() 

+

4733 return 

+

4734 

+

4735 

+

4736@register 

+

4737class PieBreakpointCommand(GenericCommand): 

+

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

+

4739 

+

4740 _cmdline_ = "pie breakpoint" 

+

4741 _syntax_ = f"{_cmdline_} OFFSET" 

+

4742 

+

4743 @parse_arguments({"offset": ""}, {}) 

+

4744 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

4745 args : argparse.Namespace = kwargs["arguments"] 

+

4746 if not args.offset: 4746 ↛ 4747line 4746 didn't jump to line 4747, because the condition on line 4746 was never true

+

4747 self.usage() 

+

4748 return 

+

4749 

+

4750 addr = parse_address(args.offset) 

+

4751 self.set_pie_breakpoint(lambda base: f"b *{base + addr}", addr) 

+

4752 

+

4753 # When the process is already on, set real breakpoints immediately 

+

4754 if is_alive(): 4754 ↛ 4755line 4754 didn't jump to line 4755, because the condition on line 4754 was never true

+

4755 vmmap = gef.memory.maps 

+

4756 base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] 

+

4757 for bp_ins in gef.session.pie_breakpoints.values(): 

+

4758 bp_ins.instantiate(base_address) 

+

4759 return 

+

4760 

+

4761 @staticmethod 

+

4762 def set_pie_breakpoint(set_func: Callable[[int], str], addr: int) -> None: 

+

4763 gef.session.pie_breakpoints[gef.session.pie_counter] = PieVirtualBreakpoint(set_func, gef.session.pie_counter, addr) 

+

4764 gef.session.pie_counter += 1 

+

4765 return 

+

4766 

+

4767 

+

4768@register 

+

4769class PieInfoCommand(GenericCommand): 

+

4770 """Display breakpoint info.""" 

+

4771 

+

4772 _cmdline_ = "pie info" 

+

4773 _syntax_ = f"{_cmdline_} BREAKPOINT" 

+

4774 

+

4775 @parse_arguments({"breakpoints": [-1,]}, {}) 

+

4776 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

4777 args : argparse.Namespace = kwargs["arguments"] 

+

4778 if args.breakpoints[0] == -1: 

+

4779 # No breakpoint info needed 

+

4780 bps = gef.session.pie_breakpoints.values() 

+

4781 else: 

+

4782 bps = [gef.session.pie_breakpoints[x] 

+

4783 for x in args.breakpoints 

+

4784 if x in gef.session.pie_breakpoints] 

+

4785 

+

4786 lines = ["{:6s} {:6s} {:18s}".format("VNum","Num","Addr")] 

+

4787 lines += [ 

+

4788 f"{x.vbp_num:6d} {str(x.bp_num) if x.bp_num else 'N/A':6s} {x.addr:18s}" for x in bps 

+

4789 ] 

+

4790 gef_print("\n".join(lines)) 

+

4791 return 

+

4792 

+

4793 

+

4794@register 

+

4795class PieDeleteCommand(GenericCommand): 

+

4796 """Delete a PIE breakpoint.""" 

+

4797 

+

4798 _cmdline_ = "pie delete" 

+

4799 _syntax_ = f"{_cmdline_} [BREAKPOINT]" 

+

4800 

+

4801 @parse_arguments({"breakpoints": [-1,]}, {}) 

+

4802 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

4803 global gef 

+

4804 args : argparse.Namespace = kwargs["arguments"] 

+

4805 if args.breakpoints[0] == -1: 4805 ↛ 4807line 4805 didn't jump to line 4807, because the condition on line 4805 was never true

+

4806 # no arg, delete all 

+

4807 to_delete = list(gef.session.pie_breakpoints.values()) 

+

4808 self.delete_bp(to_delete) 

+

4809 else: 

+

4810 self.delete_bp([gef.session.pie_breakpoints[x] 

+

4811 for x in args.breakpoints 

+

4812 if x in gef.session.pie_breakpoints]) 

+

4813 return 

+

4814 

+

4815 

+

4816 @staticmethod 

+

4817 def delete_bp(breakpoints: List[PieVirtualBreakpoint]) -> None: 

+

4818 global gef 

+

4819 for bp in breakpoints: 

+

4820 # delete current real breakpoints if exists 

+

4821 if bp.bp_num: 4821 ↛ 4822line 4821 didn't jump to line 4822, because the condition on line 4821 was never true

+

4822 gdb.execute(f"delete {bp.bp_num}") 

+

4823 # delete virtual breakpoints 

+

4824 del gef.session.pie_breakpoints[bp.vbp_num] 

+

4825 return 

+

4826 

+

4827 

+

4828@register 

+

4829class PieRunCommand(GenericCommand): 

+

4830 """Run process with PIE breakpoint support.""" 

+

4831 

+

4832 _cmdline_ = "pie run" 

+

4833 _syntax_ = _cmdline_ 

+

4834 

+

4835 def do_invoke(self, argv: List[str]) -> None: 

+

4836 global gef 

+

4837 fpath = get_filepath() 

+

4838 if not fpath: 4838 ↛ 4839line 4838 didn't jump to line 4839, because the condition on line 4838 was never true

+

4839 warn("No executable to debug, use `file` to load a binary") 

+

4840 return 

+

4841 

+

4842 if not os.access(fpath, os.X_OK): 4842 ↛ 4843line 4842 didn't jump to line 4843, because the condition on line 4842 was never true

+

4843 warn(f"The file '{fpath}' is not executable.") 

+

4844 return 

+

4845 

+

4846 if is_alive(): 4846 ↛ 4847line 4846 didn't jump to line 4847, because the condition on line 4846 was never true

+

4847 warn("gdb is already running. Restart process.") 

+

4848 

+

4849 # get base address 

+

4850 gdb.execute("set stop-on-solib-events 1") 

+

4851 hide_context() 

+

4852 gdb.execute(f"run {' '.join(argv)}") 

+

4853 unhide_context() 

+

4854 gdb.execute("set stop-on-solib-events 0") 

+

4855 vmmap = gef.memory.maps 

+

4856 base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] 

+

4857 info(f"base address {hex(base_address)}") 

+

4858 

+

4859 # modify all breakpoints 

+

4860 for bp_ins in gef.session.pie_breakpoints.values(): 

+

4861 bp_ins.instantiate(base_address) 

+

4862 

+

4863 try: 

+

4864 gdb.execute("continue") 

+

4865 except gdb.error as e: 

+

4866 err(e) 

+

4867 gdb.execute("kill") 

+

4868 return 

+

4869 

+

4870 

+

4871@register 

+

4872class PieAttachCommand(GenericCommand): 

+

4873 """Do attach with PIE breakpoint support.""" 

+

4874 

+

4875 _cmdline_ = "pie attach" 

+

4876 _syntax_ = f"{_cmdline_} PID" 

+

4877 

+

4878 def do_invoke(self, argv: List[str]) -> None: 

+

4879 try: 

+

4880 gdb.execute(f"attach {' '.join(argv)}", to_string=True) 

+

4881 except gdb.error as e: 

+

4882 err(e) 

+

4883 return 

+

4884 # after attach, we are stopped so that we can 

+

4885 # get base address to modify our breakpoint 

+

4886 vmmap = gef.memory.maps 

+

4887 base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] 

+

4888 

+

4889 for bp_ins in gef.session.pie_breakpoints.values(): 

+

4890 bp_ins.instantiate(base_address) 

+

4891 gdb.execute("context") 

+

4892 return 

+

4893 

+

4894 

+

4895@register 

+

4896class PieRemoteCommand(GenericCommand): 

+

4897 """Attach to a remote connection with PIE breakpoint support.""" 

+

4898 

+

4899 _cmdline_ = "pie remote" 

+

4900 _syntax_ = f"{_cmdline_} REMOTE" 

+

4901 

+

4902 def do_invoke(self, argv: List[str]) -> None: 

+

4903 try: 

+

4904 gdb.execute(f"gef-remote {' '.join(argv)}") 

+

4905 except gdb.error as e: 

+

4906 err(e) 

+

4907 return 

+

4908 # after remote attach, we are stopped so that we can 

+

4909 # get base address to modify our breakpoint 

+

4910 vmmap = gef.memory.maps 

+

4911 base_address = [x.page_start for x in vmmap if x.realpath == get_filepath()][0] 

+

4912 

+

4913 for bp_ins in gef.session.pie_breakpoints.values(): 

+

4914 bp_ins.instantiate(base_address) 

+

4915 gdb.execute("context") 

+

4916 return 

+

4917 

+

4918 

+

4919@register 

+

4920class SmartEvalCommand(GenericCommand): 

+

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

+

4922 

+

4923 _cmdline_ = "$" 

+

4924 _syntax_ = f"{_cmdline_} EXPR\n{_cmdline_} ADDRESS1 ADDRESS2" 

+

4925 _example_ = (f"\n{_cmdline_} $pc+1" 

+

4926 f"\n{_cmdline_} 0x00007ffff7a10000 0x00007ffff7bce000") 

+

4927 

+

4928 def do_invoke(self, argv: List[str]) -> None: 

+

4929 argc = len(argv) 

+

4930 if argc == 1: 

+

4931 self.evaluate(argv) 

+

4932 return 

+

4933 

+

4934 if argc == 2: 4934 ↛ 4936line 4934 didn't jump to line 4936, because the condition on line 4934 was never false

+

4935 self.distance(argv) 

+

4936 return 

+

4937 

+

4938 def evaluate(self, expr: List[str]) -> None: 

+

4939 def show_as_int(i: int) -> None: 

+

4940 off = gef.arch.ptrsize*8 

+

4941 def comp2_x(x: Any) -> str: return f"{(x + (1 << off)) % (1 << off):x}" 

+

4942 def comp2_b(x: Any) -> str: return f"{(x + (1 << off)) % (1 << off):b}" 

+

4943 

+

4944 try: 

+

4945 s_i = comp2_x(res) 

+

4946 s_i = s_i.rjust(len(s_i)+1, "0") if len(s_i)%2 else s_i 

+

4947 gef_print(f"{i:d}") 

+

4948 gef_print("0x" + comp2_x(res)) 

+

4949 gef_print("0b" + comp2_b(res)) 

+

4950 gef_print(f"{binascii.unhexlify(s_i)}") 

+

4951 gef_print(f"{binascii.unhexlify(s_i)[::-1]}") 

+

4952 except: 

+

4953 pass 

+

4954 return 

+

4955 

+

4956 parsed_expr = [] 

+

4957 for xp in expr: 

+

4958 try: 

+

4959 xp = gdb.parse_and_eval(xp) 

+

4960 xp = int(xp) 

+

4961 parsed_expr.append(f"{xp:d}") 

+

4962 except gdb.error: 

+

4963 parsed_expr.append(str(xp)) 

+

4964 

+

4965 try: 

+

4966 res = eval(" ".join(parsed_expr)) 

+

4967 if isinstance(res, int): 4967 ↛ 4970line 4967 didn't jump to line 4970, because the condition on line 4967 was never false

+

4968 show_as_int(res) 

+

4969 else: 

+

4970 gef_print(f"{res}") 

+

4971 except SyntaxError: 

+

4972 gef_print(" ".join(parsed_expr)) 

+

4973 return 

+

4974 

+

4975 def distance(self, args: Tuple[str, str]) -> None: 

+

4976 try: 

+

4977 x = int(args[0], 16) if is_hex(args[0]) else int(args[0]) 

+

4978 y = int(args[1], 16) if is_hex(args[1]) else int(args[1]) 

+

4979 gef_print(f"{abs(x - y)}") 

+

4980 except ValueError: 

+

4981 warn(f"Distance requires 2 numbers: {self._cmdline_} 0 0xffff") 

+

4982 return 

+

4983 

+

4984 

+

4985@register 

+

4986class CanaryCommand(GenericCommand): 

+

4987 """Shows the canary value of the current process.""" 

+

4988 

+

4989 _cmdline_ = "canary" 

+

4990 _syntax_ = _cmdline_ 

+

4991 

+

4992 @only_if_gdb_running 

+

4993 def do_invoke(self, argv: List[str]) -> None: 

+

4994 self.dont_repeat() 

+

4995 

+

4996 has_canary = Elf(get_filepath()).checksec["Canary"] 

+

4997 if not has_canary: 4997 ↛ 4998line 4997 didn't jump to line 4998, because the condition on line 4997 was never true

+

4998 warn("This binary was not compiled with SSP.") 

+

4999 return 

+

5000 

+

5001 res = gef.session.canary 

+

5002 if not res: 5002 ↛ 5003line 5002 didn't jump to line 5003, because the condition on line 5002 was never true

+

5003 err("Failed to get the canary") 

+

5004 return 

+

5005 

+

5006 canary, location = res 

+

5007 info(f"The canary of process {gef.session.pid} is at {location:#x}, value is {canary:#x}") 

+

5008 return 

+

5009 

+

5010 

+

5011@register 

+

5012class ProcessStatusCommand(GenericCommand): 

+

5013 """Extends the info given by GDB `info proc`, by giving an exhaustive description of the 

+

5014 process status (file descriptors, ancestor, descendants, etc.).""" 

+

5015 

+

5016 _cmdline_ = "process-status" 

+

5017 _syntax_ = _cmdline_ 

+

5018 _aliases_ = ["status", ] 

+

5019 

+

5020 def __init__(self) -> None: 

+

5021 super().__init__(complete=gdb.COMPLETE_NONE) 

+

5022 return 

+

5023 

+

5024 @only_if_gdb_running 

+

5025 @only_if_gdb_target_local 

+

5026 def do_invoke(self, argv: List[str]) -> None: 

+

5027 self.show_info_proc() 

+

5028 self.show_ancestor() 

+

5029 self.show_descendants() 

+

5030 self.show_fds() 

+

5031 self.show_connections() 

+

5032 return 

+

5033 

+

5034 def get_state_of(self, pid: int) -> Dict[str, str]: 

+

5035 res = {} 

+

5036 with open(f"/proc/{pid}/status", "r") as f: 

+

5037 file = f.readlines() 

+

5038 for line in file: 

+

5039 key, value = line.split(":", 1) 

+

5040 res[key.strip()] = value.strip() 

+

5041 return res 

+

5042 

+

5043 def get_cmdline_of(self, pid: int) -> str: 

+

5044 with open(f"/proc/{pid}/cmdline", "r") as f: 

+

5045 return f.read().replace("\x00", "\x20").strip() 

+

5046 

+

5047 def get_process_path_of(self, pid: int) -> str: 

+

5048 return os.readlink(f"/proc/{pid}/exe") 

+

5049 

+

5050 def get_children_pids(self, pid: int) -> List[int]: 

+

5051 cmd = [gef.session.constants["ps"], "-o", "pid", "--ppid", f"{pid}", "--noheaders"] 

+

5052 try: 

+

5053 return [int(x) for x in gef_execute_external(cmd, as_list=True)] 5053 ↛ exit,   5053 ↛ exit2 missed branches: 1) line 5053 didn't run the list comprehension on line 5053, 2) line 5053 didn't return from function 'get_children_pids', because the return on line 5053 wasn't executed

+

5054 except Exception: 

+

5055 return [] 

+

5056 

+

5057 def show_info_proc(self) -> None: 

+

5058 info("Process Information") 

+

5059 pid = gef.session.pid 

+

5060 cmdline = self.get_cmdline_of(pid) 

+

5061 gef_print(f"\tPID {RIGHT_ARROW} {pid}", 

+

5062 f"\tExecutable {RIGHT_ARROW} {self.get_process_path_of(pid)}", 

+

5063 f"\tCommand line {RIGHT_ARROW} '{cmdline}'", sep="\n") 

+

5064 return 

+

5065 

+

5066 def show_ancestor(self) -> None: 

+

5067 info("Parent Process Information") 

+

5068 ppid = int(self.get_state_of(gef.session.pid)["PPid"]) 

+

5069 state = self.get_state_of(ppid) 

+

5070 cmdline = self.get_cmdline_of(ppid) 

+

5071 gef_print(f"\tParent PID {RIGHT_ARROW} {state['Pid']}", 

+

5072 f"\tCommand line {RIGHT_ARROW} '{cmdline}'", sep="\n") 

+

5073 return 

+

5074 

+

5075 def show_descendants(self) -> None: 

+

5076 info("Children Process Information") 

+

5077 children = self.get_children_pids(gef.session.pid) 

+

5078 if not children: 5078 ↛ 5082line 5078 didn't jump to line 5082, because the condition on line 5078 was never false

+

5079 gef_print("\tNo child process") 

+

5080 return 

+

5081 

+

5082 for child_pid in children: 

+

5083 state = self.get_state_of(child_pid) 

+

5084 pid = state["Pid"] 

+

5085 gef_print(f"\tPID {RIGHT_ARROW} {pid} (Name: '{self.get_process_path_of(pid)}', CmdLine: '{self.get_cmdline_of(pid)}')") 

+

5086 return 

+

5087 

+

5088 def show_fds(self) -> None: 

+

5089 pid = gef.session.pid 

+

5090 path = f"/proc/{pid:d}/fd" 

+

5091 

+

5092 info("File Descriptors:") 

+

5093 items = os.listdir(path) 

+

5094 if not items: 5094 ↛ 5095line 5094 didn't jump to line 5095, because the condition on line 5094 was never true

+

5095 gef_print("\tNo FD opened") 

+

5096 return 

+

5097 

+

5098 for fname in items: 

+

5099 fullpath = os.path.join(path, fname) 

+

5100 if os.path.islink(fullpath): 5100 ↛ 5098line 5100 didn't jump to line 5098, because the condition on line 5100 was never false

+

5101 gef_print(f"\t{fullpath} {RIGHT_ARROW} {os.readlink(fullpath)}") 

+

5102 return 

+

5103 

+

5104 def list_sockets(self, pid: int) -> List[int]: 

+

5105 sockets = [] 

+

5106 path = f"/proc/{pid:d}/fd" 

+

5107 items = os.listdir(path) 

+

5108 for fname in items: 

+

5109 fullpath = os.path.join(path, fname) 

+

5110 if os.path.islink(fullpath) and os.readlink(fullpath).startswith("socket:"): 5110 ↛ 5111line 5110 didn't jump to line 5111, because the condition on line 5110 was never true

+

5111 p = os.readlink(fullpath).replace("socket:", "")[1:-1] 

+

5112 sockets.append(int(p)) 

+

5113 return sockets 

+

5114 

+

5115 def parse_ip_port(self, addr: str) -> Tuple[str, int]: 

+

5116 ip, port = addr.split(":") 

+

5117 return socket.inet_ntoa(struct.pack("<I", int(ip, 16))), int(port, 16) 

+

5118 

+

5119 def show_connections(self) -> None: 

+

5120 # https://github.com/torvalds/linux/blob/v4.7/include/net/tcp_states.h#L16 

+

5121 tcp_states_str = { 

+

5122 0x01: "TCP_ESTABLISHED", 

+

5123 0x02: "TCP_SYN_SENT", 

+

5124 0x03: "TCP_SYN_RECV", 

+

5125 0x04: "TCP_FIN_WAIT1", 

+

5126 0x05: "TCP_FIN_WAIT2", 

+

5127 0x06: "TCP_TIME_WAIT", 

+

5128 0x07: "TCP_CLOSE", 

+

5129 0x08: "TCP_CLOSE_WAIT", 

+

5130 0x09: "TCP_LAST_ACK", 

+

5131 0x0A: "TCP_LISTEN", 

+

5132 0x0B: "TCP_CLOSING", 

+

5133 0x0C: "TCP_NEW_SYN_RECV", 

+

5134 } 

+

5135 

+

5136 udp_states_str = { 

+

5137 0x07: "UDP_LISTEN", 

+

5138 } 

+

5139 

+

5140 info("Network Connections") 

+

5141 pid = gef.session.pid 

+

5142 sockets = self.list_sockets(pid) 

+

5143 if not sockets: 5143 ↛ 5147line 5143 didn't jump to line 5147, because the condition on line 5143 was never false

+

5144 gef_print("\tNo open connections") 

+

5145 return 

+

5146 

+

5147 entries = dict() 

+

5148 with open(f"/proc/{pid:d}/net/tcp", "r") as tcp: 

+

5149 entries["TCP"] = [x.split() for x in tcp.readlines()[1:]] 

+

5150 with open(f"/proc/{pid:d}/net/udp", "r") as udp: 

+

5151 entries["UDP"] = [x.split() for x in udp.readlines()[1:]] 

+

5152 

+

5153 for proto in entries: 

+

5154 for entry in entries[proto]: 

+

5155 local, remote, state = entry[1:4] 

+

5156 inode = int(entry[9]) 

+

5157 if inode in sockets: 

+

5158 local = self.parse_ip_port(local) 

+

5159 remote = self.parse_ip_port(remote) 

+

5160 state = int(state, 16) 

+

5161 state_str = tcp_states_str[state] if proto == "TCP" else udp_states_str[state] 

+

5162 

+

5163 gef_print(f"\t{local[0]}:{local[1]} {RIGHT_ARROW} {remote[0]}:{remote[1]} ({state_str})") 

+

5164 return 

+

5165 

+

5166 

+

5167@register 

+

5168class GefThemeCommand(GenericCommand): 

+

5169 """Customize GEF appearance.""" 

+

5170 

+

5171 _cmdline_ = "theme" 

+

5172 _syntax_ = f"{_cmdline_} [KEY [VALUE]]" 

+

5173 

+

5174 def __init__(self) -> None: 

+

5175 super().__init__(self._cmdline_) 

+

5176 self["context_title_line"] = ("gray", "Color of the borders in context window") 

+

5177 self["context_title_message"] = ("cyan", "Color of the title in context window") 

+

5178 self["default_title_line"] = ("gray", "Default color of borders") 

+

5179 self["default_title_message"] = ("cyan", "Default color of title") 

+

5180 self["table_heading"] = ("blue", "Color of the column headings to tables (e.g. vmmap)") 

+

5181 self["old_context"] = ("gray", "Color to use to show things such as code that is not immediately relevant") 

+

5182 self["disassemble_current_instruction"] = ("green", "Color to use to highlight the current $pc when disassembling") 

+

5183 self["dereference_string"] = ("yellow", "Color of dereferenced string") 

+

5184 self["dereference_code"] = ("gray", "Color of dereferenced code") 

+

5185 self["dereference_base_address"] = ("cyan", "Color of dereferenced address") 

+

5186 self["dereference_register_value"] = ("bold blue", "Color of dereferenced register") 

+

5187 self["registers_register_name"] = ("blue", "Color of the register name in the register window") 

+

5188 self["registers_value_changed"] = ("bold red", "Color of the changed register in the register window") 

+

5189 self["address_stack"] = ("pink", "Color to use when a stack address is found") 

+

5190 self["address_heap"] = ("green", "Color to use when a heap address is found") 

+

5191 self["address_code"] = ("red", "Color to use when a code address is found") 

+

5192 self["source_current_line"] = ("green", "Color to use for the current code line in the source window") 

+

5193 return 

+

5194 

+

5195 def do_invoke(self, args: List[str]) -> None: 

+

5196 self.dont_repeat() 

+

5197 argc = len(args) 

+

5198 

+

5199 if argc == 0: 

+

5200 for key in self.settings: 

+

5201 setting = self[key] 

+

5202 value = Color.colorify(setting, setting) 

+

5203 gef_print(f"{key:40s}: {value}") 

+

5204 return 

+

5205 

+

5206 setting_name = args[0] 

+

5207 if not setting_name in self: 

+

5208 err("Invalid key") 

+

5209 return 

+

5210 

+

5211 if argc == 1: 

+

5212 value = self[setting_name] 

+

5213 gef_print(f"{setting_name:40s}: {Color.colorify(value, value)}") 

+

5214 return 

+

5215 

+

5216 colors = [color for color in args[1:] if color in Color.colors] 

+

5217 self[setting_name] = " ".join(colors) 

+

5218 return 

+

5219 

+

5220 

+

5221class ExternalStructureManager: 

+

5222 class Structure: 

+

5223 def __init__(self, manager: "ExternalStructureManager", mod_path: pathlib.Path, struct_name: str) -> None: 

+

5224 self.manager = manager 

+

5225 self.module_path = mod_path 

+

5226 self.name = struct_name 

+

5227 self.class_type = self.__get_structure_class() 

+

5228 # if the symbol points to a class factory method and not a class 

+

5229 if not hasattr(self.class_type, "_fields_") and callable(self.class_type): 5229 ↛ 5230line 5229 didn't jump to line 5230, because the condition on line 5229 was never true

+

5230 self.class_type = self.class_type(gef) 

+

5231 return 

+

5232 

+

5233 def __str__(self) -> str: 

+

5234 return self.name 

+

5235 

+

5236 def pprint(self) -> None: 

+

5237 res = [] 

+

5238 for _name, _type in self.class_type._fields_: 

+

5239 size = ctypes.sizeof(_type) 

+

5240 name = Color.colorify(_name, gef.config["pcustom.structure_name"]) 

+

5241 type = Color.colorify(_type.__name__, gef.config["pcustom.structure_type"]) 

+

5242 size = Color.colorify(hex(size), gef.config["pcustom.structure_size"]) 

+

5243 offset = Color.boldify(f"{getattr(self.class_type, _name).offset:04x}") 

+

5244 res.append(f"{offset} {name:32s} {type:16s} /* size={size} */") 

+

5245 gef_print("\n".join(res)) 

+

5246 return 

+

5247 

+

5248 def __get_structure_class(self) -> Type: 

+

5249 """Returns a tuple of (class, instance) if modname!classname exists""" 

+

5250 fpath = self.module_path 

+

5251 spec = importlib.util.spec_from_file_location(fpath.stem, fpath) 

+

5252 module = importlib.util.module_from_spec(spec) 

+

5253 sys.modules[fpath.stem] = module 

+

5254 spec.loader.exec_module(module) 

+

5255 _class = getattr(module, self.name) 

+

5256 return _class 

+

5257 

+

5258 def apply_at(self, address: int, max_depth: int, depth: int = 0) -> None: 

+

5259 """Apply (recursively if possible) the structure format to the given address.""" 

+

5260 if depth >= max_depth: 5260 ↛ 5261line 5260 didn't jump to line 5261, because the condition on line 5260 was never true

+

5261 warn("maximum recursion level reached") 

+

5262 return 

+

5263 

+

5264 # read the data at the specified address 

+

5265 _structure = self.class_type() 

+

5266 _sizeof_structure = ctypes.sizeof(_structure) 

+

5267 

+

5268 try: 

+

5269 data = gef.memory.read(address, _sizeof_structure) 

+

5270 except gdb.MemoryError: 

+

5271 err(f"{' ' * depth}Cannot read memory {address:#x}") 

+

5272 return 

+

5273 

+

5274 # deserialize the data 

+

5275 length = min(len(data), _sizeof_structure) 

+

5276 ctypes.memmove(ctypes.addressof(_structure), data, length) 

+

5277 

+

5278 # pretty print all the fields (and call recursively if possible) 

+

5279 ptrsize = gef.arch.ptrsize 

+

5280 unpack = u32 if ptrsize == 4 else u64 

+

5281 for field in _structure._fields_: 

+

5282 _name, _type = field 

+

5283 _value = getattr(_structure, _name) 

+

5284 _offset = getattr(self.class_type, _name).offset 

+

5285 

+

5286 if ((ptrsize == 4 and _type is ctypes.c_uint32) 5286 ↛ 5290line 5286 didn't jump to line 5290, because the condition on line 5286 was never true

+

5287 or (ptrsize == 8 and _type is ctypes.c_uint64) 

+

5288 or (ptrsize == ctypes.sizeof(ctypes.c_void_p) and _type is ctypes.c_void_p)): 

+

5289 # try to dereference pointers 

+

5290 _value = RIGHT_ARROW.join(dereference_from(_value)) 

+

5291 

+

5292 line = f"{' ' * depth}" 

+

5293 line += f"{address:#x}+{_offset:#04x} {_name} : ".ljust(40) 

+

5294 line += f"{_value} ({_type.__name__})" 

+

5295 parsed_value = self.__get_ctypes_value(_structure, _name, _value) 

+

5296 if parsed_value: 5296 ↛ 5297line 5296 didn't jump to line 5297, because the condition on line 5296 was never true

+

5297 line += f"{RIGHT_ARROW} {parsed_value}" 

+

5298 gef_print(line) 

+

5299 

+

5300 if issubclass(_type, ctypes.Structure): 5300 ↛ 5301line 5300 didn't jump to line 5301, because the condition on line 5300 was never true

+

5301 self.apply_at(address + _offset, max_depth, depth + 1) 

+

5302 elif _type.__name__.startswith("LP_"): 

+

5303 # Pointer to a structure of a different type 

+

5304 __sub_type_name = _type.__name__.lstrip("LP_") 

+

5305 result = self.manager.find(__sub_type_name) 

+

5306 if result: 5306 ↛ 5281line 5306 didn't jump to line 5281, because the condition on line 5306 was never false

+

5307 _, __structure = result 

+

5308 __address = unpack(gef.memory.read(address + _offset, ptrsize)) 

+

5309 __structure.apply_at(__address, max_depth, depth + 1) 

+

5310 return 

+

5311 

+

5312 def __get_ctypes_value(self, struct, item, value) -> str: 

+

5313 if not hasattr(struct, "_values_"): return "" 5313 ↛ 5314line 5313 didn't jump to line 5314, because the condition on line 5313 was never false

+

5314 default = "" 

+

5315 for name, values in struct._values_: 

+

5316 if name != item: continue 

+

5317 if callable(values): 

+

5318 return values(value) 

+

5319 try: 

+

5320 for val, desc in values: 

+

5321 if value == val: return desc 

+

5322 if val is None: default = desc 

+

5323 except Exception as e: 

+

5324 err(f"Error parsing '{name}': {e}") 

+

5325 return default 

+

5326 

+

5327 class Module(dict): 

+

5328 def __init__(self, manager: "ExternalStructureManager", path: pathlib.Path) -> None: 

+

5329 self.manager = manager 

+

5330 self.path = path 

+

5331 self.name = path.stem 

+

5332 self.raw = self.__load() 

+

5333 

+

5334 for entry in self: 

+

5335 structure = ExternalStructureManager.Structure(manager, self.path, entry) 

+

5336 self[structure.name] = structure 

+

5337 return 

+

5338 

+

5339 def __load(self) -> ModuleType: 

+

5340 """Load a custom module, and return it.""" 

+

5341 fpath = self.path 

+

5342 spec = importlib.util.spec_from_file_location(fpath.stem, fpath) 

+

5343 module = importlib.util.module_from_spec(spec) 

+

5344 sys.modules[fpath.stem] = module 

+

5345 spec.loader.exec_module(module) 

+

5346 return module 

+

5347 

+

5348 def __str__(self) -> str: 

+

5349 return self.name 

+

5350 

+

5351 def __iter__(self) -> Generator[str, None, None]: 

+

5352 _invalid = {"BigEndianStructure", "LittleEndianStructure", "Structure"} 

+

5353 for x in dir(self.raw): 

+

5354 if x in _invalid: continue 

+

5355 _attr = getattr(self.raw, x) 

+

5356 

+

5357 # if it's a ctypes.Structure class, add it 

+

5358 if inspect.isclass(_attr) and issubclass(_attr, ctypes.Structure): 

+

5359 yield x 

+

5360 continue 

+

5361 

+

5362 # also accept class factory functions 

+

5363 if callable(_attr) and _attr.__module__ == self.name and x.endswith("_t"): 5363 ↛ 5364line 5363 didn't jump to line 5364, because the condition on line 5363 was never true

+

5364 yield x 

+

5365 continue 

+

5366 return 

+

5367 

+

5368 class Modules(dict): 

+

5369 def __init__(self, manager: "ExternalStructureManager") -> None: 

+

5370 self.manager: "ExternalStructureManager" = manager 

+

5371 self.root: pathlib.Path = manager.path 

+

5372 

+

5373 for entry in self.root.iterdir(): 

+

5374 if not entry.is_file(): continue 

+

5375 if entry.suffix != ".py": continue 5375 ↛ 5373line 5375 didn't jump to line 5373, because the continue on line 5375 wasn't executed

+

5376 if entry.name == "__init__.py": continue 5376 ↛ 5373line 5376 didn't jump to line 5373, because the continue on line 5376 wasn't executed

+

5377 module = ExternalStructureManager.Module(manager, entry) 

+

5378 self[module.name] = module 

+

5379 return 

+

5380 

+

5381 def __contains__(self, structure_name: str) -> bool: 

+

5382 """Return True if the structure name is found in any of the modules""" 

+

5383 for module in self.values(): 

+

5384 if structure_name in module: 

+

5385 return True 

+

5386 return False 

+

5387 

+

5388 def __init__(self) -> None: 

+

5389 self.clear_caches() 

+

5390 return 

+

5391 

+

5392 def clear_caches(self) -> None: 

+

5393 self._path = None 

+

5394 self._modules = None 

+

5395 return 

+

5396 

+

5397 @property 

+

5398 def modules(self) -> "ExternalStructureManager.Modules": 

+

5399 if not self._modules: 

+

5400 self._modules = ExternalStructureManager.Modules(self) 

+

5401 return self._modules 

+

5402 

+

5403 @property 

+

5404 def path(self) -> pathlib.Path: 

+

5405 if not self._path: 

+

5406 self._path = pathlib.Path(gef.config["pcustom.struct_path"]).expanduser().absolute() 

+

5407 return self._path 

+

5408 

+

5409 @property 

+

5410 def structures(self) -> Generator[Tuple["ExternalStructureManager.Module", "ExternalStructureManager.Structure"], None, None]: 

+

5411 for module in self.modules.values(): 

+

5412 for structure in module.values(): 

+

5413 yield module, structure 

+

5414 return 

+

5415 

+

5416 @lru_cache() 

+

5417 def find(self, structure_name: str) -> Optional[Tuple["ExternalStructureManager.Module", "ExternalStructureManager.Structure"]]: 

+

5418 """Return the module and structure for the given structure name; `None` if the structure name was not found.""" 

+

5419 for module in self.modules.values(): 

+

5420 if structure_name in module: 

+

5421 return module, module[structure_name] 

+

5422 return None 

+

5423 

+

5424 

+

5425@register 

+

5426class PCustomCommand(GenericCommand): 

+

5427 """Dump user defined structure. 

+

5428 This command attempts to reproduce WinDBG awesome `dt` command for GDB and allows 

+

5429 to apply structures (from symbols or custom) directly to an address. 

+

5430 Custom structures can be defined in pure Python using ctypes, and should be stored 

+

5431 in a specific directory, whose path must be stored in the `pcustom.struct_path` 

+

5432 configuration setting.""" 

+

5433 

+

5434 _cmdline_ = "pcustom" 

+

5435 _syntax_ = f"{_cmdline_} [list|edit <StructureName>|show <StructureName>]|<StructureName> 0xADDRESS]" 

+

5436 

+

5437 def __init__(self) -> None: 

+

5438 super().__init__(prefix=True) 

+

5439 self["struct_path"] = (str(pathlib.Path(gef.config["gef.tempdir"]) / "structs"), "Path to store/load the structure ctypes files") 

+

5440 self["max_depth"] = (4, "Maximum level of recursion supported") 

+

5441 self["structure_name"] = ("bold blue", "Color of the structure name") 

+

5442 self["structure_type"] = ("bold red", "Color of the attribute type") 

+

5443 self["structure_size"] = ("green", "Color of the attribute size") 

+

5444 return 

+

5445 

+

5446 @parse_arguments({"type": "", "address": ""}, {}) 

+

5447 def do_invoke(self, *_: Any, **kwargs: Dict[str, Any]) -> None: 

+

5448 args : argparse.Namespace = kwargs["arguments"] 

+

5449 if not args.type: 

+

5450 gdb.execute("pcustom list") 

+

5451 return 

+

5452 

+

5453 _, structname = self.explode_type(args.type) 

+

5454 

+

5455 if not args.address: 

+

5456 gdb.execute(f"pcustom show {structname}") 

+

5457 return 

+

5458 

+

5459 if not is_alive(): 

+

5460 err("Session is not active") 

+

5461 return 

+

5462 

+

5463 manager = ExternalStructureManager() 

+

5464 address = parse_address(args.address) 

+

5465 result = manager.find(structname) 

+

5466 if not result: 

+

5467 err(f"No structure named '{structname}' found") 

+

5468 return 

+

5469 

+

5470 _, structure = result 

+

5471 structure.apply_at(address, self["max_depth"]) 

+

5472 return 

+

5473 

+

5474 def explode_type(self, arg: str) -> Tuple[str, str]: 

+

5475 modname, structname = arg.split(":", 1) if ":" in arg else (arg, arg) 

+

5476 structname = structname.split(".", 1)[0] if "." in structname else structname 

+

5477 return modname, structname 

+

5478 

+

5479 

+

5480@register 

+

5481class PCustomListCommand(PCustomCommand): 

+

5482 """PCustom: list available structures""" 

+

5483 

+

5484 _cmdline_ = "pcustom list" 

+

5485 _syntax_ = f"{_cmdline_}" 

+

5486 

+

5487 def __init__(self) -> None: 

+

5488 super().__init__() 

+

5489 return 

+

5490 

+

5491 def do_invoke(self, _: List) -> None: 

+

5492 """Dump the list of all the structures and their respective.""" 

+

5493 manager = ExternalStructureManager() 

+

5494 info(f"Listing custom structures from '{manager.path}'") 

+

5495 struct_color = gef.config["pcustom.structure_type"] 

+

5496 filename_color = gef.config["pcustom.structure_name"] 

+

5497 for module in manager.modules.values(): 

+

5498 __modules = ", ".join([Color.colorify(structure_name, struct_color) for structure_name in module.values()]) 

+

5499 __filename = Color.colorify(str(module.path), filename_color) 

+

5500 gef_print(f"{RIGHT_ARROW} {__filename} ({__modules})") 

+

5501 return 

+

5502 

+

5503 

+

5504@register 

+

5505class PCustomShowCommand(PCustomCommand): 

+

5506 """PCustom: show the content of a given structure""" 

+

5507 

+

5508 _cmdline_ = "pcustom show" 

+

5509 _syntax_ = f"{_cmdline_} StructureName" 

+

5510 __aliases__ = ["pcustom create", "pcustom update"] 

+

5511 

+

5512 def __init__(self) -> None: 

+

5513 super().__init__() 

+

5514 return 

+

5515 

+

5516 def do_invoke(self, argv: List[str]) -> None: 

+

5517 if len(argv) == 0: 5517 ↛ 5518line 5517 didn't jump to line 5518, because the condition on line 5517 was never true

+

5518 self.usage() 

+

5519 return 

+

5520 

+

5521 _, structname = self.explode_type(argv[0]) 

+

5522 manager = ExternalStructureManager() 

+

5523 result = manager.find(structname) 

+

5524 if result: 

+

5525 _, structure = result 

+

5526 structure.pprint() 

+

5527 else: 

+

5528 err(f"No structure named '{structname}' found") 

+

5529 return 

+

5530 

+

5531 

+

5532@register 

+

5533class PCustomEditCommand(PCustomCommand): 

+

5534 """PCustom: edit the content of a given structure""" 

+

5535 

+

5536 _cmdline_ = "pcustom edit" 

+

5537 _syntax_ = f"{_cmdline_} StructureName" 

+

5538 __aliases__ = ["pcustom create", "pcustom new", "pcustom update"] 

+

5539 

+

5540 def __init__(self) -> None: 

+

5541 super().__init__() 

+

5542 return 

+

5543 

+

5544 def do_invoke(self, argv: List[str]) -> None: 

+

5545 if len(argv) == 0: 

+

5546 self.usage() 

+

5547 return 

+

5548 

+

5549 modname, structname = self.explode_type(argv[0]) 

+

5550 self.__create_or_edit_structure(modname, structname) 

+

5551 return 

+

5552 

+

5553 def __create_or_edit_structure(self, mod_name: str, struct_name: str) -> int: 

+

5554 path = pathlib.Path(gef.config["pcustom.struct_path"]).expanduser() / f"{mod_name}.py" 

+

5555 if path.is_file(): 

+

5556 info(f"Editing '{path}'") 

+

5557 else: 

+

5558 ok(f"Creating '{path}' from template") 

+

5559 self.__create_template(struct_name, path) 

+

5560 

+

5561 cmd = (os.getenv("EDITOR") or "nano").split() 

+

5562 cmd.append(str(path.absolute())) 

+

5563 return subprocess.call(cmd) 

+

5564 

+

5565 def __create_template(self, structname: str, fpath: pathlib.Path) -> None: 

+

5566 template = f"""from ctypes import * 

+

5567 

+

5568class {structname}(Structure): 

+

5569 _fields_ = [] 

+

5570 

+

5571 _values_ = [] 

+

5572""" 

+

5573 with fpath.open("w") as f: 

+

5574 f.write(template) 

+

5575 return 

+

5576 

+

5577 

+

5578@register 

+

5579class ChangeFdCommand(GenericCommand): 

+

5580 """ChangeFdCommand: redirect file descriptor during runtime.""" 

+

5581 

+

5582 _cmdline_ = "hijack-fd" 

+

5583 _syntax_ = f"{_cmdline_} FD_NUM NEW_OUTPUT" 

+

5584 _example_ = f"{_cmdline_} 2 /tmp/stderr_output.txt" 

+

5585 

+

5586 @only_if_gdb_running 

+

5587 @only_if_gdb_target_local 

+

5588 def do_invoke(self, argv: List[str]) -> None: 

+

5589 if len(argv) != 2: 

+

5590 self.usage() 

+

5591 return 

+

5592 

+

5593 if not os.access(f"/proc/{gef.session.pid:d}/fd/{argv[0]}", os.R_OK): 

+

5594 self.usage() 

+

5595 return 

+

5596 

+

5597 old_fd = int(argv[0]) 

+

5598 new_output = argv[1] 

+

5599 

+

5600 if ":" in new_output: 

+

5601 address = socket.gethostbyname(new_output.split(":")[0]) 

+

5602 port = int(new_output.split(":")[1]) 

+

5603 

+

5604 AF_INET = 2 

+

5605 SOCK_STREAM = 1 

+

5606 res = gdb.execute(f"""call (int)socket({AF_INET}, {SOCK_STREAM}, 0)""", to_string=True) 

+

5607 new_fd = self.get_fd_from_result(res) 

+

5608 

+

5609 # fill in memory with sockaddr_in struct contents 

+

5610 # we will do this in the stack, since connect() wants a pointer to a struct 

+

5611 vmmap = gef.memory.maps 

+

5612 stack_addr = [entry.page_start for entry in vmmap if entry.path == "[stack]"][0] 

+

5613 original_contents = gef.memory.read(stack_addr, 8) 

+

5614 

+

5615 gef.memory.write(stack_addr, b"\x02\x00", 2) 

+

5616 gef.memory.write(stack_addr + 0x2, struct.pack("<H", socket.htons(port)), 2) 

+

5617 gef.memory.write(stack_addr + 0x4, socket.inet_aton(address), 4) 

+

5618 

+

5619 info(f"Trying to connect to {new_output}") 

+

5620 res = gdb.execute(f"""call (int)connect({new_fd}, {stack_addr}, {16})""", to_string=True) 

+

5621 

+

5622 # recover stack state 

+

5623 gef.memory.write(stack_addr, original_contents, 8) 

+

5624 

+

5625 res = self.get_fd_from_result(res) 

+

5626 if res == -1: 

+

5627 err(f"Failed to connect to {address}:{port}") 

+

5628 return 

+

5629 

+

5630 info(f"Connected to {new_output}") 

+

5631 else: 

+

5632 res = gdb.execute(f"""call (int)open("{new_output}", 66, 0666)""", to_string=True) 

+

5633 new_fd = self.get_fd_from_result(res) 

+

5634 

+

5635 info(f"Opened '{new_output}' as fd #{new_fd:d}") 

+

5636 gdb.execute(f"""call (int)dup2({new_fd:d}, {old_fd:d})""", to_string=True) 

+

5637 info(f"Duplicated fd #{new_fd:d}{RIGHT_ARROW}#{old_fd:d}") 

+

5638 gdb.execute(f"""call (int)close({new_fd:d})""", to_string=True) 

+

5639 info(f"Closed extra fd #{new_fd:d}") 

+

5640 ok("Success") 

+

5641 return 

+

5642 

+

5643 def get_fd_from_result(self, res: str) -> int: 

+

5644 # Output example: $1 = 3 

+

5645 res = gdb.execute(f"""p/d {int(res.split()[2], 0)}""", to_string=True) 

+

5646 return int(res.split()[2], 0) 

+

5647 

+

5648 

+

5649@register 

+

5650class ScanSectionCommand(GenericCommand): 

+

5651 """Search for addresses that are located in a memory mapping (haystack) that belonging 

+

5652 to another (needle).""" 

+

5653 

+

5654 _cmdline_ = "scan" 

+

5655 _syntax_ = f"{_cmdline_} HAYSTACK NEEDLE" 

+

5656 _aliases_ = ["lookup",] 

+

5657 _example_ = f"\n{_cmdline_} stack libc" 

+

5658 

+

5659 @only_if_gdb_running 

+

5660 def do_invoke(self, argv: List[str]) -> None: 

+

5661 if len(argv) != 2: 5661 ↛ 5662line 5661 didn't jump to line 5662, because the condition on line 5661 was never true

+

5662 self.usage() 

+

5663 return 

+

5664 

+

5665 haystack = argv[0] 

+

5666 needle = argv[1] 

+

5667 

+

5668 info(f"Searching for addresses in '{Color.yellowify(haystack)}' " 

+

5669 f"that point to '{Color.yellowify(needle)}'") 

+

5670 

+

5671 if haystack == "binary": 

+

5672 haystack = get_filepath() 

+

5673 

+

5674 if needle == "binary": 5674 ↛ 5675line 5674 didn't jump to line 5675, because the condition on line 5674 was never true

+

5675 needle = get_filepath() 

+

5676 

+

5677 needle_sections = [] 

+

5678 haystack_sections = [] 

+

5679 

+

5680 if "0x" in haystack: 5680 ↛ 5681line 5680 didn't jump to line 5681, because the condition on line 5680 was never true

+

5681 start, end = parse_string_range(haystack) 

+

5682 haystack_sections.append((start, end, "")) 

+

5683 

+

5684 if "0x" in needle: 5684 ↛ 5685line 5684 didn't jump to line 5685, because the condition on line 5684 was never true

+

5685 start, end = parse_string_range(needle) 

+

5686 needle_sections.append((start, end)) 

+

5687 

+

5688 for sect in gef.memory.maps: 

+

5689 if haystack in sect.path: 

+

5690 haystack_sections.append((sect.page_start, sect.page_end, os.path.basename(sect.path))) 

+

5691 if needle in sect.path: 

+

5692 needle_sections.append((sect.page_start, sect.page_end)) 

+

5693 

+

5694 step = gef.arch.ptrsize 

+

5695 unpack = u32 if step == 4 else u64 

+

5696 

+

5697 for hstart, hend, hname in haystack_sections: 

+

5698 try: 

+

5699 mem = gef.memory.read(hstart, hend - hstart) 

+

5700 except gdb.MemoryError: 

+

5701 continue 

+

5702 

+

5703 for i in range(0, len(mem), step): 

+

5704 target = unpack(mem[i:i+step]) 

+

5705 for nstart, nend in needle_sections: 

+

5706 if target >= nstart and target < nend: 

+

5707 deref = DereferenceCommand.pprint_dereferenced(hstart, int(i / step)) 

+

5708 if hname != "": 5708 ↛ 5712line 5708 didn't jump to line 5712, because the condition on line 5708 was never false

+

5709 name = Color.colorify(hname, "yellow") 

+

5710 gef_print(f"{name}: {deref}") 

+

5711 else: 

+

5712 gef_print(f" {deref}") 

+

5713 

+

5714 return 

+

5715 

+

5716 

+

5717@register 

+

5718class SearchPatternCommand(GenericCommand): 

+

5719 """SearchPatternCommand: search a pattern in memory. If given an hex value (starting with 0x) 

+

5720 the command will also try to look for upwards cross-references to this address.""" 

+

5721 

+

5722 _cmdline_ = "search-pattern" 

+

5723 _syntax_ = f"{_cmdline_} PATTERN [little|big] [section]" 

+

5724 _aliases_ = ["grep", "xref"] 

+

5725 _example_ = [f"{_cmdline_} AAAAAAAA", 

+

5726 f"{_cmdline_} 0x555555554000 little stack", 

+

5727 f"{_cmdline_} AAAA 0x600000-0x601000", 

+

5728 f"{_cmdline_} --regex 0x401000 0x401500 ([\\\\x20-\\\\x7E]{{2,}})(?=\\\\x00) <-- It matchs null-end-printable(from x20-x7e) C strings (min size 2 bytes)"] 

+

5729 

+

5730 def __init__(self) -> None: 

+

5731 super().__init__() 

+

5732 self["max_size_preview"] = (10, "max size preview of bytes") 

+

5733 self["nr_pages_chunk"] = (0x400, "number of pages readed for each memory read chunk") 

+

5734 return 

+

5735 

+

5736 def print_section(self, section: Section) -> None: 

+

5737 title = "In " 

+

5738 if section.path: 5738 ↛ 5741line 5738 didn't jump to line 5741, because the condition on line 5738 was never false

+

5739 title += f"'{Color.blueify(section.path)}'" 

+

5740 

+

5741 title += f"({section.page_start:#x}-{section.page_end:#x})" 

+

5742 title += f", permission={section.permission}" 

+

5743 ok(title) 

+

5744 return 

+

5745 

+

5746 def print_loc(self, loc: Tuple[int, int, str]) -> None: 

+

5747 gef_print(f""" {loc[0]:#x} - {loc[1]:#x} {RIGHT_ARROW} "{Color.pinkify(loc[2])}" """) 

+

5748 return 

+

5749 

+

5750 def search_pattern_by_address(self, pattern: str, start_address: int, end_address: int) -> List[Tuple[int, int, Optional[str]]]: 

+

5751 """Search a pattern within a range defined by arguments.""" 

+

5752 _pattern = gef_pybytes(pattern) 

+

5753 step = self["nr_pages_chunk"] * gef.session.pagesize 

+

5754 locations = [] 

+

5755 

+

5756 for chunk_addr in range(start_address, end_address, step): 

+

5757 if chunk_addr + step > end_address: 5757 ↛ 5760line 5757 didn't jump to line 5760, because the condition on line 5757 was never false

+

5758 chunk_size = end_address - chunk_addr 

+

5759 else: 

+

5760 chunk_size = step 

+

5761 

+

5762 try: 

+

5763 mem = gef.memory.read(chunk_addr, chunk_size) 

+

5764 except gdb.MemoryError as e: 

+

5765 return [] 

+

5766 

+

5767 for match in re.finditer(_pattern, mem): 

+

5768 start = chunk_addr + match.start() 

+

5769 if is_ascii_string(start): 

+

5770 ustr = gef.memory.read_ascii_string(start) or "" 

+

5771 end = start + len(ustr) 

+

5772 else: 

+

5773 ustr = gef_pystring(_pattern) + "[...]" 

+

5774 end = start + len(_pattern) 

+

5775 locations.append((start, end, ustr)) 

+

5776 

+

5777 del mem 

+

5778 

+

5779 return locations 

+

5780 

+

5781 def search_binpattern_by_address(self, binpattern: bytes, start_address: int, end_address: int) -> List[Tuple[int, int, Optional[str]]]: 

+

5782 """Search a binary pattern within a range defined by arguments.""" 

+

5783 

+

5784 step = self["nr_pages_chunk"] * gef.session.pagesize 

+

5785 locations = [] 

+

5786 

+

5787 for chunk_addr in range(start_address, end_address, step): 

+

5788 if chunk_addr + step > end_address: 5788 ↛ 5791line 5788 didn't jump to line 5791, because the condition on line 5788 was never false

+

5789 chunk_size = end_address - chunk_addr 

+

5790 else: 

+

5791 chunk_size = step 

+

5792 

+

5793 try: 

+

5794 mem = gef.memory.read(chunk_addr, chunk_size) 

+

5795 except gdb.MemoryError as e: 

+

5796 return [] 

+

5797 preview_size = self["max_size_preview"] 

+

5798 for match in re.finditer(binpattern, mem): 

+

5799 start = chunk_addr + match.start() 

+

5800 preview = str(mem[slice(*match.span())][0:preview_size]) + "..." 

+

5801 size_match = match.span()[1] - match.span()[0] 

+

5802 if size_match > 0: 5802 ↛ 5804line 5802 didn't jump to line 5804, because the condition on line 5802 was never false

+

5803 size_match -= 1 

+

5804 end = start + size_match 

+

5805 

+

5806 locations.append((start, end, preview)) 

+

5807 

+

5808 del mem 

+

5809 

+

5810 return locations 

+

5811 

+

5812 def search_pattern(self, pattern: str, section_name: str) -> None: 

+

5813 """Search a pattern within the whole userland memory.""" 

+

5814 for section in gef.memory.maps: 

+

5815 if not section.permission & Permission.READ: continue 

+

5816 if section.path == "[vvar]": continue 

+

5817 if not section_name in section.path: continue 5817 ↛ 5814line 5817 didn't jump to line 5814, because the continue on line 5817 wasn't executed

+

5818 

+

5819 start = section.page_start 

+

5820 end = section.page_end - 1 

+

5821 old_section = None 

+

5822 

+

5823 for loc in self.search_pattern_by_address(pattern, start, end): 

+

5824 addr_loc_start = lookup_address(loc[0]) 

+

5825 if addr_loc_start and addr_loc_start.section: 5825 ↛ 5830line 5825 didn't jump to line 5830, because the condition on line 5825 was never false

+

5826 if old_section != addr_loc_start.section: 5826 ↛ 5830line 5826 didn't jump to line 5830, because the condition on line 5826 was never false

+

5827 self.print_section(addr_loc_start.section) 

+

5828 old_section = addr_loc_start.section 

+

5829 

+

5830 self.print_loc(loc) 

+

5831 return 

+

5832 

+

5833 @only_if_gdb_running 

+

5834 def do_invoke(self, argv: List[str]) -> None: 

+

5835 argc = len(argv) 

+

5836 if argc < 1: 5836 ↛ 5837line 5836 didn't jump to line 5837, because the condition on line 5836 was never true

+

5837 self.usage() 

+

5838 return 

+

5839 

+

5840 if argc > 3 and argv[0].startswith("--regex"): 

+

5841 pattern = ' '.join(argv[3:]) 

+

5842 pattern = ast.literal_eval("b'" + pattern + "'") 

+

5843 

+

5844 addr_start = parse_address(argv[1]) 

+

5845 addr_end = parse_address(argv[2]) 

+

5846 

+

5847 for loc in self.search_binpattern_by_address(pattern, addr_start, addr_end): 

+

5848 self.print_loc(loc) 

+

5849 

+

5850 return 

+

5851 

+

5852 pattern = argv[0] 

+

5853 endian = gef.arch.endianness 

+

5854 

+

5855 if argc >= 2: 5855 ↛ 5856line 5855 didn't jump to line 5856, because the condition on line 5855 was never true

+

5856 if argv[1].lower() == "big": endian = Endianness.BIG_ENDIAN 

+

5857 elif argv[1].lower() == "little": endian = Endianness.LITTLE_ENDIAN 

+

5858 

+

5859 if is_hex(pattern): 5859 ↛ 5860line 5859 didn't jump to line 5860, because the condition on line 5859 was never true

+

5860 if endian == Endianness.BIG_ENDIAN: 

+

5861 pattern = "".join(["\\x" + pattern[i:i + 2] for i in range(2, len(pattern), 2)]) 

+

5862 else: 

+

5863 pattern = "".join(["\\x" + pattern[i:i + 2] for i in range(len(pattern) - 2, 0, -2)]) 

+

5864 

+

5865 if argc == 3: 5865 ↛ 5866line 5865 didn't jump to line 5866, because the condition on line 5865 was never true

+

5866 info(f"Searching '{Color.yellowify(pattern)}' in {argv[2]}") 

+

5867 

+

5868 if "0x" in argv[2]: 

+

5869 start, end = parse_string_range(argv[2]) 

+

5870 

+

5871 loc = lookup_address(start) 

+

5872 if loc.valid: 

+

5873 self.print_section(loc.section) 

+

5874 

+

5875 for loc in self.search_pattern_by_address(pattern, start, end): 

+

5876 self.print_loc(loc) 

+

5877 else: 

+

5878 section_name = argv[2] 

+

5879 if section_name == "binary": 

+

5880 section_name = get_filepath() or "" 

+

5881 

+

5882 self.search_pattern(pattern, section_name) 

+

5883 else: 

+

5884 info(f"Searching '{Color.yellowify(pattern)}' in memory") 

+

5885 self.search_pattern(pattern, "") 

+

5886 return 

+

5887 

+

5888 

+

5889@register 

+

5890class FlagsCommand(GenericCommand): 

+

5891 """Edit flags in a human friendly way.""" 

+

5892 

+

5893 _cmdline_ = "edit-flags" 

+

5894 _syntax_ = f"{_cmdline_} [(+|-|~)FLAGNAME ...]" 

+

5895 _aliases_ = ["flags",] 

+

5896 _example_ = (f"\n{_cmdline_}" 

+

5897 f"\n{_cmdline_} +zero # sets ZERO flag") 

+

5898 

+

5899 def do_invoke(self, argv: List[str]) -> None: 

+

5900 if not gef.arch.flag_register: 5900 ↛ 5901line 5900 didn't jump to line 5901, because the condition on line 5900 was never true

+

5901 warn(f"The architecture {gef.arch.arch}:{gef.arch.mode} doesn't have flag register.") 

+

5902 return 

+

5903 

+

5904 for flag in argv: 

+

5905 if len(flag) < 2: 5905 ↛ 5906line 5905 didn't jump to line 5906, because the condition on line 5905 was never true

+

5906 continue 

+

5907 

+

5908 action = flag[0] 

+

5909 name = flag[1:].lower() 

+

5910 

+

5911 if action not in ("+", "-", "~"): 5911 ↛ 5912line 5911 didn't jump to line 5912, because the condition on line 5911 was never true

+

5912 err(f"Invalid action for flag '{flag}'") 

+

5913 continue 

+

5914 

+

5915 if name not in gef.arch.flags_table.values(): 5915 ↛ 5916line 5915 didn't jump to line 5916, because the condition on line 5915 was never true

+

5916 err(f"Invalid flag name '{flag[1:]}'") 

+

5917 continue 

+

5918 

+

5919 for off in gef.arch.flags_table: 

+

5920 if gef.arch.flags_table[off] == name: 

+

5921 old_flag = gef.arch.register(gef.arch.flag_register) 

+

5922 if action == "+": 

+

5923 new_flags = old_flag | (1 << off) 

+

5924 elif action == "-": 

+

5925 new_flags = old_flag & ~(1 << off) 

+

5926 else: 

+

5927 new_flags = old_flag ^ (1 << off) 

+

5928 

+

5929 gdb.execute(f"set ({gef.arch.flag_register}) = {new_flags:#x}") 

+

5930 

+

5931 gef_print(gef.arch.flag_register_to_human()) 

+

5932 return 

+

5933 

+

5934 

+

5935@register 

+

5936class RemoteCommand(GenericCommand): 

+

5937 """GDB `target remote` command on steroids. This command will use the remote procfs to create 

+

5938 a local copy of the execution environment, including the target binary and its libraries 

+

5939 in the local temporary directory (the value by default is in `gef.config.tempdir`). Additionally, it 

+

5940 will fetch all the /proc/PID/maps and loads all its information. If procfs is not available remotely, the command 

+

5941 will likely fail. You can however still use the limited command provided by GDB `target remote`.""" 

+

5942 

+

5943 _cmdline_ = "gef-remote" 

+

5944 _syntax_ = f"{_cmdline_} [OPTIONS] TARGET" 

+

5945 _example_ = [f"{_cmdline_} localhost 1234", 

+

5946 f"{_cmdline_} --pid 6789 localhost 1234", 

+

5947 f"{_cmdline_} --qemu-user --qemu-binary /bin/debugme localhost 4444 "] 

+

5948 

+

5949 def __init__(self) -> None: 

+

5950 super().__init__(prefix=False) 

+

5951 return 

+

5952 

+

5953 @parse_arguments({"host": "", "port": 0}, {"--pid": -1, "--qemu-user": True, "--qemu-binary": ""}) 

+

5954 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

5955 if gef.session.remote is not None: 5955 ↛ 5956line 5955 didn't jump to line 5956, because the condition on line 5955 was never true

+

5956 err("You already are in remote session. Close it first before opening a new one...") 

+

5957 return 

+

5958 

+

5959 # argument check 

+

5960 args : argparse.Namespace = kwargs["arguments"] 

+

5961 if not args.host or not args.port: 5961 ↛ 5962line 5961 didn't jump to line 5962, because the condition on line 5961 was never true

+

5962 err("Missing parameters") 

+

5963 return 

+

5964 

+

5965 # qemu-user support 

+

5966 qemu_binary: Optional[pathlib.Path] = None 

+

5967 try: 

+

5968 if args.qemu_user: 

+

5969 qemu_binary = pathlib.Path(args.qemu_binary).expanduser().absolute() if args.qemu_binary else gef.session.file 

+

5970 if not qemu_binary or not qemu_binary.exists(): 5970 ↛ 5971line 5970 didn't jump to line 5971, because the condition on line 5970 was never true

+

5971 raise FileNotFoundError(f"{qemu_binary} does not exist") 

+

5972 except Exception as e: 

+

5973 err(f"Failed to initialize qemu-user mode, reason: {str(e)}") 

+

5974 return 

+

5975 

+

5976 # try to establish the remote session, throw on error 

+

5977 # Set `.remote_initializing` to True here - `GefRemoteSessionManager` invokes code which 

+

5978 # calls `is_remote_debug` which checks if `remote_initializing` is True or `.remote` is None 

+

5979 # This prevents some spurious errors being thrown during startup 

+

5980 gef.session.remote_initializing = True 

+

5981 gef.session.remote = GefRemoteSessionManager(args.host, args.port, args.pid, qemu_binary) 

+

5982 gef.session.remote_initializing = False 

+

5983 reset_all_caches() 

+

5984 gdb.execute("context") 

+

5985 return 

+

5986 

+

5987 

+

5988@register 

+

5989class SkipiCommand(GenericCommand): 

+

5990 """Skip N instruction(s) execution""" 

+

5991 

+

5992 _cmdline_ = "skipi" 

+

5993 _syntax_ = ("{_cmdline_} [LOCATION] [--n NUM_INSTRUCTIONS]" 

+

5994 "\n\tLOCATION\taddress/symbol from where to skip" 

+

5995 "\t--n NUM_INSTRUCTIONS\tSkip the specified number of instructions instead of the default 1.") 

+

5996 

+

5997 _example_ = [f"{_cmdline_}", 

+

5998 f"{_cmdline_} --n 3", 

+

5999 f"{_cmdline_} 0x69696969", 

+

6000 f"{_cmdline_} 0x69696969 --n 6",] 

+

6001 

+

6002 def __init__(self) -> None: 

+

6003 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6004 return 

+

6005 

+

6006 @only_if_gdb_running 

+

6007 @parse_arguments({"address": "$pc"}, {"--n": 1}) 

+

6008 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6009 args : argparse.Namespace = kwargs["arguments"] 

+

6010 address = parse_address(args.address) 

+

6011 num_instructions = args.n 

+

6012 

+

6013 last_addr = gdb_get_nth_next_instruction_address(address, num_instructions) 

+

6014 total_bytes = (last_addr - address) + gef_get_instruction_at(last_addr).size() 

+

6015 target_addr = address + total_bytes 

+

6016 

+

6017 info(f"skipping {num_instructions} instructions ({total_bytes} bytes) from {address:#x} to {target_addr:#x}") 

+

6018 gdb.execute(f"set $pc = {target_addr:#x}") 

+

6019 return 

+

6020 

+

6021 

+

6022@register 

+

6023class NopCommand(GenericCommand): 

+

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

+

6025 aware.""" 

+

6026 

+

6027 _cmdline_ = "nop" 

+

6028 _syntax_ = ("{_cmdline_} [LOCATION] [--i ITEMS] [--f] [--n] [--b]" 

+

6029 "\n\tLOCATION\taddress/symbol to patch (by default this command replaces whole instructions)" 

+

6030 "\t--i ITEMS\tnumber of items to insert (default 1)" 

+

6031 "\t--f\tForce patch even when the selected settings could overwrite partial instructions" 

+

6032 "\t--n\tInstead of replacing whole instructions, insert ITEMS nop instructions, no matter how many instructions it overwrites" 

+

6033 "\t--b\tInstead of replacing whole instructions, fill ITEMS bytes with nops") 

+

6034 _example_ = [f"{_cmdline_}", 

+

6035 f"{_cmdline_} $pc+3", 

+

6036 f"{_cmdline_} --i 2 $pc+3", 

+

6037 f"{_cmdline_} --b", 

+

6038 f"{_cmdline_} --b $pc+3", 

+

6039 f"{_cmdline_} --f --b --i 2 $pc+3" 

+

6040 f"{_cmdline_} --n --i 2 $pc+3",] 

+

6041 

+

6042 def __init__(self) -> None: 

+

6043 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6044 return 

+

6045 

+

6046 @only_if_gdb_running 

+

6047 @parse_arguments({"address": "$pc"}, {"--i": 1, "--b": True, "--f": True, "--n": True}) 

+

6048 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6049 args : argparse.Namespace = kwargs["arguments"] 

+

6050 address = parse_address(args.address) 

+

6051 nop = gef.arch.nop_insn 

+

6052 num_items = args.i or 1 

+

6053 fill_bytes = args.b 

+

6054 fill_nops = args.n 

+

6055 force_flag = args.f or False 

+

6056 

+

6057 if fill_nops and fill_bytes: 

+

6058 err("only is possible specify --b or --n at same time") 

+

6059 return 

+

6060 

+

6061 total_bytes = 0 

+

6062 if fill_bytes: 

+

6063 total_bytes = num_items 

+

6064 elif fill_nops: 

+

6065 total_bytes = num_items * len(nop) 

+

6066 else: 

+

6067 try: 

+

6068 last_addr = gdb_get_nth_next_instruction_address(address, num_items) 

+

6069 except: 

+

6070 err(f"Cannot patch instruction at {address:#x} reaching unmapped area") 

+

6071 return 

+

6072 total_bytes = (last_addr - address) + gef_get_instruction_at(last_addr).size() 

+

6073 

+

6074 if len(nop) > total_bytes or total_bytes % len(nop): 

+

6075 warn(f"Patching {total_bytes} bytes at {address:#x} will result in LAST-NOP " 

+

6076 f"(byte nr {total_bytes % len(nop):#x}) broken and may cause a crash or " 

+

6077 f"break disassembly. Use --f (force) to ignore this warning") 

+

6078 if not force_flag: 

+

6079 return 

+

6080 

+

6081 target_end_address = address + total_bytes 

+

6082 curr_ins = gef_current_instruction(address) 

+

6083 while curr_ins.address + curr_ins.size() < target_end_address: 

+

6084 if not Address(value=curr_ins.address + 1).valid: 

+

6085 err(f"Cannot patch instruction at {address:#x}: reaching unmapped area") 

+

6086 return 

+

6087 curr_ins = gef_next_instruction(curr_ins.address) 

+

6088 

+

6089 final_ins_end_addr = curr_ins.address + curr_ins.size() 

+

6090 

+

6091 if final_ins_end_addr != target_end_address: 

+

6092 warn(f"Patching {total_bytes} bytes at {address:#x} will result in LAST-INSTRUCTION " 

+

6093 f"({curr_ins.address:#x}) being partial overwritten and may cause a crash or " 

+

6094 f"break disassembly. You must use --f to allow misaligned patching.") 

+

6095 if not force_flag: 

+

6096 return 

+

6097 

+

6098 nops = bytearray(nop * total_bytes) 

+

6099 end_address = Address(value=address + total_bytes - 1) 

+

6100 if not end_address.valid: 6100 ↛ 6101line 6100 didn't jump to line 6101, because the condition on line 6100 was never true

+

6101 err(f"Cannot patch instruction at {address:#x}: reaching unmapped " 

+

6102 f"area: {end_address:#x}") 

+

6103 return 

+

6104 

+

6105 ok(f"Patching {total_bytes} bytes from {address:#x}") 

+

6106 gef.memory.write(address, nops, total_bytes) 

+

6107 

+

6108 return 

+

6109 

+

6110 

+

6111@register 

+

6112class StubCommand(GenericCommand): 

+

6113 """Stub out the specified function. This function is useful when needing to skip one 

+

6114 function to be called and disrupt your runtime flow (ex. fork).""" 

+

6115 

+

6116 _cmdline_ = "stub" 

+

6117 _syntax_ = (f"{_cmdline_} [--retval RETVAL] [address]" 

+

6118 "\taddress\taddress/symbol to stub out" 

+

6119 "\t--retval RETVAL\tSet the return value") 

+

6120 _example_ = f"{_cmdline_} --retval 0 fork" 

+

6121 

+

6122 def __init__(self) -> None: 

+

6123 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6124 return 

+

6125 

+

6126 @only_if_gdb_running 

+

6127 @parse_arguments({"address": ""}, {("-r", "--retval"): 0}) 

+

6128 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6129 args : argparse.Namespace = kwargs["arguments"] 

+

6130 loc = args.address if args.address else f"*{gef.arch.pc:#x}" 

+

6131 StubBreakpoint(loc, args.retval) 

+

6132 return 

+

6133 

+

6134 

+

6135@register 

+

6136class GlibcHeapCommand(GenericCommand): 

+

6137 """Base command to get information about the Glibc heap structure.""" 

+

6138 

+

6139 _cmdline_ = "heap" 

+

6140 _syntax_ = f"{_cmdline_} (chunk|chunks|bins|arenas|set-arena)" 

+

6141 

+

6142 def __init__(self) -> None: 

+

6143 super().__init__(prefix=True) 

+

6144 return 

+

6145 

+

6146 @only_if_gdb_running 

+

6147 def do_invoke(self, _: List[str]) -> None: 

+

6148 self.usage() 

+

6149 return 

+

6150 

+

6151 

+

6152@register 

+

6153class GlibcHeapSetArenaCommand(GenericCommand): 

+

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

+

6155 

+

6156 _cmdline_ = "heap set-arena" 

+

6157 _syntax_ = f"{_cmdline_} [address|&symbol]" 

+

6158 _example_ = f"{_cmdline_} 0x001337001337" 

+

6159 

+

6160 def __init__(self) -> None: 

+

6161 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6162 return 

+

6163 

+

6164 @only_if_gdb_running 

+

6165 @parse_arguments({"addr": ""}, {"--reset": True}) 

+

6166 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6167 global gef 

+

6168 

+

6169 args: argparse.Namespace = kwargs["arguments"] 

+

6170 

+

6171 if args.reset: 6171 ↛ 6172line 6171 didn't jump to line 6172, because the condition on line 6171 was never true

+

6172 gef.heap.reset_caches() 

+

6173 return 

+

6174 

+

6175 if not args.addr: 6175 ↛ 6176line 6175 didn't jump to line 6176, because the condition on line 6175 was never true

+

6176 ok(f"Current arena set to: '{gef.heap.selected_arena}'") 

+

6177 return 

+

6178 

+

6179 try: 

+

6180 new_arena_address = parse_address(args.addr) 

+

6181 except gdb.error: 

+

6182 err("Invalid symbol for arena") 

+

6183 return 

+

6184 

+

6185 new_arena = GlibcArena( f"*{new_arena_address:#x}") 

+

6186 if new_arena in gef.heap.arenas: 6186 ↛ 6191line 6186 didn't jump to line 6191, because the condition on line 6186 was never false

+

6187 # if entered arena is in arena list then just select it 

+

6188 gef.heap.selected_arena = new_arena 

+

6189 else: 

+

6190 # otherwise set the main arena to the entered arena 

+

6191 gef.heap.main_arena = new_arena 

+

6192 return 

+

6193 

+

6194 

+

6195@register 

+

6196class GlibcHeapArenaCommand(GenericCommand): 

+

6197 """Display information on a heap chunk.""" 

+

6198 

+

6199 _cmdline_ = "heap arenas" 

+

6200 _syntax_ = _cmdline_ 

+

6201 

+

6202 @only_if_gdb_running 

+

6203 def do_invoke(self, _: List[str]) -> None: 

+

6204 for arena in gef.heap.arenas: 

+

6205 gef_print(str(arena)) 

+

6206 return 

+

6207 

+

6208 

+

6209@register 

+

6210class GlibcHeapChunkCommand(GenericCommand): 

+

6211 """Display information on a heap chunk. 

+

6212 See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123.""" 

+

6213 

+

6214 _cmdline_ = "heap chunk" 

+

6215 _syntax_ = f"{_cmdline_} [-h] [--allow-unaligned] [--number] address" 

+

6216 

+

6217 def __init__(self) -> None: 

+

6218 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6219 return 

+

6220 

+

6221 @parse_arguments({"address": ""}, {"--allow-unaligned": True, "--number": 1}) 

+

6222 @only_if_gdb_running 

+

6223 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6224 args : argparse.Namespace = kwargs["arguments"] 

+

6225 if not args.address: 6225 ↛ 6226line 6225 didn't jump to line 6226, because the condition on line 6225 was never true

+

6226 err("Missing chunk address") 

+

6227 self.usage() 

+

6228 return 

+

6229 

+

6230 addr = parse_address(args.address) 

+

6231 current_chunk = GlibcChunk(addr, allow_unaligned=args.allow_unaligned) 

+

6232 

+

6233 if args.number > 1: 

+

6234 for _i in range(args.number): 6234 ↛ 6250line 6234 didn't jump to line 6250, because the loop on line 6234 didn't complete

+

6235 if current_chunk.size == 0: 6235 ↛ 6236line 6235 didn't jump to line 6236, because the condition on line 6235 was never true

+

6236 break 

+

6237 

+

6238 gef_print(str(current_chunk)) 

+

6239 next_chunk_addr = current_chunk.get_next_chunk_addr() 

+

6240 if not Address(value=next_chunk_addr).valid: 

+

6241 break 

+

6242 

+

6243 next_chunk = current_chunk.get_next_chunk() 

+

6244 if next_chunk is None: 6244 ↛ 6245line 6244 didn't jump to line 6245, because the condition on line 6244 was never true

+

6245 break 

+

6246 

+

6247 current_chunk = next_chunk 

+

6248 else: 

+

6249 gef_print(current_chunk.psprint()) 

+

6250 return 

+

6251 

+

6252 

+

6253@register 

+

6254class GlibcHeapChunksCommand(GenericCommand): 

+

6255 """Display all heap chunks for the current arena. As an optional argument 

+

6256 the base address of a different arena can be passed""" 

+

6257 

+

6258 _cmdline_ = "heap chunks" 

+

6259 _syntax_ = f"{_cmdline_} [-h] [--all] [--allow-unaligned] [arena_address]" 

+

6260 _example_ = (f"\n{_cmdline_}" 

+

6261 f"\n{_cmdline_} 0x555555775000") 

+

6262 

+

6263 def __init__(self) -> None: 

+

6264 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6265 self["peek_nb_byte"] = (16, "Hexdump N first byte(s) inside the chunk data (0 to disable)") 

+

6266 return 

+

6267 

+

6268 @parse_arguments({"arena_address": ""}, {("--all", "-a"): True, "--allow-unaligned": True}) 

+

6269 @only_if_gdb_running 

+

6270 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6271 args = kwargs["arguments"] 

+

6272 if args.all or not args.arena_address: 

+

6273 for arena in gef.heap.arenas: 6273 ↛ 6277line 6273 didn't jump to line 6277, because the loop on line 6273 didn't complete

+

6274 self.dump_chunks_arena(arena, print_arena=args.all, allow_unaligned=args.allow_unaligned) 

+

6275 if not args.all: 6275 ↛ 6273line 6275 didn't jump to line 6273, because the condition on line 6275 was never false

+

6276 return 

+

6277 try: 

+

6278 arena_addr = parse_address(args.arena_address) 

+

6279 arena = GlibcArena(f"*{arena_addr:#x}") 

+

6280 self.dump_chunks_arena(arena, allow_unaligned=args.allow_unaligned) 

+

6281 except gdb.error: 

+

6282 err("Invalid arena") 

+

6283 return 

+

6284 

+

6285 def dump_chunks_arena(self, arena: GlibcArena, print_arena: bool = False, allow_unaligned: bool = False) -> None: 

+

6286 heap_addr = arena.heap_addr(allow_unaligned=allow_unaligned) 

+

6287 if heap_addr is None: 6287 ↛ 6288line 6287 didn't jump to line 6288, because the condition on line 6287 was never true

+

6288 err("Could not find heap for arena") 

+

6289 return 

+

6290 if print_arena: 6290 ↛ 6291line 6290 didn't jump to line 6291, because the condition on line 6290 was never true

+

6291 gef_print(str(arena)) 

+

6292 if arena.is_main_arena(): 

+

6293 heap_end = arena.top + GlibcChunk(arena.top, from_base=True).size 

+

6294 self.dump_chunks_heap(heap_addr, heap_end, arena, allow_unaligned=allow_unaligned) 

+

6295 else: 

+

6296 heap_info_structs = arena.get_heap_info_list() or [] 

+

6297 for heap_info in heap_info_structs: 

+

6298 if not self.dump_chunks_heap(heap_info.heap_start, heap_info.heap_end, arena, allow_unaligned=allow_unaligned): 6298 ↛ 6299line 6298 didn't jump to line 6299, because the condition on line 6298 was never true

+

6299 break 

+

6300 return 

+

6301 

+

6302 def dump_chunks_heap(self, start: int, end: int, arena: GlibcArena, allow_unaligned: bool = False) -> bool: 

+

6303 nb = self["peek_nb_byte"] 

+

6304 chunk_iterator = GlibcChunk(start, from_base=True, allow_unaligned=allow_unaligned) 

+

6305 for chunk in chunk_iterator: 6305 ↛ 6319line 6305 didn't jump to line 6319, because the loop on line 6305 didn't complete

+

6306 if chunk.base_address == arena.top: 

+

6307 gef_print( 

+

6308 f"{chunk!s} {LEFT_ARROW} {Color.greenify('top chunk')}") 

+

6309 break 

+

6310 

+

6311 if chunk.base_address > end: 6311 ↛ 6312line 6311 didn't jump to line 6312, because the condition on line 6311 was never true

+

6312 err("Corrupted heap, cannot continue.") 

+

6313 return False 

+

6314 

+

6315 line = str(chunk) 

+

6316 if nb: 6316 ↛ 6318line 6316 didn't jump to line 6318, because the condition on line 6316 was never false

+

6317 line += f"\n [{hexdump(gef.memory.read(chunk.data_address, nb), nb, base=chunk.data_address)}]" 

+

6318 gef_print(line) 

+

6319 return True 

+

6320 

+

6321 

+

6322@register 

+

6323class GlibcHeapBinsCommand(GenericCommand): 

+

6324 """Display information on the bins on an arena (default: main_arena). 

+

6325 See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123.""" 

+

6326 

+

6327 _bin_types_ = ("tcache", "fast", "unsorted", "small", "large") 

+

6328 _cmdline_ = "heap bins" 

+

6329 _syntax_ = f"{_cmdline_} [{'|'.join(_bin_types_)}]" 

+

6330 

+

6331 def __init__(self) -> None: 

+

6332 super().__init__(prefix=True, complete=gdb.COMPLETE_LOCATION) 

+

6333 return 

+

6334 

+

6335 @only_if_gdb_running 

+

6336 def do_invoke(self, argv: List[str]) -> None: 

+

6337 if not argv: 

+

6338 for bin_t in self._bin_types_: 

+

6339 gdb.execute(f"heap bins {bin_t}") 

+

6340 return 

+

6341 

+

6342 bin_t = argv[0] 

+

6343 if bin_t not in self._bin_types_: 

+

6344 self.usage() 

+

6345 return 

+

6346 

+

6347 gdb.execute(f"heap bins {bin_t}") 

+

6348 return 

+

6349 

+

6350 @staticmethod 

+

6351 def pprint_bin(arena_addr: str, index: int, _type: str = "") -> int: 

+

6352 arena = GlibcArena(arena_addr) 

+

6353 

+

6354 fd, bk = arena.bin(index) 

+

6355 if (fd, bk) == (0x00, 0x00): 6355 ↛ 6356line 6355 didn't jump to line 6356, because the condition on line 6355 was never true

+

6356 warn("Invalid backward and forward bin pointers(fw==bk==NULL)") 

+

6357 return -1 

+

6358 

+

6359 if _type == "tcache": 6359 ↛ 6360line 6359 didn't jump to line 6360, because the condition on line 6359 was never true

+

6360 chunkClass = GlibcTcacheChunk 

+

6361 elif _type == "fast": 6361 ↛ 6362line 6361 didn't jump to line 6362, because the condition on line 6361 was never true

+

6362 chunkClass = GlibcFastChunk 

+

6363 else: 

+

6364 chunkClass = GlibcChunk 

+

6365 

+

6366 nb_chunk = 0 

+

6367 head = chunkClass(bk, from_base=True).fd 

+

6368 if fd == head: 

+

6369 return nb_chunk 

+

6370 

+

6371 ok(f"{_type}bins[{index:d}]: fw={fd:#x}, bk={bk:#x}") 

+

6372 

+

6373 m = [] 

+

6374 while fd != head: 

+

6375 chunk = chunkClass(fd, from_base=True) 

+

6376 m.append(f"{RIGHT_ARROW} {chunk!s}") 

+

6377 fd = chunk.fd 

+

6378 nb_chunk += 1 

+

6379 

+

6380 if m: 6380 ↛ 6382line 6380 didn't jump to line 6382, because the condition on line 6380 was never false

+

6381 gef_print(" ".join(m)) 

+

6382 return nb_chunk 

+

6383 

+

6384 

+

6385@register 

+

6386class GlibcHeapTcachebinsCommand(GenericCommand): 

+

6387 """Display information on the Tcachebins on an arena (default: main_arena). 

+

6388 See https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc.""" 

+

6389 

+

6390 _cmdline_ = "heap bins tcache" 

+

6391 _syntax_ = f"{_cmdline_} [all] [thread_ids...]" 

+

6392 

+

6393 TCACHE_MAX_BINS = 0x40 

+

6394 

+

6395 def __init__(self) -> None: 

+

6396 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6397 return 

+

6398 

+

6399 @only_if_gdb_running 

+

6400 def do_invoke(self, argv: List[str]) -> None: 

+

6401 # Determine if we are using libc with tcache built in (2.26+) 

+

6402 if gef.libc.version and gef.libc.version < (2, 26): 6402 ↛ 6403line 6402 didn't jump to line 6403, because the condition on line 6402 was never true

+

6403 info("No Tcache in this version of libc") 

+

6404 return 

+

6405 

+

6406 current_thread = gdb.selected_thread() 

+

6407 if current_thread is None: 6407 ↛ 6408line 6407 didn't jump to line 6408, because the condition on line 6407 was never true

+

6408 err("Couldn't find current thread") 

+

6409 return 

+

6410 

+

6411 # As a nicety, we want to display threads in ascending order by gdb number 

+

6412 threads = sorted(gdb.selected_inferior().threads(), key=lambda t: t.num) 

+

6413 if argv: 

+

6414 if "all" in argv: 6414 ↛ 6417line 6414 didn't jump to line 6417, because the condition on line 6414 was never false

+

6415 tids = [t.num for t in threads] 

+

6416 else: 

+

6417 tids = self.check_thread_ids(argv) 

+

6418 else: 

+

6419 tids = [current_thread.num] 

+

6420 

+

6421 for thread in threads: 

+

6422 if thread.num not in tids: 

+

6423 continue 

+

6424 

+

6425 thread.switch() 

+

6426 

+

6427 tcache_addr = self.find_tcache() 

+

6428 if tcache_addr == 0: 6428 ↛ 6429line 6428 didn't jump to line 6429, because the condition on line 6428 was never true

+

6429 info(f"Uninitialized tcache for thread {thread.num:d}") 

+

6430 continue 

+

6431 

+

6432 gef_print(titlify(f"Tcachebins for thread {thread.num:d}")) 

+

6433 tcache_empty = True 

+

6434 for i in range(self.TCACHE_MAX_BINS): 

+

6435 chunk, count = self.tcachebin(tcache_addr, i) 

+

6436 chunks = set() 

+

6437 msg = [] 

+

6438 chunk_size = 0 

+

6439 

+

6440 # Only print the entry if there are valid chunks. Don't trust count 

+

6441 while True: 

+

6442 if chunk is None: 

+

6443 break 

+

6444 

+

6445 try: 

+

6446 msg.append(f"{LEFT_ARROW} {chunk!s} ") 

+

6447 if not chunk_size: 

+

6448 chunk_size = chunk.usable_size 

+

6449 

+

6450 if chunk.data_address in chunks: 6450 ↛ 6451line 6450 didn't jump to line 6451, because the condition on line 6450 was never true

+

6451 msg.append(f"{RIGHT_ARROW} [loop detected]") 

+

6452 break 

+

6453 

+

6454 chunks.add(chunk.data_address) 

+

6455 

+

6456 next_chunk = chunk.fd 

+

6457 if next_chunk == 0: 

+

6458 break 

+

6459 

+

6460 chunk = GlibcTcacheChunk(next_chunk) 

+

6461 except gdb.MemoryError: 

+

6462 msg.append(f"{LEFT_ARROW} [Corrupted chunk at {chunk.data_address:#x}]") 

+

6463 break 

+

6464 

+

6465 if msg: 

+

6466 tcache_empty = False 

+

6467 tidx = gef.heap.csize2tidx(chunk_size) 

+

6468 size = gef.heap.tidx2size(tidx) 

+

6469 count = len(chunks) 

+

6470 gef_print(f"Tcachebins[idx={tidx:d}, size={size:#x}, count={count}]", end="") 

+

6471 gef_print("".join(msg)) 

+

6472 

+

6473 if tcache_empty: 

+

6474 gef_print("All tcachebins are empty") 

+

6475 

+

6476 current_thread.switch() 

+

6477 return 

+

6478 

+

6479 @staticmethod 

+

6480 def find_tcache() -> int: 

+

6481 """Return the location of the current thread's tcache.""" 

+

6482 try: 

+

6483 # For multithreaded binaries, the tcache symbol (in thread local 

+

6484 # storage) will give us the correct address. 

+

6485 tcache_addr = parse_address("(void *) tcache") 

+

6486 except gdb.error: 

+

6487 # In binaries not linked with pthread (and therefore there is only 

+

6488 # one thread), we can't use the tcache symbol, but we can guess the 

+

6489 # correct address because the tcache is consistently the first 

+

6490 # allocation in the main arena. 

+

6491 heap_base = gef.heap.base_address 

+

6492 if heap_base is None: 

+

6493 err("No heap section") 

+

6494 return 0x0 

+

6495 tcache_addr = heap_base + 0x10 

+

6496 return tcache_addr 

+

6497 

+

6498 @staticmethod 

+

6499 def check_thread_ids(tids: List[int]) -> List[int]: 

+

6500 """Check the validity, dedup, and return all valid tids.""" 

+

6501 existing_tids = [t.num for t in gdb.selected_inferior().threads()] 

+

6502 valid_tids = set() 

+

6503 for tid in tids: 

+

6504 try: 

+

6505 tid = int(tid) 

+

6506 except ValueError: 

+

6507 err(f"Invalid thread id {tid:d}") 

+

6508 continue 

+

6509 if tid in existing_tids: 

+

6510 valid_tids.add(tid) 

+

6511 else: 

+

6512 err(f"Unknown thread {tid}") 

+

6513 

+

6514 return list(valid_tids) 

+

6515 

+

6516 @staticmethod 

+

6517 def tcachebin(tcache_base: int, i: int) -> Tuple[Optional[GlibcTcacheChunk], int]: 

+

6518 """Return the head chunk in tcache[i] and the number of chunks in the bin.""" 

+

6519 if i >= GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS: 6519 ↛ 6520line 6519 didn't jump to line 6520, because the condition on line 6519 was never true

+

6520 err("Incorrect index value, index value must be between 0 and {}-1, given {}".format(GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS, i)) 

+

6521 return None, 0 

+

6522 

+

6523 tcache_chunk = GlibcTcacheChunk(tcache_base) 

+

6524 

+

6525 # Glibc changed the size of the tcache in version 2.30; this fix has 

+

6526 # been backported inconsistently between distributions. We detect the 

+

6527 # difference by checking the size of the allocated chunk for the 

+

6528 # tcache. 

+

6529 # Minimum usable size of allocated tcache chunk = ? 

+

6530 # For new tcache: 

+

6531 # TCACHE_MAX_BINS * _2_ + TCACHE_MAX_BINS * ptrsize 

+

6532 # For old tcache: 

+

6533 # TCACHE_MAX_BINS * _1_ + TCACHE_MAX_BINS * ptrsize 

+

6534 new_tcache_min_size = ( 

+

6535 GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS * 2 + 

+

6536 GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS * gef.arch.ptrsize) 

+

6537 

+

6538 if tcache_chunk.usable_size < new_tcache_min_size: 6538 ↛ 6539line 6538 didn't jump to line 6539, because the condition on line 6538 was never true

+

6539 tcache_count_size = 1 

+

6540 count = ord(gef.memory.read(tcache_base + tcache_count_size*i, 1)) 

+

6541 else: 

+

6542 tcache_count_size = 2 

+

6543 count = u16(gef.memory.read(tcache_base + tcache_count_size*i, 2)) 

+

6544 

+

6545 chunk = dereference(tcache_base + tcache_count_size*GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS + i*gef.arch.ptrsize) 

+

6546 chunk = GlibcTcacheChunk(int(chunk)) if chunk else None 

+

6547 return chunk, count 

+

6548 

+

6549 

+

6550@register 

+

6551class GlibcHeapFastbinsYCommand(GenericCommand): 

+

6552 """Display information on the fastbinsY on an arena (default: main_arena). 

+

6553 See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123.""" 

+

6554 

+

6555 _cmdline_ = "heap bins fast" 

+

6556 _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" 

+

6557 

+

6558 def __init__(self) -> None: 

+

6559 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6560 return 

+

6561 

+

6562 @parse_arguments({"arena_address": ""}, {}) 

+

6563 @only_if_gdb_running 

+

6564 def do_invoke(self, *_: Any, **kwargs: Any) -> None: 

+

6565 def fastbin_index(sz: int) -> int: 

+

6566 return (sz >> 4) - 2 if SIZE_SZ == 8 else (sz >> 3) - 2 

+

6567 

+

6568 args : argparse.Namespace = kwargs["arguments"] 

+

6569 if not gef.heap.main_arena: 6569 ↛ 6570line 6569 didn't jump to line 6570, because the condition on line 6569 was never true

+

6570 err("Heap not initialized") 

+

6571 return 

+

6572 

+

6573 SIZE_SZ = gef.arch.ptrsize 

+

6574 MAX_FAST_SIZE = 80 * SIZE_SZ // 4 

+

6575 NFASTBINS = fastbin_index(MAX_FAST_SIZE) - 1 

+

6576 

+

6577 arena = GlibcArena(f"*{args.arena_address}") if args.arena_address else gef.heap.selected_arena 

+

6578 if arena is None: 6578 ↛ 6579line 6578 didn't jump to line 6579, because the condition on line 6578 was never true

+

6579 err("Invalid Glibc arena") 

+

6580 return 

+

6581 

+

6582 gef_print(titlify(f"Fastbins for arena at {arena.addr:#x}")) 

+

6583 for i in range(NFASTBINS): 

+

6584 gef_print(f"Fastbins[idx={i:d}, size={(i+2)*SIZE_SZ*2:#x}] ", end="") 

+

6585 chunk = arena.fastbin(i) 

+

6586 chunks = set() 

+

6587 

+

6588 while True: 

+

6589 if chunk is None: 

+

6590 gef_print("0x00", end="") 

+

6591 break 

+

6592 

+

6593 try: 

+

6594 gef_print(f"{LEFT_ARROW} {chunk!s} ", end="") 

+

6595 if chunk.data_address in chunks: 6595 ↛ 6596line 6595 didn't jump to line 6596, because the condition on line 6595 was never true

+

6596 gef_print(f"{RIGHT_ARROW} [loop detected]", end="") 

+

6597 break 

+

6598 

+

6599 if fastbin_index(chunk.size) != i: 6599 ↛ 6600line 6599 didn't jump to line 6600, because the condition on line 6599 was never true

+

6600 gef_print("[incorrect fastbin_index] ", end="") 

+

6601 

+

6602 chunks.add(chunk.data_address) 

+

6603 

+

6604 next_chunk = chunk.fd 

+

6605 if next_chunk == 0: 6605 ↛ 6608line 6605 didn't jump to line 6608, because the condition on line 6605 was never false

+

6606 break 

+

6607 

+

6608 chunk = GlibcFastChunk(next_chunk, from_base=True) 

+

6609 except gdb.MemoryError: 

+

6610 gef_print(f"{LEFT_ARROW} [Corrupted chunk at {chunk.data_address:#x}]", end="") 

+

6611 break 

+

6612 gef_print() 

+

6613 return 

+

6614 

+

6615 

+

6616@register 

+

6617class GlibcHeapUnsortedBinsCommand(GenericCommand): 

+

6618 """Display information on the Unsorted Bins of an arena (default: main_arena). 

+

6619 See: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1689.""" 

+

6620 

+

6621 _cmdline_ = "heap bins unsorted" 

+

6622 _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" 

+

6623 

+

6624 def __init__(self) -> None: 

+

6625 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6626 return 

+

6627 

+

6628 @parse_arguments({"arena_address": ""}, {}) 

+

6629 @only_if_gdb_running 

+

6630 def do_invoke(self, *_: Any, **kwargs: Any) -> None: 

+

6631 args : argparse.Namespace = kwargs["arguments"] 

+

6632 if gef.heap.main_arena is None: 6632 ↛ 6633line 6632 didn't jump to line 6633, because the condition on line 6632 was never true

+

6633 err("Heap not initialized") 

+

6634 return 

+

6635 arena_addr = args.arena_address if args.arena_address else f"{gef.heap.selected_arena.addr:#x}" 

+

6636 gef_print(titlify(f"Unsorted Bin for arena at {arena_addr}")) 

+

6637 nb_chunk = GlibcHeapBinsCommand.pprint_bin(f"*{arena_addr}", 0, "unsorted_") 

+

6638 if nb_chunk >= 0: 6638 ↛ 6640line 6638 didn't jump to line 6640, because the condition on line 6638 was never false

+

6639 info(f"Found {nb_chunk:d} chunks in unsorted bin.") 

+

6640 return 

+

6641 

+

6642 

+

6643@register 

+

6644class GlibcHeapSmallBinsCommand(GenericCommand): 

+

6645 """Convenience command for viewing small bins.""" 

+

6646 

+

6647 _cmdline_ = "heap bins small" 

+

6648 _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" 

+

6649 

+

6650 def __init__(self) -> None: 

+

6651 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6652 return 

+

6653 

+

6654 @parse_arguments({"arena_address": ""}, {}) 

+

6655 @only_if_gdb_running 

+

6656 def do_invoke(self, *_: Any, **kwargs: Any) -> None: 

+

6657 args : argparse.Namespace = kwargs["arguments"] 

+

6658 if not gef.heap.main_arena: 6658 ↛ 6659line 6658 didn't jump to line 6659, because the condition on line 6658 was never true

+

6659 err("Heap not initialized") 

+

6660 return 

+

6661 

+

6662 arena_address = args.arena_address or f"{gef.heap.selected_arena.address:#x}" 

+

6663 gef_print(titlify(f"Small Bins for arena at {arena_address}")) 

+

6664 bins = {} 

+

6665 for i in range(1, 63): 

+

6666 nb_chunk = GlibcHeapBinsCommand.pprint_bin(f"*{arena_address}", i, "small_") 

+

6667 if nb_chunk < 0: 6667 ↛ 6668line 6667 didn't jump to line 6668, because the condition on line 6667 was never true

+

6668 break 

+

6669 if nb_chunk > 0: 

+

6670 bins[i] = nb_chunk 

+

6671 info(f"Found {sum(bins.values()):d} chunks in {len(bins):d} small non-empty bins.") 

+

6672 return 

+

6673 

+

6674 

+

6675@register 

+

6676class GlibcHeapLargeBinsCommand(GenericCommand): 

+

6677 """Convenience command for viewing large bins.""" 

+

6678 

+

6679 _cmdline_ = "heap bins large" 

+

6680 _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" 

+

6681 

+

6682 def __init__(self) -> None: 

+

6683 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6684 return 

+

6685 

+

6686 @parse_arguments({"arena_address": ""}, {}) 

+

6687 @only_if_gdb_running 

+

6688 def do_invoke(self, *_: Any, **kwargs: Any) -> None: 

+

6689 args : argparse.Namespace = kwargs["arguments"] 

+

6690 if gef.heap.main_arena is None: 6690 ↛ 6691line 6690 didn't jump to line 6691, because the condition on line 6690 was never true

+

6691 err("Heap not initialized") 

+

6692 return 

+

6693 

+

6694 arena_addr = args.arena_address if args.arena_address else f"{gef.heap.selected_arena.addr:#x}" 

+

6695 gef_print(titlify(f"Large Bins for arena at {arena_addr}")) 

+

6696 bins = {} 

+

6697 for i in range(63, 126): 

+

6698 nb_chunk = GlibcHeapBinsCommand.pprint_bin(f"*{arena_addr}", i, "large_") 

+

6699 if nb_chunk < 0: 6699 ↛ 6700line 6699 didn't jump to line 6700, because the condition on line 6699 was never true

+

6700 break 

+

6701 if nb_chunk > 0: 

+

6702 bins[i] = nb_chunk 

+

6703 info(f"Found {sum(bins.values()):d} chunks in {len(bins):d} large non-empty bins.") 

+

6704 return 

+

6705 

+

6706 

+

6707@register 

+

6708class SolveKernelSymbolCommand(GenericCommand): 

+

6709 """Solve kernel symbols from kallsyms table.""" 

+

6710 

+

6711 _cmdline_ = "ksymaddr" 

+

6712 _syntax_ = f"{_cmdline_} SymbolToSearch" 

+

6713 _example_ = f"{_cmdline_} prepare_creds" 

+

6714 

+

6715 @parse_arguments({"symbol": ""}, {}) 

+

6716 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6717 def hex_to_int(num): 

+

6718 try: 

+

6719 return int(num, 16) 

+

6720 except ValueError: 

+

6721 return 0 

+

6722 args : argparse.Namespace = kwargs["arguments"] 

+

6723 if not args.symbol: 6723 ↛ 6724line 6723 didn't jump to line 6724, because the condition on line 6723 was never true

+

6724 self.usage() 

+

6725 return 

+

6726 sym = args.symbol 

+

6727 with open("/proc/kallsyms", "r") as f: 

+

6728 syms = [line.strip().split(" ", 2) for line in f] 

+

6729 matches = [(hex_to_int(addr), sym_t, " ".join(name.split())) for addr, sym_t, name in syms if sym in name] 

+

6730 for addr, sym_t, name in matches: 

+

6731 if sym == name.split()[0]: 

+

6732 ok(f"Found matching symbol for '{name}' at {addr:#x} (type={sym_t})") 

+

6733 else: 

+

6734 warn(f"Found partial match for '{sym}' at {addr:#x} (type={sym_t}): {name}") 

+

6735 if not matches: 6735 ↛ 6736line 6735 didn't jump to line 6736, because the condition on line 6735 was never true

+

6736 err(f"No match for '{sym}'") 

+

6737 elif matches[0][0] == 0: 6737 ↛ 6739line 6737 didn't jump to line 6739, because the condition on line 6737 was never false

+

6738 err("Check that you have the correct permissions to view kernel symbol addresses") 

+

6739 return 

+

6740 

+

6741 

+

6742@register 

+

6743class DetailRegistersCommand(GenericCommand): 

+

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

+

6745 

+

6746 _cmdline_ = "registers" 

+

6747 _syntax_ = f"{_cmdline_} [[Register1][Register2] ... [RegisterN]]" 

+

6748 _example_ = (f"\n{_cmdline_}" 

+

6749 f"\n{_cmdline_} $eax $eip $esp") 

+

6750 

+

6751 @only_if_gdb_running 

+

6752 @parse_arguments({"registers": [""]}, {}) 

+

6753 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

6754 unchanged_color = gef.config["theme.registers_register_name"] 

+

6755 changed_color = gef.config["theme.registers_value_changed"] 

+

6756 string_color = gef.config["theme.dereference_string"] 

+

6757 regs = gef.arch.all_registers 

+

6758 

+

6759 args : argparse.Namespace = kwargs["arguments"] 

+

6760 if args.registers and args.registers[0]: 

+

6761 required_regs = set(args.registers) 

+

6762 valid_regs = [reg for reg in gef.arch.all_registers if reg in required_regs] 

+

6763 if valid_regs: 6763 ↛ 6765line 6763 didn't jump to line 6765, because the condition on line 6763 was never false

+

6764 regs = valid_regs 

+

6765 invalid_regs = [reg for reg in required_regs if reg not in valid_regs] 

+

6766 if invalid_regs: 6766 ↛ 6767line 6766 didn't jump to line 6767, because the condition on line 6766 was never true

+

6767 err(f"invalid registers for architecture: {', '.join(invalid_regs)}") 

+

6768 

+

6769 memsize = gef.arch.ptrsize 

+

6770 endian = str(gef.arch.endianness) 

+

6771 charset = string.printable 

+

6772 widest = max(map(len, gef.arch.all_registers)) 

+

6773 special_line = "" 

+

6774 

+

6775 for regname in regs: 

+

6776 reg = gdb.parse_and_eval(regname) 

+

6777 if reg.type.code == gdb.TYPE_CODE_VOID: 6777 ↛ 6778line 6777 didn't jump to line 6778, because the condition on line 6777 was never true

+

6778 continue 

+

6779 

+

6780 padreg = regname.ljust(widest, " ") 

+

6781 

+

6782 if str(reg) == "<unavailable>": 6782 ↛ 6783line 6782 didn't jump to line 6783, because the condition on line 6782 was never true

+

6783 gef_print(f"{Color.colorify(padreg, unchanged_color)}: " 

+

6784 f"{Color.colorify('no value', 'yellow underline')}") 

+

6785 continue 

+

6786 

+

6787 value = align_address(int(reg)) 

+

6788 old_value = ContextCommand.old_registers.get(regname, 0) 

+

6789 if value == old_value: 

+

6790 color = unchanged_color 

+

6791 else: 

+

6792 color = changed_color 

+

6793 

+

6794 # Special (e.g. segment) registers go on their own line 

+

6795 if regname in gef.arch.special_registers: 

+

6796 special_line += f"{Color.colorify(regname, color)}: " 

+

6797 special_line += f"{gef.arch.register(regname):#04x} " 

+

6798 continue 

+

6799 

+

6800 line = f"{Color.colorify(padreg, color)}: " 

+

6801 

+

6802 if regname == gef.arch.flag_register: 

+

6803 line += gef.arch.flag_register_to_human() 

+

6804 gef_print(line) 

+

6805 continue 

+

6806 

+

6807 addr = lookup_address(align_address(int(value))) 

+

6808 if addr.valid: 

+

6809 line += str(addr) 

+

6810 else: 

+

6811 line += format_address_spaces(value) 

+

6812 addrs = dereference_from(value) 

+

6813 

+

6814 if len(addrs) > 1: 

+

6815 sep = f" {RIGHT_ARROW} " 

+

6816 line += sep 

+

6817 line += sep.join(addrs[1:]) 

+

6818 

+

6819 # check to see if reg value is ascii 

+

6820 try: 

+

6821 fmt = f"{endian}{'I' if memsize == 4 else 'Q'}" 

+

6822 last_addr = int(addrs[-1], 16) 

+

6823 val = gef_pystring(struct.pack(fmt, last_addr)) 

+

6824 if all([_ in charset for _ in val]): 

+

6825 line += f" (\"{Color.colorify(val, string_color)}\"?)" 

+

6826 except ValueError: 

+

6827 pass 

+

6828 

+

6829 gef_print(line) 

+

6830 

+

6831 if special_line: 6831 ↛ 6833line 6831 didn't jump to line 6833, because the condition on line 6831 was never false

+

6832 gef_print(special_line) 

+

6833 return 

+

6834 

+

6835 

+

6836@register 

+

6837class ShellcodeCommand(GenericCommand): 

+

6838 """ShellcodeCommand uses @JonathanSalwan simple-yet-awesome shellcode API to 

+

6839 download shellcodes.""" 

+

6840 

+

6841 _cmdline_ = "shellcode" 

+

6842 _syntax_ = f"{_cmdline_} (search|get)" 

+

6843 

+

6844 def __init__(self) -> None: 

+

6845 super().__init__(prefix=True) 

+

6846 return 

+

6847 

+

6848 def do_invoke(self, _: List[str]) -> None: 

+

6849 err("Missing sub-command (search|get)") 

+

6850 self.usage() 

+

6851 return 

+

6852 

+

6853 

+

6854@register 

+

6855class ShellcodeSearchCommand(GenericCommand): 

+

6856 """Search pattern in shell-storm's shellcode database.""" 

+

6857 

+

6858 _cmdline_ = "shellcode search" 

+

6859 _syntax_ = f"{_cmdline_} PATTERN1 PATTERN2" 

+

6860 _aliases_ = ["sc-search",] 

+

6861 

+

6862 api_base = "http://shell-storm.org" 

+

6863 search_url = f"{api_base}/api/?s=" 

+

6864 

+

6865 def do_invoke(self, argv: List[str]) -> None: 

+

6866 if not argv: 6866 ↛ 6867line 6866 didn't jump to line 6867, because the condition on line 6866 was never true

+

6867 err("Missing pattern to search") 

+

6868 self.usage() 

+

6869 return 

+

6870 

+

6871 self.search_shellcode(argv) 

+

6872 return 

+

6873 

+

6874 def search_shellcode(self, search_options: List) -> None: 

+

6875 # API : http://shell-storm.org/shellcode/ 

+

6876 args = "*".join(search_options) 

+

6877 

+

6878 res = http_get(self.search_url + args) 

+

6879 if res is None: 6879 ↛ 6880line 6879 didn't jump to line 6880, because the condition on line 6879 was never true

+

6880 err("Could not query search page") 

+

6881 return 

+

6882 

+

6883 ret = gef_pystring(res) 

+

6884 

+

6885 # format: [author, OS/arch, cmd, id, link] 

+

6886 lines = ret.split("\\n") 

+

6887 refs = [line.split("::::") for line in lines] 

+

6888 

+

6889 if refs: 6889 ↛ 6900line 6889 didn't jump to line 6900, because the condition on line 6889 was never false

+

6890 info("Showing matching shellcodes") 

+

6891 info("\t".join(["Id", "Platform", "Description"])) 

+

6892 for ref in refs: 

+

6893 try: 

+

6894 _, arch, cmd, sid, _ = ref 

+

6895 gef_print("\t".join([sid, arch, cmd])) 

+

6896 except ValueError: 

+

6897 continue 

+

6898 

+

6899 info("Use `shellcode get <id>` to fetch shellcode") 

+

6900 return 

+

6901 

+

6902 

+

6903@register 

+

6904class ShellcodeGetCommand(GenericCommand): 

+

6905 """Download shellcode from shell-storm's shellcode database.""" 

+

6906 

+

6907 _cmdline_ = "shellcode get" 

+

6908 _syntax_ = f"{_cmdline_} SHELLCODE_ID" 

+

6909 _aliases_ = ["sc-get",] 

+

6910 

+

6911 api_base = "http://shell-storm.org" 

+

6912 get_url = f"{api_base}/shellcode/files/shellcode-{{:d}}.html" 

+

6913 

+

6914 def do_invoke(self, argv: List[str]) -> None: 

+

6915 if len(argv) != 1: 6915 ↛ 6916line 6915 didn't jump to line 6916, because the condition on line 6915 was never true

+

6916 err("Missing ID to download") 

+

6917 self.usage() 

+

6918 return 

+

6919 

+

6920 if not argv[0].isdigit(): 6920 ↛ 6921line 6920 didn't jump to line 6921, because the condition on line 6920 was never true

+

6921 err("ID is not a number") 

+

6922 self.usage() 

+

6923 return 

+

6924 

+

6925 self.get_shellcode(int(argv[0])) 

+

6926 return 

+

6927 

+

6928 def get_shellcode(self, sid: int) -> None: 

+

6929 info(f"Downloading shellcode id={sid}") 

+

6930 res = http_get(self.get_url.format(sid)) 

+

6931 if res is None: 

+

6932 err(f"Failed to fetch shellcode #{sid}") 

+

6933 return 

+

6934 

+

6935 ok("Downloaded, written to disk...") 

+

6936 with tempfile.NamedTemporaryFile(prefix="sc-", suffix=".txt", mode='w+b', delete=False, dir=gef.config["gef.tempdir"]) as fd: 

+

6937 shellcode = res.split(b"<pre>")[1].split(b"</pre>")[0] 

+

6938 shellcode = shellcode.replace(b"&quot;", b'"') 

+

6939 fd.write(shellcode) 

+

6940 ok(f"Shellcode written to '{fd.name}'") 

+

6941 return 

+

6942 

+

6943 

+

6944@register 

+

6945class ProcessListingCommand(GenericCommand): 

+

6946 """List and filter process. If a PATTERN is given as argument, results shown will be grepped 

+

6947 by this pattern.""" 

+

6948 

+

6949 _cmdline_ = "process-search" 

+

6950 _syntax_ = f"{_cmdline_} [-h] [--attach] [--smart-scan] [REGEX_PATTERN]" 

+

6951 _aliases_ = ["ps"] 

+

6952 _example_ = f"{_cmdline_} gdb.*" 

+

6953 

+

6954 def __init__(self) -> None: 

+

6955 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

6956 self["ps_command"] = (f"{gef.session.constants['ps']} auxww", "`ps` command to get process information") 

+

6957 return 

+

6958 

+

6959 @parse_arguments({"pattern": ""}, {"--attach": True, "--smart-scan": True}) 

+

6960 def do_invoke(self, _: List, **kwargs: Any) -> None: 

+

6961 args : argparse.Namespace = kwargs["arguments"] 

+

6962 do_attach = args.attach 

+

6963 smart_scan = args.smart_scan 

+

6964 pattern = args.pattern 

+

6965 pattern = re.compile("^.*$") if not args else re.compile(pattern) 

+

6966 

+

6967 for process in self.get_processes(): 

+

6968 pid = int(process["pid"]) 

+

6969 command = process["command"] 

+

6970 

+

6971 if not re.search(pattern, command): 

+

6972 continue 

+

6973 

+

6974 if smart_scan: 

+

6975 if command.startswith("[") and command.endswith("]"): continue 6975 ↛ 6967line 6975 didn't jump to line 6967, because the continue on line 6975 wasn't executed

+

6976 if command.startswith("socat "): continue 6976 ↛ 6967line 6976 didn't jump to line 6967, because the continue on line 6976 wasn't executed

+

6977 if command.startswith("grep "): continue 6977 ↛ 6967line 6977 didn't jump to line 6967, because the continue on line 6977 wasn't executed

+

6978 if command.startswith("gdb "): continue 6978 ↛ 6980line 6978 didn't jump to line 6980, because the condition on line 6978 was never false

+

6979 

+

6980 if args and do_attach: 6980 ↛ 6981line 6980 didn't jump to line 6981, because the condition on line 6980 was never true

+

6981 ok(f"Attaching to process='{process['command']}' pid={pid:d}") 

+

6982 gdb.execute(f"attach {pid:d}") 

+

6983 return None 

+

6984 

+

6985 line = [process[i] for i in ("pid", "user", "cpu", "mem", "tty", "command")] 

+

6986 gef_print("\t\t".join(line)) 

+

6987 

+

6988 return None 

+

6989 

+

6990 def get_processes(self) -> Generator[Dict[str, str], None, None]: 

+

6991 output = gef_execute_external(self["ps_command"].split(), True) 

+

6992 names = [x.lower().replace("%", "") for x in output[0].split()] 

+

6993 

+

6994 for line in output[1:]: 

+

6995 fields = line.split() 

+

6996 t = {} 

+

6997 

+

6998 for i, name in enumerate(names): 

+

6999 if i == len(names) - 1: 

+

7000 t[name] = " ".join(fields[i:]) 

+

7001 else: 

+

7002 t[name] = fields[i] 

+

7003 

+

7004 yield t 

+

7005 

+

7006 return 

+

7007 

+

7008 

+

7009@register 

+

7010class ElfInfoCommand(GenericCommand): 

+

7011 """Display a limited subset of ELF header information. If no argument is provided, the command will 

+

7012 show information about the current ELF being debugged.""" 

+

7013 

+

7014 _cmdline_ = "elf-info" 

+

7015 _syntax_ = f"{_cmdline_} [FILE]" 

+

7016 _example_ = f"{_cmdline_} /bin/ls" 

+

7017 

+

7018 def __init__(self) -> None: 

+

7019 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

7020 return 

+

7021 

+

7022 @parse_arguments({}, {"--filename": ""}) 

+

7023 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

7024 args : argparse.Namespace = kwargs["arguments"] 

+

7025 

+

7026 if is_qemu_system(): 7026 ↛ 7027line 7026 didn't jump to line 7027, because the condition on line 7026 was never true

+

7027 err("Unsupported") 

+

7028 return 

+

7029 

+

7030 filename = args.filename or get_filepath() 

+

7031 if filename is None: 7031 ↛ 7032line 7031 didn't jump to line 7032, because the condition on line 7031 was never true

+

7032 return 

+

7033 

+

7034 try: 

+

7035 elf = Elf(filename) 

+

7036 except ValueError as ve: 

+

7037 err(f"`{filename}` is an invalid value for ELF file") 

+

7038 return 

+

7039 

+

7040 data = [ 

+

7041 ("Magic", f"{hexdump(struct.pack('>I', elf.e_magic), show_raw=True)}"), 

+

7042 ("Class", f"{elf.e_class.value:#x} - {elf.e_class.name}"), 

+

7043 ("Endianness", f"{elf.e_endianness.value:#x} - {Endianness(elf.e_endianness).name}"), 

+

7044 ("Version", f"{elf.e_eiversion:#x}"), 

+

7045 ("OS ABI", f"{elf.e_osabi.value:#x} - {elf.e_osabi.name if elf.e_osabi else ''}"), 

+

7046 ("ABI Version", f"{elf.e_abiversion:#x}"), 

+

7047 ("Type", f"{elf.e_type.value:#x} - {elf.e_type.name}"), 

+

7048 ("Machine", f"{elf.e_machine.value:#x} - {elf.e_machine.name}"), 

+

7049 ("Program Header Table", f"{format_address(elf.e_phoff)}"), 

+

7050 ("Section Header Table", f"{format_address(elf.e_shoff)}"), 

+

7051 ("Header Table", f"{format_address(elf.e_phoff)}"), 

+

7052 ("ELF Version", f"{elf.e_version:#x}"), 

+

7053 ("Header size", "{0} ({0:#x})".format(elf.e_ehsize)), 

+

7054 ("Entry point", f"{format_address(elf.e_entry)}"), 

+

7055 ] 

+

7056 

+

7057 for title, content in data: 

+

7058 gef_print(f"{Color.boldify(f'{title:<22}')}: {content}") 

+

7059 

+

7060 gef_print("") 

+

7061 gef_print(titlify("Program Header")) 

+

7062 

+

7063 gef_print(" [{:>2s}] {:12s} {:>8s} {:>10s} {:>10s} {:>8s} {:>8s} {:5s} {:>8s}".format( 

+

7064 "#", "Type", "Offset", "Virtaddr", "Physaddr", "FileSiz", "MemSiz", "Flags", "Align")) 

+

7065 

+

7066 for i, p in enumerate(elf.phdrs): 

+

7067 p_type = p.p_type.name if p.p_type else "" 

+

7068 p_flags = str(p.p_flags.name).lstrip("Flag.") if p.p_flags else "???" 

+

7069 

+

7070 gef_print(" [{:2d}] {:12s} {:#8x} {:#10x} {:#10x} {:#8x} {:#8x} {:5s} {:#8x}".format( 

+

7071 i, p_type, p.p_offset, p.p_vaddr, p.p_paddr, p.p_filesz, p.p_memsz, p_flags, p.p_align)) 

+

7072 

+

7073 gef_print("") 

+

7074 gef_print(titlify("Section Header")) 

+

7075 gef_print(" [{:>2s}] {:20s} {:>15s} {:>10s} {:>8s} {:>8s} {:>8s} {:5s} {:4s} {:4s} {:>8s}".format( 

+

7076 "#", "Name", "Type", "Address", "Offset", "Size", "EntSiz", "Flags", "Link", "Info", "Align")) 

+

7077 

+

7078 for i, s in enumerate(elf.shdrs): 

+

7079 sh_type = s.sh_type.name if s.sh_type else "UNKN" 

+

7080 sh_flags = str(s.sh_flags).lstrip("Flags.") if s.sh_flags else "UNKN" 

+

7081 

+

7082 gef_print(f" [{i:2d}] {s.name:20s} {sh_type:>15s} {s.sh_addr:#10x} {s.sh_offset:#8x} " 

+

7083 f"{s.sh_size:#8x} {s.sh_entsize:#8x} {sh_flags:5s} {s.sh_link:#4x} {s.sh_info:#4x} {s.sh_addralign:#8x}") 

+

7084 return 

+

7085 

+

7086 

+

7087@register 

+

7088class EntryPointBreakCommand(GenericCommand): 

+

7089 """Tries to find best entry point and sets a temporary breakpoint on it. The command will test for 

+

7090 well-known symbols for entry points, such as `main`, `_main`, `__libc_start_main`, etc. defined by 

+

7091 the setting `entrypoint_symbols`.""" 

+

7092 

+

7093 _cmdline_ = "entry-break" 

+

7094 _syntax_ = _cmdline_ 

+

7095 _aliases_ = ["start",] 

+

7096 

+

7097 def __init__(self) -> None: 

+

7098 super().__init__() 

+

7099 self["entrypoint_symbols"] = ("main _main __libc_start_main __uClibc_main start _start", "Possible symbols for entry points") 

+

7100 return 

+

7101 

+

7102 def do_invoke(self, argv: List[str]) -> None: 

+

7103 fpath = get_filepath() 

+

7104 if fpath is None: 7104 ↛ 7105line 7104 didn't jump to line 7105, because the condition on line 7104 was never true

+

7105 warn("No executable to debug, use `file` to load a binary") 

+

7106 return 

+

7107 

+

7108 if not os.access(fpath, os.X_OK): 7108 ↛ 7109line 7108 didn't jump to line 7109, because the condition on line 7108 was never true

+

7109 warn(f"The file '{fpath}' is not executable.") 

+

7110 return 

+

7111 

+

7112 if is_alive() and not gef.session.qemu_mode: 

+

7113 warn("gdb is already running") 

+

7114 return 

+

7115 

+

7116 bp = None 

+

7117 entrypoints = self["entrypoint_symbols"].split() 

+

7118 

+

7119 for sym in entrypoints: 7119 ↛ 7135line 7119 didn't jump to line 7135, because the loop on line 7119 didn't complete

+

7120 try: 

+

7121 value = parse_address(sym) 

+

7122 info(f"Breaking at '{value:#x}'") 

+

7123 bp = EntryBreakBreakpoint(sym) 

+

7124 gdb.execute(f"run {' '.join(argv)}") 

+

7125 return 

+

7126 

+

7127 except gdb.error as gdb_error: 

+

7128 if 'The "remote" target does not support "run".' in str(gdb_error): 

+

7129 # this case can happen when doing remote debugging 

+

7130 gdb.execute("continue") 

+

7131 return 

+

7132 continue 

+

7133 

+

7134 # if here, clear the breakpoint if any set 

+

7135 if bp: 

+

7136 bp.delete() 

+

7137 

+

7138 # break at entry point 

+

7139 entry = gef.binary.entry_point 

+

7140 

+

7141 if is_pie(fpath): 

+

7142 self.set_init_tbreak_pie(entry, argv) 

+

7143 gdb.execute("continue") 

+

7144 return 

+

7145 

+

7146 self.set_init_tbreak(entry) 

+

7147 gdb.execute(f"run {' '.join(argv)}") 

+

7148 return 

+

7149 

+

7150 def set_init_tbreak(self, addr: int) -> EntryBreakBreakpoint: 

+

7151 info(f"Breaking at entry-point: {addr:#x}") 

+

7152 bp = EntryBreakBreakpoint(f"*{addr:#x}") 

+

7153 return bp 

+

7154 

+

7155 def set_init_tbreak_pie(self, addr: int, argv: List[str]) -> EntryBreakBreakpoint: 

+

7156 warn("PIC binary detected, retrieving text base address") 

+

7157 gdb.execute("set stop-on-solib-events 1") 

+

7158 hide_context() 

+

7159 gdb.execute(f"run {' '.join(argv)}") 

+

7160 unhide_context() 

+

7161 gdb.execute("set stop-on-solib-events 0") 

+

7162 vmmap = gef.memory.maps 

+

7163 base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] 

+

7164 return self.set_init_tbreak(base_address + addr) 

+

7165 

+

7166 

+

7167@register 

+

7168class NamedBreakpointCommand(GenericCommand): 

+

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

+

7170 

+

7171 _cmdline_ = "name-break" 

+

7172 _syntax_ = f"{_cmdline_} name [address]" 

+

7173 _aliases_ = ["nb",] 

+

7174 _example = f"{_cmdline_} main *0x4008a9" 

+

7175 

+

7176 def __init__(self) -> None: 

+

7177 super().__init__() 

+

7178 return 

+

7179 

+

7180 @parse_arguments({"name": "", "address": "*$pc"}, {}) 

+

7181 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

7182 args : argparse.Namespace = kwargs["arguments"] 

+

7183 if not args.name: 7183 ↛ 7184line 7183 didn't jump to line 7184, because the condition on line 7183 was never true

+

7184 err("Missing name for breakpoint") 

+

7185 self.usage() 

+

7186 return 

+

7187 

+

7188 NamedBreakpoint(args.address, args.name) 

+

7189 return 

+

7190 

+

7191 

+

7192@register 

+

7193class ContextCommand(GenericCommand): 

+

7194 """Displays a comprehensive and modular summary of runtime context. Unless setting `enable` is 

+

7195 set to False, this command will be spawned automatically every time GDB hits a breakpoint, a 

+

7196 watchpoint, or any kind of interrupt. By default, it will show panes that contain the register 

+

7197 states, the stack, and the disassembly code around $pc.""" 

+

7198 

+

7199 _cmdline_ = "context" 

+

7200 _syntax_ = f"{_cmdline_} [legend|regs|stack|code|args|memory|source|trace|threads|extra]" 

+

7201 _aliases_ = ["ctx",] 

+

7202 

+

7203 old_registers: Dict[str, Optional[int]] = {} 

+

7204 

+

7205 def __init__(self) -> None: 

+

7206 super().__init__() 

+

7207 self["enable"] = (True, "Enable/disable printing the context when breaking") 

+

7208 self["show_source_code_variable_values"] = (True, "Show extra PC context info in the source code") 

+

7209 self["show_stack_raw"] = (False, "Show the stack pane as raw hexdump (no dereference)") 

+

7210 self["show_registers_raw"] = (False, "Show the registers pane with raw values (no dereference)") 

+

7211 self["show_opcodes_size"] = (0, "Number of bytes of opcodes to display next to the disassembly") 

+

7212 self["peek_calls"] = (True, "Peek into calls") 

+

7213 self["peek_ret"] = (True, "Peek at return address") 

+

7214 self["nb_lines_stack"] = (8, "Number of line in the stack pane") 

+

7215 self["grow_stack_down"] = (False, "Order of stack downward starts at largest down to stack pointer") 

+

7216 self["nb_lines_backtrace"] = (10, "Number of line in the backtrace pane") 

+

7217 self["nb_lines_backtrace_before"] = (2, "Number of line in the backtrace pane before selected frame") 

+

7218 self["nb_lines_threads"] = (-1, "Number of line in the threads pane") 

+

7219 self["nb_lines_code"] = (6, "Number of instruction after $pc") 

+

7220 self["nb_lines_code_prev"] = (3, "Number of instruction before $pc") 

+

7221 self["ignore_registers"] = ("", "Space-separated list of registers not to display (e.g. '$cs $ds $gs')") 

+

7222 self["clear_screen"] = (True, "Clear the screen before printing the context") 

+

7223 self["layout"] = ("legend regs stack code args source memory threads trace extra", "Change the order/presence of the context sections") 

+

7224 self["redirect"] = ("", "Redirect the context information to another TTY") 

+

7225 self["libc_args"] = (False, "[DEPRECATED - Unused] Show libc function call args description") 

+

7226 self["libc_args_path"] = ("", "[DEPRECATED - Unused] Path to libc function call args json files, provided via gef-extras") 

+

7227 

+

7228 self.layout_mapping = { 

+

7229 "legend": (self.show_legend, None, None), 

+

7230 "regs": (self.context_regs, None, None), 

+

7231 "stack": (self.context_stack, None, None), 

+

7232 "code": (self.context_code, None, None), 

+

7233 "args": (self.context_args, None, None), 

+

7234 "memory": (self.context_memory, None, None), 

+

7235 "source": (self.context_source, None, None), 

+

7236 "trace": (self.context_trace, None, None), 

+

7237 "threads": (self.context_threads, None, None), 

+

7238 "extra": (self.context_additional_information, None, None), 

+

7239 } 

+

7240 

+

7241 self.instruction_iterator = gef_disassemble 

+

7242 return 

+

7243 

+

7244 def post_load(self) -> None: 

+

7245 gef_on_continue_hook(self.update_registers) 

+

7246 gef_on_continue_hook(self.empty_extra_messages) 

+

7247 return 

+

7248 

+

7249 def show_legend(self) -> None: 

+

7250 if gef.config["gef.disable_color"] is True: 7250 ↛ 7251line 7250 didn't jump to line 7251, because the condition on line 7250 was never true

+

7251 return 

+

7252 str_color = gef.config["theme.dereference_string"] 

+

7253 code_addr_color = gef.config["theme.address_code"] 

+

7254 stack_addr_color = gef.config["theme.address_stack"] 

+

7255 heap_addr_color = gef.config["theme.address_heap"] 

+

7256 changed_register_color = gef.config["theme.registers_value_changed"] 

+

7257 

+

7258 gef_print("[ Legend: {} | {} | {} | {} | {} ]".format(Color.colorify("Modified register", changed_register_color), 

+

7259 Color.colorify("Code", code_addr_color), 

+

7260 Color.colorify("Heap", heap_addr_color), 

+

7261 Color.colorify("Stack", stack_addr_color), 

+

7262 Color.colorify("String", str_color))) 

+

7263 return 

+

7264 

+

7265 @only_if_gdb_running 

+

7266 def do_invoke(self, argv: List[str]) -> None: 

+

7267 if not self["enable"] or gef.ui.context_hidden: 

+

7268 return 

+

7269 

+

7270 if not all(_ in self.layout_mapping for _ in argv): 7270 ↛ 7271line 7270 didn't jump to line 7271, because the condition on line 7270 was never true

+

7271 self.usage() 

+

7272 return 

+

7273 

+

7274 if len(argv) > 0: 7274 ↛ 7275line 7274 didn't jump to line 7275, because the condition on line 7274 was never true

+

7275 current_layout = argv 

+

7276 else: 

+

7277 current_layout = self["layout"].strip().split() 

+

7278 

+

7279 if not current_layout: 7279 ↛ 7280line 7279 didn't jump to line 7280, because the condition on line 7279 was never true

+

7280 return 

+

7281 

+

7282 self.tty_rows, self.tty_columns = get_terminal_size() 

+

7283 

+

7284 redirect = self["redirect"] 

+

7285 if redirect and os.access(redirect, os.W_OK): 7285 ↛ 7286line 7285 didn't jump to line 7286, because the condition on line 7285 was never true

+

7286 enable_redirect_output(to_file=redirect) 

+

7287 

+

7288 for section in current_layout: 

+

7289 if section[0] == "-": 

+

7290 continue 

+

7291 

+

7292 try: 

+

7293 display_pane_function, pane_title_function, condition = self.layout_mapping[section] 

+

7294 if condition: 7294 ↛ 7295line 7294 didn't jump to line 7295, because the condition on line 7294 was never true

+

7295 if not condition(): 

+

7296 continue 

+

7297 if pane_title_function: 7297 ↛ 7298line 7297 didn't jump to line 7298, because the condition on line 7297 was never true

+

7298 self.context_title(pane_title_function()) 

+

7299 display_pane_function() 

+

7300 except gdb.MemoryError as e: 

+

7301 # a MemoryError will happen when $pc is corrupted (invalid address) 

+

7302 err(str(e)) 

+

7303 except IndexError: 

+

7304 # the `section` is not present, just skip 

+

7305 pass 

+

7306 

+

7307 self.context_title("") 

+

7308 

+

7309 if self["clear_screen"] and len(argv) == 0: 

+

7310 clear_screen(redirect) 

+

7311 

+

7312 if redirect and os.access(redirect, os.W_OK): 7312 ↛ 7313line 7312 didn't jump to line 7313, because the condition on line 7312 was never true

+

7313 disable_redirect_output() 

+

7314 return 

+

7315 

+

7316 def context_title(self, m: Optional[str]) -> None: 

+

7317 # allow for not displaying a title line 

+

7318 if m is None: 7318 ↛ 7319line 7318 didn't jump to line 7319, because the condition on line 7318 was never true

+

7319 return 

+

7320 

+

7321 line_color = gef.config["theme.context_title_line"] 

+

7322 msg_color = gef.config["theme.context_title_message"] 

+

7323 

+

7324 # print an empty line in case of "" 

+

7325 if not m: 

+

7326 gef_print(Color.colorify(HORIZONTAL_LINE * self.tty_columns, line_color)) 

+

7327 return 

+

7328 

+

7329 trail_len = len(m) + 6 

+

7330 title = "" 

+

7331 title += Color.colorify("{:{padd}<{width}} ".format("", 

+

7332 width=max(self.tty_columns - trail_len, 0), 

+

7333 padd=HORIZONTAL_LINE), 

+

7334 line_color) 

+

7335 title += Color.colorify(m, msg_color) 

+

7336 title += Color.colorify(" {:{padd}<4}".format("", padd=HORIZONTAL_LINE), 

+

7337 line_color) 

+

7338 gef_print(title) 

+

7339 return 

+

7340 

+

7341 def context_regs(self) -> None: 

+

7342 self.context_title("registers") 

+

7343 ignored_registers = set(self["ignore_registers"].split()) 

+

7344 

+

7345 if self["show_registers_raw"] is False: 7345 ↛ 7351line 7345 didn't jump to line 7351, because the condition on line 7345 was never false

+

7346 regs = set(gef.arch.all_registers) 

+

7347 printable_registers = " ".join(list(regs - ignored_registers)) 

+

7348 gdb.execute(f"registers {printable_registers}") 

+

7349 return 

+

7350 

+

7351 widest = l = max(map(len, gef.arch.all_registers)) 

+

7352 l += 5 

+

7353 l += gef.arch.ptrsize * 2 

+

7354 nb = get_terminal_size()[1] // l 

+

7355 i = 1 

+

7356 line = "" 

+

7357 changed_color = gef.config["theme.registers_value_changed"] 

+

7358 regname_color = gef.config["theme.registers_register_name"] 

+

7359 

+

7360 for reg in gef.arch.all_registers: 

+

7361 if reg in ignored_registers: 

+

7362 continue 

+

7363 

+

7364 try: 

+

7365 r = gdb.parse_and_eval(reg) 

+

7366 if r.type.code == gdb.TYPE_CODE_VOID: 

+

7367 continue 

+

7368 

+

7369 new_value_type_flag = r.type.code == gdb.TYPE_CODE_FLAGS 

+

7370 new_value = int(r) 

+

7371 

+

7372 except (gdb.MemoryError, gdb.error): 

+

7373 # If this exception is triggered, it means that the current register 

+

7374 # is corrupted. Just use the register "raw" value (not eval-ed) 

+

7375 new_value = gef.arch.register(reg) 

+

7376 new_value_type_flag = False 

+

7377 

+

7378 except Exception: 

+

7379 new_value = 0 

+

7380 new_value_type_flag = False 

+

7381 

+

7382 old_value = self.old_registers.get(reg, 0) 

+

7383 

+

7384 padreg = reg.ljust(widest, " ") 

+

7385 value = align_address(new_value) 

+

7386 old_value = align_address(old_value or 0) 

+

7387 if value == old_value: 

+

7388 line += f"{Color.colorify(padreg, regname_color)}: " 

+

7389 else: 

+

7390 line += f"{Color.colorify(padreg, changed_color)}: " 

+

7391 if new_value_type_flag: 

+

7392 line += f"{format_address_spaces(value)} " 

+

7393 else: 

+

7394 addr = lookup_address(align_address(int(value))) 

+

7395 if addr.valid: 

+

7396 line += f"{addr!s} " 

+

7397 else: 

+

7398 line += f"{format_address_spaces(value)} " 

+

7399 

+

7400 if i % nb == 0: 

+

7401 gef_print(line) 

+

7402 line = "" 

+

7403 i += 1 

+

7404 

+

7405 if line: 

+

7406 gef_print(line) 

+

7407 

+

7408 gef_print(f"Flags: {gef.arch.flag_register_to_human()}") 

+

7409 return 

+

7410 

+

7411 def context_stack(self) -> None: 

+

7412 self.context_title("stack") 

+

7413 

+

7414 show_raw = self["show_stack_raw"] 

+

7415 nb_lines = self["nb_lines_stack"] 

+

7416 

+

7417 try: 

+

7418 sp = gef.arch.sp 

+

7419 if show_raw is True: 7419 ↛ 7420line 7419 didn't jump to line 7420, because the condition on line 7419 was never true

+

7420 mem = gef.memory.read(sp, 0x10 * nb_lines) 

+

7421 gef_print(hexdump(mem, base=sp)) 

+

7422 else: 

+

7423 gdb.execute(f"dereference -l {nb_lines:d} {sp:#x}") 

+

7424 

+

7425 except gdb.MemoryError: 

+

7426 err("Cannot read memory from $SP (corrupted stack pointer?)") 

+

7427 

+

7428 return 

+

7429 

+

7430 def addr_has_breakpoint(self, address: int, bp_locations: List[str]) -> bool: 

+

7431 return any(hex(address) in b for b in bp_locations) 

+

7432 

+

7433 def context_code(self) -> None: 

+

7434 nb_insn = self["nb_lines_code"] 

+

7435 nb_insn_prev = self["nb_lines_code_prev"] 

+

7436 show_opcodes_size = "show_opcodes_size" in self and self["show_opcodes_size"] 

+

7437 past_insns_color = gef.config["theme.old_context"] 

+

7438 cur_insn_color = gef.config["theme.disassemble_current_instruction"] 

+

7439 pc = gef.arch.pc 

+

7440 breakpoints = gdb.breakpoints() or [] 

+

7441 bp_locations = [b.location for b in breakpoints if b.location and b.location.startswith("*")] 

+

7442 

+

7443 frame = gdb.selected_frame() 

+

7444 arch_name = f"{gef.arch.arch.lower()}:{gef.arch.mode}" 

+

7445 

+

7446 self.context_title(f"code:{arch_name}") 

+

7447 

+

7448 try: 

+

7449 

+

7450 

+

7451 for insn in self.instruction_iterator(pc, nb_insn, nb_prev=nb_insn_prev): 

+

7452 line = [] 

+

7453 is_taken = False 

+

7454 target = None 

+

7455 bp_prefix = Color.redify(BP_GLYPH) if self.addr_has_breakpoint(insn.address, bp_locations) else " " 

+

7456 

+

7457 if show_opcodes_size == 0: 

+

7458 text = str(insn) 

+

7459 else: 

+

7460 insn_fmt = f"{{:{show_opcodes_size}o}}" 

+

7461 text = insn_fmt.format(insn) 

+

7462 

+

7463 if insn.address < pc: 

+

7464 line += f"{bp_prefix} {Color.colorify(text, past_insns_color)}" 

+

7465 

+

7466 elif insn.address == pc: 

+

7467 line += f"{bp_prefix}{Color.colorify(f'{RIGHT_ARROW[1:]}{text}', cur_insn_color)}" 

+

7468 

+

7469 if gef.arch.is_conditional_branch(insn): 7469 ↛ 7470line 7469 didn't jump to line 7470, because the condition on line 7469 was never true

+

7470 is_taken, reason = gef.arch.is_branch_taken(insn) 

+

7471 if is_taken: 

+

7472 target = insn.operands[-1].split()[0] 

+

7473 reason = f"[Reason: {reason}]" if reason else "" 

+

7474 line += Color.colorify(f"\tTAKEN {reason}", "bold green") 

+

7475 else: 

+

7476 reason = f"[Reason: !({reason})]" if reason else "" 

+

7477 line += Color.colorify(f"\tNOT taken {reason}", "bold red") 

+

7478 elif gef.arch.is_call(insn) and self["peek_calls"] is True: 7478 ↛ 7479line 7478 didn't jump to line 7479, because the condition on line 7478 was never true

+

7479 target = insn.operands[-1].split()[0] 

+

7480 elif gef.arch.is_ret(insn) and self["peek_ret"] is True: 

+

7481 target = gef.arch.get_ra(insn, frame) 

+

7482 

+

7483 else: 

+

7484 line += f"{bp_prefix} {text}" 

+

7485 

+

7486 gef_print("".join(line)) 

+

7487 

+

7488 if target: 

+

7489 try: 

+

7490 address = int(target, 0) if isinstance(target, str) else target 

+

7491 except ValueError: 

+

7492 # If the operand isn't an address right now we can't parse it 

+

7493 continue 

+

7494 for i, tinsn in enumerate(self.instruction_iterator(address, nb_insn)): 7494 ↛ 7495,   7494 ↛ 74972 missed branches: 1) line 7494 didn't jump to line 7495, because the loop on line 7494 never started, 2) line 7494 didn't jump to line 7497, because the loop on line 7494 didn't complete

+

7495 text= f" {DOWN_ARROW if i == 0 else ' '} {tinsn!s}" 

+

7496 gef_print(text) 

+

7497 break 

+

7498 

+

7499 except gdb.MemoryError: 

+

7500 err("Cannot disassemble from $PC") 

+

7501 return 

+

7502 

+

7503 def context_args(self) -> None: 

+

7504 insn = gef_current_instruction(gef.arch.pc) 

+

7505 if not gef.arch.is_call(insn): 7505 ↛ 7508line 7505 didn't jump to line 7508

+

7506 return 

+

7507 

+

7508 self.size2type = { 

+

7509 1: "BYTE", 

+

7510 2: "WORD", 

+

7511 4: "DWORD", 

+

7512 8: "QWORD", 

+

7513 } 

+

7514 

+

7515 if insn.operands[-1].startswith(self.size2type[gef.arch.ptrsize]+" PTR"): 

+

7516 target = "*" + insn.operands[-1].split()[-1] 

+

7517 elif "$"+insn.operands[0] in gef.arch.all_registers: 

+

7518 target = f"*{gef.arch.register('$' + insn.operands[0]):#x}" 

+

7519 else: 

+

7520 # is there a symbol? 

+

7521 ops = " ".join(insn.operands) 

+

7522 if "<" in ops and ">" in ops: 

+

7523 # extract it 

+

7524 target = re.sub(r".*<([^\(> ]*).*", r"\1", ops) 

+

7525 else: 

+

7526 # it's an address, just use as is 

+

7527 target = re.sub(r".*(0x[a-fA-F0-9]*).*", r"\1", ops) 

+

7528 

+

7529 sym = gdb.lookup_global_symbol(target) 

+

7530 if sym is None: 

+

7531 self.print_guessed_arguments(target) 

+

7532 return 

+

7533 

+

7534 if sym.type.code != gdb.TYPE_CODE_FUNC: 

+

7535 err(f"Symbol '{target}' is not a function: type={sym.type.code}") 

+

7536 return 

+

7537 

+

7538 self.print_arguments_from_symbol(target, sym) 

+

7539 return 

+

7540 

+

7541 def print_arguments_from_symbol(self, function_name: str, symbol: "gdb.Symbol") -> None: 

+

7542 """If symbols were found, parse them and print the argument adequately.""" 

+

7543 args = [] 

+

7544 

+

7545 for i, f in enumerate(symbol.type.fields()): 

+

7546 _value = gef.arch.get_ith_parameter(i, in_func=False)[1] 

+

7547 _value = RIGHT_ARROW.join(dereference_from(_value)) 

+

7548 _name = f.name or f"var_{i}" 

+

7549 _type = f.type.name or self.size2type[f.type.sizeof] 

+

7550 args.append(f"{_type} {_name} = {_value}") 

+

7551 

+

7552 self.context_title("arguments") 

+

7553 

+

7554 if not args: 

+

7555 gef_print(f"{function_name} (<void>)") 

+

7556 return 

+

7557 

+

7558 gef_print(f"{function_name} (\n "+",\n ".join(args)+"\n)") 

+

7559 return 

+

7560 

+

7561 def print_guessed_arguments(self, function_name: str) -> None: 

+

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

+

7563 

+

7564 def __get_current_block_start_address() -> Optional[int]: 

+

7565 pc = gef.arch.pc 

+

7566 try: 

+

7567 block = gdb.block_for_pc(pc) 

+

7568 block_start = block.start if block else gdb_get_nth_previous_instruction_address(pc, 5) 

+

7569 except RuntimeError: 

+

7570 block_start = gdb_get_nth_previous_instruction_address(pc, 5) 

+

7571 return block_start 

+

7572 

+

7573 parameter_set = set() 

+

7574 pc = gef.arch.pc 

+

7575 block_start = __get_current_block_start_address() 

+

7576 if not block_start: 

+

7577 return 

+

7578 

+

7579 function_parameters = gef.arch.function_parameters 

+

7580 arg_key_color = gef.config["theme.registers_register_name"] 

+

7581 

+

7582 for insn in self.instruction_iterator(block_start, pc - block_start): 

+

7583 if not insn.operands: 

+

7584 continue 

+

7585 

+

7586 if is_x86_32(): 

+

7587 if insn.mnemonic == "push": 

+

7588 parameter_set.add(insn.operands[0]) 

+

7589 else: 

+

7590 op = "$" + insn.operands[0] 

+

7591 if op in function_parameters: 

+

7592 parameter_set.add(op) 

+

7593 

+

7594 if is_x86_64(): 

+

7595 # also consider extended registers 

+

7596 extended_registers = {"$rdi": ["$edi", "$di"], 

+

7597 "$rsi": ["$esi", "$si"], 

+

7598 "$rdx": ["$edx", "$dx"], 

+

7599 "$rcx": ["$ecx", "$cx"], 

+

7600 } 

+

7601 for exreg in extended_registers: 

+

7602 if op in extended_registers[exreg]: 

+

7603 parameter_set.add(exreg) 

+

7604 

+

7605 if is_x86_32(): 

+

7606 nb_argument = len(parameter_set) 

+

7607 else: 

+

7608 nb_argument = max([function_parameters.index(p)+1 for p in parameter_set], default=0) 

+

7609 

+

7610 args = [] 

+

7611 for i in range(nb_argument): 

+

7612 _key, _values = gef.arch.get_ith_parameter(i, in_func=False) 

+

7613 _values = RIGHT_ARROW.join(dereference_from(_values)) 

+

7614 args.append(f"{Color.colorify(_key, arg_key_color)} = {_values}") 

+

7615 

+

7616 self.context_title("arguments (guessed)") 

+

7617 gef_print(f"{function_name} (") 

+

7618 if args: 

+

7619 gef_print(" " + ",\n ".join(args)) 

+

7620 gef_print(")") 

+

7621 return 

+

7622 

+

7623 def line_has_breakpoint(self, file_name: str, line_number: int, bp_locations: List[str]) -> bool: 

+

7624 filename_line = f"{file_name}:{line_number}" 

+

7625 return any(filename_line in loc for loc in bp_locations) 

+

7626 

+

7627 def context_source(self) -> None: 

+

7628 try: 

+

7629 pc = gef.arch.pc 

+

7630 symtabline = gdb.find_pc_line(pc) 

+

7631 symtab = symtabline.symtab 

+

7632 # we subtract one because the line number returned by gdb start at 1 

+

7633 line_num = symtabline.line - 1 

+

7634 if not symtab.is_valid(): 7634 ↛ 7635line 7634 didn't jump to line 7635, because the condition on line 7634 was never true

+

7635 return 

+

7636 

+

7637 fpath = symtab.fullname() 

+

7638 with open(fpath, "r") as f: 

+

7639 lines = [l.rstrip() for l in f.readlines()] 

+

7640 

+

7641 except Exception: 

+

7642 return 

+

7643 

+

7644 file_base_name = os.path.basename(symtab.filename) 

+

7645 breakpoints = gdb.breakpoints() or [] 

+

7646 bp_locations = [b.location for b in breakpoints if b.location and file_base_name in b.location] 

+

7647 past_lines_color = gef.config["theme.old_context"] 

+

7648 

+

7649 nb_line = self["nb_lines_code"] 

+

7650 fn = symtab.filename 

+

7651 if len(fn) > 20: 

+

7652 fn = f"{fn[:15]}[...]{os.path.splitext(fn)[1]}" 

+

7653 title = f"source:{fn}+{line_num + 1}" 

+

7654 cur_line_color = gef.config["theme.source_current_line"] 

+

7655 self.context_title(title) 

+

7656 show_extra_info = self["show_source_code_variable_values"] 

+

7657 

+

7658 for i in range(line_num - nb_line + 1, line_num + nb_line): 

+

7659 if i < 0: 7659 ↛ 7660line 7659 didn't jump to line 7660, because the condition on line 7659 was never true

+

7660 continue 

+

7661 

+

7662 bp_prefix = Color.redify(BP_GLYPH) if self.line_has_breakpoint(file_base_name, i + 1, bp_locations) else " " 

+

7663 

+

7664 if i < line_num: 

+

7665 gef_print("{}{}".format(bp_prefix, Color.colorify(f" {i + 1:4d}\t {lines[i]}", past_lines_color))) 

+

7666 

+

7667 if i == line_num: 

+

7668 prefix = f"{bp_prefix}{RIGHT_ARROW[1:]}{i + 1:4d}\t " 

+

7669 leading = len(lines[i]) - len(lines[i].lstrip()) 

+

7670 if show_extra_info: 7670 ↛ 7674line 7670 didn't jump to line 7674, because the condition on line 7670 was never false

+

7671 extra_info = self.get_pc_context_info(pc, lines[i]) 

+

7672 if extra_info: 

+

7673 gef_print(f"{' ' * (len(prefix) + leading)}{extra_info}") 

+

7674 gef_print(Color.colorify(f"{prefix}{lines[i]}", cur_line_color)) 

+

7675 

+

7676 if i > line_num: 

+

7677 try: 

+

7678 gef_print(f"{bp_prefix} {i + 1:4d}\t {lines[i]}") 

+

7679 except IndexError: 

+

7680 break 

+

7681 return 

+

7682 

+

7683 def get_pc_context_info(self, pc: int, line: str) -> str: 

+

7684 try: 

+

7685 current_block = gdb.block_for_pc(pc) 

+

7686 if not current_block or not current_block.is_valid(): return "" 7686 ↛ exitline 7686 didn't return from function 'get_pc_context_info', because the return on line 7686 wasn't executed

+

7687 m = collections.OrderedDict() 

+

7688 while current_block and not current_block.is_static: 

+

7689 for sym in current_block: 

+

7690 symbol = sym.name 

+

7691 if not sym.is_function and re.search(fr"\W{symbol}\W", line): 

+

7692 val = gdb.parse_and_eval(symbol) 

+

7693 if val.type.code in (gdb.TYPE_CODE_PTR, gdb.TYPE_CODE_ARRAY): 7693 ↛ 7694line 7693 didn't jump to line 7694, because the condition on line 7693 was never true

+

7694 addr = int(val.address) 

+

7695 addrs = dereference_from(addr) 

+

7696 if len(addrs) > 2: 

+

7697 addrs = [addrs[0], "[...]", addrs[-1]] 

+

7698 

+

7699 f = f" {RIGHT_ARROW} " 

+

7700 val = f.join(addrs) 

+

7701 elif val.type.code == gdb.TYPE_CODE_INT: 7701 ↛ 7704line 7701 didn't jump to line 7704, because the condition on line 7701 was never false

+

7702 val = hex(int(val)) 

+

7703 else: 

+

7704 continue 

+

7705 

+

7706 if symbol not in m: 7706 ↛ 7689line 7706 didn't jump to line 7689, because the condition on line 7706 was never false

+

7707 m[symbol] = val 

+

7708 current_block = current_block.superblock 

+

7709 

+

7710 if m: 

+

7711 return "// " + ", ".join([f"{Color.yellowify(a)}={b}" for a, b in m.items()]) 

+

7712 except Exception: 

+

7713 pass 

+

7714 return "" 

+

7715 

+

7716 def context_trace(self) -> None: 

+

7717 self.context_title("trace") 

+

7718 

+

7719 nb_backtrace = self["nb_lines_backtrace"] 

+

7720 if nb_backtrace <= 0: 7720 ↛ 7721line 7720 didn't jump to line 7721, because the condition on line 7720 was never true

+

7721 return 

+

7722 

+

7723 # backward compat for gdb (gdb < 7.10) 

+

7724 if not hasattr(gdb, "FrameDecorator"): 7724 ↛ 7725line 7724 didn't jump to line 7725, because the condition on line 7724 was never true

+

7725 gdb.execute(f"backtrace {nb_backtrace:d}") 

+

7726 return 

+

7727 

+

7728 orig_frame = gdb.selected_frame() 

+

7729 current_frame = gdb.newest_frame() 

+

7730 frames = [current_frame] 

+

7731 while current_frame != orig_frame: 7731 ↛ 7732line 7731 didn't jump to line 7732, because the condition on line 7731 was never true

+

7732 current_frame = current_frame.older() 

+

7733 frames.append(current_frame) 

+

7734 

+

7735 nb_backtrace_before = self["nb_lines_backtrace_before"] 

+

7736 level = max(len(frames) - nb_backtrace_before - 1, 0) 

+

7737 current_frame = frames[level] 

+

7738 

+

7739 while current_frame: 

+

7740 current_frame.select() 

+

7741 if not current_frame.is_valid(): 7741 ↛ 7742line 7741 didn't jump to line 7742, because the condition on line 7741 was never true

+

7742 continue 

+

7743 

+

7744 pc = current_frame.pc() 

+

7745 name = current_frame.name() 

+

7746 items = [] 

+

7747 items.append(f"{pc:#x}") 

+

7748 if name: 

+

7749 frame_args = gdb.FrameDecorator.FrameDecorator(current_frame).frame_args() or [] 

+

7750 m = "{}({})".format(Color.greenify(name), 

+

7751 ", ".join(["{}={!s}".format(Color.yellowify(x.sym), 

+

7752 x.sym.value(current_frame)) for x in frame_args])) 

+

7753 items.append(m) 

+

7754 else: 

+

7755 try: 

+

7756 insn = next(gef_disassemble(pc, 1)) 

+

7757 except gdb.MemoryError: 

+

7758 break 

+

7759 

+

7760 # check if the gdb symbol table may know the address 

+

7761 sym_found = gdb_get_location_from_symbol(pc) 

+

7762 symbol = "" 

+

7763 if sym_found: 7763 ↛ 7764line 7763 didn't jump to line 7764, because the condition on line 7763 was never true

+

7764 sym_name, offset = sym_found 

+

7765 symbol = f" <{sym_name}+{offset:x}> " 

+

7766 

+

7767 items.append(Color.redify(f"{symbol}{insn.mnemonic} {', '.join(insn.operands)}")) 

+

7768 

+

7769 gef_print("[{}] {}".format(Color.colorify(f"#{level}", "bold green" if current_frame == orig_frame else "bold pink"), 

+

7770 RIGHT_ARROW.join(items))) 

+

7771 current_frame = current_frame.older() 

+

7772 level += 1 

+

7773 nb_backtrace -= 1 

+

7774 if nb_backtrace == 0: 7774 ↛ 7775line 7774 didn't jump to line 7775, because the condition on line 7774 was never true

+

7775 break 

+

7776 

+

7777 orig_frame.select() 

+

7778 return 

+

7779 

+

7780 def context_threads(self) -> None: 

+

7781 def reason() -> str: 

+

7782 res = gdb.execute("info program", to_string=True) 

+

7783 if not res: 7783 ↛ 7784line 7783 didn't jump to line 7784, because the condition on line 7783 was never true

+

7784 return "NOT RUNNING" 

+

7785 

+

7786 for line in res.splitlines(): 7786 ↛ 7799line 7786 didn't jump to line 7799, because the loop on line 7786 didn't complete

+

7787 line = line.strip() 

+

7788 if line.startswith("It stopped with signal "): 

+

7789 return line.replace("It stopped with signal ", "").split(",", 1)[0] 

+

7790 if line == "The program being debugged is not being run.": 7790 ↛ 7791line 7790 didn't jump to line 7791, because the condition on line 7790 was never true

+

7791 return "NOT RUNNING" 

+

7792 if line == "It stopped at a breakpoint that has since been deleted.": 7792 ↛ 7793line 7792 didn't jump to line 7793, because the condition on line 7792 was never true

+

7793 return "TEMPORARY BREAKPOINT" 

+

7794 if line.startswith("It stopped at breakpoint "): 

+

7795 return "BREAKPOINT" 

+

7796 if line == "It stopped after being stepped.": 7796 ↛ 7797line 7796 didn't jump to line 7797, because the condition on line 7796 was never true

+

7797 return "SINGLE STEP" 

+

7798 

+

7799 return "STOPPED" 

+

7800 

+

7801 self.context_title("threads") 

+

7802 

+

7803 threads = gdb.selected_inferior().threads()[::-1] 

+

7804 idx = self["nb_lines_threads"] 

+

7805 if idx > 0: 7805 ↛ 7806line 7805 didn't jump to line 7806, because the condition on line 7805 was never true

+

7806 threads = threads[0:idx] 

+

7807 

+

7808 if idx == 0: 7808 ↛ 7809line 7808 didn't jump to line 7809, because the condition on line 7808 was never true

+

7809 return 

+

7810 

+

7811 if not threads: 7811 ↛ 7812line 7811 didn't jump to line 7812, because the condition on line 7811 was never true

+

7812 err("No thread selected") 

+

7813 return 

+

7814 

+

7815 selected_thread = gdb.selected_thread() 

+

7816 selected_frame = gdb.selected_frame() 

+

7817 

+

7818 for i, thread in enumerate(threads): 

+

7819 line = f"[{Color.colorify(f'#{i:d}', 'bold green' if thread == selected_thread else 'bold pink')}] Id {thread.num:d}, " 

+

7820 if thread.name: 

+

7821 line += f"""Name: "{thread.name}", """ 

+

7822 if thread.is_running(): 7822 ↛ 7823line 7822 didn't jump to line 7823, because the condition on line 7822 was never true

+

7823 line += Color.colorify("running", "bold green") 

+

7824 elif thread.is_stopped(): 7824 ↛ 7840line 7824 didn't jump to line 7840, because the condition on line 7824 was never false

+

7825 line += Color.colorify("stopped", "bold red") 

+

7826 thread.switch() 

+

7827 frame = gdb.selected_frame() 

+

7828 frame_name = frame.name() 

+

7829 

+

7830 # check if the gdb symbol table may know the address 

+

7831 if not frame_name: 

+

7832 sym_found = gdb_get_location_from_symbol(frame.pc()) 

+

7833 if sym_found: 7833 ↛ 7834line 7833 didn't jump to line 7834, because the condition on line 7833 was never true

+

7834 sym_name, offset = sym_found 

+

7835 frame_name = f"<{sym_name}+{offset:x}>" 

+

7836 

+

7837 line += (f" {Color.colorify(f'{frame.pc():#x}', 'blue')} in " 

+

7838 f"{Color.colorify(frame_name or '??', 'bold yellow')} (), " 

+

7839 f"reason: {Color.colorify(reason(), 'bold pink')}") 

+

7840 elif thread.is_exited(): 

+

7841 line += Color.colorify("exited", "bold yellow") 

+

7842 gef_print(line) 

+

7843 i += 1 

+

7844 

+

7845 selected_thread.switch() 

+

7846 selected_frame.select() 

+

7847 return 

+

7848 

+

7849 def context_additional_information(self) -> None: 

+

7850 if not gef.ui.context_messages: 

+

7851 return 

+

7852 

+

7853 self.context_title("extra") 

+

7854 for level, text in gef.ui.context_messages: 

+

7855 if level == "error": err(text) 7855 ↛ 7854line 7855 didn't jump to line 7854

+

7856 elif level == "warn": warn(text) 7856 ↛ 7857line 7856 didn't jump to line 7857, because the condition on line 7856 was never false

+

7857 elif level == "success": ok(text) 

+

7858 else: info(text) 

+

7859 return 

+

7860 

+

7861 def context_memory(self) -> None: 

+

7862 for address, opt in sorted(gef.ui.watches.items()): 

+

7863 sz, fmt = opt[0:2] 

+

7864 self.context_title(f"memory:{address:#x}") 

+

7865 if fmt == "pointers": 7865 ↛ 7866line 7865 didn't jump to line 7866, because the condition on line 7865 was never true

+

7866 gdb.execute(f"dereference -l {sz:d} {address:#x}") 

+

7867 else: 

+

7868 gdb.execute(f"hexdump {fmt} -s {sz:d} {address:#x}") 

+

7869 

+

7870 @classmethod 

+

7871 def update_registers(cls, _) -> None: 

+

7872 for reg in gef.arch.all_registers: 

+

7873 try: 

+

7874 cls.old_registers[reg] = gef.arch.register(reg) 

+

7875 except Exception: 

+

7876 cls.old_registers[reg] = 0 

+

7877 return 

+

7878 

+

7879 def empty_extra_messages(self, _) -> None: 

+

7880 gef.ui.context_messages.clear() 

+

7881 return 

+

7882 

+

7883 

+

7884@register 

+

7885class MemoryCommand(GenericCommand): 

+

7886 """Add or remove address ranges to the memory view.""" 

+

7887 _cmdline_ = "memory" 

+

7888 _syntax_ = f"{_cmdline_} (watch|unwatch|reset|list)" 

+

7889 

+

7890 def __init__(self) -> None: 

+

7891 super().__init__(prefix=True) 

+

7892 return 

+

7893 

+

7894 @only_if_gdb_running 

+

7895 def do_invoke(self, argv: List[str]) -> None: 

+

7896 self.usage() 

+

7897 return 

+

7898 

+

7899 

+

7900@register 

+

7901class MemoryWatchCommand(GenericCommand): 

+

7902 """Adds address ranges to the memory view.""" 

+

7903 _cmdline_ = "memory watch" 

+

7904 _syntax_ = f"{_cmdline_} ADDRESS [SIZE] [(qword|dword|word|byte|pointers)]" 

+

7905 _example_ = (f"\n{_cmdline_} 0x603000 0x100 byte" 

+

7906 f"\n{_cmdline_} $sp") 

+

7907 

+

7908 def __init__(self) -> None: 

+

7909 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

7910 return 

+

7911 

+

7912 @only_if_gdb_running 

+

7913 def do_invoke(self, argv: List[str]) -> None: 

+

7914 if len(argv) not in (1, 2, 3): 7914 ↛ 7915line 7914 didn't jump to line 7915, because the condition on line 7914 was never true

+

7915 self.usage() 

+

7916 return 

+

7917 

+

7918 address = parse_address(argv[0]) 

+

7919 size = parse_address(argv[1]) if len(argv) > 1 else 0x10 

+

7920 group = "byte" 

+

7921 

+

7922 if len(argv) == 3: 

+

7923 group = argv[2].lower() 

+

7924 if group not in ("qword", "dword", "word", "byte", "pointers"): 7924 ↛ 7925line 7924 didn't jump to line 7925, because the condition on line 7924 was never true

+

7925 warn(f"Unexpected grouping '{group}'") 

+

7926 self.usage() 

+

7927 return 

+

7928 else: 

+

7929 if gef.arch.ptrsize == 4: 7929 ↛ 7930line 7929 didn't jump to line 7930, because the condition on line 7929 was never true

+

7930 group = "dword" 

+

7931 elif gef.arch.ptrsize == 8: 7931 ↛ 7934line 7931 didn't jump to line 7934, because the condition on line 7931 was never false

+

7932 group = "qword" 

+

7933 

+

7934 gef.ui.watches[address] = (size, group) 

+

7935 ok(f"Adding memwatch to {address:#x}") 

+

7936 return 

+

7937 

+

7938 

+

7939@register 

+

7940class MemoryUnwatchCommand(GenericCommand): 

+

7941 """Removes address ranges to the memory view.""" 

+

7942 _cmdline_ = "memory unwatch" 

+

7943 _syntax_ = f"{_cmdline_} ADDRESS" 

+

7944 _example_ = (f"\n{_cmdline_} 0x603000" 

+

7945 f"\n{_cmdline_} $sp") 

+

7946 

+

7947 def __init__(self) -> None: 

+

7948 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

7949 return 

+

7950 

+

7951 @only_if_gdb_running 

+

7952 def do_invoke(self, argv: List[str]) -> None: 

+

7953 if not argv: 7953 ↛ 7954line 7953 didn't jump to line 7954, because the condition on line 7953 was never true

+

7954 self.usage() 

+

7955 return 

+

7956 

+

7957 address = parse_address(argv[0]) 

+

7958 res = gef.ui.watches.pop(address, None) 

+

7959 if not res: 7959 ↛ 7962line 7959 didn't jump to line 7962, because the condition on line 7959 was never false

+

7960 warn(f"You weren't watching {address:#x}") 

+

7961 else: 

+

7962 ok(f"Removed memwatch of {address:#x}") 

+

7963 return 

+

7964 

+

7965 

+

7966@register 

+

7967class MemoryWatchResetCommand(GenericCommand): 

+

7968 """Removes all watchpoints.""" 

+

7969 _cmdline_ = "memory reset" 

+

7970 _syntax_ = f"{_cmdline_}" 

+

7971 

+

7972 @only_if_gdb_running 

+

7973 def do_invoke(self, _: List[str]) -> None: 

+

7974 gef.ui.watches.clear() 

+

7975 ok("Memory watches cleared") 

+

7976 return 

+

7977 

+

7978 

+

7979@register 

+

7980class MemoryWatchListCommand(GenericCommand): 

+

7981 """Lists all watchpoints to display in context layout.""" 

+

7982 _cmdline_ = "memory list" 

+

7983 _syntax_ = f"{_cmdline_}" 

+

7984 

+

7985 @only_if_gdb_running 

+

7986 def do_invoke(self, _: List[str]) -> None: 

+

7987 if not gef.ui.watches: 7987 ↛ 7991line 7987 didn't jump to line 7991, because the condition on line 7987 was never false

+

7988 info("No memory watches") 

+

7989 return 

+

7990 

+

7991 info("Memory watches:") 

+

7992 for address, opt in sorted(gef.ui.watches.items()): 

+

7993 gef_print(f"- {address:#x} ({opt[0]}, {opt[1]})") 

+

7994 return 

+

7995 

+

7996 

+

7997@register 

+

7998class HexdumpCommand(GenericCommand): 

+

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

+

8000 

+

8001 _cmdline_ = "hexdump" 

+

8002 _syntax_ = f"{_cmdline_} (qword|dword|word|byte) [LOCATION] [--size SIZE] [--reverse]" 

+

8003 _example_ = f"{_cmdline_} byte $rsp --size 16 --reverse" 

+

8004 

+

8005 def __init__(self) -> None: 

+

8006 super().__init__(complete=gdb.COMPLETE_LOCATION, prefix=True) 

+

8007 self["always_show_ascii"] = (False, "If true, hexdump will always display the ASCII dump") 

+

8008 self.format: Optional[str] = None 

+

8009 self.__last_target = "$sp" 

+

8010 return 

+

8011 

+

8012 @only_if_gdb_running 

+

8013 @parse_arguments({"address": "",}, {("--reverse", "-r"): True, ("--size", "-s"): 0}) 

+

8014 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

8015 valid_formats = ["byte", "word", "dword", "qword"] 

+

8016 if not self.format or self.format not in valid_formats: 8016 ↛ 8017line 8016 didn't jump to line 8017, because the condition on line 8016 was never true

+

8017 err("Invalid command") 

+

8018 return 

+

8019 

+

8020 args : argparse.Namespace = kwargs["arguments"] 

+

8021 target = args.address or self.__last_target 

+

8022 start_addr = parse_address(target) 

+

8023 read_from = align_address(start_addr) 

+

8024 

+

8025 if self.format == "byte": 

+

8026 read_len = args.size or 0x40 

+

8027 read_from += self.repeat_count * read_len 

+

8028 mem = gef.memory.read(read_from, read_len) 

+

8029 lines = hexdump(mem, base=read_from).splitlines() 

+

8030 else: 

+

8031 read_len = args.size or 0x10 

+

8032 lines = self._hexdump(read_from, read_len, self.format, self.repeat_count * read_len) 

+

8033 

+

8034 if args.reverse: 

+

8035 lines.reverse() 

+

8036 

+

8037 self.__last_target = target 

+

8038 gef_print("\n".join(lines)) 

+

8039 return 

+

8040 

+

8041 def _hexdump(self, start_addr: int, length: int, arrange_as: str, offset: int = 0) -> List[str]: 

+

8042 endianness = gef.arch.endianness 

+

8043 

+

8044 base_address_color = gef.config["theme.dereference_base_address"] 

+

8045 show_ascii = gef.config["hexdump.always_show_ascii"] 

+

8046 

+

8047 formats = { 

+

8048 "qword": ("Q", 8), 

+

8049 "dword": ("I", 4), 

+

8050 "word": ("H", 2), 

+

8051 } 

+

8052 

+

8053 r, l = formats[arrange_as] 

+

8054 fmt_str = f"{{base}}{VERTICAL_LINE}+{{offset:#06x}} {{sym}}{{val:#0{l*2+2}x}} {{text}}" 

+

8055 fmt_pack = f"{endianness!s}{r}" 

+

8056 lines = [] 

+

8057 

+

8058 i = 0 

+

8059 text = "" 

+

8060 while i < length: 

+

8061 cur_addr = start_addr + (i + offset) * l 

+

8062 sym = gdb_get_location_from_symbol(cur_addr) 

+

8063 sym = "<{:s}+{:04x}> ".format(*sym) if sym else "" 

+

8064 mem = gef.memory.read(cur_addr, l) 

+

8065 val = struct.unpack(fmt_pack, mem)[0] 

+

8066 if show_ascii: 8066 ↛ 8067line 8066 didn't jump to line 8067, because the condition on line 8066 was never true

+

8067 text = "".join([chr(b) if 0x20 <= b < 0x7F else "." for b in mem]) 

+

8068 lines.append(fmt_str.format(base=Color.colorify(format_address(cur_addr), base_address_color), 

+

8069 offset=(i + offset) * l, sym=sym, val=val, text=text)) 

+

8070 i += 1 

+

8071 

+

8072 return lines 

+

8073 

+

8074 

+

8075@register 

+

8076class HexdumpQwordCommand(HexdumpCommand): 

+

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

+

8078 

+

8079 _cmdline_ = "hexdump qword" 

+

8080 _syntax_ = f"{_cmdline_} [ADDRESS] [[L][SIZE]] [REVERSE]" 

+

8081 _example_ = f"{_cmdline_} qword $rsp L16 REVERSE" 

+

8082 

+

8083 def __init__(self) -> None: 

+

8084 super().__init__() 

+

8085 self.format = "qword" 

+

8086 return 

+

8087 

+

8088 

+

8089@register 

+

8090class HexdumpDwordCommand(HexdumpCommand): 

+

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

+

8092 

+

8093 _cmdline_ = "hexdump dword" 

+

8094 _syntax_ = f"{_cmdline_} [ADDRESS] [[L][SIZE]] [REVERSE]" 

+

8095 _example_ = f"{_cmdline_} $esp L16 REVERSE" 

+

8096 

+

8097 def __init__(self) -> None: 

+

8098 super().__init__() 

+

8099 self.format = "dword" 

+

8100 return 

+

8101 

+

8102 

+

8103@register 

+

8104class HexdumpWordCommand(HexdumpCommand): 

+

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

+

8106 

+

8107 _cmdline_ = "hexdump word" 

+

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 = "word" 

+

8114 return 

+

8115 

+

8116 

+

8117@register 

+

8118class HexdumpByteCommand(HexdumpCommand): 

+

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

+

8120 

+

8121 _cmdline_ = "hexdump byte" 

+

8122 _syntax_ = f"{_cmdline_} [ADDRESS] [[L][SIZE]] [REVERSE]" 

+

8123 _example_ = f"{_cmdline_} $rsp L16" 

+

8124 

+

8125 def __init__(self) -> None: 

+

8126 super().__init__() 

+

8127 self.format = "byte" 

+

8128 return 

+

8129 

+

8130 

+

8131@register 

+

8132class PatchCommand(GenericCommand): 

+

8133 """Write specified values to the specified address.""" 

+

8134 

+

8135 _cmdline_ = "patch" 

+

8136 _syntax_ = (f"{_cmdline_} (qword|dword|word|byte) LOCATION VALUES\n" 

+

8137 f"{_cmdline_} string LOCATION \"double-escaped string\"") 

+

8138 SUPPORTED_SIZES = { 

+

8139 "qword": (8, "Q"), 

+

8140 "dword": (4, "L"), 

+

8141 "word": (2, "H"), 

+

8142 "byte": (1, "B"), 

+

8143 } 

+

8144 

+

8145 def __init__(self) -> None: 

+

8146 super().__init__(prefix=True, complete=gdb.COMPLETE_LOCATION) 

+

8147 self.format: Optional[str] = None 

+

8148 return 

+

8149 

+

8150 @only_if_gdb_running 

+

8151 @parse_arguments({"location": "", "values": ["", ]}, {}) 

+

8152 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

8153 args : argparse.Namespace = kwargs["arguments"] 

+

8154 if not self.format or self.format not in self.SUPPORTED_SIZES: 8154 ↛ 8155line 8154 didn't jump to line 8155, because the condition on line 8154 was never true

+

8155 self.usage() 

+

8156 return 

+

8157 

+

8158 if not args.location or not args.values: 8158 ↛ 8159line 8158 didn't jump to line 8159, because the condition on line 8158 was never true

+

8159 self.usage() 

+

8160 return 

+

8161 

+

8162 addr = align_address(parse_address(args.location)) 

+

8163 size, fcode = self.SUPPORTED_SIZES[self.format] 

+

8164 values = args.values 

+

8165 

+

8166 if size == 1: 

+

8167 if values[0].startswith("$_gef"): 

+

8168 var_name = values[0] 

+

8169 try: 

+

8170 values = str(gdb.parse_and_eval(var_name)).lstrip("{").rstrip("}").replace(",","").split(" ") 

+

8171 except: 

+

8172 gef_print(f"Bad variable specified, check value with command: p {var_name}") 

+

8173 return 

+

8174 

+

8175 d = str(gef.arch.endianness) 

+

8176 for value in values: 

+

8177 value = parse_address(value) & ((1 << size * 8) - 1) 

+

8178 vstr = struct.pack(d + fcode, value) 

+

8179 gef.memory.write(addr, vstr, length=size) 

+

8180 addr += size 

+

8181 return 

+

8182 

+

8183 

+

8184@register 

+

8185class PatchQwordCommand(PatchCommand): 

+

8186 """Write specified QWORD to the specified address.""" 

+

8187 

+

8188 _cmdline_ = "patch qword" 

+

8189 _syntax_ = f"{_cmdline_} LOCATION QWORD1 [QWORD2 [QWORD3..]]" 

+

8190 _example_ = f"{_cmdline_} $rip 0x4141414141414141" 

+

8191 

+

8192 def __init__(self) -> None: 

+

8193 super().__init__() 

+

8194 self.format = "qword" 

+

8195 return 

+

8196 

+

8197 

+

8198@register 

+

8199class PatchDwordCommand(PatchCommand): 

+

8200 """Write specified DWORD to the specified address.""" 

+

8201 

+

8202 _cmdline_ = "patch dword" 

+

8203 _syntax_ = f"{_cmdline_} LOCATION DWORD1 [DWORD2 [DWORD3..]]" 

+

8204 _example_ = f"{_cmdline_} $rip 0x41414141" 

+

8205 

+

8206 def __init__(self) -> None: 

+

8207 super().__init__() 

+

8208 self.format = "dword" 

+

8209 return 

+

8210 

+

8211 

+

8212@register 

+

8213class PatchWordCommand(PatchCommand): 

+

8214 """Write specified WORD to the specified address.""" 

+

8215 

+

8216 _cmdline_ = "patch word" 

+

8217 _syntax_ = f"{_cmdline_} LOCATION WORD1 [WORD2 [WORD3..]]" 

+

8218 _example_ = f"{_cmdline_} $rip 0x4141" 

+

8219 

+

8220 def __init__(self) -> None: 

+

8221 super().__init__() 

+

8222 self.format = "word" 

+

8223 return 

+

8224 

+

8225 

+

8226@register 

+

8227class PatchByteCommand(PatchCommand): 

+

8228 """Write specified BYTE to the specified address.""" 

+

8229 

+

8230 _cmdline_ = "patch byte" 

+

8231 _syntax_ = f"{_cmdline_} LOCATION BYTE1 [BYTE2 [BYTE3..]]" 

+

8232 _example_ = f"{_cmdline_} $pc 0x41 0x41 0x41 0x41 0x41" 

+

8233 

+

8234 def __init__(self) -> None: 

+

8235 super().__init__() 

+

8236 self.format = "byte" 

+

8237 return 

+

8238 

+

8239 

+

8240@register 

+

8241class PatchStringCommand(GenericCommand): 

+

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

+

8243 

+

8244 _cmdline_ = "patch string" 

+

8245 _syntax_ = f"{_cmdline_} ADDRESS \"double backslash-escaped string\"" 

+

8246 _example_ = f"{_cmdline_} $sp \"GEFROCKS\"" 

+

8247 

+

8248 @only_if_gdb_running 

+

8249 def do_invoke(self, argv: List[str]) -> None: 

+

8250 argc = len(argv) 

+

8251 if argc != 2: 8251 ↛ 8252line 8251 didn't jump to line 8252, because the condition on line 8251 was never true

+

8252 self.usage() 

+

8253 return 

+

8254 

+

8255 location, s = argv[0:2] 

+

8256 addr = align_address(parse_address(location)) 

+

8257 

+

8258 try: 

+

8259 s = codecs.escape_decode(s)[0] 

+

8260 except binascii.Error: 

+

8261 gef_print(f"Could not decode '\\xXX' encoded string \"{s}\"") 

+

8262 return 

+

8263 

+

8264 gef.memory.write(addr, s, len(s)) 

+

8265 return 

+

8266 

+

8267 

+

8268@lru_cache() 

+

8269def dereference_from(address: int) -> List[str]: 

+

8270 if not is_alive(): 8270 ↛ 8271line 8270 didn't jump to line 8271, because the condition on line 8270 was never true

+

8271 return [format_address(address),] 

+

8272 

+

8273 code_color = gef.config["theme.dereference_code"] 

+

8274 string_color = gef.config["theme.dereference_string"] 

+

8275 max_recursion = gef.config["dereference.max_recursion"] or 10 

+

8276 addr = lookup_address(align_address(address)) 

+

8277 msg = [format_address(addr.value),] 

+

8278 seen_addrs = set() 

+

8279 

+

8280 while addr.section and max_recursion: 

+

8281 if addr.value in seen_addrs: 

+

8282 msg.append("[loop detected]") 

+

8283 break 

+

8284 seen_addrs.add(addr.value) 

+

8285 

+

8286 max_recursion -= 1 

+

8287 

+

8288 # Is this value a pointer or a value? 

+

8289 # -- If it's a pointer, dereference 

+

8290 deref = addr.dereference() 

+

8291 if deref is None: 

+

8292 # if here, dereferencing addr has triggered a MemoryError, no need to go further 

+

8293 msg.append(str(addr)) 

+

8294 break 

+

8295 

+

8296 new_addr = lookup_address(deref) 

+

8297 if new_addr.valid: 

+

8298 addr = new_addr 

+

8299 msg.append(str(addr)) 

+

8300 continue 

+

8301 

+

8302 # -- Otherwise try to parse the value 

+

8303 if addr.section: 8303 ↛ 8324line 8303 didn't jump to line 8324, because the condition on line 8303 was never false

+

8304 if addr.section.is_executable() and addr.is_in_text_segment() and not is_ascii_string(addr.value): 

+

8305 insn = gef_current_instruction(addr.value) 

+

8306 insn_str = f"{insn.location} {insn.mnemonic} {', '.join(insn.operands)}" 

+

8307 msg.append(Color.colorify(insn_str, code_color)) 

+

8308 break 

+

8309 

+

8310 elif addr.section.permission & Permission.READ: 8310 ↛ 8324line 8310 didn't jump to line 8324, because the condition on line 8310 was never false

+

8311 if is_ascii_string(addr.value): 

+

8312 s = gef.memory.read_cstring(addr.value) 

+

8313 if len(s) < gef.arch.ptrsize: 

+

8314 txt = f'{format_address(deref)} ("{Color.colorify(s, string_color)}"?)' 

+

8315 elif len(s) > 50: 

+

8316 txt = Color.colorify(f'"{s[:50]}[...]"', string_color) 

+

8317 else: 

+

8318 txt = Color.colorify(f'"{s}"', string_color) 

+

8319 

+

8320 msg.append(txt) 

+

8321 break 

+

8322 

+

8323 # if not able to parse cleanly, simply display and break 

+

8324 val = "{:#0{ma}x}".format(int(deref & 0xFFFFFFFFFFFFFFFF), ma=(gef.arch.ptrsize * 2 + 2)) 

+

8325 msg.append(val) 

+

8326 break 

+

8327 

+

8328 return msg 

+

8329 

+

8330 

+

8331@register 

+

8332class DereferenceCommand(GenericCommand): 

+

8333 """Dereference recursively from an address and display information. This acts like WinDBG `dps` 

+

8334 command.""" 

+

8335 

+

8336 _cmdline_ = "dereference" 

+

8337 _syntax_ = f"{_cmdline_} [-h] [--length LENGTH] [--reference REFERENCE] [address]" 

+

8338 _aliases_ = ["telescope", ] 

+

8339 _example_ = f"{_cmdline_} --length 20 --reference $sp+0x10 $sp" 

+

8340 

+

8341 def __init__(self) -> None: 

+

8342 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

8343 self["max_recursion"] = (7, "Maximum level of pointer recursion") 

+

8344 return 

+

8345 

+

8346 @staticmethod 

+

8347 def pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) -> str: 

+

8348 base_address_color = gef.config["theme.dereference_base_address"] 

+

8349 registers_color = gef.config["theme.dereference_register_value"] 

+

8350 

+

8351 sep = f" {RIGHT_ARROW} " 

+

8352 memalign = gef.arch.ptrsize 

+

8353 

+

8354 offset = idx * memalign 

+

8355 current_address = align_address(addr + offset) 

+

8356 addrs = dereference_from(current_address) 

+

8357 l = "" 

+

8358 addr_l = format_address(int(addrs[0], 16)) 

+

8359 l += "{}{}{:+#07x}: {:{ma}s}".format(Color.colorify(addr_l, base_address_color), 

+

8360 VERTICAL_LINE, base_offset+offset, 

+

8361 sep.join(addrs[1:]), ma=(memalign*2 + 2)) 

+

8362 

+

8363 register_hints = [] 

+

8364 

+

8365 for regname in gef.arch.all_registers: 

+

8366 regvalue = gef.arch.register(regname) 

+

8367 if current_address == regvalue: 

+

8368 register_hints.append(regname) 

+

8369 

+

8370 if register_hints: 

+

8371 m = f"\t{LEFT_ARROW}{', '.join(list(register_hints))}" 

+

8372 l += Color.colorify(m, registers_color) 

+

8373 

+

8374 offset += memalign 

+

8375 return l 

+

8376 

+

8377 @only_if_gdb_running 

+

8378 @parse_arguments({"address": "$sp"}, {("-r", "--reference"): "", ("-l", "--length"): 10}) 

+

8379 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

8380 args : argparse.Namespace = kwargs["arguments"] 

+

8381 nb = args.length 

+

8382 

+

8383 target = args.address 

+

8384 target_addr = parse_address(target) 

+

8385 

+

8386 reference = args.reference or target 

+

8387 ref_addr = parse_address(reference) 

+

8388 

+

8389 if process_lookup_address(target_addr) is None: 

+

8390 err(f"Unmapped address: '{target}'") 

+

8391 return 

+

8392 

+

8393 if process_lookup_address(ref_addr) is None: 8393 ↛ 8394line 8393 didn't jump to line 8394, because the condition on line 8393 was never true

+

8394 err(f"Unmapped address: '{reference}'") 

+

8395 return 

+

8396 

+

8397 if gef.config["context.grow_stack_down"] is True: 8397 ↛ 8398line 8397 didn't jump to line 8398, because the condition on line 8397 was never true

+

8398 insnum_step = -1 

+

8399 if nb > 0: 

+

8400 from_insnum = nb * (self.repeat_count + 1) - 1 

+

8401 to_insnum = self.repeat_count * nb - 1 

+

8402 else: 

+

8403 from_insnum = self.repeat_count * nb 

+

8404 to_insnum = nb * (self.repeat_count + 1) 

+

8405 else: 

+

8406 insnum_step = 1 

+

8407 if nb > 0: 

+

8408 from_insnum = self.repeat_count * nb 

+

8409 to_insnum = nb * (self.repeat_count + 1) 

+

8410 else: 

+

8411 from_insnum = nb * (self.repeat_count + 1) + 1 

+

8412 to_insnum = (self.repeat_count * nb) + 1 

+

8413 

+

8414 start_address = align_address(target_addr) 

+

8415 base_offset = start_address - align_address(ref_addr) 

+

8416 

+

8417 for i in range(from_insnum, to_insnum, insnum_step): 

+

8418 gef_print(DereferenceCommand.pprint_dereferenced(start_address, i, base_offset)) 

+

8419 

+

8420 return 

+

8421 

+

8422 

+

8423@register 

+

8424class ASLRCommand(GenericCommand): 

+

8425 """View/modify the ASLR setting of GDB. By default, GDB will disable ASLR when it starts the process. (i.e. not 

+

8426 attached). This command allows to change that setting.""" 

+

8427 

+

8428 _cmdline_ = "aslr" 

+

8429 _syntax_ = f"{_cmdline_} [(on|off)]" 

+

8430 

+

8431 def do_invoke(self, argv: List[str]) -> None: 

+

8432 argc = len(argv) 

+

8433 

+

8434 if argc == 0: 

+

8435 ret = gdb.execute("show disable-randomization", to_string=True) or "" 

+

8436 i = ret.find("virtual address space is ") 

+

8437 if i < 0: 8437 ↛ 8438line 8437 didn't jump to line 8438, because the condition on line 8437 was never true

+

8438 return 

+

8439 

+

8440 msg = "ASLR is currently " 

+

8441 if ret[i + 25:].strip() == "on.": 

+

8442 msg += Color.redify("disabled") 

+

8443 else: 

+

8444 msg += Color.greenify("enabled") 

+

8445 

+

8446 gef_print(msg) 

+

8447 return 

+

8448 

+

8449 elif argc == 1: 8449 ↛ 8461line 8449 didn't jump to line 8461, because the condition on line 8449 was never false

+

8450 if argv[0] == "on": 8450 ↛ 8454line 8450 didn't jump to line 8454, because the condition on line 8450 was never false

+

8451 info("Enabling ASLR") 

+

8452 gdb.execute("set disable-randomization off") 

+

8453 return 

+

8454 elif argv[0] == "off": 

+

8455 info("Disabling ASLR") 

+

8456 gdb.execute("set disable-randomization on") 

+

8457 return 

+

8458 

+

8459 warn("Invalid command") 

+

8460 

+

8461 self.usage() 

+

8462 return 

+

8463 

+

8464 

+

8465@register 

+

8466class ResetCacheCommand(GenericCommand): 

+

8467 """Reset cache of all stored data. This command is here for debugging and test purposes, GEF 

+

8468 handles properly the cache reset under "normal" scenario.""" 

+

8469 

+

8470 _cmdline_ = "reset-cache" 

+

8471 _syntax_ = _cmdline_ 

+

8472 

+

8473 def do_invoke(self, _: List[str]) -> None: 

+

8474 reset_all_caches() 

+

8475 return 

+

8476 

+

8477 

+

8478@register 

+

8479class VMMapCommand(GenericCommand): 

+

8480 """Display a comprehensive layout of the virtual memory mapping. If a filter argument, GEF will 

+

8481 filter out the mapping whose pathname do not match that filter.""" 

+

8482 

+

8483 _cmdline_ = "vmmap" 

+

8484 _syntax_ = f"{_cmdline_} [FILTER]" 

+

8485 _example_ = f"{_cmdline_} libc" 

+

8486 

+

8487 @only_if_gdb_running 

+

8488 def do_invoke(self, argv: List[str]) -> None: 

+

8489 vmmap = gef.memory.maps 

+

8490 if not vmmap: 8490 ↛ 8491line 8490 didn't jump to line 8491, because the condition on line 8490 was never true

+

8491 err("No address mapping information found") 

+

8492 return 

+

8493 

+

8494 if not gef.config["gef.disable_color"]: 8494 ↛ 8497line 8494 didn't jump to line 8497, because the condition on line 8494 was never false

+

8495 self.show_legend() 

+

8496 

+

8497 color = gef.config["theme.table_heading"] 

+

8498 

+

8499 headers = ["Start", "End", "Offset", "Perm", "Path"] 

+

8500 gef_print(Color.colorify("{:<{w}s}{:<{w}s}{:<{w}s}{:<4s} {:s}".format(*headers, w=gef.arch.ptrsize*2+3), color)) 

+

8501 

+

8502 for entry in vmmap: 

+

8503 if not argv: 

+

8504 self.print_entry(entry) 

+

8505 continue 

+

8506 if argv[0] in entry.path: 

+

8507 self.print_entry(entry) 

+

8508 elif self.is_integer(argv[0]): 8508 ↛ 8509line 8508 didn't jump to line 8509, because the condition on line 8508 was never true

+

8509 addr = int(argv[0], 0) 

+

8510 if addr >= entry.page_start and addr < entry.page_end: 

+

8511 self.print_entry(entry) 

+

8512 return 

+

8513 

+

8514 def print_entry(self, entry: Section) -> None: 

+

8515 line_color = "" 

+

8516 if entry.path == "[stack]": 

+

8517 line_color = gef.config["theme.address_stack"] 

+

8518 elif entry.path == "[heap]": 8518 ↛ 8519line 8518 didn't jump to line 8519, because the condition on line 8518 was never true

+

8519 line_color = gef.config["theme.address_heap"] 

+

8520 elif entry.permission & Permission.READ and entry.permission & Permission.EXECUTE: 

+

8521 line_color = gef.config["theme.address_code"] 

+

8522 

+

8523 l = [ 

+

8524 Color.colorify(format_address(entry.page_start), line_color), 

+

8525 Color.colorify(format_address(entry.page_end), line_color), 

+

8526 Color.colorify(format_address(entry.offset), line_color), 

+

8527 ] 

+

8528 if entry.permission == Permission.ALL: 8528 ↛ 8529line 8528 didn't jump to line 8529, because the condition on line 8528 was never true

+

8529 l.append(Color.colorify(str(entry.permission), "underline " + line_color)) 

+

8530 else: 

+

8531 l.append(Color.colorify(str(entry.permission), line_color)) 

+

8532 

+

8533 l.append(Color.colorify(entry.path, line_color)) 

+

8534 line = " ".join(l) 

+

8535 

+

8536 gef_print(line) 

+

8537 return 

+

8538 

+

8539 def show_legend(self) -> None: 

+

8540 code_addr_color = gef.config["theme.address_code"] 

+

8541 stack_addr_color = gef.config["theme.address_stack"] 

+

8542 heap_addr_color = gef.config["theme.address_heap"] 

+

8543 

+

8544 gef_print("[ Legend: {} | {} | {} ]".format(Color.colorify("Code", code_addr_color), 

+

8545 Color.colorify("Heap", heap_addr_color), 

+

8546 Color.colorify("Stack", stack_addr_color) 

+

8547 )) 

+

8548 return 

+

8549 

+

8550 def is_integer(self, n: str) -> bool: 

+

8551 try: 

+

8552 int(n, 0) 

+

8553 except ValueError: 

+

8554 return False 

+

8555 return True 

+

8556 

+

8557 

+

8558@register 

+

8559class XFilesCommand(GenericCommand): 

+

8560 """Shows all libraries (and sections) loaded by binary. This command extends the GDB command 

+

8561 `info files`, by retrieving more information from extra sources, and providing a better 

+

8562 display. If an argument FILE is given, the output will grep information related to only that file. 

+

8563 If an argument name is also given, the output will grep to the name within FILE.""" 

+

8564 

+

8565 _cmdline_ = "xfiles" 

+

8566 _syntax_ = f"{_cmdline_} [FILE [NAME]]" 

+

8567 _example_ = f"\n{_cmdline_} libc\n{_cmdline_} libc IO_vtables" 

+

8568 

+

8569 @only_if_gdb_running 

+

8570 def do_invoke(self, argv: List[str]) -> None: 

+

8571 color = gef.config["theme.table_heading"] 

+

8572 headers = ["Start", "End", "Name", "File"] 

+

8573 gef_print(Color.colorify("{:<{w}s}{:<{w}s}{:<21s} {:s}".format(*headers, w=gef.arch.ptrsize*2+3), color)) 

+

8574 

+

8575 filter_by_file = argv[0] if argv and argv[0] else None 

+

8576 filter_by_name = argv[1] if len(argv) > 1 and argv[1] else None 

+

8577 

+

8578 for xfile in get_info_files(): 

+

8579 if filter_by_file: 8579 ↛ 8580line 8579 didn't jump to line 8580, because the condition on line 8579 was never true

+

8580 if filter_by_file not in xfile.filename: 

+

8581 continue 

+

8582 if filter_by_name and filter_by_name not in xfile.name: 

+

8583 continue 

+

8584 

+

8585 l = [ 

+

8586 format_address(xfile.zone_start), 

+

8587 format_address(xfile.zone_end), 

+

8588 f"{xfile.name:<21s}", 

+

8589 xfile.filename, 

+

8590 ] 

+

8591 gef_print(" ".join(l)) 

+

8592 return 

+

8593 

+

8594 

+

8595@register 

+

8596class XAddressInfoCommand(GenericCommand): 

+

8597 """Retrieve and display runtime information for the location(s) given as parameter.""" 

+

8598 

+

8599 _cmdline_ = "xinfo" 

+

8600 _syntax_ = f"{_cmdline_} LOCATION" 

+

8601 _example_ = f"{_cmdline_} $pc" 

+

8602 

+

8603 def __init__(self) -> None: 

+

8604 super().__init__(complete=gdb.COMPLETE_LOCATION) 

+

8605 return 

+

8606 

+

8607 @only_if_gdb_running 

+

8608 def do_invoke(self, argv: List[str]) -> None: 

+

8609 if not argv: 

+

8610 err("At least one valid address must be specified") 

+

8611 self.usage() 

+

8612 return 

+

8613 

+

8614 for sym in argv: 

+

8615 try: 

+

8616 addr = align_address(parse_address(sym)) 

+

8617 gef_print(titlify(f"xinfo: {addr:#x}")) 

+

8618 self.infos(addr) 

+

8619 

+

8620 except gdb.error as gdb_err: 

+

8621 err(f"{gdb_err}") 

+

8622 return 

+

8623 

+

8624 def infos(self, address: int) -> None: 

+

8625 addr = lookup_address(address) 

+

8626 if not addr.valid: 8626 ↛ 8627line 8626 didn't jump to line 8627, because the condition on line 8626 was never true

+

8627 warn(f"Cannot reach {address:#x} in memory space") 

+

8628 return 

+

8629 

+

8630 sect = addr.section 

+

8631 info = addr.info 

+

8632 

+

8633 if sect: 8633 ↛ 8641line 8633 didn't jump to line 8641, because the condition on line 8633 was never false

+

8634 gef_print(f"Page: {format_address(sect.page_start)} {RIGHT_ARROW} " 

+

8635 f"{format_address(sect.page_end)} (size={sect.page_end-sect.page_start:#x})" 

+

8636 f"\nPermissions: {sect.permission}" 

+

8637 f"\nPathname: {sect.path}" 

+

8638 f"\nOffset (from page): {addr.value-sect.page_start:#x}" 

+

8639 f"\nInode: {sect.inode}") 

+

8640 

+

8641 if info: 8641 ↛ 8642line 8641 didn't jump to line 8642, because the condition on line 8641 was never true

+

8642 gef_print(f"Segment: {info.name} " 

+

8643 f"({format_address(info.zone_start)}-{format_address(info.zone_end)})" 

+

8644 f"\nOffset (from segment): {addr.value-info.zone_start:#x}") 

+

8645 

+

8646 sym = gdb_get_location_from_symbol(address) 

+

8647 if sym: 8647 ↛ 8648line 8647 didn't jump to line 8648, because the condition on line 8647 was never true

+

8648 name, offset = sym 

+

8649 msg = f"Symbol: {name}" 

+

8650 if offset: 

+

8651 msg += f"+{offset:d}" 

+

8652 gef_print(msg) 

+

8653 

+

8654 return 

+

8655 

+

8656 

+

8657@register 

+

8658class XorMemoryCommand(GenericCommand): 

+

8659 """XOR a block of memory. The command allows to simply display the result, or patch it 

+

8660 runtime at runtime.""" 

+

8661 

+

8662 _cmdline_ = "xor-memory" 

+

8663 _syntax_ = f"{_cmdline_} (display|patch) ADDRESS SIZE KEY" 

+

8664 

+

8665 def __init__(self) -> None: 

+

8666 super().__init__(prefix=True) 

+

8667 return 

+

8668 

+

8669 def do_invoke(self, _: List[str]) -> None: 

+

8670 self.usage() 

+

8671 return 

+

8672 

+

8673 

+

8674@register 

+

8675class XorMemoryDisplayCommand(GenericCommand): 

+

8676 """Display a block of memory pointed by ADDRESS by xor-ing each byte with KEY. The key must be 

+

8677 provided in hexadecimal format.""" 

+

8678 

+

8679 _cmdline_ = "xor-memory display" 

+

8680 _syntax_ = f"{_cmdline_} ADDRESS SIZE KEY" 

+

8681 _example_ = f"{_cmdline_} $sp 16 41414141" 

+

8682 

+

8683 @only_if_gdb_running 

+

8684 def do_invoke(self, argv: List[str]) -> None: 

+

8685 if len(argv) != 3: 8685 ↛ 8686line 8685 didn't jump to line 8686, because the condition on line 8685 was never true

+

8686 self.usage() 

+

8687 return 

+

8688 

+

8689 address = parse_address(argv[0]) 

+

8690 length = int(argv[1], 0) 

+

8691 key = argv[2] 

+

8692 block = gef.memory.read(address, length) 

+

8693 info(f"Displaying XOR-ing {address:#x}-{address + len(block):#x} with {key!r}") 

+

8694 

+

8695 gef_print(titlify("Original block")) 

+

8696 gef_print(hexdump(block, base=address)) 

+

8697 

+

8698 gef_print(titlify("XOR-ed block")) 

+

8699 gef_print(hexdump(xor(block, key), base=address)) 

+

8700 return 

+

8701 

+

8702 

+

8703@register 

+

8704class XorMemoryPatchCommand(GenericCommand): 

+

8705 """Patch a block of memory pointed by ADDRESS by xor-ing each byte with KEY. The key must be 

+

8706 provided in hexadecimal format.""" 

+

8707 

+

8708 _cmdline_ = "xor-memory patch" 

+

8709 _syntax_ = f"{_cmdline_} ADDRESS SIZE KEY" 

+

8710 _example_ = f"{_cmdline_} $sp 16 41414141" 

+

8711 

+

8712 @only_if_gdb_running 

+

8713 def do_invoke(self, argv: List[str]) -> None: 

+

8714 if len(argv) != 3: 8714 ↛ 8715line 8714 didn't jump to line 8715, because the condition on line 8714 was never true

+

8715 self.usage() 

+

8716 return 

+

8717 

+

8718 address = parse_address(argv[0]) 

+

8719 length = int(argv[1], 0) 

+

8720 key = argv[2] 

+

8721 block = gef.memory.read(address, length) 

+

8722 info(f"Patching XOR-ing {address:#x}-{address + len(block):#x} with {key!r}") 

+

8723 xored_block = xor(block, key) 

+

8724 gef.memory.write(address, xored_block, length) 

+

8725 return 

+

8726 

+

8727 

+

8728@register 

+

8729class TraceRunCommand(GenericCommand): 

+

8730 """Create a runtime trace of all instructions executed from $pc to LOCATION specified. The 

+

8731 trace is stored in a text file that can be next imported in IDA Pro to visualize the runtime 

+

8732 path.""" 

+

8733 

+

8734 _cmdline_ = "trace-run" 

+

8735 _syntax_ = f"{_cmdline_} LOCATION [MAX_CALL_DEPTH]" 

+

8736 _example_ = f"{_cmdline_} 0x555555554610" 

+

8737 

+

8738 def __init__(self) -> None: 

+

8739 super().__init__(self._cmdline_, complete=gdb.COMPLETE_LOCATION) 

+

8740 self["max_tracing_recursion"] = (1, "Maximum depth of tracing") 

+

8741 self["tracefile_prefix"] = ("./gef-trace-", "Specify the tracing output file prefix") 

+

8742 return 

+

8743 

+

8744 @only_if_gdb_running 

+

8745 def do_invoke(self, argv: List[str]) -> None: 

+

8746 if len(argv) not in (1, 2): 8746 ↛ 8747line 8746 didn't jump to line 8747, because the condition on line 8746 was never true

+

8747 self.usage() 

+

8748 return 

+

8749 

+

8750 if len(argv) == 2 and argv[1].isdigit(): 8750 ↛ 8751line 8750 didn't jump to line 8751, because the condition on line 8750 was never true

+

8751 depth = int(argv[1]) 

+

8752 else: 

+

8753 depth = 1 

+

8754 

+

8755 try: 

+

8756 loc_start = gef.arch.pc 

+

8757 loc_end = parse_address(argv[0]) 

+

8758 except gdb.error as e: 

+

8759 err(f"Invalid location: {e}") 

+

8760 return 

+

8761 

+

8762 self.trace(loc_start, loc_end, depth) 

+

8763 return 

+

8764 

+

8765 def get_frames_size(self) -> int: 

+

8766 n = 0 

+

8767 f = gdb.newest_frame() 

+

8768 while f: 

+

8769 n += 1 

+

8770 f = f.older() 

+

8771 return n 

+

8772 

+

8773 def trace(self, loc_start: int, loc_end: int, depth: int) -> None: 

+

8774 info(f"Tracing from {loc_start:#x} to {loc_end:#x} (max depth={depth:d})") 

+

8775 logfile = f"{self['tracefile_prefix']}{loc_start:#x}-{loc_end:#x}.txt" 

+

8776 with RedirectOutputContext(to=logfile): 

+

8777 hide_context() 

+

8778 self.start_tracing(loc_start, loc_end, depth) 

+

8779 unhide_context() 

+

8780 ok(f"Done, logfile stored as '{logfile}'") 

+

8781 info("Hint: import logfile with `ida_color_gdb_trace.py` script in IDA to visualize path") 

+

8782 return 

+

8783 

+

8784 def start_tracing(self, loc_start: int, loc_end: int, depth: int) -> None: 

+

8785 loc_cur = loc_start 

+

8786 frame_count_init = self.get_frames_size() 

+

8787 

+

8788 gef_print("#", 

+

8789 f"# Execution tracing of {get_filepath()}", 

+

8790 f"# Start address: {format_address(loc_start)}", 

+

8791 f"# End address: {format_address(loc_end)}", 

+

8792 f"# Recursion level: {depth:d}", 

+

8793 "# automatically generated by gef.py", 

+

8794 "#\n", sep="\n") 

+

8795 

+

8796 while loc_cur != loc_end: 8796 ↛ 8815line 8796 didn't jump to line 8815, because the condition on line 8796 was never false

+

8797 try: 

+

8798 delta = self.get_frames_size() - frame_count_init 

+

8799 

+

8800 if delta <= depth: 

+

8801 gdb.execute("stepi") 

+

8802 else: 

+

8803 gdb.execute("finish") 

+

8804 

+

8805 loc_cur = gef.arch.pc 

+

8806 gdb.flush() 

+

8807 

+

8808 except gdb.error as e: 

+

8809 gef_print("#", 

+

8810 f"# Execution interrupted at address {format_address(loc_cur)}", 

+

8811 f"# Exception: {e}", 

+

8812 "#\n", sep="\n") 

+

8813 break 

+

8814 

+

8815 return 

+

8816 

+

8817 

+

8818@register 

+

8819class PatternCommand(GenericCommand): 

+

8820 """Generate or Search a De Bruijn Sequence of unique substrings of length N 

+

8821 and a total length of LENGTH. The default value of N is set to match the 

+

8822 currently loaded architecture.""" 

+

8823 

+

8824 _cmdline_ = "pattern" 

+

8825 _syntax_ = f"{_cmdline_} (create|search) ARGS" 

+

8826 

+

8827 def __init__(self) -> None: 

+

8828 super().__init__(prefix=True) 

+

8829 self["length"] = (1024, "Default length of a cyclic buffer to generate") 

+

8830 return 

+

8831 

+

8832 def do_invoke(self, _: List[str]) -> None: 

+

8833 self.usage() 

+

8834 return 

+

8835 

+

8836 

+

8837@register 

+

8838class PatternCreateCommand(GenericCommand): 

+

8839 """Generate a De Bruijn Sequence of unique substrings of length N and a 

+

8840 total length of LENGTH. The default value of N is set to match the currently 

+

8841 loaded architecture.""" 

+

8842 

+

8843 _cmdline_ = "pattern create" 

+

8844 _syntax_ = f"{_cmdline_} [-h] [-n N] [length]" 

+

8845 _example_ = f"{_cmdline_} 4096" 

+

8846 

+

8847 @parse_arguments({"length": 0}, {("-n", "--n"): 0}) 

+

8848 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

8849 args : argparse.Namespace = kwargs["arguments"] 

+

8850 length = args.length or gef.config["pattern.length"] 

+

8851 n = args.n or gef.arch.ptrsize 

+

8852 info(f"Generating a pattern of {length:d} bytes (n={n:d})") 

+

8853 pattern_str = gef_pystring(generate_cyclic_pattern(length, n)) 

+

8854 gef_print(pattern_str) 

+

8855 ok(f"Saved as '{gef_convenience(pattern_str)}'") 

+

8856 return 

+

8857 

+

8858 

+

8859@register 

+

8860class PatternSearchCommand(GenericCommand): 

+

8861 """Search a De Bruijn Sequence of unique substrings of length N and a 

+

8862 maximum total length of MAX_LENGTH. The default value of N is set to match 

+

8863 the currently loaded architecture. The PATTERN argument can be a GDB symbol 

+

8864 (such as a register name), a string or a hexadecimal value""" 

+

8865 

+

8866 _cmdline_ = "pattern search" 

+

8867 _syntax_ = f"{_cmdline_} [-h] [-n N] [--max-length MAX_LENGTH] [pattern]" 

+

8868 _example_ = [f"{_cmdline_} $pc", 

+

8869 f"{_cmdline_} 0x61616164", 

+

8870 f"{_cmdline_} aaab"] 

+

8871 _aliases_ = ["pattern offset"] 

+

8872 

+

8873 @only_if_gdb_running 

+

8874 @parse_arguments({"pattern": ""}, {("--period", "-n"): 0, ("--max-length", "-l"): 0}) 

+

8875 def do_invoke(self, _: List[str], **kwargs: Any) -> None: 

+

8876 args = kwargs["arguments"] 

+

8877 if not args.pattern: 8877 ↛ 8878line 8877 didn't jump to line 8878, because the condition on line 8877 was never true

+

8878 warn("No pattern provided") 

+

8879 return 

+

8880 

+

8881 max_length = args.max_length or gef.config["pattern.length"] 

+

8882 n = args.period or gef.arch.ptrsize 

+

8883 if n not in (2, 4, 8) or n > gef.arch.ptrsize: 8883 ↛ 8884line 8883 didn't jump to line 8884, because the condition on line 8883 was never true

+

8884 err("Incorrect value for period") 

+

8885 return 

+

8886 self.search(args.pattern, max_length, n) 

+

8887 return 

+

8888 

+

8889 def search(self, pattern: str, size: int, period: int) -> None: 

+

8890 pattern_be, pattern_le = None, None 

+

8891 

+

8892 # 1. check if it's a symbol (like "$sp" or "0x1337") 

+

8893 symbol = safe_parse_and_eval(pattern) 

+

8894 if symbol: 

+

8895 addr = int(abs(symbol)) 

+

8896 dereferenced_value = dereference(addr) 

+

8897 if dereferenced_value: 8897 ↛ 8898line 8897 didn't jump to line 8898, because the condition on line 8897 was never true

+

8898 addr = int(abs(dereferenced_value)) 

+

8899 mask = (1<<(8 * period))-1 

+

8900 addr &= mask 

+

8901 pattern_le = addr.to_bytes(period, 'little') 

+

8902 pattern_be = addr.to_bytes(period, 'big') 

+

8903 else: 

+

8904 # 2. assume it's a plain string 

+

8905 pattern_be = gef_pybytes(pattern) 

+

8906 pattern_le = gef_pybytes(pattern[::-1]) 

+

8907 

+

8908 info(f"Searching for '{pattern_le.hex()}'/'{pattern_be.hex()}' with period={period}") 

+

8909 cyclic_pattern = generate_cyclic_pattern(size, period) 

+

8910 off = cyclic_pattern.find(pattern_le) 

+

8911 if off >= 0: 

+

8912 ok(f"Found at offset {off:d} (little-endian search) " 

+

8913 f"{Color.colorify('likely', 'bold red') if gef.arch.endianness == Endianness.LITTLE_ENDIAN else ''}") 

+

8914 return 

+

8915 

+

8916 off = cyclic_pattern.find(pattern_be) 

+

8917 if off >= 0: 8917 ↛ 8918line 8917 didn't jump to line 8918, because the condition on line 8917 was never true

+

8918 ok(f"Found at offset {off:d} (big-endian search) " 

+

8919 f"{Color.colorify('likely', 'bold green') if gef.arch.endianness == Endianness.BIG_ENDIAN else ''}") 

+

8920 return 

+

8921 

+

8922 err(f"Pattern '{pattern}' not found") 

+

8923 return 

+

8924 

+

8925 

+

8926@register 

+

8927class ChecksecCommand(GenericCommand): 

+

8928 """Checksec the security properties of the current executable or passed as argument. The 

+

8929 command checks for the following protections: 

+

8930 - PIE 

+

8931 - NX 

+

8932 - RelRO 

+

8933 - Glibc Stack Canaries 

+

8934 - Fortify Source""" 

+

8935 

+

8936 _cmdline_ = "checksec" 

+

8937 _syntax_ = f"{_cmdline_} [FILENAME]" 

+

8938 _example_ = f"{_cmdline_} /bin/ls" 

+

8939 

+

8940 def __init__(self) -> None: 

+

8941 super().__init__(complete=gdb.COMPLETE_FILENAME) 

+

8942 return 

+

8943 

+

8944 def do_invoke(self, argv: List[str]) -> None: 

+

8945 argc = len(argv) 

+

8946 

+

8947 if argc == 0: 8947 ↛ 8952line 8947 didn't jump to line 8952, because the condition on line 8947 was never false

+

8948 filename = get_filepath() 

+

8949 if filename is None: 8949 ↛ 8950line 8949 didn't jump to line 8950, because the condition on line 8949 was never true

+

8950 warn("No executable/library specified") 

+

8951 return 

+

8952 elif argc == 1: 

+

8953 filename = os.path.realpath(os.path.expanduser(argv[0])) 

+

8954 if not os.access(filename, os.R_OK): 

+

8955 err("Invalid filename") 

+

8956 return 

+

8957 else: 

+

8958 self.usage() 

+

8959 return 

+

8960 

+

8961 info(f"{self._cmdline_} for '{filename}'") 

+

8962 self.print_security_properties(filename) 

+

8963 return 

+

8964 

+

8965 def print_security_properties(self, filename: str) -> None: 

+

8966 sec = Elf(filename).checksec 

+

8967 for prop in sec: 

+

8968 if prop in ("Partial RelRO", "Full RelRO"): continue 

+

8969 val = sec[prop] 

+

8970 msg = Color.greenify(Color.boldify(TICK)) if val is True else Color.redify(Color.boldify(CROSS)) 

+

8971 if val and prop == "Canary" and is_alive(): 8971 ↛ 8972line 8971 didn't jump to line 8972, because the condition on line 8971 was never true

+

8972 canary = gef.session.canary[0] if gef.session.canary else 0 

+

8973 msg += f"(value: {canary:#x})" 

+

8974 

+

8975 gef_print(f"{prop:<30s}: {msg}") 

+

8976 

+

8977 if sec["Full RelRO"]: 

+

8978 gef_print(f"{'RelRO':<30s}: {Color.greenify('Full')}") 

+

8979 elif sec["Partial RelRO"]: 8979 ↛ 8982line 8979 didn't jump to line 8982, because the condition on line 8979 was never false

+

8980 gef_print(f"{'RelRO':<30s}: {Color.yellowify('Partial')}") 

+

8981 else: 

+

8982 gef_print(f"{'RelRO':<30s}: {Color.redify(Color.boldify(CROSS))}") 

+

8983 return 

+

8984 

+

8985 

+

8986@register 

+

8987class GotCommand(GenericCommand): 

+

8988 """Display current status of the got inside the process.""" 

+

8989 

+

8990 _cmdline_ = "got" 

+

8991 _syntax_ = f"{_cmdline_} [FUNCTION_NAME ...] " 

+

8992 _example_ = "got read printf exit" 

+

8993 

+

8994 def __init__(self): 

+

8995 super().__init__() 

+

8996 self["function_resolved"] = ("green", 

+

8997 "Line color of the got command output for resolved function") 

+

8998 self["function_not_resolved"] = ("yellow", 

+

8999 "Line color of the got command output for unresolved function") 

+

9000 return 

+

9001 

+

9002 @only_if_gdb_running 

+

9003 def do_invoke(self, argv: List[str]) -> None: 

+

9004 readelf = gef.session.constants["readelf"] 

+

9005 

+

9006 if is_remote_debug(): 9006 ↛ 9007line 9006 didn't jump to line 9007, because the condition on line 9006 was never true

+

9007 elf_file = str(gef.session.remote.lfile) 

+

9008 elf_virtual_path = str(gef.session.remote.file) 

+

9009 else: 

+

9010 elf_file = str(gef.session.file) 

+

9011 elf_virtual_path = str(gef.session.file) 

+

9012 

+

9013 func_names_filter = argv if argv else [] 

+

9014 vmmap = gef.memory.maps 

+

9015 base_address = min(x.page_start for x in vmmap if x.path == elf_virtual_path) 

+

9016 end_address = max(x.page_end for x in vmmap if x.path == elf_virtual_path) 

+

9017 

+

9018 # get the checksec output. 

+

9019 checksec_status = Elf(elf_file).checksec 

+

9020 relro_status = "Full RelRO" 

+

9021 full_relro = checksec_status["Full RelRO"] 

+

9022 pie = checksec_status["PIE"] # if pie we will have offset instead of abs address. 

+

9023 

+

9024 if not full_relro: 9024 ↛ 9025line 9024 didn't jump to line 9025, because the condition on line 9024 was never true

+

9025 relro_status = "Partial RelRO" 

+

9026 partial_relro = checksec_status["Partial RelRO"] 

+

9027 

+

9028 if not partial_relro: 

+

9029 relro_status = "No RelRO" 

+

9030 

+

9031 # retrieve jump slots using readelf 

+

9032 lines = gef_execute_external([readelf, "--relocs", elf_file], as_list=True) 

+

9033 jmpslots = [line for line in lines if "JUMP" in line] 

+

9034 

+

9035 gef_print(f"\nGOT protection: {relro_status} | GOT functions: {len(jmpslots)}\n ") 

+

9036 

+

9037 for line in jmpslots: 

+

9038 address, _, _, _, name = line.split()[:5] 

+

9039 

+

9040 # if we have a filter let's skip the entries that are not requested. 

+

9041 if func_names_filter: 

+

9042 if not any(map(lambda x: x in name, func_names_filter)): 

+

9043 continue 

+

9044 

+

9045 address_val = int(address, 16) 

+

9046 

+

9047 # address_val is an offset from the base_address if we have PIE. 

+

9048 if pie or is_remote_debug(): 9048 ↛ 9052line 9048 didn't jump to line 9052, because the condition on line 9048 was never false

+

9049 address_val = base_address + address_val 

+

9050 

+

9051 # read the address of the function. 

+

9052 got_address = gef.memory.read_integer(address_val) 

+

9053 

+

9054 # for the swag: different colors if the function has been resolved or not. 

+

9055 if base_address < got_address < end_address: 9055 ↛ 9056line 9055 didn't jump to line 9056, because the condition on line 9055 was never true

+

9056 color = self["function_not_resolved"] 

+

9057 else: 

+

9058 color = self["function_resolved"] 

+

9059 

+

9060 line = f"[{hex(address_val)}] " 

+

9061 line += Color.colorify(f"{name} {RIGHT_ARROW} {hex(got_address)}", color) 

+

9062 gef_print(line) 

+

9063 return 

+

9064 

+

9065 

+

9066@register 

+

9067class HighlightCommand(GenericCommand): 

+

9068 """Highlight user-defined text matches in GEF output universally.""" 

+

9069 _cmdline_ = "highlight" 

+

9070 _syntax_ = f"{_cmdline_} (add|remove|list|clear)" 

+

9071 _aliases_ = ["hl"] 

+

9072 

+

9073 def __init__(self) -> None: 

+

9074 super().__init__(prefix=True) 

+

9075 self["regex"] = (False, "Enable regex highlighting") 

+

9076 

+

9077 def do_invoke(self, _: List[str]) -> None: 

+

9078 return self.usage() 

+

9079 

+

9080 

+

9081@register 

+

9082class HighlightListCommand(GenericCommand): 

+

9083 """Show the current highlight table with matches to colors.""" 

+

9084 _cmdline_ = "highlight list" 

+

9085 _aliases_ = ["highlight ls", "hll"] 

+

9086 _syntax_ = _cmdline_ 

+

9087 

+

9088 def print_highlight_table(self) -> None: 

+

9089 if not gef.ui.highlight_table: 

+

9090 err("no matches found") 

+

9091 return 

+

9092 

+

9093 left_pad = max(map(len, gef.ui.highlight_table.keys())) 

+

9094 for match, color in sorted(gef.ui.highlight_table.items()): 

+

9095 print(f"{Color.colorify(match.ljust(left_pad), color)} {VERTICAL_LINE} " 

+

9096 f"{Color.colorify(color, color)}") 

+

9097 return 

+

9098 

+

9099 def do_invoke(self, _: List[str]) -> None: 

+

9100 return self.print_highlight_table() 

+

9101 

+

9102 

+

9103@register 

+

9104class HighlightClearCommand(GenericCommand): 

+

9105 """Clear the highlight table, remove all matches.""" 

+

9106 _cmdline_ = "highlight clear" 

+

9107 _aliases_ = ["hlc"] 

+

9108 _syntax_ = _cmdline_ 

+

9109 

+

9110 def do_invoke(self, _: List[str]) -> None: 

+

9111 return gef.ui.highlight_table.clear() 

+

9112 

+

9113 

+

9114@register 

+

9115class HighlightAddCommand(GenericCommand): 

+

9116 """Add a match to the highlight table.""" 

+

9117 _cmdline_ = "highlight add" 

+

9118 _syntax_ = f"{_cmdline_} MATCH COLOR" 

+

9119 _aliases_ = ["highlight set", "hla"] 

+

9120 _example_ = f"{_cmdline_} 41414141 yellow" 

+

9121 

+

9122 def do_invoke(self, argv: List[str]) -> None: 

+

9123 if len(argv) < 2: 9123 ↛ 9124line 9123 didn't jump to line 9124, because the condition on line 9123 was never true

+

9124 return self.usage() 

+

9125 

+

9126 match, color = argv 

+

9127 gef.ui.highlight_table[match] = color 

+

9128 return 

+

9129 

+

9130 

+

9131@register 

+

9132class HighlightRemoveCommand(GenericCommand): 

+

9133 """Remove a match in the highlight table.""" 

+

9134 _cmdline_ = "highlight remove" 

+

9135 _syntax_ = f"{_cmdline_} MATCH" 

+

9136 _aliases_ = [ 

+

9137 "highlight delete", 

+

9138 "highlight del", 

+

9139 "highlight unset", 

+

9140 "highlight rm", 

+

9141 "hlr", 

+

9142 ] 

+

9143 _example_ = f"{_cmdline_} remove 41414141" 

+

9144 

+

9145 def do_invoke(self, argv: List[str]) -> None: 

+

9146 if not argv: 

+

9147 return self.usage() 

+

9148 

+

9149 gef.ui.highlight_table.pop(argv[0], None) 

+

9150 return 

+

9151 

+

9152 

+

9153@register 

+

9154class FormatStringSearchCommand(GenericCommand): 

+

9155 """Exploitable format-string helper: this command will set up specific breakpoints 

+

9156 at well-known dangerous functions (printf, snprintf, etc.), and check if the pointer 

+

9157 holding the format string is writable, and therefore susceptible to format string 

+

9158 attacks if an attacker can control its content.""" 

+

9159 _cmdline_ = "format-string-helper" 

+

9160 _syntax_ = _cmdline_ 

+

9161 _aliases_ = ["fmtstr-helper",] 

+

9162 

+

9163 def do_invoke(self, _: List[str]) -> None: 

+

9164 dangerous_functions = { 

+

9165 "printf": 0, 

+

9166 "sprintf": 1, 

+

9167 "fprintf": 1, 

+

9168 "snprintf": 2, 

+

9169 "vsnprintf": 2, 

+

9170 } 

+

9171 

+

9172 nb_installed_breaks = 0 

+

9173 

+

9174 with RedirectOutputContext(to="/dev/null"): 

+

9175 for function_name in dangerous_functions: 

+

9176 argument_number = dangerous_functions[function_name] 

+

9177 FormatStringBreakpoint(function_name, argument_number) 

+

9178 nb_installed_breaks += 1 

+

9179 

+

9180 ok(f"Enabled {nb_installed_breaks} FormatString " 

+

9181 f"breakpoint{'s' if nb_installed_breaks > 1 else ''}") 

+

9182 return 

+

9183 

+

9184 

+

9185@register 

+

9186class HeapAnalysisCommand(GenericCommand): 

+

9187 """Heap vulnerability analysis helper: this command aims to track dynamic heap allocation 

+

9188 done through malloc()/free() to provide some insights on possible heap vulnerabilities. The 

+

9189 following vulnerabilities are checked: 

+

9190 - NULL free 

+

9191 - Use-after-Free 

+

9192 - Double Free 

+

9193 - Heap overlap""" 

+

9194 _cmdline_ = "heap-analysis-helper" 

+

9195 _syntax_ = _cmdline_ 

+

9196 

+

9197 def __init__(self) -> None: 

+

9198 super().__init__(complete=gdb.COMPLETE_NONE) 

+

9199 self["check_free_null"] = (False, "Break execution when a free(NULL) is encountered") 

+

9200 self["check_double_free"] = (True, "Break execution when a double free is encountered") 

+

9201 self["check_weird_free"] = (True, "Break execution when free() is called against a non-tracked pointer") 

+

9202 self["check_uaf"] = (True, "Break execution when a possible Use-after-Free condition is found") 

+

9203 self["check_heap_overlap"] = (True, "Break execution when a possible overlap in allocation is found") 

+

9204 

+

9205 self.bp_malloc = None 

+

9206 self.bp_calloc = None 

+

9207 self.bp_free = None 

+

9208 self.bp_realloc = None 

+

9209 return 

+

9210 

+

9211 @only_if_gdb_running 

+

9212 @experimental_feature 

+

9213 def do_invoke(self, argv: List[str]) -> None: 

+

9214 if not argv: 9214 ↛ 9218line 9214 didn't jump to line 9218, because the condition on line 9214 was never false

+

9215 self.setup() 

+

9216 return 

+

9217 

+

9218 if argv[0] == "show": 

+

9219 self.dump_tracked_allocations() 

+

9220 return 

+

9221 

+

9222 def setup(self) -> None: 

+

9223 ok("Tracking malloc() & calloc()") 

+

9224 self.bp_malloc = TraceMallocBreakpoint("__libc_malloc") 

+

9225 self.bp_calloc = TraceMallocBreakpoint("__libc_calloc") 

+

9226 ok("Tracking free()") 

+

9227 self.bp_free = TraceFreeBreakpoint() 

+

9228 ok("Tracking realloc()") 

+

9229 self.bp_realloc = TraceReallocBreakpoint() 

+

9230 

+

9231 ok("Disabling hardware watchpoints (this may increase the latency)") 

+

9232 gdb.execute("set can-use-hw-watchpoints 0") 

+

9233 

+

9234 info("Dynamic breakpoints correctly setup, " 

+

9235 "GEF will break execution if a possible vulnerabity is found.") 

+

9236 warn(f"{Color.colorify('Note', 'bold underline yellow')}: " 

+

9237 "The heap analysis slows down the execution noticeably.") 

+

9238 

+

9239 # when inferior quits, we need to clean everything for a next execution 

+

9240 gef_on_exit_hook(self.clean) 

+

9241 return 

+

9242 

+

9243 def dump_tracked_allocations(self) -> None: 

+

9244 global gef 

+

9245 

+

9246 if gef.session.heap_allocated_chunks: 

+

9247 ok("Tracked as in-use chunks:") 

+

9248 for addr, sz in gef.session.heap_allocated_chunks: 

+

9249 gef_print(f"{CROSS} malloc({sz:d}) = {addr:#x}") 

+

9250 else: 

+

9251 ok("No malloc() chunk tracked") 

+

9252 

+

9253 if gef.session.heap_freed_chunks: 

+

9254 ok("Tracked as free-ed chunks:") 

+

9255 for addr, sz in gef.session.heap_freed_chunks: 

+

9256 gef_print(f"{TICK} free({sz:d}) = {addr:#x}") 

+

9257 else: 

+

9258 ok("No free() chunk tracked") 

+

9259 return 

+

9260 

+

9261 def clean(self, _: "gdb.Event") -> None: 

+

9262 global gef 

+

9263 

+

9264 ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - Cleaning up") 

+

9265 for bp in [self.bp_malloc, self.bp_calloc, self.bp_free, self.bp_realloc]: 

+

9266 if hasattr(bp, "retbp") and bp.retbp: 9266 ↛ 9274line 9266 didn't jump to line 9274, because the condition on line 9266 was never false

+

9267 try: 

+

9268 bp.retbp.delete() 

+

9269 except RuntimeError: 

+

9270 # in some cases, gdb was found failing to correctly remove the retbp 

+

9271 # but they can be safely ignored since the debugging session is over 

+

9272 pass 

+

9273 

+

9274 bp.delete() 

+

9275 

+

9276 for wp in gef.session.heap_uaf_watchpoints: 

+

9277 wp.delete() 

+

9278 

+

9279 gef.session.heap_allocated_chunks = [] 

+

9280 gef.session.heap_freed_chunks = [] 

+

9281 gef.session.heap_uaf_watchpoints = [] 

+

9282 

+

9283 ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - Re-enabling hardware watchpoints") 

+

9284 gdb.execute("set can-use-hw-watchpoints 1") 

+

9285 

+

9286 gef_on_exit_unhook(self.clean) 

+

9287 return 

+

9288 

+

9289 

+

9290# 

+

9291# GDB Function declaration 

+

9292# 

+

9293@deprecated("") 

+

9294def register_function(cls: Type["GenericFunction"]) -> Type["GenericFunction"]: 

+

9295 """Decorator for registering a new convenience function to GDB.""" 

+

9296 return cls 

+

9297 

+

9298 

+

9299class GenericFunction(gdb.Function): 

+

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

+

9301 

+

9302 _function_ : str 

+

9303 _syntax_: str = "" 

+

9304 _example_ : str = "" 

+

9305 

+

9306 def __init__(self) -> None: 

+

9307 super().__init__(self._function_) 

+

9308 

+

9309 def invoke(self, *args: Any) -> int: 

+

9310 if not is_alive(): 

+

9311 raise gdb.GdbError("No debugging session active") 

+

9312 return self.do_invoke(args) 

+

9313 

+

9314 def arg_to_long(self, args: List, index: int, default: int = 0) -> int: 

+

9315 try: 

+

9316 addr = args[index] 

+

9317 return int(addr) if addr.address is None else int(addr.address) 

+

9318 except IndexError: 

+

9319 return default 

+

9320 

+

9321 def do_invoke(self, args: Any) -> int: 

+

9322 raise NotImplementedError 

+

9323 

+

9324 

+

9325@register 

+

9326class StackOffsetFunction(GenericFunction): 

+

9327 """Return the current stack base address plus an optional offset.""" 

+

9328 _function_ = "_stack" 

+

9329 _syntax_ = f"${_function_}()" 

+

9330 

+

9331 def do_invoke(self, args: List) -> int: 

+

9332 base = get_section_base_address("[stack]") 

+

9333 if not base: 9333 ↛ 9334line 9333 didn't jump to line 9334, because the condition on line 9333 was never true

+

9334 raise gdb.GdbError("Stack not found") 

+

9335 

+

9336 return self.arg_to_long(args, 0) + base 

+

9337 

+

9338 

+

9339@register 

+

9340class HeapBaseFunction(GenericFunction): 

+

9341 """Return the current heap base address plus an optional offset.""" 

+

9342 _function_ = "_heap" 

+

9343 _syntax_ = f"${_function_}()" 

+

9344 

+

9345 def do_invoke(self, args: List) -> int: 

+

9346 base = gef.heap.base_address 

+

9347 if not base: 9347 ↛ 9348line 9347 didn't jump to line 9348, because the condition on line 9347 was never true

+

9348 base = get_section_base_address("[heap]") 

+

9349 if not base: 

+

9350 raise gdb.GdbError("Heap not found") 

+

9351 return self.arg_to_long(args, 0) + base 

+

9352 

+

9353 

+

9354@register 

+

9355class SectionBaseFunction(GenericFunction): 

+

9356 """Return the matching file's base address plus an optional offset. 

+

9357 Defaults to current file. Note that quotes need to be escaped""" 

+

9358 _function_ = "_base" 

+

9359 _syntax_ = "$_base([filepath])" 

+

9360 _example_ = "p $_base(\\\"/usr/lib/ld-2.33.so\\\")" 

+

9361 

+

9362 def do_invoke(self, args: List) -> int: 

+

9363 addr = 0 

+

9364 try: 

+

9365 name = args[0].string() 

+

9366 except IndexError: 9366 ↛ 9368line 9366 didn't jump to line 9368

+

9367 name = gef.session.file.name 

+

9368 except gdb.error: 

+

9369 err(f"Invalid arg: {args[0]}") 

+

9370 return 0 

+

9371 

+

9372 try: 

+

9373 base = get_section_base_address(name) 

+

9374 if base: 9374 ↛ 9379line 9374 didn't jump to line 9379, because the condition on line 9374 was never false

+

9375 addr = int(base) 

+

9376 except TypeError: 

+

9377 err(f"Cannot find section {name}") 

+

9378 return 0 

+

9379 return addr 

+

9380 

+

9381 

+

9382@register 

+

9383class BssBaseFunction(GenericFunction): 

+

9384 """Return the current bss base address plus the given offset.""" 

+

9385 _function_ = "_bss" 

+

9386 _syntax_ = f"${_function_}([OFFSET])" 

+

9387 _example_ = "deref $_bss(0x20)" 

+

9388 

+

9389 def do_invoke(self, args: List) -> int: 

+

9390 base = get_zone_base_address(".bss") 

+

9391 if not base: 9391 ↛ 9392line 9391 didn't jump to line 9392, because the condition on line 9391 was never true

+

9392 raise gdb.GdbError("BSS not found") 

+

9393 return self.arg_to_long(args, 0) + base 

+

9394 

+

9395 

+

9396@register 

+

9397class GotBaseFunction(GenericFunction): 

+

9398 """Return the current GOT base address plus the given offset.""" 

+

9399 _function_ = "_got" 

+

9400 _syntax_ = f"${_function_}([OFFSET])" 

+

9401 _example_ = "deref $_got(0x20)" 

+

9402 

+

9403 def do_invoke(self, args: List) -> int: 

+

9404 base = get_zone_base_address(".got") 

+

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("GOT not found") 

+

9407 return base + self.arg_to_long(args, 0) 

+

9408 

+

9409 

+

9410@register 

+

9411class GefFunctionsCommand(GenericCommand): 

+

9412 """List the convenience functions provided by GEF.""" 

+

9413 _cmdline_ = "functions" 

+

9414 _syntax_ = _cmdline_ 

+

9415 

+

9416 def __init__(self) -> None: 

+

9417 super().__init__() 

+

9418 self.docs = [] 

+

9419 self.should_refresh = True 

+

9420 return 

+

9421 

+

9422 def __add__(self, function: GenericFunction): 

+

9423 """Add function to documentation.""" 

+

9424 doc = getattr(function, "__doc__", "").lstrip() 

+

9425 if not hasattr(function, "_syntax_"): 9425 ↛ 9426line 9425 didn't jump to line 9426, because the condition on line 9425 was never true

+

9426 raise ValueError("Function is invalid") 

+

9427 syntax = getattr(function, "_syntax_").lstrip() 

+

9428 msg = f"{Color.colorify(syntax, 'bold cyan')}\n {doc}" 

+

9429 example = getattr(function, "_example_", "").strip() 

+

9430 if example: 

+

9431 msg += f"\n {Color.yellowify('Example:')} {example}" 

+

9432 self.docs.append(msg) 

+

9433 return self 

+

9434 

+

9435 def __radd__(self, function: GenericFunction): 

+

9436 return self.__add__(function) 

+

9437 

+

9438 def __str__(self) -> str: 

+

9439 if self.should_refresh: 9439 ↛ 9441line 9439 didn't jump to line 9441, because the condition on line 9439 was never false

+

9440 self.__rebuild() 

+

9441 return self.__doc__ or "" 

+

9442 

+

9443 def __rebuild(self) -> None: 

+

9444 """Rebuild the documentation for functions.""" 

+

9445 for function in gef.gdb.functions.values(): 

+

9446 self += function 

+

9447 

+

9448 self.command_size = len(gef.gdb.commands) 

+

9449 _, cols = get_terminal_size() 

+

9450 separator = HORIZONTAL_LINE*cols 

+

9451 self.__doc__ = f"\n{separator}\n".join(sorted(self.docs)) 

+

9452 self.should_refresh = False 

+

9453 return 

+

9454 

+

9455 def do_invoke(self, argv) -> None: 

+

9456 self.dont_repeat() 

+

9457 gef_print(titlify("GEF - Convenience Functions")) 

+

9458 gef_print("These functions can be used as arguments to other " 

+

9459 "commands to dynamically calculate values\n") 

+

9460 gef_print(str(self)) 

+

9461 return 

+

9462 

+

9463 

+

9464# 

+

9465# GEF internal command classes 

+

9466# 

+

9467class GefCommand(gdb.Command): 

+

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

+

9469 

+

9470 _cmdline_ = "gef" 

+

9471 _syntax_ = f"{_cmdline_} (missing|config|save|restore|set|run)" 

+

9472 

+

9473 def __init__(self) -> None: 

+

9474 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, True) 

+

9475 gef.config["gef.follow_child"] = GefSetting(True, bool, "Automatically set GDB to follow child when forking") 

+

9476 gef.config["gef.readline_compat"] = GefSetting(False, bool, "Workaround for readline SOH/ETX issue (SEGV)") 

+

9477 gef.config["gef.debug"] = GefSetting(False, bool, "Enable debug mode for gef") 

+

9478 gef.config["gef.autosave_breakpoints_file"] = GefSetting("", str, "Automatically save and restore breakpoints") 

+

9479 gef.config["gef.extra_plugins_dir"] = GefSetting("", str, "Autoload additional GEF commands from external directory", hooks={"on_write": self.load_extra_plugins}) 

+

9480 gef.config["gef.disable_color"] = GefSetting(False, bool, "Disable all colors in GEF") 

+

9481 gef.config["gef.tempdir"] = GefSetting(GEF_TEMP_DIR, str, "Directory to use for temporary/cache content") 

+

9482 gef.config["gef.show_deprecation_warnings"] = GefSetting(True, bool, "Toggle the display of the `deprecated` warnings") 

+

9483 gef.config["gef.buffer"] = GefSetting(True, bool, "Internally buffer command output until completion") 

+

9484 gef.config["gef.bruteforce_main_arena"] = GefSetting(False, bool, "Allow bruteforcing main_arena symbol if everything else fails") 

+

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

+

9486 

+

9487 self.commands : Dict[str, GenericCommand] = collections.OrderedDict() 

+

9488 self.functions : Dict[str, GenericFunction] = collections.OrderedDict() 

+

9489 self.missing: Dict[str, Exception] = {} 

+

9490 return 

+

9491 

+

9492 @property 

+

9493 def loaded_commands(self) -> List[Tuple[str, Type[GenericCommand], Any]]: 

+

9494 print("Obsolete loaded_commands") 

+

9495 raise 

+

9496 

+

9497 @property 

+

9498 def loaded_functions(self) -> List[Type[GenericFunction]]: 

+

9499 print("Obsolete loaded_functions") 

+

9500 raise 

+

9501 

+

9502 @property 

+

9503 def missing_commands(self) -> Dict[str, Exception]: 

+

9504 print("Obsolete missing_commands") 

+

9505 raise 

+

9506 

+

9507 def setup(self) -> None: 

+

9508 self.load() 

+

9509 

+

9510 GefHelpCommand() 

+

9511 GefConfigCommand() 

+

9512 GefSaveCommand() 

+

9513 GefMissingCommand() 

+

9514 GefSetCommand() 

+

9515 GefRunCommand() 

+

9516 GefInstallExtraScriptCommand() 

+

9517 

+

9518 # restore the settings from config file if any 

+

9519 GefRestoreCommand() 

+

9520 return 

+

9521 

+

9522 def load_extra_plugins(self) -> int: 

+

9523 def load_plugin(fpath: pathlib.Path) -> bool: 

+

9524 try: 

+

9525 dbg(f"Loading '{fpath}'") 

+

9526 gdb.execute(f"source {fpath}") 

+

9527 except Exception as e: 

+

9528 warn(f"Exception while loading {fpath}: {str(e)}") 

+

9529 return False 

+

9530 return True 

+

9531 

+

9532 nb_added = -1 

+

9533 start_time = time.perf_counter() 

+

9534 try: 

+

9535 nb_inital = len(__registered_commands__) 

+

9536 directories: List[str] = gef.config["gef.extra_plugins_dir"].split(";") or [] 

+

9537 for d in directories: 

+

9538 d = d.strip() 

+

9539 if not d: continue 9539 ↛ 9540line 9539 didn't jump to line 9540, because the condition on line 9539 was never false

+

9540 directory = pathlib.Path(d).expanduser() 

+

9541 if not directory.is_dir(): continue 

+

9542 sys.path.append(str(directory.absolute())) 

+

9543 for entry in directory.iterdir(): 

+

9544 if entry.is_dir(): 

+

9545 if entry.name in ('gdb', 'gef', '__pycache__'): continue 

+

9546 load_plugin(entry / "__init__.py") 

+

9547 else: 

+

9548 if entry.suffix != ".py": continue 

+

9549 if entry.name == "__init__.py": continue 

+

9550 load_plugin(entry) 

+

9551 

+

9552 nb_added = len(__registered_commands__) - nb_inital 

+

9553 if nb_added > 0: 9553 ↛ 9554line 9553 didn't jump to line 9554, because the condition on line 9553 was never true

+

9554 self.load() 

+

9555 nb_failed = len(__registered_commands__) - len(self.commands) 

+

9556 end_time = time.perf_counter() 

+

9557 load_time = end_time - start_time 

+

9558 ok(f"{Color.colorify(str(nb_added), 'bold green')} extra commands added from " 

+

9559 f"'{Color.colorify(', '.join(directories), 'bold blue')}' in {load_time:.2f} seconds") 

+

9560 if nb_failed != 0: 

+

9561 warn(f"{Color.colorify(str(nb_failed), 'bold light_gray')} extra commands/functions failed to be added. " 

+

9562 "Check `gef missing` to know why") 

+

9563 

+

9564 except gdb.error as e: 

+

9565 err(f"failed: {e}") 

+

9566 return nb_added 

+

9567 

+

9568 @property 

+

9569 def loaded_command_names(self) -> Iterable[str]: 

+

9570 print("obsolete loaded_command_names") 

+

9571 return self.commands.keys() 

+

9572 

+

9573 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9574 self.dont_repeat() 

+

9575 gdb.execute("gef help") 

+

9576 return 

+

9577 

+

9578 def add_context_pane(self, pane_name: str, display_pane_function: Callable, pane_title_function: Callable, condition: Optional[Callable]) -> None: 

+

9579 """Add a new context pane to ContextCommand.""" 

+

9580 for _, class_instance in self.commands.items(): 

+

9581 if isinstance(class_instance, ContextCommand): 

+

9582 context = class_instance 

+

9583 break 

+

9584 else: 

+

9585 err("Cannot find ContextCommand") 

+

9586 return 

+

9587 

+

9588 # assure users can toggle the new context 

+

9589 corrected_settings_name = pane_name.replace(" ", "_") 

+

9590 gef.config["context.layout"] += f" {corrected_settings_name}" 

+

9591 

+

9592 # overload the printing of pane title 

+

9593 context.layout_mapping[corrected_settings_name] = (display_pane_function, pane_title_function, condition) 

+

9594 

+

9595 def load(self) -> None: 

+

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

+

9597 current_commands = set( self.commands.keys() ) 

+

9598 new_commands = set( [x._cmdline_ for x in __registered_commands__] ) - current_commands 

+

9599 current_functions = set( self.functions.keys() ) 

+

9600 new_functions = set([x._function_ for x in __registered_functions__]) - current_functions 

+

9601 self.missing.clear() 

+

9602 self.__load_time_ms = time.time()* 1000 

+

9603 

+

9604 # load all new functions 

+

9605 for name in sorted(new_functions): 

+

9606 for function_cls in __registered_functions__: 9606 ↛ 9605line 9606 didn't jump to line 9605, because the loop on line 9606 didn't complete

+

9607 if function_cls._function_ == name: 

+

9608 self.functions[name] = function_cls() 

+

9609 break 

+

9610 

+

9611 # load all new commands 

+

9612 for name in sorted(new_commands): 

+

9613 try: 

+

9614 for command_cls in __registered_commands__: 9614 ↛ 9612line 9614 didn't jump to line 9612, because the loop on line 9614 didn't complete

+

9615 if command_cls._cmdline_ == name: 

+

9616 command_instance = command_cls() 

+

9617 

+

9618 # create the aliases if any 

+

9619 if hasattr(command_instance, "_aliases_"): 

+

9620 aliases = getattr(command_instance, "_aliases_") 

+

9621 for alias in aliases: 

+

9622 GefAlias(alias, name) 

+

9623 

+

9624 self.commands[name] = command_instance 

+

9625 break 

+

9626 

+

9627 except Exception as reason: 

+

9628 self.missing[name] = reason 

+

9629 

+

9630 self.__load_time_ms = (time.time()* 1000) - self.__load_time_ms 

+

9631 return 

+

9632 

+

9633 

+

9634 def show_banner(self) -> None: 

+

9635 gef_print(f"{Color.greenify('GEF')} for {gef.session.os} ready, " 

+

9636 f"type `{Color.colorify('gef', 'underline yellow')}' to start, " 

+

9637 f"`{Color.colorify('gef config', 'underline pink')}' to configure") 

+

9638 

+

9639 ver = f"{sys.version_info.major:d}.{sys.version_info.minor:d}" 

+

9640 gef_print(f"{Color.colorify(str(len(self.commands)), 'bold green')} commands loaded " 

+

9641 f"and {Color.colorify(str(len(self.functions)), 'bold blue')} functions added for " 

+

9642 f"GDB {Color.colorify(gdb.VERSION, 'bold yellow')} in {self.__load_time_ms:.2f}ms " 

+

9643 f"using Python engine {Color.colorify(ver, 'bold red')}") 

+

9644 

+

9645 nb_missing = len(self.missing) 

+

9646 if nb_missing: 9646 ↛ 9647line 9646 didn't jump to line 9647, because the condition on line 9646 was never true

+

9647 warn(f"{Color.colorify(str(nb_missing), 'bold red')} " 

+

9648 f"command{'s' if nb_missing > 1 else ''} could not be loaded, " 

+

9649 f"run `{Color.colorify('gef missing', 'underline pink')}` to know why.") 

+

9650 return 

+

9651 

+

9652 

+

9653class GefHelpCommand(gdb.Command): 

+

9654 """GEF help sub-command.""" 

+

9655 _cmdline_ = "gef help" 

+

9656 _syntax_ = _cmdline_ 

+

9657 

+

9658 def __init__(self) -> None: 

+

9659 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) 

+

9660 self.docs = [] 

+

9661 self.should_refresh = True 

+

9662 self.command_size = 0 

+

9663 return 

+

9664 

+

9665 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9666 self.dont_repeat() 

+

9667 gef_print(titlify("GEF - GDB Enhanced Features")) 

+

9668 gef_print(str(self)) 

+

9669 return 

+

9670 

+

9671 def __rebuild(self) -> None: 

+

9672 """Rebuild the documentation.""" 

+

9673 for name, cmd in gef.gdb.commands.items(): 

+

9674 self += (name, cmd) 

+

9675 

+

9676 self.command_size = len(gef.gdb.commands) 

+

9677 _, cols = get_terminal_size() 

+

9678 separator = HORIZONTAL_LINE*cols 

+

9679 self.__doc__ = f"\n{separator}\n".join(sorted(self.docs)) 

+

9680 self.should_refresh = False 

+

9681 return 

+

9682 

+

9683 def __add__(self, command: Tuple[str, GenericCommand]): 

+

9684 """Add command to GEF documentation.""" 

+

9685 cmd, class_obj = command 

+

9686 if " " in cmd: 

+

9687 # do not print subcommands in gef help 

+

9688 return self 

+

9689 doc = getattr(class_obj, "__doc__", "").lstrip() 

+

9690 aliases = f"Aliases: {', '.join(class_obj._aliases_)}" if hasattr(class_obj, "_aliases_") else "" 

+

9691 msg = f"{Color.colorify(cmd, 'bold red')}\n{doc}\n{aliases}" 

+

9692 self.docs.append(msg) 

+

9693 return self 

+

9694 

+

9695 def __radd__(self, command: Tuple[str, GenericCommand]): 

+

9696 return self.__add__(command) 

+

9697 

+

9698 def __str__(self) -> str: 

+

9699 """Lazily regenerate the `gef help` object if it was modified""" 

+

9700 # quick check in case the docs have changed 

+

9701 if self.should_refresh or self.command_size != len(gef.gdb.commands): 9701 ↛ 9703line 9701 didn't jump to line 9703, because the condition on line 9701 was never false

+

9702 self.__rebuild() 

+

9703 return self.__doc__ or "" 

+

9704 

+

9705 

+

9706class GefConfigCommand(gdb.Command): 

+

9707 """GEF configuration sub-command 

+

9708 This command will help set/view GEF settings for the current debugging session. 

+

9709 It is possible to make those changes permanent by running `gef save` (refer 

+

9710 to this command help), and/or restore previously saved settings by running 

+

9711 `gef restore` (refer help). 

+

9712 """ 

+

9713 _cmdline_ = "gef config" 

+

9714 _syntax_ = f"{_cmdline_} [setting_name] [setting_value]" 

+

9715 

+

9716 def __init__(self) -> None: 

+

9717 super().__init__(self._cmdline_, gdb.COMMAND_NONE, prefix=False) 

+

9718 return 

+

9719 

+

9720 def invoke(self, args: str, from_tty: bool) -> None: 

+

9721 self.dont_repeat() 

+

9722 argv = gdb.string_to_argv(args) 

+

9723 argc = len(argv) 

+

9724 

+

9725 if not (0 <= argc <= 2): 9725 ↛ 9726line 9725 didn't jump to line 9726, because the condition on line 9725 was never true

+

9726 err("Invalid number of arguments") 

+

9727 return 

+

9728 

+

9729 if argc == 0: 

+

9730 gef_print(titlify("GEF configuration settings")) 

+

9731 self.print_settings() 

+

9732 return 

+

9733 

+

9734 if argc == 1: 

+

9735 prefix = argv[0] 

+

9736 names = [x for x in gef.config.keys() if x.startswith(prefix)] 

+

9737 if names: 9737 ↛ 9744line 9737 didn't jump to line 9744, because the condition on line 9737 was never false

+

9738 if len(names) == 1: 9738 ↛ 9742line 9738 didn't jump to line 9742, because the condition on line 9738 was never false

+

9739 gef_print(titlify(f"GEF configuration setting: {names[0]}")) 

+

9740 self.print_setting(names[0], verbose=True) 

+

9741 else: 

+

9742 gef_print(titlify(f"GEF configuration settings matching '{argv[0]}'")) 

+

9743 for name in names: self.print_setting(name) 

+

9744 return 

+

9745 

+

9746 self.set_setting(argv) 

+

9747 return 

+

9748 

+

9749 def print_setting(self, plugin_name: str, verbose: bool = False) -> None: 

+

9750 res = gef.config.raw_entry(plugin_name) 

+

9751 string_color = gef.config["theme.dereference_string"] 

+

9752 misc_color = gef.config["theme.dereference_base_address"] 

+

9753 

+

9754 if not res: 9754 ↛ 9755line 9754 didn't jump to line 9755, because the condition on line 9754 was never true

+

9755 return 

+

9756 

+

9757 _setting = Color.colorify(plugin_name, "green") 

+

9758 _type = res.type.__name__ 

+

9759 if _type == "str": 

+

9760 _value = f'"{Color.colorify(res.value, string_color)}"' 

+

9761 else: 

+

9762 _value = Color.colorify(res.value, misc_color) 

+

9763 

+

9764 gef_print(f"{_setting} ({_type}) = {_value}") 

+

9765 

+

9766 if verbose: 

+

9767 gef_print(Color.colorify("\nDescription:", "bold underline")) 

+

9768 gef_print(f"\t{res.description}") 

+

9769 return 

+

9770 

+

9771 def print_settings(self) -> None: 

+

9772 for x in sorted(gef.config): 

+

9773 self.print_setting(x) 

+

9774 return 

+

9775 

+

9776 def set_setting(self, argv: Tuple[str, Any]) -> None: 

+

9777 global gef 

+

9778 key, new_value = argv 

+

9779 

+

9780 if "." not in key: 9780 ↛ 9781line 9780 didn't jump to line 9781, because the condition on line 9780 was never true

+

9781 err("Invalid command format") 

+

9782 return 

+

9783 

+

9784 loaded_commands = list( gef.gdb.commands.keys()) + ["gef"] 

+

9785 plugin_name = key.split(".", 1)[0] 

+

9786 if plugin_name not in loaded_commands: 9786 ↛ 9787line 9786 didn't jump to line 9787, because the condition on line 9786 was never true

+

9787 err(f"Unknown plugin '{plugin_name}'") 

+

9788 return 

+

9789 

+

9790 if key not in gef.config: 9790 ↛ 9791line 9790 didn't jump to line 9791, because the condition on line 9790 was never true

+

9791 err(f"'{key}' is not a valid configuration setting") 

+

9792 return 

+

9793 

+

9794 _type = gef.config.raw_entry(key).type 

+

9795 try: 

+

9796 if _type == bool: 

+

9797 _newval = True if new_value.upper() in ("TRUE", "T", "1") else False 

+

9798 else: 

+

9799 _newval = new_value 

+

9800 

+

9801 gef.config[key] = _newval 

+

9802 except Exception as e: 

+

9803 err(f"'{key}' expects type '{_type.__name__}', got {type(new_value).__name__}: reason {str(e)}") 

+

9804 return 

+

9805 

+

9806 reset_all_caches() 

+

9807 return 

+

9808 

+

9809 def complete(self, text: str, word: str) -> List[str]: 

+

9810 settings = sorted(gef.config) 

+

9811 

+

9812 if text == "": 

+

9813 # no prefix: example: `gef config TAB` 

+

9814 return [s for s in settings if word in s] 

+

9815 

+

9816 if "." not in text: 

+

9817 # if looking for possible prefix 

+

9818 return [s for s in settings if s.startswith(text.strip())] 

+

9819 

+

9820 # finally, look for possible values for given prefix 

+

9821 return [s.split(".", 1)[1] for s in settings if s.startswith(text.strip())] 

+

9822 

+

9823 

+

9824class GefSaveCommand(gdb.Command): 

+

9825 """GEF save sub-command. 

+

9826 Saves the current configuration of GEF to disk (by default in file '~/.gef.rc').""" 

+

9827 _cmdline_ = "gef save" 

+

9828 _syntax_ = _cmdline_ 

+

9829 

+

9830 def __init__(self) -> None: 

+

9831 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) 

+

9832 return 

+

9833 

+

9834 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9835 self.dont_repeat() 

+

9836 cfg = configparser.RawConfigParser() 

+

9837 old_sect = None 

+

9838 

+

9839 # save the configuration 

+

9840 for key in sorted(gef.config): 

+

9841 sect, optname = key.split(".", 1) 

+

9842 value = gef.config[key] 

+

9843 

+

9844 if old_sect != sect: 

+

9845 cfg.add_section(sect) 

+

9846 old_sect = sect 

+

9847 

+

9848 cfg.set(sect, optname, value) 

+

9849 

+

9850 # save the aliases 

+

9851 cfg.add_section("aliases") 

+

9852 for alias in gef.session.aliases: 

+

9853 cfg.set("aliases", alias._alias, alias._command) 

+

9854 

+

9855 with GEF_RC.open("w") as fd: 

+

9856 cfg.write(fd) 

+

9857 

+

9858 ok(f"Configuration saved to '{GEF_RC}'") 

+

9859 return 

+

9860 

+

9861 

+

9862class GefRestoreCommand(gdb.Command): 

+

9863 """GEF restore sub-command. 

+

9864 Loads settings from file '~/.gef.rc' and apply them to the configuration of GEF.""" 

+

9865 _cmdline_ = "gef restore" 

+

9866 _syntax_ = _cmdline_ 

+

9867 

+

9868 def __init__(self) -> None: 

+

9869 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) 

+

9870 self.reload(True) 

+

9871 return 

+

9872 

+

9873 def invoke(self, args: str, from_tty: bool) -> None: 

+

9874 self.dont_repeat() 

+

9875 if GEF_RC.is_file(): 

+

9876 quiet = (args.lower() == "quiet") 

+

9877 self.reload(quiet) 

+

9878 return 

+

9879 

+

9880 def reload(self, quiet: bool): 

+

9881 cfg = configparser.ConfigParser() 

+

9882 cfg.read(GEF_RC) 

+

9883 

+

9884 for section in cfg.sections(): 

+

9885 if section == "aliases": 

+

9886 # load the aliases 

+

9887 for key in cfg.options(section): 

+

9888 try: 

+

9889 GefAlias(key, cfg.get(section, key)) 

+

9890 except: 

+

9891 pass 

+

9892 continue 

+

9893 

+

9894 # load the other options 

+

9895 for optname in cfg.options(section): 

+

9896 key = f"{section}.{optname}" 

+

9897 try: 

+

9898 setting = gef.config.raw_entry(key) 

+

9899 except Exception: 

+

9900 continue 

+

9901 new_value = cfg.get(section, optname) 

+

9902 if setting.type == bool: 

+

9903 new_value = True if new_value.upper() in ("TRUE", "T", "1") else False 

+

9904 setting.value = setting.type(new_value) 

+

9905 

+

9906 if not quiet: 9906 ↛ 9907line 9906 didn't jump to line 9907, because the condition on line 9906 was never true

+

9907 ok(f"Configuration from '{Color.colorify(str(GEF_RC), 'bold blue')}' restored") 

+

9908 return 

+

9909 

+

9910 

+

9911class GefMissingCommand(gdb.Command): 

+

9912 """GEF missing sub-command 

+

9913 Display the GEF commands that could not be loaded, along with the reason of why 

+

9914 they could not be loaded. 

+

9915 """ 

+

9916 _cmdline_ = "gef missing" 

+

9917 _syntax_ = _cmdline_ 

+

9918 

+

9919 def __init__(self) -> None: 

+

9920 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) 

+

9921 return 

+

9922 

+

9923 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9924 self.dont_repeat() 

+

9925 missing_commands = gef.gdb.missing 

+

9926 if not missing_commands: 

+

9927 ok("No missing command") 

+

9928 return 

+

9929 

+

9930 for missing_command, reason in missing_commands.items(): 

+

9931 warn(f"Command `{missing_command}` is missing, reason {RIGHT_ARROW} {reason}") 

+

9932 return 

+

9933 

+

9934 

+

9935class GefSetCommand(gdb.Command): 

+

9936 """Override GDB set commands with the context from GEF.""" 

+

9937 _cmdline_ = "gef set" 

+

9938 _syntax_ = f"{_cmdline_} [GDB_SET_ARGUMENTS]" 

+

9939 

+

9940 def __init__(self) -> None: 

+

9941 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_SYMBOL, False) 

+

9942 return 

+

9943 

+

9944 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9945 self.dont_repeat() 

+

9946 args = args.split() 

+

9947 cmd = ["set", args[0],] 

+

9948 for p in args[1:]: 

+

9949 if p.startswith("$_gef"): 9949 ↛ 9953line 9949 didn't jump to line 9953, because the condition on line 9949 was never false

+

9950 c = gdb.parse_and_eval(p) 

+

9951 cmd.append(c.string()) 

+

9952 else: 

+

9953 cmd.append(p) 

+

9954 

+

9955 gdb.execute(" ".join(cmd)) 

+

9956 return 

+

9957 

+

9958 

+

9959class GefRunCommand(gdb.Command): 

+

9960 """Override GDB run commands with the context from GEF. 

+

9961 Simple wrapper for GDB run command to use arguments set from `gef set args`.""" 

+

9962 _cmdline_ = "gef run" 

+

9963 _syntax_ = f"{_cmdline_} [GDB_RUN_ARGUMENTS]" 

+

9964 

+

9965 def __init__(self) -> None: 

+

9966 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_FILENAME, False) 

+

9967 return 

+

9968 

+

9969 def invoke(self, args: Any, from_tty: bool) -> None: 

+

9970 self.dont_repeat() 

+

9971 if is_alive(): 

+

9972 gdb.execute("continue") 

+

9973 return 

+

9974 

+

9975 argv = args.split() 

+

9976 gdb.execute(f"gef set args {' '.join(argv)}") 

+

9977 gdb.execute("run") 

+

9978 return 

+

9979 

+

9980 

+

9981class GefAlias(gdb.Command): 

+

9982 """Simple aliasing wrapper because GDB doesn't do what it should.""" 

+

9983 

+

9984 def __init__(self, alias: str, command: str, completer_class: int = gdb.COMPLETE_NONE, command_class: int = gdb.COMMAND_NONE) -> None: 

+

9985 p = command.split() 

+

9986 if not p: 9986 ↛ 9987line 9986 didn't jump to line 9987, because the condition on line 9986 was never true

+

9987 return 

+

9988 

+

9989 if any(x for x in gef.session.aliases if x._alias == alias): 

+

9990 return 

+

9991 

+

9992 self._command = command 

+

9993 self._alias = alias 

+

9994 c = command.split()[0] 

+

9995 r = self.lookup_command(c) 

+

9996 self.__doc__ = f"Alias for '{Color.greenify(command)}'" 

+

9997 if r is not None: 

+

9998 _instance = r[1] 

+

9999 self.__doc__ += f": {_instance.__doc__}" 

+

10000 

+

10001 if hasattr(_instance, "complete"): 10001 ↛ 10002line 10001 didn't jump to line 10002, because the condition on line 10001 was never true

+

10002 self.complete = _instance.complete 

+

10003 

+

10004 super().__init__(alias, command_class, completer_class=completer_class) 

+

10005 gef.session.aliases.append(self) 

+

10006 return 

+

10007 

+

10008 def invoke(self, args: Any, from_tty: bool) -> None: 

+

10009 gdb.execute(f"{self._command} {args}", from_tty=from_tty) 

+

10010 return 

+

10011 

+

10012 def lookup_command(self, cmd: str) -> Optional[Tuple[str, GenericCommand]]: 

+

10013 global gef 

+

10014 for _name, _instance in gef.gdb.commands.items(): 

+

10015 if cmd == _name: 

+

10016 return _name, _instance 

+

10017 

+

10018 return None 

+

10019 

+

10020 

+

10021@register 

+

10022class AliasesCommand(GenericCommand): 

+

10023 """Base command to add, remove, or list aliases.""" 

+

10024 

+

10025 _cmdline_ = "aliases" 

+

10026 _syntax_ = f"{_cmdline_} (add|rm|ls)" 

+

10027 

+

10028 def __init__(self) -> None: 

+

10029 super().__init__(prefix=True) 

+

10030 return 

+

10031 

+

10032 def do_invoke(self, _: List[str]) -> None: 

+

10033 self.usage() 

+

10034 return 

+

10035 

+

10036 

+

10037@register 

+

10038class AliasesAddCommand(AliasesCommand): 

+

10039 """Command to add aliases.""" 

+

10040 

+

10041 _cmdline_ = "aliases add" 

+

10042 _syntax_ = f"{_cmdline_} [ALIAS] [COMMAND]" 

+

10043 _example_ = f"{_cmdline_} scope telescope" 

+

10044 

+

10045 def __init__(self) -> None: 

+

10046 super().__init__() 

+

10047 return 

+

10048 

+

10049 def do_invoke(self, argv: List[str]) -> None: 

+

10050 if len(argv) < 2: 10050 ↛ 10051line 10050 didn't jump to line 10051, because the condition on line 10050 was never true

+

10051 self.usage() 

+

10052 return 

+

10053 GefAlias(argv[0], " ".join(argv[1:])) 

+

10054 return 

+

10055 

+

10056 

+

10057@register 

+

10058class AliasesRmCommand(AliasesCommand): 

+

10059 """Command to remove aliases.""" 

+

10060 

+

10061 _cmdline_ = "aliases rm" 

+

10062 _syntax_ = f"{_cmdline_} [ALIAS]" 

+

10063 

+

10064 def __init__(self) -> None: 

+

10065 super().__init__() 

+

10066 return 

+

10067 

+

10068 def do_invoke(self, argv: List[str]) -> None: 

+

10069 global gef 

+

10070 if len(argv) != 1: 10070 ↛ 10071line 10070 didn't jump to line 10071, because the condition on line 10070 was never true

+

10071 self.usage() 

+

10072 return 

+

10073 try: 

+

10074 alias_to_remove = next(filter(lambda x: x._alias == argv[0], gef.session.aliases)) 

+

10075 gef.session.aliases.remove(alias_to_remove) 

+

10076 except (ValueError, StopIteration): 

+

10077 err(f"{argv[0]} not found in aliases.") 

+

10078 return 

+

10079 gef_print("You must reload GEF for alias removals to apply.") 

+

10080 return 

+

10081 

+

10082 

+

10083@register 

+

10084class AliasesListCommand(AliasesCommand): 

+

10085 """Command to list aliases.""" 

+

10086 

+

10087 _cmdline_ = "aliases ls" 

+

10088 _syntax_ = _cmdline_ 

+

10089 

+

10090 def __init__(self) -> None: 

+

10091 super().__init__() 

+

10092 return 

+

10093 

+

10094 def do_invoke(self, _: List[str]) -> None: 

+

10095 ok("Aliases defined:") 

+

10096 for a in gef.session.aliases: 

+

10097 gef_print(f"{a._alias:30s} {RIGHT_ARROW} {a._command}") 

+

10098 return 

+

10099 

+

10100 

+

10101class GefTmuxSetup(gdb.Command): 

+

10102 """Setup a confortable tmux debugging environment.""" 

+

10103 

+

10104 def __init__(self) -> None: 

+

10105 super().__init__("tmux-setup", gdb.COMMAND_NONE, gdb.COMPLETE_NONE) 

+

10106 GefAlias("screen-setup", "tmux-setup") 

+

10107 return 

+

10108 

+

10109 def invoke(self, args: Any, from_tty: bool) -> None: 

+

10110 self.dont_repeat() 

+

10111 

+

10112 tmux = os.getenv("TMUX") 

+

10113 if tmux: 

+

10114 self.tmux_setup() 

+

10115 return 

+

10116 

+

10117 screen = os.getenv("TERM") 

+

10118 if screen is not None and screen == "screen": 

+

10119 self.screen_setup() 

+

10120 return 

+

10121 

+

10122 warn("Not in a tmux/screen session") 

+

10123 return 

+

10124 

+

10125 def tmux_setup(self) -> None: 

+

10126 """Prepare the tmux environment by vertically splitting the current pane, and 

+

10127 forcing the context to be redirected there.""" 

+

10128 tmux = which("tmux") 

+

10129 ok("tmux session found, splitting window...") 

+

10130 

+

10131 pane, pty = subprocess.check_output([tmux, "splitw", "-h", '-F#{session_name}:#{window_index}.#{pane_index}-#{pane_tty}', "-P"]).decode().strip().split("-") 

+

10132 atexit.register(lambda : subprocess.run([tmux, "kill-pane", "-t", pane])) 

+

10133 # clear the screen and let it wait for input forever 

+

10134 gdb.execute(f"! {tmux} send-keys -t {pane} 'clear ; cat' C-m") 

+

10135 gdb.execute(f"! {tmux} select-pane -L") 

+

10136 

+

10137 ok(f"Setting `context.redirect` to '{pty}'...") 

+

10138 gdb.execute(f"gef config context.redirect {pty}") 

+

10139 ok("Done!") 

+

10140 return 

+

10141 

+

10142 def screen_setup(self) -> None: 

+

10143 """Hackish equivalent of the tmux_setup() function for screen.""" 

+

10144 screen = which("screen") 

+

10145 sty = os.getenv("STY") 

+

10146 ok("screen session found, splitting window...") 

+

10147 fd_script, script_path = tempfile.mkstemp() 

+

10148 fd_tty, tty_path = tempfile.mkstemp() 

+

10149 os.close(fd_tty) 

+

10150 

+

10151 with os.fdopen(fd_script, "w") as f: 

+

10152 f.write("startup_message off\n") 

+

10153 f.write("split -v\n") 

+

10154 f.write("focus right\n") 

+

10155 f.write(f"screen bash -c 'tty > {tty_path}; clear; cat'\n") 

+

10156 f.write("focus left\n") 

+

10157 

+

10158 gdb.execute(f"! {screen} -r {sty} -m -d -X source {script_path}") 

+

10159 # artificial delay to make sure `tty_path` is populated 

+

10160 time.sleep(0.25) 

+

10161 with open(tty_path, "r") as f: 

+

10162 pty = f.read().strip() 

+

10163 ok(f"Setting `context.redirect` to '{pty}'...") 

+

10164 gdb.execute(f"gef config context.redirect {pty}") 

+

10165 ok("Done!") 

+

10166 os.unlink(script_path) 

+

10167 os.unlink(tty_path) 

+

10168 return 

+

10169 

+

10170 

+

10171class GefInstallExtraScriptCommand(gdb.Command): 

+

10172 """`gef install` command: installs one or more scripts from the `gef-extras` script repo. Note that the command 

+

10173 doesn't check for external dependencies the script(s) might require.""" 

+

10174 _cmdline_ = "gef install" 

+

10175 _syntax_ = f"{_cmdline_} SCRIPTNAME [SCRIPTNAME [SCRIPTNAME...]]" 

+

10176 

+

10177 def __init__(self) -> None: 

+

10178 super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) 

+

10179 self.branch = gef.config.get("gef.extras_default_branch", GEF_EXTRAS_DEFAULT_BRANCH) 

+

10180 return 

+

10181 

+

10182 def invoke(self, argv: str, from_tty: bool) -> None: 

+

10183 self.dont_repeat() 

+

10184 if not argv: 10184 ↛ 10185line 10184 didn't jump to line 10185, because the condition on line 10184 was never true

+

10185 err("No script name provided") 

+

10186 return 

+

10187 

+

10188 args = argv.split() 

+

10189 

+

10190 if "--list" in args or "-l" in args: 10190 ↛ 10191line 10190 didn't jump to line 10191, because the condition on line 10190 was never true

+

10191 subprocess.run(["xdg-open", f"https://github.com/hugsy/gef-extras/{self.branch}/"]) 

+

10192 return 

+

10193 

+

10194 self.dirpath = pathlib.Path(gef.config["gef.tempdir"]).expanduser().absolute() 

+

10195 if not self.dirpath.is_dir(): 10195 ↛ 10196line 10195 didn't jump to line 10196, because the condition on line 10195 was never true

+

10196 err("'gef.tempdir' is not a valid directory") 

+

10197 return 

+

10198 

+

10199 for script in args: 

+

10200 script = script.lower() 

+

10201 if not self.__install_extras_script(script): 10201 ↛ 10202line 10201 didn't jump to line 10202, because the condition on line 10201 was never true

+

10202 warn(f"Failed to install '{script}', skipping...") 

+

10203 return 

+

10204 

+

10205 

+

10206 def __install_extras_script(self, script: str) -> bool: 

+

10207 fpath = self.dirpath / f"{script}.py" 

+

10208 if not fpath.exists(): 10208 ↛ 10220line 10208 didn't jump to line 10220, because the condition on line 10208 was never false

+

10209 url = f"https://raw.githubusercontent.com/hugsy/gef-extras/{self.branch}/scripts/{script}.py" 

+

10210 info(f"Searching for '{script}.py' in `gef-extras@{self.branch}`...") 

+

10211 data = http_get(url) 

+

10212 if not data: 10212 ↛ 10213line 10212 didn't jump to line 10213, because the condition on line 10212 was never true

+

10213 warn("Not found") 

+

10214 return False 

+

10215 

+

10216 with fpath.open("wb") as fd: 

+

10217 fd.write(data) 

+

10218 fd.flush() 

+

10219 

+

10220 old_command_set = set(gef.gdb.commands) 

+

10221 gdb.execute(f"source {fpath}") 

+

10222 new_command_set = set(gef.gdb.commands) 

+

10223 new_commands = [f"`{c[0]}`" for c in (new_command_set - old_command_set)] 

+

10224 ok(f"Installed file '{fpath}', new command(s) available: {', '.join(new_commands)}") 

+

10225 return True 

+

10226 

+

10227 

+

10228# 

+

10229# GEF internal classes 

+

10230# 

+

10231 

+

10232def __gef_prompt__(current_prompt: Callable[[Callable], str]) -> str: 

+

10233 """GEF custom prompt function.""" 

+

10234 if gef.config["gef.readline_compat"] is True: return GEF_PROMPT 

+

10235 if gef.config["gef.disable_color"] is True: return GEF_PROMPT 

+

10236 prompt = "" 

+

10237 if gef.session.remote: 

+

10238 prompt += Color.boldify("(remote) ") 

+

10239 prompt += GEF_PROMPT_ON if is_alive() else GEF_PROMPT_OFF 

+

10240 return prompt 

+

10241 

+

10242 

+

10243class GefManager(metaclass=abc.ABCMeta): 

+

10244 def reset_caches(self) -> None: 

+

10245 """Reset the LRU-cached attributes""" 

+

10246 for attr in dir(self): 

+

10247 try: 

+

10248 obj = getattr(self, attr) 

+

10249 if not hasattr(obj, "cache_clear"): 10249 ↛ 10251line 10249 didn't jump to line 10251, because the condition on line 10249 was never false

+

10250 continue 

+

10251 obj.cache_clear() 

+

10252 except: # we're reseting the cache here, we don't care if (or which) exception triggers 

+

10253 continue 

+

10254 return 

+

10255 

+

10256 

+

10257class GefMemoryManager(GefManager): 

+

10258 """Class that manages memory access for gef.""" 

+

10259 def __init__(self) -> None: 

+

10260 self.reset_caches() 

+

10261 return 

+

10262 

+

10263 def reset_caches(self) -> None: 

+

10264 super().reset_caches() 

+

10265 self.__maps = None 

+

10266 return 

+

10267 

+

10268 def write(self, address: int, buffer: ByteString, length: int = 0x10) -> None: 

+

10269 """Write `buffer` at address `address`.""" 

+

10270 gdb.selected_inferior().write_memory(address, buffer, length) 

+

10271 

+

10272 def read(self, addr: int, length: int = 0x10) -> bytes: 

+

10273 """Return a `length` long byte array with the copy of the process memory at `addr`.""" 

+

10274 return gdb.selected_inferior().read_memory(addr, length).tobytes() 

+

10275 

+

10276 def read_integer(self, addr: int) -> int: 

+

10277 """Return an integer read from memory.""" 

+

10278 sz = gef.arch.ptrsize 

+

10279 mem = self.read(addr, sz) 

+

10280 unpack = u32 if sz == 4 else u64 

+

10281 return unpack(mem) 

+

10282 

+

10283 def read_cstring(self, 

+

10284 address: int, 

+

10285 max_length: int = GEF_MAX_STRING_LENGTH, 

+

10286 encoding: Optional[str] = None) -> str: 

+

10287 """Return a C-string read from memory.""" 

+

10288 encoding = encoding or "unicode-escape" 

+

10289 length = min(address | (DEFAULT_PAGE_SIZE-1), max_length+1) 

+

10290 

+

10291 try: 

+

10292 res_bytes = self.read(address, length) 

+

10293 except gdb.error: 

+

10294 err(f"Can't read memory at '{address}'") 

+

10295 return "" 

+

10296 try: 

+

10297 with warnings.catch_warnings(): 

+

10298 # ignore DeprecationWarnings (see #735) 

+

10299 warnings.simplefilter("ignore") 

+

10300 res = res_bytes.decode(encoding, "strict") 

+

10301 except UnicodeDecodeError: 

+

10302 # latin-1 as fallback due to its single-byte to glyph mapping 

+

10303 res = res_bytes.decode("latin-1", "replace") 

+

10304 

+

10305 res = res.split("\x00", 1)[0] 

+

10306 ustr = res.replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t") 

+

10307 if max_length and len(res) > max_length: 

+

10308 return f"{ustr[:max_length]}[...]" 

+

10309 return ustr 

+

10310 

+

10311 def read_ascii_string(self, address: int) -> Optional[str]: 

+

10312 """Read an ASCII string from memory""" 

+

10313 cstr = self.read_cstring(address) 

+

10314 if isinstance(cstr, str) and cstr and all(x in string.printable for x in cstr): 

+

10315 return cstr 

+

10316 return None 

+

10317 

+

10318 @property 

+

10319 def maps(self) -> List[Section]: 

+

10320 if not self.__maps: 

+

10321 self.__maps = self.__parse_maps() 

+

10322 return self.__maps 

+

10323 

+

10324 def __parse_maps(self) -> List[Section]: 

+

10325 """Return the mapped memory sections""" 

+

10326 try: 

+

10327 if is_qemu_system(): 10327 ↛ 10328line 10327 didn't jump to line 10328, because the condition on line 10327 was never true

+

10328 return list(self.__parse_info_mem()) 

+

10329 except gdb.error: 

+

10330 # Target may not support this command 

+

10331 pass 

+

10332 try: 

+

10333 return list(self.__parse_procfs_maps()) 

+

10334 except FileNotFoundError: 

+

10335 return list(self.__parse_gdb_info_sections()) 

+

10336 

+

10337 def __parse_procfs_maps(self) -> Generator[Section, None, None]: 

+

10338 """Get the memory mapping from procfs.""" 

+

10339 procfs_mapfile = gef.session.maps 

+

10340 if not procfs_mapfile: 

+

10341 is_remote = gef.session.remote is not None 

+

10342 raise FileNotFoundError(f"Missing {'remote ' if is_remote else ''}procfs map file") 

+

10343 with procfs_mapfile.open("r") as fd: 

+

10344 for line in fd: 

+

10345 line = line.strip() 

+

10346 addr, perm, off, _, rest = line.split(" ", 4) 

+

10347 rest = rest.split(" ", 1) 

+

10348 if len(rest) == 1: 

+

10349 inode = rest[0] 

+

10350 pathname = "" 

+

10351 else: 

+

10352 inode = rest[0] 

+

10353 pathname = rest[1].lstrip() 

+

10354 

+

10355 addr_start, addr_end = parse_string_range(addr) 

+

10356 off = int(off, 16) 

+

10357 perm = Permission.from_process_maps(perm) 

+

10358 inode = int(inode) 

+

10359 yield Section(page_start=addr_start, 

+

10360 page_end=addr_end, 

+

10361 offset=off, 

+

10362 permission=perm, 

+

10363 inode=inode, 

+

10364 path=pathname) 

+

10365 return 

+

10366 

+

10367 def __parse_gdb_info_sections(self) -> Generator[Section, None, None]: 

+

10368 """Get the memory mapping from GDB's command `maintenance info sections` (limited info).""" 

+

10369 stream = StringIO(gdb.execute("maintenance info sections", to_string=True)) 

+

10370 

+

10371 for line in stream: 

+

10372 if not line: 10372 ↛ 10373line 10372 didn't jump to line 10373, because the condition on line 10372 was never true

+

10373 break 

+

10374 

+

10375 try: 

+

10376 parts = [x for x in line.split()] 

+

10377 addr_start, addr_end = [int(x, 16) for x in parts[1].split("->")] 

+

10378 off = int(parts[3][:-1], 16) 

+

10379 path = parts[4] 

+

10380 perm = Permission.from_info_sections(parts[5:]) 

+

10381 yield Section( 

+

10382 page_start=addr_start, 

+

10383 page_end=addr_end, 

+

10384 offset=off, 

+

10385 permission=perm, 

+

10386 inode="", 

+

10387 path=path 

+

10388 ) 

+

10389 

+

10390 except IndexError: 10390 ↛ 10391line 10390 didn't jump to line 10391, because the exception caught by line 10390 didn't happen

+

10391 continue 

+

10392 except ValueError: 

+

10393 continue 

+

10394 return 

+

10395 

+

10396 def __parse_info_mem(self) -> Generator[Section, None, None]: 

+

10397 """Get the memory mapping from GDB's command `monitor info mem`""" 

+

10398 for line in StringIO(gdb.execute("monitor info mem", to_string=True)): 

+

10399 if not line: 

+

10400 break 

+

10401 try: 

+

10402 ranges, off, perms = line.split() 

+

10403 off = int(off, 16) 

+

10404 start, end = [int(s, 16) for s in ranges.split("-")] 

+

10405 except ValueError as e: 

+

10406 continue 

+

10407 

+

10408 perm = Permission.from_info_mem(perms) 

+

10409 yield Section( 

+

10410 page_start=start, 

+

10411 page_end=end, 

+

10412 offset=off, 

+

10413 permission=perm, 

+

10414 inode="", 

+

10415 ) 

+

10416 

+

10417 

+

10418class GefHeapManager(GefManager): 

+

10419 """Class managing session heap.""" 

+

10420 def __init__(self) -> None: 

+

10421 self.reset_caches() 

+

10422 return 

+

10423 

+

10424 def reset_caches(self) -> None: 

+

10425 self.__libc_main_arena: Optional[GlibcArena] = None 

+

10426 self.__libc_selected_arena: Optional[GlibcArena] = None 

+

10427 self.__heap_base = None 

+

10428 return 

+

10429 

+

10430 @property 

+

10431 def main_arena(self) -> Optional[GlibcArena]: 

+

10432 if not self.__libc_main_arena: 

+

10433 try: 

+

10434 __main_arena_addr = GefHeapManager.find_main_arena_addr() 

+

10435 self.__libc_main_arena = GlibcArena(f"*{__main_arena_addr:#x}") 

+

10436 # the initialization of `main_arena` also defined `selected_arena`, so 

+

10437 # by default, `main_arena` == `selected_arena` 

+

10438 self.selected_arena = self.__libc_main_arena 

+

10439 except: 

+

10440 # the search for arena can fail when the session is not started 

+

10441 pass 

+

10442 return self.__libc_main_arena 

+

10443 

+

10444 @main_arena.setter 

+

10445 def main_arena(self, value: GlibcArena) -> None: 

+

10446 self.__libc_main_arena = value 

+

10447 return 

+

10448 

+

10449 @staticmethod 

+

10450 @lru_cache() 

+

10451 def find_main_arena_addr() -> int: 

+

10452 """A helper function to find the glibc `main_arena` address, either from 

+

10453 symbol, from its offset from `__malloc_hook` or by brute force.""" 

+

10454 # Before anything else, use libc offset from config if available 

+

10455 if gef.config["gef.main_arena_offset"]: 10455 ↛ 10456line 10455 didn't jump to line 10456, because the condition on line 10455 was never true

+

10456 try: 

+

10457 libc_base = get_section_base_address("libc") 

+

10458 offset = parse_address(gef.config["gef.main_arena_offset"]) 

+

10459 if libc_base: 

+

10460 dbg(f"Using main_arena_offset={offset:#x} from config") 

+

10461 addr = libc_base + offset 

+

10462 

+

10463 # Verify the found address before returning 

+

10464 if GlibcArena.verify(addr): 

+

10465 return addr 

+

10466 except gdb.error: 

+

10467 pass 

+

10468 

+

10469 # First, try to find `main_arena` symbol directly 

+

10470 try: 

+

10471 return parse_address(f"&{LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME}") 

+

10472 except gdb.error: 

+

10473 pass 

+

10474 

+

10475 # Second, try to find it by offset from `__malloc_hook` 

+

10476 if gef.libc.version < (2, 34): 

+

10477 try: 

+

10478 malloc_hook_addr = parse_address("(void *)&__malloc_hook") 

+

10479 

+

10480 struct_size = ctypes.sizeof(GlibcArena.malloc_state_t()) 

+

10481 

+

10482 if is_x86(): 

+

10483 addr = align_address_to_size(malloc_hook_addr + gef.arch.ptrsize, 0x20) 

+

10484 elif is_arch(Elf.Abi.AARCH64): 

+

10485 addr = malloc_hook_addr - gef.arch.ptrsize*2 - struct_size 

+

10486 elif is_arch(Elf.Abi.ARM): 

+

10487 addr = malloc_hook_addr - gef.arch.ptrsize - struct_size 

+

10488 else: 

+

10489 addr = None 

+

10490 

+

10491 # Verify the found address before returning 

+

10492 if addr and GlibcArena.verify(addr): 

+

10493 return addr 

+

10494 

+

10495 except gdb.error: 

+

10496 pass 

+

10497 

+

10498 # Last resort, try to find it via brute force if enabled in settings 

+

10499 if gef.config["gef.bruteforce_main_arena"]: 

+

10500 alignment = 0x8 

+

10501 try: 

+

10502 dbg("Trying to bruteforce main_arena address") 

+

10503 # setup search_range for `main_arena` to `.data` of glibc 

+

10504 search_filter = lambda f: "libc" in f.filename and f.name == ".data" 

+

10505 dotdata = list(filter(search_filter, get_info_files()))[0] 

+

10506 search_range = range(dotdata.zone_start, dotdata.zone_end, alignment) 

+

10507 # find first possible candidate 

+

10508 for addr in search_range: 

+

10509 if GlibcArena.verify(addr): 

+

10510 dbg(f"Found candidate at {addr:#x}") 

+

10511 return addr 

+

10512 dbg("Bruteforce not successful") 

+

10513 except Exception: 

+

10514 pass 

+

10515 

+

10516 # Nothing helped 

+

10517 err_msg = f"Cannot find main_arena for {gef.arch.arch}. You might want to set a manually found libc offset " 

+

10518 if not gef.config["gef.bruteforce_main_arena"]: 

+

10519 err_msg += "or allow bruteforcing " 

+

10520 err_msg += "through the GEF config." 

+

10521 raise OSError(err_msg) 

+

10522 

+

10523 @property 

+

10524 def selected_arena(self) -> Optional[GlibcArena]: 

+

10525 if not self.__libc_selected_arena: 10525 ↛ 10527line 10525 didn't jump to line 10527, because the condition on line 10525 was never true

+

10526 # `selected_arena` must default to `main_arena` 

+

10527 self.__libc_selected_arena = self.main_arena 

+

10528 return self.__libc_selected_arena 

+

10529 

+

10530 @selected_arena.setter 

+

10531 def selected_arena(self, value: GlibcArena) -> None: 

+

10532 self.__libc_selected_arena = value 

+

10533 return 

+

10534 

+

10535 @property 

+

10536 def arenas(self) -> Union[List, Iterator[GlibcArena]]: 

+

10537 if not self.main_arena: 10537 ↛ 10538line 10537 didn't jump to line 10538, because the condition on line 10537 was never true

+

10538 return [] 

+

10539 return iter(self.main_arena) 

+

10540 

+

10541 @property 

+

10542 def base_address(self) -> Optional[int]: 

+

10543 if not self.__heap_base: 

+

10544 base = 0 

+

10545 try: 

+

10546 base = parse_address("mp_->sbrk_base") 

+

10547 base = self.malloc_align_address(base) 

+

10548 except gdb.error: 

+

10549 # missing symbol, try again 

+

10550 base = 0 

+

10551 if not base: 10551 ↛ 10552line 10551 didn't jump to line 10552, because the condition on line 10551 was never true

+

10552 base = get_section_base_address("[heap]") 

+

10553 self.__heap_base = base 

+

10554 return self.__heap_base 

+

10555 

+

10556 @property 

+

10557 def chunks(self) -> Union[List, Iterator]: 

+

10558 if not self.base_address: 

+

10559 return [] 

+

10560 return iter(GlibcChunk(self.base_address, from_base=True)) 

+

10561 

+

10562 @property 

+

10563 def min_chunk_size(self) -> int: 

+

10564 return 4 * gef.arch.ptrsize 

+

10565 

+

10566 @property 

+

10567 def malloc_alignment(self) -> int: 

+

10568 __default_malloc_alignment = 0x10 

+

10569 if gef.libc.version >= (2, 26) and is_x86_32(): 10569 ↛ 10572line 10569 didn't jump to line 10572, because the condition on line 10569 was never true

+

10570 # Special case introduced in Glibc 2.26: 

+

10571 # https://elixir.bootlin.com/glibc/glibc-2.26/source/sysdeps/i386/malloc-alignment.h#L22 

+

10572 return __default_malloc_alignment 

+

10573 # Generic case: 

+

10574 # https://elixir.bootlin.com/glibc/glibc-2.26/source/sysdeps/generic/malloc-alignment.h#L22 

+

10575 return 2 * gef.arch.ptrsize 

+

10576 

+

10577 def csize2tidx(self, size: int) -> int: 

+

10578 return abs((size - self.min_chunk_size + self.malloc_alignment - 1)) // self.malloc_alignment 

+

10579 

+

10580 def tidx2size(self, idx: int) -> int: 

+

10581 return idx * self.malloc_alignment + self.min_chunk_size 

+

10582 

+

10583 def malloc_align_address(self, address: int) -> int: 

+

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

+

10585 malloc_alignment = self.malloc_alignment 

+

10586 ceil = lambda n: int(-1 * n // 1 * -1) 

+

10587 return malloc_alignment * ceil((address / malloc_alignment)) 

+

10588 

+

10589 

+

10590class GefSetting: 

+

10591 """Basic class for storing gef settings as objects""" 

+

10592 READ_ACCESS = 0 

+

10593 WRITE_ACCESS = 1 

+

10594 

+

10595 def __init__(self, value: Any, cls: Optional[type] = None, description: Optional[str] = None, hooks: Optional[Dict[str, Callable]] = None) -> None: 

+

10596 self.value = value 

+

10597 self.type = cls or type(value) 

+

10598 self.description = description or "" 

+

10599 self.hooks: Tuple[List[Callable], List[Callable]] = ([], []) 

+

10600 if hooks: 

+

10601 for access, func in hooks.items(): 

+

10602 if access == "on_read": 10602 ↛ 10603line 10602 didn't jump to line 10603, because the condition on line 10602 was never true

+

10603 idx = GefSetting.READ_ACCESS 

+

10604 elif access == "on_write": 10604 ↛ 10607line 10604 didn't jump to line 10607, because the condition on line 10604 was never false

+

10605 idx = GefSetting.WRITE_ACCESS 

+

10606 else: 

+

10607 raise ValueError 

+

10608 if not callable(func): 10608 ↛ 10609line 10608 didn't jump to line 10609, because the condition on line 10608 was never true

+

10609 raise ValueError(f"hook is not callable") 

+

10610 self.hooks[idx].append(func) 

+

10611 return 

+

10612 

+

10613 def __str__(self) -> str: 

+

10614 return f"Setting(type={self.type.__name__}, value='{self.value}', desc='{self.description[:10]}...', "\ 

+

10615 f"read_hooks={len(self.hooks[GefSetting.READ_ACCESS])}, write_hooks={len(self.hooks[GefSetting.READ_ACCESS])})" 

+

10616 

+

10617 

+

10618class GefSettingsManager(dict): 

+

10619 """ 

+

10620 GefSettings acts as a dict where the global settings are stored and can be read, written or deleted as any other dict. 

+

10621 For instance, to read a specific command setting: `gef.config[mycommand.mysetting]` 

+

10622 """ 

+

10623 def __getitem__(self, name: str) -> Any: 

+

10624 setting : GefSetting = super().__getitem__(name) 

+

10625 self.__invoke_read_hooks(setting) 

+

10626 return setting.value 

+

10627 

+

10628 def __setitem__(self, name: str, value: Any) -> None: 

+

10629 # check if the key exists 

+

10630 if super().__contains__(name): 

+

10631 # if so, update its value directly 

+

10632 setting = super().__getitem__(name) 

+

10633 if not isinstance(setting, GefSetting): raise ValueError 10633 ↛ exitline 10633 didn't except from function '__setitem__', because the raise on line 10633 wasn't executed

+

10634 setting.value = setting.type(value) 

+

10635 else: 

+

10636 # if not, `value` must be a GefSetting 

+

10637 if not isinstance(value, GefSetting): raise Exception("Invalid argument") 10637 ↛ exitline 10637 didn't except from function '__setitem__', because the raise on line 10637 wasn't executed

+

10638 if not value.type: raise Exception("Invalid type") 10638 ↛ exitline 10638 didn't except from function '__setitem__', because the raise on line 10638 wasn't executed

+

10639 if not value.description: raise Exception("Invalid description") 10639 ↛ exitline 10639 didn't except from function '__setitem__', because the raise on line 10639 wasn't executed

+

10640 setting = value 

+

10641 super().__setitem__(name, setting) 

+

10642 self.__invoke_write_hooks(setting) 

+

10643 return 

+

10644 

+

10645 def __delitem__(self, name: str) -> None: 

+

10646 super().__delitem__(name) 

+

10647 return 

+

10648 

+

10649 def raw_entry(self, name: str) -> GefSetting: 

+

10650 return super().__getitem__(name) 

+

10651 

+

10652 def __invoke_read_hooks(self, setting: GefSetting) -> None: 

+

10653 self.__invoke_hooks(is_write=False, setting=setting) 

+

10654 return 

+

10655 

+

10656 def __invoke_write_hooks(self, setting: GefSetting) -> None: 

+

10657 self.__invoke_hooks(is_write=True, setting=setting) 

+

10658 return 

+

10659 

+

10660 def __invoke_hooks(self, is_write: bool, setting: GefSetting) -> None: 

+

10661 if not setting.hooks: 10661 ↛ 10662line 10661 didn't jump to line 10662, because the condition on line 10661 was never true

+

10662 return 

+

10663 idx = int(is_write) 

+

10664 if setting.hooks[idx]: 

+

10665 for callback in setting.hooks[idx]: 

+

10666 callback() 

+

10667 return 

+

10668 

+

10669 

+

10670class GefSessionManager(GefManager): 

+

10671 """Class managing the runtime properties of GEF. """ 

+

10672 def __init__(self) -> None: 

+

10673 self.reset_caches() 

+

10674 self.remote: Optional["GefRemoteSessionManager"] = None 

+

10675 self.remote_initializing: bool = False 

+

10676 self.qemu_mode: bool = False 

+

10677 self.convenience_vars_index: int = 0 

+

10678 self.heap_allocated_chunks: List[Tuple[int, int]] = [] 

+

10679 self.heap_freed_chunks: List[Tuple[int, int]] = [] 

+

10680 self.heap_uaf_watchpoints: List[UafWatchpoint] = [] 

+

10681 self.pie_breakpoints: Dict[int, PieVirtualBreakpoint] = {} 

+

10682 self.pie_counter: int = 1 

+

10683 self.aliases: List[GefAlias] = [] 

+

10684 self.modules: List[FileFormat] = [] 

+

10685 self.constants = {} # a dict for runtime constants (like 3rd party file paths) 

+

10686 for constant in ("python3", "readelf", "file", "ps"): 

+

10687 self.constants[constant] = which(constant) 

+

10688 return 

+

10689 

+

10690 def reset_caches(self) -> None: 

+

10691 super().reset_caches() 

+

10692 self._auxiliary_vector = None 

+

10693 self._pagesize = None 

+

10694 self._os = None 

+

10695 self._pid = None 

+

10696 self._file = None 

+

10697 self._maps: Optional[pathlib.Path] = None 

+

10698 self._root: Optional[pathlib.Path] = None 

+

10699 return 

+

10700 

+

10701 def __str__(self) -> str: 

+

10702 return f"Session({'Local' if self.remote is None else 'Remote'}, pid={self.pid or 'Not running'}, os='{self.os}')" 

+

10703 

+

10704 @property 

+

10705 def auxiliary_vector(self) -> Optional[Dict[str, int]]: 

+

10706 if not is_alive(): 

+

10707 return None 

+

10708 if is_qemu_system(): 10708 ↛ 10709line 10708 didn't jump to line 10709, because the condition on line 10708 was never true

+

10709 return None 

+

10710 if not self._auxiliary_vector: 

+

10711 auxiliary_vector = {} 

+

10712 auxv_info = gdb.execute("info auxv", to_string=True) 

+

10713 if not auxv_info or "failed" in auxv_info: 10713 ↛ 10714line 10713 didn't jump to line 10714, because the condition on line 10713 was never true

+

10714 err("Failed to query auxiliary variables") 

+

10715 return None 

+

10716 for line in auxv_info.splitlines(): 

+

10717 line = line.split('"')[0].strip() # remove the ending string (if any) 

+

10718 line = line.split() # split the string by whitespace(s) 

+

10719 if len(line) < 4: 10719 ↛ 10720line 10719 didn't jump to line 10720, because the condition on line 10719 was never true

+

10720 continue 

+

10721 __av_type = line[1] 

+

10722 __av_value = line[-1] 

+

10723 auxiliary_vector[__av_type] = int(__av_value, base=0) 

+

10724 self._auxiliary_vector = auxiliary_vector 

+

10725 return self._auxiliary_vector 

+

10726 

+

10727 @property 

+

10728 def os(self) -> str: 

+

10729 """Return the current OS.""" 

+

10730 if not self._os: 

+

10731 self._os = platform.system().lower() 

+

10732 return self._os 

+

10733 

+

10734 @property 

+

10735 def pid(self) -> int: 

+

10736 """Return the PID of the target process.""" 

+

10737 if not self._pid: 

+

10738 pid = gdb.selected_inferior().pid if not gef.session.qemu_mode else gdb.selected_thread().ptid[1] 

+

10739 if not pid: 

+

10740 raise RuntimeError("cannot retrieve PID for target process") 

+

10741 self._pid = pid 

+

10742 return self._pid 

+

10743 

+

10744 @property 

+

10745 def file(self) -> Optional[pathlib.Path]: 

+

10746 """Return a Path object of the target process.""" 

+

10747 if gef.session.remote is not None: 

+

10748 return gef.session.remote.file 

+

10749 fpath: str = gdb.current_progspace().filename 

+

10750 if fpath and not self._file: 

+

10751 self._file = pathlib.Path(fpath).expanduser() 

+

10752 return self._file 

+

10753 

+

10754 @property 

+

10755 def cwd(self) -> Optional[pathlib.Path]: 

+

10756 if gef.session.remote is not None: 

+

10757 return gef.session.remote.root 

+

10758 return self.file.parent if self.file else None 

+

10759 

+

10760 @property 

+

10761 def pagesize(self) -> int: 

+

10762 """Get the system page size""" 

+

10763 auxval = self.auxiliary_vector 

+

10764 if not auxval: 

+

10765 return DEFAULT_PAGE_SIZE 

+

10766 self._pagesize = auxval["AT_PAGESZ"] 

+

10767 return self._pagesize 

+

10768 

+

10769 @property 

+

10770 def canary(self) -> Optional[Tuple[int, int]]: 

+

10771 """Return a tuple of the canary address and value, read from the canonical 

+

10772 location if supported by the architecture. Otherwise, read from the auxiliary 

+

10773 vector.""" 

+

10774 try: 

+

10775 canary_location = gef.arch.canary_address() 

+

10776 canary = gef.memory.read_integer(canary_location) 

+

10777 except NotImplementedError: 

+

10778 # Fall back to `AT_RANDOM`, which is the original source 

+

10779 # of the canary value but not the canonical location 

+

10780 return self.original_canary 

+

10781 return canary, canary_location 

+

10782 

+

10783 @property 

+

10784 def original_canary(self) -> Optional[Tuple[int, int]]: 

+

10785 """Return a tuple of the initial canary address and value, read from the 

+

10786 auxiliary vector.""" 

+

10787 auxval = self.auxiliary_vector 

+

10788 if not auxval: 

+

10789 return None 

+

10790 canary_location = auxval["AT_RANDOM"] 

+

10791 canary = gef.memory.read_integer(canary_location) 

+

10792 canary &= ~0xFF 

+

10793 return canary, canary_location 

+

10794 

+

10795 

+

10796 @property 

+

10797 def maps(self) -> Optional[pathlib.Path]: 

+

10798 """Returns the Path to the procfs entry for the memory mapping.""" 

+

10799 if not is_alive(): 

+

10800 return None 

+

10801 if not self._maps: 

+

10802 if gef.session.remote is not None: 

+

10803 self._maps = gef.session.remote.maps 

+

10804 else: 

+

10805 self._maps = pathlib.Path(f"/proc/{self.pid}/maps") 

+

10806 return self._maps 

+

10807 

+

10808 @property 

+

10809 def root(self) -> Optional[pathlib.Path]: 

+

10810 """Returns the path to the process's root directory.""" 

+

10811 if not is_alive(): 

+

10812 return None 

+

10813 if not self._root: 

+

10814 self._root = pathlib.Path(f"/proc/{self.pid}/root") 

+

10815 return self._root 

+

10816 

+

10817class GefRemoteSessionManager(GefSessionManager): 

+

10818 """Class for managing remote sessions with GEF. It will create a temporary environment 

+

10819 designed to clone the remote one.""" 

+

10820 def __init__(self, host: str, port: int, pid: int =-1, qemu: Optional[pathlib.Path] = None) -> None: 

+

10821 super().__init__() 

+

10822 self.__host = host 

+

10823 self.__port = port 

+

10824 self.__local_root_fd = tempfile.TemporaryDirectory() 

+

10825 self.__local_root_path = pathlib.Path(self.__local_root_fd.name) 

+

10826 self.__qemu = qemu 

+

10827 dbg(f"[remote] initializing remote session with {self.target} under {self.root}") 

+

10828 if not self.connect(pid): 10828 ↛ 10829line 10828 didn't jump to line 10829, because the condition on line 10828 was never true

+

10829 raise EnvironmentError(f"Cannot connect to remote target {self.target}") 

+

10830 if not self.setup(): 10830 ↛ 10831line 10830 didn't jump to line 10831, because the condition on line 10830 was never true

+

10831 raise EnvironmentError(f"Failed to create a proper environment for {self.target}") 

+

10832 return 

+

10833 

+

10834 def close(self) -> None: 

+

10835 self.__local_root_fd.cleanup() 

+

10836 try: 

+

10837 gef_on_new_unhook(self.remote_objfile_event_handler) 

+

10838 gef_on_new_hook(new_objfile_handler) 

+

10839 except Exception as e: 

+

10840 warn(f"Exception while restoring local context: {str(e)}") 

+

10841 return 

+

10842 

+

10843 def in_qemu_user(self) -> bool: 

+

10844 return self.__qemu is not None 

+

10845 

+

10846 def __str__(self) -> str: 

+

10847 return f"RemoteSession(target='{self.target}', local='{self.root}', pid={self.pid}, qemu_user={bool(self.in_qemu_user())})" 

+

10848 

+

10849 @property 

+

10850 def target(self) -> str: 

+

10851 return f"{self.__host}:{self.__port}" 

+

10852 

+

10853 @property 

+

10854 def root(self) -> pathlib.Path: 

+

10855 return self.__local_root_path.absolute() 

+

10856 

+

10857 @property 

+

10858 def file(self) -> pathlib.Path: 

+

10859 """Path to the file being debugged as seen by the remote endpoint.""" 

+

10860 if not self._file: 

+

10861 filename = gdb.current_progspace().filename 

+

10862 if not filename: 10862 ↛ 10863line 10862 didn't jump to line 10863, because the condition on line 10862 was never true

+

10863 raise RuntimeError("No session started") 

+

10864 start_idx = len("target:") if filename.startswith("target:") else 0 

+

10865 self._file = pathlib.Path(filename[start_idx:]) 

+

10866 return self._file 

+

10867 

+

10868 @property 

+

10869 def lfile(self) -> pathlib.Path: 

+

10870 """Local path to the file being debugged.""" 

+

10871 return self.root / str(self.file).lstrip("/") 

+

10872 

+

10873 @property 

+

10874 def maps(self) -> pathlib.Path: 

+

10875 if not self._maps: 

+

10876 self._maps = self.root / f"proc/{self.pid}/maps" 

+

10877 return self._maps 

+

10878 

+

10879 def sync(self, src: str, dst: Optional[str] = None) -> bool: 

+

10880 """Copy the `src` into the temporary chroot. If `dst` is provided, that path will be 

+

10881 used instead of `src`.""" 

+

10882 if not dst: 

+

10883 dst = src 

+

10884 tgt = self.root / dst.lstrip("/") 

+

10885 if tgt.exists(): 10885 ↛ 10886line 10885 didn't jump to line 10886, because the condition on line 10885 was never true

+

10886 return True 

+

10887 tgt.parent.mkdir(parents=True, exist_ok=True) 

+

10888 dbg(f"[remote] downloading '{src}' -> '{tgt}'") 

+

10889 gdb.execute(f"remote get {src} {tgt.absolute()}") 

+

10890 return tgt.exists() 

+

10891 

+

10892 def connect(self, pid: int) -> bool: 

+

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

+

10894 # before anything, register our new hook to download files from the remote target 

+

10895 dbg(f"[remote] Installing new objfile handlers") 

+

10896 gef_on_new_unhook(new_objfile_handler) 

+

10897 gef_on_new_hook(self.remote_objfile_event_handler) 

+

10898 

+

10899 # then attempt to connect 

+

10900 is_extended_mode = (pid > -1) 

+

10901 dbg(f"[remote] Enabling extended remote: {bool(is_extended_mode)}") 

+

10902 try: 

+

10903 with DisableContextOutputContext(): 

+

10904 cmd = f"target {'extended-' if is_extended_mode else ''}remote {self.target}" 

+

10905 dbg(f"[remote] Executing '{cmd}'") 

+

10906 gdb.execute(cmd) 

+

10907 if is_extended_mode: 10907 ↛ 10908line 10907 didn't jump to line 10908, because the condition on line 10907 was never true

+

10908 gdb.execute(f"attach {pid:d}") 

+

10909 return True 

+

10910 except Exception as e: 

+

10911 err(f"Failed to connect to {self.target}: {e}") 

+

10912 

+

10913 # a failure will trigger the cleanup, deleting our hook anyway 

+

10914 return False 

+

10915 

+

10916 def setup(self) -> bool: 

+

10917 # setup remote adequately depending on remote or qemu mode 

+

10918 if self.in_qemu_user(): 

+

10919 dbg(f"Setting up as qemu session, target={self.__qemu}") 

+

10920 self.__setup_qemu() 

+

10921 else: 

+

10922 dbg(f"Setting up as remote session") 

+

10923 self.__setup_remote() 

+

10924 

+

10925 # refresh gef to consider the binary 

+

10926 reset_all_caches() 

+

10927 gef.binary = Elf(self.lfile) 

+

10928 reset_architecture() 

+

10929 return True 

+

10930 

+

10931 def __setup_qemu(self) -> bool: 

+

10932 # setup emulated file in the chroot 

+

10933 assert self.__qemu 

+

10934 target = self.root / str(self.__qemu.parent).lstrip("/") 

+

10935 target.mkdir(parents=True, exist_ok=False) 

+

10936 shutil.copy2(self.__qemu, target) 

+

10937 self._file = self.__qemu 

+

10938 assert self.lfile.exists() 

+

10939 

+

10940 # create a procfs 

+

10941 procfs = self.root / f"proc/{self.pid}/" 

+

10942 procfs.mkdir(parents=True, exist_ok=True) 

+

10943 

+

10944 ## /proc/pid/cmdline 

+

10945 cmdline = procfs / "cmdline" 

+

10946 if not cmdline.exists(): 10946 ↛ 10951line 10946 didn't jump to line 10951, because the condition on line 10946 was never false

+

10947 with cmdline.open("w") as fd: 

+

10948 fd.write("") 

+

10949 

+

10950 ## /proc/pid/environ 

+

10951 environ = procfs / "environ" 

+

10952 if not environ.exists(): 10952 ↛ 10957line 10952 didn't jump to line 10957, because the condition on line 10952 was never false

+

10953 with environ.open("wb") as fd: 

+

10954 fd.write(b"PATH=/bin\x00HOME=/tmp\x00") 

+

10955 

+

10956 ## /proc/pid/maps 

+

10957 maps = procfs / "maps" 

+

10958 if not maps.exists(): 10958 ↛ 10963line 10958 didn't jump to line 10963, because the condition on line 10958 was never false

+

10959 with maps.open("w") as fd: 

+

10960 fname = self.file.absolute() 

+

10961 mem_range = "00000000-ffffffff" if is_32bit() else "0000000000000000-ffffffffffffffff" 

+

10962 fd.write(f"{mem_range} rwxp 00000000 00:00 0 {fname}\n") 

+

10963 return True 

+

10964 

+

10965 def __setup_remote(self) -> bool: 

+

10966 # get the file 

+

10967 fpath = f"/proc/{self.pid}/exe" 

+

10968 if not self.sync(fpath, str(self.file)): 10968 ↛ 10969line 10968 didn't jump to line 10969, because the condition on line 10968 was never true

+

10969 err(f"'{fpath}' could not be fetched on the remote system.") 

+

10970 return False 

+

10971 

+

10972 # pseudo procfs 

+

10973 for _file in ("maps", "environ", "cmdline"): 

+

10974 fpath = f"/proc/{self.pid}/{_file}" 

+

10975 if not self.sync(fpath): 10975 ↛ 10976line 10975 didn't jump to line 10976, because the condition on line 10975 was never true

+

10976 err(f"'{fpath}' could not be fetched on the remote system.") 

+

10977 return False 

+

10978 

+

10979 # makeup a fake mem mapping in case we failed to retrieve it 

+

10980 maps = self.root / f"proc/{self.pid}/maps" 

+

10981 if not maps.exists(): 10981 ↛ 10982line 10981 didn't jump to line 10982, because the condition on line 10981 was never true

+

10982 with maps.open("w") as fd: 

+

10983 fname = self.file.absolute() 

+

10984 mem_range = "00000000-ffffffff" if is_32bit() else "0000000000000000-ffffffffffffffff" 

+

10985 fd.write(f"{mem_range} rwxp 00000000 00:00 0 {fname}\n") 

+

10986 return True 

+

10987 

+

10988 def remote_objfile_event_handler(self, evt: "gdb.NewObjFileEvent") -> None: 

+

10989 dbg(f"[remote] in remote_objfile_handler({evt.new_objfile.filename if evt else 'None'}))") 

+

10990 if not evt or not evt.new_objfile.filename: 10990 ↛ 10991line 10990 didn't jump to line 10991, because the condition on line 10990 was never true

+

10991 return 

+

10992 if not evt.new_objfile.filename.startswith("target:") and not evt.new_objfile.filename.startswith("/"): 

+

10993 warn(f"[remote] skipping '{evt.new_objfile.filename}'") 

+

10994 return 

+

10995 if evt.new_objfile.filename.startswith("target:"): 

+

10996 src: str = evt.new_objfile.filename[len("target:"):] 

+

10997 if not self.sync(src): 10997 ↛ 10998line 10997 didn't jump to line 10998, because the condition on line 10997 was never true

+

10998 raise FileNotFoundError(f"Failed to sync '{src}'") 

+

10999 return 

+

11000 

+

11001 

+

11002class GefUiManager(GefManager): 

+

11003 """Class managing UI settings.""" 

+

11004 def __init__(self) -> None: 

+

11005 self.redirect_fd : Optional[TextIOWrapper] = None 

+

11006 self.context_hidden = False 

+

11007 self.stream_buffer : Optional[StringIO] = None 

+

11008 self.highlight_table: Dict[str, str] = {} 

+

11009 self.watches: Dict[int, Tuple[int, str]] = {} 

+

11010 self.context_messages: List[Tuple[str, str]] = [] 

+

11011 return 

+

11012 

+

11013 

+

11014class GefLibcManager(GefManager): 

+

11015 """Class managing everything libc-related (except heap).""" 

+

11016 def __init__(self) -> None: 

+

11017 self._version : Optional[Tuple[int, int]] = None 

+

11018 return 

+

11019 

+

11020 def __str__(self) -> str: 

+

11021 return f"Libc(version='{self.version}')" 

+

11022 

+

11023 @property 

+

11024 def version(self) -> Optional[Tuple[int, int]]: 

+

11025 if not is_alive(): 11025 ↛ 11026line 11025 didn't jump to line 11026, because the condition on line 11025 was never true

+

11026 return None 

+

11027 if not self._version: 

+

11028 self._version = GefLibcManager.find_libc_version() 

+

11029 return self._version 

+

11030 

+

11031 @staticmethod 

+

11032 @lru_cache() 

+

11033 def find_libc_version() -> Tuple[int, ...]: 

+

11034 sections = gef.memory.maps 

+

11035 for section in sections: 11035 ↛ 11048line 11035 didn't jump to line 11048, because the loop on line 11035 didn't complete

+

11036 match = re.search(r"libc6?[-_](\d+)\.(\d+)\.so", section.path) 

+

11037 if match: 11037 ↛ 11038line 11037 didn't jump to line 11038, because the condition on line 11037 was never true

+

11038 return tuple(int(_) for _ in match.groups()) 

+

11039 if "libc" in section.path: 

+

11040 try: 

+

11041 with open(section.path, "rb") as f: 

+

11042 data = f.read() 

+

11043 except OSError: 

+

11044 continue 

+

11045 match = re.search(PATTERN_LIBC_VERSION, data) 

+

11046 if match: 11046 ↛ 11035line 11046 didn't jump to line 11035, because the condition on line 11046 was never false

+

11047 return tuple(int(_) for _ in match.groups()) 

+

11048 return 0, 0 

+

11049 

+

11050 

+

11051 

+

11052 

+

11053class Gef: 

+

11054 """The GEF root class, which serves as a entrypoint for all the debugging session attributes (architecture, 

+

11055 memory, settings, etc.).""" 

+

11056 binary: Optional[FileFormat] 

+

11057 arch: Architecture 

+

11058 config : GefSettingsManager 

+

11059 ui: GefUiManager 

+

11060 libc: GefLibcManager 

+

11061 memory : GefMemoryManager 

+

11062 heap : GefHeapManager 

+

11063 session : GefSessionManager 

+

11064 gdb: GefCommand 

+

11065 

+

11066 def __init__(self) -> None: 

+

11067 self.binary: Optional[FileFormat] = None 

+

11068 self.arch: Architecture = GenericArchitecture() # see PR #516, will be reset by `new_objfile_handler` 

+

11069 self.config = GefSettingsManager() 

+

11070 self.ui = GefUiManager() 

+

11071 self.libc = GefLibcManager() 

+

11072 return 

+

11073 

+

11074 def __str__(self) -> str: 

+

11075 return f"Gef(binary='{self.binary or 'None'}', arch={self.arch})" 

+

11076 

+

11077 def reinitialize_managers(self) -> None: 

+

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

+

11079 self.memory = GefMemoryManager() 

+

11080 self.heap = GefHeapManager() 

+

11081 self.session = GefSessionManager() 

+

11082 return 

+

11083 

+

11084 def setup(self) -> None: 

+

11085 """Setup initialize the runtime setup, which may require for the `gef` to be not None.""" 

+

11086 self.reinitialize_managers() 

+

11087 self.gdb = GefCommand() 

+

11088 self.gdb.setup() 

+

11089 tempdir = self.config["gef.tempdir"] 

+

11090 gef_makedirs(tempdir) 

+

11091 gdb.execute(f"save gdb-index {tempdir}") 

+

11092 return 

+

11093 

+

11094 def reset_caches(self) -> None: 

+

11095 """Recursively clean the cache of all the managers. Avoid calling this function directly, using `reset-cache` 

+

11096 is preferred""" 

+

11097 for mgr in (self.memory, self.heap, self.session, self.arch): 

+

11098 mgr.reset_caches() 

+

11099 return 

+

11100 

+

11101 

+

11102if __name__ == "__main__": 11102 ↛ exitline 11102 didn't jump to the function exit

+

11103 if sys.version_info[0] == 2: 11103 ↛ 11104line 11103 didn't jump to line 11104, because the condition on line 11103 was never true

+

11104 err("GEF has dropped Python2 support for GDB when it reached EOL on 2020/01/01.") 

+

11105 err("If you require GEF for GDB+Python2, use https://github.com/hugsy/gef-legacy.") 

+

11106 exit(1) 

+

11107 

+

11108 if GDB_VERSION < GDB_MIN_VERSION or PYTHON_VERSION < PYTHON_MIN_VERSION: 11108 ↛ 11109line 11108 didn't jump to line 11109, because the condition on line 11108 was never true

+

11109 err("You're using an old version of GDB. GEF will not work correctly. " 

+

11110 f"Consider updating to GDB {'.'.join(map(str, GDB_MIN_VERSION))} or higher " 

+

11111 f"(with Python {'.'.join(map(str, PYTHON_MIN_VERSION))} or higher).") 

+

11112 exit(1) 

+

11113 

+

11114 try: 

+

11115 pyenv = which("pyenv") 

+

11116 PYENV_ROOT = gef_pystring(subprocess.check_output([pyenv, "root"]).strip()) 

+

11117 PYENV_VERSION = gef_pystring(subprocess.check_output([pyenv, "version-name"]).strip()) 

+

11118 site_packages_dir = os.path.join(PYENV_ROOT, "versions", PYENV_VERSION, "lib", 

+

11119 f"python{PYENV_VERSION[:3]}", "site-packages") 

+

11120 site.addsitedir(site_packages_dir) 

+

11121 except FileNotFoundError: 

+

11122 pass 

+

11123 

+

11124 # When using a Python virtual environment, GDB still loads the system-installed Python 

+

11125 # so GEF doesn't load site-packages dir from environment 

+

11126 # In order to fix it, from the shell with venv activated we run the python binary, 

+

11127 # take and parse its path, add the path to the current python process using sys.path.extend 

+

11128 PYTHONBIN = which("python3") 

+

11129 PREFIX = gef_pystring(subprocess.check_output([PYTHONBIN, '-c', 'import os, sys;print((sys.prefix))'])).strip("\\n") 

+

11130 if PREFIX != sys.base_prefix: 11130 ↛ 11131line 11130 didn't jump to line 11131, because the condition on line 11130 was never true

+

11131 SITE_PACKAGES_DIRS = subprocess.check_output( 

+

11132 [PYTHONBIN, "-c", "import os, sys;print(os.linesep.join(sys.path).strip())"]).decode("utf-8").split() 

+

11133 sys.path.extend(SITE_PACKAGES_DIRS) 

+

11134 

+

11135 # setup config 

+

11136 gdb_initial_settings = ( 

+

11137 "set confirm off", 

+

11138 "set verbose off", 

+

11139 "set pagination off", 

+

11140 "set print elements 0", 

+

11141 "set history save on", 

+

11142 f"set history filename {os.getenv('GDBHISTFILE', '~/.gdb_history')}", 

+

11143 "set output-radix 0x10", 

+

11144 "set print pretty on", 

+

11145 "set disassembly-flavor intel", 

+

11146 "handle SIGALRM print nopass", 

+

11147 ) 

+

11148 for cmd in gdb_initial_settings: 

+

11149 try: 

+

11150 gdb.execute(cmd) 

+

11151 except gdb.error: 

+

11152 pass 

+

11153 

+

11154 # load GEF, set up the managers and load the plugins, functions, 

+

11155 reset() 

+

11156 gef.gdb.load() 

+

11157 gef.gdb.show_banner() 

+

11158 

+

11159 # load config 

+

11160 gef.gdb.load_extra_plugins() 

+

11161 

+

11162 # setup gdb prompt 

+

11163 gdb.prompt_hook = __gef_prompt__ 

+

11164 

+

11165 # gdb events configuration 

+

11166 gef_on_continue_hook(continue_handler) 

+

11167 gef_on_stop_hook(hook_stop_handler) 

+

11168 gef_on_new_hook(new_objfile_handler) 

+

11169 gef_on_exit_hook(exit_handler) 

+

11170 gef_on_memchanged_hook(memchanged_handler) 

+

11171 gef_on_regchanged_hook(regchanged_handler) 

+

11172 

+

11173 if gdb.current_progspace().filename is not None: 11173 ↛ 11177line 11173 didn't jump to line 11177, because the condition on line 11173 was never false

+

11174 # if here, we are sourcing gef from a gdb session already attached, force call to new_objfile (see issue #278) 

+

11175 new_objfile_handler(None) 

+

11176 

+

11177 GefTmuxSetup() 

+

11178 

+

11179 # `target remote` commands cannot be disabled, so print a warning message instead 

+

11180 errmsg = "Using `target remote` with GEF does not work, use `gef-remote` instead. You've been warned." 

+

11181 gdb.execute(f"define target hook-remote\n pi if calling_function() != \"connect\": err(\"{errmsg}\") \nend") 

+

11182 gdb.execute(f"define target hook-extended-remote\n pi if calling_function() != \"connect\": err(\"{errmsg}\") \nend") 

+
+ + + diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 000000000..771c969b4 --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,110 @@ + + + + + Coverage report + + + + + +
+
+

Coverage report: + 71.5956% +

+ +
+ +
+

+ coverage.py v7.2.7, + created at 2023-07-21 20:06 +0000 +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Modulestatementsmissingexcludedbranchespartialcoverage
gef.py755418250253641771.5956%
Total755418250253641771.5956%
+

+ 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..137c12ccc --- /dev/null +++ b/coverage/status.json @@ -0,0 +1 @@ +{"format":2,"version":"7.2.7","globals":"fe0721e3b7c0a5f33218a097f7e5438c","files":{"gef_py":{"hash":"170c9ac7faa0070163c804a33fd9d5cd","index":{"nums":[4,1,7554,0,1825,2536,417,1041],"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..fd2d1760b --- /dev/null +++ b/deprecated/index.html @@ -0,0 +1,1788 @@ + + + + + + + + + + + + + + + + + + + + + + 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..be13224cf --- /dev/null +++ b/faq/index.html @@ -0,0 +1,1995 @@ + + + + + + + + + + + + + + + + + + + + + + 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..21d66e6a4 --- /dev/null +++ b/functions/base/index.html @@ -0,0 +1,1712 @@ + + + + + + + + + + + + + + + + + + + + + + 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..cb8a4f666 --- /dev/null +++ b/functions/bss/index.html @@ -0,0 +1,1711 @@ + + + + + + + + + + + + + + + + + + + + + + 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..8ac2f85ea --- /dev/null +++ b/functions/got/index.html @@ -0,0 +1,1711 @@ + + + + + + + + + + + + + + + + + + + + + + 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..42b8a2618 --- /dev/null +++ b/functions/heap/index.html @@ -0,0 +1,1711 @@ + + + + + + + + + + + + + + + + + + + + + + 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..b31ebf1d8 --- /dev/null +++ b/functions/stack/index.html @@ -0,0 +1,1711 @@ + + + + + + + + + + + + + + + + + + + + + + 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..389f5fb18 --- /dev/null +++ b/index.html @@ -0,0 +1,1949 @@ + + + + + + + + + + + + + + + + + + + + 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
  • +
+

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..8295fef12 --- /dev/null +++ b/install/index.html @@ -0,0 +1,1990 @@ + + + + + + + + + + + + + + + + + + + + + + Installation - GEF - GDB Enhanced Features documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + +

Installing GEF

+

Prerequisites

+

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..d3b0eca69 --- /dev/null +++ b/obsolete/docs/index.html @@ -0,0 +1,1704 @@ + + + + + + + + + + + + + + + + + + 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..9266c6cc4 --- /dev/null +++ b/screenshots/index.html @@ -0,0 +1,2024 @@ + + + + + + + + + + + + + + + + + + + + + + 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..b375afd48 --- /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

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":""},{"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
  • 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 (Integer) of the n-th instruction after addr.

"},{"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.

"},{"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.Event') \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: int = 16) \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

Check the validity, dedup, and return all valid tids.

"},{"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-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..4162bbefe --- /dev/null +++ b/settings/context/index.html @@ -0,0 +1,2116 @@ + + + + + + + + + + + + + + + + + + + + + + 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..f478ca6c1 --- /dev/null +++ b/settings/dereference/index.html @@ -0,0 +1,1755 @@ + + + + + + + + + + + + + + + + + + + + + + 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..ca186c2ad --- /dev/null +++ b/settings/entry-break/index.html @@ -0,0 +1,1755 @@ + + + + + + + + + + + + + + + + + + + + + + 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..9bcb321e1 --- /dev/null +++ b/settings/gef/index.html @@ -0,0 +1,1945 @@ + + + + + + + + + + + + + + + + + + + + + + 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..63d752336 --- /dev/null +++ b/settings/got/index.html @@ -0,0 +1,1774 @@ + + + + + + + + + + + + + + + + + + + + + + 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..d0b215614 --- /dev/null +++ b/settings/heap-analysis-helper/index.html @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + 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..7f6bf4757 --- /dev/null +++ b/settings/heap-chunks/index.html @@ -0,0 +1,1755 @@ + + + + + + + + + + + + + + + + + + + + + + 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..a0423f804 --- /dev/null +++ b/settings/hexdump/index.html @@ -0,0 +1,1755 @@ + + + + + + + + + + + + + + + + + + + + + + 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..358e244fb --- /dev/null +++ b/settings/highlight/index.html @@ -0,0 +1,1755 @@ + + + + + + + + + + + + + + + + + + + + + + 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..338a449b9 --- /dev/null +++ b/settings/pattern/index.html @@ -0,0 +1,1755 @@ + + + + + + + + + + + + + + + + + + + + + + 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..0d6392d18 --- /dev/null +++ b/settings/pcustom/index.html @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + 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..1ecc0bcb7 --- /dev/null +++ b/settings/print-format/index.html @@ -0,0 +1,1755 @@ + + + + + + + + + + + + + + + + + + + + + + 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..9dec74b0a --- /dev/null +++ b/settings/process-search/index.html @@ -0,0 +1,1755 @@ + + + + + + + + + + + + + + + + + + + + + + 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..90df824be --- /dev/null +++ b/settings/search-pattern/index.html @@ -0,0 +1,1774 @@ + + + + + + + + + + + + + + + + + + + + + + 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..c23bb87f6 --- /dev/null +++ b/settings/theme/index.html @@ -0,0 +1,2059 @@ + + + + + + + + + + + + + + + + + + + + + + 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..2da847265 --- /dev/null +++ b/settings/trace-run/index.html @@ -0,0 +1,1772 @@ + + + + + + + + + + + + + + + + + + + + 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..577cccabb1be765a1f97686b95b63a4d8783eafe GIT binary patch literal 127 zcmV-_0D%7=iwFoo<+@}7|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