From 61782e4bcdb383ed51ba803f32b69be27051eca2 Mon Sep 17 00:00:00 2001 From: hugsy Date: Sat, 11 Dec 2021 17:56:51 -0800 Subject: [PATCH 01/62] [Refactor] Adds a global class `Gef` and instance `gef` that will be used to make the API simpler and more Pythonic. Also adds memory access (via `gef.memory`) and settings (via `gef.config`) --- gef.py | 1173 +++++++++++++++++++++++---------------------- tests/runtests.py | 4 +- 2 files changed, 597 insertions(+), 580 deletions(-) diff --git a/gef.py b/gef.py index 88e27fa3c..582099c64 100644 --- a/gef.py +++ b/gef.py @@ -65,6 +65,7 @@ import itertools import json import os +import pathlib import platform import re import shutil @@ -136,11 +137,10 @@ def update_gef(argv): print("[-] gef cannot run as standalone") sys.exit(0) -__gef__ = None +gef = None __commands__ = [] __functions__ = [] __aliases__ = [] -__config__ = {} __watches__ = {} __infos_files__ = [] __gef_convenience_vars_index__ = 0 @@ -164,9 +164,8 @@ def update_gef(argv): GDB_MIN_VERSION = (7, 7) GDB_VERSION = tuple(map(int, re.search(r"(\d+)[^\d]+(\d+)", gdb.VERSION).groups())) - -current_elf = None -current_arch = None +PYTHON_VERSION = sys.version_info[0:2] +PYTHON_MIN_VERSION = (3, 4) libc_args_definitions = {} @@ -202,7 +201,7 @@ def highlight_text(text): if not highlight_table: return text - if get_gef_setting("highlight.regex"): + if gef.config["highlight.regex"]: for match, color in highlight_table.items(): text = re.sub("(" + match + ")", Color.colorify("\\1", color), text) return text @@ -243,7 +242,7 @@ def wrapper(*args, **kwargs): try: rv = f(*args, **kwargs) finally: - redirect = get_gef_setting("context.redirect") + redirect = gef.config["context.redirect"] if redirect.startswith("/dev/pts/"): if not __gef_redirect_output_fd__: # if the FD has never been open, open it @@ -265,7 +264,7 @@ def wrapper(*args, **kwargs): # if the tty was closed, revert back to stdout fd = sys.stdout __gef_redirect_output_fd__ = None - set_gef_setting("context.redirect", "") + gef.config["context.redirect"] = "" fd.write(__gef_int_stream_buffer__.getvalue()) fd.flush() @@ -324,7 +323,7 @@ def blinkify(msg): return Color.colorify(msg, "blink") @staticmethod def colorify(text, attrs): """Color text according to the given attributes.""" - if get_gef_setting("gef.disable_color") is True: return text + if gef.config["gef.disable_color"] == True: return text colors = Color.colors msg = [colors[attr] for attr in attrs.split() if attr in colors] @@ -347,9 +346,9 @@ def __init__(self, *args, **kwargs): def __str__(self): value = format_address(self.value) - code_color = get_gef_setting("theme.address_code") - stack_color = get_gef_setting("theme.address_stack") - heap_color = get_gef_setting("theme.address_heap") + code_color = gef.config["theme.address_code"] + stack_color = gef.config["theme.address_stack"] + heap_color = gef.config["theme.address_heap"] if self.is_in_text_segment(): return Color.colorify(value, code_color) if self.is_in_heap_segment(): @@ -786,11 +785,11 @@ def search_for_main_arena(): malloc_hook_addr = parse_address("(void *)&__malloc_hook") if is_x86(): - addr = align_address_to_size(malloc_hook_addr + current_arch.ptrsize, 0x20) + addr = align_address_to_size(malloc_hook_addr + gef.arch.ptrsize, 0x20) elif is_arch(Elf.AARCH64) or is_arch(Elf.ARM): - addr = malloc_hook_addr - current_arch.ptrsize*2 - MallocStateStruct("*0").struct_size + addr = malloc_hook_addr - gef.arch.ptrsize*2 - MallocStateStruct("*0").struct_size else: - raise OSError("Cannot find main_arena for {}".format(current_arch.arch)) + raise OSError("Cannot find main_arena for {}".format(gef.arch.arch)) __gef_current_arena__ = "*0x{:x}".format(addr) return addr @@ -813,7 +812,7 @@ def __init__(self, addr): self.int_size = cached_lookup_type("int").sizeof self.size_t = cached_lookup_type("size_t") if not self.size_t: - ptr_type = "unsigned long" if current_arch.ptrsize == 8 else "unsigned int" + ptr_type = "unsigned long" if gef.arch.ptrsize == 8 else "unsigned int" self.size_t = cached_lookup_type(ptr_type) # Account for separation of have_fastchunks flag into its own field @@ -838,31 +837,31 @@ def fastbins_addr(self): @property def top_addr(self): - return self.fastbins_addr + self.num_fastbins * current_arch.ptrsize + return self.fastbins_addr + self.num_fastbins * gef.arch.ptrsize @property def last_remainder_addr(self): - return self.top_addr + current_arch.ptrsize + return self.top_addr + gef.arch.ptrsize @property def bins_addr(self): - return self.last_remainder_addr + current_arch.ptrsize + return self.last_remainder_addr + gef.arch.ptrsize @property def next_addr(self): - return self.bins_addr + self.num_bins * current_arch.ptrsize + self.int_size * 4 + return self.bins_addr + self.num_bins * gef.arch.ptrsize + self.int_size * 4 @property def next_free_addr(self): - return self.next_addr + current_arch.ptrsize + return self.next_addr + gef.arch.ptrsize @property def system_mem_addr(self): - return self.next_free_addr + current_arch.ptrsize * 2 + return self.next_free_addr + gef.arch.ptrsize * 2 @property def struct_size(self): - return self.system_mem_addr + current_arch.ptrsize * 2 - self.__addr + return self.system_mem_addr + gef.arch.ptrsize * 2 - self.__addr # struct members @property @@ -917,7 +916,7 @@ def __init__(self, addr): self.__addr = addr if type(addr) is int else parse_address(addr) self.size_t = cached_lookup_type("size_t") if not self.size_t: - ptr_type = "unsigned long" if current_arch.ptrsize == 8 else "unsigned int" + ptr_type = "unsigned long" if gef.arch.ptrsize == 8 else "unsigned int" self.size_t = cached_lookup_type(ptr_type) @property @@ -930,11 +929,11 @@ def ar_ptr_addr(self): @property def prev_addr(self): - return self.ar_ptr_addr + current_arch.ptrsize + return self.ar_ptr_addr + gef.arch.ptrsize @property def size_addr(self): - return self.prev_addr + current_arch.ptrsize + return self.prev_addr + gef.arch.ptrsize @property def mprotect_size_addr(self): @@ -1010,7 +1009,7 @@ def fastbin(self, i): addr = int(self.fastbinsY[i]) if addr == 0: return None - return GlibcChunk(addr + 2 * current_arch.ptrsize) + return GlibcChunk(addr + 2 * gef.arch.ptrsize) def bin(self, i): idx = i * 2 @@ -1076,7 +1075,7 @@ class GlibcChunk: Ref: https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/.""" def __init__(self, addr, from_base=False, allow_unaligned=True): - self.ptrsize = current_arch.ptrsize + self.ptrsize = gef.arch.ptrsize if from_base: self.data_address = addr + 2 * self.ptrsize else: @@ -1090,7 +1089,7 @@ def __init__(self, addr, from_base=False, allow_unaligned=True): return def get_chunk_size(self): - return read_int_from_memory(self.size_addr) & (~0x07) + return gef.memory.read_integer(self.size_addr) & (~0x07) @property def size(self): @@ -1108,7 +1107,7 @@ def usable_size(self): return self.get_usable_size() def get_prev_chunk_size(self): - return read_int_from_memory(self.prev_size_addr) + return gef.memory.read_integer(self.prev_size_addr) def get_next_chunk(self, allow_unaligned=False): addr = self.get_next_chunk_addr() @@ -1121,10 +1120,10 @@ def get_next_chunk_addr(self): def get_fwd_ptr(self, sll): # Not a single-linked-list (sll) or no Safe-Linking support yet if not sll or get_libc_version() < (2, 32): - return read_int_from_memory(self.data_address) + return gef.memory.read_integer(self.data_address) # Unmask ("reveal") the Safe-Linking pointer else: - return read_int_from_memory(self.data_address) ^ (self.data_address >> 12) + return gef.memory.read_integer(self.data_address) ^ (self.data_address >> 12) @property def fwd(self): @@ -1133,7 +1132,7 @@ def fwd(self): fd = fwd # for compat def get_bkw_ptr(self): - return read_int_from_memory(self.data_address + self.ptrsize) + return gef.memory.read_integer(self.data_address + self.ptrsize) @property def bck(self): @@ -1143,13 +1142,13 @@ def bck(self): # endif free-ed functions def has_p_bit(self): - return read_int_from_memory(self.size_addr) & 0x01 + return gef.memory.read_integer(self.size_addr) & 0x01 def has_m_bit(self): - return read_int_from_memory(self.size_addr) & 0x02 + return gef.memory.read_integer(self.size_addr) & 0x02 def has_n_bit(self): - return read_int_from_memory(self.size_addr) & 0x04 + return gef.memory.read_integer(self.size_addr) & 0x04 def is_used(self): """Check if the current block is used by: @@ -1285,9 +1284,9 @@ def titlify(text, color=None, msg_color=None): cols = get_terminal_size()[1] nb = (cols - len(text) - 2) // 2 if color is None: - color = __config__.get("theme.default_title_line")[0] + color = gef.config["theme.default_title_line"] if msg_color is None: - msg_color = __config__.get("theme.default_title_message")[0] + msg_color = gef.config["theme.default_title_message"] msg = [] msg.append(Color.colorify("{} ".format(HORIZONTAL_LINE * nb), color)) @@ -1402,7 +1401,7 @@ def style_byte(b, color=True): "ff": "green", } sbyte = "{:02x}".format(b) - if not color or get_gef_setting("highlight.regex"): + if not color or gef.config["highlight.regex"]: return sbyte if sbyte in style: @@ -1453,8 +1452,7 @@ def hexdump(source, length=0x10, separator=".", show_raw=False, show_symbol=True def is_debug(): """Check if debug mode is enabled.""" - return get_gef_setting("gef.debug") is True - + return gef.config["gef.debug"] == True context_hidden = False @@ -1485,38 +1483,6 @@ def disable_redirect_output(): return -@lru_cache() -def get_gef_setting(name): - """Read global gef settings. - Return None if not found. A valid config setting can never return None, - but False, 0 or "".""" - global __config__ - setting = __config__.get(name, None) - if not setting: - return None - return setting[0] - - -def set_gef_setting(name, value, _type=None, _desc=None): - """Set global gef settings. - Raise ValueError if `name` doesn't exist and `type` and `desc` - are not provided.""" - global __config__ - - if name not in __config__: - # create new setting - if _type is None or _desc is None: - raise ValueError("Setting '{}' is undefined, need to provide type and description".format(name)) - __config__[name] = [_type(value), _type, _desc] - return - - # set existing setting - func = __config__[name][1] - __config__[name][0] = func(value) - get_gef_setting.cache_clear() - return - - def gef_makedirs(path, mode=0o755): """Recursive mkdir() creation. If successful, return the absolute path of the directory created.""" abspath = os.path.expanduser(path) @@ -1579,7 +1545,7 @@ def gdb_disassemble(start_pc, **kwargs): loc = gdb_get_location_from_symbol(address) location = "<{}+{}>".format(*loc) if loc else "" - opcodes = read_memory(insn["addr"], insn["length"]) + opcodes = gef.memory.read(insn["addr"], insn["length"]) yield Instruction(address, location, mnemo, operands, opcodes) @@ -1587,8 +1553,8 @@ def gdb_disassemble(start_pc, **kwargs): def gdb_get_nth_previous_instruction_address(addr, n): """Return the address (Integer) of the `n`-th instruction before `addr`.""" # fixed-length ABI - if current_arch.instruction_length: - return max(0, addr - n * current_arch.instruction_length) + if gef.arch.instruction_length: + return max(0, addr - n * gef.arch.instruction_length) # variable-length ABI cur_insn_addr = gef_current_instruction(addr).address @@ -1624,8 +1590,8 @@ def gdb_get_nth_previous_instruction_address(addr, n): def gdb_get_nth_next_instruction_address(addr, n): """Return the address (Integer) of the `n`-th instruction after `addr`.""" # fixed-length ABI - if current_arch.instruction_length: - return addr + n * current_arch.instruction_length + if gef.arch.instruction_length: + return addr + n * gef.arch.instruction_length # variable-length ABI insn = list(gdb_disassemble(addr, count=n))[-1] @@ -1687,7 +1653,7 @@ def cs_insn_to_gef_insn(cs_insn): page_start = align_address_to_page(location) offset = location - page_start - pc = current_arch.pc + pc = gef.arch.pc skip = int(kwargs.get("skip", 0)) nb_prev = int(kwargs.get("nb_prev", 0)) @@ -1695,7 +1661,7 @@ def cs_insn_to_gef_insn(cs_insn): location = gdb_get_nth_previous_instruction_address(pc, nb_prev) nb_insn += nb_prev - code = kwargs.get("code", read_memory(location, gef_getpagesize() - offset - 1)) + code = kwargs.get("code", gef.memory.read(location, gef_getpagesize() - offset - 1)) code = bytes(code) for insn in cs.disasm(code, location): @@ -2113,10 +2079,10 @@ def get_ra(self, insn, frame): if self.is_ret(insn): # If it's a pop, we have to peek into the stack, otherwise use lr if insn.mnemonic == "pop": - ra_addr = current_arch.sp + (len(insn.operands)-1) * get_memory_alignment() + ra_addr = gef.arch.sp + (len(insn.operands)-1) * get_memory_alignment() ra = to_unsigned_long(dereference(ra_addr)) elif insn.mnemonic == "ldr": - return to_unsigned_long(dereference(current_arch.sp)) + return to_unsigned_long(dereference(gef.arch.sp)) else: # 'bx lr' or 'add pc, lr, #0' return get_register("$lr") elif frame.older(): @@ -2340,7 +2306,7 @@ def is_branch_taken(self, insn): def get_ra(self, insn, frame): ra = None if self.is_ret(insn): - ra = to_unsigned_long(dereference(current_arch.sp)) + ra = to_unsigned_long(dereference(gef.arch.sp)) if frame.older(): ra = frame.older().pc() @@ -2363,10 +2329,10 @@ def mprotect_asm(cls, addr, size, perm): def get_ith_parameter(self, i, in_func=True): if in_func: i += 1 # Account for RA being at the top of the stack - sp = current_arch.sp - sz = current_arch.ptrsize + sp = gef.arch.sp + sz = gef.arch.ptrsize loc = sp + (i * sz) - val = read_int_from_memory(loc) + val = gef.memory.read_integer(loc) key = "[sp + {:#x}]".format(i * sz) return key, val @@ -2740,60 +2706,9 @@ def mprotect_asm(cls, addr, size, perm): return "; ".join(insns) -def write_memory(address, buffer, length=0x10): - """Write `buffer` at address `address`.""" - return gdb.selected_inferior().write_memory(address, buffer, length) - - -@lru_cache() -def read_memory(addr, length=0x10): - """Return a `length` long byte array with the copy of the process memory at `addr`.""" - return gdb.selected_inferior().read_memory(addr, length).tobytes() - - -def read_int_from_memory(addr): - """Return an integer read from memory.""" - sz = current_arch.ptrsize - mem = read_memory(addr, sz) - unpack = u32 if sz == 4 else u64 - return unpack(mem) - - -def read_cstring_from_memory(address, max_length=GEF_MAX_STRING_LENGTH, encoding=None): - """Return a C-string read from memory.""" - - encoding = encoding or "unicode-escape" - - length = min(address | (DEFAULT_PAGE_SIZE-1), max_length+1) - try: - res_bytes = bytes(read_memory(address, length)) - except gdb.error: - err("Can't read memory at '{}'".format(address)) - return "" - try: - with warnings.catch_warnings(): - # ignore DeprecationWarnings (see #735) - warnings.simplefilter("ignore") - res = res_bytes.decode(encoding, "strict") - except UnicodeDecodeError: - # latin-1 as fallback due to its single-byte to glyph mapping - res = res_bytes.decode("latin-1", "replace") - - res = res.split("\x00", 1)[0] - ustr = res.replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t") - if max_length and len(res) > max_length: - return "{}[...]".format(ustr[:max_length]) - - return ustr - - -def read_ascii_string(address): - """Read an ASCII string from memory""" - cstr = read_cstring_from_memory(address) - if isinstance(cstr, str) and cstr and all([x in string.printable for x in cstr]): - return cstr - return None - +# +# Helpers +# def p8(x: int, s: bool = False) -> bytes: """Pack one byte respecting the current architecture endianness.""" @@ -2831,7 +2746,7 @@ def u64(x: bytes, s: bool = False) -> int: def is_ascii_string(address): """Helper function to determine if the buffer pointed by `address` is an ASCII string (in GDB)""" try: - return read_ascii_string(address) is not None + return gef.memory.read_ascii_string(address) is not None except Exception: return False @@ -2871,12 +2786,12 @@ def wrapper(*args, **kwargs): return wrapper -def obsolete_command(f): +def deprecated(f): """Decorator to add a warning when a command is obsolete and will be removed.""" @functools.wraps(f) def wrapper(*args, **kwargs): - warn("This command is obsolete and will be removed in a feature release.") + warn("'{}' is obsolete and will be removed in a feature release.".format(f.__name__)) return f(*args, **kwargs) return wrapper @@ -2914,10 +2829,10 @@ def only_if_current_arch_in(valid_architectures): def wrapper(f): def inner_f(*args, **kwargs): - if current_arch in valid_architectures: + if gef.arch in valid_architectures: f(*args, **kwargs) else: - reason = "This command cannot work for the '{}' architecture".format(current_arch.arch) + reason = "This command cannot work for the '{}' architecture".format(gef.arch.arch) raise EnvironmentError(reason) return inner_f return wrapper @@ -3162,12 +3077,12 @@ def is_macho(filename): def download_file(target, use_cache=False, local_name=None): - """Download filename `target` inside the mirror tree inside the get_gef_setting("gef.tempdir"). - The tree architecture must be get_gef_setting("gef.tempdir")/gef//. + """Download filename `target` inside the mirror tree inside the gef.config["gef.tempdir"]. + The tree architecture must be gef.config["gef.tempdir"]/gef//. This allow a "chroot-like" tree format.""" try: - local_root = os.path.sep.join([get_gef_setting("gef.tempdir"), str(get_pid())]) + local_root = os.path.sep.join([gef.config["gef.tempdir"], str(get_pid())]) if local_name is None: local_path = os.path.sep.join([local_root, os.path.dirname(target)]) local_name = os.path.sep.join([local_path, os.path.basename(target)]) @@ -3244,7 +3159,7 @@ def get_process_maps_linux(proc_map_file): def get_mach_regions(): - sp = current_arch.sp + sp = gef.arch.sp for line in gdb.execute("info mach-regions", to_string=True).splitlines(): line = line.strip() addr, perm, _ = line.split(" ", 2) @@ -3458,7 +3373,7 @@ def exit_handler(event): reset_all_caches() __gef_qemu_mode__ = False - if __gef_remote__ and get_gef_setting("gef-remote.clean_on_exit") is True: + if __gef_remote__ and gef.config["gef-remote.clean_on_exit"] == True: shutil.rmtree("/tmp/gef/{:d}".format(__gef_remote__)) __gef_remote__ = None return @@ -3476,10 +3391,10 @@ def regchanged_handler(event): def load_libc_args(): # load libc function arguments' definitions - if not get_gef_setting("context.libc_args"): + if not gef.config["context.libc_args"]: return - path = get_gef_setting("context.libc_args_path") + path = gef.config["context.libc_args_path"] if path is None: warn("Config `context.libc_args_path` not set but `context.libc_args` is True. Make sure you have `gef-extras` installed") return @@ -3490,7 +3405,7 @@ def load_libc_args(): warn("Config `context.libc_args_path` set but it's not a directory") return - _arch_mode = "{}_{}".format(current_arch.arch.lower(), current_arch.mode) + _arch_mode = "{}_{}".format(gef.arch.arch.lower(), gef.arch.mode) _libc_args_file = "{}/{}.json".format(path, _arch_mode) global libc_args_definitions @@ -3578,8 +3493,8 @@ def get_generic_running_arch(module, prefix, to_string=False): if not is_alive(): return None, None - if current_arch is not None: - arch, mode = current_arch.arch, current_arch.mode + if gef.arch is not None: + arch, mode = gef.arch.arch, gef.arch.mode else: raise OSError("Emulation not supported for your OS") @@ -3607,16 +3522,16 @@ def get_capstone_arch(arch=None, mode=None, endian=None, to_string=False): mode = "32" endian = is_big_endian() return get_generic_arch(capstone, "CS", - arch or current_arch.arch, - mode or current_arch.mode, + arch or gef.arch.arch, + mode or gef.arch.mode, endian or is_big_endian(), to_string) if (arch, mode, endian) == (None, None, None): return get_generic_running_arch(capstone, "CS", to_string) return get_generic_arch(capstone, "CS", - arch or current_arch.arch, - mode or current_arch.mode, + arch or gef.arch.arch, + mode or gef.arch.mode, endian or is_big_endian(), to_string) @@ -3654,13 +3569,13 @@ def get_unicorn_registers(to_string=False): unicorn = sys.modules["unicorn"] regs = {} - if current_arch is not None: - arch = current_arch.arch.lower() + if gef.arch is not None: + arch = gef.arch.arch.lower() else: raise OSError("Oops") const = getattr(unicorn, "{}_const".format(arch)) - for reg in current_arch.all_registers: + for reg in gef.arch.all_registers: regname = "UC_{:s}_REG_{:s}".format(arch.upper(), reg[1:].upper()) if to_string: regs[reg] = "{:s}.{:s}".format(const.__name__, regname) @@ -3748,7 +3663,7 @@ def is_x86(): @lru_cache() def is_arch(arch): - elf = current_elf or get_elf_headers() + elf = gef.binary or get_elf_headers() return elf.e_machine == arch @@ -3759,6 +3674,7 @@ def set_arch(arch=None, default=None): set that arch. Return the selected arch, or raise an OSError. """ + global gef arches = { "ARM": ARM, Elf.ARM: ARM, "AARCH64": AARCH64, "ARM64": AARCH64, Elf.AARCH64: AARCH64, @@ -3771,31 +3687,30 @@ def set_arch(arch=None, default=None): "SPARC64": SPARC64, Elf.SPARC64: SPARC64, "MIPS": MIPS, Elf.MIPS: MIPS, } - global current_arch, current_elf if arch: try: - current_arch = arches[arch.upper()]() - return current_arch + gef.arch = arches[arch.upper()]() + return gef.arch except KeyError: raise OSError("Specified arch {:s} is not supported".format(arch.upper())) - if not current_elf: + if not gef.binary: elf = get_elf_headers() - current_elf = elf if elf.is_valid() else None + gef.binary = elf if elf.is_valid() else None - arch_name = current_elf.e_machine if current_elf else get_arch() + arch_name = gef.binary.e_machine if gef.binary else get_arch() try: - current_arch = arches[arch_name]() + gef.arch = arches[arch_name]() except KeyError: if default: try: - current_arch = arches[default.upper()]() + gef.arch = arches[default.upper()]() except KeyError: raise OSError("CPU not supported, neither is default {:s}".format(default.upper())) else: raise OSError("CPU type is currently not supported: {:s}".format(get_arch())) - return current_arch + return gef.arch @lru_cache() @@ -3844,7 +3759,7 @@ def clear_screen(tty=""): f.write("\x1b[H\x1b[J") except PermissionError: __gef_redirect_output_fd__ = None - set_gef_setting("context.redirect", "") + gef.config["context.redirect"] = "" return @@ -3899,7 +3814,7 @@ def malloc_align_address(address): # Generic case: # https://elixir.bootlin.com/glibc/glibc-2.26/source/sysdeps/generic/malloc-alignment.h#L22 __alignof__long_double = int(safe_parse_and_eval("_Alignof(long double)") or __default_malloc_alignment) # fallback to default if the expression fails to evaluate - malloc_alignment = max(__alignof__long_double, 2 * current_arch.ptrsize) + malloc_alignment = max(__alignof__long_double, 2 * gef.arch.ptrsize) ceil = lambda n: int(-1 * n // 1 * -1) # align address to nearest next multiple of malloc_alignment @@ -4035,7 +3950,7 @@ def gef_read_canary(): return None canary_location = auxval["AT_RANDOM"] - canary = read_int_from_memory(canary_location) + canary = gef.memory.read_integer(canary_location) canary &= ~0xFF return canary, canary_location @@ -4198,14 +4113,14 @@ def __init__(self, spec, num_args): def stop(self): reset_all_caches() msg = [] - ptr, addr = current_arch.get_ith_parameter(self.num_args) + ptr, addr = gef.arch.get_ith_parameter(self.num_args) addr = lookup_address(addr) if not addr.valid: return False if addr.section.permission.value & Permission.WRITE: - content = read_cstring_from_memory(addr.value) + content = gef.memory.read_cstring(addr.value) name = addr.info.name if addr.info else addr.section.path msg.append(Color.colorify("Format string helper", "yellow bold")) msg.append("Possible insecure format string: {:s}('{:s}' {:s} {:#x}: '{:s}')".format(self.location, ptr, RIGHT_ARROW, addr.value, content)) @@ -4251,7 +4166,7 @@ def __init__(self, loc, code, pc): def stop(self): info("Restoring original context") - write_memory(self.original_pc, self.original_code, len(self.original_code)) + gef.memory.write(self.original_pc, self.original_code, len(self.original_code)) info("Restoring $pc") gdb.execute("set $pc = {:#x}".format(self.original_pc)) return True @@ -4268,7 +4183,7 @@ def __init__(self, name): def stop(self): reset_all_caches() - _, size = current_arch.get_ith_parameter(0) + _, size = gef.arch.get_ith_parameter(0) self.retbp = TraceMallocRetBreakpoint(size, self.name) return False @@ -4289,11 +4204,11 @@ def stop(self): if self.return_value: loc = int(self.return_value) else: - loc = parse_address(current_arch.return_register) + loc = parse_address(gef.arch.return_register) size = self.size ok("{} - {}({})={:#x}".format(Color.colorify("Heap-Analysis", "yellow bold"), self.name, size, loc)) - check_heap_overlap = get_gef_setting("heap-analysis-helper.check_heap_overlap") + check_heap_overlap = gef.config["heap-analysis-helper.check_heap_overlap"] # pop from free-ed list if it was in it if __heap_freed_list__: @@ -4353,8 +4268,8 @@ def __init__(self): return def stop(self): - _, ptr = current_arch.get_ith_parameter(0) - _, size = current_arch.get_ith_parameter(1) + _, ptr = gef.arch.get_ith_parameter(0) + _, size = gef.arch.get_ith_parameter(1) self.retbp = TraceReallocRetBreakpoint(ptr, size) return False @@ -4375,7 +4290,7 @@ def stop(self): if self.return_value: newloc = int(self.return_value) else: - newloc = parse_address(current_arch.return_register) + newloc = parse_address(gef.arch.return_register) if newloc != self: ok("{} - realloc({:#x}, {})={}".format(Color.colorify("Heap-Analysis", "yellow bold"), @@ -4413,18 +4328,18 @@ def __init__(self): def stop(self): reset_all_caches() - _, addr = current_arch.get_ith_parameter(0) + _, addr = gef.arch.get_ith_parameter(0) msg = [] - check_free_null = get_gef_setting("heap-analysis-helper.check_free_null") - check_double_free = get_gef_setting("heap-analysis-helper.check_double_free") - check_weird_free = get_gef_setting("heap-analysis-helper.check_weird_free") - check_uaf = get_gef_setting("heap-analysis-helper.check_uaf") + check_free_null = gef.config["heap-analysis-helper.check_free_null"] + check_double_free = gef.config["heap-analysis-helper.check_double_free"] + check_weird_free = gef.config["heap-analysis-helper.check_weird_free"] + check_uaf = gef.config["heap-analysis-helper.check_uaf"] ok("{} - free({:#x})".format(Color.colorify("Heap-Analysis", "yellow bold"), addr)) if addr == 0: if check_free_null: msg.append(Color.colorify("Heap-Analysis", "yellow bold")) - msg.append("Attempting to free(NULL) at {:#x}".format(current_arch.pc)) + msg.append("Attempting to free(NULL) at {:#x}".format(gef.arch.pc)) msg.append("Reason: if NULL page is allocatable, this can lead to code execution.") push_context_message("warn", "\n".join(msg)) return True @@ -4433,7 +4348,7 @@ def stop(self): if addr in [x for (x, y) in __heap_freed_list__]: if check_double_free: msg.append(Color.colorify("Heap-Analysis", "yellow bold")) - msg.append("Double-free detected {} free({:#x}) is called at {:#x} but is already in the free-ed list".format(RIGHT_ARROW, addr, current_arch.pc)) + msg.append("Double-free detected {} free({:#x}) is called at {:#x} but is already in the free-ed list".format(RIGHT_ARROW, addr, gef.arch.pc)) msg.append("Execution will likely crash...") push_context_message("warn", "\n".join(msg)) return True @@ -4500,7 +4415,7 @@ def stop(self): # software watchpoints stop after the next statement (see # https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html) - pc = gdb_get_nth_previous_instruction_address(current_arch.pc, 2) + pc = gdb_get_nth_previous_instruction_address(gef.arch.pc, 2) insn = gef_current_instruction(pc) msg = [] msg.append(Color.colorify("Heap-Analysis", "yellow bold")) @@ -4556,7 +4471,7 @@ 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) """ - __gef__.add_context_pane(pane_name, display_pane_function, pane_title_function) + gef.instance.add_context_pane(pane_name, display_pane_function, pane_title_function) return @@ -4566,12 +4481,12 @@ def pane_title(): return "example:pane" def register_external_command(obj): """Registering function for new GEF (sub-)command to GDB.""" - global __commands__, __gef__ + global __commands__, gef cls = obj.__class__ __commands__.append(cls) - __gef__.load(initial=False) - __gef__.doc.add_command_to_doc((cls._cmdline_, cls, None)) - __gef__.doc.refresh() + gef.instance.load(initial=False) + gef.instance.doc.add_command_to_doc((cls._cmdline_, cls, None)) + gef.instance.doc.refresh() return cls @@ -4654,51 +4569,58 @@ def __sanitize_class_name(clsname): if " " not in clsname: return clsname return "-".join(clsname.split()) - class_name = __sanitize_class_name(self.__class__._cmdline_) return "{:s}.{:s}".format(class_name, name) + def __iter__(self): + for key in gef.config.keys(): + if key.startswith(self._cmdline_): + yield key.replace("{:s}.".format(self._cmdline_), "", 1) + @property def settings(self): """Return the list of settings for this command.""" - return [ x.split(".", 1)[1] for x in __config__ - if x.startswith("{:s}.".format(self._cmdline_)) ] + return list(iter(self)) + @deprecated def get_setting(self, name): + return self.__getitem__(name) + + def __getitem__(self, name): key = self.__get_setting_name(name) - setting = __config__[key] - return setting[1](setting[0]) + return gef.config[key] + @deprecated def has_setting(self, name): - key = self.__get_setting_name(name) - return key in __config__ + return self.__contains__(name) - def update_setting(self, name, value, description=None): - """Update the value of a setting without destroying the description""" - # make sure settings are always associated to the root command (which derives from GenericCommand) - if "GenericCommand" not in [x.__name__ for x in self.__class__.__bases__]: - return - key = self.__get_setting_name(name) - __config__[key][0] = value - __config__[key][1] = type(value) - if description: - __config__[key][3] = description - get_gef_setting.cache_clear() - return + def __contains__(self, name): + return self.__get_setting_name(name) in gef.config + @deprecated def add_setting(self, name, value, description=""): + return self.__setitem__(name, (value, type(value), description)) + + def __setitem__(self, name, value): # make sure settings are always associated to the root command (which derives from GenericCommand) if "GenericCommand" not in [x.__name__ for x in self.__class__.__bases__]: return key = self.__get_setting_name(name) - __config__[key] = [value, type(value), description] - get_gef_setting.cache_clear() + if key in gef.config: + gef.config[key].value = value + else: + if len(value) == 1: + gef.config[key] = GefSetting(value[0]) + elif len(value) == 2: + gef.config[key] = GefSetting(value[0], description=value[1]) return + @deprecated def del_setting(self, name): - key = self.__get_setting_name(name) - del __config__[key] - get_gef_setting.cache_clear() + return self.__delitem__(name) + + def __delitem__(self, name): + del gef.config[self.__get_setting_name(name)] return def __set_repeat_count(self, argv, from_tty): @@ -4714,20 +4636,6 @@ def __set_repeat_count(self, argv, from_tty): return -# Copy/paste this template for new command -# @register_command -# class TemplateCommand(GenericCommand): -# """TemplateCommand: description here will be seen in the help menu for the command.""" -# _cmdline_ = "template-fake" -# _syntax_ = "{:s}".format(_cmdline_) -# _aliases_ = ["tpl-fk",] -# def __init__(self): -# super().__init__(complete=gdb.COMPLETE_FILENAME) -# return -# def do_invoke(self, argv): -# return - - @register_command class VersionCommand(GenericCommand): """Display GEF version info.""" @@ -4756,7 +4664,7 @@ def do_invoke(self, argv): gef_print("GDB-Python: {}".format(py_ver, )) if "full" in argv: - gef_print("Loaded commands: {}".format(", ".join(__gef__.loaded_command_names))) + gef_print("Loaded commands: {}".format(", ".join(gef.instance.loaded_command_names))) return @@ -4793,7 +4701,7 @@ def __init__(self): def do_invoke(self, argv, *args, **kwargs): """Default value for print-format command.""" args = kwargs["arguments"] - args.bitlen = args.bitlen or current_arch.ptrsize * 2 + args.bitlen = args.bitlen or gef.arch.ptrsize * 2 valid_bitlens = self.format_matrix.keys() if args.bitlen not in valid_bitlens: @@ -4811,7 +4719,7 @@ def do_invoke(self, argv, *args, **kwargs): data = [] for addr in range(start_addr, end_addr, size): - value = struct.unpack(fmt, read_memory(addr, size))[0] + value = struct.unpack(fmt, gef.memory.read(addr, size))[0] data += [value] sdata = ", ".join(map(hex, data)) @@ -5057,7 +4965,7 @@ def do_invoke(self, argv): def evaluate(self, expr): def show_as_int(i): - off = current_arch.ptrsize*8 + off = gef.arch.ptrsize*8 def comp2_x(x): return "{:x}".format((x + (1 << off)) % (1 << off)) def comp2_b(x): return "{:b}".format((x + (1 << off)) % (1 << off)) @@ -5125,7 +5033,7 @@ def do_invoke(self, argv): return canary, location = res - info("Found AT_RANDOM at {:#x}, reading {} bytes".format(location, current_arch.ptrsize)) + info("Found AT_RANDOM at {:#x}, reading {} bytes".format(location, gef.arch.ptrsize)) info("The canary of process {} is {:#x}".format(get_pid(), canary)) return @@ -5302,23 +5210,23 @@ class GefThemeCommand(GenericCommand): def __init__(self, *args, **kwargs): super().__init__(self._cmdline_) - self.add_setting("context_title_line", "gray", "Color of the borders in context window") - self.add_setting("context_title_message", "cyan", "Color of the title in context window") - self.add_setting("default_title_line", "gray", "Default color of borders") - self.add_setting("default_title_message", "cyan", "Default color of title") - self.add_setting("table_heading", "blue", "Color of the column headings to tables (e.g. vmmap)") - self.add_setting("old_context", "gray", "Color to use to show things such as code that is not immediately relevant") - self.add_setting("disassemble_current_instruction", "green", "Color to use to highlight the current $pc when disassembling") - self.add_setting("dereference_string", "yellow", "Color of dereferenced string") - self.add_setting("dereference_code", "gray", "Color of dereferenced code") - self.add_setting("dereference_base_address", "cyan", "Color of dereferenced address") - self.add_setting("dereference_register_value", "bold blue", "Color of dereferenced register") - self.add_setting("registers_register_name", "blue", "Color of the register name in the register window") - self.add_setting("registers_value_changed", "bold red", "Color of the changed register in the register window") - self.add_setting("address_stack", "pink", "Color to use when a stack address is found") - self.add_setting("address_heap", "green", "Color to use when a heap address is found") - self.add_setting("address_code", "red", "Color to use when a code address is found") - self.add_setting("source_current_line", "green", "Color to use for the current code line in the source window") + self["context_title_line"] = ( "gray", "Color of the borders in context window") + self["context_title_message"] = ( "cyan", "Color of the title in context window") + self["default_title_line"] = ( "gray", "Default color of borders") + self["default_title_message"] = ( "cyan", "Default color of title") + self["table_heading"] = ( "blue", "Color of the column headings to tables (e.g. vmmap)") + self["old_context"] = ( "gray", "Color to use to show things such as code that is not immediately relevant") + self["disassemble_current_instruction"] = ( "green", "Color to use to highlight the current $pc when disassembling") + self["dereference_string"] = ( "yellow", "Color of dereferenced string") + self["dereference_code"] = ( "gray", "Color of dereferenced code") + self["dereference_base_address"] = ( "cyan", "Color of dereferenced address") + self["dereference_register_value"] = ( "bold blue", "Color of dereferenced register") + self["registers_register_name"] = ( "blue", "Color of the register name in the register window") + self["registers_value_changed"] = ( "bold red", "Color of the changed register in the register window") + self["address_stack"] = ( "pink", "Color to use when a stack address is found") + self["address_heap"] = ( "green", "Color to use when a heap address is found") + self["address_code"] = ( "red", "Color to use when a code address is found") + self["source_current_line"] = ( "green", "Color to use for the current code line in the source window") return def do_invoke(self, args): @@ -5326,25 +5234,25 @@ def do_invoke(self, args): argc = len(args) if argc == 0: - for setting in sorted(self.settings): - value = self.get_setting(setting) - value = Color.colorify(value, value) - gef_print("{:40s}: {:s}".format(setting, value)) + for key in self.settings: + setting = self[key] + value = Color.colorify(setting, setting) + gef_print("{:40s}: {:s}".format(key, value)) return setting = args[0] - if not self.has_setting(setting): + if not setting in self: err("Invalid key") return if argc == 1: - value = self.get_setting(setting) + value = self[setting] value = Color.colorify(value, value) gef_print("{:40s}: {:s}".format(setting, value)) return val = [x for x in args[1:] if x in Color.colors] - self.add_setting(setting, " ".join(val)) + self[setting] = " ".join(val) return @@ -5362,11 +5270,11 @@ class PCustomCommand(GenericCommand): def __init__(self): super().__init__(prefix=True) - self.add_setting("struct_path", os.sep.join([get_gef_setting("gef.tempdir"), "structs"]), "Path to store/load the structure ctypes files") - self.add_setting("max_depth", 4, "Maximum level of recursion supported") - self.add_setting("structure_name", "bold blue", "Color of the structure name") - self.add_setting("structure_type", "bold red", "Color of the attribute type") - self.add_setting("structure_size", "green", "Color of the attribute size") + self["struct_path"] = ( os.sep.join( (gef.config["gef.tempdir"], "structs")), "Path to store/load the structure ctypes files") + self["max_depth"] = ( 4, "Maximum level of recursion supported") + self["structure_name"] = ( "bold blue", "Color of the structure name") + self["structure_type"] = ( "bold red", "Color of the attribute type") + self["structure_size"] = ( "green", "Color of the attribute size") return @@ -5391,7 +5299,7 @@ def do_invoke(self, argv): return def get_pcustom_absolute_root_path(self): - path = os.path.expanduser(get_gef_setting("pcustom.struct_path")) + path = os.path.expanduser(gef.config["pcustom.struct_path"]) path = os.path.realpath(path) if not os.path.isdir(path): raise RuntimeError("setting `struct_path` must be set correctly") @@ -5441,13 +5349,13 @@ def apply_structure_to_address(self, mod_name, struct_name, addr, depth=0): err("Invalid structure name '{:s}'".format(struct_name)) return - if depth >= self.get_setting("max_depth"): + if depth >= self["max_depth"]: warn("maximum recursion level reached") return try: _class, _struct = self.get_structure_class(mod_name, struct_name) - data = read_memory(addr, ctypes.sizeof(_struct)) + data = gef.memory.read(addr, ctypes.sizeof(_struct)) except gdb.MemoryError: err("{}Cannot reach memory {:#x}".format(" " * depth, addr)) return @@ -5480,7 +5388,7 @@ def apply_structure_to_address(self, mod_name, struct_name, addr, depth=0): self.apply_structure_to_address(mod_name, _type.__name__, addr + _offset, depth + 1) elif _type.__name__.startswith("LP_"): # hack __sub_type_name = _type.__name__.replace("LP_", "") - __deref = u64( read_memory(addr + _offset, 8) ) + __deref = u64( gef.memory.read(addr + _offset, 8) ) self.apply_structure_to_address(mod_name, __sub_type_name, __deref, depth + 1) return @@ -5563,8 +5471,8 @@ def __list_custom_structures(self): path = self.get_pcustom_absolute_root_path() info("Listing custom structures from '{:s}'".format(path)) structures = self.enumerate_structures() - struct_color = get_gef_setting("pcustom.structure_type") - filename_color = get_gef_setting("pcustom.structure_name") + struct_color = gef.config["pcustom.structure_type"] + filename_color = gef.config["pcustom.structure_name"] for filename in structures: __modules = ", ".join([Color.colorify(x, struct_color) for x in structures[filename]]) __filename = Color.colorify(filename, filename_color) @@ -5613,9 +5521,9 @@ def __dump_custom_structure(self, mod_name, struct_name): for _name, _type in _struct._fields_: _size = ctypes.sizeof(_type) - __name = Color.colorify(_name, get_gef_setting("pcustom.structure_name")) - __type = Color.colorify(_type.__name__, get_gef_setting("pcustom.structure_type")) - __size = Color.colorify(hex(_size), get_gef_setting("pcustom.structure_size")) + __name = Color.colorify(_name, gef.config["pcustom.structure_name"]) + __type = Color.colorify(_type.__name__, gef.config["pcustom.structure_type"]) + __size = Color.colorify(hex(_size), gef.config["pcustom.structure_size"]) __offset = Color.boldify("{:04x}".format(getattr(_class, _name).offset)) gef_print("{:s} {:32s} {:16s} /* size={:s} */".format(__offset, __name, __type, __size)) return @@ -5710,17 +5618,17 @@ def do_invoke(self, argv): # we will do this in the stack, since connect() wants a pointer to a struct vmmap = get_process_maps() stack_addr = [entry.page_start for entry in vmmap if entry.path == "[stack]"][0] - original_contents = read_memory(stack_addr, 8) + original_contents = gef.memory.read(stack_addr, 8) - write_memory(stack_addr, "\x02\x00", 2) - write_memory(stack_addr + 0x2, struct.pack(" size: m = "Cannot patch instruction at {:#x} (nop_size is:{:d},insn_size is:{:d})".format(loc, len(nops), size) @@ -6817,7 +6725,7 @@ def nop_bytes(self, loc, num_bytes): return while len(nops) < size: - nops += current_arch.nop_insn + nops += gef.arch.nop_insn if len(nops) != size: err("Cannot patch instruction at {:#x} (nop instruction does not evenly fit in requested size)" @@ -6825,7 +6733,7 @@ def nop_bytes(self, loc, num_bytes): return ok("Patching {:d} bytes from {:s}".format(size, format_address(loc))) - write_memory(loc, nops, size) + gef.memory.write(loc, nops, size) return @@ -6849,7 +6757,7 @@ def __init__(self): @parse_arguments({"address": ""}, {("-r", "--retval"): 0}) def do_invoke(self, argv, *args, **kwargs): args = kwargs["arguments"] - loc = args.address if args.address else "*{:#x}".format(current_arch.pc) + loc = args.address if args.address else "*{:#x}".format(gef.arch.pc) StubBreakpoint(loc, args.retval) return @@ -6880,7 +6788,7 @@ def __init__(self): def do_invoke(self, argv, *args, **kwargs): args = kwargs["arguments"] show_opcodes = args.show_opcodes - length = args.length or get_gef_setting("context.nb_lines_code") + length = args.length or gef.config["context.nb_lines_code"] location = parse_address(args.location) if not location: info("Can't find address for {}".format(args.location)) @@ -6897,7 +6805,7 @@ def do_invoke(self, argv, *args, **kwargs): text_insn = insn_fmt.format(insn) msg = "" - if insn.address == current_arch.pc: + if insn.address == gef.arch.pc: msg = Color.colorify("{} {}".format(RIGHT_ARROW, text_insn), "bold red") reason = self.capstone_analyze_pc(insn, length)[0] if reason: @@ -6911,8 +6819,8 @@ def do_invoke(self, argv, *args, **kwargs): return def capstone_analyze_pc(self, insn, nb_insn): - if current_arch.is_conditional_branch(insn): - is_taken, reason = current_arch.is_branch_taken(insn) + if gef.arch.is_conditional_branch(insn): + is_taken, reason = gef.arch.is_branch_taken(insn) if is_taken: reason = "[Reason: {:s}]".format(reason) if reason else "" msg = Color.colorify("\tTAKEN {:s}".format(reason), "bold green") @@ -6921,7 +6829,7 @@ def capstone_analyze_pc(self, insn, nb_insn): msg = Color.colorify("\tNOT taken {:s}".format(reason), "bold red") return (is_taken, msg) - if current_arch.is_call(insn): + if gef.arch.is_call(insn): target_address = int(insn.operands[-1].split()[0], 16) msg = [] for i, new_insn in enumerate(capstone_disassemble(target_address, nb_insn)): @@ -7055,7 +6963,7 @@ class GlibcHeapChunksCommand(GenericCommand): def __init__(self): super().__init__(complete=gdb.COMPLETE_LOCATION) - self.add_setting("peek_nb_byte", 16, "Hexdump N first byte(s) inside the chunk data (0 to disable)") + self["peek_nb_byte"] = ( 16, "Hexdump N first byte(s) inside the chunk data (0 to disable)") return @parse_arguments({"arena_address": ""}, {("--all", "-a"): True, "--allow-unaligned": True}) @@ -7090,7 +6998,7 @@ def dump_chunks_arena(self, arena, print_arena=False, allow_unaligned=False): return def dump_chunks_heap(self, start, until=None, top=None, allow_unaligned=False): - nb = self.get_setting("peek_nb_byte") + nb = self["peek_nb_byte"] current_chunk = GlibcChunk(start, from_base=True, allow_unaligned=allow_unaligned) while True: if current_chunk.base_address == top: @@ -7100,7 +7008,7 @@ def dump_chunks_heap(self, start, until=None, top=None, allow_unaligned=False): break line = str(current_chunk) if nb: - line += "\n [{}]".format(hexdump(read_memory(current_chunk.data_address, nb), nb, base=current_chunk.data_address)) + line += "\n [{}]".format(hexdump(gef.memory.read(current_chunk.data_address, nb), nb, base=current_chunk.data_address)) gef_print(line) next_chunk_addr = current_chunk.get_next_chunk_addr() @@ -7251,7 +7159,7 @@ def do_invoke(self, argv): if msg: tcache_empty = False - gef_print("Tcachebins[idx={:d}, size={:#x}] count={:d} ".format(i, (i+2)*(current_arch.ptrsize)*2, count), end="") + gef_print("Tcachebins[idx={:d}, size={:#x}] count={:d} ".format(i, (i+2)*(gef.arch.ptrsize)*2, count), end="") gef_print("".join(msg)) if tcache_empty: @@ -7314,16 +7222,16 @@ def tcachebin(tcache_base, i): # TCACHE_MAX_BINS * _1_ + TCACHE_MAX_BINS * ptrsize new_tcache_min_size = ( GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS * 2 + - GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS * current_arch.ptrsize) + GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS * gef.arch.ptrsize) if tcache_chunk.usable_size < new_tcache_min_size: tcache_count_size = 1 - count = ord(read_memory(tcache_base + tcache_count_size*i, 1)) + count = ord(gef.memory.read(tcache_base + tcache_count_size*i, 1)) else: tcache_count_size = 2 - count = u16(read_memory(tcache_base + tcache_count_size*i, 2)) + count = u16(gef.memory.read(tcache_base + tcache_count_size*i, 2)) - chunk = dereference(tcache_base + tcache_count_size*GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS + i*current_arch.ptrsize) + chunk = dereference(tcache_base + tcache_count_size*GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS + i*gef.arch.ptrsize) chunk = GlibcChunk(int(chunk)) if chunk else None return chunk, count @@ -7345,7 +7253,7 @@ def do_invoke(self, argv): def fastbin_index(sz): return (sz >> 4) - 2 if SIZE_SZ == 8 else (sz >> 3) - 2 - SIZE_SZ = current_arch.ptrsize + SIZE_SZ = gef.arch.ptrsize MAX_FAST_SIZE = 80 * SIZE_SZ // 4 NFASTBINS = fastbin_index(MAX_FAST_SIZE) - 1 @@ -7518,25 +7426,25 @@ class DetailRegistersCommand(GenericCommand): @only_if_gdb_running @parse_arguments({"registers": [""]}, {}) def do_invoke(self, argv, *args, **kwargs): - unchanged_color = get_gef_setting("theme.registers_register_name") - changed_color = get_gef_setting("theme.registers_value_changed") - string_color = get_gef_setting("theme.dereference_string") - regs = current_arch.all_registers + unchanged_color = gef.config["theme.registers_register_name"] + changed_color = gef.config["theme.registers_value_changed"] + string_color = gef.config["theme.dereference_string"] + regs = gef.arch.all_registers args = kwargs["arguments"] if args.registers and args.registers[0]: required_regs = set(args.registers) - valid_regs = [reg for reg in current_arch.all_registers if reg in required_regs] + valid_regs = [reg for reg in gef.arch.all_registers if reg in required_regs] if valid_regs: regs = valid_regs invalid_regs = [reg for reg in required_regs if reg not in valid_regs] if invalid_regs: err("invalid registers for architecture: {}".format(", ".join(invalid_regs))) - memsize = current_arch.ptrsize + memsize = gef.arch.ptrsize endian = endian_str() charset = string.printable - widest = max(map(len, current_arch.all_registers)) + widest = max(map(len, gef.arch.all_registers)) special_line = "" for regname in regs: @@ -7560,15 +7468,15 @@ def do_invoke(self, argv, *args, **kwargs): color = changed_color # Special (e.g. segment) registers go on their own line - if regname in current_arch.special_registers: + if regname in gef.arch.special_registers: special_line += "{}: ".format(Color.colorify(regname, color)) special_line += "0x{:04x} ".format(get_register(regname)) continue line = "{}: ".format(Color.colorify(padreg, color)) - if regname == current_arch.flag_register: - line += current_arch.flag_register_to_human() + if regname == gef.arch.flag_register: + line += gef.arch.flag_register_to_human() gef_print(line) continue @@ -7701,7 +7609,7 @@ def get_shellcode(self, sid): return ok("Downloaded, written to disk...") - tempdir = get_gef_setting("gef.tempdir") + tempdir = gef.config["gef.tempdir"] fd, fname = tempfile.mkstemp(suffix=".txt", prefix="sc-", text=True, dir=tempdir) shellcode = res.splitlines()[7:-11] shellcode = b"\n".join(shellcode).replace(b""", b'"') @@ -7780,8 +7688,8 @@ class AssembleCommand(GenericCommand): def __init__(self): super().__init__() - self.add_setting("default_architecture", "X86", "Specify the default architecture to use when assembling") - self.add_setting("default_mode", "64", "Specify the default architecture to use when assembling") + self["default_architecture"] = ( "X86", "Specify the default architecture to use when assembling") + self["default_mode"] = ( "64", "Specify the default architecture to use when assembling") return def pre_load(self): @@ -7815,7 +7723,7 @@ def list_archs(self): @parse_arguments({"instructions": [""]}, {"--mode": "", "--arch": "", "--overwrite-location": 0, "--endian": "little", "--list-archs": True, "--as-shellcode": True}) def do_invoke(self, argv, *args, **kwargs): - arch_s, mode_s, endian_s = self.get_setting("default_architecture"), self.get_setting("default_mode"), "" + arch_s, mode_s, endian_s = self["default_architecture"], self["default_mode"], "" args = kwargs["arguments"] if args.list_archs: @@ -7827,7 +7735,7 @@ def do_invoke(self, argv, *args, **kwargs): return if is_alive(): - arch_s, mode_s = current_arch.arch, current_arch.mode + arch_s, mode_s = gef.arch.arch, gef.arch.mode endian_s = "big" if is_big_endian() else "" if args.arch: @@ -7884,7 +7792,7 @@ def do_invoke(self, argv, *args, **kwargs): if args.overwrite_location: l = len(raw) info("Overwriting {:d} bytes at {:s}".format(l, format_address(args.overwrite_location))) - write_memory(args.overwrite_location, raw, l) + gef.memory.write(args.overwrite_location, raw, l) return @@ -7901,7 +7809,7 @@ class ProcessListingCommand(GenericCommand): def __init__(self): super().__init__(complete=gdb.COMPLETE_LOCATION) ps = which("ps") - self.add_setting("ps_command", "{:s} auxww".format(ps), "`ps` command to get process information") + self["ps_command"] = ( "{:s} auxww".format(ps), "`ps` command to get process information") return @parse_arguments({"pattern": ""}, {"--attach": True, "--smart-scan": True}) @@ -7936,7 +7844,7 @@ def do_invoke(self, argv, *args, **kwargs): return None def get_processes(self): - output = gef_execute_external(self.get_setting("ps_command").split(), True) + output = gef_execute_external(self["ps_command"].split(), True) names = [x.lower().replace("%", "") for x in output[0].split()] for line in output[1:]: @@ -8170,7 +8078,7 @@ class EntryPointBreakCommand(GenericCommand): def __init__(self, *args, **kwargs): super().__init__() - self.add_setting("entrypoint_symbols", "main _main __libc_start_main __uClibc_main start _start", "Possible symbols for entry points") + self["entrypoint_symbols"] = ( "main _main __libc_start_main __uClibc_main start _start", "Possible symbols for entry points") return def do_invoke(self, argv): @@ -8188,7 +8096,7 @@ def do_invoke(self, argv): return bp = None - entrypoints = self.get_setting("entrypoint_symbols").split() + entrypoints = self["entrypoint_symbols"].split() for sym in entrypoints: try: @@ -8280,29 +8188,29 @@ class ContextCommand(GenericCommand): def __init__(self): super().__init__() - self.add_setting("enable", True, "Enable/disable printing the context when breaking") - self.add_setting("show_source_code_variable_values", True, "Show extra PC context info in the source code") - self.add_setting("show_stack_raw", False, "Show the stack pane as raw hexdump (no dereference)") - self.add_setting("show_registers_raw", False, "Show the registers pane with raw values (no dereference)") - self.add_setting("show_opcodes_size", 0, "Number of bytes of opcodes to display next to the disassembly") - self.add_setting("peek_calls", True, "Peek into calls") - self.add_setting("peek_ret", True, "Peek at return address") - self.add_setting("nb_lines_stack", 8, "Number of line in the stack pane") - self.add_setting("grow_stack_down", False, "Order of stack downward starts at largest down to stack pointer") - self.add_setting("nb_lines_backtrace", 10, "Number of line in the backtrace pane") - self.add_setting("nb_lines_backtrace_before", 2, "Number of line in the backtrace pane before selected frame") - self.add_setting("nb_lines_threads", -1, "Number of line in the threads pane") - self.add_setting("nb_lines_code", 6, "Number of instruction after $pc") - self.add_setting("nb_lines_code_prev", 3, "Number of instruction before $pc") - self.add_setting("ignore_registers", "", "Space-separated list of registers not to display (e.g. '$cs $ds $gs')") - self.add_setting("clear_screen", True, "Clear the screen before printing the context") - self.add_setting("layout", "legend regs stack code args source memory threads trace extra", "Change the order/presence of the context sections") - self.add_setting("redirect", "", "Redirect the context information to another TTY") - self.add_setting("libc_args", False, "Show libc function call args description") - self.add_setting("libc_args_path", "", "Path to libc function call args json files, provided via gef-extras") + self["enable"] = ( True, "Enable/disable printing the context when breaking") + self["show_source_code_variable_values"] = ( True, "Show extra PC context info in the source code") + self["show_stack_raw"] = ( False, "Show the stack pane as raw hexdump (no dereference)") + self["show_registers_raw"] = ( False, "Show the registers pane with raw values (no dereference)") + self["show_opcodes_size"] = ( 0, "Number of bytes of opcodes to display next to the disassembly") + self["peek_calls"] = ( True, "Peek into calls") + self["peek_ret"] = ( True, "Peek at return address") + self["nb_lines_stack"] = ( 8, "Number of line in the stack pane") + self["grow_stack_down"] = ( False, "Order of stack downward starts at largest down to stack pointer") + self["nb_lines_backtrace"] = ( 10, "Number of line in the backtrace pane") + self["nb_lines_backtrace_before"] = ( 2, "Number of line in the backtrace pane before selected frame") + self["nb_lines_threads"] = ( -1, "Number of line in the threads pane") + self["nb_lines_code"] = ( 6, "Number of instruction after $pc") + self["nb_lines_code_prev"] = ( 3, "Number of instruction before $pc") + self["ignore_registers"] = ( "", "Space-separated list of registers not to display (e.g. '$cs $ds $gs')") + self["clear_screen"] = ( True, "Clear the screen before printing the context") + self["layout"] = ( "legend regs stack code args source memory threads trace extra", "Change the order/presence of the context sections") + self["redirect"] = ("", "Redirect the context information to another TTY") + self["libc_args"] = ( False, "Show libc function call args description") + self["libc_args_path"] = ( "", "Path to libc function call args json files, provided via gef-extras") if "capstone" in list(sys.modules.keys()): - self.add_setting("use_capstone", False, "Use capstone as disassembler in the code pane (instead of GDB)") + self["use_capstone"] = ( False, "Use capstone as disassembler in the code pane (instead of GDB)") self.layout_mapping = { "legend": (self.show_legend, None), @@ -8324,13 +8232,13 @@ def post_load(self): return def show_legend(self): - if get_gef_setting("gef.disable_color") is True: + if gef.config["gef.disable_color"] is True: return - str_color = get_gef_setting("theme.dereference_string") - code_addr_color = get_gef_setting("theme.address_code") - stack_addr_color = get_gef_setting("theme.address_stack") - heap_addr_color = get_gef_setting("theme.address_heap") - changed_register_color = get_gef_setting("theme.registers_value_changed") + str_color = gef.config["theme.dereference_string"] + code_addr_color = gef.config["theme.address_code"] + stack_addr_color = gef.config["theme.address_stack"] + heap_addr_color = gef.config["theme.address_heap"] + changed_register_color = gef.config["theme.registers_value_changed"] gef_print("[ Legend: {} | {} | {} | {} | {} ]".format(Color.colorify("Modified register", changed_register_color), Color.colorify("Code", code_addr_color), @@ -8342,7 +8250,7 @@ def show_legend(self): @only_if_gdb_running def do_invoke(self, argv): - if not self.get_setting("enable") or context_hidden: + if not self["enable"] or context_hidden: return if not all(_ in self.layout_mapping for _ in argv): @@ -8352,14 +8260,14 @@ def do_invoke(self, argv): if len(argv) > 0: current_layout = argv else: - current_layout = self.get_setting("layout").strip().split() + current_layout = self["layout"].strip().split() if not current_layout: return self.tty_rows, self.tty_columns = get_terminal_size() - redirect = self.get_setting("redirect") + redirect = self["redirect"] if redirect and os.access(redirect, os.W_OK): enable_redirect_output(to_file=redirect) @@ -8378,7 +8286,7 @@ def do_invoke(self, argv): self.context_title("") - if self.get_setting("clear_screen") and len(argv) == 0: + if self["clear_screen"] and len(argv) == 0: clear_screen(redirect) if redirect and os.access(redirect, os.W_OK): @@ -8390,8 +8298,8 @@ def context_title(self, m): if m is None: return - line_color = get_gef_setting("theme.context_title_line") - msg_color = get_gef_setting("theme.context_title_message") + line_color = gef.config["theme.context_title_line"] + msg_color = gef.config["theme.context_title_message"] # print an empty line in case of "" if not m: @@ -8412,24 +8320,24 @@ def context_title(self, m): def context_regs(self): self.context_title("registers") - ignored_registers = set(self.get_setting("ignore_registers").split()) + ignored_registers = set(self["ignore_registers"].split()) - if self.get_setting("show_registers_raw") is False: - regs = set(current_arch.all_registers) + if self["show_registers_raw"] is False: + regs = set(gef.arch.all_registers) printable_registers = " ".join(list(regs - ignored_registers)) gdb.execute("registers {}".format(printable_registers)) return - widest = l = max(map(len, current_arch.all_registers)) + widest = l = max(map(len, gef.arch.all_registers)) l += 5 - l += current_arch.ptrsize * 2 + l += gef.arch.ptrsize * 2 nb = get_terminal_size()[1] // l i = 1 line = "" - changed_color = get_gef_setting("theme.registers_value_changed") - regname_color = get_gef_setting("theme.registers_register_name") + changed_color = gef.config["theme.registers_value_changed"] + regname_color = gef.config["theme.registers_register_name"] - for reg in current_arch.all_registers: + for reg in gef.arch.all_registers: if reg in ignored_registers: continue @@ -8477,19 +8385,19 @@ def context_regs(self): if line: gef_print(line) - gef_print("Flags: {:s}".format(current_arch.flag_register_to_human())) + gef_print("Flags: {:s}".format(gef.arch.flag_register_to_human())) return def context_stack(self): self.context_title("stack") - show_raw = self.get_setting("show_stack_raw") - nb_lines = self.get_setting("nb_lines_stack") + show_raw = self["show_stack_raw"] + nb_lines = self["nb_lines_stack"] try: - sp = current_arch.sp + sp = gef.arch.sp if show_raw is True: - mem = read_memory(sp, 0x10 * nb_lines) + mem = gef.memory.read(sp, 0x10 * nb_lines) gef_print(hexdump(mem, base=sp)) else: gdb.execute("dereference -l {:d} {:#x}".format(nb_lines, sp)) @@ -8503,18 +8411,18 @@ def addr_has_breakpoint(self, address, bp_locations): return any(hex(address) in b for b in bp_locations) def context_code(self): - nb_insn = self.get_setting("nb_lines_code") - nb_insn_prev = self.get_setting("nb_lines_code_prev") - use_capstone = self.has_setting("use_capstone") and self.get_setting("use_capstone") - show_opcodes_size = self.has_setting("show_opcodes_size") and self.get_setting("show_opcodes_size") - past_insns_color = get_gef_setting("theme.old_context") - cur_insn_color = get_gef_setting("theme.disassemble_current_instruction") - pc = current_arch.pc + nb_insn = self["nb_lines_code"] + nb_insn_prev = self["nb_lines_code_prev"] + use_capstone = "use_capstone" in self and self["use_capstone"] + show_opcodes_size = "show_opcodes_size" in self and self["show_opcodes_size"] + past_insns_color = gef.config["theme.old_context"] + cur_insn_color = gef.config["theme.disassemble_current_instruction"] + pc = gef.arch.pc breakpoints = gdb.breakpoints() or [] bp_locations = [b.location for b in breakpoints if b.location and b.location.startswith("*")] frame = gdb.selected_frame() - arch_name = "{}:{}".format(current_arch.arch.lower(), current_arch.mode) + arch_name = "{}:{}".format(gef.arch.arch.lower(), gef.arch.mode) self.context_title("code:{}".format(arch_name)) @@ -8539,8 +8447,8 @@ def context_code(self): elif insn.address == pc: line += "{}{}".format(bp_prefix, Color.colorify("{:s}{:s}".format(RIGHT_ARROW[1:], text), cur_insn_color)) - if current_arch.is_conditional_branch(insn): - is_taken, reason = current_arch.is_branch_taken(insn) + if gef.arch.is_conditional_branch(insn): + is_taken, reason = gef.arch.is_branch_taken(insn) if is_taken: target = insn.operands[-1].split()[0] reason = "[Reason: {:s}]".format(reason) if reason else "" @@ -8548,10 +8456,10 @@ def context_code(self): else: reason = "[Reason: !({:s})]".format(reason) if reason else "" line += Color.colorify("\tNOT taken {:s}".format(reason), "bold red") - elif current_arch.is_call(insn) and self.get_setting("peek_calls") is True: + elif gef.arch.is_call(insn) and self["peek_calls"] is True: target = insn.operands[-1].split()[0] - elif current_arch.is_ret(insn) and self.get_setting("peek_ret") is True: - target = current_arch.get_ra(insn, frame) + elif gef.arch.is_ret(insn) and self["peek_ret"] is True: + target = gef.arch.get_ra(insn, frame) else: line += "{} {}".format(bp_prefix, text) @@ -8576,8 +8484,8 @@ def context_code(self): return def context_args(self): - insn = gef_current_instruction(current_arch.pc) - if not current_arch.is_call(insn): + insn = gef_current_instruction(gef.arch.pc) + if not gef.arch.is_call(insn): return self.size2type = { @@ -8587,9 +8495,9 @@ def context_args(self): 8: "QWORD", } - if insn.operands[-1].startswith(self.size2type[current_arch.ptrsize]+" PTR"): + if insn.operands[-1].startswith(self.size2type[gef.arch.ptrsize]+" PTR"): target = "*" + insn.operands[-1].split()[-1] - elif "$"+insn.operands[0] in current_arch.all_registers: + elif "$"+insn.operands[0] in gef.arch.all_registers: target = "*{:#x}".format(get_register("$"+insn.operands[0])) else: # is there a symbol? @@ -8618,7 +8526,7 @@ def print_arguments_from_symbol(self, function_name, symbol): args = [] for i, f in enumerate(symbol.type.fields()): - _value = current_arch.get_ith_parameter(i, in_func=False)[1] + _value = gef.arch.get_ith_parameter(i, in_func=False)[1] _value = RIGHT_ARROW.join(dereference_from(_value)) _name = f.name or "var_{}".format(i) _type = f.type.name or self.size2type[f.type.sizeof] @@ -8639,7 +8547,7 @@ def print_guessed_arguments(self, function_name): """When no symbol, read the current basic block and look for "interesting" instructions.""" def __get_current_block_start_address(): - pc = current_arch.pc + pc = gef.arch.pc try: block = gdb.block_for_pc(pc) block_start = block.start if block else gdb_get_nth_previous_instruction_address(pc, 5) @@ -8648,14 +8556,14 @@ def __get_current_block_start_address(): return block_start parameter_set = set() - pc = current_arch.pc + pc = gef.arch.pc block_start = __get_current_block_start_address() if not block_start: return - use_capstone = self.has_setting("use_capstone") and self.get_setting("use_capstone") + use_capstone = "use_capstone" in self and self["use_capstone"] instruction_iterator = capstone_disassemble if use_capstone else gef_disassemble - function_parameters = current_arch.function_parameters - arg_key_color = get_gef_setting("theme.registers_register_name") + function_parameters = gef.arch.function_parameters + arg_key_color = gef.config["theme.registers_register_name"] for insn in instruction_iterator(block_start, pc - block_start): if not insn.operands: @@ -8681,7 +8589,7 @@ def __get_current_block_start_address(): parameter_set.add(exreg) nb_argument = None - _arch_mode = "{}_{}".format(current_arch.arch.lower(), current_arch.mode) + _arch_mode = "{}_{}".format(gef.arch.arch.lower(), gef.arch.mode) _function_name = None if function_name.endswith("@plt"): _function_name = function_name.split("@")[0] @@ -8700,7 +8608,7 @@ def __get_current_block_start_address(): args = [] for i in range(nb_argument): - _key, _values = current_arch.get_ith_parameter(i, in_func=False) + _key, _values = gef.arch.get_ith_parameter(i, in_func=False) _values = RIGHT_ARROW.join(dereference_from(_values)) try: args.append("{} = {} (def: {})".format(Color.colorify(_key, arg_key_color), _values, @@ -8721,7 +8629,7 @@ def line_has_breakpoint(self, file_name, line_number, bp_locations): def context_source(self): try: - pc = current_arch.pc + pc = gef.arch.pc symtabline = gdb.find_pc_line(pc) symtab = symtabline.symtab # we subtract one because the line number returned by gdb start at 1 @@ -8739,16 +8647,16 @@ def context_source(self): file_base_name = os.path.basename(symtab.filename) breakpoints = gdb.breakpoints() or [] bp_locations = [b.location for b in breakpoints if b.location and file_base_name in b.location] - past_lines_color = get_gef_setting("theme.old_context") + past_lines_color = gef.config["theme.old_context"] - nb_line = self.get_setting("nb_lines_code") + nb_line = self["nb_lines_code"] fn = symtab.filename if len(fn) > 20: fn = "{}[...]{}".format(fn[:15], os.path.splitext(fn)[1]) title = "source:{}+{}".format(fn, line_num + 1) - cur_line_color = get_gef_setting("theme.source_current_line") + cur_line_color = gef.config["theme.source_current_line"] self.context_title(title) - show_extra_info = self.get_setting("show_source_code_variable_values") + show_extra_info = self["show_source_code_variable_values"] for i in range(line_num - nb_line + 1, line_num + nb_line): if i < 0: @@ -8811,7 +8719,7 @@ def get_pc_context_info(self, pc, line): def context_trace(self): self.context_title("trace") - nb_backtrace = self.get_setting("nb_lines_backtrace") + nb_backtrace = self["nb_lines_backtrace"] if nb_backtrace <= 0: return @@ -8827,7 +8735,7 @@ def context_trace(self): current_frame = current_frame.older() frames.append(current_frame) - nb_backtrace_before = self.get_setting("nb_lines_backtrace_before") + nb_backtrace_before = self["nb_lines_backtrace_before"] level = max(len(frames) - nb_backtrace_before - 1, 0) current_frame = frames[level] @@ -8896,7 +8804,7 @@ def reason(): self.context_title("threads") threads = gdb.selected_inferior().threads()[::-1] - idx = self.get_setting("nb_lines_threads") + idx = self["nb_lines_threads"] if idx > 0: threads = threads[0:idx] @@ -8971,7 +8879,7 @@ def context_memory(self): @classmethod def update_registers(cls, event): - for reg in current_arch.all_registers: + for reg in gef.arch.all_registers: try: cls.old_registers[reg] = get_register(reg) except Exception: @@ -9030,9 +8938,9 @@ def do_invoke(self, argv): self.usage() return else: - if current_arch.ptrsize == 4: + if gef.arch.ptrsize == 4: group = "dword" - elif current_arch.ptrsize == 8: + elif gef.arch.ptrsize == 8: group = "qword" __watches__[address] = (size, group) @@ -9111,7 +9019,7 @@ class HexdumpCommand(GenericCommand): def __init__(self): super().__init__(complete=gdb.COMPLETE_LOCATION, prefix=True) - self.add_setting("always_show_ascii", False, "If true, hexdump will always display the ASCII dump") + self["always_show_ascii"] = ( False, "If true, hexdump will always display the ASCII dump") self.format = None self.__last_target = "$sp" return @@ -9132,7 +9040,7 @@ def do_invoke(self, argv, *args, **kwargs): if self.format == "byte": read_len = args.size or 0x40 read_from += self.repeat_count * read_len - mem = read_memory(read_from, read_len) + mem = gef.memory.read(read_from, read_len) lines = hexdump(mem, base=read_from).splitlines() else: read_len = args.size or 0x10 @@ -9148,8 +9056,8 @@ def do_invoke(self, argv, *args, **kwargs): def _hexdump(self, start_addr, length, arrange_as, offset=0): endianness = endian_str() - base_address_color = get_gef_setting("theme.dereference_base_address") - show_ascii = get_gef_setting("hexdump.always_show_ascii") + base_address_color = gef.config["theme.dereference_base_address"] + show_ascii = gef.config["hexdump.always_show_ascii"] formats = { "qword": ("Q", 8), @@ -9168,7 +9076,7 @@ def _hexdump(self, start_addr, length, arrange_as, offset=0): cur_addr = start_addr + (i + offset) * l sym = gdb_get_location_from_symbol(cur_addr) sym = "<{:s}+{:04x}> ".format(*sym) if sym else "" - mem = read_memory(cur_addr, l) + mem = gef.memory.read(cur_addr, l) val = struct.unpack(fmt_pack, mem)[0] if show_ascii: text = "".join([chr(b) if 0x20 <= b < 0x7F else "." for b in mem]) @@ -9273,7 +9181,7 @@ def do_invoke(self, argv, *args, **kwargs): for value in args.values: value = parse_address(value) & ((1 << size * 8) - 1) vstr = struct.pack(d + fcode, value) - write_memory(addr, vstr, length=size) + gef.memory.write(addr, vstr, length=size) addr += size return @@ -9358,7 +9266,7 @@ def do_invoke(self, argv): gef_print("Could not decode '\\xXX' encoded string \"{}\"".format(s)) return - write_memory(addr, s, len(s)) + gef.memory.write(addr, s, len(s)) return @lru_cache() @@ -9366,9 +9274,9 @@ def dereference_from(addr): if not is_alive(): return [format_address(addr),] - code_color = get_gef_setting("theme.dereference_code") - string_color = get_gef_setting("theme.dereference_string") - max_recursion = get_gef_setting("dereference.max_recursion") or 10 + code_color = gef.config["theme.dereference_code"] + string_color = gef.config["theme.dereference_string"] + max_recursion = gef.config["dereference.max_recursion"] or 10 addr = lookup_address(align_address(int(addr))) msg = [format_address(addr.value),] seen_addrs = set() @@ -9405,7 +9313,7 @@ def dereference_from(addr): elif addr.section.permission.value & Permission.READ: if is_ascii_string(addr.value): - s = read_cstring_from_memory(addr.value) + s = gef.memory.read_cstring(addr.value) if len(s) < get_memory_alignment(): txt = '{:s} ("{:s}"?)'.format(format_address(deref), Color.colorify(s, string_color)) elif len(s) > 50: @@ -9417,7 +9325,7 @@ def dereference_from(addr): break # if not able to parse cleanly, simply display and break - val = "{:#0{ma}x}".format(int(deref & 0xFFFFFFFFFFFFFFFF), ma=(current_arch.ptrsize * 2 + 2)) + val = "{:#0{ma}x}".format(int(deref & 0xFFFFFFFFFFFFFFFF), ma=(gef.arch.ptrsize * 2 + 2)) msg.append(val) break @@ -9436,16 +9344,16 @@ class DereferenceCommand(GenericCommand): def __init__(self): super().__init__(complete=gdb.COMPLETE_LOCATION) - self.add_setting("max_recursion", 7, "Maximum level of pointer recursion") + self["max_recursion"] = ( 7, "Maximum level of pointer recursion") return @staticmethod def pprint_dereferenced(addr, idx, base_offset=0): - base_address_color = get_gef_setting("theme.dereference_base_address") - registers_color = get_gef_setting("theme.dereference_register_value") + base_address_color = gef.config["theme.dereference_base_address"] + registers_color = gef.config["theme.dereference_register_value"] sep = " {:s} ".format(RIGHT_ARROW) - memalign = current_arch.ptrsize + memalign = gef.arch.ptrsize offset = idx * memalign current_address = align_address(addr + offset) @@ -9458,7 +9366,7 @@ def pprint_dereferenced(addr, idx, base_offset=0): register_hints = [] - for regname in current_arch.all_registers: + for regname in gef.arch.all_registers: regvalue = get_register(regname) if current_address == regvalue: register_hints.append(regname) @@ -9490,7 +9398,7 @@ def do_invoke(self, *args, **kwargs): err("Unmapped address: '{}'".format(reference)) return - if get_gef_setting("context.grow_stack_down") is True: + if gef.config["context.grow_stack_down"] is True: from_insnum = nb * (self.repeat_count + 1) - 1 to_insnum = self.repeat_count * nb - 1 insnum_step = -1 @@ -9579,10 +9487,10 @@ def do_invoke(self, argv): err("No address mapping information found") return - if not get_gef_setting("gef.disable_color"): + if not gef.config["gef.disable_color"]: self.show_legend() - color = get_gef_setting("theme.table_heading") + color = gef.config["theme.table_heading"] headers = ["Start", "End", "Offset", "Perm", "Path"] gef_print(Color.colorify("{:<{w}s}{:<{w}s}{:<{w}s}{:<4s} {:s}".format(*headers, w=get_memory_alignment()*2+3), color)) @@ -9602,11 +9510,11 @@ def do_invoke(self, argv): def print_entry(self, entry): line_color = "" if entry.path == "[stack]": - line_color = get_gef_setting("theme.address_stack") + line_color = gef.config["theme.address_stack"] elif entry.path == "[heap]": - line_color = get_gef_setting("theme.address_heap") + line_color = gef.config["theme.address_heap"] elif entry.permission.value & Permission.READ and entry.permission.value & Permission.EXECUTE: - line_color = get_gef_setting("theme.address_code") + line_color = gef.config["theme.address_code"] l = [] l.append(Color.colorify(format_address(entry.page_start), line_color)) @@ -9625,9 +9533,9 @@ def print_entry(self, entry): return def show_legend(self): - code_addr_color = get_gef_setting("theme.address_code") - stack_addr_color = get_gef_setting("theme.address_stack") - heap_addr_color = get_gef_setting("theme.address_heap") + code_addr_color = gef.config["theme.address_code"] + stack_addr_color = gef.config["theme.address_stack"] + heap_addr_color = gef.config["theme.address_heap"] gef_print("[ Legend: {} | {} | {} ]".format(Color.colorify("Code", code_addr_color), Color.colorify("Heap", heap_addr_color), @@ -9656,7 +9564,7 @@ class XFilesCommand(GenericCommand): @only_if_gdb_running def do_invoke(self, argv): - color = get_gef_setting("theme.table_heading") + color = gef.config["theme.table_heading"] headers = ["Start", "End", "Name", "File"] gef_print(Color.colorify("{:<{w}s}{:<{w}s}{:<21s} {:s}".format(*headers, w=get_memory_alignment()*2+3), color)) @@ -9779,7 +9687,7 @@ def do_invoke(self, argv): address = parse_address(argv[0]) length = int(argv[1], 0) key = argv[2] - block = read_memory(address, length) + block = gef.memory.read(address, length) info("Displaying XOR-ing {:#x}-{:#x} with {:s}".format(address, address + len(block), repr(key))) gef_print(titlify("Original block")) @@ -9808,10 +9716,10 @@ def do_invoke(self, argv): address = parse_address(argv[0]) length = int(argv[1], 0) key = argv[2] - block = read_memory(address, length) + block = gef.memory.read(address, length) info("Patching XOR-ing {:#x}-{:#x} with '{:s}'".format(address, address + len(block), key)) xored_block = xor(block, key) - write_memory(address, xored_block, length) + gef.memory.write(address, xored_block, length) return @@ -9827,8 +9735,8 @@ class TraceRunCommand(GenericCommand): def __init__(self): super().__init__(self._cmdline_, complete=gdb.COMPLETE_LOCATION) - self.add_setting("max_tracing_recursion", 1, "Maximum depth of tracing") - self.add_setting("tracefile_prefix", "./gef-trace-", "Specify the tracing output file prefix") + self["max_tracing_recursion"] = ( 1, "Maximum depth of tracing") + self["tracefile_prefix"] = ( "./gef-trace-", "Specify the tracing output file prefix") return @only_if_gdb_running @@ -9843,7 +9751,7 @@ def do_invoke(self, argv): depth = 1 try: - loc_start = current_arch.pc + loc_start = gef.arch.pc loc_end = parse_address(argv[0]) except gdb.error as e: err("Invalid location: {:s}".format(e)) @@ -9862,7 +9770,7 @@ def get_frames_size(self): def trace(self, loc_start, loc_end, depth): info("Tracing from {:#x} to {:#x} (max depth={:d})".format(loc_start, loc_end, depth)) - logfile = "{:s}{:#x}-{:#x}.txt".format(self.get_setting("tracefile_prefix"), loc_start, loc_end) + logfile = "{:s}{:#x}-{:#x}.txt".format(self["tracefile_prefix"], loc_start, loc_end) enable_redirect_output(to_file=logfile) hide_context() self.start_tracing(loc_start, loc_end, depth) @@ -9893,7 +9801,7 @@ def start_tracing(self, loc_start, loc_end, depth): else: gdb.execute("finish") - loc_cur = current_arch.pc + loc_cur = gef.arch.pc gdb.flush() except gdb.error as e: @@ -9917,7 +9825,7 @@ class PatternCommand(GenericCommand): def __init__(self): super().__init__(prefix=True) - self.add_setting("length", 1024, "Default length of a cyclic buffer to generate") + self["length"] = ( 1024, "Default length of a cyclic buffer to generate") return def do_invoke(self, argv): @@ -9938,8 +9846,8 @@ class PatternCreateCommand(GenericCommand): @parse_arguments({"length": 0}, {("-n", "--n"): 0}) def do_invoke(self, *args, **kwargs): args = kwargs["arguments"] - length = args.length or get_gef_setting("pattern.length") - n = args.n or current_arch.ptrsize + length = args.length or gef.config["pattern.length"] + n = args.n or gef.arch.ptrsize info("Generating a pattern of {:d} bytes (n={:d})".format(length, n)) pattern_str = gef_pystring(generate_cyclic_pattern(length, n)) gef_print(pattern_str) @@ -9963,8 +9871,8 @@ class PatternSearchCommand(GenericCommand): @parse_arguments({"pattern": ""}, {("-n", "--n"): 0, ("-l", "--max-length"): 0}) def do_invoke(self, *args, **kwargs): args = kwargs["arguments"] - max_length = args.max_length or get_gef_setting("pattern.length") - n = args.n or current_arch.ptrsize + max_length = args.max_length or gef.config["pattern.length"] + n = args.n or gef.arch.ptrsize info("Searching for '{:s}'".format(args.pattern)) self.search(args.pattern, max_length, n) return @@ -9985,8 +9893,8 @@ def search(self, pattern, size, period): 4: "I", 8: "Q", } - pattern_be = struct.pack(">{}".format(struct_packsize[current_arch.ptrsize]), addr) - pattern_le = struct.pack("<{}".format(struct_packsize[current_arch.ptrsize]), addr) + pattern_be = struct.pack(">{}".format(struct_packsize[gef.arch.ptrsize]), addr) + pattern_le = struct.pack("<{}".format(struct_packsize[gef.arch.ptrsize]), addr) else: # 2. assume it's a plain string pattern_be = gef_pybytes(pattern) @@ -10083,9 +9991,9 @@ class GotCommand(GenericCommand): def __init__(self, *args, **kwargs): super().__init__() - self.add_setting("function_resolved", "green", "Line color of the got command output if the function has " + self["function_resolved"] = ( "green", "Line color of the got command output if the function has " "been resolved") - self.add_setting("function_not_resolved", "yellow", "Line color of the got command output if the function has " + self["function_not_resolved"] = ( "yellow", "Line color of the got command output if the function has " "not been resolved") return @@ -10155,13 +10063,13 @@ def do_invoke(self, argv): address_val = base_address + address_val # read the address of the function. - got_address = read_int_from_memory(address_val) + got_address = gef.memory.read_integer(address_val) # for the swag: different colors if the function has been resolved or not. if base_address < got_address < end_address: - color = self.get_setting("function_not_resolved") # function hasn't already been resolved + color = self["function_not_resolved"] # function hasn't already been resolved else: - color = self.get_setting("function_resolved") # function has already been resolved + color = self["function_resolved"] # function has already been resolved line = "[{}] ".format(hex(address_val)) line += Color.colorify("{} {} {}".format(name, RIGHT_ARROW, hex(got_address)), color) @@ -10179,7 +10087,7 @@ class HighlightCommand(GenericCommand): def __init__(self): super().__init__(prefix=True) - self.add_setting("regex", False, "Enable regex highlighting") + self["regex"] = ( False, "Enable regex highlighting") def do_invoke(self, argv): return self.usage() @@ -10299,11 +10207,11 @@ class HeapAnalysisCommand(GenericCommand): def __init__(self, *args, **kwargs): super().__init__(complete=gdb.COMPLETE_NONE) - self.add_setting("check_free_null", False, "Break execution when a free(NULL) is encountered") - self.add_setting("check_double_free", True, "Break execution when a double free is encountered") - self.add_setting("check_weird_free", True, "Break execution when free() is called against a non-tracked pointer") - self.add_setting("check_uaf", True, "Break execution when a possible Use-after-Free condition is found") - self.add_setting("check_heap_overlap", True, "Break execution when a possible overlap in allocation is found") + self["check_free_null"] = ( False, "Break execution when a free(NULL) is encountered") + self["check_double_free"] = ( True, "Break execution when a double free is encountered") + self["check_weird_free"] = ( True, "Break execution when free() is called against a non-tracked pointer") + self["check_uaf"] = ( True, "Break execution when a possible Use-after-Free condition is found") + self["check_heap_overlap"] = ( True, "Break execution when a possible overlap in allocation is found") self.bp_malloc = None self.bp_calloc = None @@ -10393,8 +10301,8 @@ class IsSyscallCommand(GenericCommand): _syntax_ = _cmdline_ def do_invoke(self, argv): - insn = gef_current_instruction(current_arch.pc) - ok("Current instruction is{}a syscall".format(" " if self.is_syscall(current_arch, insn) else " not ")) + insn = gef_current_instruction(gef.arch.pc) + ok("Current instruction is{}a syscall".format(" " if self.is_syscall(gef.arch, insn) else " not ")) return @@ -10411,24 +10319,26 @@ class SyscallArgsCommand(GenericCommand): def __init__(self): super().__init__() - self.add_setting("path", os.path.join(get_gef_setting("gef.tempdir"), "syscall-tables"), - "Path to store/load the syscall tables files") + path = pathlib.Path(gef.config["gef.tempdir"]) / "syscall-tables" + if not path.exists(): + raise EnvironmentError("Syscall tables directory not found") + self["path"] = (str(path.absolute()), "Path to store/load the syscall tables files") return def do_invoke(self, argv): - color = get_gef_setting("theme.table_heading") + color = gef.config["theme.table_heading"] path = self.get_settings_path() if path is None: err("Cannot open '{0}': check directory and/or `gef config {0}` setting, " - "currently: '{1}'".format("syscall-args.path", self.get_setting("path"))) + "currently: '{1}'".format("syscall-args.path", self["path"])) info("This setting can be configured by running gef-extras' install script.") return - arch = current_arch.__class__.__name__ + arch = gef.arch.__class__.__name__ syscall_table = self.get_syscall_table(arch) - reg_value = get_register(current_arch.syscall_register) + reg_value = get_register(gef.arch.syscall_register) if reg_value not in syscall_table: warn("There is no system call for {:#x}".format(reg_value)) return @@ -10475,7 +10385,7 @@ def get_syscall_table(self, modname): return getattr(_mod, "syscall_table") def get_settings_path(self): - path = os.path.expanduser(self.get_setting("path")) + path = os.path.expanduser(self["path"]) path = os.path.realpath(path) return path if os.path.isdir(path) else None @@ -10615,8 +10525,8 @@ def __init__(self): return def setup(self): - global __gef__ - for function in __gef__.loaded_functions: + global gef + for function in gef.instance.loaded_functions: self.add_function_to_doc(function) self.__doc__ = "\n".join(sorted(self.docs)) return @@ -10651,13 +10561,13 @@ class GefCommand(gdb.Command): def __init__(self): super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, True) - set_gef_setting("gef.follow_child", True, bool, "Automatically set GDB to follow child when forking") - set_gef_setting("gef.readline_compat", False, bool, "Workaround for readline SOH/ETX issue (SEGV)") - set_gef_setting("gef.debug", False, bool, "Enable debug mode for gef") - set_gef_setting("gef.autosave_breakpoints_file", "", str, "Automatically save and restore breakpoints") - set_gef_setting("gef.extra_plugins_dir", "", str, "Autoload additional GEF commands from external directory") - set_gef_setting("gef.disable_color", False, bool, "Disable all colors in GEF") - set_gef_setting("gef.tempdir", GEF_TEMP_DIR, str, "Directory to use for temporary/cache content") + gef.config["gef.follow_child"] = GefSetting(True, bool, "Automatically set GDB to follow child when forking") + gef.config["gef.readline_compat"] = GefSetting(False, bool, "Workaround for readline SOH/ETX issue (SEGV)") + gef.config["gef.debug"] = GefSetting(False, bool, "Enable debug mode for gef") + gef.config["gef.autosave_breakpoints_file"] = GefSetting("", str, "Automatically save and restore breakpoints") + gef.config["gef.extra_plugins_dir"] = GefSetting("", str, "Autoload additional GEF commands from external directory") + gef.config["gef.disable_color"] = GefSetting(False, bool, "Disable all colors in GEF") + gef.config["gef.tempdir"] = GefSetting(GEF_TEMP_DIR, str, "Directory to use for temporary/cache content") self.loaded_commands = [] self.loaded_functions = [] self.missing_commands = {} @@ -10688,7 +10598,7 @@ def setup(self): return def __reload_auto_breakpoints(self): - bkp_fname = __config__.get("gef.autosave_breakpoints_file", None) + bkp_fname = gef.config["gef.autosave_breakpoints_file"] bkp_fname = bkp_fname[0] if bkp_fname else None if bkp_fname: # restore if existing @@ -10708,7 +10618,7 @@ def __load_extra_plugins(self): nb_added = -1 try: nb_inital = len(self.loaded_commands) - directories = get_gef_setting("gef.extra_plugins_dir") + directories = gef.config["gef.extra_plugins_dir"] if directories: for directory in directories.split(";"): directory = os.path.realpath(os.path.expanduser(directory)) @@ -10776,8 +10686,8 @@ def is_loaded(x): GefAlias(alias, cmd) except Exception as reason: - self.missing_commands[cmd] = reason - nb_missing += 1 + self.missing_commands[cmd] = reason + nb_missing += 1 # sort by command name self.loaded_commands = sorted(self.loaded_commands, key=lambda x: x[1]._cmdline_) @@ -10877,7 +10787,7 @@ def invoke(self, args, from_tty): if argc == 1: prefix = argv[0] - names = [x for x in __config__.keys() if x.startswith(prefix)] + names = [x for x in gef.config.keys() if x.startswith(prefix)] if names: if len(names) == 1: gef_print(titlify("GEF configuration setting: {:s}".format(names[0]))) @@ -10887,71 +10797,71 @@ def invoke(self, args, from_tty): for name in names: self.print_setting(name) return - self.set_setting(argc, argv) + self.set_setting(argv) return def print_setting(self, plugin_name, verbose=False): - res = __config__.get(plugin_name) - string_color = get_gef_setting("theme.dereference_string") - misc_color = get_gef_setting("theme.dereference_base_address") + res = gef.config.raw_entry(plugin_name) + string_color = gef.config["theme.dereference_string"] + misc_color = gef.config["theme.dereference_base_address"] if not res: return - _value, _type, _desc = res _setting = Color.colorify(plugin_name, "green") - _type = _type.__name__ + _type = res.type.__name__ if _type == "str": - _value = '"{:s}"'.format(Color.colorify(_value, string_color)) + _value = '"{:s}"'.format(Color.colorify(res.value, string_color)) else: - _value = Color.colorify(_value, misc_color) + _value = Color.colorify(res.value, misc_color) gef_print("{:s} ({:s}) = {:s}".format(_setting, _type, _value)) if verbose: gef_print(Color.colorify("\nDescription:", "bold underline")) - gef_print("\t{:s}".format(_desc)) + gef_print("\t{:s}".format(res.description)) return def print_settings(self): - for x in sorted(__config__): + for x in sorted(gef.config): self.print_setting(x) return - def set_setting(self, argc, argv): - global __gef__ - if "." not in argv[0]: + def set_setting(self, argv): + global gef + key, new_value = argv + + if "." not in key: err("Invalid command format") return - loaded_commands = [ x[0] for x in __gef__.loaded_commands ] + ["gef"] - plugin_name = argv[0].split(".", 1)[0] + loaded_commands = [ x[0] for x in gef.instance.loaded_commands ] + ["gef"] + plugin_name = key.split(".", 1)[0] if plugin_name not in loaded_commands: err("Unknown plugin '{:s}'".format(plugin_name)) return - _type = __config__.get(argv[0], [None, None, None])[1] - if _type is None: - err("Failed to get '{:s}' config setting".format(argv[0],)) + if key not in gef.config: + err("'{}' is not a valid configuration setting".format(key)) return + _type = gef.config.raw_entry(key).type try: if _type == bool: - _newval = True if argv[1].upper() in ("TRUE", "T", "1") else False + _newval = True if new_value.upper() in ("TRUE", "T", "1") else False else: - _newval = _type(argv[1]) + _newval = new_value + gef.config[key] = _newval except Exception: - err("{} expects type '{}'".format(argv[0], _type.__name__)) + err("{} expects type '{}'".format(key, _type.__name__)) return reset_all_caches() - __config__[argv[0]][0] = _newval - get_gef_setting.cache_clear() return def complete(self, text, word): - settings = sorted(__config__) + settings = sorted(gef.config) if text == "": # no prefix: example: `gef config TAB` @@ -10981,9 +10891,9 @@ def invoke(self, args, from_tty): old_sect = None # save the configuration - for key in sorted(__config__): + for key in sorted(gef.config): sect, optname = key.split(".", 1) - value = __config__.get(key, None) + value = gef.config[key] value = value[0] if value else None if old_sect != sect: @@ -11037,18 +10947,18 @@ def invoke(self, args, from_tty): for optname in cfg.options(section): try: key = "{:s}.{:s}".format(section, optname) - _type = __config__.get(key)[1] + _type = gef.config[key].type new_value = cfg.get(section, optname) if _type == bool: new_value = True if new_value == "True" else False else: new_value = _type(new_value) - __config__[key][0] = new_value + gef.config[key][0] = new_value except Exception: pass # ensure that the temporary directory always exists - gef_makedirs(__config__["gef.tempdir"][0]) + gef_makedirs(gef.config["gef.tempdir"]) if not quiet: ok("Configuration from '{:s}' restored".format(Color.colorify(GEF_RC, "bold blue"))) @@ -11069,13 +10979,13 @@ def __init__(self, *args, **kwargs): def invoke(self, args, from_tty): self.dont_repeat() - missing_commands = __gef__.missing_commands.keys() + missing_commands = gef.instance.missing_commands.keys() if not missing_commands: ok("No missing command") return for missing_command in missing_commands: - reason = __gef__.missing_commands[missing_command] + reason = gef.instance.missing_commands[missing_command] warn("Command `{}` is missing, reason {} {}".format(missing_command, RIGHT_ARROW, reason)) return @@ -11158,8 +11068,8 @@ def invoke(self, args, from_tty): return def lookup_command(self, cmd): - global __gef__ - for _name, _class, _instance in __gef__.loaded_commands: + global gef + for _name, _class, _instance in gef.instance.loaded_commands: if cmd == _name: return _name, _class, _instance @@ -11313,21 +11223,132 @@ def screen_setup(self): def __gef_prompt__(current_prompt): """GEF custom prompt function.""" - if get_gef_setting("gef.readline_compat") is True: return GEF_PROMPT - if get_gef_setting("gef.disable_color") is True: return GEF_PROMPT + if gef.config["gef.readline_compat"] is True: return GEF_PROMPT + if gef.config["gef.disable_color"] is True: return GEF_PROMPT if is_alive(): return GEF_PROMPT_ON return GEF_PROMPT_OFF -if __name__ == "__main__": +class GefMemory: + """Class that describes memory access.""" + + def write(self, address, buffer, length=0x10): + """Write `buffer` at address `address`.""" + return gdb.selected_inferior().write_memory(address, buffer, length) + + @lru_cache() + def read(self, addr, length=0x10): + """Return a `length` long byte array with the copy of the process memory at `addr`.""" + return gdb.selected_inferior().read_memory(addr, length).tobytes() + + def read_integer(self, addr): + """Return an integer read from memory.""" + sz = gef.arch.ptrsize + mem = self.read(addr, sz) + unpack = u32 if sz == 4 else u64 + return unpack(mem) + + def read_cstring(self, address, max_length=GEF_MAX_STRING_LENGTH, encoding=None): + """Return a C-string read from memory.""" + encoding = encoding or "unicode-escape" + length = min(address | (DEFAULT_PAGE_SIZE-1), max_length+1) + + try: + res_bytes = bytes(self.read(address, length)) + except gdb.error: + err("Can't read memory at '{}'".format(address)) + return "" + try: + with warnings.catch_warnings(): + # ignore DeprecationWarnings (see #735) + warnings.simplefilter("ignore") + res = res_bytes.decode(encoding, "strict") + except UnicodeDecodeError: + # latin-1 as fallback due to its single-byte to glyph mapping + res = res_bytes.decode("latin-1", "replace") + + res = res.split("\x00", 1)[0] + ustr = res.replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t") + if max_length and len(res) > max_length: + return "{}[...]".format(ustr[:max_length]) + + return ustr + + + def read_ascii_string(self, address): + """Read an ASCII string from memory""" + cstr = self.read_cstring(address) + if isinstance(cstr, str) and cstr and all([x in string.printable for x in cstr]): + return cstr + return None + +class GefSetting: + def __init__(self, value, cls = None, description = None): + self.value = value + self.type = cls or type(value) + self.description = description or "" + + +class GefSettings(dict): + """ + 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]` + """ + def __getitem__(self, name): + try: + return dict.__getitem__(self, name).value + except KeyError: + return None + + def __setitem__(self, name, value): + # check if the key exists + if dict.__contains__(self, name): + # if so, update its value directly + setting = dict.__getitem__(self, name) + setting.value = setting.type(value) + dict.__setitem__(self, name, setting) + else: + # if not, `value` must be a GefSetting + if not isinstance(value, GefSetting): raise Exception("Invalid argument") + if not value.type: raise Exception("Invalid type") + if not value.description: raise Exception("Invalid description") + dict.__setitem__(self, name, value) + return + + def __delitem__(self, name): + dict.__setitem__(self, name) + return + + def raw_entry(self, name): + return dict.__getitem__(self, name) + + +class Gef: + """The GEF root class""" + def __init__(self): + self.binary = None + self.arch = None + self.memory = GefMemory() + self.config = GefSettings() + return + def setup(self): + self.instance = GefCommand() + self.instance.setup() + tempdir = self.config["gef.tempdir"] + gef_makedirs(tempdir) + gdb.execute("save gdb-index {}".format(tempdir)) + return + + +if __name__ == "__main__": if sys.version_info[0] == 2: err("GEF has dropped Python2 support for GDB when it reached EOL on 2020/01/01.") err("If you require GEF for GDB+Python2, use https://github.com/hugsy/gef-legacy.") - elif GDB_VERSION < GDB_MIN_VERSION: + elif GDB_VERSION < GDB_MIN_VERSION or PYTHON_VERSION < PYTHON_MIN_VERSION: err("You're using an old version of GDB. GEF will not work correctly. " - "Consider updating to GDB {} or higher.".format(".".join(map(str, GDB_MIN_VERSION)))) + "Consider updating to GDB {} or higher (with Python {} or higher).".format(".".join(map(str, GDB_MIN_VERSION)), ".".join(map(str, PYTHON_MIN_VERSION)))) else: try: @@ -11382,12 +11403,8 @@ def __gef_prompt__(current_prompt): gdb.execute("handle SIGALRM print nopass") # load GEF - __gef__ = GefCommand() - __gef__.setup() - - tempdir = get_gef_setting("gef.tempdir") - gef_makedirs(tempdir) - gdb.execute("save gdb-index {}".format(tempdir)) + gef = Gef() + gef.setup() # gdb events configuration gef_on_continue_hook(continue_handler) diff --git a/tests/runtests.py b/tests/runtests.py index c2db5f08d..23dbd43ac 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -28,7 +28,7 @@ BIN_LS = Path("/bin/ls") BIN_SH = Path("/bin/sh") TMPDIR = Path(tempfile.gettempdir()) - +GEF_DEFAULT_PROMPT = "gef➤ " class GdbAssertionError(AssertionError): pass @@ -845,7 +845,7 @@ def test_func_get_memory_alignment(self): @include_for_architectures(["x86_64", "i686"]) def test_func_set_arch(self): - res = gdb_test_python_method("current_arch.arch, current_arch.mode", before="set_arch()") + res = gdb_test_python_method("gef.arch.arch, gef.arch.mode", before="set_arch()") res = (res.splitlines()[-1]) self.assertIn("X86", res) return From 380412ee17dd639913c9455eead96386881a810b Mon Sep 17 00:00:00 2001 From: hugsy Date: Sat, 11 Dec 2021 20:28:01 -0800 Subject: [PATCH 02/62] Added GEF compatibility matrix --- docs/compat.md | 14 ++++++++++++++ gef.py | 4 ++-- mkdocs.yml | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 docs/compat.md diff --git a/docs/compat.md b/docs/compat.md new file mode 100644 index 000000000..4ecc6548b --- /dev/null +++ b/docs/compat.md @@ -0,0 +1,14 @@ +# GEF Compatibility + +This matrix indicates the version of Python and/or GDB + +| GEF version | GDB Python compatibility* | Python compatibility* | +|:--:|:--:|:--:| +| [2018.02](https://github.com/hugsy/gef/releases/tag/2018.02) | 7.2 | Python 2.7, Python 3.4 | +| [2020.03](https://github.com/hugsy/gef/releases/tag/2020.03) | 7.4 | Python 2.7, Python 3.4 | +| [2022.01](https://github.com/hugsy/gef/releases/tag/2020.01) | 7.7 | Python 3.4 | +| [Current](https://github.com/hugsy/gef/tree/master) | 8.0+ | Python 3.6+ | + + + +* Up to - included \ No newline at end of file diff --git a/gef.py b/gef.py index 582099c64..4fd8781ce 100644 --- a/gef.py +++ b/gef.py @@ -162,10 +162,10 @@ def update_gef(argv): GEF_TEMP_DIR = os.path.join(tempfile.gettempdir(), "gef") GEF_MAX_STRING_LENGTH = 50 -GDB_MIN_VERSION = (7, 7) +GDB_MIN_VERSION = (8, 0) +PYTHON_MIN_VERSION = (3, 6) GDB_VERSION = tuple(map(int, re.search(r"(\d+)[^\d]+(\d+)", gdb.VERSION).groups())) PYTHON_VERSION = sys.version_info[0:2] -PYTHON_MIN_VERSION = (3, 4) libc_args_definitions = {} diff --git a/mkdocs.yml b/mkdocs.yml index 16dec5494..5114f6a3c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,6 +3,7 @@ theme: readthedocs nav: - Home: index.md - Configuration: config.md +- Compatibility: compat.md - Frequently Asked Questions: faq.md - Extending GEF: api.md - Features: commands.md From cdfdf4296989e5d55150db5cdf7596eb56f0723c Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 11:24:26 -0800 Subject: [PATCH 03/62] More changes to a more pythonic version - creates a `GefHeapManager` class - deprecates many functions to an equivalent more readable - made `GlibcArena` and `GlibcChunk` classes iterable --- docs/compat.md | 2 +- gef.py | 784 +++++++++++++++++++++++++++++-------------------- 2 files changed, 465 insertions(+), 321 deletions(-) diff --git a/docs/compat.md b/docs/compat.md index 4ecc6548b..a5545c967 100644 --- a/docs/compat.md +++ b/docs/compat.md @@ -6,7 +6,7 @@ This matrix indicates the version of Python and/or GDB |:--:|:--:|:--:| | [2018.02](https://github.com/hugsy/gef/releases/tag/2018.02) | 7.2 | Python 2.7, Python 3.4 | | [2020.03](https://github.com/hugsy/gef/releases/tag/2020.03) | 7.4 | Python 2.7, Python 3.4 | -| [2022.01](https://github.com/hugsy/gef/releases/tag/2020.01) | 7.7 | Python 3.4 | +| [2022.01](https://github.com/hugsy/gef/releases/tag/2022.01) | 7.7 | Python 3.4 | | [Current](https://github.com/hugsy/gef/tree/master) | 8.0+ | Python 3.6+ | diff --git a/gef.py b/gef.py index 4fd8781ce..f7b80e0ae 100644 --- a/gef.py +++ b/gef.py @@ -58,6 +58,7 @@ import codecs import collections import ctypes +import enum import functools import hashlib import importlib @@ -152,7 +153,7 @@ def update_gef(argv): __pie_counter__ = 1 __gef_remote__ = None __gef_qemu_mode__ = False -__gef_current_arena__ = "main_arena" +# __gef_current_arena__ = "main_arena" __gef_int_stream_buffer__ = None __gef_redirect_output_fd__ = None @@ -167,6 +168,8 @@ def update_gef(argv): GDB_VERSION = tuple(map(int, re.search(r"(\d+)[^\d]+(\d+)", gdb.VERSION).groups())) PYTHON_VERSION = sys.version_info[0:2] +LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME = "main_arena" + libc_args_definitions = {} highlight_table = {} @@ -176,14 +179,12 @@ def update_gef(argv): def reset_all_caches(): """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.""" - global __gef_current_arena__ - for mod in dir(sys.modules["__main__"]): obj = getattr(sys.modules["__main__"], mod) if hasattr(obj, "cache_clear"): obj.cache_clear() - __gef_current_arena__ = "main_arena" + gef.heap.selected_arena = None return @@ -273,7 +274,201 @@ def wrapper(*args, **kwargs): return wrapper +# +# Helpers +# + +def p8(x: int, s: bool = False) -> bytes: + """Pack one byte respecting the current architecture endianness.""" + return struct.pack("{}B".format(endian_str()), x) if not s else struct.pack("{}b".format(endian_str()), x) + +def p16(x: int, s: bool = False) -> bytes: + """Pack one word respecting the current architecture endianness.""" + return struct.pack("{}H".format(endian_str()), x) if not s else struct.pack("{}h".format(endian_str()), x) + +def p32(x: int, s: bool = False) -> bytes: + """Pack one dword respecting the current architecture endianness.""" + return struct.pack("{}I".format(endian_str()), x) if not s else struct.pack("{}i".format(endian_str()), x) + +def p64(x: int, s: bool = False) -> bytes: + """Pack one qword respecting the current architecture endianness.""" + return struct.pack("{}Q".format(endian_str()), x) if not s else struct.pack("{}q".format(endian_str()), x) + +def u8(x: bytes, s: bool = False) -> int: + """Unpack one byte respecting the current architecture endianness.""" + return struct.unpack("{}B".format(endian_str()), x)[0] if not s else struct.unpack("{}b".format(endian_str()), x)[0] + +def u16(x: bytes, s: bool = False) -> int: + """Unpack one word respecting the current architecture endianness.""" + return struct.unpack("{}H".format(endian_str()), x)[0] if not s else struct.unpack("{}h".format(endian_str()), x)[0] + +def u32(x: bytes, s: bool = False) -> int: + """Unpack one dword respecting the current architecture endianness.""" + return struct.unpack("{}I".format(endian_str()), x)[0] if not s else struct.unpack("{}i".format(endian_str()), x)[0] + +def u64(x: bytes, s: bool = False) -> int: + """Unpack one qword respecting the current architecture endianness.""" + return struct.unpack("{}Q".format(endian_str()), x)[0] if not s else struct.unpack("{}q".format(endian_str()), x)[0] + + +def is_ascii_string(address): + """Helper function to determine if the buffer pointed by `address` is an ASCII string (in GDB)""" + try: + return gef.memory.read_ascii_string(address) is not None + except Exception: + return False + + +def is_alive(): + """Check if GDB is running.""" + try: + return gdb.selected_inferior().pid > 0 + except Exception: + return False + + +# +# Decorators +# + +def only_if_gdb_running(f): + """Decorator wrapper to check if GDB is running.""" + + @functools.wraps(f) + def wrapper(*args, **kwargs): + if is_alive(): + return f(*args, **kwargs) + else: + warn("No debugging session active") + + return wrapper + + +def only_if_gdb_target_local(f): + """Decorator wrapper to check if GDB is running locally (target not remote).""" + + @functools.wraps(f) + def wrapper(*args, **kwargs): + if not is_remote_debug(): + return f(*args, **kwargs) + else: + warn("This command cannot work for remote sessions.") + + return wrapper + + +def deprecated(solution): + """Decorator to add a warning when a command is obsolete and will be removed.""" + def decorator(f): + @functools.wraps(f) + def wrapper(*args, **kwargs): + warn("'{}' is deprecated and will be removed in a feature release.".format(f.__name__)) + warn(solution) + return f(*args, **kwargs) + return wrapper + return decorator + + +def experimental_feature(f): + """Decorator to add a warning when a feature is experimental.""" + + @functools.wraps(f) + def wrapper(*args, **kwargs): + warn("This feature is under development, expect bugs and unstability...") + return f(*args, **kwargs) + + return wrapper + + +def only_if_gdb_version_higher_than(required_gdb_version): + """Decorator to check whether current GDB version requirements.""" + + def wrapper(f): + def inner_f(*args, **kwargs): + if GDB_VERSION >= required_gdb_version: + f(*args, **kwargs) + else: + reason = "GDB >= {} for this command".format(required_gdb_version) + raise EnvironmentError(reason) + return inner_f + return wrapper + +def only_if_current_arch_in(valid_architectures): + """Decorator to allow commands for only a subset of the architectured supported by GEF. + This decorator is to use lightly, as it goes against the purpose of GEF to support all + architectures GDB does. However in some cases, it is necessary.""" + + def wrapper(f): + def inner_f(*args, **kwargs): + if gef.arch in valid_architectures: + f(*args, **kwargs) + else: + reason = "This command cannot work for the '{}' architecture".format(gef.arch.arch) + raise EnvironmentError(reason) + return inner_f + return wrapper + + +def FakeExit(*args, **kwargs): + raise RuntimeWarning + +sys.exit = FakeExit + +def parse_arguments(required_arguments, optional_arguments): + """Argument parsing decorator.""" + + def int_wrapper(x): return int(x, 0) + + def decorator(f): + def wrapper(*args, **kwargs): + parser = argparse.ArgumentParser(prog=args[0]._cmdline_, add_help=True) + for argname in required_arguments: + argvalue = required_arguments[argname] + argtype = type(argvalue) + if argtype is int: + argtype = int_wrapper + + argname_is_list = isinstance(argname, list) or isinstance(argname, tuple) + if not argname_is_list and argname.startswith("-"): + # optional args + if argtype is bool: + parser.add_argument(argname, action="store_true" if argvalue else "store_false") + else: + parser.add_argument(argname, type=argtype, required=True, default=argvalue) + else: + if argtype in (list, tuple): + nargs = '*' + argtype = type(argvalue[0]) + else: + nargs = '?' + # positional args + parser.add_argument(argname, type=argtype, default=argvalue, nargs=nargs) + + for argname in optional_arguments: + argname_is_list = isinstance(argname, list) or isinstance(argname, tuple) + if not argname_is_list and not argname.startswith("-"): + # refuse positional arguments + continue + argvalue = optional_arguments[argname] + argtype = type(argvalue) + if not argname_is_list: + argname = [argname,] + if argtype is int: + argtype = int_wrapper + if argtype is bool: + parser.add_argument(*argname, action="store_true" if argvalue else "store_false") + else: + parser.add_argument(*argname, type=argtype, default=argvalue) + + try: + parsed_args = parser.parse_args(*(args[1:])) + except RuntimeWarning: + return + kwargs["arguments"] = parsed_args + return f(*args, **kwargs) + return wrapper + return decorator class Color: """Used to colorify terminal output.""" colors = { @@ -466,6 +661,14 @@ def realpath(self): Zone = collections.namedtuple("Zone", ["name", "zone_start", "zone_end", "filename"]) +class Endianness(enum.Enum): + LITTLE_ENDIAN = 1 + BIG_ENDIAN = 2 + + def __str__(self): + if self == Endianness.LITTLE_ENDIAN: + return "<" + return ">" class Elf: """Basic ELF parsing. @@ -474,9 +677,6 @@ class Elf: - http://refspecs.freestandards.org/elf/elfspec_ppc.pdf - http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html """ - LITTLE_ENDIAN = 1 - BIG_ENDIAN = 2 - ELF_32_BITS = 0x01 ELF_64_BITS = 0x02 ELF_MAGIC = 0x7f454c46 @@ -510,7 +710,7 @@ class Elf: e_magic = ELF_MAGIC e_class = ELF_32_BITS - e_endianness = LITTLE_ENDIAN + e_endianness = Endianness.LITTLE_ENDIAN e_eiversion = None e_osabi = None e_abiversion = None @@ -781,7 +981,6 @@ def is_valid(self): @lru_cache() def search_for_main_arena(): - global __gef_current_arena__ malloc_hook_addr = parse_address("(void *)&__malloc_hook") if is_x86(): @@ -791,7 +990,7 @@ def search_for_main_arena(): else: raise OSError("Cannot find main_arena for {}".format(gef.arch.arch)) - __gef_current_arena__ = "*0x{:x}".format(addr) + addr = "*0x{:x}".format(addr) return addr @@ -805,6 +1004,8 @@ def __init__(self, addr): warn("Could not parse address '&{}' when searching malloc_state struct, " "using '&main_arena' instead".format(addr)) self.__addr = search_for_main_arena() + # if `search_for_main_arena` throws `gdb.error` on symbol lookup: it means the session is not started + # so just propagate the exception self.num_fastbins = 10 self.num_bins = 254 @@ -968,8 +1169,8 @@ class GlibcArena: """Glibc arena class Ref: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1671""" - def __init__(self, addr, name=None): - self.__name = name or __gef_current_arena__ + def __init__(self, addr): + # self.__name = name or __gef_current_arena__ try: arena = gdb.parse_and_eval(addr) malloc_state_t = cached_lookup_type("struct malloc_state") @@ -999,10 +1200,22 @@ def __int__(self): return self.__addr def __iter__(self): - arena = self - while arena is not None: - yield arena - arena = arena.get_next() + return self + + def __next__(self): + # arena = self + # while arena is not None: + # yield arena + # arena = arena.get_next() + next_arena_address = int(self.next) + # arena_main = GlibcArena(self.__name) + if next_arena_address == int(gef.heap.main_arena): + raise StopIteration + return GlibcArena("*{:#x} ".format(next_arena_address)) + + def __eq__(self, other): + # You cannot have 2 arenas at the same address, so this check should be enough + return self.__addr == int(self) def fastbin(self, i): """Return head chunk in fastbinsY[i].""" @@ -1017,15 +1230,16 @@ def bin(self, i): bw = int(self.bins[idx + 1]) return fd, bw - def get_next(self): - addr_next = int(self.next) - arena_main = GlibcArena(self.__name) - if addr_next == arena_main.__addr: - return None - return GlibcArena("*{:#x} ".format(addr_next)) + # def get_next(self): + # addr_next = int(self.next) + # arena_main = GlibcArena(self.__name) + # if addr_next == arena_main.__addr: + # return None + # return GlibcArena("*{:#x} ".format(addr_next)) + @deprecated("use `==` operator instead") def is_main_arena(self): - return int(self) == parse_address("&main_arena") + return int(self) == int(gef.heap.main_arena) def heap_addr(self, allow_unaligned=False): if self.is_main_arena(): @@ -1109,6 +1323,12 @@ def usable_size(self): def get_prev_chunk_size(self): return gef.memory.read_integer(self.prev_size_addr) + def __iter__(self): + return self + + def __next__(self): + return self.get_next_chunk() + def get_next_chunk(self, allow_unaligned=False): addr = self.get_next_chunk_addr() return GlibcChunk(addr, allow_unaligned=allow_unaligned) @@ -1264,19 +1484,20 @@ def get_libc_version(): return 0, 0 -@lru_cache() -def get_glibc_arena(addr=None): - try: - addr = "*{}".format(addr) if addr else __gef_current_arena__ - return GlibcArena(addr) - except Exception as e: - err("Failed to get the glibc arena, heap commands may not work properly: {}".format(e)) - return None +# @lru_cache() +# def get_glibc_arena(addr=None): +# try: +# addr = "*{}".format(addr) if addr else __gef_current_arena__ +# return GlibcArena(addr) +# except Exception as e: +# err("Failed to get the glibc arena, heap commands may not work properly: {}".format(e)) +# return None +# def get_glibc_arenas(addr=None): +# return iter( GlibcArena(addr) ) -def get_glibc_arenas(addr=None, get_all=True): - arena = get_glibc_arena(addr) - return [arena for arena in iter(arena)] if get_all else [arena] +# def get_first_arena(addr=None): +# return next( get_glibc_arenas(addr) ) def titlify(text, color=None, msg_color=None): @@ -1766,17 +1987,17 @@ def get_arch(): return arch_str -@lru_cache() -def get_endian(): - """Return the binary endianness.""" +# @lru_cache() +# def get_endian(): +# """Return the binary endianness.""" - endian = gdb.execute("show endian", to_string=True).strip().lower() - if "little endian" in endian: - return Elf.LITTLE_ENDIAN - if "big endian" in endian: - return Elf.BIG_ENDIAN +# endian = gdb.execute("show endian", to_string=True).strip().lower() +# if "little endian" in endian: +# return Elf.LITTLE_ENDIAN +# if "big endian" in endian: +# return Elf.BIG_ENDIAN - raise EnvironmentError("Invalid endianness") +# raise EnvironmentError("Invalid endianness") @lru_cache() @@ -1794,8 +2015,14 @@ def is_pie(fpath): return checksec(fpath)["PIE"] -def is_big_endian(): return get_endian() == Elf.BIG_ENDIAN -def is_little_endian(): return not is_big_endian() +@deprecated("Prefer `gef.arch.endianness == Endianness.BIG_ENDIAN`") +def is_big_endian(): + return gef.arch.endianness == Endianness.BIG_ENDIAN + + +@deprecated("gef.arch.endianness == Endianness.LITTLE_ENDIAN") +def is_little_endian(): + return gef.arch.endianness == Endianness.LITTLE_ENDIAN def flags_to_human(reg_value, value_table): @@ -1807,6 +2034,10 @@ def flags_to_human(reg_value, value_table): return "[{}]".format(" ".join(flags)) +# +# Architecture classes +# + class Architecture(metaclass=abc.ABCMeta): """Generic metaclass for the architecture supported by GEF.""" @@ -1851,9 +2082,29 @@ def sp(self): def fp(self): return get_register("$fp") + __ptrsize = None @property def ptrsize(self): - return get_memory_alignment() + if not self.__ptrsize: + res = cached_lookup_type("size_t") + if res is not None: + self.__ptrsize = res.sizeof + else: + self.__ptrsize = gdb.parse_and_eval("$pc").type.sizeof + return self.__ptrsize + + __endianness = None + @property + def endianness(self) -> Endianness: + if not self.__endianness: + output = gdb.execute("show endian", to_string=True).strip().lower() + if "little endian" in output: + self.__endianness = Endianness.LITTLE_ENDIAN + elif "big endian" in output: + self.__endianness = Endianness.BIG_ENDIAN + else: + raise EnvironmentError(f"No valid endianess found in '{output}'") + return self.__endianness def get_ith_parameter(self, i, in_func=True): """Retrieves the correct parameter used for the current function call.""" @@ -1863,6 +2114,26 @@ def get_ith_parameter(self, i, in_func=True): return key, val +class GenericArchitecture(Architecture): + arch = "Generic" + mode = "" + all_registers = () + instruction_length = 0 + return_register = "" + function_parameters = () + syscall_register = "" + syscall_instructions = () + nop_insn = b"" + flag_register = None + flags_table = None + def flag_register_to_human(self, val=None): raise NotImplemented + def is_call(self, insn): raise NotImplemented + def is_ret(self, insn): raise NotImplemented + def is_conditional_branch(self, insn): raise NotImplemented + def is_branch_taken(self, insn): raise NotImplemented + def get_ra(self, insn, frame): raise NotImplemented + + class RISCV(Architecture): arch = "RISCV" mode = "RISCV" @@ -2706,198 +2977,8 @@ def mprotect_asm(cls, addr, size, perm): return "; ".join(insns) -# -# Helpers -# - -def p8(x: int, s: bool = False) -> bytes: - """Pack one byte respecting the current architecture endianness.""" - return struct.pack("{}B".format(endian_str()), x) if not s else struct.pack("{}b".format(endian_str()), x) - -def p16(x: int, s: bool = False) -> bytes: - """Pack one word respecting the current architecture endianness.""" - return struct.pack("{}H".format(endian_str()), x) if not s else struct.pack("{}h".format(endian_str()), x) - -def p32(x: int, s: bool = False) -> bytes: - """Pack one dword respecting the current architecture endianness.""" - return struct.pack("{}I".format(endian_str()), x) if not s else struct.pack("{}i".format(endian_str()), x) - -def p64(x: int, s: bool = False) -> bytes: - """Pack one qword respecting the current architecture endianness.""" - return struct.pack("{}Q".format(endian_str()), x) if not s else struct.pack("{}q".format(endian_str()), x) - -def u8(x: bytes, s: bool = False) -> int: - """Unpack one byte respecting the current architecture endianness.""" - return struct.unpack("{}B".format(endian_str()), x)[0] if not s else struct.unpack("{}b".format(endian_str()), x)[0] - -def u16(x: bytes, s: bool = False) -> int: - """Unpack one word respecting the current architecture endianness.""" - return struct.unpack("{}H".format(endian_str()), x)[0] if not s else struct.unpack("{}h".format(endian_str()), x)[0] - -def u32(x: bytes, s: bool = False) -> int: - """Unpack one dword respecting the current architecture endianness.""" - return struct.unpack("{}I".format(endian_str()), x)[0] if not s else struct.unpack("{}i".format(endian_str()), x)[0] - -def u64(x: bytes, s: bool = False) -> int: - """Unpack one qword respecting the current architecture endianness.""" - return struct.unpack("{}Q".format(endian_str()), x)[0] if not s else struct.unpack("{}q".format(endian_str()), x)[0] - - -def is_ascii_string(address): - """Helper function to determine if the buffer pointed by `address` is an ASCII string (in GDB)""" - try: - return gef.memory.read_ascii_string(address) is not None - except Exception: - return False - - -def is_alive(): - """Check if GDB is running.""" - try: - return gdb.selected_inferior().pid > 0 - except Exception: - return False - return False - - -def only_if_gdb_running(f): - """Decorator wrapper to check if GDB is running.""" - - @functools.wraps(f) - def wrapper(*args, **kwargs): - if is_alive(): - return f(*args, **kwargs) - else: - warn("No debugging session active") - - return wrapper - - -def only_if_gdb_target_local(f): - """Decorator wrapper to check if GDB is running locally (target not remote).""" - - @functools.wraps(f) - def wrapper(*args, **kwargs): - if not is_remote_debug(): - return f(*args, **kwargs) - else: - warn("This command cannot work for remote sessions.") - - return wrapper - - -def deprecated(f): - """Decorator to add a warning when a command is obsolete and will be removed.""" - - @functools.wraps(f) - def wrapper(*args, **kwargs): - warn("'{}' is obsolete and will be removed in a feature release.".format(f.__name__)) - return f(*args, **kwargs) - - return wrapper - - -def experimental_feature(f): - """Decorator to add a warning when a feature is experimental.""" - - @functools.wraps(f) - def wrapper(*args, **kwargs): - warn("This feature is under development, expect bugs and unstability...") - return f(*args, **kwargs) - - return wrapper - - -def only_if_gdb_version_higher_than(required_gdb_version): - """Decorator to check whether current GDB version requirements.""" - - def wrapper(f): - def inner_f(*args, **kwargs): - if GDB_VERSION >= required_gdb_version: - f(*args, **kwargs) - else: - reason = "GDB >= {} for this command".format(required_gdb_version) - raise EnvironmentError(reason) - return inner_f - return wrapper - - -def only_if_current_arch_in(valid_architectures): - """Decorator to allow commands for only a subset of the architectured supported by GEF. - This decorator is to use lightly, as it goes against the purpose of GEF to support all - architectures GDB does. However in some cases, it is necessary.""" - - def wrapper(f): - def inner_f(*args, **kwargs): - if gef.arch in valid_architectures: - f(*args, **kwargs) - else: - reason = "This command cannot work for the '{}' architecture".format(gef.arch.arch) - raise EnvironmentError(reason) - return inner_f - return wrapper -def FakeExit(*args, **kwargs): - raise RuntimeWarning - -sys.exit = FakeExit - -def parse_arguments(required_arguments, optional_arguments): - """Argument parsing decorator.""" - - def int_wrapper(x): return int(x, 0) - - def decorator(f): - def wrapper(*args, **kwargs): - parser = argparse.ArgumentParser(prog=args[0]._cmdline_, add_help=True) - for argname in required_arguments: - argvalue = required_arguments[argname] - argtype = type(argvalue) - if argtype is int: - argtype = int_wrapper - - argname_is_list = isinstance(argname, list) or isinstance(argname, tuple) - if not argname_is_list and argname.startswith("-"): - # optional args - if argtype is bool: - parser.add_argument(argname, action="store_true" if argvalue else "store_false") - else: - parser.add_argument(argname, type=argtype, required=True, default=argvalue) - else: - if argtype in (list, tuple): - nargs = '*' - argtype = type(argvalue[0]) - else: - nargs = '?' - # positional args - parser.add_argument(argname, type=argtype, default=argvalue, nargs=nargs) - - for argname in optional_arguments: - argname_is_list = isinstance(argname, list) or isinstance(argname, tuple) - if not argname_is_list and not argname.startswith("-"): - # refuse positional arguments - continue - argvalue = optional_arguments[argname] - argtype = type(argvalue) - if not argname_is_list: - argname = [argname,] - if argtype is int: - argtype = int_wrapper - if argtype is bool: - parser.add_argument(*argname, action="store_true" if argvalue else "store_false") - else: - parser.add_argument(*argname, type=argtype, default=argvalue) - - try: - parsed_args = parser.parse_args(*(args[1:])) - except RuntimeWarning: - return - kwargs["arguments"] = parsed_args - return f(*args, **kwargs) - return wrapper - return decorator - def copy_to_clipboard(data): """Helper function to submit data to the clipboard""" @@ -3623,25 +3704,25 @@ def get_elf_headers(filename=None): return Elf(filename) -def _ptr_width(): - void = cached_lookup_type("void") - if void is None: - uintptr_t = cached_lookup_type("uintptr_t") - return uintptr_t.sizeof - else: - return void.pointer().sizeof +# def _ptr_width(): +# void = cached_lookup_type("void") +# if void is None: +# uintptr_t = cached_lookup_type("uintptr_t") +# return uintptr_t.sizeof +# else: +# return void.pointer().sizeof @lru_cache() def is_64bit(): """Checks if current target is 64bit.""" - return _ptr_width() == 8 + return gef.arch.ptrsize == 8 @lru_cache() def is_32bit(): """Checks if current target is 32bit.""" - return _ptr_width() == 4 + return gef.arch.ptrsize == 4 @lru_cache() @@ -3721,7 +3802,7 @@ def cached_lookup_type(_type): return None -@lru_cache() +@deprecated("Use `gef.arch.ptrsize` instead") def get_memory_alignment(in_bits=False): """Try to determine the size of a pointer on this system. First, try to parse it out of the ELF header. @@ -3729,11 +3810,6 @@ def get_memory_alignment(in_bits=False): Finally, try the size of $pc. If `in_bits` is set to True, the result is returned in bits, otherwise in bytes.""" - if is_32bit(): - return 4 if not in_bits else 32 - elif is_64bit(): - return 8 if not in_bits else 64 - res = cached_lookup_type("size_t") if res is not None: return res.sizeof if not in_bits else res.sizeof * 8 @@ -3742,6 +3818,7 @@ def get_memory_alignment(in_bits=False): return gdb.parse_and_eval("$pc").type.sizeof except: pass + raise EnvironmentError("GEF is running under an unsupported mode") @@ -3830,13 +3907,12 @@ def parse_address(address): def is_in_x86_kernel(address): address = align_address(address) - memalign = get_memory_alignment(in_bits=True) - 1 + memalign = gef.arch.ptrsize*8 - 1 return (address >> memalign) == 0xF - -@lru_cache() +@deprecated("Use `str(gef.arch.endianness)` instead") def endian_str(): - return "<" if is_little_endian() else ">" + return str(gef.arch.endianness) @lru_cache() @@ -4582,7 +4658,7 @@ def settings(self): """Return the list of settings for this command.""" return list(iter(self)) - @deprecated + @deprecated("") def get_setting(self, name): return self.__getitem__(name) @@ -4590,14 +4666,14 @@ def __getitem__(self, name): key = self.__get_setting_name(name) return gef.config[key] - @deprecated + @deprecated("") def has_setting(self, name): return self.__contains__(name) def __contains__(self, name): return self.__get_setting_name(name) in gef.config - @deprecated + @deprecated("") def add_setting(self, name, value, description=""): return self.__setitem__(name, (value, type(value), description)) @@ -4615,7 +4691,7 @@ def __setitem__(self, name, value): gef.config[key] = GefSetting(value[0], description=value[1]) return - @deprecated + @deprecated("") def del_setting(self, name): return self.__delitem__(name) @@ -4672,14 +4748,8 @@ def do_invoke(self, argv): class PrintFormatCommand(GenericCommand): """Print bytes format in high level languages.""" - format_matrix = { - 8: (endian_str() + "B", "char", "db"), - 16: (endian_str() + "H", "short", "dw"), - 32: (endian_str() + "I", "int", "dd"), - 64: (endian_str() + "Q", "long long", "dq"), - } - - valid_formats = ["py", "c", "js", "asm"] + valid_formats = ("py", "c", "js", "asm") + valid_bitness = (8, 16, 32, 64) _cmdline_ = "print-format" _aliases_ = ["pf",] @@ -4688,7 +4758,7 @@ class PrintFormatCommand(GenericCommand): \t--bitlen SIZE specifies size of bit (possible values: {}, default is 8). \t--length LENGTH specifies length of array (default is 256). \t--clip The output data will be copied to clipboard -\tLOCATION specifies where the address of bytes is stored.""".format(_cmdline_, str(valid_formats), str(format_matrix.keys())) +\tLOCATION specifies where the address of bytes is stored.""".format(_cmdline_, str(valid_formats), str(valid_bitness)) _example_ = "{} --lang py -l 16 $rsp".format(_cmdline_) @@ -4696,6 +4766,16 @@ def __init__(self): super().__init__(complete=gdb.COMPLETE_LOCATION) return + @property + def format_matrix(self): + # `endian_str()` is a runtime property, should not be defined as a class property + return { + 8: (endian_str() + "B", "char", "db"), + 16: (endian_str() + "H", "short", "dw"), + 32: (endian_str() + "I", "int", "dd"), + 64: (endian_str() + "Q", "long long", "dq"), + } + @only_if_gdb_running @parse_arguments({"location": "$pc", }, {("--length", "-l"): 256, "--bitlen": 0, "--lang": "py", "--clip": True,}) def do_invoke(self, argv, *args, **kwargs): @@ -5711,7 +5791,7 @@ def disconnect(self): self.sock = None return - @deprecated + @deprecated("") def do_invoke(self, argv): def parsed_arglist(arglist): args = [] @@ -6861,7 +6941,7 @@ class GlibcHeapSetArenaCommand(GenericCommand): """Display information on a heap chunk.""" _cmdline_ = "heap set-arena" - _syntax_ = "{:s} address".format(_cmdline_) + _syntax_ = "{:s} [address|symbol]".format(_cmdline_) _example_ = "{:s} 0x001337001337".format(_cmdline_) def __init__(self): @@ -6870,26 +6950,31 @@ def __init__(self): @only_if_gdb_running def do_invoke(self, argv): - global __gef_current_arena__ + global gef if not argv: - ok("Current arena set to: '{}'".format(__gef_current_arena__)) + ok("Current arena set to: '{}'".format(gef.heap.selected_arena)) return - new_arena = safe_parse_and_eval(argv[0]) - if new_arena is None: + if is_hex(argv[0]): + new_arena_address = argv[0] + else: + new_arena_symbol = safe_parse_and_eval(argv[0]) + if not new_arena_symbol: + err("Invalid symbol for arena") + return + + new_arena_address = Address(value=to_unsigned_long(new_arena_symbol)) + if not new_arena_address or not new_arena_address.valid: err("Invalid address") return - if argv[0].startswith("0x"): - new_arena = Address(value=to_unsigned_long(new_arena)) - if new_arena is None or not new_arena.valid: - err("Invalid address") - return + new_arena = GlibcArena(f"*{new_arena_address:#x}") + if new_arena not in gef.heap.arenas: + err("Invalid arena") + return - __gef_current_arena__ = "*{:s}".format(format_address(new_arena.value)) - else: - __gef_current_arena__ = argv[0] + gef.heap.selected_arena = new_arena return @@ -6902,8 +6987,9 @@ class GlibcHeapArenaCommand(GenericCommand): @only_if_gdb_running def do_invoke(self, argv): - arenas = get_glibc_arenas() - for arena in arenas: + # arenas = get_glibc_arenas() + for arena in gef.heap.arenas: + print("foo") gef_print(str(arena)) return @@ -6971,9 +7057,12 @@ def __init__(self): def do_invoke(self, *args, **kwargs): args = kwargs["arguments"] - arenas = get_glibc_arenas(addr=args.arena_address, get_all=args.all) + # arenas = get_glibc_arenas(addr=args.arena_address, get_all=args.all) + arenas = gef.heap.arenas for arena in arenas: self.dump_chunks_arena(arena, print_arena=args.all, allow_unaligned=args.allow_unaligned) + if not args.all: + break def dump_chunks_arena(self, arena, print_arena=False, allow_unaligned=False): top_chunk_addr = arena.top @@ -7334,11 +7423,11 @@ def __init__(self): @only_if_gdb_running def do_invoke(self, argv): - if get_glibc_arena() is None: - err("Invalid Glibc arena") + if not gef.heap.main_arena: + err("Heap not initialized") return - arena_addr = "*{:s}".format(argv[0]) if len(argv) == 1 else __gef_current_arena__ + arena = GlibcArena(f"*{argv[0]:s}") if len(argv) == 1 else gef.heap.selected_arena gef_print(titlify("Small Bins for arena '{:s}'".format(arena_addr))) bins = {} for i in range(1, 63): @@ -11229,8 +11318,8 @@ def __gef_prompt__(current_prompt): return GEF_PROMPT_OFF -class GefMemory: - """Class that describes memory access.""" +class GefMemoryManager: + """Class that manages memory access for gef.""" def write(self, address, buffer, length=0x10): """Write `buffer` at address `address`.""" @@ -11274,7 +11363,6 @@ def read_cstring(self, address, max_length=GEF_MAX_STRING_LENGTH, encoding=None) return ustr - def read_ascii_string(self, address): """Read an ASCII string from memory""" cstr = self.read_cstring(address) @@ -11282,14 +11370,66 @@ def read_ascii_string(self, address): return cstr return None +class GefHeapManager: + + def __init__(self): + self.__libc_main_arena = None + self.__libc_selected_arena = None + self.__heap_base = None + return + + @property + def main_arena(self): + if not self.__libc_main_arena: + try: + self.__libc_main_arena = GlibcArena(search_for_main_arena()) + # the initialization of `main_arena` also defined `selected_arena`, so + # by default, `main_arena` == `selected_arena` + self.selected_arena = self.__libc_main_arena + except: + # the search for arena can fail when the session is not started + pass + return self.__libc_main_arena + + @property + def selected_arena(self): + if not self.__libc_selected_arena: + # `selected_arena` must default to `main_arena` + self.__libc_selected_arena = self.__libc_default_arena + return self.__libc_selected_arena + + @selected_arena.setter + def selected_arena(self, value): + self.__libc_selected_arena = value + return + + @property + def arenas(self): + if not self.main_arena: + return [] + return iter(self.__libc_main_arena) + + @property + def base_address(self): + if not self.__heap_base: + self.__heap_base = HeapBaseFunction.heap_base() + return self.__heap_base + + @property + def chunks(self): + if not self.base_address: + return [] + return iter( GlibcChunk(self.base_address) ) + + class GefSetting: def __init__(self, value, cls = None, description = None): self.value = value self.type = cls or type(value) self.description = description or "" + return - -class GefSettings(dict): +class GefSettingsManager(dict): """ 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]` @@ -11323,16 +11463,24 @@ def raw_entry(self, name): return dict.__getitem__(self, name) +class GefSessionManager: + def __init__(self): + pass + class Gef: """The GEF root class""" def __init__(self): self.binary = None - self.arch = None - self.memory = GefMemory() - self.config = GefSettings() + self.arch = GenericArchitecture() # see PR #516, will be reset by `new_objfile_handler` + self.config = GefSettingsManager() return def setup(self): + """ + Setup initialize the runtime setup, which may require for the `gef` to be not None + """ + self.memory = GefMemoryManager() + self.heap = GefHeapManager() self.instance = GefCommand() self.instance.setup() tempdir = self.config["gef.tempdir"] @@ -11341,6 +11489,8 @@ def setup(self): return + + if __name__ == "__main__": if sys.version_info[0] == 2: err("GEF has dropped Python2 support for GDB when it reached EOL on 2020/01/01.") @@ -11377,35 +11527,29 @@ def setup(self): gdb.prompt_hook = __gef_prompt__ # setup config - gdb.execute("set confirm off") - gdb.execute("set verbose off") - gdb.execute("set pagination off") - gdb.execute("set print elements 0") - - # gdb history - gdb.execute("set history save on") - gdb.execute("set history filename ~/.gdb_history") - - # gdb input and output bases - gdb.execute("set output-radix 0x10") - - # pretty print - gdb.execute("set print pretty on") - - try: - # this will raise a gdb.error unless we're on x86 - gdb.execute("set disassembly-flavor intel") - except gdb.error: - # we can safely ignore this - pass - - # SIGALRM will simply display a message, but gdb won't forward the signal to the process - gdb.execute("handle SIGALRM print nopass") + gdb_initial_config = ( + "set confirm off", + "set verbose off", + "set pagination off", + "set print elements 0", + "set history save on", + "set history filename ~/.gdb_history", + "set output-radix 0x10", + "set print pretty on", + "set disassembly-flavor intel", + "handle SIGALRM print nopass", + ) + for cmd in gdb_initial_config: + try: + gdb.execute(cmd) + except gdb.error: + pass # load GEF gef = Gef() gef.setup() + print(gef.arch) # gdb events configuration gef_on_continue_hook(continue_handler) gef_on_stop_hook(hook_stop_handler) From 9f45be80346d5f7e4799b98063841800f6a1b548 Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 13:42:32 -0800 Subject: [PATCH 04/62] Fixed the heap (arena & chunk) iterators --- gef.py | 110 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 46 deletions(-) diff --git a/gef.py b/gef.py index f7b80e0ae..f4b198e1a 100644 --- a/gef.py +++ b/gef.py @@ -410,6 +410,17 @@ def inner_f(*args, **kwargs): return wrapper +def only_if_events_supported(event_type): + """Checks if GDB supports events without crashing.""" + def wrap(f): + def wrapped_f(*args, **kwargs): + if getattr(gdb, "events") and getattr(gdb.events, event_type): + return f(*args, **kwargs) + warn("GDB events cannot be set") + return wrapped_f + return wrap + + def FakeExit(*args, **kwargs): raise RuntimeWarning @@ -469,6 +480,8 @@ def wrapper(*args, **kwargs): return f(*args, **kwargs) return wrapper return decorator + + class Color: """Used to colorify terminal output.""" colors = { @@ -1200,18 +1213,14 @@ def __int__(self): return self.__addr def __iter__(self): - return self - - def __next__(self): - # arena = self - # while arena is not None: - # yield arena - # arena = arena.get_next() - next_arena_address = int(self.next) - # arena_main = GlibcArena(self.__name) - if next_arena_address == int(gef.heap.main_arena): - raise StopIteration - return GlibcArena("*{:#x} ".format(next_arena_address)) + yield self + + while True: + next_arena_address = int(self.next) + if next_arena_address == int(gef.heap.main_arena): + break + yield GlibcArena("*{:#x} ".format(next_arena_address)) + return def __eq__(self, other): # You cannot have 2 arenas at the same address, so this check should be enough @@ -1324,10 +1333,30 @@ def get_prev_chunk_size(self): return gef.memory.read_integer(self.prev_size_addr) def __iter__(self): - return self + current_chunk = self + top = gef.heap.main_arena.top + + while True: + yield current_chunk + + if current_chunk.base_address == top: + break + + if current_chunk.size == 0: + break + + next_chunk_addr = current_chunk.get_next_chunk_addr() + + if not Address(value=next_chunk_addr).valid: + break + + next_chunk = current_chunk.get_next_chunk() + if next_chunk is None: + break + + current_chunk = next_chunk + return - def __next__(self): - return self.get_next_chunk() def get_next_chunk(self, allow_unaligned=False): addr = self.get_next_chunk_addr() @@ -4045,22 +4074,22 @@ def gef_getpagesize(): return auxval["AT_PAGESZ"] -def only_if_events_supported(event_type): - """Checks if GDB supports events without crashing.""" +# +# Deprecated API +# - def wrap(f): - def wrapped_f(*args, **kwargs): - if getattr(gdb, "events") and getattr(gdb.events, event_type): - return f(*args, **kwargs) - warn("GDB events cannot be set") +@deprecated("Use `gef.config[key]`") +def get_gef_setting(name): + return gef.config - return wrapped_f - - return wrap +@deprecated("Use `gef.config[key] = value`") +def set_gef_setting(name, value): + gef.config[name] = value + return # -# Event hooking +# GDB event hooking # @@ -6987,9 +7016,7 @@ class GlibcHeapArenaCommand(GenericCommand): @only_if_gdb_running def do_invoke(self, argv): - # arenas = get_glibc_arenas() for arena in gef.heap.arenas: - print("foo") gef_print(str(arena)) return @@ -7088,29 +7115,20 @@ def dump_chunks_arena(self, arena, print_arena=False, allow_unaligned=False): def dump_chunks_heap(self, start, until=None, top=None, allow_unaligned=False): nb = self["peek_nb_byte"] - current_chunk = GlibcChunk(start, from_base=True, allow_unaligned=allow_unaligned) - while True: - if current_chunk.base_address == top: - gef_print("{} {} {}".format(str(current_chunk), LEFT_ARROW, Color.greenify("top chunk"))) - break - if current_chunk.size == 0: - break - line = str(current_chunk) + chunk_iterator = GlibcChunk(start, from_base=True, allow_unaligned=allow_unaligned) + for chunk in chunk_iterator: + line = str(chunk) if nb: - line += "\n [{}]".format(hexdump(gef.memory.read(current_chunk.data_address, nb), nb, base=current_chunk.data_address)) + line += "\n [{}]".format(hexdump(gef.memory.read(chunk.data_address, nb), nb, base=chunk.data_address)) gef_print(line) - next_chunk_addr = current_chunk.get_next_chunk_addr() + next_chunk_addr = chunk.get_next_chunk_addr() if until and next_chunk_addr >= until: break - if not Address(value=next_chunk_addr).valid: - break - next_chunk = current_chunk.get_next_chunk() - if next_chunk is None: + if chunk.base_address == top: + gef_print("{} {} {}".format(str(chunk), LEFT_ARROW, Color.greenify("top chunk"))) break - - current_chunk = next_chunk return @@ -11407,7 +11425,7 @@ def selected_arena(self, value): def arenas(self): if not self.main_arena: return [] - return iter(self.__libc_main_arena) + return iter(self.main_arena) @property def base_address(self): @@ -11419,7 +11437,7 @@ def base_address(self): def chunks(self): if not self.base_address: return [] - return iter( GlibcChunk(self.base_address) ) + return iter( GlibcChunk(self.base_address, from_base=True) ) class GefSetting: From e36152dabe7154ac24397d3be5fc0bb1aae3dad2 Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 17:50:53 -0800 Subject: [PATCH 05/62] - Separate gef managers initialization - Add `gef.session` which includes many runtime info (`.pagesize`, `.canary`, `.constants`, etc.) - Add more docstrings - The GDB command objects are now in the namespace `gef.gdb` - Adjust some gef functions to check result - Make `endian_str`, `gef_pagesize`, `gef_read_canary`, `set_gef_setting` and `get_gef_setting` deprecated APIs --- gef.py | 356 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 172 insertions(+), 184 deletions(-) diff --git a/gef.py b/gef.py index f4b198e1a..d1c5d8cdb 100644 --- a/gef.py +++ b/gef.py @@ -164,8 +164,9 @@ def update_gef(argv): GEF_MAX_STRING_LENGTH = 50 GDB_MIN_VERSION = (8, 0) -PYTHON_MIN_VERSION = (3, 6) GDB_VERSION = tuple(map(int, re.search(r"(\d+)[^\d]+(\d+)", gdb.VERSION).groups())) + +PYTHON_MIN_VERSION = (3, 6) PYTHON_VERSION = sys.version_info[0:2] LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME = "main_arena" @@ -183,8 +184,6 @@ def reset_all_caches(): obj = getattr(sys.modules["__main__"], mod) if hasattr(obj, "cache_clear"): obj.cache_clear() - - gef.heap.selected_arena = None return @@ -357,13 +356,15 @@ def wrapper(*args, **kwargs): return wrapper -def deprecated(solution): +def deprecated(solution=""): """Decorator to add a warning when a command is obsolete and will be removed.""" def decorator(f): @functools.wraps(f) def wrapper(*args, **kwargs): - warn("'{}' is deprecated and will be removed in a feature release.".format(f.__name__)) - warn(solution) + msg = f"'{f.__name__}' is deprecated and will be removed in a feature release. " + if solution: + msg += solution + warn(msg) return f(*args, **kwargs) return wrapper return decorator @@ -1357,7 +1358,6 @@ def __iter__(self): current_chunk = next_chunk return - def get_next_chunk(self, allow_unaligned=False): addr = self.get_next_chunk_addr() return GlibcChunk(addr, allow_unaligned=allow_unaligned) @@ -1513,22 +1513,6 @@ def get_libc_version(): return 0, 0 -# @lru_cache() -# def get_glibc_arena(addr=None): -# try: -# addr = "*{}".format(addr) if addr else __gef_current_arena__ -# return GlibcArena(addr) -# except Exception as e: -# err("Failed to get the glibc arena, heap commands may not work properly: {}".format(e)) -# return None - -# def get_glibc_arenas(addr=None): -# return iter( GlibcArena(addr) ) - -# def get_first_arena(addr=None): -# return next( get_glibc_arenas(addr) ) - - def titlify(text, color=None, msg_color=None): """Print a centered title.""" cols = get_terminal_size()[1] @@ -1551,6 +1535,7 @@ def ok(msg): return gef_print("{} {}".format(Color.colorify("[+]", "bold gree def info(msg): return gef_print("{} {}".format(Color.colorify("[+]", "bold blue"), msg)) +# TODO: move to gef.session.context def push_context_message(level, message): """Push the message to be displayed the next time the context is invoked.""" global __context_messages__ @@ -1964,11 +1949,7 @@ def checksec(filename): "Partial RelRO": False, } - try: - readelf = which("readelf") - except IOError: - err("Missing `readelf`") - return + readelf = gef.session.constants["readelf"] def __check_security_property(opt, filename, pattern): cmd = [readelf,] @@ -2016,19 +1997,6 @@ def get_arch(): return arch_str -# @lru_cache() -# def get_endian(): -# """Return the binary endianness.""" - -# endian = gdb.execute("show endian", to_string=True).strip().lower() -# if "little endian" in endian: -# return Elf.LITTLE_ENDIAN -# if "big endian" in endian: -# return Elf.BIG_ENDIAN - -# raise EnvironmentError("Invalid endianness") - - @lru_cache() def get_entry_point(): """Return the binary entry point.""" @@ -2063,6 +2031,17 @@ def flags_to_human(reg_value, value_table): return "[{}]".format(" ".join(flags)) +@lru_cache() +def get_section_base_address(name): + section = process_lookup_path(name) + return section.page_start if section else None + + +@lru_cache() +def get_zone_base_address(name): + zone = file_lookup_name_path(name, get_filepath()) + return zone.zone_start if zone else None + # # Architecture classes # @@ -3089,10 +3068,9 @@ def get_path_from_info_proc(): return None -@lru_cache() +@deprecated("Use `gef.session.os`") def get_os(): - """Return the current OS.""" - return platform.system().lower() + return gef.session.os @lru_cache() @@ -3118,14 +3096,9 @@ def is_qemu_system(): response = gdb.execute('maintenance packet QOffsets', to_string=True, from_tty=False) return 'received: ""' in response - -@lru_cache() +@deprecated("Use `gef.session.pid`") def get_pid(): - """Return the PID of the target process.""" - pid = gdb.selected_inferior().pid if not __gef_qemu_mode__ else gdb.selected_thread().ptid[1] - if not pid: - raise RuntimeError("cannot retrieve PID for target process") - return pid + return gef.session.pid @lru_cache() @@ -3160,10 +3133,9 @@ def get_filepath(): return get_path_from_info_proc() -@lru_cache() +@deprecated("Use `gef.session.file`") def get_filename(): - """Return the full filename of the file currently debugged.""" - return os.path.basename(gdb.current_progspace().filename) + return gef.session.file @lru_cache() @@ -3178,7 +3150,7 @@ def inferior_is_macho(): @lru_cache() def is_macho(filename): """Return True if the specified file is a Mach-O binary.""" - file_bin = which("file") + file_bin = gef.session.constants["file"] cmd = [file_bin, filename] out = gef_execute_external(cmd) if "Mach-O" in out: @@ -3472,6 +3444,7 @@ def hook_stop_handler(event): def new_objfile_handler(event): """GDB event handler for new object file cases.""" reset_all_caches() + gef.initialize_managers() set_arch() load_libc_args() return @@ -3733,15 +3706,6 @@ def get_elf_headers(filename=None): return Elf(filename) -# def _ptr_width(): -# void = cached_lookup_type("void") -# if void is None: -# uintptr_t = cached_lookup_type("uintptr_t") -# return uintptr_t.sizeof -# else: -# return void.pointer().sizeof - - @lru_cache() def is_64bit(): """Checks if current target is 64bit.""" @@ -3909,6 +3873,7 @@ def align_address_to_page(address): a = align_address(address) >> DEFAULT_PAGE_ALIGN_SHIFT return a << DEFAULT_PAGE_ALIGN_SHIFT + def malloc_align_address(address): """Align addresses according to glibc's MALLOC_ALIGNMENT. See also Issue #689 on Github""" __default_malloc_alignment = 0x10 @@ -3939,10 +3904,6 @@ def is_in_x86_kernel(address): memalign = gef.arch.ptrsize*8 - 1 return (address >> memalign) == 0xF -@deprecated("Use `str(gef.arch.endianness)` instead") -def endian_str(): - return str(gef.arch.endianness) - @lru_cache() def is_remote_debug(): @@ -4022,77 +3983,43 @@ def parse_string_range(s): return map(lambda x: int(x, 16), addrs) -@lru_cache() -def gef_get_auxiliary_values(): - """Retrieve the ELF auxiliary values of the current execution. This - information is provided by the operating system to transfer some kernel - level information to the user process. Return None if not found, or a - dict() of values as: {aux_vect_name: int(aux_vect_value)}.""" - if not is_alive(): - return None - - __auxiliary_vector = {} - auxv_info = gdb.execute("info auxv", to_string=True) - if "failed" in auxv_info: - err(auxv_info) # print GDB error - return None - for line in auxv_info.splitlines(): - line = line.split('"')[0].strip() # remove the ending string (if any) - line = line.split() # split the string by whitespace(s) - if len(line) < 4: - continue # a valid entry should have at least 4 columns - __av_type = line[1] - __av_value = line[-1] - __auxiliary_vector[__av_type] = int(__av_value, base=0) - return __auxiliary_vector - - -def gef_read_canary(): - """Read the canary of a running process using Auxiliary Vector. Return a tuple of (canary, location) - if found, None otherwise.""" - auxval = gef_get_auxiliary_values() - if not auxval: - return None - - canary_location = auxval["AT_RANDOM"] - canary = gef.memory.read_integer(canary_location) - canary &= ~0xFF - return canary, canary_location - - def gef_get_pie_breakpoint(num): global __pie_breakpoints__ return __pie_breakpoints__[num] -@lru_cache() -def gef_getpagesize(): - """Get the page size from auxiliary values.""" - auxval = gef_get_auxiliary_values() - if not auxval: - return DEFAULT_PAGE_SIZE - return auxval["AT_PAGESZ"] # # Deprecated API # +@deprecated("Use `str(gef.arch.endianness)` instead") +def endian_str(): + return str(gef.arch.endianness) @deprecated("Use `gef.config[key]`") def get_gef_setting(name): return gef.config + @deprecated("Use `gef.config[key] = value`") def set_gef_setting(name, value): gef.config[name] = value return +@deprecated("Use `gef.session.pagesize`") +def gef_getpagesize(): + return gef.session.pagesize + +@deprecated("Use `gef.session.canary`") +def gef_read_canary(): + return gef.session.canary + # # GDB event hooking # - @only_if_events_supported("cont") def gef_on_continue_hook(func): return gdb.events.cont.connect(func) @@ -4576,7 +4503,7 @@ 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) """ - gef.instance.add_context_pane(pane_name, display_pane_function, pane_title_function) + gef.gdb.add_context_pane(pane_name, display_pane_function, pane_title_function) return @@ -4589,9 +4516,9 @@ def register_external_command(obj): global __commands__, gef cls = obj.__class__ __commands__.append(cls) - gef.instance.load(initial=False) - gef.instance.doc.add_command_to_doc((cls._cmdline_, cls, None)) - gef.instance.doc.refresh() + gef.gdb.load(initial=False) + gef.gdb.doc.add_command_to_doc((cls._cmdline_, cls, None)) + gef.gdb.doc.refresh() return cls @@ -4769,7 +4696,7 @@ def do_invoke(self, argv): gef_print("GDB-Python: {}".format(py_ver, )) if "full" in argv: - gef_print("Loaded commands: {}".format(", ".join(gef.instance.loaded_command_names))) + gef_print("Loaded commands: {}".format(", ".join(gef.gdb.loaded_command_names))) return @@ -5136,7 +5063,7 @@ def do_invoke(self, argv): warn("This binary was not compiled with SSP.") return - res = gef_read_canary() + res = gef.session.canary if not res: err("Failed to get the canary") return @@ -5187,8 +5114,7 @@ def get_process_path_of(self, pid): return os.readlink("/proc/{}/exe".format(pid)) def get_children_pids(self, pid): - ps = which("ps") - cmd = [ps, "-o", "pid", "--ppid", "{}".format(pid), "--noheaders"] + cmd = [gef.session.constants["ps"], "-o", "pid", "--ppid", "{}".format(pid), "--noheaders"] try: return [int(x) for x in gef_execute_external(cmd, as_list=True)] except Exception: @@ -7915,8 +7841,7 @@ class ProcessListingCommand(GenericCommand): def __init__(self): super().__init__(complete=gdb.COMPLETE_LOCATION) - ps = which("ps") - self["ps_command"] = ( "{:s} auxww".format(ps), "`ps` command to get process information") + self["ps_command"] = ( "{:s} auxww".format(gef.session.constants["ps"]), "`ps` command to get process information") return @parse_arguments({"pattern": ""}, {"--attach": True, "--smart-scan": True}) @@ -10042,10 +9967,6 @@ def __init__(self): super().__init__(complete=gdb.COMPLETE_FILENAME) return - def pre_load(self): - which("readelf") - return - def do_invoke(self, argv): argc = len(argv) @@ -10104,10 +10025,6 @@ def __init__(self, *args, **kwargs): "not been resolved") return - def pre_load(self): - which("readelf") - return - def get_jmp_slots(self, readelf, filename): output = [] cmd = [readelf, "--relocs", filename] @@ -10121,7 +10038,7 @@ def get_jmp_slots(self, readelf, filename): def do_invoke(self, argv): try: - readelf = which("readelf") + readelf = gef.session.constants["readelf"] except IOError: err("Missing `readelf`") return @@ -10426,7 +10343,7 @@ class SyscallArgsCommand(GenericCommand): def __init__(self): super().__init__() - path = pathlib.Path(gef.config["gef.tempdir"]) / "syscall-tables" + path = pathlib.Path(self["path"]) / "syscall-tables" if not path.exists(): raise EnvironmentError("Syscall tables directory not found") self["path"] = (str(path.absolute()), "Path to store/load the syscall tables files") @@ -10497,22 +10414,10 @@ def get_settings_path(self): return path if os.path.isdir(path) else None -@lru_cache() -def get_section_base_address(name): - section = process_lookup_path(name) - if section: - return section.page_start - - return None - -@lru_cache() -def get_zone_base_address(name): - zone = file_lookup_name_path(name, get_filepath()) - if zone: - return zone.zone_start - - return None +# +# GDB Function declaration +# class GenericFunction(gdb.Function, metaclass=abc.ABCMeta): """This is an abstract class for invoking convenience functions, should not be instantiated.""" @@ -10549,7 +10454,11 @@ class StackOffsetFunction(GenericFunction): _function_ = "_stack" def do_invoke(self, args): - return self.arg_to_long(args, 0) + get_section_base_address("[stack]") + base = get_section_base_address("[stack]") + if not base: + raise gdb.GdbError("Stack not found") + + return self.arg_to_long(args, 0) + base @register_function @@ -10558,22 +10467,13 @@ class HeapBaseFunction(GenericFunction): _function_ = "_heap" def do_invoke(self, args): - base = HeapBaseFunction.heap_base() + base = gef.heap.base_address if not base: - raise gdb.GdbError("Heap not found") - + base = get_section_base_address("[heap]") + if not base: + raise gdb.GdbError("Heap not found") return self.arg_to_long(args, 0) + base - @staticmethod - def heap_base(): - try: - base = parse_address("mp_->sbrk_base") - if base != 0: - return base - except gdb.error: - pass - return get_section_base_address("[heap]") - @register_function class SectionBaseFunction(GenericFunction): @@ -10607,16 +10507,23 @@ class BssBaseFunction(GenericFunction): _example_ = "deref $_bss(0x20)" def do_invoke(self, args): - return self.arg_to_long(args, 0) + get_zone_base_address(".bss") + base = get_zone_base_address(".bss") + if not base: + raise gdb.GdbError("BSS not found") + return self.arg_to_long(args, 0) + base @register_function class GotBaseFunction(GenericFunction): """Return the current bss base address plus the given offset.""" _function_ = "_got" + _example_ = "deref $_got(0x20)" def do_invoke(self, args): - return self.arg_to_long(args, 0) + get_zone_base_address(".got") + base = get_zone_base_address(".got") + if not base: + raise gdb.GdbError("GOT not found") + return base + self.arg_to_long(args, 0) @register_command @@ -10633,7 +10540,7 @@ def __init__(self): def setup(self): global gef - for function in gef.instance.loaded_functions: + for function in gef.gdb.loaded_functions: self.add_function_to_doc(function) self.__doc__ = "\n".join(sorted(self.docs)) return @@ -10660,6 +10567,9 @@ def do_invoke(self, argv): return +# +# GEF internal classes +# class GefCommand(gdb.Command): """GEF main command: view all new commands by typing `gef`.""" @@ -10942,7 +10852,7 @@ def set_setting(self, argv): err("Invalid command format") return - loaded_commands = [ x[0] for x in gef.instance.loaded_commands ] + ["gef"] + loaded_commands = [ x[0] for x in gef.gdb.loaded_commands ] + ["gef"] plugin_name = key.split(".", 1)[0] if plugin_name not in loaded_commands: err("Unknown plugin '{:s}'".format(plugin_name)) @@ -11086,13 +10996,13 @@ def __init__(self, *args, **kwargs): def invoke(self, args, from_tty): self.dont_repeat() - missing_commands = gef.instance.missing_commands.keys() + missing_commands = gef.gdb.missing_commands.keys() if not missing_commands: ok("No missing command") return for missing_command in missing_commands: - reason = gef.instance.missing_commands[missing_command] + reason = gef.gdb.missing_commands[missing_command] warn("Command `{}` is missing, reason {} {}".format(missing_command, RIGHT_ARROW, reason)) return @@ -11176,7 +11086,7 @@ def invoke(self, args, from_tty): def lookup_command(self, cmd): global gef - for _name, _class, _instance in gef.instance.loaded_commands: + for _name, _class, _instance in gef.gdb.loaded_commands: if cmd == _name: return _name, _class, _instance @@ -11389,7 +11299,7 @@ def read_ascii_string(self, address): return None class GefHeapManager: - + """Class managing session heap.""" def __init__(self): self.__libc_main_arena = None self.__libc_selected_arena = None @@ -11430,7 +11340,7 @@ def arenas(self): @property def base_address(self): if not self.__heap_base: - self.__heap_base = HeapBaseFunction.heap_base() + self.__heap_base = parse_address("mp_->sbrk_base") return self.__heap_base @property @@ -11439,8 +11349,8 @@ def chunks(self): return [] return iter( GlibcChunk(self.base_address, from_base=True) ) - class GefSetting: + """Basic class for storing gef settings as objects""" def __init__(self, value, cls = None, description = None): self.value = value self.type = cls or type(value) @@ -11480,10 +11390,86 @@ def __delitem__(self, name): def raw_entry(self, name): return dict.__getitem__(self, name) - class GefSessionManager: + """Class managing the runtime properties of GEF. """ def __init__(self): - pass + self.__auxiliary_vector = None + self.__pagesize = None + self.__os = None + self.__pid = None + self.__file = None + self.__canary = None + self.constants = {} # a dict for runtime constants (like 3rd party file paths) + # add a few extra runtime constants to avoid lookups + # those must be found, otherwise IOError will be raised + for constant in ("python3", "readelf", "file", "ps"): + self.constants[constant] = which(constant) + return + + @property + def auxiliary_vector(self): + if not is_alive(): + return None + + if not self.__auxiliary_vector: + auxiliary_vector = {} + auxv_info = gdb.execute("info auxv", to_string=True) + if "failed" in auxv_info: + err(auxv_info) # print GDB error + return None + for line in auxv_info.splitlines(): + line = line.split('"')[0].strip() # remove the ending string (if any) + line = line.split() # split the string by whitespace(s) + if len(line) < 4: + continue # a valid entry should have at least 4 columns + __av_type = line[1] + __av_value = line[-1] + auxiliary_vector[__av_type] = int(__av_value, base=0) + self.__auxiliary_vector = auxiliary_vector + return self.__auxiliary_vector + + @property + def os(self): + """Return the current OS.""" + if not self.__os: + self.__os = platform.system().lower() + return self.__os + + @property + def pid(self): + """Return the PID of the target process.""" + if not self.__pid: + pid = gdb.selected_inferior().pid if not __gef_qemu_mode__ else gdb.selected_thread().ptid[1] + if not pid: + raise RuntimeError("cannot retrieve PID for target process") + self.__pid = pid + return self.__pid + + @property + def file(self): + """Return a Path object of the target process.""" + return pathlib.Path(gdb.current_progspace().filename) + + @property + def pagesize(self): + """Get the system page size""" + auxval = self.auxiliary_vector + if not auxval: + return DEFAULT_PAGE_SIZE + self.__pagesize = auxval["AT_PAGESZ"] + return self.__pagesize + + @property + def canary(self): + """Returns a tuple of the canary address and value, read from the auxiliary vector.""" + auxval = self.auxiliary_vector + if not auxval: + return None + canary_location = auxval["AT_RANDOM"] + canary = u64(canary_location) + canary &= ~0xFF + self.__canary = (canary, canary_location) + return self.__canary, canary_location class Gef: """The GEF root class""" @@ -11493,22 +11479,25 @@ def __init__(self): self.config = GefSettingsManager() return + def initialize_managers(self): + self.memory = GefMemoryManager() + self.heap = GefHeapManager() + self.session = GefSessionManager() + return + def setup(self): """ Setup initialize the runtime setup, which may require for the `gef` to be not None """ - self.memory = GefMemoryManager() - self.heap = GefHeapManager() - self.instance = GefCommand() - self.instance.setup() + self.initialize_managers() + self.gdb = GefCommand() + self.gdb.setup() tempdir = self.config["gef.tempdir"] gef_makedirs(tempdir) gdb.execute("save gdb-index {}".format(tempdir)) return - - if __name__ == "__main__": if sys.version_info[0] == 2: err("GEF has dropped Python2 support for GDB when it reached EOL on 2020/01/01.") @@ -11545,7 +11534,7 @@ def setup(self): gdb.prompt_hook = __gef_prompt__ # setup config - gdb_initial_config = ( + gdb_initial_settings = ( "set confirm off", "set verbose off", "set pagination off", @@ -11557,7 +11546,7 @@ def setup(self): "set disassembly-flavor intel", "handle SIGALRM print nopass", ) - for cmd in gdb_initial_config: + for cmd in gdb_initial_settings: try: gdb.execute(cmd) except gdb.error: @@ -11567,7 +11556,6 @@ def setup(self): gef = Gef() gef.setup() - print(gef.arch) # gdb events configuration gef_on_continue_hook(continue_handler) gef_on_stop_hook(hook_stop_handler) From fbbcc3ac3bc09860a866100295117cbb3b6796a4 Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 18:10:57 -0800 Subject: [PATCH 06/62] `get_memory_alignment()` -> `gef.arch.ptrsize` --- gef.py | 31 +++++++++++++++++-------------- tests/runtests.py | 10 +++++----- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/gef.py b/gef.py index d1c5d8cdb..2455fe938 100644 --- a/gef.py +++ b/gef.py @@ -1253,7 +1253,7 @@ def is_main_arena(self): def heap_addr(self, allow_unaligned=False): if self.is_main_arena(): - heap_section = HeapBaseFunction.heap_base() + heap_section = gef.heap.base_address if not heap_section: err("Heap not initialized") return None @@ -1659,7 +1659,7 @@ def hexdump(source, length=0x10, separator=".", show_raw=False, show_symbol=True @param base is the start address of the block being hexdump @return a string with the hexdump""" result = [] - align = get_memory_alignment() * 2 + 2 if is_alive() else 18 + align = gef.arch.ptrsize * 2 + 2 if is_alive() else 18 for i in range(0, len(source), length): chunk = bytearray(source[i : i + length]) @@ -2358,7 +2358,7 @@ def get_ra(self, insn, frame): if self.is_ret(insn): # If it's a pop, we have to peek into the stack, otherwise use lr if insn.mnemonic == "pop": - ra_addr = gef.arch.sp + (len(insn.operands)-1) * get_memory_alignment() + ra_addr = gef.arch.sp + (len(insn.operands)-1) * self.ptrsize ra = to_unsigned_long(dereference(ra_addr)) elif insn.mnemonic == "ldr": return to_unsigned_long(dereference(gef.arch.sp)) @@ -3835,7 +3835,7 @@ def clear_screen(tty=""): def format_address(addr): """Format the address according to its size.""" - memalign_size = get_memory_alignment() + memalign_size = gef.arch.ptrsize addr = align_address(addr) if memalign_size == 4: @@ -3846,7 +3846,7 @@ def format_address(addr): def format_address_spaces(addr, left=True): """Format the address according to its size, but with spaces instead of zeroes.""" - width = get_memory_alignment() * 2 + 2 + width = gef.arch.ptrsize * 2 + 2 addr = align_address(addr) if not left: @@ -3857,7 +3857,7 @@ def format_address_spaces(addr, left=True): def align_address(address): """Align the provided address to the process's native length.""" - if get_memory_alignment() == 4: + if gef.arch.ptrsize == 4: return address & 0xFFFFFFFF return address & 0xFFFFFFFFFFFFFFFF @@ -4268,7 +4268,7 @@ def stop(self): if check_heap_overlap: # seek all the currently allocated chunks, read their effective size and check for overlap msg = [] - align = get_memory_alignment() + align = gef.arch.ptrsize for chunk_addr, _ in __heap_allocated_list__: current_chunk = GlibcChunk(chunk_addr) current_chunk_size = current_chunk.get_chunk_size() @@ -5397,7 +5397,7 @@ def apply_structure_to_address(self, mod_name, struct_name, addr, depth=0): self.deserialize(_struct, data) - _regsize = get_memory_alignment() + _regsize = gef.arch.ptrsize for field in _struct._fields_: _name, _type = field @@ -7213,7 +7213,7 @@ def find_tcache(): # one thread), we can't use the tcache symbol, but we can guess the # correct address because the tcache is consistently the first # allocation in the main arena. - heap_base = HeapBaseFunction.heap_base() + heap_base = gef.heap.base_address if heap_base is None: err("No heap section") return 0x0 @@ -9346,7 +9346,7 @@ def dereference_from(addr): elif addr.section.permission.value & Permission.READ: if is_ascii_string(addr.value): s = gef.memory.read_cstring(addr.value) - if len(s) < get_memory_alignment(): + if len(s) < gef.arch.ptrsize: txt = '{:s} ("{:s}"?)'.format(format_address(deref), Color.colorify(s, string_color)) elif len(s) > 50: txt = Color.colorify('"{:s}[...]"'.format(s[:50]), string_color) @@ -9525,7 +9525,7 @@ def do_invoke(self, argv): color = gef.config["theme.table_heading"] headers = ["Start", "End", "Offset", "Perm", "Path"] - gef_print(Color.colorify("{:<{w}s}{:<{w}s}{:<{w}s}{:<4s} {:s}".format(*headers, w=get_memory_alignment()*2+3), color)) + gef_print(Color.colorify("{:<{w}s}{:<{w}s}{:<{w}s}{:<4s} {:s}".format(*headers, w=gef.arch.ptrsize*2+3), color)) for entry in vmmap: if not argv: @@ -9598,7 +9598,7 @@ class XFilesCommand(GenericCommand): def do_invoke(self, argv): color = gef.config["theme.table_heading"] headers = ["Start", "End", "Name", "File"] - gef_print(Color.colorify("{:<{w}s}{:<{w}s}{:<21s} {:s}".format(*headers, w=get_memory_alignment()*2+3), color)) + gef_print(Color.colorify("{:<{w}s}{:<{w}s}{:<21s} {:s}".format(*headers, w=gef.arch.ptrsize*2+3), color)) filter_by_file = argv[0] if argv and argv[0] else None filter_by_name = argv[1] if len(argv) > 1 and argv[1] else None @@ -10568,7 +10568,7 @@ def do_invoke(self, argv): # -# GEF internal classes +# GEF internal command classes # class GefCommand(gdb.Command): """GEF main command: view all new commands by typing `gef`.""" @@ -11237,6 +11237,10 @@ def screen_setup(self): return +# +# GEF internal classes +# + def __gef_prompt__(current_prompt): """GEF custom prompt function.""" @@ -11245,7 +11249,6 @@ def __gef_prompt__(current_prompt): if is_alive(): return GEF_PROMPT_ON return GEF_PROMPT_OFF - class GefMemoryManager: """Class that manages memory access for gef.""" diff --git a/tests/runtests.py b/tests/runtests.py index 23dbd43ac..31f0a02ac 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -839,7 +839,7 @@ class TestGefFunctionsUnit(GefUnitTestGeneric): """Tests GEF internal functions.""" def test_func_get_memory_alignment(self): - res = gdb_test_python_method("get_memory_alignment(in_bits=False)") + res = gdb_test_python_method("gef.arch.ptrsize") self.assertIn(res.splitlines()[-1], ("4", "8")) return @@ -859,23 +859,23 @@ def test_func_which(self): return def test_func_get_filepath(self): - res = gdb_test_python_method("get_filepath()", target=BIN_LS) + res = gdb_test_python_method("gef.session.file", target=BIN_LS) self.assertNoException(res) target = TMPDIR / "foo bar" subprocess.call(["cp", BIN_LS, target]) - res = gdb_test_python_method("get_filepath()", target=target) + res = gdb_test_python_method("gef.session.file", target=target) self.assertNoException(res) subprocess.call(["rm", target]) return def test_func_get_pid(self): - res = gdb_test_python_method("get_pid()", target=BIN_LS) + res = gdb_test_python_method("gef.session.pid", target=BIN_LS) self.assertNoException(res) self.assertTrue(int(res.splitlines()[-1])) return def test_fun_gef_get_auxiliary_values(self): - func = "gef_get_auxiliary_values()" + func = "gef.session.auxiliary_values" res = gdb_test_python_method(func, target=BIN_LS) self.assertNoException(res) # we need at least ("AT_PLATFORM", "AT_EXECFN") right now From e709aeb736d1cda338087ffee0f312104e3e82b8 Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 19:36:27 -0800 Subject: [PATCH 07/62] Fixed `heap.base_address` --- gef.py | 57 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/gef.py b/gef.py index 2455fe938..e4a2c94c5 100644 --- a/gef.py +++ b/gef.py @@ -279,35 +279,35 @@ def wrapper(*args, **kwargs): def p8(x: int, s: bool = False) -> bytes: """Pack one byte respecting the current architecture endianness.""" - return struct.pack("{}B".format(endian_str()), x) if not s else struct.pack("{}b".format(endian_str()), x) + return struct.pack("{}B".format(gef.arch.endianness), x) if not s else struct.pack("{}b".format(gef.arch.endianness), x) def p16(x: int, s: bool = False) -> bytes: """Pack one word respecting the current architecture endianness.""" - return struct.pack("{}H".format(endian_str()), x) if not s else struct.pack("{}h".format(endian_str()), x) + return struct.pack("{}H".format(gef.arch.endianness), x) if not s else struct.pack("{}h".format(gef.arch.endianness), x) def p32(x: int, s: bool = False) -> bytes: """Pack one dword respecting the current architecture endianness.""" - return struct.pack("{}I".format(endian_str()), x) if not s else struct.pack("{}i".format(endian_str()), x) + return struct.pack("{}I".format(gef.arch.endianness), x) if not s else struct.pack("{}i".format(gef.arch.endianness), x) def p64(x: int, s: bool = False) -> bytes: """Pack one qword respecting the current architecture endianness.""" - return struct.pack("{}Q".format(endian_str()), x) if not s else struct.pack("{}q".format(endian_str()), x) + return struct.pack("{}Q".format(gef.arch.endianness), x) if not s else struct.pack("{}q".format(gef.arch.endianness), x) def u8(x: bytes, s: bool = False) -> int: """Unpack one byte respecting the current architecture endianness.""" - return struct.unpack("{}B".format(endian_str()), x)[0] if not s else struct.unpack("{}b".format(endian_str()), x)[0] + return struct.unpack("{}B".format(gef.arch.endianness), x)[0] if not s else struct.unpack("{}b".format(gef.arch.endianness), x)[0] def u16(x: bytes, s: bool = False) -> int: """Unpack one word respecting the current architecture endianness.""" - return struct.unpack("{}H".format(endian_str()), x)[0] if not s else struct.unpack("{}h".format(endian_str()), x)[0] + return struct.unpack("{}H".format(gef.arch.endianness), x)[0] if not s else struct.unpack("{}h".format(gef.arch.endianness), x)[0] def u32(x: bytes, s: bool = False) -> int: """Unpack one dword respecting the current architecture endianness.""" - return struct.unpack("{}I".format(endian_str()), x)[0] if not s else struct.unpack("{}i".format(endian_str()), x)[0] + return struct.unpack("{}I".format(gef.arch.endianness), x)[0] if not s else struct.unpack("{}i".format(gef.arch.endianness), x)[0] def u64(x: bytes, s: bool = False) -> int: """Unpack one qword respecting the current architecture endianness.""" - return struct.unpack("{}Q".format(endian_str()), x)[0] if not s else struct.unpack("{}q".format(endian_str()), x)[0] + return struct.unpack("{}Q".format(gef.arch.endianness), x)[0] if not s else struct.unpack("{}q".format(gef.arch.endianness), x)[0] def is_ascii_string(address): @@ -761,7 +761,7 @@ def __init__(self, elf="", minimalist=False): self.e_magic, self.e_class, self.e_endianness, self.e_eiversion = struct.unpack(">IBBB", self.read(7)) # adjust endianness in bin reading - endian = endian_str() + endian = gef.arch.endianness # off 0x7 self.e_osabi, self.e_abiversion = struct.unpack("{}BB".format(endian), self.read(2)) @@ -845,7 +845,7 @@ def __init__(self, elf, off): if not elf: return None elf.seek(off) - endian = endian_str() + endian = gef.arch.endianness if elf.e_class == Elf.ELF_64_BITS: self.p_type, self.p_flags, self.p_offset = struct.unpack("{}IIQ".format(endian), elf.read(16)) self.p_vaddr, self.p_paddr = struct.unpack("{}QQ".format(endian), elf.read(16)) @@ -926,7 +926,7 @@ def __init__(self, elf, off): if elf is None: return None elf.seek(off) - endian = endian_str() + endian = gef.arch.endianness if elf.e_class == Elf.ELF_64_BITS: self.sh_name, self.sh_type, self.sh_flags = struct.unpack("{}IIQ".format(endian), elf.read(16)) self.sh_addr, self.sh_offset = struct.unpack("{}QQ".format(endian), elf.read(16)) @@ -1240,14 +1240,6 @@ def bin(self, i): bw = int(self.bins[idx + 1]) return fd, bw - # def get_next(self): - # addr_next = int(self.next) - # arena_main = GlibcArena(self.__name) - # if addr_next == arena_main.__addr: - # return None - # return GlibcArena("*{:#x} ".format(addr_next)) - - @deprecated("use `==` operator instead") def is_main_arena(self): return int(self) == int(gef.heap.main_arena) @@ -4001,7 +3993,6 @@ def endian_str(): def get_gef_setting(name): return gef.config - @deprecated("Use `gef.config[key] = value`") def set_gef_setting(name, value): gef.config[name] = value @@ -4724,12 +4715,12 @@ def __init__(self): @property def format_matrix(self): - # `endian_str()` is a runtime property, should not be defined as a class property + # `gef.arch.endianness` is a runtime property, should not be defined as a class property return { - 8: (endian_str() + "B", "char", "db"), - 16: (endian_str() + "H", "short", "dw"), - 32: (endian_str() + "I", "int", "dd"), - 64: (endian_str() + "Q", "long long", "dq"), + 8: (gef.arch.endianness + "B", "char", "db"), + 16: (gef.arch.endianness + "H", "short", "dw"), + 32: (gef.arch.endianness + "I", "int", "dd"), + 64: (gef.arch.endianness + "Q", "long long", "dq"), } @only_if_gdb_running @@ -7475,7 +7466,7 @@ def do_invoke(self, argv, *args, **kwargs): err("invalid registers for architecture: {}".format(", ".join(invalid_regs))) memsize = gef.arch.ptrsize - endian = endian_str() + endian = gef.arch.endianness charset = string.printable widest = max(map(len, gef.arch.all_registers)) special_line = "" @@ -9086,7 +9077,7 @@ def do_invoke(self, argv, *args, **kwargs): return def _hexdump(self, start_addr, length, arrange_as, offset=0): - endianness = endian_str() + endianness = gef.arch.endianness base_address_color = gef.config["theme.dereference_base_address"] show_ascii = gef.config["hexdump.always_show_ascii"] @@ -9209,7 +9200,7 @@ def do_invoke(self, argv, *args, **kwargs): addr = align_address(parse_address(args.location)) size, fcode = self.SUPPORTED_SIZES[self.format] - d = endian_str() + d = gef.arch.endianness for value in args.values: value = parse_address(value) & ((1 << size * 8) - 1) vstr = struct.pack(d + fcode, value) @@ -11343,7 +11334,15 @@ def arenas(self): @property def base_address(self): if not self.__heap_base: - self.__heap_base = parse_address("mp_->sbrk_base") + base = 0 + try: + base = parse_address("mp_->sbrk_base") + except gdb.error: + # missing symbol, try again + base = 0 + if not base: + base = get_section_base_address("[heap]") + self.__heap_base = base return self.__heap_base @property From 43a9920db11b8b5c9a5456da902e17b88c7ea62b Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 19:47:42 -0800 Subject: [PATCH 08/62] `get_pid()` -> `gef.session.pid` --- gef.py | 102 ++++++++++++--------------------------------------------- 1 file changed, 21 insertions(+), 81 deletions(-) diff --git a/gef.py b/gef.py index e4a2c94c5..9608b8db0 100644 --- a/gef.py +++ b/gef.py @@ -1931,16 +1931,6 @@ def checksec(filename): - Partial/Full RelRO. Return a dict() with the different keys mentioned above, and the boolean associated whether the protection was found.""" - - if is_macho(filename): - return { - "Canary": False, - "NX": False, - "PIE": False, - "Fortify": False, - "Partial RelRO": False, - } - readelf = gef.session.constants["readelf"] def __check_security_property(opt, filename, pattern): @@ -3088,10 +3078,6 @@ def is_qemu_system(): response = gdb.execute('maintenance packet QOffsets', to_string=True, from_tty=False) return 'received: ""' in response -@deprecated("Use `gef.session.pid`") -def get_pid(): - return gef.session.pid - @lru_cache() def get_filepath(): @@ -3101,7 +3087,7 @@ def get_filepath(): if is_remote_debug(): # if no filename specified, try downloading target from /proc if filename is None: - pid = get_pid() + pid = gef.session.pid if pid > 0: return download_file("/proc/{:d}/exe".format(pid), use_cache=True) return None @@ -3125,38 +3111,13 @@ def get_filepath(): return get_path_from_info_proc() -@deprecated("Use `gef.session.file`") -def get_filename(): - return gef.session.file - - -@lru_cache() -def inferior_is_macho(): - """Return True if the current file is a Mach-O binary.""" - for x in gdb.execute("info files", to_string=True).splitlines(): - if "file type mach-o" in x: - return True - return False - - -@lru_cache() -def is_macho(filename): - """Return True if the specified file is a Mach-O binary.""" - file_bin = gef.session.constants["file"] - cmd = [file_bin, filename] - out = gef_execute_external(cmd) - if "Mach-O" in out: - return True - return False - - def download_file(target, use_cache=False, local_name=None): """Download filename `target` inside the mirror tree inside the gef.config["gef.tempdir"]. The tree architecture must be gef.config["gef.tempdir"]/gef//. This allow a "chroot-like" tree format.""" try: - local_root = os.path.sep.join([gef.config["gef.tempdir"], str(get_pid())]) + local_root = os.path.sep.join([gef.config["gef.tempdir"], str(gef.session.pid)]) if local_name is None: local_path = os.path.sep.join([local_root, os.path.dirname(target)]) local_name = os.path.sep.join([local_path, os.path.basename(target)]) @@ -3232,38 +3193,12 @@ def get_process_maps_linux(proc_map_file): return -def get_mach_regions(): - sp = gef.arch.sp - for line in gdb.execute("info mach-regions", to_string=True).splitlines(): - line = line.strip() - addr, perm, _ = line.split(" ", 2) - addr_start, addr_end = [int(x, 16) for x in addr.split("-")] - perm = Permission.from_process_maps(perm.split("/")[0]) - - zone = file_lookup_address(addr_start) - if zone: - path = zone.filename - else: - path = "[stack]" if sp >= addr_start and sp < addr_end else "" - - yield Section(page_start=addr_start, - page_end=addr_end, - offset=0, - permission=perm, - inode=None, - path=path) - return - - @lru_cache() def get_process_maps(): """Return the mapped memory sections""" - if inferior_is_macho(): - return list(get_mach_regions()) - try: - pid = get_pid() + pid = gef.session.pid fpath = "/proc/{:d}/maps".format(pid) return list(get_process_maps_linux(fpath)) except FileNotFoundError as e: @@ -4006,6 +3941,13 @@ def gef_getpagesize(): def gef_read_canary(): return gef.session.canary +@deprecated("Use `gef.session.pid`") +def get_pid(): + return gef.session.pid + +@deprecated("Use `gef.session.file`") +def get_filename(): + return gef.session.file # # GDB event hooking @@ -5061,7 +5003,7 @@ def do_invoke(self, argv): canary, location = res info("Found AT_RANDOM at {:#x}, reading {} bytes".format(location, gef.arch.ptrsize)) - info("The canary of process {} is {:#x}".format(get_pid(), canary)) + info("The canary of process {} is {:#x}".format(gef.session.pid, canary)) return @@ -5113,7 +5055,7 @@ def get_children_pids(self, pid): def show_info_proc(self): info("Process Information") - pid = get_pid() + pid = gef.session.pid cmdline = self.get_cmdline_of(pid) gef_print("\tPID {} {}".format(RIGHT_ARROW, pid)) gef_print("\tExecutable {} {}".format(RIGHT_ARROW, self.get_process_path_of(pid))) @@ -5122,7 +5064,7 @@ def show_info_proc(self): def show_ancestor(self): info("Parent Process Information") - ppid = int(self.get_state_of(get_pid())["PPid"]) + ppid = int(self.get_state_of(gef.session.pid)["PPid"]) state = self.get_state_of(ppid) cmdline = self.get_cmdline_of(ppid) gef_print("\tParent PID {} {}".format(RIGHT_ARROW, state["Pid"])) @@ -5131,7 +5073,7 @@ def show_ancestor(self): def show_descendants(self): info("Children Process Information") - children = self.get_children_pids(get_pid()) + children = self.get_children_pids(gef.session.pid) if not children: gef_print("\tNo child process") return @@ -5146,7 +5088,7 @@ def show_descendants(self): return def show_fds(self): - pid = get_pid() + pid = gef.session.pid path = "/proc/{:d}/fd".format(pid) info("File Descriptors:") @@ -5198,7 +5140,7 @@ def show_connections(self): } info("Network Connections") - pid = get_pid() + pid = gef.session.pid sockets = self.list_sockets(pid) if not sockets: gef_print("\tNo open connections") @@ -5624,7 +5566,7 @@ def do_invoke(self, argv): self.usage() return - if not os.access("/proc/{:d}/fd/{:s}".format(get_pid(), argv[0]), os.R_OK): + if not os.access("/proc/{:d}/fd/{:s}".format(gef.session.pid, argv[0]), os.R_OK): self.usage() return @@ -6547,7 +6489,7 @@ def do_invoke(self, argv, *args, **kwargs): if not self.connect_target(target, args.is_extended_remote): return - pid = args.pid if args.is_extended_remote and args.pid else get_pid() + pid = args.pid if args.is_extended_remote and args.pid else gef.session.pid if args.is_extended_remote: ok("Attaching to {:d}".format(pid)) hide_context() @@ -6622,7 +6564,7 @@ def setup_remote_environment(self, pid, update_solib=False): err("Source binary is not readable") return - directory = os.path.sep.join([gef.config["gef.tempdir"], str(get_pid())]) + directory = os.path.sep.join([gef.config["gef.tempdir"], str(gef.session.pid)]) # gdb.execute("file {:s}".format(infos["exe"])) self["root"] = ( directory, "Path to store the remote data") ok("Remote information loaded to temporary path '{:s}'".format(directory)) @@ -6703,7 +6645,7 @@ def prepare_qemu_stub(self, target): gdb.execute("target remote {}".format(target)) unhide_context() - if get_pid() == 1 and "ENABLE=1" in gdb.execute("maintenance packet Qqemu.sstepbits", to_string=True, from_tty=False): + if gef.session.pid == 1 and "ENABLE=1" in gdb.execute("maintenance packet Qqemu.sstepbits", to_string=True, from_tty=False): __gef_qemu_mode__ = True reset_all_caches() info("Note: By using Qemu mode, GEF will display the memory mapping of the Qemu process where the emulated binary resides") @@ -10334,9 +10276,7 @@ class SyscallArgsCommand(GenericCommand): def __init__(self): super().__init__() - path = pathlib.Path(self["path"]) / "syscall-tables" - if not path.exists(): - raise EnvironmentError("Syscall tables directory not found") + path = pathlib.Path(gef.config["gef.tempdir"]) / "syscall-tables" self["path"] = (str(path.absolute()), "Path to store/load the syscall tables files") return From 5b20f3cd88354fe4e32771cff8c99fa4ad922293 Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 20:03:14 -0800 Subject: [PATCH 09/62] Fixed `canary` command --- gef.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/gef.py b/gef.py index 9608b8db0..32730d3f3 100644 --- a/gef.py +++ b/gef.py @@ -279,35 +279,35 @@ def wrapper(*args, **kwargs): def p8(x: int, s: bool = False) -> bytes: """Pack one byte respecting the current architecture endianness.""" - return struct.pack("{}B".format(gef.arch.endianness), x) if not s else struct.pack("{}b".format(gef.arch.endianness), x) + return struct.pack(f"{gef.arch.endianness:s}B", x) if not s else struct.pack(f"{gef.arch.endianness:s}b", x) def p16(x: int, s: bool = False) -> bytes: """Pack one word respecting the current architecture endianness.""" - return struct.pack("{}H".format(gef.arch.endianness), x) if not s else struct.pack("{}h".format(gef.arch.endianness), x) + return struct.pack(f"{gef.arch.endianness:s}H", x) if not s else struct.pack(f"{gef.arch.endianness:s}h", x) def p32(x: int, s: bool = False) -> bytes: """Pack one dword respecting the current architecture endianness.""" - return struct.pack("{}I".format(gef.arch.endianness), x) if not s else struct.pack("{}i".format(gef.arch.endianness), x) + return struct.pack(f"{gef.arch.endianness:s}I", x) if not s else struct.pack(f"{gef.arch.endianness:s}i", x) def p64(x: int, s: bool = False) -> bytes: """Pack one qword respecting the current architecture endianness.""" - return struct.pack("{}Q".format(gef.arch.endianness), x) if not s else struct.pack("{}q".format(gef.arch.endianness), x) + return struct.pack(f"{gef.arch.endianness:s}Q", x) if not s else struct.pack(f"{gef.arch.endianness:s}q", x) def u8(x: bytes, s: bool = False) -> int: """Unpack one byte respecting the current architecture endianness.""" - return struct.unpack("{}B".format(gef.arch.endianness), x)[0] if not s else struct.unpack("{}b".format(gef.arch.endianness), x)[0] + return struct.unpack(f"{gef.arch.endianness:s}B", x)[0] if not s else struct.unpack(f"{gef.arch.endianness:s}b", x)[0] def u16(x: bytes, s: bool = False) -> int: """Unpack one word respecting the current architecture endianness.""" - return struct.unpack("{}H".format(gef.arch.endianness), x)[0] if not s else struct.unpack("{}h".format(gef.arch.endianness), x)[0] + return struct.unpack(f"{gef.arch.endianness:s}H", x)[0] if not s else struct.unpack(f"{gef.arch.endianness:s}h", x)[0] def u32(x: bytes, s: bool = False) -> int: """Unpack one dword respecting the current architecture endianness.""" - return struct.unpack("{}I".format(gef.arch.endianness), x)[0] if not s else struct.unpack("{}i".format(gef.arch.endianness), x)[0] + return struct.unpack(f"{gef.arch.endianness:s}I", x)[0] if not s else struct.unpack("{}i".format(gef.arch.endianness), x)[0] def u64(x: bytes, s: bool = False) -> int: """Unpack one qword respecting the current architecture endianness.""" - return struct.unpack("{}Q".format(gef.arch.endianness), x)[0] if not s else struct.unpack("{}q".format(gef.arch.endianness), x)[0] + return struct.unpack(f"{gef.arch.endianness:s}Q", x)[0] if not s else struct.unpack(f"{gef.arch.endianness:s}q", x)[0] def is_ascii_string(address): @@ -5002,8 +5002,7 @@ def do_invoke(self, argv): return canary, location = res - info("Found AT_RANDOM at {:#x}, reading {} bytes".format(location, gef.arch.ptrsize)) - info("The canary of process {} is {:#x}".format(gef.session.pid, canary)) + info("The canary of process {} is at {:#x}, value is {:#x}".format(gef.session.pid, location, canary)) return @@ -10340,9 +10339,8 @@ def get_syscall_table(self, modname): return getattr(_mod, "syscall_table") def get_settings_path(self): - path = os.path.expanduser(self["path"]) - path = os.path.realpath(path) - return path if os.path.isdir(path) else None + path = pathlib.Path(os.path.expanduser(self["path"])) + return path if path.exists() and path.is_dir() else None @@ -11408,10 +11406,10 @@ def canary(self): if not auxval: return None canary_location = auxval["AT_RANDOM"] - canary = u64(canary_location) + canary = gef.memory.read_integer(canary_location) canary &= ~0xFF self.__canary = (canary, canary_location) - return self.__canary, canary_location + return self.__canary class Gef: """The GEF root class""" From 87e62040ebf68f82b8bfc3747daac336f893a0a8 Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 20:08:19 -0800 Subject: [PATCH 10/62] Fixed `elf-info` --- gef.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gef.py b/gef.py index 32730d3f3..fba5591da 100644 --- a/gef.py +++ b/gef.py @@ -6024,11 +6024,11 @@ def do_invoke(self, argv): endian = get_endian() if argc >= 2: - if argv[1].lower() == "big": endian = Elf.BIG_ENDIAN - elif argv[1].lower() == "little": endian = Elf.LITTLE_ENDIAN + if argv[1].lower() == "big": endian = Endianness.BIG_ENDIAN + elif argv[1].lower() == "little": endian = Endianness.LITTLE_ENDIAN if is_hex(pattern): - if endian == Elf.BIG_ENDIAN: + if endian == Endianness.BIG_ENDIAN: pattern = "".join(["\\x" + pattern[i:i + 2] for i in range(2, len(pattern), 2)]) else: pattern = "".join(["\\x" + pattern[i:i + 2] for i in range(len(pattern) - 2, 0, -2)]) @@ -7854,8 +7854,8 @@ def do_invoke(self, argv, *args, **kwargs): } endianness = { - Elf.LITTLE_ENDIAN : "Little-Endian", - Elf.BIG_ENDIAN : "Big-Endian", + Endianness.LITTLE_ENDIAN : "Little-Endian", + Endianness.BIG_ENDIAN : "Big-Endian", } osabi = { @@ -7902,7 +7902,7 @@ def do_invoke(self, argv, *args, **kwargs): data = [ ("Magic", "{0!s}".format(hexdump(struct.pack(">I", elf.e_magic), show_raw=True))), ("Class", "{0:#x} - {1}".format(elf.e_class, classes[elf.e_class])), - ("Endianness", "{0:#x} - {1}".format(elf.e_endianness, endianness[elf.e_endianness])), + ("Endianness", "{0:#x} - {1}".format(elf.e_endianness, Endianness(elf.e_endianness).name)), ("Version", "{:#x}".format(elf.e_eiversion)), ("OS ABI", "{0:#x} - {1}".format(elf.e_osabi, osabi[elf.e_osabi])), ("ABI Version", "{:#x}".format(elf.e_abiversion)), @@ -10640,7 +10640,7 @@ def is_loaded(x): if initial: gef_print("{:s} for {:s} ready, type `{:s}' to start, `{:s}' to configure" - .format(Color.greenify("GEF"), get_os(), + .format(Color.greenify("GEF"), gef.session.os, Color.colorify("gef", "underline yellow"), Color.colorify("gef config", "underline pink"))) From 52b06460794160fab11fda9b2907f18c936028e6 Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 20:12:01 -0800 Subject: [PATCH 11/62] Fixed `patch qword` --- gef.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gef.py b/gef.py index fba5591da..74ee0d8cd 100644 --- a/gef.py +++ b/gef.py @@ -1247,7 +1247,6 @@ def heap_addr(self, allow_unaligned=False): if self.is_main_arena(): heap_section = gef.heap.base_address if not heap_section: - err("Heap not initialized") return None return heap_section _addr = int(self) + self.struct_size @@ -9141,7 +9140,7 @@ def do_invoke(self, argv, *args, **kwargs): addr = align_address(parse_address(args.location)) size, fcode = self.SUPPORTED_SIZES[self.format] - d = gef.arch.endianness + d = str(gef.arch.endianness) for value in args.values: value = parse_address(value) & ((1 << size * 8) - 1) vstr = struct.pack(d + fcode, value) From d1aee8381a476df80f11d0e521266c5825dd21d8 Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 23:22:02 -0800 Subject: [PATCH 12/62] CI passing w00t --- gef.py | 61 +++++++++++++++++++++++++---------------------- tests/runtests.py | 13 +++++----- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/gef.py b/gef.py index 74ee0d8cd..bc8def245 100644 --- a/gef.py +++ b/gef.py @@ -566,6 +566,9 @@ def __str__(self): return Color.colorify(value, stack_color) return value + def __int__(self): + return self.value + def is_in_text_segment(self): return (hasattr(self.info, "name") and ".text" in self.info.name) or \ (hasattr(self.section, "path") and get_filepath() == self.section.path and self.section.is_executable()) @@ -1215,12 +1218,15 @@ def __int__(self): def __iter__(self): yield self + current_arena = self while True: - next_arena_address = int(self.next) + next_arena_address = int(current_arena.next) if next_arena_address == int(gef.heap.main_arena): break - yield GlibcArena("*{:#x} ".format(next_arena_address)) + + current_arena = GlibcArena("*{:#x} ".format(next_arena_address)) + yield current_arena return def __eq__(self, other): @@ -3944,9 +3950,13 @@ def gef_read_canary(): def get_pid(): return gef.session.pid -@deprecated("Use `gef.session.file`") +@deprecated("Use `gef.session.file.name`") def get_filename(): - return gef.session.file + return gef.session.file.name + +@deprecated("Use `gef.heap.main_arena`") +def get_glibc_arena(): + return gef.heap.main_arena # # GDB event hooking @@ -4658,10 +4668,10 @@ def __init__(self): def format_matrix(self): # `gef.arch.endianness` is a runtime property, should not be defined as a class property return { - 8: (gef.arch.endianness + "B", "char", "db"), - 16: (gef.arch.endianness + "H", "short", "dw"), - 32: (gef.arch.endianness + "I", "int", "dd"), - 64: (gef.arch.endianness + "Q", "long long", "dq"), + 8: (f"{gef.arch.endianness:s}B", "char", "db"), + 16: (f"{gef.arch.endianness:s}H", "short", "dw"), + 32: (f"{gef.arch.endianness:s}I", "int", "dd"), + 64: (f"{gef.arch.endianness:s}Q", "long long", "dq"), } @only_if_gdb_running @@ -4980,8 +4990,7 @@ def distance(self, args): @register_command class CanaryCommand(GenericCommand): - """Shows the canary value of the current process. Apply the techique detailed in - https://www.elttam.com.au/blog/playing-with-canaries/ to show the canary.""" + """Shows the canary value of the current process.""" _cmdline_ = "canary" _syntax_ = _cmdline_ @@ -6020,7 +6029,7 @@ def do_invoke(self, argv): return pattern = argv[0] - endian = get_endian() + endian = gef.arch.endianness if argc >= 2: if argv[1].lower() == "big": endian = Endianness.BIG_ENDIAN @@ -6233,7 +6242,7 @@ def run_unicorn(self, start_insn_addr, end_insn_addr, *args, **kwargs): arch, mode = get_unicorn_arch(to_string=True) unicorn_registers = get_unicorn_registers(to_string=True) cs_arch, cs_mode = get_capstone_arch(to_string=True) - fname = get_filename() + fname = gef.session.file.name to_file = kwargs.get("to_file", None) emulate_segmentation_block = "" context_segmentation_block = "" @@ -6843,19 +6852,15 @@ def do_invoke(self, argv): return if is_hex(argv[0]): - new_arena_address = argv[0] + new_arena_address = int(argv[0], 16) else: new_arena_symbol = safe_parse_and_eval(argv[0]) if not new_arena_symbol: err("Invalid symbol for arena") return + new_arena_address = to_unsigned_long(new_arena_symbol) - new_arena_address = Address(value=to_unsigned_long(new_arena_symbol)) - if not new_arena_address or not new_arena_address.valid: - err("Invalid address") - return - - new_arena = GlibcArena(f"*{new_arena_address:#x}") + new_arena = GlibcArena( "*0x{:x}".format(new_arena_address)) if new_arena not in gef.heap.arenas: err("Invalid arena") return @@ -6940,8 +6945,6 @@ def __init__(self): @only_if_gdb_running def do_invoke(self, *args, **kwargs): args = kwargs["arguments"] - - # arenas = get_glibc_arenas(addr=args.arena_address, get_all=args.all) arenas = gef.heap.arenas for arena in arenas: self.dump_chunks_arena(arena, print_arena=args.all, allow_unaligned=args.allow_unaligned) @@ -7221,7 +7224,7 @@ def fastbin_index(sz): MAX_FAST_SIZE = 80 * SIZE_SZ // 4 NFASTBINS = fastbin_index(MAX_FAST_SIZE) - 1 - arena = GlibcArena("*{:s}".format(argv[0])) if len(argv) == 1 else get_glibc_arena() + arena = GlibcArena("*{:s}".format(argv[0])) if len(argv) == 1 else gef.heap.main_arena if arena is None: err("Invalid Glibc arena") @@ -7278,7 +7281,7 @@ def do_invoke(self, argv): err("Invalid Glibc arena") return - arena_addr = "*{:s}".format(argv[0]) if len(argv) == 1 else __gef_current_arena__ + arena_addr = "*{:s}".format(argv[0]) if len(argv) == 1 else gef.heap.selected_arena gef_print(titlify("Unsorted Bin for arena '{:s}'".format(arena_addr))) nb_chunk = GlibcHeapBinsCommand.pprint_bin(arena_addr, 0, "unsorted_") if nb_chunk >= 0: @@ -7327,11 +7330,11 @@ def __init__(self): @only_if_gdb_running def do_invoke(self, argv): - if get_glibc_arena() is None: + if gef.heap.main_arena is None: err("Invalid Glibc arena") return - arena_addr = "*{:s}".format(argv[0]) if len(argv) == 1 else __gef_current_arena__ + arena_addr = "*{:s}".format(argv[0]) if len(argv) == 1 else gef.heap.selected_arena gef_print(titlify("Large Bins for arena '{:s}'".format(arena_addr))) bins = {} for i in range(63, 126): @@ -7406,7 +7409,7 @@ def do_invoke(self, argv, *args, **kwargs): err("invalid registers for architecture: {}".format(", ".join(invalid_regs))) memsize = gef.arch.ptrsize - endian = gef.arch.endianness + endian = str(gef.arch.endianness) charset = string.printable widest = max(map(len, gef.arch.all_registers)) special_line = "" @@ -9030,7 +9033,7 @@ def _hexdump(self, start_addr, length, arrange_as, offset=0): r, l = formats[arrange_as] fmt_str = "{{base}}{v}+{{offset:#06x}} {{sym}}{{val:#0{prec}x}} {{text}}".format(v=VERTICAL_LINE, prec=l*2+2) - fmt_pack = endianness + r + fmt_pack = f"{endianness:s}{r}" lines = [] i = 0 @@ -9197,7 +9200,7 @@ class PatchByteCommand(PatchCommand): _cmdline_ = "patch byte" _syntax_ = "{0:s} LOCATION BYTE1 [BYTE2 [BYTE3..]]".format(_cmdline_) - _example_ = "{:s} $rip 0x41 0x41 0x41 0x41 0x41".format(_cmdline_) + _example_ = "{:s} $pc 0x41 0x41 0x41 0x41 0x41".format(_cmdline_) def __init__(self): super().__init__() @@ -10415,7 +10418,7 @@ def do_invoke(self, args): try: name = args[0].string() except IndexError: - name = get_filename() + name = gef.session.file.name except gdb.error: err("Invalid arg: {}".format(args[0])) return 0 diff --git a/tests/runtests.py b/tests/runtests.py index 31f0a02ac..4e415e0e5 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -70,8 +70,7 @@ def test_cmd_canary(self): self.assertFailIfInactiveSession(gdb_run_cmd("canary")) res = gdb_start_silent_cmd("canary", target=_target("canary")) self.assertNoException(res) - self.assertIn("Found AT_RANDOM at", res) - self.assertIn("The canary of process ", res) + self.assertIn("The canary of process", res) return def test_cmd_capstone_disassemble(self): @@ -260,7 +259,7 @@ def test_cmd_heap_chunks(self): self.assertIn("Chunk(addr=", res) self.assertIn("top chunk", res) - cmd = "python gdb.execute('heap chunks {}'.format(get_glibc_arena().next))" + cmd = "python gdb.execute('heap chunks 0x{:x}'.format(int(list(gef.heap.arenas)[1])))" target = _target("heap-non-main") res = gdb_run_silent_cmd(cmd, target=target) self.assertNoException(res) @@ -270,7 +269,7 @@ def test_cmd_heap_chunks(self): return def test_cmd_heap_chunks_mult_heaps(self): - before = ['run', 'python gdb.execute("heap set-arena {}".format(get_glibc_arena().next))'] + before = ['run', 'python gdb.execute("heap set-arena 0x{:x}".format(int(list(gef.heap.arenas)[1])))'] cmd = "heap chunks" target = _target("heap-multiple-heaps") res = gdb_run_silent_cmd(cmd, before=before, target=target) @@ -292,7 +291,7 @@ def test_cmd_heap_bins_fast(self): return def test_cmd_heap_bins_non_main(self): - cmd = "python gdb.execute('heap bins fast {}'.format(get_glibc_arena().next))" + cmd = "python gdb.execute('heap bins fast {}'.format(gef.heap.main_arena))" before = ["set environment GLIBC_TUNABLES glibc.malloc.tcache_count=0"] target = _target("heap-non-main") res = gdb_run_silent_cmd(cmd, before=before, target=target) @@ -874,8 +873,8 @@ def test_func_get_pid(self): self.assertTrue(int(res.splitlines()[-1])) return - def test_fun_gef_get_auxiliary_values(self): - func = "gef.session.auxiliary_values" + def test_func_auxiliary_vector(self): + func = "gef.session.auxiliary_vector" res = gdb_test_python_method(func, target=BIN_LS) self.assertNoException(res) # we need at least ("AT_PLATFORM", "AT_EXECFN") right now From 1f62d53b716be00dc002aa39816d947df1019fea Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 23:25:33 -0800 Subject: [PATCH 13/62] test everything --- .github/workflows/run-tests.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 3161f81dc..d31d3baa8 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -1,15 +1,6 @@ name: CI Test for GEF -on: - push: - branches: - - master - - dev - - pull_request: - branches: - - master - - dev +on: [push, pull_request] jobs: build: From 7698f300a0fc3436ff9d36edb43172202ebb7100 Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 13 Dec 2021 23:43:37 -0800 Subject: [PATCH 14/62] making linters happy --- gef.py | 29 ++++++++++++----------------- tests/runtests.py | 3 ++- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/gef.py b/gef.py index bc8def245..cf6c38736 100644 --- a/gef.py +++ b/gef.py @@ -532,7 +532,7 @@ def blinkify(msg): return Color.colorify(msg, "blink") @staticmethod def colorify(text, attrs): """Color text according to the given attributes.""" - if gef.config["gef.disable_color"] == True: return text + if gef.config["gef.disable_color"] is True: return text colors = Color.colors msg = [colors[attr] for attr in attrs.split() if attr in colors] @@ -1684,7 +1684,7 @@ def hexdump(source, length=0x10, separator=".", show_raw=False, show_symbol=True def is_debug(): """Check if debug mode is enabled.""" - return gef.config["gef.debug"] == True + return gef.config["gef.debug"] is True context_hidden = False @@ -2121,12 +2121,12 @@ class GenericArchitecture(Architecture): nop_insn = b"" flag_register = None flags_table = None - def flag_register_to_human(self, val=None): raise NotImplemented - def is_call(self, insn): raise NotImplemented - def is_ret(self, insn): raise NotImplemented - def is_conditional_branch(self, insn): raise NotImplemented - def is_branch_taken(self, insn): raise NotImplemented - def get_ra(self, insn, frame): raise NotImplemented + def flag_register_to_human(self, val=None): return "" + def is_call(self, insn): return False + def is_ret(self, insn): return False + def is_conditional_branch(self, insn): return False + def is_branch_taken(self, insn): return False + def get_ra(self, insn, frame): return 0 class RISCV(Architecture): @@ -3388,7 +3388,7 @@ def exit_handler(event): reset_all_caches() __gef_qemu_mode__ = False - if __gef_remote__ and gef.config["gef-remote.clean_on_exit"] == True: + if __gef_remote__ and gef.config["gef-remote.clean_on_exit"] is True: shutil.rmtree("/tmp/gef/{:d}".format(__gef_remote__)) __gef_remote__ = None return @@ -7306,10 +7306,10 @@ def do_invoke(self, argv): return arena = GlibcArena(f"*{argv[0]:s}") if len(argv) == 1 else gef.heap.selected_arena - gef_print(titlify("Small Bins for arena '{:s}'".format(arena_addr))) + gef_print(titlify("Small Bins for arena '{:s}'".format(arena))) bins = {} for i in range(1, 63): - nb_chunk = GlibcHeapBinsCommand.pprint_bin(arena_addr, i, "small_") + nb_chunk = GlibcHeapBinsCommand.pprint_bin(arena, i, "small_") if nb_chunk < 0: break if nb_chunk > 0: @@ -7855,11 +7855,6 @@ def do_invoke(self, argv, *args, **kwargs): Elf.ELF_64_BITS : "64-bit", } - endianness = { - Endianness.LITTLE_ENDIAN : "Little-Endian", - Endianness.BIG_ENDIAN : "Big-Endian", - } - osabi = { Elf.OSABI_SYSTEMV : "System V", Elf.OSABI_HPUX : "HP-UX", @@ -11257,7 +11252,7 @@ def main_arena(self): def selected_arena(self): if not self.__libc_selected_arena: # `selected_arena` must default to `main_arena` - self.__libc_selected_arena = self.__libc_default_arena + self.__libc_selected_arena = self.__libc_main_arena return self.__libc_selected_arena @selected_arena.setter diff --git a/tests/runtests.py b/tests/runtests.py index 4e415e0e5..1ffd365cd 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -269,7 +269,8 @@ def test_cmd_heap_chunks(self): return def test_cmd_heap_chunks_mult_heaps(self): - before = ['run', 'python gdb.execute("heap set-arena 0x{:x}".format(int(list(gef.heap.arenas)[1])))'] + py_cmd = 'gdb.execute("heap set-arena 0x{:x}".format(int(list(gef.heap.arenas)[1])))' + before = ['run', 'python ' + py_cmd] cmd = "heap chunks" target = _target("heap-multiple-heaps") res = gdb_run_silent_cmd(cmd, before=before, target=target) From b9493f2c19a4bed68d4097d5772b7289bb43fbf3 Mon Sep 17 00:00:00 2001 From: hugsy Date: Tue, 14 Dec 2021 11:13:01 -0800 Subject: [PATCH 15/62] fixed `GlibcArena.__eq__` --- docs/compat.md | 2 +- gef.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/compat.md b/docs/compat.md index a5545c967..577224044 100644 --- a/docs/compat.md +++ b/docs/compat.md @@ -6,7 +6,7 @@ This matrix indicates the version of Python and/or GDB |:--:|:--:|:--:| | [2018.02](https://github.com/hugsy/gef/releases/tag/2018.02) | 7.2 | Python 2.7, Python 3.4 | | [2020.03](https://github.com/hugsy/gef/releases/tag/2020.03) | 7.4 | Python 2.7, Python 3.4 | -| [2022.01](https://github.com/hugsy/gef/releases/tag/2022.01) | 7.7 | Python 3.4 | +| [2022.01](https://github.com/hugsy/gef/releases/tag/2021.01) | 7.7 | Python 3.4 | | [Current](https://github.com/hugsy/gef/tree/master) | 8.0+ | Python 3.6+ | diff --git a/gef.py b/gef.py index cf6c38736..1413d79a6 100644 --- a/gef.py +++ b/gef.py @@ -1231,7 +1231,7 @@ def __iter__(self): def __eq__(self, other): # You cannot have 2 arenas at the same address, so this check should be enough - return self.__addr == int(self) + return self.__addr == int(other) def fastbin(self, i): """Return head chunk in fastbinsY[i].""" From a98dcb90f4dd4591d874789ab7df502e52cb4205 Mon Sep 17 00:00:00 2001 From: hugsy Date: Wed, 15 Dec 2021 11:43:29 -0800 Subject: [PATCH 16/62] - `get_register` -> `gef.arch.register()` - new context manager for output redirection: `RedirectOutputContext` --- gef.py | 179 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 105 insertions(+), 74 deletions(-) diff --git a/gef.py b/gef.py index 1413d79a6..9ba9bcc91 100644 --- a/gef.py +++ b/gef.py @@ -1699,6 +1699,26 @@ def unhide_context(): context_hidden = False +class RedirectOutputContext(): + def __init__(self, to="/dev/null"): + self.redirection_target_file = to + return + + def __enter__(self): + """Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`.""" + gdb.execute("set logging overwrite") + gdb.execute("set logging file {:s}".format(self.redirection_target_file)) + gdb.execute("set logging redirect on") + gdb.execute("set logging on") + return + + def __exit__(self): + """Disable the output redirection, if any.""" + gdb.execute("set logging off") + gdb.execute("set logging redirect off") + return + +@deprecated("Use `RedirectOutputContext()` context manager") def enable_redirect_output(to_file="/dev/null"): """Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`.""" gdb.execute("set logging overwrite") @@ -1707,7 +1727,7 @@ def enable_redirect_output(to_file="/dev/null"): gdb.execute("set logging on") return - +@deprecated("Use `RedirectOutputContext()` context manager") def disable_redirect_output(): """Disable the output redirection, if any.""" gdb.execute("set logging off") @@ -2065,17 +2085,47 @@ def get_ra(self, insn, frame): pass special_registers = [] + def __get_register(self, regname): + """Return a register's value.""" + curframe = gdb.selected_frame() + key = curframe.pc() ^ int(curframe.read_register('sp')) # todo: check when/if gdb.Frame implements `level()` + return self.__get_register_for_selected_frame(regname, key) + + @lru_cache() + def __get_register_for_selected_frame(self, regname, hash_key): + # 1st chance + try: + return parse_address(regname) + except gdb.error: + pass + + # 2nd chance + try: + regname = regname.lstrip("$") + value = gdb.selected_frame().read_register(regname) + return int(value) + except (ValueError, gdb.error): + pass + return None + + def register(self, name): + return self.__get_register(name) + + @property + def registers(self): + yield from self.all_registers + @property def pc(self): - return get_register("$pc") + return self.register("$pc") @property def sp(self): - return get_register("$sp") + return self.register("$sp") @property def fp(self): - return get_register("$fp") + return self.register("$fp") __ptrsize = None @property @@ -2104,7 +2154,7 @@ def endianness(self) -> Endianness: def get_ith_parameter(self, i, in_func=True): """Retrieves the correct parameter used for the current function call.""" reg = self.function_parameters[i] - val = get_register(reg) + val = self.register(reg) key = reg return key, val @@ -2191,13 +2241,13 @@ def long_to_twos_complement(v): if condition.endswith("z"): # r2 is the zero register if we are comparing to 0 - rs1 = get_register(insn.operands[0]) - rs2 = get_register("$zero") + rs1 = gef.arch.register(insn.operands[0]) + rs2 = gef.arch.register("$zero") condition = condition[:-1] elif len(insn.operands) > 2: # r2 is populated with the second operand - rs1 = get_register(insn.operands[0]) - rs2 = get_register(insn.operands[1]) + rs1 = gef.arch.register(insn.operands[0]) + rs2 = gef.arch.register(insn.operands[1]) else: raise OSError("RISC-V: Failed to get rs1 and rs2 for instruction: `{}`".format(insn)) @@ -2229,7 +2279,7 @@ def long_to_twos_complement(v): def get_ra(self, insn, frame): ra = None if self.is_ret(insn): - ra = get_register("$ra") + ra = gef.arch.register("$ra") elif frame.older(): ra = frame.older().pc() return ra @@ -2261,11 +2311,11 @@ class ARM(Architecture): def is_thumb(self): """Determine if the machine is currently in THUMB mode.""" - return is_alive() and get_register(self.flag_register) & (1 << 5) + return is_alive() and gef.arch.register(self.flag_register) & (1 << 5) @property def pc(self): - pc = get_register("$pc") + pc = gef.arch.register("$pc") if self.is_thumb(): pc += 1 return pc @@ -2300,7 +2350,7 @@ def flag_register_to_human(self, val=None): # http://www.botskool.com/user-pages/tutorials/electronics/arm-7-tutorial-part-1 if val is None: reg = self.flag_register - val = get_register(reg) + val = gef.arch.register(reg) return flags_to_human(val, self.flags_table) def is_conditional_branch(self, insn): @@ -2311,7 +2361,7 @@ def is_branch_taken(self, insn): mnemo = insn.mnemonic # ref: http://www.davespace.co.uk/arm/introduction-to-arm/conditional.html flags = dict((self.flags_table[k], k) for k in self.flags_table) - val = get_register(self.flag_register) + val = gef.arch.register(self.flag_register) taken, reason = False, "" if mnemo.endswith("eq"): taken, reason = bool(val&(1< 0, "{0[0]} > 0".format(ops) + taken, reason = gef.arch.register(ops[0]) > 0, "{0[0]} > 0".format(ops) elif mnemo == "bgez": - taken, reason = get_register(ops[0]) >= 0, "{0[0]} >= 0".format(ops) + taken, reason = gef.arch.register(ops[0]) >= 0, "{0[0]} >= 0".format(ops) elif mnemo == "bltz": - taken, reason = get_register(ops[0]) < 0, "{0[0]} < 0".format(ops) + taken, reason = gef.arch.register(ops[0]) < 0, "{0[0]} < 0".format(ops) elif mnemo == "blez": - taken, reason = get_register(ops[0]) <= 0, "{0[0]} <= 0".format(ops) + taken, reason = gef.arch.register(ops[0]) <= 0, "{0[0]} <= 0".format(ops) return taken, reason def get_ra(self, insn, frame): ra = None if self.is_ret(insn): - ra = get_register("$ra") + ra = gef.arch.register("$ra") elif frame.older(): ra = frame.older().pc() return ra @@ -3023,31 +3073,6 @@ def to_unsigned_long(v): return int(v.cast(gdb.Value(mask).type)) & mask -def get_register(regname): - """Return a register's value.""" - curframe = gdb.selected_frame() - key = curframe.pc() ^ int(curframe.read_register('sp')) # todo: check when/if gdb.Frame implements `level()` - return __get_register_for_selected_frame(regname, key) - - -@lru_cache() -def __get_register_for_selected_frame(regname, hash_key): - # 1st chance - try: - return parse_address(regname) - except gdb.error: - pass - - # 2nd chance - try: - regname = regname.lstrip("$") - value = gdb.selected_frame().read_register(regname) - return int(value) - except (ValueError, gdb.error): - pass - return None - - def get_path_from_info_proc(): for x in gdb.execute("info proc", to_string=True).splitlines(): if x.startswith("exe = "): @@ -3958,6 +3983,10 @@ def get_filename(): def get_glibc_arena(): return gef.heap.main_arena +@deprecated("Use `gef.arch.register(regname)`") +def get_register(regname): + return gef.arch.register(regname) + # # GDB event hooking # @@ -6092,7 +6121,7 @@ def do_invoke(self, argv): for off in gef.arch.flags_table: if gef.arch.flags_table[off] == name: - old_flag = get_register(gef.arch.flag_register) + old_flag = gef.arch.register(gef.arch.flag_register) if action == "+": new_flags = old_flag | (1 << off) elif action == "-": @@ -6354,7 +6383,7 @@ def reset(): info("Duplicating registers") for r in gef.arch.all_registers: - gregval = get_register(r) + gregval = gef.arch.register(r) content += " emu.reg_write({}, {:#x})\n".format(unicorn_registers[r], gregval) vmmap = get_process_maps() @@ -7437,7 +7466,7 @@ def do_invoke(self, argv, *args, **kwargs): # Special (e.g. segment) registers go on their own line if regname in gef.arch.special_registers: special_line += "{}: ".format(Color.colorify(regname, color)) - special_line += "0x{:04x} ".format(get_register(regname)) + special_line += "0x{:04x} ".format(gef.arch.register(regname)) continue line = "{}: ".format(Color.colorify(padreg, color)) @@ -8313,7 +8342,7 @@ def context_regs(self): except (gdb.MemoryError, gdb.error): # If this exception is triggered, it means that the current register # is corrupted. Just use the register "raw" value (not eval-ed) - new_value = get_register(reg) + new_value = gef.arch.register(reg) new_value_type_flag = False except Exception: @@ -8459,7 +8488,7 @@ def context_args(self): if insn.operands[-1].startswith(self.size2type[gef.arch.ptrsize]+" PTR"): target = "*" + insn.operands[-1].split()[-1] elif "$"+insn.operands[0] in gef.arch.all_registers: - target = "*{:#x}".format(get_register("$"+insn.operands[0])) + target = "*{:#x}".format(gef.arch.register("$"+insn.operands[0])) else: # is there a symbol? ops = " ".join(insn.operands) @@ -8842,7 +8871,7 @@ def context_memory(self): def update_registers(cls, event): for reg in gef.arch.all_registers: try: - cls.old_registers[reg] = get_register(reg) + cls.old_registers[reg] = gef.arch.register(reg) except Exception: cls.old_registers[reg] = 0 return @@ -9328,7 +9357,7 @@ def pprint_dereferenced(addr, idx, base_offset=0): register_hints = [] for regname in gef.arch.all_registers: - regvalue = get_register(regname) + regvalue = gef.arch.register(regname) if current_address == regvalue: register_hints.append(regname) @@ -10135,13 +10164,15 @@ def do_invoke(self, argv): "vsnprintf": 2, } - enable_redirect_output("/dev/null") + nb_installed_breaks = 0 - for func_name, num_arg in dangerous_functions.items(): - FormatStringBreakpoint(func_name, num_arg) + with RedirectOutputContext("/dev/null") as ctx: + for function_name in dangerous_functions: + argument_number = dangerous_functions[function_name] + FormatStringBreakpoint(function_name, argument_number) + nb_installed_breaks += 1 - disable_redirect_output() - ok("Enabled {:d} FormatStringBreakpoint".format(len(dangerous_functions))) + ok("Enabled {} FormatString breakpoint{}".format(nb_installed_breaks, "s" if nb_installed_breaks > 1 else "")) return @@ -10289,7 +10320,7 @@ def do_invoke(self, argv): arch = gef.arch.__class__.__name__ syscall_table = self.get_syscall_table(arch) - reg_value = get_register(gef.arch.syscall_register) + reg_value = gef.arch.register(gef.arch.syscall_register) if reg_value not in syscall_table: warn("There is no system call for {:#x}".format(reg_value)) return @@ -10297,7 +10328,7 @@ def do_invoke(self, argv): values = [] for param in syscall_entry.params: - values.append(get_register(param.reg)) + values.append(gef.arch.register(param.reg)) parameters = [s.param for s in syscall_entry.params] registers = [s.reg for s in syscall_entry.params] From 321e10423c28dc62ba88ef5e405774f7603cb9fb Mon Sep 17 00:00:00 2001 From: hugsy Date: Wed, 15 Dec 2021 16:37:48 -0800 Subject: [PATCH 17/62] added `__str__` to `Section` --- gef.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/gef.py b/gef.py index 9ba9bcc91..66e0ad624 100644 --- a/gef.py +++ b/gef.py @@ -675,6 +675,9 @@ def realpath(self): # when in a `gef-remote` session, realpath returns the path to the binary on the local disk, not remote return self.path if __gef_remote__ is None else "/tmp/gef/{:d}/{:s}".format(__gef_remote__, self.path) + def __str__(self): + return f"Section({self.page_start:#x}, {self.page_end:#x}, {str(self.permission)})" + Zone = collections.namedtuple("Zone", ["name", "zone_start", "zone_end", "filename"]) @@ -2091,7 +2094,6 @@ def __get_register(self, regname): key = curframe.pc() ^ int(curframe.read_register('sp')) # todo: check when/if gdb.Frame implements `level()` return self.__get_register_for_selected_frame(regname, key) - @lru_cache() def __get_register_for_selected_frame(self, regname, hash_key): # 1st chance try: @@ -4122,7 +4124,7 @@ def stop(self): if not addr.valid: return False - if addr.section.permission.value & Permission.WRITE: + if addr.section.is_writable(): content = gef.memory.read_cstring(addr.value) name = addr.info.name if addr.info else addr.section.path msg.append(Color.colorify("Format string helper", "yellow bold")) @@ -10166,7 +10168,8 @@ def do_invoke(self, argv): nb_installed_breaks = 0 - with RedirectOutputContext("/dev/null") as ctx: + # with RedirectOutputContext("/dev/null") as ctx: + if True: for function_name in dangerous_functions: argument_number = dangerous_functions[function_name] FormatStringBreakpoint(function_name, argument_number) @@ -11416,7 +11419,9 @@ def pid(self): @property def file(self): """Return a Path object of the target process.""" - return pathlib.Path(gdb.current_progspace().filename) + if not self.__file: + self.__file = pathlib.Path(gdb.current_progspace().filename) + return self.__file @property def pagesize(self): @@ -11439,6 +11444,7 @@ def canary(self): self.__canary = (canary, canary_location) return self.__canary +@lru_cache() class Gef: """The GEF root class""" def __init__(self): @@ -11454,9 +11460,7 @@ def initialize_managers(self): return def setup(self): - """ - Setup initialize the runtime setup, which may require for the `gef` to be not None - """ + """Setup initialize the runtime setup, which may require for the `gef` to be not None.""" self.initialize_managers() self.gdb = GefCommand() self.gdb.setup() From a7ab48e6acec6f1a0ee2056f42033d26c3896e8e Mon Sep 17 00:00:00 2001 From: theguy147 <37738506+theguy147@users.noreply.github.com> Date: Thu, 16 Dec 2021 12:32:18 +0100 Subject: [PATCH 18/62] refactor: use Generators and Comprehension (#771) * refactor: use dict comprehension (PEP 274) * refactor: use generator expressions (PEP 289) * refactor: use yield from syntax (PEP 380) --- gef.py | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/gef.py b/gef.py index 1413d79a6..ce73f3b3f 100644 --- a/gef.py +++ b/gef.py @@ -2310,7 +2310,7 @@ def is_conditional_branch(self, insn): def is_branch_taken(self, insn): mnemo = insn.mnemonic # ref: http://www.davespace.co.uk/arm/introduction-to-arm/conditional.html - flags = dict((self.flags_table[k], k) for k in self.flags_table) + flags = {self.flags_table[k]: k for k in self.flags_table} val = get_register(self.flag_register) taken, reason = False, "" @@ -2527,7 +2527,7 @@ def is_conditional_branch(self, insn): def is_branch_taken(self, insn): mnemo = insn.mnemonic # all kudos to fG! (https://github.com/gdbinit/Gdbinit/blob/master/gdbinit#L1654) - flags = dict((self.flags_table[k], k) for k in self.flags_table) + flags = {self.flags_table[k]: k for k in self.flags_table} val = get_register(self.flag_register) taken, reason = False, "" @@ -2692,7 +2692,7 @@ def is_conditional_branch(self, insn): def is_branch_taken(self, insn): mnemo = insn.mnemonic - flags = dict((self.flags_table[k], k) for k in self.flags_table) + flags = {self.flags_table[k]: k for k in self.flags_table} val = get_register(self.flag_register) taken, reason = False, "" if mnemo == "beq": taken, reason = val&(1<")] + addr_start, addr_end = (int(x, 16) for x in parts[1].split("->")) off = int(parts[3][:-1], 16) path = parts[4] inode = "" @@ -3346,7 +3346,7 @@ def xor(data, key): """Return `data` xor-ed with `key`.""" key = key.lstrip("0x") key = binascii.unhexlify(key) - return bytearray([x ^ y for x, y in zip(data, itertools.cycle(key))]) + return bytearray(x ^ y for x, y in zip(data, itertools.cycle(key))) def is_hex(pattern): @@ -3855,13 +3855,11 @@ def db(t, p): yield alphabet[a[j]] else: a[t] = a[t - p] - for c in db(t + 1, p): - yield c + yield from db(t + 1, p) for j in range(a[t - p] + 1, k): a[t] = j - for c in db(t + 1, t): - yield c + yield from db(t + 1, t) return db(1, 1) @@ -4760,7 +4758,7 @@ def do_invoke(self, argv, *args, **kwargs): # When the process is already on, set real breakpoints immediately if is_alive(): vmmap = get_process_maps() - base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] + base_address = next(x.page_start for x in vmmap if x.path == get_filepath()) for bp_ins in __pie_breakpoints__.values(): bp_ins.instantiate(base_address) return @@ -4860,7 +4858,7 @@ def do_invoke(self, argv): unhide_context() gdb.execute("set stop-on-solib-events 0") vmmap = get_process_maps() - base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] + base_address = next(x.page_start for x in vmmap if x.path == get_filepath()) info("base address {}".format(hex(base_address))) # modify all breakpoints @@ -4891,7 +4889,7 @@ def do_invoke(self, argv): # after attach, we are stopped so that we can # get base address to modify our breakpoint vmmap = get_process_maps() - base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] + base_address = next(x.page_start for x in vmmap if x.path == get_filepath()) for bp_ins in __pie_breakpoints__.values(): bp_ins.instantiate(base_address) @@ -4915,7 +4913,7 @@ def do_invoke(self, argv): # after remote attach, we are stopped so that we can # get base address to modify our breakpoint vmmap = get_process_maps() - base_address = [x.page_start for x in vmmap if x.realpath == get_filepath()][0] + base_address = next(x.page_start for x in vmmap if x.realpath == get_filepath()) for bp_ins in __pie_breakpoints__.values(): bp_ins.instantiate(base_address) @@ -5730,8 +5728,8 @@ def parsed_arglist(arglist): main_base_address = main_end_address = 0 else: vmmap = get_process_maps() - main_base_address = min([x.page_start for x in vmmap if x.realpath == get_filepath()]) - main_end_address = max([x.page_end for x in vmmap if x.realpath == get_filepath()]) + main_base_address = min(x.page_start for x in vmmap if x.realpath == get_filepath()) + main_end_address = max(x.page_end for x in vmmap if x.realpath == get_filepath()) try: if method_name == "sync": @@ -5761,8 +5759,8 @@ def synchronize(self): """Submit all active breakpoint addresses to IDA/BN.""" pc = gef.arch.pc vmmap = get_process_maps() - base_address = min([x.page_start for x in vmmap if x.path == get_filepath()]) - end_address = max([x.page_end for x in vmmap if x.path == get_filepath()]) + base_address = min(x.page_start for x in vmmap if x.path == get_filepath()) + end_address = max(x.page_end for x in vmmap if x.path == get_filepath()) if not (base_address <= pc < end_address): # do not sync in library return @@ -8105,7 +8103,7 @@ def set_init_tbreak_pie(self, addr, argv): unhide_context() gdb.execute("set stop-on-solib-events 0") vmmap = get_process_maps() - base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] + base_address = next(x.page_start for x in vmmap if x.path == get_filepath()) return self.set_init_tbreak(base_address + addr) @@ -9980,8 +9978,8 @@ def do_invoke(self, argv): # getting vmmap to understand the boundaries of the main binary # we will use this info to understand if a function has been resolved or not. vmmap = get_process_maps() - base_address = min([x.page_start for x in vmmap if x.path == get_filepath()]) - end_address = max([x.page_end for x in vmmap if x.path == get_filepath()]) + base_address = min(x.page_start for x in vmmap if x.path == get_filepath()) + end_address = max(x.page_end for x in vmmap if x.path == get_filepath()) # get the checksec output. checksec_status = checksec(get_filepath()) From f497bc8bad3e54bb76cda99c96609eb023613842 Mon Sep 17 00:00:00 2001 From: theguy147 <37738506+theguy147@users.noreply.github.com> Date: Thu, 16 Dec 2021 12:33:11 +0100 Subject: [PATCH 19/62] refactor: replace OSError aliases (#769) --- gef.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gef.py b/gef.py index ce73f3b3f..3eb09d283 100644 --- a/gef.py +++ b/gef.py @@ -390,7 +390,7 @@ def inner_f(*args, **kwargs): f(*args, **kwargs) else: reason = "GDB >= {} for this command".format(required_gdb_version) - raise EnvironmentError(reason) + raise OSError(reason) return inner_f return wrapper @@ -406,7 +406,7 @@ def inner_f(*args, **kwargs): f(*args, **kwargs) else: reason = "This command cannot work for the '{}' architecture".format(gef.arch.arch) - raise EnvironmentError(reason) + raise OSError(reason) return inner_f return wrapper @@ -2098,7 +2098,7 @@ def endianness(self) -> Endianness: elif "big endian" in output: self.__endianness = Endianness.BIG_ENDIAN else: - raise EnvironmentError(f"No valid endianess found in '{output}'") + raise OSError(f"No valid endianess found in '{output}'") return self.__endianness def get_ith_parameter(self, i, in_func=True): @@ -3156,7 +3156,7 @@ def open_file(path, use_cache=False): if is_remote_debug() and not __gef_qemu_mode__: lpath = download_file(path, use_cache) if not lpath: - raise IOError("cannot open remote path {:s}".format(path)) + raise OSError("cannot open remote path {:s}".format(path)) path = lpath return open(path, "r") @@ -3744,7 +3744,7 @@ def get_memory_alignment(in_bits=False): except: pass - raise EnvironmentError("GEF is running under an unsupported mode") + raise OSError("GEF is running under an unsupported mode") def clear_screen(tty=""): @@ -5658,7 +5658,7 @@ def is_target_alive(self, host, port): s.settimeout(1) s.connect((host, port)) s.close() - except socket.error: + except OSError: return False return True @@ -5751,7 +5751,7 @@ def parsed_arglist(arglist): jump = getattr(self.sock, "jump") jump(hex(gef.arch.pc-main_base_address),) - except socket.error: + except OSError: self.disconnect() return @@ -9966,7 +9966,7 @@ def do_invoke(self, argv): try: readelf = gef.session.constants["readelf"] - except IOError: + except OSError: err("Missing `readelf`") return From a697afdbc0f340bba03230d8cfaf5b4ac2d93b18 Mon Sep 17 00:00:00 2001 From: hugsy Date: Wed, 5 Jan 2022 10:39:21 -0800 Subject: [PATCH 20/62] use avatars for contributors and sponsors in readme and docs/index --- README.md | 19 ++++++++++++------- docs/index.md | 10 ++-------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 53c177080..caebf55c3 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,8 @@ Unlike other GDB plugins, GEF has an extensive and up-to-date [documentation](ht ## Contribute ## +[ ![contributors-img](https://contrib.rocks/image?repo=hugsy/gef) ](https://github.com/hugsy/gef/graphs/contributors) + To get involved, refer to the [Contribution documentation](https://gef.readthedocs.io/en/master/#contribution) and the [guidelines](https://github.com/hugsy/gef/blob/dev/.github/CONTRIBUTING.md) to start. @@ -90,14 +92,17 @@ To get involved, refer to the [Contribution documentation](https://gef.readthedo 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: - - [@nkaretnikov](https://github.com/nkaretnikov) - - [@R3zk0n](https://github.com/r3zk0n) - - [@merces](https://github.com/merces) - - [@nbars](https://github.com/nbars) - - [@maycon](https://github.com/maycon) - - [@jespinhara](https://github.com/jespinhara) +[](https://github.com/nkaretnikov) +[](https://github.com/r3zk0n) +[](https://github.com/merces) +[](https://github.com/nbars) +[](https://github.com/maycon) +[](https://github.com/jespinhara) +[](https://github.com/therealdreg) +[](https://github.com/mikesart) + Want to be part of this list of amazing people? [Jump here!](https://github.com/sponsors/hugsy) -### Happy Hacking ### +## Happy Hacking ## diff --git a/docs/index.md b/docs/index.md index d7d290e01..367b9504d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -175,16 +175,10 @@ _Side Note_: `GEF` fully relies on the GDB API and other Linux-specific sources `gef` was created and maintained by myself, [`@_hugsy_`](https://twitter.com/_hugsy_), but kept fresh thanks to [all the contributors](https://github.com/hugsy/gef/graphs/contributors). -Or if you just like the tool, feel free to drop a simple *"thanks"* on Discord, Twitter or other, it is **always** very appreciated. - +[ ![contributors-img](https://contrib.rocks/image?repo=hugsy/gef) ](https://github.com/hugsy/gef/graphs/contributors) -### 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: - - - [@nkaretnikov](https://github.com/nkaretnikov) - - [@R3zk0n](https://github.com/r3zk0n) - - [@merces](https://github.com/merces) +Or if you just like the tool, feel free to drop a simple *"thanks"* on Discord, Twitter or other, it is **always** very appreciated. ### Extra Credits ### From 8a27a38e502eeef594df736bbc4f52f8b5ef618e Mon Sep 17 00:00:00 2001 From: theguy147 <37738506+theguy147@users.noreply.github.com> Date: Fri, 7 Jan 2022 18:43:29 +0100 Subject: [PATCH 21/62] refactor: remove utf8 encoding declaration (#770) --- gef.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/gef.py b/gef.py index 3eb09d283..0009ef980 100644 --- a/gef.py +++ b/gef.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -# -# ####################################################################################### # GEF - Multi-Architecture GDB Enhanced Features for Exploiters & Reverse-Engineers # From 4f6ab0c9a6b35ea6c09d641793f7c2eecef98465 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 12:10:20 -0800 Subject: [PATCH 22/62] Added `gef.memory.maps` --- gef.py | 298 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 166 insertions(+), 132 deletions(-) diff --git a/gef.py b/gef.py index 66e0ad624..93cf556d0 100644 --- a/gef.py +++ b/gef.py @@ -59,6 +59,7 @@ import collections import ctypes import enum +from fcntl import F_DUPFD_CLOEXEC import functools import hashlib import importlib @@ -176,14 +177,18 @@ def update_gef(argv): highlight_table = {} ANSI_SPLIT_RE = r"(\033\[[\d;]*m)" +# idea: lru_cache wrapper that register back callback items for cache clearing def reset_all_caches(): """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.""" + for mod in dir(sys.modules["__main__"]): obj = getattr(sys.modules["__main__"], mod) if hasattr(obj, "cache_clear"): obj.cache_clear() + + gef.reset_caches() return @@ -1496,7 +1501,7 @@ def psprint(self): @lru_cache() def get_libc_version(): - sections = get_process_maps() + sections = gef.memory.maps for section in sections: match = re.search(r"libc6?[-_](\d+)\.(\d+)\.so", section.path) if match: @@ -1685,22 +1690,19 @@ def hexdump(source, length=0x10, separator=".", show_raw=False, show_symbol=True return "\n".join(result) -def is_debug(): +def is_debug() -> bool: """Check if debug mode is enabled.""" - return gef.config["gef.debug"] is True - -context_hidden = False - - -def hide_context(): - global context_hidden - context_hidden = True + return gef.config["gef.debug"] == True +def hide_context() -> bool: + """ Helper function to hide the context pane """ + gef.session.context_hidden = True + return True -def unhide_context(): - global context_hidden - context_hidden = False - +def unhide_context() -> bool: + """ Helper function to unhide the context pane """ + gef.session.context_hidden = False + return True class RedirectOutputContext(): def __init__(self, to="/dev/null"): @@ -3177,18 +3179,6 @@ def download_file(target, use_cache=False, local_name=None): return local_name -def open_file(path, use_cache=False): - """Attempt to open the given file, if remote debugging is active, download - it first to the mirror in /tmp/.""" - if is_remote_debug() and not __gef_qemu_mode__: - lpath = download_file(path, use_cache) - if not lpath: - raise IOError("cannot open remote path {:s}".format(path)) - path = lpath - - return open(path, "r") - - def get_function_length(sym): """Attempt to get the length of the raw bytes of a function.""" dis = gdb.execute("disassemble {:s}".format(sym), to_string=True).splitlines() @@ -3197,79 +3187,6 @@ def get_function_length(sym): return end_addr - start_addr -def get_process_maps_linux(proc_map_file): - """Parse the Linux process `/proc/pid/maps` file.""" - with open_file(proc_map_file, use_cache=False) as f: - file = f.readlines() - for line in file: - line = line.strip() - addr, perm, off, _, rest = line.split(" ", 4) - rest = rest.split(" ", 1) - if len(rest) == 1: - inode = rest[0] - pathname = "" - else: - inode = rest[0] - pathname = rest[1].lstrip() - - addr_start, addr_end = [int(x, 16) for x in addr.split("-")] - off = int(off, 16) - perm = Permission.from_process_maps(perm) - - yield Section(page_start=addr_start, - page_end=addr_end, - offset=off, - permission=perm, - inode=inode, - path=pathname) - return - - -@lru_cache() -def get_process_maps(): - """Return the mapped memory sections""" - - try: - pid = gef.session.pid - fpath = "/proc/{:d}/maps".format(pid) - return list(get_process_maps_linux(fpath)) - except FileNotFoundError as e: - warn("Failed to read /proc//maps, using GDB sections info: {}".format(e)) - return list(get_info_sections()) - - -@lru_cache() -def get_info_sections(): - """Retrieve the debuggee sections.""" - stream = StringIO(gdb.execute("maintenance info sections", to_string=True)) - - for line in stream: - if not line: - break - - try: - parts = [x for x in line.split()] - addr_start, addr_end = [int(x, 16) for x in parts[1].split("->")] - off = int(parts[3][:-1], 16) - path = parts[4] - inode = "" - perm = Permission.from_info_sections(parts[5:]) - - yield Section(page_start=addr_start, - page_end=addr_end, - offset=off, - permission=perm, - inode=inode, - path=path) - - except IndexError: - continue - except ValueError: - continue - - return - - @lru_cache() def get_info_files(): """Retrieve all the files loaded by debuggee.""" @@ -3315,7 +3232,7 @@ def process_lookup_address(address): if is_in_x86_kernel(address): return None - for sect in get_process_maps(): + for sect in gef.memory.maps: if sect.page_start <= address < sect.page_end: return sect @@ -3330,7 +3247,7 @@ def process_lookup_path(name, perm=Permission.ALL): err("Process is not running") return None - for sect in get_process_maps(): + for sect in gef.memory.maps: if name in sect.path and sect.permission.value & perm: return sect @@ -3403,7 +3320,7 @@ def hook_stop_handler(event): def new_objfile_handler(event): """GDB event handler for new object file cases.""" reset_all_caches() - gef.initialize_managers() + gef.reinitialize_managers() set_arch() load_libc_args() return @@ -3424,11 +3341,13 @@ def exit_handler(event): def memchanged_handler(event): """GDB event handler for mem changes cases.""" reset_all_caches() + return def regchanged_handler(event): """GDB event handler for reg changes cases.""" reset_all_caches() + return def load_libc_args(): @@ -3461,10 +3380,10 @@ def load_libc_args(): with open(_libc_args_file) as _libc_args: libc_args_definitions[_arch_mode] = json.load(_libc_args) except FileNotFoundError: - del(libc_args_definitions[_arch_mode]) + del libc_args_definitions[_arch_mode] warn("Config context.libc_args is set but definition cannot be loaded: file {} not found".format(_libc_args_file)) except json.decoder.JSONDecodeError as e: - del(libc_args_definitions[_arch_mode]) + del libc_args_definitions[_arch_mode] warn("Config context.libc_args is set but definition cannot be loaded from file {}: {}".format(_libc_args_file, e)) return @@ -3946,9 +3865,6 @@ def gef_get_pie_breakpoint(num): global __pie_breakpoints__ return __pie_breakpoints__[num] - - - # # Deprecated API # @@ -3989,6 +3905,11 @@ def get_glibc_arena(): def get_register(regname): return gef.arch.register(regname) +@deprecated("Use `gef.memory.maps`") +def get_process_maps(): + return gef.memory.maps + + # # GDB event hooking # @@ -4790,7 +4711,7 @@ def do_invoke(self, argv, *args, **kwargs): # When the process is already on, set real breakpoints immediately if is_alive(): - vmmap = get_process_maps() + vmmap = gef.memory.maps base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] for bp_ins in __pie_breakpoints__.values(): bp_ins.instantiate(base_address) @@ -4890,7 +4811,7 @@ def do_invoke(self, argv): gdb.execute("run {}".format(" ".join(argv))) unhide_context() gdb.execute("set stop-on-solib-events 0") - vmmap = get_process_maps() + vmmap = gef.memory.maps base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] info("base address {}".format(hex(base_address))) @@ -4921,7 +4842,7 @@ def do_invoke(self, argv): return # after attach, we are stopped so that we can # get base address to modify our breakpoint - vmmap = get_process_maps() + vmmap = gef.memory.maps base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] for bp_ins in __pie_breakpoints__.values(): @@ -4945,7 +4866,7 @@ def do_invoke(self, argv): return # after remote attach, we are stopped so that we can # get base address to modify our breakpoint - vmmap = get_process_maps() + vmmap = gef.memory.maps base_address = [x.page_start for x in vmmap if x.realpath == get_filepath()][0] for bp_ins in __pie_breakpoints__.values(): @@ -5622,7 +5543,7 @@ def do_invoke(self, argv): # fill in memory with sockaddr_in struct contents # we will do this in the stack, since connect() wants a pointer to a struct - vmmap = get_process_maps() + vmmap = gef.memory.maps stack_addr = [entry.page_start for entry in vmmap if entry.path == "[stack]"][0] original_contents = gef.memory.read(stack_addr, 8) @@ -5760,7 +5681,7 @@ def parsed_arglist(arglist): if not is_alive(): main_base_address = main_end_address = 0 else: - vmmap = get_process_maps() + vmmap = gef.memory.maps main_base_address = min([x.page_start for x in vmmap if x.realpath == get_filepath()]) main_end_address = max([x.page_end for x in vmmap if x.realpath == get_filepath()]) @@ -5791,7 +5712,7 @@ def parsed_arglist(arglist): def synchronize(self): """Submit all active breakpoint addresses to IDA/BN.""" pc = gef.arch.pc - vmmap = get_process_maps() + vmmap = gef.memory.maps base_address = min([x.page_start for x in vmmap if x.path == get_filepath()]) end_address = max([x.page_end for x in vmmap if x.path == get_filepath()]) if not (base_address <= pc < end_address): @@ -5935,7 +5856,7 @@ def do_invoke(self, argv): start, end = parse_string_range(needle) needle_sections.append((start, end)) - for sect in get_process_maps(): + for sect in gef.memory.maps: if haystack in sect.path: haystack_sections.append((sect.page_start, sect.page_end, os.path.basename(sect.path))) if needle in sect.path: @@ -6033,7 +5954,7 @@ def search_pattern_by_address(self, pattern, start_address, end_address): def search_pattern(self, pattern, section_name): """Search a pattern within the whole userland memory.""" - for section in get_process_maps(): + for section in gef.memory.maps: if not section.permission & Permission.READ: continue if section.path == "[vvar]": continue if not section_name in section.path: continue @@ -6388,7 +6309,7 @@ def reset(): gregval = gef.arch.register(r) content += " emu.reg_write({}, {:#x})\n".format(unicorn_registers[r], gregval) - vmmap = get_process_maps() + vmmap = gef.memory.maps if not vmmap: warn("An error occurred when reading memory map.") return @@ -6541,7 +6462,7 @@ def do_invoke(self, argv, *args, **kwargs): return if self.download_all_libs: - vmmap = get_process_maps() + vmmap = gef.memory.maps success = 0 for sect in vmmap: if sect.path.startswith("/"): @@ -6687,7 +6608,7 @@ def prepare_qemu_stub(self, target): __gef_qemu_mode__ = True reset_all_caches() info("Note: By using Qemu mode, GEF will display the memory mapping of the Qemu process where the emulated binary resides") - get_process_maps() + gef.memory.maps gdb.execute("context") return @@ -7641,7 +7562,7 @@ def do_invoke(self, argv): ropper = sys.modules["ropper"] if "--file" not in argv: path = get_filepath() - sect = next(filter(lambda x: x.path == path, get_process_maps())) + sect = next(filter(lambda x: x.path == path, gef.memory.maps)) argv.append("--file") argv.append(path) argv.append("-I") @@ -8135,7 +8056,7 @@ def set_init_tbreak_pie(self, addr, argv): gdb.execute("run {}".format(" ".join(argv))) unhide_context() gdb.execute("set stop-on-solib-events 0") - vmmap = get_process_maps() + vmmap = gef.memory.maps base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] return self.set_init_tbreak(base_address + addr) @@ -8242,7 +8163,7 @@ def show_legend(self): @only_if_gdb_running def do_invoke(self, argv): - if not self["enable"] or context_hidden: + if not self["enable"] or gef.session.context_hidden: return if not all(_ in self.layout_mapping for _ in argv): @@ -9474,7 +9395,7 @@ class VMMapCommand(GenericCommand): @only_if_gdb_running def do_invoke(self, argv): - vmmap = get_process_maps() + vmmap = gef.memory.maps if not vmmap: err("No address mapping information found") return @@ -10010,7 +9931,7 @@ def do_invoke(self, argv): # getting vmmap to understand the boundaries of the main binary # we will use this info to understand if a function has been resolved or not. - vmmap = get_process_maps() + vmmap = gef.memory.maps base_address = min([x.page_start for x in vmmap if x.path == get_filepath()]) end_address = max([x.page_end for x in vmmap if x.path == get_filepath()]) @@ -11209,14 +11130,35 @@ def __gef_prompt__(current_prompt): if is_alive(): return GEF_PROMPT_ON return GEF_PROMPT_OFF -class GefMemoryManager: + +class GefManager(metaclass=abc.ABCMeta): + def reset_caches(self): + """Reset the LRU-cached attributes""" + for attr in dir(self): + try: + obj = getattr(self, attr) + if not hasattr(obj, "cache_clear"): + continue + obj.cache_clear() + except: # we're reseeting the cache here, we don't care if (or which) exception triggers + continue + return + +class GefMemoryManager(GefManager): """Class that manages memory access for gef.""" + def __init__(self): + self.reset_caches() + return + + def reset_caches(self): + super().reset_caches() + self.__maps = None + return def write(self, address, buffer, length=0x10): """Write `buffer` at address `address`.""" return gdb.selected_inferior().write_memory(address, buffer, length) - @lru_cache() def read(self, addr, length=0x10): """Return a `length` long byte array with the copy of the process memory at `addr`.""" return gdb.selected_inferior().read_memory(addr, length).tobytes() @@ -11251,7 +11193,6 @@ def read_cstring(self, address, max_length=GEF_MAX_STRING_LENGTH, encoding=None) ustr = res.replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t") if max_length and len(res) > max_length: return "{}[...]".format(ustr[:max_length]) - return ustr def read_ascii_string(self, address): @@ -11261,9 +11202,91 @@ def read_ascii_string(self, address): return cstr return None -class GefHeapManager: + @property + def maps(self): + if not self.__maps: + self.__maps = self.__parse_maps() + return self.__maps + + def __parse_maps(self): + """Return the mapped memory sections""" + try: + return list(self.__parse_procfs_maps()) + except FileNotFoundError as e: + return list(self.__parse_gdb_info_sections()) + + def __parse_procfs_maps(self): + """Get the memory mapping from procfs.""" + def open_file(path, use_cache=False): + """Attempt to open the given file, if remote debugging is active, download + it first to the mirror in /tmp/.""" + if is_remote_debug() and not __gef_qemu_mode__: + lpath = download_file(path, use_cache) + if not lpath: + raise IOError("cannot open remote path {:s}".format(path)) + path = lpath + return open(path, "r") + + __process_map_file = f"/proc/{gef.session.pid}/maps" + with open_file(__process_map_file, use_cache=False) as fd: + for line in fd: + line = line.strip() + addr, perm, off, _, rest = line.split(" ", 4) + rest = rest.split(" ", 1) + if len(rest) == 1: + inode = rest[0] + pathname = "" + else: + inode = rest[0] + pathname = rest[1].lstrip() + + addr_start, addr_end = [int(x, 16) for x in addr.split("-")] + off = int(off, 16) + perm = Permission.from_process_maps(perm) + yield Section(page_start=addr_start, + page_end=addr_end, + offset=off, + permission=perm, + inode=inode, + path=pathname) + return + + def __parse_gdb_info_sections(self): + """Get the memory mapping from GDB's command `maintenance info sections` (limited info).""" + stream = StringIO(gdb.execute("maintenance info sections", to_string=True)) + + for line in stream: + if not line: + break + + try: + parts = [x for x in line.split()] + addr_start, addr_end = [int(x, 16) for x in parts[1].split("->")] + off = int(parts[3][:-1], 16) + path = parts[4] + perm = Permission.from_info_sections(parts[5:]) + yield Section( + page_start=addr_start, + page_end=addr_end, + offset=off, + permission=perm, + inode="", + path=path + ) + + except IndexError: + continue + except ValueError: + continue + return + +class GefHeapManager(GefManager): """Class managing session heap.""" def __init__(self): + self.reset_caches() + return + + def reset_caches(self): self.__libc_main_arena = None self.__libc_selected_arena = None self.__heap_base = None @@ -11361,15 +11384,21 @@ def __delitem__(self, name): def raw_entry(self, name): return dict.__getitem__(self, name) -class GefSessionManager: +class GefSessionManager(GefManager): """Class managing the runtime properties of GEF. """ def __init__(self): + self.reset_caches() + return + + def reset_caches(self): + super().reset_caches() self.__auxiliary_vector = None self.__pagesize = None self.__os = None self.__pid = None self.__file = None self.__canary = None + self.context_hidden = False self.constants = {} # a dict for runtime constants (like 3rd party file paths) # add a few extra runtime constants to avoid lookups # those must be found, otherwise IOError will be raised @@ -11444,7 +11473,7 @@ def canary(self): self.__canary = (canary, canary_location) return self.__canary -@lru_cache() + class Gef: """The GEF root class""" def __init__(self): @@ -11453,7 +11482,7 @@ def __init__(self): self.config = GefSettingsManager() return - def initialize_managers(self): + def reinitialize_managers(self): self.memory = GefMemoryManager() self.heap = GefHeapManager() self.session = GefSessionManager() @@ -11461,7 +11490,7 @@ def initialize_managers(self): def setup(self): """Setup initialize the runtime setup, which may require for the `gef` to be not None.""" - self.initialize_managers() + self.reinitialize_managers() self.gdb = GefCommand() self.gdb.setup() tempdir = self.config["gef.tempdir"] @@ -11469,6 +11498,11 @@ def setup(self): gdb.execute("save gdb-index {}".format(tempdir)) return + def reset_caches(self): + for mgr in (self.memory, self.heap, self.session): + mgr.reset_caches() + return + if __name__ == "__main__": if sys.version_info[0] == 2: From f0126ce748df48752123bb810ac14fdb9504b9d1 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 13:01:14 -0800 Subject: [PATCH 23/62] added `gef.session.qemu_mode` and `gef.session.remote` --- gef.py | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/gef.py b/gef.py index 2fd23c375..e878e3ee1 100644 --- a/gef.py +++ b/gef.py @@ -149,9 +149,6 @@ def update_gef(argv): __heap_uaf_watchpoints__ = [] __pie_breakpoints__ = {} __pie_counter__ = 1 -__gef_remote__ = None -__gef_qemu_mode__ = False -# __gef_current_arena__ = "main_arena" __gef_int_stream_buffer__ = None __gef_redirect_output_fd__ = None @@ -675,7 +672,7 @@ def size(self): @property def realpath(self): # when in a `gef-remote` session, realpath returns the path to the binary on the local disk, not remote - return self.path if __gef_remote__ is None else "/tmp/gef/{:d}/{:s}".format(__gef_remote__, self.path) + return self.path if gef.session.remote is None else "/tmp/gef/{:d}/{:s}".format(gef.session.remote, self.path) def __str__(self): return f"Section({self.page_start:#x}, {self.page_end:#x}, {str(self.permission)})" @@ -3132,8 +3129,8 @@ def get_filepath(): fname = filename[len(".gnu_debugdata for target:") :] return download_file(fname, use_cache=True, local_name=fname) - elif __gef_remote__ is not None: - return "/tmp/gef/{:d}/{:s}".format(__gef_remote__, get_path_from_info_proc()) + elif gef.session.remote is not None: + return "/tmp/gef/{:d}/{:s}".format(gef.session.remote, get_path_from_info_proc()) return filename else: if filename is not None: @@ -3325,13 +3322,11 @@ def new_objfile_handler(event): def exit_handler(event): """GDB event handler for exit cases.""" - global __gef_remote__, __gef_qemu_mode__ - reset_all_caches() - __gef_qemu_mode__ = False - if __gef_remote__ and gef.config["gef-remote.clean_on_exit"] is True: - shutil.rmtree("/tmp/gef/{:d}".format(__gef_remote__)) - __gef_remote__ = None + gef.session.qemu_mode = False + if gef.session.remote and gef.config["gef-remote.clean_on_exit"] is True: + shutil.rmtree("/tmp/gef/{:d}".format(gef.session.remote)) + gef.session.remote = None return @@ -3783,7 +3778,7 @@ def is_in_x86_kernel(address): @lru_cache() def is_remote_debug(): """"Return True is the current debugging session is running through GDB remote session.""" - return __gef_remote__ is not None or "remote" in gdb.execute("maintenance print target-stack", to_string=True) + return gef.session.remote is not None or "remote" in gdb.execute("maintenance print target-stack", to_string=True) def de_bruijn(alphabet, n): @@ -6411,9 +6406,7 @@ def __init__(self): "--pid": 0, "--qemu-mode": True}) def do_invoke(self, argv, *args, **kwargs): - global __gef_remote__ - - if __gef_remote__ is not None: + if gef.session.remote is not None: err("You already are in remote session. Close it first before opening a new one...") return @@ -6483,7 +6476,7 @@ def do_invoke(self, argv, *args, **kwargs): # refresh the architecture setting set_arch() - __gef_remote__ = pid + gef.session.remote = pid return def new_objfile_handler(self, event): @@ -6564,7 +6557,7 @@ def usage(self): return def prepare_qemu_stub(self, target): - global gef, __gef_qemu_mode__ + global gef reset_all_caches() arch = get_arch() @@ -6600,7 +6593,7 @@ def prepare_qemu_stub(self, target): unhide_context() if gef.session.pid == 1 and "ENABLE=1" in gdb.execute("maintenance packet Qqemu.sstepbits", to_string=True, from_tty=False): - __gef_qemu_mode__ = True + gef.session.qemu_mode = True reset_all_caches() info("Note: By using Qemu mode, GEF will display the memory mapping of the Qemu process where the emulated binary resides") gef.memory.maps @@ -7999,7 +7992,7 @@ def do_invoke(self, argv): warn("The file '{}' is not executable.".format(fpath)) return - if is_alive() and not __gef_qemu_mode__: + if is_alive() and not gef.session.qemu_mode: warn("gdb is already running") return @@ -11215,7 +11208,7 @@ def __parse_procfs_maps(self): def open_file(path, use_cache=False): """Attempt to open the given file, if remote debugging is active, download it first to the mirror in /tmp/.""" - if is_remote_debug() and not __gef_qemu_mode__: + if is_remote_debug() and not gef.session.qemu_mode: lpath = download_file(path, use_cache) if not lpath: raise IOError("cannot open remote path {:s}".format(path)) @@ -11383,6 +11376,9 @@ class GefSessionManager(GefManager): """Class managing the runtime properties of GEF. """ def __init__(self): self.reset_caches() + self.context_hidden = False + self.remote = None + self.qemu_mode = False return def reset_caches(self): @@ -11393,7 +11389,6 @@ def reset_caches(self): self.__pid = None self.__file = None self.__canary = None - self.context_hidden = False self.constants = {} # a dict for runtime constants (like 3rd party file paths) # add a few extra runtime constants to avoid lookups # those must be found, otherwise IOError will be raised @@ -11434,7 +11429,7 @@ def os(self): def pid(self): """Return the PID of the target process.""" if not self.__pid: - pid = gdb.selected_inferior().pid if not __gef_qemu_mode__ else gdb.selected_thread().ptid[1] + pid = gdb.selected_inferior().pid if not gef.session.qemu_mode else gdb.selected_thread().ptid[1] if not pid: raise RuntimeError("cannot retrieve PID for target process") self.__pid = pid @@ -11468,7 +11463,6 @@ def canary(self): self.__canary = (canary, canary_location) return self.__canary - class Gef: """The GEF root class""" def __init__(self): From 8262adcc7c12cbff7e0d560c20d5fa1c348e6dcb Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 13:14:13 -0800 Subject: [PATCH 24/62] added a simple helper `reset()` that allows to entirely reset the gef session using `pi reset()` --- gef.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/gef.py b/gef.py index e878e3ee1..5b2bf293c 100644 --- a/gef.py +++ b/gef.py @@ -185,6 +185,22 @@ def reset_all_caches(): gef.reset_caches() return +def reset(): + global gef + + arch = None + if gef: + reset_all_caches() + arch = gef.arch + del gef + + gef = None + gef = Gef() + gef.setup() + + if arch: + gef.arch = arch + return def highlight_text(text): """ @@ -11548,8 +11564,7 @@ def reset_caches(self): pass # load GEF - gef = Gef() - gef.setup() + reset() # gdb events configuration gef_on_continue_hook(continue_handler) From 0ee63e37fa95e7ff4651f95c5efeabb071afdc23 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 13:26:27 -0800 Subject: [PATCH 25/62] `__gef_redirect_output_fd__` -> `gef.ui.redirect_fd` --- gef.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/gef.py b/gef.py index 5b2bf293c..8779b437a 100644 --- a/gef.py +++ b/gef.py @@ -150,7 +150,6 @@ def update_gef(argv): __pie_breakpoints__ = {} __pie_counter__ = 1 __gef_int_stream_buffer__ = None -__gef_redirect_output_fd__ = None DEFAULT_PAGE_ALIGN_SHIFT = 12 DEFAULT_PAGE_SIZE = 1 << DEFAULT_PAGE_ALIGN_SHIFT @@ -248,7 +247,7 @@ def bufferize(f): @functools.wraps(f) def wrapper(*args, **kwargs): - global __gef_int_stream_buffer__, __gef_redirect_output_fd__ + global __gef_int_stream_buffer__, gef if __gef_int_stream_buffer__: return f(*args, **kwargs) @@ -259,26 +258,26 @@ def wrapper(*args, **kwargs): finally: redirect = gef.config["context.redirect"] if redirect.startswith("/dev/pts/"): - if not __gef_redirect_output_fd__: + if not gef.ui.redirect_fd: # if the FD has never been open, open it fd = open(redirect, "wt") - __gef_redirect_output_fd__ = fd - elif redirect != __gef_redirect_output_fd__.name: + gef.ui.redirect_fd = fd + elif redirect != gef.ui.redirect_fd.name: # if the user has changed the redirect setting during runtime, update the state - __gef_redirect_output_fd__.close() + gef.ui.redirect_fd.close() fd = open(redirect, "wt") - __gef_redirect_output_fd__ = fd + gef.ui.redirect_fd = fd else: # otherwise, keep using it - fd = __gef_redirect_output_fd__ + fd = gef.ui.redirect_fd else: fd = sys.stdout - __gef_redirect_output_fd__ = None + gef.ui.redirect_fd = None - if __gef_redirect_output_fd__ and fd.closed: + if gef.ui.redirect_fd and fd.closed: # if the tty was closed, revert back to stdout fd = sys.stdout - __gef_redirect_output_fd__ = None + gef.ui.redirect_fd = None gef.config["context.redirect"] = "" fd.write(__gef_int_stream_buffer__.getvalue()) @@ -3703,7 +3702,7 @@ def get_memory_alignment(in_bits=False): def clear_screen(tty=""): """Clear the screen.""" - global __gef_redirect_output_fd__ + global gef if not tty: gdb.execute("shell clear -x") return @@ -3714,7 +3713,7 @@ def clear_screen(tty=""): with open(tty, "wt") as f: f.write("\x1b[H\x1b[J") except PermissionError: - __gef_redirect_output_fd__ = None + gef.ui.redirect_fd = None gef.config["context.redirect"] = "" return @@ -11479,6 +11478,12 @@ def canary(self): self.__canary = (canary, canary_location) return self.__canary +class GefUiManager(GefManager): + """Class managing UI settings.""" + def __init__(self): + self.output_fd = None + return + class Gef: """The GEF root class""" def __init__(self): @@ -11491,6 +11496,7 @@ def reinitialize_managers(self): self.memory = GefMemoryManager() self.heap = GefHeapManager() self.session = GefSessionManager() + self.ui = GefUiManager() return def setup(self): @@ -11504,7 +11510,7 @@ def setup(self): return def reset_caches(self): - for mgr in (self.memory, self.heap, self.session): + for mgr in (self.memory, self.heap, self.session, self.ui): mgr.reset_caches() return From df129ed70ba7cce05f651ffd272f4c9b8c86d558 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 13:30:31 -0800 Subject: [PATCH 26/62] replaced `__gef_int_stream_buffer__ ` -> `gef.ui.stream_buffer` --- gef.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/gef.py b/gef.py index 8779b437a..c2148b021 100644 --- a/gef.py +++ b/gef.py @@ -149,7 +149,6 @@ def update_gef(argv): __heap_uaf_watchpoints__ = [] __pie_breakpoints__ = {} __pie_counter__ = 1 -__gef_int_stream_buffer__ = None DEFAULT_PAGE_ALIGN_SHIFT = 12 DEFAULT_PAGE_SIZE = 1 << DEFAULT_PAGE_ALIGN_SHIFT @@ -237,8 +236,8 @@ def highlight_text(text): def gef_print(x="", *args, **kwargs): """Wrapper around print(), using string buffering feature.""" x = highlight_text(x) - if __gef_int_stream_buffer__ and not is_debug(): - return __gef_int_stream_buffer__.write(x + kwargs.get("end", "\n")) + if gef.ui.stream_buffer and not is_debug(): + return gef.ui.stream_buffer.write(x + kwargs.get("end", "\n")) return print(x, *args, **kwargs) @@ -247,12 +246,12 @@ def bufferize(f): @functools.wraps(f) def wrapper(*args, **kwargs): - global __gef_int_stream_buffer__, gef + global gef - if __gef_int_stream_buffer__: + if gef.ui.stream_buffer: return f(*args, **kwargs) - __gef_int_stream_buffer__ = StringIO() + gef.ui.stream_buffer = StringIO() try: rv = f(*args, **kwargs) finally: @@ -280,9 +279,9 @@ def wrapper(*args, **kwargs): gef.ui.redirect_fd = None gef.config["context.redirect"] = "" - fd.write(__gef_int_stream_buffer__.getvalue()) + fd.write(gef.ui.stream_buffer.getvalue()) fd.flush() - __gef_int_stream_buffer__ = None + gef.ui.stream_buffer = None return rv return wrapper @@ -1705,12 +1704,12 @@ def is_debug() -> bool: def hide_context() -> bool: """ Helper function to hide the context pane """ - gef.session.context_hidden = True + gef.ui.context_hidden = True return True def unhide_context() -> bool: """ Helper function to unhide the context pane """ - gef.session.context_hidden = False + gef.ui.context_hidden = False return True class RedirectOutputContext(): @@ -8166,7 +8165,7 @@ def show_legend(self): @only_if_gdb_running def do_invoke(self, argv): - if not self["enable"] or gef.session.context_hidden: + if not self["enable"] or gef.ui.context_hidden: return if not all(_ in self.layout_mapping for _ in argv): @@ -11391,7 +11390,6 @@ class GefSessionManager(GefManager): """Class managing the runtime properties of GEF. """ def __init__(self): self.reset_caches() - self.context_hidden = False self.remote = None self.qemu_mode = False return @@ -11482,6 +11480,8 @@ class GefUiManager(GefManager): """Class managing UI settings.""" def __init__(self): self.output_fd = None + self.context_hidden = False + self.stream_buffer = None return class Gef: From 809c735992da43bb5ebec113cbf43f76c5871419 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 14:16:19 -0800 Subject: [PATCH 27/62] removed global `__infos_files__` , was obsolete since we started using `lru_cache` --- gef.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/gef.py b/gef.py index c2148b021..fe3c7a7a9 100644 --- a/gef.py +++ b/gef.py @@ -141,7 +141,6 @@ def update_gef(argv): __functions__ = [] __aliases__ = [] __watches__ = {} -__infos_files__ = [] __gef_convenience_vars_index__ = 0 __context_messages__ = [] __heap_allocated_list__ = [] @@ -3199,13 +3198,9 @@ def get_function_length(sym): def get_info_files(): """Retrieve all the files loaded by debuggee.""" lines = gdb.execute("info files", to_string=True).splitlines() - - if len(lines) < len(__infos_files__): - return __infos_files__ - + infos = [] for line in lines: line = line.strip() - if not line: break @@ -3222,11 +3217,8 @@ def get_info_files(): else: filename = get_filepath() - info = Zone(section_name, addr_start, addr_end, filename) - - __infos_files__.append(info) - - return __infos_files__ + infos.append(Zone(section_name, addr_start, addr_end, filename)) + return infos def process_lookup_address(address): From eb7312b9682a784b1809730e2e690c257bf65c97 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 14:20:19 -0800 Subject: [PATCH 28/62] `__commands__` --> `gef.session.commands` --- gef.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gef.py b/gef.py index fe3c7a7a9..439dda6ed 100644 --- a/gef.py +++ b/gef.py @@ -137,7 +137,6 @@ def update_gef(argv): sys.exit(0) gef = None -__commands__ = [] __functions__ = [] __aliases__ = [] __watches__ = {} @@ -4403,9 +4402,9 @@ def pane_title(): return "example:pane" def register_external_command(obj): """Registering function for new GEF (sub-)command to GDB.""" - global __commands__, gef + global gef cls = obj.__class__ - __commands__.append(cls) + gef.session.commands.append(cls) gef.gdb.load(initial=False) gef.gdb.doc.add_command_to_doc((cls._cmdline_, cls, None)) gef.gdb.doc.refresh() @@ -4414,16 +4413,16 @@ def register_external_command(obj): def register_command(cls): """Decorator for registering new GEF (sub-)command to GDB.""" - global __commands__ - __commands__.append(cls) + global gef + gef.session.commands.append(cls) return cls def register_priority_command(cls): """Decorator for registering new command with priority, meaning that it must loaded before the other generic commands.""" - global __commands__ - __commands__.insert(0, cls) + global gef + gef.session.commands.insert(0, cls) return cls @@ -10556,7 +10555,7 @@ def add_context_pane(self, pane_name, display_pane_function, pane_title_function def load(self, initial=False): """Load all the commands and functions defined by GEF into GDB.""" nb_missing = 0 - self.commands = [(x._cmdline_, x) for x in __commands__] + self.commands = [(x._cmdline_, x) for x in gef.session.commands] # load all of the functions for function_class_name in __functions__: @@ -11384,6 +11383,7 @@ def __init__(self): self.reset_caches() self.remote = None self.qemu_mode = False + self.commands = [] return def reset_caches(self): From d83b23991cceacf9e7d3516edbc384fbf793bf90 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 14:32:18 -0800 Subject: [PATCH 29/62] `highlight_table` --> `gef.ui.highlight_table` --- gef.py | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/gef.py b/gef.py index 439dda6ed..640b48934 100644 --- a/gef.py +++ b/gef.py @@ -137,8 +137,6 @@ def update_gef(argv): sys.exit(0) gef = None -__functions__ = [] -__aliases__ = [] __watches__ = {} __gef_convenience_vars_index__ = 0 __context_messages__ = [] @@ -164,11 +162,8 @@ def update_gef(argv): libc_args_definitions = {} -highlight_table = {} ANSI_SPLIT_RE = r"(\033\[[\d;]*m)" -# idea: lru_cache wrapper that register back callback items for cache clearing - def reset_all_caches(): """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.""" @@ -200,26 +195,27 @@ def reset(): def highlight_text(text): """ - Highlight text using highlight_table { match -> color } settings. + 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 - highlight_table and wrap the specified color in the highlight_table + 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. """ - if not highlight_table: + global gef + if not gef.ui.highlight_table: return text if gef.config["highlight.regex"]: - for match, color in highlight_table.items(): + for match, color in gef.ui.highlight_table.items(): text = re.sub("(" + match + ")", Color.colorify("\\1", color), text) return text ansiSplit = re.split(ANSI_SPLIT_RE, text) - for match, color in highlight_table.items(): + for match, color in gef.ui.highlight_table.items(): for index, val in enumerate(ansiSplit): found = val.find(match) if found > -1: @@ -4428,8 +4424,8 @@ def register_priority_command(cls): def register_function(cls): """Decorator for registering a new convenience function to GDB.""" - global __functions__ - __functions__.append(cls) + global gef + gef.session.functions.append(cls) return cls @@ -9999,11 +9995,11 @@ class HighlightListCommand(GenericCommand): _syntax_ = _cmdline_ def print_highlight_table(self): - if not highlight_table: + if not gef.ui.highlight_table: return err("no matches found") - left_pad = max(map(len, highlight_table.keys())) - for match, color in sorted(highlight_table.items()): + left_pad = max(map(len, gef.ui.highlight_table.keys())) + for match, color in sorted(gef.ui.highlight_table.items()): print("{} {} {}".format(Color.colorify(match.ljust(left_pad), color), VERTICAL_LINE, Color.colorify(color, color))) return @@ -10019,7 +10015,7 @@ class HighlightClearCommand(GenericCommand): _syntax_ = _cmdline_ def do_invoke(self, argv): - return highlight_table.clear() + return gef.ui.highlight_table.clear() @register_command @@ -10035,7 +10031,7 @@ def do_invoke(self, argv): return self.usage() match, color = argv - highlight_table[match] = color + gef.ui.highlight_table[match] = color return @@ -10057,7 +10053,7 @@ def do_invoke(self, argv): if not argv: return self.usage() - highlight_table.pop(argv[0], None) + gef.ui.highlight_table.pop(argv[0], None) return @@ -10558,7 +10554,7 @@ def load(self, initial=False): self.commands = [(x._cmdline_, x) for x in gef.session.commands] # load all of the functions - for function_class_name in __functions__: + for function_class_name in gef.session.functions: self.loaded_functions.append(function_class_name()) def is_loaded(x): @@ -10795,7 +10791,7 @@ def invoke(self, args, from_tty): # save the aliases cfg.add_section("aliases") - for alias in __aliases__: + for alias in gef.session.aliases: cfg.set("aliases", alias._alias, alias._command) with open(GEF_RC, "w") as fd: @@ -10935,7 +10931,7 @@ def __init__(self, alias, command, completer_class=gdb.COMPLETE_NONE, command_cl if not p: return - if any(x for x in __aliases__ if x._alias == alias): + if any(x for x in gef.session.aliases if x._alias == alias): return self._command = command @@ -10951,7 +10947,7 @@ def __init__(self, alias, command, completer_class=gdb.COMPLETE_NONE, command_cl self.complete = _instance.complete super().__init__(alias, command_class, completer_class=completer_class) - __aliases__.append(self) + gef.session.aliases.append(self) return def invoke(self, args, from_tty): @@ -11012,13 +11008,13 @@ def __init__(self): return def do_invoke(self, argv): - global __aliases__ + global gef if len(argv) != 1: self.usage() return try: - alias_to_remove = next(filter(lambda x: x._alias == argv[0], __aliases__)) - __aliases__.remove(alias_to_remove) + alias_to_remove = next(filter(lambda x: x._alias == argv[0], gef.session.aliases)) + gef.session.aliases.remove(alias_to_remove) except (ValueError, StopIteration): err("{0} not found in aliases.".format(argv[0])) return @@ -11038,7 +11034,7 @@ def __init__(self): def do_invoke(self, argv): ok("Aliases defined:") - for a in __aliases__: + for a in gef.session.aliases: gef_print("{:30s} {} {}".format(a._alias, RIGHT_ARROW, a._command)) return @@ -11384,6 +11380,8 @@ def __init__(self): self.remote = None self.qemu_mode = False self.commands = [] + self.functions = [] + self.aliases = [] return def reset_caches(self): @@ -11474,6 +11472,7 @@ def __init__(self): self.output_fd = None self.context_hidden = False self.stream_buffer = None + self.highlight_table = {} return class Gef: From 67df573699860ebf0730e4fe8fcefd3f2619acf1 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 14:36:36 -0800 Subject: [PATCH 30/62] `libc_args_definitions` --> `gef.session.libc_args_definitions` --- gef.py | 73 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/gef.py b/gef.py index 640b48934..2a4ef0279 100644 --- a/gef.py +++ b/gef.py @@ -85,17 +85,33 @@ from io import StringIO from urllib.request import urlopen -LEFT_ARROW = " \u2190 " -RIGHT_ARROW = " \u2192 " -DOWN_ARROW = "\u21b3" -HORIZONTAL_LINE = "\u2500" -VERTICAL_LINE = "\u2502" -CROSS = "\u2718 " -TICK = "\u2713 " -BP_GLYPH = "\u25cf" -GEF_PROMPT = "gef\u27a4 " -GEF_PROMPT_ON = "\001\033[1;32m\002{0:s}\001\033[0m\002".format(GEF_PROMPT) -GEF_PROMPT_OFF = "\001\033[1;31m\002{0:s}\001\033[0m\002".format(GEF_PROMPT) + +GDB_MIN_VERSION = (8, 0) +GDB_VERSION = tuple(map(int, re.search(r"(\d+)[^\d]+(\d+)", gdb.VERSION).groups())) +PYTHON_MIN_VERSION = (3, 6) +PYTHON_VERSION = sys.version_info[0:2] + +DEFAULT_PAGE_ALIGN_SHIFT = 12 +DEFAULT_PAGE_SIZE = 1 << DEFAULT_PAGE_ALIGN_SHIFT + +GEF_RC = os.getenv("GEF_RC") or os.path.join(os.getenv("HOME"), ".gef.rc") +GEF_TEMP_DIR = os.path.join(tempfile.gettempdir(), "gef") +GEF_MAX_STRING_LENGTH = 50 + +LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME = "main_arena" +ANSI_SPLIT_RE = r"(\033\[[\d;]*m)" + +LEFT_ARROW = " \u2190 " +RIGHT_ARROW = " \u2192 " +DOWN_ARROW = "\u21b3" +HORIZONTAL_LINE = "\u2500" +VERTICAL_LINE = "\u2502" +CROSS = "\u2718 " +TICK = "\u2713 " +BP_GLYPH = "\u25cf" +GEF_PROMPT = "gef\u27a4 " +GEF_PROMPT_ON = "\001\033[1;32m\002{0:s}\001\033[0m\002".format(GEF_PROMPT) +GEF_PROMPT_OFF = "\001\033[1;31m\002{0:s}\001\033[0m\002".format(GEF_PROMPT) def http_get(url): @@ -146,23 +162,6 @@ def update_gef(argv): __pie_breakpoints__ = {} __pie_counter__ = 1 -DEFAULT_PAGE_ALIGN_SHIFT = 12 -DEFAULT_PAGE_SIZE = 1 << DEFAULT_PAGE_ALIGN_SHIFT -GEF_RC = os.getenv("GEF_RC") or os.path.join(os.getenv("HOME"), ".gef.rc") -GEF_TEMP_DIR = os.path.join(tempfile.gettempdir(), "gef") -GEF_MAX_STRING_LENGTH = 50 - -GDB_MIN_VERSION = (8, 0) -GDB_VERSION = tuple(map(int, re.search(r"(\d+)[^\d]+(\d+)", gdb.VERSION).groups())) - -PYTHON_MIN_VERSION = (3, 6) -PYTHON_VERSION = sys.version_info[0:2] - -LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME = "main_arena" - -libc_args_definitions = {} - -ANSI_SPLIT_RE = r"(\033\[[\d;]*m)" def reset_all_caches(): """Free all caches. If an object is cached, it will have a callable attribute `cache_clear` @@ -3344,6 +3343,8 @@ def regchanged_handler(event): def load_libc_args(): + global gef + # load libc function arguments' definitions if not gef.config["context.libc_args"]: return @@ -3362,21 +3363,19 @@ def load_libc_args(): _arch_mode = "{}_{}".format(gef.arch.arch.lower(), gef.arch.mode) _libc_args_file = "{}/{}.json".format(path, _arch_mode) - global libc_args_definitions - # current arch and mode already loaded - if _arch_mode in libc_args_definitions: + if _arch_mode in gef.session.highlight_table: return - libc_args_definitions[_arch_mode] = {} + gef.session.highlight_table[_arch_mode] = {} try: with open(_libc_args_file) as _libc_args: - libc_args_definitions[_arch_mode] = json.load(_libc_args) + gef.session.highlight_table[_arch_mode] = json.load(_libc_args) except FileNotFoundError: - del libc_args_definitions[_arch_mode] + del gef.session.highlight_table[_arch_mode] warn("Config context.libc_args is set but definition cannot be loaded: file {} not found".format(_libc_args_file)) except json.decoder.JSONDecodeError as e: - del libc_args_definitions[_arch_mode] + del gef.session.highlight_table[_arch_mode] warn("Config context.libc_args is set but definition cannot be loaded from file {}: {}".format(_libc_args_file, e)) return @@ -8496,7 +8495,7 @@ def __get_current_block_start_address(): if function_name.endswith("@plt"): _function_name = function_name.split("@")[0] try: - nb_argument = len(libc_args_definitions[_arch_mode][_function_name]) + nb_argument = len(gef.session.highlight_table[_arch_mode][_function_name]) except KeyError: pass @@ -8514,7 +8513,7 @@ def __get_current_block_start_address(): _values = RIGHT_ARROW.join(dereference_from(_values)) try: args.append("{} = {} (def: {})".format(Color.colorify(_key, arg_key_color), _values, - libc_args_definitions[_arch_mode][_function_name][_key])) + gef.session.highlight_table[_arch_mode][_function_name][_key])) except KeyError: args.append("{} = {}".format(Color.colorify(_key, arg_key_color), _values)) From 93f2b15eff759cedbfad1a3e57b5d4fa28045bb5 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 14:52:06 -0800 Subject: [PATCH 31/62] restore commands & functions as globals --- gef.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/gef.py b/gef.py index 2a4ef0279..d20d8af37 100644 --- a/gef.py +++ b/gef.py @@ -153,6 +153,14 @@ def update_gef(argv): sys.exit(0) gef = None + +# +# Those globals are required since the commands/functions registration happens *before* the +# initialisation of GEF +# +__registered_commands__ = [] +__registered_functions__ = [] + __watches__ = {} __gef_convenience_vars_index__ = 0 __context_messages__ = [] @@ -204,6 +212,7 @@ def highlight_text(text): within the specified string. """ global gef + if not gef.ui.highlight_table: return text @@ -4397,9 +4406,8 @@ def pane_title(): return "example:pane" def register_external_command(obj): """Registering function for new GEF (sub-)command to GDB.""" - global gef cls = obj.__class__ - gef.session.commands.append(cls) + __registered_commands__.append(cls) gef.gdb.load(initial=False) gef.gdb.doc.add_command_to_doc((cls._cmdline_, cls, None)) gef.gdb.doc.refresh() @@ -4408,23 +4416,20 @@ def register_external_command(obj): def register_command(cls): """Decorator for registering new GEF (sub-)command to GDB.""" - global gef - gef.session.commands.append(cls) + __registered_commands__.append(cls) return cls def register_priority_command(cls): """Decorator for registering new command with priority, meaning that it must loaded before the other generic commands.""" - global gef - gef.session.commands.insert(0, cls) + __registered_commands__.insert(0, cls) return cls def register_function(cls): """Decorator for registering a new convenience function to GDB.""" - global gef - gef.session.functions.append(cls) + __registered_functions__.append(cls) return cls @@ -10550,7 +10555,7 @@ def add_context_pane(self, pane_name, display_pane_function, pane_title_function def load(self, initial=False): """Load all the commands and functions defined by GEF into GDB.""" nb_missing = 0 - self.commands = [(x._cmdline_, x) for x in gef.session.commands] + self.commands = [(x._cmdline_, x) for x in __registered_commands__] # load all of the functions for function_class_name in gef.session.functions: @@ -11378,8 +11383,6 @@ def __init__(self): self.reset_caches() self.remote = None self.qemu_mode = False - self.commands = [] - self.functions = [] self.aliases = [] return @@ -11480,13 +11483,13 @@ def __init__(self): self.binary = None self.arch = GenericArchitecture() # see PR #516, will be reset by `new_objfile_handler` self.config = GefSettingsManager() + self.ui = GefUiManager() return def reinitialize_managers(self): self.memory = GefMemoryManager() self.heap = GefHeapManager() self.session = GefSessionManager() - self.ui = GefUiManager() return def setup(self): From 84b00f1b74c99aed94bb172b9007e43d04d1ea4d Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 15:00:08 -0800 Subject: [PATCH 32/62] fixed typo in uimanager --- gef.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gef.py b/gef.py index d20d8af37..bc2c528d2 100644 --- a/gef.py +++ b/gef.py @@ -10558,7 +10558,7 @@ def load(self, initial=False): self.commands = [(x._cmdline_, x) for x in __registered_commands__] # load all of the functions - for function_class_name in gef.session.functions: + for function_class_name in __registered_functions__: self.loaded_functions.append(function_class_name()) def is_loaded(x): @@ -11471,7 +11471,7 @@ def canary(self): class GefUiManager(GefManager): """Class managing UI settings.""" def __init__(self): - self.output_fd = None + self.redirect_fd = None self.context_hidden = False self.stream_buffer = None self.highlight_table = {} From 4bcf19ac0a847776b62b2f6d80204a85892ba762 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 17:28:12 -0800 Subject: [PATCH 33/62] `new_objfile_handle` doesn't need to re-init the managers since we already reset its cache --- gef.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/gef.py b/gef.py index bc2c528d2..0fa50a11f 100644 --- a/gef.py +++ b/gef.py @@ -153,11 +153,6 @@ def update_gef(argv): sys.exit(0) gef = None - -# -# Those globals are required since the commands/functions registration happens *before* the -# initialisation of GEF -# __registered_commands__ = [] __registered_functions__ = [] @@ -3323,7 +3318,6 @@ def hook_stop_handler(event): def new_objfile_handler(event): """GDB event handler for new object file cases.""" reset_all_caches() - gef.reinitialize_managers() set_arch() load_libc_args() return @@ -11384,6 +11378,11 @@ def __init__(self): self.remote = None self.qemu_mode = False self.aliases = [] + self.constants = {} # a dict for runtime constants (like 3rd party file paths) + # add a few extra runtime constants to avoid lookups + # those must be found, otherwise IOError will be raised + for constant in ("python3", "readelf", "file", "ps"): + self.constants[constant] = which(constant) return def reset_caches(self): @@ -11394,11 +11393,6 @@ def reset_caches(self): self.__pid = None self.__file = None self.__canary = None - self.constants = {} # a dict for runtime constants (like 3rd party file paths) - # add a few extra runtime constants to avoid lookups - # those must be found, otherwise IOError will be raised - for constant in ("python3", "readelf", "file", "ps"): - self.constants[constant] = which(constant) return @property @@ -11512,10 +11506,12 @@ def reset_caches(self): if sys.version_info[0] == 2: err("GEF has dropped Python2 support for GDB when it reached EOL on 2020/01/01.") err("If you require GEF for GDB+Python2, use https://github.com/hugsy/gef-legacy.") + exit(1) - elif GDB_VERSION < GDB_MIN_VERSION or PYTHON_VERSION < PYTHON_MIN_VERSION: + if GDB_VERSION < GDB_MIN_VERSION or PYTHON_VERSION < PYTHON_MIN_VERSION: err("You're using an old version of GDB. GEF will not work correctly. " "Consider updating to GDB {} or higher (with Python {} or higher).".format(".".join(map(str, GDB_MIN_VERSION)), ".".join(map(str, PYTHON_MIN_VERSION)))) + exit(1) else: try: From b0da3f84ad1e61782e555555ed0cebece5bad640 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 17:37:17 -0800 Subject: [PATCH 34/62] `__watches__` -> `gef.ui.watches` --- gef.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/gef.py b/gef.py index 0fa50a11f..da75ad85f 100644 --- a/gef.py +++ b/gef.py @@ -156,7 +156,6 @@ def update_gef(argv): __registered_commands__ = [] __registered_functions__ = [] -__watches__ = {} __gef_convenience_vars_index__ = 0 __context_messages__ = [] __heap_allocated_list__ = [] @@ -8761,8 +8760,7 @@ def context_additional_information(self): return def context_memory(self): - global __watches__ - for address, opt in sorted(__watches__.items()): + for address, opt in sorted(gef.ui.watches.items()): sz, fmt = opt[0:2] self.context_title("memory:{:#x}".format(address)) if fmt == "pointers": @@ -8821,8 +8819,6 @@ def __init__(self): @only_if_gdb_running def do_invoke(self, argv): - global __watches__ - if len(argv) not in (1, 2, 3): self.usage() return @@ -8843,7 +8839,7 @@ def do_invoke(self, argv): elif gef.arch.ptrsize == 8: group = "qword" - __watches__[address] = (size, group) + gef.ui.watches[address] = (size, group) ok("Adding memwatch to {:#x}".format(address)) return @@ -8861,13 +8857,12 @@ def __init__(self): @only_if_gdb_running def do_invoke(self, argv): - global __watches__ if not argv: self.usage() return address = parse_address(argv[0]) - res = __watches__.pop(address, None) + res = gef.ui.watches.pop(address, None) if not res: warn("You weren't watching {:#x}".format(address)) else: @@ -8883,8 +8878,7 @@ class MemoryWatchResetCommand(GenericCommand): @only_if_gdb_running def do_invoke(self, argv): - global __watches__ - __watches__.clear() + gef.ui.watches.clear() ok("Memory watches cleared") return @@ -8897,14 +8891,12 @@ class MemoryWatchListCommand(GenericCommand): @only_if_gdb_running def do_invoke(self, argv): - global __watches__ - - if not __watches__: + if not gef.ui.watches: info("No memory watches") return info("Memory watches:") - for address, opt in sorted(__watches__.items()): + for address, opt in sorted(gef.ui.watches.items()): gef_print("- {:#x} ({}, {})".format(address, opt[0], opt[1])) return @@ -11469,6 +11461,7 @@ def __init__(self): self.context_hidden = False self.stream_buffer = None self.highlight_table = {} + self.watches = {} return class Gef: From f08667b7b6d19a66884952e2c283308b82e98bb9 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 17:40:11 -0800 Subject: [PATCH 35/62] `__context_messages__` -> `gef.ui.context_messages` --- gef.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/gef.py b/gef.py index da75ad85f..1375f93e8 100644 --- a/gef.py +++ b/gef.py @@ -157,7 +157,6 @@ def update_gef(argv): __registered_functions__ = [] __gef_convenience_vars_index__ = 0 -__context_messages__ = [] __heap_allocated_list__ = [] __heap_freed_list__ = [] __heap_uaf_watchpoints__ = [] @@ -1544,14 +1543,12 @@ def ok(msg): return gef_print("{} {}".format(Color.colorify("[+]", "bold gree def info(msg): return gef_print("{} {}".format(Color.colorify("[+]", "bold blue"), msg)) -# TODO: move to gef.session.context def push_context_message(level, message): """Push the message to be displayed the next time the context is invoked.""" - global __context_messages__ if level not in ("error", "warn", "ok", "info"): err("Invalid level '{}', discarding message".format(level)) return - __context_messages__.append((level, message)) + gef.ui.context_messages.append((level, message)) return @@ -8748,11 +8745,11 @@ def reason(): return def context_additional_information(self): - if not __context_messages__: + if not gef.ui.context_messages: return self.context_title("extra") - for level, text in __context_messages__: + for level, text in gef.ui.context_messages: if level == "error": err(text) elif level == "warn": warn(text) elif level == "success": ok(text) @@ -8785,8 +8782,7 @@ def update_registers(cls, event): return def empty_extra_messages(self, event): - global __context_messages__ - __context_messages__ = [] + gef.ui.context_messages.clear() return @@ -11462,6 +11458,7 @@ def __init__(self): self.stream_buffer = None self.highlight_table = {} self.watches = {} + self.context_messages = [] return class Gef: From bf96176c194a2922f03c2440533c8322960db4db Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 17:47:35 -0800 Subject: [PATCH 36/62] `__gef_convenience_vars_index` -> `gef.session.convenience_vars_index` --- gef.py | 67 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/gef.py b/gef.py index 1375f93e8..49c0a7cba 100644 --- a/gef.py +++ b/gef.py @@ -86,34 +86,6 @@ from urllib.request import urlopen -GDB_MIN_VERSION = (8, 0) -GDB_VERSION = tuple(map(int, re.search(r"(\d+)[^\d]+(\d+)", gdb.VERSION).groups())) -PYTHON_MIN_VERSION = (3, 6) -PYTHON_VERSION = sys.version_info[0:2] - -DEFAULT_PAGE_ALIGN_SHIFT = 12 -DEFAULT_PAGE_SIZE = 1 << DEFAULT_PAGE_ALIGN_SHIFT - -GEF_RC = os.getenv("GEF_RC") or os.path.join(os.getenv("HOME"), ".gef.rc") -GEF_TEMP_DIR = os.path.join(tempfile.gettempdir(), "gef") -GEF_MAX_STRING_LENGTH = 50 - -LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME = "main_arena" -ANSI_SPLIT_RE = r"(\033\[[\d;]*m)" - -LEFT_ARROW = " \u2190 " -RIGHT_ARROW = " \u2192 " -DOWN_ARROW = "\u21b3" -HORIZONTAL_LINE = "\u2500" -VERTICAL_LINE = "\u2502" -CROSS = "\u2718 " -TICK = "\u2713 " -BP_GLYPH = "\u25cf" -GEF_PROMPT = "gef\u27a4 " -GEF_PROMPT_ON = "\001\033[1;32m\002{0:s}\001\033[0m\002".format(GEF_PROMPT) -GEF_PROMPT_OFF = "\001\033[1;31m\002{0:s}\001\033[0m\002".format(GEF_PROMPT) - - def http_get(url): """Basic HTTP wrapper for GET request. Return the body of the page if HTTP code is OK, otherwise return None.""" @@ -152,11 +124,38 @@ def update_gef(argv): print("[-] gef cannot run as standalone") sys.exit(0) +GDB_MIN_VERSION = (8, 0) +GDB_VERSION = tuple(map(int, re.search(r"(\d+)[^\d]+(\d+)", gdb.VERSION).groups())) +PYTHON_MIN_VERSION = (3, 6) +PYTHON_VERSION = sys.version_info[0:2] + +DEFAULT_PAGE_ALIGN_SHIFT = 12 +DEFAULT_PAGE_SIZE = 1 << DEFAULT_PAGE_ALIGN_SHIFT + +GEF_RC = os.getenv("GEF_RC") or os.path.join(os.getenv("HOME"), ".gef.rc") +GEF_TEMP_DIR = os.path.join(tempfile.gettempdir(), "gef") +GEF_MAX_STRING_LENGTH = 50 + +LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME = "main_arena" +ANSI_SPLIT_RE = r"(\033\[[\d;]*m)" + +LEFT_ARROW = " \u2190 " +RIGHT_ARROW = " \u2192 " +DOWN_ARROW = "\u21b3" +HORIZONTAL_LINE = "\u2500" +VERTICAL_LINE = "\u2502" +CROSS = "\u2718 " +TICK = "\u2713 " +BP_GLYPH = "\u25cf" +GEF_PROMPT = "gef\u27a4 " +GEF_PROMPT_ON = "\001\033[1;32m\002{0:s}\001\033[0m\002".format(GEF_PROMPT) +GEF_PROMPT_OFF = "\001\033[1;31m\002{0:s}\001\033[0m\002".format(GEF_PROMPT) + + gef = None __registered_commands__ = [] __registered_functions__ = [] -__gef_convenience_vars_index__ = 0 __heap_allocated_list__ = [] __heap_freed_list__ = [] __heap_uaf_watchpoints__ = [] @@ -1198,7 +1197,6 @@ class GlibcArena: Ref: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1671""" def __init__(self, addr): - # self.__name = name or __gef_current_arena__ try: arena = gdb.parse_and_eval(addr) malloc_state_t = cached_lookup_type("struct malloc_state") @@ -1693,7 +1691,7 @@ def hexdump(source, length=0x10, separator=".", show_raw=False, show_symbol=True def is_debug() -> bool: """Check if debug mode is enabled.""" - return gef.config["gef.debug"] == True + return gef.config["gef.debug"] is True def hide_context() -> bool: """ Helper function to hide the context pane """ @@ -3837,9 +3835,9 @@ def dereference(addr): def gef_convenience(value): """Defines a new convenience value.""" - global __gef_convenience_vars_index__ - var_name = "$_gef{:d}".format(__gef_convenience_vars_index__) - __gef_convenience_vars_index__ += 1 + global gef + var_name = "$_gef{:d}".format(gef.session.convenience_vars_index) + gef.session.convenience_vars_index += 1 gdb.execute("""set {:s} = "{:s}" """.format(var_name, value)) return var_name @@ -11365,6 +11363,7 @@ def __init__(self): self.reset_caches() self.remote = None self.qemu_mode = False + self.convenience_vars_index = 0 self.aliases = [] self.constants = {} # a dict for runtime constants (like 3rd party file paths) # add a few extra runtime constants to avoid lookups From 10a97c692c649db81c288d76a27ee3c55491d344 Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 17:52:19 -0800 Subject: [PATCH 37/62] linting --- gef.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/gef.py b/gef.py index 49c0a7cba..51dccac97 100644 --- a/gef.py +++ b/gef.py @@ -56,7 +56,6 @@ import collections import ctypes import enum -from fcntl import F_DUPFD_CLOEXEC import functools import hashlib import importlib @@ -1716,7 +1715,7 @@ def __enter__(self): gdb.execute("set logging on") return - def __exit__(self): + def __exit__(self, *exc): """Disable the output redirection, if any.""" gdb.execute("set logging off") gdb.execute("set logging redirect off") @@ -3361,18 +3360,18 @@ def load_libc_args(): _libc_args_file = "{}/{}.json".format(path, _arch_mode) # current arch and mode already loaded - if _arch_mode in gef.session.highlight_table: + if _arch_mode in gef.ui.highlight_table: return - gef.session.highlight_table[_arch_mode] = {} + gef.ui.highlight_table[_arch_mode] = {} try: with open(_libc_args_file) as _libc_args: - gef.session.highlight_table[_arch_mode] = json.load(_libc_args) + gef.ui.highlight_table[_arch_mode] = json.load(_libc_args) except FileNotFoundError: - del gef.session.highlight_table[_arch_mode] + del gef.ui.highlight_table[_arch_mode] warn("Config context.libc_args is set but definition cannot be loaded: file {} not found".format(_libc_args_file)) except json.decoder.JSONDecodeError as e: - del gef.session.highlight_table[_arch_mode] + del gef.ui.highlight_table[_arch_mode] warn("Config context.libc_args is set but definition cannot be loaded from file {}: {}".format(_libc_args_file, e)) return @@ -8488,7 +8487,7 @@ def __get_current_block_start_address(): if function_name.endswith("@plt"): _function_name = function_name.split("@")[0] try: - nb_argument = len(gef.session.highlight_table[_arch_mode][_function_name]) + nb_argument = len(gef.ui.highlight_table[_arch_mode][_function_name]) except KeyError: pass @@ -8506,7 +8505,7 @@ def __get_current_block_start_address(): _values = RIGHT_ARROW.join(dereference_from(_values)) try: args.append("{} = {} (def: {})".format(Color.colorify(_key, arg_key_color), _values, - gef.session.highlight_table[_arch_mode][_function_name][_key])) + gef.ui.highlight_table[_arch_mode][_function_name][_key])) except KeyError: args.append("{} = {}".format(Color.colorify(_key, arg_key_color), _values)) @@ -11185,7 +11184,7 @@ def __parse_maps(self): """Return the mapped memory sections""" try: return list(self.__parse_procfs_maps()) - except FileNotFoundError as e: + except FileNotFoundError: return list(self.__parse_gdb_info_sections()) def __parse_procfs_maps(self): From ece16627cf3adf65743af9df0e53291d2f94242a Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 7 Jan 2022 18:00:31 -0800 Subject: [PATCH 38/62] moved the last globals to `gef.session` --- gef.py | 102 ++++++++++++++++++++++++++------------------------------- 1 file changed, 46 insertions(+), 56 deletions(-) diff --git a/gef.py b/gef.py index 51dccac97..d2e10a5a2 100644 --- a/gef.py +++ b/gef.py @@ -155,12 +155,6 @@ def update_gef(argv): __registered_commands__ = [] __registered_functions__ = [] -__heap_allocated_list__ = [] -__heap_freed_list__ = [] -__heap_uaf_watchpoints__ = [] -__pie_breakpoints__ = {} -__pie_counter__ = 1 - def reset_all_caches(): """Free all caches. If an object is cached, it will have a callable attribute `cache_clear` @@ -3848,8 +3842,7 @@ def parse_string_range(s): def gef_get_pie_breakpoint(num): - global __pie_breakpoints__ - return __pie_breakpoints__[num] + return gef.session.pie_breakpoints[num] # # Deprecated API @@ -4111,8 +4104,6 @@ def __init__(self, size, name): return def stop(self): - global __heap_uaf_watchpoints__, __heap_freed_list__, __heap_allocated_list__ - if self.return_value: loc = int(self.return_value) else: @@ -4123,22 +4114,22 @@ def stop(self): check_heap_overlap = gef.config["heap-analysis-helper.check_heap_overlap"] # pop from free-ed list if it was in it - if __heap_freed_list__: + if gef.session.heap_freed_chunks: idx = 0 - for item in __heap_freed_list__: + for item in gef.session.heap_freed_chunks: addr = item[0] if addr == loc: - __heap_freed_list__.remove(item) + gef.session.heap_freed_chunks.remove(item) continue idx += 1 # pop from uaf watchlist - if __heap_uaf_watchpoints__: + if gef.session.heap_uaf_watchpoints: idx = 0 - for wp in __heap_uaf_watchpoints__: + for wp in gef.session.heap_uaf_watchpoints: wp_addr = wp.address if loc <= wp_addr < loc + size: - __heap_uaf_watchpoints__.remove(wp) + gef.session.heap_uaf_watchpoints.remove(wp) wp.enabled = False continue idx += 1 @@ -4149,7 +4140,7 @@ def stop(self): # seek all the currently allocated chunks, read their effective size and check for overlap msg = [] align = gef.arch.ptrsize - for chunk_addr, _ in __heap_allocated_list__: + for chunk_addr, _ in gef.session.heap_allocated_chunks: current_chunk = GlibcChunk(chunk_addr) current_chunk_size = current_chunk.get_chunk_size() @@ -4167,7 +4158,7 @@ def stop(self): return True # add it to alloc-ed list - __heap_allocated_list__.append(item) + gef.session.heap_allocated_chunks.append(item) return False @@ -4197,8 +4188,6 @@ def __init__(self, ptr, size): return def stop(self): - global __heap_uaf_watchpoints__, __heap_freed_list__, __heap_allocated_list__ - if self.return_value: newloc = int(self.return_value) else: @@ -4217,15 +4206,15 @@ def stop(self): try: # check if item was in alloc-ed list - idx = [x for x, y in __heap_allocated_list__].index(self.ptr) + idx = [x for x, y in gef.session.heap_allocated_chunks].index(self.ptr) # if so pop it out - item = __heap_allocated_list__.pop(idx) + item = gef.session.heap_allocated_chunks.pop(idx) except ValueError: if is_debug(): warn("Chunk {:#x} was not in tracking list".format(self.ptr)) finally: # add new item to alloc-ed list - __heap_allocated_list__.append(item) + gef.session.heap_allocated_chunks.append(item) return False @@ -4257,7 +4246,7 @@ def stop(self): return True return False - if addr in [x for (x, y) in __heap_freed_list__]: + if addr in [x for (x, y) in gef.session.heap_freed_chunks]: if check_double_free: msg.append(Color.colorify("Heap-Analysis", "yellow bold")) msg.append("Double-free detected {} free({:#x}) is called at {:#x} but is already in the free-ed list".format(RIGHT_ARROW, addr, gef.arch.pc)) @@ -4270,8 +4259,8 @@ def stop(self): # 1. move alloc-ed item to free list try: # pop from alloc-ed list - idx = [x for x, y in __heap_allocated_list__].index(addr) - item = __heap_allocated_list__.pop(idx) + idx = [x for x, y in gef.session.heap_allocated_chunks].index(addr) + item = gef.session.heap_allocated_chunks.pop(idx) except ValueError: if check_weird_free: @@ -4283,7 +4272,7 @@ def stop(self): return False # 2. add it to free-ed list - __heap_freed_list__.append(item) + gef.session.heap_freed_chunks.append(item) self.retbp = None if check_uaf: @@ -4304,7 +4293,7 @@ def __init__(self, addr): def stop(self): reset_all_caches() wp = UafWatchpoint(self.addr) - __heap_uaf_watchpoints__.append(wp) + gef.session.heap_uaf_watchpoints.append(wp) return False @@ -4682,7 +4671,6 @@ class PieBreakpointCommand(GenericCommand): @parse_arguments({"offset": ""}, {}) def do_invoke(self, argv, *args, **kwargs): - global __pie_counter__, __pie_breakpoints__ args = kwargs["arguments"] if not args.offset: self.usage() @@ -4695,15 +4683,14 @@ def do_invoke(self, argv, *args, **kwargs): if is_alive(): vmmap = gef.memory.maps base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] - for bp_ins in __pie_breakpoints__.values(): + for bp_ins in gef.session.pie_breakpoints.values(): bp_ins.instantiate(base_address) return @staticmethod def set_pie_breakpoint(set_func, addr): - global __pie_counter__, __pie_breakpoints__ - __pie_breakpoints__[__pie_counter__] = PieVirtualBreakpoint(set_func, __pie_counter__, addr) - __pie_counter__ += 1 + gef.session.pie_breakpoints[gef.session.pie_counter] = PieVirtualBreakpoint(set_func, gef.session.pie_counter, addr) + gef.session.pie_counter += 1 return @@ -4716,14 +4703,12 @@ class PieInfoCommand(GenericCommand): @parse_arguments({"breakpoints": [-1,]}, {}) def do_invoke(self, argv, *args, **kwargs): - global __pie_breakpoints__ - args = kwargs["arguments"] if args.breakpoints[0] == -1: # No breakpoint info needed - bps = [__pie_breakpoints__[x] for x in __pie_breakpoints__] + bps = [gef.session.pie_breakpoints[x] for x in gef.session.pie_breakpoints] else: - bps = [__pie_breakpoints__[x] for x in args.breakpoints] + bps = [gef.session.pie_breakpoints[x] for x in args.breakpoints] lines = [] lines.append("VNum\tNum\tAddr") @@ -4743,26 +4728,26 @@ class PieDeleteCommand(GenericCommand): @parse_arguments({"breakpoints": [-1,]}, {}) def do_invoke(self, argv, *args, **kwargs): - global __pie_breakpoints__ + global gef args = kwargs["arguments"] if args.breakpoints[0] == -1: # no arg, delete all - to_delete = [__pie_breakpoints__[x] for x in __pie_breakpoints__] + to_delete = [gef.session.pie_breakpoints[x] for x in gef.session.pie_breakpoints] self.delete_bp(to_delete) else: - self.delete_bp([__pie_breakpoints__[x] for x in args.breakpoints]) + self.delete_bp([gef.session.pie_breakpoints[x] for x in args.breakpoints]) return @staticmethod def delete_bp(breakpoints): - global __pie_breakpoints__ + global gef for bp in breakpoints: # delete current real breakpoints if exists if bp.bp_num: gdb.execute("delete {}".format(bp.bp_num)) # delete virtual breakpoints - del __pie_breakpoints__[bp.vbp_num] + del gef.session.pie_breakpoints[bp.vbp_num] return @@ -4774,7 +4759,7 @@ class PieRunCommand(GenericCommand): _syntax_ = _cmdline_ def do_invoke(self, argv): - global __pie_breakpoints__ + global gef fpath = get_filepath() if fpath is None: warn("No executable to debug, use `file` to load a binary") @@ -4798,7 +4783,7 @@ def do_invoke(self, argv): info("base address {}".format(hex(base_address))) # modify all breakpoints - for bp_ins in __pie_breakpoints__.values(): + for bp_ins in gef.session.pie_breakpoints.values(): bp_ins.instantiate(base_address) try: @@ -4827,7 +4812,7 @@ def do_invoke(self, argv): vmmap = gef.memory.maps base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] - for bp_ins in __pie_breakpoints__.values(): + for bp_ins in gef.session.pie_breakpoints.values(): bp_ins.instantiate(base_address) gdb.execute("context") return @@ -4851,7 +4836,7 @@ def do_invoke(self, argv): vmmap = gef.memory.maps base_address = [x.page_start for x in vmmap if x.realpath == get_filepath()][0] - for bp_ins in __pie_breakpoints__.values(): + for bp_ins in gef.session.pie_breakpoints.values(): bp_ins.instantiate(base_address) gdb.execute("context") return @@ -10131,23 +10116,23 @@ def setup(self): return def dump_tracked_allocations(self): - global __heap_allocated_list__, __heap_freed_list__, __heap_uaf_watchpoints__ + global gef - if __heap_allocated_list__: + if gef.session.heap_allocated_chunks: ok("Tracked as in-use chunks:") - for addr, sz in __heap_allocated_list__: gef_print("{} malloc({:d}) = {:#x}".format(CROSS, sz, addr)) + for addr, sz in gef.session.heap_allocated_chunks: gef_print("{} malloc({:d}) = {:#x}".format(CROSS, sz, addr)) else: ok("No malloc() chunk tracked") - if __heap_freed_list__: + if gef.session.heap_freed_chunks: ok("Tracked as free-ed chunks:") - for addr, sz in __heap_freed_list__: gef_print("{} free({:d}) = {:#x}".format(TICK, sz, addr)) + for addr, sz in gef.session.heap_freed_chunks: gef_print("{} free({:d}) = {:#x}".format(TICK, sz, addr)) else: ok("No free() chunk tracked") return def clean(self, event): - global __heap_allocated_list__, __heap_freed_list__, __heap_uaf_watchpoints__ + global gef ok("{} - Cleaning up".format(Color.colorify("Heap-Analysis", "yellow bold"),)) for bp in [self.bp_malloc, self.bp_calloc, self.bp_free, self.bp_realloc]: @@ -10160,12 +10145,12 @@ def clean(self, event): bp.delete() - for wp in __heap_uaf_watchpoints__: + for wp in gef.session.heap_uaf_watchpoints: wp.delete() - __heap_allocated_list__ = [] - __heap_freed_list__ = [] - __heap_uaf_watchpoints__ = [] + gef.session.heap_allocated_chunks = [] + gef.session.heap_freed_chunks = [] + gef.session.heap_uaf_watchpoints = [] ok("{} - Re-enabling hardware watchpoints".format(Color.colorify("Heap-Analysis", "yellow bold"),)) gdb.execute("set can-use-hw-watchpoints 1") @@ -11363,6 +11348,11 @@ def __init__(self): self.remote = None self.qemu_mode = False self.convenience_vars_index = 0 + self.heap_allocated_chunks = [] + self.heap_freed_chunks = [] + self.heap_uaf_watchpoints = [] + self.pie_breakpoints = {} + self.pie_counter = 1 self.aliases = [] self.constants = {} # a dict for runtime constants (like 3rd party file paths) # add a few extra runtime constants to avoid lookups From b95c4aceac3dd6c807f061db3ccbc5bf4592c5a5 Mon Sep 17 00:00:00 2001 From: hugsy Date: Sat, 8 Jan 2022 10:38:58 -0800 Subject: [PATCH 39/62] making `ptrsize` static for x86 and x64 --- gef.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/gef.py b/gef.py index d2e10a5a2..273ec7518 100644 --- a/gef.py +++ b/gef.py @@ -2160,6 +2160,7 @@ class GenericArchitecture(Architecture): mode = "" all_registers = () instruction_length = 0 + ptrsize = 0 return_register = "" function_parameters = () syscall_register = "" @@ -2546,6 +2547,10 @@ class X86(Architecture): syscall_register = "$eax" syscall_instructions = ["sysenter", "int 0x80"] + @property + def ptrsize(self): + return 4 + def flag_register_to_human(self, val=None): reg = self.flag_register if not val: @@ -2664,6 +2669,10 @@ class X86_64(X86): # We don't want to inherit x86's stack based param getter get_ith_parameter = Architecture.get_ith_parameter + @property + def ptrsize(self): + return 8 + @classmethod def mprotect_asm(cls, addr, size, perm): _NR_mprotect = 10 @@ -11450,7 +11459,8 @@ def __init__(self): return class Gef: - """The GEF root class""" + """The GEF root class, which serves as a base classe for all the attributes for the debugging session (architecture, + memory, settings, etc.).""" def __init__(self): self.binary = None self.arch = GenericArchitecture() # see PR #516, will be reset by `new_objfile_handler` @@ -11459,6 +11469,7 @@ def __init__(self): return def reinitialize_managers(self): + """Reinitialize the managers. Avoid calling this function directly, using `pi reset()` is preferred""" self.memory = GefMemoryManager() self.heap = GefHeapManager() self.session = GefSessionManager() @@ -11475,7 +11486,9 @@ def setup(self): return def reset_caches(self): - for mgr in (self.memory, self.heap, self.session, self.ui): + """Recursively clean the cache of all the managers. Avoid calling this function directly, using `reset-cache` + is preferred""" + for mgr in (self.memory, self.heap, self.session): mgr.reset_caches() return From a04cd6401582c0d06f1d26037f50997af1ed2f00 Mon Sep 17 00:00:00 2001 From: hugsy Date: Sat, 8 Jan 2022 10:55:08 -0800 Subject: [PATCH 40/62] making `ptrsize` static for arm, arm64 and mips --- gef.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/gef.py b/gef.py index 273ec7518..2f4b7248f 100644 --- a/gef.py +++ b/gef.py @@ -2326,6 +2326,12 @@ def instruction_length(self): # Thumb instructions have variable-length (2 or 4-byte) return None if self.is_thumb() else 4 + @property + def ptrsize(self): + if not self.__ptrsize: + self.__ptrsize = 2 if self.is_thumb() else 4 + return self.__ptrsize + def is_call(self, insn): mnemo = insn.mnemonic call_mnemos = {"bl", "blx"} @@ -2443,6 +2449,7 @@ class AARCH64(ARM): function_parameters = ["$x0", "$x1", "$x2", "$x3", "$x4", "$x5", "$x6", "$x7"] syscall_register = "$x8" syscall_instructions = ["svc $x0"] + ptrsize = 8 def is_call(self, insn): mnemo = insn.mnemonic @@ -2546,10 +2553,7 @@ class X86(Architecture): } syscall_register = "$eax" syscall_instructions = ["sysenter", "int 0x80"] - - @property - def ptrsize(self): - return 4 + ptrsize = 4 def flag_register_to_human(self, val=None): reg = self.flag_register @@ -2668,10 +2672,7 @@ class X86_64(X86): syscall_instructions = ["syscall"] # We don't want to inherit x86's stack based param getter get_ith_parameter = Architecture.get_ith_parameter - - @property - def ptrsize(self): - return 8 + ptrsize = 8 @classmethod def mprotect_asm(cls, addr, size, perm): @@ -2958,6 +2959,7 @@ class MIPS(Architecture): "$t8", "$t9", "$k0", "$k1", "$s8", "$pc", "$sp", "$hi", "$lo", "$fir", "$ra", "$gp", ] instruction_length = 4 + ptrsize = 4 nop_insn = b"\x00\x00\x00\x00" # sll $0,$0,0 return_register = "$v0" flag_register = "$fcsr" @@ -3027,9 +3029,6 @@ def mprotect_asm(cls, addr, size, perm): return "; ".join(insns) - - - def copy_to_clipboard(data): """Helper function to submit data to the clipboard""" if sys.platform == "linux": From 6514ad39e221e248a1a77a335b812060414696c4 Mon Sep 17 00:00:00 2001 From: hugsy Date: Sat, 8 Jan 2022 11:11:26 -0800 Subject: [PATCH 41/62] restoring MIPS64 --- gef.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gef.py b/gef.py index 2f4b7248f..9170abf16 100644 --- a/gef.py +++ b/gef.py @@ -3029,6 +3029,12 @@ def mprotect_asm(cls, addr, size, perm): return "; ".join(insns) +class MIPS64(MIPS): + arch = "MIPS" + mode = "MIPS64" + ptrsize = 8 + + def copy_to_clipboard(data): """Helper function to submit data to the clipboard""" if sys.platform == "linux": @@ -3628,6 +3634,7 @@ def set_arch(arch=None, default=None): "SPARC": SPARC, Elf.SPARC: SPARC, "SPARC64": SPARC64, Elf.SPARC64: SPARC64, "MIPS": MIPS, Elf.MIPS: MIPS, + "MIPS64": MIPS64, } if arch: @@ -3642,6 +3649,10 @@ def set_arch(arch=None, default=None): gef.binary = elf if elf.is_valid() else None arch_name = gef.binary.e_machine if gef.binary else get_arch() + + if arch_name == "MIPS" and gef.binary.e_class == Elf.ELF_64_BITS: + arch_name = "MIPS64" + try: gef.arch = arches[arch_name]() except KeyError: From bca69dadc10124670e4c6d86ce2aeaa5e690ffcc Mon Sep 17 00:00:00 2001 From: hugsy Date: Sat, 8 Jan 2022 11:16:05 -0800 Subject: [PATCH 42/62] hardcoding endianness for x86,64 and arm,64 --- gef.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gef.py b/gef.py index 9170abf16..8b0d26acb 100644 --- a/gef.py +++ b/gef.py @@ -2305,6 +2305,7 @@ class ARM(Architecture): function_parameters = ["$r0", "$r1", "$r2", "$r3"] syscall_register = "$r7" syscall_instructions = ["swi 0x0", "swi NR"] + endianness = Endianness.LITTLE_ENDIAN def is_thumb(self): """Determine if the machine is currently in THUMB mode.""" @@ -2554,6 +2555,7 @@ class X86(Architecture): syscall_register = "$eax" syscall_instructions = ["sysenter", "int 0x80"] ptrsize = 4 + endianness = Endianness.LITTLE_ENDIAN def flag_register_to_human(self, val=None): reg = self.flag_register From 32941ad45105992908188e9ff7c6803b446868c5 Mon Sep 17 00:00:00 2001 From: hugsy Date: Sat, 8 Jan 2022 12:22:26 -0800 Subject: [PATCH 43/62] added a class decorator to register architectures --- gef.py | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/gef.py b/gef.py index 8b0d26acb..787cf1ec6 100644 --- a/gef.py +++ b/gef.py @@ -154,6 +154,7 @@ def update_gef(argv): gef = None __registered_commands__ = [] __registered_functions__ = [] +__registered_architectures__ = {} def reset_all_caches(): @@ -2049,6 +2050,13 @@ def get_zone_base_address(name): # # Architecture classes # +def register_architecture(cls): + """Class decorator for declaring an architecture to GEF.""" + global __registered_architectures__ + for key in cls.aliases: + __registered_architectures__[key] = cls + return cls + class Architecture(metaclass=abc.ABCMeta): """Generic metaclass for the architecture supported by GEF.""" @@ -2080,6 +2088,7 @@ def is_branch_taken(self, insn): pass @abc.abstractmethod def get_ra(self, insn, frame): pass + aliases = [] special_registers = [] def __get_register(self, regname): @@ -2176,9 +2185,11 @@ def is_branch_taken(self, insn): return False def get_ra(self, insn, frame): return 0 +@register_architecture class RISCV(Architecture): arch = "RISCV" mode = "RISCV" + aliases = ("RISCV") all_registers = ["$zero", "$ra", "$sp", "$gp", "$tp", "$t0", "$t1", "$t2", "$fp", "$s1", "$a0", "$a1", "$a2", "$a3", @@ -2282,9 +2293,10 @@ def get_ra(self, insn, frame): return ra +@register_architecture class ARM(Architecture): + aliases = ("ARM", Elf.ARM) arch = "ARM" - all_registers = ["$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$sp", "$lr", "$pc", "$cpsr",] @@ -2427,7 +2439,9 @@ def mprotect_asm(cls, addr, size, perm): return "; ".join(insns) +@register_architecture class AARCH64(ARM): + aliases = ("ARM64", "AARCH64", Elf.AARCH64) arch = "ARM64" mode = "" @@ -2526,7 +2540,9 @@ def is_branch_taken(self, insn): return taken, reason +@register_architecture class X86(Architecture): + aliases = ("X86", Elf.X86_32) arch = "X86" mode = "32" @@ -2660,7 +2676,9 @@ def get_ith_parameter(self, i, in_func=True): return key, val +@register_architecture class X86_64(X86): + aliases = ("X86_64", Elf.X86_64, "i386:x86-64") arch = "X86" mode = "64" @@ -2701,7 +2719,9 @@ def mprotect_asm(cls, addr, size, perm): return "; ".join(insns) +@register_architecture class PowerPC(Architecture): + aliases = ("PowerPC", Elf.POWERPC, "PPC") arch = "PPC" mode = "PPC32" @@ -2795,15 +2815,19 @@ def mprotect_asm(cls, addr, size, perm): return ";".join(insns) +@register_architecture class PowerPC64(PowerPC): + aliases = ("PowerPC64", Elf.POWERPC64, "PPC64") arch = "PPC" mode = "PPC64" +@register_architecture class SPARC(Architecture): """ Refs: - http://www.cse.scu.edu/~atkinson/teaching/sp05/259/sparc.pdf """ + aliases = ("SPARC", Elf.SPARC) arch = "SPARC" mode = "" @@ -2903,12 +2927,13 @@ def mprotect_asm(cls, addr, size, perm): return "; ".join(insns) +@register_architecture class SPARC64(SPARC): """Refs: - http://math-atlas.sourceforge.net/devel/assembly/abi_sysV_sparc.pdf - https://cr.yp.to/2005-590/sparcv9.pdf """ - + aliases = ("SPARC64", Elf.SPARC64) arch = "SPARC" mode = "V9" @@ -2949,7 +2974,9 @@ def mprotect_asm(cls, addr, size, perm): return "; ".join(insns) +@register_architecture class MIPS(Architecture): + aliases = ("MIPS", Elf.MIPS) arch = "MIPS" mode = "MIPS32" @@ -3031,7 +3058,9 @@ def mprotect_asm(cls, addr, size, perm): return "; ".join(insns) +@register_architecture class MIPS64(MIPS): + aliases = ("MIPS64") arch = "MIPS" mode = "MIPS64" ptrsize = 8 @@ -3625,19 +3654,7 @@ def set_arch(arch=None, default=None): Return the selected arch, or raise an OSError. """ global gef - arches = { - "ARM": ARM, Elf.ARM: ARM, - "AARCH64": AARCH64, "ARM64": AARCH64, Elf.AARCH64: AARCH64, - "X86": X86, Elf.X86_32: X86, - "X86_64": X86_64, Elf.X86_64: X86_64, "i386:x86-64": X86_64, - "PowerPC": PowerPC, "PPC": PowerPC, Elf.POWERPC: PowerPC, - "PowerPC64": PowerPC64, "PPC64": PowerPC64, Elf.POWERPC64: PowerPC64, - "RISCV": RISCV, Elf.RISCV: RISCV, - "SPARC": SPARC, Elf.SPARC: SPARC, - "SPARC64": SPARC64, Elf.SPARC64: SPARC64, - "MIPS": MIPS, Elf.MIPS: MIPS, - "MIPS64": MIPS64, - } + arches = __registered_architectures__ if arch: try: From d5a3bb6185e30419c8380bf1d2fb49692cc35439 Mon Sep 17 00:00:00 2001 From: hugsy Date: Sat, 8 Jan 2022 14:50:21 -0800 Subject: [PATCH 44/62] changed path to `pathlib.Path` (#775) added test for `download_file` --- gef.py | 185 +++++++++++++++++++++------------------------- tests/helpers.py | 13 ++++ tests/runtests.py | 23 +++--- 3 files changed, 109 insertions(+), 112 deletions(-) diff --git a/gef.py b/gef.py index 787cf1ec6..bc16e1ff0 100644 --- a/gef.py +++ b/gef.py @@ -1607,20 +1607,11 @@ def gef_pybytes(x): @lru_cache() def which(program): """Locate a command on the filesystem.""" - - def is_exe(fpath): - return os.path.isfile(fpath) and os.access(fpath, os.X_OK) - - fpath = os.path.split(program)[0] - if fpath: - if is_exe(program): - return program - else: - for path in os.environ["PATH"].split(os.pathsep): - path = path.strip('"') - exe_file = os.path.join(path, program) - if is_exe(exe_file): - return exe_file + for path in os.environ["PATH"].split(os.pathsep): + dirname = pathlib.Path(path) + fpath = dirname / program + if os.access(fpath, os.X_OK): + return fpath raise FileNotFoundError("Missing file `{:s}`".format(program)) @@ -1735,14 +1726,10 @@ def disable_redirect_output(): def gef_makedirs(path, mode=0o755): """Recursive mkdir() creation. If successful, return the absolute path of the directory created.""" - abspath = os.path.expanduser(path) - abspath = os.path.realpath(abspath) - - if os.path.isdir(abspath): - return abspath - - os.makedirs(abspath, mode=mode, exist_ok=True) - return abspath + fpath = pathlib.Path(path) + if not fpath.is_dir(): + fpath.mkdir(mode=mode, exist_ok=True, parents=True) + return fpath.absolute() @lru_cache() @@ -1938,9 +1925,11 @@ def gef_execute_gdb_script(commands): with os.fdopen(fd, "w") as f: f.write(commands) f.flush() - if os.access(fname, os.R_OK): + + fname = pathlib.Path(fname) + if fname.is_file() and os.access(fname, os.R_OK): gdb.execute("source {:s}".format(fname)) - os.unlink(fname) + fname.unlink() return @@ -3182,29 +3171,28 @@ def get_filepath(): return get_path_from_info_proc() -def download_file(target, use_cache=False, local_name=None): - """Download filename `target` inside the mirror tree inside the gef.config["gef.tempdir"]. +def download_file(remote_path, use_cache=False, local_name=None): + """Download filename `remote_path` inside the mirror tree inside the gef.config["gef.tempdir"]. The tree architecture must be gef.config["gef.tempdir"]/gef//. This allow a "chroot-like" tree format.""" try: - local_root = os.path.sep.join([gef.config["gef.tempdir"], str(gef.session.pid)]) + local_root = pathlib.Path(gef.config["gef.tempdir"]) / str(gef.session.pid) if local_name is None: - local_path = os.path.sep.join([local_root, os.path.dirname(target)]) - local_name = os.path.sep.join([local_path, os.path.basename(target)]) + local_path = local_root / remote_path.strip(os.sep) else: - local_path = os.path.sep.join([local_root, os.path.dirname(local_name)]) - local_name = os.path.sep.join([local_path, os.path.basename(local_name)]) + local_path = local_root / local_name.strip(os.sep) - if use_cache and os.access(local_name, os.R_OK): - return local_name + if use_cache and local_path.exists(): + return str(local_path.absolute()) - gef_makedirs(local_path) - gdb.execute("remote get {0:s} {1:s}".format(target, local_name)) + local_path.parent.mkdir(parents=True, exist_ok=True) + gdb.execute("remote get {0:s} {1:s}".format(remote_path, str(local_path.absolute()))) + local_path = str(local_path.absolute()) except gdb.error: # fallback memory view - with open(local_name, "w") as f: + with open(local_path, "w") as f: if is_32bit(): f.write("00000000-ffffffff rwxp 00000000 00:00 0 {}\n".format(get_filepath())) else: @@ -3213,7 +3201,8 @@ def download_file(target, use_cache=False, local_name=None): except Exception as e: err("download_file() failed: {}".format(str(e))) local_name = None - return local_name + + return local_path def get_function_length(sym): @@ -4580,9 +4569,9 @@ class VersionCommand(GenericCommand): _example_ = "{:s}".format(_cmdline_) def do_invoke(self, argv): - gef_fpath = os.path.abspath(os.path.expanduser(inspect.stack()[0][1])) - gef_dir = os.path.dirname(gef_fpath) - with open(gef_fpath, "rb") as f: + gef_fpath = pathlib.Path(inspect.stack()[0][1]).expanduser().absolute() + gef_dir = gef_fpath.parent + with gef_fpath.open("rb") as f: gef_hash = hashlib.sha256(f.read()).hexdigest() if os.access("{}/.git".format(gef_dir), os.X_OK): @@ -5801,8 +5790,8 @@ def import_structures(self, structs): gef_makedirs(path) for struct_name in structs: - fullpath = os.path.join(path, "{}.py".format(struct_name)) - with open(fullpath, "w") as f: + fullpath = pathlib.Path(path) / "{}.py".format(struct_name) + with fullpath.open("w") as f: f.write("from ctypes import *\n\n") f.write("class ") f.write(struct_name) @@ -7730,7 +7719,7 @@ class ProcessListingCommand(GenericCommand): def __init__(self): super().__init__(complete=gdb.COMPLETE_LOCATION) - self["ps_command"] = ( "{:s} auxww".format(gef.session.constants["ps"]), "`ps` command to get process information") + self["ps_command"] = ( "{:s} auxww".format(str(gef.session.constants["ps"])), "`ps` command to get process information") return @parse_arguments({"pattern": ""}, {"--attach": True, "--smart-scan": True}) @@ -11533,65 +11522,63 @@ def reset_caches(self): "Consider updating to GDB {} or higher (with Python {} or higher).".format(".".join(map(str, GDB_MIN_VERSION)), ".".join(map(str, PYTHON_MIN_VERSION)))) exit(1) - else: + try: + pyenv = which("pyenv") + PYENV_ROOT = gef_pystring(subprocess.check_output([pyenv, "root"]).strip()) + PYENV_VERSION = gef_pystring(subprocess.check_output([pyenv, "version-name"]).strip()) + site_packages_dir = os.path.join(PYENV_ROOT, "versions", PYENV_VERSION, "lib", + "python{}".format(PYENV_VERSION[:3]), "site-packages") + site.addsitedir(site_packages_dir) + except FileNotFoundError: + pass + + # When using a Python virtual environment, GDB still loads the system-installed Python + # so GEF doesn't load site-packages dir from environment + # In order to fix it, from the shell with venv activated we run the python binary, + # take and parse its path, add the path to the current python process using sys.path.extend + PYTHONBIN = which("python3") + PREFIX = gef_pystring(subprocess.check_output([PYTHONBIN, '-c', 'import os, sys;print((sys.prefix))'])).strip("\\n") + if PREFIX != sys.base_prefix: + SITE_PACKAGES_DIRS = subprocess.check_output( + [PYTHONBIN, "-c", "import os, sys;print(os.linesep.join(sys.path).strip())"]).decode("utf-8").split() + sys.path.extend(SITE_PACKAGES_DIRS) + + # setup prompt + gdb.prompt_hook = __gef_prompt__ + + # setup config + gdb_initial_settings = ( + "set confirm off", + "set verbose off", + "set pagination off", + "set print elements 0", + "set history save on", + "set history filename ~/.gdb_history", + "set output-radix 0x10", + "set print pretty on", + "set disassembly-flavor intel", + "handle SIGALRM print nopass", + ) + for cmd in gdb_initial_settings: try: - pyenv = which("pyenv") - PYENV_ROOT = gef_pystring(subprocess.check_output([pyenv, "root"]).strip()) - PYENV_VERSION = gef_pystring(subprocess.check_output([pyenv, "version-name"]).strip()) - site_packages_dir = os.path.join(PYENV_ROOT, "versions", PYENV_VERSION, "lib", - "python{}".format(PYENV_VERSION[:3]), "site-packages") - site.addsitedir(site_packages_dir) - except FileNotFoundError: + gdb.execute(cmd) + except gdb.error: pass - # When using a Python virtual environment, GDB still loads the system-installed Python - # so GEF doesn't load site-packages dir from environment - # In order to fix it, from the shell with venv activated we run the python binary, - # take and parse its path, add the path to the current python process using sys.path.extend - - PYTHONBIN = which("python3") - PREFIX = gef_pystring(subprocess.check_output([PYTHONBIN, '-c', 'import os, sys;print((sys.prefix))'])).strip("\\n") - if PREFIX != sys.base_prefix: - SITE_PACKAGES_DIRS = subprocess.check_output( - [PYTHONBIN, "-c", "import os, sys;print(os.linesep.join(sys.path).strip())"]).decode("utf-8").split() - sys.path.extend(SITE_PACKAGES_DIRS) - - # setup prompt - gdb.prompt_hook = __gef_prompt__ - - # setup config - gdb_initial_settings = ( - "set confirm off", - "set verbose off", - "set pagination off", - "set print elements 0", - "set history save on", - "set history filename ~/.gdb_history", - "set output-radix 0x10", - "set print pretty on", - "set disassembly-flavor intel", - "handle SIGALRM print nopass", - ) - for cmd in gdb_initial_settings: - try: - gdb.execute(cmd) - except gdb.error: - pass - - # load GEF - reset() + # load GEF + reset() - # gdb events configuration - gef_on_continue_hook(continue_handler) - gef_on_stop_hook(hook_stop_handler) - gef_on_new_hook(new_objfile_handler) - gef_on_exit_hook(exit_handler) - gef_on_memchanged_hook(memchanged_handler) - gef_on_regchanged_hook(regchanged_handler) + # gdb events configuration + gef_on_continue_hook(continue_handler) + gef_on_stop_hook(hook_stop_handler) + gef_on_new_hook(new_objfile_handler) + gef_on_exit_hook(exit_handler) + gef_on_memchanged_hook(memchanged_handler) + gef_on_regchanged_hook(regchanged_handler) - if gdb.current_progspace().filename is not None: - # if here, we are sourcing gef from a gdb session already attached - # we must force a call to the new_objfile handler (see issue #278) - new_objfile_handler(None) + if gdb.current_progspace().filename is not None: + # if here, we are sourcing gef from a gdb session already attached + # we must force a call to the new_objfile handler (see issue #278) + new_objfile_handler(None) - GefTmuxSetup() + GefTmuxSetup() diff --git a/tests/helpers.py b/tests/helpers.py index 6ff1b7188..154413b2c 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -159,3 +159,16 @@ def _target(name: str, extension: str = ".out") -> Path: if not target.exists(): raise FileNotFoundError(f"Could not find file '{target}'") return target + + +def start_gdbserver(exe=_target("default"), port=1234): + return subprocess.Popen(["gdbserver", f":{port}", exe], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + +def stop_gdbserver(gdbserver): + """Stops the gdbserver and waits until it is terminated if it was + still running. Needed to make the used port available again.""" + if gdbserver.poll() is None: + gdbserver.kill() + gdbserver.wait() + return \ No newline at end of file diff --git a/tests/runtests.py b/tests/runtests.py index 1ffd365cd..0bc631c3a 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -22,7 +22,8 @@ include_for_architectures, ARCH, is_64b, - _target + _target, + start_gdbserver, stop_gdbserver, ) BIN_LS = Path("/bin/ls") @@ -197,18 +198,6 @@ def test_cmd_got(self): return def test_cmd_gef_remote(self): - def start_gdbserver(exe=_target("default"), port=1234): - return subprocess.Popen(["gdbserver", f":{port}", exe], - stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - - def stop_gdbserver(gdbserver): - """Stops the gdbserver and waits until it is terminated if it was - still running. Needed to make the used port available again.""" - if gdbserver.poll() is None: - gdbserver.kill() - gdbserver.wait() - return - before = ["gef-remote :1234"] gdbserver = start_gdbserver() res = gdb_start_silent_cmd("vmmap", before=before) @@ -900,6 +889,14 @@ def test_func_parse_address(self): self.assertException(res) return + def test_func_download_file(self): + gdbsrv = start_gdbserver(BIN_LS) + func = f"download_file('{str(BIN_LS)}')" + res = gdb_test_python_method(func) + stop_gdbserver(gdbsrv) + self.assertNoException(res) + return + class TestGdbFunctionsUnit(GefUnitTestGeneric): """Tests gdb convenience functions added by GEF.""" From 64e311534b8968afd45cbb37f715d25ab51ed8df Mon Sep 17 00:00:00 2001 From: hugsy Date: Sat, 8 Jan 2022 23:00:14 -0800 Subject: [PATCH 45/62] [arm] fix `ptrsize` caching --- gef.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/gef.py b/gef.py index bc16e1ff0..81df1c0b9 100644 --- a/gef.py +++ b/gef.py @@ -2121,29 +2121,29 @@ def sp(self): def fp(self): return self.register("$fp") - __ptrsize = None + _ptrsize = None @property def ptrsize(self): - if not self.__ptrsize: + if not self._ptrsize: res = cached_lookup_type("size_t") if res is not None: - self.__ptrsize = res.sizeof + self._ptrsize = res.sizeof else: - self.__ptrsize = gdb.parse_and_eval("$pc").type.sizeof - return self.__ptrsize + self._ptrsize = gdb.parse_and_eval("$pc").type.sizeof + return self._ptrsize - __endianness = None + _endianness = None @property def endianness(self) -> Endianness: - if not self.__endianness: + if not self._endianness: output = gdb.execute("show endian", to_string=True).strip().lower() if "little endian" in output: - self.__endianness = Endianness.LITTLE_ENDIAN + self._endianness = Endianness.LITTLE_ENDIAN elif "big endian" in output: - self.__endianness = Endianness.BIG_ENDIAN + self._endianness = Endianness.BIG_ENDIAN else: raise OSError(f"No valid endianess found in '{output}'") - return self.__endianness + return self._endianness def get_ith_parameter(self, i, in_func=True): """Retrieves the correct parameter used for the current function call.""" @@ -2330,9 +2330,7 @@ def instruction_length(self): @property def ptrsize(self): - if not self.__ptrsize: - self.__ptrsize = 2 if self.is_thumb() else 4 - return self.__ptrsize + return 2 if self.is_thumb() else 4 def is_call(self, insn): mnemo = insn.mnemonic From 1a430d5e6b09ff8c299305fda8149be4da183f99 Mon Sep 17 00:00:00 2001 From: theguy147 <37738506+theguy147@users.noreply.github.com> Date: Sun, 9 Jan 2022 20:26:20 +0100 Subject: [PATCH 46/62] refactor: add type hints (#774) Co-authored-by: Grazfather --- gef.py | 1571 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 793 insertions(+), 778 deletions(-) diff --git a/gef.py b/gef.py index bc16e1ff0..c59fd6ab3 100644 --- a/gef.py +++ b/gef.py @@ -54,6 +54,7 @@ import binascii import codecs import collections +import configparser import ctypes import enum import functools @@ -76,16 +77,17 @@ import tempfile import time import traceback -import configparser -import xmlrpc.client as xmlrpclib import warnings - +import xmlrpc.client as xmlrpclib from functools import lru_cache from io import StringIO +from types import ModuleType +from typing import (List, Dict, Tuple, Optional, Sequence, Union, Generator, Any, Iterator, + Callable, ByteString, Set, Type) from urllib.request import urlopen -def http_get(url): +def 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.""" try: @@ -97,7 +99,7 @@ def http_get(url): return None -def update_gef(argv): +def update_gef(argv: List[str]) -> int: """Try to update `gef` to the latest version pushed on GitHub master branch. Return 0 on success, 1 on failure. """ ver = "dev" if "--dev" in argv[2:] else "master" @@ -157,7 +159,7 @@ def update_gef(argv): __registered_architectures__ = {} -def reset_all_caches(): +def 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.""" @@ -169,7 +171,7 @@ def reset_all_caches(): gef.reset_caches() return -def reset(): +def reset() -> None: global gef arch = None @@ -186,7 +188,7 @@ def reset(): gef.arch = arch return -def highlight_text(text): +def highlight_text(text: str) -> str: """ Highlight text using gef.ui.highlight_table { match -> color } settings. @@ -221,7 +223,7 @@ def highlight_text(text): return "".join(ansiSplit) -def gef_print(x="", *args, **kwargs): +def gef_print(x: str = "", *args: Tuple, **kwargs: Dict) -> Optional[int]: """Wrapper around print(), using string buffering feature.""" x = highlight_text(x) if gef.ui.stream_buffer and not is_debug(): @@ -229,11 +231,11 @@ def gef_print(x="", *args, **kwargs): return print(x, *args, **kwargs) -def bufferize(f): +def bufferize(f: Callable) -> Callable: """Store the content to be printed for a function in memory, and flush it on function exit.""" @functools.wraps(f) - def wrapper(*args, **kwargs): + def wrapper(*args: Tuple, **kwargs: Dict) -> Any: global gef if gef.ui.stream_buffer: @@ -311,7 +313,7 @@ def u64(x: bytes, s: bool = False) -> int: return struct.unpack(f"{gef.arch.endianness:s}Q", x)[0] if not s else struct.unpack(f"{gef.arch.endianness:s}q", x)[0] -def is_ascii_string(address): +def is_ascii_string(address: int) -> bool: """Helper function to determine if the buffer pointed by `address` is an ASCII string (in GDB)""" try: return gef.memory.read_ascii_string(address) is not None @@ -319,7 +321,7 @@ def is_ascii_string(address): return False -def is_alive(): +def is_alive() -> bool: """Check if GDB is running.""" try: return gdb.selected_inferior().pid > 0 @@ -330,12 +332,11 @@ def is_alive(): # # Decorators # - -def only_if_gdb_running(f): +def only_if_gdb_running(f: Callable) -> Callable: """Decorator wrapper to check if GDB is running.""" @functools.wraps(f) - def wrapper(*args, **kwargs): + def wrapper(*args: Tuple, **kwargs: Dict) -> Any: if is_alive(): return f(*args, **kwargs) else: @@ -344,11 +345,11 @@ def wrapper(*args, **kwargs): return wrapper -def only_if_gdb_target_local(f): +def only_if_gdb_target_local(f: Callable) -> Callable: """Decorator wrapper to check if GDB is running locally (target not remote).""" @functools.wraps(f) - def wrapper(*args, **kwargs): + def wrapper(*args: Tuple, **kwargs: Dict) -> Any: if not is_remote_debug(): return f(*args, **kwargs) else: @@ -357,11 +358,11 @@ def wrapper(*args, **kwargs): return wrapper -def deprecated(solution=""): +def deprecated(solution: str = "") -> Callable: """Decorator to add a warning when a command is obsolete and will be removed.""" - def decorator(f): + def decorator(f: Callable) -> Callable: @functools.wraps(f) - def wrapper(*args, **kwargs): + def wrapper(*args: Tuple, **kwargs: Dict) -> Any: msg = f"'{f.__name__}' is deprecated and will be removed in a feature release. " if solution: msg += solution @@ -371,22 +372,22 @@ def wrapper(*args, **kwargs): return decorator -def experimental_feature(f): +def experimental_feature(f: Callable) -> Callable: """Decorator to add a warning when a feature is experimental.""" @functools.wraps(f) - def wrapper(*args, **kwargs): + def wrapper(*args: Tuple, **kwargs: Dict) -> Any: warn("This feature is under development, expect bugs and unstability...") return f(*args, **kwargs) return wrapper -def only_if_gdb_version_higher_than(required_gdb_version): +def only_if_gdb_version_higher_than(required_gdb_version) -> Callable: """Decorator to check whether current GDB version requirements.""" - def wrapper(f): - def inner_f(*args, **kwargs): + def wrapper(f: Callable) -> Callable: + def inner_f(*args: Tuple, **kwargs: Dict) -> None: if GDB_VERSION >= required_gdb_version: f(*args, **kwargs) else: @@ -396,13 +397,13 @@ def inner_f(*args, **kwargs): return wrapper -def only_if_current_arch_in(valid_architectures): +def only_if_current_arch_in(valid_architectures: List) -> Callable: """Decorator to allow commands for only a subset of the architectured supported by GEF. This decorator is to use lightly, as it goes against the purpose of GEF to support all architectures GDB does. However in some cases, it is necessary.""" - def wrapper(f): - def inner_f(*args, **kwargs): + def wrapper(f: Callable) -> Callable: + def inner_f(*args: Tuple, **kwargs: Dict) -> None: if gef.arch in valid_architectures: f(*args, **kwargs) else: @@ -412,10 +413,10 @@ def inner_f(*args, **kwargs): return wrapper -def only_if_events_supported(event_type): +def only_if_events_supported(event_type) -> Callable: """Checks if GDB supports events without crashing.""" - def wrap(f): - def wrapped_f(*args, **kwargs): + def wrap(f: Callable) -> Callable: + def wrapped_f(*args: Tuple, **kwargs: Dict) -> Any: if getattr(gdb, "events") and getattr(gdb.events, event_type): return f(*args, **kwargs) warn("GDB events cannot be set") @@ -423,18 +424,18 @@ def wrapped_f(*args, **kwargs): return wrap -def FakeExit(*args, **kwargs): +def FakeExit(*args, **kwargs) -> None: raise RuntimeWarning sys.exit = FakeExit -def parse_arguments(required_arguments, optional_arguments): +def parse_arguments(required_arguments: Dict, optional_arguments: Dict) -> Optional[Callable]: """Argument parsing decorator.""" - def int_wrapper(x): return int(x, 0) + def int_wrapper(x: str) -> int: return int(x, 0) - def decorator(f): - def wrapper(*args, **kwargs): + def decorator(f: Callable) -> Optional[Callable]: + def wrapper(*args: Tuple, **kwargs: Dict) -> Optional[Callable]: parser = argparse.ArgumentParser(prog=args[0]._cmdline_, add_help=True) for argname in required_arguments: argvalue = required_arguments[argname] @@ -506,32 +507,32 @@ class Color: } @staticmethod - def redify(msg): return Color.colorify(msg, "red") + def redify(msg: str) -> str: return Color.colorify(msg, "red") @staticmethod - def greenify(msg): return Color.colorify(msg, "green") + def greenify(msg: str) -> str: return Color.colorify(msg, "green") @staticmethod - def blueify(msg): return Color.colorify(msg, "blue") + def blueify(msg: str) -> str: return Color.colorify(msg, "blue") @staticmethod - def yellowify(msg): return Color.colorify(msg, "yellow") + def yellowify(msg: str) -> str: return Color.colorify(msg, "yellow") @staticmethod - def grayify(msg): return Color.colorify(msg, "gray") + def grayify(msg: str) -> str: return Color.colorify(msg, "gray") @staticmethod - def light_grayify(msg):return Color.colorify(msg, "light_gray") + def light_grayify(msg: str) -> str: return Color.colorify(msg, "light_gray") @staticmethod - def pinkify(msg): return Color.colorify(msg, "pink") + def pinkify(msg: str) -> str: return Color.colorify(msg, "pink") @staticmethod - def cyanify(msg): return Color.colorify(msg, "cyan") + def cyanify(msg: str) -> str: return Color.colorify(msg, "cyan") @staticmethod - def boldify(msg): return Color.colorify(msg, "bold") + def boldify(msg: str) -> str: return Color.colorify(msg, "bold") @staticmethod - def underlinify(msg): return Color.colorify(msg, "underline") + def underlinify(msg: str) -> str: return Color.colorify(msg, "underline") @staticmethod - def highlightify(msg): return Color.colorify(msg, "highlight") + def highlightify(msg: str) -> str: return Color.colorify(msg, "highlight") @staticmethod - def blinkify(msg): return Color.colorify(msg, "blink") + def blinkify(msg: str) -> str: return Color.colorify(msg, "blink") @staticmethod - def colorify(text, attrs): + def colorify(text: str, attrs: str) -> str: """Color text according to the given attributes.""" if gef.config["gef.disable_color"] is True: return text @@ -547,14 +548,14 @@ def colorify(text, attrs): class Address: """GEF representation of memory addresses.""" - def __init__(self, *args, **kwargs): - self.value = kwargs.get("value", 0) + def __init__(self, *args, **kwargs) -> None: + self.value: int = kwargs.get("value", 0) self.section = kwargs.get("section", None) self.info = kwargs.get("info", None) - self.valid = kwargs.get("valid", True) + self.valid: bool = kwargs.get("valid", True) return - def __str__(self): + def __str__(self) -> str: value = format_address(self.value) code_color = gef.config["theme.address_code"] stack_color = gef.config["theme.address_stack"] @@ -567,20 +568,20 @@ def __str__(self): return Color.colorify(value, stack_color) return value - def __int__(self): + def __int__(self) -> int: return self.value - def is_in_text_segment(self): + def is_in_text_segment(self) -> bool: return (hasattr(self.info, "name") and ".text" in self.info.name) or \ (hasattr(self.section, "path") and get_filepath() == self.section.path and self.section.is_executable()) - def is_in_stack_segment(self): + def is_in_stack_segment(self) -> bool: return hasattr(self.section, "path") and "[stack]" == self.section.path - def is_in_heap_segment(self): + def is_in_heap_segment(self) -> bool: return hasattr(self.section, "path") and "[heap]" == self.section.path - def dereference(self): + def dereference(self) -> Optional[int]: addr = align_address(int(self.value)) derefed = dereference(addr) return None if derefed is None else int(derefed) @@ -594,26 +595,26 @@ class Permission: EXECUTE = 4 ALL = READ | WRITE | EXECUTE - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: self.value = kwargs.get("value", 0) return - def __or__(self, value): + def __or__(self, value: int) -> int: return self.value | value - def __and__(self, value): + def __and__(self, value: int) -> int: return self.value & value - def __xor__(self, value): + def __xor__(self, value: int) -> int: return self.value ^ value - def __eq__(self, value): + def __eq__(self, value: int) -> int: return self.value == value - def __ne__(self, value): + def __ne__(self, value: int) -> int: return self.value != value - def __str__(self): + def __str__(self) -> str: perm_str = "" perm_str += "r" if self & Permission.READ else "-" perm_str += "w" if self & Permission.WRITE else "-" @@ -621,7 +622,7 @@ def __str__(self): return perm_str @staticmethod - def from_info_sections(*args): + def from_info_sections(*args: List[str]): perm = Permission() for arg in args: if "READONLY" in arg: @@ -633,7 +634,7 @@ def from_info_sections(*args): return perm @staticmethod - def from_process_maps(perm_str): + def from_process_maps(perm_str: str): perm = Permission() if perm_str[0] == "r": perm.value += Permission.READ @@ -647,36 +648,36 @@ def from_process_maps(perm_str): class Section: """GEF representation of process memory sections.""" - def __init__(self, *args, **kwargs): - self.page_start = kwargs.get("page_start") - self.page_end = kwargs.get("page_end") - self.offset = kwargs.get("offset") - self.permission = kwargs.get("permission") + def __init__(self, *args, **kwargs) -> None: + self.page_start: int = kwargs.get("page_start") + self.page_end: int = kwargs.get("page_end") + self.offset: int = kwargs.get("offset") + self.permission: Permission = kwargs.get("permission") self.inode = kwargs.get("inode") - self.path = kwargs.get("path") + self.path: str = kwargs.get("path") return - def is_readable(self): + def is_readable(self) -> bool: return self.permission.value and self.permission.value & Permission.READ - def is_writable(self): + def is_writable(self) -> bool: return self.permission.value and self.permission.value & Permission.WRITE - def is_executable(self): + def is_executable(self) -> bool: return self.permission.value and self.permission.value & Permission.EXECUTE @property - def size(self): + def size(self) -> int: if self.page_end is None or self.page_start is None: return -1 return self.page_end - self.page_start @property - def realpath(self): + def realpath(self) -> str: # when in a `gef-remote` session, realpath returns the path to the binary on the local disk, not remote return self.path if gef.session.remote is None else "/tmp/gef/{:d}/{:s}".format(gef.session.remote, self.path) - def __str__(self): + def __str__(self) -> str: return f"Section({self.page_start:#x}, {self.page_end:#x}, {str(self.permission)})" @@ -686,7 +687,7 @@ class Endianness(enum.Enum): LITTLE_ENDIAN = 1 BIG_ENDIAN = 2 - def __str__(self): + def __str__(self) -> str: if self == Endianness.LITTLE_ENDIAN: return "<" return ">" @@ -729,17 +730,17 @@ class Elf: OSABI_FREEBSD = 0x09 OSABI_OPENBSD = 0x0C - e_magic = ELF_MAGIC - e_class = ELF_32_BITS - e_endianness = Endianness.LITTLE_ENDIAN + e_magic: int = ELF_MAGIC + e_class: int = ELF_32_BITS + e_endianness: int = Endianness.LITTLE_ENDIAN e_eiversion = None e_osabi = None e_abiversion = None - e_pad = None - e_type = ET_EXEC - e_machine = X86_32 + e_pad: int = None + e_type: int = ET_EXEC + e_machine: int = X86_32 e_version = None - e_entry = 0x00 + e_entry: int = 0x00 e_phoff = None e_shoff = None e_flags = None @@ -750,7 +751,7 @@ class Elf: e_shnum = None e_shstrndx = None - def __init__(self, elf="", minimalist=False): + def __init__(self, elf: str = "", minimalist: bool = False) -> None: """ Instantiate an ELF object. The default behavior is to create the object by parsing the ELF file. But in some cases (QEMU-stub), we may just want a simple minimal object with default values.""" @@ -807,10 +808,10 @@ def __init__(self, elf="", minimalist=False): def read(self, size): return self.fd.read(size) - def seek(self, off): + def seek(self, off: int) -> None: self.fd.seek(off, 0) - def is_valid(self): + def is_valid(self) -> bool: return self.e_magic == Elf.ELF_MAGIC @@ -848,9 +849,9 @@ class Phdr: p_memsz = None p_align = None - def __init__(self, elf, off): + def __init__(self, elf: Elf, off: int) -> None: if not elf: - return None + return elf.seek(off) endian = gef.arch.endianness if elf.e_class == Elf.ELF_64_BITS: @@ -929,9 +930,9 @@ class Shdr: sh_addralign = None sh_entsize = None - def __init__(self, elf, off): + def __init__(self, elf, off) -> None: if elf is None: - return None + return elf.seek(off) endian = gef.arch.endianness if elf.e_class == Elf.ELF_64_BITS: @@ -966,13 +967,13 @@ def __init__(self, elf, off): class Instruction: """GEF representation of a CPU instruction.""" - def __init__(self, address, location, mnemo, operands, opcodes): + def __init__(self, address: int, location, mnemo: str, operands, opcodes) -> None: self.address, self.location, self.mnemonic, self.operands, self.opcodes = address, location, mnemo, operands, opcodes return # Allow formatting an instruction with {:o} to show opcodes. # The number of bytes to display can be configured, e.g. {:4o} to only show 4 bytes of the opcodes - def __format__(self, format_spec): + def __format__(self, format_spec: str) -> str: if len(format_spec) == 0 or format_spec[-1] != "o": return str(self) @@ -991,17 +992,17 @@ def __format__(self, format_spec): self.mnemonic, ", ".join(self.operands)) - def __str__(self): + def __str__(self) -> str: return "{:#10x} {:16} {:6} {:s}".format( self.address, self.location, self.mnemonic, ", ".join(self.operands) ) - def is_valid(self): + def is_valid(self) -> bool: return "(bad)" not in self.mnemonic @lru_cache() -def search_for_main_arena(): +def search_for_main_arena(to_string: bool = False) -> Union[int, str]: malloc_hook_addr = parse_address("(void *)&__malloc_hook") if is_x86(): @@ -1011,14 +1012,15 @@ def search_for_main_arena(): else: raise OSError("Cannot find main_arena for {}".format(gef.arch.arch)) - addr = "*0x{:x}".format(addr) + if to_string: + addr = "*0x{:x}".format(addr) return addr class MallocStateStruct: """GEF representation of malloc_state from https://github.com/bminor/glibc/blob/glibc-2.28/malloc/malloc.c#L1658""" - def __init__(self, addr): + def __init__(self, addr: str) -> None: try: self.__addr = parse_address("&{}".format(addr)) except gdb.error: @@ -1050,39 +1052,39 @@ def __init__(self, addr): # struct offsets @property - def addr(self): + def addr(self) -> int: return self.__addr @property - def fastbins_addr(self): + def fastbins_addr(self) -> int: return self.__addr + self.fastbin_offset @property - def top_addr(self): + def top_addr(self) -> int: return self.fastbins_addr + self.num_fastbins * gef.arch.ptrsize @property - def last_remainder_addr(self): + def last_remainder_addr(self) -> int: return self.top_addr + gef.arch.ptrsize @property - def bins_addr(self): + def bins_addr(self) -> int: return self.last_remainder_addr + gef.arch.ptrsize @property - def next_addr(self): + def next_addr(self) -> int: return self.bins_addr + self.num_bins * gef.arch.ptrsize + self.int_size * 4 @property - def next_free_addr(self): + def next_free_addr(self) -> int: return self.next_addr + gef.arch.ptrsize @property - def system_mem_addr(self): + def system_mem_addr(self) -> int: return self.next_free_addr + gef.arch.ptrsize * 2 @property - def struct_size(self): + def struct_size(self) -> int: return self.system_mem_addr + gef.arch.ptrsize * 2 - self.__addr # struct members @@ -1134,7 +1136,7 @@ class GlibcHeapInfo: """Glibc heap_info struct See https://github.com/bminor/glibc/blob/glibc-2.34/malloc/arena.c#L64""" - def __init__(self, addr): + def __init__(self, addr) -> None: self.__addr = addr if type(addr) is int else parse_address(addr) self.size_t = cached_lookup_type("size_t") if not self.size_t: @@ -1142,23 +1144,23 @@ def __init__(self, addr): self.size_t = cached_lookup_type(ptr_type) @property - def addr(self): + def addr(self) -> int: return self.__addr @property - def ar_ptr_addr(self): + def ar_ptr_addr(self) -> int: return self.addr @property - def prev_addr(self): + def prev_addr(self) -> int: return self.ar_ptr_addr + gef.arch.ptrsize @property - def size_addr(self): + def size_addr(self) -> int: return self.prev_addr + gef.arch.ptrsize @property - def mprotect_size_addr(self): + def mprotect_size_addr(self) -> int: return self.size_addr + self.size_t.sizeof @property @@ -1170,11 +1172,11 @@ def prev(self): return self._get_size_t_pointer(self.prev_addr) @property - def size(self): + def size(self) -> int: return self._get_size_t(self.size_addr) @property - def mprotect_size(self): + def mprotect_size(self) -> int: return self._get_size_t(self.mprotect_size_addr) # helper methods @@ -1190,7 +1192,7 @@ class GlibcArena: """Glibc arena class Ref: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1671""" - def __init__(self, addr): + def __init__(self, addr: str) -> None: try: arena = gdb.parse_and_eval(addr) malloc_state_t = cached_lookup_type("struct malloc_state") @@ -1216,7 +1218,7 @@ def __getitem__(self, item): def __getattr__(self, item): return self.__arena[item] - def __int__(self): + def __int__(self) -> int: return self.__addr def __iter__(self): @@ -1232,27 +1234,27 @@ def __iter__(self): yield current_arena return - def __eq__(self, other): + def __eq__(self, other) -> bool: # You cannot have 2 arenas at the same address, so this check should be enough return self.__addr == int(other) - def fastbin(self, i): + def fastbin(self, i: int): # -> Optional[GlibcChunk] """Return head chunk in fastbinsY[i].""" addr = int(self.fastbinsY[i]) if addr == 0: return None return GlibcChunk(addr + 2 * gef.arch.ptrsize) - def bin(self, i): + def bin(self, i: int) -> Tuple[int, int]: idx = i * 2 fd = int(self.bins[idx]) bw = int(self.bins[idx + 1]) return fd, bw - def is_main_arena(self): + def is_main_arena(self) -> bool: return int(self) == int(gef.heap.main_arena) - def heap_addr(self, allow_unaligned=False): + def heap_addr(self, allow_unaligned: bool = False) -> Optional[int]: if self.is_main_arena(): heap_section = gef.heap.base_address if not heap_section: @@ -1275,7 +1277,7 @@ def get_heap_info_list(self): return heap_infos[::-1] @staticmethod - def get_heap_for_ptr(ptr): + def 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""" if is_32bit(): @@ -1312,14 +1314,14 @@ def __init__(self, addr, from_base=False, allow_unaligned=True): self.prev_size_addr = self.base_address return - def get_chunk_size(self): + def get_chunk_size(self) -> int: return gef.memory.read_integer(self.size_addr) & (~0x07) @property - def size(self): + def size(self) -> int: return self.get_chunk_size() - def get_usable_size(self): + def get_usable_size(self) -> int: # https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L4537 cursz = self.get_chunk_size() if cursz == 0: return cursz @@ -1327,10 +1329,10 @@ def get_usable_size(self): return cursz - self.ptrsize @property - def usable_size(self): + def usable_size(self) -> int: return self.get_usable_size() - def get_prev_chunk_size(self): + def get_prev_chunk_size(self) -> int: return gef.memory.read_integer(self.prev_size_addr) def __iter__(self): @@ -1358,15 +1360,15 @@ def __iter__(self): current_chunk = next_chunk return - def get_next_chunk(self, allow_unaligned=False): + def get_next_chunk(self, allow_unaligned: bool = False): # -> GlibcChunk addr = self.get_next_chunk_addr() return GlibcChunk(addr, allow_unaligned=allow_unaligned) - def get_next_chunk_addr(self): + def get_next_chunk_addr(self) -> int: return self.data_address + self.get_chunk_size() # if free-ed functions - def get_fwd_ptr(self, sll): + def get_fwd_ptr(self, sll) -> int: # Not a single-linked-list (sll) or no Safe-Linking support yet if not sll or get_libc_version() < (2, 32): return gef.memory.read_integer(self.data_address) @@ -1375,31 +1377,31 @@ def get_fwd_ptr(self, sll): return gef.memory.read_integer(self.data_address) ^ (self.data_address >> 12) @property - def fwd(self): + def fwd(self) -> int: return self.get_fwd_ptr(False) fd = fwd # for compat - def get_bkw_ptr(self): + def get_bkw_ptr(self) -> int: return gef.memory.read_integer(self.data_address + self.ptrsize) @property - def bck(self): + def bck(self) -> int: return self.get_bkw_ptr() bk = bck # for compat # endif free-ed functions - def has_p_bit(self): - return gef.memory.read_integer(self.size_addr) & 0x01 + def has_p_bit(self) -> bool: + return bool(gef.memory.read_integer(self.size_addr) & 0x01) - def has_m_bit(self): - return gef.memory.read_integer(self.size_addr) & 0x02 + def has_m_bit(self) -> bool: + return bool(gef.memory.read_integer(self.size_addr) & 0x02) - def has_n_bit(self): - return gef.memory.read_integer(self.size_addr) & 0x04 + def has_n_bit(self) -> bool: + return bool(gef.memory.read_integer(self.size_addr) & 0x04) - def is_used(self): + def is_used(self) -> 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""" @@ -1409,14 +1411,14 @@ def is_used(self): next_chunk = self.get_next_chunk() return True if next_chunk.has_p_bit() else False - def str_chunk_size_flag(self): + def str_chunk_size_flag(self) -> str: msg = [] msg.append("PREV_INUSE flag: {}".format(Color.greenify("On") if self.has_p_bit() else Color.redify("Off"))) msg.append("IS_MMAPPED flag: {}".format(Color.greenify("On") if self.has_m_bit() else Color.redify("Off"))) msg.append("NON_MAIN_ARENA flag: {}".format(Color.greenify("On") if self.has_n_bit() else Color.redify("Off"))) return "\n".join(msg) - def _str_sizes(self): + def _str_sizes(self) -> str: msg = [] failed = False @@ -1438,7 +1440,7 @@ def _str_sizes(self): return "\n".join(msg) - def _str_pointers(self): + def _str_pointers(self) -> str: fwd = self.data_address bkw = self.data_address + self.ptrsize @@ -1455,13 +1457,13 @@ def _str_pointers(self): return "\n".join(msg) - def str_as_alloced(self): + def str_as_alloced(self) -> str: return self._str_sizes() - def str_as_freed(self): + def str_as_freed(self) -> str: return "{}\n\n{}".format(self._str_sizes(), self._str_pointers()) - def flags_as_string(self): + def flags_as_string(self) -> str: flags = [] if self.has_p_bit(): flags.append(Color.colorify("PREV_INUSE", "red bold")) @@ -1480,7 +1482,7 @@ def __str__(self): self.flags_as_string()) return msg - def psprint(self): + def psprint(self) -> str: msg = [] msg.append(str(self)) if self.is_used(): @@ -1495,7 +1497,7 @@ def psprint(self): @lru_cache() -def get_libc_version(): +def get_libc_version() -> Tuple[int, ...]: sections = gef.memory.maps for section in sections: match = re.search(r"libc6?[-_](\d+)\.(\d+)\.so", section.path) @@ -1513,7 +1515,7 @@ def get_libc_version(): return 0, 0 -def titlify(text, color=None, msg_color=None): +def titlify(text: str, color: Optional[str] = None, msg_color: Optional[str] = None) -> str: """Print a centered title.""" cols = get_terminal_size()[1] nb = (cols - len(text) - 2) // 2 @@ -1529,13 +1531,23 @@ def titlify(text, color=None, msg_color=None): return "".join(msg) -def err(msg): return gef_print("{} {}".format(Color.colorify("[!]", "bold red"), msg)) -def warn(msg): return gef_print("{} {}".format(Color.colorify("[*]", "bold yellow"), msg)) -def ok(msg): return gef_print("{} {}".format(Color.colorify("[+]", "bold green"), msg)) -def info(msg): return gef_print("{} {}".format(Color.colorify("[+]", "bold blue"), msg)) +def err(msg: str) -> Optional[int]: + return gef_print("{} {}".format(Color.colorify("[!]", "bold red"), msg)) + +def warn(msg: str) -> Optional[int]: + return gef_print("{} {}".format(Color.colorify("[*]", "bold yellow"), msg)) -def push_context_message(level, message): + +def ok(msg: str) -> Optional[int]: + return gef_print("{} {}".format(Color.colorify("[+]", "bold green"), msg)) + + +def info(msg: str) -> Optional[int]: + return gef_print("{} {}".format(Color.colorify("[+]", "bold blue"), msg)) + + +def push_context_message(level: str, message: str) -> None: """Push the message to be displayed the next time the context is invoked.""" if level not in ("error", "warn", "ok", "info"): err("Invalid level '{}', discarding message".format(level)) @@ -1544,14 +1556,14 @@ def push_context_message(level, message): return -def show_last_exception(): +def show_last_exception() -> None: """Display the last Python exception.""" - def _show_code_line(fname, idx): + def _show_code_line(fname: str, idx: int) -> str: fname = os.path.expanduser(os.path.expandvars(fname)) with open(fname, "r") as f: __data = f.readlines() - return __data[idx - 1] if idx < len(__data) else "" + return __data[idx - 1] if 0 < idx < len(__data) else "" gef_print("") exc_type, exc_value, exc_traceback = sys.exc_info() @@ -1591,7 +1603,7 @@ def _show_code_line(fname, idx): return -def gef_pystring(x): +def gef_pystring(x: bytes) -> str: """Returns a sanitized version as string of the bytes list given in input.""" res = str(x, encoding="utf-8") substs = [("\n", "\\n"), ("\r", "\\r"), ("\t", "\\t"), ("\v", "\\v"), ("\b", "\\b"), ] @@ -1599,13 +1611,12 @@ def gef_pystring(x): return res -def gef_pybytes(x): +def gef_pybytes(x: str) -> bytes: """Returns an immutable bytes list from the string given as input.""" return bytes(str(x), encoding="utf-8") - @lru_cache() -def which(program): +def which(program: str) -> Optional[pathlib.Path]: """Locate a command on the filesystem.""" for path in os.environ["PATH"].split(os.pathsep): dirname = pathlib.Path(path) @@ -1616,7 +1627,7 @@ def which(program): raise FileNotFoundError("Missing file `{:s}`".format(program)) -def style_byte(b, color=True): +def style_byte(b: int, color: bool = True) -> str: style = { "nonprintable": "yellow", "printable": "white", @@ -1639,7 +1650,7 @@ def style_byte(b, color=True): return sbyte -def hexdump(source, length=0x10, separator=".", show_raw=False, show_symbol=True, base=0x00): +def hexdump(source: ByteString, length: int = 0x10, separator: str = ".", show_raw: bool = False, show_symbol: bool = True, base: int = 0x00) -> 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 @@ -1689,11 +1700,11 @@ def unhide_context() -> bool: return True class RedirectOutputContext(): - def __init__(self, to="/dev/null"): + def __init__(self, to="/dev/null") -> None: self.redirection_target_file = to return - def __enter__(self): + def __enter__(self) -> None: """Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`.""" gdb.execute("set logging overwrite") gdb.execute("set logging file {:s}".format(self.redirection_target_file)) @@ -1701,14 +1712,14 @@ def __enter__(self): gdb.execute("set logging on") return - def __exit__(self, *exc): + def __exit__(self, *exc) -> None: """Disable the output redirection, if any.""" gdb.execute("set logging off") gdb.execute("set logging redirect off") return @deprecated("Use `RedirectOutputContext()` context manager") -def enable_redirect_output(to_file="/dev/null"): +def 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`.""" gdb.execute("set logging overwrite") gdb.execute("set logging file {:s}".format(to_file)) @@ -1717,14 +1728,14 @@ def enable_redirect_output(to_file="/dev/null"): return @deprecated("Use `RedirectOutputContext()` context manager") -def disable_redirect_output(): +def disable_redirect_output() -> None: """Disable the output redirection, if any.""" gdb.execute("set logging off") gdb.execute("set logging redirect off") return -def gef_makedirs(path, mode=0o755): +def gef_makedirs(path: str, mode: int = 0o755) -> str: """Recursive mkdir() creation. If successful, return the absolute path of the directory created.""" fpath = pathlib.Path(path) if not fpath.is_dir(): @@ -1733,7 +1744,7 @@ def gef_makedirs(path, mode=0o755): @lru_cache() -def gdb_lookup_symbol(sym): +def gdb_lookup_symbol(sym: str): # -> Optional[Tuple[Optional[str], Optional[Tuple[gdb.Symtab_and_line, ...]]]] """Fetch the proper symbol or None if not defined.""" try: return gdb.decode_line(sym)[1] @@ -1742,12 +1753,11 @@ def gdb_lookup_symbol(sym): @lru_cache(maxsize=512) -def gdb_get_location_from_symbol(address): +def gdb_get_location_from_symbol(address: int) -> Optional[Tuple[str, int]]: """Retrieve the location of the `address` argument from the symbol table. Return a tuple with the name and offset if found, None otherwise.""" # this is horrible, ugly hack and shitty perf... # find a *clean* way to get gdb.Location from an address - name = None sym = gdb.execute("info symbol {:#x}".format(address), to_string=True) if sym.startswith("No symbol matches"): return None @@ -1760,7 +1770,7 @@ def gdb_get_location_from_symbol(address): return name, offset -def gdb_disassemble(start_pc, **kwargs): +def gdb_disassemble(start_pc: int, **kwargs: int): # -> Generator[Instruction] """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 @@ -1787,7 +1797,7 @@ def gdb_disassemble(start_pc, **kwargs): yield Instruction(address, location, mnemo, operands, opcodes) -def gdb_get_nth_previous_instruction_address(addr, n): +def gdb_get_nth_previous_instruction_address(addr: int, n: int) -> Optional[int]: """Return the address (Integer) of the `n`-th instruction before `addr`.""" # fixed-length ABI if gef.arch.instruction_length: @@ -1824,7 +1834,7 @@ def gdb_get_nth_previous_instruction_address(addr, n): return None -def gdb_get_nth_next_instruction_address(addr, n): +def gdb_get_nth_next_instruction_address(addr: int, n: int) -> int: """Return the address (Integer) of the `n`-th instruction after `addr`.""" # fixed-length ABI if gef.arch.instruction_length: @@ -1835,28 +1845,28 @@ def gdb_get_nth_next_instruction_address(addr, n): return insn.address -def gef_instruction_n(addr, n): +def gef_instruction_n(addr: int, n: int): # -> Instruction """Return the `n`-th instruction after `addr` as an Instruction object.""" return list(gdb_disassemble(addr, count=n + 1))[n] -def gef_get_instruction_at(addr): +def gef_get_instruction_at(addr: int): # -> Instruction """Return the full Instruction found at the specified address.""" insn = next(gef_disassemble(addr, 1)) return insn -def gef_current_instruction(addr): +def gef_current_instruction(addr: int): # -> Instruction """Return the current instruction as an Instruction object.""" return gef_instruction_n(addr, 0) -def gef_next_instruction(addr): +def gef_next_instruction(addr: int): # -> Instruction """Return the next instruction as an Instruction object.""" return gef_instruction_n(addr, 1) -def gef_disassemble(addr, nb_insn, nb_prev=0): +def gef_disassemble(addr: int, nb_insn: int, nb_prev: int = 0): # -> Generator[Instruction] """Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr`. Return an iterator of Instruction objects.""" nb_insn = max(1, nb_insn) @@ -1872,12 +1882,12 @@ def gef_disassemble(addr, nb_insn, nb_prev=0): yield insn -def capstone_disassemble(location, nb_insn, **kwargs): +def capstone_disassemble(location: int, nb_insn: int, **kwargs): # -> Generator[Instruction] """Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr` using the Capstone-Engine disassembler, if available. Return an iterator of Instruction objects.""" - def cs_insn_to_gef_insn(cs_insn): + def cs_insn_to_gef_insn(cs_insn): # -> Instruction sym_info = gdb_get_location_from_symbol(cs_insn.address) loc = "<{}+{}>".format(*sym_info) if sym_info else "" ops = [] + cs_insn.op_str.split(", ") @@ -1912,13 +1922,13 @@ def cs_insn_to_gef_insn(cs_insn): return -def gef_execute_external(command, as_list=False, *args, **kwargs): +def gef_execute_external(command: Sequence[str], as_list: bool = False, **kwargs) -> Union[str, List[str]]: """Execute an external command and return the result.""" res = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=kwargs.get("shell", False)) return [gef_pystring(_) for _ in res.splitlines()] if as_list else gef_pystring(res) -def gef_execute_gdb_script(commands): +def 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.""" fd, fname = tempfile.mkstemp(suffix=".gdb", prefix="gef_") @@ -1934,7 +1944,7 @@ def gef_execute_gdb_script(commands): @lru_cache(32) -def checksec(filename): +def checksec(filename: str) -> Dict[str, bool]: """Check the security property of the ELF binary. The following properties are: - Canary - NX @@ -1945,7 +1955,7 @@ def checksec(filename): associated whether the protection was found.""" readelf = gef.session.constants["readelf"] - def __check_security_property(opt, filename, pattern): + def __check_security_property(opt: str, filename: str, pattern: str) -> bool: cmd = [readelf,] cmd += opt.split() cmd += [filename,] @@ -1970,7 +1980,7 @@ def __check_security_property(opt, filename, pattern): @lru_cache() -def get_arch(): +def get_arch() -> str: """Return the binary's architecture.""" if is_alive(): arch = gdb.selected_frame().architecture() @@ -1992,7 +2002,7 @@ def get_arch(): @lru_cache() -def get_entry_point(): +def get_entry_point() -> Optional[int]: """Return the binary entry point.""" for line in gdb.execute("info target", to_string=True).split("\n"): @@ -2002,21 +2012,21 @@ def get_entry_point(): return None -def is_pie(fpath): +def is_pie(fpath: str) -> bool: return checksec(fpath)["PIE"] @deprecated("Prefer `gef.arch.endianness == Endianness.BIG_ENDIAN`") -def is_big_endian(): +def is_big_endian() -> bool: return gef.arch.endianness == Endianness.BIG_ENDIAN @deprecated("gef.arch.endianness == Endianness.LITTLE_ENDIAN") -def is_little_endian(): +def is_little_endian() -> bool: return gef.arch.endianness == Endianness.LITTLE_ENDIAN -def flags_to_human(reg_value, value_table): +def flags_to_human(reg_value: int, value_table: Dict[int, str]) -> str: """Return a human readable string showing the flag states.""" flags = [] for i in value_table: @@ -2026,13 +2036,13 @@ def flags_to_human(reg_value, value_table): @lru_cache() -def get_section_base_address(name): +def get_section_base_address(name: str) -> Optional[int]: section = process_lookup_path(name) return section.page_start if section else None @lru_cache() -def get_zone_base_address(name): +def get_zone_base_address(name: str) -> Optional[int]: zone = file_lookup_name_path(name, get_filepath()) return zone.zone_start if zone else None @@ -2051,42 +2061,42 @@ class Architecture(metaclass=abc.ABCMeta): """Generic metaclass for the architecture supported by GEF.""" @abc.abstractproperty - def all_registers(self): pass + def all_registers(self): pass @abc.abstractproperty - def instruction_length(self): pass + def instruction_length(self) -> Optional[int]: pass @abc.abstractproperty - def nop_insn(self): pass + def nop_insn(self): pass @abc.abstractproperty - def return_register(self): pass + def return_register(self): pass @abc.abstractproperty - def flag_register(self): pass + def flag_register(self): pass @abc.abstractproperty - def flags_table(self): pass + def flags_table(self): pass @abc.abstractproperty - def function_parameters(self): pass + def function_parameters(self) -> List[str]: pass @abc.abstractmethod - def flag_register_to_human(self, val=None): pass + def flag_register_to_human(self, val: Optional[int] = None) -> str: pass @abc.abstractmethod - def is_call(self, insn): pass + def is_call(self, insn) -> bool: pass @abc.abstractmethod - def is_ret(self, insn): pass + def is_ret(self, insn) -> Optional[bool]: pass @abc.abstractmethod - def is_conditional_branch(self, insn): pass + def is_conditional_branch(self, insn) -> bool: pass @abc.abstractmethod - def is_branch_taken(self, insn): pass + def is_branch_taken(self, insn) -> Tuple[bool, str]: pass @abc.abstractmethod - def get_ra(self, insn, frame): pass + def get_ra(self, insn, frame) -> Optional[int]: pass aliases = [] special_registers = [] - def __get_register(self, regname): + def __get_register(self, regname: str) -> Optional[int]: """Return a register's value.""" curframe = gdb.selected_frame() key = curframe.pc() ^ int(curframe.read_register('sp')) # todo: check when/if gdb.Frame implements `level()` return self.__get_register_for_selected_frame(regname, key) - def __get_register_for_selected_frame(self, regname, hash_key): + def __get_register_for_selected_frame(self, regname: str, hash_key) -> Optional[int]: # 1st chance try: return parse_address(regname) @@ -2102,28 +2112,28 @@ def __get_register_for_selected_frame(self, regname, hash_key): pass return None - def register(self, name): + def register(self, name: str) -> Optional[int]: return self.__get_register(name) @property - def registers(self): + def registers(self) -> Generator[str, None, None]: yield from self.all_registers @property - def pc(self): + def pc(self) -> Optional[int]: return self.register("$pc") @property - def sp(self): + def sp(self) -> Optional[int]: return self.register("$sp") @property - def fp(self): + def fp(self) -> Optional[int]: return self.register("$fp") __ptrsize = None @property - def ptrsize(self): + def ptrsize(self) -> int: if not self.__ptrsize: res = cached_lookup_type("size_t") if res is not None: @@ -2134,7 +2144,7 @@ def ptrsize(self): __endianness = None @property - def endianness(self) -> Endianness: + def endianness(self): # -> Endianness if not self.__endianness: output = gdb.execute("show endian", to_string=True).strip().lower() if "little endian" in output: @@ -2145,7 +2155,7 @@ def endianness(self) -> Endianness: raise OSError(f"No valid endianess found in '{output}'") return self.__endianness - def get_ith_parameter(self, i, in_func=True): + def get_ith_parameter(self, i: int, in_func: bool = True) -> Tuple[str, Optional[int]]: """Retrieves the correct parameter used for the current function call.""" reg = self.function_parameters[i] val = self.register(reg) @@ -2166,12 +2176,12 @@ class GenericArchitecture(Architecture): nop_insn = b"" flag_register = None flags_table = None - def flag_register_to_human(self, val=None): return "" - def is_call(self, insn): return False - def is_ret(self, insn): return False - def is_conditional_branch(self, insn): return False - def is_branch_taken(self, insn): return False - def get_ra(self, insn, frame): return 0 + def flag_register_to_human(self, val: Optional[int] = None) -> Optional[str]: return "" + def is_call(self, insn) -> bool: return False + def is_ret(self, insn) -> bool: return False + def is_conditional_branch(self, insn) -> bool: return False + def is_branch_taken(self, insn) -> Tuple[bool, str]: return False, "" + def get_ra(self, insn, frame) -> Optional[int]: return 0 @register_architecture @@ -2196,13 +2206,13 @@ class RISCV(Architecture): flags_table = None @property - def instruction_length(self): + def instruction_length(self) -> int: return 4 - def is_call(self, insn): + def is_call(self, insn) -> bool: return insn.mnemonic == "call" - def is_ret(self, insn): + def is_ret(self, insn) -> bool: mnemo = insn.mnemonic if mnemo == "ret": return True @@ -2214,14 +2224,14 @@ def is_ret(self, insn): return False @classmethod - def mprotect_asm(cls, addr, size, perm): + def mprotect_asm(cls, addr: int, size: int, perm): raise OSError("Architecture {:s} not supported yet".format(cls.arch)) - def is_conditional_branch(self, insn): + def is_conditional_branch(self, insn) -> bool: return insn.mnemonic.startswith("b") - def is_branch_taken(self, insn): - def long_to_twos_complement(v): + def is_branch_taken(self, insn) -> Tuple[bool, str]: + def long_to_twos_complement(v: int) -> int: """Convert a python long value to its two's complement.""" if is_32bit(): if v & 0x80000000: @@ -2273,7 +2283,7 @@ def long_to_twos_complement(v): return taken, reason - def get_ra(self, insn, frame): + def get_ra(self, insn, frame) -> int: ra = None if self.is_ret(insn): ra = gef.arch.register("$ra") @@ -2308,23 +2318,23 @@ class ARM(Architecture): syscall_instructions = ["swi 0x0", "swi NR"] endianness = Endianness.LITTLE_ENDIAN - def is_thumb(self): + def is_thumb(self) -> bool: """Determine if the machine is currently in THUMB mode.""" return is_alive() and gef.arch.register(self.flag_register) & (1 << 5) @property - def pc(self): + def pc(self) -> Optional[int]: pc = gef.arch.register("$pc") if self.is_thumb(): pc += 1 return pc @property - def mode(self): + def mode(self) -> str: return "THUMB" if self.is_thumb() else "ARM" @property - def instruction_length(self): + def instruction_length(self) -> Optional[int]: # Thumb instructions have variable-length (2 or 4-byte) return None if self.is_thumb() else 4 @@ -2334,12 +2344,12 @@ def ptrsize(self): self.__ptrsize = 2 if self.is_thumb() else 4 return self.__ptrsize - def is_call(self, insn): + def is_call(self, insn) -> bool: mnemo = insn.mnemonic call_mnemos = {"bl", "blx"} return mnemo in call_mnemos - def is_ret(self, insn): + def is_ret(self, insn) -> Optional[bool]: pop_mnemos = {"pop"} branch_mnemos = {"bl", "bx"} write_mnemos = {"ldr", "add"} @@ -2351,18 +2361,18 @@ def is_ret(self, insn): return insn.operands[0] == "pc" return - def flag_register_to_human(self, val=None): + def flag_register_to_human(self, val: Optional[int] = None) -> str: # http://www.botskool.com/user-pages/tutorials/electronics/arm-7-tutorial-part-1 if val is None: reg = self.flag_register val = gef.arch.register(reg) return flags_to_human(val, self.flags_table) - def is_conditional_branch(self, insn): + def is_conditional_branch(self, insn) -> bool: conditions = {"eq", "ne", "lt", "le", "gt", "ge", "vs", "vc", "mi", "pl", "hi", "ls", "cc", "cs"} return insn.mnemonic[-2:] in conditions - def is_branch_taken(self, insn): + def is_branch_taken(self, insn) -> Tuple[bool, str]: mnemo = insn.mnemonic # ref: http://www.davespace.co.uk/arm/introduction-to-arm/conditional.html flags = dict((self.flags_table[k], k) for k in self.flags_table) @@ -2395,7 +2405,7 @@ def is_branch_taken(self, insn): elif mnemo.endswith("cc"): taken, reason = not val&(1< int: ra = None if self.is_ret(insn): # If it's a pop, we have to peek into the stack, otherwise use lr @@ -2411,7 +2421,7 @@ def get_ra(self, insn, frame): return ra @classmethod - def mprotect_asm(cls, addr, size, perm): + def mprotect_asm(cls, addr: int, size: int, perm) -> str: _NR_mprotect = 125 insns = [ "push {r0-r2, r7}", @@ -2455,12 +2465,12 @@ class AARCH64(ARM): syscall_instructions = ["svc $x0"] ptrsize = 8 - def is_call(self, insn): + def is_call(self, insn) -> bool: mnemo = insn.mnemonic call_mnemos = {"bl", "blr"} return mnemo in call_mnemos - def flag_register_to_human(self, val=None): + def flag_register_to_human(self, val: Optional[int] = None) -> str: # http://events.linuxfoundation.org/sites/events/files/slides/KoreaLinuxForum-2014.pdf reg = self.flag_register if not val: @@ -2468,7 +2478,7 @@ def flag_register_to_human(self, val=None): return flags_to_human(val, self.flags_table) @classmethod - def mprotect_asm(cls, addr, size, perm): + def mprotect_asm(cls, addr: int, size: int, perm) -> str: _NR_mprotect = 226 insns = [ "str x8, [sp, -16]!", @@ -2491,14 +2501,14 @@ def mprotect_asm(cls, addr, size, perm): ] return "; ".join(insns) - def is_conditional_branch(self, insn): + def is_conditional_branch(self, insn) -> bool: # https://www.element14.com/community/servlet/JiveServlet/previewBody/41836-102-1-229511/ARM.Reference_Manual.pdf # sect. 5.1.1 mnemo = insn.mnemonic branch_mnemos = {"cbnz", "cbz", "tbnz", "tbz"} return mnemo.startswith("b.") or mnemo in branch_mnemos - def is_branch_taken(self, insn): + def is_branch_taken(self, insn) -> Tuple[bool, str]: mnemo, operands = insn.mnemonic, insn.operands taken, reason = False, "" @@ -2562,21 +2572,21 @@ class X86(Architecture): ptrsize = 4 endianness = Endianness.LITTLE_ENDIAN - def flag_register_to_human(self, val=None): + def flag_register_to_human(self, val: Optional[int] = None) -> str: reg = self.flag_register if not val: val = gef.arch.register(reg) return flags_to_human(val, self.flags_table) - def is_call(self, insn): + def is_call(self, insn) -> bool: mnemo = insn.mnemonic call_mnemos = {"call", "callq"} return mnemo in call_mnemos - def is_ret(self, insn): + def is_ret(self, insn) -> bool: return insn.mnemonic == "ret" - def is_conditional_branch(self, insn): + def is_conditional_branch(self, insn) -> bool: mnemo = insn.mnemonic branch_mnemos = { "ja", "jnbe", "jae", "jnb", "jnc", "jb", "jc", "jnae", "jbe", "jna", @@ -2586,7 +2596,7 @@ def is_conditional_branch(self, insn): } return mnemo in branch_mnemos - def is_branch_taken(self, insn): + def is_branch_taken(self, insn) -> Tuple[bool, str]: mnemo = insn.mnemonic # all kudos to fG! (https://github.com/gdbinit/Gdbinit/blob/master/gdbinit#L1654) flags = dict((self.flags_table[k], k) for k in self.flags_table) @@ -2631,7 +2641,7 @@ def is_branch_taken(self, insn): taken, reason = not val&(1< Optional[int]: ra = None if self.is_ret(insn): ra = to_unsigned_long(dereference(gef.arch.sp)) @@ -2641,7 +2651,7 @@ def get_ra(self, insn, frame): return ra @classmethod - def mprotect_asm(cls, addr, size, perm): + def mprotect_asm(cls, addr: int, size: int, perm) -> str: _NR_mprotect = 125 insns = [ "pushad", @@ -2654,7 +2664,7 @@ def mprotect_asm(cls, addr, size, perm): ] return "; ".join(insns) - def get_ith_parameter(self, i, in_func=True): + def get_ith_parameter(self, i: int, in_func: bool = True) -> Tuple[str, Optional[int]]: if in_func: i += 1 # Account for RA being at the top of the stack sp = gef.arch.sp @@ -2684,7 +2694,7 @@ class X86_64(X86): ptrsize = 8 @classmethod - def mprotect_asm(cls, addr, size, perm): + def mprotect_asm(cls, addr: int, size: int, perm) -> str: _NR_mprotect = 10 insns = [ "push rax", @@ -2739,25 +2749,25 @@ class PowerPC(Architecture): syscall_register = "$r0" syscall_instructions = ["sc"] - def flag_register_to_human(self, val=None): + def flag_register_to_human(self, val: Optional[int] = None) -> str: # http://www.cebix.net/downloads/bebox/pem32b.pdf (% 2.1.3) if not val: reg = self.flag_register val = gef.arch.register(reg) return flags_to_human(val, self.flags_table) - def is_call(self, insn): + def is_call(self, insn) -> bool: return False - def is_ret(self, insn): + def is_ret(self, insn) -> bool: return insn.mnemonic == "blr" - def is_conditional_branch(self, insn): + def is_conditional_branch(self, insn) -> bool: mnemo = insn.mnemonic branch_mnemos = {"beq", "bne", "ble", "blt", "bgt", "bge"} return mnemo in branch_mnemos - def is_branch_taken(self, insn): + def is_branch_taken(self, insn) -> Tuple[bool, str]: mnemo = insn.mnemonic flags = dict((self.flags_table[k], k) for k in self.flags_table) val = gef.arch.register(self.flag_register) @@ -2770,7 +2780,7 @@ def is_branch_taken(self, insn): elif mnemo == "bgt": taken, reason = val&(1< Optional[int]: ra = None if self.is_ret(insn): ra = gef.arch.register("$lr") @@ -2779,7 +2789,7 @@ def get_ra(self, insn, frame): return ra @classmethod - def mprotect_asm(cls, addr, size, perm): + def mprotect_asm(cls, addr: int, size: int, perm) -> str: # Ref: http://www.ibm.com/developerworks/library/l-ppc/index.html _NR_mprotect = 125 insns = [ @@ -2842,20 +2852,20 @@ class SPARC(Architecture): syscall_register = "%g1" syscall_instructions = ["t 0x10"] - def flag_register_to_human(self, val=None): + def flag_register_to_human(self, val: Optional[int] = None) -> str: # http://www.gaisler.com/doc/sparcv8.pdf reg = self.flag_register if not val: val = gef.arch.register(reg) return flags_to_human(val, self.flags_table) - def is_call(self, insn): + def is_call(self, insn) -> bool: return False - def is_ret(self, insn): + def is_ret(self, insn) -> bool: return insn.mnemonic == "ret" - def is_conditional_branch(self, insn): + def is_conditional_branch(self, insn) -> bool: mnemo = insn.mnemonic # http://moss.csc.ncsu.edu/~mueller/codeopt/codeopt00/notes/condbranch.html branch_mnemos = { @@ -2864,7 +2874,7 @@ def is_conditional_branch(self, insn): } return mnemo in branch_mnemos - def is_branch_taken(self, insn): + def is_branch_taken(self, insn) -> Tuple[bool, str]: mnemo = insn.mnemonic flags = dict((self.flags_table[k], k) for k in self.flags_table) val = gef.arch.register(self.flag_register) @@ -2888,7 +2898,7 @@ def is_branch_taken(self, insn): elif mnemo == "bcc": taken, reason = val&(1< Optional[int]: ra = None if self.is_ret(insn): ra = gef.arch.register("$o7") @@ -2897,7 +2907,7 @@ def get_ra(self, insn, frame): return ra @classmethod - def mprotect_asm(cls, addr, size, perm): + def mprotect_asm(cls, addr: int, size: int, perm) -> str: hi = (addr & 0xffff0000) >> 16 lo = (addr & 0x0000ffff) _NR_mprotect = 125 @@ -2944,7 +2954,7 @@ class SPARC64(SPARC): syscall_instructions = ["t 0x6d"] @classmethod - def mprotect_asm(cls, addr, size, perm): + def mprotect_asm(cls, addr: int, size: int, perm) -> str: hi = (addr & 0xffff0000) >> 16 lo = (addr & 0x0000ffff) _NR_mprotect = 125 @@ -2986,21 +2996,21 @@ class MIPS(Architecture): syscall_register = "$v0" syscall_instructions = ["syscall"] - def flag_register_to_human(self, val=None): + def flag_register_to_human(self, val: Optional[int] = None) -> str: return Color.colorify("No flag register", "yellow underline") - def is_call(self, insn): + def is_call(self, insn) -> bool: return False - def is_ret(self, insn): + def is_ret(self, insn) -> bool: return insn.mnemonic == "jr" and insn.operands[0] == "ra" - def is_conditional_branch(self, insn): + def is_conditional_branch(self, insn) -> bool: mnemo = insn.mnemonic branch_mnemos = {"beq", "bne", "beqz", "bnez", "bgtz", "bgez", "bltz", "blez"} return mnemo in branch_mnemos - def is_branch_taken(self, insn): + def is_branch_taken(self, insn) -> Tuple[bool, str]: mnemo, ops = insn.mnemonic, insn.operands taken, reason = False, "" @@ -3022,7 +3032,7 @@ def is_branch_taken(self, insn): taken, reason = gef.arch.register(ops[0]) <= 0, "{0[0]} <= 0".format(ops) return taken, reason - def get_ra(self, insn, frame): + def get_ra(self, insn, frame) -> Optional[int]: ra = None if self.is_ret(insn): ra = gef.arch.register("$ra") @@ -3031,7 +3041,7 @@ def get_ra(self, insn, frame): return ra @classmethod - def mprotect_asm(cls, addr, size, perm): + def mprotect_asm(cls, addr: int, size: int, perm) -> str: _NR_mprotect = 4125 insns = ["addi $sp, $sp, -16", "sw $v0, 0($sp)", "sw $a0, 4($sp)", @@ -3055,7 +3065,7 @@ class MIPS64(MIPS): ptrsize = 8 -def copy_to_clipboard(data): +def copy_to_clipboard(data: str) -> None: """Helper function to submit data to the clipboard""" if sys.platform == "linux": xclip = which("xclip") @@ -3073,31 +3083,31 @@ def copy_to_clipboard(data): return -def use_stdtype(): +def use_stdtype() -> str: if is_32bit(): return "uint32_t" elif is_64bit(): return "uint64_t" return "uint16_t" -def use_default_type(): +def use_default_type() -> str: if is_32bit(): return "unsigned int" elif is_64bit(): return "unsigned long" return "unsigned short" -def use_golang_type(): +def use_golang_type() -> str: if is_32bit(): return "uint32" elif is_64bit(): return "uint64" return "uint16" -def use_rust_type(): +def use_rust_type() -> str: if is_32bit(): return "u32" elif is_64bit(): return "u64" return "u16" -def to_unsigned_long(v): +def to_unsigned_long(v) -> int: """Cast a gdb.Value to unsigned long.""" mask = (1 << 64) - 1 return int(v.cast(gdb.Value(mask).type)) & mask @@ -3111,12 +3121,12 @@ def get_path_from_info_proc(): @deprecated("Use `gef.session.os`") -def get_os(): +def get_os() -> str: return gef.session.os @lru_cache() -def is_qemu(): +def is_qemu() -> bool: if not is_remote_debug(): return False response = gdb.execute('maintenance packet Qqemu.sstepbits', to_string=True, from_tty=False) @@ -3124,7 +3134,7 @@ def is_qemu(): @lru_cache() -def is_qemu_usermode(): +def is_qemu_usermode() -> bool: if not is_qemu(): return False response = gdb.execute('maintenance packet QOffsets', to_string=True, from_tty=False) @@ -3132,7 +3142,7 @@ def is_qemu_usermode(): @lru_cache() -def is_qemu_system(): +def is_qemu_system() -> bool: if not is_qemu(): return False response = gdb.execute('maintenance packet QOffsets', to_string=True, from_tty=False) @@ -3140,7 +3150,7 @@ def is_qemu_system(): @lru_cache() -def get_filepath(): +def get_filepath() -> Optional[str]: """Return the local absolute path of the file currently debugged.""" filename = gdb.current_progspace().filename @@ -3171,7 +3181,7 @@ def get_filepath(): return get_path_from_info_proc() -def download_file(remote_path, use_cache=False, local_name=None): +def download_file(remote_path: str, use_cache: bool = False, local_name: Optional[str] = None) -> Optional[str]: """Download filename `remote_path` inside the mirror tree inside the gef.config["gef.tempdir"]. The tree architecture must be gef.config["gef.tempdir"]/gef//. This allow a "chroot-like" tree format.""" @@ -3214,7 +3224,7 @@ def get_function_length(sym): @lru_cache() -def get_info_files(): +def get_info_files(): # -> List[Zone] """Retrieve all the files loaded by debuggee.""" lines = gdb.execute("info files", to_string=True).splitlines() infos = [] @@ -3240,7 +3250,7 @@ def get_info_files(): return infos -def process_lookup_address(address): +def process_lookup_address(address: int): # -> Optional[Section] """Look up for an address in memory. Return an Address object if found, None otherwise.""" if not is_alive(): @@ -3259,7 +3269,7 @@ def process_lookup_address(address): @lru_cache() -def process_lookup_path(name, perm=Permission.ALL): +def process_lookup_path(name: str, perm=Permission.ALL): # -> Optional[Section] """Look up for a path in the process memory mapping. Return a Section object if found, None otherwise.""" if not is_alive(): @@ -3274,7 +3284,7 @@ def process_lookup_path(name, perm=Permission.ALL): @lru_cache() -def file_lookup_name_path(name, path): +def file_lookup_name_path(name: str, path: str): # -> Optional[Zone] """Look up a file by name and path. Return a Zone object if found, None otherwise.""" for xfile in get_info_files(): @@ -3284,7 +3294,7 @@ def file_lookup_name_path(name, path): @lru_cache() -def file_lookup_address(address): +def file_lookup_address(address: int): # -> Optional[Zone] """Look up for a file by its address. Return a Zone object if found, None otherwise.""" for info in get_info_files(): @@ -3294,7 +3304,7 @@ def file_lookup_address(address): @lru_cache() -def lookup_address(address): +def lookup_address(address: int): # -> Address """Try to find the address in the process address space. Return an Address object, with validity flag set based on success.""" sect = process_lookup_address(address) @@ -3305,14 +3315,14 @@ def lookup_address(address): return Address(value=address, section=sect, info=info) -def xor(data, key): +def xor(data: ByteString, key: str) -> bytearray: """Return `data` xor-ed with `key`.""" key = key.lstrip("0x") key = binascii.unhexlify(key) return bytearray(x ^ y for x, y in zip(data, itertools.cycle(key))) -def is_hex(pattern): +def is_hex(pattern: str) -> bool: """Return whether provided string is a hexadecimal value.""" if not pattern.startswith("0x") and not pattern.startswith("0X"): return False @@ -3324,19 +3334,19 @@ def ida_synchronize_handler(event): return -def continue_handler(event): +def continue_handler(event) -> None: """GDB event handler for new object continue cases.""" return -def hook_stop_handler(event): +def hook_stop_handler(event) -> None: """GDB event handler for stop cases.""" reset_all_caches() gdb.execute("context") return -def new_objfile_handler(event): +def new_objfile_handler(event) -> None: """GDB event handler for new object file cases.""" reset_all_caches() set_arch() @@ -3344,7 +3354,7 @@ def new_objfile_handler(event): return -def exit_handler(event): +def exit_handler(event) -> None: """GDB event handler for exit cases.""" reset_all_caches() gef.session.qemu_mode = False @@ -3354,21 +3364,20 @@ def exit_handler(event): return -def memchanged_handler(event): +def memchanged_handler(event) -> None: """GDB event handler for mem changes cases.""" reset_all_caches() return -def regchanged_handler(event): +def regchanged_handler(event) -> None: """GDB event handler for reg changes cases.""" reset_all_caches() return -def load_libc_args(): +def load_libc_args() -> None: global gef - # load libc function arguments' definitions if not gef.config["context.libc_args"]: return @@ -3404,7 +3413,7 @@ def load_libc_args(): return -def get_terminal_size(): +def get_terminal_size() -> Tuple[int, int]: """Return the current terminal size.""" if is_debug(): return 600, 100 @@ -3432,7 +3441,7 @@ def get_terminal_size(): return 600, 100 -def get_generic_arch(module, prefix, arch, mode, big_endian, to_string=False): +def get_generic_arch(module: ModuleType, prefix: str, arch: str, mode: Optional[str], big_endian: Optional[bool], to_string: bool = False) -> Tuple[str, Union[int, str]]: """ Retrieves architecture and mode from the arguments for use for the holy {cap,key}stone/unicorn trinity. @@ -3462,7 +3471,7 @@ def get_generic_arch(module, prefix, arch, mode, big_endian, to_string=False): return arch, mode -def get_generic_running_arch(module, prefix, to_string=False): +def get_generic_running_arch(module: ModuleType, prefix: str, to_string: bool = False) -> Union[Tuple[None, None], Tuple[str, Union[int, str]]]: """ Retrieves architecture and mode from the current context. """ @@ -3478,14 +3487,14 @@ def get_generic_running_arch(module, prefix, to_string=False): return get_generic_arch(module, prefix, arch, mode, is_big_endian(), to_string) -def get_unicorn_arch(arch=None, mode=None, endian=None, to_string=False): +def get_unicorn_arch(arch: Optional[str] = None, mode: Optional[str] = None, endian: Optional[bool] = None, to_string: bool = False) -> Union[Tuple[None, None], Tuple[str, Union[int, str]]]: unicorn = sys.modules["unicorn"] if (arch, mode, endian) == (None, None, None): return get_generic_running_arch(unicorn, "UC", to_string) return get_generic_arch(unicorn, "UC", arch, mode, endian, to_string) -def get_capstone_arch(arch=None, mode=None, endian=None, to_string=False): +def get_capstone_arch(arch: Optional[str] = None, mode: Optional[str] = None, endian: Optional[bool] = None, to_string: bool = False) -> Union[Tuple[None, None], Tuple[str, Union[int, str]]]: capstone = sys.modules["capstone"] # hacky patch to unify capstone/ppc syntax with keystone & unicorn: @@ -3513,7 +3522,7 @@ def get_capstone_arch(arch=None, mode=None, endian=None, to_string=False): to_string) -def get_keystone_arch(arch=None, mode=None, endian=None, to_string=False): +def get_keystone_arch(arch: Optional[str] = None, mode: Optional[str] = None, endian: Optional[bool] = None, to_string: bool = False) -> Union[Tuple[None, None], Tuple[str, Union[int, str]]]: keystone = sys.modules["keystone"] if (arch, mode, endian) == (None, None, None): return get_generic_running_arch(keystone, "KS", to_string) @@ -3541,7 +3550,7 @@ def get_keystone_arch(arch=None, mode=None, endian=None, to_string=False): return arch, mode -def get_unicorn_registers(to_string=False): +def get_unicorn_registers(to_string: bool = False) -> Union[Dict[str, int], Dict[str, str]]: "Return a dict matching the Unicorn identifier for a specific register." unicorn = sys.modules["unicorn"] regs = {} @@ -3560,8 +3569,7 @@ def get_unicorn_registers(to_string=False): regs[reg] = getattr(const, regname) return regs - -def keystone_assemble(code, arch, mode, *args, **kwargs): +def keystone_assemble(code: str, arch: int, mode: int, *args, **kwargs) -> Optional[Union[str, bytearray]]: """Assembly encoding function based on keystone.""" keystone = sys.modules["keystone"] code = gef_pybytes(code) @@ -3587,7 +3595,7 @@ def keystone_assemble(code, arch, mode, *args, **kwargs): @lru_cache() -def get_elf_headers(filename=None): +def get_elf_headers(filename: Optional[str] = None): # -> Optional[Elf] """Return an Elf object with info from `filename`. If not provided, will return the currently debugged file.""" if filename is None: @@ -3601,19 +3609,19 @@ def get_elf_headers(filename=None): @lru_cache() -def is_64bit(): +def is_64bit() -> bool: """Checks if current target is 64bit.""" return gef.arch.ptrsize == 8 @lru_cache() -def is_32bit(): +def is_32bit() -> bool: """Checks if current target is 32bit.""" return gef.arch.ptrsize == 4 @lru_cache() -def is_x86_64(): +def is_x86_64() -> bool: """Checks if current target is x86-64""" return get_arch() == "i386:x86-64" @@ -3625,17 +3633,17 @@ def is_x86_32(): @lru_cache() -def is_x86(): +def is_x86() -> bool: return is_x86_32() or is_x86_64() @lru_cache() -def is_arch(arch): +def is_arch(arch: int) -> bool: elf = gef.binary or get_elf_headers() return elf.e_machine == arch -def set_arch(arch=None, default=None): +def set_arch(arch=None, default=None): # -> Architecture """Sets the current architecture. If an arch is explicitly specified, use that one, otherwise try to parse it out of the current target. If that fails, and default is specified, select and @@ -3675,7 +3683,7 @@ def set_arch(arch=None, default=None): @lru_cache() -def cached_lookup_type(_type): +def cached_lookup_type(_type: str): # -> Optional[gdb.Type] try: return gdb.lookup_type(_type).strip_typedefs() except RuntimeError: @@ -3683,7 +3691,7 @@ def cached_lookup_type(_type): @deprecated("Use `gef.arch.ptrsize` instead") -def get_memory_alignment(in_bits=False): +def 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`. @@ -3702,7 +3710,7 @@ def get_memory_alignment(in_bits=False): raise OSError("GEF is running under an unsupported mode") -def clear_screen(tty=""): +def clear_screen(tty: str = "") -> None: """Clear the screen.""" global gef if not tty: @@ -3720,7 +3728,7 @@ def clear_screen(tty=""): return -def format_address(addr): +def format_address(addr: int) -> str: """Format the address according to its size.""" memalign_size = gef.arch.ptrsize addr = align_address(addr) @@ -3731,7 +3739,7 @@ def format_address(addr): return "0x{:016x}".format(addr) -def format_address_spaces(addr, left=True): +def format_address_spaces(addr: int, left: bool = True) -> str: """Format the address according to its size, but with spaces instead of zeroes.""" width = gef.arch.ptrsize * 2 + 2 addr = align_address(addr) @@ -3742,7 +3750,7 @@ def format_address_spaces(addr, left=True): return "0x{:x}".format(addr).ljust(width) -def align_address(address): +def align_address(address: int) -> int: """Align the provided address to the process's native length.""" if gef.arch.ptrsize == 4: return address & 0xFFFFFFFF @@ -3750,18 +3758,18 @@ def align_address(address): return address & 0xFFFFFFFFFFFFFFFF -def align_address_to_size(address, align): +def align_address_to_size(address: int, align: int) -> int: """Align the address to the given size.""" return address + ((align - (address % align)) % align) -def align_address_to_page(address): +def align_address_to_page(address: int) -> int: """Align the address to a page.""" a = align_address(address) >> DEFAULT_PAGE_ALIGN_SHIFT return a << DEFAULT_PAGE_ALIGN_SHIFT -def malloc_align_address(address): +def malloc_align_address(address: int) -> int: """Align addresses according to glibc's MALLOC_ALIGNMENT. See also Issue #689 on Github""" __default_malloc_alignment = 0x10 if is_x86_32() and get_libc_version() >= (2, 26): @@ -3779,31 +3787,31 @@ def malloc_align_address(address): return malloc_alignment * ceil((address / malloc_alignment)) -def parse_address(address): +def parse_address(address: str) -> int: """Parse an address and return it as an Integer.""" if is_hex(address): return int(address, 16) return to_unsigned_long(gdb.parse_and_eval(address)) -def is_in_x86_kernel(address): +def is_in_x86_kernel(address: int) -> bool: address = align_address(address) memalign = gef.arch.ptrsize*8 - 1 return (address >> memalign) == 0xF @lru_cache() -def is_remote_debug(): +def is_remote_debug() -> bool: """"Return True is the current debugging session is running through GDB remote session.""" return gef.session.remote is not None or "remote" in gdb.execute("maintenance print target-stack", to_string=True) -def de_bruijn(alphabet, n): +def de_bruijn(alphabet: str, n: int) -> Generator[str, None, None]: """De Bruijn sequence for alphabet and subsequences of length n (for compat. w/ pwnlib).""" k = len(alphabet) a = [0] * k * n - def db(t, p): + def db(t: int, p: int) -> Generator[str, None, None]: if t > n: if n % p == 0: for j in range(1, p + 1): @@ -3819,13 +3827,13 @@ def db(t, p): return db(1, 1) -def generate_cyclic_pattern(length, cycle=4): +def generate_cyclic_pattern(length: int, cycle: int = 4) -> bytearray: """Create a `length` byte bytearray of a de Bruijn cyclic pattern.""" charset = bytearray(b"abcdefghijklmnopqrstuvwxyz") return bytearray(itertools.islice(de_bruijn(charset, cycle), length)) -def safe_parse_and_eval(value): +def safe_parse_and_eval(value: str): # -> Optional[gdb.Value] """GEF wrapper for gdb.parse_and_eval(): this function returns None instead of raising gdb.error if the eval failed.""" try: @@ -3836,7 +3844,7 @@ def safe_parse_and_eval(value): @lru_cache() -def dereference(addr): +def dereference(addr: int): # -> Optional[gdb.Value] """GEF wrapper for gdb dereference function.""" try: ulong_t = cached_lookup_type(use_stdtype()) or \ @@ -3853,7 +3861,7 @@ def dereference(addr): return None -def gef_convenience(value): +def gef_convenience(value: str) -> str: """Defines a new convenience value.""" global gef var_name = "$_gef{:d}".format(gef.session.convenience_vars_index) @@ -3862,49 +3870,49 @@ def gef_convenience(value): return var_name -def parse_string_range(s): +def parse_string_range(s: str) -> Iterator[int]: """Parses an address range (e.g. 0x400000-0x401000)""" addrs = s.split("-") return map(lambda x: int(x, 16), addrs) -def gef_get_pie_breakpoint(num): +def gef_get_pie_breakpoint(num: int): # -> PieVirtualBreakpoint return gef.session.pie_breakpoints[num] # # Deprecated API # @deprecated("Use `str(gef.arch.endianness)` instead") -def endian_str(): +def endian_str() -> str: return str(gef.arch.endianness) @deprecated("Use `gef.config[key]`") -def get_gef_setting(name): - return gef.config +def get_gef_setting(name: str) -> Any: + return gef.config[name] @deprecated("Use `gef.config[key] = value`") -def set_gef_setting(name, value): +def set_gef_setting(name: str, value: Any) -> None: gef.config[name] = value return @deprecated("Use `gef.session.pagesize`") -def gef_getpagesize(): +def gef_getpagesize() -> int: return gef.session.pagesize @deprecated("Use `gef.session.canary`") -def gef_read_canary(): +def gef_read_canary() -> Optional[Tuple[int, int]]: return gef.session.canary @deprecated("Use `gef.session.pid`") -def get_pid(): +def get_pid() -> int: return gef.session.pid @deprecated("Use `gef.session.file.name`") -def get_filename(): +def get_filename() -> str: return gef.session.file.name @deprecated("Use `gef.heap.main_arena`") -def get_glibc_arena(): +def get_glibc_arena(): # -> GlibcArena return gef.heap.main_arena @deprecated("Use `gef.arch.register(regname)`") @@ -3988,7 +3996,7 @@ def gef_on_regchanged_unhook(func): class PieVirtualBreakpoint: """PIE virtual breakpoint (not real breakpoint).""" - def __init__(self, set_func, vbp_num, addr): + def __init__(self, set_func: Callable[[int], str], vbp_num: int, addr: int) -> None: # set_func(base): given a base address return a # "set breakpoint" gdb command string self.set_func = set_func @@ -3998,12 +4006,12 @@ def __init__(self, set_func, vbp_num, addr): self.bp_addr = 0 # this address might be a symbol, just to know where to break if isinstance(addr, int): - self.addr = hex(addr) + self.addr: Union[int, str] = hex(addr) else: self.addr = addr return - def instantiate(self, base): + def instantiate(self, base: int) -> None: if self.bp_num: self.destroy() @@ -4021,7 +4029,7 @@ def instantiate(self, base): self.bp_addr = res_list[3] return - def destroy(self): + def destroy(self) -> None: if not self.bp_num: err("Destroy PIE breakpoint not even set") return @@ -4036,13 +4044,13 @@ def destroy(self): class FormatStringBreakpoint(gdb.Breakpoint): """Inspect stack for format string.""" - def __init__(self, spec, num_args): + def __init__(self, spec: str, num_args: int) -> None: super().__init__(spec, type=gdb.BP_BREAKPOINT, internal=False) self.num_args = num_args self.enabled = True return - def stop(self): + def stop(self) -> bool: reset_all_caches() msg = [] ptr, addr = gef.arch.get_ith_parameter(self.num_args) @@ -4067,7 +4075,7 @@ def stop(self): class StubBreakpoint(gdb.Breakpoint): """Create a breakpoint to permanently disable a call (fork/alarm/signal/etc.).""" - def __init__(self, func, retval): + def __init__(self, func: str, retval: Optional[int]) -> None: super().__init__(func, gdb.BP_BREAKPOINT, internal=False) self.func = func self.retval = retval @@ -4078,7 +4086,7 @@ def __init__(self, func, retval): info(m) return - def stop(self): + def stop(self) -> bool: m = "Ignoring call to '{:s}' ".format(self.func) m += "(setting return value to {:#x})".format(self.retval) gdb.execute("return (unsigned int){:#x}".format(self.retval)) @@ -4090,13 +4098,13 @@ class ChangePermissionBreakpoint(gdb.Breakpoint): """When hit, this temporary breakpoint will restore the original code, and position $pc correctly.""" - def __init__(self, loc, code, pc): + def __init__(self, loc: str, code: ByteString, pc: int) -> None: super().__init__(loc, gdb.BP_BREAKPOINT, internal=False) self.original_code = code self.original_pc = pc return - def stop(self): + def stop(self) -> bool: info("Restoring original context") gef.memory.write(self.original_pc, self.original_code, len(self.original_code)) info("Restoring $pc") @@ -4107,13 +4115,13 @@ def stop(self): class TraceMallocBreakpoint(gdb.Breakpoint): """Track allocations done with malloc() or calloc().""" - def __init__(self, name): + def __init__(self, name: str) -> None: super().__init__(name, gdb.BP_BREAKPOINT, internal=True) self.silent = True self.name = name return - def stop(self): + def stop(self) -> bool: reset_all_caches() _, size = gef.arch.get_ith_parameter(0) self.retbp = TraceMallocRetBreakpoint(size, self.name) @@ -4123,14 +4131,14 @@ def stop(self): class TraceMallocRetBreakpoint(gdb.FinishBreakpoint): """Internal temporary breakpoint to retrieve the return value of malloc().""" - def __init__(self, size, name): + def __init__(self, size: int, name: str) -> None: super().__init__(gdb.newest_frame(), internal=True) self.size = size self.name = name self.silent = True return - def stop(self): + def stop(self) -> bool: if self.return_value: loc = int(self.return_value) else: @@ -4192,12 +4200,12 @@ def stop(self): class TraceReallocBreakpoint(gdb.Breakpoint): """Track re-allocations done with realloc().""" - def __init__(self): + def __init__(self) -> None: super().__init__("__libc_realloc", gdb.BP_BREAKPOINT, internal=True) self.silent = True return - def stop(self): + def stop(self) -> bool: _, ptr = gef.arch.get_ith_parameter(0) _, size = gef.arch.get_ith_parameter(1) self.retbp = TraceReallocRetBreakpoint(ptr, size) @@ -4207,14 +4215,14 @@ def stop(self): class TraceReallocRetBreakpoint(gdb.FinishBreakpoint): """Internal temporary breakpoint to retrieve the return value of realloc().""" - def __init__(self, ptr, size): + def __init__(self, ptr: int, size: int) -> None: super().__init__(gdb.newest_frame(), internal=True) self.ptr = ptr self.size = size self.silent = True return - def stop(self): + def stop(self) -> bool: if self.return_value: newloc = int(self.return_value) else: @@ -4249,12 +4257,12 @@ def stop(self): class TraceFreeBreakpoint(gdb.Breakpoint): """Track calls to free() and attempts to detect inconsistencies.""" - def __init__(self): + def __init__(self) -> None: super().__init__("__libc_free", gdb.BP_BREAKPOINT, internal=True) self.silent = True return - def stop(self): + def stop(self) -> bool: reset_all_caches() _, addr = gef.arch.get_ith_parameter(0) msg = [] @@ -4311,13 +4319,13 @@ def stop(self): class TraceFreeRetBreakpoint(gdb.FinishBreakpoint): """Internal temporary breakpoint to track free()d values.""" - def __init__(self, addr): + def __init__(self, addr: int) -> None: super().__init__(gdb.newest_frame(), internal=True) self.silent = True self.addr = addr return - def stop(self): + def stop(self) -> bool: reset_all_caches() wp = UafWatchpoint(self.addr) gef.session.heap_uaf_watchpoints.append(wp) @@ -4327,14 +4335,14 @@ def stop(self): class UafWatchpoint(gdb.Breakpoint): """Custom watchpoints set TraceFreeBreakpoint() to monitor free()d pointers being used.""" - def __init__(self, addr): + def __init__(self, addr: int) -> None: super().__init__("*{:#x}".format(addr), gdb.BP_WATCHPOINT, internal=True) self.address = addr self.silent = True self.enabled = True return - def stop(self): + def stop(self) -> bool: """If this method is triggered, we likely have a UaF. Break the execution and report it.""" reset_all_caches() frame = gdb.selected_frame() @@ -4357,12 +4365,12 @@ def stop(self): class EntryBreakBreakpoint(gdb.Breakpoint): """Breakpoint used internally to stop execution at the most convenient entry point.""" - def __init__(self, location): + def __init__(self, location: str) -> None: super().__init__(location, gdb.BP_BREAKPOINT, internal=True, temporary=True) self.silent = True return - def stop(self): + def stop(self) -> bool: reset_all_caches() return True @@ -4370,13 +4378,13 @@ def stop(self): class NamedBreakpoint(gdb.Breakpoint): """Breakpoint which shows a specified name, when hit.""" - def __init__(self, location, name): + def __init__(self, location: str, name: str) -> None: super().__init__(spec=location, type=gdb.BP_BREAKPOINT, internal=False, temporary=False) self.name = name self.loc = location return - def stop(self): + def stop(self) -> bool: reset_all_caches() push_context_message("info", "Hit breakpoint {} ({})".format(self.loc, Color.colorify(self.name, "red bold"))) return True @@ -4386,7 +4394,7 @@ def stop(self): # Context Panes # -def register_external_context_pane(pane_name, display_pane_function, pane_title_function): +def register_external_context_pane(pane_name: str, display_pane_function: Callable[[], None], pane_title_function: Callable[[], Optional[str]]) -> None: """ Registering function for new GEF Context View. pane_name: a string that has no spaces (used in settings) @@ -4439,7 +4447,7 @@ def register_function(cls): class GenericCommand(gdb.Command, metaclass=abc.ABCMeta): """This is an abstract class for invoking commands, should not be instantiated.""" - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: self.pre_load() syntax = Color.yellowify("\nSyntax: ") + self._syntax_ example = Color.yellowify("\nExample: ") + self._example_ if self._example_ else "" @@ -4454,7 +4462,7 @@ def __init__(self, *args, **kwargs): self.post_load() return - def invoke(self, args, from_tty): + def invoke(self, args: str, from_tty: bool) -> None: try: argv = gdb.string_to_argv(args) self.__set_repeat_count(argv, from_tty) @@ -4468,27 +4476,27 @@ def invoke(self, args, from_tty): err("Command '{:s}' failed to execute properly, reason: {:s}".format(self._cmdline_, str(e))) return - def usage(self): + def usage(self) -> None: err("Syntax\n{}".format(self._syntax_)) return @abc.abstractproperty - def _cmdline_(self): pass + def _cmdline_(self) -> Optional[str]: pass @abc.abstractproperty - def _syntax_(self): pass + def _syntax_(self) -> Optional[str]: pass @abc.abstractproperty - def _example_(self): return "" + def _example_(self) -> str: return "" @abc.abstractmethod - def do_invoke(self, argv): pass + def do_invoke(self, argv: List) -> None: pass - def pre_load(self): pass + def pre_load(self) -> None: pass - def post_load(self): pass + def post_load(self) -> None: pass - def __get_setting_name(self, name): + def __get_setting_name(self, name: str) -> str: def __sanitize_class_name(clsname): if " " not in clsname: return clsname @@ -4496,13 +4504,13 @@ def __sanitize_class_name(clsname): class_name = __sanitize_class_name(self.__class__._cmdline_) return "{:s}.{:s}".format(class_name, name) - def __iter__(self): + def __iter__(self) -> Generator[str, None, None]: for key in gef.config.keys(): if key.startswith(self._cmdline_): yield key.replace("{:s}.".format(self._cmdline_), "", 1) @property - def settings(self): + def settings(self) -> List[str]: """Return the list of settings for this command.""" return list(iter(self)) @@ -4515,17 +4523,17 @@ def __getitem__(self, name): return gef.config[key] @deprecated("") - def has_setting(self, name): + def has_setting(self, name: str) -> bool: return self.__contains__(name) - def __contains__(self, name): + def __contains__(self, name: str) -> bool: return self.__get_setting_name(name) in gef.config @deprecated("") - def add_setting(self, name, value, description=""): + def add_setting(self, name: str, value: Tuple[Any, type, str], description: str = "") -> None: return self.__setitem__(name, (value, type(value), description)) - def __setitem__(self, name, value): + def __setitem__(self, name: str, value: Union[Any, Tuple[Any, str]]) -> None: # make sure settings are always associated to the root command (which derives from GenericCommand) if "GenericCommand" not in [x.__name__ for x in self.__class__.__bases__]: return @@ -4540,14 +4548,14 @@ def __setitem__(self, name, value): return @deprecated("") - def del_setting(self, name): + def del_setting(self, name: str) -> None: return self.__delitem__(name) - def __delitem__(self, name): + def __delitem__(self, name: str) -> None: del gef.config[self.__get_setting_name(name)] return - def __set_repeat_count(self, argv, from_tty): + def __set_repeat_count(self, argv, from_tty: bool) -> None: if not from_tty: self.repeat = False self.repeat_count = 0 @@ -4568,7 +4576,7 @@ class VersionCommand(GenericCommand): _syntax_ = "{:s}".format(_cmdline_) _example_ = "{:s}".format(_cmdline_) - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: gef_fpath = pathlib.Path(inspect.stack()[0][1]).expanduser().absolute() gef_dir = gef_fpath.parent with gef_fpath.open("rb") as f: @@ -4610,12 +4618,12 @@ class PrintFormatCommand(GenericCommand): _example_ = "{} --lang py -l 16 $rsp".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @property - def format_matrix(self): + def format_matrix(self) -> Dict[int, Tuple[str, str, str]]: # `gef.arch.endianness` is a runtime property, should not be defined as a class property return { 8: (f"{gef.arch.endianness:s}B", "char", "db"), @@ -4626,7 +4634,7 @@ def format_matrix(self): @only_if_gdb_running @parse_arguments({"location": "$pc", }, {("--length", "-l"): 256, "--bitlen": 0, "--lang": "py", "--clip": True,}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> None: """Default value for print-format command.""" args = kwargs["arguments"] args.bitlen = args.bitlen or gef.arch.ptrsize * 2 @@ -4679,11 +4687,11 @@ class PieCommand(GenericCommand): _cmdline_ = "pie" _syntax_ = "{:s} (breakpoint|info|delete|run|attach|remote)".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=True) return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if not argv: self.usage() return @@ -4697,7 +4705,7 @@ class PieBreakpointCommand(GenericCommand): _syntax_ = "{:s} OFFSET".format(_cmdline_) @parse_arguments({"offset": ""}, {}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> None: args = kwargs["arguments"] if not args.offset: self.usage() @@ -4715,7 +4723,7 @@ def do_invoke(self, argv, *args, **kwargs): return @staticmethod - def set_pie_breakpoint(set_func, addr): + def set_pie_breakpoint(set_func: Callable[[int], str], addr: int) -> None: gef.session.pie_breakpoints[gef.session.pie_counter] = PieVirtualBreakpoint(set_func, gef.session.pie_counter, addr) gef.session.pie_counter += 1 return @@ -4729,7 +4737,7 @@ class PieInfoCommand(GenericCommand): _syntax_ = "{:s} BREAKPOINT".format(_cmdline_) @parse_arguments({"breakpoints": [-1,]}, {}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> None: args = kwargs["arguments"] if args.breakpoints[0] == -1: # No breakpoint info needed @@ -4754,7 +4762,7 @@ class PieDeleteCommand(GenericCommand): _syntax_ = "{:s} [BREAKPOINT]".format(_cmdline_) @parse_arguments({"breakpoints": [-1,]}, {}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> None: global gef args = kwargs["arguments"] if args.breakpoints[0] == -1: @@ -4767,7 +4775,7 @@ def do_invoke(self, argv, *args, **kwargs): @staticmethod - def delete_bp(breakpoints): + def delete_bp(breakpoints: List) -> None: global gef for bp in breakpoints: # delete current real breakpoints if exists @@ -4785,7 +4793,7 @@ class PieRunCommand(GenericCommand): _cmdline_ = "pie run" _syntax_ = _cmdline_ - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: global gef fpath = get_filepath() if fpath is None: @@ -4828,7 +4836,7 @@ class PieAttachCommand(GenericCommand): _cmdline_ = "pie attach" _syntax_ = "{:s} PID".format(_cmdline_) - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: try: gdb.execute("attach {}".format(" ".join(argv)), to_string=True) except gdb.error as e: @@ -4852,7 +4860,7 @@ class PieRemoteCommand(GenericCommand): _cmdline_ = "pie remote" _syntax_ = "{:s} REMOTE".format(_cmdline_) - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: try: gdb.execute("gef-remote {}".format(" ".join(argv))) except gdb.error as e: @@ -4877,7 +4885,7 @@ class SmartEvalCommand(GenericCommand): _syntax_ = "{0:s} EXPR\n{0:s} ADDRESS1 ADDRESS2".format(_cmdline_) _example_ = "\n{0:s} $pc+1\n{0:s} 0x00007ffff7a10000 0x00007ffff7bce000".format(_cmdline_) - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: argc = len(argv) if argc == 1: self.evaluate(argv) @@ -4887,7 +4895,7 @@ def do_invoke(self, argv): self.distance(argv) return - def evaluate(self, expr): + def evaluate(self, expr: List) -> None: def show_as_int(i): off = gef.arch.ptrsize*8 def comp2_x(x): return "{:x}".format((x + (1 << off)) % (1 << off)) @@ -4924,7 +4932,7 @@ def comp2_b(x): return "{:b}".format((x + (1 << off)) % (1 << off)) gef_print(" ".join(parsed_expr)) return - def distance(self, args): + def distance(self, args: Tuple[str, str]): try: x = int(args[0], 16) if is_hex(args[0]) else int(args[0]) y = int(args[1], 16) if is_hex(args[1]) else int(args[1]) @@ -4942,7 +4950,7 @@ class CanaryCommand(GenericCommand): _syntax_ = _cmdline_ @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: self.dont_repeat() has_canary = checksec(get_filepath())["Canary"] @@ -4969,13 +4977,13 @@ class ProcessStatusCommand(GenericCommand): _syntax_ = _cmdline_ _aliases_ = ["status", ] - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_NONE) return @only_if_gdb_running @only_if_gdb_target_local - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: self.show_info_proc() self.show_ancestor() self.show_descendants() @@ -4983,7 +4991,7 @@ def do_invoke(self, argv): self.show_connections() return - def get_state_of(self, pid): + def get_state_of(self, pid: int) -> Dict[str, str]: res = {} with open("/proc/{}/status".format(pid), "r") as f: file = f.readlines() @@ -4992,21 +5000,21 @@ def get_state_of(self, pid): res[key.strip()] = value.strip() return res - def get_cmdline_of(self, pid): + def get_cmdline_of(self, pid: int) -> str: with open("/proc/{}/cmdline".format(pid), "r") as f: return f.read().replace("\x00", "\x20").strip() - def get_process_path_of(self, pid): + def get_process_path_of(self, pid: int) -> str: return os.readlink("/proc/{}/exe".format(pid)) - def get_children_pids(self, pid): + def get_children_pids(self, pid: int) -> List[int]: cmd = [gef.session.constants["ps"], "-o", "pid", "--ppid", "{}".format(pid), "--noheaders"] try: return [int(x) for x in gef_execute_external(cmd, as_list=True)] except Exception: return [] - def show_info_proc(self): + def show_info_proc(self) -> None: info("Process Information") pid = gef.session.pid cmdline = self.get_cmdline_of(pid) @@ -5015,7 +5023,7 @@ def show_info_proc(self): gef_print("\tCommand line {} '{}'".format(RIGHT_ARROW, cmdline)) return - def show_ancestor(self): + def show_ancestor(self) -> None: info("Parent Process Information") ppid = int(self.get_state_of(gef.session.pid)["PPid"]) state = self.get_state_of(ppid) @@ -5024,7 +5032,7 @@ def show_ancestor(self): gef_print("\tCommand line {} '{}'".format(RIGHT_ARROW, cmdline)) return - def show_descendants(self): + def show_descendants(self) -> None: info("Children Process Information") children = self.get_children_pids(gef.session.pid) if not children: @@ -5040,7 +5048,7 @@ def show_descendants(self): self.get_cmdline_of(pid))) return - def show_fds(self): + def show_fds(self) -> None: pid = gef.session.pid path = "/proc/{:d}/fd".format(pid) @@ -5056,7 +5064,7 @@ def show_fds(self): gef_print("\t{:s} {:s} {:s}".format (fullpath, RIGHT_ARROW, os.readlink(fullpath))) return - def list_sockets(self, pid): + def list_sockets(self, pid: int) -> List[int]: sockets = [] path = "/proc/{:d}/fd".format(pid) items = os.listdir(path) @@ -5067,11 +5075,11 @@ def list_sockets(self, pid): sockets.append(int(p)) return sockets - def parse_ip_port(self, addr): + def parse_ip_port(self, addr: str) -> Tuple[str, int]: ip, port = addr.split(":") return socket.inet_ntoa(struct.pack(" None: # https://github.com/torvalds/linux/blob/v4.7/include/net/tcp_states.h#L16 tcp_states_str = { 0x01: "TCP_ESTABLISHED", @@ -5129,7 +5137,7 @@ class GefThemeCommand(GenericCommand): _cmdline_ = "theme" _syntax_ = "{:s} [KEY [VALUE]]".format(_cmdline_) - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(self._cmdline_) self["context_title_line"] = ( "gray", "Color of the borders in context window") self["context_title_message"] = ( "cyan", "Color of the title in context window") @@ -5150,7 +5158,7 @@ def __init__(self, *args, **kwargs): self["source_current_line"] = ( "green", "Color to use for the current code line in the source window") return - def do_invoke(self, args): + def do_invoke(self, args: List) -> None: self.dont_repeat() argc = len(args) @@ -5189,7 +5197,7 @@ class PCustomCommand(GenericCommand): _cmdline_ = "pcustom" _syntax_ = "{:s} [list|edit |show ]| 0xADDRESS]".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=True) self["struct_path"] = ( os.sep.join( (gef.config["gef.tempdir"], "structs")), "Path to store/load the structure ctypes files") self["max_depth"] = ( 4, "Maximum level of recursion supported") @@ -5199,7 +5207,7 @@ def __init__(self): return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: argc = len(argv) if argc == 0: gdb.execute("pcustom list") @@ -5219,14 +5227,14 @@ def do_invoke(self, argv): self.apply_structure_to_address(modname, structname, address) return - def get_pcustom_absolute_root_path(self): + def get_pcustom_absolute_root_path(self) -> Union[str, bytes]: path = os.path.expanduser(gef.config["pcustom.struct_path"]) path = os.path.realpath(path) if not os.path.isdir(path): raise RuntimeError("setting `struct_path` must be set correctly") return path - def get_pcustom_filepath_for_structure(self, structure_name): + def get_pcustom_filepath_for_structure(self, structure_name: str) -> str: structure_files = self.enumerate_structures() fpath = None for fname in structure_files: @@ -5237,24 +5245,24 @@ def get_pcustom_filepath_for_structure(self, structure_name): raise FileNotFoundError("no file for structure '{}'".format(structure_name)) return fpath - def is_valid_struct(self, structure_name): + def is_valid_struct(self, structure_name: str) -> bool: structure_files = self.enumerate_structures() all_structures = set() for fname in structure_files: all_structures |= structure_files[fname] return structure_name in all_structures - def get_modulename_structname_from_arg(self, arg): + def get_modulename_structname_from_arg(self, arg: str) -> Tuple[str, str]: modname, structname = arg.split(":", 1) if ":" in arg else (arg, arg) structname = structname.split(".", 1)[0] if "." in structname else structname - return (modname, structname) + return modname, structname - def deserialize(self, struct, data): + def deserialize(self, struct: ctypes.Structure, data: bytes) -> None: length = min(len(data), ctypes.sizeof(struct)) ctypes.memmove(ctypes.addressof(struct), data, length) return - def get_structure_class(self, modname, classname): + def get_structure_class(self, modname: str, classname: str) -> Tuple[Type, ctypes.Structure]: """ Returns a tuple of (class, instance) if modname!classname exists """ @@ -5265,7 +5273,7 @@ def get_structure_class(self, modname, classname): @only_if_gdb_running - def apply_structure_to_address(self, mod_name, struct_name, addr, depth=0): + def apply_structure_to_address(self, mod_name: str, struct_name: str, addr: int, depth: int = 0) -> None: if not self.is_valid_struct(mod_name): err("Invalid structure name '{:s}'".format(struct_name)) return @@ -5313,7 +5321,7 @@ def apply_structure_to_address(self, mod_name, struct_name, addr, depth=0): self.apply_structure_to_address(mod_name, __sub_type_name, __deref, depth + 1) return - def get_ctypes_value(self, struct, item, value): + def get_ctypes_value(self, struct, item, value) -> str: if not hasattr(struct, "_values_"): return "" values_list = getattr(struct, "_values_") default = "" @@ -5330,7 +5338,7 @@ def get_ctypes_value(self, struct, item, value): return default - def enumerate_structure_files(self): + def enumerate_structure_files(self) -> List[str]: """ Return a list of all the files in the pcustom directory """ @@ -5344,7 +5352,7 @@ def enumerate_structure_files(self): module_files.append( os.path.realpath(fpath) ) return module_files - def enumerate_structures(self): + def enumerate_structures(self) -> Dict[str, Set[str]]: """ Return a hash of all the structures, with the key set the to filepath """ @@ -5355,7 +5363,7 @@ def enumerate_structures(self): structures[module_path] = self.enumerate_structures_from_module(module) return structures - def load_module(self, file_path): + def load_module(self, file_path: str) -> ModuleType: """Load a custom module, and return it""" module_name = file_path.split(os.sep)[-1].replace(".py", "") spec = importlib.util.spec_from_file_location(module_name, file_path) @@ -5364,7 +5372,7 @@ def load_module(self, file_path): spec.loader.exec_module(module) return module - def enumerate_structures_from_module(self, module): + def enumerate_structures_from_module(self, module: ModuleType) -> Set[str]: _invalid = {"BigEndianStructure", "LittleEndianStructure", "Structure"} _structs = {x for x in dir(module) \ if inspect.isclass(getattr(module, x)) \ @@ -5379,15 +5387,15 @@ class PCustomListCommand(PCustomCommand): _cmdline_ = "pcustom list" _syntax_ = "{:s}".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__() return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: self.__list_custom_structures() return - def __list_custom_structures(self): + def __list_custom_structures(self) -> None: """Dump the list of all the structures and their respective.""" path = self.get_pcustom_absolute_root_path() info("Listing custom structures from '{:s}'".format(path)) @@ -5409,11 +5417,11 @@ class PCustomShowCommand(PCustomCommand): _syntax_ = "{:s} StructureName".format(_cmdline_) __aliases__ = ["pcustom create", "pcustom update"] - def __init__(self): + def __init__(self) -> None: super().__init__() return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if len(argv) == 0: self.usage() return @@ -5422,7 +5430,7 @@ def do_invoke(self, argv): self.__dump_structure(modname, structname) return - def __dump_structure(self, mod_name, struct_name): + def __dump_structure(self, mod_name: str, struct_name: str) -> None: # If it's a builtin or defined in the ELF use gdb's `ptype` try: gdb.execute("ptype struct {:s}".format(struct_name)) @@ -5433,7 +5441,7 @@ def __dump_structure(self, mod_name, struct_name): self.__dump_custom_structure(mod_name, struct_name) return - def __dump_custom_structure(self, mod_name, struct_name): + def __dump_custom_structure(self, mod_name: str, struct_name: str) -> None: if not self.is_valid_struct(mod_name): err("Invalid structure name '{:s}'".format(struct_name)) return @@ -5458,11 +5466,11 @@ class PCustomEditCommand(PCustomCommand): _syntax_ = "{:s} StructureName".format(_cmdline_) __aliases__ = ["pcustom create", "pcustom new", "pcustom update"] - def __init__(self): + def __init__(self) -> None: super().__init__() return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if len(argv) == 0: self.usage() return @@ -5471,7 +5479,7 @@ def do_invoke(self, argv): self.__create_or_edit_structure(modname, structname) return - def __create_or_edit_structure(self, mod_name, struct_name): + def __create_or_edit_structure(self, mod_name: str, struct_name: str) -> Optional[int]: root = self.get_pcustom_absolute_root_path() if root is None: err("Invalid struct path") @@ -5489,7 +5497,7 @@ def __create_or_edit_structure(self, mod_name, struct_name): cmd.append(fullname) return subprocess.call(cmd) - def __create_new_structure_template(self, structname, fullname): + def __create_new_structure_template(self, structname: str, fullname: str) -> None: template = [ "from ctypes import *", "", @@ -5514,7 +5522,7 @@ class ChangeFdCommand(GenericCommand): @only_if_gdb_running @only_if_gdb_target_local - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if len(argv) != 2: self.usage() return @@ -5569,7 +5577,7 @@ def do_invoke(self, argv): ok("Success") return - def get_fd_from_result(self, res): + def get_fd_from_result(self, res: str) -> int: # Output example: $1 = 3 res = int(res.split()[2], 0) res = gdb.execute("""p/d {}""".format(res), to_string=True) @@ -5588,7 +5596,7 @@ class IdaInteractCommand(GenericCommand): _aliases_ = ["binaryninja-interact", "bn", "binja"] _example_ = "\n{0:s} Jump $pc\n{0:s} SetColor $pc ff00ff".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=False) host, port = "127.0.0.1", 1337 self["host"] = ( host, "IP address to use connect to IDA/Binary Ninja script") @@ -5600,7 +5608,7 @@ def __init__(self): self.old_bps = set() return - def is_target_alive(self, host, port): + def is_target_alive(self, host: str, port: int) -> bool: try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(1) @@ -5610,7 +5618,7 @@ def is_target_alive(self, host, port): return False return True - def connect(self, host=None, port=None): + def connect(self, host: Optional[str] = None, port: Optional[int] = None) -> None: """Connect to the XML-RPC service.""" host = host or self["host"] port = port or self["port"] @@ -5626,15 +5634,15 @@ def connect(self, host=None, port=None): self.sock = sock return - def disconnect(self): + def disconnect(self) -> None: gef_on_stop_unhook(ida_synchronize_handler) gef_on_continue_unhook(ida_synchronize_handler) self.sock = None return @deprecated("") - def do_invoke(self, argv): - def parsed_arglist(arglist): + def do_invoke(self, argv: List) -> None: + def parsed_arglist(arglist) -> List[str]: args = [] for arg in arglist: try: @@ -5703,7 +5711,7 @@ def parsed_arglist(arglist): self.disconnect() return - def synchronize(self): + def synchronize(self) -> None: """Submit all active breakpoint addresses to IDA/BN.""" pc = gef.arch.pc vmmap = gef.memory.maps @@ -5762,7 +5770,7 @@ def synchronize(self): bp.delete() return - def usage(self, meth=None): + def usage(self, meth: Optional[str] = None) -> None: if self.sock is None: return @@ -5778,7 +5786,7 @@ def usage(self, meth=None): gef_print(self.sock.system.methodHelp(m)) return - def import_structures(self, structs): + def import_structures(self, structs: Dict[str, List[Tuple[int, str, int]]]) -> None: if self.version[0] != "IDA Pro": return @@ -5822,7 +5830,7 @@ class ScanSectionCommand(GenericCommand): _example_ = "\n{0:s} stack libc".format(_cmdline_) @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if len(argv) != 2: self.usage() return @@ -5889,7 +5897,7 @@ class SearchPatternCommand(GenericCommand): _aliases_ = ["grep", "xref"] _example_ = "\n{0:s} AAAAAAAA\n{0:s} 0x555555554000 little stack\n{0:s} AAAA 0x600000-0x601000".format(_cmdline_) - def print_section(self, section): + def print_section(self, section) -> None: title = "In " if section.path: title += "'{}'".format(Color.blueify(section.path)) @@ -5899,13 +5907,13 @@ def print_section(self, section): ok(title) return - def print_loc(self, loc): + def print_loc(self, loc) -> None: gef_print(""" {:#x} - {:#x} {} "{}" """.format(loc[0], loc[1], RIGHT_ARROW, Color.pinkify(loc[2]),)) return - def search_pattern_by_address(self, pattern, start_address, end_address): + def search_pattern_by_address(self, pattern: str, start_address: int, end_address: int) -> List[Tuple[int, int, Optional[str]]]: """Search a pattern within a range defined by arguments.""" - pattern = gef_pybytes(pattern) + _pattern = gef_pybytes(pattern) step = 0x400 * 0x1000 locations = [] @@ -5932,21 +5940,21 @@ def search_pattern_by_address(self, pattern, start_address, end_address): else: raise e - for match in re.finditer(pattern, mem): + for match in re.finditer(_pattern, mem): start = chunk_addr + match.start() if is_ascii_string(start): ustr = gef.memory.read_ascii_string(start) end = start + len(ustr) else: - ustr = gef_pystring(pattern) + "[...]" - end = start + len(pattern) + ustr = gef_pystring(_pattern) + "[...]" + end = start + len(_pattern) locations.append((start, end, ustr)) del mem return locations - def search_pattern(self, pattern, section_name): + def search_pattern(self, pattern: str, section_name: str) -> None: """Search a pattern within the whole userland memory.""" for section in gef.memory.maps: if not section.permission & Permission.READ: continue @@ -5968,7 +5976,7 @@ def search_pattern(self, pattern, section_name): return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: argc = len(argv) if argc < 1: self.usage() @@ -6020,7 +6028,7 @@ class FlagsCommand(GenericCommand): _aliases_ = ["flags",] _example_ = "\n{0:s}\n{0:s} +zero # sets ZERO flag".format(_cmdline_) - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: for flag in argv: if len(flag) < 2: continue @@ -6063,11 +6071,11 @@ class ChangePermissionCommand(GenericCommand): _aliases_ = ["mprotect"] _example_ = "{:s} $sp 7".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return - def pre_load(self): + def pre_load(self) -> None: try: __import__("keystone") except ImportError: @@ -6076,7 +6084,7 @@ def pre_load(self): return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if len(argv) not in (1, 2): err("Incorrect syntax") self.usage() @@ -6122,7 +6130,7 @@ def do_invoke(self, argv): gdb.execute("continue") return - def get_stub_by_arch(self, addr, size, perm): + def get_stub_by_arch(self, addr: int, size: int, perm) -> Union[str, bytearray, None]: code = gef.arch.mprotect_asm(addr, size, perm) arch, mode = get_keystone_arch() raw_insns = keystone_assemble(code, arch, mode, raw=True) @@ -6148,13 +6156,13 @@ class UnicornEmulateCommand(GenericCommand): _aliases_ = ["emulate",] _example_ = "{0:s} --start $pc 10 --output-file /tmp/my-gef-emulation.py".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) self["verbose"] = ( False, "Set unicorn-engine in verbose mode") self["show_disassembly"] = ( False, "Show every instruction executed") return - def pre_load(self): + def pre_load(self) -> None: try: __import__("unicorn") except ImportError: @@ -6170,19 +6178,19 @@ def pre_load(self): @only_if_gdb_running @parse_arguments({"nb": 1}, {"--start": "", "--until": "", "--skip-emulation": True, "--output-file": ""}) - def do_invoke(self, *args, **kwargs): + def do_invoke(self, *args, **kwargs) -> None: args = kwargs["arguments"] start_address = parse_address(str(args.start or gef.arch.pc)) end_address = parse_address(str(args.until or self.get_unicorn_end_addr(start_address, args.nb))) self.run_unicorn(start_address, end_address, skip_emulation=args.skip_emulation, to_file=args.output_file) return - def get_unicorn_end_addr(self, start_addr, nb): + def get_unicorn_end_addr(self, start_addr: int, nb: int) -> int: dis = list(gef_disassemble(start_addr, nb + 1)) last_insn = dis[-1] return last_insn.address - def run_unicorn(self, start_insn_addr, end_insn_addr, *args, **kwargs): + def run_unicorn(self, start_insn_addr: int, end_insn_addr: int, *args, **kwargs) -> None: verbose = self["verbose"] or False skip_emulation = kwargs.get("skip_emulation", False) arch, mode = get_unicorn_arch(to_string=True) @@ -6395,7 +6403,7 @@ class RemoteCommand(GenericCommand): _example_ = "\n{0:s} --pid 6789 localhost:1234"\ "\n{0:s} --qemu-mode localhost:4444 # when using qemu-user".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=False) self.handler_connected = False self["clean_on_exit"] = ( False, "Clean the temporary data downloaded when the session exits.") @@ -6409,7 +6417,7 @@ def __init__(self): "--is-extended-remote": True, "--pid": 0, "--qemu-mode": True}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv, *args, **kwargs) -> None: if gef.session.remote is not None: err("You already are in remote session. Close it first before opening a new one...") return @@ -6483,7 +6491,7 @@ def do_invoke(self, argv, *args, **kwargs): gef.session.remote = pid return - def new_objfile_handler(self, event): + def new_objfile_handler(self, event) -> None: """Hook that handles new_objfile events, will update remote environment accordingly.""" if not is_remote_debug(): return @@ -6495,7 +6503,7 @@ def new_objfile_handler(self, event): ok("Download success: {:s} {:s} {:s}".format(remote_lib, RIGHT_ARROW, local_lib)) return - def setup_remote_environment(self, pid, update_solib=False): + def setup_remote_environment(self, pid: int, update_solib: bool = False) -> None: """Clone the remote environment locally in the temporary directory. The command will duplicate the entries in the /proc/ locally and then source those information into the current gdb context to allow gef to use @@ -6521,7 +6529,7 @@ def setup_remote_environment(self, pid, update_solib=False): ok("Remote information loaded to temporary path '{:s}'".format(directory)) return - def connect_target(self, target, is_extended_remote): + def connect_target(self, target: str, is_extended_remote: bool) -> bool: """Connect to remote target and get symbols. To prevent `gef` from requesting information not fetched just yet, we disable the context disable when connection was successful.""" hide_context() @@ -6536,18 +6544,18 @@ def connect_target(self, target, is_extended_remote): unhide_context() return ret - def load_from_remote_proc(self, pid, info): + def load_from_remote_proc(self, pid: int, info: str) -> Optional[str]: """Download one item from /proc/pid.""" remote_name = "/proc/{:d}/{:s}".format(pid, info) return download_file(remote_name, use_cache=False) - def refresh_shared_library_path(self): + def refresh_shared_library_path(self) -> None: dirs = [r for r, d, f in os.walk(self["root"])] path = ":".join(dirs) gdb.execute("set solib-search-path {:s}".format(path,)) return - def usage(self): + def usage(self) -> None: h = self._syntax_ h += "\n\t TARGET (mandatory) specifies the host:port, serial port or tty to connect to.\n" h += "\t-U will update gdb `solib-search-path` attribute to include the files downloaded from server (default: False).\n" @@ -6560,7 +6568,7 @@ def usage(self): info(h) return - def prepare_qemu_stub(self, target): + def prepare_qemu_stub(self, target: str) -> None: global gef reset_all_caches() @@ -6616,17 +6624,17 @@ class NopCommand(GenericCommand): --nb NUM_BYTES\tInstead of writing one instruction, patch the specified number of bytes""".format(_cmdline_) _example_ = "{:s} $pc".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return - def get_insn_size(self, addr): + def get_insn_size(self, addr: int) -> int: cur_insn = gef_current_instruction(addr) next_insn = gef_instruction_n(addr, 2) return next_insn.address - cur_insn.address @parse_arguments({"address": "$pc"}, {"--nb": 0, }) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv, *args, **kwargs) -> None: args = kwargs["arguments"] address = parse_address(args.address) if args.address else gef.arch.pc number_of_bytes = args.nb or 1 @@ -6634,7 +6642,7 @@ def do_invoke(self, argv, *args, **kwargs): return @only_if_gdb_running - def nop_bytes(self, loc, num_bytes): + def nop_bytes(self, loc: int, num_bytes: int) -> None: size = self.get_insn_size(loc) if num_bytes == 0 else num_bytes nops = gef.arch.nop_insn @@ -6668,13 +6676,13 @@ class StubCommand(GenericCommand): \t--retval RETVAL\tSet the return value""".format(_cmdline_) _example_ = "{:s} --retval 0 fork".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running @parse_arguments({"address": ""}, {("-r", "--retval"): 0}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv, *args, **kwargs) -> None: args = kwargs["arguments"] loc = args.address if args.address else "*{:#x}".format(gef.arch.pc) StubBreakpoint(loc, args.retval) @@ -6690,7 +6698,7 @@ class CapstoneDisassembleCommand(GenericCommand): _aliases_ = ["cs-dis"] _example_ = "{:s} --length 50 $pc".format(_cmdline_) - def pre_load(self): + def pre_load(self) -> None: try: __import__("capstone") except ImportError: @@ -6704,7 +6712,7 @@ def __init__(self): @only_if_gdb_running @parse_arguments({("location"): "$pc"}, {("--show-opcodes", "-s"): True, "--length": 0}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv, *args, **kwargs) -> None: args = kwargs["arguments"] show_opcodes = args.show_opcodes length = args.length or gef.config["context.nb_lines_code"] @@ -6737,7 +6745,7 @@ def do_invoke(self, argv, *args, **kwargs): gef_print(msg) return - def capstone_analyze_pc(self, insn, nb_insn): + def capstone_analyze_pc(self, insn, nb_insn: int) -> Tuple[bool, str]: if gef.arch.is_conditional_branch(insn): is_taken, reason = gef.arch.is_branch_taken(insn) if is_taken: @@ -6765,12 +6773,12 @@ class GlibcHeapCommand(GenericCommand): _cmdline_ = "heap" _syntax_ = "{:s} (chunk|chunks|bins|arenas|set-arena)".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=True) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: self.usage() return @@ -6783,12 +6791,12 @@ class GlibcHeapSetArenaCommand(GenericCommand): _syntax_ = "{:s} [address|symbol]".format(_cmdline_) _example_ = "{:s} 0x001337001337".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: global gef if not argv: @@ -6821,7 +6829,7 @@ class GlibcHeapArenaCommand(GenericCommand): _syntax_ = _cmdline_ @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: for arena in gef.heap.arenas: gef_print(str(arena)) return @@ -6835,13 +6843,13 @@ class GlibcHeapChunkCommand(GenericCommand): _cmdline_ = "heap chunk" _syntax_ = "{:s} [-h] [--allow-unaligned] [--number] address".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @parse_arguments({"address": ""}, {"--allow-unaligned": True, "--number": 1}) @only_if_gdb_running - def do_invoke(self, *args, **kwargs): + def do_invoke(self, *args, **kwargs) -> None: args = kwargs["arguments"] if not args.address: err("Missing chunk address") @@ -6880,14 +6888,14 @@ class GlibcHeapChunksCommand(GenericCommand): _syntax_ = "{0} [-h] [--all] [--allow-unaligned] [arena_address]".format(_cmdline_) _example_ = "\n{0}\n{0} 0x555555775000".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) self["peek_nb_byte"] = ( 16, "Hexdump N first byte(s) inside the chunk data (0 to disable)") return @parse_arguments({"arena_address": ""}, {("--all", "-a"): True, "--allow-unaligned": True}) @only_if_gdb_running - def do_invoke(self, *args, **kwargs): + def do_invoke(self, *args, **kwargs) -> None: args = kwargs["arguments"] arenas = gef.heap.arenas for arena in arenas: @@ -6895,7 +6903,7 @@ def do_invoke(self, *args, **kwargs): if not args.all: break - def dump_chunks_arena(self, arena, print_arena=False, allow_unaligned=False): + def dump_chunks_arena(self, arena: GlibcArena, print_arena: bool = False, allow_unaligned: bool = False) -> None: top_chunk_addr = arena.top heap_addr = arena.heap_addr(allow_unaligned=allow_unaligned) if heap_addr is None: @@ -6917,7 +6925,7 @@ def dump_chunks_arena(self, arena, print_arena=False, allow_unaligned=False): self.dump_chunks_heap(start, until=until, top=top_chunk_addr, allow_unaligned=allow_unaligned) return - def dump_chunks_heap(self, start, until=None, top=None, allow_unaligned=False): + def dump_chunks_heap(self, start: int, until: Optional[int] = None, top: Optional[int] = None, allow_unaligned: bool = False) -> None: nb = self["peek_nb_byte"] chunk_iterator = GlibcChunk(start, from_base=True, allow_unaligned=allow_unaligned) for chunk in chunk_iterator: @@ -6945,12 +6953,12 @@ class GlibcHeapBinsCommand(GenericCommand): _cmdline_ = "heap bins" _syntax_ = "{:s} [{:s}]".format(_cmdline_, "|".join(_bin_types_)) - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=True, complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if not argv: for bin_t in GlibcHeapBinsCommand._bin_types_: gdb.execute("heap bins {:s}".format(bin_t)) @@ -6965,7 +6973,7 @@ def do_invoke(self, argv): return @staticmethod - def pprint_bin(arena_addr, index, _type=""): + def pprint_bin(arena_addr: str, index: int, _type: str = "") -> int: arena = GlibcArena(arena_addr) fw, bk = arena.bin(index) @@ -7002,12 +7010,12 @@ class GlibcHeapTcachebinsCommand(GenericCommand): TCACHE_MAX_BINS = 0x40 - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: # Determine if we are using libc with tcache built in (2.26+) if get_libc_version() < (2, 26): info("No Tcache in this version of libc") @@ -7080,7 +7088,7 @@ def do_invoke(self, argv): return @staticmethod - def find_tcache(): + def find_tcache() -> int: """Return the location of the current thread's tcache.""" try: # For multithreaded binaries, the tcache symbol (in thread local @@ -7099,7 +7107,7 @@ def find_tcache(): return tcache_addr @staticmethod - def check_thread_ids(tids): + def check_thread_ids(tids: List[int]) -> List[int]: """Check the validity, dedup, and return all valid tids.""" existing_tids = [t.num for t in gdb.selected_inferior().threads()] valid_tids = set() @@ -7117,7 +7125,7 @@ def check_thread_ids(tids): return list(valid_tids) @staticmethod - def tcachebin(tcache_base, i): + def tcachebin(tcache_base: int, i: int) -> Tuple[Optional[GlibcChunk], int]: """Return the head chunk in tcache[i] and the number of chunks in the bin.""" assert i < GlibcHeapTcachebinsCommand.TCACHE_MAX_BINS, "index should be less then TCACHE_MAX_BINS" tcache_chunk = GlibcChunk(tcache_base) @@ -7155,12 +7163,12 @@ class GlibcHeapFastbinsYCommand(GenericCommand): _cmdline_ = "heap bins fast" _syntax_ = "{:s} [ARENA_ADDRESS]".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: def fastbin_index(sz): return (sz >> 4) - 2 if SIZE_SZ == 8 else (sz >> 3) - 2 @@ -7215,12 +7223,12 @@ class GlibcHeapUnsortedBinsCommand(GenericCommand): _cmdline_ = "heap bins unsorted" _syntax_ = "{:s} [ARENA_ADDRESS]".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if get_glibc_arena() is None: err("Invalid Glibc arena") return @@ -7239,12 +7247,12 @@ class GlibcHeapSmallBinsCommand(GenericCommand): _cmdline_ = "heap bins small" _syntax_ = "{:s} [ARENA_ADDRESS]".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if not gef.heap.main_arena: err("Heap not initialized") return @@ -7268,12 +7276,12 @@ class GlibcHeapLargeBinsCommand(GenericCommand): _cmdline_ = "heap bins large" _syntax_ = "{:s} [ARENA_ADDRESS]".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if gef.heap.main_arena is None: err("Invalid Glibc arena") return @@ -7300,7 +7308,7 @@ class SolveKernelSymbolCommand(GenericCommand): _example_ = "{:s} prepare_creds".format(_cmdline_) @parse_arguments({"symbol": ""}, {}) - def do_invoke(self, *args, **kwargs): + def do_invoke(self, *args, **kwargs) -> None: def hex_to_int(num): try: return int(num, 16) @@ -7336,7 +7344,7 @@ class DetailRegistersCommand(GenericCommand): @only_if_gdb_running @parse_arguments({"registers": [""]}, {}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv: List, *args, **kwargs) -> None: unchanged_color = gef.config["theme.registers_register_name"] changed_color = gef.config["theme.registers_value_changed"] string_color = gef.config["theme.dereference_string"] @@ -7428,11 +7436,11 @@ class ShellcodeCommand(GenericCommand): _cmdline_ = "shellcode" _syntax_ = "{:s} (search|get)".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=True) return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: err("Missing sub-command (search|get)") self.usage() return @@ -7449,7 +7457,7 @@ class ShellcodeSearchCommand(GenericCommand): api_base = "http://shell-storm.org" search_url = "{}/api/?s=".format(api_base) - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if not argv: err("Missing pattern to search") self.usage() @@ -7458,7 +7466,7 @@ def do_invoke(self, argv): self.search_shellcode(argv) return - def search_shellcode(self, search_options): + def search_shellcode(self, search_options: List) -> None: # API : http://shell-storm.org/shellcode/ args = "*".join(search_options) @@ -7498,7 +7506,7 @@ class ShellcodeGetCommand(GenericCommand): api_base = "http://shell-storm.org" get_url = "{}/shellcode/files/shellcode-{{:d}}.php".format(api_base) - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if len(argv) != 1: err("Missing ID to download") self.usage() @@ -7512,7 +7520,7 @@ def do_invoke(self, argv): self.get_shellcode(int(argv[0])) return - def get_shellcode(self, sid): + def get_shellcode(self, sid: int) -> None: info("Downloading shellcode id={:d}".format(sid)) res = http_get(self.get_url.format(sid)) if res is None: @@ -7537,11 +7545,11 @@ class RopperCommand(GenericCommand): _cmdline_ = "ropper" _syntax_ = "{:s} [ROPPER_OPTIONS]".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_NONE) return - def pre_load(self): + def pre_load(self) -> None: try: __import__("ropper") except ImportError: @@ -7550,7 +7558,7 @@ def pre_load(self): return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: ropper = sys.modules["ropper"] if "--file" not in argv: path = get_filepath() @@ -7597,13 +7605,13 @@ class AssembleCommand(GenericCommand): valid_archs = valid_arch_modes.keys() valid_modes = [_ for sublist in valid_arch_modes.values() for _ in sublist] - def __init__(self): + def __init__(self) -> None: super().__init__() self["default_architecture"] = ( "X86", "Specify the default architecture to use when assembling") self["default_mode"] = ( "64", "Specify the default architecture to use when assembling") return - def pre_load(self): + def pre_load(self) -> None: try: __import__("keystone") except ImportError: @@ -7611,13 +7619,13 @@ def pre_load(self): raise ImportWarning(msg) return - def usage(self): + def usage(self) -> None: super().usage() gef_print("") self.list_archs() return - def list_archs(self): + def list_archs(self) -> None: gef_print("Available architectures/modes (with endianness):") # for updates, see https://github.com/keystone-engine/keystone/blob/master/include/keystone/keystone.h for arch in self.valid_arch_modes: @@ -7633,7 +7641,7 @@ def list_archs(self): return @parse_arguments({"instructions": [""]}, {"--mode": "", "--arch": "", "--overwrite-location": 0, "--endian": "little", "--list-archs": True, "--as-shellcode": True}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv: List, *args, **kwargs) -> None: arch_s, mode_s, endian_s = self["default_architecture"], self["default_mode"], "" args = kwargs["arguments"] @@ -7717,13 +7725,13 @@ class ProcessListingCommand(GenericCommand): _aliases_ = ["ps"] _example_ = "{:s} gdb.*".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) self["ps_command"] = ( "{:s} auxww".format(str(gef.session.constants["ps"])), "`ps` command to get process information") return @parse_arguments({"pattern": ""}, {"--attach": True, "--smart-scan": True}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv: List, *args, **kwargs) -> None: args = kwargs["arguments"] do_attach = args.attach smart_scan = args.smart_scan @@ -7753,7 +7761,7 @@ def do_invoke(self, argv, *args, **kwargs): return None - def get_processes(self): + def get_processes(self) -> Generator[Dict[str,str], Any, None]: output = gef_execute_external(self["ps_command"].split(), True) names = [x.lower().replace("%", "") for x in output[0].split()] @@ -7781,12 +7789,12 @@ class ElfInfoCommand(GenericCommand): _syntax_ = "{:s} [FILE]".format(_cmdline_) _example_ = "{:s} /bin/ls".format(_cmdline_) - def __init__(self, *args, **kwargs): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @parse_arguments({}, {"--filename": ""}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv: List, *args, **kwargs) -> None: args = kwargs["arguments"] if is_qemu_system(): @@ -7981,12 +7989,12 @@ class EntryPointBreakCommand(GenericCommand): _syntax_ = _cmdline_ _aliases_ = ["start",] - def __init__(self, *args, **kwargs): + def __init__(self) -> None: super().__init__() self["entrypoint_symbols"] = ( "main _main __libc_start_main __uClibc_main start _start", "Possible symbols for entry points") return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: fpath = get_filepath() if fpath is None: warn("No executable to debug, use `file` to load a binary") @@ -8036,12 +8044,12 @@ def do_invoke(self, argv): gdb.execute("run {}".format(" ".join(argv))) return - def set_init_tbreak(self, addr): + def set_init_tbreak(self, addr: int) -> EntryBreakBreakpoint: info("Breaking at entry-point: {:#x}".format(addr)) bp = EntryBreakBreakpoint("*{:#x}".format(addr)) return bp - def set_init_tbreak_pie(self, addr, argv): + def set_init_tbreak_pie(self, addr: int, argv: List[str]) -> EntryBreakBreakpoint: warn("PIC binary detected, retrieving text base address") gdb.execute("set stop-on-solib-events 1") hide_context() @@ -8062,12 +8070,12 @@ class NamedBreakpointCommand(GenericCommand): _aliases_ = ["nb",] _example = "{:s} main *0x4008a9" - def __init__(self, *args, **kwargs): + def __init__(self) -> None: super().__init__() return @parse_arguments({"name": "", "address": "*$pc"}, {}) - def do_invoke(self, *args, **kwargs): + def do_invoke(self, *args, **kwargs) -> None: args = kwargs["arguments"] if not args.name: err("Missing name for breakpoint") @@ -8091,7 +8099,7 @@ class ContextCommand(GenericCommand): old_registers = {} - def __init__(self): + def __init__(self) -> None: super().__init__() self["enable"] = ( True, "Enable/disable printing the context when breaking") self["show_source_code_variable_values"] = ( True, "Show extra PC context info in the source code") @@ -8131,12 +8139,12 @@ def __init__(self): } return - def post_load(self): + def post_load(self) -> None: gef_on_continue_hook(self.update_registers) gef_on_continue_hook(self.empty_extra_messages) return - def show_legend(self): + def show_legend(self) -> None: if gef.config["gef.disable_color"] is True: return str_color = gef.config["theme.dereference_string"] @@ -8154,7 +8162,7 @@ def show_legend(self): return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if not self["enable"] or gef.ui.context_hidden: return @@ -8198,7 +8206,7 @@ def do_invoke(self, argv): disable_redirect_output() return - def context_title(self, m): + def context_title(self, m: Optional[str]) -> None: # allow for not displaying a title line if m is None: return @@ -8223,7 +8231,7 @@ def context_title(self, m): gef_print(title) return - def context_regs(self): + def context_regs(self) -> None: self.context_title("registers") ignored_registers = set(self["ignore_registers"].split()) @@ -8293,7 +8301,7 @@ def context_regs(self): gef_print("Flags: {:s}".format(gef.arch.flag_register_to_human())) return - def context_stack(self): + def context_stack(self) -> None: self.context_title("stack") show_raw = self["show_stack_raw"] @@ -8312,10 +8320,10 @@ def context_stack(self): return - def addr_has_breakpoint(self, address, bp_locations): + def addr_has_breakpoint(self, address: int, bp_locations: List[str]) -> bool: return any(hex(address) in b for b in bp_locations) - def context_code(self): + def context_code(self) -> None: nb_insn = self["nb_lines_code"] nb_insn_prev = self["nb_lines_code_prev"] use_capstone = "use_capstone" in self and self["use_capstone"] @@ -8388,7 +8396,7 @@ def context_code(self): err("Cannot disassemble from $PC") return - def context_args(self): + def context_args(self) -> None: insn = gef_current_instruction(gef.arch.pc) if not gef.arch.is_call(insn): return @@ -8426,7 +8434,7 @@ def context_args(self): self.print_arguments_from_symbol(target, sym) return - def print_arguments_from_symbol(self, function_name, symbol): + def print_arguments_from_symbol(self, function_name: str, symbol) -> None: """If symbols were found, parse them and print the argument adequately.""" args = [] @@ -8448,10 +8456,10 @@ def print_arguments_from_symbol(self, function_name, symbol): gef_print(")") return - def print_guessed_arguments(self, function_name): + def print_guessed_arguments(self, function_name: str) -> None: """When no symbol, read the current basic block and look for "interesting" instructions.""" - def __get_current_block_start_address(): + def __get_current_block_start_address() -> Optional[int]: pc = gef.arch.pc try: block = gdb.block_for_pc(pc) @@ -8528,11 +8536,11 @@ def __get_current_block_start_address(): gef_print(")") return - def line_has_breakpoint(self, file_name, line_number, bp_locations): + def line_has_breakpoint(self, file_name: str, line_number: int, bp_locations: List[str]) -> bool: filename_line = "{}:{}".format(file_name, line_number) return any(filename_line in loc for loc in bp_locations) - def context_source(self): + def context_source(self) -> None: try: pc = gef.arch.pc symtabline = gdb.find_pc_line(pc) @@ -8588,7 +8596,7 @@ def context_source(self): break return - def get_pc_context_info(self, pc, line): + def get_pc_context_info(self, pc: int, line: str) -> str: try: current_block = gdb.block_for_pc(pc) if not current_block or not current_block.is_valid(): return "" @@ -8621,7 +8629,7 @@ def get_pc_context_info(self, pc, line): pass return "" - def context_trace(self): + def context_trace(self) -> None: self.context_title("trace") nb_backtrace = self["nb_lines_backtrace"] @@ -8685,8 +8693,8 @@ def context_trace(self): orig_frame.select() return - def context_threads(self): - def reason(): + def context_threads(self) -> None: + def reason() -> str: res = gdb.execute("info program", to_string=True).splitlines() if not res: return "NOT RUNNING" @@ -8753,7 +8761,7 @@ def reason(): selected_frame.select() return - def context_additional_information(self): + def context_additional_information(self) -> None: if not gef.ui.context_messages: return @@ -8765,7 +8773,7 @@ def context_additional_information(self): else: info(text) return - def context_memory(self): + def context_memory(self) -> None: for address, opt in sorted(gef.ui.watches.items()): sz, fmt = opt[0:2] self.context_title("memory:{:#x}".format(address)) @@ -8782,7 +8790,7 @@ def context_memory(self): )) @classmethod - def update_registers(cls, event): + def update_registers(cls, _) -> None: for reg in gef.arch.all_registers: try: cls.old_registers[reg] = gef.arch.register(reg) @@ -8790,7 +8798,7 @@ def update_registers(cls, event): cls.old_registers[reg] = 0 return - def empty_extra_messages(self, event): + def empty_extra_messages(self, _) -> None: gef.ui.context_messages.clear() return @@ -8801,12 +8809,12 @@ class MemoryCommand(GenericCommand): _cmdline_ = "memory" _syntax_ = "{:s} (watch|unwatch|reset|list)".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=True) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: self.usage() return @@ -8818,12 +8826,12 @@ class MemoryWatchCommand(GenericCommand): _syntax_ = "{:s} ADDRESS [SIZE] [(qword|dword|word|byte|pointers)]".format(_cmdline_) _example_ = "\n\t{0:s} 0x603000 0x100 byte\n\t{0:s} $sp".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if len(argv) not in (1, 2, 3): self.usage() return @@ -8856,12 +8864,12 @@ class MemoryUnwatchCommand(GenericCommand): _syntax_ = "{:s} ADDRESS".format(_cmdline_) _example_ = "\n\t{0:s} 0x603000\n\t{0:s} $sp".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if not argv: self.usage() return @@ -8882,7 +8890,7 @@ class MemoryWatchResetCommand(GenericCommand): _syntax_ = "{:s}".format(_cmdline_) @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: gef.ui.watches.clear() ok("Memory watches cleared") return @@ -8895,7 +8903,7 @@ class MemoryWatchListCommand(GenericCommand): _syntax_ = "{:s}".format(_cmdline_) @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if not gef.ui.watches: info("No memory watches") return @@ -8914,7 +8922,7 @@ class HexdumpCommand(GenericCommand): _syntax_ = "{:s} (qword|dword|word|byte) [LOCATION] [--size SIZE] [--reverse]".format(_cmdline_) _example_ = "{:s} byte $rsp --size 16 --reverse".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION, prefix=True) self["always_show_ascii"] = ( False, "If true, hexdump will always display the ASCII dump") self.format = None @@ -8923,7 +8931,7 @@ def __init__(self): @only_if_gdb_running @parse_arguments({"address": "",}, {("--reverse", "-r"): True, ("--size", "-s"): 0}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv: List, *args, **kwargs) -> None: valid_formats = ["byte", "word", "dword", "qword"] if not self.format or self.format not in valid_formats: err("Invalid command") @@ -8950,7 +8958,7 @@ def do_invoke(self, argv, *args, **kwargs): gef_print("\n".join(lines)) return - def _hexdump(self, start_addr, length, arrange_as, offset=0): + def _hexdump(self, start_addr: int, length: int, arrange_as: str, offset: int = 0) -> List[str]: endianness = gef.arch.endianness base_address_color = gef.config["theme.dereference_base_address"] @@ -8992,7 +9000,7 @@ class HexdumpQwordCommand(HexdumpCommand): _syntax_ = "{:s} [ADDRESS] [[L][SIZE]] [REVERSE]".format(_cmdline_) _example_ = "{:s} qword $rsp L16 REVERSE".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__() self.format = "qword" return @@ -9006,7 +9014,7 @@ class HexdumpDwordCommand(HexdumpCommand): _syntax_ = "{:s} [ADDRESS] [[L][SIZE]] [REVERSE]".format(_cmdline_) _example_ = "{:s} $esp L16 REVERSE".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__() self.format = "dword" return @@ -9020,7 +9028,7 @@ class HexdumpWordCommand(HexdumpCommand): _syntax_ = "{:s} [ADDRESS] [[L][SIZE]] [REVERSE]".format(_cmdline_) _example_ = "{:s} $esp L16 REVERSE".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__() self.format = "word" return @@ -9034,7 +9042,7 @@ class HexdumpByteCommand(HexdumpCommand): _syntax_ = "{:s} [ADDRESS] [[L][SIZE]] [REVERSE]".format(_cmdline_) _example_ = "{:s} $rsp L16".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__() self.format = "byte" return @@ -9054,14 +9062,14 @@ class PatchCommand(GenericCommand): "byte": (1, "B"), } - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=True, complete=gdb.COMPLETE_LOCATION) self.format = None return @only_if_gdb_running @parse_arguments({"location": "", "values": ["", ]}, {}) - def do_invoke(self, argv, *args, **kwargs): + def do_invoke(self, argv: List, *args, **kwargs) -> None: args = kwargs["arguments"] if not self.format or self.format not in self.SUPPORTED_SIZES: self.usage() @@ -9091,7 +9099,7 @@ class PatchQwordCommand(PatchCommand): _syntax_ = "{0:s} LOCATION QWORD1 [QWORD2 [QWORD3..]]".format(_cmdline_) _example_ = "{:s} $rip 0x4141414141414141".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__() self.format = "qword" return @@ -9105,7 +9113,7 @@ class PatchDwordCommand(PatchCommand): _syntax_ = "{0:s} LOCATION DWORD1 [DWORD2 [DWORD3..]]".format(_cmdline_) _example_ = "{:s} $rip 0x41414141".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__() self.format = "dword" return @@ -9119,7 +9127,7 @@ class PatchWordCommand(PatchCommand): _syntax_ = "{0:s} LOCATION WORD1 [WORD2 [WORD3..]]".format(_cmdline_) _example_ = "{:s} $rip 0x4141".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__() self.format = "word" return @@ -9133,7 +9141,7 @@ class PatchByteCommand(PatchCommand): _syntax_ = "{0:s} LOCATION BYTE1 [BYTE2 [BYTE3..]]".format(_cmdline_) _example_ = "{:s} $pc 0x41 0x41 0x41 0x41 0x41".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__() self.format = "byte" return @@ -9148,7 +9156,7 @@ class PatchStringCommand(GenericCommand): _example_ = "{:s} $sp \"GEFROCKS\"".format(_cmdline_) @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: argc = len(argv) if argc != 2: self.usage() @@ -9167,7 +9175,7 @@ def do_invoke(self, argv): return @lru_cache() -def dereference_from(addr): +def dereference_from(addr: int) -> List[str]: if not is_alive(): return [format_address(addr),] @@ -9239,13 +9247,13 @@ class DereferenceCommand(GenericCommand): _aliases_ = ["telescope", ] _example_ = "{:s} --length 20 --reference $sp+0x10 $sp".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) self["max_recursion"] = ( 7, "Maximum level of pointer recursion") return @staticmethod - def pprint_dereferenced(addr, idx, base_offset=0): + def pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) -> str: base_address_color = gef.config["theme.dereference_base_address"] registers_color = gef.config["theme.dereference_register_value"] @@ -9277,7 +9285,7 @@ def pprint_dereferenced(addr, idx, base_offset=0): @only_if_gdb_running @parse_arguments({"address": "$sp"}, {("-r", "--reference"): "", ("-l", "--length"): 10}) - def do_invoke(self, *args, **kwargs): + def do_invoke(self, *args, **kwargs) -> None: args = kwargs["arguments"] nb = args.length @@ -9321,7 +9329,7 @@ class ASLRCommand(GenericCommand): _cmdline_ = "aslr" _syntax_ = "{:s} [(on|off)]".format(_cmdline_) - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: argc = len(argv) if argc == 0: @@ -9363,7 +9371,7 @@ class ResetCacheCommand(GenericCommand): _cmdline_ = "reset-cache" _syntax_ = _cmdline_ - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: reset_all_caches() return @@ -9378,7 +9386,7 @@ class VMMapCommand(GenericCommand): _example_ = "{:s} libc".format(_cmdline_) @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: vmmap = gef.memory.maps if not vmmap: err("No address mapping information found") @@ -9404,7 +9412,7 @@ def do_invoke(self, argv): self.print_entry(entry) return - def print_entry(self, entry): + def print_entry(self, entry: Section) -> None: line_color = "" if entry.path == "[stack]": line_color = gef.config["theme.address_stack"] @@ -9429,7 +9437,7 @@ def print_entry(self, entry): gef_print(line) return - def show_legend(self): + def show_legend(self) -> None: code_addr_color = gef.config["theme.address_code"] stack_addr_color = gef.config["theme.address_stack"] heap_addr_color = gef.config["theme.address_heap"] @@ -9440,7 +9448,7 @@ def show_legend(self): )) return - def is_integer(self, n): + def is_integer(self, n: str) -> bool: try: int(n, 0) except ValueError: @@ -9460,7 +9468,7 @@ class XFilesCommand(GenericCommand): _example_ = "\n{0:s} libc\n{0:s} libc IO_vtables".format(_cmdline_) @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: color = gef.config["theme.table_heading"] headers = ["Start", "End", "Name", "File"] gef_print(Color.colorify("{:<{w}s}{:<{w}s}{:<21s} {:s}".format(*headers, w=gef.arch.ptrsize*2+3), color)) @@ -9492,12 +9500,12 @@ class XAddressInfoCommand(GenericCommand): _syntax_ = "{:s} LOCATION".format(_cmdline_) _example_ = "{:s} $pc".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if not argv: err("At least one valid address must be specified") self.usage() @@ -9513,7 +9521,7 @@ def do_invoke(self, argv): err("{:s}".format(str(gdb_err))) return - def infos(self, address): + def infos(self, address: int) -> None: addr = lookup_address(address) if not addr.valid: warn("Cannot reach {:#x} in memory space".format(address)) @@ -9557,11 +9565,11 @@ class XorMemoryCommand(GenericCommand): _cmdline_ = "xor-memory" _syntax_ = "{:s} (display|patch) ADDRESS SIZE KEY".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=True) return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: self.usage() return @@ -9576,7 +9584,7 @@ class XorMemoryDisplayCommand(GenericCommand): _example_ = "{:s} $sp 16 41414141".format(_cmdline_) @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if len(argv) != 3: self.usage() return @@ -9605,7 +9613,7 @@ class XorMemoryPatchCommand(GenericCommand): _example_ = "{:s} $sp 16 41414141".format(_cmdline_) @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if len(argv) != 3: self.usage() return @@ -9630,14 +9638,14 @@ class TraceRunCommand(GenericCommand): _syntax_ = "{:s} LOCATION [MAX_CALL_DEPTH]".format(_cmdline_) _example_ = "{:s} 0x555555554610".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(self._cmdline_, complete=gdb.COMPLETE_LOCATION) self["max_tracing_recursion"] = ( 1, "Maximum depth of tracing") self["tracefile_prefix"] = ( "./gef-trace-", "Specify the tracing output file prefix") return @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if len(argv) not in (1, 2): self.usage() return @@ -9657,7 +9665,7 @@ def do_invoke(self, argv): self.trace(loc_start, loc_end, depth) return - def get_frames_size(self): + def get_frames_size(self) -> int: n = 0 f = gdb.newest_frame() while f: @@ -9665,7 +9673,7 @@ def get_frames_size(self): f = f.older() return n - def trace(self, loc_start, loc_end, depth): + def trace(self, loc_start: int, loc_end: int, depth: int) -> None: info("Tracing from {:#x} to {:#x} (max depth={:d})".format(loc_start, loc_end, depth)) logfile = "{:s}{:#x}-{:#x}.txt".format(self["tracefile_prefix"], loc_start, loc_end) enable_redirect_output(to_file=logfile) @@ -9677,7 +9685,7 @@ def trace(self, loc_start, loc_end, depth): info("Hint: import logfile with `ida_color_gdb_trace.py` script in IDA to visualize path") return - def start_tracing(self, loc_start, loc_end, depth): + def start_tracing(self, loc_start: int, loc_end: int, depth: int) -> None: loc_cur = loc_start frame_count_init = self.get_frames_size() @@ -9720,12 +9728,12 @@ class PatternCommand(GenericCommand): _cmdline_ = "pattern" _syntax_ = "{:s} (create|search) ARGS".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=True) self["length"] = ( 1024, "Default length of a cyclic buffer to generate") return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: self.usage() return @@ -9741,7 +9749,7 @@ class PatternCreateCommand(GenericCommand): _example_ = "{:s} 4096".format(_cmdline_) @parse_arguments({"length": 0}, {("-n", "--n"): 0}) - def do_invoke(self, *args, **kwargs): + def do_invoke(self, *args, **kwargs) -> None: args = kwargs["arguments"] length = args.length or gef.config["pattern.length"] n = args.n or gef.arch.ptrsize @@ -9766,7 +9774,7 @@ class PatternSearchCommand(GenericCommand): @only_if_gdb_running @parse_arguments({"pattern": ""}, {("-n", "--n"): 0, ("-l", "--max-length"): 0}) - def do_invoke(self, *args, **kwargs): + def do_invoke(self, *args, **kwargs) -> None: args = kwargs["arguments"] max_length = args.max_length or gef.config["pattern.length"] n = args.n or gef.arch.ptrsize @@ -9774,7 +9782,7 @@ def do_invoke(self, *args, **kwargs): self.search(args.pattern, max_length, n) return - def search(self, pattern, size, period): + def search(self, pattern: str, size: int, period: int) -> None: pattern_be, pattern_le = None, None # 1. check if it's a symbol (like "$sp" or "0x1337") @@ -9828,11 +9836,11 @@ class ChecksecCommand(GenericCommand): _syntax_ = "{:s} [FILENAME]".format(_cmdline_) _example_ = "{} /bin/ls".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_FILENAME) return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: argc = len(argv) if argc == 0: @@ -9853,7 +9861,7 @@ def do_invoke(self, argv): self.print_security_properties(filename) return - def print_security_properties(self, filename): + def print_security_properties(self, filename: str) -> None: sec = checksec(filename) for prop in sec: if prop in ("Partial RelRO", "Full RelRO"): continue @@ -9890,7 +9898,7 @@ def __init__(self, *args, **kwargs): "not been resolved") return - def get_jmp_slots(self, readelf, filename): + def get_jmp_slots(self, readelf: str, filename: str) -> List[str]: output = [] cmd = [readelf, "--relocs", filename] lines = gef_execute_external(cmd, as_list=True) @@ -9900,7 +9908,7 @@ def get_jmp_slots(self, readelf, filename): return output @only_if_gdb_running - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: try: readelf = gef.session.constants["readelf"] @@ -9974,11 +9982,11 @@ class HighlightCommand(GenericCommand): _syntax_ = "{} (add|remove|list|clear)".format(_cmdline_) _aliases_ = ["hl"] - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=True) self["regex"] = ( False, "Enable regex highlighting") - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: return self.usage() @@ -9989,16 +9997,17 @@ class HighlightListCommand(GenericCommand): _aliases_ = ["highlight ls", "hll"] _syntax_ = _cmdline_ - def print_highlight_table(self): + def print_highlight_table(self) -> None: if not gef.ui.highlight_table: - return err("no matches found") + err("no matches found") + return left_pad = max(map(len, gef.ui.highlight_table.keys())) for match, color in sorted(gef.ui.highlight_table.items()): print("{} {} {}".format(Color.colorify(match.ljust(left_pad), color), VERTICAL_LINE, Color.colorify(color, color))) return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: return self.print_highlight_table() @@ -10009,7 +10018,7 @@ class HighlightClearCommand(GenericCommand): _aliases_ = ["hlc"] _syntax_ = _cmdline_ - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: return gef.ui.highlight_table.clear() @@ -10021,7 +10030,7 @@ class HighlightAddCommand(GenericCommand): _aliases_ = ["highlight set", "hla"] _example_ = "{} 41414141 yellow".format(_cmdline_) - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if len(argv) < 2: return self.usage() @@ -10044,7 +10053,7 @@ class HighlightRemoveCommand(GenericCommand): ] _example_ = "{} remove 41414141".format(_cmdline_) - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if not argv: return self.usage() @@ -10062,7 +10071,7 @@ class FormatStringSearchCommand(GenericCommand): _syntax_ = _cmdline_ _aliases_ = ["fmtstr-helper",] - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: dangerous_functions = { "printf": 0, "sprintf": 1, @@ -10097,7 +10106,7 @@ class HeapAnalysisCommand(GenericCommand): _cmdline_ = "heap-analysis-helper" _syntax_ = _cmdline_ - def __init__(self, *args, **kwargs): + def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_NONE) self["check_free_null"] = ( False, "Break execution when a free(NULL) is encountered") self["check_double_free"] = ( True, "Break execution when a double free is encountered") @@ -10113,7 +10122,7 @@ def __init__(self, *args, **kwargs): @only_if_gdb_running @experimental_feature - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if not argv: self.setup() return @@ -10122,7 +10131,7 @@ def do_invoke(self, argv): self.dump_tracked_allocations() return - def setup(self): + def setup(self) -> None: ok("Tracking malloc() & calloc()") self.bp_malloc = TraceMallocBreakpoint("__libc_malloc") self.bp_calloc = TraceMallocBreakpoint("__libc_calloc") @@ -10142,7 +10151,7 @@ def setup(self): gef_on_exit_hook(self.clean) return - def dump_tracked_allocations(self): + def dump_tracked_allocations(self) -> None: global gef if gef.session.heap_allocated_chunks: @@ -10158,7 +10167,7 @@ def dump_tracked_allocations(self): ok("No free() chunk tracked") return - def clean(self, event): + def clean(self, _) -> None: global gef ok("{} - Cleaning up".format(Color.colorify("Heap-Analysis", "yellow bold"),)) @@ -10192,13 +10201,13 @@ class IsSyscallCommand(GenericCommand): _cmdline_ = "is-syscall" _syntax_ = _cmdline_ - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: insn = gef_current_instruction(gef.arch.pc) ok("Current instruction is{}a syscall".format(" " if self.is_syscall(gef.arch, insn) else " not ")) return - def is_syscall(self, arch, instruction): + def is_syscall(self, arch, instruction: Instruction) -> bool: insn_str = instruction.mnemonic + " " + ", ".join(instruction.operands) return insn_str.strip() in arch.syscall_instructions @@ -10209,13 +10218,13 @@ class SyscallArgsCommand(GenericCommand): _cmdline_ = "syscall-args" _syntax_ = _cmdline_ - def __init__(self): + def __init__(self) -> None: super().__init__() path = pathlib.Path(gef.config["gef.tempdir"]) / "syscall-tables" self["path"] = (str(path.absolute()), "Path to store/load the syscall tables files") return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: color = gef.config["theme.table_heading"] path = self.get_settings_path() @@ -10261,20 +10270,20 @@ def do_invoke(self, argv): return - def get_filepath(self, x): + def get_filepath(self, x: str) -> Optional[str]: p = self.get_settings_path() if not p: return None return os.path.join(p, "{}.py".format(x)) - def get_module(self, modname): + def get_module(self, modname: str): _fullname = self.get_filepath(modname) return importlib.machinery.SourceFileLoader(modname, _fullname).load_module(None) - def get_syscall_table(self, modname): + def get_syscall_table(self, modname: str): _mod = self.get_module(modname) return getattr(_mod, "syscall_table") - def get_settings_path(self): + def get_settings_path(self) -> Optional[pathlib.Path]: path = pathlib.Path(os.path.expanduser(self["path"])) return path if path.exists() and path.is_dir() else None @@ -10291,18 +10300,18 @@ class GenericFunction(gdb.Function, metaclass=abc.ABCMeta): @abc.abstractproperty def _function_(self): pass @property - def _syntax_(self): + def _syntax_(self) -> str: return "${}([offset])".format(self._function_) - def __init__ (self): + def __init__(self) -> None: super().__init__(self._function_) - def invoke(self, *args): + def invoke(self, *args) -> int: if not is_alive(): raise gdb.GdbError("No debugging session active") return int(self.do_invoke(args)) - def arg_to_long(self, args, index, default=0): + def arg_to_long(self, args: List, index: int, default: int = 0) -> int: try: addr = args[index] return int(addr) if addr.address is None else int(addr.address) @@ -10310,7 +10319,7 @@ def arg_to_long(self, args, index, default=0): return default @abc.abstractmethod - def do_invoke(self, args): pass + def do_invoke(self, args) -> None: pass @register_function @@ -10318,7 +10327,7 @@ class StackOffsetFunction(GenericFunction): """Return the current stack base address plus an optional offset.""" _function_ = "_stack" - def do_invoke(self, args): + def do_invoke(self, args: List) -> int: base = get_section_base_address("[stack]") if not base: raise gdb.GdbError("Stack not found") @@ -10331,7 +10340,7 @@ class HeapBaseFunction(GenericFunction): """Return the current heap base address plus an optional offset.""" _function_ = "_heap" - def do_invoke(self, args): + def do_invoke(self, args: List) -> int: base = gef.heap.base_address if not base: base = get_section_base_address("[heap]") @@ -10348,7 +10357,7 @@ class SectionBaseFunction(GenericFunction): _syntax_ = "$_base([filepath])" _example_ = "p $_base(\\\"/usr/lib/ld-2.33.so\\\")" - def do_invoke(self, args): + def do_invoke(self, args: List) -> int: try: name = args[0].string() except IndexError: @@ -10371,7 +10380,7 @@ class BssBaseFunction(GenericFunction): _function_ = "_bss" _example_ = "deref $_bss(0x20)" - def do_invoke(self, args): + def do_invoke(self, args: List) -> int: base = get_zone_base_address(".bss") if not base: raise gdb.GdbError("BSS not found") @@ -10384,7 +10393,7 @@ class GotBaseFunction(GenericFunction): _function_ = "_got" _example_ = "deref $_got(0x20)" - def do_invoke(self, args): + def do_invoke(self, args: List) -> int: base = get_zone_base_address(".got") if not base: raise gdb.GdbError("GOT not found") @@ -10397,20 +10406,20 @@ class GefFunctionsCommand(GenericCommand): _cmdline_ = "functions" _syntax_ = _cmdline_ - def __init__(self): + def __init__(self) -> None: super().__init__() self.docs = [] self.setup() return - def setup(self): + def setup(self) -> None: global gef for function in gef.gdb.loaded_functions: self.add_function_to_doc(function) self.__doc__ = "\n".join(sorted(self.docs)) return - def add_function_to_doc(self, function): + def add_function_to_doc(self, function) -> None: """Add function to documentation.""" doc = getattr(function, "__doc__", "").lstrip() doc = "\n ".join(doc.split("\n")) @@ -10423,7 +10432,7 @@ def add_function_to_doc(self, function): self.docs.append(msg) return - def do_invoke(self, argv): + def do_invoke(self, argv) -> None: self.dont_repeat() gef_print(titlify("GEF - Convenience Functions")) gef_print("These functions can be used as arguments to other " @@ -10441,7 +10450,7 @@ class GefCommand(gdb.Command): _cmdline_ = "gef" _syntax_ = "{:s} (missing|config|save|restore|set|run)".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, True) gef.config["gef.follow_child"] = GefSetting(True, bool, "Automatically set GDB to follow child when forking") gef.config["gef.readline_compat"] = GefSetting(False, bool, "Workaround for readline SOH/ETX issue (SEGV)") @@ -10455,7 +10464,7 @@ def __init__(self): self.missing_commands = {} return - def setup(self): + def setup(self) -> None: self.load(initial=True) # loading GEF sub-commands self.doc = GefHelpCommand(self.loaded_commands) @@ -10479,7 +10488,7 @@ def setup(self): gdb.execute("gef restore quiet") return - def __reload_auto_breakpoints(self): + def __reload_auto_breakpoints(self) -> None: bkp_fname = gef.config["gef.autosave_breakpoints_file"] bkp_fname = bkp_fname[0] if bkp_fname else None if bkp_fname: @@ -10496,7 +10505,7 @@ def __reload_auto_breakpoints(self): gef_execute_gdb_script("\n".join(source) + "\n") return - def __load_extra_plugins(self): + def __load_extra_plugins(self) -> int: nb_added = -1 try: nb_inital = len(self.loaded_commands) @@ -10520,30 +10529,33 @@ def __load_extra_plugins(self): return nb_added @property - def loaded_command_names(self): + def loaded_command_names(self) -> List: return [x[0] for x in self.loaded_commands] - def invoke(self, args, from_tty): + def invoke(self, args, from_tty) -> None: self.dont_repeat() gdb.execute("gef help") return - def add_context_pane(self, pane_name, display_pane_function, pane_title_function): + def add_context_pane(self, pane_name: str, display_pane_function: Callable, pane_title_function: Callable) -> None: """Add a new context pane to ContextCommand.""" - for _, _, class_obj in self.loaded_commands: - if isinstance(class_obj, ContextCommand): - context_obj = class_obj + for _, _, class_instance in self.loaded_commands: + if isinstance(class_instance, ContextCommand): + context = class_instance break + else: + err("Cannot find ContextCommand") + return # assure users can toggle the new context corrected_settings_name = pane_name.replace(" ", "_") - layout_settings = context_obj.get_setting("layout") - context_obj.update_setting("layout", "{} {}".format(layout_settings, corrected_settings_name)) + layout_settings = context.get_setting("layout") + context.update_setting("layout", "{} {}".format(layout_settings, corrected_settings_name)) # overload the printing of pane title - context_obj.layout_mapping[corrected_settings_name] = (display_pane_function, pane_title_function) + context.layout_mapping[corrected_settings_name] = (display_pane_function, pane_title_function) - def load(self, initial=False): + def load(self, initial: bool = False) -> None: """Load all the commands and functions defined by GEF into GDB.""" nb_missing = 0 self.commands = [(x._cmdline_, x) for x in __registered_commands__] @@ -10552,18 +10564,18 @@ def load(self, initial=False): for function_class_name in __registered_functions__: self.loaded_functions.append(function_class_name()) - def is_loaded(x): + def is_loaded(x) -> bool: return any(u for u in self.loaded_commands if x == u[0]) - for cmd, class_name in self.commands: + for cmd, class_obj in self.commands: if is_loaded(cmd): continue try: - self.loaded_commands.append((cmd, class_name, class_name())) + self.loaded_commands.append((cmd, class_obj, class_obj())) - if hasattr(class_name, "_aliases_"): - aliases = getattr(class_name, "_aliases_") + if hasattr(class_obj, "_aliases_"): + aliases = getattr(class_obj, "_aliases_") for alias in aliases: GefAlias(alias, cmd) @@ -10600,39 +10612,39 @@ class GefHelpCommand(gdb.Command): _cmdline_ = "gef help" _syntax_ = _cmdline_ - def __init__(self, commands, *args, **kwargs): + def __init__(self, commands: List[Tuple[str, Any, Any]], *args, **kwargs) -> None: super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) self.docs = [] self.generate_help(commands) self.refresh() return - def invoke(self, args, from_tty): + def invoke(self, args, from_tty) -> None: self.dont_repeat() gef_print(titlify("GEF - GDB Enhanced Features")) - gef_print(self.__doc__) + gef_print(self.__doc__ or "") return - def generate_help(self, commands): + def generate_help(self, commands: List[Tuple[str, Type, Any]]) -> None: """Generate builtin commands documentation.""" for command in commands: self.add_command_to_doc(command) return - def add_command_to_doc(self, command): + def add_command_to_doc(self, command: Tuple[str, Any, Any]) -> None: """Add command to GEF documentation.""" - cmd, class_name, _ = command + cmd, class_obj, _ = command if " " in cmd: # do not print subcommands in gef help return - doc = getattr(class_name, "__doc__", "").lstrip() + doc = getattr(class_obj, "__doc__", "").lstrip() doc = "\n ".join(doc.split("\n")) - aliases = " (alias: {:s})".format(", ".join(class_name._aliases_)) if hasattr(class_name, "_aliases_") else "" + aliases = " (alias: {:s})".format(", ".join(class_obj._aliases_)) if hasattr(class_obj, "_aliases_") else "" msg = "{cmd:<25s} -- {help:s}{aliases:s}".format(cmd=cmd, help=doc, aliases=aliases) self.docs.append(msg) return - def refresh(self): + def refresh(self) -> None: """Refresh the documentation.""" self.__doc__ = "\n".join(sorted(self.docs)) return @@ -10648,12 +10660,12 @@ class GefConfigCommand(gdb.Command): _cmdline_ = "gef config" _syntax_ = "{:s} [setting_name] [setting_value]".format(_cmdline_) - def __init__(self, loaded_commands, *args, **kwargs): + def __init__(self, loaded_commands, *args, **kwargs) -> None: super().__init__(self._cmdline_, gdb.COMMAND_NONE, prefix=False) self.loaded_commands = loaded_commands return - def invoke(self, args, from_tty): + def invoke(self, args: str, from_tty) -> None: self.dont_repeat() argv = gdb.string_to_argv(args) argc = len(argv) @@ -10682,7 +10694,7 @@ def invoke(self, args, from_tty): self.set_setting(argv) return - def print_setting(self, plugin_name, verbose=False): + def print_setting(self, plugin_name: str, verbose: bool = False) -> None: res = gef.config.raw_entry(plugin_name) string_color = gef.config["theme.dereference_string"] misc_color = gef.config["theme.dereference_base_address"] @@ -10704,12 +10716,12 @@ def print_setting(self, plugin_name, verbose=False): gef_print("\t{:s}".format(res.description)) return - def print_settings(self): + def print_settings(self) -> None: for x in sorted(gef.config): self.print_setting(x) return - def set_setting(self, argv): + def set_setting(self, argv: Tuple[str, Any]) -> None: global gef key, new_value = argv @@ -10742,7 +10754,7 @@ def set_setting(self, argv): reset_all_caches() return - def complete(self, text, word): + def complete(self, text: str, word: str) -> List[str]: settings = sorted(gef.config) if text == "": @@ -10763,11 +10775,11 @@ class GefSaveCommand(gdb.Command): _cmdline_ = "gef save" _syntax_ = _cmdline_ - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) return - def invoke(self, args, from_tty): + def invoke(self, args, from_tty) -> None: self.dont_repeat() cfg = configparser.RawConfigParser() old_sect = None @@ -10802,11 +10814,11 @@ class GefRestoreCommand(gdb.Command): _cmdline_ = "gef restore" _syntax_ = _cmdline_ - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) return - def invoke(self, args, from_tty): + def invoke(self, args: str, from_tty) -> None: self.dont_repeat() if not os.access(GEF_RC, os.R_OK): return @@ -10855,11 +10867,11 @@ class GefMissingCommand(gdb.Command): _cmdline_ = "gef missing" _syntax_ = _cmdline_ - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, False) return - def invoke(self, args, from_tty): + def invoke(self, args, from_tty) -> None: self.dont_repeat() missing_commands = gef.gdb.missing_commands.keys() if not missing_commands: @@ -10877,11 +10889,11 @@ class GefSetCommand(gdb.Command): _cmdline_ = "gef set" _syntax_ = "{:s} [GDB_SET_ARGUMENTS]".format(_cmdline_) - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_SYMBOL, False) return - def invoke(self, args, from_tty): + def invoke(self, args, from_tty) -> None: self.dont_repeat() args = args.split() cmd = ["set", args[0],] @@ -10902,11 +10914,11 @@ class GefRunCommand(gdb.Command): _cmdline_ = "gef run" _syntax_ = "{:s} [GDB_RUN_ARGUMENTS]".format(_cmdline_) - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_FILENAME, False) return - def invoke(self, args, from_tty): + def invoke(self, args, from_tty) -> None: self.dont_repeat() if is_alive(): gdb.execute("continue") @@ -10921,7 +10933,7 @@ def invoke(self, args, from_tty): class GefAlias(gdb.Command): """Simple aliasing wrapper because GDB doesn't do what it should.""" - def __init__(self, alias, command, completer_class=gdb.COMPLETE_NONE, command_class=gdb.COMMAND_NONE): + def __init__(self, alias, command, completer_class=gdb.COMPLETE_NONE, command_class=gdb.COMMAND_NONE) -> None: p = command.split() if not p: return @@ -10945,11 +10957,11 @@ def __init__(self, alias, command, completer_class=gdb.COMPLETE_NONE, command_cl gef.session.aliases.append(self) return - def invoke(self, args, from_tty): + def invoke(self, args, from_tty) -> None: gdb.execute("{} {}".format(self._command, args), from_tty=from_tty) return - def lookup_command(self, cmd): + def lookup_command(self, cmd: str) -> Optional[Tuple[str, Type, Any]]: global gef for _name, _class, _instance in gef.gdb.loaded_commands: if cmd == _name: @@ -10964,11 +10976,11 @@ class AliasesCommand(GenericCommand): _cmdline_ = "aliases" _syntax_ = "{:s} (add|rm|ls)".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__(prefix=True) return - def do_invoke(self, argv): + def do_invoke(self, argv) -> None: self.usage() return @@ -10980,11 +10992,11 @@ class AliasesAddCommand(AliasesCommand): _syntax_ = "{0} [ALIAS] [COMMAND]".format(_cmdline_) _example_ = "{0} scope telescope".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__() return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: if (len(argv) < 2): self.usage() return @@ -10998,11 +11010,11 @@ class AliasesRmCommand(AliasesCommand): _cmdline_ = "aliases rm" _syntax_ = "{0} [ALIAS]".format(_cmdline_) - def __init__(self): + def __init__(self) -> None: super().__init__() return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: global gef if len(argv) != 1: self.usage() @@ -11023,11 +11035,11 @@ class AliasesListCommand(AliasesCommand): _cmdline_ = "aliases ls" _syntax_ = _cmdline_ - def __init__(self): + def __init__(self) -> None: super().__init__() return - def do_invoke(self, argv): + def do_invoke(self, argv: List) -> None: ok("Aliases defined:") for a in gef.session.aliases: gef_print("{:30s} {} {}".format(a._alias, RIGHT_ARROW, a._command)) @@ -11036,12 +11048,12 @@ def do_invoke(self, argv): class GefTmuxSetup(gdb.Command): """Setup a confortable tmux debugging environment.""" - def __init__(self): + def __init__(self) -> None: super().__init__("tmux-setup", gdb.COMMAND_NONE, gdb.COMPLETE_NONE) GefAlias("screen-setup", "tmux-setup") return - def invoke(self, args, from_tty): + def invoke(self, args, from_tty) -> None: self.dont_repeat() tmux = os.getenv("TMUX") @@ -11057,7 +11069,7 @@ def invoke(self, args, from_tty): warn("Not in a tmux/screen session") return - def tmux_setup(self): + def tmux_setup(self) -> None: """Prepare the tmux environment by vertically splitting the current pane, and forcing the context to be redirected there.""" tmux = which("tmux") @@ -11073,7 +11085,7 @@ def tmux_setup(self): ok("Done!") return - def screen_setup(self): + def screen_setup(self) -> None: """Hackish equivalent of the tmux_setup() function for screen.""" screen = which("screen") sty = os.getenv("STY") @@ -11106,7 +11118,7 @@ def screen_setup(self): # GEF internal classes # -def __gef_prompt__(current_prompt): +def __gef_prompt__(current_prompt) -> str: """GEF custom prompt function.""" if gef.config["gef.readline_compat"] is True: return GEF_PROMPT @@ -11116,7 +11128,7 @@ def __gef_prompt__(current_prompt): class GefManager(metaclass=abc.ABCMeta): - def reset_caches(self): + def reset_caches(self) -> None: """Reset the LRU-cached attributes""" for attr in dir(self): try: @@ -11130,31 +11142,31 @@ def reset_caches(self): class GefMemoryManager(GefManager): """Class that manages memory access for gef.""" - def __init__(self): + def __init__(self) -> None: self.reset_caches() return - def reset_caches(self): + def reset_caches(self) -> None: super().reset_caches() self.__maps = None return - def write(self, address, buffer, length=0x10): + def write(self, address: int, buffer: ByteString, length: int = 0x10): # -> memoryview object """Write `buffer` at address `address`.""" return gdb.selected_inferior().write_memory(address, buffer, length) - def read(self, addr, length=0x10): + def read(self, addr: int, length: int = 0x10) -> bytes: """Return a `length` long byte array with the copy of the process memory at `addr`.""" return gdb.selected_inferior().read_memory(addr, length).tobytes() - def read_integer(self, addr): + def read_integer(self, addr: int) -> int: """Return an integer read from memory.""" sz = gef.arch.ptrsize mem = self.read(addr, sz) unpack = u32 if sz == 4 else u64 return unpack(mem) - def read_cstring(self, address, max_length=GEF_MAX_STRING_LENGTH, encoding=None): + def read_cstring(self, address: int, max_length: int = GEF_MAX_STRING_LENGTH, encoding: Optional[str] = None) -> str: """Return a C-string read from memory.""" encoding = encoding or "unicode-escape" length = min(address | (DEFAULT_PAGE_SIZE-1), max_length+1) @@ -11179,7 +11191,7 @@ def read_cstring(self, address, max_length=GEF_MAX_STRING_LENGTH, encoding=None) return "{}[...]".format(ustr[:max_length]) return ustr - def read_ascii_string(self, address): + def read_ascii_string(self, address: int) -> Optional[str]: """Read an ASCII string from memory""" cstr = self.read_cstring(address) if isinstance(cstr, str) and cstr and all([x in string.printable for x in cstr]): @@ -11266,21 +11278,21 @@ def __parse_gdb_info_sections(self): class GefHeapManager(GefManager): """Class managing session heap.""" - def __init__(self): + def __init__(self) -> None: self.reset_caches() return - def reset_caches(self): - self.__libc_main_arena = None - self.__libc_selected_arena = None + def reset_caches(self) -> None: + self.__libc_main_arena: Optional[GlibcArena] = None + self.__libc_selected_arena: Optional[GlibcArena] = None self.__heap_base = None return @property - def main_arena(self): + def main_arena(self) -> Optional[GlibcArena]: if not self.__libc_main_arena: try: - self.__libc_main_arena = GlibcArena(search_for_main_arena()) + self.__libc_main_arena = GlibcArena(search_for_main_arena(to_string=True)) # the initialization of `main_arena` also defined `selected_arena`, so # by default, `main_arena` == `selected_arena` self.selected_arena = self.__libc_main_arena @@ -11290,25 +11302,25 @@ def main_arena(self): return self.__libc_main_arena @property - def selected_arena(self): + def selected_arena(self) -> Optional[GlibcArena]: if not self.__libc_selected_arena: # `selected_arena` must default to `main_arena` self.__libc_selected_arena = self.__libc_main_arena return self.__libc_selected_arena @selected_arena.setter - def selected_arena(self, value): + def selected_arena(self, value: GlibcArena) -> None: self.__libc_selected_arena = value return @property - def arenas(self): + def arenas(self) -> Union[List, Iterator[GlibcArena]]: if not self.main_arena: return [] return iter(self.main_arena) @property - def base_address(self): + def base_address(self) -> Optional[int]: if not self.__heap_base: base = 0 try: @@ -11322,31 +11334,32 @@ def base_address(self): return self.__heap_base @property - def chunks(self): + def chunks(self) -> Union[List, Iterator]: if not self.base_address: return [] return iter( GlibcChunk(self.base_address, from_base=True) ) class GefSetting: """Basic class for storing gef settings as objects""" - def __init__(self, value, cls = None, description = None): + def __init__(self, value: Any, cls: Optional[type] = None, description: Optional[str] = None) -> None: self.value = value self.type = cls or type(value) self.description = description or "" return + class GefSettingsManager(dict): """ 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]` """ - def __getitem__(self, name): + def __getitem__(self, name: str) -> Any: try: return dict.__getitem__(self, name).value except KeyError: return None - def __setitem__(self, name, value): + def __setitem__(self, name: str, value) -> None: # check if the key exists if dict.__contains__(self, name): # if so, update its value directly @@ -11361,16 +11374,16 @@ def __setitem__(self, name, value): dict.__setitem__(self, name, value) return - def __delitem__(self, name): + def __delitem__(self, name: str) -> None: dict.__setitem__(self, name) return - def raw_entry(self, name): + def raw_entry(self, name: str) -> Any: return dict.__getitem__(self, name) class GefSessionManager(GefManager): """Class managing the runtime properties of GEF. """ - def __init__(self): + def __init__(self) -> None: self.reset_caches() self.remote = None self.qemu_mode = False @@ -11388,7 +11401,7 @@ def __init__(self): self.constants[constant] = which(constant) return - def reset_caches(self): + def reset_caches(self) -> None: super().reset_caches() self.__auxiliary_vector = None self.__pagesize = None @@ -11399,7 +11412,7 @@ def reset_caches(self): return @property - def auxiliary_vector(self): + def auxiliary_vector(self) -> Optional[Dict[str, int]]: if not is_alive(): return None @@ -11421,14 +11434,14 @@ def auxiliary_vector(self): return self.__auxiliary_vector @property - def os(self): + def os(self) -> str: """Return the current OS.""" if not self.__os: self.__os = platform.system().lower() return self.__os @property - def pid(self): + def pid(self) -> int: """Return the PID of the target process.""" if not self.__pid: pid = gdb.selected_inferior().pid if not gef.session.qemu_mode else gdb.selected_thread().ptid[1] @@ -11438,14 +11451,14 @@ def pid(self): return self.__pid @property - def file(self): + def file(self) -> pathlib.Path: """Return a Path object of the target process.""" if not self.__file: self.__file = pathlib.Path(gdb.current_progspace().filename) return self.__file @property - def pagesize(self): + def pagesize(self) -> int: """Get the system page size""" auxval = self.auxiliary_vector if not auxval: @@ -11454,7 +11467,7 @@ def pagesize(self): return self.__pagesize @property - def canary(self): + def canary(self) -> Optional[Tuple[int, int]]: """Returns a tuple of the canary address and value, read from the auxiliary vector.""" auxval = self.auxiliary_vector if not auxval: @@ -11465,6 +11478,7 @@ def canary(self): self.__canary = (canary, canary_location) return self.__canary + class GefUiManager(GefManager): """Class managing UI settings.""" def __init__(self): @@ -11476,24 +11490,25 @@ def __init__(self): self.context_messages = [] return + class Gef: """The GEF root class, which serves as a base classe for all the attributes for the debugging session (architecture, memory, settings, etc.).""" - def __init__(self): - self.binary = None + def __init__(self) -> None: + self.binary: Optional[Elf] = None self.arch = GenericArchitecture() # see PR #516, will be reset by `new_objfile_handler` - self.config = GefSettingsManager() + self.config: Dict[str, Any] = GefSettingsManager() self.ui = GefUiManager() return - def reinitialize_managers(self): + def reinitialize_managers(self) -> None: """Reinitialize the managers. Avoid calling this function directly, using `pi reset()` is preferred""" self.memory = GefMemoryManager() self.heap = GefHeapManager() self.session = GefSessionManager() return - def setup(self): + def setup(self) -> None: """Setup initialize the runtime setup, which may require for the `gef` to be not None.""" self.reinitialize_managers() self.gdb = GefCommand() @@ -11503,7 +11518,7 @@ def setup(self): gdb.execute("save gdb-index {}".format(tempdir)) return - def reset_caches(self): + def reset_caches(self) -> None: """Recursively clean the cache of all the managers. Avoid calling this function directly, using `reset-cache` is preferred""" for mgr in (self.memory, self.heap, self.session): From 5f641bb10e3ea838c50de61aacc78946125625c7 Mon Sep 17 00:00:00 2001 From: hugsy Date: Sun, 9 Jan 2022 13:58:31 -0800 Subject: [PATCH 47/62] Replaced `GEF_RC` to a `Path` object (#775) --- gef.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/gef.py b/gef.py index 71914f358..14786e959 100644 --- a/gef.py +++ b/gef.py @@ -133,7 +133,7 @@ def update_gef(argv: List[str]) -> int: DEFAULT_PAGE_ALIGN_SHIFT = 12 DEFAULT_PAGE_SIZE = 1 << DEFAULT_PAGE_ALIGN_SHIFT -GEF_RC = os.getenv("GEF_RC") or os.path.join(os.getenv("HOME"), ".gef.rc") +GEF_RC = pathlib.Path(os.getenv("GEF_RC")).absolute() if os.getenv("GEF_RC") else pathlib.Path().home() / ".gef.rc" GEF_TEMP_DIR = os.path.join(tempfile.gettempdir(), "gef") GEF_MAX_STRING_LENGTH = 50 @@ -153,10 +153,10 @@ def update_gef(argv: List[str]) -> int: GEF_PROMPT_OFF = "\001\033[1;31m\002{0:s}\001\033[0m\002".format(GEF_PROMPT) -gef = None -__registered_commands__ = [] -__registered_functions__ = [] -__registered_architectures__ = {} +gef : "Gef" = None +__registered_commands__ : List["GenericCommand"] = [] +__registered_functions__ : List["GenericFunction"] = [] +__registered_architectures__ : Dict[Union[int, str], "Architecture"] = {} def reset_all_caches() -> None: @@ -180,7 +180,6 @@ def reset() -> None: arch = gef.arch del gef - gef = None gef = Gef() gef.setup() @@ -10799,10 +10798,10 @@ def invoke(self, args, from_tty) -> None: for alias in gef.session.aliases: cfg.set("aliases", alias._alias, alias._command) - with open(GEF_RC, "w") as fd: + with GEF_RC.open("w") as fd: cfg.write(fd) - ok("Configuration saved to '{:s}'".format(GEF_RC)) + ok("Configuration saved to '{:s}'".format(str(GEF_RC))) return @@ -10853,7 +10852,7 @@ def invoke(self, args: str, from_tty) -> None: gef_makedirs(gef.config["gef.tempdir"]) if not quiet: - ok("Configuration from '{:s}' restored".format(Color.colorify(GEF_RC, "bold blue"))) + ok("Configuration from '{:s}' restored".format(Color.colorify(str(GEF_RC), "bold blue"))) return @@ -11494,7 +11493,7 @@ class Gef: memory, settings, etc.).""" def __init__(self) -> None: self.binary: Optional[Elf] = None - self.arch = GenericArchitecture() # see PR #516, will be reset by `new_objfile_handler` + self.arch: Architecture = GenericArchitecture() # see PR #516, will be reset by `new_objfile_handler` self.config: Dict[str, Any] = GefSettingsManager() self.ui = GefUiManager() return From b653a6efd7aff8497608c1fea2cbc13ad71bb4dc Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 10 Jan 2022 14:02:08 -0800 Subject: [PATCH 48/62] Automatically generating gef api (#776) --- docs/api.md | 280 +- docs/api/gef.md | 24513 +++++++++++++++++++++++++++++++++ scripts/generate-api-docs.sh | 45 + 3 files changed, 24588 insertions(+), 250 deletions(-) create mode 100644 docs/api/gef.md create mode 100644 scripts/generate-api-docs.sh diff --git a/docs/api.md b/docs/api.md index e96c6bf28..56ab136e3 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,4 +1,4 @@ -# Extending GEF # +# Extending GEF `GEF` intends to provide a battery-included, quickly installable and crazy fast debugging environment sitting on top of GDB. @@ -12,7 +12,7 @@ A [dedicated repository](https://github.com/hugsy/gef-extras) was born to host repo is open to all for contributions, no restrictions and the most valuable ones will be integrated into `gef.py`. -## Quick start ## +## Quick start Here is the most basic skeleton for creating a new `GEF` command named `newcmd`: @@ -20,22 +20,19 @@ Here is the most basic skeleton for creating a new `GEF` command named `newcmd`: class NewCommand(GenericCommand): """Dummy new command.""" _cmdline_ = "newcmd" - _syntax_ = "{:s}".format(_cmdline_) + _syntax_ = f"{_cmdline_:s}" @only_if_gdb_running # not required, ensures that the debug session is started def do_invoke(self, argv): - # do anything allowed by gef, for example show the current running - # architecture as Python object: - print(" = {}".format(current_arch) ) + # let's say we want to print some info about the architecture of the current binary + print(f"{gef.arch=}") # or showing the current $pc - print("pc = {:#x}".format(current_arch.pc)) + print(f"{gef.arch.pc=:#x}") return register_external_command(NewCommand()) ``` -Yes, that's it! - Loading it in `GEF` is as easy as ``` gef➤ source /path/to/newcmd.py @@ -44,10 +41,15 @@ gef➤ source /path/to/newcmd.py We can call it: -![](https://camo.githubusercontent.com/d41c1c0c0267916f4749800906d201fe5d328db5/687474703a2f2f692e696d6775722e636f6d2f306734416543622e706e67) +``` +gef➤ newcmd +gef.arch=<__main__.X86_64 object at 0x7fd5583571c0> +gef.arch.pc=0x55555555a7d0 +``` +Yes, that's it! Check out [the complete API](docs/api/gef.md) to see what else GEF offers. -## Detailed explanation ## +## Detailed explanation Our new command must be a class that inherits from GEF's `GenericCommand`. The *only* requirements are: @@ -70,7 +72,8 @@ or add to your `~/.gdbinit`: $ echo source /path/to/newcmd.py >> ~/.gdbinit ``` -## Custom context panes ## + +## 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 @@ -97,7 +100,7 @@ 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 ### +### Context Pane API The API demonstrated above requires very specific argument types: `register_external_context_pane(pane_name, display_pane_function, pane_title_function)` @@ -107,7 +110,7 @@ The API demonstrated above requires very specific argument types: in the pane -`pane_title_function`: a function that returns the title string or None to hide the title -## API ## +## 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 @@ -124,111 +127,19 @@ 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. -### Reference - -#### Global - -```python -register_external_command() -``` -Procedure to add the new GEF command - ---- - -```python -parse_address() -``` -Parse an expression into a integer from the current debugging context. - - -```python -gef ➤ pi hex(parse_address("main+0x4")) -'0x55555555a7d4' -``` - ---- - -```python -current_arch -``` -Global variable associated with the architecture of the currently debugged process. The variable is an instance of the `Architecture` class (see below). - ---- - -```python -current_elf -``` -Global variable associated to the currently debugging ELF file. - - -#### Logging - -```python -ok(msg) -info(msg) -warn(msg) -err(msg) -``` - - -#### CPU - +Some basic examples: + - read the memory ```python -get_register(register_name) -``` - -Returns the value of given register. The function will fail outside a running debugging context. - - - - -#### Memory - - -```python -read_memory(addr, length=0x10) -``` -Returns a `length` long byte array with a copy of the process memory read from `addr`. - -Ex: -```python -0:000 ➤ pi print(hexdump( read_memory(parse_address("$pc"), length=0x20 ))) +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..... ``` ---- - -```python -write_memory(addr, buffer, length=0x10) -``` -Writes `buffer` to memory at address `addr`. - ---- - -```python -read_int_from_memory(addr) -``` - -Reads the size of an integer from `addr`, and unpacks it correctly (based on the current arch's endianness) - ---- - -```python -read_cstring_from_memory(addr) -``` -Return a NULL-terminated array of bytes, from `addr`. - ---- - -```python -get_process_maps() + - get access to the memory layout ``` -Returns an iterable of Section objects (see below) corresponding to the current memory layout of the process. - -```python -0:000 ➤ pi print('\n'.join([ f"{x.page_start:#x} -> {x.page_end:#x}" for x in get_process_maps()])) +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 @@ -242,96 +153,20 @@ Returns an iterable of Section objects (see below) corresponding to the current [...] ``` -#### Code - -```python -gef_disassemble(addr, nb_insn, from_top=False) -``` -Disassemble `nb_insn` instructions after `addr`. If `from_top` is False (default), it will also disassemble the `nb_insn` instructions before `addr`. Return an iterator of Instruction objects (see below). +The API also offers a number of decorators to simply 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 current GDB session is local i.e. not debugging using GDB `remote`. + - and many more... -#### Runtime hooks - ---- - -```python -gef_on_continue_hook -gef_on_continue_unhook -``` -Takes a callback function FUNC as parameter: add/remove a call to `FUNC` when GDB continues execution. - ---- - -```python -gef_on_stop_hook -gef_on_stop_unhook -``` - -Takes a callback function FUNC as parameter: add/remove a call to `FUNC` when GDB stops execution (breakpoints, watchpoints, interrupt, signal, etc.). - ---- - -```python -gef_on_new_hook -gef_on_new_unhook -``` - -Takes a callback function FUNC as parameter: add/remove a call to `FUNC` when GDB loads a new binary. - ---- - -```python -gef_on_exit_hook -gef_on_exit_unhook -``` - -Takes a callback function FUNC as parameter: add/remove a call to `FUNC` when GDB exits an inferior. - - -### `do_invoke` decorators ### - -```python -@only_if_gdb_running -``` - -Modifies a function to only execute if a GDB session is running. A GDB session is running if: -* a PID exists for the targeted binary -* GDB is running on a coredump of a binary - ---- - -```python -@only_if_gdb_target_local -``` -Checks if the current GDB session is local i.e. not debugging using GDB `remote`. - ---- - -```python -@only_if_gdb_version_higher_than( (MAJOR, MINOR) ) -``` - -Checks if the GDB version is higher or equal to the MAJOR and MINOR providedas arguments (both as Integers). This is required since some commands/API ofGDB are only present in the very latest version of GDB. - ---- - -```python -@obsolete_command -``` - -Decorator to add a warning when a command is obsolete and may be removed without warning in future releases. - ---- +### Reference -```python -@experimental_feature -``` -Decorator to add a warning when a feature is experimental, and its API/behavior may change in future releases. +For a complete reference of the API offered by GEF, visit [docs/api/gef.md](docs/api/gef.md). ---- +### Parsing command arguments ```python @parse_arguments( {"required_argument_1": DefaultValue1, ...}, {"--optional-argument-1": DefaultValue1, ...} ) @@ -379,58 +214,3 @@ 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) ``` - ---- - -```python -@only_if_current_arch_in(valid_architectures) -``` -Decorator to allow commands for only a subset of the architectured supported by GEF. This decorator is to use lightly, as it goes against the purpose of GEF to support all architectures GDB does. However in some cases, it is necessary. - -```python -@only_if_current_arch_in(["X86", "RISCV"]) -def do_invoke(self, argv): - [...] -``` - - -### Classes ### - -For exhaustive documentation, run -```bash -$ gdb -q -ex 'pi help()' -ex quit -``` - -#### Generic #### - -New GEF commands **must** inherit `GenericCommand`, have `_cmdline_` and -`_syntax_` attributes, and have a instance method `do_invoke(args)` defined. - -Other than that, new commands can enjoy all the GEF abstract layer -representation classes, such as: - - * `Instruction` : GEF representation of instruction as pure Python objects. - * `Address`: GEF representation of memory addresses. - * `Section`: GEF representation of process memory sections. - * `Permission`: Page permission object. - * `Elf`: [ELF](http://www.skyfree.org/linux/references/ELF_Format.pdf) parsing - object. - -#### Architectures #### - - * `Architecture` : Generic metaclass for the architectures supported by GEF. - * `ARM` - * `AARCH64` - * `X86` - * `X86_64` - * `PowerPC` - * `PowerPC64` - * `SPARC` - * `SPARC64` - * `MIPS` - - -#### Heap #### - - * `GlibcArena` : Glibc arena class - * `GlibcChunk` : Glibc chunk class. diff --git a/docs/api/gef.md b/docs/api/gef.md new file mode 100644 index 000000000..54acdb3a0 --- /dev/null +++ b/docs/api/gef.md @@ -0,0 +1,24513 @@ + + +# module `GEF` + + + + +**Global Variables** +--------------- +- **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** +- **gef** +- **pattern_libc_ver** +- **PREFIX** +- **gdb_initial_settings** +- **cmd** + +--- + + + +## function `FakeExit` + +```python +FakeExit(*args, **kwargs) → None +``` + + + + + + +--- + + + +## function `align_address` + +```python +align_address(address: int) → int +``` + +Align the provided address to the process's native length. + + +--- + + + +## function `align_address_to_page` + +```python +align_address_to_page(address: int) → int +``` + +Align the address to a page. + + +--- + + + +## function `align_address_to_size` + +```python +align_address_to_size(address: int, align: int) → int +``` + +Align the address to the given size. + + +--- + + + +## function `bufferize` + +```python +bufferize(f: Callable) → Callable +``` + +Store the content to be printed for a function in memory, and flush it on function exit. + + +--- + + + +## function `capstone_disassemble` + +```python +capstone_disassemble(location: int, nb_insn: int, **kwargs) +``` + +Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr` using the Capstone-Engine disassembler, if available. Return an iterator of Instruction objects. + + +--- + + + +## function `clear_screen` + +```python +clear_screen(tty: str = '') → None +``` + +Clear the screen. + + +--- + + + +## function `continue_handler` + +```python +continue_handler(event) → None +``` + +GDB event handler for new object continue cases. + + +--- + + + +## function `copy_to_clipboard` + +```python +copy_to_clipboard(data: str) → None +``` + +Helper function to submit data to the clipboard + + +--- + + + +## function `de_bruijn` + +```python +de_bruijn(alphabet: str, n: int) → Generator[str, NoneType, NoneType] +``` + +De Bruijn sequence for alphabet and subsequences of length n (for compat. w/ pwnlib). + + +--- + + + +## function `deprecated` + +```python +deprecated(solution: str = '') → Callable +``` + +Decorator to add a warning when a command is obsolete and will be removed. + + +--- + + + +## function `disable_redirect_output` + +```python +disable_redirect_output() → None +``` + +Disable the output redirection, if any. + + +--- + + + +## function `download_file` + +```python +download_file( + remote_path: str, + use_cache: bool = False, + local_name: Optional[str] = None +) → Union[str, NoneType] +``` + +Download filename `remote_path` inside the mirror tree inside the gef.config["gef.tempdir"]. The tree architecture must be gef.config["gef.tempdir"]/gef//. This allow a "chroot-like" tree format. + + +--- + + + +## function `enable_redirect_output` + +```python +enable_redirect_output(to_file: str = '/dev/null') → None +``` + +Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`. + + +--- + + + +## function `endian_str` + +```python +endian_str() → str +``` + + + + + + +--- + + + +## function `err` + +```python +err(msg: str) → Union[int, NoneType] +``` + + + + + + +--- + + + +## function `exit_handler` + +```python +exit_handler(event) → None +``` + +GDB event handler for exit cases. + + +--- + + + +## function `experimental_feature` + +```python +experimental_feature(f: Callable) → Callable +``` + +Decorator to add a warning when a feature is experimental. + + +--- + + + +## function `flags_to_human` + +```python +flags_to_human(reg_value: int, value_table: Dict[int, str]) → str +``` + +Return a human readable string showing the flag states. + + +--- + + + +## function `format_address` + +```python +format_address(addr: int) → str +``` + +Format the address according to its size. + + +--- + + + +## function `format_address_spaces` + +```python +format_address_spaces(addr: int, left: bool = True) → str +``` + +Format the address according to its size, but with spaces instead of zeroes. + + +--- + + + +## function `gdb_disassemble` + +```python +gdb_disassemble(start_pc: int, **kwargs: int) +``` + +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_next_instruction_address` + +```python +gdb_get_nth_next_instruction_address(addr: int, n: int) → int +``` + +Return the address (Integer) of the `n`-th instruction after `addr`. + + +--- + + + +## function `gdb_get_nth_previous_instruction_address` + +```python +gdb_get_nth_previous_instruction_address( + addr: int, + n: int +) → Union[int, NoneType] +``` + +Return the address (Integer) of the `n`-th instruction before `addr`. + + +--- + + + +## function `gef_convenience` + +```python +gef_convenience(value: str) → str +``` + +Defines a new convenience value. + + +--- + + + +## function `gef_current_instruction` + +```python +gef_current_instruction(addr: int) +``` + +Return the current instruction as an Instruction object. + + +--- + + + +## function `gef_disassemble` + +```python +gef_disassemble(addr: int, nb_insn: int, nb_prev: int = 0) +``` + +Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr`. Return an iterator of Instruction objects. + + +--- + + + +## function `gef_execute_external` + +```python +gef_execute_external( + command: Sequence[str], + as_list: bool = False, + **kwargs +) → Union[str, List[str]] +``` + +Execute an external command and return the result. + + +--- + + + +## function `gef_execute_gdb_script` + +```python +gef_execute_gdb_script(commands: str) → None +``` + +Execute the parameter `source` as GDB command. This is done by writing `commands` to a temporary file, which is then executed via GDB `source` command. The tempfile is then deleted. + + +--- + + + +## function `gef_get_instruction_at` + +```python +gef_get_instruction_at(addr: int) +``` + +Return the full Instruction found at the specified address. + + +--- + + + +## function `gef_get_pie_breakpoint` + +```python +gef_get_pie_breakpoint(num: int) +``` + + + + + + +--- + + + +## function `gef_getpagesize` + +```python +gef_getpagesize() → int +``` + + + + + + +--- + + + +## function `gef_instruction_n` + +```python +gef_instruction_n(addr: int, n: int) +``` + +Return the `n`-th instruction after `addr` as an Instruction object. + + +--- + + + +## function `gef_makedirs` + +```python +gef_makedirs(path: str, mode: int = 493) → str +``` + +Recursive mkdir() creation. If successful, return the absolute path of the directory created. + + +--- + + + +## function `gef_next_instruction` + +```python +gef_next_instruction(addr: int) +``` + +Return the next instruction as an Instruction object. + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `wrapped_f` + +```python +wrapped_f(*args: Tuple, **kwargs: Dict) → Any +``` + + + + + + +--- + + + +## function `gef_print` + +```python +gef_print(x: str = '', *args: Tuple, **kwargs: Dict) → Union[int, NoneType] +``` + +Wrapper around print(), using string buffering feature. + + +--- + + + +## function `gef_pybytes` + +```python +gef_pybytes(x: str) → bytes +``` + +Returns an immutable bytes list from the string given as input. + + +--- + + + +## function `gef_pystring` + +```python +gef_pystring(x: bytes) → str +``` + +Returns a sanitized version as string of the bytes list given in input. + + +--- + + + +## function `gef_read_canary` + +```python +gef_read_canary() → Union[Tuple[int, int], NoneType] +``` + + + + + + +--- + + + +## function `generate_cyclic_pattern` + +```python +generate_cyclic_pattern(length: int, cycle: int = 4) → bytearray +``` + +Create a `length` byte bytearray of a de Bruijn cyclic pattern. + + +--- + + + +## function `get_capstone_arch` + +```python +get_capstone_arch( + arch: Optional[str] = None, + mode: Optional[str] = None, + endian: Optional[bool] = None, + to_string: bool = False +) → Union[Tuple[NoneType, NoneType], Tuple[str, Union[int, str]]] +``` + + + + + + +--- + + + +## function `get_filename` + +```python +get_filename() → str +``` + + + + + + +--- + + + +## function `get_function_length` + +```python +get_function_length(sym) +``` + +Attempt to get the length of the raw bytes of a function. + + +--- + + + +## function `get_gef_setting` + +```python +get_gef_setting(name: str) → Any +``` + + + + + + +--- + + + +## function `get_generic_arch` + +```python +get_generic_arch( + module: module, + prefix: str, + arch: str, + mode: Optional[str], + big_endian: Optional[bool], + to_string: bool = False +) → Tuple[str, Union[int, str]] +``` + +Retrieves architecture and mode from the arguments for use for the holy {cap,key}stone/unicorn trinity. + + +--- + + + +## function `get_generic_running_arch` + +```python +get_generic_running_arch( + module: module, + prefix: str, + to_string: bool = False +) → Union[Tuple[NoneType, NoneType], Tuple[str, Union[int, str]]] +``` + +Retrieves architecture and mode from the current context. + + +--- + + + +## function `get_glibc_arena` + +```python +get_glibc_arena() +``` + + + + + + +--- + + + +## function `get_keystone_arch` + +```python +get_keystone_arch( + arch: Optional[str] = None, + mode: Optional[str] = None, + endian: Optional[bool] = None, + to_string: bool = False +) → Union[Tuple[NoneType, NoneType], Tuple[str, Union[int, str]]] +``` + + + + + + +--- + + + +## function `get_memory_alignment` + +```python +get_memory_alignment(in_bits: bool = False) → int +``` + +Try to determine the size of a pointer on this system. First, try to parse it out of the ELF header. Next, use the size of `size_t`. Finally, try the size of $pc. If `in_bits` is set to True, the result is returned in bits, otherwise in bytes. + + +--- + + + +## function `get_os` + +```python +get_os() → str +``` + + + + + + +--- + + + +## function `get_path_from_info_proc` + +```python +get_path_from_info_proc() +``` + + + + + + +--- + + + +## function `get_pid` + +```python +get_pid() → int +``` + + + + + + +--- + + + +## function `get_process_maps` + +```python +get_process_maps() +``` + + + + + + +--- + + + +## function `get_register` + +```python +get_register(regname) +``` + + + + + + +--- + + + +## function `get_terminal_size` + +```python +get_terminal_size() → Tuple[int, int] +``` + +Return the current terminal size. + + +--- + + + +## function `get_unicorn_arch` + +```python +get_unicorn_arch( + arch: Optional[str] = None, + mode: Optional[str] = None, + endian: Optional[bool] = None, + to_string: bool = False +) → Union[Tuple[NoneType, NoneType], Tuple[str, Union[int, str]]] +``` + + + + + + +--- + + + +## function `get_unicorn_registers` + +```python +get_unicorn_registers( + to_string: bool = False +) → Union[Dict[str, int], Dict[str, str]] +``` + +Return a dict matching the Unicorn identifier for a specific register. + + +--- + + + +## function `hexdump` + +```python +hexdump( + source: ByteString, + length: int = 16, + separator: str = '.', + show_raw: bool = False, + show_symbol: bool = True, + base: int = 0 +) → str +``` + +Return the hexdump of `src` argument. @param source *MUST* be of type bytes or bytearray @param length is the length of items per line @param separator is the default character to use if one byte is not printable @param show_raw if True, do not add the line nor the text translation @param base is the start address of the block being hexdump @return a string with the hexdump + + +--- + + + +## function `hide_context` + +```python +hide_context() → bool +``` + +Helper function to hide the context pane + + +--- + + + +## function `highlight_text` + +```python +highlight_text(text: str) → str +``` + +Highlight text using gef.ui.highlight_table { match -> color } settings. + +If RegEx is enabled it will create a match group around all items in the gef.ui.highlight_table and wrap the specified color in the gef.ui.highlight_table around those matches. + +If RegEx is disabled, split by ANSI codes and 'colorify' each match found within the specified string. + + +--- + + + +## function `hook_stop_handler` + +```python +hook_stop_handler(event) → None +``` + +GDB event handler for stop cases. + + +--- + + + +## function `http_get` + +```python +http_get(url: str) → Union[bytes, NoneType] +``` + +Basic HTTP wrapper for GET request. Return the body of the page if HTTP code is OK, otherwise return None. + + +--- + + + +## function `ida_synchronize_handler` + +```python +ida_synchronize_handler(event) +``` + + + + + + +--- + + + +## function `info` + +```python +info(msg: str) → Union[int, NoneType] +``` + + + + + + +--- + + + +## function `is_alive` + +```python +is_alive() → bool +``` + +Check if GDB is running. + + +--- + + + +## function `is_ascii_string` + +```python +is_ascii_string(address: int) → bool +``` + +Helper function to determine if the buffer pointed by `address` is an ASCII string (in GDB) + + +--- + + + +## function `is_big_endian` + +```python +is_big_endian() → bool +``` + + + + + + +--- + + + +## function `is_debug` + +```python +is_debug() → bool +``` + +Check if debug mode is enabled. + + +--- + + + +## function `is_hex` + +```python +is_hex(pattern: str) → bool +``` + +Return whether provided string is a hexadecimal value. + + +--- + + + +## function `is_in_x86_kernel` + +```python +is_in_x86_kernel(address: int) → bool +``` + + + + + + +--- + + + +## function `is_little_endian` + +```python +is_little_endian() → bool +``` + + + + + + +--- + + + +## function `is_pie` + +```python +is_pie(fpath: str) → bool +``` + + + + + + +--- + + + +## function `keystone_assemble` + +```python +keystone_assemble( + code: str, + arch: int, + mode: int, + *args, + **kwargs +) → Union[str, bytearray, NoneType] +``` + +Assembly encoding function based on keystone. + + +--- + + + +## function `load_libc_args` + +```python +load_libc_args() → None +``` + + + + + + +--- + + + +## function `malloc_align_address` + +```python +malloc_align_address(address: int) → int +``` + +Align addresses according to glibc's MALLOC_ALIGNMENT. See also Issue #689 on Github + + +--- + + + +## function `memchanged_handler` + +```python +memchanged_handler(event) → None +``` + +GDB event handler for mem changes cases. + + +--- + + + +## function `new_objfile_handler` + +```python +new_objfile_handler(event) → None +``` + +GDB event handler for new object file cases. + + +--- + + + +## function `ok` + +```python +ok(msg: str) → Union[int, NoneType] +``` + + + + + + +--- + + + +## function `only_if_current_arch_in` + +```python +only_if_current_arch_in(valid_architectures: List) → Callable +``` + +Decorator to allow commands for only a subset of the architectured supported by GEF. This decorator is to use lightly, as it goes against the purpose of GEF to support all architectures GDB does. However in some cases, it is necessary. + + +--- + + + +## function `only_if_events_supported` + +```python +only_if_events_supported(event_type) → Callable +``` + +Checks if GDB supports events without crashing. + + +--- + + + +## function `only_if_gdb_running` + +```python +only_if_gdb_running(f: Callable) → Callable +``` + +Decorator wrapper to check if GDB is running. + + +--- + + + +## function `only_if_gdb_target_local` + +```python +only_if_gdb_target_local(f: Callable) → Callable +``` + +Decorator wrapper to check if GDB is running locally (target not remote). + + +--- + + + +## function `only_if_gdb_version_higher_than` + +```python +only_if_gdb_version_higher_than(required_gdb_version) → Callable +``` + +Decorator to check whether current GDB version requirements. + + +--- + + + +## function `p16` + +```python +p16(x: int, s: bool = False) → bytes +``` + +Pack one word respecting the current architecture endianness. + + +--- + + + +## function `p32` + +```python +p32(x: int, s: bool = False) → bytes +``` + +Pack one dword respecting the current architecture endianness. + + +--- + + + +## function `p64` + +```python +p64(x: int, s: bool = False) → bytes +``` + +Pack one qword respecting the current architecture endianness. + + +--- + + + +## function `p8` + +```python +p8(x: int, s: bool = False) → bytes +``` + +Pack one byte respecting the current architecture endianness. + + +--- + + + +## function `parse_address` + +```python +parse_address(address: str) → int +``` + +Parse an address and return it as an Integer. + + +--- + + + +## function `parse_arguments` + +```python +parse_arguments( + required_arguments: Dict, + optional_arguments: Dict +) → Union[Callable, NoneType] +``` + +Argument parsing decorator. + + +--- + + + +## function `parse_string_range` + +```python +parse_string_range(s: str) → Iterator[int] +``` + +Parses an address range (e.g. 0x400000-0x401000) + + +--- + + + +## function `process_lookup_address` + +```python +process_lookup_address(address: int) +``` + +Look up for an address in memory. Return an Address object if found, None otherwise. + + +--- + + + +## function `push_context_message` + +```python +push_context_message(level: str, message: str) → None +``` + +Push the message to be displayed the next time the context is invoked. + + +--- + + + +## function `regchanged_handler` + +```python +regchanged_handler(event) → None +``` + +GDB event handler for reg changes cases. + + +--- + + + +## function `register_architecture` + +```python +register_architecture(cls) +``` + +Class decorator for declaring an architecture to GEF. + + +--- + + + +## function `register_command` + +```python +register_command(cls) +``` + +Decorator for registering new GEF (sub-)command to GDB. + + +--- + + + +## function `register_external_command` + +```python +register_external_command(obj) +``` + +Registering function for new GEF (sub-)command to GDB. + + +--- + + + +## function `register_external_context_pane` + +```python +register_external_context_pane( + pane_name: str, + display_pane_function: Callable[[], NoneType], + pane_title_function: Callable[[], Optional[str]] +) → 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. + +Example Usage: 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) + + +--- + + + +## function `register_function` + +```python +register_function(cls) +``` + +Decorator for registering a new convenience function to GDB. + + +--- + + + +## function `register_priority_command` + +```python +register_priority_command(cls) +``` + +Decorator for registering new command with priority, meaning that it must loaded before the other generic commands. + + +--- + + + +## function `reset` + +```python +reset() → None +``` + + + + + + +--- + + + +## function `reset_all_caches` + +```python +reset_all_caches() → None +``` + +Free all caches. If an object is cached, it will have a callable attribute `cache_clear` which will be invoked to purge the function cache. + + +--- + + + +## function `safe_parse_and_eval` + +```python +safe_parse_and_eval(value: str) +``` + +GEF wrapper for gdb.parse_and_eval(): this function returns None instead of raising gdb.error if the eval failed. + + +--- + + + +## function `set_arch` + +```python +set_arch(arch=None, default=None) +``` + +Sets the current architecture. If an arch is explicitly specified, use that one, otherwise try to parse it out of the current target. If that fails, and default is specified, select and set that arch. Return the selected arch, or raise an OSError. + + +--- + + + +## function `set_gef_setting` + +```python +set_gef_setting(name: str, value: Any) → None +``` + + + + + + +--- + + + +## function `show_last_exception` + +```python +show_last_exception() → None +``` + +Display the last Python exception. + + +--- + + + +## function `style_byte` + +```python +style_byte(b: int, color: bool = True) → str +``` + + + + + + +--- + + + +## function `titlify` + +```python +titlify( + text: str, + color: Optional[str] = None, + msg_color: Optional[str] = None +) → str +``` + +Print a centered title. + + +--- + + + +## function `to_unsigned_long` + +```python +to_unsigned_long(v) → int +``` + +Cast a gdb.Value to unsigned long. + + +--- + + + +## function `u16` + +```python +u16(x: bytes, s: bool = False) → int +``` + +Unpack one word respecting the current architecture endianness. + + +--- + + + +## function `u32` + +```python +u32(x: bytes, s: bool = False) → int +``` + +Unpack one dword respecting the current architecture endianness. + + +--- + + + +## function `u64` + +```python +u64(x: bytes, s: bool = False) → int +``` + +Unpack one qword respecting the current architecture endianness. + + +--- + + + +## function `u8` + +```python +u8(x: bytes, s: bool = False) → int +``` + +Unpack one byte respecting the current architecture endianness. + + +--- + + + +## function `unhide_context` + +```python +unhide_context() → bool +``` + +Helper function to unhide the context pane + + +--- + + + +## function `update_gef` + +```python +update_gef(argv: List[str]) → int +``` + +Try to update `gef` to the latest version pushed on GitHub master branch. Return 0 on success, 1 on failure. + + +--- + + + +## function `use_default_type` + +```python +use_default_type() → str +``` + + + + + + +--- + + + +## function `use_golang_type` + +```python +use_golang_type() → str +``` + + + + + + +--- + + + +## function `use_rust_type` + +```python +use_rust_type() → str +``` + + + + + + +--- + + + +## function `use_stdtype` + +```python +use_stdtype() → str +``` + + + + + + +--- + + + +## function `warn` + +```python +warn(msg: str) → Union[int, NoneType] +``` + + + + + + +--- + + + +## function `xor` + +```python +xor(data: ByteString, key: str) → bytearray +``` + +Return `data` xor-ed with `key`. + + +--- + +## class `AARCH64` + + + + + +--- + +#### property AARCH64.fp + + + + + +--- + +#### property AARCH64.instruction_length + + + + + +--- + +#### property AARCH64.pc + + + + + +--- + +#### property AARCH64.registers + + + + + +--- + +#### property AARCH64.sp + + + + + + + +--- + + + +### method `AARCH64.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +### method `AARCH64.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `AARCH64.get_ra` + +```python +get_ra(insn, frame) → int +``` + + + + + +--- + + + +### method `AARCH64.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `AARCH64.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `AARCH64.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `AARCH64.is_ret` + +```python +is_ret(insn) → Union[bool, NoneType] +``` + + + + + +--- + + + +### method `AARCH64.is_thumb` + +```python +is_thumb() → bool +``` + +Determine if the machine is currently in THUMB mode. + +--- + + + +### classmethod `AARCH64.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm) → str +``` + + + + + +--- + + + +### method `AARCH64.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## class `ARM` + + + + + +--- + +#### property ARM.fp + + + + + +--- + +#### property ARM.instruction_length + + + + + +--- + +#### property ARM.mode + + + + + +--- + +#### property ARM.pc + + + + + +--- + +#### property ARM.ptrsize + + + + + +--- + +#### property ARM.registers + + + + + +--- + +#### property ARM.sp + + + + + + + +--- + + + +### method `ARM.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +### method `ARM.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `ARM.get_ra` + +```python +get_ra(insn, frame) → int +``` + + + + + +--- + + + +### method `ARM.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `ARM.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `ARM.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `ARM.is_ret` + +```python +is_ret(insn) → Union[bool, NoneType] +``` + + + + + +--- + + + +### method `ARM.is_thumb` + +```python +is_thumb() → bool +``` + +Determine if the machine is currently in THUMB mode. + +--- + + + +### classmethod `ARM.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm) → str +``` + + + + + +--- + + + +### method `ARM.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## 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. + + + +### method `ASLRCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property ASLRCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ASLRCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ASLRCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `ASLRCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `ASLRCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ASLRCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ASLRCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ASLRCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ASLRCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ASLRCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Address` +GEF representation of memory addresses. + + + +### method `Address.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + + + +--- + + + +### method `Address.dereference` + +```python +dereference() → Union[int, NoneType] +``` + + + + + +--- + + + +### method `Address.is_in_heap_segment` + +```python +is_in_heap_segment() → bool +``` + + + + + +--- + + + +### method `Address.is_in_stack_segment` + +```python +is_in_stack_segment() → bool +``` + + + + + +--- + + + +### method `Address.is_in_text_segment` + +```python +is_in_text_segment() → bool +``` + + + + + + +--- + +## class `AliasesAddCommand` +Command to add aliases. + + + +### method `AliasesAddCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property AliasesAddCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `AliasesAddCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `AliasesAddCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `AliasesAddCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `AliasesAddCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `AliasesAddCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `AliasesAddCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `AliasesAddCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `AliasesAddCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `AliasesAddCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `AliasesCommand` +Base command to add, remove, or list aliases. + + + +### method `AliasesCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property AliasesCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `AliasesCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `AliasesCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `AliasesCommand.do_invoke` + +```python +do_invoke(argv) → None +``` + + + + + +--- + + + +### method `AliasesCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `AliasesCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `AliasesCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `AliasesCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `AliasesCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `AliasesCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `AliasesListCommand` +Command to list aliases. + + + +### method `AliasesListCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property AliasesListCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `AliasesListCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `AliasesListCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `AliasesListCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `AliasesListCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `AliasesListCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `AliasesListCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `AliasesListCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `AliasesListCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `AliasesListCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `AliasesRmCommand` +Command to remove aliases. + + + +### method `AliasesRmCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property AliasesRmCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `AliasesRmCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `AliasesRmCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `AliasesRmCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `AliasesRmCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `AliasesRmCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `AliasesRmCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `AliasesRmCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `AliasesRmCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `AliasesRmCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Architecture` +Generic metaclass for the architecture supported by GEF. + + +--- + +#### property Architecture.endianness + + + + + +--- + +#### property Architecture.fp + + + + + +--- + +#### property Architecture.pc + + + + + +--- + +#### property Architecture.ptrsize + + + + + +--- + +#### property Architecture.registers + + + + + +--- + +#### property Architecture.sp + + + + + + + +--- + + + +### method `Architecture.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +### method `Architecture.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `Architecture.get_ra` + +```python +get_ra(insn, frame) → Union[int, NoneType] +``` + + + + + +--- + + + +### method `Architecture.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `Architecture.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `Architecture.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `Architecture.is_ret` + +```python +is_ret(insn) → Union[bool, NoneType] +``` + + + + + +--- + + + +### method `Architecture.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## class `AssembleCommand` +Inline code assemble. Architecture can be set in GEF runtime config. + + + +### method `AssembleCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property AssembleCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `AssembleCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `AssembleCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `AssembleCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `AssembleCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `AssembleCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `AssembleCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `AssembleCommand.list_archs` + +```python +list_archs() → None +``` + + + + + +--- + + + +### method `AssembleCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `AssembleCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `AssembleCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `BssBaseFunction` +Return the current bss base address plus the given offset. + + + +### method `BssBaseFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +### method `BssBaseFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +### method `BssBaseFunction.do_invoke` + +```python +do_invoke(args: List) → int +``` + + + + + +--- + + + +### method `BssBaseFunction.invoke` + +```python +invoke(*args) → int +``` + + + + + + +--- + +## class `CanaryCommand` +Shows the canary value of the current process. + + + +### method `CanaryCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property CanaryCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `CanaryCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `CanaryCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `CanaryCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `CanaryCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `CanaryCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `CanaryCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `CanaryCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `CanaryCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `CanaryCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `CapstoneDisassembleCommand` +Use capstone disassembly framework to disassemble code. + + + +### method `CapstoneDisassembleCommand.__init__` + +```python +__init__() +``` + + + + + + +--- + +#### property CapstoneDisassembleCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `CapstoneDisassembleCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `CapstoneDisassembleCommand.capstone_analyze_pc` + +```python +capstone_analyze_pc(insn, nb_insn: int) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `CapstoneDisassembleCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `CapstoneDisassembleCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `CapstoneDisassembleCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `CapstoneDisassembleCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `CapstoneDisassembleCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `CapstoneDisassembleCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `CapstoneDisassembleCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `CapstoneDisassembleCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ChangeFdCommand` +ChangeFdCommand: redirect file descriptor during runtime. + + + +### method `ChangeFdCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property ChangeFdCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ChangeFdCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ChangeFdCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `ChangeFdCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `ChangeFdCommand.get_fd_from_result` + +```python +get_fd_from_result(res: str) → int +``` + + + + + +--- + + + +### method `ChangeFdCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ChangeFdCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ChangeFdCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ChangeFdCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ChangeFdCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ChangeFdCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ChangePermissionBreakpoint` +When hit, this temporary breakpoint will restore the original code, and position $pc correctly. + + + +### method `ChangePermissionBreakpoint.__init__` + +```python +__init__(loc: str, code: ByteString, pc: int) → None +``` + + + + + + + + +--- + + + +### method `ChangePermissionBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `ChangePermissionCommand` +Change a page permission. By default, it will change it to 7 (RWX). + + + +### method `ChangePermissionCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ChangePermissionCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ChangePermissionCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ChangePermissionCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `ChangePermissionCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `ChangePermissionCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ChangePermissionCommand.get_stub_by_arch` + +```python +get_stub_by_arch(addr: int, size: int, perm) → Union[str, bytearray, NoneType] +``` + + + + + +--- + + + +### method `ChangePermissionCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ChangePermissionCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ChangePermissionCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ChangePermissionCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ChangePermissionCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## 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 + + + +### method `ChecksecCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ChecksecCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ChecksecCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ChecksecCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `ChecksecCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `ChecksecCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ChecksecCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ChecksecCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ChecksecCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ChecksecCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ChecksecCommand.print_security_properties` + +```python +print_security_properties(filename: str) → None +``` + + + + + +--- + + + +### method `ChecksecCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Color` +Used to colorify terminal output. + + + + +--- + + + +### method `Color.blinkify` + +```python +blinkify(msg: str) → str +``` + + + + + +--- + + + +### method `Color.blueify` + +```python +blueify(msg: str) → str +``` + + + + + +--- + + + +### method `Color.boldify` + +```python +boldify(msg: str) → str +``` + + + + + +--- + + + +### method `Color.colorify` + +```python +colorify(text: str, attrs: str) → str +``` + +Color text according to the given attributes. + +--- + + + +### method `Color.cyanify` + +```python +cyanify(msg: str) → str +``` + + + + + +--- + + + +### method `Color.grayify` + +```python +grayify(msg: str) → str +``` + + + + + +--- + + + +### method `Color.greenify` + +```python +greenify(msg: str) → str +``` + + + + + +--- + + + +### method `Color.highlightify` + +```python +highlightify(msg: str) → str +``` + + + + + +--- + + + +### method `Color.light_grayify` + +```python +light_grayify(msg: str) → str +``` + + + + + +--- + + + +### method `Color.pinkify` + +```python +pinkify(msg: str) → str +``` + + + + + +--- + + + +### method `Color.redify` + +```python +redify(msg: str) → str +``` + + + + + +--- + + + +### method `Color.underlinify` + +```python +underlinify(msg: str) → str +``` + + + + + +--- + + + +### method `Color.yellowify` + +```python +yellowify(msg: str) → str +``` + + + + + + +--- + +## class `ContextCommand` +Displays a comprehensive and modular summary of runtime context. Unless setting `enable` is set to False, this command will be spawned automatically every time GDB hits a breakpoint, a watchpoint, or any kind of interrupt. By default, it will show panes that contain the register states, the stack, and the disassembly code around $pc. + + + +### method `ContextCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ContextCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ContextCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ContextCommand.addr_has_breakpoint` + +```python +addr_has_breakpoint(address: int, bp_locations: List[str]) → bool +``` + + + + + +--- + + + +### method `ContextCommand.context_additional_information` + +```python +context_additional_information() → None +``` + + + + + +--- + + + +### method `ContextCommand.context_args` + +```python +context_args() → None +``` + + + + + +--- + + + +### method `ContextCommand.context_code` + +```python +context_code() → None +``` + + + + + +--- + + + +### method `ContextCommand.context_memory` + +```python +context_memory() → None +``` + + + + + +--- + + + +### method `ContextCommand.context_regs` + +```python +context_regs() → None +``` + + + + + +--- + + + +### method `ContextCommand.context_source` + +```python +context_source() → None +``` + + + + + +--- + + + +### method `ContextCommand.context_stack` + +```python +context_stack() → None +``` + + + + + +--- + + + +### method `ContextCommand.context_threads` + +```python +context_threads() → None +``` + + + + + +--- + + + +### method `ContextCommand.context_title` + +```python +context_title(m: Optional[str]) → None +``` + + + + + +--- + + + +### method `ContextCommand.context_trace` + +```python +context_trace() → None +``` + + + + + +--- + + + +### method `ContextCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `ContextCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `ContextCommand.empty_extra_messages` + +```python +empty_extra_messages(_) → None +``` + + + + + +--- + + + +### method `ContextCommand.get_pc_context_info` + +```python +get_pc_context_info(pc: int, line: str) → str +``` + + + + + +--- + + + +### method `ContextCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ContextCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ContextCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ContextCommand.line_has_breakpoint` + +```python +line_has_breakpoint( + file_name: str, + line_number: int, + bp_locations: List[str] +) → bool +``` + + + + + +--- + + + +### method `ContextCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ContextCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ContextCommand.print_arguments_from_symbol` + +```python +print_arguments_from_symbol(function_name: str, symbol) → None +``` + +If symbols were found, parse them and print the argument adequately. + +--- + + + +### method `ContextCommand.print_guessed_arguments` + +```python +print_guessed_arguments(function_name: str) → None +``` + +When no symbol, read the current basic block and look for "interesting" instructions. + +--- + + + +### method `ContextCommand.show_legend` + +```python +show_legend() → None +``` + + + + + +--- + + + +### classmethod `ContextCommand.update_registers` + +```python +update_registers(_) → None +``` + + + + + +--- + + + +### method `ContextCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `DereferenceCommand` +Dereference recursively from an address and display information. This acts like WinDBG `dps` command. + + + +### method `DereferenceCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property DereferenceCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `DereferenceCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `DereferenceCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `DereferenceCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `DereferenceCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `DereferenceCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `DereferenceCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `DereferenceCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `DereferenceCommand.pprint_dereferenced` + +```python +pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) → str +``` + + + + + +--- + + + +### method `DereferenceCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `DereferenceCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `DetailRegistersCommand` +Display full details on one, many or all registers value from current architecture. + + + +### method `DetailRegistersCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property DetailRegistersCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `DetailRegistersCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `DetailRegistersCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `DetailRegistersCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `DetailRegistersCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `DetailRegistersCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `DetailRegistersCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `DetailRegistersCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `DetailRegistersCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `DetailRegistersCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Elf` +Basic ELF parsing. Ref: +- http://www.skyfree.org/linux/references/ELF_Format.pdf +- http://refspecs.freestandards.org/elf/elfspec_ppc.pdf +- http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html + + + +### method `Elf.__init__` + +```python +__init__(elf: str = '', minimalist: bool = False) → None +``` + +Instantiate an ELF object. The default behavior is to create the object by parsing the ELF file. But in some cases (QEMU-stub), we may just want a simple minimal object with default values. + + + + +--- + + + +### method `Elf.is_valid` + +```python +is_valid() → bool +``` + + + + + +--- + + + +### method `Elf.read` + +```python +read(size) +``` + + + + + +--- + + + +### method `Elf.seek` + +```python +seek(off: int) → None +``` + + + + + + +--- + +## class `ElfInfoCommand` +Display a limited subset of ELF header information. If no argument is provided, the command will show information about the current ELF being debugged. + + + +### method `ElfInfoCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ElfInfoCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ElfInfoCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ElfInfoCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `ElfInfoCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `ElfInfoCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ElfInfoCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ElfInfoCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ElfInfoCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ElfInfoCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ElfInfoCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Endianness` +An enumeration. + + + + + +--- + +## class `EntryBreakBreakpoint` +Breakpoint used internally to stop execution at the most convenient entry point. + + + +### method `EntryBreakBreakpoint.__init__` + +```python +__init__(location: str) → None +``` + + + + + + + + +--- + + + +### method `EntryBreakBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `EntryPointBreakCommand` +Tries to find best entry point and sets a temporary breakpoint on it. The command will test for well-known symbols for entry points, such as `main`, `_main`, `__libc_start_main`, etc. defined by the setting `entrypoint_symbols`. + + + +### method `EntryPointBreakCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property EntryPointBreakCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `EntryPointBreakCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `EntryPointBreakCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `EntryPointBreakCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `EntryPointBreakCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `EntryPointBreakCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `EntryPointBreakCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `EntryPointBreakCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `EntryPointBreakCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `EntryPointBreakCommand.set_init_tbreak` + +```python +set_init_tbreak(addr: int) → EntryBreakBreakpoint +``` + + + + + +--- + + + +### method `EntryPointBreakCommand.set_init_tbreak_pie` + +```python +set_init_tbreak_pie(addr: int, argv: List[str]) → EntryBreakBreakpoint +``` + + + + + +--- + + + +### method `EntryPointBreakCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `FlagsCommand` +Edit flags in a human friendly way. + + + +### method `FlagsCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property FlagsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `FlagsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `FlagsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `FlagsCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `FlagsCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `FlagsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `FlagsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `FlagsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `FlagsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `FlagsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `FormatStringBreakpoint` +Inspect stack for format string. + + + +### method `FormatStringBreakpoint.__init__` + +```python +__init__(spec: str, num_args: int) → None +``` + + + + + + + + +--- + + + +### method `FormatStringBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `FormatStringSearchCommand` +Exploitable format-string helper: this command will set up specific breakpoints at well-known dangerous functions (printf, snprintf, etc.), and check if the pointer holding the format string is writable, and therefore susceptible to format string attacks if an attacker can control its content. + + + +### method `FormatStringSearchCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property FormatStringSearchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `FormatStringSearchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `FormatStringSearchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `FormatStringSearchCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `FormatStringSearchCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `FormatStringSearchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `FormatStringSearchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `FormatStringSearchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `FormatStringSearchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `FormatStringSearchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GdbRemoveReadlineFinder` + + + + + + + +--- + + + +### method `GdbRemoveReadlineFinder.find_module` + +```python +find_module(fullname, path=None) +``` + + + + + +--- + + + +### method `GdbRemoveReadlineFinder.load_module` + +```python +load_module(fullname) +``` + + + + + + +--- + +## class `Gef` +The GEF root class, which serves as a base classe for all the attributes for the debugging session (architecture, memory, settings, etc.). + + + +### method `Gef.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +### method `Gef.reinitialize_managers` + +```python +reinitialize_managers() → None +``` + +Reinitialize the managers. Avoid calling this function directly, using `pi reset()` is preferred + +--- + + + +### method `Gef.reset_caches` + +```python +reset_caches() → None +``` + +Recursively clean the cache of all the managers. Avoid calling this function directly, using `reset-cache` is preferred + +--- + + + +### method `Gef.setup` + +```python +setup() → None +``` + +Setup initialize the runtime setup, which may require for the `gef` to be not None. + + +--- + +## class `GefAlias` +Simple aliasing wrapper because GDB doesn't do what it should. + + + +### method `GefAlias.__init__` + +```python +__init__(alias, command, completer_class=0, command_class=-1) → None +``` + + + + + + + + +--- + + + +### method `GefAlias.invoke` + +```python +invoke(args, from_tty) → None +``` + + + + + +--- + + + +### method `GefAlias.lookup_command` + +```python +lookup_command(cmd: str) → Union[Tuple[str, Type, Any], NoneType] +``` + + + + + + +--- + +## class `GefCommand` +GEF main command: view all new commands by typing `gef`. + + + +### method `GefCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefCommand.loaded_command_names + + + + + + + +--- + + + +### method `GefCommand.add_context_pane` + +```python +add_context_pane( + pane_name: str, + display_pane_function: Callable, + pane_title_function: Callable +) → None +``` + +Add a new context pane to ContextCommand. + +--- + + + +### method `GefCommand.invoke` + +```python +invoke(args, from_tty) → None +``` + + + + + +--- + + + +### method `GefCommand.load` + +```python +load(initial: bool = False) → None +``` + +Load all the commands and functions defined by GEF into GDB. + +--- + + + +### method `GefCommand.setup` + +```python +setup() → 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). + + + +### method `GefConfigCommand.__init__` + +```python +__init__(loaded_commands, *args, **kwargs) → None +``` + + + + + + + + +--- + + + +### method `GefConfigCommand.complete` + +```python +complete(text: str, word: str) → List[str] +``` + + + + + +--- + + + +### method `GefConfigCommand.invoke` + +```python +invoke(args: str, from_tty) → None +``` + + + + + +--- + + + +### method `GefConfigCommand.print_setting` + +```python +print_setting(plugin_name: str, verbose: bool = False) → None +``` + + + + + +--- + + + +### method `GefConfigCommand.print_settings` + +```python +print_settings() → None +``` + + + + + +--- + + + +### method `GefConfigCommand.set_setting` + +```python +set_setting(argv: Tuple[str, Any]) → None +``` + + + + + + +--- + +## class `GefFunctionsCommand` +List the convenience functions provided by GEF. + + + +### method `GefFunctionsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefFunctionsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GefFunctionsCommand.add_function_to_doc` + +```python +add_function_to_doc(function) → None +``` + +Add function to documentation. + +--- + + + +### method `GefFunctionsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GefFunctionsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GefFunctionsCommand.do_invoke` + +```python +do_invoke(argv) → None +``` + + + + + +--- + + + +### method `GefFunctionsCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GefFunctionsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GefFunctionsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GefFunctionsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GefFunctionsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GefFunctionsCommand.setup` + +```python +setup() → None +``` + + + + + +--- + + + +### method `GefFunctionsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GefHeapManager` +Class managing session heap. + + + +### method `GefHeapManager.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefHeapManager.arenas + + + + + +--- + +#### property GefHeapManager.base_address + + + + + +--- + +#### property GefHeapManager.chunks + + + + + +--- + +#### property GefHeapManager.main_arena + + + + + +--- + +#### property GefHeapManager.selected_arena + + + + + + + +--- + + + +### method `GefHeapManager.reset_caches` + +```python +reset_caches() → None +``` + + + + + + +--- + +## class `GefHelpCommand` +GEF help sub-command. + + + +### method `GefHelpCommand.__init__` + +```python +__init__(commands: List[Tuple[str, Any, Any]], *args, **kwargs) → None +``` + + + + + + + + +--- + + + +### method `GefHelpCommand.add_command_to_doc` + +```python +add_command_to_doc(command: Tuple[str, Any, Any]) → None +``` + +Add command to GEF documentation. + +--- + + + +### method `GefHelpCommand.generate_help` + +```python +generate_help(commands: List[Tuple[str, Type, Any]]) → None +``` + +Generate builtin commands documentation. + +--- + + + +### method `GefHelpCommand.invoke` + +```python +invoke(args, from_tty) → None +``` + + + + + +--- + + + +### method `GefHelpCommand.refresh` + +```python +refresh() → None +``` + +Refresh the documentation. + + +--- + +## class `GefManager` + + + + + + + +--- + + + +### method `GefManager.reset_caches` + +```python +reset_caches() → None +``` + +Reset the LRU-cached attributes + + +--- + +## class `GefMemoryManager` +Class that manages memory access for gef. + + + +### method `GefMemoryManager.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefMemoryManager.maps + + + + + + + +--- + + + +### method `GefMemoryManager.read` + +```python +read(addr: int, length: int = 16) → bytes +``` + +Return a `length` long byte array with the copy of the process memory at `addr`. + +--- + + + +### method `GefMemoryManager.read_ascii_string` + +```python +read_ascii_string(address: int) → Union[str, NoneType] +``` + +Read an ASCII string from memory + +--- + + + +### method `GefMemoryManager.read_cstring` + +```python +read_cstring( + address: int, + max_length: int = 50, + encoding: Optional[str] = None +) → str +``` + +Return a C-string read from memory. + +--- + + + +### method `GefMemoryManager.read_integer` + +```python +read_integer(addr: int) → int +``` + +Return an integer read from memory. + +--- + + + +### method `GefMemoryManager.reset_caches` + +```python +reset_caches() → None +``` + + + + + +--- + + + +### method `GefMemoryManager.write` + +```python +write(address: int, buffer: ByteString, length: int = 16) +``` + +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. + + + +### method `GefMissingCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + + + +--- + + + +### method `GefMissingCommand.invoke` + +```python +invoke(args, from_tty) → None +``` + + + + + + +--- + +## class `GefRestoreCommand` +GEF restore sub-command. Loads settings from file '~/.gef.rc' and apply them to the configuration of GEF. + + + +### method `GefRestoreCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + + + +--- + + + +### method `GefRestoreCommand.invoke` + +```python +invoke(args: str, from_tty) → None +``` + + + + + + +--- + +## 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`. + + + +### method `GefRunCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + + + +--- + + + +### method `GefRunCommand.invoke` + +```python +invoke(args, from_tty) → None +``` + + + + + + +--- + +## class `GefSaveCommand` +GEF save sub-command. Saves the current configuration of GEF to disk (by default in file '~/.gef.rc'). + + + +### method `GefSaveCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + + + +--- + + + +### method `GefSaveCommand.invoke` + +```python +invoke(args, from_tty) → None +``` + + + + + + +--- + +## class `GefSessionManager` +Class managing the runtime properties of GEF. + + + +### method `GefSessionManager.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GefSessionManager.auxiliary_vector + + + + + +--- + +#### property GefSessionManager.canary + +Returns a tuple of the canary address and value, read from the auxiliary vector. + +--- + +#### property GefSessionManager.file + +Return a Path object of the target process. + +--- + +#### 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. + + + +--- + + + +### method `GefSessionManager.reset_caches` + +```python +reset_caches() → None +``` + + + + + + +--- + +## class `GefSetCommand` +Override GDB set commands with the context from GEF. + + + +### method `GefSetCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + + + +--- + + + +### method `GefSetCommand.invoke` + +```python +invoke(args, from_tty) → None +``` + + + + + + +--- + +## class `GefSetting` +Basic class for storing gef settings as objects + + + +### method `GefSetting.__init__` + +```python +__init__( + value: Any, + cls: Optional[type] = None, + description: Optional[str] = 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]` + + + + +--- + + + +### method `GefSettingsManager.raw_entry` + +```python +raw_entry(name: str) → Any +``` + + + + + + +--- + +## class `GefThemeCommand` +Customize GEF appearance. + + + +### method `GefThemeCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property GefThemeCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GefThemeCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GefThemeCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GefThemeCommand.do_invoke` + +```python +do_invoke(args: List) → None +``` + + + + + +--- + + + +### method `GefThemeCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GefThemeCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GefThemeCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GefThemeCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GefThemeCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GefThemeCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GefTmuxSetup` +Setup a confortable tmux debugging environment. + + + +### method `GefTmuxSetup.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +### method `GefTmuxSetup.invoke` + +```python +invoke(args, from_tty) → None +``` + + + + + +--- + + + +### method `GefTmuxSetup.screen_setup` + +```python +screen_setup() → None +``` + +Hackish equivalent of the tmux_setup() function for screen. + +--- + + + +### method `GefTmuxSetup.tmux_setup` + +```python +tmux_setup() → None +``` + +Prepare the tmux environment by vertically splitting the current pane, and forcing the context to be redirected there. + + +--- + +## class `GefUiManager` +Class managing UI settings. + + + +### method `GefUiManager.__init__` + +```python +__init__() +``` + + + + + + + + +--- + + + +### method `GefUiManager.reset_caches` + +```python +reset_caches() → None +``` + +Reset the LRU-cached attributes + + +--- + +## class `GenericArchitecture` + + + + + +--- + +#### property GenericArchitecture.endianness + + + + + +--- + +#### property GenericArchitecture.fp + + + + + +--- + +#### property GenericArchitecture.pc + + + + + +--- + +#### property GenericArchitecture.registers + + + + + +--- + +#### property GenericArchitecture.sp + + + + + + + +--- + + + +### method `GenericArchitecture.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → Union[str, NoneType] +``` + + + + + +--- + + + +### method `GenericArchitecture.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `GenericArchitecture.get_ra` + +```python +get_ra(insn, frame) → Union[int, NoneType] +``` + + + + + +--- + + + +### method `GenericArchitecture.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `GenericArchitecture.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `GenericArchitecture.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `GenericArchitecture.is_ret` + +```python +is_ret(insn) → bool +``` + + + + + +--- + + + +### method `GenericArchitecture.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## class `GenericCommand` +This is an abstract class for invoking commands, should not be instantiated. + + + +### method `GenericCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property GenericCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GenericCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GenericCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GenericCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `GenericCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GenericCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GenericCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GenericCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GenericCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GenericCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GenericFunction` +This is an abstract class for invoking convenience functions, should not be instantiated. + + + +### method `GenericFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +### method `GenericFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +### method `GenericFunction.do_invoke` + +```python +do_invoke(args) → None +``` + + + + + +--- + + + +### method `GenericFunction.invoke` + +```python +invoke(*args) → int +``` + + + + + + +--- + +## class `GlibcArena` +Glibc arena class Ref: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1671 + + + +### method `GlibcArena.__init__` + +```python +__init__(addr: str) → None +``` + + + + + + + + +--- + + + +### method `GlibcArena.bin` + +```python +bin(i: int) → Tuple[int, int] +``` + + + + + +--- + + + +### method `GlibcArena.fastbin` + +```python +fastbin(i: int) +``` + +Return head chunk in fastbinsY[i]. + +--- + + + +### method `GlibcArena.get_heap_for_ptr` + +```python +get_heap_for_ptr(ptr: int) → int +``` + +Find the corresponding heap for a given pointer (int). See https://github.com/bminor/glibc/blob/glibc-2.34/malloc/arena.c#L129 + +--- + + + +### method `GlibcArena.get_heap_info_list` + +```python +get_heap_info_list() +``` + + + + + +--- + + + +### method `GlibcArena.heap_addr` + +```python +heap_addr(allow_unaligned: bool = False) → Union[int, NoneType] +``` + + + + + +--- + + + +### method `GlibcArena.is_main_arena` + +```python +is_main_arena() → bool +``` + + + + + + +--- + +## 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/. + + + +### method `GlibcChunk.__init__` + +```python +__init__(addr, from_base=False, allow_unaligned=True) +``` + + + + + + +--- + +#### property GlibcChunk.bck + + + + + +--- + +#### property GlibcChunk.bk + + + + + +--- + +#### property GlibcChunk.fd + + + + + +--- + +#### property GlibcChunk.fwd + + + + + +--- + +#### property GlibcChunk.size + + + + + +--- + +#### property GlibcChunk.usable_size + + + + + + + +--- + + + +### method `GlibcChunk.flags_as_string` + +```python +flags_as_string() → str +``` + + + + + +--- + + + +### method `GlibcChunk.get_bkw_ptr` + +```python +get_bkw_ptr() → int +``` + + + + + +--- + + + +### method `GlibcChunk.get_chunk_size` + +```python +get_chunk_size() → int +``` + + + + + +--- + + + +### method `GlibcChunk.get_fwd_ptr` + +```python +get_fwd_ptr(sll) → int +``` + + + + + +--- + + + +### method `GlibcChunk.get_next_chunk` + +```python +get_next_chunk(allow_unaligned: bool = False) +``` + + + + + +--- + + + +### method `GlibcChunk.get_next_chunk_addr` + +```python +get_next_chunk_addr() → int +``` + + + + + +--- + + + +### method `GlibcChunk.get_prev_chunk_size` + +```python +get_prev_chunk_size() → int +``` + + + + + +--- + + + +### method `GlibcChunk.get_usable_size` + +```python +get_usable_size() → int +``` + + + + + +--- + + + +### method `GlibcChunk.has_m_bit` + +```python +has_m_bit() → bool +``` + + + + + +--- + + + +### method `GlibcChunk.has_n_bit` + +```python +has_n_bit() → bool +``` + + + + + +--- + + + +### method `GlibcChunk.has_p_bit` + +```python +has_p_bit() → bool +``` + + + + + +--- + + + +### method `GlibcChunk.is_used` + +```python +is_used() → bool +``` + +Check if the current block is used by: +- checking the M bit is true +- or checking that next chunk PREV_INUSE flag is true + +--- + + + +### method `GlibcChunk.psprint` + +```python +psprint() → str +``` + + + + + +--- + + + +### method `GlibcChunk.str_as_alloced` + +```python +str_as_alloced() → str +``` + + + + + +--- + + + +### method `GlibcChunk.str_as_freed` + +```python +str_as_freed() → str +``` + + + + + +--- + + + +### method `GlibcChunk.str_chunk_size_flag` + +```python +str_chunk_size_flag() → str +``` + + + + + + +--- + +## class `GlibcHeapArenaCommand` +Display information on a heap chunk. + + + +### method `GlibcHeapArenaCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property GlibcHeapArenaCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GlibcHeapArenaCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GlibcHeapArenaCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GlibcHeapArenaCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `GlibcHeapArenaCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GlibcHeapArenaCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GlibcHeapArenaCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GlibcHeapArenaCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapArenaCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapArenaCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapBinsCommand` +Display information on the bins on an arena (default: main_arena). See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123. + + + +### method `GlibcHeapBinsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapBinsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GlibcHeapBinsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GlibcHeapBinsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GlibcHeapBinsCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `GlibcHeapBinsCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GlibcHeapBinsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GlibcHeapBinsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GlibcHeapBinsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapBinsCommand.pprint_bin` + +```python +pprint_bin(arena_addr: str, index: int, _type: str = '') → int +``` + + + + + +--- + + + +### method `GlibcHeapBinsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapBinsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapChunkCommand` +Display information on a heap chunk. See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123. + + + +### method `GlibcHeapChunkCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapChunkCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GlibcHeapChunkCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GlibcHeapChunkCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `GlibcHeapChunkCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `GlibcHeapChunkCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GlibcHeapChunkCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GlibcHeapChunkCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GlibcHeapChunkCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapChunkCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapChunkCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapChunksCommand` +Display all heap chunks for the current arena. As an optional argument the base address of a different arena can be passed + + + +### method `GlibcHeapChunksCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapChunksCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GlibcHeapChunksCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GlibcHeapChunksCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `GlibcHeapChunksCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `GlibcHeapChunksCommand.dump_chunks_arena` + +```python +dump_chunks_arena( + arena: __main__.GlibcArena, + print_arena: bool = False, + allow_unaligned: bool = False +) → None +``` + + + + + +--- + + + +### method `GlibcHeapChunksCommand.dump_chunks_heap` + +```python +dump_chunks_heap( + start: int, + until: Optional[int] = None, + top: Optional[int] = None, + allow_unaligned: bool = False +) → None +``` + + + + + +--- + + + +### method `GlibcHeapChunksCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GlibcHeapChunksCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GlibcHeapChunksCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GlibcHeapChunksCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapChunksCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapChunksCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapCommand` +Base command to get information about the Glibc heap structure. + + + +### method `GlibcHeapCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GlibcHeapCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GlibcHeapCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GlibcHeapCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `GlibcHeapCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GlibcHeapCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GlibcHeapCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GlibcHeapCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapFastbinsYCommand` +Display information on the fastbinsY on an arena (default: main_arena). See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123. + + + +### method `GlibcHeapFastbinsYCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapFastbinsYCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GlibcHeapFastbinsYCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GlibcHeapFastbinsYCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GlibcHeapFastbinsYCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `GlibcHeapFastbinsYCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GlibcHeapFastbinsYCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GlibcHeapFastbinsYCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GlibcHeapFastbinsYCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapFastbinsYCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapFastbinsYCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapInfo` +Glibc heap_info struct See https://github.com/bminor/glibc/blob/glibc-2.34/malloc/arena.c#L64 + + + +### method `GlibcHeapInfo.__init__` + +```python +__init__(addr) → None +``` + + + + + + +--- + +#### property GlibcHeapInfo.addr + + + + + +--- + +#### property GlibcHeapInfo.ar_ptr + + + + + +--- + +#### property GlibcHeapInfo.ar_ptr_addr + + + + + +--- + +#### property GlibcHeapInfo.mprotect_size + + + + + +--- + +#### property GlibcHeapInfo.mprotect_size_addr + + + + + +--- + +#### property GlibcHeapInfo.prev + + + + + +--- + +#### property GlibcHeapInfo.prev_addr + + + + + +--- + +#### property GlibcHeapInfo.size + + + + + +--- + +#### property GlibcHeapInfo.size_addr + + + + + + + + +--- + +## class `GlibcHeapLargeBinsCommand` +Convenience command for viewing large bins. + + + +### method `GlibcHeapLargeBinsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapLargeBinsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GlibcHeapLargeBinsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GlibcHeapLargeBinsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GlibcHeapLargeBinsCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `GlibcHeapLargeBinsCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GlibcHeapLargeBinsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GlibcHeapLargeBinsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GlibcHeapLargeBinsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapLargeBinsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapLargeBinsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapSetArenaCommand` +Display information on a heap chunk. + + + +### method `GlibcHeapSetArenaCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapSetArenaCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GlibcHeapSetArenaCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GlibcHeapSetArenaCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GlibcHeapSetArenaCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `GlibcHeapSetArenaCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GlibcHeapSetArenaCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GlibcHeapSetArenaCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GlibcHeapSetArenaCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapSetArenaCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapSetArenaCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapSmallBinsCommand` +Convenience command for viewing small bins. + + + +### method `GlibcHeapSmallBinsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapSmallBinsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GlibcHeapSmallBinsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GlibcHeapSmallBinsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GlibcHeapSmallBinsCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `GlibcHeapSmallBinsCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GlibcHeapSmallBinsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GlibcHeapSmallBinsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GlibcHeapSmallBinsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapSmallBinsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapSmallBinsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapTcachebinsCommand` +Display information on the Tcachebins on an arena (default: main_arena). See https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc. + + + +### method `GlibcHeapTcachebinsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapTcachebinsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GlibcHeapTcachebinsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GlibcHeapTcachebinsCommand.check_thread_ids` + +```python +check_thread_ids(tids: List[int]) → List[int] +``` + +Check the validity, dedup, and return all valid tids. + +--- + + + +### method `GlibcHeapTcachebinsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GlibcHeapTcachebinsCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `GlibcHeapTcachebinsCommand.find_tcache` + +```python +find_tcache() → int +``` + +Return the location of the current thread's tcache. + +--- + + + +### method `GlibcHeapTcachebinsCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GlibcHeapTcachebinsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GlibcHeapTcachebinsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GlibcHeapTcachebinsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapTcachebinsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapTcachebinsCommand.tcachebin` + +```python +tcachebin( + tcache_base: int, + i: int +) → Tuple[Union[__main__.GlibcChunk, NoneType], int] +``` + +Return the head chunk in tcache[i] and the number of chunks in the bin. + +--- + + + +### method `GlibcHeapTcachebinsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GlibcHeapUnsortedBinsCommand` +Display information on the Unsorted Bins of an arena (default: main_arena). See: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1689. + + + +### method `GlibcHeapUnsortedBinsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property GlibcHeapUnsortedBinsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GlibcHeapUnsortedBinsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GlibcHeapUnsortedBinsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GlibcHeapUnsortedBinsCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `GlibcHeapUnsortedBinsCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GlibcHeapUnsortedBinsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GlibcHeapUnsortedBinsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GlibcHeapUnsortedBinsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapUnsortedBinsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GlibcHeapUnsortedBinsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `GotBaseFunction` +Return the current bss base address plus the given offset. + + + +### method `GotBaseFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +### method `GotBaseFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +### method `GotBaseFunction.do_invoke` + +```python +do_invoke(args: List) → int +``` + + + + + +--- + + + +### method `GotBaseFunction.invoke` + +```python +invoke(*args) → int +``` + + + + + + +--- + +## class `GotCommand` +Display current status of the got inside the process. + + + +### method `GotCommand.__init__` + +```python +__init__(*args, **kwargs) +``` + + + + + + +--- + +#### property GotCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `GotCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `GotCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `GotCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `GotCommand.get_jmp_slots` + +```python +get_jmp_slots(readelf: str, filename: str) → List[str] +``` + + + + + +--- + + + +### method `GotCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `GotCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `GotCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `GotCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `GotCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `GotCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HeapAnalysisCommand` +Heap vulnerability analysis helper: this command aims to track dynamic heap allocation done through malloc()/free() to provide some insights on possible heap vulnerabilities. The following vulnerabilities are checked: +- NULL free +- Use-after-Free +- Double Free +- Heap overlap + + + +### method `HeapAnalysisCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HeapAnalysisCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `HeapAnalysisCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `HeapAnalysisCommand.clean` + +```python +clean(_) → None +``` + + + + + +--- + + + +### method `HeapAnalysisCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `HeapAnalysisCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `HeapAnalysisCommand.dump_tracked_allocations` + +```python +dump_tracked_allocations() → None +``` + + + + + +--- + + + +### method `HeapAnalysisCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `HeapAnalysisCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `HeapAnalysisCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `HeapAnalysisCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `HeapAnalysisCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `HeapAnalysisCommand.setup` + +```python +setup() → None +``` + + + + + +--- + + + +### method `HeapAnalysisCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HeapBaseFunction` +Return the current heap base address plus an optional offset. + + + +### method `HeapBaseFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +### method `HeapBaseFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +### method `HeapBaseFunction.do_invoke` + +```python +do_invoke(args: List) → int +``` + + + + + +--- + + + +### method `HeapBaseFunction.invoke` + +```python +invoke(*args) → int +``` + + + + + + +--- + +## class `HexdumpByteCommand` +Display SIZE lines of hexdump as BYTE from the memory location pointed by ADDRESS. + + + +### method `HexdumpByteCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HexdumpByteCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `HexdumpByteCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `HexdumpByteCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `HexdumpByteCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `HexdumpByteCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `HexdumpByteCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `HexdumpByteCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `HexdumpByteCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `HexdumpByteCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `HexdumpByteCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HexdumpCommand` +Display SIZE lines of hexdump from the memory location pointed by LOCATION. + + + +### method `HexdumpCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HexdumpCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `HexdumpCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `HexdumpCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `HexdumpCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `HexdumpCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `HexdumpCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `HexdumpCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `HexdumpCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `HexdumpCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `HexdumpCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HexdumpDwordCommand` +Display SIZE lines of hexdump as DWORD from the memory location pointed by ADDRESS. + + + +### method `HexdumpDwordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HexdumpDwordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `HexdumpDwordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `HexdumpDwordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `HexdumpDwordCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `HexdumpDwordCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `HexdumpDwordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `HexdumpDwordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `HexdumpDwordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `HexdumpDwordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `HexdumpDwordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HexdumpQwordCommand` +Display SIZE lines of hexdump as QWORD from the memory location pointed by ADDRESS. + + + +### method `HexdumpQwordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HexdumpQwordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `HexdumpQwordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `HexdumpQwordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `HexdumpQwordCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `HexdumpQwordCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `HexdumpQwordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `HexdumpQwordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `HexdumpQwordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `HexdumpQwordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `HexdumpQwordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HexdumpWordCommand` +Display SIZE lines of hexdump as WORD from the memory location pointed by ADDRESS. + + + +### method `HexdumpWordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HexdumpWordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `HexdumpWordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `HexdumpWordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `HexdumpWordCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `HexdumpWordCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `HexdumpWordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `HexdumpWordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `HexdumpWordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `HexdumpWordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `HexdumpWordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HighlightAddCommand` +Add a match to the highlight table. + + + +### method `HighlightAddCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property HighlightAddCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `HighlightAddCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `HighlightAddCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `HighlightAddCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `HighlightAddCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `HighlightAddCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `HighlightAddCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `HighlightAddCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `HighlightAddCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `HighlightAddCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HighlightClearCommand` +Clear the highlight table, remove all matches. + + + +### method `HighlightClearCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property HighlightClearCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `HighlightClearCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `HighlightClearCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `HighlightClearCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `HighlightClearCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `HighlightClearCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `HighlightClearCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `HighlightClearCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `HighlightClearCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `HighlightClearCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HighlightCommand` +Highlight user-defined text matches in GEF output universally. + + + +### method `HighlightCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property HighlightCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `HighlightCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `HighlightCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `HighlightCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `HighlightCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `HighlightCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `HighlightCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `HighlightCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `HighlightCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `HighlightCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HighlightListCommand` +Show the current highlight table with matches to colors. + + + +### method `HighlightListCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property HighlightListCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `HighlightListCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `HighlightListCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `HighlightListCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `HighlightListCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `HighlightListCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `HighlightListCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `HighlightListCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `HighlightListCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `HighlightListCommand.print_highlight_table` + +```python +print_highlight_table() → None +``` + + + + + +--- + + + +### method `HighlightListCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `HighlightRemoveCommand` +Remove a match in the highlight table. + + + +### method `HighlightRemoveCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property HighlightRemoveCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `HighlightRemoveCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `HighlightRemoveCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `HighlightRemoveCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `HighlightRemoveCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `HighlightRemoveCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `HighlightRemoveCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `HighlightRemoveCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `HighlightRemoveCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `HighlightRemoveCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `IdaInteractCommand` +IDA Interact: set of commands to interact with IDA via a XML RPC service deployed via the IDA script `ida_gef.py`. It should be noted that this command can also be used to interact with Binary Ninja (using the script `binja_gef.py`) using the same interface. + + + +### method `IdaInteractCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property IdaInteractCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `IdaInteractCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `IdaInteractCommand.connect` + +```python +connect(host: Optional[str] = None, port: Optional[int] = None) → None +``` + +Connect to the XML-RPC service. + +--- + + + +### method `IdaInteractCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `IdaInteractCommand.disconnect` + +```python +disconnect() → None +``` + + + + + +--- + + + +### method `IdaInteractCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `IdaInteractCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `IdaInteractCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `IdaInteractCommand.import_structures` + +```python +import_structures(structs: Dict[str, List[Tuple[int, str, int]]]) → None +``` + + + + + +--- + + + +### method `IdaInteractCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `IdaInteractCommand.is_target_alive` + +```python +is_target_alive(host: str, port: int) → bool +``` + + + + + +--- + + + +### method `IdaInteractCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `IdaInteractCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `IdaInteractCommand.synchronize` + +```python +synchronize() → None +``` + +Submit all active breakpoint addresses to IDA/BN. + +--- + + + +### method `IdaInteractCommand.usage` + +```python +usage(meth: Optional[str] = None) → None +``` + + + + + + +--- + +## class `Instruction` +GEF representation of a CPU instruction. + + + +### method `Instruction.__init__` + +```python +__init__(address: int, location, mnemo: str, operands, opcodes) → None +``` + + + + + + + + +--- + + + +### method `Instruction.is_valid` + +```python +is_valid() → bool +``` + + + + + + +--- + +## class `IsSyscallCommand` +Tells whether the next instruction is a system call. + + + +### method `IsSyscallCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property IsSyscallCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `IsSyscallCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `IsSyscallCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `IsSyscallCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `IsSyscallCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `IsSyscallCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `IsSyscallCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `IsSyscallCommand.is_syscall` + +```python +is_syscall(arch, instruction: __main__.Instruction) → bool +``` + + + + + +--- + + + +### method `IsSyscallCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `IsSyscallCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `IsSyscallCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `MIPS` + + + + + +--- + +#### property MIPS.endianness + + + + + +--- + +#### property MIPS.fp + + + + + +--- + +#### property MIPS.pc + + + + + +--- + +#### property MIPS.registers + + + + + +--- + +#### property MIPS.sp + + + + + + + +--- + + + +### method `MIPS.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +### method `MIPS.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `MIPS.get_ra` + +```python +get_ra(insn, frame) → Union[int, NoneType] +``` + + + + + +--- + + + +### method `MIPS.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `MIPS.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `MIPS.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `MIPS.is_ret` + +```python +is_ret(insn) → bool +``` + + + + + +--- + + + +### classmethod `MIPS.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm) → str +``` + + + + + +--- + + + +### method `MIPS.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## class `MIPS64` + + + + + +--- + +#### property MIPS64.endianness + + + + + +--- + +#### property MIPS64.fp + + + + + +--- + +#### property MIPS64.pc + + + + + +--- + +#### property MIPS64.registers + + + + + +--- + +#### property MIPS64.sp + + + + + + + +--- + + + +### method `MIPS64.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +### method `MIPS64.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `MIPS64.get_ra` + +```python +get_ra(insn, frame) → Union[int, NoneType] +``` + + + + + +--- + + + +### method `MIPS64.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `MIPS64.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `MIPS64.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `MIPS64.is_ret` + +```python +is_ret(insn) → bool +``` + + + + + +--- + + + +### classmethod `MIPS64.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm) → str +``` + + + + + +--- + + + +### method `MIPS64.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## class `MallocStateStruct` +GEF representation of malloc_state from https://github.com/bminor/glibc/blob/glibc-2.28/malloc/malloc.c#L1658 + + + +### method `MallocStateStruct.__init__` + +```python +__init__(addr: str) → None +``` + + + + + + +--- + +#### property MallocStateStruct.addr + + + + + +--- + +#### property MallocStateStruct.bins + + + + + +--- + +#### property MallocStateStruct.bins_addr + + + + + +--- + +#### property MallocStateStruct.fastbinsY + + + + + +--- + +#### property MallocStateStruct.fastbins_addr + + + + + +--- + +#### property MallocStateStruct.last_remainder + + + + + +--- + +#### property MallocStateStruct.last_remainder_addr + + + + + +--- + +#### property MallocStateStruct.next + + + + + +--- + +#### property MallocStateStruct.next_addr + + + + + +--- + +#### property MallocStateStruct.next_free + + + + + +--- + +#### property MallocStateStruct.next_free_addr + + + + + +--- + +#### property MallocStateStruct.struct_size + + + + + +--- + +#### property MallocStateStruct.system_mem + + + + + +--- + +#### property MallocStateStruct.system_mem_addr + + + + + +--- + +#### property MallocStateStruct.top + + + + + +--- + +#### property MallocStateStruct.top_addr + + + + + + + +--- + + + +### method `MallocStateStruct.get_size_t` + +```python +get_size_t(addr) +``` + + + + + +--- + + + +### method `MallocStateStruct.get_size_t_array` + +```python +get_size_t_array(addr, length) +``` + + + + + +--- + + + +### method `MallocStateStruct.get_size_t_pointer` + +```python +get_size_t_pointer(addr) +``` + + + + + + +--- + +## class `MemoryCommand` +Add or remove address ranges to the memory view. + + + +### method `MemoryCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property MemoryCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `MemoryCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `MemoryCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `MemoryCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `MemoryCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `MemoryCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `MemoryCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `MemoryCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `MemoryCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `MemoryCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `MemoryUnwatchCommand` +Removes address ranges to the memory view. + + + +### method `MemoryUnwatchCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property MemoryUnwatchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `MemoryUnwatchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `MemoryUnwatchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `MemoryUnwatchCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `MemoryUnwatchCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `MemoryUnwatchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `MemoryUnwatchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `MemoryUnwatchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `MemoryUnwatchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `MemoryUnwatchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `MemoryWatchCommand` +Adds address ranges to the memory view. + + + +### method `MemoryWatchCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property MemoryWatchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `MemoryWatchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `MemoryWatchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `MemoryWatchCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `MemoryWatchCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `MemoryWatchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `MemoryWatchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `MemoryWatchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `MemoryWatchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `MemoryWatchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `MemoryWatchListCommand` +Lists all watchpoints to display in context layout. + + + +### method `MemoryWatchListCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property MemoryWatchListCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `MemoryWatchListCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `MemoryWatchListCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `MemoryWatchListCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `MemoryWatchListCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `MemoryWatchListCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `MemoryWatchListCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `MemoryWatchListCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `MemoryWatchListCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `MemoryWatchListCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `MemoryWatchResetCommand` +Removes all watchpoints. + + + +### method `MemoryWatchResetCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property MemoryWatchResetCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `MemoryWatchResetCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `MemoryWatchResetCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `MemoryWatchResetCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `MemoryWatchResetCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `MemoryWatchResetCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `MemoryWatchResetCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `MemoryWatchResetCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `MemoryWatchResetCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `MemoryWatchResetCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `NamedBreakpoint` +Breakpoint which shows a specified name, when hit. + + + +### method `NamedBreakpoint.__init__` + +```python +__init__(location: str, name: str) → None +``` + + + + + + + + +--- + + + +### method `NamedBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `NamedBreakpointCommand` +Sets a breakpoint and assigns a name to it, which will be shown, when it's hit. + + + +### method `NamedBreakpointCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property NamedBreakpointCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `NamedBreakpointCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `NamedBreakpointCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `NamedBreakpointCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `NamedBreakpointCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `NamedBreakpointCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `NamedBreakpointCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `NamedBreakpointCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `NamedBreakpointCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `NamedBreakpointCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `NopCommand` +Patch the instruction(s) pointed by parameters with NOP. Note: this command is architecture aware. + + + +### method `NopCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property NopCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `NopCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `NopCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `NopCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `NopCommand.get_insn_size` + +```python +get_insn_size(addr: int) → int +``` + + + + + +--- + + + +### method `NopCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `NopCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `NopCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `NopCommand.nop_bytes` + +```python +nop_bytes(loc: int, num_bytes: int) → None +``` + + + + + +--- + + + +### method `NopCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `NopCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `NopCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PCustomCommand` +Dump user defined structure. This command attempts to reproduce WinDBG awesome `dt` command for GDB and allows to apply structures (from symbols or custom) directly to an address. Custom structures can be defined in pure Python using ctypes, and should be stored in a specific directory, whose path must be stored in the `pcustom.struct_path` configuration setting. + + + +### method `PCustomCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PCustomCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PCustomCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PCustomCommand.apply_structure_to_address` + +```python +apply_structure_to_address( + mod_name: str, + struct_name: str, + addr: int, + depth: int = 0 +) → None +``` + + + + + +--- + + + +### method `PCustomCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `PCustomCommand.deserialize` + +```python +deserialize(struct: _ctypes.Structure, data: bytes) → None +``` + + + + + +--- + + + +### method `PCustomCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `PCustomCommand.enumerate_structure_files` + +```python +enumerate_structure_files() → List[str] +``` + +Return a list of all the files in the pcustom directory + +--- + + + +### method `PCustomCommand.enumerate_structures` + +```python +enumerate_structures() → Dict[str, Set[str]] +``` + +Return a hash of all the structures, with the key set the to filepath + +--- + + + +### method `PCustomCommand.enumerate_structures_from_module` + +```python +enumerate_structures_from_module(module: module) → Set[str] +``` + + + + + +--- + + + +### method `PCustomCommand.get_ctypes_value` + +```python +get_ctypes_value(struct, item, value) → str +``` + + + + + +--- + + + +### method `PCustomCommand.get_modulename_structname_from_arg` + +```python +get_modulename_structname_from_arg(arg: str) → Tuple[str, str] +``` + + + + + +--- + + + +### method `PCustomCommand.get_pcustom_absolute_root_path` + +```python +get_pcustom_absolute_root_path() → Union[str, bytes] +``` + + + + + +--- + + + +### method `PCustomCommand.get_pcustom_filepath_for_structure` + +```python +get_pcustom_filepath_for_structure(structure_name: str) → str +``` + + + + + +--- + + + +### method `PCustomCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PCustomCommand.get_structure_class` + +```python +get_structure_class( + modname: str, + classname: str +) → Tuple[Type, _ctypes.Structure] +``` + +Returns a tuple of (class, instance) if modname!classname exists + +--- + + + +### method `PCustomCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PCustomCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PCustomCommand.is_valid_struct` + +```python +is_valid_struct(structure_name: str) → bool +``` + + + + + +--- + + + +### method `PCustomCommand.load_module` + +```python +load_module(file_path: str) → module +``` + +Load a custom module, and return it + +--- + + + +### method `PCustomCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PCustomCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PCustomCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PCustomEditCommand` +PCustom: edit the content of a given structure + + + +### method `PCustomEditCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PCustomEditCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PCustomEditCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PCustomEditCommand.apply_structure_to_address` + +```python +apply_structure_to_address( + mod_name: str, + struct_name: str, + addr: int, + depth: int = 0 +) → None +``` + + + + + +--- + + + +### method `PCustomEditCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `PCustomEditCommand.deserialize` + +```python +deserialize(struct: _ctypes.Structure, data: bytes) → None +``` + + + + + +--- + + + +### method `PCustomEditCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `PCustomEditCommand.enumerate_structure_files` + +```python +enumerate_structure_files() → List[str] +``` + +Return a list of all the files in the pcustom directory + +--- + + + +### method `PCustomEditCommand.enumerate_structures` + +```python +enumerate_structures() → Dict[str, Set[str]] +``` + +Return a hash of all the structures, with the key set the to filepath + +--- + + + +### method `PCustomEditCommand.enumerate_structures_from_module` + +```python +enumerate_structures_from_module(module: module) → Set[str] +``` + + + + + +--- + + + +### method `PCustomEditCommand.get_ctypes_value` + +```python +get_ctypes_value(struct, item, value) → str +``` + + + + + +--- + + + +### method `PCustomEditCommand.get_modulename_structname_from_arg` + +```python +get_modulename_structname_from_arg(arg: str) → Tuple[str, str] +``` + + + + + +--- + + + +### method `PCustomEditCommand.get_pcustom_absolute_root_path` + +```python +get_pcustom_absolute_root_path() → Union[str, bytes] +``` + + + + + +--- + + + +### method `PCustomEditCommand.get_pcustom_filepath_for_structure` + +```python +get_pcustom_filepath_for_structure(structure_name: str) → str +``` + + + + + +--- + + + +### method `PCustomEditCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PCustomEditCommand.get_structure_class` + +```python +get_structure_class( + modname: str, + classname: str +) → Tuple[Type, _ctypes.Structure] +``` + +Returns a tuple of (class, instance) if modname!classname exists + +--- + + + +### method `PCustomEditCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PCustomEditCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PCustomEditCommand.is_valid_struct` + +```python +is_valid_struct(structure_name: str) → bool +``` + + + + + +--- + + + +### method `PCustomEditCommand.load_module` + +```python +load_module(file_path: str) → module +``` + +Load a custom module, and return it + +--- + + + +### method `PCustomEditCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PCustomEditCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PCustomEditCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PCustomListCommand` +PCustom: list available structures + + + +### method `PCustomListCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PCustomListCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PCustomListCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PCustomListCommand.apply_structure_to_address` + +```python +apply_structure_to_address( + mod_name: str, + struct_name: str, + addr: int, + depth: int = 0 +) → None +``` + + + + + +--- + + + +### method `PCustomListCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `PCustomListCommand.deserialize` + +```python +deserialize(struct: _ctypes.Structure, data: bytes) → None +``` + + + + + +--- + + + +### method `PCustomListCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `PCustomListCommand.enumerate_structure_files` + +```python +enumerate_structure_files() → List[str] +``` + +Return a list of all the files in the pcustom directory + +--- + + + +### method `PCustomListCommand.enumerate_structures` + +```python +enumerate_structures() → Dict[str, Set[str]] +``` + +Return a hash of all the structures, with the key set the to filepath + +--- + + + +### method `PCustomListCommand.enumerate_structures_from_module` + +```python +enumerate_structures_from_module(module: module) → Set[str] +``` + + + + + +--- + + + +### method `PCustomListCommand.get_ctypes_value` + +```python +get_ctypes_value(struct, item, value) → str +``` + + + + + +--- + + + +### method `PCustomListCommand.get_modulename_structname_from_arg` + +```python +get_modulename_structname_from_arg(arg: str) → Tuple[str, str] +``` + + + + + +--- + + + +### method `PCustomListCommand.get_pcustom_absolute_root_path` + +```python +get_pcustom_absolute_root_path() → Union[str, bytes] +``` + + + + + +--- + + + +### method `PCustomListCommand.get_pcustom_filepath_for_structure` + +```python +get_pcustom_filepath_for_structure(structure_name: str) → str +``` + + + + + +--- + + + +### method `PCustomListCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PCustomListCommand.get_structure_class` + +```python +get_structure_class( + modname: str, + classname: str +) → Tuple[Type, _ctypes.Structure] +``` + +Returns a tuple of (class, instance) if modname!classname exists + +--- + + + +### method `PCustomListCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PCustomListCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PCustomListCommand.is_valid_struct` + +```python +is_valid_struct(structure_name: str) → bool +``` + + + + + +--- + + + +### method `PCustomListCommand.load_module` + +```python +load_module(file_path: str) → module +``` + +Load a custom module, and return it + +--- + + + +### method `PCustomListCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PCustomListCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PCustomListCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PCustomShowCommand` +PCustom: show the content of a given structure + + + +### method `PCustomShowCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PCustomShowCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PCustomShowCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PCustomShowCommand.apply_structure_to_address` + +```python +apply_structure_to_address( + mod_name: str, + struct_name: str, + addr: int, + depth: int = 0 +) → None +``` + + + + + +--- + + + +### method `PCustomShowCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `PCustomShowCommand.deserialize` + +```python +deserialize(struct: _ctypes.Structure, data: bytes) → None +``` + + + + + +--- + + + +### method `PCustomShowCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `PCustomShowCommand.enumerate_structure_files` + +```python +enumerate_structure_files() → List[str] +``` + +Return a list of all the files in the pcustom directory + +--- + + + +### method `PCustomShowCommand.enumerate_structures` + +```python +enumerate_structures() → Dict[str, Set[str]] +``` + +Return a hash of all the structures, with the key set the to filepath + +--- + + + +### method `PCustomShowCommand.enumerate_structures_from_module` + +```python +enumerate_structures_from_module(module: module) → Set[str] +``` + + + + + +--- + + + +### method `PCustomShowCommand.get_ctypes_value` + +```python +get_ctypes_value(struct, item, value) → str +``` + + + + + +--- + + + +### method `PCustomShowCommand.get_modulename_structname_from_arg` + +```python +get_modulename_structname_from_arg(arg: str) → Tuple[str, str] +``` + + + + + +--- + + + +### method `PCustomShowCommand.get_pcustom_absolute_root_path` + +```python +get_pcustom_absolute_root_path() → Union[str, bytes] +``` + + + + + +--- + + + +### method `PCustomShowCommand.get_pcustom_filepath_for_structure` + +```python +get_pcustom_filepath_for_structure(structure_name: str) → str +``` + + + + + +--- + + + +### method `PCustomShowCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PCustomShowCommand.get_structure_class` + +```python +get_structure_class( + modname: str, + classname: str +) → Tuple[Type, _ctypes.Structure] +``` + +Returns a tuple of (class, instance) if modname!classname exists + +--- + + + +### method `PCustomShowCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PCustomShowCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PCustomShowCommand.is_valid_struct` + +```python +is_valid_struct(structure_name: str) → bool +``` + + + + + +--- + + + +### method `PCustomShowCommand.load_module` + +```python +load_module(file_path: str) → module +``` + +Load a custom module, and return it + +--- + + + +### method `PCustomShowCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PCustomShowCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PCustomShowCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchByteCommand` +Write specified WORD to the specified address. + + + +### method `PatchByteCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatchByteCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PatchByteCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PatchByteCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `PatchByteCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `PatchByteCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PatchByteCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PatchByteCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PatchByteCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PatchByteCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PatchByteCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchCommand` +Write specified values to the specified address. + + + +### method `PatchCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PatchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PatchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `PatchCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `PatchCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PatchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PatchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PatchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PatchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PatchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchDwordCommand` +Write specified DWORD to the specified address. + + + +### method `PatchDwordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatchDwordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PatchDwordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PatchDwordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `PatchDwordCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `PatchDwordCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PatchDwordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PatchDwordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PatchDwordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PatchDwordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PatchDwordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchQwordCommand` +Write specified QWORD to the specified address. + + + +### method `PatchQwordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatchQwordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PatchQwordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PatchQwordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `PatchQwordCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `PatchQwordCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PatchQwordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PatchQwordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PatchQwordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PatchQwordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PatchQwordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchStringCommand` +Write specified string to the specified memory location pointed by ADDRESS. + + + +### method `PatchStringCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property PatchStringCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PatchStringCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PatchStringCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `PatchStringCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `PatchStringCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PatchStringCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PatchStringCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PatchStringCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PatchStringCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PatchStringCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatchWordCommand` +Write specified WORD to the specified address. + + + +### method `PatchWordCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatchWordCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PatchWordCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PatchWordCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `PatchWordCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `PatchWordCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PatchWordCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PatchWordCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PatchWordCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PatchWordCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PatchWordCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatternCommand` +Generate or Search a De Bruijn Sequence of unique substrings of length N and a total length of LENGTH. The default value of N is set to match the currently loaded architecture. + + + +### method `PatternCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PatternCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PatternCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PatternCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `PatternCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `PatternCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PatternCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PatternCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PatternCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PatternCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PatternCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatternCreateCommand` +Generate a De Bruijn Sequence of unique substrings of length N and a total length of LENGTH. The default value of N is set to match the currently loaded architecture. + + + +### method `PatternCreateCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property PatternCreateCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PatternCreateCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PatternCreateCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `PatternCreateCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `PatternCreateCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PatternCreateCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PatternCreateCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PatternCreateCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PatternCreateCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PatternCreateCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PatternSearchCommand` +Search a De Bruijn Sequence of unique substrings of length N and a maximum total length of MAX_LENGTH. The default value of N is set to match the currently loaded architecture. The PATTERN argument can be a GDB symbol (such as a register name), a string or a hexadecimal value + + + +### method `PatternSearchCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property PatternSearchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PatternSearchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PatternSearchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `PatternSearchCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `PatternSearchCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PatternSearchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PatternSearchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PatternSearchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PatternSearchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PatternSearchCommand.search` + +```python +search(pattern: str, size: int, period: int) → None +``` + + + + + +--- + + + +### method `PatternSearchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Permission` +GEF representation of Linux permission. + + + +### method `Permission.__init__` + +```python +__init__(**kwargs) → None +``` + + + + + + + + +--- + + + +### method `Permission.from_info_sections` + +```python +from_info_sections(*args: List[str]) +``` + + + + + +--- + + + +### method `Permission.from_process_maps` + +```python +from_process_maps(perm_str: str) +``` + + + + + + +--- + +## class `Phdr` + + + + + + +### method `Phdr.__init__` + +```python +__init__(elf: __main__.Elf, off: int) → None +``` + + + + + + + + + +--- + +## class `PieAttachCommand` +Do attach with PIE breakpoint support. + + + +### method `PieAttachCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property PieAttachCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PieAttachCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PieAttachCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `PieAttachCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `PieAttachCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PieAttachCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PieAttachCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PieAttachCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PieAttachCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PieAttachCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieBreakpointCommand` +Set a PIE breakpoint at an offset from the target binaries base address. + + + +### method `PieBreakpointCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property PieBreakpointCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PieBreakpointCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PieBreakpointCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `PieBreakpointCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `PieBreakpointCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PieBreakpointCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PieBreakpointCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PieBreakpointCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PieBreakpointCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PieBreakpointCommand.set_pie_breakpoint` + +```python +set_pie_breakpoint(set_func: Callable[[int], str], addr: int) → None +``` + + + + + +--- + + + +### method `PieBreakpointCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieCommand` +PIE breakpoint support. + + + +### method `PieCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PieCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PieCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PieCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `PieCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `PieCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PieCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PieCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PieCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PieCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PieCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieDeleteCommand` +Delete a PIE breakpoint. + + + +### method `PieDeleteCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property PieDeleteCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PieDeleteCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PieDeleteCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `PieDeleteCommand.delete_bp` + +```python +delete_bp(breakpoints: List) → None +``` + + + + + +--- + + + +### function `PieDeleteCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `PieDeleteCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PieDeleteCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PieDeleteCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PieDeleteCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PieDeleteCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PieDeleteCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieInfoCommand` +Display breakpoint info. + + + +### method `PieInfoCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property PieInfoCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PieInfoCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PieInfoCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `PieInfoCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `PieInfoCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PieInfoCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PieInfoCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PieInfoCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PieInfoCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PieInfoCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieRemoteCommand` +Attach to a remote connection with PIE breakpoint support. + + + +### method `PieRemoteCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property PieRemoteCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PieRemoteCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PieRemoteCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `PieRemoteCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `PieRemoteCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PieRemoteCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PieRemoteCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PieRemoteCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PieRemoteCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PieRemoteCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieRunCommand` +Run process with PIE breakpoint support. + + + +### method `PieRunCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property PieRunCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PieRunCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PieRunCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `PieRunCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `PieRunCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PieRunCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PieRunCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PieRunCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PieRunCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PieRunCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `PieVirtualBreakpoint` +PIE virtual breakpoint (not real breakpoint). + + + +### method `PieVirtualBreakpoint.__init__` + +```python +__init__(set_func: Callable[[int], str], vbp_num: int, addr: int) → None +``` + + + + + + + + +--- + + + +### method `PieVirtualBreakpoint.destroy` + +```python +destroy() → None +``` + + + + + +--- + + + +### method `PieVirtualBreakpoint.instantiate` + +```python +instantiate(base: int) → None +``` + + + + + + +--- + +## class `PowerPC` + + + + + +--- + +#### property PowerPC.endianness + + + + + +--- + +#### property PowerPC.fp + + + + + +--- + +#### property PowerPC.pc + + + + + +--- + +#### property PowerPC.ptrsize + + + + + +--- + +#### property PowerPC.registers + + + + + +--- + +#### property PowerPC.sp + + + + + + + +--- + + + +### method `PowerPC.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +### method `PowerPC.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `PowerPC.get_ra` + +```python +get_ra(insn, frame) → Union[int, NoneType] +``` + + + + + +--- + + + +### method `PowerPC.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `PowerPC.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `PowerPC.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `PowerPC.is_ret` + +```python +is_ret(insn) → bool +``` + + + + + +--- + + + +### classmethod `PowerPC.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm) → str +``` + + + + + +--- + + + +### method `PowerPC.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## class `PowerPC64` + + + + + +--- + +#### property PowerPC64.endianness + + + + + +--- + +#### property PowerPC64.fp + + + + + +--- + +#### property PowerPC64.pc + + + + + +--- + +#### property PowerPC64.ptrsize + + + + + +--- + +#### property PowerPC64.registers + + + + + +--- + +#### property PowerPC64.sp + + + + + + + +--- + + + +### method `PowerPC64.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +### method `PowerPC64.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `PowerPC64.get_ra` + +```python +get_ra(insn, frame) → Union[int, NoneType] +``` + + + + + +--- + + + +### method `PowerPC64.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `PowerPC64.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `PowerPC64.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `PowerPC64.is_ret` + +```python +is_ret(insn) → bool +``` + + + + + +--- + + + +### classmethod `PowerPC64.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm) → str +``` + + + + + +--- + + + +### method `PowerPC64.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## class `PrintFormatCommand` +Print bytes format in high level languages. + + + +### method `PrintFormatCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property PrintFormatCommand.format_matrix + + + + + +--- + +#### property PrintFormatCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `PrintFormatCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `PrintFormatCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `PrintFormatCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `PrintFormatCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `PrintFormatCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `PrintFormatCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `PrintFormatCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `PrintFormatCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `PrintFormatCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ProcessListingCommand` +List and filter process. If a PATTERN is given as argument, results shown will be grepped by this pattern. + + + +### method `ProcessListingCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ProcessListingCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ProcessListingCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ProcessListingCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `ProcessListingCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `ProcessListingCommand.get_processes` + +```python +get_processes() → Generator[Dict[str, str], Any, NoneType] +``` + + + + + +--- + + + +### method `ProcessListingCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ProcessListingCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ProcessListingCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ProcessListingCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ProcessListingCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ProcessListingCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ProcessStatusCommand` +Extends the info given by GDB `info proc`, by giving an exhaustive description of the process status (file descriptors, ancestor, descendants, etc.). + + + +### method `ProcessStatusCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ProcessStatusCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ProcessStatusCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ProcessStatusCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `ProcessStatusCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `ProcessStatusCommand.get_children_pids` + +```python +get_children_pids(pid: int) → List[int] +``` + + + + + +--- + + + +### method `ProcessStatusCommand.get_cmdline_of` + +```python +get_cmdline_of(pid: int) → str +``` + + + + + +--- + + + +### method `ProcessStatusCommand.get_process_path_of` + +```python +get_process_path_of(pid: int) → str +``` + + + + + +--- + + + +### method `ProcessStatusCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ProcessStatusCommand.get_state_of` + +```python +get_state_of(pid: int) → Dict[str, str] +``` + + + + + +--- + + + +### method `ProcessStatusCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ProcessStatusCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ProcessStatusCommand.list_sockets` + +```python +list_sockets(pid: int) → List[int] +``` + + + + + +--- + + + +### method `ProcessStatusCommand.parse_ip_port` + +```python +parse_ip_port(addr: str) → Tuple[str, int] +``` + + + + + +--- + + + +### method `ProcessStatusCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ProcessStatusCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ProcessStatusCommand.show_ancestor` + +```python +show_ancestor() → None +``` + + + + + +--- + + + +### method `ProcessStatusCommand.show_connections` + +```python +show_connections() → None +``` + + + + + +--- + + + +### method `ProcessStatusCommand.show_descendants` + +```python +show_descendants() → None +``` + + + + + +--- + + + +### method `ProcessStatusCommand.show_fds` + +```python +show_fds() → None +``` + + + + + +--- + + + +### method `ProcessStatusCommand.show_info_proc` + +```python +show_info_proc() → None +``` + + + + + +--- + + + +### method `ProcessStatusCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `RISCV` + + + + + +--- + +#### property RISCV.endianness + + + + + +--- + +#### property RISCV.fp + + + + + +--- + +#### property RISCV.instruction_length + + + + + +--- + +#### property RISCV.pc + + + + + +--- + +#### property RISCV.ptrsize + + + + + +--- + +#### property RISCV.registers + + + + + +--- + +#### property RISCV.sp + + + + + + + +--- + + + +### method `RISCV.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `RISCV.get_ra` + +```python +get_ra(insn, frame) → int +``` + + + + + +--- + + + +### method `RISCV.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `RISCV.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `RISCV.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `RISCV.is_ret` + +```python +is_ret(insn) → bool +``` + + + + + +--- + + + +### classmethod `RISCV.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm) +``` + + + + + +--- + + + +### method `RISCV.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## class `RedirectOutputContext` + + + + + + +### method `RedirectOutputContext.__init__` + +```python +__init__(to='/dev/null') → None +``` + + + + + + + + + +--- + +## class `RemoteCommand` +gef wrapper for the `target remote` command. This command will automatically download the target binary in the local temporary directory (defaut /tmp) and then source it. Additionally, it will fetch all the /proc/PID/maps and loads all its information. + + + +### method `RemoteCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property RemoteCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `RemoteCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `RemoteCommand.connect_target` + +```python +connect_target(target: str, is_extended_remote: bool) → bool +``` + +Connect to remote target and get symbols. To prevent `gef` from requesting information not fetched just yet, we disable the context disable when connection was successful. + +--- + + + +### method `RemoteCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `RemoteCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `RemoteCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `RemoteCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `RemoteCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `RemoteCommand.load_from_remote_proc` + +```python +load_from_remote_proc(pid: int, info: str) → Union[str, NoneType] +``` + +Download one item from /proc/pid. + +--- + + + +### method `RemoteCommand.new_objfile_handler` + +```python +new_objfile_handler(event) → None +``` + +Hook that handles new_objfile events, will update remote environment accordingly. + +--- + + + +### method `RemoteCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `RemoteCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `RemoteCommand.prepare_qemu_stub` + +```python +prepare_qemu_stub(target: str) → None +``` + + + + + +--- + + + +### method `RemoteCommand.refresh_shared_library_path` + +```python +refresh_shared_library_path() → None +``` + + + + + +--- + + + +### method `RemoteCommand.setup_remote_environment` + +```python +setup_remote_environment(pid: int, update_solib: bool = False) → None +``` + +Clone the remote environment locally in the temporary directory. The command will duplicate the entries in the /proc/ locally and then source those information into the current gdb context to allow gef to use all the extra commands as it was local debugging. + +--- + + + +### method `RemoteCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ResetCacheCommand` +Reset cache of all stored data. This command is here for debugging and test purposes, GEF handles properly the cache reset under "normal" scenario. + + + +### method `ResetCacheCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property ResetCacheCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ResetCacheCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ResetCacheCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `ResetCacheCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `ResetCacheCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ResetCacheCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ResetCacheCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ResetCacheCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ResetCacheCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ResetCacheCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `RopperCommand` +Ropper (http://scoding.de/ropper) plugin. + + + +### method `RopperCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property RopperCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `RopperCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `RopperCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `RopperCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `RopperCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `RopperCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `RopperCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `RopperCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `RopperCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `RopperCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `SPARC` +Refs: +- http://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 + + + + + + + +--- + + + +### method `SPARC.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +### method `SPARC.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `SPARC.get_ra` + +```python +get_ra(insn, frame) → Union[int, NoneType] +``` + + + + + +--- + + + +### method `SPARC.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `SPARC.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `SPARC.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `SPARC.is_ret` + +```python +is_ret(insn) → bool +``` + + + + + +--- + + + +### classmethod `SPARC.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm) → str +``` + + + + + +--- + + + +### method `SPARC.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## 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 + + + + + + + +--- + + + +### method `SPARC64.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +### method `SPARC64.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `SPARC64.get_ra` + +```python +get_ra(insn, frame) → Union[int, NoneType] +``` + + + + + +--- + + + +### method `SPARC64.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `SPARC64.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `SPARC64.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `SPARC64.is_ret` + +```python +is_ret(insn) → bool +``` + + + + + +--- + + + +### classmethod `SPARC64.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm) → str +``` + + + + + +--- + + + +### method `SPARC64.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## class `ScanSectionCommand` +Search for addresses that are located in a memory mapping (haystack) that belonging to another (needle). + + + +### method `ScanSectionCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property ScanSectionCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ScanSectionCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ScanSectionCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `ScanSectionCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `ScanSectionCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ScanSectionCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ScanSectionCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ScanSectionCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ScanSectionCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ScanSectionCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `SearchPatternCommand` +SearchPatternCommand: search a pattern in memory. If given an hex value (starting with 0x) the command will also try to look for upwards cross-references to this address. + + + +### method `SearchPatternCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property SearchPatternCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `SearchPatternCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `SearchPatternCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `SearchPatternCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `SearchPatternCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `SearchPatternCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `SearchPatternCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `SearchPatternCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `SearchPatternCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `SearchPatternCommand.print_loc` + +```python +print_loc(loc) → None +``` + + + + + +--- + + + +### method `SearchPatternCommand.print_section` + +```python +print_section(section) → None +``` + + + + + +--- + + + +### method `SearchPatternCommand.search_pattern` + +```python +search_pattern(pattern: str, section_name: str) → None +``` + +Search a pattern within the whole userland memory. + +--- + + + +### method `SearchPatternCommand.search_pattern_by_address` + +```python +search_pattern_by_address( + pattern: str, + start_address: int, + end_address: int +) → List[Tuple[int, int, Union[str, NoneType]]] +``` + +Search a pattern within a range defined by arguments. + +--- + + + +### method `SearchPatternCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Section` +GEF representation of process memory sections. + + + +### method `Section.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property Section.realpath + + + + + +--- + +#### property Section.size + + + + + + + +--- + + + +### method `Section.is_executable` + +```python +is_executable() → bool +``` + + + + + +--- + + + +### method `Section.is_readable` + +```python +is_readable() → bool +``` + + + + + +--- + + + +### method `Section.is_writable` + +```python +is_writable() → bool +``` + + + + + + +--- + +## class `SectionBaseFunction` +Return the matching file's base address plus an optional offset. Defaults to current file. Note that quotes need to be escaped + + + +### method `SectionBaseFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +### method `SectionBaseFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +### method `SectionBaseFunction.do_invoke` + +```python +do_invoke(args: List) → int +``` + + + + + +--- + + + +### method `SectionBaseFunction.invoke` + +```python +invoke(*args) → int +``` + + + + + + +--- + +## class `Shdr` + + + + + + +### method `Shdr.__init__` + +```python +__init__(elf, off) → None +``` + + + + + + + + + +--- + +## class `ShellcodeCommand` +ShellcodeCommand uses @JonathanSalwan simple-yet-awesome shellcode API to download shellcodes. + + + +### method `ShellcodeCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property ShellcodeCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ShellcodeCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ShellcodeCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `ShellcodeCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `ShellcodeCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ShellcodeCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ShellcodeCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ShellcodeCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ShellcodeCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ShellcodeCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ShellcodeGetCommand` +Download shellcode from shell-storm's shellcode database. + + + +### method `ShellcodeGetCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property ShellcodeGetCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ShellcodeGetCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ShellcodeGetCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `ShellcodeGetCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `ShellcodeGetCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ShellcodeGetCommand.get_shellcode` + +```python +get_shellcode(sid: int) → None +``` + + + + + +--- + + + +### method `ShellcodeGetCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ShellcodeGetCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ShellcodeGetCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ShellcodeGetCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ShellcodeGetCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `ShellcodeSearchCommand` +Search pattern in shell-storm's shellcode database. + + + +### method `ShellcodeSearchCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property ShellcodeSearchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `ShellcodeSearchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `ShellcodeSearchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `ShellcodeSearchCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `ShellcodeSearchCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `ShellcodeSearchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `ShellcodeSearchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `ShellcodeSearchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `ShellcodeSearchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `ShellcodeSearchCommand.search_shellcode` + +```python +search_shellcode(search_options: List) → None +``` + + + + + +--- + + + +### method `ShellcodeSearchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `SmartEvalCommand` +SmartEval: Smart eval (vague approach to mimic WinDBG `?`). + + + +### method `SmartEvalCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property SmartEvalCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `SmartEvalCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `SmartEvalCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `SmartEvalCommand.distance` + +```python +distance(args: Tuple[str, str]) +``` + + + + + +--- + + + +### method `SmartEvalCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `SmartEvalCommand.evaluate` + +```python +evaluate(expr: List) → None +``` + + + + + +--- + + + +### method `SmartEvalCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `SmartEvalCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `SmartEvalCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `SmartEvalCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `SmartEvalCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `SmartEvalCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `SolveKernelSymbolCommand` +Solve kernel symbols from kallsyms table. + + + +### method `SolveKernelSymbolCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property SolveKernelSymbolCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `SolveKernelSymbolCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `SolveKernelSymbolCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `SolveKernelSymbolCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `SolveKernelSymbolCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `SolveKernelSymbolCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `SolveKernelSymbolCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `SolveKernelSymbolCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `SolveKernelSymbolCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `SolveKernelSymbolCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `StackOffsetFunction` +Return the current stack base address plus an optional offset. + + + +### method `StackOffsetFunction.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +### method `StackOffsetFunction.arg_to_long` + +```python +arg_to_long(args: List, index: int, default: int = 0) → int +``` + + + + + +--- + + + +### method `StackOffsetFunction.do_invoke` + +```python +do_invoke(args: List) → int +``` + + + + + +--- + + + +### method `StackOffsetFunction.invoke` + +```python +invoke(*args) → int +``` + + + + + + +--- + +## class `StubBreakpoint` +Create a breakpoint to permanently disable a call (fork/alarm/signal/etc.). + + + +### method `StubBreakpoint.__init__` + +```python +__init__(func: str, retval: Optional[int]) → None +``` + + + + + + + + +--- + + + +### method `StubBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `StubCommand` +Stub out the specified function. This function is useful when needing to skip one function to be called and disrupt your runtime flow (ex. fork). + + + +### method `StubCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property StubCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `StubCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `StubCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `StubCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `StubCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `StubCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `StubCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `StubCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `StubCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `StubCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `SyscallArgsCommand` +Gets the syscall name and arguments based on the register values in the current state. + + + +### method `SyscallArgsCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property SyscallArgsCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `SyscallArgsCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `SyscallArgsCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `SyscallArgsCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `SyscallArgsCommand.get_filepath` + +```python +get_filepath(x: str) → Union[str, NoneType] +``` + + + + + +--- + + + +### method `SyscallArgsCommand.get_module` + +```python +get_module(modname: str) +``` + + + + + +--- + + + +### method `SyscallArgsCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `SyscallArgsCommand.get_settings_path` + +```python +get_settings_path() → Union[pathlib.Path, NoneType] +``` + + + + + +--- + + + +### method `SyscallArgsCommand.get_syscall_table` + +```python +get_syscall_table(modname: str) +``` + + + + + +--- + + + +### method `SyscallArgsCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `SyscallArgsCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `SyscallArgsCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `SyscallArgsCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `SyscallArgsCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `TraceFreeBreakpoint` +Track calls to free() and attempts to detect inconsistencies. + + + +### method `TraceFreeBreakpoint.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +### method `TraceFreeBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceFreeRetBreakpoint` +Internal temporary breakpoint to track free()d values. + + + +### method `TraceFreeRetBreakpoint.__init__` + +```python +__init__(addr: int) → None +``` + + + + + + + + +--- + + + +### method `TraceFreeRetBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceMallocBreakpoint` +Track allocations done with malloc() or calloc(). + + + +### method `TraceMallocBreakpoint.__init__` + +```python +__init__(name: str) → None +``` + + + + + + + + +--- + + + +### method `TraceMallocBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceMallocRetBreakpoint` +Internal temporary breakpoint to retrieve the return value of malloc(). + + + +### method `TraceMallocRetBreakpoint.__init__` + +```python +__init__(size: int, name: str) → None +``` + + + + + + + + +--- + + + +### method `TraceMallocRetBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceReallocBreakpoint` +Track re-allocations done with realloc(). + + + +### method `TraceReallocBreakpoint.__init__` + +```python +__init__() → None +``` + + + + + + + + +--- + + + +### method `TraceReallocBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceReallocRetBreakpoint` +Internal temporary breakpoint to retrieve the return value of realloc(). + + + +### method `TraceReallocRetBreakpoint.__init__` + +```python +__init__(ptr: int, size: int) → None +``` + + + + + + + + +--- + + + +### method `TraceReallocRetBreakpoint.stop` + +```python +stop() → bool +``` + + + + + + +--- + +## class `TraceRunCommand` +Create a runtime trace of all instructions executed from $pc to LOCATION specified. The trace is stored in a text file that can be next imported in IDA Pro to visualize the runtime path. + + + +### method `TraceRunCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property TraceRunCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `TraceRunCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `TraceRunCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `TraceRunCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `TraceRunCommand.get_frames_size` + +```python +get_frames_size() → int +``` + + + + + +--- + + + +### method `TraceRunCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `TraceRunCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `TraceRunCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `TraceRunCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `TraceRunCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `TraceRunCommand.start_tracing` + +```python +start_tracing(loc_start: int, loc_end: int, depth: int) → None +``` + + + + + +--- + + + +### method `TraceRunCommand.trace` + +```python +trace(loc_start: int, loc_end: int, depth: int) → None +``` + + + + + +--- + + + +### method `TraceRunCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `UafWatchpoint` +Custom watchpoints set TraceFreeBreakpoint() to monitor free()d pointers being used. + + + +### method `UafWatchpoint.__init__` + +```python +__init__(addr: int) → None +``` + + + + + + + + +--- + + + +### method `UafWatchpoint.stop` + +```python +stop() → bool +``` + +If this method is triggered, we likely have a UaF. Break the execution and report it. + + +--- + +## class `UnicornEmulateCommand` +Use Unicorn-Engine to emulate the behavior of the binary, without affecting the GDB runtime. By default the command will emulate only the next instruction, but location and number of instruction can be changed via arguments to the command line. By default, it will emulate the next instruction from current PC. + + + +### method `UnicornEmulateCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property UnicornEmulateCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `UnicornEmulateCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `UnicornEmulateCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### function `UnicornEmulateCommand.wrapper` + +```python +wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +``` + + + + + +--- + + + +### method `UnicornEmulateCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `UnicornEmulateCommand.get_unicorn_end_addr` + +```python +get_unicorn_end_addr(start_addr: int, nb: int) → int +``` + + + + + +--- + + + +### method `UnicornEmulateCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `UnicornEmulateCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `UnicornEmulateCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `UnicornEmulateCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `UnicornEmulateCommand.run_unicorn` + +```python +run_unicorn(start_insn_addr: int, end_insn_addr: int, *args, **kwargs) → None +``` + + + + + +--- + + + +### method `UnicornEmulateCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## 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. + + + +### method `VMMapCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property VMMapCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `VMMapCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `VMMapCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `VMMapCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `VMMapCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `VMMapCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `VMMapCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `VMMapCommand.is_integer` + +```python +is_integer(n: str) → bool +``` + + + + + +--- + + + +### method `VMMapCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `VMMapCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `VMMapCommand.print_entry` + +```python +print_entry(entry: __main__.Section) → None +``` + + + + + +--- + + + +### method `VMMapCommand.show_legend` + +```python +show_legend() → None +``` + + + + + +--- + + + +### method `VMMapCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `VersionCommand` +Display GEF version info. + + + +### method `VersionCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property VersionCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `VersionCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `VersionCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `VersionCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `VersionCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `VersionCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `VersionCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `VersionCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `VersionCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `VersionCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `X86` + + + + + +--- + +#### property X86.fp + + + + + +--- + +#### property X86.pc + + + + + +--- + +#### property X86.registers + + + + + +--- + +#### property X86.sp + + + + + + + +--- + + + +### method `X86.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +### method `X86.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + + + + + +--- + + + +### method `X86.get_ra` + +```python +get_ra(insn, frame) → Union[int, NoneType] +``` + + + + + +--- + + + +### method `X86.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `X86.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `X86.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `X86.is_ret` + +```python +is_ret(insn) → bool +``` + + + + + +--- + + + +### classmethod `X86.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm) → str +``` + + + + + +--- + + + +### method `X86.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## class `X86_64` + + + + + +--- + +#### property X86_64.fp + + + + + +--- + +#### property X86_64.pc + + + + + +--- + +#### property X86_64.registers + + + + + +--- + +#### property X86_64.sp + + + + + + + +--- + + + +### method `X86_64.flag_register_to_human` + +```python +flag_register_to_human(val: Optional[int] = None) → str +``` + + + + + +--- + + + +### method `X86_64.get_ith_parameter` + +```python +get_ith_parameter( + i: int, + in_func: bool = True +) → Tuple[str, Union[int, NoneType]] +``` + +Retrieves the correct parameter used for the current function call. + +--- + + + +### method `X86_64.get_ra` + +```python +get_ra(insn, frame) → Union[int, NoneType] +``` + + + + + +--- + + + +### method `X86_64.is_branch_taken` + +```python +is_branch_taken(insn) → Tuple[bool, str] +``` + + + + + +--- + + + +### method `X86_64.is_call` + +```python +is_call(insn) → bool +``` + + + + + +--- + + + +### method `X86_64.is_conditional_branch` + +```python +is_conditional_branch(insn) → bool +``` + + + + + +--- + + + +### method `X86_64.is_ret` + +```python +is_ret(insn) → bool +``` + + + + + +--- + + + +### classmethod `X86_64.mprotect_asm` + +```python +mprotect_asm(addr: int, size: int, perm) → str +``` + + + + + +--- + + + +### method `X86_64.register` + +```python +register(name: str) → Union[int, NoneType] +``` + + + + + + +--- + +## class `XAddressInfoCommand` +Retrieve and display runtime information for the location(s) given as parameter. + + + +### method `XAddressInfoCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property XAddressInfoCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `XAddressInfoCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `XAddressInfoCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `XAddressInfoCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `XAddressInfoCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `XAddressInfoCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `XAddressInfoCommand.infos` + +```python +infos(address: int) → None +``` + + + + + +--- + + + +### method `XAddressInfoCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `XAddressInfoCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `XAddressInfoCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `XAddressInfoCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `XFilesCommand` +Shows all libraries (and sections) loaded by binary. This command extends the GDB command `info files`, by retrieving more information from extra sources, and providing a better display. If an argument FILE is given, the output will grep information related to only that file. If an argument name is also given, the output will grep to the name within FILE. + + + +### method `XFilesCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property XFilesCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `XFilesCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `XFilesCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `XFilesCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `XFilesCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `XFilesCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `XFilesCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `XFilesCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `XFilesCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `XFilesCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `XorMemoryCommand` +XOR a block of memory. The command allows to simply display the result, or patch it runtime at runtime. + + + +### method `XorMemoryCommand.__init__` + +```python +__init__() → None +``` + + + + + + +--- + +#### property XorMemoryCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `XorMemoryCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `XorMemoryCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `XorMemoryCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `XorMemoryCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `XorMemoryCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `XorMemoryCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `XorMemoryCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `XorMemoryCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `XorMemoryCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `XorMemoryDisplayCommand` +Display a block of memory pointed by ADDRESS by xor-ing each byte with KEY. The key must be provided in hexadecimal format. + + + +### method `XorMemoryDisplayCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property XorMemoryDisplayCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `XorMemoryDisplayCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `XorMemoryDisplayCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `XorMemoryDisplayCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `XorMemoryDisplayCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `XorMemoryDisplayCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `XorMemoryDisplayCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `XorMemoryDisplayCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `XorMemoryDisplayCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `XorMemoryDisplayCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `XorMemoryPatchCommand` +Patch a block of memory pointed by ADDRESS by xor-ing each byte with KEY. The key must be provided in hexadecimal format. + + + +### method `XorMemoryPatchCommand.__init__` + +```python +__init__(*args, **kwargs) → None +``` + + + + + + +--- + +#### property XorMemoryPatchCommand.settings + +Return the list of settings for this command. + + + +--- + + + +### method `XorMemoryPatchCommand.add_setting` + +```python +add_setting( + name: str, + value: Tuple[Any, type, str], + description: str = '' +) → None +``` + + + + + +--- + + + +### method `XorMemoryPatchCommand.del_setting` + +```python +del_setting(name: str) → None +``` + + + + + +--- + + + +### method `XorMemoryPatchCommand.do_invoke` + +```python +do_invoke(argv: List) → None +``` + + + + + +--- + + + +### method `XorMemoryPatchCommand.get_setting` + +```python +get_setting(name) +``` + + + + + +--- + + + +### method `XorMemoryPatchCommand.has_setting` + +```python +has_setting(name: str) → bool +``` + + + + + +--- + + + +### method `XorMemoryPatchCommand.invoke` + +```python +invoke(args: str, from_tty: bool) → None +``` + + + + + +--- + + + +### method `XorMemoryPatchCommand.post_load` + +```python +post_load() → None +``` + + + + + +--- + + + +### method `XorMemoryPatchCommand.pre_load` + +```python +pre_load() → None +``` + + + + + +--- + + + +### method `XorMemoryPatchCommand.usage` + +```python +usage() → None +``` + + + + + + +--- + +## class `Zone` +Zone(name, zone_start, zone_end, filename) + + + + + + + +--- + +_This file was automatically generated via [lazydocs](https://github.com/ml-tooling/lazydocs)._ diff --git a/scripts/generate-api-docs.sh b/scripts/generate-api-docs.sh new file mode 100644 index 000000000..9c2812bbe --- /dev/null +++ b/scripts/generate-api-docs.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +set -e + +script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +gef_root=$(dirname "$script_dir") +output_path="${gef_root}/docs/api/" +src_base_url="https://github.com/hugsy/gef/blob/dev/" + + +check() +{ + python -c "import lazydocs" || exit 1 +} + + +clean_doc() +{ + rm -fr -- ${output_path}/*.md +} + + +generate_doc() +{ + gdb -q \ + -ex "pi from lazydocs.generation import generate_docs" \ + -ex "pi generate_docs(paths=['__main__',], output_path='${output_path}')" \ + -ex quit +} + +fixup_doc() +{ + mv ${output_path}/__main__.md ${output_path}/gef.md + sed -i 's?# module `__main__`?# module `GEF`?' ${output_path}/gef.md + sed -i 's???g' ${output_path}/gef.md + + # for item in ${output_path}/__main__.*.md; do + # mv ${item} ${item/__main__./gef.} + # done +} + +check +clean_doc +generate_doc ${api} +fixup_doc From f7979f54ea33c08daa722d2c0ad6851bfb3cc067 Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 10 Jan 2022 14:21:00 -0800 Subject: [PATCH 49/62] Markdown doc also shows if a function/class is deprecated (#776) --- docs/api/gef.md | 1618 ++++++++++++----------------------------------- gef.py | 4 + 2 files changed, 411 insertions(+), 1211 deletions(-) diff --git a/docs/api/gef.md b/docs/api/gef.md index 54acdb3a0..16bb9485b 100644 --- a/docs/api/gef.md +++ b/docs/api/gef.md @@ -189,7 +189,7 @@ Decorator to add a warning when a command is obsolete and will be removed. disable_redirect_output() → None ``` -Disable the output redirection, if any. +Disable the output redirection, if any. `disable_redirect_output` is **DEPRECATED** and will be removed in the future. Use `RedirectOutputContext()` context manager --- @@ -219,7 +219,7 @@ Download filename `remote_path` inside the mirror tree inside the gef.config["ge 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`. +Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`. `enable_redirect_output` is **DEPRECATED** and will be removed in the future. Use `RedirectOutputContext()` context manager --- @@ -232,9 +232,7 @@ Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects endian_str() → str ``` - - - +`endian_str` is **DEPRECATED** and will be removed in the future. Use `str(gef.arch.endianness)` instead --- @@ -468,9 +466,7 @@ gef_get_pie_breakpoint(num: int) gef_getpagesize() → int ``` - - - +`gef_getpagesize` is **DEPRECATED** and will be removed in the future. Use `gef.session.pagesize` --- @@ -741,9 +737,7 @@ Returns a sanitized version as string of the bytes list given in input. gef_read_canary() → Union[Tuple[int, int], NoneType] ``` - - - +`gef_read_canary` is **DEPRECATED** and will be removed in the future. Use `gef.session.canary` --- @@ -789,9 +783,7 @@ get_capstone_arch( get_filename() → str ``` - - - +`get_filename` is **DEPRECATED** and will be removed in the future. Use `gef.session.file.name` --- @@ -817,9 +809,7 @@ Attempt to get the length of the raw bytes of a function. get_gef_setting(name: str) → Any ``` - - - +`get_gef_setting` is **DEPRECATED** and will be removed in the future. Use `gef.config[key]` --- @@ -869,9 +859,7 @@ Retrieves architecture and mode from the current context. get_glibc_arena() ``` - - - +`get_glibc_arena` is **DEPRECATED** and will be removed in the future. Use `gef.heap.main_arena` --- @@ -904,7 +892,7 @@ get_keystone_arch( 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. +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 --- @@ -917,9 +905,7 @@ Try to determine the size of a pointer on this system. First, try to parse it ou get_os() → str ``` - - - +`get_os` is **DEPRECATED** and will be removed in the future. Use `gef.session.os` --- @@ -947,9 +933,7 @@ get_path_from_info_proc() get_pid() → int ``` - - - +`get_pid` is **DEPRECATED** and will be removed in the future. Use `gef.session.pid` --- @@ -962,9 +946,7 @@ get_pid() → int get_process_maps() ``` - - - +`get_process_maps` is **DEPRECATED** and will be removed in the future. Use `gef.memory.maps` --- @@ -977,9 +959,7 @@ get_process_maps() get_register(regname) ``` - - - +`get_register` is **DEPRECATED** and will be removed in the future. Use `gef.arch.register(regname)` --- @@ -1172,9 +1152,7 @@ Helper function to determine if the buffer pointed by `address` is an ASCII stri is_big_endian() → bool ``` - - - +`is_big_endian` is **DEPRECATED** and will be removed in the future. Prefer `gef.arch.endianness == Endianness.BIG_ENDIAN` --- @@ -1228,9 +1206,7 @@ is_in_x86_kernel(address: int) → bool is_little_endian() → bool ``` - - - +`is_little_endian` is **DEPRECATED** and will be removed in the future. gef.arch.endianness == Endianness.LITTLE_ENDIAN --- @@ -1682,9 +1658,7 @@ Sets the current architecture. If an arch is explicitly specified, use that one, 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` --- @@ -2347,9 +2321,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2361,9 +2333,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2389,9 +2359,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2403,9 +2371,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2581,9 +2547,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2595,9 +2559,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2623,9 +2585,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2637,9 +2597,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2738,9 +2696,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2752,9 +2708,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2780,9 +2734,7 @@ do_invoke(argv) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2794,9 +2746,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2895,9 +2845,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2909,9 +2857,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2937,9 +2883,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -2951,9 +2895,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3052,9 +2994,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3066,9 +3006,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3094,9 +3032,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3108,9 +3044,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3379,9 +3313,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3393,9 +3325,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3421,9 +3351,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3435,9 +3363,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3613,9 +3539,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3627,9 +3551,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3655,9 +3577,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3669,9 +3589,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3770,9 +3688,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3798,9 +3714,7 @@ capstone_analyze_pc(insn, nb_insn: int) → Tuple[bool, str] del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3826,9 +3740,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3840,9 +3752,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3941,9 +3851,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3955,9 +3863,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -3997,9 +3903,7 @@ get_fd_from_result(res: str) → int get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4011,9 +3915,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4147,9 +4049,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4161,9 +4061,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4189,9 +4087,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4217,9 +4113,7 @@ get_stub_by_arch(addr: int, size: int, perm) → Union[str, bytearray, NoneType] has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4323,9 +4217,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4337,9 +4229,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4365,9 +4255,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4379,9 +4267,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4683,9 +4569,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4851,9 +4735,7 @@ context_trace() → None del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4907,9 +4789,7 @@ get_pc_context_info(pc: int, line: str) → str get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -4921,9 +4801,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5092,9 +4970,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5106,9 +4982,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5134,9 +5008,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5148,9 +5020,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5263,9 +5133,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5277,9 +5145,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5305,9 +5171,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5319,9 +5183,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5484,9 +5346,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5498,9 +5358,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5526,9 +5384,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5540,9 +5396,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5685,9 +5539,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5699,9 +5551,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5727,9 +5577,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5741,9 +5589,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5870,9 +5716,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5884,9 +5728,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5912,9 +5754,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -5926,9 +5766,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -6062,9 +5900,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -6076,9 +5912,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -6104,9 +5938,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -6118,9 +5950,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -6552,11 +6382,9 @@ add_setting( ) → None ``` +`add_setting` is **DEPRECATED** and will be removed in the future. - - - ---- +--- @@ -6566,9 +6394,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -6594,9 +6420,7 @@ do_invoke(argv) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -6608,9 +6432,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -7295,9 +7117,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -7309,9 +7129,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -7337,9 +7155,7 @@ do_invoke(args: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -7351,9 +7167,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -7708,9 +7522,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -7722,9 +7534,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -7750,9 +7560,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -7764,9 +7572,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8322,9 +8128,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8336,9 +8140,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8364,9 +8166,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8378,9 +8178,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8479,9 +8277,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8493,9 +8289,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8521,9 +8315,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8535,9 +8327,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8650,9 +8440,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8664,9 +8452,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8692,9 +8478,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8706,9 +8490,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8807,9 +8589,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8821,9 +8601,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8886,9 +8664,7 @@ dump_chunks_heap( get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -8900,9 +8676,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9001,9 +8775,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9015,9 +8787,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9043,9 +8813,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9057,9 +8825,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9158,9 +8924,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9172,9 +8936,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9200,9 +8962,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9214,9 +8974,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9408,9 +9166,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9422,9 +9178,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9450,9 +9204,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9464,9 +9216,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9565,9 +9315,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9579,9 +9327,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9607,9 +9353,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9621,9 +9365,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9722,9 +9464,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9736,9 +9476,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9764,9 +9502,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9778,9 +9514,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9879,9 +9613,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9905,9 +9637,7 @@ Check the validity, dedup, and return all valid tids. del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9945,9 +9675,7 @@ Return the location of the current thread's tcache. get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -9959,9 +9687,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10075,9 +9801,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10089,9 +9813,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10117,9 +9839,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10131,9 +9851,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10295,9 +10013,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10309,9 +10025,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10351,9 +10065,7 @@ get_jmp_slots(readelf: str, filename: str) → List[str] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10365,9 +10077,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10470,9 +10180,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10498,9 +10206,7 @@ clean(_) → None del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10540,9 +10246,7 @@ dump_tracked_allocations() → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10554,9 +10258,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10732,9 +10434,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10746,9 +10446,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10774,9 +10472,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10788,9 +10484,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10889,9 +10583,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10903,9 +10595,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10931,9 +10621,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -10945,9 +10633,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11046,9 +10732,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11060,9 +10744,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11088,9 +10770,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11102,9 +10782,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11203,9 +10881,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11217,9 +10893,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11245,9 +10919,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11259,9 +10931,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11360,9 +11030,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11374,9 +11042,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11402,9 +11068,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11416,9 +11080,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11517,9 +11179,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11531,9 +11191,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11559,9 +11217,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11573,9 +11229,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11674,9 +11328,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11688,9 +11340,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11716,9 +11366,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11730,9 +11378,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11831,9 +11477,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11845,9 +11489,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11873,9 +11515,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11887,9 +11527,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -11988,9 +11626,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12002,9 +11638,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12030,9 +11664,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12044,9 +11676,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12159,9 +11789,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12173,9 +11801,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12201,9 +11827,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12215,9 +11839,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12316,9 +11938,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12342,9 +11962,7 @@ Connect to the XML-RPC service. del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12370,9 +11988,7 @@ disconnect() → None do_invoke(argv: List) → None ``` - - - +`do_invoke` is **DEPRECATED** and will be removed in the future. --- @@ -12384,9 +12000,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12398,9 +12012,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12574,9 +12186,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12588,9 +12198,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12616,9 +12224,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -12630,9 +12236,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13292,9 +12896,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13306,9 +12908,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13334,9 +12934,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13348,9 +12946,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13449,9 +13045,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13463,9 +13057,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13491,9 +13083,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13505,9 +13095,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13606,9 +13194,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13620,9 +13206,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13648,9 +13232,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13662,9 +13244,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13763,9 +13343,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13777,9 +13355,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13805,9 +13381,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13819,9 +13393,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13920,9 +13492,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13934,9 +13504,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13962,9 +13530,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -13976,9 +13542,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14112,9 +13676,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14126,9 +13688,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14154,9 +13714,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14168,9 +13726,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14269,9 +13825,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14283,9 +13837,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14325,9 +13877,7 @@ get_insn_size(addr: int) → int get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14339,9 +13889,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14454,9 +14002,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14487,9 +14033,7 @@ apply_structure_to_address( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14623,9 +14167,7 @@ get_pcustom_filepath_for_structure(structure_name: str) → str get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14652,9 +14194,7 @@ Returns a tuple of (class, instance) if modname!classname exists has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14779,9 +14319,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14812,9 +14350,7 @@ apply_structure_to_address( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14948,9 +14484,7 @@ get_pcustom_filepath_for_structure(structure_name: str) → str get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -14977,9 +14511,7 @@ Returns a tuple of (class, instance) if modname!classname exists has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15104,9 +14636,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15137,9 +14667,7 @@ apply_structure_to_address( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15273,9 +14801,7 @@ get_pcustom_filepath_for_structure(structure_name: str) → str get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15302,9 +14828,7 @@ Returns a tuple of (class, instance) if modname!classname exists has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15429,9 +14953,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15462,9 +14984,7 @@ apply_structure_to_address( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15598,9 +15118,7 @@ get_pcustom_filepath_for_structure(structure_name: str) → str get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15627,9 +15145,7 @@ Returns a tuple of (class, instance) if modname!classname exists has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15754,9 +15270,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15768,9 +15282,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15796,9 +15308,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15810,9 +15320,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15911,9 +15419,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15925,9 +15431,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15953,9 +15457,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -15967,9 +15469,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16068,9 +15568,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16082,9 +15580,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16110,9 +15606,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16124,9 +15618,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16225,9 +15717,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16239,9 +15729,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16267,9 +15755,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16281,9 +15767,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16382,9 +15866,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16396,9 +15878,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16424,9 +15904,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16438,9 +15916,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16539,9 +16015,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16553,9 +16027,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16581,9 +16053,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16595,9 +16065,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16696,9 +16164,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16710,9 +16176,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16738,9 +16202,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16752,9 +16214,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16853,9 +16313,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16867,9 +16325,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16895,9 +16351,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -16909,9 +16363,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17010,9 +16462,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17024,9 +16474,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17052,9 +16500,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17066,9 +16512,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17253,9 +16697,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17267,9 +16709,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17295,9 +16735,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17309,9 +16747,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17410,9 +16846,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17424,9 +16858,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17452,9 +16884,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17466,9 +16896,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17581,9 +17009,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17595,9 +17021,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17623,9 +17047,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17637,9 +17059,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17738,9 +17158,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17752,9 +17170,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17794,9 +17210,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17808,9 +17222,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17909,9 +17321,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17923,9 +17333,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17951,9 +17359,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -17965,9 +17371,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18066,9 +17470,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18080,9 +17482,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18108,9 +17508,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18122,9 +17520,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18223,9 +17619,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18237,9 +17631,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18265,9 +17657,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18279,9 +17669,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18809,9 +18197,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18823,9 +18209,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18851,9 +18235,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18865,9 +18247,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18966,9 +18346,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -18980,9 +18358,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19022,9 +18398,7 @@ get_processes() → Generator[Dict[str, str], Any, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19036,9 +18410,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19137,9 +18509,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19151,9 +18521,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19219,11 +18587,9 @@ get_process_path_of(pid: int) → str ```python get_setting(name) -``` - - - +``` +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19249,9 +18615,7 @@ get_state_of(pid: int) → Dict[str, str] has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19651,9 +19015,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19677,9 +19039,7 @@ Connect to remote target and get symbols. To prevent `gef` from requesting infor del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19705,9 +19065,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19719,9 +19077,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19884,9 +19240,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19898,9 +19252,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19926,9 +19278,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -19940,9 +19290,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20041,9 +19389,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20055,9 +19401,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20083,9 +19427,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20097,9 +19439,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20569,9 +19909,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20583,9 +19921,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20611,9 +19947,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20625,9 +19959,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20726,9 +20058,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20740,9 +20070,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20768,9 +20096,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -20782,9 +20108,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21104,9 +20428,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21118,9 +20440,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21146,9 +20466,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21160,9 +20478,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21261,9 +20577,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21275,9 +20589,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21303,9 +20615,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21331,9 +20641,7 @@ get_shellcode(sid: int) → None has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21432,9 +20740,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21446,9 +20752,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21474,9 +20778,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21488,9 +20790,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21603,9 +20903,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21617,9 +20915,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21673,9 +20969,7 @@ evaluate(expr: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21687,9 +20981,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21788,9 +21080,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21802,9 +21092,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21830,9 +21118,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -21844,9 +21130,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22043,9 +21327,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22057,9 +21339,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22085,9 +21365,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22099,9 +21377,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22200,9 +21476,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22214,9 +21488,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22270,9 +21542,7 @@ get_module(modname: str) get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22312,9 +21582,7 @@ get_syscall_table(modname: str) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22623,9 +21891,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22637,9 +21903,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22679,9 +21943,7 @@ get_frames_size() → int get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22693,9 +21955,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22855,9 +22115,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22869,9 +22127,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22897,9 +22153,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -22925,9 +22179,7 @@ get_unicorn_end_addr(start_addr: int, nb: int) → int has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23040,9 +22292,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23054,9 +22304,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23082,9 +22330,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23096,9 +22342,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23239,9 +22483,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23253,9 +22495,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23281,9 +22521,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23295,9 +22533,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23738,9 +22974,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23752,9 +22986,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23780,9 +23012,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23794,9 +23024,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23909,9 +23137,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23923,9 +23149,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23951,9 +23175,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -23965,9 +23187,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24066,9 +23286,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24080,9 +23298,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24108,9 +23324,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24122,9 +23336,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24223,9 +23435,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24237,9 +23447,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24265,9 +23473,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24279,9 +23485,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24380,9 +23584,7 @@ add_setting( ) → None ``` - - - +`add_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24394,9 +23596,7 @@ add_setting( del_setting(name: str) → None ``` - - - +`del_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24422,9 +23622,7 @@ do_invoke(argv: List) → None get_setting(name) ``` - - - +`get_setting` is **DEPRECATED** and will be removed in the future. --- @@ -24436,9 +23634,7 @@ get_setting(name) has_setting(name: str) → bool ``` - - - +`has_setting` is **DEPRECATED** and will be removed in the future. --- diff --git a/gef.py b/gef.py index 14786e959..34dd8d8f4 100644 --- a/gef.py +++ b/gef.py @@ -367,6 +367,10 @@ def wrapper(*args: Tuple, **kwargs: Dict) -> Any: msg += solution warn(msg) return f(*args, **kwargs) + + if not wrapper.__doc__: + wrapper.__doc__ = "" + wrapper.__doc__ += f"\r\n`{f.__name__}` is **DEPRECATED** and will be removed in the future.\r\n{solution}" return wrapper return decorator From 3179289a688a6f000b305d9c357a1aca1a25379a Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 10 Jan 2022 14:57:33 -0800 Subject: [PATCH 50/62] [docs] Partially fix hrefs in `api/gef.md` --- docs/api/gef.md | 5832 +++++++++++++++++----------------- scripts/generate-api-docs.sh | 9 +- 2 files changed, 2921 insertions(+), 2920 deletions(-) diff --git a/docs/api/gef.md b/docs/api/gef.md index 16bb9485b..72ac80842 100644 --- a/docs/api/gef.md +++ b/docs/api/gef.md @@ -36,7 +36,7 @@ --- - + ## function `FakeExit` @@ -51,7 +51,7 @@ FakeExit(*args, **kwargs) → None --- - + ## function `align_address` @@ -64,7 +64,7 @@ Align the provided address to the process's native length. --- - + ## function `align_address_to_page` @@ -77,7 +77,7 @@ Align the address to a page. --- - + ## function `align_address_to_size` @@ -90,7 +90,7 @@ Align the address to the given size. --- - + ## function `bufferize` @@ -103,7 +103,7 @@ Store the content to be printed for a function in memory, and flush it on functi --- - + ## function `capstone_disassemble` @@ -116,7 +116,7 @@ Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr` usin --- - + ## function `clear_screen` @@ -129,7 +129,7 @@ Clear the screen. --- - + ## function `continue_handler` @@ -142,7 +142,7 @@ GDB event handler for new object continue cases. --- - + ## function `copy_to_clipboard` @@ -155,7 +155,7 @@ Helper function to submit data to the clipboard --- - + ## function `de_bruijn` @@ -168,7 +168,7 @@ De Bruijn sequence for alphabet and subsequences of length n (for compat. w/ pwn --- - + ## function `deprecated` @@ -181,7 +181,7 @@ Decorator to add a warning when a command is obsolete and will be removed. --- - + ## function `disable_redirect_output` @@ -194,7 +194,7 @@ Disable the output redirection, if any. `disable_redirect_output` is **DEPRECAT --- - + ## function `download_file` @@ -211,7 +211,7 @@ Download filename `remote_path` inside the mirror tree inside the gef.config["ge --- - + ## function `enable_redirect_output` @@ -224,7 +224,7 @@ Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects --- - + ## function `endian_str` @@ -237,7 +237,7 @@ endian_str() → str --- - + ## function `err` @@ -252,7 +252,7 @@ err(msg: str) → Union[int, NoneType] --- - + ## function `exit_handler` @@ -265,7 +265,7 @@ GDB event handler for exit cases. --- - + ## function `experimental_feature` @@ -278,7 +278,7 @@ Decorator to add a warning when a feature is experimental. --- - + ## function `flags_to_human` @@ -291,7 +291,7 @@ Return a human readable string showing the flag states. --- - + ## function `format_address` @@ -304,7 +304,7 @@ Format the address according to its size. --- - + ## function `format_address_spaces` @@ -317,7 +317,7 @@ Format the address according to its size, but with spaces instead of zeroes. --- - + ## function `gdb_disassemble` @@ -332,7 +332,7 @@ Disassemble instructions from `start_pc` (Integer). Accepts the following named --- - + ## function `gdb_get_nth_next_instruction_address` @@ -345,7 +345,7 @@ Return the address (Integer) of the `n`-th instruction after `addr`. --- - + ## function `gdb_get_nth_previous_instruction_address` @@ -361,7 +361,7 @@ Return the address (Integer) of the `n`-th instruction before `addr`. --- - + ## function `gef_convenience` @@ -374,7 +374,7 @@ Defines a new convenience value. --- - + ## function `gef_current_instruction` @@ -387,7 +387,7 @@ Return the current instruction as an Instruction object. --- - + ## function `gef_disassemble` @@ -400,7 +400,7 @@ Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr`. Ret --- - + ## function `gef_execute_external` @@ -417,7 +417,7 @@ Execute an external command and return the result. --- - + ## function `gef_execute_gdb_script` @@ -430,7 +430,7 @@ Execute the parameter `source` as GDB command. This is done by writing `commands --- - + ## function `gef_get_instruction_at` @@ -443,7 +443,7 @@ Return the full Instruction found at the specified address. --- - + ## function `gef_get_pie_breakpoint` @@ -458,7 +458,7 @@ gef_get_pie_breakpoint(num: int) --- - + ## function `gef_getpagesize` @@ -471,7 +471,7 @@ gef_getpagesize() → int --- - + ## function `gef_instruction_n` @@ -484,7 +484,7 @@ Return the `n`-th instruction after `addr` as an Instruction object. --- - + ## function `gef_makedirs` @@ -497,7 +497,7 @@ Recursive mkdir() creation. If successful, return the absolute path of the direc --- - + ## function `gef_next_instruction` @@ -510,7 +510,7 @@ Return the next instruction as an Instruction object. --- - + ## function `wrapped_f` @@ -525,7 +525,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -540,7 +540,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -555,7 +555,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -570,7 +570,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -585,7 +585,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -600,7 +600,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -615,7 +615,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -630,7 +630,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -645,7 +645,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -660,7 +660,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -675,7 +675,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -690,7 +690,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `gef_print` @@ -703,7 +703,7 @@ Wrapper around print(), using string buffering feature. --- - + ## function `gef_pybytes` @@ -716,7 +716,7 @@ Returns an immutable bytes list from the string given as input. --- - + ## function `gef_pystring` @@ -729,7 +729,7 @@ Returns a sanitized version as string of the bytes list given in input. --- - + ## function `gef_read_canary` @@ -742,7 +742,7 @@ gef_read_canary() → Union[Tuple[int, int], NoneType] --- - + ## function `generate_cyclic_pattern` @@ -755,7 +755,7 @@ Create a `length` byte bytearray of a de Bruijn cyclic pattern. --- - + ## function `get_capstone_arch` @@ -775,7 +775,7 @@ get_capstone_arch( --- - + ## function `get_filename` @@ -788,7 +788,7 @@ get_filename() → str --- - + ## function `get_function_length` @@ -801,7 +801,7 @@ Attempt to get the length of the raw bytes of a function. --- - + ## function `get_gef_setting` @@ -814,7 +814,7 @@ get_gef_setting(name: str) → Any --- - + ## function `get_generic_arch` @@ -834,7 +834,7 @@ Retrieves architecture and mode from the arguments for use for the holy {cap,key --- - + ## function `get_generic_running_arch` @@ -851,7 +851,7 @@ Retrieves architecture and mode from the current context. --- - + ## function `get_glibc_arena` @@ -864,7 +864,7 @@ get_glibc_arena() --- - + ## function `get_keystone_arch` @@ -884,7 +884,7 @@ get_keystone_arch( --- - + ## function `get_memory_alignment` @@ -897,7 +897,7 @@ Try to determine the size of a pointer on this system. First, try to parse it o --- - + ## function `get_os` @@ -910,7 +910,7 @@ get_os() → str --- - + ## function `get_path_from_info_proc` @@ -925,7 +925,7 @@ get_path_from_info_proc() --- - + ## function `get_pid` @@ -938,7 +938,7 @@ get_pid() → int --- - + ## function `get_process_maps` @@ -951,7 +951,7 @@ get_process_maps() --- - + ## function `get_register` @@ -964,7 +964,7 @@ get_register(regname) --- - + ## function `get_terminal_size` @@ -977,7 +977,7 @@ Return the current terminal size. --- - + ## function `get_unicorn_arch` @@ -997,7 +997,7 @@ get_unicorn_arch( --- - + ## function `get_unicorn_registers` @@ -1012,7 +1012,7 @@ Return a dict matching the Unicorn identifier for a specific register. --- - + ## function `hexdump` @@ -1032,7 +1032,7 @@ Return the hexdump of `src` argument. @param source *MUST* be of type bytes or b --- - + ## function `hide_context` @@ -1045,7 +1045,7 @@ Helper function to hide the context pane --- - + ## function `highlight_text` @@ -1062,7 +1062,7 @@ If RegEx is disabled, split by ANSI codes and 'colorify' each match found within --- - + ## function `hook_stop_handler` @@ -1075,7 +1075,7 @@ GDB event handler for stop cases. --- - + ## function `http_get` @@ -1088,7 +1088,7 @@ Basic HTTP wrapper for GET request. Return the body of the page if HTTP code is --- - + ## function `ida_synchronize_handler` @@ -1103,7 +1103,7 @@ ida_synchronize_handler(event) --- - + ## function `info` @@ -1118,7 +1118,7 @@ info(msg: str) → Union[int, NoneType] --- - + ## function `is_alive` @@ -1131,7 +1131,7 @@ Check if GDB is running. --- - + ## function `is_ascii_string` @@ -1144,7 +1144,7 @@ Helper function to determine if the buffer pointed by `address` is an ASCII stri --- - + ## function `is_big_endian` @@ -1157,7 +1157,7 @@ is_big_endian() → bool --- - + ## function `is_debug` @@ -1170,7 +1170,7 @@ Check if debug mode is enabled. --- - + ## function `is_hex` @@ -1183,7 +1183,7 @@ Return whether provided string is a hexadecimal value. --- - + ## function `is_in_x86_kernel` @@ -1198,7 +1198,7 @@ is_in_x86_kernel(address: int) → bool --- - + ## function `is_little_endian` @@ -1211,7 +1211,7 @@ is_little_endian() → bool --- - + ## function `is_pie` @@ -1226,7 +1226,7 @@ is_pie(fpath: str) → bool --- - + ## function `keystone_assemble` @@ -1245,7 +1245,7 @@ Assembly encoding function based on keystone. --- - + ## function `load_libc_args` @@ -1260,7 +1260,7 @@ load_libc_args() → None --- - + ## function `malloc_align_address` @@ -1273,7 +1273,7 @@ Align addresses according to glibc's MALLOC_ALIGNMENT. See also Issue #689 on Gi --- - + ## function `memchanged_handler` @@ -1286,7 +1286,7 @@ GDB event handler for mem changes cases. --- - + ## function `new_objfile_handler` @@ -1299,7 +1299,7 @@ GDB event handler for new object file cases. --- - + ## function `ok` @@ -1314,7 +1314,7 @@ ok(msg: str) → Union[int, NoneType] --- - + ## function `only_if_current_arch_in` @@ -1327,7 +1327,7 @@ Decorator to allow commands for only a subset of the architectured supported by --- - + ## function `only_if_events_supported` @@ -1340,7 +1340,7 @@ Checks if GDB supports events without crashing. --- - + ## function `only_if_gdb_running` @@ -1353,7 +1353,7 @@ Decorator wrapper to check if GDB is running. --- - + ## function `only_if_gdb_target_local` @@ -1366,7 +1366,7 @@ Decorator wrapper to check if GDB is running locally (target not remote). --- - + ## function `only_if_gdb_version_higher_than` @@ -1379,7 +1379,7 @@ Decorator to check whether current GDB version requirements. --- - + ## function `p16` @@ -1392,7 +1392,7 @@ Pack one word respecting the current architecture endianness. --- - + ## function `p32` @@ -1405,7 +1405,7 @@ Pack one dword respecting the current architecture endianness. --- - + ## function `p64` @@ -1418,7 +1418,7 @@ Pack one qword respecting the current architecture endianness. --- - + ## function `p8` @@ -1431,7 +1431,7 @@ Pack one byte respecting the current architecture endianness. --- - + ## function `parse_address` @@ -1444,7 +1444,7 @@ Parse an address and return it as an Integer. --- - + ## function `parse_arguments` @@ -1460,7 +1460,7 @@ Argument parsing decorator. --- - + ## function `parse_string_range` @@ -1473,7 +1473,7 @@ Parses an address range (e.g. 0x400000-0x401000) --- - + ## function `process_lookup_address` @@ -1486,7 +1486,7 @@ Look up for an address in memory. Return an Address object if found, None otherw --- - + ## function `push_context_message` @@ -1499,7 +1499,7 @@ Push the message to be displayed the next time the context is invoked. --- - + ## function `regchanged_handler` @@ -1512,7 +1512,7 @@ GDB event handler for reg changes cases. --- - + ## function `register_architecture` @@ -1525,7 +1525,7 @@ Class decorator for declaring an architecture to GEF. --- - + ## function `register_command` @@ -1538,7 +1538,7 @@ Decorator for registering new GEF (sub-)command to GDB. --- - + ## function `register_external_command` @@ -1551,7 +1551,7 @@ Registering function for new GEF (sub-)command to GDB. --- - + ## function `register_external_context_pane` @@ -1570,7 +1570,7 @@ Example Usage: def display_pane(): gef_print("Wow, I am a context pane!") def pa --- - + ## function `register_function` @@ -1583,7 +1583,7 @@ Decorator for registering a new convenience function to GDB. --- - + ## function `register_priority_command` @@ -1596,7 +1596,7 @@ Decorator for registering new command with priority, meaning that it must loaded --- - + ## function `reset` @@ -1611,7 +1611,7 @@ reset() → None --- - + ## function `reset_all_caches` @@ -1624,7 +1624,7 @@ Free all caches. If an object is cached, it will have a callable attribute `cach --- - + ## function `safe_parse_and_eval` @@ -1637,7 +1637,7 @@ GEF wrapper for gdb.parse_and_eval(): this function returns None instead of rais --- - + ## function `set_arch` @@ -1650,7 +1650,7 @@ Sets the current architecture. If an arch is explicitly specified, use that one, --- - + ## function `set_gef_setting` @@ -1663,7 +1663,7 @@ set_gef_setting(name: str, value: Any) → None --- - + ## function `show_last_exception` @@ -1676,7 +1676,7 @@ Display the last Python exception. --- - + ## function `style_byte` @@ -1691,7 +1691,7 @@ style_byte(b: int, color: bool = True) → str --- - + ## function `titlify` @@ -1708,7 +1708,7 @@ Print a centered title. --- - + ## function `to_unsigned_long` @@ -1721,7 +1721,7 @@ Cast a gdb.Value to unsigned long. --- - + ## function `u16` @@ -1734,7 +1734,7 @@ Unpack one word respecting the current architecture endianness. --- - + ## function `u32` @@ -1747,7 +1747,7 @@ Unpack one dword respecting the current architecture endianness. --- - + ## function `u64` @@ -1760,7 +1760,7 @@ Unpack one qword respecting the current architecture endianness. --- - + ## function `u8` @@ -1773,7 +1773,7 @@ Unpack one byte respecting the current architecture endianness. --- - + ## function `unhide_context` @@ -1786,7 +1786,7 @@ Helper function to unhide the context pane --- - + ## function `update_gef` @@ -1799,7 +1799,7 @@ Try to update `gef` to the latest version pushed on GitHub master branch. Return --- - + ## function `use_default_type` @@ -1814,7 +1814,7 @@ use_default_type() → str --- - + ## function `use_golang_type` @@ -1829,7 +1829,7 @@ use_golang_type() → str --- - + ## function `use_rust_type` @@ -1844,7 +1844,7 @@ use_rust_type() → str --- - + ## function `use_stdtype` @@ -1859,7 +1859,7 @@ use_stdtype() → str --- - + ## function `warn` @@ -1874,7 +1874,7 @@ warn(msg: str) → Union[int, NoneType] --- - + ## function `xor` @@ -1937,9 +1937,9 @@ Return `data` xor-ed with `key`. --- - + -### method `AARCH64.flag_register_to_human` +## function `AARCH64.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → str @@ -1951,9 +1951,9 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + -### method `AARCH64.get_ith_parameter` +## function `AARCH64.get_ith_parameter` ```python get_ith_parameter( @@ -1966,9 +1966,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `AARCH64.get_ra` +## function `AARCH64.get_ra` ```python get_ra(insn, frame) → int @@ -1980,9 +1980,9 @@ get_ra(insn, frame) → int --- - + -### method `AARCH64.is_branch_taken` +## function `AARCH64.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -1994,9 +1994,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `AARCH64.is_call` +## function `AARCH64.is_call` ```python is_call(insn) → bool @@ -2008,9 +2008,9 @@ is_call(insn) → bool --- - + -### method `AARCH64.is_conditional_branch` +## function `AARCH64.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -2022,9 +2022,9 @@ is_conditional_branch(insn) → bool --- - + -### method `AARCH64.is_ret` +## function `AARCH64.is_ret` ```python is_ret(insn) → Union[bool, NoneType] @@ -2036,9 +2036,9 @@ is_ret(insn) → Union[bool, NoneType] --- - + -### method `AARCH64.is_thumb` +## function `AARCH64.is_thumb` ```python is_thumb() → bool @@ -2048,9 +2048,9 @@ Determine if the machine is currently in THUMB mode. --- - + -### classmethod `AARCH64.mprotect_asm` +## function `AARCH64.mprotect_asm` ```python mprotect_asm(addr: int, size: int, perm) → str @@ -2062,9 +2062,9 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + -### method `AARCH64.register` +## function `AARCH64.register` ```python register(name: str) → Union[int, NoneType] @@ -2143,9 +2143,9 @@ register(name: str) → Union[int, NoneType] --- - + -### method `ARM.flag_register_to_human` +## function `ARM.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → str @@ -2157,9 +2157,9 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + -### method `ARM.get_ith_parameter` +## function `ARM.get_ith_parameter` ```python get_ith_parameter( @@ -2172,9 +2172,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `ARM.get_ra` +## function `ARM.get_ra` ```python get_ra(insn, frame) → int @@ -2186,9 +2186,9 @@ get_ra(insn, frame) → int --- - + -### method `ARM.is_branch_taken` +## function `ARM.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -2200,9 +2200,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `ARM.is_call` +## function `ARM.is_call` ```python is_call(insn) → bool @@ -2214,9 +2214,9 @@ is_call(insn) → bool --- - + -### method `ARM.is_conditional_branch` +## function `ARM.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -2228,9 +2228,9 @@ is_conditional_branch(insn) → bool --- - + -### method `ARM.is_ret` +## function `ARM.is_ret` ```python is_ret(insn) → Union[bool, NoneType] @@ -2242,9 +2242,9 @@ is_ret(insn) → Union[bool, NoneType] --- - + -### method `ARM.is_thumb` +## function `ARM.is_thumb` ```python is_thumb() → bool @@ -2254,9 +2254,9 @@ Determine if the machine is currently in THUMB mode. --- - + -### classmethod `ARM.mprotect_asm` +## function `ARM.mprotect_asm` ```python mprotect_asm(addr: int, size: int, perm) → str @@ -2268,9 +2268,9 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + -### method `ARM.register` +## function `ARM.register` ```python register(name: str) → Union[int, NoneType] @@ -2286,9 +2286,9 @@ register(name: str) → Union[int, NoneType] ## 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. - + -### method `ASLRCommand.__init__` +## function `ASLRCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -2309,9 +2309,9 @@ Return the list of settings for this command. --- - + -### method `ASLRCommand.add_setting` +## function `ASLRCommand.add_setting` ```python add_setting( @@ -2325,9 +2325,9 @@ add_setting( --- - + -### method `ASLRCommand.del_setting` +## function `ASLRCommand.del_setting` ```python del_setting(name: str) → None @@ -2337,9 +2337,9 @@ del_setting(name: str) → None --- - + -### method `ASLRCommand.do_invoke` +## function `ASLRCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -2351,9 +2351,9 @@ do_invoke(argv: List) → None --- - + -### method `ASLRCommand.get_setting` +## function `ASLRCommand.get_setting` ```python get_setting(name) @@ -2363,9 +2363,9 @@ get_setting(name) --- - + -### method `ASLRCommand.has_setting` +## function `ASLRCommand.has_setting` ```python has_setting(name: str) → bool @@ -2375,9 +2375,9 @@ has_setting(name: str) → bool --- - + -### method `ASLRCommand.invoke` +## function `ASLRCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -2389,9 +2389,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ASLRCommand.post_load` +## function `ASLRCommand.post_load` ```python post_load() → None @@ -2403,9 +2403,9 @@ post_load() → None --- - + -### method `ASLRCommand.pre_load` +## function `ASLRCommand.pre_load` ```python pre_load() → None @@ -2417,9 +2417,9 @@ pre_load() → None --- - + -### method `ASLRCommand.usage` +## function `ASLRCommand.usage` ```python usage() → None @@ -2435,9 +2435,9 @@ usage() → None ## class `Address` GEF representation of memory addresses. - + -### method `Address.__init__` +## function `Address.__init__` ```python __init__(*args, **kwargs) → None @@ -2452,9 +2452,9 @@ __init__(*args, **kwargs) → None --- - + -### method `Address.dereference` +## function `Address.dereference` ```python dereference() → Union[int, NoneType] @@ -2466,9 +2466,9 @@ dereference() → Union[int, NoneType] --- - + -### method `Address.is_in_heap_segment` +## function `Address.is_in_heap_segment` ```python is_in_heap_segment() → bool @@ -2480,9 +2480,9 @@ is_in_heap_segment() → bool --- - + -### method `Address.is_in_stack_segment` +## function `Address.is_in_stack_segment` ```python is_in_stack_segment() → bool @@ -2494,9 +2494,9 @@ is_in_stack_segment() → bool --- - + -### method `Address.is_in_text_segment` +## function `Address.is_in_text_segment` ```python is_in_text_segment() → bool @@ -2512,9 +2512,9 @@ is_in_text_segment() → bool ## class `AliasesAddCommand` Command to add aliases. - + -### method `AliasesAddCommand.__init__` +## function `AliasesAddCommand.__init__` ```python __init__() → None @@ -2535,9 +2535,9 @@ Return the list of settings for this command. --- - + -### method `AliasesAddCommand.add_setting` +## function `AliasesAddCommand.add_setting` ```python add_setting( @@ -2551,9 +2551,9 @@ add_setting( --- - + -### method `AliasesAddCommand.del_setting` +## function `AliasesAddCommand.del_setting` ```python del_setting(name: str) → None @@ -2563,9 +2563,9 @@ del_setting(name: str) → None --- - + -### method `AliasesAddCommand.do_invoke` +## function `AliasesAddCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -2577,9 +2577,9 @@ do_invoke(argv: List) → None --- - + -### method `AliasesAddCommand.get_setting` +## function `AliasesAddCommand.get_setting` ```python get_setting(name) @@ -2589,9 +2589,9 @@ get_setting(name) --- - + -### method `AliasesAddCommand.has_setting` +## function `AliasesAddCommand.has_setting` ```python has_setting(name: str) → bool @@ -2601,9 +2601,9 @@ has_setting(name: str) → bool --- - + -### method `AliasesAddCommand.invoke` +## function `AliasesAddCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -2615,9 +2615,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `AliasesAddCommand.post_load` +## function `AliasesAddCommand.post_load` ```python post_load() → None @@ -2629,9 +2629,9 @@ post_load() → None --- - + -### method `AliasesAddCommand.pre_load` +## function `AliasesAddCommand.pre_load` ```python pre_load() → None @@ -2643,9 +2643,9 @@ pre_load() → None --- - + -### method `AliasesAddCommand.usage` +## function `AliasesAddCommand.usage` ```python usage() → None @@ -2661,9 +2661,9 @@ usage() → None ## class `AliasesCommand` Base command to add, remove, or list aliases. - + -### method `AliasesCommand.__init__` +## function `AliasesCommand.__init__` ```python __init__() → None @@ -2684,9 +2684,9 @@ Return the list of settings for this command. --- - + -### method `AliasesCommand.add_setting` +## function `AliasesCommand.add_setting` ```python add_setting( @@ -2700,9 +2700,9 @@ add_setting( --- - + -### method `AliasesCommand.del_setting` +## function `AliasesCommand.del_setting` ```python del_setting(name: str) → None @@ -2712,9 +2712,9 @@ del_setting(name: str) → None --- - + -### method `AliasesCommand.do_invoke` +## function `AliasesCommand.do_invoke` ```python do_invoke(argv) → None @@ -2726,9 +2726,9 @@ do_invoke(argv) → None --- - + -### method `AliasesCommand.get_setting` +## function `AliasesCommand.get_setting` ```python get_setting(name) @@ -2738,9 +2738,9 @@ get_setting(name) --- - + -### method `AliasesCommand.has_setting` +## function `AliasesCommand.has_setting` ```python has_setting(name: str) → bool @@ -2750,9 +2750,9 @@ has_setting(name: str) → bool --- - + -### method `AliasesCommand.invoke` +## function `AliasesCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -2764,9 +2764,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `AliasesCommand.post_load` +## function `AliasesCommand.post_load` ```python post_load() → None @@ -2778,9 +2778,9 @@ post_load() → None --- - + -### method `AliasesCommand.pre_load` +## function `AliasesCommand.pre_load` ```python pre_load() → None @@ -2792,9 +2792,9 @@ pre_load() → None --- - + -### method `AliasesCommand.usage` +## function `AliasesCommand.usage` ```python usage() → None @@ -2810,9 +2810,9 @@ usage() → None ## class `AliasesListCommand` Command to list aliases. - + -### method `AliasesListCommand.__init__` +## function `AliasesListCommand.__init__` ```python __init__() → None @@ -2833,9 +2833,9 @@ Return the list of settings for this command. --- - + -### method `AliasesListCommand.add_setting` +## function `AliasesListCommand.add_setting` ```python add_setting( @@ -2849,9 +2849,9 @@ add_setting( --- - + -### method `AliasesListCommand.del_setting` +## function `AliasesListCommand.del_setting` ```python del_setting(name: str) → None @@ -2861,9 +2861,9 @@ del_setting(name: str) → None --- - + -### method `AliasesListCommand.do_invoke` +## function `AliasesListCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -2875,9 +2875,9 @@ do_invoke(argv: List) → None --- - + -### method `AliasesListCommand.get_setting` +## function `AliasesListCommand.get_setting` ```python get_setting(name) @@ -2887,9 +2887,9 @@ get_setting(name) --- - + -### method `AliasesListCommand.has_setting` +## function `AliasesListCommand.has_setting` ```python has_setting(name: str) → bool @@ -2899,9 +2899,9 @@ has_setting(name: str) → bool --- - + -### method `AliasesListCommand.invoke` +## function `AliasesListCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -2913,9 +2913,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `AliasesListCommand.post_load` +## function `AliasesListCommand.post_load` ```python post_load() → None @@ -2927,9 +2927,9 @@ post_load() → None --- - + -### method `AliasesListCommand.pre_load` +## function `AliasesListCommand.pre_load` ```python pre_load() → None @@ -2941,9 +2941,9 @@ pre_load() → None --- - + -### method `AliasesListCommand.usage` +## function `AliasesListCommand.usage` ```python usage() → None @@ -2959,9 +2959,9 @@ usage() → None ## class `AliasesRmCommand` Command to remove aliases. - + -### method `AliasesRmCommand.__init__` +## function `AliasesRmCommand.__init__` ```python __init__() → None @@ -2982,9 +2982,9 @@ Return the list of settings for this command. --- - + -### method `AliasesRmCommand.add_setting` +## function `AliasesRmCommand.add_setting` ```python add_setting( @@ -2998,9 +2998,9 @@ add_setting( --- - + -### method `AliasesRmCommand.del_setting` +## function `AliasesRmCommand.del_setting` ```python del_setting(name: str) → None @@ -3010,9 +3010,9 @@ del_setting(name: str) → None --- - + -### method `AliasesRmCommand.do_invoke` +## function `AliasesRmCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -3024,9 +3024,9 @@ do_invoke(argv: List) → None --- - + -### method `AliasesRmCommand.get_setting` +## function `AliasesRmCommand.get_setting` ```python get_setting(name) @@ -3036,9 +3036,9 @@ get_setting(name) --- - + -### method `AliasesRmCommand.has_setting` +## function `AliasesRmCommand.has_setting` ```python has_setting(name: str) → bool @@ -3048,9 +3048,9 @@ has_setting(name: str) → bool --- - + -### method `AliasesRmCommand.invoke` +## function `AliasesRmCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -3062,9 +3062,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `AliasesRmCommand.post_load` +## function `AliasesRmCommand.post_load` ```python post_load() → None @@ -3076,9 +3076,9 @@ post_load() → None --- - + -### method `AliasesRmCommand.pre_load` +## function `AliasesRmCommand.pre_load` ```python pre_load() → None @@ -3090,9 +3090,9 @@ pre_load() → None --- - + -### method `AliasesRmCommand.usage` +## function `AliasesRmCommand.usage` ```python usage() → None @@ -3161,9 +3161,9 @@ Generic metaclass for the architecture supported by GEF. --- - + -### method `Architecture.flag_register_to_human` +## function `Architecture.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → str @@ -3175,9 +3175,9 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + -### method `Architecture.get_ith_parameter` +## function `Architecture.get_ith_parameter` ```python get_ith_parameter( @@ -3190,9 +3190,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `Architecture.get_ra` +## function `Architecture.get_ra` ```python get_ra(insn, frame) → Union[int, NoneType] @@ -3204,9 +3204,9 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + -### method `Architecture.is_branch_taken` +## function `Architecture.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -3218,9 +3218,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `Architecture.is_call` +## function `Architecture.is_call` ```python is_call(insn) → bool @@ -3232,9 +3232,9 @@ is_call(insn) → bool --- - + -### method `Architecture.is_conditional_branch` +## function `Architecture.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -3246,9 +3246,9 @@ is_conditional_branch(insn) → bool --- - + -### method `Architecture.is_ret` +## function `Architecture.is_ret` ```python is_ret(insn) → Union[bool, NoneType] @@ -3260,9 +3260,9 @@ is_ret(insn) → Union[bool, NoneType] --- - + -### method `Architecture.register` +## function `Architecture.register` ```python register(name: str) → Union[int, NoneType] @@ -3278,9 +3278,9 @@ register(name: str) → Union[int, NoneType] ## class `AssembleCommand` Inline code assemble. Architecture can be set in GEF runtime config. - + -### method `AssembleCommand.__init__` +## function `AssembleCommand.__init__` ```python __init__() → None @@ -3301,9 +3301,9 @@ Return the list of settings for this command. --- - + -### method `AssembleCommand.add_setting` +## function `AssembleCommand.add_setting` ```python add_setting( @@ -3317,9 +3317,9 @@ add_setting( --- - + -### method `AssembleCommand.del_setting` +## function `AssembleCommand.del_setting` ```python del_setting(name: str) → None @@ -3329,9 +3329,9 @@ del_setting(name: str) → None --- - + -### function `AssembleCommand.wrapper` +## function `AssembleCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -3343,9 +3343,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `AssembleCommand.get_setting` +## function `AssembleCommand.get_setting` ```python get_setting(name) @@ -3355,9 +3355,9 @@ get_setting(name) --- - + -### method `AssembleCommand.has_setting` +## function `AssembleCommand.has_setting` ```python has_setting(name: str) → bool @@ -3367,9 +3367,9 @@ has_setting(name: str) → bool --- - + -### method `AssembleCommand.invoke` +## function `AssembleCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -3381,9 +3381,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `AssembleCommand.list_archs` +## function `AssembleCommand.list_archs` ```python list_archs() → None @@ -3395,9 +3395,9 @@ list_archs() → None --- - + -### method `AssembleCommand.post_load` +## function `AssembleCommand.post_load` ```python post_load() → None @@ -3409,9 +3409,9 @@ post_load() → None --- - + -### method `AssembleCommand.pre_load` +## function `AssembleCommand.pre_load` ```python pre_load() → None @@ -3423,9 +3423,9 @@ pre_load() → None --- - + -### method `AssembleCommand.usage` +## function `AssembleCommand.usage` ```python usage() → None @@ -3441,9 +3441,9 @@ usage() → None ## class `BssBaseFunction` Return the current bss base address plus the given offset. - + -### method `BssBaseFunction.__init__` +## function `BssBaseFunction.__init__` ```python __init__() → None @@ -3458,9 +3458,9 @@ __init__() → None --- - + -### method `BssBaseFunction.arg_to_long` +## function `BssBaseFunction.arg_to_long` ```python arg_to_long(args: List, index: int, default: int = 0) → int @@ -3472,9 +3472,9 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + -### method `BssBaseFunction.do_invoke` +## function `BssBaseFunction.do_invoke` ```python do_invoke(args: List) → int @@ -3486,9 +3486,9 @@ do_invoke(args: List) → int --- - + -### method `BssBaseFunction.invoke` +## function `BssBaseFunction.invoke` ```python invoke(*args) → int @@ -3504,9 +3504,9 @@ invoke(*args) → int ## class `CanaryCommand` Shows the canary value of the current process. - + -### method `CanaryCommand.__init__` +## function `CanaryCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -3527,9 +3527,9 @@ Return the list of settings for this command. --- - + -### method `CanaryCommand.add_setting` +## function `CanaryCommand.add_setting` ```python add_setting( @@ -3543,9 +3543,9 @@ add_setting( --- - + -### method `CanaryCommand.del_setting` +## function `CanaryCommand.del_setting` ```python del_setting(name: str) → None @@ -3555,9 +3555,9 @@ del_setting(name: str) → None --- - + -### method `CanaryCommand.do_invoke` +## function `CanaryCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -3569,9 +3569,9 @@ do_invoke(argv: List) → None --- - + -### method `CanaryCommand.get_setting` +## function `CanaryCommand.get_setting` ```python get_setting(name) @@ -3581,9 +3581,9 @@ get_setting(name) --- - + -### method `CanaryCommand.has_setting` +## function `CanaryCommand.has_setting` ```python has_setting(name: str) → bool @@ -3593,9 +3593,9 @@ has_setting(name: str) → bool --- - + -### method `CanaryCommand.invoke` +## function `CanaryCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -3607,9 +3607,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `CanaryCommand.post_load` +## function `CanaryCommand.post_load` ```python post_load() → None @@ -3621,9 +3621,9 @@ post_load() → None --- - + -### method `CanaryCommand.pre_load` +## function `CanaryCommand.pre_load` ```python pre_load() → None @@ -3635,9 +3635,9 @@ pre_load() → None --- - + -### method `CanaryCommand.usage` +## function `CanaryCommand.usage` ```python usage() → None @@ -3653,9 +3653,9 @@ usage() → None ## class `CapstoneDisassembleCommand` Use capstone disassembly framework to disassemble code. - + -### method `CapstoneDisassembleCommand.__init__` +## function `CapstoneDisassembleCommand.__init__` ```python __init__() @@ -3676,9 +3676,9 @@ Return the list of settings for this command. --- - + -### method `CapstoneDisassembleCommand.add_setting` +## function `CapstoneDisassembleCommand.add_setting` ```python add_setting( @@ -3692,9 +3692,9 @@ add_setting( --- - + -### method `CapstoneDisassembleCommand.capstone_analyze_pc` +## function `CapstoneDisassembleCommand.capstone_analyze_pc` ```python capstone_analyze_pc(insn, nb_insn: int) → Tuple[bool, str] @@ -3706,9 +3706,9 @@ capstone_analyze_pc(insn, nb_insn: int) → Tuple[bool, str] --- - + -### method `CapstoneDisassembleCommand.del_setting` +## function `CapstoneDisassembleCommand.del_setting` ```python del_setting(name: str) → None @@ -3718,9 +3718,9 @@ del_setting(name: str) → None --- - + -### function `CapstoneDisassembleCommand.wrapper` +## function `CapstoneDisassembleCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -3732,9 +3732,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `CapstoneDisassembleCommand.get_setting` +## function `CapstoneDisassembleCommand.get_setting` ```python get_setting(name) @@ -3744,9 +3744,9 @@ get_setting(name) --- - + -### method `CapstoneDisassembleCommand.has_setting` +## function `CapstoneDisassembleCommand.has_setting` ```python has_setting(name: str) → bool @@ -3756,9 +3756,9 @@ has_setting(name: str) → bool --- - + -### method `CapstoneDisassembleCommand.invoke` +## function `CapstoneDisassembleCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -3770,9 +3770,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `CapstoneDisassembleCommand.post_load` +## function `CapstoneDisassembleCommand.post_load` ```python post_load() → None @@ -3784,9 +3784,9 @@ post_load() → None --- - + -### method `CapstoneDisassembleCommand.pre_load` +## function `CapstoneDisassembleCommand.pre_load` ```python pre_load() → None @@ -3798,9 +3798,9 @@ pre_load() → None --- - + -### method `CapstoneDisassembleCommand.usage` +## function `CapstoneDisassembleCommand.usage` ```python usage() → None @@ -3816,9 +3816,9 @@ usage() → None ## class `ChangeFdCommand` ChangeFdCommand: redirect file descriptor during runtime. - + -### method `ChangeFdCommand.__init__` +## function `ChangeFdCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -3839,9 +3839,9 @@ Return the list of settings for this command. --- - + -### method `ChangeFdCommand.add_setting` +## function `ChangeFdCommand.add_setting` ```python add_setting( @@ -3855,9 +3855,9 @@ add_setting( --- - + -### method `ChangeFdCommand.del_setting` +## function `ChangeFdCommand.del_setting` ```python del_setting(name: str) → None @@ -3867,9 +3867,9 @@ del_setting(name: str) → None --- - + -### method `ChangeFdCommand.do_invoke` +## function `ChangeFdCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -3881,9 +3881,9 @@ do_invoke(argv: List) → None --- - + -### method `ChangeFdCommand.get_fd_from_result` +## function `ChangeFdCommand.get_fd_from_result` ```python get_fd_from_result(res: str) → int @@ -3895,9 +3895,9 @@ get_fd_from_result(res: str) → int --- - + -### method `ChangeFdCommand.get_setting` +## function `ChangeFdCommand.get_setting` ```python get_setting(name) @@ -3907,9 +3907,9 @@ get_setting(name) --- - + -### method `ChangeFdCommand.has_setting` +## function `ChangeFdCommand.has_setting` ```python has_setting(name: str) → bool @@ -3919,9 +3919,9 @@ has_setting(name: str) → bool --- - + -### method `ChangeFdCommand.invoke` +## function `ChangeFdCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -3933,9 +3933,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ChangeFdCommand.post_load` +## function `ChangeFdCommand.post_load` ```python post_load() → None @@ -3947,9 +3947,9 @@ post_load() → None --- - + -### method `ChangeFdCommand.pre_load` +## function `ChangeFdCommand.pre_load` ```python pre_load() → None @@ -3961,9 +3961,9 @@ pre_load() → None --- - + -### method `ChangeFdCommand.usage` +## function `ChangeFdCommand.usage` ```python usage() → None @@ -3979,9 +3979,9 @@ usage() → None ## class `ChangePermissionBreakpoint` When hit, this temporary breakpoint will restore the original code, and position $pc correctly. - + -### method `ChangePermissionBreakpoint.__init__` +## function `ChangePermissionBreakpoint.__init__` ```python __init__(loc: str, code: ByteString, pc: int) → None @@ -3996,9 +3996,9 @@ __init__(loc: str, code: ByteString, pc: int) → None --- - + -### method `ChangePermissionBreakpoint.stop` +## function `ChangePermissionBreakpoint.stop` ```python stop() → bool @@ -4014,9 +4014,9 @@ stop() → bool ## class `ChangePermissionCommand` Change a page permission. By default, it will change it to 7 (RWX). - + -### method `ChangePermissionCommand.__init__` +## function `ChangePermissionCommand.__init__` ```python __init__() → None @@ -4037,9 +4037,9 @@ Return the list of settings for this command. --- - + -### method `ChangePermissionCommand.add_setting` +## function `ChangePermissionCommand.add_setting` ```python add_setting( @@ -4053,9 +4053,9 @@ add_setting( --- - + -### method `ChangePermissionCommand.del_setting` +## function `ChangePermissionCommand.del_setting` ```python del_setting(name: str) → None @@ -4065,9 +4065,9 @@ del_setting(name: str) → None --- - + -### method `ChangePermissionCommand.do_invoke` +## function `ChangePermissionCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -4079,9 +4079,9 @@ do_invoke(argv: List) → None --- - + -### method `ChangePermissionCommand.get_setting` +## function `ChangePermissionCommand.get_setting` ```python get_setting(name) @@ -4091,9 +4091,9 @@ get_setting(name) --- - + -### method `ChangePermissionCommand.get_stub_by_arch` +## function `ChangePermissionCommand.get_stub_by_arch` ```python get_stub_by_arch(addr: int, size: int, perm) → Union[str, bytearray, NoneType] @@ -4105,9 +4105,9 @@ get_stub_by_arch(addr: int, size: int, perm) → Union[str, bytearray, NoneType] --- - + -### method `ChangePermissionCommand.has_setting` +## function `ChangePermissionCommand.has_setting` ```python has_setting(name: str) → bool @@ -4117,9 +4117,9 @@ has_setting(name: str) → bool --- - + -### method `ChangePermissionCommand.invoke` +## function `ChangePermissionCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -4131,9 +4131,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ChangePermissionCommand.post_load` +## function `ChangePermissionCommand.post_load` ```python post_load() → None @@ -4145,9 +4145,9 @@ post_load() → None --- - + -### method `ChangePermissionCommand.pre_load` +## function `ChangePermissionCommand.pre_load` ```python pre_load() → None @@ -4159,9 +4159,9 @@ pre_load() → None --- - + -### method `ChangePermissionCommand.usage` +## function `ChangePermissionCommand.usage` ```python usage() → None @@ -4182,9 +4182,9 @@ Checksec the security properties of the current executable or passed as argument - Glibc Stack Canaries - Fortify Source - + -### method `ChecksecCommand.__init__` +## function `ChecksecCommand.__init__` ```python __init__() → None @@ -4205,9 +4205,9 @@ Return the list of settings for this command. --- - + -### method `ChecksecCommand.add_setting` +## function `ChecksecCommand.add_setting` ```python add_setting( @@ -4221,9 +4221,9 @@ add_setting( --- - + -### method `ChecksecCommand.del_setting` +## function `ChecksecCommand.del_setting` ```python del_setting(name: str) → None @@ -4233,9 +4233,9 @@ del_setting(name: str) → None --- - + -### method `ChecksecCommand.do_invoke` +## function `ChecksecCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -4247,9 +4247,9 @@ do_invoke(argv: List) → None --- - + -### method `ChecksecCommand.get_setting` +## function `ChecksecCommand.get_setting` ```python get_setting(name) @@ -4259,9 +4259,9 @@ get_setting(name) --- - + -### method `ChecksecCommand.has_setting` +## function `ChecksecCommand.has_setting` ```python has_setting(name: str) → bool @@ -4271,9 +4271,9 @@ has_setting(name: str) → bool --- - + -### method `ChecksecCommand.invoke` +## function `ChecksecCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -4285,9 +4285,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ChecksecCommand.post_load` +## function `ChecksecCommand.post_load` ```python post_load() → None @@ -4299,9 +4299,9 @@ post_load() → None --- - + -### method `ChecksecCommand.pre_load` +## function `ChecksecCommand.pre_load` ```python pre_load() → None @@ -4313,9 +4313,9 @@ pre_load() → None --- - + -### method `ChecksecCommand.print_security_properties` +## function `ChecksecCommand.print_security_properties` ```python print_security_properties(filename: str) → None @@ -4327,9 +4327,9 @@ print_security_properties(filename: str) → None --- - + -### method `ChecksecCommand.usage` +## function `ChecksecCommand.usage` ```python usage() → None @@ -4350,9 +4350,9 @@ Used to colorify terminal output. --- - + -### method `Color.blinkify` +## function `Color.blinkify` ```python blinkify(msg: str) → str @@ -4364,9 +4364,9 @@ blinkify(msg: str) → str --- - + -### method `Color.blueify` +## function `Color.blueify` ```python blueify(msg: str) → str @@ -4378,9 +4378,9 @@ blueify(msg: str) → str --- - + -### method `Color.boldify` +## function `Color.boldify` ```python boldify(msg: str) → str @@ -4392,9 +4392,9 @@ boldify(msg: str) → str --- - + -### method `Color.colorify` +## function `Color.colorify` ```python colorify(text: str, attrs: str) → str @@ -4404,9 +4404,9 @@ Color text according to the given attributes. --- - + -### method `Color.cyanify` +## function `Color.cyanify` ```python cyanify(msg: str) → str @@ -4418,9 +4418,9 @@ cyanify(msg: str) → str --- - + -### method `Color.grayify` +## function `Color.grayify` ```python grayify(msg: str) → str @@ -4432,9 +4432,9 @@ grayify(msg: str) → str --- - + -### method `Color.greenify` +## function `Color.greenify` ```python greenify(msg: str) → str @@ -4446,9 +4446,9 @@ greenify(msg: str) → str --- - + -### method `Color.highlightify` +## function `Color.highlightify` ```python highlightify(msg: str) → str @@ -4460,9 +4460,9 @@ highlightify(msg: str) → str --- - + -### method `Color.light_grayify` +## function `Color.light_grayify` ```python light_grayify(msg: str) → str @@ -4474,9 +4474,9 @@ light_grayify(msg: str) → str --- - + -### method `Color.pinkify` +## function `Color.pinkify` ```python pinkify(msg: str) → str @@ -4488,9 +4488,9 @@ pinkify(msg: str) → str --- - + -### method `Color.redify` +## function `Color.redify` ```python redify(msg: str) → str @@ -4502,9 +4502,9 @@ redify(msg: str) → str --- - + -### method `Color.underlinify` +## function `Color.underlinify` ```python underlinify(msg: str) → str @@ -4516,9 +4516,9 @@ underlinify(msg: str) → str --- - + -### method `Color.yellowify` +## function `Color.yellowify` ```python yellowify(msg: str) → str @@ -4534,9 +4534,9 @@ 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. - + -### method `ContextCommand.__init__` +## function `ContextCommand.__init__` ```python __init__() → None @@ -4557,9 +4557,9 @@ Return the list of settings for this command. --- - + -### method `ContextCommand.add_setting` +## function `ContextCommand.add_setting` ```python add_setting( @@ -4573,9 +4573,9 @@ add_setting( --- - + -### method `ContextCommand.addr_has_breakpoint` +## function `ContextCommand.addr_has_breakpoint` ```python addr_has_breakpoint(address: int, bp_locations: List[str]) → bool @@ -4587,9 +4587,9 @@ addr_has_breakpoint(address: int, bp_locations: List[str]) → bool --- - + -### method `ContextCommand.context_additional_information` +## function `ContextCommand.context_additional_information` ```python context_additional_information() → None @@ -4601,9 +4601,9 @@ context_additional_information() → None --- - + -### method `ContextCommand.context_args` +## function `ContextCommand.context_args` ```python context_args() → None @@ -4615,9 +4615,9 @@ context_args() → None --- - + -### method `ContextCommand.context_code` +## function `ContextCommand.context_code` ```python context_code() → None @@ -4629,9 +4629,9 @@ context_code() → None --- - + -### method `ContextCommand.context_memory` +## function `ContextCommand.context_memory` ```python context_memory() → None @@ -4643,9 +4643,9 @@ context_memory() → None --- - + -### method `ContextCommand.context_regs` +## function `ContextCommand.context_regs` ```python context_regs() → None @@ -4657,9 +4657,9 @@ context_regs() → None --- - + -### method `ContextCommand.context_source` +## function `ContextCommand.context_source` ```python context_source() → None @@ -4671,9 +4671,9 @@ context_source() → None --- - + -### method `ContextCommand.context_stack` +## function `ContextCommand.context_stack` ```python context_stack() → None @@ -4685,9 +4685,9 @@ context_stack() → None --- - + -### method `ContextCommand.context_threads` +## function `ContextCommand.context_threads` ```python context_threads() → None @@ -4699,9 +4699,9 @@ context_threads() → None --- - + -### method `ContextCommand.context_title` +## function `ContextCommand.context_title` ```python context_title(m: Optional[str]) → None @@ -4713,9 +4713,9 @@ context_title(m: Optional[str]) → None --- - + -### method `ContextCommand.context_trace` +## function `ContextCommand.context_trace` ```python context_trace() → None @@ -4727,9 +4727,9 @@ context_trace() → None --- - + -### method `ContextCommand.del_setting` +## function `ContextCommand.del_setting` ```python del_setting(name: str) → None @@ -4739,9 +4739,9 @@ del_setting(name: str) → None --- - + -### method `ContextCommand.do_invoke` +## function `ContextCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -4753,9 +4753,9 @@ do_invoke(argv: List) → None --- - + -### method `ContextCommand.empty_extra_messages` +## function `ContextCommand.empty_extra_messages` ```python empty_extra_messages(_) → None @@ -4767,9 +4767,9 @@ empty_extra_messages(_) → None --- - + -### method `ContextCommand.get_pc_context_info` +## function `ContextCommand.get_pc_context_info` ```python get_pc_context_info(pc: int, line: str) → str @@ -4781,9 +4781,9 @@ get_pc_context_info(pc: int, line: str) → str --- - + -### method `ContextCommand.get_setting` +## function `ContextCommand.get_setting` ```python get_setting(name) @@ -4793,9 +4793,9 @@ get_setting(name) --- - + -### method `ContextCommand.has_setting` +## function `ContextCommand.has_setting` ```python has_setting(name: str) → bool @@ -4805,9 +4805,9 @@ has_setting(name: str) → bool --- - + -### method `ContextCommand.invoke` +## function `ContextCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -4819,9 +4819,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ContextCommand.line_has_breakpoint` +## function `ContextCommand.line_has_breakpoint` ```python line_has_breakpoint( @@ -4837,9 +4837,9 @@ line_has_breakpoint( --- - + -### method `ContextCommand.post_load` +## function `ContextCommand.post_load` ```python post_load() → None @@ -4851,9 +4851,9 @@ post_load() → None --- - + -### method `ContextCommand.pre_load` +## function `ContextCommand.pre_load` ```python pre_load() → None @@ -4865,9 +4865,9 @@ pre_load() → None --- - + -### method `ContextCommand.print_arguments_from_symbol` +## function `ContextCommand.print_arguments_from_symbol` ```python print_arguments_from_symbol(function_name: str, symbol) → None @@ -4877,9 +4877,9 @@ If symbols were found, parse them and print the argument adequately. --- - + -### method `ContextCommand.print_guessed_arguments` +## function `ContextCommand.print_guessed_arguments` ```python print_guessed_arguments(function_name: str) → None @@ -4889,9 +4889,9 @@ When no symbol, read the current basic block and look for "interesting" instruct --- - + -### method `ContextCommand.show_legend` +## function `ContextCommand.show_legend` ```python show_legend() → None @@ -4903,9 +4903,9 @@ show_legend() → None --- - + -### classmethod `ContextCommand.update_registers` +## function `ContextCommand.update_registers` ```python update_registers(_) → None @@ -4917,9 +4917,9 @@ update_registers(_) → None --- - + -### method `ContextCommand.usage` +## function `ContextCommand.usage` ```python usage() → None @@ -4935,9 +4935,9 @@ usage() → None ## class `DereferenceCommand` Dereference recursively from an address and display information. This acts like WinDBG `dps` command. - + -### method `DereferenceCommand.__init__` +## function `DereferenceCommand.__init__` ```python __init__() → None @@ -4958,9 +4958,9 @@ Return the list of settings for this command. --- - + -### method `DereferenceCommand.add_setting` +## function `DereferenceCommand.add_setting` ```python add_setting( @@ -4974,9 +4974,9 @@ add_setting( --- - + -### method `DereferenceCommand.del_setting` +## function `DereferenceCommand.del_setting` ```python del_setting(name: str) → None @@ -4986,9 +4986,9 @@ del_setting(name: str) → None --- - + -### function `DereferenceCommand.wrapper` +## function `DereferenceCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -5000,9 +5000,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `DereferenceCommand.get_setting` +## function `DereferenceCommand.get_setting` ```python get_setting(name) @@ -5012,9 +5012,9 @@ get_setting(name) --- - + -### method `DereferenceCommand.has_setting` +## function `DereferenceCommand.has_setting` ```python has_setting(name: str) → bool @@ -5024,9 +5024,9 @@ has_setting(name: str) → bool --- - + -### method `DereferenceCommand.invoke` +## function `DereferenceCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -5038,9 +5038,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `DereferenceCommand.post_load` +## function `DereferenceCommand.post_load` ```python post_load() → None @@ -5052,9 +5052,9 @@ post_load() → None --- - + -### method `DereferenceCommand.pprint_dereferenced` +## function `DereferenceCommand.pprint_dereferenced` ```python pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) → str @@ -5066,9 +5066,9 @@ pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) → str --- - + -### method `DereferenceCommand.pre_load` +## function `DereferenceCommand.pre_load` ```python pre_load() → None @@ -5080,9 +5080,9 @@ pre_load() → None --- - + -### method `DereferenceCommand.usage` +## function `DereferenceCommand.usage` ```python usage() → None @@ -5098,9 +5098,9 @@ usage() → None ## class `DetailRegistersCommand` Display full details on one, many or all registers value from current architecture. - + -### method `DetailRegistersCommand.__init__` +## function `DetailRegistersCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -5121,9 +5121,9 @@ Return the list of settings for this command. --- - + -### method `DetailRegistersCommand.add_setting` +## function `DetailRegistersCommand.add_setting` ```python add_setting( @@ -5137,9 +5137,9 @@ add_setting( --- - + -### method `DetailRegistersCommand.del_setting` +## function `DetailRegistersCommand.del_setting` ```python del_setting(name: str) → None @@ -5149,9 +5149,9 @@ del_setting(name: str) → None --- - + -### function `DetailRegistersCommand.wrapper` +## function `DetailRegistersCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -5163,9 +5163,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `DetailRegistersCommand.get_setting` +## function `DetailRegistersCommand.get_setting` ```python get_setting(name) @@ -5175,9 +5175,9 @@ get_setting(name) --- - + -### method `DetailRegistersCommand.has_setting` +## function `DetailRegistersCommand.has_setting` ```python has_setting(name: str) → bool @@ -5187,9 +5187,9 @@ has_setting(name: str) → bool --- - + -### method `DetailRegistersCommand.invoke` +## function `DetailRegistersCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -5201,9 +5201,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `DetailRegistersCommand.post_load` +## function `DetailRegistersCommand.post_load` ```python post_load() → None @@ -5215,9 +5215,9 @@ post_load() → None --- - + -### method `DetailRegistersCommand.pre_load` +## function `DetailRegistersCommand.pre_load` ```python pre_load() → None @@ -5229,9 +5229,9 @@ pre_load() → None --- - + -### method `DetailRegistersCommand.usage` +## function `DetailRegistersCommand.usage` ```python usage() → None @@ -5250,9 +5250,9 @@ Basic ELF parsing. Ref: - http://refspecs.freestandards.org/elf/elfspec_ppc.pdf - http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html - + -### method `Elf.__init__` +## function `Elf.__init__` ```python __init__(elf: str = '', minimalist: bool = False) → None @@ -5265,9 +5265,9 @@ Instantiate an ELF object. The default behavior is to create the object by parsi --- - + -### method `Elf.is_valid` +## function `Elf.is_valid` ```python is_valid() → bool @@ -5279,9 +5279,9 @@ is_valid() → bool --- - + -### method `Elf.read` +## function `Elf.read` ```python read(size) @@ -5293,9 +5293,9 @@ read(size) --- - + -### method `Elf.seek` +## function `Elf.seek` ```python seek(off: int) → None @@ -5311,9 +5311,9 @@ 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. - + -### method `ElfInfoCommand.__init__` +## function `ElfInfoCommand.__init__` ```python __init__() → None @@ -5334,9 +5334,9 @@ Return the list of settings for this command. --- - + -### method `ElfInfoCommand.add_setting` +## function `ElfInfoCommand.add_setting` ```python add_setting( @@ -5350,9 +5350,9 @@ add_setting( --- - + -### method `ElfInfoCommand.del_setting` +## function `ElfInfoCommand.del_setting` ```python del_setting(name: str) → None @@ -5362,9 +5362,9 @@ del_setting(name: str) → None --- - + -### function `ElfInfoCommand.wrapper` +## function `ElfInfoCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -5376,9 +5376,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `ElfInfoCommand.get_setting` +## function `ElfInfoCommand.get_setting` ```python get_setting(name) @@ -5388,9 +5388,9 @@ get_setting(name) --- - + -### method `ElfInfoCommand.has_setting` +## function `ElfInfoCommand.has_setting` ```python has_setting(name: str) → bool @@ -5400,9 +5400,9 @@ has_setting(name: str) → bool --- - + -### method `ElfInfoCommand.invoke` +## function `ElfInfoCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -5414,9 +5414,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ElfInfoCommand.post_load` +## function `ElfInfoCommand.post_load` ```python post_load() → None @@ -5428,9 +5428,9 @@ post_load() → None --- - + -### method `ElfInfoCommand.pre_load` +## function `ElfInfoCommand.pre_load` ```python pre_load() → None @@ -5442,9 +5442,9 @@ pre_load() → None --- - + -### method `ElfInfoCommand.usage` +## function `ElfInfoCommand.usage` ```python usage() → None @@ -5469,9 +5469,9 @@ An enumeration. ## class `EntryBreakBreakpoint` Breakpoint used internally to stop execution at the most convenient entry point. - + -### method `EntryBreakBreakpoint.__init__` +## function `EntryBreakBreakpoint.__init__` ```python __init__(location: str) → None @@ -5486,9 +5486,9 @@ __init__(location: str) → None --- - + -### method `EntryBreakBreakpoint.stop` +## function `EntryBreakBreakpoint.stop` ```python stop() → bool @@ -5504,9 +5504,9 @@ 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`. - + -### method `EntryPointBreakCommand.__init__` +## function `EntryPointBreakCommand.__init__` ```python __init__() → None @@ -5527,9 +5527,9 @@ Return the list of settings for this command. --- - + -### method `EntryPointBreakCommand.add_setting` +## function `EntryPointBreakCommand.add_setting` ```python add_setting( @@ -5543,9 +5543,9 @@ add_setting( --- - + -### method `EntryPointBreakCommand.del_setting` +## function `EntryPointBreakCommand.del_setting` ```python del_setting(name: str) → None @@ -5555,9 +5555,9 @@ del_setting(name: str) → None --- - + -### method `EntryPointBreakCommand.do_invoke` +## function `EntryPointBreakCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -5569,9 +5569,9 @@ do_invoke(argv: List) → None --- - + -### method `EntryPointBreakCommand.get_setting` +## function `EntryPointBreakCommand.get_setting` ```python get_setting(name) @@ -5581,9 +5581,9 @@ get_setting(name) --- - + -### method `EntryPointBreakCommand.has_setting` +## function `EntryPointBreakCommand.has_setting` ```python has_setting(name: str) → bool @@ -5593,9 +5593,9 @@ has_setting(name: str) → bool --- - + -### method `EntryPointBreakCommand.invoke` +## function `EntryPointBreakCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -5607,9 +5607,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `EntryPointBreakCommand.post_load` +## function `EntryPointBreakCommand.post_load` ```python post_load() → None @@ -5621,9 +5621,9 @@ post_load() → None --- - + -### method `EntryPointBreakCommand.pre_load` +## function `EntryPointBreakCommand.pre_load` ```python pre_load() → None @@ -5635,9 +5635,9 @@ pre_load() → None --- - + -### method `EntryPointBreakCommand.set_init_tbreak` +## function `EntryPointBreakCommand.set_init_tbreak` ```python set_init_tbreak(addr: int) → EntryBreakBreakpoint @@ -5649,9 +5649,9 @@ set_init_tbreak(addr: int) → EntryBreakBreakpoint --- - + -### method `EntryPointBreakCommand.set_init_tbreak_pie` +## function `EntryPointBreakCommand.set_init_tbreak_pie` ```python set_init_tbreak_pie(addr: int, argv: List[str]) → EntryBreakBreakpoint @@ -5663,9 +5663,9 @@ set_init_tbreak_pie(addr: int, argv: List[str]) → EntryBreakBreakpoint --- - + -### method `EntryPointBreakCommand.usage` +## function `EntryPointBreakCommand.usage` ```python usage() → None @@ -5681,9 +5681,9 @@ usage() → None ## class `FlagsCommand` Edit flags in a human friendly way. - + -### method `FlagsCommand.__init__` +## function `FlagsCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -5704,9 +5704,9 @@ Return the list of settings for this command. --- - + -### method `FlagsCommand.add_setting` +## function `FlagsCommand.add_setting` ```python add_setting( @@ -5720,9 +5720,9 @@ add_setting( --- - + -### method `FlagsCommand.del_setting` +## function `FlagsCommand.del_setting` ```python del_setting(name: str) → None @@ -5732,9 +5732,9 @@ del_setting(name: str) → None --- - + -### method `FlagsCommand.do_invoke` +## function `FlagsCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -5746,9 +5746,9 @@ do_invoke(argv: List) → None --- - + -### method `FlagsCommand.get_setting` +## function `FlagsCommand.get_setting` ```python get_setting(name) @@ -5758,9 +5758,9 @@ get_setting(name) --- - + -### method `FlagsCommand.has_setting` +## function `FlagsCommand.has_setting` ```python has_setting(name: str) → bool @@ -5770,9 +5770,9 @@ has_setting(name: str) → bool --- - + -### method `FlagsCommand.invoke` +## function `FlagsCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -5784,9 +5784,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `FlagsCommand.post_load` +## function `FlagsCommand.post_load` ```python post_load() → None @@ -5798,9 +5798,9 @@ post_load() → None --- - + -### method `FlagsCommand.pre_load` +## function `FlagsCommand.pre_load` ```python pre_load() → None @@ -5812,9 +5812,9 @@ pre_load() → None --- - + -### method `FlagsCommand.usage` +## function `FlagsCommand.usage` ```python usage() → None @@ -5830,9 +5830,9 @@ usage() → None ## class `FormatStringBreakpoint` Inspect stack for format string. - + -### method `FormatStringBreakpoint.__init__` +## function `FormatStringBreakpoint.__init__` ```python __init__(spec: str, num_args: int) → None @@ -5847,9 +5847,9 @@ __init__(spec: str, num_args: int) → None --- - + -### method `FormatStringBreakpoint.stop` +## function `FormatStringBreakpoint.stop` ```python stop() → bool @@ -5865,9 +5865,9 @@ 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. - + -### method `FormatStringSearchCommand.__init__` +## function `FormatStringSearchCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -5888,9 +5888,9 @@ Return the list of settings for this command. --- - + -### method `FormatStringSearchCommand.add_setting` +## function `FormatStringSearchCommand.add_setting` ```python add_setting( @@ -5904,9 +5904,9 @@ add_setting( --- - + -### method `FormatStringSearchCommand.del_setting` +## function `FormatStringSearchCommand.del_setting` ```python del_setting(name: str) → None @@ -5916,9 +5916,9 @@ del_setting(name: str) → None --- - + -### method `FormatStringSearchCommand.do_invoke` +## function `FormatStringSearchCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -5930,9 +5930,9 @@ do_invoke(argv: List) → None --- - + -### method `FormatStringSearchCommand.get_setting` +## function `FormatStringSearchCommand.get_setting` ```python get_setting(name) @@ -5942,9 +5942,9 @@ get_setting(name) --- - + -### method `FormatStringSearchCommand.has_setting` +## function `FormatStringSearchCommand.has_setting` ```python has_setting(name: str) → bool @@ -5954,9 +5954,9 @@ has_setting(name: str) → bool --- - + -### method `FormatStringSearchCommand.invoke` +## function `FormatStringSearchCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -5968,9 +5968,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `FormatStringSearchCommand.post_load` +## function `FormatStringSearchCommand.post_load` ```python post_load() → None @@ -5982,9 +5982,9 @@ post_load() → None --- - + -### method `FormatStringSearchCommand.pre_load` +## function `FormatStringSearchCommand.pre_load` ```python pre_load() → None @@ -5996,9 +5996,9 @@ pre_load() → None --- - + -### method `FormatStringSearchCommand.usage` +## function `FormatStringSearchCommand.usage` ```python usage() → None @@ -6021,9 +6021,9 @@ usage() → None --- - + -### method `GdbRemoveReadlineFinder.find_module` +## function `GdbRemoveReadlineFinder.find_module` ```python find_module(fullname, path=None) @@ -6035,9 +6035,9 @@ find_module(fullname, path=None) --- - + -### method `GdbRemoveReadlineFinder.load_module` +## function `GdbRemoveReadlineFinder.load_module` ```python load_module(fullname) @@ -6053,9 +6053,9 @@ load_module(fullname) ## class `Gef` The GEF root class, which serves as a base classe for all the attributes for the debugging session (architecture, memory, settings, etc.). - + -### method `Gef.__init__` +## function `Gef.__init__` ```python __init__() → None @@ -6070,9 +6070,9 @@ __init__() → None --- - + -### method `Gef.reinitialize_managers` +## function `Gef.reinitialize_managers` ```python reinitialize_managers() → None @@ -6082,9 +6082,9 @@ Reinitialize the managers. Avoid calling this function directly, using `pi reset --- - + -### method `Gef.reset_caches` +## function `Gef.reset_caches` ```python reset_caches() → None @@ -6094,9 +6094,9 @@ Recursively clean the cache of all the managers. Avoid calling this function dir --- - + -### method `Gef.setup` +## function `Gef.setup` ```python setup() → None @@ -6110,9 +6110,9 @@ Setup initialize the runtime setup, which may require for the `gef` to be not No ## class `GefAlias` Simple aliasing wrapper because GDB doesn't do what it should. - + -### method `GefAlias.__init__` +## function `GefAlias.__init__` ```python __init__(alias, command, completer_class=0, command_class=-1) → None @@ -6127,9 +6127,9 @@ __init__(alias, command, completer_class=0, command_class=-1) → None --- - + -### method `GefAlias.invoke` +## function `GefAlias.invoke` ```python invoke(args, from_tty) → None @@ -6141,9 +6141,9 @@ invoke(args, from_tty) → None --- - + -### method `GefAlias.lookup_command` +## function `GefAlias.lookup_command` ```python lookup_command(cmd: str) → Union[Tuple[str, Type, Any], NoneType] @@ -6159,9 +6159,9 @@ lookup_command(cmd: str) → Union[Tuple[str, Type, Any], NoneType] ## class `GefCommand` GEF main command: view all new commands by typing `gef`. - + -### method `GefCommand.__init__` +## function `GefCommand.__init__` ```python __init__() → None @@ -6184,9 +6184,9 @@ __init__() → None --- - + -### method `GefCommand.add_context_pane` +## function `GefCommand.add_context_pane` ```python add_context_pane( @@ -6200,9 +6200,9 @@ Add a new context pane to ContextCommand. --- - + -### method `GefCommand.invoke` +## function `GefCommand.invoke` ```python invoke(args, from_tty) → None @@ -6214,9 +6214,9 @@ invoke(args, from_tty) → None --- - + -### method `GefCommand.load` +## function `GefCommand.load` ```python load(initial: bool = False) → None @@ -6226,9 +6226,9 @@ Load all the commands and functions defined by GEF into GDB. --- - + -### method `GefCommand.setup` +## function `GefCommand.setup` ```python setup() → None @@ -6244,9 +6244,9 @@ setup() → 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). - + -### method `GefConfigCommand.__init__` +## function `GefConfigCommand.__init__` ```python __init__(loaded_commands, *args, **kwargs) → None @@ -6261,9 +6261,9 @@ __init__(loaded_commands, *args, **kwargs) → None --- - + -### method `GefConfigCommand.complete` +## function `GefConfigCommand.complete` ```python complete(text: str, word: str) → List[str] @@ -6275,9 +6275,9 @@ complete(text: str, word: str) → List[str] --- - + -### method `GefConfigCommand.invoke` +## function `GefConfigCommand.invoke` ```python invoke(args: str, from_tty) → None @@ -6289,9 +6289,9 @@ invoke(args: str, from_tty) → None --- - + -### method `GefConfigCommand.print_setting` +## function `GefConfigCommand.print_setting` ```python print_setting(plugin_name: str, verbose: bool = False) → None @@ -6303,9 +6303,9 @@ print_setting(plugin_name: str, verbose: bool = False) → None --- - + -### method `GefConfigCommand.print_settings` +## function `GefConfigCommand.print_settings` ```python print_settings() → None @@ -6317,9 +6317,9 @@ print_settings() → None --- - + -### method `GefConfigCommand.set_setting` +## function `GefConfigCommand.set_setting` ```python set_setting(argv: Tuple[str, Any]) → None @@ -6335,9 +6335,9 @@ set_setting(argv: Tuple[str, Any]) → None ## class `GefFunctionsCommand` List the convenience functions provided by GEF. - + -### method `GefFunctionsCommand.__init__` +## function `GefFunctionsCommand.__init__` ```python __init__() → None @@ -6358,9 +6358,9 @@ Return the list of settings for this command. --- - + -### method `GefFunctionsCommand.add_function_to_doc` +## function `GefFunctionsCommand.add_function_to_doc` ```python add_function_to_doc(function) → None @@ -6370,9 +6370,9 @@ Add function to documentation. --- - + -### method `GefFunctionsCommand.add_setting` +## function `GefFunctionsCommand.add_setting` ```python add_setting( @@ -6386,9 +6386,9 @@ add_setting( --- - + -### method `GefFunctionsCommand.del_setting` +## function `GefFunctionsCommand.del_setting` ```python del_setting(name: str) → None @@ -6398,9 +6398,9 @@ del_setting(name: str) → None --- - + -### method `GefFunctionsCommand.do_invoke` +## function `GefFunctionsCommand.do_invoke` ```python do_invoke(argv) → None @@ -6412,9 +6412,9 @@ do_invoke(argv) → None --- - + -### method `GefFunctionsCommand.get_setting` +## function `GefFunctionsCommand.get_setting` ```python get_setting(name) @@ -6424,9 +6424,9 @@ get_setting(name) --- - + -### method `GefFunctionsCommand.has_setting` +## function `GefFunctionsCommand.has_setting` ```python has_setting(name: str) → bool @@ -6436,9 +6436,9 @@ has_setting(name: str) → bool --- - + -### method `GefFunctionsCommand.invoke` +## function `GefFunctionsCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -6450,9 +6450,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GefFunctionsCommand.post_load` +## function `GefFunctionsCommand.post_load` ```python post_load() → None @@ -6464,9 +6464,9 @@ post_load() → None --- - + -### method `GefFunctionsCommand.pre_load` +## function `GefFunctionsCommand.pre_load` ```python pre_load() → None @@ -6478,9 +6478,9 @@ pre_load() → None --- - + -### method `GefFunctionsCommand.setup` +## function `GefFunctionsCommand.setup` ```python setup() → None @@ -6492,9 +6492,9 @@ setup() → None --- - + -### method `GefFunctionsCommand.usage` +## function `GefFunctionsCommand.usage` ```python usage() → None @@ -6510,9 +6510,9 @@ usage() → None ## class `GefHeapManager` Class managing session heap. - + -### method `GefHeapManager.__init__` +## function `GefHeapManager.__init__` ```python __init__() → None @@ -6567,9 +6567,9 @@ __init__() → None --- - + -### method `GefHeapManager.reset_caches` +## function `GefHeapManager.reset_caches` ```python reset_caches() → None @@ -6585,9 +6585,9 @@ reset_caches() → None ## class `GefHelpCommand` GEF help sub-command. - + -### method `GefHelpCommand.__init__` +## function `GefHelpCommand.__init__` ```python __init__(commands: List[Tuple[str, Any, Any]], *args, **kwargs) → None @@ -6602,9 +6602,9 @@ __init__(commands: List[Tuple[str, Any, Any]], *args, **kwargs) → None --- - + -### method `GefHelpCommand.add_command_to_doc` +## function `GefHelpCommand.add_command_to_doc` ```python add_command_to_doc(command: Tuple[str, Any, Any]) → None @@ -6614,9 +6614,9 @@ Add command to GEF documentation. --- - + -### method `GefHelpCommand.generate_help` +## function `GefHelpCommand.generate_help` ```python generate_help(commands: List[Tuple[str, Type, Any]]) → None @@ -6626,9 +6626,9 @@ Generate builtin commands documentation. --- - + -### method `GefHelpCommand.invoke` +## function `GefHelpCommand.invoke` ```python invoke(args, from_tty) → None @@ -6640,9 +6640,9 @@ invoke(args, from_tty) → None --- - + -### method `GefHelpCommand.refresh` +## function `GefHelpCommand.refresh` ```python refresh() → None @@ -6663,9 +6663,9 @@ Refresh the documentation. --- - + -### method `GefManager.reset_caches` +## function `GefManager.reset_caches` ```python reset_caches() → None @@ -6679,9 +6679,9 @@ Reset the LRU-cached attributes ## class `GefMemoryManager` Class that manages memory access for gef. - + -### method `GefMemoryManager.__init__` +## function `GefMemoryManager.__init__` ```python __init__() → None @@ -6704,9 +6704,9 @@ __init__() → None --- - + -### method `GefMemoryManager.read` +## function `GefMemoryManager.read` ```python read(addr: int, length: int = 16) → bytes @@ -6716,9 +6716,9 @@ Return a `length` long byte array with the copy of the process memory at `addr`. --- - + -### method `GefMemoryManager.read_ascii_string` +## function `GefMemoryManager.read_ascii_string` ```python read_ascii_string(address: int) → Union[str, NoneType] @@ -6728,9 +6728,9 @@ Read an ASCII string from memory --- - + -### method `GefMemoryManager.read_cstring` +## function `GefMemoryManager.read_cstring` ```python read_cstring( @@ -6744,9 +6744,9 @@ Return a C-string read from memory. --- - + -### method `GefMemoryManager.read_integer` +## function `GefMemoryManager.read_integer` ```python read_integer(addr: int) → int @@ -6756,9 +6756,9 @@ Return an integer read from memory. --- - + -### method `GefMemoryManager.reset_caches` +## function `GefMemoryManager.reset_caches` ```python reset_caches() → None @@ -6770,9 +6770,9 @@ reset_caches() → None --- - + -### method `GefMemoryManager.write` +## function `GefMemoryManager.write` ```python write(address: int, buffer: ByteString, length: int = 16) @@ -6786,9 +6786,9 @@ 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. - + -### method `GefMissingCommand.__init__` +## function `GefMissingCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -6803,9 +6803,9 @@ __init__(*args, **kwargs) → None --- - + -### method `GefMissingCommand.invoke` +## function `GefMissingCommand.invoke` ```python invoke(args, from_tty) → None @@ -6821,9 +6821,9 @@ invoke(args, from_tty) → None ## class `GefRestoreCommand` GEF restore sub-command. Loads settings from file '~/.gef.rc' and apply them to the configuration of GEF. - + -### method `GefRestoreCommand.__init__` +## function `GefRestoreCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -6838,9 +6838,9 @@ __init__(*args, **kwargs) → None --- - + -### method `GefRestoreCommand.invoke` +## function `GefRestoreCommand.invoke` ```python invoke(args: str, from_tty) → None @@ -6856,9 +6856,9 @@ invoke(args: str, from_tty) → None ## 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`. - + -### method `GefRunCommand.__init__` +## function `GefRunCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -6873,9 +6873,9 @@ __init__(*args, **kwargs) → None --- - + -### method `GefRunCommand.invoke` +## function `GefRunCommand.invoke` ```python invoke(args, from_tty) → None @@ -6891,9 +6891,9 @@ invoke(args, from_tty) → None ## class `GefSaveCommand` GEF save sub-command. Saves the current configuration of GEF to disk (by default in file '~/.gef.rc'). - + -### method `GefSaveCommand.__init__` +## function `GefSaveCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -6908,9 +6908,9 @@ __init__(*args, **kwargs) → None --- - + -### method `GefSaveCommand.invoke` +## function `GefSaveCommand.invoke` ```python invoke(args, from_tty) → None @@ -6926,9 +6926,9 @@ invoke(args, from_tty) → None ## class `GefSessionManager` Class managing the runtime properties of GEF. - + -### method `GefSessionManager.__init__` +## function `GefSessionManager.__init__` ```python __init__() → None @@ -6981,9 +6981,9 @@ Return the PID of the target process. --- - + -### method `GefSessionManager.reset_caches` +## function `GefSessionManager.reset_caches` ```python reset_caches() → None @@ -6999,9 +6999,9 @@ reset_caches() → None ## class `GefSetCommand` Override GDB set commands with the context from GEF. - + -### method `GefSetCommand.__init__` +## function `GefSetCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -7016,9 +7016,9 @@ __init__(*args, **kwargs) → None --- - + -### method `GefSetCommand.invoke` +## function `GefSetCommand.invoke` ```python invoke(args, from_tty) → None @@ -7034,9 +7034,9 @@ invoke(args, from_tty) → None ## class `GefSetting` Basic class for storing gef settings as objects - + -### method `GefSetting.__init__` +## function `GefSetting.__init__` ```python __init__( @@ -7064,9 +7064,9 @@ GefSettings acts as a dict where the global settings are stored and can be read, --- - + -### method `GefSettingsManager.raw_entry` +## function `GefSettingsManager.raw_entry` ```python raw_entry(name: str) → Any @@ -7082,9 +7082,9 @@ raw_entry(name: str) → Any ## class `GefThemeCommand` Customize GEF appearance. - + -### method `GefThemeCommand.__init__` +## function `GefThemeCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -7105,9 +7105,9 @@ Return the list of settings for this command. --- - + -### method `GefThemeCommand.add_setting` +## function `GefThemeCommand.add_setting` ```python add_setting( @@ -7121,9 +7121,9 @@ add_setting( --- - + -### method `GefThemeCommand.del_setting` +## function `GefThemeCommand.del_setting` ```python del_setting(name: str) → None @@ -7133,9 +7133,9 @@ del_setting(name: str) → None --- - + -### method `GefThemeCommand.do_invoke` +## function `GefThemeCommand.do_invoke` ```python do_invoke(args: List) → None @@ -7147,9 +7147,9 @@ do_invoke(args: List) → None --- - + -### method `GefThemeCommand.get_setting` +## function `GefThemeCommand.get_setting` ```python get_setting(name) @@ -7159,9 +7159,9 @@ get_setting(name) --- - + -### method `GefThemeCommand.has_setting` +## function `GefThemeCommand.has_setting` ```python has_setting(name: str) → bool @@ -7171,9 +7171,9 @@ has_setting(name: str) → bool --- - + -### method `GefThemeCommand.invoke` +## function `GefThemeCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -7185,9 +7185,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GefThemeCommand.post_load` +## function `GefThemeCommand.post_load` ```python post_load() → None @@ -7199,9 +7199,9 @@ post_load() → None --- - + -### method `GefThemeCommand.pre_load` +## function `GefThemeCommand.pre_load` ```python pre_load() → None @@ -7213,9 +7213,9 @@ pre_load() → None --- - + -### method `GefThemeCommand.usage` +## function `GefThemeCommand.usage` ```python usage() → None @@ -7231,9 +7231,9 @@ usage() → None ## class `GefTmuxSetup` Setup a confortable tmux debugging environment. - + -### method `GefTmuxSetup.__init__` +## function `GefTmuxSetup.__init__` ```python __init__() → None @@ -7248,9 +7248,9 @@ __init__() → None --- - + -### method `GefTmuxSetup.invoke` +## function `GefTmuxSetup.invoke` ```python invoke(args, from_tty) → None @@ -7262,9 +7262,9 @@ invoke(args, from_tty) → None --- - + -### method `GefTmuxSetup.screen_setup` +## function `GefTmuxSetup.screen_setup` ```python screen_setup() → None @@ -7274,9 +7274,9 @@ Hackish equivalent of the tmux_setup() function for screen. --- - + -### method `GefTmuxSetup.tmux_setup` +## function `GefTmuxSetup.tmux_setup` ```python tmux_setup() → None @@ -7290,9 +7290,9 @@ Prepare the tmux environment by vertically splitting the current pane, and forci ## class `GefUiManager` Class managing UI settings. - + -### method `GefUiManager.__init__` +## function `GefUiManager.__init__` ```python __init__() @@ -7307,9 +7307,9 @@ __init__() --- - + -### method `GefUiManager.reset_caches` +## function `GefUiManager.reset_caches` ```python reset_caches() → None @@ -7370,9 +7370,9 @@ Reset the LRU-cached attributes --- - + -### method `GenericArchitecture.flag_register_to_human` +## function `GenericArchitecture.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → Union[str, NoneType] @@ -7384,9 +7384,9 @@ flag_register_to_human(val: Optional[int] = None) → Union[str, NoneType] --- - + -### method `GenericArchitecture.get_ith_parameter` +## function `GenericArchitecture.get_ith_parameter` ```python get_ith_parameter( @@ -7399,9 +7399,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `GenericArchitecture.get_ra` +## function `GenericArchitecture.get_ra` ```python get_ra(insn, frame) → Union[int, NoneType] @@ -7413,9 +7413,9 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + -### method `GenericArchitecture.is_branch_taken` +## function `GenericArchitecture.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -7427,9 +7427,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `GenericArchitecture.is_call` +## function `GenericArchitecture.is_call` ```python is_call(insn) → bool @@ -7441,9 +7441,9 @@ is_call(insn) → bool --- - + -### method `GenericArchitecture.is_conditional_branch` +## function `GenericArchitecture.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -7455,9 +7455,9 @@ is_conditional_branch(insn) → bool --- - + -### method `GenericArchitecture.is_ret` +## function `GenericArchitecture.is_ret` ```python is_ret(insn) → bool @@ -7469,9 +7469,9 @@ is_ret(insn) → bool --- - + -### method `GenericArchitecture.register` +## function `GenericArchitecture.register` ```python register(name: str) → Union[int, NoneType] @@ -7487,9 +7487,9 @@ register(name: str) → Union[int, NoneType] ## class `GenericCommand` This is an abstract class for invoking commands, should not be instantiated. - + -### method `GenericCommand.__init__` +## function `GenericCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -7510,9 +7510,9 @@ Return the list of settings for this command. --- - + -### method `GenericCommand.add_setting` +## function `GenericCommand.add_setting` ```python add_setting( @@ -7526,9 +7526,9 @@ add_setting( --- - + -### method `GenericCommand.del_setting` +## function `GenericCommand.del_setting` ```python del_setting(name: str) → None @@ -7538,9 +7538,9 @@ del_setting(name: str) → None --- - + -### method `GenericCommand.do_invoke` +## function `GenericCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -7552,9 +7552,9 @@ do_invoke(argv: List) → None --- - + -### method `GenericCommand.get_setting` +## function `GenericCommand.get_setting` ```python get_setting(name) @@ -7564,9 +7564,9 @@ get_setting(name) --- - + -### method `GenericCommand.has_setting` +## function `GenericCommand.has_setting` ```python has_setting(name: str) → bool @@ -7576,9 +7576,9 @@ has_setting(name: str) → bool --- - + -### method `GenericCommand.invoke` +## function `GenericCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -7590,9 +7590,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GenericCommand.post_load` +## function `GenericCommand.post_load` ```python post_load() → None @@ -7604,9 +7604,9 @@ post_load() → None --- - + -### method `GenericCommand.pre_load` +## function `GenericCommand.pre_load` ```python pre_load() → None @@ -7618,9 +7618,9 @@ pre_load() → None --- - + -### method `GenericCommand.usage` +## function `GenericCommand.usage` ```python usage() → None @@ -7636,9 +7636,9 @@ usage() → None ## class `GenericFunction` This is an abstract class for invoking convenience functions, should not be instantiated. - + -### method `GenericFunction.__init__` +## function `GenericFunction.__init__` ```python __init__() → None @@ -7653,9 +7653,9 @@ __init__() → None --- - + -### method `GenericFunction.arg_to_long` +## function `GenericFunction.arg_to_long` ```python arg_to_long(args: List, index: int, default: int = 0) → int @@ -7667,9 +7667,9 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + -### method `GenericFunction.do_invoke` +## function `GenericFunction.do_invoke` ```python do_invoke(args) → None @@ -7681,9 +7681,9 @@ do_invoke(args) → None --- - + -### method `GenericFunction.invoke` +## function `GenericFunction.invoke` ```python invoke(*args) → int @@ -7699,9 +7699,9 @@ invoke(*args) → int ## class `GlibcArena` Glibc arena class Ref: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1671 - + -### method `GlibcArena.__init__` +## function `GlibcArena.__init__` ```python __init__(addr: str) → None @@ -7716,9 +7716,9 @@ __init__(addr: str) → None --- - + -### method `GlibcArena.bin` +## function `GlibcArena.bin` ```python bin(i: int) → Tuple[int, int] @@ -7730,9 +7730,9 @@ bin(i: int) → Tuple[int, int] --- - + -### method `GlibcArena.fastbin` +## function `GlibcArena.fastbin` ```python fastbin(i: int) @@ -7742,9 +7742,9 @@ Return head chunk in fastbinsY[i]. --- - + -### method `GlibcArena.get_heap_for_ptr` +## function `GlibcArena.get_heap_for_ptr` ```python get_heap_for_ptr(ptr: int) → int @@ -7754,9 +7754,9 @@ Find the corresponding heap for a given pointer (int). See https://github.com/bm --- - + -### method `GlibcArena.get_heap_info_list` +## function `GlibcArena.get_heap_info_list` ```python get_heap_info_list() @@ -7768,9 +7768,9 @@ get_heap_info_list() --- - + -### method `GlibcArena.heap_addr` +## function `GlibcArena.heap_addr` ```python heap_addr(allow_unaligned: bool = False) → Union[int, NoneType] @@ -7782,9 +7782,9 @@ heap_addr(allow_unaligned: bool = False) → Union[int, NoneType] --- - + -### method `GlibcArena.is_main_arena` +## function `GlibcArena.is_main_arena` ```python is_main_arena() → bool @@ -7800,9 +7800,9 @@ is_main_arena() → bool ## 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/. - + -### method `GlibcChunk.__init__` +## function `GlibcChunk.__init__` ```python __init__(addr, from_base=False, allow_unaligned=True) @@ -7865,9 +7865,9 @@ __init__(addr, from_base=False, allow_unaligned=True) --- - + -### method `GlibcChunk.flags_as_string` +## function `GlibcChunk.flags_as_string` ```python flags_as_string() → str @@ -7879,9 +7879,9 @@ flags_as_string() → str --- - + -### method `GlibcChunk.get_bkw_ptr` +## function `GlibcChunk.get_bkw_ptr` ```python get_bkw_ptr() → int @@ -7893,9 +7893,9 @@ get_bkw_ptr() → int --- - + -### method `GlibcChunk.get_chunk_size` +## function `GlibcChunk.get_chunk_size` ```python get_chunk_size() → int @@ -7907,9 +7907,9 @@ get_chunk_size() → int --- - + -### method `GlibcChunk.get_fwd_ptr` +## function `GlibcChunk.get_fwd_ptr` ```python get_fwd_ptr(sll) → int @@ -7921,9 +7921,9 @@ get_fwd_ptr(sll) → int --- - + -### method `GlibcChunk.get_next_chunk` +## function `GlibcChunk.get_next_chunk` ```python get_next_chunk(allow_unaligned: bool = False) @@ -7935,9 +7935,9 @@ get_next_chunk(allow_unaligned: bool = False) --- - + -### method `GlibcChunk.get_next_chunk_addr` +## function `GlibcChunk.get_next_chunk_addr` ```python get_next_chunk_addr() → int @@ -7949,9 +7949,9 @@ get_next_chunk_addr() → int --- - + -### method `GlibcChunk.get_prev_chunk_size` +## function `GlibcChunk.get_prev_chunk_size` ```python get_prev_chunk_size() → int @@ -7963,9 +7963,9 @@ get_prev_chunk_size() → int --- - + -### method `GlibcChunk.get_usable_size` +## function `GlibcChunk.get_usable_size` ```python get_usable_size() → int @@ -7977,9 +7977,9 @@ get_usable_size() → int --- - + -### method `GlibcChunk.has_m_bit` +## function `GlibcChunk.has_m_bit` ```python has_m_bit() → bool @@ -7991,9 +7991,9 @@ has_m_bit() → bool --- - + -### method `GlibcChunk.has_n_bit` +## function `GlibcChunk.has_n_bit` ```python has_n_bit() → bool @@ -8005,9 +8005,9 @@ has_n_bit() → bool --- - + -### method `GlibcChunk.has_p_bit` +## function `GlibcChunk.has_p_bit` ```python has_p_bit() → bool @@ -8019,9 +8019,9 @@ has_p_bit() → bool --- - + -### method `GlibcChunk.is_used` +## function `GlibcChunk.is_used` ```python is_used() → bool @@ -8033,9 +8033,9 @@ Check if the current block is used by: --- - + -### method `GlibcChunk.psprint` +## function `GlibcChunk.psprint` ```python psprint() → str @@ -8047,9 +8047,9 @@ psprint() → str --- - + -### method `GlibcChunk.str_as_alloced` +## function `GlibcChunk.str_as_alloced` ```python str_as_alloced() → str @@ -8061,9 +8061,9 @@ str_as_alloced() → str --- - + -### method `GlibcChunk.str_as_freed` +## function `GlibcChunk.str_as_freed` ```python str_as_freed() → str @@ -8075,9 +8075,9 @@ str_as_freed() → str --- - + -### method `GlibcChunk.str_chunk_size_flag` +## function `GlibcChunk.str_chunk_size_flag` ```python str_chunk_size_flag() → str @@ -8093,9 +8093,9 @@ str_chunk_size_flag() → str ## class `GlibcHeapArenaCommand` Display information on a heap chunk. - + -### method `GlibcHeapArenaCommand.__init__` +## function `GlibcHeapArenaCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -8116,9 +8116,9 @@ Return the list of settings for this command. --- - + -### method `GlibcHeapArenaCommand.add_setting` +## function `GlibcHeapArenaCommand.add_setting` ```python add_setting( @@ -8132,9 +8132,9 @@ add_setting( --- - + -### method `GlibcHeapArenaCommand.del_setting` +## function `GlibcHeapArenaCommand.del_setting` ```python del_setting(name: str) → None @@ -8144,9 +8144,9 @@ del_setting(name: str) → None --- - + -### method `GlibcHeapArenaCommand.do_invoke` +## function `GlibcHeapArenaCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -8158,9 +8158,9 @@ do_invoke(argv: List) → None --- - + -### method `GlibcHeapArenaCommand.get_setting` +## function `GlibcHeapArenaCommand.get_setting` ```python get_setting(name) @@ -8170,9 +8170,9 @@ get_setting(name) --- - + -### method `GlibcHeapArenaCommand.has_setting` +## function `GlibcHeapArenaCommand.has_setting` ```python has_setting(name: str) → bool @@ -8182,9 +8182,9 @@ has_setting(name: str) → bool --- - + -### method `GlibcHeapArenaCommand.invoke` +## function `GlibcHeapArenaCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -8196,9 +8196,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GlibcHeapArenaCommand.post_load` +## function `GlibcHeapArenaCommand.post_load` ```python post_load() → None @@ -8210,9 +8210,9 @@ post_load() → None --- - + -### method `GlibcHeapArenaCommand.pre_load` +## function `GlibcHeapArenaCommand.pre_load` ```python pre_load() → None @@ -8224,9 +8224,9 @@ pre_load() → None --- - + -### method `GlibcHeapArenaCommand.usage` +## function `GlibcHeapArenaCommand.usage` ```python usage() → None @@ -8242,9 +8242,9 @@ 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. - + -### method `GlibcHeapBinsCommand.__init__` +## function `GlibcHeapBinsCommand.__init__` ```python __init__() → None @@ -8265,9 +8265,9 @@ Return the list of settings for this command. --- - + -### method `GlibcHeapBinsCommand.add_setting` +## function `GlibcHeapBinsCommand.add_setting` ```python add_setting( @@ -8281,9 +8281,9 @@ add_setting( --- - + -### method `GlibcHeapBinsCommand.del_setting` +## function `GlibcHeapBinsCommand.del_setting` ```python del_setting(name: str) → None @@ -8293,9 +8293,9 @@ del_setting(name: str) → None --- - + -### method `GlibcHeapBinsCommand.do_invoke` +## function `GlibcHeapBinsCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -8307,9 +8307,9 @@ do_invoke(argv: List) → None --- - + -### method `GlibcHeapBinsCommand.get_setting` +## function `GlibcHeapBinsCommand.get_setting` ```python get_setting(name) @@ -8319,9 +8319,9 @@ get_setting(name) --- - + -### method `GlibcHeapBinsCommand.has_setting` +## function `GlibcHeapBinsCommand.has_setting` ```python has_setting(name: str) → bool @@ -8331,9 +8331,9 @@ has_setting(name: str) → bool --- - + -### method `GlibcHeapBinsCommand.invoke` +## function `GlibcHeapBinsCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -8345,9 +8345,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GlibcHeapBinsCommand.post_load` +## function `GlibcHeapBinsCommand.post_load` ```python post_load() → None @@ -8359,9 +8359,9 @@ post_load() → None --- - + -### method `GlibcHeapBinsCommand.pprint_bin` +## function `GlibcHeapBinsCommand.pprint_bin` ```python pprint_bin(arena_addr: str, index: int, _type: str = '') → int @@ -8373,9 +8373,9 @@ pprint_bin(arena_addr: str, index: int, _type: str = '') → int --- - + -### method `GlibcHeapBinsCommand.pre_load` +## function `GlibcHeapBinsCommand.pre_load` ```python pre_load() → None @@ -8387,9 +8387,9 @@ pre_load() → None --- - + -### method `GlibcHeapBinsCommand.usage` +## function `GlibcHeapBinsCommand.usage` ```python usage() → None @@ -8405,9 +8405,9 @@ usage() → None ## class `GlibcHeapChunkCommand` Display information on a heap chunk. See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123. - + -### method `GlibcHeapChunkCommand.__init__` +## function `GlibcHeapChunkCommand.__init__` ```python __init__() → None @@ -8428,9 +8428,9 @@ Return the list of settings for this command. --- - + -### method `GlibcHeapChunkCommand.add_setting` +## function `GlibcHeapChunkCommand.add_setting` ```python add_setting( @@ -8444,9 +8444,9 @@ add_setting( --- - + -### method `GlibcHeapChunkCommand.del_setting` +## function `GlibcHeapChunkCommand.del_setting` ```python del_setting(name: str) → None @@ -8456,9 +8456,9 @@ del_setting(name: str) → None --- - + -### function `GlibcHeapChunkCommand.wrapper` +## function `GlibcHeapChunkCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -8470,9 +8470,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `GlibcHeapChunkCommand.get_setting` +## function `GlibcHeapChunkCommand.get_setting` ```python get_setting(name) @@ -8482,9 +8482,9 @@ get_setting(name) --- - + -### method `GlibcHeapChunkCommand.has_setting` +## function `GlibcHeapChunkCommand.has_setting` ```python has_setting(name: str) → bool @@ -8494,9 +8494,9 @@ has_setting(name: str) → bool --- - + -### method `GlibcHeapChunkCommand.invoke` +## function `GlibcHeapChunkCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -8508,9 +8508,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GlibcHeapChunkCommand.post_load` +## function `GlibcHeapChunkCommand.post_load` ```python post_load() → None @@ -8522,9 +8522,9 @@ post_load() → None --- - + -### method `GlibcHeapChunkCommand.pre_load` +## function `GlibcHeapChunkCommand.pre_load` ```python pre_load() → None @@ -8536,9 +8536,9 @@ pre_load() → None --- - + -### method `GlibcHeapChunkCommand.usage` +## function `GlibcHeapChunkCommand.usage` ```python usage() → None @@ -8554,9 +8554,9 @@ 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 - + -### method `GlibcHeapChunksCommand.__init__` +## function `GlibcHeapChunksCommand.__init__` ```python __init__() → None @@ -8577,9 +8577,9 @@ Return the list of settings for this command. --- - + -### method `GlibcHeapChunksCommand.add_setting` +## function `GlibcHeapChunksCommand.add_setting` ```python add_setting( @@ -8593,9 +8593,9 @@ add_setting( --- - + -### method `GlibcHeapChunksCommand.del_setting` +## function `GlibcHeapChunksCommand.del_setting` ```python del_setting(name: str) → None @@ -8605,9 +8605,9 @@ del_setting(name: str) → None --- - + -### function `GlibcHeapChunksCommand.wrapper` +## function `GlibcHeapChunksCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -8619,9 +8619,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `GlibcHeapChunksCommand.dump_chunks_arena` +## function `GlibcHeapChunksCommand.dump_chunks_arena` ```python dump_chunks_arena( @@ -8637,9 +8637,9 @@ dump_chunks_arena( --- - + -### method `GlibcHeapChunksCommand.dump_chunks_heap` +## function `GlibcHeapChunksCommand.dump_chunks_heap` ```python dump_chunks_heap( @@ -8656,9 +8656,9 @@ dump_chunks_heap( --- - + -### method `GlibcHeapChunksCommand.get_setting` +## function `GlibcHeapChunksCommand.get_setting` ```python get_setting(name) @@ -8668,9 +8668,9 @@ get_setting(name) --- - + -### method `GlibcHeapChunksCommand.has_setting` +## function `GlibcHeapChunksCommand.has_setting` ```python has_setting(name: str) → bool @@ -8680,9 +8680,9 @@ has_setting(name: str) → bool --- - + -### method `GlibcHeapChunksCommand.invoke` +## function `GlibcHeapChunksCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -8694,9 +8694,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GlibcHeapChunksCommand.post_load` +## function `GlibcHeapChunksCommand.post_load` ```python post_load() → None @@ -8708,9 +8708,9 @@ post_load() → None --- - + -### method `GlibcHeapChunksCommand.pre_load` +## function `GlibcHeapChunksCommand.pre_load` ```python pre_load() → None @@ -8722,9 +8722,9 @@ pre_load() → None --- - + -### method `GlibcHeapChunksCommand.usage` +## function `GlibcHeapChunksCommand.usage` ```python usage() → None @@ -8740,9 +8740,9 @@ usage() → None ## class `GlibcHeapCommand` Base command to get information about the Glibc heap structure. - + -### method `GlibcHeapCommand.__init__` +## function `GlibcHeapCommand.__init__` ```python __init__() → None @@ -8763,9 +8763,9 @@ Return the list of settings for this command. --- - + -### method `GlibcHeapCommand.add_setting` +## function `GlibcHeapCommand.add_setting` ```python add_setting( @@ -8779,9 +8779,9 @@ add_setting( --- - + -### method `GlibcHeapCommand.del_setting` +## function `GlibcHeapCommand.del_setting` ```python del_setting(name: str) → None @@ -8791,9 +8791,9 @@ del_setting(name: str) → None --- - + -### method `GlibcHeapCommand.do_invoke` +## function `GlibcHeapCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -8805,9 +8805,9 @@ do_invoke(argv: List) → None --- - + -### method `GlibcHeapCommand.get_setting` +## function `GlibcHeapCommand.get_setting` ```python get_setting(name) @@ -8817,9 +8817,9 @@ get_setting(name) --- - + -### method `GlibcHeapCommand.has_setting` +## function `GlibcHeapCommand.has_setting` ```python has_setting(name: str) → bool @@ -8829,9 +8829,9 @@ has_setting(name: str) → bool --- - + -### method `GlibcHeapCommand.invoke` +## function `GlibcHeapCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -8843,9 +8843,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GlibcHeapCommand.post_load` +## function `GlibcHeapCommand.post_load` ```python post_load() → None @@ -8857,9 +8857,9 @@ post_load() → None --- - + -### method `GlibcHeapCommand.pre_load` +## function `GlibcHeapCommand.pre_load` ```python pre_load() → None @@ -8871,9 +8871,9 @@ pre_load() → None --- - + -### method `GlibcHeapCommand.usage` +## function `GlibcHeapCommand.usage` ```python usage() → None @@ -8889,9 +8889,9 @@ 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. - + -### method `GlibcHeapFastbinsYCommand.__init__` +## function `GlibcHeapFastbinsYCommand.__init__` ```python __init__() → None @@ -8912,9 +8912,9 @@ Return the list of settings for this command. --- - + -### method `GlibcHeapFastbinsYCommand.add_setting` +## function `GlibcHeapFastbinsYCommand.add_setting` ```python add_setting( @@ -8928,9 +8928,9 @@ add_setting( --- - + -### method `GlibcHeapFastbinsYCommand.del_setting` +## function `GlibcHeapFastbinsYCommand.del_setting` ```python del_setting(name: str) → None @@ -8940,9 +8940,9 @@ del_setting(name: str) → None --- - + -### method `GlibcHeapFastbinsYCommand.do_invoke` +## function `GlibcHeapFastbinsYCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -8954,9 +8954,9 @@ do_invoke(argv: List) → None --- - + -### method `GlibcHeapFastbinsYCommand.get_setting` +## function `GlibcHeapFastbinsYCommand.get_setting` ```python get_setting(name) @@ -8966,9 +8966,9 @@ get_setting(name) --- - + -### method `GlibcHeapFastbinsYCommand.has_setting` +## function `GlibcHeapFastbinsYCommand.has_setting` ```python has_setting(name: str) → bool @@ -8978,9 +8978,9 @@ has_setting(name: str) → bool --- - + -### method `GlibcHeapFastbinsYCommand.invoke` +## function `GlibcHeapFastbinsYCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -8992,9 +8992,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GlibcHeapFastbinsYCommand.post_load` +## function `GlibcHeapFastbinsYCommand.post_load` ```python post_load() → None @@ -9006,9 +9006,9 @@ post_load() → None --- - + -### method `GlibcHeapFastbinsYCommand.pre_load` +## function `GlibcHeapFastbinsYCommand.pre_load` ```python pre_load() → None @@ -9020,9 +9020,9 @@ pre_load() → None --- - + -### method `GlibcHeapFastbinsYCommand.usage` +## function `GlibcHeapFastbinsYCommand.usage` ```python usage() → None @@ -9038,9 +9038,9 @@ usage() → None ## class `GlibcHeapInfo` Glibc heap_info struct See https://github.com/bminor/glibc/blob/glibc-2.34/malloc/arena.c#L64 - + -### method `GlibcHeapInfo.__init__` +## function `GlibcHeapInfo.__init__` ```python __init__(addr) → None @@ -9131,9 +9131,9 @@ __init__(addr) → None ## class `GlibcHeapLargeBinsCommand` Convenience command for viewing large bins. - + -### method `GlibcHeapLargeBinsCommand.__init__` +## function `GlibcHeapLargeBinsCommand.__init__` ```python __init__() → None @@ -9154,9 +9154,9 @@ Return the list of settings for this command. --- - + -### method `GlibcHeapLargeBinsCommand.add_setting` +## function `GlibcHeapLargeBinsCommand.add_setting` ```python add_setting( @@ -9170,9 +9170,9 @@ add_setting( --- - + -### method `GlibcHeapLargeBinsCommand.del_setting` +## function `GlibcHeapLargeBinsCommand.del_setting` ```python del_setting(name: str) → None @@ -9182,9 +9182,9 @@ del_setting(name: str) → None --- - + -### method `GlibcHeapLargeBinsCommand.do_invoke` +## function `GlibcHeapLargeBinsCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -9196,9 +9196,9 @@ do_invoke(argv: List) → None --- - + -### method `GlibcHeapLargeBinsCommand.get_setting` +## function `GlibcHeapLargeBinsCommand.get_setting` ```python get_setting(name) @@ -9208,9 +9208,9 @@ get_setting(name) --- - + -### method `GlibcHeapLargeBinsCommand.has_setting` +## function `GlibcHeapLargeBinsCommand.has_setting` ```python has_setting(name: str) → bool @@ -9220,9 +9220,9 @@ has_setting(name: str) → bool --- - + -### method `GlibcHeapLargeBinsCommand.invoke` +## function `GlibcHeapLargeBinsCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -9234,9 +9234,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GlibcHeapLargeBinsCommand.post_load` +## function `GlibcHeapLargeBinsCommand.post_load` ```python post_load() → None @@ -9248,9 +9248,9 @@ post_load() → None --- - + -### method `GlibcHeapLargeBinsCommand.pre_load` +## function `GlibcHeapLargeBinsCommand.pre_load` ```python pre_load() → None @@ -9262,9 +9262,9 @@ pre_load() → None --- - + -### method `GlibcHeapLargeBinsCommand.usage` +## function `GlibcHeapLargeBinsCommand.usage` ```python usage() → None @@ -9280,9 +9280,9 @@ usage() → None ## class `GlibcHeapSetArenaCommand` Display information on a heap chunk. - + -### method `GlibcHeapSetArenaCommand.__init__` +## function `GlibcHeapSetArenaCommand.__init__` ```python __init__() → None @@ -9303,9 +9303,9 @@ Return the list of settings for this command. --- - + -### method `GlibcHeapSetArenaCommand.add_setting` +## function `GlibcHeapSetArenaCommand.add_setting` ```python add_setting( @@ -9319,9 +9319,9 @@ add_setting( --- - + -### method `GlibcHeapSetArenaCommand.del_setting` +## function `GlibcHeapSetArenaCommand.del_setting` ```python del_setting(name: str) → None @@ -9331,9 +9331,9 @@ del_setting(name: str) → None --- - + -### method `GlibcHeapSetArenaCommand.do_invoke` +## function `GlibcHeapSetArenaCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -9345,9 +9345,9 @@ do_invoke(argv: List) → None --- - + -### method `GlibcHeapSetArenaCommand.get_setting` +## function `GlibcHeapSetArenaCommand.get_setting` ```python get_setting(name) @@ -9357,9 +9357,9 @@ get_setting(name) --- - + -### method `GlibcHeapSetArenaCommand.has_setting` +## function `GlibcHeapSetArenaCommand.has_setting` ```python has_setting(name: str) → bool @@ -9369,9 +9369,9 @@ has_setting(name: str) → bool --- - + -### method `GlibcHeapSetArenaCommand.invoke` +## function `GlibcHeapSetArenaCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -9383,9 +9383,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GlibcHeapSetArenaCommand.post_load` +## function `GlibcHeapSetArenaCommand.post_load` ```python post_load() → None @@ -9397,9 +9397,9 @@ post_load() → None --- - + -### method `GlibcHeapSetArenaCommand.pre_load` +## function `GlibcHeapSetArenaCommand.pre_load` ```python pre_load() → None @@ -9411,9 +9411,9 @@ pre_load() → None --- - + -### method `GlibcHeapSetArenaCommand.usage` +## function `GlibcHeapSetArenaCommand.usage` ```python usage() → None @@ -9429,9 +9429,9 @@ usage() → None ## class `GlibcHeapSmallBinsCommand` Convenience command for viewing small bins. - + -### method `GlibcHeapSmallBinsCommand.__init__` +## function `GlibcHeapSmallBinsCommand.__init__` ```python __init__() → None @@ -9452,9 +9452,9 @@ Return the list of settings for this command. --- - + -### method `GlibcHeapSmallBinsCommand.add_setting` +## function `GlibcHeapSmallBinsCommand.add_setting` ```python add_setting( @@ -9468,9 +9468,9 @@ add_setting( --- - + -### method `GlibcHeapSmallBinsCommand.del_setting` +## function `GlibcHeapSmallBinsCommand.del_setting` ```python del_setting(name: str) → None @@ -9480,9 +9480,9 @@ del_setting(name: str) → None --- - + -### method `GlibcHeapSmallBinsCommand.do_invoke` +## function `GlibcHeapSmallBinsCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -9494,9 +9494,9 @@ do_invoke(argv: List) → None --- - + -### method `GlibcHeapSmallBinsCommand.get_setting` +## function `GlibcHeapSmallBinsCommand.get_setting` ```python get_setting(name) @@ -9506,9 +9506,9 @@ get_setting(name) --- - + -### method `GlibcHeapSmallBinsCommand.has_setting` +## function `GlibcHeapSmallBinsCommand.has_setting` ```python has_setting(name: str) → bool @@ -9518,9 +9518,9 @@ has_setting(name: str) → bool --- - + -### method `GlibcHeapSmallBinsCommand.invoke` +## function `GlibcHeapSmallBinsCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -9532,9 +9532,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GlibcHeapSmallBinsCommand.post_load` +## function `GlibcHeapSmallBinsCommand.post_load` ```python post_load() → None @@ -9546,9 +9546,9 @@ post_load() → None --- - + -### method `GlibcHeapSmallBinsCommand.pre_load` +## function `GlibcHeapSmallBinsCommand.pre_load` ```python pre_load() → None @@ -9560,9 +9560,9 @@ pre_load() → None --- - + -### method `GlibcHeapSmallBinsCommand.usage` +## function `GlibcHeapSmallBinsCommand.usage` ```python usage() → None @@ -9578,9 +9578,9 @@ 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. - + -### method `GlibcHeapTcachebinsCommand.__init__` +## function `GlibcHeapTcachebinsCommand.__init__` ```python __init__() → None @@ -9601,9 +9601,9 @@ Return the list of settings for this command. --- - + -### method `GlibcHeapTcachebinsCommand.add_setting` +## function `GlibcHeapTcachebinsCommand.add_setting` ```python add_setting( @@ -9617,9 +9617,9 @@ add_setting( --- - + -### method `GlibcHeapTcachebinsCommand.check_thread_ids` +## function `GlibcHeapTcachebinsCommand.check_thread_ids` ```python check_thread_ids(tids: List[int]) → List[int] @@ -9629,9 +9629,9 @@ Check the validity, dedup, and return all valid tids. --- - + -### method `GlibcHeapTcachebinsCommand.del_setting` +## function `GlibcHeapTcachebinsCommand.del_setting` ```python del_setting(name: str) → None @@ -9641,9 +9641,9 @@ del_setting(name: str) → None --- - + -### method `GlibcHeapTcachebinsCommand.do_invoke` +## function `GlibcHeapTcachebinsCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -9655,9 +9655,9 @@ do_invoke(argv: List) → None --- - + -### method `GlibcHeapTcachebinsCommand.find_tcache` +## function `GlibcHeapTcachebinsCommand.find_tcache` ```python find_tcache() → int @@ -9667,9 +9667,9 @@ Return the location of the current thread's tcache. --- - + -### method `GlibcHeapTcachebinsCommand.get_setting` +## function `GlibcHeapTcachebinsCommand.get_setting` ```python get_setting(name) @@ -9679,9 +9679,9 @@ get_setting(name) --- - + -### method `GlibcHeapTcachebinsCommand.has_setting` +## function `GlibcHeapTcachebinsCommand.has_setting` ```python has_setting(name: str) → bool @@ -9691,9 +9691,9 @@ has_setting(name: str) → bool --- - + -### method `GlibcHeapTcachebinsCommand.invoke` +## function `GlibcHeapTcachebinsCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -9705,9 +9705,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GlibcHeapTcachebinsCommand.post_load` +## function `GlibcHeapTcachebinsCommand.post_load` ```python post_load() → None @@ -9719,9 +9719,9 @@ post_load() → None --- - + -### method `GlibcHeapTcachebinsCommand.pre_load` +## function `GlibcHeapTcachebinsCommand.pre_load` ```python pre_load() → None @@ -9733,9 +9733,9 @@ pre_load() → None --- - + -### method `GlibcHeapTcachebinsCommand.tcachebin` +## function `GlibcHeapTcachebinsCommand.tcachebin` ```python tcachebin( @@ -9748,9 +9748,9 @@ Return the head chunk in tcache[i] and the number of chunks in the bin. --- - + -### method `GlibcHeapTcachebinsCommand.usage` +## function `GlibcHeapTcachebinsCommand.usage` ```python usage() → None @@ -9766,9 +9766,9 @@ 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. - + -### method `GlibcHeapUnsortedBinsCommand.__init__` +## function `GlibcHeapUnsortedBinsCommand.__init__` ```python __init__() → None @@ -9789,9 +9789,9 @@ Return the list of settings for this command. --- - + -### method `GlibcHeapUnsortedBinsCommand.add_setting` +## function `GlibcHeapUnsortedBinsCommand.add_setting` ```python add_setting( @@ -9805,9 +9805,9 @@ add_setting( --- - + -### method `GlibcHeapUnsortedBinsCommand.del_setting` +## function `GlibcHeapUnsortedBinsCommand.del_setting` ```python del_setting(name: str) → None @@ -9817,9 +9817,9 @@ del_setting(name: str) → None --- - + -### method `GlibcHeapUnsortedBinsCommand.do_invoke` +## function `GlibcHeapUnsortedBinsCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -9831,9 +9831,9 @@ do_invoke(argv: List) → None --- - + -### method `GlibcHeapUnsortedBinsCommand.get_setting` +## function `GlibcHeapUnsortedBinsCommand.get_setting` ```python get_setting(name) @@ -9843,9 +9843,9 @@ get_setting(name) --- - + -### method `GlibcHeapUnsortedBinsCommand.has_setting` +## function `GlibcHeapUnsortedBinsCommand.has_setting` ```python has_setting(name: str) → bool @@ -9855,9 +9855,9 @@ has_setting(name: str) → bool --- - + -### method `GlibcHeapUnsortedBinsCommand.invoke` +## function `GlibcHeapUnsortedBinsCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -9869,9 +9869,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GlibcHeapUnsortedBinsCommand.post_load` +## function `GlibcHeapUnsortedBinsCommand.post_load` ```python post_load() → None @@ -9883,9 +9883,9 @@ post_load() → None --- - + -### method `GlibcHeapUnsortedBinsCommand.pre_load` +## function `GlibcHeapUnsortedBinsCommand.pre_load` ```python pre_load() → None @@ -9897,9 +9897,9 @@ pre_load() → None --- - + -### method `GlibcHeapUnsortedBinsCommand.usage` +## function `GlibcHeapUnsortedBinsCommand.usage` ```python usage() → None @@ -9915,9 +9915,9 @@ usage() → None ## class `GotBaseFunction` Return the current bss base address plus the given offset. - + -### method `GotBaseFunction.__init__` +## function `GotBaseFunction.__init__` ```python __init__() → None @@ -9932,9 +9932,9 @@ __init__() → None --- - + -### method `GotBaseFunction.arg_to_long` +## function `GotBaseFunction.arg_to_long` ```python arg_to_long(args: List, index: int, default: int = 0) → int @@ -9946,9 +9946,9 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + -### method `GotBaseFunction.do_invoke` +## function `GotBaseFunction.do_invoke` ```python do_invoke(args: List) → int @@ -9960,9 +9960,9 @@ do_invoke(args: List) → int --- - + -### method `GotBaseFunction.invoke` +## function `GotBaseFunction.invoke` ```python invoke(*args) → int @@ -9978,9 +9978,9 @@ invoke(*args) → int ## class `GotCommand` Display current status of the got inside the process. - + -### method `GotCommand.__init__` +## function `GotCommand.__init__` ```python __init__(*args, **kwargs) @@ -10001,9 +10001,9 @@ Return the list of settings for this command. --- - + -### method `GotCommand.add_setting` +## function `GotCommand.add_setting` ```python add_setting( @@ -10017,9 +10017,9 @@ add_setting( --- - + -### method `GotCommand.del_setting` +## function `GotCommand.del_setting` ```python del_setting(name: str) → None @@ -10029,9 +10029,9 @@ del_setting(name: str) → None --- - + -### method `GotCommand.do_invoke` +## function `GotCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -10043,9 +10043,9 @@ do_invoke(argv: List) → None --- - + -### method `GotCommand.get_jmp_slots` +## function `GotCommand.get_jmp_slots` ```python get_jmp_slots(readelf: str, filename: str) → List[str] @@ -10057,9 +10057,9 @@ get_jmp_slots(readelf: str, filename: str) → List[str] --- - + -### method `GotCommand.get_setting` +## function `GotCommand.get_setting` ```python get_setting(name) @@ -10069,9 +10069,9 @@ get_setting(name) --- - + -### method `GotCommand.has_setting` +## function `GotCommand.has_setting` ```python has_setting(name: str) → bool @@ -10081,9 +10081,9 @@ has_setting(name: str) → bool --- - + -### method `GotCommand.invoke` +## function `GotCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -10095,9 +10095,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `GotCommand.post_load` +## function `GotCommand.post_load` ```python post_load() → None @@ -10109,9 +10109,9 @@ post_load() → None --- - + -### method `GotCommand.pre_load` +## function `GotCommand.pre_load` ```python pre_load() → None @@ -10123,9 +10123,9 @@ pre_load() → None --- - + -### method `GotCommand.usage` +## function `GotCommand.usage` ```python usage() → None @@ -10145,9 +10145,9 @@ Heap vulnerability analysis helper: this command aims to track dynamic heap allo - Double Free - Heap overlap - + -### method `HeapAnalysisCommand.__init__` +## function `HeapAnalysisCommand.__init__` ```python __init__() → None @@ -10168,9 +10168,9 @@ Return the list of settings for this command. --- - + -### method `HeapAnalysisCommand.add_setting` +## function `HeapAnalysisCommand.add_setting` ```python add_setting( @@ -10184,9 +10184,9 @@ add_setting( --- - + -### method `HeapAnalysisCommand.clean` +## function `HeapAnalysisCommand.clean` ```python clean(_) → None @@ -10198,9 +10198,9 @@ clean(_) → None --- - + -### method `HeapAnalysisCommand.del_setting` +## function `HeapAnalysisCommand.del_setting` ```python del_setting(name: str) → None @@ -10210,9 +10210,9 @@ del_setting(name: str) → None --- - + -### method `HeapAnalysisCommand.do_invoke` +## function `HeapAnalysisCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -10224,9 +10224,9 @@ do_invoke(argv: List) → None --- - + -### method `HeapAnalysisCommand.dump_tracked_allocations` +## function `HeapAnalysisCommand.dump_tracked_allocations` ```python dump_tracked_allocations() → None @@ -10238,9 +10238,9 @@ dump_tracked_allocations() → None --- - + -### method `HeapAnalysisCommand.get_setting` +## function `HeapAnalysisCommand.get_setting` ```python get_setting(name) @@ -10250,9 +10250,9 @@ get_setting(name) --- - + -### method `HeapAnalysisCommand.has_setting` +## function `HeapAnalysisCommand.has_setting` ```python has_setting(name: str) → bool @@ -10262,9 +10262,9 @@ has_setting(name: str) → bool --- - + -### method `HeapAnalysisCommand.invoke` +## function `HeapAnalysisCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -10276,9 +10276,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `HeapAnalysisCommand.post_load` +## function `HeapAnalysisCommand.post_load` ```python post_load() → None @@ -10290,9 +10290,9 @@ post_load() → None --- - + -### method `HeapAnalysisCommand.pre_load` +## function `HeapAnalysisCommand.pre_load` ```python pre_load() → None @@ -10304,9 +10304,9 @@ pre_load() → None --- - + -### method `HeapAnalysisCommand.setup` +## function `HeapAnalysisCommand.setup` ```python setup() → None @@ -10318,9 +10318,9 @@ setup() → None --- - + -### method `HeapAnalysisCommand.usage` +## function `HeapAnalysisCommand.usage` ```python usage() → None @@ -10336,9 +10336,9 @@ usage() → None ## class `HeapBaseFunction` Return the current heap base address plus an optional offset. - + -### method `HeapBaseFunction.__init__` +## function `HeapBaseFunction.__init__` ```python __init__() → None @@ -10353,9 +10353,9 @@ __init__() → None --- - + -### method `HeapBaseFunction.arg_to_long` +## function `HeapBaseFunction.arg_to_long` ```python arg_to_long(args: List, index: int, default: int = 0) → int @@ -10367,9 +10367,9 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + -### method `HeapBaseFunction.do_invoke` +## function `HeapBaseFunction.do_invoke` ```python do_invoke(args: List) → int @@ -10381,9 +10381,9 @@ do_invoke(args: List) → int --- - + -### method `HeapBaseFunction.invoke` +## function `HeapBaseFunction.invoke` ```python invoke(*args) → int @@ -10399,9 +10399,9 @@ invoke(*args) → int ## class `HexdumpByteCommand` Display SIZE lines of hexdump as BYTE from the memory location pointed by ADDRESS. - + -### method `HexdumpByteCommand.__init__` +## function `HexdumpByteCommand.__init__` ```python __init__() → None @@ -10422,9 +10422,9 @@ Return the list of settings for this command. --- - + -### method `HexdumpByteCommand.add_setting` +## function `HexdumpByteCommand.add_setting` ```python add_setting( @@ -10438,9 +10438,9 @@ add_setting( --- - + -### method `HexdumpByteCommand.del_setting` +## function `HexdumpByteCommand.del_setting` ```python del_setting(name: str) → None @@ -10450,9 +10450,9 @@ del_setting(name: str) → None --- - + -### function `HexdumpByteCommand.wrapper` +## function `HexdumpByteCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -10464,9 +10464,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `HexdumpByteCommand.get_setting` +## function `HexdumpByteCommand.get_setting` ```python get_setting(name) @@ -10476,9 +10476,9 @@ get_setting(name) --- - + -### method `HexdumpByteCommand.has_setting` +## function `HexdumpByteCommand.has_setting` ```python has_setting(name: str) → bool @@ -10488,9 +10488,9 @@ has_setting(name: str) → bool --- - + -### method `HexdumpByteCommand.invoke` +## function `HexdumpByteCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -10502,9 +10502,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `HexdumpByteCommand.post_load` +## function `HexdumpByteCommand.post_load` ```python post_load() → None @@ -10516,9 +10516,9 @@ post_load() → None --- - + -### method `HexdumpByteCommand.pre_load` +## function `HexdumpByteCommand.pre_load` ```python pre_load() → None @@ -10530,9 +10530,9 @@ pre_load() → None --- - + -### method `HexdumpByteCommand.usage` +## function `HexdumpByteCommand.usage` ```python usage() → None @@ -10548,9 +10548,9 @@ usage() → None ## class `HexdumpCommand` Display SIZE lines of hexdump from the memory location pointed by LOCATION. - + -### method `HexdumpCommand.__init__` +## function `HexdumpCommand.__init__` ```python __init__() → None @@ -10571,9 +10571,9 @@ Return the list of settings for this command. --- - + -### method `HexdumpCommand.add_setting` +## function `HexdumpCommand.add_setting` ```python add_setting( @@ -10587,9 +10587,9 @@ add_setting( --- - + -### method `HexdumpCommand.del_setting` +## function `HexdumpCommand.del_setting` ```python del_setting(name: str) → None @@ -10599,9 +10599,9 @@ del_setting(name: str) → None --- - + -### function `HexdumpCommand.wrapper` +## function `HexdumpCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -10613,9 +10613,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `HexdumpCommand.get_setting` +## function `HexdumpCommand.get_setting` ```python get_setting(name) @@ -10625,9 +10625,9 @@ get_setting(name) --- - + -### method `HexdumpCommand.has_setting` +## function `HexdumpCommand.has_setting` ```python has_setting(name: str) → bool @@ -10637,9 +10637,9 @@ has_setting(name: str) → bool --- - + -### method `HexdumpCommand.invoke` +## function `HexdumpCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -10651,9 +10651,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `HexdumpCommand.post_load` +## function `HexdumpCommand.post_load` ```python post_load() → None @@ -10665,9 +10665,9 @@ post_load() → None --- - + -### method `HexdumpCommand.pre_load` +## function `HexdumpCommand.pre_load` ```python pre_load() → None @@ -10679,9 +10679,9 @@ pre_load() → None --- - + -### method `HexdumpCommand.usage` +## function `HexdumpCommand.usage` ```python usage() → None @@ -10697,9 +10697,9 @@ usage() → None ## class `HexdumpDwordCommand` Display SIZE lines of hexdump as DWORD from the memory location pointed by ADDRESS. - + -### method `HexdumpDwordCommand.__init__` +## function `HexdumpDwordCommand.__init__` ```python __init__() → None @@ -10720,9 +10720,9 @@ Return the list of settings for this command. --- - + -### method `HexdumpDwordCommand.add_setting` +## function `HexdumpDwordCommand.add_setting` ```python add_setting( @@ -10736,9 +10736,9 @@ add_setting( --- - + -### method `HexdumpDwordCommand.del_setting` +## function `HexdumpDwordCommand.del_setting` ```python del_setting(name: str) → None @@ -10748,9 +10748,9 @@ del_setting(name: str) → None --- - + -### function `HexdumpDwordCommand.wrapper` +## function `HexdumpDwordCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -10762,9 +10762,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `HexdumpDwordCommand.get_setting` +## function `HexdumpDwordCommand.get_setting` ```python get_setting(name) @@ -10774,9 +10774,9 @@ get_setting(name) --- - + -### method `HexdumpDwordCommand.has_setting` +## function `HexdumpDwordCommand.has_setting` ```python has_setting(name: str) → bool @@ -10786,9 +10786,9 @@ has_setting(name: str) → bool --- - + -### method `HexdumpDwordCommand.invoke` +## function `HexdumpDwordCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -10800,9 +10800,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `HexdumpDwordCommand.post_load` +## function `HexdumpDwordCommand.post_load` ```python post_load() → None @@ -10814,9 +10814,9 @@ post_load() → None --- - + -### method `HexdumpDwordCommand.pre_load` +## function `HexdumpDwordCommand.pre_load` ```python pre_load() → None @@ -10828,9 +10828,9 @@ pre_load() → None --- - + -### method `HexdumpDwordCommand.usage` +## function `HexdumpDwordCommand.usage` ```python usage() → None @@ -10846,9 +10846,9 @@ usage() → None ## class `HexdumpQwordCommand` Display SIZE lines of hexdump as QWORD from the memory location pointed by ADDRESS. - + -### method `HexdumpQwordCommand.__init__` +## function `HexdumpQwordCommand.__init__` ```python __init__() → None @@ -10869,9 +10869,9 @@ Return the list of settings for this command. --- - + -### method `HexdumpQwordCommand.add_setting` +## function `HexdumpQwordCommand.add_setting` ```python add_setting( @@ -10885,9 +10885,9 @@ add_setting( --- - + -### method `HexdumpQwordCommand.del_setting` +## function `HexdumpQwordCommand.del_setting` ```python del_setting(name: str) → None @@ -10897,9 +10897,9 @@ del_setting(name: str) → None --- - + -### function `HexdumpQwordCommand.wrapper` +## function `HexdumpQwordCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -10911,9 +10911,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `HexdumpQwordCommand.get_setting` +## function `HexdumpQwordCommand.get_setting` ```python get_setting(name) @@ -10923,9 +10923,9 @@ get_setting(name) --- - + -### method `HexdumpQwordCommand.has_setting` +## function `HexdumpQwordCommand.has_setting` ```python has_setting(name: str) → bool @@ -10935,9 +10935,9 @@ has_setting(name: str) → bool --- - + -### method `HexdumpQwordCommand.invoke` +## function `HexdumpQwordCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -10949,9 +10949,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `HexdumpQwordCommand.post_load` +## function `HexdumpQwordCommand.post_load` ```python post_load() → None @@ -10963,9 +10963,9 @@ post_load() → None --- - + -### method `HexdumpQwordCommand.pre_load` +## function `HexdumpQwordCommand.pre_load` ```python pre_load() → None @@ -10977,9 +10977,9 @@ pre_load() → None --- - + -### method `HexdumpQwordCommand.usage` +## function `HexdumpQwordCommand.usage` ```python usage() → None @@ -10995,9 +10995,9 @@ usage() → None ## class `HexdumpWordCommand` Display SIZE lines of hexdump as WORD from the memory location pointed by ADDRESS. - + -### method `HexdumpWordCommand.__init__` +## function `HexdumpWordCommand.__init__` ```python __init__() → None @@ -11018,9 +11018,9 @@ Return the list of settings for this command. --- - + -### method `HexdumpWordCommand.add_setting` +## function `HexdumpWordCommand.add_setting` ```python add_setting( @@ -11034,9 +11034,9 @@ add_setting( --- - + -### method `HexdumpWordCommand.del_setting` +## function `HexdumpWordCommand.del_setting` ```python del_setting(name: str) → None @@ -11046,9 +11046,9 @@ del_setting(name: str) → None --- - + -### function `HexdumpWordCommand.wrapper` +## function `HexdumpWordCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -11060,9 +11060,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `HexdumpWordCommand.get_setting` +## function `HexdumpWordCommand.get_setting` ```python get_setting(name) @@ -11072,9 +11072,9 @@ get_setting(name) --- - + -### method `HexdumpWordCommand.has_setting` +## function `HexdumpWordCommand.has_setting` ```python has_setting(name: str) → bool @@ -11084,9 +11084,9 @@ has_setting(name: str) → bool --- - + -### method `HexdumpWordCommand.invoke` +## function `HexdumpWordCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -11098,9 +11098,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `HexdumpWordCommand.post_load` +## function `HexdumpWordCommand.post_load` ```python post_load() → None @@ -11112,9 +11112,9 @@ post_load() → None --- - + -### method `HexdumpWordCommand.pre_load` +## function `HexdumpWordCommand.pre_load` ```python pre_load() → None @@ -11126,9 +11126,9 @@ pre_load() → None --- - + -### method `HexdumpWordCommand.usage` +## function `HexdumpWordCommand.usage` ```python usage() → None @@ -11144,9 +11144,9 @@ usage() → None ## class `HighlightAddCommand` Add a match to the highlight table. - + -### method `HighlightAddCommand.__init__` +## function `HighlightAddCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -11167,9 +11167,9 @@ Return the list of settings for this command. --- - + -### method `HighlightAddCommand.add_setting` +## function `HighlightAddCommand.add_setting` ```python add_setting( @@ -11183,9 +11183,9 @@ add_setting( --- - + -### method `HighlightAddCommand.del_setting` +## function `HighlightAddCommand.del_setting` ```python del_setting(name: str) → None @@ -11195,9 +11195,9 @@ del_setting(name: str) → None --- - + -### method `HighlightAddCommand.do_invoke` +## function `HighlightAddCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -11209,9 +11209,9 @@ do_invoke(argv: List) → None --- - + -### method `HighlightAddCommand.get_setting` +## function `HighlightAddCommand.get_setting` ```python get_setting(name) @@ -11221,9 +11221,9 @@ get_setting(name) --- - + -### method `HighlightAddCommand.has_setting` +## function `HighlightAddCommand.has_setting` ```python has_setting(name: str) → bool @@ -11233,9 +11233,9 @@ has_setting(name: str) → bool --- - + -### method `HighlightAddCommand.invoke` +## function `HighlightAddCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -11247,9 +11247,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `HighlightAddCommand.post_load` +## function `HighlightAddCommand.post_load` ```python post_load() → None @@ -11261,9 +11261,9 @@ post_load() → None --- - + -### method `HighlightAddCommand.pre_load` +## function `HighlightAddCommand.pre_load` ```python pre_load() → None @@ -11275,9 +11275,9 @@ pre_load() → None --- - + -### method `HighlightAddCommand.usage` +## function `HighlightAddCommand.usage` ```python usage() → None @@ -11293,9 +11293,9 @@ usage() → None ## class `HighlightClearCommand` Clear the highlight table, remove all matches. - + -### method `HighlightClearCommand.__init__` +## function `HighlightClearCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -11316,9 +11316,9 @@ Return the list of settings for this command. --- - + -### method `HighlightClearCommand.add_setting` +## function `HighlightClearCommand.add_setting` ```python add_setting( @@ -11332,9 +11332,9 @@ add_setting( --- - + -### method `HighlightClearCommand.del_setting` +## function `HighlightClearCommand.del_setting` ```python del_setting(name: str) → None @@ -11344,9 +11344,9 @@ del_setting(name: str) → None --- - + -### method `HighlightClearCommand.do_invoke` +## function `HighlightClearCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -11358,9 +11358,9 @@ do_invoke(argv: List) → None --- - + -### method `HighlightClearCommand.get_setting` +## function `HighlightClearCommand.get_setting` ```python get_setting(name) @@ -11370,9 +11370,9 @@ get_setting(name) --- - + -### method `HighlightClearCommand.has_setting` +## function `HighlightClearCommand.has_setting` ```python has_setting(name: str) → bool @@ -11382,9 +11382,9 @@ has_setting(name: str) → bool --- - + -### method `HighlightClearCommand.invoke` +## function `HighlightClearCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -11396,9 +11396,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `HighlightClearCommand.post_load` +## function `HighlightClearCommand.post_load` ```python post_load() → None @@ -11410,9 +11410,9 @@ post_load() → None --- - + -### method `HighlightClearCommand.pre_load` +## function `HighlightClearCommand.pre_load` ```python pre_load() → None @@ -11424,9 +11424,9 @@ pre_load() → None --- - + -### method `HighlightClearCommand.usage` +## function `HighlightClearCommand.usage` ```python usage() → None @@ -11442,9 +11442,9 @@ usage() → None ## class `HighlightCommand` Highlight user-defined text matches in GEF output universally. - + -### method `HighlightCommand.__init__` +## function `HighlightCommand.__init__` ```python __init__() → None @@ -11465,9 +11465,9 @@ Return the list of settings for this command. --- - + -### method `HighlightCommand.add_setting` +## function `HighlightCommand.add_setting` ```python add_setting( @@ -11481,9 +11481,9 @@ add_setting( --- - + -### method `HighlightCommand.del_setting` +## function `HighlightCommand.del_setting` ```python del_setting(name: str) → None @@ -11493,9 +11493,9 @@ del_setting(name: str) → None --- - + -### method `HighlightCommand.do_invoke` +## function `HighlightCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -11507,9 +11507,9 @@ do_invoke(argv: List) → None --- - + -### method `HighlightCommand.get_setting` +## function `HighlightCommand.get_setting` ```python get_setting(name) @@ -11519,9 +11519,9 @@ get_setting(name) --- - + -### method `HighlightCommand.has_setting` +## function `HighlightCommand.has_setting` ```python has_setting(name: str) → bool @@ -11531,9 +11531,9 @@ has_setting(name: str) → bool --- - + -### method `HighlightCommand.invoke` +## function `HighlightCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -11545,9 +11545,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `HighlightCommand.post_load` +## function `HighlightCommand.post_load` ```python post_load() → None @@ -11559,9 +11559,9 @@ post_load() → None --- - + -### method `HighlightCommand.pre_load` +## function `HighlightCommand.pre_load` ```python pre_load() → None @@ -11573,9 +11573,9 @@ pre_load() → None --- - + -### method `HighlightCommand.usage` +## function `HighlightCommand.usage` ```python usage() → None @@ -11591,9 +11591,9 @@ usage() → None ## class `HighlightListCommand` Show the current highlight table with matches to colors. - + -### method `HighlightListCommand.__init__` +## function `HighlightListCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -11614,9 +11614,9 @@ Return the list of settings for this command. --- - + -### method `HighlightListCommand.add_setting` +## function `HighlightListCommand.add_setting` ```python add_setting( @@ -11630,9 +11630,9 @@ add_setting( --- - + -### method `HighlightListCommand.del_setting` +## function `HighlightListCommand.del_setting` ```python del_setting(name: str) → None @@ -11642,9 +11642,9 @@ del_setting(name: str) → None --- - + -### method `HighlightListCommand.do_invoke` +## function `HighlightListCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -11656,9 +11656,9 @@ do_invoke(argv: List) → None --- - + -### method `HighlightListCommand.get_setting` +## function `HighlightListCommand.get_setting` ```python get_setting(name) @@ -11668,9 +11668,9 @@ get_setting(name) --- - + -### method `HighlightListCommand.has_setting` +## function `HighlightListCommand.has_setting` ```python has_setting(name: str) → bool @@ -11680,9 +11680,9 @@ has_setting(name: str) → bool --- - + -### method `HighlightListCommand.invoke` +## function `HighlightListCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -11694,9 +11694,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `HighlightListCommand.post_load` +## function `HighlightListCommand.post_load` ```python post_load() → None @@ -11708,9 +11708,9 @@ post_load() → None --- - + -### method `HighlightListCommand.pre_load` +## function `HighlightListCommand.pre_load` ```python pre_load() → None @@ -11722,9 +11722,9 @@ pre_load() → None --- - + -### method `HighlightListCommand.print_highlight_table` +## function `HighlightListCommand.print_highlight_table` ```python print_highlight_table() → None @@ -11736,9 +11736,9 @@ print_highlight_table() → None --- - + -### method `HighlightListCommand.usage` +## function `HighlightListCommand.usage` ```python usage() → None @@ -11754,9 +11754,9 @@ usage() → None ## class `HighlightRemoveCommand` Remove a match in the highlight table. - + -### method `HighlightRemoveCommand.__init__` +## function `HighlightRemoveCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -11777,9 +11777,9 @@ Return the list of settings for this command. --- - + -### method `HighlightRemoveCommand.add_setting` +## function `HighlightRemoveCommand.add_setting` ```python add_setting( @@ -11793,9 +11793,9 @@ add_setting( --- - + -### method `HighlightRemoveCommand.del_setting` +## function `HighlightRemoveCommand.del_setting` ```python del_setting(name: str) → None @@ -11805,9 +11805,9 @@ del_setting(name: str) → None --- - + -### method `HighlightRemoveCommand.do_invoke` +## function `HighlightRemoveCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -11819,9 +11819,9 @@ do_invoke(argv: List) → None --- - + -### method `HighlightRemoveCommand.get_setting` +## function `HighlightRemoveCommand.get_setting` ```python get_setting(name) @@ -11831,9 +11831,9 @@ get_setting(name) --- - + -### method `HighlightRemoveCommand.has_setting` +## function `HighlightRemoveCommand.has_setting` ```python has_setting(name: str) → bool @@ -11843,9 +11843,9 @@ has_setting(name: str) → bool --- - + -### method `HighlightRemoveCommand.invoke` +## function `HighlightRemoveCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -11857,9 +11857,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `HighlightRemoveCommand.post_load` +## function `HighlightRemoveCommand.post_load` ```python post_load() → None @@ -11871,9 +11871,9 @@ post_load() → None --- - + -### method `HighlightRemoveCommand.pre_load` +## function `HighlightRemoveCommand.pre_load` ```python pre_load() → None @@ -11885,9 +11885,9 @@ pre_load() → None --- - + -### method `HighlightRemoveCommand.usage` +## function `HighlightRemoveCommand.usage` ```python usage() → None @@ -11903,9 +11903,9 @@ usage() → None ## class `IdaInteractCommand` IDA Interact: set of commands to interact with IDA via a XML RPC service deployed via the IDA script `ida_gef.py`. It should be noted that this command can also be used to interact with Binary Ninja (using the script `binja_gef.py`) using the same interface. - + -### method `IdaInteractCommand.__init__` +## function `IdaInteractCommand.__init__` ```python __init__() → None @@ -11926,9 +11926,9 @@ Return the list of settings for this command. --- - + -### method `IdaInteractCommand.add_setting` +## function `IdaInteractCommand.add_setting` ```python add_setting( @@ -11942,9 +11942,9 @@ add_setting( --- - + -### method `IdaInteractCommand.connect` +## function `IdaInteractCommand.connect` ```python connect(host: Optional[str] = None, port: Optional[int] = None) → None @@ -11954,9 +11954,9 @@ Connect to the XML-RPC service. --- - + -### method `IdaInteractCommand.del_setting` +## function `IdaInteractCommand.del_setting` ```python del_setting(name: str) → None @@ -11966,9 +11966,9 @@ del_setting(name: str) → None --- - + -### method `IdaInteractCommand.disconnect` +## function `IdaInteractCommand.disconnect` ```python disconnect() → None @@ -11980,9 +11980,9 @@ disconnect() → None --- - + -### method `IdaInteractCommand.do_invoke` +## function `IdaInteractCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -11992,9 +11992,9 @@ do_invoke(argv: List) → None --- - + -### method `IdaInteractCommand.get_setting` +## function `IdaInteractCommand.get_setting` ```python get_setting(name) @@ -12004,9 +12004,9 @@ get_setting(name) --- - + -### method `IdaInteractCommand.has_setting` +## function `IdaInteractCommand.has_setting` ```python has_setting(name: str) → bool @@ -12016,9 +12016,9 @@ has_setting(name: str) → bool --- - + -### method `IdaInteractCommand.import_structures` +## function `IdaInteractCommand.import_structures` ```python import_structures(structs: Dict[str, List[Tuple[int, str, int]]]) → None @@ -12030,9 +12030,9 @@ import_structures(structs: Dict[str, List[Tuple[int, str, int]]]) → None --- - + -### method `IdaInteractCommand.invoke` +## function `IdaInteractCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -12044,9 +12044,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `IdaInteractCommand.is_target_alive` +## function `IdaInteractCommand.is_target_alive` ```python is_target_alive(host: str, port: int) → bool @@ -12058,9 +12058,9 @@ is_target_alive(host: str, port: int) → bool --- - + -### method `IdaInteractCommand.post_load` +## function `IdaInteractCommand.post_load` ```python post_load() → None @@ -12072,9 +12072,9 @@ post_load() → None --- - + -### method `IdaInteractCommand.pre_load` +## function `IdaInteractCommand.pre_load` ```python pre_load() → None @@ -12086,9 +12086,9 @@ pre_load() → None --- - + -### method `IdaInteractCommand.synchronize` +## function `IdaInteractCommand.synchronize` ```python synchronize() → None @@ -12098,9 +12098,9 @@ Submit all active breakpoint addresses to IDA/BN. --- - + -### method `IdaInteractCommand.usage` +## function `IdaInteractCommand.usage` ```python usage(meth: Optional[str] = None) → None @@ -12116,9 +12116,9 @@ usage(meth: Optional[str] = None) → None ## class `Instruction` GEF representation of a CPU instruction. - + -### method `Instruction.__init__` +## function `Instruction.__init__` ```python __init__(address: int, location, mnemo: str, operands, opcodes) → None @@ -12133,9 +12133,9 @@ __init__(address: int, location, mnemo: str, operands, opcodes) → None --- - + -### method `Instruction.is_valid` +## function `Instruction.is_valid` ```python is_valid() → bool @@ -12151,9 +12151,9 @@ is_valid() → bool ## class `IsSyscallCommand` Tells whether the next instruction is a system call. - + -### method `IsSyscallCommand.__init__` +## function `IsSyscallCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -12174,9 +12174,9 @@ Return the list of settings for this command. --- - + -### method `IsSyscallCommand.add_setting` +## function `IsSyscallCommand.add_setting` ```python add_setting( @@ -12190,9 +12190,9 @@ add_setting( --- - + -### method `IsSyscallCommand.del_setting` +## function `IsSyscallCommand.del_setting` ```python del_setting(name: str) → None @@ -12202,9 +12202,9 @@ del_setting(name: str) → None --- - + -### method `IsSyscallCommand.do_invoke` +## function `IsSyscallCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -12216,9 +12216,9 @@ do_invoke(argv: List) → None --- - + -### method `IsSyscallCommand.get_setting` +## function `IsSyscallCommand.get_setting` ```python get_setting(name) @@ -12228,9 +12228,9 @@ get_setting(name) --- - + -### method `IsSyscallCommand.has_setting` +## function `IsSyscallCommand.has_setting` ```python has_setting(name: str) → bool @@ -12240,9 +12240,9 @@ has_setting(name: str) → bool --- - + -### method `IsSyscallCommand.invoke` +## function `IsSyscallCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -12254,9 +12254,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `IsSyscallCommand.is_syscall` +## function `IsSyscallCommand.is_syscall` ```python is_syscall(arch, instruction: __main__.Instruction) → bool @@ -12268,9 +12268,9 @@ is_syscall(arch, instruction: __main__.Instruction) → bool --- - + -### method `IsSyscallCommand.post_load` +## function `IsSyscallCommand.post_load` ```python post_load() → None @@ -12282,9 +12282,9 @@ post_load() → None --- - + -### method `IsSyscallCommand.pre_load` +## function `IsSyscallCommand.pre_load` ```python pre_load() → None @@ -12296,9 +12296,9 @@ pre_load() → None --- - + -### method `IsSyscallCommand.usage` +## function `IsSyscallCommand.usage` ```python usage() → None @@ -12361,9 +12361,9 @@ usage() → None --- - + -### method `MIPS.flag_register_to_human` +## function `MIPS.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → str @@ -12375,9 +12375,9 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + -### method `MIPS.get_ith_parameter` +## function `MIPS.get_ith_parameter` ```python get_ith_parameter( @@ -12390,9 +12390,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `MIPS.get_ra` +## function `MIPS.get_ra` ```python get_ra(insn, frame) → Union[int, NoneType] @@ -12404,9 +12404,9 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + -### method `MIPS.is_branch_taken` +## function `MIPS.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -12418,9 +12418,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `MIPS.is_call` +## function `MIPS.is_call` ```python is_call(insn) → bool @@ -12432,9 +12432,9 @@ is_call(insn) → bool --- - + -### method `MIPS.is_conditional_branch` +## function `MIPS.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -12446,9 +12446,9 @@ is_conditional_branch(insn) → bool --- - + -### method `MIPS.is_ret` +## function `MIPS.is_ret` ```python is_ret(insn) → bool @@ -12460,9 +12460,9 @@ is_ret(insn) → bool --- - + -### classmethod `MIPS.mprotect_asm` +## function `MIPS.mprotect_asm` ```python mprotect_asm(addr: int, size: int, perm) → str @@ -12474,9 +12474,9 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + -### method `MIPS.register` +## function `MIPS.register` ```python register(name: str) → Union[int, NoneType] @@ -12539,9 +12539,9 @@ register(name: str) → Union[int, NoneType] --- - + -### method `MIPS64.flag_register_to_human` +## function `MIPS64.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → str @@ -12553,9 +12553,9 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + -### method `MIPS64.get_ith_parameter` +## function `MIPS64.get_ith_parameter` ```python get_ith_parameter( @@ -12568,9 +12568,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `MIPS64.get_ra` +## function `MIPS64.get_ra` ```python get_ra(insn, frame) → Union[int, NoneType] @@ -12582,9 +12582,9 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + -### method `MIPS64.is_branch_taken` +## function `MIPS64.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -12596,9 +12596,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `MIPS64.is_call` +## function `MIPS64.is_call` ```python is_call(insn) → bool @@ -12610,9 +12610,9 @@ is_call(insn) → bool --- - + -### method `MIPS64.is_conditional_branch` +## function `MIPS64.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -12624,9 +12624,9 @@ is_conditional_branch(insn) → bool --- - + -### method `MIPS64.is_ret` +## function `MIPS64.is_ret` ```python is_ret(insn) → bool @@ -12638,9 +12638,9 @@ is_ret(insn) → bool --- - + -### classmethod `MIPS64.mprotect_asm` +## function `MIPS64.mprotect_asm` ```python mprotect_asm(addr: int, size: int, perm) → str @@ -12652,9 +12652,9 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + -### method `MIPS64.register` +## function `MIPS64.register` ```python register(name: str) → Union[int, NoneType] @@ -12670,9 +12670,9 @@ register(name: str) → Union[int, NoneType] ## class `MallocStateStruct` GEF representation of malloc_state from https://github.com/bminor/glibc/blob/glibc-2.28/malloc/malloc.c#L1658 - + -### method `MallocStateStruct.__init__` +## function `MallocStateStruct.__init__` ```python __init__(addr: str) → None @@ -12815,9 +12815,9 @@ __init__(addr: str) → None --- - + -### method `MallocStateStruct.get_size_t` +## function `MallocStateStruct.get_size_t` ```python get_size_t(addr) @@ -12829,9 +12829,9 @@ get_size_t(addr) --- - + -### method `MallocStateStruct.get_size_t_array` +## function `MallocStateStruct.get_size_t_array` ```python get_size_t_array(addr, length) @@ -12843,9 +12843,9 @@ get_size_t_array(addr, length) --- - + -### method `MallocStateStruct.get_size_t_pointer` +## function `MallocStateStruct.get_size_t_pointer` ```python get_size_t_pointer(addr) @@ -12861,9 +12861,9 @@ get_size_t_pointer(addr) ## class `MemoryCommand` Add or remove address ranges to the memory view. - + -### method `MemoryCommand.__init__` +## function `MemoryCommand.__init__` ```python __init__() → None @@ -12884,9 +12884,9 @@ Return the list of settings for this command. --- - + -### method `MemoryCommand.add_setting` +## function `MemoryCommand.add_setting` ```python add_setting( @@ -12900,9 +12900,9 @@ add_setting( --- - + -### method `MemoryCommand.del_setting` +## function `MemoryCommand.del_setting` ```python del_setting(name: str) → None @@ -12912,9 +12912,9 @@ del_setting(name: str) → None --- - + -### method `MemoryCommand.do_invoke` +## function `MemoryCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -12926,9 +12926,9 @@ do_invoke(argv: List) → None --- - + -### method `MemoryCommand.get_setting` +## function `MemoryCommand.get_setting` ```python get_setting(name) @@ -12938,9 +12938,9 @@ get_setting(name) --- - + -### method `MemoryCommand.has_setting` +## function `MemoryCommand.has_setting` ```python has_setting(name: str) → bool @@ -12950,9 +12950,9 @@ has_setting(name: str) → bool --- - + -### method `MemoryCommand.invoke` +## function `MemoryCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -12964,9 +12964,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `MemoryCommand.post_load` +## function `MemoryCommand.post_load` ```python post_load() → None @@ -12978,9 +12978,9 @@ post_load() → None --- - + -### method `MemoryCommand.pre_load` +## function `MemoryCommand.pre_load` ```python pre_load() → None @@ -12992,9 +12992,9 @@ pre_load() → None --- - + -### method `MemoryCommand.usage` +## function `MemoryCommand.usage` ```python usage() → None @@ -13010,9 +13010,9 @@ usage() → None ## class `MemoryUnwatchCommand` Removes address ranges to the memory view. - + -### method `MemoryUnwatchCommand.__init__` +## function `MemoryUnwatchCommand.__init__` ```python __init__() → None @@ -13033,9 +13033,9 @@ Return the list of settings for this command. --- - + -### method `MemoryUnwatchCommand.add_setting` +## function `MemoryUnwatchCommand.add_setting` ```python add_setting( @@ -13049,9 +13049,9 @@ add_setting( --- - + -### method `MemoryUnwatchCommand.del_setting` +## function `MemoryUnwatchCommand.del_setting` ```python del_setting(name: str) → None @@ -13061,9 +13061,9 @@ del_setting(name: str) → None --- - + -### method `MemoryUnwatchCommand.do_invoke` +## function `MemoryUnwatchCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -13075,9 +13075,9 @@ do_invoke(argv: List) → None --- - + -### method `MemoryUnwatchCommand.get_setting` +## function `MemoryUnwatchCommand.get_setting` ```python get_setting(name) @@ -13087,9 +13087,9 @@ get_setting(name) --- - + -### method `MemoryUnwatchCommand.has_setting` +## function `MemoryUnwatchCommand.has_setting` ```python has_setting(name: str) → bool @@ -13099,9 +13099,9 @@ has_setting(name: str) → bool --- - + -### method `MemoryUnwatchCommand.invoke` +## function `MemoryUnwatchCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -13113,9 +13113,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `MemoryUnwatchCommand.post_load` +## function `MemoryUnwatchCommand.post_load` ```python post_load() → None @@ -13127,9 +13127,9 @@ post_load() → None --- - + -### method `MemoryUnwatchCommand.pre_load` +## function `MemoryUnwatchCommand.pre_load` ```python pre_load() → None @@ -13141,9 +13141,9 @@ pre_load() → None --- - + -### method `MemoryUnwatchCommand.usage` +## function `MemoryUnwatchCommand.usage` ```python usage() → None @@ -13159,9 +13159,9 @@ usage() → None ## class `MemoryWatchCommand` Adds address ranges to the memory view. - + -### method `MemoryWatchCommand.__init__` +## function `MemoryWatchCommand.__init__` ```python __init__() → None @@ -13182,9 +13182,9 @@ Return the list of settings for this command. --- - + -### method `MemoryWatchCommand.add_setting` +## function `MemoryWatchCommand.add_setting` ```python add_setting( @@ -13198,9 +13198,9 @@ add_setting( --- - + -### method `MemoryWatchCommand.del_setting` +## function `MemoryWatchCommand.del_setting` ```python del_setting(name: str) → None @@ -13210,9 +13210,9 @@ del_setting(name: str) → None --- - + -### method `MemoryWatchCommand.do_invoke` +## function `MemoryWatchCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -13224,9 +13224,9 @@ do_invoke(argv: List) → None --- - + -### method `MemoryWatchCommand.get_setting` +## function `MemoryWatchCommand.get_setting` ```python get_setting(name) @@ -13236,9 +13236,9 @@ get_setting(name) --- - + -### method `MemoryWatchCommand.has_setting` +## function `MemoryWatchCommand.has_setting` ```python has_setting(name: str) → bool @@ -13248,9 +13248,9 @@ has_setting(name: str) → bool --- - + -### method `MemoryWatchCommand.invoke` +## function `MemoryWatchCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -13262,9 +13262,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `MemoryWatchCommand.post_load` +## function `MemoryWatchCommand.post_load` ```python post_load() → None @@ -13276,9 +13276,9 @@ post_load() → None --- - + -### method `MemoryWatchCommand.pre_load` +## function `MemoryWatchCommand.pre_load` ```python pre_load() → None @@ -13290,9 +13290,9 @@ pre_load() → None --- - + -### method `MemoryWatchCommand.usage` +## function `MemoryWatchCommand.usage` ```python usage() → None @@ -13308,9 +13308,9 @@ usage() → None ## class `MemoryWatchListCommand` Lists all watchpoints to display in context layout. - + -### method `MemoryWatchListCommand.__init__` +## function `MemoryWatchListCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -13331,9 +13331,9 @@ Return the list of settings for this command. --- - + -### method `MemoryWatchListCommand.add_setting` +## function `MemoryWatchListCommand.add_setting` ```python add_setting( @@ -13347,9 +13347,9 @@ add_setting( --- - + -### method `MemoryWatchListCommand.del_setting` +## function `MemoryWatchListCommand.del_setting` ```python del_setting(name: str) → None @@ -13359,9 +13359,9 @@ del_setting(name: str) → None --- - + -### method `MemoryWatchListCommand.do_invoke` +## function `MemoryWatchListCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -13373,9 +13373,9 @@ do_invoke(argv: List) → None --- - + -### method `MemoryWatchListCommand.get_setting` +## function `MemoryWatchListCommand.get_setting` ```python get_setting(name) @@ -13385,9 +13385,9 @@ get_setting(name) --- - + -### method `MemoryWatchListCommand.has_setting` +## function `MemoryWatchListCommand.has_setting` ```python has_setting(name: str) → bool @@ -13397,9 +13397,9 @@ has_setting(name: str) → bool --- - + -### method `MemoryWatchListCommand.invoke` +## function `MemoryWatchListCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -13411,9 +13411,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `MemoryWatchListCommand.post_load` +## function `MemoryWatchListCommand.post_load` ```python post_load() → None @@ -13425,9 +13425,9 @@ post_load() → None --- - + -### method `MemoryWatchListCommand.pre_load` +## function `MemoryWatchListCommand.pre_load` ```python pre_load() → None @@ -13439,9 +13439,9 @@ pre_load() → None --- - + -### method `MemoryWatchListCommand.usage` +## function `MemoryWatchListCommand.usage` ```python usage() → None @@ -13457,9 +13457,9 @@ usage() → None ## class `MemoryWatchResetCommand` Removes all watchpoints. - + -### method `MemoryWatchResetCommand.__init__` +## function `MemoryWatchResetCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -13480,9 +13480,9 @@ Return the list of settings for this command. --- - + -### method `MemoryWatchResetCommand.add_setting` +## function `MemoryWatchResetCommand.add_setting` ```python add_setting( @@ -13496,9 +13496,9 @@ add_setting( --- - + -### method `MemoryWatchResetCommand.del_setting` +## function `MemoryWatchResetCommand.del_setting` ```python del_setting(name: str) → None @@ -13508,9 +13508,9 @@ del_setting(name: str) → None --- - + -### method `MemoryWatchResetCommand.do_invoke` +## function `MemoryWatchResetCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -13522,9 +13522,9 @@ do_invoke(argv: List) → None --- - + -### method `MemoryWatchResetCommand.get_setting` +## function `MemoryWatchResetCommand.get_setting` ```python get_setting(name) @@ -13534,9 +13534,9 @@ get_setting(name) --- - + -### method `MemoryWatchResetCommand.has_setting` +## function `MemoryWatchResetCommand.has_setting` ```python has_setting(name: str) → bool @@ -13546,9 +13546,9 @@ has_setting(name: str) → bool --- - + -### method `MemoryWatchResetCommand.invoke` +## function `MemoryWatchResetCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -13560,9 +13560,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `MemoryWatchResetCommand.post_load` +## function `MemoryWatchResetCommand.post_load` ```python post_load() → None @@ -13574,9 +13574,9 @@ post_load() → None --- - + -### method `MemoryWatchResetCommand.pre_load` +## function `MemoryWatchResetCommand.pre_load` ```python pre_load() → None @@ -13588,9 +13588,9 @@ pre_load() → None --- - + -### method `MemoryWatchResetCommand.usage` +## function `MemoryWatchResetCommand.usage` ```python usage() → None @@ -13606,9 +13606,9 @@ usage() → None ## class `NamedBreakpoint` Breakpoint which shows a specified name, when hit. - + -### method `NamedBreakpoint.__init__` +## function `NamedBreakpoint.__init__` ```python __init__(location: str, name: str) → None @@ -13623,9 +13623,9 @@ __init__(location: str, name: str) → None --- - + -### method `NamedBreakpoint.stop` +## function `NamedBreakpoint.stop` ```python stop() → bool @@ -13641,9 +13641,9 @@ stop() → bool ## class `NamedBreakpointCommand` Sets a breakpoint and assigns a name to it, which will be shown, when it's hit. - + -### method `NamedBreakpointCommand.__init__` +## function `NamedBreakpointCommand.__init__` ```python __init__() → None @@ -13664,9 +13664,9 @@ Return the list of settings for this command. --- - + -### method `NamedBreakpointCommand.add_setting` +## function `NamedBreakpointCommand.add_setting` ```python add_setting( @@ -13680,9 +13680,9 @@ add_setting( --- - + -### method `NamedBreakpointCommand.del_setting` +## function `NamedBreakpointCommand.del_setting` ```python del_setting(name: str) → None @@ -13692,9 +13692,9 @@ del_setting(name: str) → None --- - + -### function `NamedBreakpointCommand.wrapper` +## function `NamedBreakpointCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -13706,9 +13706,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `NamedBreakpointCommand.get_setting` +## function `NamedBreakpointCommand.get_setting` ```python get_setting(name) @@ -13718,9 +13718,9 @@ get_setting(name) --- - + -### method `NamedBreakpointCommand.has_setting` +## function `NamedBreakpointCommand.has_setting` ```python has_setting(name: str) → bool @@ -13730,9 +13730,9 @@ has_setting(name: str) → bool --- - + -### method `NamedBreakpointCommand.invoke` +## function `NamedBreakpointCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -13744,9 +13744,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `NamedBreakpointCommand.post_load` +## function `NamedBreakpointCommand.post_load` ```python post_load() → None @@ -13758,9 +13758,9 @@ post_load() → None --- - + -### method `NamedBreakpointCommand.pre_load` +## function `NamedBreakpointCommand.pre_load` ```python pre_load() → None @@ -13772,9 +13772,9 @@ pre_load() → None --- - + -### method `NamedBreakpointCommand.usage` +## function `NamedBreakpointCommand.usage` ```python usage() → None @@ -13790,9 +13790,9 @@ usage() → None ## class `NopCommand` Patch the instruction(s) pointed by parameters with NOP. Note: this command is architecture aware. - + -### method `NopCommand.__init__` +## function `NopCommand.__init__` ```python __init__() → None @@ -13813,9 +13813,9 @@ Return the list of settings for this command. --- - + -### method `NopCommand.add_setting` +## function `NopCommand.add_setting` ```python add_setting( @@ -13829,9 +13829,9 @@ add_setting( --- - + -### method `NopCommand.del_setting` +## function `NopCommand.del_setting` ```python del_setting(name: str) → None @@ -13841,9 +13841,9 @@ del_setting(name: str) → None --- - + -### function `NopCommand.wrapper` +## function `NopCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -13855,9 +13855,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `NopCommand.get_insn_size` +## function `NopCommand.get_insn_size` ```python get_insn_size(addr: int) → int @@ -13869,9 +13869,9 @@ get_insn_size(addr: int) → int --- - + -### method `NopCommand.get_setting` +## function `NopCommand.get_setting` ```python get_setting(name) @@ -13881,9 +13881,9 @@ get_setting(name) --- - + -### method `NopCommand.has_setting` +## function `NopCommand.has_setting` ```python has_setting(name: str) → bool @@ -13893,9 +13893,9 @@ has_setting(name: str) → bool --- - + -### method `NopCommand.invoke` +## function `NopCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -13907,9 +13907,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `NopCommand.nop_bytes` +## function `NopCommand.nop_bytes` ```python nop_bytes(loc: int, num_bytes: int) → None @@ -13921,9 +13921,9 @@ nop_bytes(loc: int, num_bytes: int) → None --- - + -### method `NopCommand.post_load` +## function `NopCommand.post_load` ```python post_load() → None @@ -13935,9 +13935,9 @@ post_load() → None --- - + -### method `NopCommand.pre_load` +## function `NopCommand.pre_load` ```python pre_load() → None @@ -13949,9 +13949,9 @@ pre_load() → None --- - + -### method `NopCommand.usage` +## function `NopCommand.usage` ```python usage() → None @@ -13967,9 +13967,9 @@ 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. - + -### method `PCustomCommand.__init__` +## function `PCustomCommand.__init__` ```python __init__() → None @@ -13990,9 +13990,9 @@ Return the list of settings for this command. --- - + -### method `PCustomCommand.add_setting` +## function `PCustomCommand.add_setting` ```python add_setting( @@ -14006,9 +14006,9 @@ add_setting( --- - + -### method `PCustomCommand.apply_structure_to_address` +## function `PCustomCommand.apply_structure_to_address` ```python apply_structure_to_address( @@ -14025,9 +14025,9 @@ apply_structure_to_address( --- - + -### method `PCustomCommand.del_setting` +## function `PCustomCommand.del_setting` ```python del_setting(name: str) → None @@ -14037,9 +14037,9 @@ del_setting(name: str) → None --- - + -### method `PCustomCommand.deserialize` +## function `PCustomCommand.deserialize` ```python deserialize(struct: _ctypes.Structure, data: bytes) → None @@ -14051,9 +14051,9 @@ deserialize(struct: _ctypes.Structure, data: bytes) → None --- - + -### method `PCustomCommand.do_invoke` +## function `PCustomCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -14065,9 +14065,9 @@ do_invoke(argv: List) → None --- - + -### method `PCustomCommand.enumerate_structure_files` +## function `PCustomCommand.enumerate_structure_files` ```python enumerate_structure_files() → List[str] @@ -14077,9 +14077,9 @@ Return a list of all the files in the pcustom directory --- - + -### method `PCustomCommand.enumerate_structures` +## function `PCustomCommand.enumerate_structures` ```python enumerate_structures() → Dict[str, Set[str]] @@ -14089,9 +14089,9 @@ Return a hash of all the structures, with the key set the to filepath --- - + -### method `PCustomCommand.enumerate_structures_from_module` +## function `PCustomCommand.enumerate_structures_from_module` ```python enumerate_structures_from_module(module: module) → Set[str] @@ -14103,9 +14103,9 @@ enumerate_structures_from_module(module: module) → Set[str] --- - + -### method `PCustomCommand.get_ctypes_value` +## function `PCustomCommand.get_ctypes_value` ```python get_ctypes_value(struct, item, value) → str @@ -14117,9 +14117,9 @@ get_ctypes_value(struct, item, value) → str --- - + -### method `PCustomCommand.get_modulename_structname_from_arg` +## function `PCustomCommand.get_modulename_structname_from_arg` ```python get_modulename_structname_from_arg(arg: str) → Tuple[str, str] @@ -14131,9 +14131,9 @@ get_modulename_structname_from_arg(arg: str) → Tuple[str, str] --- - + -### method `PCustomCommand.get_pcustom_absolute_root_path` +## function `PCustomCommand.get_pcustom_absolute_root_path` ```python get_pcustom_absolute_root_path() → Union[str, bytes] @@ -14145,9 +14145,9 @@ get_pcustom_absolute_root_path() → Union[str, bytes] --- - + -### method `PCustomCommand.get_pcustom_filepath_for_structure` +## function `PCustomCommand.get_pcustom_filepath_for_structure` ```python get_pcustom_filepath_for_structure(structure_name: str) → str @@ -14159,9 +14159,9 @@ get_pcustom_filepath_for_structure(structure_name: str) → str --- - + -### method `PCustomCommand.get_setting` +## function `PCustomCommand.get_setting` ```python get_setting(name) @@ -14171,9 +14171,9 @@ get_setting(name) --- - + -### method `PCustomCommand.get_structure_class` +## function `PCustomCommand.get_structure_class` ```python get_structure_class( @@ -14186,9 +14186,9 @@ Returns a tuple of (class, instance) if modname!classname exists --- - + -### method `PCustomCommand.has_setting` +## function `PCustomCommand.has_setting` ```python has_setting(name: str) → bool @@ -14198,9 +14198,9 @@ has_setting(name: str) → bool --- - + -### method `PCustomCommand.invoke` +## function `PCustomCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -14212,9 +14212,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PCustomCommand.is_valid_struct` +## function `PCustomCommand.is_valid_struct` ```python is_valid_struct(structure_name: str) → bool @@ -14226,9 +14226,9 @@ is_valid_struct(structure_name: str) → bool --- - + -### method `PCustomCommand.load_module` +## function `PCustomCommand.load_module` ```python load_module(file_path: str) → module @@ -14238,9 +14238,9 @@ Load a custom module, and return it --- - + -### method `PCustomCommand.post_load` +## function `PCustomCommand.post_load` ```python post_load() → None @@ -14252,9 +14252,9 @@ post_load() → None --- - + -### method `PCustomCommand.pre_load` +## function `PCustomCommand.pre_load` ```python pre_load() → None @@ -14266,9 +14266,9 @@ pre_load() → None --- - + -### method `PCustomCommand.usage` +## function `PCustomCommand.usage` ```python usage() → None @@ -14284,9 +14284,9 @@ usage() → None ## class `PCustomEditCommand` PCustom: edit the content of a given structure - + -### method `PCustomEditCommand.__init__` +## function `PCustomEditCommand.__init__` ```python __init__() → None @@ -14307,9 +14307,9 @@ Return the list of settings for this command. --- - + -### method `PCustomEditCommand.add_setting` +## function `PCustomEditCommand.add_setting` ```python add_setting( @@ -14323,9 +14323,9 @@ add_setting( --- - + -### method `PCustomEditCommand.apply_structure_to_address` +## function `PCustomEditCommand.apply_structure_to_address` ```python apply_structure_to_address( @@ -14342,9 +14342,9 @@ apply_structure_to_address( --- - + -### method `PCustomEditCommand.del_setting` +## function `PCustomEditCommand.del_setting` ```python del_setting(name: str) → None @@ -14354,9 +14354,9 @@ del_setting(name: str) → None --- - + -### method `PCustomEditCommand.deserialize` +## function `PCustomEditCommand.deserialize` ```python deserialize(struct: _ctypes.Structure, data: bytes) → None @@ -14368,9 +14368,9 @@ deserialize(struct: _ctypes.Structure, data: bytes) → None --- - + -### method `PCustomEditCommand.do_invoke` +## function `PCustomEditCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -14382,9 +14382,9 @@ do_invoke(argv: List) → None --- - + -### method `PCustomEditCommand.enumerate_structure_files` +## function `PCustomEditCommand.enumerate_structure_files` ```python enumerate_structure_files() → List[str] @@ -14394,9 +14394,9 @@ Return a list of all the files in the pcustom directory --- - + -### method `PCustomEditCommand.enumerate_structures` +## function `PCustomEditCommand.enumerate_structures` ```python enumerate_structures() → Dict[str, Set[str]] @@ -14406,9 +14406,9 @@ Return a hash of all the structures, with the key set the to filepath --- - + -### method `PCustomEditCommand.enumerate_structures_from_module` +## function `PCustomEditCommand.enumerate_structures_from_module` ```python enumerate_structures_from_module(module: module) → Set[str] @@ -14420,9 +14420,9 @@ enumerate_structures_from_module(module: module) → Set[str] --- - + -### method `PCustomEditCommand.get_ctypes_value` +## function `PCustomEditCommand.get_ctypes_value` ```python get_ctypes_value(struct, item, value) → str @@ -14434,9 +14434,9 @@ get_ctypes_value(struct, item, value) → str --- - + -### method `PCustomEditCommand.get_modulename_structname_from_arg` +## function `PCustomEditCommand.get_modulename_structname_from_arg` ```python get_modulename_structname_from_arg(arg: str) → Tuple[str, str] @@ -14448,9 +14448,9 @@ get_modulename_structname_from_arg(arg: str) → Tuple[str, str] --- - + -### method `PCustomEditCommand.get_pcustom_absolute_root_path` +## function `PCustomEditCommand.get_pcustom_absolute_root_path` ```python get_pcustom_absolute_root_path() → Union[str, bytes] @@ -14462,9 +14462,9 @@ get_pcustom_absolute_root_path() → Union[str, bytes] --- - + -### method `PCustomEditCommand.get_pcustom_filepath_for_structure` +## function `PCustomEditCommand.get_pcustom_filepath_for_structure` ```python get_pcustom_filepath_for_structure(structure_name: str) → str @@ -14476,9 +14476,9 @@ get_pcustom_filepath_for_structure(structure_name: str) → str --- - + -### method `PCustomEditCommand.get_setting` +## function `PCustomEditCommand.get_setting` ```python get_setting(name) @@ -14488,9 +14488,9 @@ get_setting(name) --- - + -### method `PCustomEditCommand.get_structure_class` +## function `PCustomEditCommand.get_structure_class` ```python get_structure_class( @@ -14503,9 +14503,9 @@ Returns a tuple of (class, instance) if modname!classname exists --- - + -### method `PCustomEditCommand.has_setting` +## function `PCustomEditCommand.has_setting` ```python has_setting(name: str) → bool @@ -14515,9 +14515,9 @@ has_setting(name: str) → bool --- - + -### method `PCustomEditCommand.invoke` +## function `PCustomEditCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -14529,9 +14529,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PCustomEditCommand.is_valid_struct` +## function `PCustomEditCommand.is_valid_struct` ```python is_valid_struct(structure_name: str) → bool @@ -14543,9 +14543,9 @@ is_valid_struct(structure_name: str) → bool --- - + -### method `PCustomEditCommand.load_module` +## function `PCustomEditCommand.load_module` ```python load_module(file_path: str) → module @@ -14555,9 +14555,9 @@ Load a custom module, and return it --- - + -### method `PCustomEditCommand.post_load` +## function `PCustomEditCommand.post_load` ```python post_load() → None @@ -14569,9 +14569,9 @@ post_load() → None --- - + -### method `PCustomEditCommand.pre_load` +## function `PCustomEditCommand.pre_load` ```python pre_load() → None @@ -14583,9 +14583,9 @@ pre_load() → None --- - + -### method `PCustomEditCommand.usage` +## function `PCustomEditCommand.usage` ```python usage() → None @@ -14601,9 +14601,9 @@ usage() → None ## class `PCustomListCommand` PCustom: list available structures - + -### method `PCustomListCommand.__init__` +## function `PCustomListCommand.__init__` ```python __init__() → None @@ -14624,9 +14624,9 @@ Return the list of settings for this command. --- - + -### method `PCustomListCommand.add_setting` +## function `PCustomListCommand.add_setting` ```python add_setting( @@ -14640,9 +14640,9 @@ add_setting( --- - + -### method `PCustomListCommand.apply_structure_to_address` +## function `PCustomListCommand.apply_structure_to_address` ```python apply_structure_to_address( @@ -14659,9 +14659,9 @@ apply_structure_to_address( --- - + -### method `PCustomListCommand.del_setting` +## function `PCustomListCommand.del_setting` ```python del_setting(name: str) → None @@ -14671,9 +14671,9 @@ del_setting(name: str) → None --- - + -### method `PCustomListCommand.deserialize` +## function `PCustomListCommand.deserialize` ```python deserialize(struct: _ctypes.Structure, data: bytes) → None @@ -14685,9 +14685,9 @@ deserialize(struct: _ctypes.Structure, data: bytes) → None --- - + -### method `PCustomListCommand.do_invoke` +## function `PCustomListCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -14699,9 +14699,9 @@ do_invoke(argv: List) → None --- - + -### method `PCustomListCommand.enumerate_structure_files` +## function `PCustomListCommand.enumerate_structure_files` ```python enumerate_structure_files() → List[str] @@ -14711,9 +14711,9 @@ Return a list of all the files in the pcustom directory --- - + -### method `PCustomListCommand.enumerate_structures` +## function `PCustomListCommand.enumerate_structures` ```python enumerate_structures() → Dict[str, Set[str]] @@ -14723,9 +14723,9 @@ Return a hash of all the structures, with the key set the to filepath --- - + -### method `PCustomListCommand.enumerate_structures_from_module` +## function `PCustomListCommand.enumerate_structures_from_module` ```python enumerate_structures_from_module(module: module) → Set[str] @@ -14737,9 +14737,9 @@ enumerate_structures_from_module(module: module) → Set[str] --- - + -### method `PCustomListCommand.get_ctypes_value` +## function `PCustomListCommand.get_ctypes_value` ```python get_ctypes_value(struct, item, value) → str @@ -14751,9 +14751,9 @@ get_ctypes_value(struct, item, value) → str --- - + -### method `PCustomListCommand.get_modulename_structname_from_arg` +## function `PCustomListCommand.get_modulename_structname_from_arg` ```python get_modulename_structname_from_arg(arg: str) → Tuple[str, str] @@ -14765,9 +14765,9 @@ get_modulename_structname_from_arg(arg: str) → Tuple[str, str] --- - + -### method `PCustomListCommand.get_pcustom_absolute_root_path` +## function `PCustomListCommand.get_pcustom_absolute_root_path` ```python get_pcustom_absolute_root_path() → Union[str, bytes] @@ -14779,9 +14779,9 @@ get_pcustom_absolute_root_path() → Union[str, bytes] --- - + -### method `PCustomListCommand.get_pcustom_filepath_for_structure` +## function `PCustomListCommand.get_pcustom_filepath_for_structure` ```python get_pcustom_filepath_for_structure(structure_name: str) → str @@ -14793,9 +14793,9 @@ get_pcustom_filepath_for_structure(structure_name: str) → str --- - + -### method `PCustomListCommand.get_setting` +## function `PCustomListCommand.get_setting` ```python get_setting(name) @@ -14805,9 +14805,9 @@ get_setting(name) --- - + -### method `PCustomListCommand.get_structure_class` +## function `PCustomListCommand.get_structure_class` ```python get_structure_class( @@ -14820,9 +14820,9 @@ Returns a tuple of (class, instance) if modname!classname exists --- - + -### method `PCustomListCommand.has_setting` +## function `PCustomListCommand.has_setting` ```python has_setting(name: str) → bool @@ -14832,9 +14832,9 @@ has_setting(name: str) → bool --- - + -### method `PCustomListCommand.invoke` +## function `PCustomListCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -14846,9 +14846,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PCustomListCommand.is_valid_struct` +## function `PCustomListCommand.is_valid_struct` ```python is_valid_struct(structure_name: str) → bool @@ -14860,9 +14860,9 @@ is_valid_struct(structure_name: str) → bool --- - + -### method `PCustomListCommand.load_module` +## function `PCustomListCommand.load_module` ```python load_module(file_path: str) → module @@ -14872,9 +14872,9 @@ Load a custom module, and return it --- - + -### method `PCustomListCommand.post_load` +## function `PCustomListCommand.post_load` ```python post_load() → None @@ -14886,9 +14886,9 @@ post_load() → None --- - + -### method `PCustomListCommand.pre_load` +## function `PCustomListCommand.pre_load` ```python pre_load() → None @@ -14900,9 +14900,9 @@ pre_load() → None --- - + -### method `PCustomListCommand.usage` +## function `PCustomListCommand.usage` ```python usage() → None @@ -14918,9 +14918,9 @@ usage() → None ## class `PCustomShowCommand` PCustom: show the content of a given structure - + -### method `PCustomShowCommand.__init__` +## function `PCustomShowCommand.__init__` ```python __init__() → None @@ -14941,9 +14941,9 @@ Return the list of settings for this command. --- - + -### method `PCustomShowCommand.add_setting` +## function `PCustomShowCommand.add_setting` ```python add_setting( @@ -14957,9 +14957,9 @@ add_setting( --- - + -### method `PCustomShowCommand.apply_structure_to_address` +## function `PCustomShowCommand.apply_structure_to_address` ```python apply_structure_to_address( @@ -14976,9 +14976,9 @@ apply_structure_to_address( --- - + -### method `PCustomShowCommand.del_setting` +## function `PCustomShowCommand.del_setting` ```python del_setting(name: str) → None @@ -14988,9 +14988,9 @@ del_setting(name: str) → None --- - + -### method `PCustomShowCommand.deserialize` +## function `PCustomShowCommand.deserialize` ```python deserialize(struct: _ctypes.Structure, data: bytes) → None @@ -15002,9 +15002,9 @@ deserialize(struct: _ctypes.Structure, data: bytes) → None --- - + -### method `PCustomShowCommand.do_invoke` +## function `PCustomShowCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -15016,9 +15016,9 @@ do_invoke(argv: List) → None --- - + -### method `PCustomShowCommand.enumerate_structure_files` +## function `PCustomShowCommand.enumerate_structure_files` ```python enumerate_structure_files() → List[str] @@ -15028,9 +15028,9 @@ Return a list of all the files in the pcustom directory --- - + -### method `PCustomShowCommand.enumerate_structures` +## function `PCustomShowCommand.enumerate_structures` ```python enumerate_structures() → Dict[str, Set[str]] @@ -15040,9 +15040,9 @@ Return a hash of all the structures, with the key set the to filepath --- - + -### method `PCustomShowCommand.enumerate_structures_from_module` +## function `PCustomShowCommand.enumerate_structures_from_module` ```python enumerate_structures_from_module(module: module) → Set[str] @@ -15054,9 +15054,9 @@ enumerate_structures_from_module(module: module) → Set[str] --- - + -### method `PCustomShowCommand.get_ctypes_value` +## function `PCustomShowCommand.get_ctypes_value` ```python get_ctypes_value(struct, item, value) → str @@ -15068,9 +15068,9 @@ get_ctypes_value(struct, item, value) → str --- - + -### method `PCustomShowCommand.get_modulename_structname_from_arg` +## function `PCustomShowCommand.get_modulename_structname_from_arg` ```python get_modulename_structname_from_arg(arg: str) → Tuple[str, str] @@ -15082,9 +15082,9 @@ get_modulename_structname_from_arg(arg: str) → Tuple[str, str] --- - + -### method `PCustomShowCommand.get_pcustom_absolute_root_path` +## function `PCustomShowCommand.get_pcustom_absolute_root_path` ```python get_pcustom_absolute_root_path() → Union[str, bytes] @@ -15096,9 +15096,9 @@ get_pcustom_absolute_root_path() → Union[str, bytes] --- - + -### method `PCustomShowCommand.get_pcustom_filepath_for_structure` +## function `PCustomShowCommand.get_pcustom_filepath_for_structure` ```python get_pcustom_filepath_for_structure(structure_name: str) → str @@ -15110,9 +15110,9 @@ get_pcustom_filepath_for_structure(structure_name: str) → str --- - + -### method `PCustomShowCommand.get_setting` +## function `PCustomShowCommand.get_setting` ```python get_setting(name) @@ -15122,9 +15122,9 @@ get_setting(name) --- - + -### method `PCustomShowCommand.get_structure_class` +## function `PCustomShowCommand.get_structure_class` ```python get_structure_class( @@ -15137,9 +15137,9 @@ Returns a tuple of (class, instance) if modname!classname exists --- - + -### method `PCustomShowCommand.has_setting` +## function `PCustomShowCommand.has_setting` ```python has_setting(name: str) → bool @@ -15149,9 +15149,9 @@ has_setting(name: str) → bool --- - + -### method `PCustomShowCommand.invoke` +## function `PCustomShowCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -15163,9 +15163,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PCustomShowCommand.is_valid_struct` +## function `PCustomShowCommand.is_valid_struct` ```python is_valid_struct(structure_name: str) → bool @@ -15177,9 +15177,9 @@ is_valid_struct(structure_name: str) → bool --- - + -### method `PCustomShowCommand.load_module` +## function `PCustomShowCommand.load_module` ```python load_module(file_path: str) → module @@ -15189,9 +15189,9 @@ Load a custom module, and return it --- - + -### method `PCustomShowCommand.post_load` +## function `PCustomShowCommand.post_load` ```python post_load() → None @@ -15203,9 +15203,9 @@ post_load() → None --- - + -### method `PCustomShowCommand.pre_load` +## function `PCustomShowCommand.pre_load` ```python pre_load() → None @@ -15217,9 +15217,9 @@ pre_load() → None --- - + -### method `PCustomShowCommand.usage` +## function `PCustomShowCommand.usage` ```python usage() → None @@ -15235,9 +15235,9 @@ usage() → None ## class `PatchByteCommand` Write specified WORD to the specified address. - + -### method `PatchByteCommand.__init__` +## function `PatchByteCommand.__init__` ```python __init__() → None @@ -15258,9 +15258,9 @@ Return the list of settings for this command. --- - + -### method `PatchByteCommand.add_setting` +## function `PatchByteCommand.add_setting` ```python add_setting( @@ -15274,9 +15274,9 @@ add_setting( --- - + -### method `PatchByteCommand.del_setting` +## function `PatchByteCommand.del_setting` ```python del_setting(name: str) → None @@ -15286,9 +15286,9 @@ del_setting(name: str) → None --- - + -### function `PatchByteCommand.wrapper` +## function `PatchByteCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -15300,9 +15300,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `PatchByteCommand.get_setting` +## function `PatchByteCommand.get_setting` ```python get_setting(name) @@ -15312,9 +15312,9 @@ get_setting(name) --- - + -### method `PatchByteCommand.has_setting` +## function `PatchByteCommand.has_setting` ```python has_setting(name: str) → bool @@ -15324,9 +15324,9 @@ has_setting(name: str) → bool --- - + -### method `PatchByteCommand.invoke` +## function `PatchByteCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -15338,9 +15338,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PatchByteCommand.post_load` +## function `PatchByteCommand.post_load` ```python post_load() → None @@ -15352,9 +15352,9 @@ post_load() → None --- - + -### method `PatchByteCommand.pre_load` +## function `PatchByteCommand.pre_load` ```python pre_load() → None @@ -15366,9 +15366,9 @@ pre_load() → None --- - + -### method `PatchByteCommand.usage` +## function `PatchByteCommand.usage` ```python usage() → None @@ -15384,9 +15384,9 @@ usage() → None ## class `PatchCommand` Write specified values to the specified address. - + -### method `PatchCommand.__init__` +## function `PatchCommand.__init__` ```python __init__() → None @@ -15407,9 +15407,9 @@ Return the list of settings for this command. --- - + -### method `PatchCommand.add_setting` +## function `PatchCommand.add_setting` ```python add_setting( @@ -15423,9 +15423,9 @@ add_setting( --- - + -### method `PatchCommand.del_setting` +## function `PatchCommand.del_setting` ```python del_setting(name: str) → None @@ -15435,9 +15435,9 @@ del_setting(name: str) → None --- - + -### function `PatchCommand.wrapper` +## function `PatchCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -15449,9 +15449,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `PatchCommand.get_setting` +## function `PatchCommand.get_setting` ```python get_setting(name) @@ -15461,9 +15461,9 @@ get_setting(name) --- - + -### method `PatchCommand.has_setting` +## function `PatchCommand.has_setting` ```python has_setting(name: str) → bool @@ -15473,9 +15473,9 @@ has_setting(name: str) → bool --- - + -### method `PatchCommand.invoke` +## function `PatchCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -15487,9 +15487,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PatchCommand.post_load` +## function `PatchCommand.post_load` ```python post_load() → None @@ -15501,9 +15501,9 @@ post_load() → None --- - + -### method `PatchCommand.pre_load` +## function `PatchCommand.pre_load` ```python pre_load() → None @@ -15515,9 +15515,9 @@ pre_load() → None --- - + -### method `PatchCommand.usage` +## function `PatchCommand.usage` ```python usage() → None @@ -15533,9 +15533,9 @@ usage() → None ## class `PatchDwordCommand` Write specified DWORD to the specified address. - + -### method `PatchDwordCommand.__init__` +## function `PatchDwordCommand.__init__` ```python __init__() → None @@ -15556,9 +15556,9 @@ Return the list of settings for this command. --- - + -### method `PatchDwordCommand.add_setting` +## function `PatchDwordCommand.add_setting` ```python add_setting( @@ -15572,9 +15572,9 @@ add_setting( --- - + -### method `PatchDwordCommand.del_setting` +## function `PatchDwordCommand.del_setting` ```python del_setting(name: str) → None @@ -15584,9 +15584,9 @@ del_setting(name: str) → None --- - + -### function `PatchDwordCommand.wrapper` +## function `PatchDwordCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -15598,9 +15598,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `PatchDwordCommand.get_setting` +## function `PatchDwordCommand.get_setting` ```python get_setting(name) @@ -15610,9 +15610,9 @@ get_setting(name) --- - + -### method `PatchDwordCommand.has_setting` +## function `PatchDwordCommand.has_setting` ```python has_setting(name: str) → bool @@ -15622,9 +15622,9 @@ has_setting(name: str) → bool --- - + -### method `PatchDwordCommand.invoke` +## function `PatchDwordCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -15636,9 +15636,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PatchDwordCommand.post_load` +## function `PatchDwordCommand.post_load` ```python post_load() → None @@ -15650,9 +15650,9 @@ post_load() → None --- - + -### method `PatchDwordCommand.pre_load` +## function `PatchDwordCommand.pre_load` ```python pre_load() → None @@ -15664,9 +15664,9 @@ pre_load() → None --- - + -### method `PatchDwordCommand.usage` +## function `PatchDwordCommand.usage` ```python usage() → None @@ -15682,9 +15682,9 @@ usage() → None ## class `PatchQwordCommand` Write specified QWORD to the specified address. - + -### method `PatchQwordCommand.__init__` +## function `PatchQwordCommand.__init__` ```python __init__() → None @@ -15705,9 +15705,9 @@ Return the list of settings for this command. --- - + -### method `PatchQwordCommand.add_setting` +## function `PatchQwordCommand.add_setting` ```python add_setting( @@ -15721,9 +15721,9 @@ add_setting( --- - + -### method `PatchQwordCommand.del_setting` +## function `PatchQwordCommand.del_setting` ```python del_setting(name: str) → None @@ -15733,9 +15733,9 @@ del_setting(name: str) → None --- - + -### function `PatchQwordCommand.wrapper` +## function `PatchQwordCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -15747,9 +15747,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `PatchQwordCommand.get_setting` +## function `PatchQwordCommand.get_setting` ```python get_setting(name) @@ -15759,9 +15759,9 @@ get_setting(name) --- - + -### method `PatchQwordCommand.has_setting` +## function `PatchQwordCommand.has_setting` ```python has_setting(name: str) → bool @@ -15771,9 +15771,9 @@ has_setting(name: str) → bool --- - + -### method `PatchQwordCommand.invoke` +## function `PatchQwordCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -15785,9 +15785,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PatchQwordCommand.post_load` +## function `PatchQwordCommand.post_load` ```python post_load() → None @@ -15799,9 +15799,9 @@ post_load() → None --- - + -### method `PatchQwordCommand.pre_load` +## function `PatchQwordCommand.pre_load` ```python pre_load() → None @@ -15813,9 +15813,9 @@ pre_load() → None --- - + -### method `PatchQwordCommand.usage` +## function `PatchQwordCommand.usage` ```python usage() → None @@ -15831,9 +15831,9 @@ usage() → None ## class `PatchStringCommand` Write specified string to the specified memory location pointed by ADDRESS. - + -### method `PatchStringCommand.__init__` +## function `PatchStringCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -15854,9 +15854,9 @@ Return the list of settings for this command. --- - + -### method `PatchStringCommand.add_setting` +## function `PatchStringCommand.add_setting` ```python add_setting( @@ -15870,9 +15870,9 @@ add_setting( --- - + -### method `PatchStringCommand.del_setting` +## function `PatchStringCommand.del_setting` ```python del_setting(name: str) → None @@ -15882,9 +15882,9 @@ del_setting(name: str) → None --- - + -### method `PatchStringCommand.do_invoke` +## function `PatchStringCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -15896,9 +15896,9 @@ do_invoke(argv: List) → None --- - + -### method `PatchStringCommand.get_setting` +## function `PatchStringCommand.get_setting` ```python get_setting(name) @@ -15908,9 +15908,9 @@ get_setting(name) --- - + -### method `PatchStringCommand.has_setting` +## function `PatchStringCommand.has_setting` ```python has_setting(name: str) → bool @@ -15920,9 +15920,9 @@ has_setting(name: str) → bool --- - + -### method `PatchStringCommand.invoke` +## function `PatchStringCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -15934,9 +15934,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PatchStringCommand.post_load` +## function `PatchStringCommand.post_load` ```python post_load() → None @@ -15948,9 +15948,9 @@ post_load() → None --- - + -### method `PatchStringCommand.pre_load` +## function `PatchStringCommand.pre_load` ```python pre_load() → None @@ -15962,9 +15962,9 @@ pre_load() → None --- - + -### method `PatchStringCommand.usage` +## function `PatchStringCommand.usage` ```python usage() → None @@ -15980,9 +15980,9 @@ usage() → None ## class `PatchWordCommand` Write specified WORD to the specified address. - + -### method `PatchWordCommand.__init__` +## function `PatchWordCommand.__init__` ```python __init__() → None @@ -16003,9 +16003,9 @@ Return the list of settings for this command. --- - + -### method `PatchWordCommand.add_setting` +## function `PatchWordCommand.add_setting` ```python add_setting( @@ -16019,9 +16019,9 @@ add_setting( --- - + -### method `PatchWordCommand.del_setting` +## function `PatchWordCommand.del_setting` ```python del_setting(name: str) → None @@ -16031,9 +16031,9 @@ del_setting(name: str) → None --- - + -### function `PatchWordCommand.wrapper` +## function `PatchWordCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -16045,9 +16045,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `PatchWordCommand.get_setting` +## function `PatchWordCommand.get_setting` ```python get_setting(name) @@ -16057,9 +16057,9 @@ get_setting(name) --- - + -### method `PatchWordCommand.has_setting` +## function `PatchWordCommand.has_setting` ```python has_setting(name: str) → bool @@ -16069,9 +16069,9 @@ has_setting(name: str) → bool --- - + -### method `PatchWordCommand.invoke` +## function `PatchWordCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -16083,9 +16083,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PatchWordCommand.post_load` +## function `PatchWordCommand.post_load` ```python post_load() → None @@ -16097,9 +16097,9 @@ post_load() → None --- - + -### method `PatchWordCommand.pre_load` +## function `PatchWordCommand.pre_load` ```python pre_load() → None @@ -16111,9 +16111,9 @@ pre_load() → None --- - + -### method `PatchWordCommand.usage` +## function `PatchWordCommand.usage` ```python usage() → None @@ -16129,9 +16129,9 @@ 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. - + -### method `PatternCommand.__init__` +## function `PatternCommand.__init__` ```python __init__() → None @@ -16152,9 +16152,9 @@ Return the list of settings for this command. --- - + -### method `PatternCommand.add_setting` +## function `PatternCommand.add_setting` ```python add_setting( @@ -16168,9 +16168,9 @@ add_setting( --- - + -### method `PatternCommand.del_setting` +## function `PatternCommand.del_setting` ```python del_setting(name: str) → None @@ -16180,9 +16180,9 @@ del_setting(name: str) → None --- - + -### method `PatternCommand.do_invoke` +## function `PatternCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -16194,9 +16194,9 @@ do_invoke(argv: List) → None --- - + -### method `PatternCommand.get_setting` +## function `PatternCommand.get_setting` ```python get_setting(name) @@ -16206,9 +16206,9 @@ get_setting(name) --- - + -### method `PatternCommand.has_setting` +## function `PatternCommand.has_setting` ```python has_setting(name: str) → bool @@ -16218,9 +16218,9 @@ has_setting(name: str) → bool --- - + -### method `PatternCommand.invoke` +## function `PatternCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -16232,9 +16232,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PatternCommand.post_load` +## function `PatternCommand.post_load` ```python post_load() → None @@ -16246,9 +16246,9 @@ post_load() → None --- - + -### method `PatternCommand.pre_load` +## function `PatternCommand.pre_load` ```python pre_load() → None @@ -16260,9 +16260,9 @@ pre_load() → None --- - + -### method `PatternCommand.usage` +## function `PatternCommand.usage` ```python usage() → None @@ -16278,9 +16278,9 @@ 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. - + -### method `PatternCreateCommand.__init__` +## function `PatternCreateCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -16301,9 +16301,9 @@ Return the list of settings for this command. --- - + -### method `PatternCreateCommand.add_setting` +## function `PatternCreateCommand.add_setting` ```python add_setting( @@ -16317,9 +16317,9 @@ add_setting( --- - + -### method `PatternCreateCommand.del_setting` +## function `PatternCreateCommand.del_setting` ```python del_setting(name: str) → None @@ -16329,9 +16329,9 @@ del_setting(name: str) → None --- - + -### function `PatternCreateCommand.wrapper` +## function `PatternCreateCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -16343,9 +16343,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `PatternCreateCommand.get_setting` +## function `PatternCreateCommand.get_setting` ```python get_setting(name) @@ -16355,9 +16355,9 @@ get_setting(name) --- - + -### method `PatternCreateCommand.has_setting` +## function `PatternCreateCommand.has_setting` ```python has_setting(name: str) → bool @@ -16367,9 +16367,9 @@ has_setting(name: str) → bool --- - + -### method `PatternCreateCommand.invoke` +## function `PatternCreateCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -16381,9 +16381,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PatternCreateCommand.post_load` +## function `PatternCreateCommand.post_load` ```python post_load() → None @@ -16395,9 +16395,9 @@ post_load() → None --- - + -### method `PatternCreateCommand.pre_load` +## function `PatternCreateCommand.pre_load` ```python pre_load() → None @@ -16409,9 +16409,9 @@ pre_load() → None --- - + -### method `PatternCreateCommand.usage` +## function `PatternCreateCommand.usage` ```python usage() → None @@ -16427,9 +16427,9 @@ 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 - + -### method `PatternSearchCommand.__init__` +## function `PatternSearchCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -16450,9 +16450,9 @@ Return the list of settings for this command. --- - + -### method `PatternSearchCommand.add_setting` +## function `PatternSearchCommand.add_setting` ```python add_setting( @@ -16466,9 +16466,9 @@ add_setting( --- - + -### method `PatternSearchCommand.del_setting` +## function `PatternSearchCommand.del_setting` ```python del_setting(name: str) → None @@ -16478,9 +16478,9 @@ del_setting(name: str) → None --- - + -### function `PatternSearchCommand.wrapper` +## function `PatternSearchCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -16492,9 +16492,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `PatternSearchCommand.get_setting` +## function `PatternSearchCommand.get_setting` ```python get_setting(name) @@ -16504,9 +16504,9 @@ get_setting(name) --- - + -### method `PatternSearchCommand.has_setting` +## function `PatternSearchCommand.has_setting` ```python has_setting(name: str) → bool @@ -16516,9 +16516,9 @@ has_setting(name: str) → bool --- - + -### method `PatternSearchCommand.invoke` +## function `PatternSearchCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -16530,9 +16530,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PatternSearchCommand.post_load` +## function `PatternSearchCommand.post_load` ```python post_load() → None @@ -16544,9 +16544,9 @@ post_load() → None --- - + -### method `PatternSearchCommand.pre_load` +## function `PatternSearchCommand.pre_load` ```python pre_load() → None @@ -16558,9 +16558,9 @@ pre_load() → None --- - + -### method `PatternSearchCommand.search` +## function `PatternSearchCommand.search` ```python search(pattern: str, size: int, period: int) → None @@ -16572,9 +16572,9 @@ search(pattern: str, size: int, period: int) → None --- - + -### method `PatternSearchCommand.usage` +## function `PatternSearchCommand.usage` ```python usage() → None @@ -16590,9 +16590,9 @@ usage() → None ## class `Permission` GEF representation of Linux permission. - + -### method `Permission.__init__` +## function `Permission.__init__` ```python __init__(**kwargs) → None @@ -16607,9 +16607,9 @@ __init__(**kwargs) → None --- - + -### method `Permission.from_info_sections` +## function `Permission.from_info_sections` ```python from_info_sections(*args: List[str]) @@ -16621,9 +16621,9 @@ from_info_sections(*args: List[str]) --- - + -### method `Permission.from_process_maps` +## function `Permission.from_process_maps` ```python from_process_maps(perm_str: str) @@ -16641,9 +16641,9 @@ from_process_maps(perm_str: str) - + -### method `Phdr.__init__` +## function `Phdr.__init__` ```python __init__(elf: __main__.Elf, off: int) → None @@ -16662,9 +16662,9 @@ __init__(elf: __main__.Elf, off: int) → None ## class `PieAttachCommand` Do attach with PIE breakpoint support. - + -### method `PieAttachCommand.__init__` +## function `PieAttachCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -16685,9 +16685,9 @@ Return the list of settings for this command. --- - + -### method `PieAttachCommand.add_setting` +## function `PieAttachCommand.add_setting` ```python add_setting( @@ -16701,9 +16701,9 @@ add_setting( --- - + -### method `PieAttachCommand.del_setting` +## function `PieAttachCommand.del_setting` ```python del_setting(name: str) → None @@ -16713,9 +16713,9 @@ del_setting(name: str) → None --- - + -### method `PieAttachCommand.do_invoke` +## function `PieAttachCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -16727,9 +16727,9 @@ do_invoke(argv: List) → None --- - + -### method `PieAttachCommand.get_setting` +## function `PieAttachCommand.get_setting` ```python get_setting(name) @@ -16739,9 +16739,9 @@ get_setting(name) --- - + -### method `PieAttachCommand.has_setting` +## function `PieAttachCommand.has_setting` ```python has_setting(name: str) → bool @@ -16751,9 +16751,9 @@ has_setting(name: str) → bool --- - + -### method `PieAttachCommand.invoke` +## function `PieAttachCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -16765,9 +16765,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PieAttachCommand.post_load` +## function `PieAttachCommand.post_load` ```python post_load() → None @@ -16779,9 +16779,9 @@ post_load() → None --- - + -### method `PieAttachCommand.pre_load` +## function `PieAttachCommand.pre_load` ```python pre_load() → None @@ -16793,9 +16793,9 @@ pre_load() → None --- - + -### method `PieAttachCommand.usage` +## function `PieAttachCommand.usage` ```python usage() → None @@ -16811,9 +16811,9 @@ usage() → None ## class `PieBreakpointCommand` Set a PIE breakpoint at an offset from the target binaries base address. - + -### method `PieBreakpointCommand.__init__` +## function `PieBreakpointCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -16834,9 +16834,9 @@ Return the list of settings for this command. --- - + -### method `PieBreakpointCommand.add_setting` +## function `PieBreakpointCommand.add_setting` ```python add_setting( @@ -16850,9 +16850,9 @@ add_setting( --- - + -### method `PieBreakpointCommand.del_setting` +## function `PieBreakpointCommand.del_setting` ```python del_setting(name: str) → None @@ -16862,9 +16862,9 @@ del_setting(name: str) → None --- - + -### function `PieBreakpointCommand.wrapper` +## function `PieBreakpointCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -16876,9 +16876,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `PieBreakpointCommand.get_setting` +## function `PieBreakpointCommand.get_setting` ```python get_setting(name) @@ -16888,9 +16888,9 @@ get_setting(name) --- - + -### method `PieBreakpointCommand.has_setting` +## function `PieBreakpointCommand.has_setting` ```python has_setting(name: str) → bool @@ -16900,9 +16900,9 @@ has_setting(name: str) → bool --- - + -### method `PieBreakpointCommand.invoke` +## function `PieBreakpointCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -16914,9 +16914,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PieBreakpointCommand.post_load` +## function `PieBreakpointCommand.post_load` ```python post_load() → None @@ -16928,9 +16928,9 @@ post_load() → None --- - + -### method `PieBreakpointCommand.pre_load` +## function `PieBreakpointCommand.pre_load` ```python pre_load() → None @@ -16942,9 +16942,9 @@ pre_load() → None --- - + -### method `PieBreakpointCommand.set_pie_breakpoint` +## function `PieBreakpointCommand.set_pie_breakpoint` ```python set_pie_breakpoint(set_func: Callable[[int], str], addr: int) → None @@ -16956,9 +16956,9 @@ set_pie_breakpoint(set_func: Callable[[int], str], addr: int) → None --- - + -### method `PieBreakpointCommand.usage` +## function `PieBreakpointCommand.usage` ```python usage() → None @@ -16974,9 +16974,9 @@ usage() → None ## class `PieCommand` PIE breakpoint support. - + -### method `PieCommand.__init__` +## function `PieCommand.__init__` ```python __init__() → None @@ -16997,9 +16997,9 @@ Return the list of settings for this command. --- - + -### method `PieCommand.add_setting` +## function `PieCommand.add_setting` ```python add_setting( @@ -17013,9 +17013,9 @@ add_setting( --- - + -### method `PieCommand.del_setting` +## function `PieCommand.del_setting` ```python del_setting(name: str) → None @@ -17025,9 +17025,9 @@ del_setting(name: str) → None --- - + -### method `PieCommand.do_invoke` +## function `PieCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -17039,9 +17039,9 @@ do_invoke(argv: List) → None --- - + -### method `PieCommand.get_setting` +## function `PieCommand.get_setting` ```python get_setting(name) @@ -17051,9 +17051,9 @@ get_setting(name) --- - + -### method `PieCommand.has_setting` +## function `PieCommand.has_setting` ```python has_setting(name: str) → bool @@ -17063,9 +17063,9 @@ has_setting(name: str) → bool --- - + -### method `PieCommand.invoke` +## function `PieCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -17077,9 +17077,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PieCommand.post_load` +## function `PieCommand.post_load` ```python post_load() → None @@ -17091,9 +17091,9 @@ post_load() → None --- - + -### method `PieCommand.pre_load` +## function `PieCommand.pre_load` ```python pre_load() → None @@ -17105,9 +17105,9 @@ pre_load() → None --- - + -### method `PieCommand.usage` +## function `PieCommand.usage` ```python usage() → None @@ -17123,9 +17123,9 @@ usage() → None ## class `PieDeleteCommand` Delete a PIE breakpoint. - + -### method `PieDeleteCommand.__init__` +## function `PieDeleteCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -17146,9 +17146,9 @@ Return the list of settings for this command. --- - + -### method `PieDeleteCommand.add_setting` +## function `PieDeleteCommand.add_setting` ```python add_setting( @@ -17162,9 +17162,9 @@ add_setting( --- - + -### method `PieDeleteCommand.del_setting` +## function `PieDeleteCommand.del_setting` ```python del_setting(name: str) → None @@ -17174,9 +17174,9 @@ del_setting(name: str) → None --- - + -### method `PieDeleteCommand.delete_bp` +## function `PieDeleteCommand.delete_bp` ```python delete_bp(breakpoints: List) → None @@ -17188,9 +17188,9 @@ delete_bp(breakpoints: List) → None --- - + -### function `PieDeleteCommand.wrapper` +## function `PieDeleteCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -17202,9 +17202,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `PieDeleteCommand.get_setting` +## function `PieDeleteCommand.get_setting` ```python get_setting(name) @@ -17214,9 +17214,9 @@ get_setting(name) --- - + -### method `PieDeleteCommand.has_setting` +## function `PieDeleteCommand.has_setting` ```python has_setting(name: str) → bool @@ -17226,9 +17226,9 @@ has_setting(name: str) → bool --- - + -### method `PieDeleteCommand.invoke` +## function `PieDeleteCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -17240,9 +17240,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PieDeleteCommand.post_load` +## function `PieDeleteCommand.post_load` ```python post_load() → None @@ -17254,9 +17254,9 @@ post_load() → None --- - + -### method `PieDeleteCommand.pre_load` +## function `PieDeleteCommand.pre_load` ```python pre_load() → None @@ -17268,9 +17268,9 @@ pre_load() → None --- - + -### method `PieDeleteCommand.usage` +## function `PieDeleteCommand.usage` ```python usage() → None @@ -17286,9 +17286,9 @@ usage() → None ## class `PieInfoCommand` Display breakpoint info. - + -### method `PieInfoCommand.__init__` +## function `PieInfoCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -17309,9 +17309,9 @@ Return the list of settings for this command. --- - + -### method `PieInfoCommand.add_setting` +## function `PieInfoCommand.add_setting` ```python add_setting( @@ -17325,9 +17325,9 @@ add_setting( --- - + -### method `PieInfoCommand.del_setting` +## function `PieInfoCommand.del_setting` ```python del_setting(name: str) → None @@ -17337,9 +17337,9 @@ del_setting(name: str) → None --- - + -### function `PieInfoCommand.wrapper` +## function `PieInfoCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -17351,9 +17351,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `PieInfoCommand.get_setting` +## function `PieInfoCommand.get_setting` ```python get_setting(name) @@ -17363,9 +17363,9 @@ get_setting(name) --- - + -### method `PieInfoCommand.has_setting` +## function `PieInfoCommand.has_setting` ```python has_setting(name: str) → bool @@ -17375,9 +17375,9 @@ has_setting(name: str) → bool --- - + -### method `PieInfoCommand.invoke` +## function `PieInfoCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -17389,9 +17389,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PieInfoCommand.post_load` +## function `PieInfoCommand.post_load` ```python post_load() → None @@ -17403,9 +17403,9 @@ post_load() → None --- - + -### method `PieInfoCommand.pre_load` +## function `PieInfoCommand.pre_load` ```python pre_load() → None @@ -17417,9 +17417,9 @@ pre_load() → None --- - + -### method `PieInfoCommand.usage` +## function `PieInfoCommand.usage` ```python usage() → None @@ -17435,9 +17435,9 @@ usage() → None ## class `PieRemoteCommand` Attach to a remote connection with PIE breakpoint support. - + -### method `PieRemoteCommand.__init__` +## function `PieRemoteCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -17458,9 +17458,9 @@ Return the list of settings for this command. --- - + -### method `PieRemoteCommand.add_setting` +## function `PieRemoteCommand.add_setting` ```python add_setting( @@ -17474,9 +17474,9 @@ add_setting( --- - + -### method `PieRemoteCommand.del_setting` +## function `PieRemoteCommand.del_setting` ```python del_setting(name: str) → None @@ -17486,9 +17486,9 @@ del_setting(name: str) → None --- - + -### method `PieRemoteCommand.do_invoke` +## function `PieRemoteCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -17500,9 +17500,9 @@ do_invoke(argv: List) → None --- - + -### method `PieRemoteCommand.get_setting` +## function `PieRemoteCommand.get_setting` ```python get_setting(name) @@ -17512,9 +17512,9 @@ get_setting(name) --- - + -### method `PieRemoteCommand.has_setting` +## function `PieRemoteCommand.has_setting` ```python has_setting(name: str) → bool @@ -17524,9 +17524,9 @@ has_setting(name: str) → bool --- - + -### method `PieRemoteCommand.invoke` +## function `PieRemoteCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -17538,9 +17538,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PieRemoteCommand.post_load` +## function `PieRemoteCommand.post_load` ```python post_load() → None @@ -17552,9 +17552,9 @@ post_load() → None --- - + -### method `PieRemoteCommand.pre_load` +## function `PieRemoteCommand.pre_load` ```python pre_load() → None @@ -17566,9 +17566,9 @@ pre_load() → None --- - + -### method `PieRemoteCommand.usage` +## function `PieRemoteCommand.usage` ```python usage() → None @@ -17584,9 +17584,9 @@ usage() → None ## class `PieRunCommand` Run process with PIE breakpoint support. - + -### method `PieRunCommand.__init__` +## function `PieRunCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -17607,9 +17607,9 @@ Return the list of settings for this command. --- - + -### method `PieRunCommand.add_setting` +## function `PieRunCommand.add_setting` ```python add_setting( @@ -17623,9 +17623,9 @@ add_setting( --- - + -### method `PieRunCommand.del_setting` +## function `PieRunCommand.del_setting` ```python del_setting(name: str) → None @@ -17635,9 +17635,9 @@ del_setting(name: str) → None --- - + -### method `PieRunCommand.do_invoke` +## function `PieRunCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -17649,9 +17649,9 @@ do_invoke(argv: List) → None --- - + -### method `PieRunCommand.get_setting` +## function `PieRunCommand.get_setting` ```python get_setting(name) @@ -17661,9 +17661,9 @@ get_setting(name) --- - + -### method `PieRunCommand.has_setting` +## function `PieRunCommand.has_setting` ```python has_setting(name: str) → bool @@ -17673,9 +17673,9 @@ has_setting(name: str) → bool --- - + -### method `PieRunCommand.invoke` +## function `PieRunCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -17687,9 +17687,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PieRunCommand.post_load` +## function `PieRunCommand.post_load` ```python post_load() → None @@ -17701,9 +17701,9 @@ post_load() → None --- - + -### method `PieRunCommand.pre_load` +## function `PieRunCommand.pre_load` ```python pre_load() → None @@ -17715,9 +17715,9 @@ pre_load() → None --- - + -### method `PieRunCommand.usage` +## function `PieRunCommand.usage` ```python usage() → None @@ -17733,9 +17733,9 @@ usage() → None ## class `PieVirtualBreakpoint` PIE virtual breakpoint (not real breakpoint). - + -### method `PieVirtualBreakpoint.__init__` +## function `PieVirtualBreakpoint.__init__` ```python __init__(set_func: Callable[[int], str], vbp_num: int, addr: int) → None @@ -17750,9 +17750,9 @@ __init__(set_func: Callable[[int], str], vbp_num: int, addr: int) → None --- - + -### method `PieVirtualBreakpoint.destroy` +## function `PieVirtualBreakpoint.destroy` ```python destroy() → None @@ -17764,9 +17764,9 @@ destroy() → None --- - + -### method `PieVirtualBreakpoint.instantiate` +## function `PieVirtualBreakpoint.instantiate` ```python instantiate(base: int) → None @@ -17837,9 +17837,9 @@ instantiate(base: int) → None --- - + -### method `PowerPC.flag_register_to_human` +## function `PowerPC.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → str @@ -17851,9 +17851,9 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + -### method `PowerPC.get_ith_parameter` +## function `PowerPC.get_ith_parameter` ```python get_ith_parameter( @@ -17866,9 +17866,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `PowerPC.get_ra` +## function `PowerPC.get_ra` ```python get_ra(insn, frame) → Union[int, NoneType] @@ -17880,9 +17880,9 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + -### method `PowerPC.is_branch_taken` +## function `PowerPC.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -17894,9 +17894,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `PowerPC.is_call` +## function `PowerPC.is_call` ```python is_call(insn) → bool @@ -17908,9 +17908,9 @@ is_call(insn) → bool --- - + -### method `PowerPC.is_conditional_branch` +## function `PowerPC.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -17922,9 +17922,9 @@ is_conditional_branch(insn) → bool --- - + -### method `PowerPC.is_ret` +## function `PowerPC.is_ret` ```python is_ret(insn) → bool @@ -17936,9 +17936,9 @@ is_ret(insn) → bool --- - + -### classmethod `PowerPC.mprotect_asm` +## function `PowerPC.mprotect_asm` ```python mprotect_asm(addr: int, size: int, perm) → str @@ -17950,9 +17950,9 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + -### method `PowerPC.register` +## function `PowerPC.register` ```python register(name: str) → Union[int, NoneType] @@ -18023,9 +18023,9 @@ register(name: str) → Union[int, NoneType] --- - + -### method `PowerPC64.flag_register_to_human` +## function `PowerPC64.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → str @@ -18037,9 +18037,9 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + -### method `PowerPC64.get_ith_parameter` +## function `PowerPC64.get_ith_parameter` ```python get_ith_parameter( @@ -18052,9 +18052,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `PowerPC64.get_ra` +## function `PowerPC64.get_ra` ```python get_ra(insn, frame) → Union[int, NoneType] @@ -18066,9 +18066,9 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + -### method `PowerPC64.is_branch_taken` +## function `PowerPC64.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -18080,9 +18080,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `PowerPC64.is_call` +## function `PowerPC64.is_call` ```python is_call(insn) → bool @@ -18094,9 +18094,9 @@ is_call(insn) → bool --- - + -### method `PowerPC64.is_conditional_branch` +## function `PowerPC64.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -18108,9 +18108,9 @@ is_conditional_branch(insn) → bool --- - + -### method `PowerPC64.is_ret` +## function `PowerPC64.is_ret` ```python is_ret(insn) → bool @@ -18122,9 +18122,9 @@ is_ret(insn) → bool --- - + -### classmethod `PowerPC64.mprotect_asm` +## function `PowerPC64.mprotect_asm` ```python mprotect_asm(addr: int, size: int, perm) → str @@ -18136,9 +18136,9 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + -### method `PowerPC64.register` +## function `PowerPC64.register` ```python register(name: str) → Union[int, NoneType] @@ -18154,9 +18154,9 @@ register(name: str) → Union[int, NoneType] ## class `PrintFormatCommand` Print bytes format in high level languages. - + -### method `PrintFormatCommand.__init__` +## function `PrintFormatCommand.__init__` ```python __init__() → None @@ -18185,9 +18185,9 @@ Return the list of settings for this command. --- - + -### method `PrintFormatCommand.add_setting` +## function `PrintFormatCommand.add_setting` ```python add_setting( @@ -18201,9 +18201,9 @@ add_setting( --- - + -### method `PrintFormatCommand.del_setting` +## function `PrintFormatCommand.del_setting` ```python del_setting(name: str) → None @@ -18213,9 +18213,9 @@ del_setting(name: str) → None --- - + -### function `PrintFormatCommand.wrapper` +## function `PrintFormatCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -18227,9 +18227,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `PrintFormatCommand.get_setting` +## function `PrintFormatCommand.get_setting` ```python get_setting(name) @@ -18239,9 +18239,9 @@ get_setting(name) --- - + -### method `PrintFormatCommand.has_setting` +## function `PrintFormatCommand.has_setting` ```python has_setting(name: str) → bool @@ -18251,9 +18251,9 @@ has_setting(name: str) → bool --- - + -### method `PrintFormatCommand.invoke` +## function `PrintFormatCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -18265,9 +18265,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `PrintFormatCommand.post_load` +## function `PrintFormatCommand.post_load` ```python post_load() → None @@ -18279,9 +18279,9 @@ post_load() → None --- - + -### method `PrintFormatCommand.pre_load` +## function `PrintFormatCommand.pre_load` ```python pre_load() → None @@ -18293,9 +18293,9 @@ pre_load() → None --- - + -### method `PrintFormatCommand.usage` +## function `PrintFormatCommand.usage` ```python usage() → None @@ -18311,9 +18311,9 @@ usage() → None ## class `ProcessListingCommand` List and filter process. If a PATTERN is given as argument, results shown will be grepped by this pattern. - + -### method `ProcessListingCommand.__init__` +## function `ProcessListingCommand.__init__` ```python __init__() → None @@ -18334,9 +18334,9 @@ Return the list of settings for this command. --- - + -### method `ProcessListingCommand.add_setting` +## function `ProcessListingCommand.add_setting` ```python add_setting( @@ -18350,9 +18350,9 @@ add_setting( --- - + -### method `ProcessListingCommand.del_setting` +## function `ProcessListingCommand.del_setting` ```python del_setting(name: str) → None @@ -18362,9 +18362,9 @@ del_setting(name: str) → None --- - + -### function `ProcessListingCommand.wrapper` +## function `ProcessListingCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -18376,9 +18376,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `ProcessListingCommand.get_processes` +## function `ProcessListingCommand.get_processes` ```python get_processes() → Generator[Dict[str, str], Any, NoneType] @@ -18390,9 +18390,9 @@ get_processes() → Generator[Dict[str, str], Any, NoneType] --- - + -### method `ProcessListingCommand.get_setting` +## function `ProcessListingCommand.get_setting` ```python get_setting(name) @@ -18402,9 +18402,9 @@ get_setting(name) --- - + -### method `ProcessListingCommand.has_setting` +## function `ProcessListingCommand.has_setting` ```python has_setting(name: str) → bool @@ -18414,9 +18414,9 @@ has_setting(name: str) → bool --- - + -### method `ProcessListingCommand.invoke` +## function `ProcessListingCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -18428,9 +18428,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ProcessListingCommand.post_load` +## function `ProcessListingCommand.post_load` ```python post_load() → None @@ -18442,9 +18442,9 @@ post_load() → None --- - + -### method `ProcessListingCommand.pre_load` +## function `ProcessListingCommand.pre_load` ```python pre_load() → None @@ -18456,9 +18456,9 @@ pre_load() → None --- - + -### method `ProcessListingCommand.usage` +## function `ProcessListingCommand.usage` ```python usage() → None @@ -18474,9 +18474,9 @@ 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.). - + -### method `ProcessStatusCommand.__init__` +## function `ProcessStatusCommand.__init__` ```python __init__() → None @@ -18497,9 +18497,9 @@ Return the list of settings for this command. --- - + -### method `ProcessStatusCommand.add_setting` +## function `ProcessStatusCommand.add_setting` ```python add_setting( @@ -18513,9 +18513,9 @@ add_setting( --- - + -### method `ProcessStatusCommand.del_setting` +## function `ProcessStatusCommand.del_setting` ```python del_setting(name: str) → None @@ -18525,9 +18525,9 @@ del_setting(name: str) → None --- - + -### method `ProcessStatusCommand.do_invoke` +## function `ProcessStatusCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -18539,9 +18539,9 @@ do_invoke(argv: List) → None --- - + -### method `ProcessStatusCommand.get_children_pids` +## function `ProcessStatusCommand.get_children_pids` ```python get_children_pids(pid: int) → List[int] @@ -18553,9 +18553,9 @@ get_children_pids(pid: int) → List[int] --- - + -### method `ProcessStatusCommand.get_cmdline_of` +## function `ProcessStatusCommand.get_cmdline_of` ```python get_cmdline_of(pid: int) → str @@ -18567,9 +18567,9 @@ get_cmdline_of(pid: int) → str --- - + -### method `ProcessStatusCommand.get_process_path_of` +## function `ProcessStatusCommand.get_process_path_of` ```python get_process_path_of(pid: int) → str @@ -18581,9 +18581,9 @@ get_process_path_of(pid: int) → str --- - + -### method `ProcessStatusCommand.get_setting` +## function `ProcessStatusCommand.get_setting` ```python get_setting(name) @@ -18593,9 +18593,9 @@ get_setting(name) --- - + -### method `ProcessStatusCommand.get_state_of` +## function `ProcessStatusCommand.get_state_of` ```python get_state_of(pid: int) → Dict[str, str] @@ -18607,9 +18607,9 @@ get_state_of(pid: int) → Dict[str, str] --- - + -### method `ProcessStatusCommand.has_setting` +## function `ProcessStatusCommand.has_setting` ```python has_setting(name: str) → bool @@ -18619,9 +18619,9 @@ has_setting(name: str) → bool --- - + -### method `ProcessStatusCommand.invoke` +## function `ProcessStatusCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -18633,9 +18633,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ProcessStatusCommand.list_sockets` +## function `ProcessStatusCommand.list_sockets` ```python list_sockets(pid: int) → List[int] @@ -18647,9 +18647,9 @@ list_sockets(pid: int) → List[int] --- - + -### method `ProcessStatusCommand.parse_ip_port` +## function `ProcessStatusCommand.parse_ip_port` ```python parse_ip_port(addr: str) → Tuple[str, int] @@ -18661,9 +18661,9 @@ parse_ip_port(addr: str) → Tuple[str, int] --- - + -### method `ProcessStatusCommand.post_load` +## function `ProcessStatusCommand.post_load` ```python post_load() → None @@ -18675,9 +18675,9 @@ post_load() → None --- - + -### method `ProcessStatusCommand.pre_load` +## function `ProcessStatusCommand.pre_load` ```python pre_load() → None @@ -18689,9 +18689,9 @@ pre_load() → None --- - + -### method `ProcessStatusCommand.show_ancestor` +## function `ProcessStatusCommand.show_ancestor` ```python show_ancestor() → None @@ -18703,9 +18703,9 @@ show_ancestor() → None --- - + -### method `ProcessStatusCommand.show_connections` +## function `ProcessStatusCommand.show_connections` ```python show_connections() → None @@ -18717,9 +18717,9 @@ show_connections() → None --- - + -### method `ProcessStatusCommand.show_descendants` +## function `ProcessStatusCommand.show_descendants` ```python show_descendants() → None @@ -18731,9 +18731,9 @@ show_descendants() → None --- - + -### method `ProcessStatusCommand.show_fds` +## function `ProcessStatusCommand.show_fds` ```python show_fds() → None @@ -18745,9 +18745,9 @@ show_fds() → None --- - + -### method `ProcessStatusCommand.show_info_proc` +## function `ProcessStatusCommand.show_info_proc` ```python show_info_proc() → None @@ -18759,9 +18759,9 @@ show_info_proc() → None --- - + -### method `ProcessStatusCommand.usage` +## function `ProcessStatusCommand.usage` ```python usage() → None @@ -18840,9 +18840,9 @@ usage() → None --- - + -### method `RISCV.get_ith_parameter` +## function `RISCV.get_ith_parameter` ```python get_ith_parameter( @@ -18855,9 +18855,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `RISCV.get_ra` +## function `RISCV.get_ra` ```python get_ra(insn, frame) → int @@ -18869,9 +18869,9 @@ get_ra(insn, frame) → int --- - + -### method `RISCV.is_branch_taken` +## function `RISCV.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -18883,9 +18883,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `RISCV.is_call` +## function `RISCV.is_call` ```python is_call(insn) → bool @@ -18897,9 +18897,9 @@ is_call(insn) → bool --- - + -### method `RISCV.is_conditional_branch` +## function `RISCV.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -18911,9 +18911,9 @@ is_conditional_branch(insn) → bool --- - + -### method `RISCV.is_ret` +## function `RISCV.is_ret` ```python is_ret(insn) → bool @@ -18925,9 +18925,9 @@ is_ret(insn) → bool --- - + -### classmethod `RISCV.mprotect_asm` +## function `RISCV.mprotect_asm` ```python mprotect_asm(addr: int, size: int, perm) @@ -18939,9 +18939,9 @@ mprotect_asm(addr: int, size: int, perm) --- - + -### method `RISCV.register` +## function `RISCV.register` ```python register(name: str) → Union[int, NoneType] @@ -18959,9 +18959,9 @@ register(name: str) → Union[int, NoneType] - + -### method `RedirectOutputContext.__init__` +## function `RedirectOutputContext.__init__` ```python __init__(to='/dev/null') → None @@ -18980,9 +18980,9 @@ __init__(to='/dev/null') → None ## class `RemoteCommand` gef wrapper for the `target remote` command. This command will automatically download the target binary in the local temporary directory (defaut /tmp) and then source it. Additionally, it will fetch all the /proc/PID/maps and loads all its information. - + -### method `RemoteCommand.__init__` +## function `RemoteCommand.__init__` ```python __init__() → None @@ -19003,9 +19003,9 @@ Return the list of settings for this command. --- - + -### method `RemoteCommand.add_setting` +## function `RemoteCommand.add_setting` ```python add_setting( @@ -19019,9 +19019,9 @@ add_setting( --- - + -### method `RemoteCommand.connect_target` +## function `RemoteCommand.connect_target` ```python connect_target(target: str, is_extended_remote: bool) → bool @@ -19031,9 +19031,9 @@ Connect to remote target and get symbols. To prevent `gef` from requesting infor --- - + -### method `RemoteCommand.del_setting` +## function `RemoteCommand.del_setting` ```python del_setting(name: str) → None @@ -19043,9 +19043,9 @@ del_setting(name: str) → None --- - + -### function `RemoteCommand.wrapper` +## function `RemoteCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -19057,9 +19057,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `RemoteCommand.get_setting` +## function `RemoteCommand.get_setting` ```python get_setting(name) @@ -19069,9 +19069,9 @@ get_setting(name) --- - + -### method `RemoteCommand.has_setting` +## function `RemoteCommand.has_setting` ```python has_setting(name: str) → bool @@ -19081,9 +19081,9 @@ has_setting(name: str) → bool --- - + -### method `RemoteCommand.invoke` +## function `RemoteCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -19095,9 +19095,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `RemoteCommand.load_from_remote_proc` +## function `RemoteCommand.load_from_remote_proc` ```python load_from_remote_proc(pid: int, info: str) → Union[str, NoneType] @@ -19107,9 +19107,9 @@ Download one item from /proc/pid. --- - + -### method `RemoteCommand.new_objfile_handler` +## function `RemoteCommand.new_objfile_handler` ```python new_objfile_handler(event) → None @@ -19119,9 +19119,9 @@ Hook that handles new_objfile events, will update remote environment accordingly --- - + -### method `RemoteCommand.post_load` +## function `RemoteCommand.post_load` ```python post_load() → None @@ -19133,9 +19133,9 @@ post_load() → None --- - + -### method `RemoteCommand.pre_load` +## function `RemoteCommand.pre_load` ```python pre_load() → None @@ -19147,9 +19147,9 @@ pre_load() → None --- - + -### method `RemoteCommand.prepare_qemu_stub` +## function `RemoteCommand.prepare_qemu_stub` ```python prepare_qemu_stub(target: str) → None @@ -19161,9 +19161,9 @@ prepare_qemu_stub(target: str) → None --- - + -### method `RemoteCommand.refresh_shared_library_path` +## function `RemoteCommand.refresh_shared_library_path` ```python refresh_shared_library_path() → None @@ -19175,9 +19175,9 @@ refresh_shared_library_path() → None --- - + -### method `RemoteCommand.setup_remote_environment` +## function `RemoteCommand.setup_remote_environment` ```python setup_remote_environment(pid: int, update_solib: bool = False) → None @@ -19187,9 +19187,9 @@ Clone the remote environment locally in the temporary directory. The command wil --- - + -### method `RemoteCommand.usage` +## function `RemoteCommand.usage` ```python usage() → None @@ -19205,9 +19205,9 @@ 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. - + -### method `ResetCacheCommand.__init__` +## function `ResetCacheCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -19228,9 +19228,9 @@ Return the list of settings for this command. --- - + -### method `ResetCacheCommand.add_setting` +## function `ResetCacheCommand.add_setting` ```python add_setting( @@ -19244,9 +19244,9 @@ add_setting( --- - + -### method `ResetCacheCommand.del_setting` +## function `ResetCacheCommand.del_setting` ```python del_setting(name: str) → None @@ -19256,9 +19256,9 @@ del_setting(name: str) → None --- - + -### method `ResetCacheCommand.do_invoke` +## function `ResetCacheCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -19270,9 +19270,9 @@ do_invoke(argv: List) → None --- - + -### method `ResetCacheCommand.get_setting` +## function `ResetCacheCommand.get_setting` ```python get_setting(name) @@ -19282,9 +19282,9 @@ get_setting(name) --- - + -### method `ResetCacheCommand.has_setting` +## function `ResetCacheCommand.has_setting` ```python has_setting(name: str) → bool @@ -19294,9 +19294,9 @@ has_setting(name: str) → bool --- - + -### method `ResetCacheCommand.invoke` +## function `ResetCacheCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -19308,9 +19308,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ResetCacheCommand.post_load` +## function `ResetCacheCommand.post_load` ```python post_load() → None @@ -19322,9 +19322,9 @@ post_load() → None --- - + -### method `ResetCacheCommand.pre_load` +## function `ResetCacheCommand.pre_load` ```python pre_load() → None @@ -19336,9 +19336,9 @@ pre_load() → None --- - + -### method `ResetCacheCommand.usage` +## function `ResetCacheCommand.usage` ```python usage() → None @@ -19354,9 +19354,9 @@ usage() → None ## class `RopperCommand` Ropper (http://scoding.de/ropper) plugin. - + -### method `RopperCommand.__init__` +## function `RopperCommand.__init__` ```python __init__() → None @@ -19377,9 +19377,9 @@ Return the list of settings for this command. --- - + -### method `RopperCommand.add_setting` +## function `RopperCommand.add_setting` ```python add_setting( @@ -19393,9 +19393,9 @@ add_setting( --- - + -### method `RopperCommand.del_setting` +## function `RopperCommand.del_setting` ```python del_setting(name: str) → None @@ -19405,9 +19405,9 @@ del_setting(name: str) → None --- - + -### method `RopperCommand.do_invoke` +## function `RopperCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -19419,9 +19419,9 @@ do_invoke(argv: List) → None --- - + -### method `RopperCommand.get_setting` +## function `RopperCommand.get_setting` ```python get_setting(name) @@ -19431,9 +19431,9 @@ get_setting(name) --- - + -### method `RopperCommand.has_setting` +## function `RopperCommand.has_setting` ```python has_setting(name: str) → bool @@ -19443,9 +19443,9 @@ has_setting(name: str) → bool --- - + -### method `RopperCommand.invoke` +## function `RopperCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -19457,9 +19457,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `RopperCommand.post_load` +## function `RopperCommand.post_load` ```python post_load() → None @@ -19471,9 +19471,9 @@ post_load() → None --- - + -### method `RopperCommand.pre_load` +## function `RopperCommand.pre_load` ```python pre_load() → None @@ -19485,9 +19485,9 @@ pre_load() → None --- - + -### method `RopperCommand.usage` +## function `RopperCommand.usage` ```python usage() → None @@ -19557,9 +19557,9 @@ Refs: --- - + -### method `SPARC.flag_register_to_human` +## function `SPARC.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → str @@ -19571,9 +19571,9 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + -### method `SPARC.get_ith_parameter` +## function `SPARC.get_ith_parameter` ```python get_ith_parameter( @@ -19586,9 +19586,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `SPARC.get_ra` +## function `SPARC.get_ra` ```python get_ra(insn, frame) → Union[int, NoneType] @@ -19600,9 +19600,9 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + -### method `SPARC.is_branch_taken` +## function `SPARC.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -19614,9 +19614,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `SPARC.is_call` +## function `SPARC.is_call` ```python is_call(insn) → bool @@ -19628,9 +19628,9 @@ is_call(insn) → bool --- - + -### method `SPARC.is_conditional_branch` +## function `SPARC.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -19642,9 +19642,9 @@ is_conditional_branch(insn) → bool --- - + -### method `SPARC.is_ret` +## function `SPARC.is_ret` ```python is_ret(insn) → bool @@ -19656,9 +19656,9 @@ is_ret(insn) → bool --- - + -### classmethod `SPARC.mprotect_asm` +## function `SPARC.mprotect_asm` ```python mprotect_asm(addr: int, size: int, perm) → str @@ -19670,9 +19670,9 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + -### method `SPARC.register` +## function `SPARC.register` ```python register(name: str) → Union[int, NoneType] @@ -19743,9 +19743,9 @@ Refs: --- - + -### method `SPARC64.flag_register_to_human` +## function `SPARC64.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → str @@ -19757,9 +19757,9 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + -### method `SPARC64.get_ith_parameter` +## function `SPARC64.get_ith_parameter` ```python get_ith_parameter( @@ -19772,9 +19772,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `SPARC64.get_ra` +## function `SPARC64.get_ra` ```python get_ra(insn, frame) → Union[int, NoneType] @@ -19786,9 +19786,9 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + -### method `SPARC64.is_branch_taken` +## function `SPARC64.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -19800,9 +19800,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `SPARC64.is_call` +## function `SPARC64.is_call` ```python is_call(insn) → bool @@ -19814,9 +19814,9 @@ is_call(insn) → bool --- - + -### method `SPARC64.is_conditional_branch` +## function `SPARC64.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -19828,9 +19828,9 @@ is_conditional_branch(insn) → bool --- - + -### method `SPARC64.is_ret` +## function `SPARC64.is_ret` ```python is_ret(insn) → bool @@ -19842,9 +19842,9 @@ is_ret(insn) → bool --- - + -### classmethod `SPARC64.mprotect_asm` +## function `SPARC64.mprotect_asm` ```python mprotect_asm(addr: int, size: int, perm) → str @@ -19856,9 +19856,9 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + -### method `SPARC64.register` +## function `SPARC64.register` ```python register(name: str) → Union[int, NoneType] @@ -19874,9 +19874,9 @@ register(name: str) → Union[int, NoneType] ## class `ScanSectionCommand` Search for addresses that are located in a memory mapping (haystack) that belonging to another (needle). - + -### method `ScanSectionCommand.__init__` +## function `ScanSectionCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -19897,9 +19897,9 @@ Return the list of settings for this command. --- - + -### method `ScanSectionCommand.add_setting` +## function `ScanSectionCommand.add_setting` ```python add_setting( @@ -19913,9 +19913,9 @@ add_setting( --- - + -### method `ScanSectionCommand.del_setting` +## function `ScanSectionCommand.del_setting` ```python del_setting(name: str) → None @@ -19925,9 +19925,9 @@ del_setting(name: str) → None --- - + -### method `ScanSectionCommand.do_invoke` +## function `ScanSectionCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -19939,9 +19939,9 @@ do_invoke(argv: List) → None --- - + -### method `ScanSectionCommand.get_setting` +## function `ScanSectionCommand.get_setting` ```python get_setting(name) @@ -19951,9 +19951,9 @@ get_setting(name) --- - + -### method `ScanSectionCommand.has_setting` +## function `ScanSectionCommand.has_setting` ```python has_setting(name: str) → bool @@ -19963,9 +19963,9 @@ has_setting(name: str) → bool --- - + -### method `ScanSectionCommand.invoke` +## function `ScanSectionCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -19977,9 +19977,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ScanSectionCommand.post_load` +## function `ScanSectionCommand.post_load` ```python post_load() → None @@ -19991,9 +19991,9 @@ post_load() → None --- - + -### method `ScanSectionCommand.pre_load` +## function `ScanSectionCommand.pre_load` ```python pre_load() → None @@ -20005,9 +20005,9 @@ pre_load() → None --- - + -### method `ScanSectionCommand.usage` +## function `ScanSectionCommand.usage` ```python usage() → None @@ -20023,9 +20023,9 @@ 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. - + -### method `SearchPatternCommand.__init__` +## function `SearchPatternCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -20046,9 +20046,9 @@ Return the list of settings for this command. --- - + -### method `SearchPatternCommand.add_setting` +## function `SearchPatternCommand.add_setting` ```python add_setting( @@ -20062,9 +20062,9 @@ add_setting( --- - + -### method `SearchPatternCommand.del_setting` +## function `SearchPatternCommand.del_setting` ```python del_setting(name: str) → None @@ -20074,9 +20074,9 @@ del_setting(name: str) → None --- - + -### method `SearchPatternCommand.do_invoke` +## function `SearchPatternCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -20088,9 +20088,9 @@ do_invoke(argv: List) → None --- - + -### method `SearchPatternCommand.get_setting` +## function `SearchPatternCommand.get_setting` ```python get_setting(name) @@ -20100,9 +20100,9 @@ get_setting(name) --- - + -### method `SearchPatternCommand.has_setting` +## function `SearchPatternCommand.has_setting` ```python has_setting(name: str) → bool @@ -20112,9 +20112,9 @@ has_setting(name: str) → bool --- - + -### method `SearchPatternCommand.invoke` +## function `SearchPatternCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -20126,9 +20126,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `SearchPatternCommand.post_load` +## function `SearchPatternCommand.post_load` ```python post_load() → None @@ -20140,9 +20140,9 @@ post_load() → None --- - + -### method `SearchPatternCommand.pre_load` +## function `SearchPatternCommand.pre_load` ```python pre_load() → None @@ -20154,9 +20154,9 @@ pre_load() → None --- - + -### method `SearchPatternCommand.print_loc` +## function `SearchPatternCommand.print_loc` ```python print_loc(loc) → None @@ -20168,9 +20168,9 @@ print_loc(loc) → None --- - + -### method `SearchPatternCommand.print_section` +## function `SearchPatternCommand.print_section` ```python print_section(section) → None @@ -20182,9 +20182,9 @@ print_section(section) → None --- - + -### method `SearchPatternCommand.search_pattern` +## function `SearchPatternCommand.search_pattern` ```python search_pattern(pattern: str, section_name: str) → None @@ -20194,9 +20194,9 @@ Search a pattern within the whole userland memory. --- - + -### method `SearchPatternCommand.search_pattern_by_address` +## function `SearchPatternCommand.search_pattern_by_address` ```python search_pattern_by_address( @@ -20210,9 +20210,9 @@ Search a pattern within a range defined by arguments. --- - + -### method `SearchPatternCommand.usage` +## function `SearchPatternCommand.usage` ```python usage() → None @@ -20228,9 +20228,9 @@ usage() → None ## class `Section` GEF representation of process memory sections. - + -### method `Section.__init__` +## function `Section.__init__` ```python __init__(*args, **kwargs) → None @@ -20261,9 +20261,9 @@ __init__(*args, **kwargs) → None --- - + -### method `Section.is_executable` +## function `Section.is_executable` ```python is_executable() → bool @@ -20275,9 +20275,9 @@ is_executable() → bool --- - + -### method `Section.is_readable` +## function `Section.is_readable` ```python is_readable() → bool @@ -20289,9 +20289,9 @@ is_readable() → bool --- - + -### method `Section.is_writable` +## function `Section.is_writable` ```python is_writable() → bool @@ -20307,9 +20307,9 @@ 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 - + -### method `SectionBaseFunction.__init__` +## function `SectionBaseFunction.__init__` ```python __init__() → None @@ -20324,9 +20324,9 @@ __init__() → None --- - + -### method `SectionBaseFunction.arg_to_long` +## function `SectionBaseFunction.arg_to_long` ```python arg_to_long(args: List, index: int, default: int = 0) → int @@ -20338,9 +20338,9 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + -### method `SectionBaseFunction.do_invoke` +## function `SectionBaseFunction.do_invoke` ```python do_invoke(args: List) → int @@ -20352,9 +20352,9 @@ do_invoke(args: List) → int --- - + -### method `SectionBaseFunction.invoke` +## function `SectionBaseFunction.invoke` ```python invoke(*args) → int @@ -20372,9 +20372,9 @@ invoke(*args) → int - + -### method `Shdr.__init__` +## function `Shdr.__init__` ```python __init__(elf, off) → None @@ -20393,9 +20393,9 @@ __init__(elf, off) → None ## class `ShellcodeCommand` ShellcodeCommand uses @JonathanSalwan simple-yet-awesome shellcode API to download shellcodes. - + -### method `ShellcodeCommand.__init__` +## function `ShellcodeCommand.__init__` ```python __init__() → None @@ -20416,9 +20416,9 @@ Return the list of settings for this command. --- - + -### method `ShellcodeCommand.add_setting` +## function `ShellcodeCommand.add_setting` ```python add_setting( @@ -20432,9 +20432,9 @@ add_setting( --- - + -### method `ShellcodeCommand.del_setting` +## function `ShellcodeCommand.del_setting` ```python del_setting(name: str) → None @@ -20444,9 +20444,9 @@ del_setting(name: str) → None --- - + -### method `ShellcodeCommand.do_invoke` +## function `ShellcodeCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -20458,9 +20458,9 @@ do_invoke(argv: List) → None --- - + -### method `ShellcodeCommand.get_setting` +## function `ShellcodeCommand.get_setting` ```python get_setting(name) @@ -20470,9 +20470,9 @@ get_setting(name) --- - + -### method `ShellcodeCommand.has_setting` +## function `ShellcodeCommand.has_setting` ```python has_setting(name: str) → bool @@ -20482,9 +20482,9 @@ has_setting(name: str) → bool --- - + -### method `ShellcodeCommand.invoke` +## function `ShellcodeCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -20496,9 +20496,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ShellcodeCommand.post_load` +## function `ShellcodeCommand.post_load` ```python post_load() → None @@ -20510,9 +20510,9 @@ post_load() → None --- - + -### method `ShellcodeCommand.pre_load` +## function `ShellcodeCommand.pre_load` ```python pre_load() → None @@ -20524,9 +20524,9 @@ pre_load() → None --- - + -### method `ShellcodeCommand.usage` +## function `ShellcodeCommand.usage` ```python usage() → None @@ -20542,9 +20542,9 @@ usage() → None ## class `ShellcodeGetCommand` Download shellcode from shell-storm's shellcode database. - + -### method `ShellcodeGetCommand.__init__` +## function `ShellcodeGetCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -20565,9 +20565,9 @@ Return the list of settings for this command. --- - + -### method `ShellcodeGetCommand.add_setting` +## function `ShellcodeGetCommand.add_setting` ```python add_setting( @@ -20581,9 +20581,9 @@ add_setting( --- - + -### method `ShellcodeGetCommand.del_setting` +## function `ShellcodeGetCommand.del_setting` ```python del_setting(name: str) → None @@ -20593,9 +20593,9 @@ del_setting(name: str) → None --- - + -### method `ShellcodeGetCommand.do_invoke` +## function `ShellcodeGetCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -20607,9 +20607,9 @@ do_invoke(argv: List) → None --- - + -### method `ShellcodeGetCommand.get_setting` +## function `ShellcodeGetCommand.get_setting` ```python get_setting(name) @@ -20619,9 +20619,9 @@ get_setting(name) --- - + -### method `ShellcodeGetCommand.get_shellcode` +## function `ShellcodeGetCommand.get_shellcode` ```python get_shellcode(sid: int) → None @@ -20633,9 +20633,9 @@ get_shellcode(sid: int) → None --- - + -### method `ShellcodeGetCommand.has_setting` +## function `ShellcodeGetCommand.has_setting` ```python has_setting(name: str) → bool @@ -20645,9 +20645,9 @@ has_setting(name: str) → bool --- - + -### method `ShellcodeGetCommand.invoke` +## function `ShellcodeGetCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -20659,9 +20659,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ShellcodeGetCommand.post_load` +## function `ShellcodeGetCommand.post_load` ```python post_load() → None @@ -20673,9 +20673,9 @@ post_load() → None --- - + -### method `ShellcodeGetCommand.pre_load` +## function `ShellcodeGetCommand.pre_load` ```python pre_load() → None @@ -20687,9 +20687,9 @@ pre_load() → None --- - + -### method `ShellcodeGetCommand.usage` +## function `ShellcodeGetCommand.usage` ```python usage() → None @@ -20705,9 +20705,9 @@ usage() → None ## class `ShellcodeSearchCommand` Search pattern in shell-storm's shellcode database. - + -### method `ShellcodeSearchCommand.__init__` +## function `ShellcodeSearchCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -20728,9 +20728,9 @@ Return the list of settings for this command. --- - + -### method `ShellcodeSearchCommand.add_setting` +## function `ShellcodeSearchCommand.add_setting` ```python add_setting( @@ -20744,9 +20744,9 @@ add_setting( --- - + -### method `ShellcodeSearchCommand.del_setting` +## function `ShellcodeSearchCommand.del_setting` ```python del_setting(name: str) → None @@ -20756,9 +20756,9 @@ del_setting(name: str) → None --- - + -### method `ShellcodeSearchCommand.do_invoke` +## function `ShellcodeSearchCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -20770,9 +20770,9 @@ do_invoke(argv: List) → None --- - + -### method `ShellcodeSearchCommand.get_setting` +## function `ShellcodeSearchCommand.get_setting` ```python get_setting(name) @@ -20782,9 +20782,9 @@ get_setting(name) --- - + -### method `ShellcodeSearchCommand.has_setting` +## function `ShellcodeSearchCommand.has_setting` ```python has_setting(name: str) → bool @@ -20794,9 +20794,9 @@ has_setting(name: str) → bool --- - + -### method `ShellcodeSearchCommand.invoke` +## function `ShellcodeSearchCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -20808,9 +20808,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `ShellcodeSearchCommand.post_load` +## function `ShellcodeSearchCommand.post_load` ```python post_load() → None @@ -20822,9 +20822,9 @@ post_load() → None --- - + -### method `ShellcodeSearchCommand.pre_load` +## function `ShellcodeSearchCommand.pre_load` ```python pre_load() → None @@ -20836,9 +20836,9 @@ pre_load() → None --- - + -### method `ShellcodeSearchCommand.search_shellcode` +## function `ShellcodeSearchCommand.search_shellcode` ```python search_shellcode(search_options: List) → None @@ -20850,9 +20850,9 @@ search_shellcode(search_options: List) → None --- - + -### method `ShellcodeSearchCommand.usage` +## function `ShellcodeSearchCommand.usage` ```python usage() → None @@ -20868,9 +20868,9 @@ usage() → None ## class `SmartEvalCommand` SmartEval: Smart eval (vague approach to mimic WinDBG `?`). - + -### method `SmartEvalCommand.__init__` +## function `SmartEvalCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -20891,9 +20891,9 @@ Return the list of settings for this command. --- - + -### method `SmartEvalCommand.add_setting` +## function `SmartEvalCommand.add_setting` ```python add_setting( @@ -20907,9 +20907,9 @@ add_setting( --- - + -### method `SmartEvalCommand.del_setting` +## function `SmartEvalCommand.del_setting` ```python del_setting(name: str) → None @@ -20919,9 +20919,9 @@ del_setting(name: str) → None --- - + -### method `SmartEvalCommand.distance` +## function `SmartEvalCommand.distance` ```python distance(args: Tuple[str, str]) @@ -20933,9 +20933,9 @@ distance(args: Tuple[str, str]) --- - + -### method `SmartEvalCommand.do_invoke` +## function `SmartEvalCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -20947,9 +20947,9 @@ do_invoke(argv: List) → None --- - + -### method `SmartEvalCommand.evaluate` +## function `SmartEvalCommand.evaluate` ```python evaluate(expr: List) → None @@ -20961,9 +20961,9 @@ evaluate(expr: List) → None --- - + -### method `SmartEvalCommand.get_setting` +## function `SmartEvalCommand.get_setting` ```python get_setting(name) @@ -20973,9 +20973,9 @@ get_setting(name) --- - + -### method `SmartEvalCommand.has_setting` +## function `SmartEvalCommand.has_setting` ```python has_setting(name: str) → bool @@ -20985,9 +20985,9 @@ has_setting(name: str) → bool --- - + -### method `SmartEvalCommand.invoke` +## function `SmartEvalCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -20999,9 +20999,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `SmartEvalCommand.post_load` +## function `SmartEvalCommand.post_load` ```python post_load() → None @@ -21013,9 +21013,9 @@ post_load() → None --- - + -### method `SmartEvalCommand.pre_load` +## function `SmartEvalCommand.pre_load` ```python pre_load() → None @@ -21027,9 +21027,9 @@ pre_load() → None --- - + -### method `SmartEvalCommand.usage` +## function `SmartEvalCommand.usage` ```python usage() → None @@ -21045,9 +21045,9 @@ usage() → None ## class `SolveKernelSymbolCommand` Solve kernel symbols from kallsyms table. - + -### method `SolveKernelSymbolCommand.__init__` +## function `SolveKernelSymbolCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -21068,9 +21068,9 @@ Return the list of settings for this command. --- - + -### method `SolveKernelSymbolCommand.add_setting` +## function `SolveKernelSymbolCommand.add_setting` ```python add_setting( @@ -21084,9 +21084,9 @@ add_setting( --- - + -### method `SolveKernelSymbolCommand.del_setting` +## function `SolveKernelSymbolCommand.del_setting` ```python del_setting(name: str) → None @@ -21096,9 +21096,9 @@ del_setting(name: str) → None --- - + -### function `SolveKernelSymbolCommand.wrapper` +## function `SolveKernelSymbolCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -21110,9 +21110,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `SolveKernelSymbolCommand.get_setting` +## function `SolveKernelSymbolCommand.get_setting` ```python get_setting(name) @@ -21122,9 +21122,9 @@ get_setting(name) --- - + -### method `SolveKernelSymbolCommand.has_setting` +## function `SolveKernelSymbolCommand.has_setting` ```python has_setting(name: str) → bool @@ -21134,9 +21134,9 @@ has_setting(name: str) → bool --- - + -### method `SolveKernelSymbolCommand.invoke` +## function `SolveKernelSymbolCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -21148,9 +21148,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `SolveKernelSymbolCommand.post_load` +## function `SolveKernelSymbolCommand.post_load` ```python post_load() → None @@ -21162,9 +21162,9 @@ post_load() → None --- - + -### method `SolveKernelSymbolCommand.pre_load` +## function `SolveKernelSymbolCommand.pre_load` ```python pre_load() → None @@ -21176,9 +21176,9 @@ pre_load() → None --- - + -### method `SolveKernelSymbolCommand.usage` +## function `SolveKernelSymbolCommand.usage` ```python usage() → None @@ -21194,9 +21194,9 @@ usage() → None ## class `StackOffsetFunction` Return the current stack base address plus an optional offset. - + -### method `StackOffsetFunction.__init__` +## function `StackOffsetFunction.__init__` ```python __init__() → None @@ -21211,9 +21211,9 @@ __init__() → None --- - + -### method `StackOffsetFunction.arg_to_long` +## function `StackOffsetFunction.arg_to_long` ```python arg_to_long(args: List, index: int, default: int = 0) → int @@ -21225,9 +21225,9 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + -### method `StackOffsetFunction.do_invoke` +## function `StackOffsetFunction.do_invoke` ```python do_invoke(args: List) → int @@ -21239,9 +21239,9 @@ do_invoke(args: List) → int --- - + -### method `StackOffsetFunction.invoke` +## function `StackOffsetFunction.invoke` ```python invoke(*args) → int @@ -21257,9 +21257,9 @@ invoke(*args) → int ## class `StubBreakpoint` Create a breakpoint to permanently disable a call (fork/alarm/signal/etc.). - + -### method `StubBreakpoint.__init__` +## function `StubBreakpoint.__init__` ```python __init__(func: str, retval: Optional[int]) → None @@ -21274,9 +21274,9 @@ __init__(func: str, retval: Optional[int]) → None --- - + -### method `StubBreakpoint.stop` +## function `StubBreakpoint.stop` ```python stop() → bool @@ -21292,9 +21292,9 @@ 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). - + -### method `StubCommand.__init__` +## function `StubCommand.__init__` ```python __init__() → None @@ -21315,9 +21315,9 @@ Return the list of settings for this command. --- - + -### method `StubCommand.add_setting` +## function `StubCommand.add_setting` ```python add_setting( @@ -21331,9 +21331,9 @@ add_setting( --- - + -### method `StubCommand.del_setting` +## function `StubCommand.del_setting` ```python del_setting(name: str) → None @@ -21343,9 +21343,9 @@ del_setting(name: str) → None --- - + -### function `StubCommand.wrapper` +## function `StubCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -21357,9 +21357,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `StubCommand.get_setting` +## function `StubCommand.get_setting` ```python get_setting(name) @@ -21369,9 +21369,9 @@ get_setting(name) --- - + -### method `StubCommand.has_setting` +## function `StubCommand.has_setting` ```python has_setting(name: str) → bool @@ -21381,9 +21381,9 @@ has_setting(name: str) → bool --- - + -### method `StubCommand.invoke` +## function `StubCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -21395,9 +21395,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `StubCommand.post_load` +## function `StubCommand.post_load` ```python post_load() → None @@ -21409,9 +21409,9 @@ post_load() → None --- - + -### method `StubCommand.pre_load` +## function `StubCommand.pre_load` ```python pre_load() → None @@ -21423,9 +21423,9 @@ pre_load() → None --- - + -### method `StubCommand.usage` +## function `StubCommand.usage` ```python usage() → None @@ -21441,9 +21441,9 @@ usage() → None ## class `SyscallArgsCommand` Gets the syscall name and arguments based on the register values in the current state. - + -### method `SyscallArgsCommand.__init__` +## function `SyscallArgsCommand.__init__` ```python __init__() → None @@ -21464,9 +21464,9 @@ Return the list of settings for this command. --- - + -### method `SyscallArgsCommand.add_setting` +## function `SyscallArgsCommand.add_setting` ```python add_setting( @@ -21480,9 +21480,9 @@ add_setting( --- - + -### method `SyscallArgsCommand.del_setting` +## function `SyscallArgsCommand.del_setting` ```python del_setting(name: str) → None @@ -21492,9 +21492,9 @@ del_setting(name: str) → None --- - + -### method `SyscallArgsCommand.do_invoke` +## function `SyscallArgsCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -21506,9 +21506,9 @@ do_invoke(argv: List) → None --- - + -### method `SyscallArgsCommand.get_filepath` +## function `SyscallArgsCommand.get_filepath` ```python get_filepath(x: str) → Union[str, NoneType] @@ -21520,9 +21520,9 @@ get_filepath(x: str) → Union[str, NoneType] --- - + -### method `SyscallArgsCommand.get_module` +## function `SyscallArgsCommand.get_module` ```python get_module(modname: str) @@ -21534,9 +21534,9 @@ get_module(modname: str) --- - + -### method `SyscallArgsCommand.get_setting` +## function `SyscallArgsCommand.get_setting` ```python get_setting(name) @@ -21546,9 +21546,9 @@ get_setting(name) --- - + -### method `SyscallArgsCommand.get_settings_path` +## function `SyscallArgsCommand.get_settings_path` ```python get_settings_path() → Union[pathlib.Path, NoneType] @@ -21560,9 +21560,9 @@ get_settings_path() → Union[pathlib.Path, NoneType] --- - + -### method `SyscallArgsCommand.get_syscall_table` +## function `SyscallArgsCommand.get_syscall_table` ```python get_syscall_table(modname: str) @@ -21574,9 +21574,9 @@ get_syscall_table(modname: str) --- - + -### method `SyscallArgsCommand.has_setting` +## function `SyscallArgsCommand.has_setting` ```python has_setting(name: str) → bool @@ -21586,9 +21586,9 @@ has_setting(name: str) → bool --- - + -### method `SyscallArgsCommand.invoke` +## function `SyscallArgsCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -21600,9 +21600,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `SyscallArgsCommand.post_load` +## function `SyscallArgsCommand.post_load` ```python post_load() → None @@ -21614,9 +21614,9 @@ post_load() → None --- - + -### method `SyscallArgsCommand.pre_load` +## function `SyscallArgsCommand.pre_load` ```python pre_load() → None @@ -21628,9 +21628,9 @@ pre_load() → None --- - + -### method `SyscallArgsCommand.usage` +## function `SyscallArgsCommand.usage` ```python usage() → None @@ -21646,9 +21646,9 @@ usage() → None ## class `TraceFreeBreakpoint` Track calls to free() and attempts to detect inconsistencies. - + -### method `TraceFreeBreakpoint.__init__` +## function `TraceFreeBreakpoint.__init__` ```python __init__() → None @@ -21663,9 +21663,9 @@ __init__() → None --- - + -### method `TraceFreeBreakpoint.stop` +## function `TraceFreeBreakpoint.stop` ```python stop() → bool @@ -21681,9 +21681,9 @@ stop() → bool ## class `TraceFreeRetBreakpoint` Internal temporary breakpoint to track free()d values. - + -### method `TraceFreeRetBreakpoint.__init__` +## function `TraceFreeRetBreakpoint.__init__` ```python __init__(addr: int) → None @@ -21698,9 +21698,9 @@ __init__(addr: int) → None --- - + -### method `TraceFreeRetBreakpoint.stop` +## function `TraceFreeRetBreakpoint.stop` ```python stop() → bool @@ -21716,9 +21716,9 @@ stop() → bool ## class `TraceMallocBreakpoint` Track allocations done with malloc() or calloc(). - + -### method `TraceMallocBreakpoint.__init__` +## function `TraceMallocBreakpoint.__init__` ```python __init__(name: str) → None @@ -21733,9 +21733,9 @@ __init__(name: str) → None --- - + -### method `TraceMallocBreakpoint.stop` +## function `TraceMallocBreakpoint.stop` ```python stop() → bool @@ -21751,9 +21751,9 @@ stop() → bool ## class `TraceMallocRetBreakpoint` Internal temporary breakpoint to retrieve the return value of malloc(). - + -### method `TraceMallocRetBreakpoint.__init__` +## function `TraceMallocRetBreakpoint.__init__` ```python __init__(size: int, name: str) → None @@ -21768,9 +21768,9 @@ __init__(size: int, name: str) → None --- - + -### method `TraceMallocRetBreakpoint.stop` +## function `TraceMallocRetBreakpoint.stop` ```python stop() → bool @@ -21786,9 +21786,9 @@ stop() → bool ## class `TraceReallocBreakpoint` Track re-allocations done with realloc(). - + -### method `TraceReallocBreakpoint.__init__` +## function `TraceReallocBreakpoint.__init__` ```python __init__() → None @@ -21803,9 +21803,9 @@ __init__() → None --- - + -### method `TraceReallocBreakpoint.stop` +## function `TraceReallocBreakpoint.stop` ```python stop() → bool @@ -21821,9 +21821,9 @@ stop() → bool ## class `TraceReallocRetBreakpoint` Internal temporary breakpoint to retrieve the return value of realloc(). - + -### method `TraceReallocRetBreakpoint.__init__` +## function `TraceReallocRetBreakpoint.__init__` ```python __init__(ptr: int, size: int) → None @@ -21838,9 +21838,9 @@ __init__(ptr: int, size: int) → None --- - + -### method `TraceReallocRetBreakpoint.stop` +## function `TraceReallocRetBreakpoint.stop` ```python stop() → bool @@ -21856,9 +21856,9 @@ 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. - + -### method `TraceRunCommand.__init__` +## function `TraceRunCommand.__init__` ```python __init__() → None @@ -21879,9 +21879,9 @@ Return the list of settings for this command. --- - + -### method `TraceRunCommand.add_setting` +## function `TraceRunCommand.add_setting` ```python add_setting( @@ -21895,9 +21895,9 @@ add_setting( --- - + -### method `TraceRunCommand.del_setting` +## function `TraceRunCommand.del_setting` ```python del_setting(name: str) → None @@ -21907,9 +21907,9 @@ del_setting(name: str) → None --- - + -### method `TraceRunCommand.do_invoke` +## function `TraceRunCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -21921,9 +21921,9 @@ do_invoke(argv: List) → None --- - + -### method `TraceRunCommand.get_frames_size` +## function `TraceRunCommand.get_frames_size` ```python get_frames_size() → int @@ -21935,9 +21935,9 @@ get_frames_size() → int --- - + -### method `TraceRunCommand.get_setting` +## function `TraceRunCommand.get_setting` ```python get_setting(name) @@ -21947,9 +21947,9 @@ get_setting(name) --- - + -### method `TraceRunCommand.has_setting` +## function `TraceRunCommand.has_setting` ```python has_setting(name: str) → bool @@ -21959,9 +21959,9 @@ has_setting(name: str) → bool --- - + -### method `TraceRunCommand.invoke` +## function `TraceRunCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -21973,9 +21973,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `TraceRunCommand.post_load` +## function `TraceRunCommand.post_load` ```python post_load() → None @@ -21987,9 +21987,9 @@ post_load() → None --- - + -### method `TraceRunCommand.pre_load` +## function `TraceRunCommand.pre_load` ```python pre_load() → None @@ -22001,9 +22001,9 @@ pre_load() → None --- - + -### method `TraceRunCommand.start_tracing` +## function `TraceRunCommand.start_tracing` ```python start_tracing(loc_start: int, loc_end: int, depth: int) → None @@ -22015,9 +22015,9 @@ start_tracing(loc_start: int, loc_end: int, depth: int) → None --- - + -### method `TraceRunCommand.trace` +## function `TraceRunCommand.trace` ```python trace(loc_start: int, loc_end: int, depth: int) → None @@ -22029,9 +22029,9 @@ trace(loc_start: int, loc_end: int, depth: int) → None --- - + -### method `TraceRunCommand.usage` +## function `TraceRunCommand.usage` ```python usage() → None @@ -22047,9 +22047,9 @@ usage() → None ## class `UafWatchpoint` Custom watchpoints set TraceFreeBreakpoint() to monitor free()d pointers being used. - + -### method `UafWatchpoint.__init__` +## function `UafWatchpoint.__init__` ```python __init__(addr: int) → None @@ -22064,9 +22064,9 @@ __init__(addr: int) → None --- - + -### method `UafWatchpoint.stop` +## function `UafWatchpoint.stop` ```python stop() → bool @@ -22080,9 +22080,9 @@ If this method is triggered, we likely have a UaF. Break the execution and repor ## class `UnicornEmulateCommand` Use Unicorn-Engine to emulate the behavior of the binary, without affecting the GDB runtime. By default the command will emulate only the next instruction, but location and number of instruction can be changed via arguments to the command line. By default, it will emulate the next instruction from current PC. - + -### method `UnicornEmulateCommand.__init__` +## function `UnicornEmulateCommand.__init__` ```python __init__() → None @@ -22103,9 +22103,9 @@ Return the list of settings for this command. --- - + -### method `UnicornEmulateCommand.add_setting` +## function `UnicornEmulateCommand.add_setting` ```python add_setting( @@ -22119,9 +22119,9 @@ add_setting( --- - + -### method `UnicornEmulateCommand.del_setting` +## function `UnicornEmulateCommand.del_setting` ```python del_setting(name: str) → None @@ -22131,9 +22131,9 @@ del_setting(name: str) → None --- - + -### function `UnicornEmulateCommand.wrapper` +## function `UnicornEmulateCommand.wrapper` ```python wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] @@ -22145,9 +22145,9 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + -### method `UnicornEmulateCommand.get_setting` +## function `UnicornEmulateCommand.get_setting` ```python get_setting(name) @@ -22157,9 +22157,9 @@ get_setting(name) --- - + -### method `UnicornEmulateCommand.get_unicorn_end_addr` +## function `UnicornEmulateCommand.get_unicorn_end_addr` ```python get_unicorn_end_addr(start_addr: int, nb: int) → int @@ -22171,9 +22171,9 @@ get_unicorn_end_addr(start_addr: int, nb: int) → int --- - + -### method `UnicornEmulateCommand.has_setting` +## function `UnicornEmulateCommand.has_setting` ```python has_setting(name: str) → bool @@ -22183,9 +22183,9 @@ has_setting(name: str) → bool --- - + -### method `UnicornEmulateCommand.invoke` +## function `UnicornEmulateCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -22197,9 +22197,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `UnicornEmulateCommand.post_load` +## function `UnicornEmulateCommand.post_load` ```python post_load() → None @@ -22211,9 +22211,9 @@ post_load() → None --- - + -### method `UnicornEmulateCommand.pre_load` +## function `UnicornEmulateCommand.pre_load` ```python pre_load() → None @@ -22225,9 +22225,9 @@ pre_load() → None --- - + -### method `UnicornEmulateCommand.run_unicorn` +## function `UnicornEmulateCommand.run_unicorn` ```python run_unicorn(start_insn_addr: int, end_insn_addr: int, *args, **kwargs) → None @@ -22239,9 +22239,9 @@ run_unicorn(start_insn_addr: int, end_insn_addr: int, *args, **kwargs) → None --- - + -### method `UnicornEmulateCommand.usage` +## function `UnicornEmulateCommand.usage` ```python usage() → None @@ -22257,9 +22257,9 @@ usage() → None ## 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. - + -### method `VMMapCommand.__init__` +## function `VMMapCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -22280,9 +22280,9 @@ Return the list of settings for this command. --- - + -### method `VMMapCommand.add_setting` +## function `VMMapCommand.add_setting` ```python add_setting( @@ -22296,9 +22296,9 @@ add_setting( --- - + -### method `VMMapCommand.del_setting` +## function `VMMapCommand.del_setting` ```python del_setting(name: str) → None @@ -22308,9 +22308,9 @@ del_setting(name: str) → None --- - + -### method `VMMapCommand.do_invoke` +## function `VMMapCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -22322,9 +22322,9 @@ do_invoke(argv: List) → None --- - + -### method `VMMapCommand.get_setting` +## function `VMMapCommand.get_setting` ```python get_setting(name) @@ -22334,9 +22334,9 @@ get_setting(name) --- - + -### method `VMMapCommand.has_setting` +## function `VMMapCommand.has_setting` ```python has_setting(name: str) → bool @@ -22346,9 +22346,9 @@ has_setting(name: str) → bool --- - + -### method `VMMapCommand.invoke` +## function `VMMapCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -22360,9 +22360,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `VMMapCommand.is_integer` +## function `VMMapCommand.is_integer` ```python is_integer(n: str) → bool @@ -22374,9 +22374,9 @@ is_integer(n: str) → bool --- - + -### method `VMMapCommand.post_load` +## function `VMMapCommand.post_load` ```python post_load() → None @@ -22388,9 +22388,9 @@ post_load() → None --- - + -### method `VMMapCommand.pre_load` +## function `VMMapCommand.pre_load` ```python pre_load() → None @@ -22402,9 +22402,9 @@ pre_load() → None --- - + -### method `VMMapCommand.print_entry` +## function `VMMapCommand.print_entry` ```python print_entry(entry: __main__.Section) → None @@ -22416,9 +22416,9 @@ print_entry(entry: __main__.Section) → None --- - + -### method `VMMapCommand.show_legend` +## function `VMMapCommand.show_legend` ```python show_legend() → None @@ -22430,9 +22430,9 @@ show_legend() → None --- - + -### method `VMMapCommand.usage` +## function `VMMapCommand.usage` ```python usage() → None @@ -22448,9 +22448,9 @@ usage() → None ## class `VersionCommand` Display GEF version info. - + -### method `VersionCommand.__init__` +## function `VersionCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -22471,9 +22471,9 @@ Return the list of settings for this command. --- - + -### method `VersionCommand.add_setting` +## function `VersionCommand.add_setting` ```python add_setting( @@ -22487,9 +22487,9 @@ add_setting( --- - + -### method `VersionCommand.del_setting` +## function `VersionCommand.del_setting` ```python del_setting(name: str) → None @@ -22499,9 +22499,9 @@ del_setting(name: str) → None --- - + -### method `VersionCommand.do_invoke` +## function `VersionCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -22513,9 +22513,9 @@ do_invoke(argv: List) → None --- - + -### method `VersionCommand.get_setting` +## function `VersionCommand.get_setting` ```python get_setting(name) @@ -22525,9 +22525,9 @@ get_setting(name) --- - + -### method `VersionCommand.has_setting` +## function `VersionCommand.has_setting` ```python has_setting(name: str) → bool @@ -22537,9 +22537,9 @@ has_setting(name: str) → bool --- - + -### method `VersionCommand.invoke` +## function `VersionCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -22551,9 +22551,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `VersionCommand.post_load` +## function `VersionCommand.post_load` ```python post_load() → None @@ -22565,9 +22565,9 @@ post_load() → None --- - + -### method `VersionCommand.pre_load` +## function `VersionCommand.pre_load` ```python pre_load() → None @@ -22579,9 +22579,9 @@ pre_load() → None --- - + -### method `VersionCommand.usage` +## function `VersionCommand.usage` ```python usage() → None @@ -22636,9 +22636,9 @@ usage() → None --- - + -### method `X86.flag_register_to_human` +## function `X86.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → str @@ -22650,9 +22650,9 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + -### method `X86.get_ith_parameter` +## function `X86.get_ith_parameter` ```python get_ith_parameter( @@ -22667,9 +22667,9 @@ get_ith_parameter( --- - + -### method `X86.get_ra` +## function `X86.get_ra` ```python get_ra(insn, frame) → Union[int, NoneType] @@ -22681,9 +22681,9 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + -### method `X86.is_branch_taken` +## function `X86.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -22695,9 +22695,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `X86.is_call` +## function `X86.is_call` ```python is_call(insn) → bool @@ -22709,9 +22709,9 @@ is_call(insn) → bool --- - + -### method `X86.is_conditional_branch` +## function `X86.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -22723,9 +22723,9 @@ is_conditional_branch(insn) → bool --- - + -### method `X86.is_ret` +## function `X86.is_ret` ```python is_ret(insn) → bool @@ -22737,9 +22737,9 @@ is_ret(insn) → bool --- - + -### classmethod `X86.mprotect_asm` +## function `X86.mprotect_asm` ```python mprotect_asm(addr: int, size: int, perm) → str @@ -22751,9 +22751,9 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + -### method `X86.register` +## function `X86.register` ```python register(name: str) → Union[int, NoneType] @@ -22808,9 +22808,9 @@ register(name: str) → Union[int, NoneType] --- - + -### method `X86_64.flag_register_to_human` +## function `X86_64.flag_register_to_human` ```python flag_register_to_human(val: Optional[int] = None) → str @@ -22822,9 +22822,9 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + -### method `X86_64.get_ith_parameter` +## function `X86_64.get_ith_parameter` ```python get_ith_parameter( @@ -22837,9 +22837,9 @@ Retrieves the correct parameter used for the current function call. --- - + -### method `X86_64.get_ra` +## function `X86_64.get_ra` ```python get_ra(insn, frame) → Union[int, NoneType] @@ -22851,9 +22851,9 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + -### method `X86_64.is_branch_taken` +## function `X86_64.is_branch_taken` ```python is_branch_taken(insn) → Tuple[bool, str] @@ -22865,9 +22865,9 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + -### method `X86_64.is_call` +## function `X86_64.is_call` ```python is_call(insn) → bool @@ -22879,9 +22879,9 @@ is_call(insn) → bool --- - + -### method `X86_64.is_conditional_branch` +## function `X86_64.is_conditional_branch` ```python is_conditional_branch(insn) → bool @@ -22893,9 +22893,9 @@ is_conditional_branch(insn) → bool --- - + -### method `X86_64.is_ret` +## function `X86_64.is_ret` ```python is_ret(insn) → bool @@ -22907,9 +22907,9 @@ is_ret(insn) → bool --- - + -### classmethod `X86_64.mprotect_asm` +## function `X86_64.mprotect_asm` ```python mprotect_asm(addr: int, size: int, perm) → str @@ -22921,9 +22921,9 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + -### method `X86_64.register` +## function `X86_64.register` ```python register(name: str) → Union[int, NoneType] @@ -22939,9 +22939,9 @@ register(name: str) → Union[int, NoneType] ## class `XAddressInfoCommand` Retrieve and display runtime information for the location(s) given as parameter. - + -### method `XAddressInfoCommand.__init__` +## function `XAddressInfoCommand.__init__` ```python __init__() → None @@ -22962,9 +22962,9 @@ Return the list of settings for this command. --- - + -### method `XAddressInfoCommand.add_setting` +## function `XAddressInfoCommand.add_setting` ```python add_setting( @@ -22978,9 +22978,9 @@ add_setting( --- - + -### method `XAddressInfoCommand.del_setting` +## function `XAddressInfoCommand.del_setting` ```python del_setting(name: str) → None @@ -22990,9 +22990,9 @@ del_setting(name: str) → None --- - + -### method `XAddressInfoCommand.do_invoke` +## function `XAddressInfoCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -23004,9 +23004,9 @@ do_invoke(argv: List) → None --- - + -### method `XAddressInfoCommand.get_setting` +## function `XAddressInfoCommand.get_setting` ```python get_setting(name) @@ -23016,9 +23016,9 @@ get_setting(name) --- - + -### method `XAddressInfoCommand.has_setting` +## function `XAddressInfoCommand.has_setting` ```python has_setting(name: str) → bool @@ -23028,9 +23028,9 @@ has_setting(name: str) → bool --- - + -### method `XAddressInfoCommand.infos` +## function `XAddressInfoCommand.infos` ```python infos(address: int) → None @@ -23042,9 +23042,9 @@ infos(address: int) → None --- - + -### method `XAddressInfoCommand.invoke` +## function `XAddressInfoCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -23056,9 +23056,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `XAddressInfoCommand.post_load` +## function `XAddressInfoCommand.post_load` ```python post_load() → None @@ -23070,9 +23070,9 @@ post_load() → None --- - + -### method `XAddressInfoCommand.pre_load` +## function `XAddressInfoCommand.pre_load` ```python pre_load() → None @@ -23084,9 +23084,9 @@ pre_load() → None --- - + -### method `XAddressInfoCommand.usage` +## function `XAddressInfoCommand.usage` ```python usage() → None @@ -23102,9 +23102,9 @@ 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. - + -### method `XFilesCommand.__init__` +## function `XFilesCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -23125,9 +23125,9 @@ Return the list of settings for this command. --- - + -### method `XFilesCommand.add_setting` +## function `XFilesCommand.add_setting` ```python add_setting( @@ -23141,9 +23141,9 @@ add_setting( --- - + -### method `XFilesCommand.del_setting` +## function `XFilesCommand.del_setting` ```python del_setting(name: str) → None @@ -23153,9 +23153,9 @@ del_setting(name: str) → None --- - + -### method `XFilesCommand.do_invoke` +## function `XFilesCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -23167,9 +23167,9 @@ do_invoke(argv: List) → None --- - + -### method `XFilesCommand.get_setting` +## function `XFilesCommand.get_setting` ```python get_setting(name) @@ -23179,9 +23179,9 @@ get_setting(name) --- - + -### method `XFilesCommand.has_setting` +## function `XFilesCommand.has_setting` ```python has_setting(name: str) → bool @@ -23191,9 +23191,9 @@ has_setting(name: str) → bool --- - + -### method `XFilesCommand.invoke` +## function `XFilesCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -23205,9 +23205,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `XFilesCommand.post_load` +## function `XFilesCommand.post_load` ```python post_load() → None @@ -23219,9 +23219,9 @@ post_load() → None --- - + -### method `XFilesCommand.pre_load` +## function `XFilesCommand.pre_load` ```python pre_load() → None @@ -23233,9 +23233,9 @@ pre_load() → None --- - + -### method `XFilesCommand.usage` +## function `XFilesCommand.usage` ```python usage() → None @@ -23251,9 +23251,9 @@ usage() → None ## class `XorMemoryCommand` XOR a block of memory. The command allows to simply display the result, or patch it runtime at runtime. - + -### method `XorMemoryCommand.__init__` +## function `XorMemoryCommand.__init__` ```python __init__() → None @@ -23274,9 +23274,9 @@ Return the list of settings for this command. --- - + -### method `XorMemoryCommand.add_setting` +## function `XorMemoryCommand.add_setting` ```python add_setting( @@ -23290,9 +23290,9 @@ add_setting( --- - + -### method `XorMemoryCommand.del_setting` +## function `XorMemoryCommand.del_setting` ```python del_setting(name: str) → None @@ -23302,9 +23302,9 @@ del_setting(name: str) → None --- - + -### method `XorMemoryCommand.do_invoke` +## function `XorMemoryCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -23316,9 +23316,9 @@ do_invoke(argv: List) → None --- - + -### method `XorMemoryCommand.get_setting` +## function `XorMemoryCommand.get_setting` ```python get_setting(name) @@ -23328,9 +23328,9 @@ get_setting(name) --- - + -### method `XorMemoryCommand.has_setting` +## function `XorMemoryCommand.has_setting` ```python has_setting(name: str) → bool @@ -23340,9 +23340,9 @@ has_setting(name: str) → bool --- - + -### method `XorMemoryCommand.invoke` +## function `XorMemoryCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -23354,9 +23354,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `XorMemoryCommand.post_load` +## function `XorMemoryCommand.post_load` ```python post_load() → None @@ -23368,9 +23368,9 @@ post_load() → None --- - + -### method `XorMemoryCommand.pre_load` +## function `XorMemoryCommand.pre_load` ```python pre_load() → None @@ -23382,9 +23382,9 @@ pre_load() → None --- - + -### method `XorMemoryCommand.usage` +## function `XorMemoryCommand.usage` ```python usage() → None @@ -23400,9 +23400,9 @@ 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. - + -### method `XorMemoryDisplayCommand.__init__` +## function `XorMemoryDisplayCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -23423,9 +23423,9 @@ Return the list of settings for this command. --- - + -### method `XorMemoryDisplayCommand.add_setting` +## function `XorMemoryDisplayCommand.add_setting` ```python add_setting( @@ -23439,9 +23439,9 @@ add_setting( --- - + -### method `XorMemoryDisplayCommand.del_setting` +## function `XorMemoryDisplayCommand.del_setting` ```python del_setting(name: str) → None @@ -23451,9 +23451,9 @@ del_setting(name: str) → None --- - + -### method `XorMemoryDisplayCommand.do_invoke` +## function `XorMemoryDisplayCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -23465,9 +23465,9 @@ do_invoke(argv: List) → None --- - + -### method `XorMemoryDisplayCommand.get_setting` +## function `XorMemoryDisplayCommand.get_setting` ```python get_setting(name) @@ -23477,9 +23477,9 @@ get_setting(name) --- - + -### method `XorMemoryDisplayCommand.has_setting` +## function `XorMemoryDisplayCommand.has_setting` ```python has_setting(name: str) → bool @@ -23489,9 +23489,9 @@ has_setting(name: str) → bool --- - + -### method `XorMemoryDisplayCommand.invoke` +## function `XorMemoryDisplayCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -23503,9 +23503,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `XorMemoryDisplayCommand.post_load` +## function `XorMemoryDisplayCommand.post_load` ```python post_load() → None @@ -23517,9 +23517,9 @@ post_load() → None --- - + -### method `XorMemoryDisplayCommand.pre_load` +## function `XorMemoryDisplayCommand.pre_load` ```python pre_load() → None @@ -23531,9 +23531,9 @@ pre_load() → None --- - + -### method `XorMemoryDisplayCommand.usage` +## function `XorMemoryDisplayCommand.usage` ```python usage() → None @@ -23549,9 +23549,9 @@ 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. - + -### method `XorMemoryPatchCommand.__init__` +## function `XorMemoryPatchCommand.__init__` ```python __init__(*args, **kwargs) → None @@ -23572,9 +23572,9 @@ Return the list of settings for this command. --- - + -### method `XorMemoryPatchCommand.add_setting` +## function `XorMemoryPatchCommand.add_setting` ```python add_setting( @@ -23588,9 +23588,9 @@ add_setting( --- - + -### method `XorMemoryPatchCommand.del_setting` +## function `XorMemoryPatchCommand.del_setting` ```python del_setting(name: str) → None @@ -23600,9 +23600,9 @@ del_setting(name: str) → None --- - + -### method `XorMemoryPatchCommand.do_invoke` +## function `XorMemoryPatchCommand.do_invoke` ```python do_invoke(argv: List) → None @@ -23614,9 +23614,9 @@ do_invoke(argv: List) → None --- - + -### method `XorMemoryPatchCommand.get_setting` +## function `XorMemoryPatchCommand.get_setting` ```python get_setting(name) @@ -23626,9 +23626,9 @@ get_setting(name) --- - + -### method `XorMemoryPatchCommand.has_setting` +## function `XorMemoryPatchCommand.has_setting` ```python has_setting(name: str) → bool @@ -23638,9 +23638,9 @@ has_setting(name: str) → bool --- - + -### method `XorMemoryPatchCommand.invoke` +## function `XorMemoryPatchCommand.invoke` ```python invoke(args: str, from_tty: bool) → None @@ -23652,9 +23652,9 @@ invoke(args: str, from_tty: bool) → None --- - + -### method `XorMemoryPatchCommand.post_load` +## function `XorMemoryPatchCommand.post_load` ```python post_load() → None @@ -23666,9 +23666,9 @@ post_load() → None --- - + -### method `XorMemoryPatchCommand.pre_load` +## function `XorMemoryPatchCommand.pre_load` ```python pre_load() → None @@ -23680,9 +23680,9 @@ pre_load() → None --- - + -### method `XorMemoryPatchCommand.usage` +## function `XorMemoryPatchCommand.usage` ```python usage() → None diff --git a/scripts/generate-api-docs.sh b/scripts/generate-api-docs.sh index 9c2812bbe..18c2482a3 100644 --- a/scripts/generate-api-docs.sh +++ b/scripts/generate-api-docs.sh @@ -30,13 +30,14 @@ generate_doc() fixup_doc() { + # rename mv ${output_path}/__main__.md ${output_path}/gef.md + + # replace the title sed -i 's?# module `__main__`?# module `GEF`?' ${output_path}/gef.md - sed -i 's???g' ${output_path}/gef.md - # for item in ${output_path}/__main__.*.md; do - # mv ${item} ${item/__main__./gef.} - # done + # fix the hrefs + sed -i -ze 's!\n\n## function `\2`!g' ./docs/api/gef.md } check From c25f9c100b2f72b2e2270c2bf4e9d7a75b6fd283 Mon Sep 17 00:00:00 2001 From: hugsy Date: Mon, 10 Jan 2022 19:25:54 -0800 Subject: [PATCH 51/62] [gef] fixing glibc main arena calculation for arm [docs] `@deprecated` adds a note in the api doc --- docs/api/gef.md | 3048 +++++++++++++++++----------------- gef.py | 22 +- scripts/generate-api-docs.sh | 14 +- 3 files changed, 1543 insertions(+), 1541 deletions(-) diff --git a/docs/api/gef.md b/docs/api/gef.md index 72ac80842..9b1ae2542 100644 --- a/docs/api/gef.md +++ b/docs/api/gef.md @@ -36,7 +36,7 @@ --- - + ## function `FakeExit` @@ -51,7 +51,7 @@ FakeExit(*args, **kwargs) → None --- - + ## function `align_address` @@ -64,7 +64,7 @@ Align the provided address to the process's native length. --- - + ## function `align_address_to_page` @@ -77,7 +77,7 @@ Align the address to a page. --- - + ## function `align_address_to_size` @@ -90,7 +90,7 @@ Align the address to the given size. --- - + ## function `bufferize` @@ -103,7 +103,7 @@ Store the content to be printed for a function in memory, and flush it on functi --- - + ## function `capstone_disassemble` @@ -116,7 +116,7 @@ Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr` usin --- - + ## function `clear_screen` @@ -129,7 +129,7 @@ Clear the screen. --- - + ## function `continue_handler` @@ -142,7 +142,7 @@ GDB event handler for new object continue cases. --- - + ## function `copy_to_clipboard` @@ -155,7 +155,7 @@ Helper function to submit data to the clipboard --- - + ## function `de_bruijn` @@ -168,7 +168,7 @@ De Bruijn sequence for alphabet and subsequences of length n (for compat. w/ pwn --- - + ## function `deprecated` @@ -181,7 +181,7 @@ Decorator to add a warning when a command is obsolete and will be removed. --- - + ## function `disable_redirect_output` @@ -194,7 +194,7 @@ Disable the output redirection, if any. `disable_redirect_output` is **DEPRECAT --- - + ## function `download_file` @@ -211,7 +211,7 @@ Download filename `remote_path` inside the mirror tree inside the gef.config["ge --- - + ## function `enable_redirect_output` @@ -224,7 +224,7 @@ Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects --- - + ## function `endian_str` @@ -237,7 +237,7 @@ endian_str() → str --- - + ## function `err` @@ -252,7 +252,7 @@ err(msg: str) → Union[int, NoneType] --- - + ## function `exit_handler` @@ -265,7 +265,7 @@ GDB event handler for exit cases. --- - + ## function `experimental_feature` @@ -278,7 +278,7 @@ Decorator to add a warning when a feature is experimental. --- - + ## function `flags_to_human` @@ -291,7 +291,7 @@ Return a human readable string showing the flag states. --- - + ## function `format_address` @@ -304,7 +304,7 @@ Format the address according to its size. --- - + ## function `format_address_spaces` @@ -317,7 +317,7 @@ Format the address according to its size, but with spaces instead of zeroes. --- - + ## function `gdb_disassemble` @@ -332,7 +332,7 @@ Disassemble instructions from `start_pc` (Integer). Accepts the following named --- - + ## function `gdb_get_nth_next_instruction_address` @@ -345,7 +345,7 @@ Return the address (Integer) of the `n`-th instruction after `addr`. --- - + ## function `gdb_get_nth_previous_instruction_address` @@ -361,7 +361,7 @@ Return the address (Integer) of the `n`-th instruction before `addr`. --- - + ## function `gef_convenience` @@ -374,7 +374,7 @@ Defines a new convenience value. --- - + ## function `gef_current_instruction` @@ -387,7 +387,7 @@ Return the current instruction as an Instruction object. --- - + ## function `gef_disassemble` @@ -400,7 +400,7 @@ Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr`. Ret --- - + ## function `gef_execute_external` @@ -417,7 +417,7 @@ Execute an external command and return the result. --- - + ## function `gef_execute_gdb_script` @@ -430,7 +430,7 @@ Execute the parameter `source` as GDB command. This is done by writing `commands --- - + ## function `gef_get_instruction_at` @@ -443,7 +443,7 @@ Return the full Instruction found at the specified address. --- - + ## function `gef_get_pie_breakpoint` @@ -458,7 +458,7 @@ gef_get_pie_breakpoint(num: int) --- - + ## function `gef_getpagesize` @@ -471,7 +471,7 @@ gef_getpagesize() → int --- - + ## function `gef_instruction_n` @@ -484,7 +484,7 @@ Return the `n`-th instruction after `addr` as an Instruction object. --- - + ## function `gef_makedirs` @@ -497,7 +497,7 @@ Recursive mkdir() creation. If successful, return the absolute path of the direc --- - + ## function `gef_next_instruction` @@ -510,7 +510,7 @@ Return the next instruction as an Instruction object. --- - + ## function `wrapped_f` @@ -525,7 +525,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -540,7 +540,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -555,7 +555,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -570,7 +570,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -585,7 +585,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -600,7 +600,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -615,7 +615,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -630,7 +630,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -645,7 +645,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -660,7 +660,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -675,7 +675,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `wrapped_f` @@ -690,7 +690,7 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any --- - + ## function `gef_print` @@ -703,7 +703,7 @@ Wrapper around print(), using string buffering feature. --- - + ## function `gef_pybytes` @@ -716,7 +716,7 @@ Returns an immutable bytes list from the string given as input. --- - + ## function `gef_pystring` @@ -729,7 +729,7 @@ Returns a sanitized version as string of the bytes list given in input. --- - + ## function `gef_read_canary` @@ -742,7 +742,7 @@ gef_read_canary() → Union[Tuple[int, int], NoneType] --- - + ## function `generate_cyclic_pattern` @@ -755,7 +755,7 @@ Create a `length` byte bytearray of a de Bruijn cyclic pattern. --- - + ## function `get_capstone_arch` @@ -775,7 +775,7 @@ get_capstone_arch( --- - + ## function `get_filename` @@ -788,7 +788,7 @@ get_filename() → str --- - + ## function `get_function_length` @@ -801,7 +801,7 @@ Attempt to get the length of the raw bytes of a function. --- - + ## function `get_gef_setting` @@ -814,7 +814,7 @@ get_gef_setting(name: str) → Any --- - + ## function `get_generic_arch` @@ -834,7 +834,7 @@ Retrieves architecture and mode from the arguments for use for the holy {cap,key --- - + ## function `get_generic_running_arch` @@ -851,7 +851,7 @@ Retrieves architecture and mode from the current context. --- - + ## function `get_glibc_arena` @@ -864,7 +864,7 @@ get_glibc_arena() --- - + ## function `get_keystone_arch` @@ -884,7 +884,7 @@ get_keystone_arch( --- - + ## function `get_memory_alignment` @@ -897,7 +897,7 @@ Try to determine the size of a pointer on this system. First, try to parse it o --- - + ## function `get_os` @@ -910,7 +910,7 @@ get_os() → str --- - + ## function `get_path_from_info_proc` @@ -925,7 +925,7 @@ get_path_from_info_proc() --- - + ## function `get_pid` @@ -938,7 +938,7 @@ get_pid() → int --- - + ## function `get_process_maps` @@ -951,7 +951,7 @@ get_process_maps() --- - + ## function `get_register` @@ -964,7 +964,7 @@ get_register(regname) --- - + ## function `get_terminal_size` @@ -977,7 +977,7 @@ Return the current terminal size. --- - + ## function `get_unicorn_arch` @@ -997,7 +997,7 @@ get_unicorn_arch( --- - + ## function `get_unicorn_registers` @@ -1012,7 +1012,7 @@ Return a dict matching the Unicorn identifier for a specific register. --- - + ## function `hexdump` @@ -1032,7 +1032,7 @@ Return the hexdump of `src` argument. @param source *MUST* be of type bytes or b --- - + ## function `hide_context` @@ -1045,7 +1045,7 @@ Helper function to hide the context pane --- - + ## function `highlight_text` @@ -1062,7 +1062,7 @@ If RegEx is disabled, split by ANSI codes and 'colorify' each match found within --- - + ## function `hook_stop_handler` @@ -1075,7 +1075,7 @@ GDB event handler for stop cases. --- - + ## function `http_get` @@ -1088,7 +1088,7 @@ Basic HTTP wrapper for GET request. Return the body of the page if HTTP code is --- - + ## function `ida_synchronize_handler` @@ -1103,7 +1103,7 @@ ida_synchronize_handler(event) --- - + ## function `info` @@ -1118,7 +1118,7 @@ info(msg: str) → Union[int, NoneType] --- - + ## function `is_alive` @@ -1131,7 +1131,7 @@ Check if GDB is running. --- - + ## function `is_ascii_string` @@ -1144,7 +1144,7 @@ Helper function to determine if the buffer pointed by `address` is an ASCII stri --- - + ## function `is_big_endian` @@ -1157,7 +1157,7 @@ is_big_endian() → bool --- - + ## function `is_debug` @@ -1170,7 +1170,7 @@ Check if debug mode is enabled. --- - + ## function `is_hex` @@ -1183,7 +1183,7 @@ Return whether provided string is a hexadecimal value. --- - + ## function `is_in_x86_kernel` @@ -1198,7 +1198,7 @@ is_in_x86_kernel(address: int) → bool --- - + ## function `is_little_endian` @@ -1211,7 +1211,7 @@ is_little_endian() → bool --- - + ## function `is_pie` @@ -1226,7 +1226,7 @@ is_pie(fpath: str) → bool --- - + ## function `keystone_assemble` @@ -1245,7 +1245,7 @@ Assembly encoding function based on keystone. --- - + ## function `load_libc_args` @@ -1260,7 +1260,7 @@ load_libc_args() → None --- - + ## function `malloc_align_address` @@ -1273,7 +1273,7 @@ Align addresses according to glibc's MALLOC_ALIGNMENT. See also Issue #689 on Gi --- - + ## function `memchanged_handler` @@ -1286,7 +1286,7 @@ GDB event handler for mem changes cases. --- - + ## function `new_objfile_handler` @@ -1299,7 +1299,7 @@ GDB event handler for new object file cases. --- - + ## function `ok` @@ -1314,7 +1314,7 @@ ok(msg: str) → Union[int, NoneType] --- - + ## function `only_if_current_arch_in` @@ -1327,7 +1327,7 @@ Decorator to allow commands for only a subset of the architectured supported by --- - + ## function `only_if_events_supported` @@ -1340,7 +1340,7 @@ Checks if GDB supports events without crashing. --- - + ## function `only_if_gdb_running` @@ -1353,7 +1353,7 @@ Decorator wrapper to check if GDB is running. --- - + ## function `only_if_gdb_target_local` @@ -1366,7 +1366,7 @@ Decorator wrapper to check if GDB is running locally (target not remote). --- - + ## function `only_if_gdb_version_higher_than` @@ -1379,7 +1379,7 @@ Decorator to check whether current GDB version requirements. --- - + ## function `p16` @@ -1392,7 +1392,7 @@ Pack one word respecting the current architecture endianness. --- - + ## function `p32` @@ -1405,7 +1405,7 @@ Pack one dword respecting the current architecture endianness. --- - + ## function `p64` @@ -1418,7 +1418,7 @@ Pack one qword respecting the current architecture endianness. --- - + ## function `p8` @@ -1431,7 +1431,7 @@ Pack one byte respecting the current architecture endianness. --- - + ## function `parse_address` @@ -1444,7 +1444,7 @@ Parse an address and return it as an Integer. --- - + ## function `parse_arguments` @@ -1460,7 +1460,7 @@ Argument parsing decorator. --- - + ## function `parse_string_range` @@ -1473,7 +1473,7 @@ Parses an address range (e.g. 0x400000-0x401000) --- - + ## function `process_lookup_address` @@ -1486,7 +1486,7 @@ Look up for an address in memory. Return an Address object if found, None otherw --- - + ## function `push_context_message` @@ -1499,7 +1499,7 @@ Push the message to be displayed the next time the context is invoked. --- - + ## function `regchanged_handler` @@ -1512,7 +1512,7 @@ GDB event handler for reg changes cases. --- - + ## function `register_architecture` @@ -1525,7 +1525,7 @@ Class decorator for declaring an architecture to GEF. --- - + ## function `register_command` @@ -1538,7 +1538,7 @@ Decorator for registering new GEF (sub-)command to GDB. --- - + ## function `register_external_command` @@ -1551,7 +1551,7 @@ Registering function for new GEF (sub-)command to GDB. --- - + ## function `register_external_context_pane` @@ -1570,7 +1570,7 @@ Example Usage: def display_pane(): gef_print("Wow, I am a context pane!") def pa --- - + ## function `register_function` @@ -1583,7 +1583,7 @@ Decorator for registering a new convenience function to GDB. --- - + ## function `register_priority_command` @@ -1596,7 +1596,7 @@ Decorator for registering new command with priority, meaning that it must loaded --- - + ## function `reset` @@ -1611,7 +1611,7 @@ reset() → None --- - + ## function `reset_all_caches` @@ -1624,7 +1624,7 @@ Free all caches. If an object is cached, it will have a callable attribute `cach --- - + ## function `safe_parse_and_eval` @@ -1637,7 +1637,7 @@ GEF wrapper for gdb.parse_and_eval(): this function returns None instead of rais --- - + ## function `set_arch` @@ -1650,7 +1650,7 @@ Sets the current architecture. If an arch is explicitly specified, use that one, --- - + ## function `set_gef_setting` @@ -1663,7 +1663,7 @@ set_gef_setting(name: str, value: Any) → None --- - + ## function `show_last_exception` @@ -1676,7 +1676,7 @@ Display the last Python exception. --- - + ## function `style_byte` @@ -1691,7 +1691,7 @@ style_byte(b: int, color: bool = True) → str --- - + ## function `titlify` @@ -1708,7 +1708,7 @@ Print a centered title. --- - + ## function `to_unsigned_long` @@ -1721,7 +1721,7 @@ Cast a gdb.Value to unsigned long. --- - + ## function `u16` @@ -1734,7 +1734,7 @@ Unpack one word respecting the current architecture endianness. --- - + ## function `u32` @@ -1747,7 +1747,7 @@ Unpack one dword respecting the current architecture endianness. --- - + ## function `u64` @@ -1760,7 +1760,7 @@ Unpack one qword respecting the current architecture endianness. --- - + ## function `u8` @@ -1773,7 +1773,7 @@ Unpack one byte respecting the current architecture endianness. --- - + ## function `unhide_context` @@ -1786,7 +1786,7 @@ Helper function to unhide the context pane --- - + ## function `update_gef` @@ -1799,7 +1799,7 @@ Try to update `gef` to the latest version pushed on GitHub master branch. Return --- - + ## function `use_default_type` @@ -1814,7 +1814,7 @@ use_default_type() → str --- - + ## function `use_golang_type` @@ -1829,7 +1829,7 @@ use_golang_type() → str --- - + ## function `use_rust_type` @@ -1844,7 +1844,7 @@ use_rust_type() → str --- - + ## function `use_stdtype` @@ -1859,7 +1859,7 @@ use_stdtype() → str --- - + ## function `warn` @@ -1874,7 +1874,7 @@ warn(msg: str) → Union[int, NoneType] --- - + ## function `xor` @@ -1937,7 +1937,7 @@ Return `data` xor-ed with `key`. --- - + ## function `AARCH64.flag_register_to_human` @@ -1951,7 +1951,7 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + ## function `AARCH64.get_ith_parameter` @@ -1966,7 +1966,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `AARCH64.get_ra` @@ -1980,7 +1980,7 @@ get_ra(insn, frame) → int --- - + ## function `AARCH64.is_branch_taken` @@ -1994,7 +1994,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `AARCH64.is_call` @@ -2008,7 +2008,7 @@ is_call(insn) → bool --- - + ## function `AARCH64.is_conditional_branch` @@ -2022,7 +2022,7 @@ is_conditional_branch(insn) → bool --- - + ## function `AARCH64.is_ret` @@ -2036,7 +2036,7 @@ is_ret(insn) → Union[bool, NoneType] --- - + ## function `AARCH64.is_thumb` @@ -2048,7 +2048,7 @@ Determine if the machine is currently in THUMB mode. --- - + ## function `AARCH64.mprotect_asm` @@ -2062,7 +2062,7 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + ## function `AARCH64.register` @@ -2143,7 +2143,7 @@ register(name: str) → Union[int, NoneType] --- - + ## function `ARM.flag_register_to_human` @@ -2157,7 +2157,7 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + ## function `ARM.get_ith_parameter` @@ -2172,7 +2172,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `ARM.get_ra` @@ -2186,7 +2186,7 @@ get_ra(insn, frame) → int --- - + ## function `ARM.is_branch_taken` @@ -2200,7 +2200,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `ARM.is_call` @@ -2214,7 +2214,7 @@ is_call(insn) → bool --- - + ## function `ARM.is_conditional_branch` @@ -2228,7 +2228,7 @@ is_conditional_branch(insn) → bool --- - + ## function `ARM.is_ret` @@ -2242,7 +2242,7 @@ is_ret(insn) → Union[bool, NoneType] --- - + ## function `ARM.is_thumb` @@ -2254,7 +2254,7 @@ Determine if the machine is currently in THUMB mode. --- - + ## function `ARM.mprotect_asm` @@ -2268,7 +2268,7 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + ## function `ARM.register` @@ -2286,7 +2286,7 @@ register(name: str) → Union[int, NoneType] ## 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__` @@ -2309,7 +2309,7 @@ Return the list of settings for this command. --- - + ## function `ASLRCommand.add_setting` @@ -2325,7 +2325,7 @@ add_setting( --- - + ## function `ASLRCommand.del_setting` @@ -2337,7 +2337,7 @@ del_setting(name: str) → None --- - + ## function `ASLRCommand.do_invoke` @@ -2351,7 +2351,7 @@ do_invoke(argv: List) → None --- - + ## function `ASLRCommand.get_setting` @@ -2363,7 +2363,7 @@ get_setting(name) --- - + ## function `ASLRCommand.has_setting` @@ -2375,7 +2375,7 @@ has_setting(name: str) → bool --- - + ## function `ASLRCommand.invoke` @@ -2389,7 +2389,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ASLRCommand.post_load` @@ -2403,7 +2403,7 @@ post_load() → None --- - + ## function `ASLRCommand.pre_load` @@ -2417,7 +2417,7 @@ pre_load() → None --- - + ## function `ASLRCommand.usage` @@ -2435,7 +2435,7 @@ usage() → None ## class `Address` GEF representation of memory addresses. - + ## function `Address.__init__` @@ -2452,7 +2452,7 @@ __init__(*args, **kwargs) → None --- - + ## function `Address.dereference` @@ -2466,7 +2466,7 @@ dereference() → Union[int, NoneType] --- - + ## function `Address.is_in_heap_segment` @@ -2480,7 +2480,7 @@ is_in_heap_segment() → bool --- - + ## function `Address.is_in_stack_segment` @@ -2494,7 +2494,7 @@ is_in_stack_segment() → bool --- - + ## function `Address.is_in_text_segment` @@ -2512,7 +2512,7 @@ is_in_text_segment() → bool ## class `AliasesAddCommand` Command to add aliases. - + ## function `AliasesAddCommand.__init__` @@ -2535,7 +2535,7 @@ Return the list of settings for this command. --- - + ## function `AliasesAddCommand.add_setting` @@ -2551,7 +2551,7 @@ add_setting( --- - + ## function `AliasesAddCommand.del_setting` @@ -2563,7 +2563,7 @@ del_setting(name: str) → None --- - + ## function `AliasesAddCommand.do_invoke` @@ -2577,7 +2577,7 @@ do_invoke(argv: List) → None --- - + ## function `AliasesAddCommand.get_setting` @@ -2589,7 +2589,7 @@ get_setting(name) --- - + ## function `AliasesAddCommand.has_setting` @@ -2601,7 +2601,7 @@ has_setting(name: str) → bool --- - + ## function `AliasesAddCommand.invoke` @@ -2615,7 +2615,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `AliasesAddCommand.post_load` @@ -2629,7 +2629,7 @@ post_load() → None --- - + ## function `AliasesAddCommand.pre_load` @@ -2643,7 +2643,7 @@ pre_load() → None --- - + ## function `AliasesAddCommand.usage` @@ -2661,7 +2661,7 @@ usage() → None ## class `AliasesCommand` Base command to add, remove, or list aliases. - + ## function `AliasesCommand.__init__` @@ -2684,7 +2684,7 @@ Return the list of settings for this command. --- - + ## function `AliasesCommand.add_setting` @@ -2700,7 +2700,7 @@ add_setting( --- - + ## function `AliasesCommand.del_setting` @@ -2712,7 +2712,7 @@ del_setting(name: str) → None --- - + ## function `AliasesCommand.do_invoke` @@ -2726,7 +2726,7 @@ do_invoke(argv) → None --- - + ## function `AliasesCommand.get_setting` @@ -2738,7 +2738,7 @@ get_setting(name) --- - + ## function `AliasesCommand.has_setting` @@ -2750,7 +2750,7 @@ has_setting(name: str) → bool --- - + ## function `AliasesCommand.invoke` @@ -2764,7 +2764,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `AliasesCommand.post_load` @@ -2778,7 +2778,7 @@ post_load() → None --- - + ## function `AliasesCommand.pre_load` @@ -2792,7 +2792,7 @@ pre_load() → None --- - + ## function `AliasesCommand.usage` @@ -2810,7 +2810,7 @@ usage() → None ## class `AliasesListCommand` Command to list aliases. - + ## function `AliasesListCommand.__init__` @@ -2833,7 +2833,7 @@ Return the list of settings for this command. --- - + ## function `AliasesListCommand.add_setting` @@ -2849,7 +2849,7 @@ add_setting( --- - + ## function `AliasesListCommand.del_setting` @@ -2861,7 +2861,7 @@ del_setting(name: str) → None --- - + ## function `AliasesListCommand.do_invoke` @@ -2875,7 +2875,7 @@ do_invoke(argv: List) → None --- - + ## function `AliasesListCommand.get_setting` @@ -2887,7 +2887,7 @@ get_setting(name) --- - + ## function `AliasesListCommand.has_setting` @@ -2899,7 +2899,7 @@ has_setting(name: str) → bool --- - + ## function `AliasesListCommand.invoke` @@ -2913,7 +2913,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `AliasesListCommand.post_load` @@ -2927,7 +2927,7 @@ post_load() → None --- - + ## function `AliasesListCommand.pre_load` @@ -2941,7 +2941,7 @@ pre_load() → None --- - + ## function `AliasesListCommand.usage` @@ -2959,7 +2959,7 @@ usage() → None ## class `AliasesRmCommand` Command to remove aliases. - + ## function `AliasesRmCommand.__init__` @@ -2982,7 +2982,7 @@ Return the list of settings for this command. --- - + ## function `AliasesRmCommand.add_setting` @@ -2998,7 +2998,7 @@ add_setting( --- - + ## function `AliasesRmCommand.del_setting` @@ -3010,7 +3010,7 @@ del_setting(name: str) → None --- - + ## function `AliasesRmCommand.do_invoke` @@ -3024,7 +3024,7 @@ do_invoke(argv: List) → None --- - + ## function `AliasesRmCommand.get_setting` @@ -3036,7 +3036,7 @@ get_setting(name) --- - + ## function `AliasesRmCommand.has_setting` @@ -3048,7 +3048,7 @@ has_setting(name: str) → bool --- - + ## function `AliasesRmCommand.invoke` @@ -3062,7 +3062,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `AliasesRmCommand.post_load` @@ -3076,7 +3076,7 @@ post_load() → None --- - + ## function `AliasesRmCommand.pre_load` @@ -3090,7 +3090,7 @@ pre_load() → None --- - + ## function `AliasesRmCommand.usage` @@ -3161,7 +3161,7 @@ Generic metaclass for the architecture supported by GEF. --- - + ## function `Architecture.flag_register_to_human` @@ -3175,7 +3175,7 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + ## function `Architecture.get_ith_parameter` @@ -3190,7 +3190,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `Architecture.get_ra` @@ -3204,7 +3204,7 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + ## function `Architecture.is_branch_taken` @@ -3218,7 +3218,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `Architecture.is_call` @@ -3232,7 +3232,7 @@ is_call(insn) → bool --- - + ## function `Architecture.is_conditional_branch` @@ -3246,7 +3246,7 @@ is_conditional_branch(insn) → bool --- - + ## function `Architecture.is_ret` @@ -3260,7 +3260,7 @@ is_ret(insn) → Union[bool, NoneType] --- - + ## function `Architecture.register` @@ -3278,7 +3278,7 @@ register(name: str) → Union[int, NoneType] ## class `AssembleCommand` Inline code assemble. Architecture can be set in GEF runtime config. - + ## function `AssembleCommand.__init__` @@ -3301,7 +3301,7 @@ Return the list of settings for this command. --- - + ## function `AssembleCommand.add_setting` @@ -3317,7 +3317,7 @@ add_setting( --- - + ## function `AssembleCommand.del_setting` @@ -3329,7 +3329,7 @@ del_setting(name: str) → None --- - + ## function `AssembleCommand.wrapper` @@ -3343,7 +3343,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `AssembleCommand.get_setting` @@ -3355,7 +3355,7 @@ get_setting(name) --- - + ## function `AssembleCommand.has_setting` @@ -3367,7 +3367,7 @@ has_setting(name: str) → bool --- - + ## function `AssembleCommand.invoke` @@ -3381,7 +3381,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `AssembleCommand.list_archs` @@ -3395,7 +3395,7 @@ list_archs() → None --- - + ## function `AssembleCommand.post_load` @@ -3409,7 +3409,7 @@ post_load() → None --- - + ## function `AssembleCommand.pre_load` @@ -3423,7 +3423,7 @@ pre_load() → None --- - + ## function `AssembleCommand.usage` @@ -3441,7 +3441,7 @@ usage() → None ## class `BssBaseFunction` Return the current bss base address plus the given offset. - + ## function `BssBaseFunction.__init__` @@ -3458,7 +3458,7 @@ __init__() → None --- - + ## function `BssBaseFunction.arg_to_long` @@ -3472,7 +3472,7 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + ## function `BssBaseFunction.do_invoke` @@ -3486,7 +3486,7 @@ do_invoke(args: List) → int --- - + ## function `BssBaseFunction.invoke` @@ -3504,7 +3504,7 @@ invoke(*args) → int ## class `CanaryCommand` Shows the canary value of the current process. - + ## function `CanaryCommand.__init__` @@ -3527,7 +3527,7 @@ Return the list of settings for this command. --- - + ## function `CanaryCommand.add_setting` @@ -3543,7 +3543,7 @@ add_setting( --- - + ## function `CanaryCommand.del_setting` @@ -3555,7 +3555,7 @@ del_setting(name: str) → None --- - + ## function `CanaryCommand.do_invoke` @@ -3569,7 +3569,7 @@ do_invoke(argv: List) → None --- - + ## function `CanaryCommand.get_setting` @@ -3581,7 +3581,7 @@ get_setting(name) --- - + ## function `CanaryCommand.has_setting` @@ -3593,7 +3593,7 @@ has_setting(name: str) → bool --- - + ## function `CanaryCommand.invoke` @@ -3607,7 +3607,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `CanaryCommand.post_load` @@ -3621,7 +3621,7 @@ post_load() → None --- - + ## function `CanaryCommand.pre_load` @@ -3635,7 +3635,7 @@ pre_load() → None --- - + ## function `CanaryCommand.usage` @@ -3653,7 +3653,7 @@ usage() → None ## class `CapstoneDisassembleCommand` Use capstone disassembly framework to disassemble code. - + ## function `CapstoneDisassembleCommand.__init__` @@ -3676,7 +3676,7 @@ Return the list of settings for this command. --- - + ## function `CapstoneDisassembleCommand.add_setting` @@ -3692,7 +3692,7 @@ add_setting( --- - + ## function `CapstoneDisassembleCommand.capstone_analyze_pc` @@ -3706,7 +3706,7 @@ capstone_analyze_pc(insn, nb_insn: int) → Tuple[bool, str] --- - + ## function `CapstoneDisassembleCommand.del_setting` @@ -3718,7 +3718,7 @@ del_setting(name: str) → None --- - + ## function `CapstoneDisassembleCommand.wrapper` @@ -3732,7 +3732,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `CapstoneDisassembleCommand.get_setting` @@ -3744,7 +3744,7 @@ get_setting(name) --- - + ## function `CapstoneDisassembleCommand.has_setting` @@ -3756,7 +3756,7 @@ has_setting(name: str) → bool --- - + ## function `CapstoneDisassembleCommand.invoke` @@ -3770,7 +3770,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `CapstoneDisassembleCommand.post_load` @@ -3784,7 +3784,7 @@ post_load() → None --- - + ## function `CapstoneDisassembleCommand.pre_load` @@ -3798,7 +3798,7 @@ pre_load() → None --- - + ## function `CapstoneDisassembleCommand.usage` @@ -3816,7 +3816,7 @@ usage() → None ## class `ChangeFdCommand` ChangeFdCommand: redirect file descriptor during runtime. - + ## function `ChangeFdCommand.__init__` @@ -3839,7 +3839,7 @@ Return the list of settings for this command. --- - + ## function `ChangeFdCommand.add_setting` @@ -3855,7 +3855,7 @@ add_setting( --- - + ## function `ChangeFdCommand.del_setting` @@ -3867,7 +3867,7 @@ del_setting(name: str) → None --- - + ## function `ChangeFdCommand.do_invoke` @@ -3881,7 +3881,7 @@ do_invoke(argv: List) → None --- - + ## function `ChangeFdCommand.get_fd_from_result` @@ -3895,7 +3895,7 @@ get_fd_from_result(res: str) → int --- - + ## function `ChangeFdCommand.get_setting` @@ -3907,7 +3907,7 @@ get_setting(name) --- - + ## function `ChangeFdCommand.has_setting` @@ -3919,7 +3919,7 @@ has_setting(name: str) → bool --- - + ## function `ChangeFdCommand.invoke` @@ -3933,7 +3933,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ChangeFdCommand.post_load` @@ -3947,7 +3947,7 @@ post_load() → None --- - + ## function `ChangeFdCommand.pre_load` @@ -3961,7 +3961,7 @@ pre_load() → None --- - + ## function `ChangeFdCommand.usage` @@ -3979,7 +3979,7 @@ usage() → None ## class `ChangePermissionBreakpoint` When hit, this temporary breakpoint will restore the original code, and position $pc correctly. - + ## function `ChangePermissionBreakpoint.__init__` @@ -3996,7 +3996,7 @@ __init__(loc: str, code: ByteString, pc: int) → None --- - + ## function `ChangePermissionBreakpoint.stop` @@ -4014,7 +4014,7 @@ stop() → bool ## class `ChangePermissionCommand` Change a page permission. By default, it will change it to 7 (RWX). - + ## function `ChangePermissionCommand.__init__` @@ -4037,7 +4037,7 @@ Return the list of settings for this command. --- - + ## function `ChangePermissionCommand.add_setting` @@ -4053,7 +4053,7 @@ add_setting( --- - + ## function `ChangePermissionCommand.del_setting` @@ -4065,7 +4065,7 @@ del_setting(name: str) → None --- - + ## function `ChangePermissionCommand.do_invoke` @@ -4079,7 +4079,7 @@ do_invoke(argv: List) → None --- - + ## function `ChangePermissionCommand.get_setting` @@ -4091,7 +4091,7 @@ get_setting(name) --- - + ## function `ChangePermissionCommand.get_stub_by_arch` @@ -4105,7 +4105,7 @@ get_stub_by_arch(addr: int, size: int, perm) → Union[str, bytearray, NoneType] --- - + ## function `ChangePermissionCommand.has_setting` @@ -4117,7 +4117,7 @@ has_setting(name: str) → bool --- - + ## function `ChangePermissionCommand.invoke` @@ -4131,7 +4131,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ChangePermissionCommand.post_load` @@ -4145,7 +4145,7 @@ post_load() → None --- - + ## function `ChangePermissionCommand.pre_load` @@ -4159,7 +4159,7 @@ pre_load() → None --- - + ## function `ChangePermissionCommand.usage` @@ -4182,7 +4182,7 @@ Checksec the security properties of the current executable or passed as argument - Glibc Stack Canaries - Fortify Source - + ## function `ChecksecCommand.__init__` @@ -4205,7 +4205,7 @@ Return the list of settings for this command. --- - + ## function `ChecksecCommand.add_setting` @@ -4221,7 +4221,7 @@ add_setting( --- - + ## function `ChecksecCommand.del_setting` @@ -4233,7 +4233,7 @@ del_setting(name: str) → None --- - + ## function `ChecksecCommand.do_invoke` @@ -4247,7 +4247,7 @@ do_invoke(argv: List) → None --- - + ## function `ChecksecCommand.get_setting` @@ -4259,7 +4259,7 @@ get_setting(name) --- - + ## function `ChecksecCommand.has_setting` @@ -4271,7 +4271,7 @@ has_setting(name: str) → bool --- - + ## function `ChecksecCommand.invoke` @@ -4285,7 +4285,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ChecksecCommand.post_load` @@ -4299,7 +4299,7 @@ post_load() → None --- - + ## function `ChecksecCommand.pre_load` @@ -4313,7 +4313,7 @@ pre_load() → None --- - + ## function `ChecksecCommand.print_security_properties` @@ -4327,7 +4327,7 @@ print_security_properties(filename: str) → None --- - + ## function `ChecksecCommand.usage` @@ -4350,7 +4350,7 @@ Used to colorify terminal output. --- - + ## function `Color.blinkify` @@ -4364,7 +4364,7 @@ blinkify(msg: str) → str --- - + ## function `Color.blueify` @@ -4378,7 +4378,7 @@ blueify(msg: str) → str --- - + ## function `Color.boldify` @@ -4392,7 +4392,7 @@ boldify(msg: str) → str --- - + ## function `Color.colorify` @@ -4404,7 +4404,7 @@ Color text according to the given attributes. --- - + ## function `Color.cyanify` @@ -4418,7 +4418,7 @@ cyanify(msg: str) → str --- - + ## function `Color.grayify` @@ -4432,7 +4432,7 @@ grayify(msg: str) → str --- - + ## function `Color.greenify` @@ -4446,7 +4446,7 @@ greenify(msg: str) → str --- - + ## function `Color.highlightify` @@ -4460,7 +4460,7 @@ highlightify(msg: str) → str --- - + ## function `Color.light_grayify` @@ -4474,7 +4474,7 @@ light_grayify(msg: str) → str --- - + ## function `Color.pinkify` @@ -4488,7 +4488,7 @@ pinkify(msg: str) → str --- - + ## function `Color.redify` @@ -4502,7 +4502,7 @@ redify(msg: str) → str --- - + ## function `Color.underlinify` @@ -4516,7 +4516,7 @@ underlinify(msg: str) → str --- - + ## function `Color.yellowify` @@ -4534,7 +4534,7 @@ 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__` @@ -4557,7 +4557,7 @@ Return the list of settings for this command. --- - + ## function `ContextCommand.add_setting` @@ -4573,7 +4573,7 @@ add_setting( --- - + ## function `ContextCommand.addr_has_breakpoint` @@ -4587,7 +4587,7 @@ addr_has_breakpoint(address: int, bp_locations: List[str]) → bool --- - + ## function `ContextCommand.context_additional_information` @@ -4601,7 +4601,7 @@ context_additional_information() → None --- - + ## function `ContextCommand.context_args` @@ -4615,7 +4615,7 @@ context_args() → None --- - + ## function `ContextCommand.context_code` @@ -4629,7 +4629,7 @@ context_code() → None --- - + ## function `ContextCommand.context_memory` @@ -4643,7 +4643,7 @@ context_memory() → None --- - + ## function `ContextCommand.context_regs` @@ -4657,7 +4657,7 @@ context_regs() → None --- - + ## function `ContextCommand.context_source` @@ -4671,7 +4671,7 @@ context_source() → None --- - + ## function `ContextCommand.context_stack` @@ -4685,7 +4685,7 @@ context_stack() → None --- - + ## function `ContextCommand.context_threads` @@ -4699,7 +4699,7 @@ context_threads() → None --- - + ## function `ContextCommand.context_title` @@ -4713,7 +4713,7 @@ context_title(m: Optional[str]) → None --- - + ## function `ContextCommand.context_trace` @@ -4727,7 +4727,7 @@ context_trace() → None --- - + ## function `ContextCommand.del_setting` @@ -4739,7 +4739,7 @@ del_setting(name: str) → None --- - + ## function `ContextCommand.do_invoke` @@ -4753,7 +4753,7 @@ do_invoke(argv: List) → None --- - + ## function `ContextCommand.empty_extra_messages` @@ -4767,7 +4767,7 @@ empty_extra_messages(_) → None --- - + ## function `ContextCommand.get_pc_context_info` @@ -4781,7 +4781,7 @@ get_pc_context_info(pc: int, line: str) → str --- - + ## function `ContextCommand.get_setting` @@ -4793,7 +4793,7 @@ get_setting(name) --- - + ## function `ContextCommand.has_setting` @@ -4805,7 +4805,7 @@ has_setting(name: str) → bool --- - + ## function `ContextCommand.invoke` @@ -4819,7 +4819,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ContextCommand.line_has_breakpoint` @@ -4837,7 +4837,7 @@ line_has_breakpoint( --- - + ## function `ContextCommand.post_load` @@ -4851,7 +4851,7 @@ post_load() → None --- - + ## function `ContextCommand.pre_load` @@ -4865,7 +4865,7 @@ pre_load() → None --- - + ## function `ContextCommand.print_arguments_from_symbol` @@ -4877,7 +4877,7 @@ If symbols were found, parse them and print the argument adequately. --- - + ## function `ContextCommand.print_guessed_arguments` @@ -4889,7 +4889,7 @@ When no symbol, read the current basic block and look for "interesting" instruct --- - + ## function `ContextCommand.show_legend` @@ -4903,7 +4903,7 @@ show_legend() → None --- - + ## function `ContextCommand.update_registers` @@ -4917,7 +4917,7 @@ update_registers(_) → None --- - + ## function `ContextCommand.usage` @@ -4935,7 +4935,7 @@ usage() → None ## class `DereferenceCommand` Dereference recursively from an address and display information. This acts like WinDBG `dps` command. - + ## function `DereferenceCommand.__init__` @@ -4958,7 +4958,7 @@ Return the list of settings for this command. --- - + ## function `DereferenceCommand.add_setting` @@ -4974,7 +4974,7 @@ add_setting( --- - + ## function `DereferenceCommand.del_setting` @@ -4986,7 +4986,7 @@ del_setting(name: str) → None --- - + ## function `DereferenceCommand.wrapper` @@ -5000,7 +5000,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `DereferenceCommand.get_setting` @@ -5012,7 +5012,7 @@ get_setting(name) --- - + ## function `DereferenceCommand.has_setting` @@ -5024,7 +5024,7 @@ has_setting(name: str) → bool --- - + ## function `DereferenceCommand.invoke` @@ -5038,7 +5038,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `DereferenceCommand.post_load` @@ -5052,7 +5052,7 @@ post_load() → None --- - + ## function `DereferenceCommand.pprint_dereferenced` @@ -5066,7 +5066,7 @@ pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) → str --- - + ## function `DereferenceCommand.pre_load` @@ -5080,7 +5080,7 @@ pre_load() → None --- - + ## function `DereferenceCommand.usage` @@ -5098,7 +5098,7 @@ usage() → None ## class `DetailRegistersCommand` Display full details on one, many or all registers value from current architecture. - + ## function `DetailRegistersCommand.__init__` @@ -5121,7 +5121,7 @@ Return the list of settings for this command. --- - + ## function `DetailRegistersCommand.add_setting` @@ -5137,7 +5137,7 @@ add_setting( --- - + ## function `DetailRegistersCommand.del_setting` @@ -5149,7 +5149,7 @@ del_setting(name: str) → None --- - + ## function `DetailRegistersCommand.wrapper` @@ -5163,7 +5163,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `DetailRegistersCommand.get_setting` @@ -5175,7 +5175,7 @@ get_setting(name) --- - + ## function `DetailRegistersCommand.has_setting` @@ -5187,7 +5187,7 @@ has_setting(name: str) → bool --- - + ## function `DetailRegistersCommand.invoke` @@ -5201,7 +5201,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `DetailRegistersCommand.post_load` @@ -5215,7 +5215,7 @@ post_load() → None --- - + ## function `DetailRegistersCommand.pre_load` @@ -5229,7 +5229,7 @@ pre_load() → None --- - + ## function `DetailRegistersCommand.usage` @@ -5250,7 +5250,7 @@ Basic ELF parsing. Ref: - http://refspecs.freestandards.org/elf/elfspec_ppc.pdf - http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html - + ## function `Elf.__init__` @@ -5265,7 +5265,7 @@ Instantiate an ELF object. The default behavior is to create the object by parsi --- - + ## function `Elf.is_valid` @@ -5279,7 +5279,7 @@ is_valid() → bool --- - + ## function `Elf.read` @@ -5293,7 +5293,7 @@ read(size) --- - + ## function `Elf.seek` @@ -5311,7 +5311,7 @@ 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__` @@ -5334,7 +5334,7 @@ Return the list of settings for this command. --- - + ## function `ElfInfoCommand.add_setting` @@ -5350,7 +5350,7 @@ add_setting( --- - + ## function `ElfInfoCommand.del_setting` @@ -5362,7 +5362,7 @@ del_setting(name: str) → None --- - + ## function `ElfInfoCommand.wrapper` @@ -5376,7 +5376,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `ElfInfoCommand.get_setting` @@ -5388,7 +5388,7 @@ get_setting(name) --- - + ## function `ElfInfoCommand.has_setting` @@ -5400,7 +5400,7 @@ has_setting(name: str) → bool --- - + ## function `ElfInfoCommand.invoke` @@ -5414,7 +5414,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ElfInfoCommand.post_load` @@ -5428,7 +5428,7 @@ post_load() → None --- - + ## function `ElfInfoCommand.pre_load` @@ -5442,7 +5442,7 @@ pre_load() → None --- - + ## function `ElfInfoCommand.usage` @@ -5469,7 +5469,7 @@ An enumeration. ## class `EntryBreakBreakpoint` Breakpoint used internally to stop execution at the most convenient entry point. - + ## function `EntryBreakBreakpoint.__init__` @@ -5486,7 +5486,7 @@ __init__(location: str) → None --- - + ## function `EntryBreakBreakpoint.stop` @@ -5504,7 +5504,7 @@ 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__` @@ -5527,7 +5527,7 @@ Return the list of settings for this command. --- - + ## function `EntryPointBreakCommand.add_setting` @@ -5543,7 +5543,7 @@ add_setting( --- - + ## function `EntryPointBreakCommand.del_setting` @@ -5555,7 +5555,7 @@ del_setting(name: str) → None --- - + ## function `EntryPointBreakCommand.do_invoke` @@ -5569,7 +5569,7 @@ do_invoke(argv: List) → None --- - + ## function `EntryPointBreakCommand.get_setting` @@ -5581,7 +5581,7 @@ get_setting(name) --- - + ## function `EntryPointBreakCommand.has_setting` @@ -5593,7 +5593,7 @@ has_setting(name: str) → bool --- - + ## function `EntryPointBreakCommand.invoke` @@ -5607,7 +5607,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `EntryPointBreakCommand.post_load` @@ -5621,7 +5621,7 @@ post_load() → None --- - + ## function `EntryPointBreakCommand.pre_load` @@ -5635,7 +5635,7 @@ pre_load() → None --- - + ## function `EntryPointBreakCommand.set_init_tbreak` @@ -5649,7 +5649,7 @@ set_init_tbreak(addr: int) → EntryBreakBreakpoint --- - + ## function `EntryPointBreakCommand.set_init_tbreak_pie` @@ -5663,7 +5663,7 @@ set_init_tbreak_pie(addr: int, argv: List[str]) → EntryBreakBreakpoint --- - + ## function `EntryPointBreakCommand.usage` @@ -5681,7 +5681,7 @@ usage() → None ## class `FlagsCommand` Edit flags in a human friendly way. - + ## function `FlagsCommand.__init__` @@ -5704,7 +5704,7 @@ Return the list of settings for this command. --- - + ## function `FlagsCommand.add_setting` @@ -5720,7 +5720,7 @@ add_setting( --- - + ## function `FlagsCommand.del_setting` @@ -5732,7 +5732,7 @@ del_setting(name: str) → None --- - + ## function `FlagsCommand.do_invoke` @@ -5746,7 +5746,7 @@ do_invoke(argv: List) → None --- - + ## function `FlagsCommand.get_setting` @@ -5758,7 +5758,7 @@ get_setting(name) --- - + ## function `FlagsCommand.has_setting` @@ -5770,7 +5770,7 @@ has_setting(name: str) → bool --- - + ## function `FlagsCommand.invoke` @@ -5784,7 +5784,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `FlagsCommand.post_load` @@ -5798,7 +5798,7 @@ post_load() → None --- - + ## function `FlagsCommand.pre_load` @@ -5812,7 +5812,7 @@ pre_load() → None --- - + ## function `FlagsCommand.usage` @@ -5830,7 +5830,7 @@ usage() → None ## class `FormatStringBreakpoint` Inspect stack for format string. - + ## function `FormatStringBreakpoint.__init__` @@ -5847,7 +5847,7 @@ __init__(spec: str, num_args: int) → None --- - + ## function `FormatStringBreakpoint.stop` @@ -5865,7 +5865,7 @@ 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__` @@ -5888,7 +5888,7 @@ Return the list of settings for this command. --- - + ## function `FormatStringSearchCommand.add_setting` @@ -5904,7 +5904,7 @@ add_setting( --- - + ## function `FormatStringSearchCommand.del_setting` @@ -5916,7 +5916,7 @@ del_setting(name: str) → None --- - + ## function `FormatStringSearchCommand.do_invoke` @@ -5930,7 +5930,7 @@ do_invoke(argv: List) → None --- - + ## function `FormatStringSearchCommand.get_setting` @@ -5942,7 +5942,7 @@ get_setting(name) --- - + ## function `FormatStringSearchCommand.has_setting` @@ -5954,7 +5954,7 @@ has_setting(name: str) → bool --- - + ## function `FormatStringSearchCommand.invoke` @@ -5968,7 +5968,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `FormatStringSearchCommand.post_load` @@ -5982,7 +5982,7 @@ post_load() → None --- - + ## function `FormatStringSearchCommand.pre_load` @@ -5996,7 +5996,7 @@ pre_load() → None --- - + ## function `FormatStringSearchCommand.usage` @@ -6021,7 +6021,7 @@ usage() → None --- - + ## function `GdbRemoveReadlineFinder.find_module` @@ -6035,7 +6035,7 @@ find_module(fullname, path=None) --- - + ## function `GdbRemoveReadlineFinder.load_module` @@ -6053,7 +6053,7 @@ load_module(fullname) ## class `Gef` The GEF root class, which serves as a base classe for all the attributes for the debugging session (architecture, memory, settings, etc.). - + ## function `Gef.__init__` @@ -6070,7 +6070,7 @@ __init__() → None --- - + ## function `Gef.reinitialize_managers` @@ -6082,7 +6082,7 @@ Reinitialize the managers. Avoid calling this function directly, using `pi reset --- - + ## function `Gef.reset_caches` @@ -6094,7 +6094,7 @@ Recursively clean the cache of all the managers. Avoid calling this function dir --- - + ## function `Gef.setup` @@ -6110,7 +6110,7 @@ Setup initialize the runtime setup, which may require for the `gef` to be not No ## class `GefAlias` Simple aliasing wrapper because GDB doesn't do what it should. - + ## function `GefAlias.__init__` @@ -6127,7 +6127,7 @@ __init__(alias, command, completer_class=0, command_class=-1) → None --- - + ## function `GefAlias.invoke` @@ -6141,7 +6141,7 @@ invoke(args, from_tty) → None --- - + ## function `GefAlias.lookup_command` @@ -6159,7 +6159,7 @@ lookup_command(cmd: str) → Union[Tuple[str, Type, Any], NoneType] ## class `GefCommand` GEF main command: view all new commands by typing `gef`. - + ## function `GefCommand.__init__` @@ -6184,7 +6184,7 @@ __init__() → None --- - + ## function `GefCommand.add_context_pane` @@ -6200,7 +6200,7 @@ Add a new context pane to ContextCommand. --- - + ## function `GefCommand.invoke` @@ -6214,7 +6214,7 @@ invoke(args, from_tty) → None --- - + ## function `GefCommand.load` @@ -6226,7 +6226,7 @@ Load all the commands and functions defined by GEF into GDB. --- - + ## function `GefCommand.setup` @@ -6244,7 +6244,7 @@ setup() → 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__` @@ -6261,7 +6261,7 @@ __init__(loaded_commands, *args, **kwargs) → None --- - + ## function `GefConfigCommand.complete` @@ -6275,7 +6275,7 @@ complete(text: str, word: str) → List[str] --- - + ## function `GefConfigCommand.invoke` @@ -6289,7 +6289,7 @@ invoke(args: str, from_tty) → None --- - + ## function `GefConfigCommand.print_setting` @@ -6303,7 +6303,7 @@ print_setting(plugin_name: str, verbose: bool = False) → None --- - + ## function `GefConfigCommand.print_settings` @@ -6317,7 +6317,7 @@ print_settings() → None --- - + ## function `GefConfigCommand.set_setting` @@ -6335,7 +6335,7 @@ set_setting(argv: Tuple[str, Any]) → None ## class `GefFunctionsCommand` List the convenience functions provided by GEF. - + ## function `GefFunctionsCommand.__init__` @@ -6358,7 +6358,7 @@ Return the list of settings for this command. --- - + ## function `GefFunctionsCommand.add_function_to_doc` @@ -6370,7 +6370,7 @@ Add function to documentation. --- - + ## function `GefFunctionsCommand.add_setting` @@ -6386,7 +6386,7 @@ add_setting( --- - + ## function `GefFunctionsCommand.del_setting` @@ -6398,7 +6398,7 @@ del_setting(name: str) → None --- - + ## function `GefFunctionsCommand.do_invoke` @@ -6412,7 +6412,7 @@ do_invoke(argv) → None --- - + ## function `GefFunctionsCommand.get_setting` @@ -6424,7 +6424,7 @@ get_setting(name) --- - + ## function `GefFunctionsCommand.has_setting` @@ -6436,7 +6436,7 @@ has_setting(name: str) → bool --- - + ## function `GefFunctionsCommand.invoke` @@ -6450,7 +6450,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GefFunctionsCommand.post_load` @@ -6464,7 +6464,7 @@ post_load() → None --- - + ## function `GefFunctionsCommand.pre_load` @@ -6478,7 +6478,7 @@ pre_load() → None --- - + ## function `GefFunctionsCommand.setup` @@ -6492,7 +6492,7 @@ setup() → None --- - + ## function `GefFunctionsCommand.usage` @@ -6510,7 +6510,7 @@ usage() → None ## class `GefHeapManager` Class managing session heap. - + ## function `GefHeapManager.__init__` @@ -6567,7 +6567,7 @@ __init__() → None --- - + ## function `GefHeapManager.reset_caches` @@ -6585,7 +6585,7 @@ reset_caches() → None ## class `GefHelpCommand` GEF help sub-command. - + ## function `GefHelpCommand.__init__` @@ -6602,7 +6602,7 @@ __init__(commands: List[Tuple[str, Any, Any]], *args, **kwargs) → None --- - + ## function `GefHelpCommand.add_command_to_doc` @@ -6614,7 +6614,7 @@ Add command to GEF documentation. --- - + ## function `GefHelpCommand.generate_help` @@ -6626,7 +6626,7 @@ Generate builtin commands documentation. --- - + ## function `GefHelpCommand.invoke` @@ -6640,7 +6640,7 @@ invoke(args, from_tty) → None --- - + ## function `GefHelpCommand.refresh` @@ -6663,7 +6663,7 @@ Refresh the documentation. --- - + ## function `GefManager.reset_caches` @@ -6679,7 +6679,7 @@ Reset the LRU-cached attributes ## class `GefMemoryManager` Class that manages memory access for gef. - + ## function `GefMemoryManager.__init__` @@ -6704,7 +6704,7 @@ __init__() → None --- - + ## function `GefMemoryManager.read` @@ -6716,7 +6716,7 @@ Return a `length` long byte array with the copy of the process memory at `addr`. --- - + ## function `GefMemoryManager.read_ascii_string` @@ -6728,7 +6728,7 @@ Read an ASCII string from memory --- - + ## function `GefMemoryManager.read_cstring` @@ -6744,7 +6744,7 @@ Return a C-string read from memory. --- - + ## function `GefMemoryManager.read_integer` @@ -6756,7 +6756,7 @@ Return an integer read from memory. --- - + ## function `GefMemoryManager.reset_caches` @@ -6770,7 +6770,7 @@ reset_caches() → None --- - + ## function `GefMemoryManager.write` @@ -6786,7 +6786,7 @@ 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__` @@ -6803,7 +6803,7 @@ __init__(*args, **kwargs) → None --- - + ## function `GefMissingCommand.invoke` @@ -6821,7 +6821,7 @@ invoke(args, from_tty) → None ## class `GefRestoreCommand` GEF restore sub-command. Loads settings from file '~/.gef.rc' and apply them to the configuration of GEF. - + ## function `GefRestoreCommand.__init__` @@ -6838,7 +6838,7 @@ __init__(*args, **kwargs) → None --- - + ## function `GefRestoreCommand.invoke` @@ -6856,7 +6856,7 @@ invoke(args: str, from_tty) → None ## 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__` @@ -6873,7 +6873,7 @@ __init__(*args, **kwargs) → None --- - + ## function `GefRunCommand.invoke` @@ -6891,7 +6891,7 @@ invoke(args, from_tty) → None ## class `GefSaveCommand` GEF save sub-command. Saves the current configuration of GEF to disk (by default in file '~/.gef.rc'). - + ## function `GefSaveCommand.__init__` @@ -6908,7 +6908,7 @@ __init__(*args, **kwargs) → None --- - + ## function `GefSaveCommand.invoke` @@ -6926,7 +6926,7 @@ invoke(args, from_tty) → None ## class `GefSessionManager` Class managing the runtime properties of GEF. - + ## function `GefSessionManager.__init__` @@ -6981,7 +6981,7 @@ Return the PID of the target process. --- - + ## function `GefSessionManager.reset_caches` @@ -6999,7 +6999,7 @@ reset_caches() → None ## class `GefSetCommand` Override GDB set commands with the context from GEF. - + ## function `GefSetCommand.__init__` @@ -7016,7 +7016,7 @@ __init__(*args, **kwargs) → None --- - + ## function `GefSetCommand.invoke` @@ -7034,7 +7034,7 @@ invoke(args, from_tty) → None ## class `GefSetting` Basic class for storing gef settings as objects - + ## function `GefSetting.__init__` @@ -7064,7 +7064,7 @@ GefSettings acts as a dict where the global settings are stored and can be read, --- - + ## function `GefSettingsManager.raw_entry` @@ -7082,7 +7082,7 @@ raw_entry(name: str) → Any ## class `GefThemeCommand` Customize GEF appearance. - + ## function `GefThemeCommand.__init__` @@ -7105,7 +7105,7 @@ Return the list of settings for this command. --- - + ## function `GefThemeCommand.add_setting` @@ -7121,7 +7121,7 @@ add_setting( --- - + ## function `GefThemeCommand.del_setting` @@ -7133,7 +7133,7 @@ del_setting(name: str) → None --- - + ## function `GefThemeCommand.do_invoke` @@ -7147,7 +7147,7 @@ do_invoke(args: List) → None --- - + ## function `GefThemeCommand.get_setting` @@ -7159,7 +7159,7 @@ get_setting(name) --- - + ## function `GefThemeCommand.has_setting` @@ -7171,7 +7171,7 @@ has_setting(name: str) → bool --- - + ## function `GefThemeCommand.invoke` @@ -7185,7 +7185,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GefThemeCommand.post_load` @@ -7199,7 +7199,7 @@ post_load() → None --- - + ## function `GefThemeCommand.pre_load` @@ -7213,7 +7213,7 @@ pre_load() → None --- - + ## function `GefThemeCommand.usage` @@ -7231,7 +7231,7 @@ usage() → None ## class `GefTmuxSetup` Setup a confortable tmux debugging environment. - + ## function `GefTmuxSetup.__init__` @@ -7248,7 +7248,7 @@ __init__() → None --- - + ## function `GefTmuxSetup.invoke` @@ -7262,7 +7262,7 @@ invoke(args, from_tty) → None --- - + ## function `GefTmuxSetup.screen_setup` @@ -7274,7 +7274,7 @@ Hackish equivalent of the tmux_setup() function for screen. --- - + ## function `GefTmuxSetup.tmux_setup` @@ -7290,7 +7290,7 @@ Prepare the tmux environment by vertically splitting the current pane, and forci ## class `GefUiManager` Class managing UI settings. - + ## function `GefUiManager.__init__` @@ -7307,7 +7307,7 @@ __init__() --- - + ## function `GefUiManager.reset_caches` @@ -7370,7 +7370,7 @@ Reset the LRU-cached attributes --- - + ## function `GenericArchitecture.flag_register_to_human` @@ -7384,7 +7384,7 @@ flag_register_to_human(val: Optional[int] = None) → Union[str, NoneType] --- - + ## function `GenericArchitecture.get_ith_parameter` @@ -7399,7 +7399,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `GenericArchitecture.get_ra` @@ -7413,7 +7413,7 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + ## function `GenericArchitecture.is_branch_taken` @@ -7427,7 +7427,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `GenericArchitecture.is_call` @@ -7441,7 +7441,7 @@ is_call(insn) → bool --- - + ## function `GenericArchitecture.is_conditional_branch` @@ -7455,7 +7455,7 @@ is_conditional_branch(insn) → bool --- - + ## function `GenericArchitecture.is_ret` @@ -7469,7 +7469,7 @@ is_ret(insn) → bool --- - + ## function `GenericArchitecture.register` @@ -7487,7 +7487,7 @@ register(name: str) → Union[int, NoneType] ## class `GenericCommand` This is an abstract class for invoking commands, should not be instantiated. - + ## function `GenericCommand.__init__` @@ -7510,7 +7510,7 @@ Return the list of settings for this command. --- - + ## function `GenericCommand.add_setting` @@ -7526,7 +7526,7 @@ add_setting( --- - + ## function `GenericCommand.del_setting` @@ -7538,7 +7538,7 @@ del_setting(name: str) → None --- - + ## function `GenericCommand.do_invoke` @@ -7552,7 +7552,7 @@ do_invoke(argv: List) → None --- - + ## function `GenericCommand.get_setting` @@ -7564,7 +7564,7 @@ get_setting(name) --- - + ## function `GenericCommand.has_setting` @@ -7576,7 +7576,7 @@ has_setting(name: str) → bool --- - + ## function `GenericCommand.invoke` @@ -7590,7 +7590,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GenericCommand.post_load` @@ -7604,7 +7604,7 @@ post_load() → None --- - + ## function `GenericCommand.pre_load` @@ -7618,7 +7618,7 @@ pre_load() → None --- - + ## function `GenericCommand.usage` @@ -7636,7 +7636,7 @@ usage() → None ## class `GenericFunction` This is an abstract class for invoking convenience functions, should not be instantiated. - + ## function `GenericFunction.__init__` @@ -7653,7 +7653,7 @@ __init__() → None --- - + ## function `GenericFunction.arg_to_long` @@ -7667,7 +7667,7 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + ## function `GenericFunction.do_invoke` @@ -7681,7 +7681,7 @@ do_invoke(args) → None --- - + ## function `GenericFunction.invoke` @@ -7699,7 +7699,7 @@ invoke(*args) → int ## class `GlibcArena` Glibc arena class Ref: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1671 - + ## function `GlibcArena.__init__` @@ -7716,7 +7716,7 @@ __init__(addr: str) → None --- - + ## function `GlibcArena.bin` @@ -7730,7 +7730,7 @@ bin(i: int) → Tuple[int, int] --- - + ## function `GlibcArena.fastbin` @@ -7742,7 +7742,7 @@ Return head chunk in fastbinsY[i]. --- - + ## function `GlibcArena.get_heap_for_ptr` @@ -7754,7 +7754,7 @@ Find the corresponding heap for a given pointer (int). See https://github.com/bm --- - + ## function `GlibcArena.get_heap_info_list` @@ -7768,7 +7768,7 @@ get_heap_info_list() --- - + ## function `GlibcArena.heap_addr` @@ -7782,7 +7782,7 @@ heap_addr(allow_unaligned: bool = False) → Union[int, NoneType] --- - + ## function `GlibcArena.is_main_arena` @@ -7800,7 +7800,7 @@ is_main_arena() → bool ## 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__` @@ -7865,7 +7865,7 @@ __init__(addr, from_base=False, allow_unaligned=True) --- - + ## function `GlibcChunk.flags_as_string` @@ -7879,7 +7879,7 @@ flags_as_string() → str --- - + ## function `GlibcChunk.get_bkw_ptr` @@ -7893,7 +7893,7 @@ get_bkw_ptr() → int --- - + ## function `GlibcChunk.get_chunk_size` @@ -7907,7 +7907,7 @@ get_chunk_size() → int --- - + ## function `GlibcChunk.get_fwd_ptr` @@ -7921,7 +7921,7 @@ get_fwd_ptr(sll) → int --- - + ## function `GlibcChunk.get_next_chunk` @@ -7935,7 +7935,7 @@ get_next_chunk(allow_unaligned: bool = False) --- - + ## function `GlibcChunk.get_next_chunk_addr` @@ -7949,7 +7949,7 @@ get_next_chunk_addr() → int --- - + ## function `GlibcChunk.get_prev_chunk_size` @@ -7963,7 +7963,7 @@ get_prev_chunk_size() → int --- - + ## function `GlibcChunk.get_usable_size` @@ -7977,7 +7977,7 @@ get_usable_size() → int --- - + ## function `GlibcChunk.has_m_bit` @@ -7991,7 +7991,7 @@ has_m_bit() → bool --- - + ## function `GlibcChunk.has_n_bit` @@ -8005,7 +8005,7 @@ has_n_bit() → bool --- - + ## function `GlibcChunk.has_p_bit` @@ -8019,7 +8019,7 @@ has_p_bit() → bool --- - + ## function `GlibcChunk.is_used` @@ -8033,7 +8033,7 @@ Check if the current block is used by: --- - + ## function `GlibcChunk.psprint` @@ -8047,7 +8047,7 @@ psprint() → str --- - + ## function `GlibcChunk.str_as_alloced` @@ -8061,7 +8061,7 @@ str_as_alloced() → str --- - + ## function `GlibcChunk.str_as_freed` @@ -8075,7 +8075,7 @@ str_as_freed() → str --- - + ## function `GlibcChunk.str_chunk_size_flag` @@ -8093,7 +8093,7 @@ str_chunk_size_flag() → str ## class `GlibcHeapArenaCommand` Display information on a heap chunk. - + ## function `GlibcHeapArenaCommand.__init__` @@ -8116,7 +8116,7 @@ Return the list of settings for this command. --- - + ## function `GlibcHeapArenaCommand.add_setting` @@ -8132,7 +8132,7 @@ add_setting( --- - + ## function `GlibcHeapArenaCommand.del_setting` @@ -8144,7 +8144,7 @@ del_setting(name: str) → None --- - + ## function `GlibcHeapArenaCommand.do_invoke` @@ -8158,7 +8158,7 @@ do_invoke(argv: List) → None --- - + ## function `GlibcHeapArenaCommand.get_setting` @@ -8170,7 +8170,7 @@ get_setting(name) --- - + ## function `GlibcHeapArenaCommand.has_setting` @@ -8182,7 +8182,7 @@ has_setting(name: str) → bool --- - + ## function `GlibcHeapArenaCommand.invoke` @@ -8196,7 +8196,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GlibcHeapArenaCommand.post_load` @@ -8210,7 +8210,7 @@ post_load() → None --- - + ## function `GlibcHeapArenaCommand.pre_load` @@ -8224,7 +8224,7 @@ pre_load() → None --- - + ## function `GlibcHeapArenaCommand.usage` @@ -8242,7 +8242,7 @@ 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__` @@ -8265,7 +8265,7 @@ Return the list of settings for this command. --- - + ## function `GlibcHeapBinsCommand.add_setting` @@ -8281,7 +8281,7 @@ add_setting( --- - + ## function `GlibcHeapBinsCommand.del_setting` @@ -8293,7 +8293,7 @@ del_setting(name: str) → None --- - + ## function `GlibcHeapBinsCommand.do_invoke` @@ -8307,7 +8307,7 @@ do_invoke(argv: List) → None --- - + ## function `GlibcHeapBinsCommand.get_setting` @@ -8319,7 +8319,7 @@ get_setting(name) --- - + ## function `GlibcHeapBinsCommand.has_setting` @@ -8331,7 +8331,7 @@ has_setting(name: str) → bool --- - + ## function `GlibcHeapBinsCommand.invoke` @@ -8345,7 +8345,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GlibcHeapBinsCommand.post_load` @@ -8359,7 +8359,7 @@ post_load() → None --- - + ## function `GlibcHeapBinsCommand.pprint_bin` @@ -8373,7 +8373,7 @@ pprint_bin(arena_addr: str, index: int, _type: str = '') → int --- - + ## function `GlibcHeapBinsCommand.pre_load` @@ -8387,7 +8387,7 @@ pre_load() → None --- - + ## function `GlibcHeapBinsCommand.usage` @@ -8405,7 +8405,7 @@ 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__` @@ -8428,7 +8428,7 @@ Return the list of settings for this command. --- - + ## function `GlibcHeapChunkCommand.add_setting` @@ -8444,7 +8444,7 @@ add_setting( --- - + ## function `GlibcHeapChunkCommand.del_setting` @@ -8456,7 +8456,7 @@ del_setting(name: str) → None --- - + ## function `GlibcHeapChunkCommand.wrapper` @@ -8470,7 +8470,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `GlibcHeapChunkCommand.get_setting` @@ -8482,7 +8482,7 @@ get_setting(name) --- - + ## function `GlibcHeapChunkCommand.has_setting` @@ -8494,7 +8494,7 @@ has_setting(name: str) → bool --- - + ## function `GlibcHeapChunkCommand.invoke` @@ -8508,7 +8508,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GlibcHeapChunkCommand.post_load` @@ -8522,7 +8522,7 @@ post_load() → None --- - + ## function `GlibcHeapChunkCommand.pre_load` @@ -8536,7 +8536,7 @@ pre_load() → None --- - + ## function `GlibcHeapChunkCommand.usage` @@ -8554,7 +8554,7 @@ 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__` @@ -8577,7 +8577,7 @@ Return the list of settings for this command. --- - + ## function `GlibcHeapChunksCommand.add_setting` @@ -8593,7 +8593,7 @@ add_setting( --- - + ## function `GlibcHeapChunksCommand.del_setting` @@ -8605,7 +8605,7 @@ del_setting(name: str) → None --- - + ## function `GlibcHeapChunksCommand.wrapper` @@ -8619,7 +8619,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `GlibcHeapChunksCommand.dump_chunks_arena` @@ -8637,7 +8637,7 @@ dump_chunks_arena( --- - + ## function `GlibcHeapChunksCommand.dump_chunks_heap` @@ -8656,7 +8656,7 @@ dump_chunks_heap( --- - + ## function `GlibcHeapChunksCommand.get_setting` @@ -8668,7 +8668,7 @@ get_setting(name) --- - + ## function `GlibcHeapChunksCommand.has_setting` @@ -8680,7 +8680,7 @@ has_setting(name: str) → bool --- - + ## function `GlibcHeapChunksCommand.invoke` @@ -8694,7 +8694,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GlibcHeapChunksCommand.post_load` @@ -8708,7 +8708,7 @@ post_load() → None --- - + ## function `GlibcHeapChunksCommand.pre_load` @@ -8722,7 +8722,7 @@ pre_load() → None --- - + ## function `GlibcHeapChunksCommand.usage` @@ -8740,7 +8740,7 @@ usage() → None ## class `GlibcHeapCommand` Base command to get information about the Glibc heap structure. - + ## function `GlibcHeapCommand.__init__` @@ -8763,7 +8763,7 @@ Return the list of settings for this command. --- - + ## function `GlibcHeapCommand.add_setting` @@ -8779,7 +8779,7 @@ add_setting( --- - + ## function `GlibcHeapCommand.del_setting` @@ -8791,7 +8791,7 @@ del_setting(name: str) → None --- - + ## function `GlibcHeapCommand.do_invoke` @@ -8805,7 +8805,7 @@ do_invoke(argv: List) → None --- - + ## function `GlibcHeapCommand.get_setting` @@ -8817,7 +8817,7 @@ get_setting(name) --- - + ## function `GlibcHeapCommand.has_setting` @@ -8829,7 +8829,7 @@ has_setting(name: str) → bool --- - + ## function `GlibcHeapCommand.invoke` @@ -8843,7 +8843,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GlibcHeapCommand.post_load` @@ -8857,7 +8857,7 @@ post_load() → None --- - + ## function `GlibcHeapCommand.pre_load` @@ -8871,7 +8871,7 @@ pre_load() → None --- - + ## function `GlibcHeapCommand.usage` @@ -8889,7 +8889,7 @@ 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__` @@ -8912,7 +8912,7 @@ Return the list of settings for this command. --- - + ## function `GlibcHeapFastbinsYCommand.add_setting` @@ -8928,7 +8928,7 @@ add_setting( --- - + ## function `GlibcHeapFastbinsYCommand.del_setting` @@ -8940,7 +8940,7 @@ del_setting(name: str) → None --- - + ## function `GlibcHeapFastbinsYCommand.do_invoke` @@ -8954,7 +8954,7 @@ do_invoke(argv: List) → None --- - + ## function `GlibcHeapFastbinsYCommand.get_setting` @@ -8966,7 +8966,7 @@ get_setting(name) --- - + ## function `GlibcHeapFastbinsYCommand.has_setting` @@ -8978,7 +8978,7 @@ has_setting(name: str) → bool --- - + ## function `GlibcHeapFastbinsYCommand.invoke` @@ -8992,7 +8992,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GlibcHeapFastbinsYCommand.post_load` @@ -9006,7 +9006,7 @@ post_load() → None --- - + ## function `GlibcHeapFastbinsYCommand.pre_load` @@ -9020,7 +9020,7 @@ pre_load() → None --- - + ## function `GlibcHeapFastbinsYCommand.usage` @@ -9038,7 +9038,7 @@ usage() → None ## class `GlibcHeapInfo` Glibc heap_info struct See https://github.com/bminor/glibc/blob/glibc-2.34/malloc/arena.c#L64 - + ## function `GlibcHeapInfo.__init__` @@ -9131,7 +9131,7 @@ __init__(addr) → None ## class `GlibcHeapLargeBinsCommand` Convenience command for viewing large bins. - + ## function `GlibcHeapLargeBinsCommand.__init__` @@ -9154,7 +9154,7 @@ Return the list of settings for this command. --- - + ## function `GlibcHeapLargeBinsCommand.add_setting` @@ -9170,7 +9170,7 @@ add_setting( --- - + ## function `GlibcHeapLargeBinsCommand.del_setting` @@ -9182,7 +9182,7 @@ del_setting(name: str) → None --- - + ## function `GlibcHeapLargeBinsCommand.do_invoke` @@ -9196,7 +9196,7 @@ do_invoke(argv: List) → None --- - + ## function `GlibcHeapLargeBinsCommand.get_setting` @@ -9208,7 +9208,7 @@ get_setting(name) --- - + ## function `GlibcHeapLargeBinsCommand.has_setting` @@ -9220,7 +9220,7 @@ has_setting(name: str) → bool --- - + ## function `GlibcHeapLargeBinsCommand.invoke` @@ -9234,7 +9234,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GlibcHeapLargeBinsCommand.post_load` @@ -9248,7 +9248,7 @@ post_load() → None --- - + ## function `GlibcHeapLargeBinsCommand.pre_load` @@ -9262,7 +9262,7 @@ pre_load() → None --- - + ## function `GlibcHeapLargeBinsCommand.usage` @@ -9280,7 +9280,7 @@ usage() → None ## class `GlibcHeapSetArenaCommand` Display information on a heap chunk. - + ## function `GlibcHeapSetArenaCommand.__init__` @@ -9303,7 +9303,7 @@ Return the list of settings for this command. --- - + ## function `GlibcHeapSetArenaCommand.add_setting` @@ -9319,7 +9319,7 @@ add_setting( --- - + ## function `GlibcHeapSetArenaCommand.del_setting` @@ -9331,7 +9331,7 @@ del_setting(name: str) → None --- - + ## function `GlibcHeapSetArenaCommand.do_invoke` @@ -9345,7 +9345,7 @@ do_invoke(argv: List) → None --- - + ## function `GlibcHeapSetArenaCommand.get_setting` @@ -9357,7 +9357,7 @@ get_setting(name) --- - + ## function `GlibcHeapSetArenaCommand.has_setting` @@ -9369,7 +9369,7 @@ has_setting(name: str) → bool --- - + ## function `GlibcHeapSetArenaCommand.invoke` @@ -9383,7 +9383,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GlibcHeapSetArenaCommand.post_load` @@ -9397,7 +9397,7 @@ post_load() → None --- - + ## function `GlibcHeapSetArenaCommand.pre_load` @@ -9411,7 +9411,7 @@ pre_load() → None --- - + ## function `GlibcHeapSetArenaCommand.usage` @@ -9429,7 +9429,7 @@ usage() → None ## class `GlibcHeapSmallBinsCommand` Convenience command for viewing small bins. - + ## function `GlibcHeapSmallBinsCommand.__init__` @@ -9452,7 +9452,7 @@ Return the list of settings for this command. --- - + ## function `GlibcHeapSmallBinsCommand.add_setting` @@ -9468,7 +9468,7 @@ add_setting( --- - + ## function `GlibcHeapSmallBinsCommand.del_setting` @@ -9480,7 +9480,7 @@ del_setting(name: str) → None --- - + ## function `GlibcHeapSmallBinsCommand.do_invoke` @@ -9494,7 +9494,7 @@ do_invoke(argv: List) → None --- - + ## function `GlibcHeapSmallBinsCommand.get_setting` @@ -9506,7 +9506,7 @@ get_setting(name) --- - + ## function `GlibcHeapSmallBinsCommand.has_setting` @@ -9518,7 +9518,7 @@ has_setting(name: str) → bool --- - + ## function `GlibcHeapSmallBinsCommand.invoke` @@ -9532,7 +9532,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GlibcHeapSmallBinsCommand.post_load` @@ -9546,7 +9546,7 @@ post_load() → None --- - + ## function `GlibcHeapSmallBinsCommand.pre_load` @@ -9560,7 +9560,7 @@ pre_load() → None --- - + ## function `GlibcHeapSmallBinsCommand.usage` @@ -9578,7 +9578,7 @@ 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__` @@ -9601,7 +9601,7 @@ Return the list of settings for this command. --- - + ## function `GlibcHeapTcachebinsCommand.add_setting` @@ -9617,7 +9617,7 @@ add_setting( --- - + ## function `GlibcHeapTcachebinsCommand.check_thread_ids` @@ -9629,7 +9629,7 @@ Check the validity, dedup, and return all valid tids. --- - + ## function `GlibcHeapTcachebinsCommand.del_setting` @@ -9641,7 +9641,7 @@ del_setting(name: str) → None --- - + ## function `GlibcHeapTcachebinsCommand.do_invoke` @@ -9655,7 +9655,7 @@ do_invoke(argv: List) → None --- - + ## function `GlibcHeapTcachebinsCommand.find_tcache` @@ -9667,7 +9667,7 @@ Return the location of the current thread's tcache. --- - + ## function `GlibcHeapTcachebinsCommand.get_setting` @@ -9679,7 +9679,7 @@ get_setting(name) --- - + ## function `GlibcHeapTcachebinsCommand.has_setting` @@ -9691,7 +9691,7 @@ has_setting(name: str) → bool --- - + ## function `GlibcHeapTcachebinsCommand.invoke` @@ -9705,7 +9705,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GlibcHeapTcachebinsCommand.post_load` @@ -9719,7 +9719,7 @@ post_load() → None --- - + ## function `GlibcHeapTcachebinsCommand.pre_load` @@ -9733,7 +9733,7 @@ pre_load() → None --- - + ## function `GlibcHeapTcachebinsCommand.tcachebin` @@ -9748,7 +9748,7 @@ Return the head chunk in tcache[i] and the number of chunks in the bin. --- - + ## function `GlibcHeapTcachebinsCommand.usage` @@ -9766,7 +9766,7 @@ 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__` @@ -9789,7 +9789,7 @@ Return the list of settings for this command. --- - + ## function `GlibcHeapUnsortedBinsCommand.add_setting` @@ -9805,7 +9805,7 @@ add_setting( --- - + ## function `GlibcHeapUnsortedBinsCommand.del_setting` @@ -9817,7 +9817,7 @@ del_setting(name: str) → None --- - + ## function `GlibcHeapUnsortedBinsCommand.do_invoke` @@ -9831,7 +9831,7 @@ do_invoke(argv: List) → None --- - + ## function `GlibcHeapUnsortedBinsCommand.get_setting` @@ -9843,7 +9843,7 @@ get_setting(name) --- - + ## function `GlibcHeapUnsortedBinsCommand.has_setting` @@ -9855,7 +9855,7 @@ has_setting(name: str) → bool --- - + ## function `GlibcHeapUnsortedBinsCommand.invoke` @@ -9869,7 +9869,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GlibcHeapUnsortedBinsCommand.post_load` @@ -9883,7 +9883,7 @@ post_load() → None --- - + ## function `GlibcHeapUnsortedBinsCommand.pre_load` @@ -9897,7 +9897,7 @@ pre_load() → None --- - + ## function `GlibcHeapUnsortedBinsCommand.usage` @@ -9915,7 +9915,7 @@ usage() → None ## class `GotBaseFunction` Return the current bss base address plus the given offset. - + ## function `GotBaseFunction.__init__` @@ -9932,7 +9932,7 @@ __init__() → None --- - + ## function `GotBaseFunction.arg_to_long` @@ -9946,7 +9946,7 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + ## function `GotBaseFunction.do_invoke` @@ -9960,7 +9960,7 @@ do_invoke(args: List) → int --- - + ## function `GotBaseFunction.invoke` @@ -9978,7 +9978,7 @@ invoke(*args) → int ## class `GotCommand` Display current status of the got inside the process. - + ## function `GotCommand.__init__` @@ -10001,7 +10001,7 @@ Return the list of settings for this command. --- - + ## function `GotCommand.add_setting` @@ -10017,7 +10017,7 @@ add_setting( --- - + ## function `GotCommand.del_setting` @@ -10029,7 +10029,7 @@ del_setting(name: str) → None --- - + ## function `GotCommand.do_invoke` @@ -10043,7 +10043,7 @@ do_invoke(argv: List) → None --- - + ## function `GotCommand.get_jmp_slots` @@ -10057,7 +10057,7 @@ get_jmp_slots(readelf: str, filename: str) → List[str] --- - + ## function `GotCommand.get_setting` @@ -10069,7 +10069,7 @@ get_setting(name) --- - + ## function `GotCommand.has_setting` @@ -10081,7 +10081,7 @@ has_setting(name: str) → bool --- - + ## function `GotCommand.invoke` @@ -10095,7 +10095,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `GotCommand.post_load` @@ -10109,7 +10109,7 @@ post_load() → None --- - + ## function `GotCommand.pre_load` @@ -10123,7 +10123,7 @@ pre_load() → None --- - + ## function `GotCommand.usage` @@ -10145,7 +10145,7 @@ Heap vulnerability analysis helper: this command aims to track dynamic heap allo - Double Free - Heap overlap - + ## function `HeapAnalysisCommand.__init__` @@ -10168,7 +10168,7 @@ Return the list of settings for this command. --- - + ## function `HeapAnalysisCommand.add_setting` @@ -10184,7 +10184,7 @@ add_setting( --- - + ## function `HeapAnalysisCommand.clean` @@ -10198,7 +10198,7 @@ clean(_) → None --- - + ## function `HeapAnalysisCommand.del_setting` @@ -10210,7 +10210,7 @@ del_setting(name: str) → None --- - + ## function `HeapAnalysisCommand.do_invoke` @@ -10224,7 +10224,7 @@ do_invoke(argv: List) → None --- - + ## function `HeapAnalysisCommand.dump_tracked_allocations` @@ -10238,7 +10238,7 @@ dump_tracked_allocations() → None --- - + ## function `HeapAnalysisCommand.get_setting` @@ -10250,7 +10250,7 @@ get_setting(name) --- - + ## function `HeapAnalysisCommand.has_setting` @@ -10262,7 +10262,7 @@ has_setting(name: str) → bool --- - + ## function `HeapAnalysisCommand.invoke` @@ -10276,7 +10276,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `HeapAnalysisCommand.post_load` @@ -10290,7 +10290,7 @@ post_load() → None --- - + ## function `HeapAnalysisCommand.pre_load` @@ -10304,7 +10304,7 @@ pre_load() → None --- - + ## function `HeapAnalysisCommand.setup` @@ -10318,7 +10318,7 @@ setup() → None --- - + ## function `HeapAnalysisCommand.usage` @@ -10336,7 +10336,7 @@ usage() → None ## class `HeapBaseFunction` Return the current heap base address plus an optional offset. - + ## function `HeapBaseFunction.__init__` @@ -10353,7 +10353,7 @@ __init__() → None --- - + ## function `HeapBaseFunction.arg_to_long` @@ -10367,7 +10367,7 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + ## function `HeapBaseFunction.do_invoke` @@ -10381,7 +10381,7 @@ do_invoke(args: List) → int --- - + ## function `HeapBaseFunction.invoke` @@ -10399,7 +10399,7 @@ invoke(*args) → int ## class `HexdumpByteCommand` Display SIZE lines of hexdump as BYTE from the memory location pointed by ADDRESS. - + ## function `HexdumpByteCommand.__init__` @@ -10422,7 +10422,7 @@ Return the list of settings for this command. --- - + ## function `HexdumpByteCommand.add_setting` @@ -10438,7 +10438,7 @@ add_setting( --- - + ## function `HexdumpByteCommand.del_setting` @@ -10450,7 +10450,7 @@ del_setting(name: str) → None --- - + ## function `HexdumpByteCommand.wrapper` @@ -10464,7 +10464,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `HexdumpByteCommand.get_setting` @@ -10476,7 +10476,7 @@ get_setting(name) --- - + ## function `HexdumpByteCommand.has_setting` @@ -10488,7 +10488,7 @@ has_setting(name: str) → bool --- - + ## function `HexdumpByteCommand.invoke` @@ -10502,7 +10502,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `HexdumpByteCommand.post_load` @@ -10516,7 +10516,7 @@ post_load() → None --- - + ## function `HexdumpByteCommand.pre_load` @@ -10530,7 +10530,7 @@ pre_load() → None --- - + ## function `HexdumpByteCommand.usage` @@ -10548,7 +10548,7 @@ usage() → None ## class `HexdumpCommand` Display SIZE lines of hexdump from the memory location pointed by LOCATION. - + ## function `HexdumpCommand.__init__` @@ -10571,7 +10571,7 @@ Return the list of settings for this command. --- - + ## function `HexdumpCommand.add_setting` @@ -10587,7 +10587,7 @@ add_setting( --- - + ## function `HexdumpCommand.del_setting` @@ -10599,7 +10599,7 @@ del_setting(name: str) → None --- - + ## function `HexdumpCommand.wrapper` @@ -10613,7 +10613,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `HexdumpCommand.get_setting` @@ -10625,7 +10625,7 @@ get_setting(name) --- - + ## function `HexdumpCommand.has_setting` @@ -10637,7 +10637,7 @@ has_setting(name: str) → bool --- - + ## function `HexdumpCommand.invoke` @@ -10651,7 +10651,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `HexdumpCommand.post_load` @@ -10665,7 +10665,7 @@ post_load() → None --- - + ## function `HexdumpCommand.pre_load` @@ -10679,7 +10679,7 @@ pre_load() → None --- - + ## function `HexdumpCommand.usage` @@ -10697,7 +10697,7 @@ usage() → None ## class `HexdumpDwordCommand` Display SIZE lines of hexdump as DWORD from the memory location pointed by ADDRESS. - + ## function `HexdumpDwordCommand.__init__` @@ -10720,7 +10720,7 @@ Return the list of settings for this command. --- - + ## function `HexdumpDwordCommand.add_setting` @@ -10736,7 +10736,7 @@ add_setting( --- - + ## function `HexdumpDwordCommand.del_setting` @@ -10748,7 +10748,7 @@ del_setting(name: str) → None --- - + ## function `HexdumpDwordCommand.wrapper` @@ -10762,7 +10762,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `HexdumpDwordCommand.get_setting` @@ -10774,7 +10774,7 @@ get_setting(name) --- - + ## function `HexdumpDwordCommand.has_setting` @@ -10786,7 +10786,7 @@ has_setting(name: str) → bool --- - + ## function `HexdumpDwordCommand.invoke` @@ -10800,7 +10800,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `HexdumpDwordCommand.post_load` @@ -10814,7 +10814,7 @@ post_load() → None --- - + ## function `HexdumpDwordCommand.pre_load` @@ -10828,7 +10828,7 @@ pre_load() → None --- - + ## function `HexdumpDwordCommand.usage` @@ -10846,7 +10846,7 @@ usage() → None ## class `HexdumpQwordCommand` Display SIZE lines of hexdump as QWORD from the memory location pointed by ADDRESS. - + ## function `HexdumpQwordCommand.__init__` @@ -10869,7 +10869,7 @@ Return the list of settings for this command. --- - + ## function `HexdumpQwordCommand.add_setting` @@ -10885,7 +10885,7 @@ add_setting( --- - + ## function `HexdumpQwordCommand.del_setting` @@ -10897,7 +10897,7 @@ del_setting(name: str) → None --- - + ## function `HexdumpQwordCommand.wrapper` @@ -10911,7 +10911,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `HexdumpQwordCommand.get_setting` @@ -10923,7 +10923,7 @@ get_setting(name) --- - + ## function `HexdumpQwordCommand.has_setting` @@ -10935,7 +10935,7 @@ has_setting(name: str) → bool --- - + ## function `HexdumpQwordCommand.invoke` @@ -10949,7 +10949,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `HexdumpQwordCommand.post_load` @@ -10963,7 +10963,7 @@ post_load() → None --- - + ## function `HexdumpQwordCommand.pre_load` @@ -10977,7 +10977,7 @@ pre_load() → None --- - + ## function `HexdumpQwordCommand.usage` @@ -10995,7 +10995,7 @@ usage() → None ## class `HexdumpWordCommand` Display SIZE lines of hexdump as WORD from the memory location pointed by ADDRESS. - + ## function `HexdumpWordCommand.__init__` @@ -11018,7 +11018,7 @@ Return the list of settings for this command. --- - + ## function `HexdumpWordCommand.add_setting` @@ -11034,7 +11034,7 @@ add_setting( --- - + ## function `HexdumpWordCommand.del_setting` @@ -11046,7 +11046,7 @@ del_setting(name: str) → None --- - + ## function `HexdumpWordCommand.wrapper` @@ -11060,7 +11060,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `HexdumpWordCommand.get_setting` @@ -11072,7 +11072,7 @@ get_setting(name) --- - + ## function `HexdumpWordCommand.has_setting` @@ -11084,7 +11084,7 @@ has_setting(name: str) → bool --- - + ## function `HexdumpWordCommand.invoke` @@ -11098,7 +11098,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `HexdumpWordCommand.post_load` @@ -11112,7 +11112,7 @@ post_load() → None --- - + ## function `HexdumpWordCommand.pre_load` @@ -11126,7 +11126,7 @@ pre_load() → None --- - + ## function `HexdumpWordCommand.usage` @@ -11144,7 +11144,7 @@ usage() → None ## class `HighlightAddCommand` Add a match to the highlight table. - + ## function `HighlightAddCommand.__init__` @@ -11167,7 +11167,7 @@ Return the list of settings for this command. --- - + ## function `HighlightAddCommand.add_setting` @@ -11183,7 +11183,7 @@ add_setting( --- - + ## function `HighlightAddCommand.del_setting` @@ -11195,7 +11195,7 @@ del_setting(name: str) → None --- - + ## function `HighlightAddCommand.do_invoke` @@ -11209,7 +11209,7 @@ do_invoke(argv: List) → None --- - + ## function `HighlightAddCommand.get_setting` @@ -11221,7 +11221,7 @@ get_setting(name) --- - + ## function `HighlightAddCommand.has_setting` @@ -11233,7 +11233,7 @@ has_setting(name: str) → bool --- - + ## function `HighlightAddCommand.invoke` @@ -11247,7 +11247,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `HighlightAddCommand.post_load` @@ -11261,7 +11261,7 @@ post_load() → None --- - + ## function `HighlightAddCommand.pre_load` @@ -11275,7 +11275,7 @@ pre_load() → None --- - + ## function `HighlightAddCommand.usage` @@ -11293,7 +11293,7 @@ usage() → None ## class `HighlightClearCommand` Clear the highlight table, remove all matches. - + ## function `HighlightClearCommand.__init__` @@ -11316,7 +11316,7 @@ Return the list of settings for this command. --- - + ## function `HighlightClearCommand.add_setting` @@ -11332,7 +11332,7 @@ add_setting( --- - + ## function `HighlightClearCommand.del_setting` @@ -11344,7 +11344,7 @@ del_setting(name: str) → None --- - + ## function `HighlightClearCommand.do_invoke` @@ -11358,7 +11358,7 @@ do_invoke(argv: List) → None --- - + ## function `HighlightClearCommand.get_setting` @@ -11370,7 +11370,7 @@ get_setting(name) --- - + ## function `HighlightClearCommand.has_setting` @@ -11382,7 +11382,7 @@ has_setting(name: str) → bool --- - + ## function `HighlightClearCommand.invoke` @@ -11396,7 +11396,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `HighlightClearCommand.post_load` @@ -11410,7 +11410,7 @@ post_load() → None --- - + ## function `HighlightClearCommand.pre_load` @@ -11424,7 +11424,7 @@ pre_load() → None --- - + ## function `HighlightClearCommand.usage` @@ -11442,7 +11442,7 @@ usage() → None ## class `HighlightCommand` Highlight user-defined text matches in GEF output universally. - + ## function `HighlightCommand.__init__` @@ -11465,7 +11465,7 @@ Return the list of settings for this command. --- - + ## function `HighlightCommand.add_setting` @@ -11481,7 +11481,7 @@ add_setting( --- - + ## function `HighlightCommand.del_setting` @@ -11493,7 +11493,7 @@ del_setting(name: str) → None --- - + ## function `HighlightCommand.do_invoke` @@ -11507,7 +11507,7 @@ do_invoke(argv: List) → None --- - + ## function `HighlightCommand.get_setting` @@ -11519,7 +11519,7 @@ get_setting(name) --- - + ## function `HighlightCommand.has_setting` @@ -11531,7 +11531,7 @@ has_setting(name: str) → bool --- - + ## function `HighlightCommand.invoke` @@ -11545,7 +11545,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `HighlightCommand.post_load` @@ -11559,7 +11559,7 @@ post_load() → None --- - + ## function `HighlightCommand.pre_load` @@ -11573,7 +11573,7 @@ pre_load() → None --- - + ## function `HighlightCommand.usage` @@ -11591,7 +11591,7 @@ usage() → None ## class `HighlightListCommand` Show the current highlight table with matches to colors. - + ## function `HighlightListCommand.__init__` @@ -11614,7 +11614,7 @@ Return the list of settings for this command. --- - + ## function `HighlightListCommand.add_setting` @@ -11630,7 +11630,7 @@ add_setting( --- - + ## function `HighlightListCommand.del_setting` @@ -11642,7 +11642,7 @@ del_setting(name: str) → None --- - + ## function `HighlightListCommand.do_invoke` @@ -11656,7 +11656,7 @@ do_invoke(argv: List) → None --- - + ## function `HighlightListCommand.get_setting` @@ -11668,7 +11668,7 @@ get_setting(name) --- - + ## function `HighlightListCommand.has_setting` @@ -11680,7 +11680,7 @@ has_setting(name: str) → bool --- - + ## function `HighlightListCommand.invoke` @@ -11694,7 +11694,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `HighlightListCommand.post_load` @@ -11708,7 +11708,7 @@ post_load() → None --- - + ## function `HighlightListCommand.pre_load` @@ -11722,7 +11722,7 @@ pre_load() → None --- - + ## function `HighlightListCommand.print_highlight_table` @@ -11736,7 +11736,7 @@ print_highlight_table() → None --- - + ## function `HighlightListCommand.usage` @@ -11754,7 +11754,7 @@ usage() → None ## class `HighlightRemoveCommand` Remove a match in the highlight table. - + ## function `HighlightRemoveCommand.__init__` @@ -11777,7 +11777,7 @@ Return the list of settings for this command. --- - + ## function `HighlightRemoveCommand.add_setting` @@ -11793,7 +11793,7 @@ add_setting( --- - + ## function `HighlightRemoveCommand.del_setting` @@ -11805,7 +11805,7 @@ del_setting(name: str) → None --- - + ## function `HighlightRemoveCommand.do_invoke` @@ -11819,7 +11819,7 @@ do_invoke(argv: List) → None --- - + ## function `HighlightRemoveCommand.get_setting` @@ -11831,7 +11831,7 @@ get_setting(name) --- - + ## function `HighlightRemoveCommand.has_setting` @@ -11843,7 +11843,7 @@ has_setting(name: str) → bool --- - + ## function `HighlightRemoveCommand.invoke` @@ -11857,7 +11857,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `HighlightRemoveCommand.post_load` @@ -11871,7 +11871,7 @@ post_load() → None --- - + ## function `HighlightRemoveCommand.pre_load` @@ -11885,7 +11885,7 @@ pre_load() → None --- - + ## function `HighlightRemoveCommand.usage` @@ -11903,7 +11903,7 @@ usage() → None ## class `IdaInteractCommand` IDA Interact: set of commands to interact with IDA via a XML RPC service deployed via the IDA script `ida_gef.py`. It should be noted that this command can also be used to interact with Binary Ninja (using the script `binja_gef.py`) using the same interface. - + ## function `IdaInteractCommand.__init__` @@ -11926,7 +11926,7 @@ Return the list of settings for this command. --- - + ## function `IdaInteractCommand.add_setting` @@ -11942,7 +11942,7 @@ add_setting( --- - + ## function `IdaInteractCommand.connect` @@ -11954,7 +11954,7 @@ Connect to the XML-RPC service. --- - + ## function `IdaInteractCommand.del_setting` @@ -11966,7 +11966,7 @@ del_setting(name: str) → None --- - + ## function `IdaInteractCommand.disconnect` @@ -11980,7 +11980,7 @@ disconnect() → None --- - + ## function `IdaInteractCommand.do_invoke` @@ -11992,7 +11992,7 @@ do_invoke(argv: List) → None --- - + ## function `IdaInteractCommand.get_setting` @@ -12004,7 +12004,7 @@ get_setting(name) --- - + ## function `IdaInteractCommand.has_setting` @@ -12016,7 +12016,7 @@ has_setting(name: str) → bool --- - + ## function `IdaInteractCommand.import_structures` @@ -12030,7 +12030,7 @@ import_structures(structs: Dict[str, List[Tuple[int, str, int]]]) → None --- - + ## function `IdaInteractCommand.invoke` @@ -12044,7 +12044,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `IdaInteractCommand.is_target_alive` @@ -12058,7 +12058,7 @@ is_target_alive(host: str, port: int) → bool --- - + ## function `IdaInteractCommand.post_load` @@ -12072,7 +12072,7 @@ post_load() → None --- - + ## function `IdaInteractCommand.pre_load` @@ -12086,7 +12086,7 @@ pre_load() → None --- - + ## function `IdaInteractCommand.synchronize` @@ -12098,7 +12098,7 @@ Submit all active breakpoint addresses to IDA/BN. --- - + ## function `IdaInteractCommand.usage` @@ -12116,7 +12116,7 @@ usage(meth: Optional[str] = None) → None ## class `Instruction` GEF representation of a CPU instruction. - + ## function `Instruction.__init__` @@ -12133,7 +12133,7 @@ __init__(address: int, location, mnemo: str, operands, opcodes) → None --- - + ## function `Instruction.is_valid` @@ -12151,7 +12151,7 @@ is_valid() → bool ## class `IsSyscallCommand` Tells whether the next instruction is a system call. - + ## function `IsSyscallCommand.__init__` @@ -12174,7 +12174,7 @@ Return the list of settings for this command. --- - + ## function `IsSyscallCommand.add_setting` @@ -12190,7 +12190,7 @@ add_setting( --- - + ## function `IsSyscallCommand.del_setting` @@ -12202,7 +12202,7 @@ del_setting(name: str) → None --- - + ## function `IsSyscallCommand.do_invoke` @@ -12216,7 +12216,7 @@ do_invoke(argv: List) → None --- - + ## function `IsSyscallCommand.get_setting` @@ -12228,7 +12228,7 @@ get_setting(name) --- - + ## function `IsSyscallCommand.has_setting` @@ -12240,7 +12240,7 @@ has_setting(name: str) → bool --- - + ## function `IsSyscallCommand.invoke` @@ -12254,7 +12254,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `IsSyscallCommand.is_syscall` @@ -12268,7 +12268,7 @@ is_syscall(arch, instruction: __main__.Instruction) → bool --- - + ## function `IsSyscallCommand.post_load` @@ -12282,7 +12282,7 @@ post_load() → None --- - + ## function `IsSyscallCommand.pre_load` @@ -12296,7 +12296,7 @@ pre_load() → None --- - + ## function `IsSyscallCommand.usage` @@ -12361,7 +12361,7 @@ usage() → None --- - + ## function `MIPS.flag_register_to_human` @@ -12375,7 +12375,7 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + ## function `MIPS.get_ith_parameter` @@ -12390,7 +12390,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `MIPS.get_ra` @@ -12404,7 +12404,7 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + ## function `MIPS.is_branch_taken` @@ -12418,7 +12418,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `MIPS.is_call` @@ -12432,7 +12432,7 @@ is_call(insn) → bool --- - + ## function `MIPS.is_conditional_branch` @@ -12446,7 +12446,7 @@ is_conditional_branch(insn) → bool --- - + ## function `MIPS.is_ret` @@ -12460,7 +12460,7 @@ is_ret(insn) → bool --- - + ## function `MIPS.mprotect_asm` @@ -12474,7 +12474,7 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + ## function `MIPS.register` @@ -12539,7 +12539,7 @@ register(name: str) → Union[int, NoneType] --- - + ## function `MIPS64.flag_register_to_human` @@ -12553,7 +12553,7 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + ## function `MIPS64.get_ith_parameter` @@ -12568,7 +12568,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `MIPS64.get_ra` @@ -12582,7 +12582,7 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + ## function `MIPS64.is_branch_taken` @@ -12596,7 +12596,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `MIPS64.is_call` @@ -12610,7 +12610,7 @@ is_call(insn) → bool --- - + ## function `MIPS64.is_conditional_branch` @@ -12624,7 +12624,7 @@ is_conditional_branch(insn) → bool --- - + ## function `MIPS64.is_ret` @@ -12638,7 +12638,7 @@ is_ret(insn) → bool --- - + ## function `MIPS64.mprotect_asm` @@ -12652,7 +12652,7 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + ## function `MIPS64.register` @@ -12670,7 +12670,7 @@ register(name: str) → Union[int, NoneType] ## class `MallocStateStruct` GEF representation of malloc_state from https://github.com/bminor/glibc/blob/glibc-2.28/malloc/malloc.c#L1658 - + ## function `MallocStateStruct.__init__` @@ -12815,7 +12815,7 @@ __init__(addr: str) → None --- - + ## function `MallocStateStruct.get_size_t` @@ -12829,7 +12829,7 @@ get_size_t(addr) --- - + ## function `MallocStateStruct.get_size_t_array` @@ -12843,7 +12843,7 @@ get_size_t_array(addr, length) --- - + ## function `MallocStateStruct.get_size_t_pointer` @@ -12861,7 +12861,7 @@ get_size_t_pointer(addr) ## class `MemoryCommand` Add or remove address ranges to the memory view. - + ## function `MemoryCommand.__init__` @@ -12884,7 +12884,7 @@ Return the list of settings for this command. --- - + ## function `MemoryCommand.add_setting` @@ -12900,7 +12900,7 @@ add_setting( --- - + ## function `MemoryCommand.del_setting` @@ -12912,7 +12912,7 @@ del_setting(name: str) → None --- - + ## function `MemoryCommand.do_invoke` @@ -12926,7 +12926,7 @@ do_invoke(argv: List) → None --- - + ## function `MemoryCommand.get_setting` @@ -12938,7 +12938,7 @@ get_setting(name) --- - + ## function `MemoryCommand.has_setting` @@ -12950,7 +12950,7 @@ has_setting(name: str) → bool --- - + ## function `MemoryCommand.invoke` @@ -12964,7 +12964,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `MemoryCommand.post_load` @@ -12978,7 +12978,7 @@ post_load() → None --- - + ## function `MemoryCommand.pre_load` @@ -12992,7 +12992,7 @@ pre_load() → None --- - + ## function `MemoryCommand.usage` @@ -13010,7 +13010,7 @@ usage() → None ## class `MemoryUnwatchCommand` Removes address ranges to the memory view. - + ## function `MemoryUnwatchCommand.__init__` @@ -13033,7 +13033,7 @@ Return the list of settings for this command. --- - + ## function `MemoryUnwatchCommand.add_setting` @@ -13049,7 +13049,7 @@ add_setting( --- - + ## function `MemoryUnwatchCommand.del_setting` @@ -13061,7 +13061,7 @@ del_setting(name: str) → None --- - + ## function `MemoryUnwatchCommand.do_invoke` @@ -13075,7 +13075,7 @@ do_invoke(argv: List) → None --- - + ## function `MemoryUnwatchCommand.get_setting` @@ -13087,7 +13087,7 @@ get_setting(name) --- - + ## function `MemoryUnwatchCommand.has_setting` @@ -13099,7 +13099,7 @@ has_setting(name: str) → bool --- - + ## function `MemoryUnwatchCommand.invoke` @@ -13113,7 +13113,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `MemoryUnwatchCommand.post_load` @@ -13127,7 +13127,7 @@ post_load() → None --- - + ## function `MemoryUnwatchCommand.pre_load` @@ -13141,7 +13141,7 @@ pre_load() → None --- - + ## function `MemoryUnwatchCommand.usage` @@ -13159,7 +13159,7 @@ usage() → None ## class `MemoryWatchCommand` Adds address ranges to the memory view. - + ## function `MemoryWatchCommand.__init__` @@ -13182,7 +13182,7 @@ Return the list of settings for this command. --- - + ## function `MemoryWatchCommand.add_setting` @@ -13198,7 +13198,7 @@ add_setting( --- - + ## function `MemoryWatchCommand.del_setting` @@ -13210,7 +13210,7 @@ del_setting(name: str) → None --- - + ## function `MemoryWatchCommand.do_invoke` @@ -13224,7 +13224,7 @@ do_invoke(argv: List) → None --- - + ## function `MemoryWatchCommand.get_setting` @@ -13236,7 +13236,7 @@ get_setting(name) --- - + ## function `MemoryWatchCommand.has_setting` @@ -13248,7 +13248,7 @@ has_setting(name: str) → bool --- - + ## function `MemoryWatchCommand.invoke` @@ -13262,7 +13262,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `MemoryWatchCommand.post_load` @@ -13276,7 +13276,7 @@ post_load() → None --- - + ## function `MemoryWatchCommand.pre_load` @@ -13290,7 +13290,7 @@ pre_load() → None --- - + ## function `MemoryWatchCommand.usage` @@ -13308,7 +13308,7 @@ usage() → None ## class `MemoryWatchListCommand` Lists all watchpoints to display in context layout. - + ## function `MemoryWatchListCommand.__init__` @@ -13331,7 +13331,7 @@ Return the list of settings for this command. --- - + ## function `MemoryWatchListCommand.add_setting` @@ -13347,7 +13347,7 @@ add_setting( --- - + ## function `MemoryWatchListCommand.del_setting` @@ -13359,7 +13359,7 @@ del_setting(name: str) → None --- - + ## function `MemoryWatchListCommand.do_invoke` @@ -13373,7 +13373,7 @@ do_invoke(argv: List) → None --- - + ## function `MemoryWatchListCommand.get_setting` @@ -13385,7 +13385,7 @@ get_setting(name) --- - + ## function `MemoryWatchListCommand.has_setting` @@ -13397,7 +13397,7 @@ has_setting(name: str) → bool --- - + ## function `MemoryWatchListCommand.invoke` @@ -13411,7 +13411,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `MemoryWatchListCommand.post_load` @@ -13425,7 +13425,7 @@ post_load() → None --- - + ## function `MemoryWatchListCommand.pre_load` @@ -13439,7 +13439,7 @@ pre_load() → None --- - + ## function `MemoryWatchListCommand.usage` @@ -13457,7 +13457,7 @@ usage() → None ## class `MemoryWatchResetCommand` Removes all watchpoints. - + ## function `MemoryWatchResetCommand.__init__` @@ -13480,7 +13480,7 @@ Return the list of settings for this command. --- - + ## function `MemoryWatchResetCommand.add_setting` @@ -13496,7 +13496,7 @@ add_setting( --- - + ## function `MemoryWatchResetCommand.del_setting` @@ -13508,7 +13508,7 @@ del_setting(name: str) → None --- - + ## function `MemoryWatchResetCommand.do_invoke` @@ -13522,7 +13522,7 @@ do_invoke(argv: List) → None --- - + ## function `MemoryWatchResetCommand.get_setting` @@ -13534,7 +13534,7 @@ get_setting(name) --- - + ## function `MemoryWatchResetCommand.has_setting` @@ -13546,7 +13546,7 @@ has_setting(name: str) → bool --- - + ## function `MemoryWatchResetCommand.invoke` @@ -13560,7 +13560,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `MemoryWatchResetCommand.post_load` @@ -13574,7 +13574,7 @@ post_load() → None --- - + ## function `MemoryWatchResetCommand.pre_load` @@ -13588,7 +13588,7 @@ pre_load() → None --- - + ## function `MemoryWatchResetCommand.usage` @@ -13606,7 +13606,7 @@ usage() → None ## class `NamedBreakpoint` Breakpoint which shows a specified name, when hit. - + ## function `NamedBreakpoint.__init__` @@ -13623,7 +13623,7 @@ __init__(location: str, name: str) → None --- - + ## function `NamedBreakpoint.stop` @@ -13641,7 +13641,7 @@ stop() → bool ## class `NamedBreakpointCommand` Sets a breakpoint and assigns a name to it, which will be shown, when it's hit. - + ## function `NamedBreakpointCommand.__init__` @@ -13664,7 +13664,7 @@ Return the list of settings for this command. --- - + ## function `NamedBreakpointCommand.add_setting` @@ -13680,7 +13680,7 @@ add_setting( --- - + ## function `NamedBreakpointCommand.del_setting` @@ -13692,7 +13692,7 @@ del_setting(name: str) → None --- - + ## function `NamedBreakpointCommand.wrapper` @@ -13706,7 +13706,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `NamedBreakpointCommand.get_setting` @@ -13718,7 +13718,7 @@ get_setting(name) --- - + ## function `NamedBreakpointCommand.has_setting` @@ -13730,7 +13730,7 @@ has_setting(name: str) → bool --- - + ## function `NamedBreakpointCommand.invoke` @@ -13744,7 +13744,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `NamedBreakpointCommand.post_load` @@ -13758,7 +13758,7 @@ post_load() → None --- - + ## function `NamedBreakpointCommand.pre_load` @@ -13772,7 +13772,7 @@ pre_load() → None --- - + ## function `NamedBreakpointCommand.usage` @@ -13790,7 +13790,7 @@ usage() → None ## class `NopCommand` Patch the instruction(s) pointed by parameters with NOP. Note: this command is architecture aware. - + ## function `NopCommand.__init__` @@ -13813,7 +13813,7 @@ Return the list of settings for this command. --- - + ## function `NopCommand.add_setting` @@ -13829,7 +13829,7 @@ add_setting( --- - + ## function `NopCommand.del_setting` @@ -13841,7 +13841,7 @@ del_setting(name: str) → None --- - + ## function `NopCommand.wrapper` @@ -13855,7 +13855,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `NopCommand.get_insn_size` @@ -13869,7 +13869,7 @@ get_insn_size(addr: int) → int --- - + ## function `NopCommand.get_setting` @@ -13881,7 +13881,7 @@ get_setting(name) --- - + ## function `NopCommand.has_setting` @@ -13893,7 +13893,7 @@ has_setting(name: str) → bool --- - + ## function `NopCommand.invoke` @@ -13907,7 +13907,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `NopCommand.nop_bytes` @@ -13921,7 +13921,7 @@ nop_bytes(loc: int, num_bytes: int) → None --- - + ## function `NopCommand.post_load` @@ -13935,7 +13935,7 @@ post_load() → None --- - + ## function `NopCommand.pre_load` @@ -13949,7 +13949,7 @@ pre_load() → None --- - + ## function `NopCommand.usage` @@ -13967,7 +13967,7 @@ 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__` @@ -13990,7 +13990,7 @@ Return the list of settings for this command. --- - + ## function `PCustomCommand.add_setting` @@ -14006,7 +14006,7 @@ add_setting( --- - + ## function `PCustomCommand.apply_structure_to_address` @@ -14025,7 +14025,7 @@ apply_structure_to_address( --- - + ## function `PCustomCommand.del_setting` @@ -14037,7 +14037,7 @@ del_setting(name: str) → None --- - + ## function `PCustomCommand.deserialize` @@ -14051,7 +14051,7 @@ deserialize(struct: _ctypes.Structure, data: bytes) → None --- - + ## function `PCustomCommand.do_invoke` @@ -14065,7 +14065,7 @@ do_invoke(argv: List) → None --- - + ## function `PCustomCommand.enumerate_structure_files` @@ -14077,7 +14077,7 @@ Return a list of all the files in the pcustom directory --- - + ## function `PCustomCommand.enumerate_structures` @@ -14089,7 +14089,7 @@ Return a hash of all the structures, with the key set the to filepath --- - + ## function `PCustomCommand.enumerate_structures_from_module` @@ -14103,7 +14103,7 @@ enumerate_structures_from_module(module: module) → Set[str] --- - + ## function `PCustomCommand.get_ctypes_value` @@ -14117,7 +14117,7 @@ get_ctypes_value(struct, item, value) → str --- - + ## function `PCustomCommand.get_modulename_structname_from_arg` @@ -14131,7 +14131,7 @@ get_modulename_structname_from_arg(arg: str) → Tuple[str, str] --- - + ## function `PCustomCommand.get_pcustom_absolute_root_path` @@ -14145,7 +14145,7 @@ get_pcustom_absolute_root_path() → Union[str, bytes] --- - + ## function `PCustomCommand.get_pcustom_filepath_for_structure` @@ -14159,7 +14159,7 @@ get_pcustom_filepath_for_structure(structure_name: str) → str --- - + ## function `PCustomCommand.get_setting` @@ -14171,7 +14171,7 @@ get_setting(name) --- - + ## function `PCustomCommand.get_structure_class` @@ -14186,7 +14186,7 @@ Returns a tuple of (class, instance) if modname!classname exists --- - + ## function `PCustomCommand.has_setting` @@ -14198,7 +14198,7 @@ has_setting(name: str) → bool --- - + ## function `PCustomCommand.invoke` @@ -14212,7 +14212,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PCustomCommand.is_valid_struct` @@ -14226,7 +14226,7 @@ is_valid_struct(structure_name: str) → bool --- - + ## function `PCustomCommand.load_module` @@ -14238,7 +14238,7 @@ Load a custom module, and return it --- - + ## function `PCustomCommand.post_load` @@ -14252,7 +14252,7 @@ post_load() → None --- - + ## function `PCustomCommand.pre_load` @@ -14266,7 +14266,7 @@ pre_load() → None --- - + ## function `PCustomCommand.usage` @@ -14284,7 +14284,7 @@ usage() → None ## class `PCustomEditCommand` PCustom: edit the content of a given structure - + ## function `PCustomEditCommand.__init__` @@ -14307,7 +14307,7 @@ Return the list of settings for this command. --- - + ## function `PCustomEditCommand.add_setting` @@ -14323,7 +14323,7 @@ add_setting( --- - + ## function `PCustomEditCommand.apply_structure_to_address` @@ -14342,7 +14342,7 @@ apply_structure_to_address( --- - + ## function `PCustomEditCommand.del_setting` @@ -14354,7 +14354,7 @@ del_setting(name: str) → None --- - + ## function `PCustomEditCommand.deserialize` @@ -14368,7 +14368,7 @@ deserialize(struct: _ctypes.Structure, data: bytes) → None --- - + ## function `PCustomEditCommand.do_invoke` @@ -14382,7 +14382,7 @@ do_invoke(argv: List) → None --- - + ## function `PCustomEditCommand.enumerate_structure_files` @@ -14394,7 +14394,7 @@ Return a list of all the files in the pcustom directory --- - + ## function `PCustomEditCommand.enumerate_structures` @@ -14406,7 +14406,7 @@ Return a hash of all the structures, with the key set the to filepath --- - + ## function `PCustomEditCommand.enumerate_structures_from_module` @@ -14420,7 +14420,7 @@ enumerate_structures_from_module(module: module) → Set[str] --- - + ## function `PCustomEditCommand.get_ctypes_value` @@ -14434,7 +14434,7 @@ get_ctypes_value(struct, item, value) → str --- - + ## function `PCustomEditCommand.get_modulename_structname_from_arg` @@ -14448,7 +14448,7 @@ get_modulename_structname_from_arg(arg: str) → Tuple[str, str] --- - + ## function `PCustomEditCommand.get_pcustom_absolute_root_path` @@ -14462,7 +14462,7 @@ get_pcustom_absolute_root_path() → Union[str, bytes] --- - + ## function `PCustomEditCommand.get_pcustom_filepath_for_structure` @@ -14476,7 +14476,7 @@ get_pcustom_filepath_for_structure(structure_name: str) → str --- - + ## function `PCustomEditCommand.get_setting` @@ -14488,7 +14488,7 @@ get_setting(name) --- - + ## function `PCustomEditCommand.get_structure_class` @@ -14503,7 +14503,7 @@ Returns a tuple of (class, instance) if modname!classname exists --- - + ## function `PCustomEditCommand.has_setting` @@ -14515,7 +14515,7 @@ has_setting(name: str) → bool --- - + ## function `PCustomEditCommand.invoke` @@ -14529,7 +14529,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PCustomEditCommand.is_valid_struct` @@ -14543,7 +14543,7 @@ is_valid_struct(structure_name: str) → bool --- - + ## function `PCustomEditCommand.load_module` @@ -14555,7 +14555,7 @@ Load a custom module, and return it --- - + ## function `PCustomEditCommand.post_load` @@ -14569,7 +14569,7 @@ post_load() → None --- - + ## function `PCustomEditCommand.pre_load` @@ -14583,7 +14583,7 @@ pre_load() → None --- - + ## function `PCustomEditCommand.usage` @@ -14601,7 +14601,7 @@ usage() → None ## class `PCustomListCommand` PCustom: list available structures - + ## function `PCustomListCommand.__init__` @@ -14624,7 +14624,7 @@ Return the list of settings for this command. --- - + ## function `PCustomListCommand.add_setting` @@ -14640,7 +14640,7 @@ add_setting( --- - + ## function `PCustomListCommand.apply_structure_to_address` @@ -14659,7 +14659,7 @@ apply_structure_to_address( --- - + ## function `PCustomListCommand.del_setting` @@ -14671,7 +14671,7 @@ del_setting(name: str) → None --- - + ## function `PCustomListCommand.deserialize` @@ -14685,7 +14685,7 @@ deserialize(struct: _ctypes.Structure, data: bytes) → None --- - + ## function `PCustomListCommand.do_invoke` @@ -14699,7 +14699,7 @@ do_invoke(argv: List) → None --- - + ## function `PCustomListCommand.enumerate_structure_files` @@ -14711,7 +14711,7 @@ Return a list of all the files in the pcustom directory --- - + ## function `PCustomListCommand.enumerate_structures` @@ -14723,7 +14723,7 @@ Return a hash of all the structures, with the key set the to filepath --- - + ## function `PCustomListCommand.enumerate_structures_from_module` @@ -14737,7 +14737,7 @@ enumerate_structures_from_module(module: module) → Set[str] --- - + ## function `PCustomListCommand.get_ctypes_value` @@ -14751,7 +14751,7 @@ get_ctypes_value(struct, item, value) → str --- - + ## function `PCustomListCommand.get_modulename_structname_from_arg` @@ -14765,7 +14765,7 @@ get_modulename_structname_from_arg(arg: str) → Tuple[str, str] --- - + ## function `PCustomListCommand.get_pcustom_absolute_root_path` @@ -14779,7 +14779,7 @@ get_pcustom_absolute_root_path() → Union[str, bytes] --- - + ## function `PCustomListCommand.get_pcustom_filepath_for_structure` @@ -14793,7 +14793,7 @@ get_pcustom_filepath_for_structure(structure_name: str) → str --- - + ## function `PCustomListCommand.get_setting` @@ -14805,7 +14805,7 @@ get_setting(name) --- - + ## function `PCustomListCommand.get_structure_class` @@ -14820,7 +14820,7 @@ Returns a tuple of (class, instance) if modname!classname exists --- - + ## function `PCustomListCommand.has_setting` @@ -14832,7 +14832,7 @@ has_setting(name: str) → bool --- - + ## function `PCustomListCommand.invoke` @@ -14846,7 +14846,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PCustomListCommand.is_valid_struct` @@ -14860,7 +14860,7 @@ is_valid_struct(structure_name: str) → bool --- - + ## function `PCustomListCommand.load_module` @@ -14872,7 +14872,7 @@ Load a custom module, and return it --- - + ## function `PCustomListCommand.post_load` @@ -14886,7 +14886,7 @@ post_load() → None --- - + ## function `PCustomListCommand.pre_load` @@ -14900,7 +14900,7 @@ pre_load() → None --- - + ## function `PCustomListCommand.usage` @@ -14918,7 +14918,7 @@ usage() → None ## class `PCustomShowCommand` PCustom: show the content of a given structure - + ## function `PCustomShowCommand.__init__` @@ -14941,7 +14941,7 @@ Return the list of settings for this command. --- - + ## function `PCustomShowCommand.add_setting` @@ -14957,7 +14957,7 @@ add_setting( --- - + ## function `PCustomShowCommand.apply_structure_to_address` @@ -14976,7 +14976,7 @@ apply_structure_to_address( --- - + ## function `PCustomShowCommand.del_setting` @@ -14988,7 +14988,7 @@ del_setting(name: str) → None --- - + ## function `PCustomShowCommand.deserialize` @@ -15002,7 +15002,7 @@ deserialize(struct: _ctypes.Structure, data: bytes) → None --- - + ## function `PCustomShowCommand.do_invoke` @@ -15016,7 +15016,7 @@ do_invoke(argv: List) → None --- - + ## function `PCustomShowCommand.enumerate_structure_files` @@ -15028,7 +15028,7 @@ Return a list of all the files in the pcustom directory --- - + ## function `PCustomShowCommand.enumerate_structures` @@ -15040,7 +15040,7 @@ Return a hash of all the structures, with the key set the to filepath --- - + ## function `PCustomShowCommand.enumerate_structures_from_module` @@ -15054,7 +15054,7 @@ enumerate_structures_from_module(module: module) → Set[str] --- - + ## function `PCustomShowCommand.get_ctypes_value` @@ -15068,7 +15068,7 @@ get_ctypes_value(struct, item, value) → str --- - + ## function `PCustomShowCommand.get_modulename_structname_from_arg` @@ -15082,7 +15082,7 @@ get_modulename_structname_from_arg(arg: str) → Tuple[str, str] --- - + ## function `PCustomShowCommand.get_pcustom_absolute_root_path` @@ -15096,7 +15096,7 @@ get_pcustom_absolute_root_path() → Union[str, bytes] --- - + ## function `PCustomShowCommand.get_pcustom_filepath_for_structure` @@ -15110,7 +15110,7 @@ get_pcustom_filepath_for_structure(structure_name: str) → str --- - + ## function `PCustomShowCommand.get_setting` @@ -15122,7 +15122,7 @@ get_setting(name) --- - + ## function `PCustomShowCommand.get_structure_class` @@ -15137,7 +15137,7 @@ Returns a tuple of (class, instance) if modname!classname exists --- - + ## function `PCustomShowCommand.has_setting` @@ -15149,7 +15149,7 @@ has_setting(name: str) → bool --- - + ## function `PCustomShowCommand.invoke` @@ -15163,7 +15163,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PCustomShowCommand.is_valid_struct` @@ -15177,7 +15177,7 @@ is_valid_struct(structure_name: str) → bool --- - + ## function `PCustomShowCommand.load_module` @@ -15189,7 +15189,7 @@ Load a custom module, and return it --- - + ## function `PCustomShowCommand.post_load` @@ -15203,7 +15203,7 @@ post_load() → None --- - + ## function `PCustomShowCommand.pre_load` @@ -15217,7 +15217,7 @@ pre_load() → None --- - + ## function `PCustomShowCommand.usage` @@ -15235,7 +15235,7 @@ usage() → None ## class `PatchByteCommand` Write specified WORD to the specified address. - + ## function `PatchByteCommand.__init__` @@ -15258,7 +15258,7 @@ Return the list of settings for this command. --- - + ## function `PatchByteCommand.add_setting` @@ -15274,7 +15274,7 @@ add_setting( --- - + ## function `PatchByteCommand.del_setting` @@ -15286,7 +15286,7 @@ del_setting(name: str) → None --- - + ## function `PatchByteCommand.wrapper` @@ -15300,7 +15300,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `PatchByteCommand.get_setting` @@ -15312,7 +15312,7 @@ get_setting(name) --- - + ## function `PatchByteCommand.has_setting` @@ -15324,7 +15324,7 @@ has_setting(name: str) → bool --- - + ## function `PatchByteCommand.invoke` @@ -15338,7 +15338,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PatchByteCommand.post_load` @@ -15352,7 +15352,7 @@ post_load() → None --- - + ## function `PatchByteCommand.pre_load` @@ -15366,7 +15366,7 @@ pre_load() → None --- - + ## function `PatchByteCommand.usage` @@ -15384,7 +15384,7 @@ usage() → None ## class `PatchCommand` Write specified values to the specified address. - + ## function `PatchCommand.__init__` @@ -15407,7 +15407,7 @@ Return the list of settings for this command. --- - + ## function `PatchCommand.add_setting` @@ -15423,7 +15423,7 @@ add_setting( --- - + ## function `PatchCommand.del_setting` @@ -15435,7 +15435,7 @@ del_setting(name: str) → None --- - + ## function `PatchCommand.wrapper` @@ -15449,7 +15449,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `PatchCommand.get_setting` @@ -15461,7 +15461,7 @@ get_setting(name) --- - + ## function `PatchCommand.has_setting` @@ -15473,7 +15473,7 @@ has_setting(name: str) → bool --- - + ## function `PatchCommand.invoke` @@ -15487,7 +15487,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PatchCommand.post_load` @@ -15501,7 +15501,7 @@ post_load() → None --- - + ## function `PatchCommand.pre_load` @@ -15515,7 +15515,7 @@ pre_load() → None --- - + ## function `PatchCommand.usage` @@ -15533,7 +15533,7 @@ usage() → None ## class `PatchDwordCommand` Write specified DWORD to the specified address. - + ## function `PatchDwordCommand.__init__` @@ -15556,7 +15556,7 @@ Return the list of settings for this command. --- - + ## function `PatchDwordCommand.add_setting` @@ -15572,7 +15572,7 @@ add_setting( --- - + ## function `PatchDwordCommand.del_setting` @@ -15584,7 +15584,7 @@ del_setting(name: str) → None --- - + ## function `PatchDwordCommand.wrapper` @@ -15598,7 +15598,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `PatchDwordCommand.get_setting` @@ -15610,7 +15610,7 @@ get_setting(name) --- - + ## function `PatchDwordCommand.has_setting` @@ -15622,7 +15622,7 @@ has_setting(name: str) → bool --- - + ## function `PatchDwordCommand.invoke` @@ -15636,7 +15636,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PatchDwordCommand.post_load` @@ -15650,7 +15650,7 @@ post_load() → None --- - + ## function `PatchDwordCommand.pre_load` @@ -15664,7 +15664,7 @@ pre_load() → None --- - + ## function `PatchDwordCommand.usage` @@ -15682,7 +15682,7 @@ usage() → None ## class `PatchQwordCommand` Write specified QWORD to the specified address. - + ## function `PatchQwordCommand.__init__` @@ -15705,7 +15705,7 @@ Return the list of settings for this command. --- - + ## function `PatchQwordCommand.add_setting` @@ -15721,7 +15721,7 @@ add_setting( --- - + ## function `PatchQwordCommand.del_setting` @@ -15733,7 +15733,7 @@ del_setting(name: str) → None --- - + ## function `PatchQwordCommand.wrapper` @@ -15747,7 +15747,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `PatchQwordCommand.get_setting` @@ -15759,7 +15759,7 @@ get_setting(name) --- - + ## function `PatchQwordCommand.has_setting` @@ -15771,7 +15771,7 @@ has_setting(name: str) → bool --- - + ## function `PatchQwordCommand.invoke` @@ -15785,7 +15785,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PatchQwordCommand.post_load` @@ -15799,7 +15799,7 @@ post_load() → None --- - + ## function `PatchQwordCommand.pre_load` @@ -15813,7 +15813,7 @@ pre_load() → None --- - + ## function `PatchQwordCommand.usage` @@ -15831,7 +15831,7 @@ usage() → None ## class `PatchStringCommand` Write specified string to the specified memory location pointed by ADDRESS. - + ## function `PatchStringCommand.__init__` @@ -15854,7 +15854,7 @@ Return the list of settings for this command. --- - + ## function `PatchStringCommand.add_setting` @@ -15870,7 +15870,7 @@ add_setting( --- - + ## function `PatchStringCommand.del_setting` @@ -15882,7 +15882,7 @@ del_setting(name: str) → None --- - + ## function `PatchStringCommand.do_invoke` @@ -15896,7 +15896,7 @@ do_invoke(argv: List) → None --- - + ## function `PatchStringCommand.get_setting` @@ -15908,7 +15908,7 @@ get_setting(name) --- - + ## function `PatchStringCommand.has_setting` @@ -15920,7 +15920,7 @@ has_setting(name: str) → bool --- - + ## function `PatchStringCommand.invoke` @@ -15934,7 +15934,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PatchStringCommand.post_load` @@ -15948,7 +15948,7 @@ post_load() → None --- - + ## function `PatchStringCommand.pre_load` @@ -15962,7 +15962,7 @@ pre_load() → None --- - + ## function `PatchStringCommand.usage` @@ -15980,7 +15980,7 @@ usage() → None ## class `PatchWordCommand` Write specified WORD to the specified address. - + ## function `PatchWordCommand.__init__` @@ -16003,7 +16003,7 @@ Return the list of settings for this command. --- - + ## function `PatchWordCommand.add_setting` @@ -16019,7 +16019,7 @@ add_setting( --- - + ## function `PatchWordCommand.del_setting` @@ -16031,7 +16031,7 @@ del_setting(name: str) → None --- - + ## function `PatchWordCommand.wrapper` @@ -16045,7 +16045,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `PatchWordCommand.get_setting` @@ -16057,7 +16057,7 @@ get_setting(name) --- - + ## function `PatchWordCommand.has_setting` @@ -16069,7 +16069,7 @@ has_setting(name: str) → bool --- - + ## function `PatchWordCommand.invoke` @@ -16083,7 +16083,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PatchWordCommand.post_load` @@ -16097,7 +16097,7 @@ post_load() → None --- - + ## function `PatchWordCommand.pre_load` @@ -16111,7 +16111,7 @@ pre_load() → None --- - + ## function `PatchWordCommand.usage` @@ -16129,7 +16129,7 @@ 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__` @@ -16152,7 +16152,7 @@ Return the list of settings for this command. --- - + ## function `PatternCommand.add_setting` @@ -16168,7 +16168,7 @@ add_setting( --- - + ## function `PatternCommand.del_setting` @@ -16180,7 +16180,7 @@ del_setting(name: str) → None --- - + ## function `PatternCommand.do_invoke` @@ -16194,7 +16194,7 @@ do_invoke(argv: List) → None --- - + ## function `PatternCommand.get_setting` @@ -16206,7 +16206,7 @@ get_setting(name) --- - + ## function `PatternCommand.has_setting` @@ -16218,7 +16218,7 @@ has_setting(name: str) → bool --- - + ## function `PatternCommand.invoke` @@ -16232,7 +16232,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PatternCommand.post_load` @@ -16246,7 +16246,7 @@ post_load() → None --- - + ## function `PatternCommand.pre_load` @@ -16260,7 +16260,7 @@ pre_load() → None --- - + ## function `PatternCommand.usage` @@ -16278,7 +16278,7 @@ 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__` @@ -16301,7 +16301,7 @@ Return the list of settings for this command. --- - + ## function `PatternCreateCommand.add_setting` @@ -16317,7 +16317,7 @@ add_setting( --- - + ## function `PatternCreateCommand.del_setting` @@ -16329,7 +16329,7 @@ del_setting(name: str) → None --- - + ## function `PatternCreateCommand.wrapper` @@ -16343,7 +16343,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `PatternCreateCommand.get_setting` @@ -16355,7 +16355,7 @@ get_setting(name) --- - + ## function `PatternCreateCommand.has_setting` @@ -16367,7 +16367,7 @@ has_setting(name: str) → bool --- - + ## function `PatternCreateCommand.invoke` @@ -16381,7 +16381,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PatternCreateCommand.post_load` @@ -16395,7 +16395,7 @@ post_load() → None --- - + ## function `PatternCreateCommand.pre_load` @@ -16409,7 +16409,7 @@ pre_load() → None --- - + ## function `PatternCreateCommand.usage` @@ -16427,7 +16427,7 @@ 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__` @@ -16450,7 +16450,7 @@ Return the list of settings for this command. --- - + ## function `PatternSearchCommand.add_setting` @@ -16466,7 +16466,7 @@ add_setting( --- - + ## function `PatternSearchCommand.del_setting` @@ -16478,7 +16478,7 @@ del_setting(name: str) → None --- - + ## function `PatternSearchCommand.wrapper` @@ -16492,7 +16492,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `PatternSearchCommand.get_setting` @@ -16504,7 +16504,7 @@ get_setting(name) --- - + ## function `PatternSearchCommand.has_setting` @@ -16516,7 +16516,7 @@ has_setting(name: str) → bool --- - + ## function `PatternSearchCommand.invoke` @@ -16530,7 +16530,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PatternSearchCommand.post_load` @@ -16544,7 +16544,7 @@ post_load() → None --- - + ## function `PatternSearchCommand.pre_load` @@ -16558,7 +16558,7 @@ pre_load() → None --- - + ## function `PatternSearchCommand.search` @@ -16572,7 +16572,7 @@ search(pattern: str, size: int, period: int) → None --- - + ## function `PatternSearchCommand.usage` @@ -16590,7 +16590,7 @@ usage() → None ## class `Permission` GEF representation of Linux permission. - + ## function `Permission.__init__` @@ -16607,7 +16607,7 @@ __init__(**kwargs) → None --- - + ## function `Permission.from_info_sections` @@ -16621,7 +16621,7 @@ from_info_sections(*args: List[str]) --- - + ## function `Permission.from_process_maps` @@ -16641,7 +16641,7 @@ from_process_maps(perm_str: str) - + ## function `Phdr.__init__` @@ -16662,7 +16662,7 @@ __init__(elf: __main__.Elf, off: int) → None ## class `PieAttachCommand` Do attach with PIE breakpoint support. - + ## function `PieAttachCommand.__init__` @@ -16685,7 +16685,7 @@ Return the list of settings for this command. --- - + ## function `PieAttachCommand.add_setting` @@ -16701,7 +16701,7 @@ add_setting( --- - + ## function `PieAttachCommand.del_setting` @@ -16713,7 +16713,7 @@ del_setting(name: str) → None --- - + ## function `PieAttachCommand.do_invoke` @@ -16727,7 +16727,7 @@ do_invoke(argv: List) → None --- - + ## function `PieAttachCommand.get_setting` @@ -16739,7 +16739,7 @@ get_setting(name) --- - + ## function `PieAttachCommand.has_setting` @@ -16751,7 +16751,7 @@ has_setting(name: str) → bool --- - + ## function `PieAttachCommand.invoke` @@ -16765,7 +16765,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PieAttachCommand.post_load` @@ -16779,7 +16779,7 @@ post_load() → None --- - + ## function `PieAttachCommand.pre_load` @@ -16793,7 +16793,7 @@ pre_load() → None --- - + ## function `PieAttachCommand.usage` @@ -16811,7 +16811,7 @@ usage() → None ## class `PieBreakpointCommand` Set a PIE breakpoint at an offset from the target binaries base address. - + ## function `PieBreakpointCommand.__init__` @@ -16834,7 +16834,7 @@ Return the list of settings for this command. --- - + ## function `PieBreakpointCommand.add_setting` @@ -16850,7 +16850,7 @@ add_setting( --- - + ## function `PieBreakpointCommand.del_setting` @@ -16862,7 +16862,7 @@ del_setting(name: str) → None --- - + ## function `PieBreakpointCommand.wrapper` @@ -16876,7 +16876,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `PieBreakpointCommand.get_setting` @@ -16888,7 +16888,7 @@ get_setting(name) --- - + ## function `PieBreakpointCommand.has_setting` @@ -16900,7 +16900,7 @@ has_setting(name: str) → bool --- - + ## function `PieBreakpointCommand.invoke` @@ -16914,7 +16914,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PieBreakpointCommand.post_load` @@ -16928,7 +16928,7 @@ post_load() → None --- - + ## function `PieBreakpointCommand.pre_load` @@ -16942,7 +16942,7 @@ pre_load() → None --- - + ## function `PieBreakpointCommand.set_pie_breakpoint` @@ -16956,7 +16956,7 @@ set_pie_breakpoint(set_func: Callable[[int], str], addr: int) → None --- - + ## function `PieBreakpointCommand.usage` @@ -16974,7 +16974,7 @@ usage() → None ## class `PieCommand` PIE breakpoint support. - + ## function `PieCommand.__init__` @@ -16997,7 +16997,7 @@ Return the list of settings for this command. --- - + ## function `PieCommand.add_setting` @@ -17013,7 +17013,7 @@ add_setting( --- - + ## function `PieCommand.del_setting` @@ -17025,7 +17025,7 @@ del_setting(name: str) → None --- - + ## function `PieCommand.do_invoke` @@ -17039,7 +17039,7 @@ do_invoke(argv: List) → None --- - + ## function `PieCommand.get_setting` @@ -17051,7 +17051,7 @@ get_setting(name) --- - + ## function `PieCommand.has_setting` @@ -17063,7 +17063,7 @@ has_setting(name: str) → bool --- - + ## function `PieCommand.invoke` @@ -17077,7 +17077,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PieCommand.post_load` @@ -17091,7 +17091,7 @@ post_load() → None --- - + ## function `PieCommand.pre_load` @@ -17105,7 +17105,7 @@ pre_load() → None --- - + ## function `PieCommand.usage` @@ -17123,7 +17123,7 @@ usage() → None ## class `PieDeleteCommand` Delete a PIE breakpoint. - + ## function `PieDeleteCommand.__init__` @@ -17146,7 +17146,7 @@ Return the list of settings for this command. --- - + ## function `PieDeleteCommand.add_setting` @@ -17162,7 +17162,7 @@ add_setting( --- - + ## function `PieDeleteCommand.del_setting` @@ -17174,7 +17174,7 @@ del_setting(name: str) → None --- - + ## function `PieDeleteCommand.delete_bp` @@ -17188,7 +17188,7 @@ delete_bp(breakpoints: List) → None --- - + ## function `PieDeleteCommand.wrapper` @@ -17202,7 +17202,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `PieDeleteCommand.get_setting` @@ -17214,7 +17214,7 @@ get_setting(name) --- - + ## function `PieDeleteCommand.has_setting` @@ -17226,7 +17226,7 @@ has_setting(name: str) → bool --- - + ## function `PieDeleteCommand.invoke` @@ -17240,7 +17240,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PieDeleteCommand.post_load` @@ -17254,7 +17254,7 @@ post_load() → None --- - + ## function `PieDeleteCommand.pre_load` @@ -17268,7 +17268,7 @@ pre_load() → None --- - + ## function `PieDeleteCommand.usage` @@ -17286,7 +17286,7 @@ usage() → None ## class `PieInfoCommand` Display breakpoint info. - + ## function `PieInfoCommand.__init__` @@ -17309,7 +17309,7 @@ Return the list of settings for this command. --- - + ## function `PieInfoCommand.add_setting` @@ -17325,7 +17325,7 @@ add_setting( --- - + ## function `PieInfoCommand.del_setting` @@ -17337,7 +17337,7 @@ del_setting(name: str) → None --- - + ## function `PieInfoCommand.wrapper` @@ -17351,7 +17351,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `PieInfoCommand.get_setting` @@ -17363,7 +17363,7 @@ get_setting(name) --- - + ## function `PieInfoCommand.has_setting` @@ -17375,7 +17375,7 @@ has_setting(name: str) → bool --- - + ## function `PieInfoCommand.invoke` @@ -17389,7 +17389,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PieInfoCommand.post_load` @@ -17403,7 +17403,7 @@ post_load() → None --- - + ## function `PieInfoCommand.pre_load` @@ -17417,7 +17417,7 @@ pre_load() → None --- - + ## function `PieInfoCommand.usage` @@ -17435,7 +17435,7 @@ usage() → None ## class `PieRemoteCommand` Attach to a remote connection with PIE breakpoint support. - + ## function `PieRemoteCommand.__init__` @@ -17458,7 +17458,7 @@ Return the list of settings for this command. --- - + ## function `PieRemoteCommand.add_setting` @@ -17474,7 +17474,7 @@ add_setting( --- - + ## function `PieRemoteCommand.del_setting` @@ -17486,7 +17486,7 @@ del_setting(name: str) → None --- - + ## function `PieRemoteCommand.do_invoke` @@ -17500,7 +17500,7 @@ do_invoke(argv: List) → None --- - + ## function `PieRemoteCommand.get_setting` @@ -17512,7 +17512,7 @@ get_setting(name) --- - + ## function `PieRemoteCommand.has_setting` @@ -17524,7 +17524,7 @@ has_setting(name: str) → bool --- - + ## function `PieRemoteCommand.invoke` @@ -17538,7 +17538,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PieRemoteCommand.post_load` @@ -17552,7 +17552,7 @@ post_load() → None --- - + ## function `PieRemoteCommand.pre_load` @@ -17566,7 +17566,7 @@ pre_load() → None --- - + ## function `PieRemoteCommand.usage` @@ -17584,7 +17584,7 @@ usage() → None ## class `PieRunCommand` Run process with PIE breakpoint support. - + ## function `PieRunCommand.__init__` @@ -17607,7 +17607,7 @@ Return the list of settings for this command. --- - + ## function `PieRunCommand.add_setting` @@ -17623,7 +17623,7 @@ add_setting( --- - + ## function `PieRunCommand.del_setting` @@ -17635,7 +17635,7 @@ del_setting(name: str) → None --- - + ## function `PieRunCommand.do_invoke` @@ -17649,7 +17649,7 @@ do_invoke(argv: List) → None --- - + ## function `PieRunCommand.get_setting` @@ -17661,7 +17661,7 @@ get_setting(name) --- - + ## function `PieRunCommand.has_setting` @@ -17673,7 +17673,7 @@ has_setting(name: str) → bool --- - + ## function `PieRunCommand.invoke` @@ -17687,7 +17687,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PieRunCommand.post_load` @@ -17701,7 +17701,7 @@ post_load() → None --- - + ## function `PieRunCommand.pre_load` @@ -17715,7 +17715,7 @@ pre_load() → None --- - + ## function `PieRunCommand.usage` @@ -17733,7 +17733,7 @@ usage() → None ## class `PieVirtualBreakpoint` PIE virtual breakpoint (not real breakpoint). - + ## function `PieVirtualBreakpoint.__init__` @@ -17750,7 +17750,7 @@ __init__(set_func: Callable[[int], str], vbp_num: int, addr: int) → None --- - + ## function `PieVirtualBreakpoint.destroy` @@ -17764,7 +17764,7 @@ destroy() → None --- - + ## function `PieVirtualBreakpoint.instantiate` @@ -17837,7 +17837,7 @@ instantiate(base: int) → None --- - + ## function `PowerPC.flag_register_to_human` @@ -17851,7 +17851,7 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + ## function `PowerPC.get_ith_parameter` @@ -17866,7 +17866,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `PowerPC.get_ra` @@ -17880,7 +17880,7 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + ## function `PowerPC.is_branch_taken` @@ -17894,7 +17894,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `PowerPC.is_call` @@ -17908,7 +17908,7 @@ is_call(insn) → bool --- - + ## function `PowerPC.is_conditional_branch` @@ -17922,7 +17922,7 @@ is_conditional_branch(insn) → bool --- - + ## function `PowerPC.is_ret` @@ -17936,7 +17936,7 @@ is_ret(insn) → bool --- - + ## function `PowerPC.mprotect_asm` @@ -17950,7 +17950,7 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + ## function `PowerPC.register` @@ -18023,7 +18023,7 @@ register(name: str) → Union[int, NoneType] --- - + ## function `PowerPC64.flag_register_to_human` @@ -18037,7 +18037,7 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + ## function `PowerPC64.get_ith_parameter` @@ -18052,7 +18052,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `PowerPC64.get_ra` @@ -18066,7 +18066,7 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + ## function `PowerPC64.is_branch_taken` @@ -18080,7 +18080,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `PowerPC64.is_call` @@ -18094,7 +18094,7 @@ is_call(insn) → bool --- - + ## function `PowerPC64.is_conditional_branch` @@ -18108,7 +18108,7 @@ is_conditional_branch(insn) → bool --- - + ## function `PowerPC64.is_ret` @@ -18122,7 +18122,7 @@ is_ret(insn) → bool --- - + ## function `PowerPC64.mprotect_asm` @@ -18136,7 +18136,7 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + ## function `PowerPC64.register` @@ -18154,7 +18154,7 @@ register(name: str) → Union[int, NoneType] ## class `PrintFormatCommand` Print bytes format in high level languages. - + ## function `PrintFormatCommand.__init__` @@ -18185,7 +18185,7 @@ Return the list of settings for this command. --- - + ## function `PrintFormatCommand.add_setting` @@ -18201,7 +18201,7 @@ add_setting( --- - + ## function `PrintFormatCommand.del_setting` @@ -18213,7 +18213,7 @@ del_setting(name: str) → None --- - + ## function `PrintFormatCommand.wrapper` @@ -18227,7 +18227,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `PrintFormatCommand.get_setting` @@ -18239,7 +18239,7 @@ get_setting(name) --- - + ## function `PrintFormatCommand.has_setting` @@ -18251,7 +18251,7 @@ has_setting(name: str) → bool --- - + ## function `PrintFormatCommand.invoke` @@ -18265,7 +18265,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `PrintFormatCommand.post_load` @@ -18279,7 +18279,7 @@ post_load() → None --- - + ## function `PrintFormatCommand.pre_load` @@ -18293,7 +18293,7 @@ pre_load() → None --- - + ## function `PrintFormatCommand.usage` @@ -18311,7 +18311,7 @@ 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__` @@ -18334,7 +18334,7 @@ Return the list of settings for this command. --- - + ## function `ProcessListingCommand.add_setting` @@ -18350,7 +18350,7 @@ add_setting( --- - + ## function `ProcessListingCommand.del_setting` @@ -18362,7 +18362,7 @@ del_setting(name: str) → None --- - + ## function `ProcessListingCommand.wrapper` @@ -18376,7 +18376,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `ProcessListingCommand.get_processes` @@ -18390,7 +18390,7 @@ get_processes() → Generator[Dict[str, str], Any, NoneType] --- - + ## function `ProcessListingCommand.get_setting` @@ -18402,7 +18402,7 @@ get_setting(name) --- - + ## function `ProcessListingCommand.has_setting` @@ -18414,7 +18414,7 @@ has_setting(name: str) → bool --- - + ## function `ProcessListingCommand.invoke` @@ -18428,7 +18428,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ProcessListingCommand.post_load` @@ -18442,7 +18442,7 @@ post_load() → None --- - + ## function `ProcessListingCommand.pre_load` @@ -18456,7 +18456,7 @@ pre_load() → None --- - + ## function `ProcessListingCommand.usage` @@ -18474,7 +18474,7 @@ 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__` @@ -18497,7 +18497,7 @@ Return the list of settings for this command. --- - + ## function `ProcessStatusCommand.add_setting` @@ -18513,7 +18513,7 @@ add_setting( --- - + ## function `ProcessStatusCommand.del_setting` @@ -18525,7 +18525,7 @@ del_setting(name: str) → None --- - + ## function `ProcessStatusCommand.do_invoke` @@ -18539,7 +18539,7 @@ do_invoke(argv: List) → None --- - + ## function `ProcessStatusCommand.get_children_pids` @@ -18553,7 +18553,7 @@ get_children_pids(pid: int) → List[int] --- - + ## function `ProcessStatusCommand.get_cmdline_of` @@ -18567,7 +18567,7 @@ get_cmdline_of(pid: int) → str --- - + ## function `ProcessStatusCommand.get_process_path_of` @@ -18581,7 +18581,7 @@ get_process_path_of(pid: int) → str --- - + ## function `ProcessStatusCommand.get_setting` @@ -18593,7 +18593,7 @@ get_setting(name) --- - + ## function `ProcessStatusCommand.get_state_of` @@ -18607,7 +18607,7 @@ get_state_of(pid: int) → Dict[str, str] --- - + ## function `ProcessStatusCommand.has_setting` @@ -18619,7 +18619,7 @@ has_setting(name: str) → bool --- - + ## function `ProcessStatusCommand.invoke` @@ -18633,7 +18633,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ProcessStatusCommand.list_sockets` @@ -18647,7 +18647,7 @@ list_sockets(pid: int) → List[int] --- - + ## function `ProcessStatusCommand.parse_ip_port` @@ -18661,7 +18661,7 @@ parse_ip_port(addr: str) → Tuple[str, int] --- - + ## function `ProcessStatusCommand.post_load` @@ -18675,7 +18675,7 @@ post_load() → None --- - + ## function `ProcessStatusCommand.pre_load` @@ -18689,7 +18689,7 @@ pre_load() → None --- - + ## function `ProcessStatusCommand.show_ancestor` @@ -18703,7 +18703,7 @@ show_ancestor() → None --- - + ## function `ProcessStatusCommand.show_connections` @@ -18717,7 +18717,7 @@ show_connections() → None --- - + ## function `ProcessStatusCommand.show_descendants` @@ -18731,7 +18731,7 @@ show_descendants() → None --- - + ## function `ProcessStatusCommand.show_fds` @@ -18745,7 +18745,7 @@ show_fds() → None --- - + ## function `ProcessStatusCommand.show_info_proc` @@ -18759,7 +18759,7 @@ show_info_proc() → None --- - + ## function `ProcessStatusCommand.usage` @@ -18840,7 +18840,7 @@ usage() → None --- - + ## function `RISCV.get_ith_parameter` @@ -18855,7 +18855,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `RISCV.get_ra` @@ -18869,7 +18869,7 @@ get_ra(insn, frame) → int --- - + ## function `RISCV.is_branch_taken` @@ -18883,7 +18883,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `RISCV.is_call` @@ -18897,7 +18897,7 @@ is_call(insn) → bool --- - + ## function `RISCV.is_conditional_branch` @@ -18911,7 +18911,7 @@ is_conditional_branch(insn) → bool --- - + ## function `RISCV.is_ret` @@ -18925,7 +18925,7 @@ is_ret(insn) → bool --- - + ## function `RISCV.mprotect_asm` @@ -18939,7 +18939,7 @@ mprotect_asm(addr: int, size: int, perm) --- - + ## function `RISCV.register` @@ -18959,7 +18959,7 @@ register(name: str) → Union[int, NoneType] - + ## function `RedirectOutputContext.__init__` @@ -18980,7 +18980,7 @@ __init__(to='/dev/null') → None ## class `RemoteCommand` gef wrapper for the `target remote` command. This command will automatically download the target binary in the local temporary directory (defaut /tmp) and then source it. Additionally, it will fetch all the /proc/PID/maps and loads all its information. - + ## function `RemoteCommand.__init__` @@ -19003,7 +19003,7 @@ Return the list of settings for this command. --- - + ## function `RemoteCommand.add_setting` @@ -19019,7 +19019,7 @@ add_setting( --- - + ## function `RemoteCommand.connect_target` @@ -19031,7 +19031,7 @@ Connect to remote target and get symbols. To prevent `gef` from requesting infor --- - + ## function `RemoteCommand.del_setting` @@ -19043,7 +19043,7 @@ del_setting(name: str) → None --- - + ## function `RemoteCommand.wrapper` @@ -19057,7 +19057,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `RemoteCommand.get_setting` @@ -19069,7 +19069,7 @@ get_setting(name) --- - + ## function `RemoteCommand.has_setting` @@ -19081,7 +19081,7 @@ has_setting(name: str) → bool --- - + ## function `RemoteCommand.invoke` @@ -19095,7 +19095,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `RemoteCommand.load_from_remote_proc` @@ -19107,7 +19107,7 @@ Download one item from /proc/pid. --- - + ## function `RemoteCommand.new_objfile_handler` @@ -19119,7 +19119,7 @@ Hook that handles new_objfile events, will update remote environment accordingly --- - + ## function `RemoteCommand.post_load` @@ -19133,7 +19133,7 @@ post_load() → None --- - + ## function `RemoteCommand.pre_load` @@ -19147,7 +19147,7 @@ pre_load() → None --- - + ## function `RemoteCommand.prepare_qemu_stub` @@ -19161,7 +19161,7 @@ prepare_qemu_stub(target: str) → None --- - + ## function `RemoteCommand.refresh_shared_library_path` @@ -19175,7 +19175,7 @@ refresh_shared_library_path() → None --- - + ## function `RemoteCommand.setup_remote_environment` @@ -19187,7 +19187,7 @@ Clone the remote environment locally in the temporary directory. The command wil --- - + ## function `RemoteCommand.usage` @@ -19205,7 +19205,7 @@ 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__` @@ -19228,7 +19228,7 @@ Return the list of settings for this command. --- - + ## function `ResetCacheCommand.add_setting` @@ -19244,7 +19244,7 @@ add_setting( --- - + ## function `ResetCacheCommand.del_setting` @@ -19256,7 +19256,7 @@ del_setting(name: str) → None --- - + ## function `ResetCacheCommand.do_invoke` @@ -19270,7 +19270,7 @@ do_invoke(argv: List) → None --- - + ## function `ResetCacheCommand.get_setting` @@ -19282,7 +19282,7 @@ get_setting(name) --- - + ## function `ResetCacheCommand.has_setting` @@ -19294,7 +19294,7 @@ has_setting(name: str) → bool --- - + ## function `ResetCacheCommand.invoke` @@ -19308,7 +19308,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ResetCacheCommand.post_load` @@ -19322,7 +19322,7 @@ post_load() → None --- - + ## function `ResetCacheCommand.pre_load` @@ -19336,7 +19336,7 @@ pre_load() → None --- - + ## function `ResetCacheCommand.usage` @@ -19354,7 +19354,7 @@ usage() → None ## class `RopperCommand` Ropper (http://scoding.de/ropper) plugin. - + ## function `RopperCommand.__init__` @@ -19377,7 +19377,7 @@ Return the list of settings for this command. --- - + ## function `RopperCommand.add_setting` @@ -19393,7 +19393,7 @@ add_setting( --- - + ## function `RopperCommand.del_setting` @@ -19405,7 +19405,7 @@ del_setting(name: str) → None --- - + ## function `RopperCommand.do_invoke` @@ -19419,7 +19419,7 @@ do_invoke(argv: List) → None --- - + ## function `RopperCommand.get_setting` @@ -19431,7 +19431,7 @@ get_setting(name) --- - + ## function `RopperCommand.has_setting` @@ -19443,7 +19443,7 @@ has_setting(name: str) → bool --- - + ## function `RopperCommand.invoke` @@ -19457,7 +19457,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `RopperCommand.post_load` @@ -19471,7 +19471,7 @@ post_load() → None --- - + ## function `RopperCommand.pre_load` @@ -19485,7 +19485,7 @@ pre_load() → None --- - + ## function `RopperCommand.usage` @@ -19557,7 +19557,7 @@ Refs: --- - + ## function `SPARC.flag_register_to_human` @@ -19571,7 +19571,7 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + ## function `SPARC.get_ith_parameter` @@ -19586,7 +19586,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `SPARC.get_ra` @@ -19600,7 +19600,7 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + ## function `SPARC.is_branch_taken` @@ -19614,7 +19614,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `SPARC.is_call` @@ -19628,7 +19628,7 @@ is_call(insn) → bool --- - + ## function `SPARC.is_conditional_branch` @@ -19642,7 +19642,7 @@ is_conditional_branch(insn) → bool --- - + ## function `SPARC.is_ret` @@ -19656,7 +19656,7 @@ is_ret(insn) → bool --- - + ## function `SPARC.mprotect_asm` @@ -19670,7 +19670,7 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + ## function `SPARC.register` @@ -19743,7 +19743,7 @@ Refs: --- - + ## function `SPARC64.flag_register_to_human` @@ -19757,7 +19757,7 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + ## function `SPARC64.get_ith_parameter` @@ -19772,7 +19772,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `SPARC64.get_ra` @@ -19786,7 +19786,7 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + ## function `SPARC64.is_branch_taken` @@ -19800,7 +19800,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `SPARC64.is_call` @@ -19814,7 +19814,7 @@ is_call(insn) → bool --- - + ## function `SPARC64.is_conditional_branch` @@ -19828,7 +19828,7 @@ is_conditional_branch(insn) → bool --- - + ## function `SPARC64.is_ret` @@ -19842,7 +19842,7 @@ is_ret(insn) → bool --- - + ## function `SPARC64.mprotect_asm` @@ -19856,7 +19856,7 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + ## function `SPARC64.register` @@ -19874,7 +19874,7 @@ register(name: str) → Union[int, NoneType] ## class `ScanSectionCommand` Search for addresses that are located in a memory mapping (haystack) that belonging to another (needle). - + ## function `ScanSectionCommand.__init__` @@ -19897,7 +19897,7 @@ Return the list of settings for this command. --- - + ## function `ScanSectionCommand.add_setting` @@ -19913,7 +19913,7 @@ add_setting( --- - + ## function `ScanSectionCommand.del_setting` @@ -19925,7 +19925,7 @@ del_setting(name: str) → None --- - + ## function `ScanSectionCommand.do_invoke` @@ -19939,7 +19939,7 @@ do_invoke(argv: List) → None --- - + ## function `ScanSectionCommand.get_setting` @@ -19951,7 +19951,7 @@ get_setting(name) --- - + ## function `ScanSectionCommand.has_setting` @@ -19963,7 +19963,7 @@ has_setting(name: str) → bool --- - + ## function `ScanSectionCommand.invoke` @@ -19977,7 +19977,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ScanSectionCommand.post_load` @@ -19991,7 +19991,7 @@ post_load() → None --- - + ## function `ScanSectionCommand.pre_load` @@ -20005,7 +20005,7 @@ pre_load() → None --- - + ## function `ScanSectionCommand.usage` @@ -20023,7 +20023,7 @@ 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__` @@ -20046,7 +20046,7 @@ Return the list of settings for this command. --- - + ## function `SearchPatternCommand.add_setting` @@ -20062,7 +20062,7 @@ add_setting( --- - + ## function `SearchPatternCommand.del_setting` @@ -20074,7 +20074,7 @@ del_setting(name: str) → None --- - + ## function `SearchPatternCommand.do_invoke` @@ -20088,7 +20088,7 @@ do_invoke(argv: List) → None --- - + ## function `SearchPatternCommand.get_setting` @@ -20100,7 +20100,7 @@ get_setting(name) --- - + ## function `SearchPatternCommand.has_setting` @@ -20112,7 +20112,7 @@ has_setting(name: str) → bool --- - + ## function `SearchPatternCommand.invoke` @@ -20126,7 +20126,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `SearchPatternCommand.post_load` @@ -20140,7 +20140,7 @@ post_load() → None --- - + ## function `SearchPatternCommand.pre_load` @@ -20154,7 +20154,7 @@ pre_load() → None --- - + ## function `SearchPatternCommand.print_loc` @@ -20168,7 +20168,7 @@ print_loc(loc) → None --- - + ## function `SearchPatternCommand.print_section` @@ -20182,7 +20182,7 @@ print_section(section) → None --- - + ## function `SearchPatternCommand.search_pattern` @@ -20194,7 +20194,7 @@ Search a pattern within the whole userland memory. --- - + ## function `SearchPatternCommand.search_pattern_by_address` @@ -20210,7 +20210,7 @@ Search a pattern within a range defined by arguments. --- - + ## function `SearchPatternCommand.usage` @@ -20228,7 +20228,7 @@ usage() → None ## class `Section` GEF representation of process memory sections. - + ## function `Section.__init__` @@ -20261,7 +20261,7 @@ __init__(*args, **kwargs) → None --- - + ## function `Section.is_executable` @@ -20275,7 +20275,7 @@ is_executable() → bool --- - + ## function `Section.is_readable` @@ -20289,7 +20289,7 @@ is_readable() → bool --- - + ## function `Section.is_writable` @@ -20307,7 +20307,7 @@ 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__` @@ -20324,7 +20324,7 @@ __init__() → None --- - + ## function `SectionBaseFunction.arg_to_long` @@ -20338,7 +20338,7 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + ## function `SectionBaseFunction.do_invoke` @@ -20352,7 +20352,7 @@ do_invoke(args: List) → int --- - + ## function `SectionBaseFunction.invoke` @@ -20372,7 +20372,7 @@ invoke(*args) → int - + ## function `Shdr.__init__` @@ -20393,7 +20393,7 @@ __init__(elf, off) → None ## class `ShellcodeCommand` ShellcodeCommand uses @JonathanSalwan simple-yet-awesome shellcode API to download shellcodes. - + ## function `ShellcodeCommand.__init__` @@ -20416,7 +20416,7 @@ Return the list of settings for this command. --- - + ## function `ShellcodeCommand.add_setting` @@ -20432,7 +20432,7 @@ add_setting( --- - + ## function `ShellcodeCommand.del_setting` @@ -20444,7 +20444,7 @@ del_setting(name: str) → None --- - + ## function `ShellcodeCommand.do_invoke` @@ -20458,7 +20458,7 @@ do_invoke(argv: List) → None --- - + ## function `ShellcodeCommand.get_setting` @@ -20470,7 +20470,7 @@ get_setting(name) --- - + ## function `ShellcodeCommand.has_setting` @@ -20482,7 +20482,7 @@ has_setting(name: str) → bool --- - + ## function `ShellcodeCommand.invoke` @@ -20496,7 +20496,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ShellcodeCommand.post_load` @@ -20510,7 +20510,7 @@ post_load() → None --- - + ## function `ShellcodeCommand.pre_load` @@ -20524,7 +20524,7 @@ pre_load() → None --- - + ## function `ShellcodeCommand.usage` @@ -20542,7 +20542,7 @@ usage() → None ## class `ShellcodeGetCommand` Download shellcode from shell-storm's shellcode database. - + ## function `ShellcodeGetCommand.__init__` @@ -20565,7 +20565,7 @@ Return the list of settings for this command. --- - + ## function `ShellcodeGetCommand.add_setting` @@ -20581,7 +20581,7 @@ add_setting( --- - + ## function `ShellcodeGetCommand.del_setting` @@ -20593,7 +20593,7 @@ del_setting(name: str) → None --- - + ## function `ShellcodeGetCommand.do_invoke` @@ -20607,7 +20607,7 @@ do_invoke(argv: List) → None --- - + ## function `ShellcodeGetCommand.get_setting` @@ -20619,7 +20619,7 @@ get_setting(name) --- - + ## function `ShellcodeGetCommand.get_shellcode` @@ -20633,7 +20633,7 @@ get_shellcode(sid: int) → None --- - + ## function `ShellcodeGetCommand.has_setting` @@ -20645,7 +20645,7 @@ has_setting(name: str) → bool --- - + ## function `ShellcodeGetCommand.invoke` @@ -20659,7 +20659,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ShellcodeGetCommand.post_load` @@ -20673,7 +20673,7 @@ post_load() → None --- - + ## function `ShellcodeGetCommand.pre_load` @@ -20687,7 +20687,7 @@ pre_load() → None --- - + ## function `ShellcodeGetCommand.usage` @@ -20705,7 +20705,7 @@ usage() → None ## class `ShellcodeSearchCommand` Search pattern in shell-storm's shellcode database. - + ## function `ShellcodeSearchCommand.__init__` @@ -20728,7 +20728,7 @@ Return the list of settings for this command. --- - + ## function `ShellcodeSearchCommand.add_setting` @@ -20744,7 +20744,7 @@ add_setting( --- - + ## function `ShellcodeSearchCommand.del_setting` @@ -20756,7 +20756,7 @@ del_setting(name: str) → None --- - + ## function `ShellcodeSearchCommand.do_invoke` @@ -20770,7 +20770,7 @@ do_invoke(argv: List) → None --- - + ## function `ShellcodeSearchCommand.get_setting` @@ -20782,7 +20782,7 @@ get_setting(name) --- - + ## function `ShellcodeSearchCommand.has_setting` @@ -20794,7 +20794,7 @@ has_setting(name: str) → bool --- - + ## function `ShellcodeSearchCommand.invoke` @@ -20808,7 +20808,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `ShellcodeSearchCommand.post_load` @@ -20822,7 +20822,7 @@ post_load() → None --- - + ## function `ShellcodeSearchCommand.pre_load` @@ -20836,7 +20836,7 @@ pre_load() → None --- - + ## function `ShellcodeSearchCommand.search_shellcode` @@ -20850,7 +20850,7 @@ search_shellcode(search_options: List) → None --- - + ## function `ShellcodeSearchCommand.usage` @@ -20868,7 +20868,7 @@ usage() → None ## class `SmartEvalCommand` SmartEval: Smart eval (vague approach to mimic WinDBG `?`). - + ## function `SmartEvalCommand.__init__` @@ -20891,7 +20891,7 @@ Return the list of settings for this command. --- - + ## function `SmartEvalCommand.add_setting` @@ -20907,7 +20907,7 @@ add_setting( --- - + ## function `SmartEvalCommand.del_setting` @@ -20919,7 +20919,7 @@ del_setting(name: str) → None --- - + ## function `SmartEvalCommand.distance` @@ -20933,7 +20933,7 @@ distance(args: Tuple[str, str]) --- - + ## function `SmartEvalCommand.do_invoke` @@ -20947,7 +20947,7 @@ do_invoke(argv: List) → None --- - + ## function `SmartEvalCommand.evaluate` @@ -20961,7 +20961,7 @@ evaluate(expr: List) → None --- - + ## function `SmartEvalCommand.get_setting` @@ -20973,7 +20973,7 @@ get_setting(name) --- - + ## function `SmartEvalCommand.has_setting` @@ -20985,7 +20985,7 @@ has_setting(name: str) → bool --- - + ## function `SmartEvalCommand.invoke` @@ -20999,7 +20999,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `SmartEvalCommand.post_load` @@ -21013,7 +21013,7 @@ post_load() → None --- - + ## function `SmartEvalCommand.pre_load` @@ -21027,7 +21027,7 @@ pre_load() → None --- - + ## function `SmartEvalCommand.usage` @@ -21045,7 +21045,7 @@ usage() → None ## class `SolveKernelSymbolCommand` Solve kernel symbols from kallsyms table. - + ## function `SolveKernelSymbolCommand.__init__` @@ -21068,7 +21068,7 @@ Return the list of settings for this command. --- - + ## function `SolveKernelSymbolCommand.add_setting` @@ -21084,7 +21084,7 @@ add_setting( --- - + ## function `SolveKernelSymbolCommand.del_setting` @@ -21096,7 +21096,7 @@ del_setting(name: str) → None --- - + ## function `SolveKernelSymbolCommand.wrapper` @@ -21110,7 +21110,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `SolveKernelSymbolCommand.get_setting` @@ -21122,7 +21122,7 @@ get_setting(name) --- - + ## function `SolveKernelSymbolCommand.has_setting` @@ -21134,7 +21134,7 @@ has_setting(name: str) → bool --- - + ## function `SolveKernelSymbolCommand.invoke` @@ -21148,7 +21148,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `SolveKernelSymbolCommand.post_load` @@ -21162,7 +21162,7 @@ post_load() → None --- - + ## function `SolveKernelSymbolCommand.pre_load` @@ -21176,7 +21176,7 @@ pre_load() → None --- - + ## function `SolveKernelSymbolCommand.usage` @@ -21194,7 +21194,7 @@ usage() → None ## class `StackOffsetFunction` Return the current stack base address plus an optional offset. - + ## function `StackOffsetFunction.__init__` @@ -21211,7 +21211,7 @@ __init__() → None --- - + ## function `StackOffsetFunction.arg_to_long` @@ -21225,7 +21225,7 @@ arg_to_long(args: List, index: int, default: int = 0) → int --- - + ## function `StackOffsetFunction.do_invoke` @@ -21239,7 +21239,7 @@ do_invoke(args: List) → int --- - + ## function `StackOffsetFunction.invoke` @@ -21257,7 +21257,7 @@ invoke(*args) → int ## class `StubBreakpoint` Create a breakpoint to permanently disable a call (fork/alarm/signal/etc.). - + ## function `StubBreakpoint.__init__` @@ -21274,7 +21274,7 @@ __init__(func: str, retval: Optional[int]) → None --- - + ## function `StubBreakpoint.stop` @@ -21292,7 +21292,7 @@ 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__` @@ -21315,7 +21315,7 @@ Return the list of settings for this command. --- - + ## function `StubCommand.add_setting` @@ -21331,7 +21331,7 @@ add_setting( --- - + ## function `StubCommand.del_setting` @@ -21343,7 +21343,7 @@ del_setting(name: str) → None --- - + ## function `StubCommand.wrapper` @@ -21357,7 +21357,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `StubCommand.get_setting` @@ -21369,7 +21369,7 @@ get_setting(name) --- - + ## function `StubCommand.has_setting` @@ -21381,7 +21381,7 @@ has_setting(name: str) → bool --- - + ## function `StubCommand.invoke` @@ -21395,7 +21395,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `StubCommand.post_load` @@ -21409,7 +21409,7 @@ post_load() → None --- - + ## function `StubCommand.pre_load` @@ -21423,7 +21423,7 @@ pre_load() → None --- - + ## function `StubCommand.usage` @@ -21441,7 +21441,7 @@ usage() → None ## class `SyscallArgsCommand` Gets the syscall name and arguments based on the register values in the current state. - + ## function `SyscallArgsCommand.__init__` @@ -21464,7 +21464,7 @@ Return the list of settings for this command. --- - + ## function `SyscallArgsCommand.add_setting` @@ -21480,7 +21480,7 @@ add_setting( --- - + ## function `SyscallArgsCommand.del_setting` @@ -21492,7 +21492,7 @@ del_setting(name: str) → None --- - + ## function `SyscallArgsCommand.do_invoke` @@ -21506,7 +21506,7 @@ do_invoke(argv: List) → None --- - + ## function `SyscallArgsCommand.get_filepath` @@ -21520,7 +21520,7 @@ get_filepath(x: str) → Union[str, NoneType] --- - + ## function `SyscallArgsCommand.get_module` @@ -21534,7 +21534,7 @@ get_module(modname: str) --- - + ## function `SyscallArgsCommand.get_setting` @@ -21546,7 +21546,7 @@ get_setting(name) --- - + ## function `SyscallArgsCommand.get_settings_path` @@ -21560,7 +21560,7 @@ get_settings_path() → Union[pathlib.Path, NoneType] --- - + ## function `SyscallArgsCommand.get_syscall_table` @@ -21574,7 +21574,7 @@ get_syscall_table(modname: str) --- - + ## function `SyscallArgsCommand.has_setting` @@ -21586,7 +21586,7 @@ has_setting(name: str) → bool --- - + ## function `SyscallArgsCommand.invoke` @@ -21600,7 +21600,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `SyscallArgsCommand.post_load` @@ -21614,7 +21614,7 @@ post_load() → None --- - + ## function `SyscallArgsCommand.pre_load` @@ -21628,7 +21628,7 @@ pre_load() → None --- - + ## function `SyscallArgsCommand.usage` @@ -21646,7 +21646,7 @@ usage() → None ## class `TraceFreeBreakpoint` Track calls to free() and attempts to detect inconsistencies. - + ## function `TraceFreeBreakpoint.__init__` @@ -21663,7 +21663,7 @@ __init__() → None --- - + ## function `TraceFreeBreakpoint.stop` @@ -21681,7 +21681,7 @@ stop() → bool ## class `TraceFreeRetBreakpoint` Internal temporary breakpoint to track free()d values. - + ## function `TraceFreeRetBreakpoint.__init__` @@ -21698,7 +21698,7 @@ __init__(addr: int) → None --- - + ## function `TraceFreeRetBreakpoint.stop` @@ -21716,7 +21716,7 @@ stop() → bool ## class `TraceMallocBreakpoint` Track allocations done with malloc() or calloc(). - + ## function `TraceMallocBreakpoint.__init__` @@ -21733,7 +21733,7 @@ __init__(name: str) → None --- - + ## function `TraceMallocBreakpoint.stop` @@ -21751,7 +21751,7 @@ stop() → bool ## class `TraceMallocRetBreakpoint` Internal temporary breakpoint to retrieve the return value of malloc(). - + ## function `TraceMallocRetBreakpoint.__init__` @@ -21768,7 +21768,7 @@ __init__(size: int, name: str) → None --- - + ## function `TraceMallocRetBreakpoint.stop` @@ -21786,7 +21786,7 @@ stop() → bool ## class `TraceReallocBreakpoint` Track re-allocations done with realloc(). - + ## function `TraceReallocBreakpoint.__init__` @@ -21803,7 +21803,7 @@ __init__() → None --- - + ## function `TraceReallocBreakpoint.stop` @@ -21821,7 +21821,7 @@ stop() → bool ## class `TraceReallocRetBreakpoint` Internal temporary breakpoint to retrieve the return value of realloc(). - + ## function `TraceReallocRetBreakpoint.__init__` @@ -21838,7 +21838,7 @@ __init__(ptr: int, size: int) → None --- - + ## function `TraceReallocRetBreakpoint.stop` @@ -21856,7 +21856,7 @@ 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__` @@ -21879,7 +21879,7 @@ Return the list of settings for this command. --- - + ## function `TraceRunCommand.add_setting` @@ -21895,7 +21895,7 @@ add_setting( --- - + ## function `TraceRunCommand.del_setting` @@ -21907,7 +21907,7 @@ del_setting(name: str) → None --- - + ## function `TraceRunCommand.do_invoke` @@ -21921,7 +21921,7 @@ do_invoke(argv: List) → None --- - + ## function `TraceRunCommand.get_frames_size` @@ -21935,7 +21935,7 @@ get_frames_size() → int --- - + ## function `TraceRunCommand.get_setting` @@ -21947,7 +21947,7 @@ get_setting(name) --- - + ## function `TraceRunCommand.has_setting` @@ -21959,7 +21959,7 @@ has_setting(name: str) → bool --- - + ## function `TraceRunCommand.invoke` @@ -21973,7 +21973,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `TraceRunCommand.post_load` @@ -21987,7 +21987,7 @@ post_load() → None --- - + ## function `TraceRunCommand.pre_load` @@ -22001,7 +22001,7 @@ pre_load() → None --- - + ## function `TraceRunCommand.start_tracing` @@ -22015,7 +22015,7 @@ start_tracing(loc_start: int, loc_end: int, depth: int) → None --- - + ## function `TraceRunCommand.trace` @@ -22029,7 +22029,7 @@ trace(loc_start: int, loc_end: int, depth: int) → None --- - + ## function `TraceRunCommand.usage` @@ -22047,7 +22047,7 @@ usage() → None ## class `UafWatchpoint` Custom watchpoints set TraceFreeBreakpoint() to monitor free()d pointers being used. - + ## function `UafWatchpoint.__init__` @@ -22064,7 +22064,7 @@ __init__(addr: int) → None --- - + ## function `UafWatchpoint.stop` @@ -22080,7 +22080,7 @@ If this method is triggered, we likely have a UaF. Break the execution and repor ## class `UnicornEmulateCommand` Use Unicorn-Engine to emulate the behavior of the binary, without affecting the GDB runtime. By default the command will emulate only the next instruction, but location and number of instruction can be changed via arguments to the command line. By default, it will emulate the next instruction from current PC. - + ## function `UnicornEmulateCommand.__init__` @@ -22103,7 +22103,7 @@ Return the list of settings for this command. --- - + ## function `UnicornEmulateCommand.add_setting` @@ -22119,7 +22119,7 @@ add_setting( --- - + ## function `UnicornEmulateCommand.del_setting` @@ -22131,7 +22131,7 @@ del_setting(name: str) → None --- - + ## function `UnicornEmulateCommand.wrapper` @@ -22145,7 +22145,7 @@ wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] --- - + ## function `UnicornEmulateCommand.get_setting` @@ -22157,7 +22157,7 @@ get_setting(name) --- - + ## function `UnicornEmulateCommand.get_unicorn_end_addr` @@ -22171,7 +22171,7 @@ get_unicorn_end_addr(start_addr: int, nb: int) → int --- - + ## function `UnicornEmulateCommand.has_setting` @@ -22183,7 +22183,7 @@ has_setting(name: str) → bool --- - + ## function `UnicornEmulateCommand.invoke` @@ -22197,7 +22197,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `UnicornEmulateCommand.post_load` @@ -22211,7 +22211,7 @@ post_load() → None --- - + ## function `UnicornEmulateCommand.pre_load` @@ -22225,7 +22225,7 @@ pre_load() → None --- - + ## function `UnicornEmulateCommand.run_unicorn` @@ -22239,7 +22239,7 @@ run_unicorn(start_insn_addr: int, end_insn_addr: int, *args, **kwargs) → None --- - + ## function `UnicornEmulateCommand.usage` @@ -22257,7 +22257,7 @@ usage() → None ## 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__` @@ -22280,7 +22280,7 @@ Return the list of settings for this command. --- - + ## function `VMMapCommand.add_setting` @@ -22296,7 +22296,7 @@ add_setting( --- - + ## function `VMMapCommand.del_setting` @@ -22308,7 +22308,7 @@ del_setting(name: str) → None --- - + ## function `VMMapCommand.do_invoke` @@ -22322,7 +22322,7 @@ do_invoke(argv: List) → None --- - + ## function `VMMapCommand.get_setting` @@ -22334,7 +22334,7 @@ get_setting(name) --- - + ## function `VMMapCommand.has_setting` @@ -22346,7 +22346,7 @@ has_setting(name: str) → bool --- - + ## function `VMMapCommand.invoke` @@ -22360,7 +22360,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `VMMapCommand.is_integer` @@ -22374,7 +22374,7 @@ is_integer(n: str) → bool --- - + ## function `VMMapCommand.post_load` @@ -22388,7 +22388,7 @@ post_load() → None --- - + ## function `VMMapCommand.pre_load` @@ -22402,7 +22402,7 @@ pre_load() → None --- - + ## function `VMMapCommand.print_entry` @@ -22416,7 +22416,7 @@ print_entry(entry: __main__.Section) → None --- - + ## function `VMMapCommand.show_legend` @@ -22430,7 +22430,7 @@ show_legend() → None --- - + ## function `VMMapCommand.usage` @@ -22448,7 +22448,7 @@ usage() → None ## class `VersionCommand` Display GEF version info. - + ## function `VersionCommand.__init__` @@ -22471,7 +22471,7 @@ Return the list of settings for this command. --- - + ## function `VersionCommand.add_setting` @@ -22487,7 +22487,7 @@ add_setting( --- - + ## function `VersionCommand.del_setting` @@ -22499,7 +22499,7 @@ del_setting(name: str) → None --- - + ## function `VersionCommand.do_invoke` @@ -22513,7 +22513,7 @@ do_invoke(argv: List) → None --- - + ## function `VersionCommand.get_setting` @@ -22525,7 +22525,7 @@ get_setting(name) --- - + ## function `VersionCommand.has_setting` @@ -22537,7 +22537,7 @@ has_setting(name: str) → bool --- - + ## function `VersionCommand.invoke` @@ -22551,7 +22551,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `VersionCommand.post_load` @@ -22565,7 +22565,7 @@ post_load() → None --- - + ## function `VersionCommand.pre_load` @@ -22579,7 +22579,7 @@ pre_load() → None --- - + ## function `VersionCommand.usage` @@ -22636,7 +22636,7 @@ usage() → None --- - + ## function `X86.flag_register_to_human` @@ -22650,7 +22650,7 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + ## function `X86.get_ith_parameter` @@ -22667,7 +22667,7 @@ get_ith_parameter( --- - + ## function `X86.get_ra` @@ -22681,7 +22681,7 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + ## function `X86.is_branch_taken` @@ -22695,7 +22695,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `X86.is_call` @@ -22709,7 +22709,7 @@ is_call(insn) → bool --- - + ## function `X86.is_conditional_branch` @@ -22723,7 +22723,7 @@ is_conditional_branch(insn) → bool --- - + ## function `X86.is_ret` @@ -22737,7 +22737,7 @@ is_ret(insn) → bool --- - + ## function `X86.mprotect_asm` @@ -22751,7 +22751,7 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + ## function `X86.register` @@ -22808,7 +22808,7 @@ register(name: str) → Union[int, NoneType] --- - + ## function `X86_64.flag_register_to_human` @@ -22822,7 +22822,7 @@ flag_register_to_human(val: Optional[int] = None) → str --- - + ## function `X86_64.get_ith_parameter` @@ -22837,7 +22837,7 @@ Retrieves the correct parameter used for the current function call. --- - + ## function `X86_64.get_ra` @@ -22851,7 +22851,7 @@ get_ra(insn, frame) → Union[int, NoneType] --- - + ## function `X86_64.is_branch_taken` @@ -22865,7 +22865,7 @@ is_branch_taken(insn) → Tuple[bool, str] --- - + ## function `X86_64.is_call` @@ -22879,7 +22879,7 @@ is_call(insn) → bool --- - + ## function `X86_64.is_conditional_branch` @@ -22893,7 +22893,7 @@ is_conditional_branch(insn) → bool --- - + ## function `X86_64.is_ret` @@ -22907,7 +22907,7 @@ is_ret(insn) → bool --- - + ## function `X86_64.mprotect_asm` @@ -22921,7 +22921,7 @@ mprotect_asm(addr: int, size: int, perm) → str --- - + ## function `X86_64.register` @@ -22939,7 +22939,7 @@ register(name: str) → Union[int, NoneType] ## class `XAddressInfoCommand` Retrieve and display runtime information for the location(s) given as parameter. - + ## function `XAddressInfoCommand.__init__` @@ -22962,7 +22962,7 @@ Return the list of settings for this command. --- - + ## function `XAddressInfoCommand.add_setting` @@ -22978,7 +22978,7 @@ add_setting( --- - + ## function `XAddressInfoCommand.del_setting` @@ -22990,7 +22990,7 @@ del_setting(name: str) → None --- - + ## function `XAddressInfoCommand.do_invoke` @@ -23004,7 +23004,7 @@ do_invoke(argv: List) → None --- - + ## function `XAddressInfoCommand.get_setting` @@ -23016,7 +23016,7 @@ get_setting(name) --- - + ## function `XAddressInfoCommand.has_setting` @@ -23028,7 +23028,7 @@ has_setting(name: str) → bool --- - + ## function `XAddressInfoCommand.infos` @@ -23042,7 +23042,7 @@ infos(address: int) → None --- - + ## function `XAddressInfoCommand.invoke` @@ -23056,7 +23056,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `XAddressInfoCommand.post_load` @@ -23070,7 +23070,7 @@ post_load() → None --- - + ## function `XAddressInfoCommand.pre_load` @@ -23084,7 +23084,7 @@ pre_load() → None --- - + ## function `XAddressInfoCommand.usage` @@ -23102,7 +23102,7 @@ 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__` @@ -23125,7 +23125,7 @@ Return the list of settings for this command. --- - + ## function `XFilesCommand.add_setting` @@ -23141,7 +23141,7 @@ add_setting( --- - + ## function `XFilesCommand.del_setting` @@ -23153,7 +23153,7 @@ del_setting(name: str) → None --- - + ## function `XFilesCommand.do_invoke` @@ -23167,7 +23167,7 @@ do_invoke(argv: List) → None --- - + ## function `XFilesCommand.get_setting` @@ -23179,7 +23179,7 @@ get_setting(name) --- - + ## function `XFilesCommand.has_setting` @@ -23191,7 +23191,7 @@ has_setting(name: str) → bool --- - + ## function `XFilesCommand.invoke` @@ -23205,7 +23205,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `XFilesCommand.post_load` @@ -23219,7 +23219,7 @@ post_load() → None --- - + ## function `XFilesCommand.pre_load` @@ -23233,7 +23233,7 @@ pre_load() → None --- - + ## function `XFilesCommand.usage` @@ -23251,7 +23251,7 @@ 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__` @@ -23274,7 +23274,7 @@ Return the list of settings for this command. --- - + ## function `XorMemoryCommand.add_setting` @@ -23290,7 +23290,7 @@ add_setting( --- - + ## function `XorMemoryCommand.del_setting` @@ -23302,7 +23302,7 @@ del_setting(name: str) → None --- - + ## function `XorMemoryCommand.do_invoke` @@ -23316,7 +23316,7 @@ do_invoke(argv: List) → None --- - + ## function `XorMemoryCommand.get_setting` @@ -23328,7 +23328,7 @@ get_setting(name) --- - + ## function `XorMemoryCommand.has_setting` @@ -23340,7 +23340,7 @@ has_setting(name: str) → bool --- - + ## function `XorMemoryCommand.invoke` @@ -23354,7 +23354,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `XorMemoryCommand.post_load` @@ -23368,7 +23368,7 @@ post_load() → None --- - + ## function `XorMemoryCommand.pre_load` @@ -23382,7 +23382,7 @@ pre_load() → None --- - + ## function `XorMemoryCommand.usage` @@ -23400,7 +23400,7 @@ 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__` @@ -23423,7 +23423,7 @@ Return the list of settings for this command. --- - + ## function `XorMemoryDisplayCommand.add_setting` @@ -23439,7 +23439,7 @@ add_setting( --- - + ## function `XorMemoryDisplayCommand.del_setting` @@ -23451,7 +23451,7 @@ del_setting(name: str) → None --- - + ## function `XorMemoryDisplayCommand.do_invoke` @@ -23465,7 +23465,7 @@ do_invoke(argv: List) → None --- - + ## function `XorMemoryDisplayCommand.get_setting` @@ -23477,7 +23477,7 @@ get_setting(name) --- - + ## function `XorMemoryDisplayCommand.has_setting` @@ -23489,7 +23489,7 @@ has_setting(name: str) → bool --- - + ## function `XorMemoryDisplayCommand.invoke` @@ -23503,7 +23503,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `XorMemoryDisplayCommand.post_load` @@ -23517,7 +23517,7 @@ post_load() → None --- - + ## function `XorMemoryDisplayCommand.pre_load` @@ -23531,7 +23531,7 @@ pre_load() → None --- - + ## function `XorMemoryDisplayCommand.usage` @@ -23549,7 +23549,7 @@ 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__` @@ -23572,7 +23572,7 @@ Return the list of settings for this command. --- - + ## function `XorMemoryPatchCommand.add_setting` @@ -23588,7 +23588,7 @@ add_setting( --- - + ## function `XorMemoryPatchCommand.del_setting` @@ -23600,7 +23600,7 @@ del_setting(name: str) → None --- - + ## function `XorMemoryPatchCommand.do_invoke` @@ -23614,7 +23614,7 @@ do_invoke(argv: List) → None --- - + ## function `XorMemoryPatchCommand.get_setting` @@ -23626,7 +23626,7 @@ get_setting(name) --- - + ## function `XorMemoryPatchCommand.has_setting` @@ -23638,7 +23638,7 @@ has_setting(name: str) → bool --- - + ## function `XorMemoryPatchCommand.invoke` @@ -23652,7 +23652,7 @@ invoke(args: str, from_tty: bool) → None --- - + ## function `XorMemoryPatchCommand.post_load` @@ -23666,7 +23666,7 @@ post_load() → None --- - + ## function `XorMemoryPatchCommand.pre_load` @@ -23680,7 +23680,7 @@ pre_load() → None --- - + ## function `XorMemoryPatchCommand.usage` diff --git a/gef.py b/gef.py index 34dd8d8f4..158d6f111 100644 --- a/gef.py +++ b/gef.py @@ -1010,8 +1010,10 @@ def search_for_main_arena(to_string: bool = False) -> Union[int, str]: if is_x86(): addr = align_address_to_size(malloc_hook_addr + gef.arch.ptrsize, 0x20) - elif is_arch(Elf.AARCH64) or is_arch(Elf.ARM): + elif is_arch(Elf.AARCH64): addr = malloc_hook_addr - gef.arch.ptrsize*2 - MallocStateStruct("*0").struct_size + elif is_arch(Elf.ARM): + addr = malloc_hook_addr - gef.arch.ptrsize - MallocStateStruct("*0").struct_size else: raise OSError("Cannot find main_arena for {}".format(gef.arch.arch)) @@ -1205,14 +1207,12 @@ def __init__(self, addr: str) -> None: except: self.__arena = MallocStateStruct(addr) self.__addr = self.__arena.addr - try: - self.top = int(self.top) - self.last_remainder = int(self.last_remainder) - self.n = int(self.next) - self.nfree = int(self.next_free) - self.sysmem = int(self.system_mem) - except gdb.error as e: - err("Glibc arena: {}".format(e)) + + self.top = int(self.top) + self.last_remainder = int(self.last_remainder) + self.n = int(self.next) + self.nfree = int(self.next_free) + self.sysmem = int(self.system_mem) return def __getitem__(self, item): @@ -1233,7 +1233,7 @@ def __iter__(self): if next_arena_address == int(gef.heap.main_arena): break - current_arena = GlibcArena("*{:#x} ".format(next_arena_address)) + current_arena = GlibcArena("*{:#x}".format(next_arena_address)) yield current_arena return @@ -1294,7 +1294,7 @@ def __str__(self): fmt = "{:s}(base={:#x}, top={:#x}, last_remainder={:#x}, next={:#x}, next_free={:#x}, system_mem={:#x})" return fmt.format( Color.colorify("Arena", "blue bold underline"), - self.__addr, self.top, self.last_remainder, self.n, self.nfree, self.sysmem + self.__addr, self.top, self.last_remainder, self.next, self.nfree, self.sysmem ) diff --git a/scripts/generate-api-docs.sh b/scripts/generate-api-docs.sh index 18c2482a3..b59428e47 100644 --- a/scripts/generate-api-docs.sh +++ b/scripts/generate-api-docs.sh @@ -6,7 +6,7 @@ script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) gef_root=$(dirname "$script_dir") output_path="${gef_root}/docs/api/" src_base_url="https://github.com/hugsy/gef/blob/dev/" - +full_doc_path="${gef_root}/docs/api/gef.md" check() { @@ -22,25 +22,27 @@ clean_doc() generate_doc() { + api="$1" + gdb -q \ -ex "pi from lazydocs.generation import generate_docs" \ - -ex "pi generate_docs(paths=['__main__',], output_path='${output_path}')" \ + -ex "pi generate_docs(paths=['${api}'], output_path='${output_path}')" \ -ex quit } fixup_doc() { # rename - mv ${output_path}/__main__.md ${output_path}/gef.md + mv ${output_path}/__main__.md ${full_doc_path} # replace the title - sed -i 's?# module `__main__`?# module `GEF`?' ${output_path}/gef.md + sed -i 's?# module `__main__`?# module `GEF`?' ${full_doc_path} # fix the hrefs - sed -i -ze 's!\n\n## function `\2`!g' ./docs/api/gef.md + sed -i -ze 's!\n\n## function `\2`!g' ${full_doc_path} } check clean_doc -generate_doc ${api} +generate_doc "__main__" fixup_doc From 29a9925e7b40c0abce2483e92476886cc82cac8c Mon Sep 17 00:00:00 2001 From: hugsy Date: Tue, 11 Jan 2022 15:03:54 -0800 Subject: [PATCH 52/62] [tests] fixed `heap set-arena` --- gef.py | 17 ++++++++++------- tests/runtests.py | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/gef.py b/gef.py index 158d6f111..82d43d049 100644 --- a/gef.py +++ b/gef.py @@ -1208,11 +1208,14 @@ def __init__(self, addr: str) -> None: self.__arena = MallocStateStruct(addr) self.__addr = self.__arena.addr - self.top = int(self.top) - self.last_remainder = int(self.last_remainder) - self.n = int(self.next) - self.nfree = int(self.next_free) - self.sysmem = int(self.system_mem) + try: + self.top = int(self.top) + self.last_remainder = int(self.last_remainder) + self.n = int(self.next) + self.nfree = int(self.next_free) + self.sysmem = int(self.system_mem) + except gdb.error as e: + err("Glibc arena: {}".format(e)) return def __getitem__(self, item): @@ -1294,7 +1297,7 @@ def __str__(self): fmt = "{:s}(base={:#x}, top={:#x}, last_remainder={:#x}, next={:#x}, next_free={:#x}, system_mem={:#x})" return fmt.format( Color.colorify("Arena", "blue bold underline"), - self.__addr, self.top, self.last_remainder, self.next, self.nfree, self.sysmem + self.__addr, self.top, self.last_remainder, self.n, self.nfree, self.sysmem ) @@ -6789,7 +6792,7 @@ class GlibcHeapSetArenaCommand(GenericCommand): """Display information on a heap chunk.""" _cmdline_ = "heap set-arena" - _syntax_ = "{:s} [address|symbol]".format(_cmdline_) + _syntax_ = "{:s} [address|&symbol]".format(_cmdline_) _example_ = "{:s} 0x001337001337".format(_cmdline_) def __init__(self) -> None: diff --git a/tests/runtests.py b/tests/runtests.py index 0bc631c3a..dccc34b7e 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -215,7 +215,7 @@ def test_cmd_heap_arenas(self): return def test_cmd_heap_set_arena(self): - cmd = "heap set-arena main_arena" + cmd = "heap set-arena &main_arena" target = _target("heap") self.assertFailIfInactiveSession(gdb_run_cmd(cmd, target=target)) res = gdb_run_silent_cmd(cmd, target=target, after=["heap arenas"]) From adcc1d4dd2f73d36806df149f2e8642499d26b46 Mon Sep 17 00:00:00 2001 From: hugsy Date: Tue, 11 Jan 2022 15:07:46 -0800 Subject: [PATCH 53/62] Fixed PPC specs URL --- gef.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gef.py b/gef.py index 82d43d049..060b05433 100644 --- a/gef.py +++ b/gef.py @@ -699,7 +699,7 @@ class Elf: """Basic ELF parsing. Ref: - http://www.skyfree.org/linux/references/ELF_Format.pdf - - http://refspecs.freestandards.org/elf/elfspec_ppc.pdf + - http://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf - http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html """ ELF_32_BITS = 0x01 From ad518251d5ba4bce289f20e8f778cb176f865f12 Mon Sep 17 00:00:00 2001 From: theguy147 <37738506+theguy147@users.noreply.github.com> Date: Wed, 12 Jan 2022 02:29:45 +0100 Subject: [PATCH 54/62] refactor: use f-strings across codebase (#768) --- gef.py | 1646 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 812 insertions(+), 834 deletions(-) diff --git a/gef.py b/gef.py index 060b05433..dd1481f05 100644 --- a/gef.py +++ b/gef.py @@ -103,7 +103,7 @@ def update_gef(argv: List[str]) -> int: """Try to update `gef` to the latest version pushed on GitHub master branch. Return 0 on success, 1 on failure. """ ver = "dev" if "--dev" in argv[2:] else "master" - latest_gef_data = http_get("https://raw.githubusercontent.com/hugsy/gef/{}/scripts/gef.sh".format(ver,)) + latest_gef_data = http_get(f"https://raw.githubusercontent.com/hugsy/gef/{ver}/scripts/gef.sh") if latest_gef_data is None: print("[-] Failed to get remote gef") return 1 @@ -149,8 +149,8 @@ def update_gef(argv: List[str]) -> int: TICK = "\u2713 " BP_GLYPH = "\u25cf" GEF_PROMPT = "gef\u27a4 " -GEF_PROMPT_ON = "\001\033[1;32m\002{0:s}\001\033[0m\002".format(GEF_PROMPT) -GEF_PROMPT_OFF = "\001\033[1;31m\002{0:s}\001\033[0m\002".format(GEF_PROMPT) +GEF_PROMPT_ON = f"\001\033[1;32m\002{GEF_PROMPT}\001\033[0m\002" +GEF_PROMPT_OFF = f"\001\033[1;31m\002{GEF_PROMPT}\001\033[0m\002" gef : "Gef" = None @@ -281,35 +281,35 @@ def wrapper(*args: Tuple, **kwargs: Dict) -> Any: def p8(x: int, s: bool = False) -> bytes: """Pack one byte respecting the current architecture endianness.""" - return struct.pack(f"{gef.arch.endianness:s}B", x) if not s else struct.pack(f"{gef.arch.endianness:s}b", x) + return struct.pack(f"{gef.arch.endianness}B", x) if not s else struct.pack(f"{gef.arch.endianness}b", x) def p16(x: int, s: bool = False) -> bytes: """Pack one word respecting the current architecture endianness.""" - return struct.pack(f"{gef.arch.endianness:s}H", x) if not s else struct.pack(f"{gef.arch.endianness:s}h", x) + return struct.pack(f"{gef.arch.endianness}H", x) if not s else struct.pack(f"{gef.arch.endianness}h", x) def p32(x: int, s: bool = False) -> bytes: """Pack one dword respecting the current architecture endianness.""" - return struct.pack(f"{gef.arch.endianness:s}I", x) if not s else struct.pack(f"{gef.arch.endianness:s}i", x) + return struct.pack(f"{gef.arch.endianness}I", x) if not s else struct.pack(f"{gef.arch.endianness}i", x) def p64(x: int, s: bool = False) -> bytes: """Pack one qword respecting the current architecture endianness.""" - return struct.pack(f"{gef.arch.endianness:s}Q", x) if not s else struct.pack(f"{gef.arch.endianness:s}q", x) + return struct.pack(f"{gef.arch.endianness}Q", x) if not s else struct.pack(f"{gef.arch.endianness}q", x) def u8(x: bytes, s: bool = False) -> int: """Unpack one byte respecting the current architecture endianness.""" - return struct.unpack(f"{gef.arch.endianness:s}B", x)[0] if not s else struct.unpack(f"{gef.arch.endianness:s}b", x)[0] + return struct.unpack(f"{gef.arch.endianness}B", x)[0] if not s else struct.unpack(f"{gef.arch.endianness}b", x)[0] def u16(x: bytes, s: bool = False) -> int: """Unpack one word respecting the current architecture endianness.""" - return struct.unpack(f"{gef.arch.endianness:s}H", x)[0] if not s else struct.unpack(f"{gef.arch.endianness:s}h", x)[0] + return struct.unpack(f"{gef.arch.endianness}H", x)[0] if not s else struct.unpack(f"{gef.arch.endianness}h", x)[0] def u32(x: bytes, s: bool = False) -> int: """Unpack one dword respecting the current architecture endianness.""" - return struct.unpack(f"{gef.arch.endianness:s}I", x)[0] if not s else struct.unpack("{}i".format(gef.arch.endianness), x)[0] + return struct.unpack(f"{gef.arch.endianness}I", x)[0] if not s else struct.unpack(f"{gef.arch.endianness}i", x)[0] def u64(x: bytes, s: bool = False) -> int: """Unpack one qword respecting the current architecture endianness.""" - return struct.unpack(f"{gef.arch.endianness:s}Q", x)[0] if not s else struct.unpack(f"{gef.arch.endianness:s}q", x)[0] + return struct.unpack(f"{gef.arch.endianness}Q", x)[0] if not s else struct.unpack(f"{gef.arch.endianness}q", x)[0] def is_ascii_string(address: int) -> bool: @@ -394,7 +394,7 @@ def inner_f(*args: Tuple, **kwargs: Dict) -> None: if GDB_VERSION >= required_gdb_version: f(*args, **kwargs) else: - reason = "GDB >= {} for this command".format(required_gdb_version) + reason = f"GDB >= {required_gdb_version} for this command" raise OSError(reason) return inner_f return wrapper @@ -410,7 +410,7 @@ def inner_f(*args: Tuple, **kwargs: Dict) -> None: if gef.arch in valid_architectures: f(*args, **kwargs) else: - reason = "This command cannot work for the '{}' architecture".format(gef.arch.arch) + reason = f"This command cannot work for the '{gef.arch.arch}' architecture" raise OSError(reason) return inner_f return wrapper @@ -678,10 +678,10 @@ def size(self) -> int: @property def realpath(self) -> str: # when in a `gef-remote` session, realpath returns the path to the binary on the local disk, not remote - return self.path if gef.session.remote is None else "/tmp/gef/{:d}/{:s}".format(gef.session.remote, self.path) + return self.path if gef.session.remote is None else f"/tmp/gef/{gef.session.remote:d}/{self.path}" def __str__(self) -> str: - return f"Section({self.page_start:#x}, {self.page_end:#x}, {str(self.permission)})" + return f"Section({self.page_start:#x}, {self.page_end:#x}, {self.permission!s})" Zone = collections.namedtuple("Zone", ["name", "zone_start", "zone_end", "filename"]) @@ -762,7 +762,7 @@ def __init__(self, elf: str = "", minimalist: bool = False) -> None: return if not os.access(elf, os.R_OK): - err("'{0}' not found/readable".format(elf)) + err(f"'{elf}' not found/readable") err("Failed to get file debug information, most of gef features will not work") return @@ -775,24 +775,24 @@ def __init__(self, elf: str = "", minimalist: bool = False) -> None: endian = gef.arch.endianness # off 0x7 - self.e_osabi, self.e_abiversion = struct.unpack("{}BB".format(endian), self.read(2)) + self.e_osabi, self.e_abiversion = struct.unpack(f"{endian}BB", self.read(2)) # off 0x9 self.e_pad = self.read(7) # off 0x10 - self.e_type, self.e_machine, self.e_version = struct.unpack("{}HHI".format(endian), self.read(8)) + self.e_type, self.e_machine, self.e_version = struct.unpack(f"{endian}HHI", self.read(8)) # off 0x18 if self.e_class == Elf.ELF_64_BITS: # if arch 64bits - self.e_entry, self.e_phoff, self.e_shoff = struct.unpack("{}QQQ".format(endian), self.read(24)) + self.e_entry, self.e_phoff, self.e_shoff = struct.unpack(f"{endian}QQQ", self.read(24)) else: # else arch 32bits - self.e_entry, self.e_phoff, self.e_shoff = struct.unpack("{}III".format(endian), self.read(12)) + self.e_entry, self.e_phoff, self.e_shoff = struct.unpack(f"{endian}III", self.read(12)) - self.e_flags, self.e_ehsize, self.e_phentsize, self.e_phnum = struct.unpack("{}IHHH".format(endian), self.read(10)) - self.e_shentsize, self.e_shnum, self.e_shstrndx = struct.unpack("{}HHH".format(endian), self.read(6)) + self.e_flags, self.e_ehsize, self.e_phentsize, self.e_phnum = struct.unpack(f"{endian}IHHH", self.read(10)) + self.e_shentsize, self.e_shnum, self.e_shstrndx = struct.unpack(f"{endian}HHH", self.read(6)) self.phdrs = [] for i in range(self.e_phnum): @@ -858,13 +858,13 @@ def __init__(self, elf: Elf, off: int) -> None: elf.seek(off) endian = gef.arch.endianness if elf.e_class == Elf.ELF_64_BITS: - self.p_type, self.p_flags, self.p_offset = struct.unpack("{}IIQ".format(endian), elf.read(16)) - self.p_vaddr, self.p_paddr = struct.unpack("{}QQ".format(endian), elf.read(16)) - self.p_filesz, self.p_memsz, self.p_align = struct.unpack("{}QQQ".format(endian), elf.read(24)) + self.p_type, self.p_flags, self.p_offset = struct.unpack(f"{endian}IIQ", elf.read(16)) + self.p_vaddr, self.p_paddr = struct.unpack(f"{endian}QQ", elf.read(16)) + self.p_filesz, self.p_memsz, self.p_align = struct.unpack(f"{endian}QQQ", elf.read(24)) else: - self.p_type, self.p_offset = struct.unpack("{}II".format(endian), elf.read(8)) - self.p_vaddr, self.p_paddr = struct.unpack("{}II".format(endian), elf.read(8)) - self.p_filesz, self.p_memsz, self.p_flags, self.p_align = struct.unpack("{}IIII".format(endian), elf.read(16)) + self.p_type, self.p_offset = struct.unpack(f"{endian}II", elf.read(8)) + self.p_vaddr, self.p_paddr = struct.unpack(f"{endian}II", elf.read(8)) + self.p_filesz, self.p_memsz, self.p_flags, self.p_align = struct.unpack(f"{endian}IIII", elf.read(16)) class Shdr: @@ -939,24 +939,24 @@ def __init__(self, elf, off) -> None: elf.seek(off) endian = gef.arch.endianness if elf.e_class == Elf.ELF_64_BITS: - self.sh_name, self.sh_type, self.sh_flags = struct.unpack("{}IIQ".format(endian), elf.read(16)) - self.sh_addr, self.sh_offset = struct.unpack("{}QQ".format(endian), elf.read(16)) - self.sh_size, self.sh_link, self.sh_info = struct.unpack("{}QII".format(endian), elf.read(16)) - self.sh_addralign, self.sh_entsize = struct.unpack("{}QQ".format(endian), elf.read(16)) + self.sh_name, self.sh_type, self.sh_flags = struct.unpack(f"{endian}IIQ", elf.read(16)) + self.sh_addr, self.sh_offset = struct.unpack(f"{endian}QQ", elf.read(16)) + self.sh_size, self.sh_link, self.sh_info = struct.unpack(f"{endian}QII", elf.read(16)) + self.sh_addralign, self.sh_entsize = struct.unpack(f"{endian}QQ", elf.read(16)) else: - self.sh_name, self.sh_type, self.sh_flags = struct.unpack("{}III".format(endian), elf.read(12)) - self.sh_addr, self.sh_offset = struct.unpack("{}II".format(endian), elf.read(8)) - self.sh_size, self.sh_link, self.sh_info = struct.unpack("{}III".format(endian), elf.read(12)) - self.sh_addralign, self.sh_entsize = struct.unpack("{}II".format(endian), elf.read(8)) + self.sh_name, self.sh_type, self.sh_flags = struct.unpack(f"{endian}III", elf.read(12)) + self.sh_addr, self.sh_offset = struct.unpack(f"{endian}II", elf.read(8)) + self.sh_size, self.sh_link, self.sh_info = struct.unpack(f"{endian}III", elf.read(12)) + self.sh_addralign, self.sh_entsize = struct.unpack(f"{endian}II", elf.read(8)) stroff = elf.e_shoff + elf.e_shentsize * elf.e_shstrndx if elf.e_class == Elf.ELF_64_BITS: elf.seek(stroff + 16 + 8) - offset = struct.unpack("{}Q".format(endian), elf.read(8))[0] + offset = struct.unpack(f"{endian}Q", elf.read(8))[0] else: elf.seek(stroff + 12 + 4) - offset = struct.unpack("{}I".format(endian), elf.read(4))[0] + offset = struct.unpack(f"{endian}I", elf.read(4))[0] elf.seek(offset + self.sh_name) self.sh_name = "" while True: @@ -985,20 +985,14 @@ def __format__(self, format_spec: str) -> str: else: opcodes_len = int(format_spec[:-1]) - opcodes_text = "".join("{:02x}".format(b) for b in self.opcodes[:opcodes_len]) + opcodes_text = "".join(f"{b:02x}" for b in self.opcodes[:opcodes_len]) if opcodes_len < len(self.opcodes): opcodes_text += "..." - return "{:#10x} {:{:d}} {:16} {:6} {:s}".format(self.address, - opcodes_text, - opcodes_len * 2 + 3, - self.location, - self.mnemonic, - ", ".join(self.operands)) + return (f"{self.address:#10x} {opcodes_text:{opcodes_len * 2 + 3:d}s} {self.location:16} " + f"{self.mnemonic:6} {', '.join(self.operands)}") def __str__(self) -> str: - return "{:#10x} {:16} {:6} {:s}".format( - self.address, self.location, self.mnemonic, ", ".join(self.operands) - ) + return f"{self.address:#10x} {self.location:16} {self.mnemonic:6} {', '.join(self.operands)}" def is_valid(self) -> bool: return "(bad)" not in self.mnemonic @@ -1015,25 +1009,26 @@ def search_for_main_arena(to_string: bool = False) -> Union[int, str]: elif is_arch(Elf.ARM): addr = malloc_hook_addr - gef.arch.ptrsize - MallocStateStruct("*0").struct_size else: - raise OSError("Cannot find main_arena for {}".format(gef.arch.arch)) + raise OSError(f"Cannot find main_arena for {gef.arch.arch}") if to_string: - addr = "*0x{:x}".format(addr) + addr = f"*{addr:#x}" return addr class MallocStateStruct: - """GEF representation of malloc_state from https://github.com/bminor/glibc/blob/glibc-2.28/malloc/malloc.c#L1658""" + """GEF representation of malloc_state + from https://github.com/bminor/glibc/blob/glibc-2.28/malloc/malloc.c#L1658""" def __init__(self, addr: str) -> None: try: - self.__addr = parse_address("&{}".format(addr)) + self.__addr = parse_address(f"&{addr}") except gdb.error: - warn("Could not parse address '&{}' when searching malloc_state struct, " - "using '&main_arena' instead".format(addr)) + warn(f"Could not parse address '&{addr}' when searching malloc_state struct, " + "using '&main_arena' instead") self.__addr = search_for_main_arena() - # if `search_for_main_arena` throws `gdb.error` on symbol lookup: it means the session is not started - # so just propagate the exception + # if `search_for_main_arena` throws `gdb.error` on symbol lookup: + # it means the session is not started, so just propagate the exception self.num_fastbins = 10 self.num_bins = 254 @@ -1236,7 +1231,7 @@ def __iter__(self): if next_arena_address == int(gef.heap.main_arena): break - current_arena = GlibcArena("*{:#x}".format(next_arena_address)) + current_arena = GlibcArena(f"*{next_arena_address:#x} ") yield current_arena return @@ -1294,11 +1289,9 @@ def get_heap_for_ptr(ptr: int) -> int: return ptr & ~(heap_max_size - 1) def __str__(self): - fmt = "{:s}(base={:#x}, top={:#x}, last_remainder={:#x}, next={:#x}, next_free={:#x}, system_mem={:#x})" - return fmt.format( - Color.colorify("Arena", "blue bold underline"), - self.__addr, self.top, self.last_remainder, self.n, self.nfree, self.sysmem - ) + return (f"{Color.colorify('Arena', 'blue bold underline')}(base={self.__addr:#x}, top={self.top:#x}, " + f"last_remainder={self.last_remainder:#x}, next={self.n:#x}, next_free={self.nfree:#x}, " + f"system_mem={self.sysmem:#x})") class GlibcChunk: @@ -1419,9 +1412,9 @@ def is_used(self) -> bool: def str_chunk_size_flag(self) -> str: msg = [] - msg.append("PREV_INUSE flag: {}".format(Color.greenify("On") if self.has_p_bit() else Color.redify("Off"))) - msg.append("IS_MMAPPED flag: {}".format(Color.greenify("On") if self.has_m_bit() else Color.redify("Off"))) - msg.append("NON_MAIN_ARENA flag: {}".format(Color.greenify("On") if self.has_n_bit() else Color.redify("Off"))) + msg.append(f"PREV_INUSE flag: {Color.greenify('On') if self.has_p_bit() else Color.redify('Off')}") + msg.append(f"IS_MMAPPED flag: {Color.greenify('On') if self.has_m_bit() else Color.redify('Off')}") + msg.append(f"NON_MAIN_ARENA flag: {Color.greenify('On') if self.has_n_bit() else Color.redify('Off')}") return "\n".join(msg) def _str_sizes(self) -> str: @@ -1433,13 +1426,13 @@ def _str_sizes(self) -> str: msg.append("Usable size: {0:d} ({0:#x})".format(self.get_usable_size())) failed = True except gdb.MemoryError: - msg.append("Chunk size: Cannot read at {:#x} (corrupted?)".format(self.size_addr)) + msg.append(f"Chunk size: Cannot read at {self.size_addr:#x} (corrupted?)") try: msg.append("Previous chunk size: {0:d} ({0:#x})".format(self.get_prev_chunk_size())) failed = True except gdb.MemoryError: - msg.append("Previous chunk size: Cannot read at {:#x} (corrupted?)".format(self.base_address)) + msg.append(f"Previous chunk size: Cannot read at {self.base_address:#x} (corrupted?)") if failed: msg.append(self.str_chunk_size_flag()) @@ -1452,14 +1445,14 @@ def _str_pointers(self) -> str: msg = [] try: - msg.append("Forward pointer: {0:#x}".format(self.get_fwd_ptr(False))) + msg.append(f"Forward pointer: {self.get_fwd_ptr(False):#x}") except gdb.MemoryError: - msg.append("Forward pointer: {0:#x} (corrupted?)".format(fwd)) + msg.append(f"Forward pointer: {fwd:#x} (corrupted?)") try: - msg.append("Backward pointer: {0:#x}".format(self.get_bkw_ptr())) + msg.append(f"Backward pointer: {self.get_bkw_ptr():#x}") except gdb.MemoryError: - msg.append("Backward pointer: {0:#x} (corrupted?)".format(bkw)) + msg.append(f"Backward pointer: {bkw:#x} (corrupted?)") return "\n".join(msg) @@ -1467,7 +1460,7 @@ def str_as_alloced(self) -> str: return self._str_sizes() def str_as_freed(self) -> str: - return "{}\n\n{}".format(self._str_sizes(), self._str_pointers()) + return f"{self._str_sizes()}\n\n{self._str_pointers()}" def flags_as_string(self) -> str: flags = [] @@ -1482,11 +1475,8 @@ def flags_as_string(self) -> str: return "|".join(flags) def __str__(self): - msg = "{:s}(addr={:#x}, size={:#x}, flags={:s})".format(Color.colorify("Chunk", "yellow bold underline"), - int(self.data_address), - self.get_chunk_size(), - self.flags_as_string()) - return msg + return (f"{Color.colorify('Chunk', 'yellow bold underline')}(addr={self.data_address:#x}, " + f"size={self.get_chunk_size():#x}, flags={self.flags_as_string()})") def psprint(self) -> str: msg = [] @@ -1530,33 +1520,32 @@ def titlify(text: str, color: Optional[str] = None, msg_color: Optional[str] = N if msg_color is None: msg_color = gef.config["theme.default_title_message"] - msg = [] - msg.append(Color.colorify("{} ".format(HORIZONTAL_LINE * nb), color)) - msg.append(Color.colorify(text, msg_color)) - msg.append(Color.colorify(" {}".format(HORIZONTAL_LINE * nb), color)) + msg = [Color.colorify(f"{HORIZONTAL_LINE * nb} ", color), + Color.colorify(text, msg_color), + Color.colorify(f" {HORIZONTAL_LINE * nb}", color)] return "".join(msg) def err(msg: str) -> Optional[int]: - return gef_print("{} {}".format(Color.colorify("[!]", "bold red"), msg)) + return gef_print(f"{Color.colorify('[!]', 'bold red')} {msg}") def warn(msg: str) -> Optional[int]: - return gef_print("{} {}".format(Color.colorify("[*]", "bold yellow"), msg)) + return gef_print(f"{Color.colorify('[*]', 'bold yellow')} {msg}") def ok(msg: str) -> Optional[int]: - return gef_print("{} {}".format(Color.colorify("[+]", "bold green"), msg)) + return gef_print(f"{Color.colorify('[+]', 'bold green')} {msg}") def info(msg: str) -> Optional[int]: - return gef_print("{} {}".format(Color.colorify("[+]", "bold blue"), msg)) + return gef_print(f"{Color.colorify('[+]', 'bold blue')} {msg}") def push_context_message(level: str, message: str) -> None: """Push the message to be displayed the next time the context is invoked.""" if level not in ("error", "warn", "ok", "info"): - err("Invalid level '{}', discarding message".format(level)) + err(f"Invalid level '{level}', discarding message") return gef.ui.context_messages.append((level, message)) return @@ -1575,7 +1564,7 @@ def _show_code_line(fname: str, idx: int) -> str: exc_type, exc_value, exc_traceback = sys.exc_info() gef_print(" Exception raised ".center(80, HORIZONTAL_LINE)) - gef_print("{}: {}".format(Color.colorify(exc_type.__name__, "bold underline red"), exc_value)) + gef_print(f"{Color.colorify(exc_type.__name__, 'bold underline red')}: {exc_value}") gef_print(" Detailed stacktrace ".center(80, HORIZONTAL_LINE)) for fs in traceback.extract_tb(exc_traceback)[::-1]: @@ -1584,23 +1573,21 @@ def _show_code_line(fname: str, idx: int) -> str: if not code or not code.strip(): code = _show_code_line(filename, lineno) - gef_print("""{} File "{}", line {:d}, in {}()""".format(DOWN_ARROW, Color.yellowify(filename), - lineno, Color.greenify(method))) - gef_print(" {} {}".format(RIGHT_ARROW, code)) + gef_print(f"""{DOWN_ARROW} File "{Color.yellowify(filename)}", line {lineno:d}, in {Color.greenify(method)}()""") + gef_print(f" {RIGHT_ARROW} {code}") gef_print(" Version ".center(80, HORIZONTAL_LINE)) gdb.execute("version full") gef_print(" Last 10 GDB commands ".center(80, HORIZONTAL_LINE)) gdb.execute("show commands") gef_print(" Runtime environment ".center(80, HORIZONTAL_LINE)) - gef_print("* GDB: {}".format(gdb.VERSION)) - gef_print("* Python: {:d}.{:d}.{:d} - {:s}".format(sys.version_info.major, sys.version_info.minor, - sys.version_info.micro, sys.version_info.releaselevel)) - gef_print("* OS: {:s} - {:s} ({:s})".format(platform.system(), platform.release(), platform.machine())) + gef_print(f"* GDB: {gdb.VERSION}") + gef_print(f"* Python: {sys.version_info.major:d}.{sys.version_info.minor:d}.{sys.version_info.micro:d} - {sys.version_info.releaselevel}") + gef_print(f"* OS: {platform.system()} - {platform.release()} ({platform.machine()})") try: lsb_release = which("lsb_release") - gdb.execute("!{} -a".format(lsb_release,)) + gdb.execute(f"!{lsb_release} -a") except FileNotFoundError: gef_print("lsb_release is missing, cannot collect additional debug information") @@ -1630,7 +1617,7 @@ def which(program: str) -> Optional[pathlib.Path]: if os.access(fpath, os.X_OK): return fpath - raise FileNotFoundError("Missing file `{:s}`".format(program)) + raise FileNotFoundError(f"Missing file `{program}`") def style_byte(b: int, color: bool = True) -> str: @@ -1641,7 +1628,7 @@ def style_byte(b: int, color: bool = True) -> str: "0a": "blue", "ff": "green", } - sbyte = "{:02x}".format(b) + sbyte = f"{b:02x}" if not color or gef.config["highlight.regex"]: return sbyte @@ -1682,12 +1669,7 @@ def hexdump(source: ByteString, length: int = 0x10, separator: str = ".", show_r else: sym = "" - result.append("{addr:#0{aw}x} {sym} {data:<{dw}} {text}".format(aw=align, - addr=base+i, - sym=sym, - dw=3*length, - data=hexa, - text=text)) + result.append(f"{base + i:#0{align}x} {sym} {hexa:<{3 * length}} {text}") return "\n".join(result) @@ -1713,7 +1695,7 @@ def __init__(self, to="/dev/null") -> None: def __enter__(self) -> None: """Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`.""" gdb.execute("set logging overwrite") - gdb.execute("set logging file {:s}".format(self.redirection_target_file)) + gdb.execute(f"set logging file {self.redirection_target_file}") gdb.execute("set logging redirect on") gdb.execute("set logging on") return @@ -1728,7 +1710,7 @@ def __exit__(self, *exc) -> None: def 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`.""" gdb.execute("set logging overwrite") - gdb.execute("set logging file {:s}".format(to_file)) + gdb.execute(f"set logging file {to_file}") gdb.execute("set logging redirect on") gdb.execute("set logging on") return @@ -1764,7 +1746,7 @@ def gdb_get_location_from_symbol(address: int) -> Optional[Tuple[str, int]]: Return a tuple with the name and offset if found, None otherwise.""" # this is horrible, ugly hack and shitty perf... # find a *clean* way to get gdb.Location from an address - sym = gdb.execute("info symbol {:#x}".format(address), to_string=True) + sym = gdb.execute(f"info symbol {address:#x}", to_string=True) if sym.startswith("No symbol matches"): return None @@ -1944,7 +1926,7 @@ def gef_execute_gdb_script(commands: str) -> None: fname = pathlib.Path(fname) if fname.is_file() and os.access(fname, os.R_OK): - gdb.execute("source {:s}".format(fname)) + gdb.execute(f"source {fname}") fname.unlink() return @@ -2003,7 +1985,7 @@ def get_arch() -> str: arch_str = re.findall(r"\"(.+)\"", arch_str)[0] else: # Unknown, we throw an exception to be safe - raise RuntimeError("Unknown architecture: {}".format(arch_str)) + raise RuntimeError(f"Unknown architecture: {arch_str}") return arch_str @@ -2038,7 +2020,7 @@ def flags_to_human(reg_value: int, value_table: Dict[int, str]) -> str: for i in value_table: flag_str = Color.boldify(value_table[i].upper()) if reg_value & (1< bool: @classmethod def mprotect_asm(cls, addr: int, size: int, perm): - raise OSError("Architecture {:s} not supported yet".format(cls.arch)) + raise OSError(f"Architecture {cls.arch} not supported yet") def is_conditional_branch(self, insn) -> bool: return insn.mnemonic.startswith("b") @@ -2262,7 +2244,7 @@ def long_to_twos_complement(v: int) -> int: rs1 = gef.arch.register(insn.operands[0]) rs2 = gef.arch.register(insn.operands[1]) else: - raise OSError("RISC-V: Failed to get rs1 and rs2 for instruction: `{}`".format(insn)) + raise OSError(f"RISC-V: Failed to get rs1 and rs2 for instruction: `{insn}`") # If the conditional operation is not unsigned, convert the python long into # its two's complement @@ -2273,19 +2255,19 @@ def long_to_twos_complement(v: int) -> int: condition = condition[:-1] if condition == "eq": - if rs1 == rs2: taken, reason = True, "{}={}".format(rs1, rs2) - else: taken, reason = False, "{}!={}".format(rs1, rs2) + if rs1 == rs2: taken, reason = True, f"{rs1}={rs2}" + else: taken, reason = False, f"{rs1}!={rs2}" elif condition == "ne": - if rs1 != rs2: taken, reason = True, "{}!={}".format(rs1, rs2) - else: taken, reason = False, "{}={}".format(rs1, rs2) + if rs1 != rs2: taken, reason = True, f"{rs1}!={rs2}" + else: taken, reason = False, f"{rs1}={rs2}" elif condition == "lt": - if rs1 < rs2: taken, reason = True, "{}<{}".format(rs1, rs2) - else: taken, reason = False, "{}>={}".format(rs1, rs2) + if rs1 < rs2: taken, reason = True, f"{rs1}<{rs2}" + else: taken, reason = False, f"{rs1}>={rs2}" elif condition == "ge": - if rs1 < rs2: taken, reason = True, "{}>={}".format(rs1, rs2) - else: taken, reason = False, "{}<{}".format(rs1, rs2) + if rs1 < rs2: taken, reason = True, f"{rs1}>={rs2}" + else: taken, reason = False, f"{rs1}<{rs2}" else: - raise OSError("RISC-V: Conditional instruction `{:s}` not supported yet".format(insn)) + raise OSError(f"RISC-V: Conditional instruction `{insn}` not supported yet") return taken, reason @@ -2429,13 +2411,13 @@ def mprotect_asm(cls, addr: int, size: int, perm) -> str: _NR_mprotect = 125 insns = [ "push {r0-r2, r7}", - "mov r1, {:d}".format(addr & 0xffff), - "mov r0, {:d}".format((addr & 0xffff0000) >> 16), + f"mov r1, {addr & 0xffff:d}", + f"mov r0, {(addr & 0xffff0000) >> 16:d}", "lsl r0, r0, 16", "add r0, r0, r1", - "mov r1, {:d}".format(size & 0xffff), - "mov r2, {:d}".format(perm & 0xff), - "mov r7, {:d}".format(_NR_mprotect), + f"mov r1, {size & 0xffff:d}", + f"mov r2, {perm & 0xff:d}", + f"mov r7, {_NR_mprotect:d}", "svc 0", "pop {r0-r2, r7}", ] @@ -2489,14 +2471,14 @@ def mprotect_asm(cls, addr: int, size: int, perm) -> str: "str x0, [sp, -16]!", "str x1, [sp, -16]!", "str x2, [sp, -16]!", - "mov x8, {:d}".format(_NR_mprotect), - "movz x0, 0x{:x}".format(addr & 0xFFFF), - "movk x0, 0x{:x}, lsl 16".format((addr >> 16) & 0xFFFF), - "movk x0, 0x{:x}, lsl 32".format((addr >> 32) & 0xFFFF), - "movk x0, 0x{:x}, lsl 48".format((addr >> 48) & 0xFFFF), - "movz x1, 0x{:x}".format(size & 0xFFFF), - "movk x1, 0x{:x}, lsl 16".format((size >> 16) & 0xFFFF), - "mov x2, {:d}".format(perm), + f"mov x8, {_NR_mprotect:d}", + f"movz x0, {addr & 0xFFFF:#x}", + f"movk x0, {(addr >> 16) & 0xFFFF:#x}, lsl 16", + f"movk x0, {(addr >> 32) & 0xFFFF:#x}, lsl 32", + f"movk x0, {(addr >> 48) & 0xFFFF:#x}, lsl 48", + f"movz x1, {size & 0xFFFF:#x}", + f"movk x1, {(size >> 16) & 0xFFFF:#x}, lsl 16", + f"mov x2, {perm:d}", "svc 0", "ldr x2, [sp], 16", "ldr x1, [sp], 16", @@ -2517,26 +2499,26 @@ def is_branch_taken(self, insn) -> Tuple[bool, str]: taken, reason = False, "" if mnemo in {"cbnz", "cbz", "tbnz", "tbz"}: - reg = "${}".format(operands[0]) + reg = f"${operands[0]}" op = gef.arch.register(reg) if mnemo == "cbnz": - if op!=0: taken, reason = True, "{}!=0".format(reg) - else: taken, reason = False, "{}==0".format(reg) + if op!=0: taken, reason = True, f"{reg}!=0" + else: taken, reason = False, f"{reg}==0" elif mnemo == "cbz": - if op == 0: taken, reason = True, "{}==0".format(reg) - else: taken, reason = False, "{}!=0".format(reg) + if op == 0: taken, reason = True, f"{reg}==0" + else: taken, reason = False, f"{reg}!=0" elif mnemo == "tbnz": # operands[1] has one or more white spaces in front, then a #, then the number # so we need to eliminate them i = int(operands[1].strip().lstrip("#")) - if (op & 1< str: _NR_mprotect = 125 insns = [ "pushad", - "mov eax, {:d}".format(_NR_mprotect), - "mov ebx, {:d}".format(addr), - "mov ecx, {:d}".format(size), - "mov edx, {:d}".format(perm), + f"mov eax, {_NR_mprotect:d}", + f"mov ebx, {addr:d}", + f"mov ecx, {size:d}", + f"mov edx, {perm:d}", "int 0x80", "popad", ] @@ -2675,7 +2657,7 @@ def get_ith_parameter(self, i: int, in_func: bool = True) -> Tuple[str, Optional sz = gef.arch.ptrsize loc = sp + (i * sz) val = gef.memory.read_integer(loc) - key = "[sp + {:#x}]".format(i * sz) + key = f"[sp + {i * sz:#x}]" return key, val @@ -2707,10 +2689,10 @@ def mprotect_asm(cls, addr: int, size: int, perm) -> str: "push rdx", "push rcx", "push r11", - "mov rax, {:d}".format(_NR_mprotect), - "mov rdi, {:d}".format(addr), - "mov rsi, {:d}".format(size), - "mov rdx, {:d}".format(perm), + f"mov rax, {_NR_mprotect:d}", + f"mov rdi, {addr:d}", + f"mov rsi, {size:d}", + f"mov rdx, {perm:d}", "syscall", "pop r11", "pop rcx", @@ -2802,12 +2784,12 @@ def mprotect_asm(cls, addr: int, size: int, perm) -> str: "stw 3, 4(1)", # r0 = syscall_code | r3, r4, r5 = args "stw 4, 8(1)", "stw 5, 12(1)", - "li 0, {:d}".format(_NR_mprotect), - "lis 3, {:#x}@h".format(addr), - "ori 3, 3, {:#x}@l".format(addr), - "lis 4, {:#x}@h".format(size), - "ori 4, 4, {:#x}@l".format(size), - "li 5, {:d}".format(perm), + f"li 0, {_NR_mprotect:d}", + f"lis 3, {addr:#x}@h", + f"ori 3, 3, {addr:#x}@l", + f"lis 4, {size:#x}@h", + f"ori 4, 4, {size:#x}@l", + f"li 5, {perm:d}", "sc", "lwz 0, 0(1)", "lwz 3, 4(1)", @@ -2918,11 +2900,11 @@ def mprotect_asm(cls, addr: int, size: int, perm) -> str: insns = ["add %sp, -16, %sp", "st %g1, [ %sp ]", "st %o0, [ %sp + 4 ]", "st %o1, [ %sp + 8 ]", "st %o2, [ %sp + 12 ]", - "sethi %hi({}), %o0".format(hi), - "or %o0, {}, %o0".format(lo), + f"sethi %hi({hi}), %o0", + f"or %o0, {lo}, %o0", "clr %o1", "clr %o2", - "mov {}, %g1".format(_NR_mprotect), + f"mov {_NR_mprotect}, %g1", "t 0x10", "ld [ %sp ], %g1", "ld [ %sp + 4 ], %o0", "ld [ %sp + 8 ], %o1", "ld [ %sp + 12 ], %o2", @@ -2965,11 +2947,11 @@ def mprotect_asm(cls, addr: int, size: int, perm) -> str: insns = ["add %sp, -16, %sp", "st %g1, [ %sp ]", "st %o0, [ %sp + 4 ]", "st %o1, [ %sp + 8 ]", "st %o2, [ %sp + 12 ]", - "sethi %hi({}), %o0".format(hi), - "or %o0, {}, %o0".format(lo), + f"sethi %hi({hi}), %o0", + f"or %o0, {lo}, %o0", "clr %o1", "clr %o2", - "mov {}, %g1".format(_NR_mprotect), + f"mov {_NR_mprotect}, %g1", "t 0x6d", "ld [ %sp ], %g1", "ld [ %sp + 4 ], %o0", "ld [ %sp + 8 ], %o1", "ld [ %sp + 12 ], %o2", @@ -3050,10 +3032,10 @@ def mprotect_asm(cls, addr: int, size: int, perm) -> str: insns = ["addi $sp, $sp, -16", "sw $v0, 0($sp)", "sw $a0, 4($sp)", "sw $a3, 8($sp)", "sw $a3, 12($sp)", - "li $v0, {:d}".format(_NR_mprotect), - "li $a0, {:d}".format(addr), - "li $a1, {:d}".format(size), - "li $a2, {:d}".format(perm), + f"li $v0, {_NR_mprotect:d}", + f"li $a0, {addr:d}", + f"li $a1, {size:d}", + f"li $a2, {perm:d}", "syscall", "lw $v0, 0($sp)", "lw $a1, 4($sp)", "lw $a3, 8($sp)", "lw $a3, 12($sp)", @@ -3163,7 +3145,7 @@ def get_filepath() -> Optional[str]: if filename is None: pid = gef.session.pid if pid > 0: - return download_file("/proc/{:d}/exe".format(pid), use_cache=True) + return download_file(f"/proc/{pid:d}/exe", use_cache=True) return None # if target is remote file, download @@ -3176,7 +3158,7 @@ def get_filepath() -> Optional[str]: return download_file(fname, use_cache=True, local_name=fname) elif gef.session.remote is not None: - return "/tmp/gef/{:d}/{:s}".format(gef.session.remote, get_path_from_info_proc()) + return f"/tmp/gef/{gef.session.remote:d}/{get_path_from_info_proc()}" return filename else: if filename is not None: @@ -3201,19 +3183,19 @@ def download_file(remote_path: str, use_cache: bool = False, local_name: Optiona return str(local_path.absolute()) local_path.parent.mkdir(parents=True, exist_ok=True) - gdb.execute("remote get {0:s} {1:s}".format(remote_path, str(local_path.absolute()))) + gdb.execute(f"remote get {remote_path} {local_path.absolute()}") local_path = str(local_path.absolute()) except gdb.error: # fallback memory view with open(local_path, "w") as f: if is_32bit(): - f.write("00000000-ffffffff rwxp 00000000 00:00 0 {}\n".format(get_filepath())) + f.write(f"00000000-ffffffff rwxp 00000000 00:00 0 {get_filepath()}\n") else: - f.write("0000000000000000-ffffffffffffffff rwxp 00000000 00:00 0 {}\n".format(get_filepath())) + f.write(f"0000000000000000-ffffffffffffffff rwxp 00000000 00:00 0 {get_filepath()}\n") except Exception as e: - err("download_file() failed: {}".format(str(e))) + err(f"download_file() failed: {e}") local_name = None return local_path @@ -3221,7 +3203,7 @@ def download_file(remote_path: str, use_cache: bool = False, local_name: Optiona def get_function_length(sym): """Attempt to get the length of the raw bytes of a function.""" - dis = gdb.execute("disassemble {:s}".format(sym), to_string=True).splitlines() + dis = gdb.execute(f"disassemble {sym}", to_string=True).splitlines() start_addr = int(dis[1].split()[0], 16) end_addr = int(dis[-2].split()[0], 16) return end_addr - start_addr @@ -3363,7 +3345,7 @@ def exit_handler(event) -> None: reset_all_caches() gef.session.qemu_mode = False if gef.session.remote and gef.config["gef-remote.clean_on_exit"] is True: - shutil.rmtree("/tmp/gef/{:d}".format(gef.session.remote)) + shutil.rmtree(f"/tmp/gef/{gef.session.remote:d}") gef.session.remote = None return @@ -3397,8 +3379,8 @@ def load_libc_args() -> None: warn("Config `context.libc_args_path` set but it's not a directory") return - _arch_mode = "{}_{}".format(gef.arch.arch.lower(), gef.arch.mode) - _libc_args_file = "{}/{}.json".format(path, _arch_mode) + _arch_mode = f"{gef.arch.arch.lower()}_{gef.arch.mode}" + _libc_args_file = f"{path}/{_arch_mode}.json" # current arch and mode already loaded if _arch_mode in gef.ui.highlight_table: @@ -3410,10 +3392,10 @@ def load_libc_args() -> None: gef.ui.highlight_table[_arch_mode] = json.load(_libc_args) except FileNotFoundError: del gef.ui.highlight_table[_arch_mode] - warn("Config context.libc_args is set but definition cannot be loaded: file {} not found".format(_libc_args_file)) + warn(f"Config context.libc_args is set but definition cannot be loaded: file {_libc_args_file} not found") except json.decoder.JSONDecodeError as e: del gef.ui.highlight_table[_arch_mode] - warn("Config context.libc_args is set but definition cannot be loaded from file {}: {}".format(_libc_args_file, e)) + warn(f"Config context.libc_args is set but definition cannot be loaded from file {_libc_args_file}: {e}") return @@ -3451,26 +3433,26 @@ def get_generic_arch(module: ModuleType, prefix: str, arch: str, mode: Optional[ {cap,key}stone/unicorn trinity. """ if to_string: - arch = "{:s}.{:s}_ARCH_{:s}".format(module.__name__, prefix, arch) + arch = f"{module.__name__}.{prefix}_ARCH_{arch}" if mode: - mode = "{:s}.{:s}_MODE_{:s}".format(module.__name__, prefix, str(mode)) + mode = f"{module.__name__}.{prefix}_MODE_{mode}" else: mode = "" if is_big_endian(): - mode += " + {:s}.{:s}_MODE_BIG_ENDIAN".format(module.__name__, prefix) + mode += f" + {module.__name__}.{prefix}_MODE_BIG_ENDIAN" else: - mode += " + {:s}.{:s}_MODE_LITTLE_ENDIAN".format(module.__name__, prefix) + mode += f" + {module.__name__}.{prefix}_MODE_LITTLE_ENDIAN" else: - arch = getattr(module, "{:s}_ARCH_{:s}".format(prefix, arch)) + arch = getattr(module, f"{prefix}_ARCH_{arch}") if mode: - mode = getattr(module, "{:s}_MODE_{:s}".format(prefix, mode)) + mode = getattr(module, f"{prefix}_MODE_{mode}") else: mode = 0 if big_endian: - mode |= getattr(module, "{:s}_MODE_BIG_ENDIAN".format(prefix)) + mode |= getattr(module, f"{prefix}_MODE_BIG_ENDIAN") else: - mode |= getattr(module, "{:s}_MODE_LITTLE_ENDIAN".format(prefix)) + mode |= getattr(module, f"{prefix}_MODE_LITTLE_ENDIAN") return arch, mode @@ -3549,7 +3531,7 @@ def get_keystone_arch(arch: Optional[str] = None, mode: Optional[str] = None, en mode = "" for m in modes: arch, _mode = get_generic_arch(keystone, "KS", a, m, endian, to_string) - mode += "|{}".format(_mode) + mode += f"|{_mode}" mode = mode[1:] return arch, mode @@ -3564,11 +3546,11 @@ def get_unicorn_registers(to_string: bool = False) -> Union[Dict[str, int], Dict else: raise OSError("Oops") - const = getattr(unicorn, "{}_const".format(arch)) + const = getattr(unicorn, f"{arch}_const") for reg in gef.arch.all_registers: - regname = "UC_{:s}_REG_{:s}".format(arch.upper(), reg[1:].upper()) + regname = f"UC_{arch.upper()}_REG_{reg[1:].upper()}" if to_string: - regs[reg] = "{:s}.{:s}".format(const.__name__, regname) + regs[reg] = f"{const.__name__}.{regname}" else: regs[reg] = getattr(const, regname) return regs @@ -3583,7 +3565,7 @@ def keystone_assemble(code: str, arch: int, mode: int, *args, **kwargs) -> Optio ks = keystone.Ks(arch, mode) enc, cnt = ks.asm(code, addr) except keystone.KsError as e: - err("Keystone assembler error: {:s}".format(str(e))) + err(f"Keystone assembler error: {e}") return None if cnt == 0: @@ -3662,7 +3644,7 @@ def set_arch(arch=None, default=None): # -> Architecture gef.arch = arches[arch.upper()]() return gef.arch except KeyError: - raise OSError("Specified arch {:s} is not supported".format(arch.upper())) + raise OSError(f"Specified arch {arch.upper()} is not supported") if not gef.binary: elf = get_elf_headers() @@ -3680,9 +3662,9 @@ def set_arch(arch=None, default=None): # -> Architecture try: gef.arch = arches[default.upper()]() except KeyError: - raise OSError("CPU not supported, neither is default {:s}".format(default.upper())) + raise OSError(f"CPU not supported, neither is default {default.upper()}") else: - raise OSError("CPU type is currently not supported: {:s}".format(get_arch())) + raise OSError(f"CPU type is currently not supported: {get_arch()}") return gef.arch @@ -3738,9 +3720,9 @@ def format_address(addr: int) -> str: addr = align_address(addr) if memalign_size == 4: - return "0x{:08x}".format(addr) + return f"{addr:#08x}" - return "0x{:016x}".format(addr) + return f"{addr:#016x}" def format_address_spaces(addr: int, left: bool = True) -> str: @@ -3749,9 +3731,9 @@ def format_address_spaces(addr: int, left: bool = True) -> str: addr = align_address(addr) if not left: - return "0x{:x}".format(addr).rjust(width) + return f"{addr:#x}".rjust(width) - return "0x{:x}".format(addr).ljust(width) + return f"{addr:#x}".ljust(width) def align_address(address: int) -> int: @@ -3868,9 +3850,9 @@ def dereference(addr: int): # -> Optional[gdb.Value] def gef_convenience(value: str) -> str: """Defines a new convenience value.""" global gef - var_name = "$_gef{:d}".format(gef.session.convenience_vars_index) + var_name = f"$_gef{gef.session.convenience_vars_index:d}" gef.session.convenience_vars_index += 1 - gdb.execute("""set {:s} = "{:s}" """.format(var_name, value)) + gdb.execute(f"""set {var_name} = "{value}" """) return var_name @@ -4037,7 +4019,7 @@ def destroy(self) -> None: if not self.bp_num: err("Destroy PIE breakpoint not even set") return - gdb.execute("delete {}".format(self.bp_num)) + gdb.execute(f"delete {self.bp_num}") self.bp_num = 0 return @@ -4067,9 +4049,9 @@ def stop(self) -> bool: content = gef.memory.read_cstring(addr.value) name = addr.info.name if addr.info else addr.section.path msg.append(Color.colorify("Format string helper", "yellow bold")) - msg.append("Possible insecure format string: {:s}('{:s}' {:s} {:#x}: '{:s}')".format(self.location, ptr, RIGHT_ARROW, addr.value, content)) - msg.append("Reason: Call to '{:s}()' with format string argument in position " - "#{:d} is in page {:#x} ({:s}) that has write permission".format(self.location, self.num_args, addr.section.page_start, name)) + msg.append(f"Possible insecure format string: {self.location}('{ptr}' {RIGHT_ARROW} {addr.value:#x}: '{content}')") + msg.append(f"Reason: Call to '{self.location}()' with format string argument in position " + f"#{self.num_args:d} is in page {addr.section.page_start:#x} ({name}) that has write permission") push_context_message("warn", "\n".join(msg)) return True @@ -4084,17 +4066,16 @@ def __init__(self, func: str, retval: Optional[int]) -> None: self.func = func self.retval = retval - m = "All calls to '{:s}' will be skipped".format(self.func) + m = f"All calls to '{self.func}' will be skipped" if self.retval is not None: - m += " (with return value set to {:#x})".format(self.retval) + m += f" (with return value set to {self.retval:#x})" info(m) return def stop(self) -> bool: - m = "Ignoring call to '{:s}' ".format(self.func) - m += "(setting return value to {:#x})".format(self.retval) - gdb.execute("return (unsigned int){:#x}".format(self.retval)) - ok(m) + gdb.execute(f"return (unsigned int){self.retval:#x}") + ok(f"Ignoring call to '{self.func}' " + f"(setting return value to {self.retval:#x})") return False @@ -4112,7 +4093,7 @@ def stop(self) -> bool: info("Restoring original context") gef.memory.write(self.original_pc, self.original_code, len(self.original_code)) info("Restoring $pc") - gdb.execute("set $pc = {:#x}".format(self.original_pc)) + gdb.execute(f"set $pc = {self.original_pc:#x}") return True @@ -4149,7 +4130,7 @@ def stop(self) -> bool: loc = parse_address(gef.arch.return_register) size = self.size - ok("{} - {}({})={:#x}".format(Color.colorify("Heap-Analysis", "yellow bold"), self.name, size, loc)) + ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - {self.name}({size})={loc:#x}") check_heap_overlap = gef.config["heap-analysis-helper.check_heap_overlap"] # pop from free-ed list if it was in it @@ -4189,9 +4170,9 @@ def stop(self) -> bool: msg.append(Color.colorify("Heap-Analysis", "yellow bold")) msg.append("Possible heap overlap detected") - msg.append("Reason {} new allocated chunk {:#x} (of size {:d}) overlaps in-used chunk {:#x} (of size {:#x})".format(RIGHT_ARROW, loc, size, chunk_addr, current_chunk_size)) - msg.append("Writing {0:d} bytes from {1:#x} will reach chunk {2:#x}".format(offset, chunk_addr, loc)) - msg.append("Payload example for chunk {1:#x} (to overwrite {0:#x} headers):".format(loc, chunk_addr)) + 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})") + msg.append(f"Writing {offset:d} bytes from {chunk_addr:#x} will reach chunk {loc:#x}") + msg.append(f"Payload example for chunk {chunk_addr:#x} (to overwrite {loc:#x} headers):") msg.append(" data = 'A'*{0:d} + 'B'*{1:d} + 'C'*{1:d}".format(offset, align)) push_context_message("warn", "\n".join(msg)) return True @@ -4235,11 +4216,11 @@ def stop(self) -> bool: if newloc != self: ok("{} - realloc({:#x}, {})={}".format(Color.colorify("Heap-Analysis", "yellow bold"), self.ptr, self.size, - Color.colorify("{:#x}".format(newloc), "green"),)) + Color.colorify(f"{newloc:#x}", "green"),)) else: ok("{} - realloc({:#x}, {})={}".format(Color.colorify("Heap-Analysis", "yellow bold"), self.ptr, self.size, - Color.colorify("{:#x}".format(newloc), "red"),)) + Color.colorify(f"{newloc:#x}", "red"),)) item = (newloc, self.size) @@ -4250,7 +4231,7 @@ def stop(self) -> bool: item = gef.session.heap_allocated_chunks.pop(idx) except ValueError: if is_debug(): - warn("Chunk {:#x} was not in tracking list".format(self.ptr)) + warn(f"Chunk {self.ptr:#x} was not in tracking list") finally: # add new item to alloc-ed list gef.session.heap_allocated_chunks.append(item) @@ -4275,11 +4256,11 @@ def stop(self) -> bool: check_weird_free = gef.config["heap-analysis-helper.check_weird_free"] check_uaf = gef.config["heap-analysis-helper.check_uaf"] - ok("{} - free({:#x})".format(Color.colorify("Heap-Analysis", "yellow bold"), addr)) + ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - free({addr:#x})") if addr == 0: if check_free_null: msg.append(Color.colorify("Heap-Analysis", "yellow bold")) - msg.append("Attempting to free(NULL) at {:#x}".format(gef.arch.pc)) + msg.append(f"Attempting to free(NULL) at {gef.arch.pc:#x}") msg.append("Reason: if NULL page is allocatable, this can lead to code execution.") push_context_message("warn", "\n".join(msg)) return True @@ -4288,7 +4269,7 @@ def stop(self) -> bool: if addr in [x for (x, y) in gef.session.heap_freed_chunks]: if check_double_free: msg.append(Color.colorify("Heap-Analysis", "yellow bold")) - msg.append("Double-free detected {} free({:#x}) is called at {:#x} but is already in the free-ed list".format(RIGHT_ARROW, addr, gef.arch.pc)) + 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") msg.append("Execution will likely crash...") push_context_message("warn", "\n".join(msg)) return True @@ -4305,7 +4286,7 @@ def stop(self) -> bool: if check_weird_free: msg.append(Color.colorify("Heap-Analysis", "yellow bold")) msg.append("Heap inconsistency detected:") - msg.append("Attempting to free an unknown value: {:#x}".format(addr)) + msg.append(f"Attempting to free an unknown value: {addr:#x}") push_context_message("warn", "\n".join(msg)) return True return False @@ -4340,7 +4321,7 @@ class UafWatchpoint(gdb.Breakpoint): """Custom watchpoints set TraceFreeBreakpoint() to monitor free()d pointers being used.""" def __init__(self, addr: int) -> None: - super().__init__("*{:#x}".format(addr), gdb.BP_WATCHPOINT, internal=True) + super().__init__(f"*{addr:#x}", gdb.BP_WATCHPOINT, internal=True) self.address = addr self.silent = True self.enabled = True @@ -4359,9 +4340,9 @@ def stop(self) -> bool: insn = gef_current_instruction(pc) msg = [] msg.append(Color.colorify("Heap-Analysis", "yellow bold")) - msg.append("Possible Use-after-Free in '{:s}': pointer {:#x} was freed, but is attempted to be used at {:#x}" - .format(get_filepath(), self.address, pc)) - msg.append("{:#x} {:s} {:s}".format(insn.address, insn.mnemonic, Color.yellowify(", ".join(insn.operands)))) + msg.append(f"Possible Use-after-Free in '{get_filepath()}': " + f"pointer {self.address:#x} was freed, but is attempted to be used at {pc:#x}") + msg.append(f"{insn.address:#x} {insn.mnemonic} {Color.yellowify(', '.join(insn.operands))}") push_context_message("warn", "\n".join(msg)) return True @@ -4390,7 +4371,7 @@ def __init__(self, location: str, name: str) -> None: def stop(self) -> bool: reset_all_caches() - push_context_message("info", "Hit breakpoint {} ({})".format(self.loc, Color.colorify(self.name, "red bold"))) + push_context_message("info", f"Hit breakpoint {self.loc} ({Color.colorify(self.name, 'red bold')})") return True @@ -4477,11 +4458,11 @@ def invoke(self, args: str, from_tty: bool) -> None: if is_debug(): show_last_exception() else: - err("Command '{:s}' failed to execute properly, reason: {:s}".format(self._cmdline_, str(e))) + err(f"Command '{self._cmdline_}' failed to execute properly, reason: {e}") return def usage(self) -> None: - err("Syntax\n{}".format(self._syntax_)) + err(f"Syntax\n{self._syntax_}") return @abc.abstractproperty @@ -4506,12 +4487,12 @@ def __sanitize_class_name(clsname): return clsname return "-".join(clsname.split()) class_name = __sanitize_class_name(self.__class__._cmdline_) - return "{:s}.{:s}".format(class_name, name) + return f"{class_name}.{name}" def __iter__(self) -> Generator[str, None, None]: for key in gef.config.keys(): if key.startswith(self._cmdline_): - yield key.replace("{:s}.".format(self._cmdline_), "", 1) + yield key.replace(f"{self._cmdline_}.", "", 1) @property def settings(self) -> List[str]: @@ -4577,8 +4558,8 @@ class VersionCommand(GenericCommand): """Display GEF version info.""" _cmdline_ = "version" - _syntax_ = "{:s}".format(_cmdline_) - _example_ = "{:s}".format(_cmdline_) + _syntax_ = f"{_cmdline_}" + _example_ = f"{_cmdline_}" def do_invoke(self, argv: List) -> None: gef_fpath = pathlib.Path(inspect.stack()[0][1]).expanduser().absolute() @@ -4586,21 +4567,21 @@ def do_invoke(self, argv: List) -> None: with gef_fpath.open("rb") as f: gef_hash = hashlib.sha256(f.read()).hexdigest() - if os.access("{}/.git".format(gef_dir), os.X_OK): + if os.access(f"{gef_dir}/.git", os.X_OK): ver = subprocess.check_output("git log --format='%H' -n 1 HEAD", cwd=gef_dir, shell=True).decode("utf8").strip() extra = "dirty" if len(subprocess.check_output("git ls-files -m", cwd=gef_dir, shell=True).decode("utf8").strip()) else "clean" - gef_print("GEF: rev:{} (Git - {})".format(ver, extra)) + gef_print(f"GEF: rev:{ver} (Git - {extra})") else: - gef_blob_hash = subprocess.check_output("git hash-object {}".format(gef_fpath), shell=True).decode().strip() + gef_blob_hash = subprocess.check_output(f"git hash-object {gef_fpath}", shell=True).decode().strip() gef_print("GEF: (Standalone)") - gef_print("Blob Hash({}): {}".format(gef_fpath, gef_blob_hash)) - gef_print("SHA256({}): {}".format(gef_fpath, gef_hash)) - gef_print("GDB: {}".format(gdb.VERSION, )) - py_ver = "{:d}.{:d}".format(sys.version_info.major, sys.version_info.minor) - gef_print("GDB-Python: {}".format(py_ver, )) + gef_print(f"Blob Hash({gef_fpath}): {gef_blob_hash}") + gef_print(f"SHA256({gef_fpath}): {gef_hash}") + gef_print(f"GDB: {gdb.VERSION}") + py_ver = f"{sys.version_info.major:d}.{sys.version_info.minor:d}" + gef_print(f"GDB-Python: {py_ver}") if "full" in argv: - gef_print("Loaded commands: {}".format(", ".join(gef.gdb.loaded_command_names))) + gef_print(f"Loaded commands: {', '.join(gef.gdb.loaded_command_names)}") return @@ -4613,13 +4594,13 @@ class PrintFormatCommand(GenericCommand): _cmdline_ = "print-format" _aliases_ = ["pf",] - _syntax_ = """{} [--lang LANG] [--bitlen SIZE] [(--length,-l) LENGTH] [--clip] LOCATION -\t--lang LANG specifies the output format for programming language (available: {}, default 'py'). -\t--bitlen SIZE specifies size of bit (possible values: {}, default is 8). -\t--length LENGTH specifies length of array (default is 256). -\t--clip The output data will be copied to clipboard -\tLOCATION specifies where the address of bytes is stored.""".format(_cmdline_, str(valid_formats), str(valid_bitness)) - _example_ = "{} --lang py -l 16 $rsp".format(_cmdline_) + _syntax_ = (f"{_cmdline_} [--lang LANG] [--bitlen SIZE] [(--length,-l) LENGTH] [--clip] LOCATION" + f"\t--lang LANG specifies the output format for programming language (available: {valid_formats!s}, default 'py')." + f"\t--bitlen SIZE specifies size of bit (possible values: {valid_bitness!s}, default is 8)." + "\t--length LENGTH specifies length of array (default is 256)." + "\t--clip The output data will be copied to clipboard" + "\tLOCATION specifies where the address of bytes is stored.") + _example_ = f"{_cmdline_} --lang py -l 16 $rsp" def __init__(self) -> None: @@ -4630,10 +4611,10 @@ def __init__(self) -> None: def format_matrix(self) -> Dict[int, Tuple[str, str, str]]: # `gef.arch.endianness` is a runtime property, should not be defined as a class property return { - 8: (f"{gef.arch.endianness:s}B", "char", "db"), - 16: (f"{gef.arch.endianness:s}H", "short", "dw"), - 32: (f"{gef.arch.endianness:s}I", "int", "dd"), - 64: (f"{gef.arch.endianness:s}Q", "long long", "dq"), + 8: (f"{gef.arch.endianness}B", "char", "db"), + 16: (f"{gef.arch.endianness}H", "short", "dw"), + 32: (f"{gef.arch.endianness}I", "int", "dd"), + 64: (f"{gef.arch.endianness}Q", "long long", "dq"), } @only_if_gdb_running @@ -4645,11 +4626,11 @@ def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any] valid_bitlens = self.format_matrix.keys() if args.bitlen not in valid_bitlens: - err("Size of bit must be in: {}".format(str(valid_bitlens))) + err(f"Size of bit must be in: {valid_bitlens!s}") return if args.lang not in self.valid_formats: - err("Language must be in: {}".format(str(self.valid_formats))) + err(f"Language must be in: {self.valid_formats!s}") return start_addr = parse_address(args.location) @@ -4664,15 +4645,15 @@ def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any] sdata = ", ".join(map(hex, data)) if args.lang == "py": - out = "buf = [{}]".format(sdata) + out = f"buf = [{sdata}]" elif args.lang == "c": c_type = self.format_matrix[args.bitlen][1] - out = "unsigned {0} buf[{1}] = {{{2}}};".format(c_type, args.length, sdata) + out = f"unsigned {c_type} buf[{args.length}] = {{{sdata}}};" elif args.lang == "js": - out = "var buf = [{}]".format(sdata) + out = f"var buf = [{sdata}]" elif args.lang == "asm": asm_type = self.format_matrix[args.bitlen][2] - out = "buf {0} {1}".format(asm_type, sdata) + out = f"buf {asm_type} {sdata}" if args.clip: if copy_to_clipboard(gef_pybytes(out)): @@ -4689,7 +4670,7 @@ class PieCommand(GenericCommand): """PIE breakpoint support.""" _cmdline_ = "pie" - _syntax_ = "{:s} (breakpoint|info|delete|run|attach|remote)".format(_cmdline_) + _syntax_ = f"{_cmdline_} (breakpoint|info|delete|run|attach|remote)" def __init__(self) -> None: super().__init__(prefix=True) @@ -4706,7 +4687,7 @@ class PieBreakpointCommand(GenericCommand): """Set a PIE breakpoint at an offset from the target binaries base address.""" _cmdline_ = "pie breakpoint" - _syntax_ = "{:s} OFFSET".format(_cmdline_) + _syntax_ = f"{_cmdline_} OFFSET" @parse_arguments({"offset": ""}, {}) def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> None: @@ -4716,7 +4697,7 @@ def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any] return addr = parse_address(args.offset) - self.set_pie_breakpoint(lambda base: "b *{}".format(base + addr), addr) + self.set_pie_breakpoint(lambda base: f"b *{base + addr}", addr) # When the process is already on, set real breakpoints immediately if is_alive(): @@ -4738,7 +4719,7 @@ class PieInfoCommand(GenericCommand): """Display breakpoint info.""" _cmdline_ = "pie info" - _syntax_ = "{:s} BREAKPOINT".format(_cmdline_) + _syntax_ = f"{_cmdline_} BREAKPOINT" @parse_arguments({"breakpoints": [-1,]}, {}) def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> None: @@ -4752,7 +4733,7 @@ def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any] lines = [] lines.append("VNum\tNum\tAddr") lines += [ - "{}\t{}\t{}".format(x.vbp_num, x.bp_num if x.bp_num else "N/A", x.addr) for x in bps + f"{x.vbp_num}\t{x.bp_num if x.bp_num else 'N/A'}\t{x.addr}" for x in bps ] gef_print("\n".join(lines)) return @@ -4763,7 +4744,7 @@ class PieDeleteCommand(GenericCommand): """Delete a PIE breakpoint.""" _cmdline_ = "pie delete" - _syntax_ = "{:s} [BREAKPOINT]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [BREAKPOINT]" @parse_arguments({"breakpoints": [-1,]}, {}) def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any]) -> None: @@ -4784,7 +4765,7 @@ def delete_bp(breakpoints: List) -> None: for bp in breakpoints: # delete current real breakpoints if exists if bp.bp_num: - gdb.execute("delete {}".format(bp.bp_num)) + gdb.execute(f"delete {bp.bp_num}") # delete virtual breakpoints del gef.session.pie_breakpoints[bp.vbp_num] return @@ -4805,7 +4786,7 @@ def do_invoke(self, argv: List) -> None: return if not os.access(fpath, os.X_OK): - warn("The file '{}' is not executable.".format(fpath)) + warn(f"The file '{fpath}' is not executable.") return if is_alive(): @@ -4814,12 +4795,12 @@ def do_invoke(self, argv: List) -> None: # get base address gdb.execute("set stop-on-solib-events 1") hide_context() - gdb.execute("run {}".format(" ".join(argv))) + gdb.execute(f"run {' '.join(argv)}") unhide_context() gdb.execute("set stop-on-solib-events 0") vmmap = gef.memory.maps base_address = [x.page_start for x in vmmap if x.path == get_filepath()][0] - info("base address {}".format(hex(base_address))) + info(f"base address {hex(base_address)}") # modify all breakpoints for bp_ins in gef.session.pie_breakpoints.values(): @@ -4838,11 +4819,11 @@ class PieAttachCommand(GenericCommand): """Do attach with PIE breakpoint support.""" _cmdline_ = "pie attach" - _syntax_ = "{:s} PID".format(_cmdline_) + _syntax_ = f"{_cmdline_} PID" def do_invoke(self, argv: List) -> None: try: - gdb.execute("attach {}".format(" ".join(argv)), to_string=True) + gdb.execute(f"attach {' '.join(argv)}", to_string=True) except gdb.error as e: err(e) return @@ -4862,11 +4843,11 @@ class PieRemoteCommand(GenericCommand): """Attach to a remote connection with PIE breakpoint support.""" _cmdline_ = "pie remote" - _syntax_ = "{:s} REMOTE".format(_cmdline_) + _syntax_ = f"{_cmdline_} REMOTE" def do_invoke(self, argv: List) -> None: try: - gdb.execute("gef-remote {}".format(" ".join(argv))) + gdb.execute(f"gef-remote {' '.join(argv)}") except gdb.error as e: err(e) return @@ -4886,8 +4867,9 @@ class SmartEvalCommand(GenericCommand): """SmartEval: Smart eval (vague approach to mimic WinDBG `?`).""" _cmdline_ = "$" - _syntax_ = "{0:s} EXPR\n{0:s} ADDRESS1 ADDRESS2".format(_cmdline_) - _example_ = "\n{0:s} $pc+1\n{0:s} 0x00007ffff7a10000 0x00007ffff7bce000".format(_cmdline_) + _syntax_ = f"{_cmdline_} EXPR\n{_cmdline_} ADDRESS1 ADDRESS2" + _example_ = (f"\n{_cmdline_} $pc+1" + f"\n{_cmdline_} 0x00007ffff7a10000 0x00007ffff7bce000") def do_invoke(self, argv: List) -> None: argc = len(argv) @@ -4902,17 +4884,17 @@ def do_invoke(self, argv: List) -> None: def evaluate(self, expr: List) -> None: def show_as_int(i): off = gef.arch.ptrsize*8 - def comp2_x(x): return "{:x}".format((x + (1 << off)) % (1 << off)) - def comp2_b(x): return "{:b}".format((x + (1 << off)) % (1 << off)) + def comp2_x(x): return f"{(x + (1 << off)) % (1 << off):x}" + def comp2_b(x): return f"{(x + (1 << off)) % (1 << off):b}" try: s_i = comp2_x(res) s_i = s_i.rjust(len(s_i)+1, "0") if len(s_i)%2 else s_i - gef_print("{:d}".format(i)) + gef_print(f"{i:d}") gef_print("0x" + comp2_x(res)) gef_print("0b" + comp2_b(res)) - gef_print("{}".format(binascii.unhexlify(s_i))) - gef_print("{}".format(binascii.unhexlify(s_i)[::-1])) + gef_print(f"{binascii.unhexlify(s_i)}") + gef_print(f"{binascii.unhexlify(s_i)[::-1]}") except: pass return @@ -4922,7 +4904,7 @@ def comp2_b(x): return "{:b}".format((x + (1 << off)) % (1 << off)) try: xp = gdb.parse_and_eval(xp) xp = int(xp) - parsed_expr.append("{:d}".format(xp)) + parsed_expr.append(f"{xp:d}") except gdb.error: parsed_expr.append(str(xp)) @@ -4931,7 +4913,7 @@ def comp2_b(x): return "{:b}".format((x + (1 << off)) % (1 << off)) if isinstance(res, int): show_as_int(res) else: - gef_print("{}".format(res)) + gef_print(f"{res}") except SyntaxError: gef_print(" ".join(parsed_expr)) return @@ -4940,9 +4922,9 @@ def distance(self, args: Tuple[str, str]): try: x = int(args[0], 16) if is_hex(args[0]) else int(args[0]) y = int(args[1], 16) if is_hex(args[1]) else int(args[1]) - gef_print("{}".format(abs(x - y))) + gef_print(f"{abs(x - y)}") except ValueError: - warn("Distance requires 2 numbers: {} 0 0xffff".format(self._cmdline_)) + warn(f"Distance requires 2 numbers: {self._cmdline_} 0 0xffff") return @@ -4968,7 +4950,7 @@ def do_invoke(self, argv: List) -> None: return canary, location = res - info("The canary of process {} is at {:#x}, value is {:#x}".format(gef.session.pid, location, canary)) + info(f"The canary of process {gef.session.pid} is at {location:#x}, value is {canary:#x}") return @@ -4997,7 +4979,7 @@ def do_invoke(self, argv: List) -> None: def get_state_of(self, pid: int) -> Dict[str, str]: res = {} - with open("/proc/{}/status".format(pid), "r") as f: + with open(f"/proc/{pid}/status", "r") as f: file = f.readlines() for line in file: key, value = line.split(":", 1) @@ -5005,14 +4987,14 @@ def get_state_of(self, pid: int) -> Dict[str, str]: return res def get_cmdline_of(self, pid: int) -> str: - with open("/proc/{}/cmdline".format(pid), "r") as f: + with open(f"/proc/{pid}/cmdline", "r") as f: return f.read().replace("\x00", "\x20").strip() def get_process_path_of(self, pid: int) -> str: - return os.readlink("/proc/{}/exe".format(pid)) + return os.readlink(f"/proc/{pid}/exe") def get_children_pids(self, pid: int) -> List[int]: - cmd = [gef.session.constants["ps"], "-o", "pid", "--ppid", "{}".format(pid), "--noheaders"] + cmd = [gef.session.constants["ps"], "-o", "pid", "--ppid", f"{pid}", "--noheaders"] try: return [int(x) for x in gef_execute_external(cmd, as_list=True)] except Exception: @@ -5022,9 +5004,9 @@ def show_info_proc(self) -> None: info("Process Information") pid = gef.session.pid cmdline = self.get_cmdline_of(pid) - gef_print("\tPID {} {}".format(RIGHT_ARROW, pid)) - gef_print("\tExecutable {} {}".format(RIGHT_ARROW, self.get_process_path_of(pid))) - gef_print("\tCommand line {} '{}'".format(RIGHT_ARROW, cmdline)) + gef_print(f"\tPID {RIGHT_ARROW} {pid}") + gef_print(f"\tExecutable {RIGHT_ARROW} {self.get_process_path_of(pid)}") + gef_print(f"\tCommand line {RIGHT_ARROW} '{cmdline}'") return def show_ancestor(self) -> None: @@ -5032,8 +5014,8 @@ def show_ancestor(self) -> None: ppid = int(self.get_state_of(gef.session.pid)["PPid"]) state = self.get_state_of(ppid) cmdline = self.get_cmdline_of(ppid) - gef_print("\tParent PID {} {}".format(RIGHT_ARROW, state["Pid"])) - gef_print("\tCommand line {} '{}'".format(RIGHT_ARROW, cmdline)) + gef_print(f"\tParent PID {RIGHT_ARROW} {state['Pid']}") + gef_print(f"\tCommand line {RIGHT_ARROW} '{cmdline}'") return def show_descendants(self) -> None: @@ -5046,15 +5028,12 @@ def show_descendants(self) -> None: for child_pid in children: state = self.get_state_of(child_pid) pid = state["Pid"] - gef_print("\tPID {} {} (Name: '{}', CmdLine: '{}')".format(RIGHT_ARROW, - pid, - self.get_process_path_of(pid), - self.get_cmdline_of(pid))) + gef_print(f"\tPID {RIGHT_ARROW} {pid} (Name: '{self.get_process_path_of(pid)}', CmdLine: '{self.get_cmdline_of(pid)}')") return def show_fds(self) -> None: pid = gef.session.pid - path = "/proc/{:d}/fd".format(pid) + path = f"/proc/{pid:d}/fd" info("File Descriptors:") items = os.listdir(path) @@ -5065,12 +5044,12 @@ def show_fds(self) -> None: for fname in items: fullpath = os.path.join(path, fname) if os.path.islink(fullpath): - gef_print("\t{:s} {:s} {:s}".format (fullpath, RIGHT_ARROW, os.readlink(fullpath))) + gef_print(f"\t{fullpath} {RIGHT_ARROW} {os.readlink(fullpath)}") return def list_sockets(self, pid: int) -> List[int]: sockets = [] - path = "/proc/{:d}/fd".format(pid) + path = f"/proc/{pid:d}/fd" items = os.listdir(path) for fname in items: fullpath = os.path.join(path, fname) @@ -5112,9 +5091,9 @@ def show_connections(self) -> None: return entries = dict() - with open("/proc/{:d}/net/tcp".format(pid), "r") as tcp: + with open(f"/proc/{pid:d}/net/tcp", "r") as tcp: entries["TCP"] = [x.split() for x in tcp.readlines()[1:]] - with open("/proc/{:d}/net/udp".format(pid), "r") as udp: + with open(f"/proc/{pid:d}/net/udp", "r") as udp: entries["UDP"] = [x.split() for x in udp.readlines()[1:]] for proto in entries: @@ -5127,10 +5106,7 @@ def show_connections(self) -> None: state = int(state, 16) state_str = tcp_states_str[state] if proto == "TCP" else udp_states_str[state] - gef_print("\t{}:{} {} {}:{} ({})".format(local[0], local[1], - RIGHT_ARROW, - remote[0], remote[1], - state_str)) + gef_print(f"\t{local[0]}:{local[1]} {RIGHT_ARROW} {remote[0]}:{remote[1]} ({state_str})") return @@ -5139,7 +5115,7 @@ class GefThemeCommand(GenericCommand): """Customize GEF appearance.""" _cmdline_ = "theme" - _syntax_ = "{:s} [KEY [VALUE]]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [KEY [VALUE]]" def __init__(self, *args, **kwargs) -> None: super().__init__(self._cmdline_) @@ -5170,7 +5146,7 @@ def do_invoke(self, args: List) -> None: for key in self.settings: setting = self[key] value = Color.colorify(setting, setting) - gef_print("{:40s}: {:s}".format(key, value)) + gef_print(f"{key:40s}: {value}") return setting = args[0] @@ -5181,7 +5157,7 @@ def do_invoke(self, args: List) -> None: if argc == 1: value = self[setting] value = Color.colorify(value, value) - gef_print("{:40s}: {:s}".format(setting, value)) + gef_print(f"{setting:40s}: {value}") return val = [x for x in args[1:] if x in Color.colors] @@ -5199,7 +5175,7 @@ class PCustomCommand(GenericCommand): configuration setting.""" _cmdline_ = "pcustom" - _syntax_ = "{:s} [list|edit |show ]| 0xADDRESS]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [list|edit |show ]| 0xADDRESS]" def __init__(self) -> None: super().__init__(prefix=True) @@ -5220,12 +5196,12 @@ def do_invoke(self, argv: List) -> None: modname, structname = self.get_modulename_structname_from_arg(argv[0]) if argc == 1: - gdb.execute("pcustom show {}".format(structname)) + gdb.execute(f"pcustom show {structname}") else: try: address = parse_address(argv[1]) except gdb.error: - err("Failed to parse '{:s}'".format(argv[1])) + err(f"Failed to parse '{argv[1]}'") return self.apply_structure_to_address(modname, structname, address) @@ -5246,7 +5222,7 @@ def get_pcustom_filepath_for_structure(self, structure_name: str) -> str: fpath = fname break if not fpath: - raise FileNotFoundError("no file for structure '{}'".format(structure_name)) + raise FileNotFoundError(f"no file for structure '{structure_name}'") return fpath def is_valid_struct(self, structure_name: str) -> bool: @@ -5279,7 +5255,7 @@ def get_structure_class(self, modname: str, classname: str) -> Tuple[Type, ctype @only_if_gdb_running def apply_structure_to_address(self, mod_name: str, struct_name: str, addr: int, depth: int = 0) -> None: if not self.is_valid_struct(mod_name): - err("Invalid structure name '{:s}'".format(struct_name)) + err(f"Invalid structure name '{struct_name}'") return if depth >= self["max_depth"]: @@ -5290,7 +5266,7 @@ def apply_structure_to_address(self, mod_name: str, struct_name: str, addr: int, _class, _struct = self.get_structure_class(mod_name, struct_name) data = gef.memory.read(addr, ctypes.sizeof(_struct)) except gdb.MemoryError: - err("{}Cannot reach memory {:#x}".format(" " * depth, addr)) + err(f"{' ' * depth}Cannot reach memory {addr:#x}") return self.deserialize(_struct, data) @@ -5310,11 +5286,11 @@ def apply_structure_to_address(self, mod_name: str, struct_name: str, addr: int, line = [] line += " " * depth - line += ("{:#x}+0x{:04x} {} : ".format(addr, _offset, _name)).ljust(40) - line += "{} ({})".format(_value, _type.__name__) + line += (f"{addr:#x}+{_offset:#04x} {_name} : ").ljust(40) + line += f"{_value} ({_type.__name__})" parsed_value = self.get_ctypes_value(_struct, _name, _value) if parsed_value: - line += " {} {}".format(RIGHT_ARROW, parsed_value) + line += f" {RIGHT_ARROW} {parsed_value}" gef_print("".join(line)) if issubclass(_type, ctypes.Structure): @@ -5338,7 +5314,7 @@ def get_ctypes_value(self, struct, item, value) -> str: if value == val: return desc if val is None: default = desc except: - err("Error while trying to obtain values from _values_[\"{}\"]".format(name)) + err(f"Error while trying to obtain values from _values_[\"{name}\"]") return default @@ -5389,7 +5365,7 @@ class PCustomListCommand(PCustomCommand): """PCustom: list available structures""" _cmdline_ = "pcustom list" - _syntax_ = "{:s}".format(_cmdline_) + _syntax_ = f"{_cmdline_}" def __init__(self) -> None: super().__init__() @@ -5402,14 +5378,14 @@ def do_invoke(self, argv: List) -> None: def __list_custom_structures(self) -> None: """Dump the list of all the structures and their respective.""" path = self.get_pcustom_absolute_root_path() - info("Listing custom structures from '{:s}'".format(path)) + info(f"Listing custom structures from '{path}'") structures = self.enumerate_structures() struct_color = gef.config["pcustom.structure_type"] filename_color = gef.config["pcustom.structure_name"] for filename in structures: __modules = ", ".join([Color.colorify(x, struct_color) for x in structures[filename]]) __filename = Color.colorify(filename, filename_color) - gef_print("{:s} {:s} ({:s})".format(RIGHT_ARROW, __filename, __modules)) + gef_print(f"{RIGHT_ARROW} {__filename} ({__modules})") return @@ -5418,7 +5394,7 @@ class PCustomShowCommand(PCustomCommand): """PCustom: show the content of a given structure""" _cmdline_ = "pcustom show" - _syntax_ = "{:s} StructureName".format(_cmdline_) + _syntax_ = f"{_cmdline_} StructureName" __aliases__ = ["pcustom create", "pcustom update"] def __init__(self) -> None: @@ -5437,7 +5413,7 @@ def do_invoke(self, argv: List) -> None: def __dump_structure(self, mod_name: str, struct_name: str) -> None: # If it's a builtin or defined in the ELF use gdb's `ptype` try: - gdb.execute("ptype struct {:s}".format(struct_name)) + gdb.execute(f"ptype struct {struct_name}") return except gdb.error: pass @@ -5447,7 +5423,7 @@ def __dump_structure(self, mod_name: str, struct_name: str) -> None: def __dump_custom_structure(self, mod_name: str, struct_name: str) -> None: if not self.is_valid_struct(mod_name): - err("Invalid structure name '{:s}'".format(struct_name)) + err(f"Invalid structure name '{struct_name}'") return _class, _struct = self.get_structure_class(mod_name, struct_name) @@ -5457,8 +5433,8 @@ def __dump_custom_structure(self, mod_name: str, struct_name: str) -> None: __name = Color.colorify(_name, gef.config["pcustom.structure_name"]) __type = Color.colorify(_type.__name__, gef.config["pcustom.structure_type"]) __size = Color.colorify(hex(_size), gef.config["pcustom.structure_size"]) - __offset = Color.boldify("{:04x}".format(getattr(_class, _name).offset)) - gef_print("{:s} {:32s} {:16s} /* size={:s} */".format(__offset, __name, __type, __size)) + __offset = Color.boldify(f"{getattr(_class, _name).offset:04x}") + gef_print(f"{__offset} {__name:32s} {__type:16s} /* size={__size} */") return @@ -5467,7 +5443,7 @@ class PCustomEditCommand(PCustomCommand): """PCustom: edit the content of a given structure""" _cmdline_ = "pcustom edit" - _syntax_ = "{:s} StructureName".format(_cmdline_) + _syntax_ = f"{_cmdline_} StructureName" __aliases__ = ["pcustom create", "pcustom new", "pcustom update"] def __init__(self) -> None: @@ -5491,10 +5467,10 @@ def __create_or_edit_structure(self, mod_name: str, struct_name: str) -> Optiona try: fullname = self.get_pcustom_filepath_for_structure(mod_name) - info("Editing '{:s}'".format(fullname)) + info(f"Editing '{fullname}'") except FileNotFoundError: fullname = os.sep.join([root, struct_name + ".py"]) - ok("Creating '{:s}' from template".format(fullname)) + ok(f"Creating '{fullname}' from template") self.__create_new_structure_template(struct_name, fullname) cmd = (os.getenv("EDITOR") or "nano").split() @@ -5521,8 +5497,8 @@ class ChangeFdCommand(GenericCommand): """ChangeFdCommand: redirect file descriptor during runtime.""" _cmdline_ = "hijack-fd" - _syntax_ = "{:s} FD_NUM NEW_OUTPUT".format(_cmdline_) - _example_ = "{:s} 2 /tmp/stderr_output.txt".format(_cmdline_) + _syntax_ = f"{_cmdline_} FD_NUM NEW_OUTPUT" + _example_ = f"{_cmdline_} 2 /tmp/stderr_output.txt" @only_if_gdb_running @only_if_gdb_target_local @@ -5531,7 +5507,7 @@ def do_invoke(self, argv: List) -> None: self.usage() return - if not os.access("/proc/{:d}/fd/{:s}".format(gef.session.pid, argv[0]), os.R_OK): + if not os.access(f"/proc/{gef.session.pid:d}/fd/{argv[0]}", os.R_OK): self.usage() return @@ -5544,7 +5520,7 @@ def do_invoke(self, argv: List) -> None: AF_INET = 2 SOCK_STREAM = 1 - res = gdb.execute("""call (int)socket({}, {}, 0)""".format(AF_INET, SOCK_STREAM), to_string=True) + res = gdb.execute(f"""call (int)socket({AF_INET}, {SOCK_STREAM}, 0)""", to_string=True) new_fd = self.get_fd_from_result(res) # fill in memory with sockaddr_in struct contents @@ -5557,34 +5533,34 @@ def do_invoke(self, argv: List) -> None: gef.memory.write(stack_addr + 0x2, struct.pack(" int: # Output example: $1 = 3 res = int(res.split()[2], 0) - res = gdb.execute("""p/d {}""".format(res), to_string=True) + res = gdb.execute(f"""p/d {res}""", to_string=True) res = int(res.split()[2], 0) return res @@ -5596,9 +5572,9 @@ class IdaInteractCommand(GenericCommand): using the same interface.""" _cmdline_ = "ida-interact" - _syntax_ = "{:s} METHOD [ARGS]".format(_cmdline_) + _syntax_ = f"{_cmdline_} METHOD [ARGS]" _aliases_ = ["binaryninja-interact", "bn", "binja"] - _example_ = "\n{0:s} Jump $pc\n{0:s} SetColor $pc ff00ff".format(_cmdline_) + _example_ = f"\n{_cmdline_} Jump $pc\n{_cmdline_} SetColor $pc ff00ff" def __init__(self) -> None: super().__init__(prefix=False) @@ -5628,12 +5604,12 @@ def connect(self, host: Optional[str] = None, port: Optional[int] = None) -> Non port = port or self["port"] try: - sock = xmlrpclib.ServerProxy("http://{:s}:{:d}".format(host, port)) + sock = xmlrpclib.ServerProxy(f"http://{host}:{port:d}") gef_on_stop_hook(ida_synchronize_handler) gef_on_continue_hook(ida_synchronize_handler) self.version = sock.version() except ConnectionRefusedError: - err("Failed to connect to '{:s}:{:d}'".format(host, port)) + err(f"Failed to connect to '{host}:{port:d}'") sock = None self.sock = sock return @@ -5658,7 +5634,7 @@ def parsed_arglist(arglist) -> List[str]: # if the bin is PIE, we need to subtract the base address if is_pie(get_filepath()) and main_base_address <= argval < main_end_address: argval -= main_base_address - args.append("{:#x}".format(argval,)) + args.append(f"{argval:#x}") except Exception: # if gdb can't parse the value, let ida deal with it args.append(arg) @@ -5679,9 +5655,8 @@ def parsed_arglist(arglist) -> List[str]: method_name = argv[0].lower() if method_name == "version": self.version = self.sock.version() - info("Enhancing {:s} with {:s} (SDK {:s})".format(Color.greenify("gef"), - Color.redify(self.version[0]), - Color.yellowify(self.version[1]))) + info(f"Enhancing {Color.greenify('gef')} with {Color.redify(self.version[0])} " + f"(SDK {Color.yellowify(self.version[1])})") return if not is_alive(): @@ -5743,7 +5718,7 @@ def synchronize(self) -> None: try: # it is possible that the server was stopped between now and the last sync - rc = self.sock.sync("{:#x}".format(pc-base_address), list(added), list(removed)) + rc = self.sock.sync(f"{pc-base_address:#x}", list(added), list(removed)) except ConnectionRefusedError: self.disconnect() return @@ -5753,7 +5728,7 @@ def synchronize(self) -> None: # add new bp from IDA for new_bp in ida_added: location = base_address + new_bp - gdb.Breakpoint("*{:#x}".format(location), type=gdb.BP_BREAKPOINT) + gdb.Breakpoint(f"*{location:#x}", type=gdb.BP_BREAKPOINT) self.old_bps.add(location) # and remove the old ones @@ -5802,7 +5777,7 @@ def import_structures(self, structs: Dict[str, List[Tuple[int, str, int]]]) -> N gef_makedirs(path) for struct_name in structs: - fullpath = pathlib.Path(path) / "{}.py".format(struct_name) + fullpath = pathlib.Path(path) / f"{struct_name}.py" with fullpath.open("w") as f: f.write("from ctypes import *\n\n") f.write("class ") @@ -5815,11 +5790,11 @@ def import_structures(self, structs: Dict[str, List[Tuple[int, str, int]]]) -> N elif size == 2: csize = "c_uint16" elif size == 4: csize = "c_uint32" elif size == 8: csize = "c_uint64" - else: csize = "c_byte * {}".format(size) - m = ' (\"{}\", {}),\n'.format(name, csize) + else: csize = f"c_byte * {size}" + m = f' (\"{name}\", {csize}),\n' f.write(m) f.write("]\n") - ok("Success, {:d} structure{:s} imported".format(len(structs), "s" if len(structs)>1 else "")) + ok(f"Success, {len(structs):d} structure{'s' if len(structs) > 1 else ''} imported") return @@ -5829,9 +5804,9 @@ class ScanSectionCommand(GenericCommand): to another (needle).""" _cmdline_ = "scan" - _syntax_ = "{:s} HAYSTACK NEEDLE".format(_cmdline_) + _syntax_ = f"{_cmdline_} HAYSTACK NEEDLE" _aliases_ = ["lookup",] - _example_ = "\n{0:s} stack libc".format(_cmdline_) + _example_ = f"\n{_cmdline_} stack libc" @only_if_gdb_running def do_invoke(self, argv: List) -> None: @@ -5842,8 +5817,8 @@ def do_invoke(self, argv: List) -> None: haystack = argv[0] needle = argv[1] - info("Searching for addresses in '{:s}' that point to '{:s}'" - .format(Color.yellowify(haystack), Color.yellowify(needle))) + info(f"Searching for addresses in '{Color.yellowify(haystack)}' " + f"that point to '{Color.yellowify(needle)}'") if haystack == "binary": haystack = get_filepath() @@ -5884,9 +5859,9 @@ def do_invoke(self, argv: List) -> None: deref = DereferenceCommand.pprint_dereferenced(hstart, int(i / step)) if hname != "": name = Color.colorify(hname, "yellow") - gef_print("{:s}: {:s}".format(name, deref)) + gef_print(f"{name}: {deref}") else: - gef_print(" {:s}".format(deref)) + gef_print(f" {deref}") return @@ -5897,22 +5872,24 @@ class SearchPatternCommand(GenericCommand): the command will also try to look for upwards cross-references to this address.""" _cmdline_ = "search-pattern" - _syntax_ = "{:s} PATTERN [little|big] [section]".format(_cmdline_) + _syntax_ = f"{_cmdline_} PATTERN [little|big] [section]" _aliases_ = ["grep", "xref"] - _example_ = "\n{0:s} AAAAAAAA\n{0:s} 0x555555554000 little stack\n{0:s} AAAA 0x600000-0x601000".format(_cmdline_) + _example_ = (f"\n{_cmdline_} AAAAAAAA" + f"\n{_cmdline_} 0x555555554000 little stack" + f"\n{_cmdline_} AAAA 0x600000-0x601000") def print_section(self, section) -> None: title = "In " if section.path: - title += "'{}'".format(Color.blueify(section.path)) + title += f"'{Color.blueify(section.path)}'" - title += "({:#x}-{:#x})".format(section.page_start, section.page_end) - title += ", permission={}".format(section.permission) + title += f"({section.page_start:#x}-{section.page_end:#x})" + title += f", permission={section.permission}" ok(title) return def print_loc(self, loc) -> None: - gef_print(""" {:#x} - {:#x} {} "{}" """.format(loc[0], loc[1], RIGHT_ARROW, Color.pinkify(loc[2]),)) + gef_print(f""" {loc[0]:#x} - {loc[1]:#x} {RIGHT_ARROW} "{Color.pinkify(loc[2])}" """) return def search_pattern_by_address(self, pattern: str, start_address: int, end_address: int) -> List[Tuple[int, int, Optional[str]]]: @@ -6000,7 +5977,7 @@ def do_invoke(self, argv: List) -> None: pattern = "".join(["\\x" + pattern[i:i + 2] for i in range(len(pattern) - 2, 0, -2)]) if argc == 3: - info("Searching '{:s}' in {:s}".format(Color.yellowify(pattern), argv[2])) + info(f"Searching '{Color.yellowify(pattern)}' in {argv[2]}") if "0x" in argv[2]: start, end = parse_string_range(argv[2]) @@ -6018,7 +5995,7 @@ def do_invoke(self, argv: List) -> None: self.search_pattern(pattern, section_name) else: - info("Searching '{:s}' in memory".format(Color.yellowify(pattern))) + info(f"Searching '{Color.yellowify(pattern)}' in memory") self.search_pattern(pattern, "") return @@ -6028,9 +6005,10 @@ class FlagsCommand(GenericCommand): """Edit flags in a human friendly way.""" _cmdline_ = "edit-flags" - _syntax_ = "{:s} [(+|-|~)FLAGNAME ...]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [(+|-|~)FLAGNAME ...]" _aliases_ = ["flags",] - _example_ = "\n{0:s}\n{0:s} +zero # sets ZERO flag".format(_cmdline_) + _example_ = (f"\n{_cmdline_}" + f"\n{_cmdline_} +zero # sets ZERO flag") def do_invoke(self, argv: List) -> None: for flag in argv: @@ -6041,11 +6019,11 @@ def do_invoke(self, argv: List) -> None: name = flag[1:].lower() if action not in ("+", "-", "~"): - err("Invalid action for flag '{:s}'".format(flag)) + err(f"Invalid action for flag '{flag}'") continue if name not in gef.arch.flags_table.values(): - err("Invalid flag name '{:s}'".format(flag[1:])) + err(f"Invalid flag name '{flag[1:]}'") continue for off in gef.arch.flags_table: @@ -6058,7 +6036,7 @@ def do_invoke(self, argv: List) -> None: else: new_flags = old_flag ^ (1 << off) - gdb.execute("set ({:s}) = {:#x}".format(gef.arch.flag_register, new_flags)) + gdb.execute(f"set ({gef.arch.flag_register}) = {new_flags:#x}") gef_print(gef.arch.flag_register_to_human()) return @@ -6069,11 +6047,11 @@ class ChangePermissionCommand(GenericCommand): """Change a page permission. By default, it will change it to 7 (RWX).""" _cmdline_ = "set-permission" - _syntax_ = "{:s} address [permission]\n"\ - "\taddress\t\tan address within the memory page for which the permissions should be changed\n"\ - "\tpermission\ta 3-bit bitmask with read=1, write=2 and execute=4 as integer".format(_cmdline_) + _syntax_ = (f"{_cmdline_} address [permission]\n" + "\taddress\t\tan address within the memory page for which the permissions should be changed\n" + "\tpermission\ta 3-bit bitmask with read=1, write=2 and execute=4 as integer") _aliases_ = ["mprotect"] - _example_ = "{:s} $sp 7".format(_cmdline_) + _example_ = f"{_cmdline_} $sp 7" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -6113,8 +6091,8 @@ def do_invoke(self, argv: List) -> None: size = sect.page_end - sect.page_start original_pc = gef.arch.pc - info("Generating sys_mprotect({:#x}, {:#x}, '{:s}') stub for arch {:s}" - .format(sect.page_start, size, str(Permission(value=perm)), get_arch())) + info(f"Generating sys_mprotect({sect.page_start:#x}, {size:#x}, " + f"'{Permission(value=perm)!s}') stub for arch {get_arch()}") stub = self.get_stub_by_arch(sect.page_start, size, perm) if stub is None: err("Failed to generate mprotect opcodes") @@ -6123,11 +6101,11 @@ def do_invoke(self, argv: List) -> None: info("Saving original code") original_code = gef.memory.read(original_pc, len(stub)) - bp_loc = "*{:#x}".format(original_pc + len(stub)) - info("Setting a restore breakpoint at {:s}".format(bp_loc)) + bp_loc = f"*{original_pc + len(stub):#x}" + info(f"Setting a restore breakpoint at {bp_loc}") ChangePermissionBreakpoint(bp_loc, original_code, original_pc) - info("Overwriting current memory at {:#x} ({:d} bytes)".format(loc, len(stub))) + info(f"Overwriting current memory at {loc:#x} ({len(stub):d} bytes)") gef.memory.write(original_pc, stub, len(stub)) info("Resuming execution") @@ -6149,16 +6127,15 @@ class UnicornEmulateCommand(GenericCommand): the next instruction from current PC.""" _cmdline_ = "unicorn-emulate" - _syntax_ = """{:s} [--start LOCATION] [--until LOCATION] [--skip-emulation] [--output-file PATH] [NB_INSTRUCTION] -\n\t--start LOCATION specifies the start address of the emulated run (default $pc). -\t--until LOCATION specifies the end address of the emulated run. -\t--skip-emulation\t do not execute the script once generated. -\t--output-file /PATH/TO/SCRIPT.py writes the persistent Unicorn script into this file. -\tNB_INSTRUCTION indicates the number of instructions to execute -\nAdditional options can be setup via `gef config unicorn-emulate` -""".format(_cmdline_) + _syntax_ = (f"{_cmdline_} [--start LOCATION] [--until LOCATION] [--skip-emulation] [--output-file PATH] [NB_INSTRUCTION]" + "\n\t--start LOCATION specifies the start address of the emulated run (default $pc)." + "\t--until LOCATION specifies the end address of the emulated run." + "\t--skip-emulation\t do not execute the script once generated." + "\t--output-file /PATH/TO/SCRIPT.py writes the persistent Unicorn script into this file." + "\tNB_INSTRUCTION indicates the number of instructions to execute" + "\nAdditional options can be setup via `gef config unicorn-emulate`") _aliases_ = ["emulate",] - _example_ = "{0:s} --start $pc 10 --output-file /tmp/my-gef-emulation.py".format(_cmdline_) + _example_ = f"{_cmdline_} --start $pc 10 --output-file /tmp/my-gef-emulation.py" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -6299,7 +6276,7 @@ def reset(): {context_block} """.format(pythonbin=PYTHONBIN, fname=fname, start=start_insn_addr, end=end_insn_addr, - regs=",".join(["'%s': %s" % (k.strip(), unicorn_registers[k]) for k in unicorn_registers]), + regs=",".join([f"'{k.strip()}': {unicorn_registers[k]}" for k in unicorn_registers]), verbose="True" if verbose else "False", syscall_reg=gef.arch.syscall_register, cs_arch=cs_arch, cs_mode=cs_mode, @@ -6313,7 +6290,7 @@ def reset(): for r in gef.arch.all_registers: gregval = gef.arch.register(r) - content += " emu.reg_write({}, {:#x})\n".format(unicorn_registers[r], gregval) + content += f" emu.reg_write({unicorn_registers[r]}, {gregval:#x})\n" vmmap = gef.memory.maps if not vmmap: @@ -6333,16 +6310,16 @@ def reset(): size = sect.size perm = sect.permission - content += " # Mapping {}: {:#x}-{:#x}\n".format(sect.path, page_start, page_end) - content += " emu.mem_map({:#x}, {:#x}, {})\n".format(page_start, size, oct(perm.value)) + content += f" # Mapping {sect.path}: {page_start:#x}-{page_end:#x}\n" + content += f" emu.mem_map({page_start:#x}, {size:#x}, {oct(perm.value)})\n" if perm & Permission.READ: code = gef.memory.read(page_start, size) - loc = "/tmp/gef-{}-{:#x}.raw".format(fname, page_start) + loc = f"/tmp/gef-{fname}-{page_start:#x}.raw" with open(loc, "wb") as f: f.write(bytes(code)) - content += " emu.mem_write({:#x}, open('{}', 'rb').read())\n".format(page_start, loc) + content += f" emu.mem_write({page_start:#x}, open('{loc}', 'rb').read())\n" content += "\n" content += " emu.hook_add(unicorn.UC_HOOK_CODE, code_hook)\n" @@ -6379,13 +6356,13 @@ def emulate(emu, start_addr, end_addr): os.close(tmp_fd) if kwargs.get("to_file", None): - info("Unicorn script generated as '{}'".format(tmp_filename)) + info(f"Unicorn script generated as '{tmp_filename}'") os.chmod(tmp_filename, 0o700) if skip_emulation: return - ok("Starting emulation: {:#x} {} {:#x}".format(start_insn_addr, RIGHT_ARROW, end_insn_addr)) + ok(f"Starting emulation: {start_insn_addr:#x} {RIGHT_ARROW} {end_insn_addr:#x}") res = gef_execute_external([PYTHONBIN, tmp_filename], as_list=True) gef_print("\n".join(res)) @@ -6403,9 +6380,9 @@ class RemoteCommand(GenericCommand): information.""" _cmdline_ = "gef-remote" - _syntax_ = "{:s} [OPTIONS] TARGET".format(_cmdline_) - _example_ = "\n{0:s} --pid 6789 localhost:1234"\ - "\n{0:s} --qemu-mode localhost:4444 # when using qemu-user".format(_cmdline_) + _syntax_ = f"{_cmdline_} [OPTIONS] TARGET" + _example_ = (f"\n{_cmdline_} --pid 6789 localhost:1234" + f"\n{_cmdline_} --qemu-mode localhost:4444 # when using qemu-user") def __init__(self) -> None: super().__init__(prefix=False) @@ -6454,9 +6431,9 @@ def do_invoke(self, argv, *args, **kwargs) -> None: pid = args.pid if args.is_extended_remote and args.pid else gef.session.pid if args.is_extended_remote: - ok("Attaching to {:d}".format(pid)) + ok(f"Attaching to {pid:d}") hide_context() - gdb.execute("attach {:d}".format(pid)) + gdb.execute(f"attach {pid:d}") unhide_context() self.setup_remote_environment(pid, args.update_solib) @@ -6472,11 +6449,11 @@ def do_invoke(self, argv, *args, **kwargs) -> None: if sect.path.startswith("/"): _file = download_file(sect.path) if _file is None: - err("Failed to download {:s}".format(sect.path)) + err(f"Failed to download {sect.path}") else: success += 1 - ok("Downloaded {:d} files".format(success)) + ok(f"Downloaded {success:d} files") elif args.download_lib: _file = download_file(args.download_lib) @@ -6484,7 +6461,7 @@ def do_invoke(self, argv, *args, **kwargs) -> None: err("Failed to download remote file") return - ok("Download success: {:s} {:s} {:s}".format(args.download_lib, RIGHT_ARROW, _file)) + ok(f"Download success: {args.download_lib} {RIGHT_ARROW} {_file}") if args.update_solib: self.refresh_shared_library_path() @@ -6504,7 +6481,7 @@ def new_objfile_handler(self, event) -> None: remote_lib = event.new_objfile.filename[len("target:"):] local_lib = download_file(remote_lib, use_cache=True) if local_lib: - ok("Download success: {:s} {:s} {:s}".format(remote_lib, RIGHT_ARROW, local_lib)) + ok(f"Download success: {remote_lib} {RIGHT_ARROW} {local_lib}") return def setup_remote_environment(self, pid: int, update_solib: bool = False) -> None: @@ -6518,19 +6495,19 @@ def setup_remote_environment(self, pid: int, update_solib: bool = False) -> None for i in ("maps", "environ", "cmdline",): infos[i] = self.load_from_remote_proc(pid, i) if infos[i] is None: - err("Failed to load memory map of '{:s}'".format(i)) + err(f"Failed to load memory map of '{i}'") return exepath = get_path_from_info_proc() - infos["exe"] = download_file("/proc/{:d}/exe".format(pid), use_cache=False, local_name=exepath) + infos["exe"] = download_file(f"/proc/{pid:d}/exe", use_cache=False, local_name=exepath) if not os.access(infos["exe"], os.R_OK): err("Source binary is not readable") return directory = os.path.sep.join([gef.config["gef.tempdir"], str(gef.session.pid)]) - # gdb.execute("file {:s}".format(infos["exe"])) + # gdb.execute(f"file {infos['exe']}") self["root"] = ( directory, "Path to store the remote data") - ok("Remote information loaded to temporary path '{:s}'".format(directory)) + ok(f"Remote information loaded to temporary path '{directory}'") return def connect_target(self, target: str, is_extended_remote: bool) -> bool: @@ -6538,25 +6515,25 @@ def connect_target(self, target: str, is_extended_remote: bool) -> bool: not fetched just yet, we disable the context disable when connection was successful.""" hide_context() try: - cmd = "target {} {}".format("extended-remote" if is_extended_remote else "remote", target) + cmd = f"target {'extended-remote' if is_extended_remote else 'remote'} {target}" gdb.execute(cmd) - ok("Connected to '{}'".format(target)) + ok(f"Connected to '{target}'") ret = True except Exception as e: - err("Failed to connect to {:s}: {:s}".format(target, str(e))) + err(f"Failed to connect to {target}: {e}") ret = False unhide_context() return ret def load_from_remote_proc(self, pid: int, info: str) -> Optional[str]: """Download one item from /proc/pid.""" - remote_name = "/proc/{:d}/{:s}".format(pid, info) + remote_name = f"/proc/{pid:d}/{info}" return download_file(remote_name, use_cache=False) def refresh_shared_library_path(self) -> None: dirs = [r for r, d, f in os.walk(self["root"])] path = ":".join(dirs) - gdb.execute("set solib-search-path {:s}".format(path,)) + gdb.execute(f"set solib-search-path {path}") return def usage(self) -> None: @@ -6601,11 +6578,11 @@ def prepare_qemu_stub(self, target: str) -> None: gef.binary.e_machine = Elf.SPARC gef.arch = SPARC() else: - raise RuntimeError("unsupported architecture: {}".format(arch)) + raise RuntimeError(f"unsupported architecture: {arch}") - ok("Setting Qemu-user stub for '{}' (memory mapping may be wrong)".format(gef.arch.arch)) + ok(f"Setting Qemu-user stub for '{gef.arch.arch}' (memory mapping may be wrong)") hide_context() - gdb.execute("target remote {}".format(target)) + gdb.execute(f"target remote {target}") unhide_context() if gef.session.pid == 1 and "ENABLE=1" in gdb.execute("maintenance packet Qqemu.sstepbits", to_string=True, from_tty=False): @@ -6623,10 +6600,10 @@ class NopCommand(GenericCommand): aware.""" _cmdline_ = "nop" - _syntax_ = """{:s} [LOCATION] [--nb NUM_BYTES] - LOCATION\taddress/symbol to patch - --nb NUM_BYTES\tInstead of writing one instruction, patch the specified number of bytes""".format(_cmdline_) - _example_ = "{:s} $pc".format(_cmdline_) + _syntax_ = ("{_cmdline_} [LOCATION] [--nb NUM_BYTES]" + "\n\tLOCATION\taddress/symbol to patch" + "\t--nb NUM_BYTES\tInstead of writing one instruction, patch the specified number of bytes") + _example_ = f"{_cmdline_} $pc" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -6651,19 +6628,19 @@ def nop_bytes(self, loc: int, num_bytes: int) -> None: nops = gef.arch.nop_insn if len(nops) > size: - m = "Cannot patch instruction at {:#x} (nop_size is:{:d},insn_size is:{:d})".format(loc, len(nops), size) - err(m) + err(f"Cannot patch instruction at {loc:#x} " + f"(nop_size is:{len(nops):d}, insn_size is:{size:d})") return while len(nops) < size: nops += gef.arch.nop_insn if len(nops) != size: - err("Cannot patch instruction at {:#x} (nop instruction does not evenly fit in requested size)" - .format(loc)) + err(f"Cannot patch instruction at {loc:#x} " + "(nop instruction does not evenly fit in requested size)") return - ok("Patching {:d} bytes from {:s}".format(size, format_address(loc))) + ok(f"Patching {size:d} bytes from {format_address(loc)}") gef.memory.write(loc, nops, size) return @@ -6675,10 +6652,10 @@ class StubCommand(GenericCommand): function to be called and disrupt your runtime flow (ex. fork).""" _cmdline_ = "stub" - _syntax_ = """{:s} [--retval RETVAL] [address] -\taddress\taddress/symbol to stub out -\t--retval RETVAL\tSet the return value""".format(_cmdline_) - _example_ = "{:s} --retval 0 fork".format(_cmdline_) + _syntax_ = (f"{_cmdline_} [--retval RETVAL] [address]" + "\taddress\taddress/symbol to stub out" + "\t--retval RETVAL\tSet the return value") + _example_ = f"{_cmdline_} --retval 0 fork" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -6688,7 +6665,7 @@ def __init__(self) -> None: @parse_arguments({"address": ""}, {("-r", "--retval"): 0}) def do_invoke(self, argv, *args, **kwargs) -> None: args = kwargs["arguments"] - loc = args.address if args.address else "*{:#x}".format(gef.arch.pc) + loc = args.address if args.address else f"*{gef.arch.pc:#x}" StubBreakpoint(loc, args.retval) return @@ -6698,9 +6675,9 @@ class CapstoneDisassembleCommand(GenericCommand): """Use capstone disassembly framework to disassemble code.""" _cmdline_ = "capstone-disassemble" - _syntax_ = "{:s} [-h] [--show-opcodes] [--length LENGTH] [LOCATION]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [-h] [--show-opcodes] [--length LENGTH] [LOCATION]" _aliases_ = ["cs-dis"] - _example_ = "{:s} --length 50 $pc".format(_cmdline_) + _example_ = f"{_cmdline_} --length 50 $pc" def pre_load(self) -> None: try: @@ -6722,7 +6699,7 @@ def do_invoke(self, argv, *args, **kwargs) -> None: length = args.length or gef.config["context.nb_lines_code"] location = parse_address(args.location) if not location: - info("Can't find address for {}".format(args.location)) + info(f"Can't find address for {args.location}") return insns = [] @@ -6732,19 +6709,19 @@ def do_invoke(self, argv, *args, **kwargs) -> None: opcodes_len = max(opcodes_len, len(insn.opcodes)) for insn in insns: - insn_fmt = "{{:{}o}}".format(opcodes_len) if show_opcodes else "{}" + insn_fmt = f"{{:{opcodes_len}o}}" if show_opcodes else "{}" text_insn = insn_fmt.format(insn) msg = "" if insn.address == gef.arch.pc: - msg = Color.colorify("{} {}".format(RIGHT_ARROW, text_insn), "bold red") + msg = Color.colorify(f"{RIGHT_ARROW} {text_insn}", "bold red") reason = self.capstone_analyze_pc(insn, length)[0] if reason: gef_print(msg) gef_print(reason) break else: - msg = "{} {}".format(" " * 5, text_insn) + msg = f" {text_insn}" gef_print(msg) return @@ -6753,18 +6730,18 @@ def capstone_analyze_pc(self, insn, nb_insn: int) -> Tuple[bool, str]: if gef.arch.is_conditional_branch(insn): is_taken, reason = gef.arch.is_branch_taken(insn) if is_taken: - reason = "[Reason: {:s}]".format(reason) if reason else "" - msg = Color.colorify("\tTAKEN {:s}".format(reason), "bold green") + reason = f"[Reason: {reason}]" if reason else "" + msg = Color.colorify(f"\tTAKEN {reason}", "bold green") else: - reason = "[Reason: !({:s})]".format(reason) if reason else "" - msg = Color.colorify("\tNOT taken {:s}".format(reason), "bold red") + reason = f"[Reason: !({reason})]" if reason else "" + msg = Color.colorify(f"\tNOT taken {reason}", "bold red") return (is_taken, msg) if gef.arch.is_call(insn): target_address = int(insn.operands[-1].split()[0], 16) msg = [] for i, new_insn in enumerate(capstone_disassemble(target_address, nb_insn)): - msg.append(" {} {}".format(DOWN_ARROW if i == 0 else " ", str(new_insn))) + msg.append(f" {DOWN_ARROW if i == 0 else ' '} {new_insn!s}") return (True, "\n".join(msg)) return (False, "") @@ -6775,7 +6752,7 @@ class GlibcHeapCommand(GenericCommand): """Base command to get information about the Glibc heap structure.""" _cmdline_ = "heap" - _syntax_ = "{:s} (chunk|chunks|bins|arenas|set-arena)".format(_cmdline_) + _syntax_ = f"{_cmdline_} (chunk|chunks|bins|arenas|set-arena)" def __init__(self) -> None: super().__init__(prefix=True) @@ -6792,8 +6769,8 @@ class GlibcHeapSetArenaCommand(GenericCommand): """Display information on a heap chunk.""" _cmdline_ = "heap set-arena" - _syntax_ = "{:s} [address|&symbol]".format(_cmdline_) - _example_ = "{:s} 0x001337001337".format(_cmdline_) + _syntax_ = f"{_cmdline_} [address|&symbol]" + _example_ = f"{_cmdline_} 0x001337001337" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -6804,7 +6781,7 @@ def do_invoke(self, argv: List) -> None: global gef if not argv: - ok("Current arena set to: '{}'".format(gef.heap.selected_arena)) + ok(f"Current arena set to: '{gef.heap.selected_arena}'") return if is_hex(argv[0]): @@ -6816,7 +6793,7 @@ def do_invoke(self, argv: List) -> None: return new_arena_address = to_unsigned_long(new_arena_symbol) - new_arena = GlibcArena( "*0x{:x}".format(new_arena_address)) + new_arena = GlibcArena( f"*{new_arena_address:#x}") if new_arena not in gef.heap.arenas: err("Invalid arena") return @@ -6845,7 +6822,7 @@ class GlibcHeapChunkCommand(GenericCommand): See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123.""" _cmdline_ = "heap chunk" - _syntax_ = "{:s} [-h] [--allow-unaligned] [--number] address".format(_cmdline_) + _syntax_ = f"{_cmdline_} [-h] [--allow-unaligned] [--number] address" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -6889,8 +6866,9 @@ class GlibcHeapChunksCommand(GenericCommand): the base address of a different arena can be passed""" _cmdline_ = "heap chunks" - _syntax_ = "{0} [-h] [--all] [--allow-unaligned] [arena_address]".format(_cmdline_) - _example_ = "\n{0}\n{0} 0x555555775000".format(_cmdline_) + _syntax_ = f"{_cmdline_} [-h] [--all] [--allow-unaligned] [arena_address]" + _example_ = (f"\n{_cmdline_}" + f"\n{_cmdline_} 0x555555775000") def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -6935,7 +6913,7 @@ def dump_chunks_heap(self, start: int, until: Optional[int] = None, top: Optiona for chunk in chunk_iterator: line = str(chunk) if nb: - line += "\n [{}]".format(hexdump(gef.memory.read(chunk.data_address, nb), nb, base=chunk.data_address)) + line += f"\n [{hexdump(gef.memory.read(chunk.data_address, nb), nb, base=chunk.data_address)}]" gef_print(line) next_chunk_addr = chunk.get_next_chunk_addr() @@ -6943,7 +6921,7 @@ def dump_chunks_heap(self, start: int, until: Optional[int] = None, top: Optiona break if chunk.base_address == top: - gef_print("{} {} {}".format(str(chunk), LEFT_ARROW, Color.greenify("top chunk"))) + gef_print(f"{chunk!s} {LEFT_ARROW} {Color.greenify('top chunk')}") break return @@ -6955,7 +6933,7 @@ class GlibcHeapBinsCommand(GenericCommand): _bin_types_ = ["tcache", "fast", "unsorted", "small", "large"] _cmdline_ = "heap bins" - _syntax_ = "{:s} [{:s}]".format(_cmdline_, "|".join(_bin_types_)) + _syntax_ = f"{_cmdline_} [{'|'.join(_bin_types_)}]" def __init__(self) -> None: super().__init__(prefix=True, complete=gdb.COMPLETE_LOCATION) @@ -6965,7 +6943,7 @@ def __init__(self) -> None: def do_invoke(self, argv: List) -> None: if not argv: for bin_t in GlibcHeapBinsCommand._bin_types_: - gdb.execute("heap bins {:s}".format(bin_t)) + gdb.execute(f"heap bins {bin_t}") return bin_t = argv[0] @@ -6973,7 +6951,7 @@ def do_invoke(self, argv: List) -> None: self.usage() return - gdb.execute("heap bins {}".format(bin_t)) + gdb.execute(f"heap bins {bin_t}") return @staticmethod @@ -6990,12 +6968,12 @@ def pprint_bin(arena_addr: str, index: int, _type: str = "") -> int: if fw == head: return nb_chunk - ok("{}bins[{:d}]: fw={:#x}, bk={:#x}".format(_type, index, fw, bk)) + ok(f"{_type}bins[{index:d}]: fw={fw:#x}, bk={bk:#x}") m = [] while fw != head: chunk = GlibcChunk(fw, from_base=True) - m.append("{:s} {:s}".format(RIGHT_ARROW, str(chunk))) + m.append(f"{RIGHT_ARROW} {chunk!s}") fw = chunk.fwd nb_chunk += 1 @@ -7010,7 +6988,7 @@ class GlibcHeapTcachebinsCommand(GenericCommand): See https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc.""" _cmdline_ = "heap bins tcache" - _syntax_ = "{:s} [all] [thread_ids...]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [all] [thread_ids...]" TCACHE_MAX_BINS = 0x40 @@ -7048,10 +7026,10 @@ def do_invoke(self, argv: List) -> None: tcache_addr = self.find_tcache() if tcache_addr == 0: - info("Uninitialized tcache for thread {:d}".format(thread.num)) + info(f"Uninitialized tcache for thread {thread.num:d}") continue - gef_print(titlify("Tcachebins for thread {:d}".format(thread.num))) + gef_print(titlify(f"Tcachebins for thread {thread.num:d}")) tcache_empty = True for i in range(self.TCACHE_MAX_BINS): chunk, count = self.tcachebin(tcache_addr, i) @@ -7064,9 +7042,9 @@ def do_invoke(self, argv: List) -> None: break try: - msg.append("{:s} {:s} ".format(LEFT_ARROW, str(chunk))) + msg.append(f"{LEFT_ARROW} {chunk!s} ") if chunk.data_address in chunks: - msg.append("{:s} [loop detected]".format(RIGHT_ARROW)) + msg.append(f"{RIGHT_ARROW} [loop detected]") break chunks.add(chunk.data_address) @@ -7077,12 +7055,12 @@ def do_invoke(self, argv: List) -> None: chunk = GlibcChunk(next_chunk) except gdb.MemoryError: - msg.append("{:s} [Corrupted chunk at {:#x}]".format(LEFT_ARROW, chunk.data_address)) + msg.append(f"{LEFT_ARROW} [Corrupted chunk at {chunk.data_address:#x}]") break if msg: tcache_empty = False - gef_print("Tcachebins[idx={:d}, size={:#x}] count={:d} ".format(i, (i+2)*(gef.arch.ptrsize)*2, count), end="") + gef_print(f"Tcachebins[idx={i:d}, size={(i+2)*(gef.arch.ptrsize)*2:#x}] count={count:d} ", end="") gef_print("".join(msg)) if tcache_empty: @@ -7119,12 +7097,12 @@ def check_thread_ids(tids: List[int]) -> List[int]: try: tid = int(tid) except ValueError: - err("Invalid thread id {:s}".format(tid)) + err(f"Invalid thread id {tid:d}") continue if tid in existing_tids: valid_tids.add(tid) else: - err("Unknown thread {}".format(tid)) + err(f"Unknown thread {tid}") return list(valid_tids) @@ -7165,7 +7143,7 @@ class GlibcHeapFastbinsYCommand(GenericCommand): See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123.""" _cmdline_ = "heap bins fast" - _syntax_ = "{:s} [ARENA_ADDRESS]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -7180,15 +7158,15 @@ def fastbin_index(sz): MAX_FAST_SIZE = 80 * SIZE_SZ // 4 NFASTBINS = fastbin_index(MAX_FAST_SIZE) - 1 - arena = GlibcArena("*{:s}".format(argv[0])) if len(argv) == 1 else gef.heap.main_arena + arena = GlibcArena(f"*{argv[0]}") if len(argv) == 1 else gef.heap.main_arena if arena is None: err("Invalid Glibc arena") return - gef_print(titlify("Fastbins for arena {:#x}".format(int(arena)))) + gef_print(titlify(f"Fastbins for arena {int(arena):#x}")) for i in range(NFASTBINS): - gef_print("Fastbins[idx={:d}, size={:#x}] ".format(i, (i+2)*SIZE_SZ*2), end="") + gef_print(f"Fastbins[idx={i:d}, size={(i+2)*SIZE_SZ*2:#x}] ", end="") chunk = arena.fastbin(i) chunks = set() @@ -7198,9 +7176,9 @@ def fastbin_index(sz): break try: - gef_print("{:s} {:s} ".format(LEFT_ARROW, str(chunk)), end="") + gef_print(f"{LEFT_ARROW} {chunk!s} ", end="") if chunk.data_address in chunks: - gef_print("{:s} [loop detected]".format(RIGHT_ARROW), end="") + gef_print(f"{RIGHT_ARROW} [loop detected]", end="") break if fastbin_index(chunk.get_chunk_size()) != i: @@ -7214,7 +7192,7 @@ def fastbin_index(sz): chunk = GlibcChunk(next_chunk, from_base=True) except gdb.MemoryError: - gef_print("{:s} [Corrupted chunk at {:#x}]".format(LEFT_ARROW, chunk.data_address), end="") + gef_print(f"{LEFT_ARROW} [Corrupted chunk at {chunk.data_address:#x}]", end="") break gef_print() return @@ -7225,7 +7203,7 @@ class GlibcHeapUnsortedBinsCommand(GenericCommand): See: https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1689.""" _cmdline_ = "heap bins unsorted" - _syntax_ = "{:s} [ARENA_ADDRESS]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -7237,11 +7215,11 @@ def do_invoke(self, argv: List) -> None: err("Invalid Glibc arena") return - arena_addr = "*{:s}".format(argv[0]) if len(argv) == 1 else gef.heap.selected_arena - gef_print(titlify("Unsorted Bin for arena '{:s}'".format(arena_addr))) + arena_addr = f"*{argv[0]}" if len(argv) == 1 else gef.heap.selected_arena + gef_print(titlify(f"Unsorted Bin for arena '{arena_addr:s}'")) nb_chunk = GlibcHeapBinsCommand.pprint_bin(arena_addr, 0, "unsorted_") if nb_chunk >= 0: - info("Found {:d} chunks in unsorted bin.".format(nb_chunk)) + info(f"Found {nb_chunk:d} chunks in unsorted bin.") return @register_command @@ -7249,7 +7227,7 @@ class GlibcHeapSmallBinsCommand(GenericCommand): """Convenience command for viewing small bins.""" _cmdline_ = "heap bins small" - _syntax_ = "{:s} [ARENA_ADDRESS]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -7261,8 +7239,8 @@ def do_invoke(self, argv: List) -> None: err("Heap not initialized") return - arena = GlibcArena(f"*{argv[0]:s}") if len(argv) == 1 else gef.heap.selected_arena - gef_print(titlify("Small Bins for arena '{:s}'".format(arena))) + arena = GlibcArena(f"*{argv[0]}") if len(argv) == 1 else gef.heap.selected_arena + gef_print(titlify(f"Small Bins for arena '{arena:s}'")) bins = {} for i in range(1, 63): nb_chunk = GlibcHeapBinsCommand.pprint_bin(arena, i, "small_") @@ -7270,7 +7248,7 @@ def do_invoke(self, argv: List) -> None: break if nb_chunk > 0: bins[i] = nb_chunk - info("Found {:d} chunks in {:d} small non-empty bins.".format(sum(bins.values()), len(bins))) + info(f"Found {sum(bins.values()):d} chunks in {len(bins):d} small non-empty bins.") return @register_command @@ -7278,7 +7256,7 @@ class GlibcHeapLargeBinsCommand(GenericCommand): """Convenience command for viewing large bins.""" _cmdline_ = "heap bins large" - _syntax_ = "{:s} [ARENA_ADDRESS]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [ARENA_ADDRESS]" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -7290,8 +7268,8 @@ def do_invoke(self, argv: List) -> None: err("Invalid Glibc arena") return - arena_addr = "*{:s}".format(argv[0]) if len(argv) == 1 else gef.heap.selected_arena - gef_print(titlify("Large Bins for arena '{:s}'".format(arena_addr))) + arena_addr = f"*{argv[0]}" if len(argv) == 1 else gef.heap.selected_arena + gef_print(titlify(f"Large Bins for arena '{arena_addr:s}'")) bins = {} for i in range(63, 126): nb_chunk = GlibcHeapBinsCommand.pprint_bin(arena_addr, i, "large_") @@ -7299,7 +7277,7 @@ def do_invoke(self, argv: List) -> None: break if nb_chunk > 0: bins[i] = nb_chunk - info("Found {:d} chunks in {:d} large non-empty bins.".format(sum(bins.values()), len(bins))) + info(f"Found {sum(bins.values()):d} chunks in {len(bins):d} large non-empty bins.") return @@ -7308,8 +7286,8 @@ class SolveKernelSymbolCommand(GenericCommand): """Solve kernel symbols from kallsyms table.""" _cmdline_ = "ksymaddr" - _syntax_ = "{:s} SymbolToSearch".format(_cmdline_) - _example_ = "{:s} prepare_creds".format(_cmdline_) + _syntax_ = f"{_cmdline_} SymbolToSearch" + _example_ = f"{_cmdline_} prepare_creds" @parse_arguments({"symbol": ""}, {}) def do_invoke(self, *args, **kwargs) -> None: @@ -7328,11 +7306,11 @@ def hex_to_int(num): matches = [(hex_to_int(addr), sym_t, " ".join(name.split())) for addr, sym_t, name in syms if sym in name] for addr, sym_t, name in matches: if sym == name.split()[0]: - ok("Found matching symbol for '{:s}' at {:#x} (type={:s})".format(name, addr, sym_t)) + ok(f"Found matching symbol for '{name}' at {addr:#x} (type={sym_t})") else: - warn("Found partial match for '{:s}' at {:#x} (type={:s}): {:s}".format(sym, addr, sym_t, name)) + warn(f"Found partial match for '{sym}' at {addr:#x} (type={sym_t}): {name}") if not matches: - err("No match for '{:s}'".format(sym)) + err(f"No match for '{sym}'") elif matches[0][0] == 0: err("Check that you have the correct permissions to view kernel symbol addresses") return @@ -7343,8 +7321,9 @@ class DetailRegistersCommand(GenericCommand): """Display full details on one, many or all registers value from current architecture.""" _cmdline_ = "registers" - _syntax_ = "{:s} [[Register1][Register2] ... [RegisterN]]".format(_cmdline_) - _example_ = "\n{0:s}\n{0:s} $eax $eip $esp".format(_cmdline_) + _syntax_ = f"{_cmdline_} [[Register1][Register2] ... [RegisterN]]" + _example_ = (f"\n{_cmdline_}" + f"\n{_cmdline_} $eax $eip $esp") @only_if_gdb_running @parse_arguments({"registers": [""]}, {}) @@ -7362,7 +7341,7 @@ def do_invoke(self, argv: List, *args, **kwargs) -> None: regs = valid_regs invalid_regs = [reg for reg in required_regs if reg not in valid_regs] if invalid_regs: - err("invalid registers for architecture: {}".format(", ".join(invalid_regs))) + err(f"invalid registers for architecture: {', '.join(invalid_regs)}") memsize = gef.arch.ptrsize endian = str(gef.arch.endianness) @@ -7378,7 +7357,7 @@ def do_invoke(self, argv: List, *args, **kwargs) -> None: padreg = regname.ljust(widest, " ") if str(reg) == "": - line = "{}: ".format(Color.colorify(padreg, unchanged_color)) + line = f"{Color.colorify(padreg, unchanged_color)}: " line += Color.colorify("no value", "yellow underline") gef_print(line) continue @@ -7392,11 +7371,11 @@ def do_invoke(self, argv: List, *args, **kwargs) -> None: # Special (e.g. segment) registers go on their own line if regname in gef.arch.special_registers: - special_line += "{}: ".format(Color.colorify(regname, color)) - special_line += "0x{:04x} ".format(gef.arch.register(regname)) + special_line += f"{Color.colorify(regname, color)}: " + special_line += f"{gef.arch.register(regname):#04x} " continue - line = "{}: ".format(Color.colorify(padreg, color)) + line = f"{Color.colorify(padreg, color)}: " if regname == gef.arch.flag_register: line += gef.arch.flag_register_to_human() @@ -7411,17 +7390,17 @@ def do_invoke(self, argv: List, *args, **kwargs) -> None: addrs = dereference_from(value) if len(addrs) > 1: - sep = " {:s} ".format(RIGHT_ARROW) + sep = f" {RIGHT_ARROW} " line += sep line += sep.join(addrs[1:]) # check to see if reg value is ascii try: - fmt = "{}{}".format(endian, "I" if memsize == 4 else "Q") + fmt = f"{endian}{'I' if memsize == 4 else 'Q'}" last_addr = int(addrs[-1], 16) val = gef_pystring(struct.pack(fmt, last_addr)) if all([_ in charset for _ in val]): - line += ' ("{:s}"?)'.format(Color.colorify(val, string_color)) + line += f' ("{Color.colorify(val, string_color)}"?)' except ValueError: pass @@ -7438,7 +7417,7 @@ class ShellcodeCommand(GenericCommand): download shellcodes.""" _cmdline_ = "shellcode" - _syntax_ = "{:s} (search|get)".format(_cmdline_) + _syntax_ = f"{_cmdline_} (search|get)" def __init__(self) -> None: super().__init__(prefix=True) @@ -7455,11 +7434,11 @@ class ShellcodeSearchCommand(GenericCommand): """Search pattern in shell-storm's shellcode database.""" _cmdline_ = "shellcode search" - _syntax_ = "{:s} PATTERN1 PATTERN2".format(_cmdline_) + _syntax_ = f"{_cmdline_} PATTERN1 PATTERN2" _aliases_ = ["sc-search",] api_base = "http://shell-storm.org" - search_url = "{}/api/?s=".format(api_base) + search_url = f"{api_base}/api/?s=" def do_invoke(self, argv: List) -> None: if not argv: @@ -7504,11 +7483,11 @@ class ShellcodeGetCommand(GenericCommand): """Download shellcode from shell-storm's shellcode database.""" _cmdline_ = "shellcode get" - _syntax_ = "{:s} SHELLCODE_ID".format(_cmdline_) + _syntax_ = f"{_cmdline_} SHELLCODE_ID" _aliases_ = ["sc-get",] api_base = "http://shell-storm.org" - get_url = "{}/shellcode/files/shellcode-{{:d}}.php".format(api_base) + get_url = f"{api_base}/shellcode/files/shellcode-{{:d}}.php" def do_invoke(self, argv: List) -> None: if len(argv) != 1: @@ -7525,10 +7504,10 @@ def do_invoke(self, argv: List) -> None: return def get_shellcode(self, sid: int) -> None: - info("Downloading shellcode id={:d}".format(sid)) + info(f"Downloading shellcode id={sid}") res = http_get(self.get_url.format(sid)) if res is None: - err("Failed to fetch shellcode #{:d}".format(sid)) + err(f"Failed to fetch shellcode #{sid}") return ok("Downloaded, written to disk...") @@ -7538,7 +7517,7 @@ def get_shellcode(self, sid: int) -> None: shellcode = b"\n".join(shellcode).replace(b""", b'"') os.write(fd, shellcode) os.close(fd) - ok("Shellcode written to '{:s}'".format(fname)) + ok(f"Shellcode written to '{fname}'") return @@ -7547,7 +7526,7 @@ class RopperCommand(GenericCommand): """Ropper (http://scoding.de/ropper) plugin.""" _cmdline_ = "ropper" - _syntax_ = "{:s} [ROPPER_OPTIONS]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [ROPPER_OPTIONS]" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_NONE) @@ -7570,7 +7549,7 @@ def do_invoke(self, argv: List) -> None: argv.append("--file") argv.append(path) argv.append("-I") - argv.append("{:#x}".format(sect.page_start)) + argv.append(f"{sect.page_start:#x}") import readline # ropper set up own autocompleter after which gdb/gef autocomplete don't work @@ -7590,9 +7569,10 @@ class AssembleCommand(GenericCommand): """Inline code assemble. Architecture can be set in GEF runtime config. """ _cmdline_ = "assemble" - _syntax_ = "{:s} [-h] [--list-archs] [--mode MODE] [--arch ARCH] [--overwrite-location LOCATION] [--endian ENDIAN] [--as-shellcode] instruction;[instruction;...instruction;])".format(_cmdline_) + _syntax_ = f"{_cmdline_} [-h] [--list-archs] [--mode MODE] [--arch ARCH] [--overwrite-location LOCATION] [--endian ENDIAN] [--as-shellcode] instruction;[instruction;...instruction;])" _aliases_ = ["asm",] - _example_ = "\n{0:s} -a x86 -m 32 nop ; nop ; inc eax ; int3\n{0:s} -a arm -m arm add r0, r0, 1".format(_cmdline_) + _example_ = (f"\n{_cmdline_} -a x86 -m 32 nop ; nop ; inc eax ; int3" + f"\n{_cmdline_} -a arm -m arm add r0, r0, 1") valid_arch_modes = { # Format: ARCH = [MODES] with MODE = (NAME, HAS_LITTLE_ENDIAN, HAS_BIG_ENDIAN) @@ -7633,7 +7613,7 @@ def list_archs(self) -> None: gef_print("Available architectures/modes (with endianness):") # for updates, see https://github.com/keystone-engine/keystone/blob/master/include/keystone/keystone.h for arch in self.valid_arch_modes: - gef_print("- {}".format(arch)) + gef_print(f"- {arch}") for mode, le, be in self.valid_arch_modes[arch]: if le and be: endianness = "little, big" @@ -7641,7 +7621,7 @@ def list_archs(self) -> None: endianness = "little" elif be: endianness = "big" - gef_print(" * {:<7} ({})".format(mode, endianness)) + gef_print(f" * {mode:<7} ({endianness})") return @parse_arguments({"instructions": [""]}, {"--mode": "", "--arch": "", "--overwrite-location": 0, "--endian": "little", "--list-archs": True, "--as-shellcode": True}) @@ -7674,20 +7654,20 @@ def do_invoke(self, argv: List, *args, **kwargs) -> None: endian_s = endian_s.upper() if arch_s not in self.valid_arch_modes: - raise AttributeError("invalid arch '{}'".format(arch_s)) + raise AttributeError(f"invalid arch '{arch_s}'") valid_modes = self.valid_arch_modes[arch_s] try: mode_idx = [m[0] for m in valid_modes].index(mode_s) except ValueError: - raise AttributeError("invalid mode '{}' for arch '{}'".format(mode_s, arch_s)) + raise AttributeError(f"invalid mode '{mode_s}' for arch '{arch_s}'") if endian_s == "little" and not valid_modes[mode_idx][1] or endian_s == "big" and not valid_modes[mode_idx][2]: - raise AttributeError("invalid endianness '{}' for arch/mode '{}:{}'".format(endian_s, arch_s, mode_s)) + raise AttributeError(f"invalid endianness '{endian_s}' for arch/mode '{arch_s}:{mode_s}'") arch, mode = get_keystone_arch(arch=arch_s, mode=mode_s, endian=endian_s) insns = [x.strip() for x in " ".join(args.instructions).split(";") if x] - info("Assembling {} instruction(s) for {}:{}".format(len(insns), arch_s, mode_s)) + info(f"Assembling {len(insns)} instruction(s) for {arch_s}:{mode_s}") if args.as_shellcode: gef_print("""sc="" """) @@ -7708,13 +7688,13 @@ def do_invoke(self, argv: List, *args, **kwargs) -> None: res = res.decode("utf-8") if args.as_shellcode: - res = """sc+="{0:s}" """.format(res) + res = f"""sc+="{res}" """ - gef_print("{0:60s} # {1}".format(res, insn)) + gef_print(f"{res!s:60s} # {insn}") if args.overwrite_location: l = len(raw) - info("Overwriting {:d} bytes at {:s}".format(l, format_address(args.overwrite_location))) + info(f"Overwriting {l:d} bytes at {format_address(args.overwrite_location)}") gef.memory.write(args.overwrite_location, raw, l) return @@ -7725,13 +7705,13 @@ class ProcessListingCommand(GenericCommand): by this pattern.""" _cmdline_ = "process-search" - _syntax_ = "{:s} [-h] [--attach] [--smart-scan] [REGEX_PATTERN]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [-h] [--attach] [--smart-scan] [REGEX_PATTERN]" _aliases_ = ["ps"] - _example_ = "{:s} gdb.*".format(_cmdline_) + _example_ = f"{_cmdline_} gdb.*" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) - self["ps_command"] = ( "{:s} auxww".format(str(gef.session.constants["ps"])), "`ps` command to get process information") + self["ps_command"] = (f"{gef.session.constants['ps']} auxww", "`ps` command to get process information") return @parse_arguments({"pattern": ""}, {"--attach": True, "--smart-scan": True}) @@ -7756,8 +7736,8 @@ def do_invoke(self, argv: List, *args, **kwargs) -> None: if command.startswith("gdb "): continue if args and do_attach: - ok("Attaching to process='{:s}' pid={:d}".format(process["command"], pid)) - gdb.execute("attach {:d}".format(pid)) + ok(f"Attaching to process='{process['command']}' pid={pid:d}") + gdb.execute(f"attach {pid:d}") return None line = [process[i] for i in ("pid", "user", "cpu", "mem", "tty", "command")] @@ -7790,8 +7770,8 @@ class ElfInfoCommand(GenericCommand): show information about the current ELF being debugged.""" _cmdline_ = "elf-info" - _syntax_ = "{:s} [FILE]".format(_cmdline_) - _example_ = "{:s} /bin/ls".format(_cmdline_) + _syntax_ = f"{_cmdline_} [FILE]" + _example_ = f"{_cmdline_} /bin/ls" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -7853,24 +7833,24 @@ def do_invoke(self, argv: List, *args, **kwargs) -> None: return data = [ - ("Magic", "{0!s}".format(hexdump(struct.pack(">I", elf.e_magic), show_raw=True))), - ("Class", "{0:#x} - {1}".format(elf.e_class, classes[elf.e_class])), - ("Endianness", "{0:#x} - {1}".format(elf.e_endianness, Endianness(elf.e_endianness).name)), - ("Version", "{:#x}".format(elf.e_eiversion)), - ("OS ABI", "{0:#x} - {1}".format(elf.e_osabi, osabi[elf.e_osabi])), - ("ABI Version", "{:#x}".format(elf.e_abiversion)), - ("Type", "{0:#x} - {1}".format(elf.e_type, types[elf.e_type])), - ("Machine", "{0:#x} - {1}".format(elf.e_machine, machines[elf.e_machine])), - ("Program Header Table", "{}".format(format_address(elf.e_phoff))), - ("Section Header Table", "{}".format(format_address(elf.e_shoff))), - ("Header Table", "{}".format(format_address(elf.e_phoff))), - ("ELF Version", "{:#x}".format(elf.e_version)), + ("Magic", f"{hexdump(struct.pack('>I', elf.e_magic), show_raw=True)}"), + ("Class", f"{elf.e_class:#x} - {classes[elf.e_class]}"), + ("Endianness", f"{elf.e_endianness:#x} - {Endianness(elf.e_endianness).name}"), + ("Version", f"{elf.e_eiversion:#x}"), + ("OS ABI", f"{elf.e_osabi:#x} - {osabi[elf.e_osabi]}"), + ("ABI Version", f"{elf.e_abiversion:#x}"), + ("Type", f"{elf.e_type:#x} - {types[elf.e_type]}"), + ("Machine", f"{elf.e_machine:#x} - {machines[elf.e_machine]}"), + ("Program Header Table", f"{format_address(elf.e_phoff)}"), + ("Section Header Table", f"{format_address(elf.e_shoff)}"), + ("Header Table", f"{format_address(elf.e_phoff)}"), + ("ELF Version", f"{elf.e_version:#x}"), ("Header size", "{0} ({0:#x})".format(elf.e_ehsize)), - ("Entry point", "{}".format(format_address(elf.e_entry))), + ("Entry point", f"{format_address(elf.e_entry)}"), ] for title, content in data: - gef_print("{}: {}".format(Color.boldify("{:<22}".format(title)), content)) + gef_print(f"{Color.boldify(f'{title:<22}')}: {content}") ptype = { Phdr.PT_NULL: "NULL", @@ -8005,7 +7985,7 @@ def do_invoke(self, argv: List) -> None: return if not os.access(fpath, os.X_OK): - warn("The file '{}' is not executable.".format(fpath)) + warn(f"The file '{fpath}' is not executable.") return if is_alive() and not gef.session.qemu_mode: @@ -8018,9 +7998,9 @@ def do_invoke(self, argv: List) -> None: for sym in entrypoints: try: value = parse_address(sym) - info("Breaking at '{:s}'".format(str(value))) + info(f"Breaking at '{value:#x}'") bp = EntryBreakBreakpoint(sym) - gdb.execute("run {}".format(" ".join(argv))) + gdb.execute(f"run {' '.join(argv)}") return except gdb.error as gdb_error: @@ -8045,19 +8025,19 @@ def do_invoke(self, argv: List) -> None: return self.set_init_tbreak(entry) - gdb.execute("run {}".format(" ".join(argv))) + gdb.execute(f"run {' '.join(argv)}") return def set_init_tbreak(self, addr: int) -> EntryBreakBreakpoint: - info("Breaking at entry-point: {:#x}".format(addr)) - bp = EntryBreakBreakpoint("*{:#x}".format(addr)) + info(f"Breaking at entry-point: {addr:#x}") + bp = EntryBreakBreakpoint(f"*{addr:#x}") return bp def set_init_tbreak_pie(self, addr: int, argv: List[str]) -> EntryBreakBreakpoint: warn("PIC binary detected, retrieving text base address") gdb.execute("set stop-on-solib-events 1") hide_context() - gdb.execute("run {}".format(" ".join(argv))) + gdb.execute(f"run {' '.join(argv)}") unhide_context() gdb.execute("set stop-on-solib-events 0") vmmap = gef.memory.maps @@ -8070,9 +8050,9 @@ class NamedBreakpointCommand(GenericCommand): """Sets a breakpoint and assigns a name to it, which will be shown, when it's hit.""" _cmdline_ = "name-break" - _syntax_ = "{:s} name [address]".format(_cmdline_) + _syntax_ = f"{_cmdline_} name [address]" _aliases_ = ["nb",] - _example = "{:s} main *0x4008a9" + _example = f"{_cmdline_} main *0x4008a9" def __init__(self) -> None: super().__init__() @@ -8098,7 +8078,7 @@ class ContextCommand(GenericCommand): states, the stack, and the disassembly code around $pc.""" _cmdline_ = "context" - _syntax_ = "{:s} [legend|regs|stack|code|args|memory|source|trace|threads|extra]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [legend|regs|stack|code|args|memory|source|trace|threads|extra]" _aliases_ = ["ctx",] old_registers = {} @@ -8242,7 +8222,7 @@ def context_regs(self) -> None: if self["show_registers_raw"] is False: regs = set(gef.arch.all_registers) printable_registers = " ".join(list(regs - ignored_registers)) - gdb.execute("registers {}".format(printable_registers)) + gdb.execute(f"registers {printable_registers}") return widest = l = max(map(len, gef.arch.all_registers)) @@ -8282,17 +8262,17 @@ def context_regs(self) -> None: value = align_address(new_value) old_value = align_address(old_value) if value == old_value: - line += "{}: ".format(Color.colorify(padreg, regname_color)) + line += f"{Color.colorify(padreg, regname_color)}: " else: - line += "{}: ".format(Color.colorify(padreg, changed_color)) + line += f"{Color.colorify(padreg, changed_color)}: " if new_value_type_flag: - line += "{:s} ".format(format_address_spaces(value)) + line += f"{format_address_spaces(value)} " else: addr = lookup_address(align_address(int(value))) if addr.valid: - line += "{:s} ".format(str(addr)) + line += f"{addr!s} " else: - line += "{:s} ".format(format_address_spaces(value)) + line += f"{format_address_spaces(value)} " if i % nb == 0: gef_print(line) @@ -8302,7 +8282,7 @@ def context_regs(self) -> None: if line: gef_print(line) - gef_print("Flags: {:s}".format(gef.arch.flag_register_to_human())) + gef_print(f"Flags: {gef.arch.flag_register_to_human()}") return def context_stack(self) -> None: @@ -8317,7 +8297,7 @@ def context_stack(self) -> None: mem = gef.memory.read(sp, 0x10 * nb_lines) gef_print(hexdump(mem, base=sp)) else: - gdb.execute("dereference -l {:d} {:#x}".format(nb_lines, sp)) + gdb.execute(f"dereference -l {nb_lines:d} {sp:#x}") except gdb.MemoryError: err("Cannot read memory from $SP (corrupted stack pointer?)") @@ -8339,9 +8319,9 @@ def context_code(self) -> None: bp_locations = [b.location for b in breakpoints if b.location and b.location.startswith("*")] frame = gdb.selected_frame() - arch_name = "{}:{}".format(gef.arch.arch.lower(), gef.arch.mode) + arch_name = f"{gef.arch.arch.lower()}:{gef.arch.mode}" - self.context_title("code:{}".format(arch_name)) + self.context_title(f"code:{arch_name}") try: instruction_iterator = capstone_disassemble if use_capstone else gef_disassemble @@ -8355,31 +8335,31 @@ def context_code(self) -> None: if show_opcodes_size == 0: text = str(insn) else: - insn_fmt = "{{:{}o}}".format(show_opcodes_size) + insn_fmt = f"{{:{show_opcodes_size}o}}" text = insn_fmt.format(insn) if insn.address < pc: - line += "{} {}".format(bp_prefix, Color.colorify(text, past_insns_color)) + line += f"{bp_prefix} {Color.colorify(text, past_insns_color)}" elif insn.address == pc: - line += "{}{}".format(bp_prefix, Color.colorify("{:s}{:s}".format(RIGHT_ARROW[1:], text), cur_insn_color)) + line += f"{bp_prefix}{Color.colorify(f'{RIGHT_ARROW[1:]}{text}', cur_insn_color)}" if gef.arch.is_conditional_branch(insn): is_taken, reason = gef.arch.is_branch_taken(insn) if is_taken: target = insn.operands[-1].split()[0] - reason = "[Reason: {:s}]".format(reason) if reason else "" - line += Color.colorify("\tTAKEN {:s}".format(reason), "bold green") + reason = f"[Reason: {reason}]" if reason else "" + line += Color.colorify(f"\tTAKEN {reason}", "bold green") else: - reason = "[Reason: !({:s})]".format(reason) if reason else "" - line += Color.colorify("\tNOT taken {:s}".format(reason), "bold red") + reason = f"[Reason: !({reason})]" if reason else "" + line += Color.colorify(f"\tNOT taken {reason}", "bold red") elif gef.arch.is_call(insn) and self["peek_calls"] is True: target = insn.operands[-1].split()[0] elif gef.arch.is_ret(insn) and self["peek_ret"] is True: target = gef.arch.get_ra(insn, frame) else: - line += "{} {}".format(bp_prefix, text) + line += f"{bp_prefix} {text}" gef_print("".join(line)) @@ -8392,7 +8372,7 @@ def context_code(self) -> None: # If the operand isn't an address right now we can't parse it continue for i, tinsn in enumerate(instruction_iterator(target, nb_insn)): - text= " {} {}".format (DOWN_ARROW if i == 0 else " ", str(tinsn)) + text= f" {DOWN_ARROW if i == 0 else ' '} {tinsn!s}" gef_print(text) break @@ -8415,7 +8395,7 @@ def context_args(self) -> None: if insn.operands[-1].startswith(self.size2type[gef.arch.ptrsize]+" PTR"): target = "*" + insn.operands[-1].split()[-1] elif "$"+insn.operands[0] in gef.arch.all_registers: - target = "*{:#x}".format(gef.arch.register("$"+insn.operands[0])) + target = f"*{gef.arch.register('$' + insn.operands[0]):#x}" else: # is there a symbol? ops = " ".join(insn.operands) @@ -8432,7 +8412,7 @@ def context_args(self) -> None: return if sym.type.code != gdb.TYPE_CODE_FUNC: - err("Symbol '{}' is not a function: type={}".format(target, sym.type.code)) + err(f"Symbol '{target}' is not a function: type={sym.type.code}") return self.print_arguments_from_symbol(target, sym) @@ -8445,19 +8425,17 @@ def print_arguments_from_symbol(self, function_name: str, symbol) -> None: for i, f in enumerate(symbol.type.fields()): _value = gef.arch.get_ith_parameter(i, in_func=False)[1] _value = RIGHT_ARROW.join(dereference_from(_value)) - _name = f.name or "var_{}".format(i) + _name = f.name or f"var_{i}" _type = f.type.name or self.size2type[f.type.sizeof] - args.append("{} {} = {}".format(_type, _name, _value)) + args.append(f"{_type} {_name} = {_value}") self.context_title("arguments") if not args: - gef_print("{} ()".format(function_name)) + gef_print(f"{function_name} ()") return - gef_print("{} (".format(function_name)) - gef_print(" " + ",\n ".join(args)) - gef_print(")") + gef_print(f"{function_name} (\n "+",\n ".join(args)+"\n)") return def print_guessed_arguments(self, function_name: str) -> None: @@ -8506,7 +8484,7 @@ def __get_current_block_start_address() -> Optional[int]: parameter_set.add(exreg) nb_argument = None - _arch_mode = "{}_{}".format(gef.arch.arch.lower(), gef.arch.mode) + _arch_mode = f"{gef.arch.arch.lower()}_{gef.arch.mode}" _function_name = None if function_name.endswith("@plt"): _function_name = function_name.split("@")[0] @@ -8531,17 +8509,17 @@ def __get_current_block_start_address() -> Optional[int]: args.append("{} = {} (def: {})".format(Color.colorify(_key, arg_key_color), _values, gef.ui.highlight_table[_arch_mode][_function_name][_key])) except KeyError: - args.append("{} = {}".format(Color.colorify(_key, arg_key_color), _values)) + args.append(f"{Color.colorify(_key, arg_key_color)} = {_values}") self.context_title("arguments (guessed)") - gef_print("{} (".format(function_name)) + gef_print(f"{function_name} (") if args: gef_print(" " + ",\n ".join(args)) gef_print(")") return def line_has_breakpoint(self, file_name: str, line_number: int, bp_locations: List[str]) -> bool: - filename_line = "{}:{}".format(file_name, line_number) + filename_line = f"{file_name}:{line_number}" return any(filename_line in loc for loc in bp_locations) def context_source(self) -> None: @@ -8569,8 +8547,8 @@ def context_source(self) -> None: nb_line = self["nb_lines_code"] fn = symtab.filename if len(fn) > 20: - fn = "{}[...]{}".format(fn[:15], os.path.splitext(fn)[1]) - title = "source:{}+{}".format(fn, line_num + 1) + fn = f"{fn[:15]}[...]{os.path.splitext(fn)[1]}" + title = f"source:{fn}+{line_num + 1}" cur_line_color = gef.config["theme.source_current_line"] self.context_title(title) show_extra_info = self["show_source_code_variable_values"] @@ -8582,20 +8560,20 @@ def context_source(self) -> None: bp_prefix = Color.redify(BP_GLYPH) if self.line_has_breakpoint(file_base_name, i + 1, bp_locations) else " " if i < line_num: - gef_print("{}{}".format(bp_prefix, Color.colorify(" {:4d}\t {:s}".format(i + 1, lines[i],), past_lines_color))) + gef_print("{}{}".format(bp_prefix, Color.colorify(f" {i + 1:4d}\t {lines[i]}", past_lines_color))) if i == line_num: - prefix = "{}{}{:4d}\t ".format(bp_prefix, RIGHT_ARROW[1:], i + 1) + prefix = f"{bp_prefix}{RIGHT_ARROW[1:]}{i + 1:4d}\t " leading = len(lines[i]) - len(lines[i].lstrip()) if show_extra_info: extra_info = self.get_pc_context_info(pc, lines[i]) if extra_info: - gef_print("{}{}".format(" "*(len(prefix) + leading), extra_info)) - gef_print(Color.colorify("{}{:s}".format(prefix, lines[i]), cur_line_color)) + gef_print(f"{' ' * (len(prefix) + leading)}{extra_info}") + gef_print(Color.colorify(f"{prefix}{lines[i]}", cur_line_color)) if i > line_num: try: - gef_print("{} {:4d}\t {:s}".format(bp_prefix, i + 1, lines[i],)) + gef_print(f"{bp_prefix} {i + 1:4d}\t {lines[i]}") except IndexError: break return @@ -8608,7 +8586,7 @@ def get_pc_context_info(self, pc: int, line: str) -> str: while current_block and not current_block.is_static: for sym in current_block: symbol = sym.name - if not sym.is_function and re.search(r"\W{}\W".format(symbol), line): + if not sym.is_function and re.search(fr"\W{symbol}\W", line): val = gdb.parse_and_eval(symbol) if val.type.code in (gdb.TYPE_CODE_PTR, gdb.TYPE_CODE_ARRAY): addr = int(val.address) @@ -8616,7 +8594,7 @@ def get_pc_context_info(self, pc: int, line: str) -> str: if len(addrs) > 2: addrs = [addrs[0], "[...]", addrs[-1]] - f = " {:s} ".format(RIGHT_ARROW) + f = f" {RIGHT_ARROW} " val = f.join(addrs) elif val.type.code == gdb.TYPE_CODE_INT: val = hex(int(val)) @@ -8628,7 +8606,7 @@ def get_pc_context_info(self, pc: int, line: str) -> str: current_block = current_block.superblock if m: - return "// " + ", ".join(["{}={}".format(Color.yellowify(a), b) for a, b in m.items()]) + return "// " + ", ".join([f"{Color.yellowify(a)}={b}" for a, b in m.items()]) except Exception: pass return "" @@ -8642,7 +8620,7 @@ def context_trace(self) -> None: # backward compat for gdb (gdb < 7.10) if not hasattr(gdb, "FrameDecorator"): - gdb.execute("backtrace {:d}".format(nb_backtrace)) + gdb.execute(f"backtrace {nb_backtrace:d}") return orig_frame = gdb.selected_frame() @@ -8664,7 +8642,7 @@ def context_trace(self) -> None: pc = current_frame.pc() name = current_frame.name() items = [] - items.append("{:#x}".format(pc)) + items.append(f"{pc:#x}") if name: frame_args = gdb.FrameDecorator.FrameDecorator(current_frame).frame_args() or [] m = "{}({})".format(Color.greenify(name), @@ -8682,11 +8660,11 @@ def context_trace(self) -> None: symbol = "" if sym_found: sym_name, offset = sym_found - symbol = " <{}+{:x}> ".format(sym_name, offset) + symbol = f" <{sym_name}+{offset:x}> " - items.append(Color.redify("{}{} {}".format(symbol, insn.mnemonic, ", ".join(insn.operands)))) + items.append(Color.redify(f"{symbol}{insn.mnemonic} {', '.join(insn.operands)}")) - gef_print("[{}] {}".format(Color.colorify("#{}".format(level), "bold green" if current_frame == orig_frame else "bold pink"), + gef_print("[{}] {}".format(Color.colorify(f"#{level}", "bold green" if current_frame == orig_frame else "bold pink"), RIGHT_ARROW.join(items))) current_frame = current_frame.older() level += 1 @@ -8736,9 +8714,9 @@ def reason() -> str: selected_frame = gdb.selected_frame() for i, thread in enumerate(threads): - line = """[{:s}] Id {:d}, """.format(Color.colorify("#{:d}".format(i), "bold green" if thread == selected_thread else "bold pink"), thread.num) + line = f"[{Color.colorify(f'#{i:d}', 'bold green' if thread == selected_thread else 'bold pink')}] Id {thread.num:d}, " if thread.name: - line += """Name: "{:s}", """.format(thread.name) + line += f"""Name: "{thread.name}", """ if thread.is_running(): line += Color.colorify("running", "bold green") elif thread.is_stopped(): @@ -8752,10 +8730,11 @@ def reason() -> str: sym_found = gdb_get_location_from_symbol(frame.pc()) if sym_found: sym_name, offset = sym_found - frame_name = "<{}+{:x}>".format(sym_name, offset) + frame_name = f"<{sym_name}+{offset:x}>" - line += " {:s} in {:s} ()".format(Color.colorify("{:#x}".format(frame.pc()), "blue"), Color.colorify(frame_name or "??", "bold yellow")) - line += ", reason: {}".format(Color.colorify(reason(), "bold pink")) + line += (f" {Color.colorify(f'{frame.pc():#x}', 'blue')} in " + f"{Color.colorify(frame_name or '??', 'bold yellow')} (), " + f"reason: {Color.colorify(reason(), 'bold pink')}") elif thread.is_exited(): line += Color.colorify("exited", "bold yellow") gef_print(line) @@ -8780,18 +8759,11 @@ def context_additional_information(self) -> None: def context_memory(self) -> None: for address, opt in sorted(gef.ui.watches.items()): sz, fmt = opt[0:2] - self.context_title("memory:{:#x}".format(address)) + self.context_title(f"memory:{address:#x}") if fmt == "pointers": - gdb.execute("dereference -l {size:d} {address:#x}".format( - address=address, - size=sz, - )) + gdb.execute(f"dereference -l {sz:d} {address:#x}") else: - gdb.execute("hexdump {fmt:s} -s {size:d} {address:#x}".format( - address=address, - size=sz, - fmt=fmt, - )) + gdb.execute(f"hexdump {fmt} -s {sz:d} {address:#x}") @classmethod def update_registers(cls, _) -> None: @@ -8811,7 +8783,7 @@ def empty_extra_messages(self, _) -> None: class MemoryCommand(GenericCommand): """Add or remove address ranges to the memory view.""" _cmdline_ = "memory" - _syntax_ = "{:s} (watch|unwatch|reset|list)".format(_cmdline_) + _syntax_ = f"{_cmdline_} (watch|unwatch|reset|list)" def __init__(self) -> None: super().__init__(prefix=True) @@ -8827,8 +8799,9 @@ def do_invoke(self, argv: List) -> None: class MemoryWatchCommand(GenericCommand): """Adds address ranges to the memory view.""" _cmdline_ = "memory watch" - _syntax_ = "{:s} ADDRESS [SIZE] [(qword|dword|word|byte|pointers)]".format(_cmdline_) - _example_ = "\n\t{0:s} 0x603000 0x100 byte\n\t{0:s} $sp".format(_cmdline_) + _syntax_ = f"{_cmdline_} ADDRESS [SIZE] [(qword|dword|word|byte|pointers)]" + _example_ = (f"\n{_cmdline_} 0x603000 0x100 byte" + f"\n{_cmdline_} $sp") def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -8847,7 +8820,7 @@ def do_invoke(self, argv: List) -> None: if len(argv) == 3: group = argv[2].lower() if group not in ("qword", "dword", "word", "byte", "pointers"): - warn("Unexpected grouping '{}'".format(group)) + warn(f"Unexpected grouping '{group}'") self.usage() return else: @@ -8857,7 +8830,7 @@ def do_invoke(self, argv: List) -> None: group = "qword" gef.ui.watches[address] = (size, group) - ok("Adding memwatch to {:#x}".format(address)) + ok(f"Adding memwatch to {address:#x}") return @@ -8865,8 +8838,9 @@ def do_invoke(self, argv: List) -> None: class MemoryUnwatchCommand(GenericCommand): """Removes address ranges to the memory view.""" _cmdline_ = "memory unwatch" - _syntax_ = "{:s} ADDRESS".format(_cmdline_) - _example_ = "\n\t{0:s} 0x603000\n\t{0:s} $sp".format(_cmdline_) + _syntax_ = f"{_cmdline_} ADDRESS" + _example_ = (f"\n{_cmdline_} 0x603000" + f"\n{_cmdline_} $sp") def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -8881,9 +8855,9 @@ def do_invoke(self, argv: List) -> None: address = parse_address(argv[0]) res = gef.ui.watches.pop(address, None) if not res: - warn("You weren't watching {:#x}".format(address)) + warn(f"You weren't watching {address:#x}") else: - ok("Removed memwatch of {:#x}".format(address)) + ok(f"Removed memwatch of {address:#x}") return @@ -8891,7 +8865,7 @@ def do_invoke(self, argv: List) -> None: class MemoryWatchResetCommand(GenericCommand): """Removes all watchpoints.""" _cmdline_ = "memory reset" - _syntax_ = "{:s}".format(_cmdline_) + _syntax_ = f"{_cmdline_}" @only_if_gdb_running def do_invoke(self, argv: List) -> None: @@ -8904,7 +8878,7 @@ def do_invoke(self, argv: List) -> None: class MemoryWatchListCommand(GenericCommand): """Lists all watchpoints to display in context layout.""" _cmdline_ = "memory list" - _syntax_ = "{:s}".format(_cmdline_) + _syntax_ = f"{_cmdline_}" @only_if_gdb_running def do_invoke(self, argv: List) -> None: @@ -8914,7 +8888,7 @@ def do_invoke(self, argv: List) -> None: info("Memory watches:") for address, opt in sorted(gef.ui.watches.items()): - gef_print("- {:#x} ({}, {})".format(address, opt[0], opt[1])) + gef_print(f"- {address:#x} ({opt[0]}, {opt[1]})") return @@ -8923,8 +8897,8 @@ class HexdumpCommand(GenericCommand): """Display SIZE lines of hexdump from the memory location pointed by LOCATION.""" _cmdline_ = "hexdump" - _syntax_ = "{:s} (qword|dword|word|byte) [LOCATION] [--size SIZE] [--reverse]".format(_cmdline_) - _example_ = "{:s} byte $rsp --size 16 --reverse".format(_cmdline_) + _syntax_ = f"{_cmdline_} (qword|dword|word|byte) [LOCATION] [--size SIZE] [--reverse]" + _example_ = f"{_cmdline_} byte $rsp --size 16 --reverse" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION, prefix=True) @@ -8975,8 +8949,8 @@ def _hexdump(self, start_addr: int, length: int, arrange_as: str, offset: int = } r, l = formats[arrange_as] - fmt_str = "{{base}}{v}+{{offset:#06x}} {{sym}}{{val:#0{prec}x}} {{text}}".format(v=VERTICAL_LINE, prec=l*2+2) - fmt_pack = f"{endianness:s}{r}" + fmt_str = f"{{base}}{VERTICAL_LINE}+{{offset:#06x}} {{sym}}{{val:#0{l*2+2}x}} {{text}}" + fmt_pack = f"{endianness!s}{r}" lines = [] i = 0 @@ -9001,8 +8975,8 @@ class HexdumpQwordCommand(HexdumpCommand): """Display SIZE lines of hexdump as QWORD from the memory location pointed by ADDRESS.""" _cmdline_ = "hexdump qword" - _syntax_ = "{:s} [ADDRESS] [[L][SIZE]] [REVERSE]".format(_cmdline_) - _example_ = "{:s} qword $rsp L16 REVERSE".format(_cmdline_) + _syntax_ = f"{_cmdline_} [ADDRESS] [[L][SIZE]] [REVERSE]" + _example_ = f"{_cmdline_} qword $rsp L16 REVERSE" def __init__(self) -> None: super().__init__() @@ -9015,8 +8989,8 @@ class HexdumpDwordCommand(HexdumpCommand): """Display SIZE lines of hexdump as DWORD from the memory location pointed by ADDRESS.""" _cmdline_ = "hexdump dword" - _syntax_ = "{:s} [ADDRESS] [[L][SIZE]] [REVERSE]".format(_cmdline_) - _example_ = "{:s} $esp L16 REVERSE".format(_cmdline_) + _syntax_ = f"{_cmdline_} [ADDRESS] [[L][SIZE]] [REVERSE]" + _example_ = f"{_cmdline_} $esp L16 REVERSE" def __init__(self) -> None: super().__init__() @@ -9029,8 +9003,8 @@ class HexdumpWordCommand(HexdumpCommand): """Display SIZE lines of hexdump as WORD from the memory location pointed by ADDRESS.""" _cmdline_ = "hexdump word" - _syntax_ = "{:s} [ADDRESS] [[L][SIZE]] [REVERSE]".format(_cmdline_) - _example_ = "{:s} $esp L16 REVERSE".format(_cmdline_) + _syntax_ = f"{_cmdline_} [ADDRESS] [[L][SIZE]] [REVERSE]" + _example_ = f"{_cmdline_} $esp L16 REVERSE" def __init__(self) -> None: super().__init__() @@ -9043,8 +9017,8 @@ class HexdumpByteCommand(HexdumpCommand): """Display SIZE lines of hexdump as BYTE from the memory location pointed by ADDRESS.""" _cmdline_ = "hexdump byte" - _syntax_ = "{:s} [ADDRESS] [[L][SIZE]] [REVERSE]".format(_cmdline_) - _example_ = "{:s} $rsp L16".format(_cmdline_) + _syntax_ = f"{_cmdline_} [ADDRESS] [[L][SIZE]] [REVERSE]" + _example_ = f"{_cmdline_} $rsp L16" def __init__(self) -> None: super().__init__() @@ -9057,8 +9031,8 @@ class PatchCommand(GenericCommand): """Write specified values to the specified address.""" _cmdline_ = "patch" - _syntax_ = ("{0:s} (qword|dword|word|byte) LOCATION VALUES\n" - "{0:s} string LOCATION \"double-escaped string\"".format(_cmdline_)) + _syntax_ = (f"{_cmdline_} (qword|dword|word|byte) LOCATION VALUES\n" + f"{_cmdline_} string LOCATION \"double-escaped string\"") SUPPORTED_SIZES = { "qword": (8, "Q"), "dword": (4, "L"), @@ -9100,8 +9074,8 @@ class PatchQwordCommand(PatchCommand): """Write specified QWORD to the specified address.""" _cmdline_ = "patch qword" - _syntax_ = "{0:s} LOCATION QWORD1 [QWORD2 [QWORD3..]]".format(_cmdline_) - _example_ = "{:s} $rip 0x4141414141414141".format(_cmdline_) + _syntax_ = f"{_cmdline_} LOCATION QWORD1 [QWORD2 [QWORD3..]]" + _example_ = f"{_cmdline_} $rip 0x4141414141414141" def __init__(self) -> None: super().__init__() @@ -9114,8 +9088,8 @@ class PatchDwordCommand(PatchCommand): """Write specified DWORD to the specified address.""" _cmdline_ = "patch dword" - _syntax_ = "{0:s} LOCATION DWORD1 [DWORD2 [DWORD3..]]".format(_cmdline_) - _example_ = "{:s} $rip 0x41414141".format(_cmdline_) + _syntax_ = f"{_cmdline_} LOCATION DWORD1 [DWORD2 [DWORD3..]]" + _example_ = f"{_cmdline_} $rip 0x41414141" def __init__(self) -> None: super().__init__() @@ -9128,8 +9102,8 @@ class PatchWordCommand(PatchCommand): """Write specified WORD to the specified address.""" _cmdline_ = "patch word" - _syntax_ = "{0:s} LOCATION WORD1 [WORD2 [WORD3..]]".format(_cmdline_) - _example_ = "{:s} $rip 0x4141".format(_cmdline_) + _syntax_ = f"{_cmdline_} LOCATION WORD1 [WORD2 [WORD3..]]" + _example_ = f"{_cmdline_} $rip 0x4141" def __init__(self) -> None: super().__init__() @@ -9142,8 +9116,8 @@ class PatchByteCommand(PatchCommand): """Write specified WORD to the specified address.""" _cmdline_ = "patch byte" - _syntax_ = "{0:s} LOCATION BYTE1 [BYTE2 [BYTE3..]]".format(_cmdline_) - _example_ = "{:s} $pc 0x41 0x41 0x41 0x41 0x41".format(_cmdline_) + _syntax_ = f"{_cmdline_} LOCATION BYTE1 [BYTE2 [BYTE3..]]" + _example_ = f"{_cmdline_} $pc 0x41 0x41 0x41 0x41 0x41" def __init__(self) -> None: super().__init__() @@ -9156,8 +9130,8 @@ class PatchStringCommand(GenericCommand): """Write specified string to the specified memory location pointed by ADDRESS.""" _cmdline_ = "patch string" - _syntax_ = "{:s} ADDRESS \"double backslash-escaped string\"".format(_cmdline_) - _example_ = "{:s} $sp \"GEFROCKS\"".format(_cmdline_) + _syntax_ = f"{_cmdline_} ADDRESS \"double backslash-escaped string\"" + _example_ = f"{_cmdline_} $sp \"GEFROCKS\"" @only_if_gdb_running def do_invoke(self, argv: List) -> None: @@ -9172,7 +9146,7 @@ def do_invoke(self, argv: List) -> None: try: s = codecs.escape_decode(s)[0] except binascii.Error: - gef_print("Could not decode '\\xXX' encoded string \"{}\"".format(s)) + gef_print(f"Could not decode '\\xXX' encoded string \"{s}\"") return gef.memory.write(addr, s, len(s)) @@ -9216,7 +9190,7 @@ def dereference_from(addr: int) -> List[str]: if addr.section: if addr.section.is_executable() and addr.is_in_text_segment() and not is_ascii_string(addr.value): insn = gef_current_instruction(addr.value) - insn_str = "{} {} {}".format(insn.location, insn.mnemonic, ", ".join(insn.operands)) + insn_str = f"{insn.location} {insn.mnemonic} {', '.join(insn.operands)}" msg.append(Color.colorify(insn_str, code_color)) break @@ -9224,11 +9198,11 @@ def dereference_from(addr: int) -> List[str]: if is_ascii_string(addr.value): s = gef.memory.read_cstring(addr.value) if len(s) < gef.arch.ptrsize: - txt = '{:s} ("{:s}"?)'.format(format_address(deref), Color.colorify(s, string_color)) + txt = f'{format_address(deref)} ("{Color.colorify(s, string_color)}"?)' elif len(s) > 50: - txt = Color.colorify('"{:s}[...]"'.format(s[:50]), string_color) + txt = Color.colorify(f'"{s[:50]}[...]"', string_color) else: - txt = Color.colorify('"{:s}"'.format(s), string_color) + txt = Color.colorify(f'"{s}"', string_color) msg.append(txt) break @@ -9247,9 +9221,9 @@ class DereferenceCommand(GenericCommand): command.""" _cmdline_ = "dereference" - _syntax_ = "{:s} [-h] [--length LENGTH] [--reference REFERENCE] [address]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [-h] [--length LENGTH] [--reference REFERENCE] [address]" _aliases_ = ["telescope", ] - _example_ = "{:s} --length 20 --reference $sp+0x10 $sp".format(_cmdline_) + _example_ = f"{_cmdline_} --length 20 --reference $sp+0x10 $sp" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -9261,7 +9235,7 @@ def pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) -> str: base_address_color = gef.config["theme.dereference_base_address"] registers_color = gef.config["theme.dereference_register_value"] - sep = " {:s} ".format(RIGHT_ARROW) + sep = f" {RIGHT_ARROW} " memalign = gef.arch.ptrsize offset = idx * memalign @@ -9269,9 +9243,9 @@ def pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) -> str: addrs = dereference_from(current_address) l = "" addr_l = format_address(int(addrs[0], 16)) - l += "{:s}{:s}{:+#07x}: {:{ma}s}".format(Color.colorify(addr_l, base_address_color), - VERTICAL_LINE, base_offset+offset, - sep.join(addrs[1:]), ma=(memalign*2 + 2)) + l += "{}{}{:+#07x}: {:{ma}s}".format(Color.colorify(addr_l, base_address_color), + VERTICAL_LINE, base_offset+offset, + sep.join(addrs[1:]), ma=(memalign*2 + 2)) register_hints = [] @@ -9281,7 +9255,7 @@ def pprint_dereferenced(addr: int, idx: int, base_offset: int = 0) -> str: register_hints.append(regname) if register_hints: - m = "\t{:s}{:s}".format(LEFT_ARROW, ", ".join(list(register_hints))) + m = f"\t{LEFT_ARROW}{', '.join(list(register_hints))}" l += Color.colorify(m, registers_color) offset += memalign @@ -9300,11 +9274,11 @@ def do_invoke(self, *args, **kwargs) -> None: ref_addr = parse_address(reference) if process_lookup_address(target_addr) is None: - err("Unmapped address: '{}'".format(target)) + err(f"Unmapped address: '{target}'") return if process_lookup_address(ref_addr) is None: - err("Unmapped address: '{}'".format(reference)) + err(f"Unmapped address: '{reference}'") return if gef.config["context.grow_stack_down"] is True: @@ -9331,7 +9305,7 @@ class ASLRCommand(GenericCommand): attached). This command allows to change that setting.""" _cmdline_ = "aslr" - _syntax_ = "{:s} [(on|off)]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [(on|off)]" def do_invoke(self, argv: List) -> None: argc = len(argv) @@ -9386,8 +9360,8 @@ class VMMapCommand(GenericCommand): filter out the mapping whose pathname do not match that filter.""" _cmdline_ = "vmmap" - _syntax_ = "{:s} [FILTER]".format(_cmdline_) - _example_ = "{:s} libc".format(_cmdline_) + _syntax_ = f"{_cmdline_} [FILTER]" + _example_ = f"{_cmdline_} libc" @only_if_gdb_running def do_invoke(self, argv: List) -> None: @@ -9468,8 +9442,8 @@ class XFilesCommand(GenericCommand): If an argument name is also given, the output will grep to the name within FILE.""" _cmdline_ = "xfiles" - _syntax_ = "{:s} [FILE [NAME]]".format(_cmdline_) - _example_ = "\n{0:s} libc\n{0:s} libc IO_vtables".format(_cmdline_) + _syntax_ = f"{_cmdline_} [FILE [NAME]]" + _example_ = f"\n{_cmdline_} libc\n{_cmdline_} libc IO_vtables" @only_if_gdb_running def do_invoke(self, argv: List) -> None: @@ -9490,7 +9464,7 @@ def do_invoke(self, argv: List) -> None: l = [] l.append(format_address(xfile.zone_start)) l.append(format_address(xfile.zone_end)) - l.append("{:<21s}".format(xfile.name)) + l.append(f"{xfile.name:<21s}") l.append(xfile.filename) gef_print(" ".join(l)) return @@ -9501,8 +9475,8 @@ class XAddressInfoCommand(GenericCommand): """Retrieve and display runtime information for the location(s) given as parameter.""" _cmdline_ = "xinfo" - _syntax_ = "{:s} LOCATION".format(_cmdline_) - _example_ = "{:s} $pc".format(_cmdline_) + _syntax_ = f"{_cmdline_} LOCATION" + _example_ = f"{_cmdline_} $pc" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) @@ -9518,44 +9492,41 @@ def do_invoke(self, argv: List) -> None: for sym in argv: try: addr = align_address(parse_address(sym)) - gef_print(titlify("xinfo: {:#x}".format(addr))) + gef_print(titlify(f"xinfo: {addr:#x}")) self.infos(addr) except gdb.error as gdb_err: - err("{:s}".format(str(gdb_err))) + err(f"{gdb_err}") return def infos(self, address: int) -> None: addr = lookup_address(address) if not addr.valid: - warn("Cannot reach {:#x} in memory space".format(address)) + warn(f"Cannot reach {address:#x} in memory space") return sect = addr.section info = addr.info if sect: - gef_print("Page: {:s} {:s} {:s} (size={:#x})".format(format_address(sect.page_start), - RIGHT_ARROW, - format_address(sect.page_end), - sect.page_end-sect.page_start)) - gef_print("Permissions: {}".format(sect.permission)) - gef_print("Pathname: {:s}".format(sect.path)) - gef_print("Offset (from page): {:#x}".format(addr.value-sect.page_start)) - gef_print("Inode: {:s}".format(sect.inode)) + gef_print(f"Page: {format_address(sect.page_start)} {RIGHT_ARROW} " + f"{format_address(sect.page_end)} (size={sect.page_end-sect.page_start:#x})") + gef_print(f"Permissions: {sect.permission}") + gef_print(f"Pathname: {sect.path}") + gef_print(f"Offset (from page): {addr.value-sect.page_start:#x}") + gef_print(f"Inode: {sect.inode}") if info: - gef_print("Segment: {:s} ({:s}-{:s})".format(info.name, - format_address(info.zone_start), - format_address(info.zone_end))) - gef_print("Offset (from segment): {:#x}".format(addr.value-info.zone_start)) + gef_print(f"Segment: {info.name} " + f"({format_address(info.zone_start)}-{format_address(info.zone_end)})") + gef_print(f"Offset (from segment): {addr.value-info.zone_start:#x}") sym = gdb_get_location_from_symbol(address) if sym: name, offset = sym - msg = "Symbol: {:s}".format(name) + msg = f"Symbol: {name}" if offset: - msg+= "+{:d}".format(offset) + msg+= f"+{offset:d}" gef_print(msg) return @@ -9567,7 +9538,7 @@ class XorMemoryCommand(GenericCommand): runtime at runtime.""" _cmdline_ = "xor-memory" - _syntax_ = "{:s} (display|patch) ADDRESS SIZE KEY".format(_cmdline_) + _syntax_ = f"{_cmdline_} (display|patch) ADDRESS SIZE KEY" def __init__(self) -> None: super().__init__(prefix=True) @@ -9584,8 +9555,8 @@ class XorMemoryDisplayCommand(GenericCommand): provided in hexadecimal format.""" _cmdline_ = "xor-memory display" - _syntax_ = "{:s} ADDRESS SIZE KEY".format(_cmdline_) - _example_ = "{:s} $sp 16 41414141".format(_cmdline_) + _syntax_ = f"{_cmdline_} ADDRESS SIZE KEY" + _example_ = f"{_cmdline_} $sp 16 41414141" @only_if_gdb_running def do_invoke(self, argv: List) -> None: @@ -9597,7 +9568,7 @@ def do_invoke(self, argv: List) -> None: length = int(argv[1], 0) key = argv[2] block = gef.memory.read(address, length) - info("Displaying XOR-ing {:#x}-{:#x} with {:s}".format(address, address + len(block), repr(key))) + info(f"Displaying XOR-ing {address:#x}-{address + len(block):#x} with {key!r}") gef_print(titlify("Original block")) gef_print(hexdump(block, base=address)) @@ -9613,8 +9584,8 @@ class XorMemoryPatchCommand(GenericCommand): provided in hexadecimal format.""" _cmdline_ = "xor-memory patch" - _syntax_ = "{:s} ADDRESS SIZE KEY".format(_cmdline_) - _example_ = "{:s} $sp 16 41414141".format(_cmdline_) + _syntax_ = f"{_cmdline_} ADDRESS SIZE KEY" + _example_ = f"{_cmdline_} $sp 16 41414141" @only_if_gdb_running def do_invoke(self, argv: List) -> None: @@ -9626,7 +9597,7 @@ def do_invoke(self, argv: List) -> None: length = int(argv[1], 0) key = argv[2] block = gef.memory.read(address, length) - info("Patching XOR-ing {:#x}-{:#x} with '{:s}'".format(address, address + len(block), key)) + info(f"Patching XOR-ing {address:#x}-{address + len(block):#x} with {key!r}") xored_block = xor(block, key) gef.memory.write(address, xored_block, length) return @@ -9639,8 +9610,8 @@ class TraceRunCommand(GenericCommand): path.""" _cmdline_ = "trace-run" - _syntax_ = "{:s} LOCATION [MAX_CALL_DEPTH]".format(_cmdline_) - _example_ = "{:s} 0x555555554610".format(_cmdline_) + _syntax_ = f"{_cmdline_} LOCATION [MAX_CALL_DEPTH]" + _example_ = f"{_cmdline_} 0x555555554610" def __init__(self) -> None: super().__init__(self._cmdline_, complete=gdb.COMPLETE_LOCATION) @@ -9663,7 +9634,7 @@ def do_invoke(self, argv: List) -> None: loc_start = gef.arch.pc loc_end = parse_address(argv[0]) except gdb.error as e: - err("Invalid location: {:s}".format(e)) + err(f"Invalid location: {e}") return self.trace(loc_start, loc_end, depth) @@ -9678,14 +9649,14 @@ def get_frames_size(self) -> int: return n def trace(self, loc_start: int, loc_end: int, depth: int) -> None: - info("Tracing from {:#x} to {:#x} (max depth={:d})".format(loc_start, loc_end, depth)) - logfile = "{:s}{:#x}-{:#x}.txt".format(self["tracefile_prefix"], loc_start, loc_end) + info(f"Tracing from {loc_start:#x} to {loc_end:#x} (max depth={depth:d})") + logfile = f"{self['tracefile_prefix']}{loc_start:#x}-{loc_end:#x}.txt" enable_redirect_output(to_file=logfile) hide_context() self.start_tracing(loc_start, loc_end, depth) unhide_context() disable_redirect_output() - ok("Done, logfile stored as '{:s}'".format(logfile)) + ok(f"Done, logfile stored as '{logfile}'") info("Hint: import logfile with `ida_color_gdb_trace.py` script in IDA to visualize path") return @@ -9694,10 +9665,10 @@ def start_tracing(self, loc_start: int, loc_end: int, depth: int) -> None: frame_count_init = self.get_frames_size() gef_print("#") - gef_print("# Execution tracing of {:s}".format(get_filepath())) - gef_print("# Start address: {:s}".format(format_address(loc_start))) - gef_print("# End address: {:s}".format(format_address(loc_end))) - gef_print("# Recursion level: {:d}".format(depth)) + gef_print(f"# Execution tracing of {get_filepath()}") + gef_print(f"# Start address: {format_address(loc_start)}") + gef_print(f"# End address: {format_address(loc_end)}") + gef_print(f"# Recursion level: {depth:d}") gef_print("# automatically generated by gef.py") gef_print("#\n") @@ -9715,8 +9686,8 @@ def start_tracing(self, loc_start: int, loc_end: int, depth: int) -> None: except gdb.error as e: gef_print("#") - gef_print("# Execution interrupted at address {:s}".format(format_address(loc_cur))) - gef_print("# Exception: {:s}".format(e)) + gef_print(f"# Execution interrupted at address {format_address(loc_cur)}") + gef_print(f"# Exception: {e}") gef_print("#\n") break @@ -9730,7 +9701,7 @@ class PatternCommand(GenericCommand): currently loaded architecture.""" _cmdline_ = "pattern" - _syntax_ = "{:s} (create|search) ARGS".format(_cmdline_) + _syntax_ = f"{_cmdline_} (create|search) ARGS" def __init__(self) -> None: super().__init__(prefix=True) @@ -9749,18 +9720,18 @@ class PatternCreateCommand(GenericCommand): loaded architecture.""" _cmdline_ = "pattern create" - _syntax_ = "{:s} [-h] [-n N] [length]".format(_cmdline_) - _example_ = "{:s} 4096".format(_cmdline_) + _syntax_ = f"{_cmdline_} [-h] [-n N] [length]" + _example_ = f"{_cmdline_} 4096" @parse_arguments({"length": 0}, {("-n", "--n"): 0}) def do_invoke(self, *args, **kwargs) -> None: args = kwargs["arguments"] length = args.length or gef.config["pattern.length"] n = args.n or gef.arch.ptrsize - info("Generating a pattern of {:d} bytes (n={:d})".format(length, n)) + info(f"Generating a pattern of {length:d} bytes (n={n:d})") pattern_str = gef_pystring(generate_cyclic_pattern(length, n)) gef_print(pattern_str) - ok("Saved as '{:s}'".format(gef_convenience(pattern_str))) + ok(f"Saved as '{gef_convenience(pattern_str)}'") return @@ -9772,8 +9743,10 @@ class PatternSearchCommand(GenericCommand): (such as a register name), a string or a hexadecimal value""" _cmdline_ = "pattern search" - _syntax_ = "{:s} [-h] [-n N] [--max-length MAX_LENGTH] [pattern]".format(_cmdline_) - _example_ = "\n{0:s} $pc\n{0:s} 0x61616164\n{0:s} aaab".format(_cmdline_) + _syntax_ = f"{_cmdline_} [-h] [-n N] [--max-length MAX_LENGTH] [pattern]" + _example_ = (f"\n{_cmdline_} $pc" + f"\n{_cmdline_} 0x61616164" + f"\n{_cmdline_} aaab") _aliases_ = ["pattern offset"] @only_if_gdb_running @@ -9782,7 +9755,7 @@ def do_invoke(self, *args, **kwargs) -> None: args = kwargs["arguments"] max_length = args.max_length or gef.config["pattern.length"] n = args.n or gef.arch.ptrsize - info("Searching for '{:s}'".format(args.pattern)) + info(f"Searching for '{args.pattern}'") self.search(args.pattern, max_length, n) return @@ -9802,8 +9775,8 @@ def search(self, pattern: str, size: int, period: int) -> None: 4: "I", 8: "Q", } - pattern_be = struct.pack(">{}".format(struct_packsize[gef.arch.ptrsize]), addr) - pattern_le = struct.pack("<{}".format(struct_packsize[gef.arch.ptrsize]), addr) + pattern_be = struct.pack(f">{struct_packsize[gef.arch.ptrsize]}", addr) + pattern_le = struct.pack(f"<{struct_packsize[gef.arch.ptrsize]}", addr) else: # 2. assume it's a plain string pattern_be = gef_pybytes(pattern) @@ -9813,16 +9786,18 @@ def search(self, pattern: str, size: int, period: int) -> None: found = False off = cyclic_pattern.find(pattern_le) if off >= 0: - ok("Found at offset {:d} (little-endian search) {:s}".format(off, Color.colorify("likely", "bold red") if is_little_endian() else "")) + ok(f"Found at offset {off:d} (little-endian search) " + f"{Color.colorify('likely', 'bold red') if is_little_endian() else ''}") found = True off = cyclic_pattern.find(pattern_be) if off >= 0: - ok("Found at offset {:d} (big-endian search) {:s}".format(off, Color.colorify("likely", "bold green") if is_big_endian() else "")) + ok(f"Found at offset {off:d} (big-endian search) " + f"{Color.colorify('likely', 'bold green') if is_big_endian() else ''}") found = True if not found: - err("Pattern '{}' not found".format(pattern)) + err(f"Pattern '{pattern}' not found") return @@ -9837,8 +9812,8 @@ class ChecksecCommand(GenericCommand): - Fortify Source""" _cmdline_ = "checksec" - _syntax_ = "{:s} [FILENAME]".format(_cmdline_) - _example_ = "{} /bin/ls".format(_cmdline_) + _syntax_ = f"{_cmdline_} [FILENAME]" + _example_ = f"{_cmdline_} /bin/ls" def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_FILENAME) @@ -9861,7 +9836,7 @@ def do_invoke(self, argv: List) -> None: self.usage() return - info("{:s} for '{:s}'".format(self._cmdline_, filename)) + info(f"{self._cmdline_} for '{filename}'") self.print_security_properties(filename) return @@ -9873,16 +9848,16 @@ def print_security_properties(self, filename: str) -> None: msg = Color.greenify(Color.boldify(TICK)) if val is True else Color.redify(Color.boldify(CROSS)) if val and prop == "Canary" and is_alive(): canary = gef_read_canary()[0] - msg+= "(value: {:#x})".format(canary) + msg+= f"(value: {canary:#x})" - gef_print("{:<30s}: {:s}".format(prop, msg)) + gef_print(f"{prop:<30s}: {msg}") if sec["Full RelRO"]: - gef_print("{:<30s}: {:s}".format("RelRO", Color.greenify("Full"))) + gef_print(f"{'RelRO':<30s}: {Color.greenify('Full')}") elif sec["Partial RelRO"]: - gef_print("{:<30s}: {:s}".format("RelRO", Color.yellowify("Partial"))) + gef_print(f"{'RelRO':<30s}: {Color.yellowify('Partial')}") else: - gef_print("{:<30s}: {:s}".format("RelRO", Color.redify(Color.boldify(CROSS)))) + gef_print(f"{'RelRO':<30s}: {Color.redify(Color.boldify(CROSS))}") return @@ -9891,7 +9866,7 @@ class GotCommand(GenericCommand): """Display current status of the got inside the process.""" _cmdline_ = "got" - _syntax_ = "{:s} [FUNCTION_NAME ...] ".format(_cmdline_) + _syntax_ = f"{_cmdline_} [FUNCTION_NAME ...] " _example_ = "got read printf exit" def __init__(self, *args, **kwargs): @@ -9947,7 +9922,7 @@ def do_invoke(self, argv: List) -> None: # retrieve jump slots using readelf jmpslots = self.get_jmp_slots(readelf, get_filepath()) - gef_print("\nGOT protection: {} | GOT functions: {}\n ".format(relro_status, len(jmpslots))) + gef_print(f"\nGOT protection: {relro_status} | GOT functions: {len(jmpslots)}\n ") for line in jmpslots: address, _, _, _, name = line.split()[:5] @@ -9972,8 +9947,8 @@ def do_invoke(self, argv: List) -> None: else: color = self["function_resolved"] # function has already been resolved - line = "[{}] ".format(hex(address_val)) - line += Color.colorify("{} {} {}".format(name, RIGHT_ARROW, hex(got_address)), color) + line = f"[{hex(address_val)}] " + line += Color.colorify(f"{name} {RIGHT_ARROW} {hex(got_address)}", color) gef_print(line) return @@ -9983,7 +9958,7 @@ def do_invoke(self, argv: List) -> None: class HighlightCommand(GenericCommand): """Highlight user-defined text matches in GEF output universally.""" _cmdline_ = "highlight" - _syntax_ = "{} (add|remove|list|clear)".format(_cmdline_) + _syntax_ = f"{_cmdline_} (add|remove|list|clear)" _aliases_ = ["hl"] def __init__(self) -> None: @@ -10008,7 +9983,8 @@ def print_highlight_table(self) -> None: left_pad = max(map(len, gef.ui.highlight_table.keys())) for match, color in sorted(gef.ui.highlight_table.items()): - print("{} {} {}".format(Color.colorify(match.ljust(left_pad), color), VERTICAL_LINE, Color.colorify(color, color))) + print(f"{Color.colorify(match.ljust(left_pad), color)} {VERTICAL_LINE} " + f"{Color.colorify(color, color)}") return def do_invoke(self, argv: List) -> None: @@ -10030,9 +10006,9 @@ def do_invoke(self, argv: List) -> None: class HighlightAddCommand(GenericCommand): """Add a match to the highlight table.""" _cmdline_ = "highlight add" - _syntax_ = "{} MATCH COLOR".format(_cmdline_) + _syntax_ = f"{_cmdline_} MATCH COLOR" _aliases_ = ["highlight set", "hla"] - _example_ = "{} 41414141 yellow".format(_cmdline_) + _example_ = f"{_cmdline_} 41414141 yellow" def do_invoke(self, argv: List) -> None: if len(argv) < 2: @@ -10047,7 +10023,7 @@ def do_invoke(self, argv: List) -> None: class HighlightRemoveCommand(GenericCommand): """Remove a match in the highlight table.""" _cmdline_ = "highlight remove" - _syntax_ = "{} MATCH".format(_cmdline_) + _syntax_ = f"{_cmdline_} MATCH" _aliases_ = [ "highlight delete", "highlight del", @@ -10055,7 +10031,7 @@ class HighlightRemoveCommand(GenericCommand): "highlight rm", "hlr", ] - _example_ = "{} remove 41414141".format(_cmdline_) + _example_ = f"{_cmdline_} remove 41414141" def do_invoke(self, argv: List) -> None: if not argv: @@ -10093,7 +10069,8 @@ def do_invoke(self, argv: List) -> None: FormatStringBreakpoint(function_name, argument_number) nb_installed_breaks += 1 - ok("Enabled {} FormatString breakpoint{}".format(nb_installed_breaks, "s" if nb_installed_breaks > 1 else "")) + ok(f"Enabled {nb_installed_breaks} FormatString " + f"breakpoint{'s' if nb_installed_breaks > 1 else ''}") return @@ -10147,9 +10124,10 @@ def setup(self) -> None: ok("Disabling hardware watchpoints (this may increase the latency)") gdb.execute("set can-use-hw-watchpoints 0") - info("Dynamic breakpoints correctly setup, GEF will break execution if a possible vulnerabity is found.") - warn("{}: The heap analysis slows down the execution noticeably.".format( - Color.colorify("Note", "bold underline yellow"))) + info("Dynamic breakpoints correctly setup, " + "GEF will break execution if a possible vulnerabity is found.") + warn(f"{Color.colorify('Note', 'bold underline yellow')}: " + "The heap analysis slows down the execution noticeably.") # when inferior quits, we need to clean everything for a next execution gef_on_exit_hook(self.clean) @@ -10160,13 +10138,15 @@ def dump_tracked_allocations(self) -> None: if gef.session.heap_allocated_chunks: ok("Tracked as in-use chunks:") - for addr, sz in gef.session.heap_allocated_chunks: gef_print("{} malloc({:d}) = {:#x}".format(CROSS, sz, addr)) + for addr, sz in gef.session.heap_allocated_chunks: + gef_print(f"{CROSS} malloc({sz:d}) = {addr:#x}") else: ok("No malloc() chunk tracked") if gef.session.heap_freed_chunks: ok("Tracked as free-ed chunks:") - for addr, sz in gef.session.heap_freed_chunks: gef_print("{} free({:d}) = {:#x}".format(TICK, sz, addr)) + for addr, sz in gef.session.heap_freed_chunks: + gef_print(f"{TICK} free({sz:d}) = {addr:#x}") else: ok("No free() chunk tracked") return @@ -10174,13 +10154,14 @@ def dump_tracked_allocations(self) -> None: def clean(self, _) -> None: global gef - ok("{} - Cleaning up".format(Color.colorify("Heap-Analysis", "yellow bold"),)) + ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - Cleaning up") for bp in [self.bp_malloc, self.bp_calloc, self.bp_free, self.bp_realloc]: if hasattr(bp, "retbp") and bp.retbp: try: bp.retbp.delete() except RuntimeError: - # in some cases, gdb was found failing to correctly remove the retbp but they can be safely ignored since the debugging session is over + # in some cases, gdb was found failing to correctly remove the retbp + # but they can be safely ignored since the debugging session is over pass bp.delete() @@ -10192,7 +10173,7 @@ def clean(self, _) -> None: gef.session.heap_freed_chunks = [] gef.session.heap_uaf_watchpoints = [] - ok("{} - Re-enabling hardware watchpoints".format(Color.colorify("Heap-Analysis", "yellow bold"),)) + ok(f"{Color.colorify('Heap-Analysis', 'yellow bold')} - Re-enabling hardware watchpoints") gdb.execute("set can-use-hw-watchpoints 1") gef_on_exit_unhook(self.clean) @@ -10207,7 +10188,7 @@ class IsSyscallCommand(GenericCommand): def do_invoke(self, argv: List) -> None: insn = gef_current_instruction(gef.arch.pc) - ok("Current instruction is{}a syscall".format(" " if self.is_syscall(gef.arch, insn) else " not ")) + ok(f"Current instruction is{' ' if self.is_syscall(gef.arch, insn) else ' not '}a syscall") return @@ -10243,7 +10224,7 @@ def do_invoke(self, argv: List) -> None: reg_value = gef.arch.register(gef.arch.syscall_register) if reg_value not in syscall_table: - warn("There is no system call for {:#x}".format(reg_value)) + warn(f"There is no system call for {reg_value:#x}") return syscall_entry = syscall_table[reg_value] @@ -10254,19 +10235,19 @@ def do_invoke(self, argv: List) -> None: parameters = [s.param for s in syscall_entry.params] registers = [s.reg for s in syscall_entry.params] - info("Detected syscall {}".format(Color.colorify(syscall_entry.name, color))) - gef_print(" {}({})".format(syscall_entry.name, ", ".join(parameters))) + info(f"Detected syscall {Color.colorify(syscall_entry.name, color)}") + gef_print(f" {syscall_entry.name}({', '.join(parameters)})") headers = ["Parameter", "Register", "Value"] param_names = [re.split(r" |\*", p)[-1] for p in parameters] info(Color.colorify("{:<20} {:<20} {}".format(*headers), color)) for name, register, value in zip(param_names, registers, values): - line = " {:<20} {:<20} 0x{:x}".format(name, register, value) + line = f" {name:<20} {register:<20} {value:#x}" addrs = dereference_from(value) if len(addrs) > 1: - sep = " {:s} ".format(RIGHT_ARROW) + sep = f" {RIGHT_ARROW} " line += sep line += sep.join(addrs[1:]) @@ -10277,7 +10258,7 @@ def do_invoke(self, argv: List) -> None: def get_filepath(self, x: str) -> Optional[str]: p = self.get_settings_path() if not p: return None - return os.path.join(p, "{}.py".format(x)) + return os.path.join(p, f"{x}.py") def get_module(self, modname: str): _fullname = self.get_filepath(modname) @@ -10305,7 +10286,7 @@ class GenericFunction(gdb.Function, metaclass=abc.ABCMeta): def _function_(self): pass @property def _syntax_(self) -> str: - return "${}([offset])".format(self._function_) + return f"${self._function_}([offset])" def __init__(self) -> None: super().__init__(self._function_) @@ -10367,13 +10348,13 @@ def do_invoke(self, args: List) -> int: except IndexError: name = gef.session.file.name except gdb.error: - err("Invalid arg: {}".format(args[0])) + err(f"Invalid arg: {args[0]}") return 0 try: addr = int(get_section_base_address(name)) except TypeError: - err("Cannot find section {}".format(name)) + err(f"Cannot find section {name}") return 0 return addr @@ -10428,11 +10409,10 @@ def add_function_to_doc(self, function) -> None: doc = getattr(function, "__doc__", "").lstrip() doc = "\n ".join(doc.split("\n")) syntax = getattr(function, "_syntax_", "").lstrip() - msg = "{syntax:<25s} -- {help:s}".format(syntax=syntax, help=Color.greenify(doc)) + msg = f"{syntax:<25s} -- {Color.greenify(doc)}" example = getattr(function, "_example_", "").strip() if example: - msg += "\n {padding:27s} example: {example:s}".format( - padding="", example=Color.yellowify(example)) + msg += f"\n {'':27s} example: {Color.yellowify(example)}" self.docs.append(msg) return @@ -10452,7 +10432,7 @@ class GefCommand(gdb.Command): """GEF main command: view all new commands by typing `gef`.""" _cmdline_ = "gef" - _syntax_ = "{:s} (missing|config|save|restore|set|run)".format(_cmdline_) + _syntax_ = f"{_cmdline_} (missing|config|save|restore|set|run)" def __init__(self) -> None: super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_NONE, True) @@ -10498,12 +10478,12 @@ def __reload_auto_breakpoints(self) -> None: if bkp_fname: # restore if existing if os.access(bkp_fname, os.R_OK): - gdb.execute("source {:s}".format(bkp_fname)) + gdb.execute(f"source {bkp_fname}") # add hook for autosave breakpoints on quit command source = [ "define hook-quit", - " save breakpoints {:s}".format(bkp_fname), + f" save breakpoints {bkp_fname}", "end", ] gef_execute_gdb_script("\n".join(source) + "\n") @@ -10521,15 +10501,15 @@ def __load_extra_plugins(self) -> int: sys.path.append(directory) for fname in os.listdir(directory): if not fname.endswith(".py"): continue - fpath = "{:s}/{:s}".format(directory, fname) + fpath = f"{directory}/{fname}" if os.path.isfile(fpath): - gdb.execute("source {:s}".format(fpath)) + gdb.execute(f"source {fpath}") nb_added = len(self.loaded_commands) - nb_inital if nb_added > 0: - ok("{:s} extra commands added from '{:s}'".format(Color.colorify(nb_added, "bold green"), - Color.colorify(directories, "bold blue"))) + ok(f"{Color.colorify(nb_added, 'bold green')} extra commands added from " + f"'{Color.colorify(directories, 'bold blue')}'") except gdb.error as e: - err("failed: {}".format(str(e))) + err(f"failed: {e}") return nb_added @property @@ -10554,7 +10534,7 @@ def add_context_pane(self, pane_name: str, display_pane_function: Callable, pane # assure users can toggle the new context corrected_settings_name = pane_name.replace(" ", "_") layout_settings = context.get_setting("layout") - context.update_setting("layout", "{} {}".format(layout_settings, corrected_settings_name)) + context.update_setting("layout", f"{layout_settings} {corrected_settings_name}") # overload the printing of pane title context.layout_mapping[corrected_settings_name] = (display_pane_function, pane_title_function) @@ -10591,23 +10571,20 @@ def is_loaded(x) -> bool: self.loaded_commands = sorted(self.loaded_commands, key=lambda x: x[1]._cmdline_) if initial: - gef_print("{:s} for {:s} ready, type `{:s}' to start, `{:s}' to configure" - .format(Color.greenify("GEF"), gef.session.os, - Color.colorify("gef", "underline yellow"), - Color.colorify("gef config", "underline pink"))) + gef_print(f"{Color.greenify('GEF')} for {gef.session.os} ready, " + f"type `{Color.colorify('gef', 'underline yellow')}' to start, " + f"`{Color.colorify('gef config', 'underline pink')}' to configure") - ver = "{:d}.{:d}".format(sys.version_info.major, sys.version_info.minor) + ver = f"{sys.version_info.major:d}.{sys.version_info.minor:d}" nb_cmds = len(self.loaded_commands) - gef_print("{:s} commands loaded for GDB {:s} using Python engine {:s}" - .format(Color.colorify(nb_cmds, "bold green"), - Color.colorify(gdb.VERSION, "bold yellow"), - Color.colorify(ver, "bold red"))) + gef_print(f"{Color.colorify(nb_cmds, 'bold green')} commands loaded for " + f"GDB {Color.colorify(gdb.VERSION, 'bold yellow')} " + f"using Python engine {Color.colorify(ver, 'bold red')}") if nb_missing: - warn("{:s} command{} could not be loaded, run `{:s}` to know why." - .format(Color.colorify(nb_missing, "bold red"), - "s" if nb_missing > 1 else "", - Color.colorify("gef missing", "underline pink"))) + warn(f"{Color.colorify(nb_missing, 'bold red')} " + f"command{'s' if nb_missing > 1 else ''} could not be loaded, " + f"run `{Color.colorify('gef missing', 'underline pink')}` to know why.") return @@ -10643,8 +10620,8 @@ def add_command_to_doc(self, command: Tuple[str, Any, Any]) -> None: return doc = getattr(class_obj, "__doc__", "").lstrip() doc = "\n ".join(doc.split("\n")) - aliases = " (alias: {:s})".format(", ".join(class_obj._aliases_)) if hasattr(class_obj, "_aliases_") else "" - msg = "{cmd:<25s} -- {help:s}{aliases:s}".format(cmd=cmd, help=doc, aliases=aliases) + aliases = f" (alias: {', '.join(class_obj._aliases_)})" if hasattr(class_obj, "_aliases_") else "" + msg = f"{cmd:<25s} -- {doc}{aliases}" self.docs.append(msg) return @@ -10662,7 +10639,7 @@ class GefConfigCommand(gdb.Command): `gef restore` (refer help). """ _cmdline_ = "gef config" - _syntax_ = "{:s} [setting_name] [setting_value]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [setting_name] [setting_value]" def __init__(self, loaded_commands, *args, **kwargs) -> None: super().__init__(self._cmdline_, gdb.COMMAND_NONE, prefix=False) @@ -10688,10 +10665,10 @@ def invoke(self, args: str, from_tty) -> None: names = [x for x in gef.config.keys() if x.startswith(prefix)] if names: if len(names) == 1: - gef_print(titlify("GEF configuration setting: {:s}".format(names[0]))) + gef_print(titlify(f"GEF configuration setting: {names[0]}")) self.print_setting(names[0], verbose=True) else: - gef_print(titlify("GEF configuration settings matching '{:s}'".format(argv[0]))) + gef_print(titlify(f"GEF configuration settings matching '{argv[0]}'")) for name in names: self.print_setting(name) return @@ -10709,15 +10686,15 @@ def print_setting(self, plugin_name: str, verbose: bool = False) -> None: _setting = Color.colorify(plugin_name, "green") _type = res.type.__name__ if _type == "str": - _value = '"{:s}"'.format(Color.colorify(res.value, string_color)) + _value = f'"{Color.colorify(res.value, string_color)}"' else: _value = Color.colorify(res.value, misc_color) - gef_print("{:s} ({:s}) = {:s}".format(_setting, _type, _value)) + gef_print(f"{_setting} ({_type}) = {_value}") if verbose: gef_print(Color.colorify("\nDescription:", "bold underline")) - gef_print("\t{:s}".format(res.description)) + gef_print(f"\t{res.description}") return def print_settings(self) -> None: @@ -10736,11 +10713,11 @@ def set_setting(self, argv: Tuple[str, Any]) -> None: loaded_commands = [ x[0] for x in gef.gdb.loaded_commands ] + ["gef"] plugin_name = key.split(".", 1)[0] if plugin_name not in loaded_commands: - err("Unknown plugin '{:s}'".format(plugin_name)) + err(f"Unknown plugin '{plugin_name}'") return if key not in gef.config: - err("'{}' is not a valid configuration setting".format(key)) + err(f"'{key}' is not a valid configuration setting") return _type = gef.config.raw_entry(key).type @@ -10752,7 +10729,7 @@ def set_setting(self, argv: Tuple[str, Any]) -> None: gef.config[key] = _newval except Exception: - err("{} expects type '{}'".format(key, _type.__name__)) + err(f"{key} expects type '{_type.__name__}'") return reset_all_caches() @@ -10808,7 +10785,7 @@ def invoke(self, args, from_tty) -> None: with GEF_RC.open("w") as fd: cfg.write(fd) - ok("Configuration saved to '{:s}'".format(str(GEF_RC))) + ok(f"Configuration saved to '{GEF_RC}'") return @@ -10844,7 +10821,7 @@ def invoke(self, args: str, from_tty) -> None: # load the other options for optname in cfg.options(section): try: - key = "{:s}.{:s}".format(section, optname) + key = f"{section}.{optname}" _type = gef.config[key].type new_value = cfg.get(section, optname) if _type == bool: @@ -10859,7 +10836,7 @@ def invoke(self, args: str, from_tty) -> None: gef_makedirs(gef.config["gef.tempdir"]) if not quiet: - ok("Configuration from '{:s}' restored".format(Color.colorify(str(GEF_RC), "bold blue"))) + ok(f"Configuration from '{Color.colorify(str(GEF_RC), 'bold blue')}' restored") return @@ -10884,14 +10861,14 @@ def invoke(self, args, from_tty) -> None: for missing_command in missing_commands: reason = gef.gdb.missing_commands[missing_command] - warn("Command `{}` is missing, reason {} {}".format(missing_command, RIGHT_ARROW, reason)) + warn(f"Command `{missing_command}` is missing, reason {RIGHT_ARROW} {reason}") return class GefSetCommand(gdb.Command): """Override GDB set commands with the context from GEF.""" _cmdline_ = "gef set" - _syntax_ = "{:s} [GDB_SET_ARGUMENTS]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [GDB_SET_ARGUMENTS]" def __init__(self, *args, **kwargs) -> None: super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_SYMBOL, False) @@ -10916,7 +10893,7 @@ class GefRunCommand(gdb.Command): """Override GDB run commands with the context from GEF. Simple wrapper for GDB run command to use arguments set from `gef set args`.""" _cmdline_ = "gef run" - _syntax_ = "{:s} [GDB_RUN_ARGUMENTS]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [GDB_RUN_ARGUMENTS]" def __init__(self, *args, **kwargs) -> None: super().__init__(self._cmdline_, gdb.COMMAND_SUPPORT, gdb.COMPLETE_FILENAME, False) @@ -10929,7 +10906,7 @@ def invoke(self, args, from_tty) -> None: return argv = args.split() - gdb.execute("gef set args {:s}".format(" ".join(argv))) + gdb.execute(f"gef set args {' '.join(argv)}") gdb.execute("run") return @@ -10949,10 +10926,10 @@ def __init__(self, alias, command, completer_class=gdb.COMPLETE_NONE, command_cl self._alias = alias c = command.split()[0] r = self.lookup_command(c) - self.__doc__ = "Alias for '{}'".format(Color.greenify(command)) + self.__doc__ = f"Alias for '{Color.greenify(command)}'" if r is not None: _instance = r[2] - self.__doc__ += ": {}".format(_instance.__doc__) + self.__doc__ += f": {_instance.__doc__}" if hasattr(_instance, "complete"): self.complete = _instance.complete @@ -10962,7 +10939,7 @@ def __init__(self, alias, command, completer_class=gdb.COMPLETE_NONE, command_cl return def invoke(self, args, from_tty) -> None: - gdb.execute("{} {}".format(self._command, args), from_tty=from_tty) + gdb.execute(f"{self._command} {args}", from_tty=from_tty) return def lookup_command(self, cmd: str) -> Optional[Tuple[str, Type, Any]]: @@ -10978,7 +10955,7 @@ class AliasesCommand(GenericCommand): """Base command to add, remove, or list aliases.""" _cmdline_ = "aliases" - _syntax_ = "{:s} (add|rm|ls)".format(_cmdline_) + _syntax_ = f"{_cmdline_} (add|rm|ls)" def __init__(self) -> None: super().__init__(prefix=True) @@ -10993,8 +10970,8 @@ class AliasesAddCommand(AliasesCommand): """Command to add aliases.""" _cmdline_ = "aliases add" - _syntax_ = "{0} [ALIAS] [COMMAND]".format(_cmdline_) - _example_ = "{0} scope telescope".format(_cmdline_) + _syntax_ = f"{_cmdline_} [ALIAS] [COMMAND]" + _example_ = f"{_cmdline_} scope telescope" def __init__(self) -> None: super().__init__() @@ -11012,7 +10989,7 @@ class AliasesRmCommand(AliasesCommand): """Command to remove aliases.""" _cmdline_ = "aliases rm" - _syntax_ = "{0} [ALIAS]".format(_cmdline_) + _syntax_ = f"{_cmdline_} [ALIAS]" def __init__(self) -> None: super().__init__() @@ -11027,7 +11004,7 @@ def do_invoke(self, argv: List) -> None: alias_to_remove = next(filter(lambda x: x._alias == argv[0], gef.session.aliases)) gef.session.aliases.remove(alias_to_remove) except (ValueError, StopIteration): - err("{0} not found in aliases.".format(argv[0])) + err(f"{argv[0]} not found in aliases.") return gef_print("You must reload GEF for alias removals to apply.") return @@ -11046,7 +11023,7 @@ def __init__(self) -> None: def do_invoke(self, argv: List) -> None: ok("Aliases defined:") for a in gef.session.aliases: - gef_print("{:30s} {} {}".format(a._alias, RIGHT_ARROW, a._command)) + gef_print(f"{a._alias:30s} {RIGHT_ARROW} {a._command}") return class GefTmuxSetup(gdb.Command): @@ -11079,13 +11056,13 @@ def tmux_setup(self) -> None: tmux = which("tmux") ok("tmux session found, splitting window...") old_ptses = set(os.listdir("/dev/pts")) - gdb.execute("! {} split-window -h 'clear ; cat'".format(tmux)) - gdb.execute("! {} select-pane -L".format(tmux)) + gdb.execute(f"! {tmux} split-window -h 'clear ; cat'") + gdb.execute(f"! {tmux} select-pane -L") new_ptses = set(os.listdir("/dev/pts")) pty = list(new_ptses - old_ptses)[0] - pty = "/dev/pts/{}".format(pty) - ok("Setting `context.redirect` to '{}'...".format(pty)) - gdb.execute("gef config context.redirect {}".format(pty)) + pty = f"/dev/pts/{pty}" + ok(f"Setting `context.redirect` to '{pty}'...") + gdb.execute(f"gef config context.redirect {pty}") ok("Done!") return @@ -11102,16 +11079,16 @@ def screen_setup(self) -> None: f.write("startup_message off\n") f.write("split -v\n") f.write("focus right\n") - f.write("screen bash -c 'tty > {}; clear; cat'\n".format(tty_path)) + f.write(f"screen bash -c 'tty > {tty_path}; clear; cat'\n") f.write("focus left\n") - gdb.execute("""! {} -r {} -m -d -X source {}""".format(screen, sty, script_path)) + gdb.execute(f"""! {screen} -r {sty} -m -d -X source {script_path}""") # artificial delay to make sure `tty_path` is populated time.sleep(0.25) with open(tty_path, "r") as f: pty = f.read().strip() - ok("Setting `context.redirect` to '{}'...".format(pty)) - gdb.execute("gef config context.redirect {}".format(pty)) + ok(f"Setting `context.redirect` to '{pty}'...") + gdb.execute(f"gef config context.redirect {pty}") ok("Done!") os.unlink(script_path) os.unlink(tty_path) @@ -11178,7 +11155,7 @@ def read_cstring(self, address: int, max_length: int = GEF_MAX_STRING_LENGTH, en try: res_bytes = bytes(self.read(address, length)) except gdb.error: - err("Can't read memory at '{}'".format(address)) + err(f"Can't read memory at '{address}'") return "" try: with warnings.catch_warnings(): @@ -11192,7 +11169,7 @@ def read_cstring(self, address: int, max_length: int = GEF_MAX_STRING_LENGTH, en res = res.split("\x00", 1)[0] ustr = res.replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t") if max_length and len(res) > max_length: - return "{}[...]".format(ustr[:max_length]) + return f"{ustr[:max_length]}[...]" return ustr def read_ascii_string(self, address: int) -> Optional[str]: @@ -11223,7 +11200,7 @@ def open_file(path, use_cache=False): if is_remote_debug() and not gef.session.qemu_mode: lpath = download_file(path, use_cache) if not lpath: - raise IOError("cannot open remote path {:s}".format(path)) + raise IOError(f"cannot open remote path {path}") path = lpath return open(path, "r") @@ -11519,7 +11496,7 @@ def setup(self) -> None: self.gdb.setup() tempdir = self.config["gef.tempdir"] gef_makedirs(tempdir) - gdb.execute("save gdb-index {}".format(tempdir)) + gdb.execute(f"save gdb-index {tempdir}") return def reset_caches(self) -> None: @@ -11538,7 +11515,8 @@ def reset_caches(self) -> None: if GDB_VERSION < GDB_MIN_VERSION or PYTHON_VERSION < PYTHON_MIN_VERSION: err("You're using an old version of GDB. GEF will not work correctly. " - "Consider updating to GDB {} or higher (with Python {} or higher).".format(".".join(map(str, GDB_MIN_VERSION)), ".".join(map(str, PYTHON_MIN_VERSION)))) + f"Consider updating to GDB {'.'.join(map(str, GDB_MIN_VERSION))} or higher " + f"(with Python {'.'.join(map(str, PYTHON_MIN_VERSION))} or higher).") exit(1) try: @@ -11546,7 +11524,7 @@ def reset_caches(self) -> None: PYENV_ROOT = gef_pystring(subprocess.check_output([pyenv, "root"]).strip()) PYENV_VERSION = gef_pystring(subprocess.check_output([pyenv, "version-name"]).strip()) site_packages_dir = os.path.join(PYENV_ROOT, "versions", PYENV_VERSION, "lib", - "python{}".format(PYENV_VERSION[:3]), "site-packages") + f"python{PYENV_VERSION[:3]}", "site-packages") site.addsitedir(site_packages_dir) except FileNotFoundError: pass From 8ad0c4f82dbf160037de579728e22aa1b4636eba Mon Sep 17 00:00:00 2001 From: hugsy Date: Tue, 11 Jan 2022 17:52:18 -0800 Subject: [PATCH 55/62] Fixed PPC specs URL --- docs/api/gef.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/gef.md b/docs/api/gef.md index 9b1ae2542..3b976905c 100644 --- a/docs/api/gef.md +++ b/docs/api/gef.md @@ -5247,7 +5247,7 @@ usage() → None ## class `Elf` Basic ELF parsing. Ref: - http://www.skyfree.org/linux/references/ELF_Format.pdf -- http://refspecs.freestandards.org/elf/elfspec_ppc.pdf +- http://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf - http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html From 1683fcb80322a3188ea4e62926c65b8747822fd6 Mon Sep 17 00:00:00 2001 From: hugsy Date: Tue, 11 Jan 2022 19:21:09 -0800 Subject: [PATCH 56/62] [docs] Fixed complete API link in `api.md` --- docs/api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api.md b/docs/api.md index 56ab136e3..f9e6cf48c 100644 --- a/docs/api.md +++ b/docs/api.md @@ -47,7 +47,7 @@ gef.arch=<__main__.X86_64 object at 0x7fd5583571c0> gef.arch.pc=0x55555555a7d0 ``` -Yes, that's it! Check out [the complete API](docs/api/gef.md) to see what else GEF offers. +Yes, that's it! Check out [the complete API](api/gef.md) to see what else GEF offers. ## Detailed explanation @@ -163,7 +163,7 @@ The API also offers a number of decorators to simply the creation of new/existin ### Reference -For a complete reference of the API offered by GEF, visit [docs/api/gef.md](docs/api/gef.md). +For a complete reference of the API offered by GEF, visit [`docs/api/gef.md`](api/gef.md). ### Parsing command arguments From bdea71566c33298b6ac923bc0dc5f35cbaa85e5c Mon Sep 17 00:00:00 2001 From: hugsy Date: Wed, 12 Jan 2022 09:39:38 -0800 Subject: [PATCH 57/62] first run of pr feedback --- docs/api.md | 11 ++++---- docs/compat.md | 6 ++--- gef.py | 67 ++++++++++++++++++++++++++--------------------- tests/helpers.py | 22 +++++++++++++--- tests/runtests.py | 6 ++--- 5 files changed, 66 insertions(+), 46 deletions(-) diff --git a/docs/api.md b/docs/api.md index f9e6cf48c..591af6ca1 100644 --- a/docs/api.md +++ b/docs/api.md @@ -20,14 +20,14 @@ 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_:s}" + _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=}") + print(f"gef.arch={gef.arch}") # or showing the current $pc - print(f"{gef.arch.pc=:#x}") + print(f"gef.arch.pc={gef.arch.pc:#x}") return register_external_command(NewCommand()) @@ -154,13 +154,12 @@ gef ➤ pi print('\n'.join([ f"{x.page_start:#x} -> {x.page_end:#x}" for x in ge ``` -The API also offers a number of decorators to simply the creation of new/existing commands, such as: +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 current GDB session is local i.e. not debugging using GDB `remote`. + - `@only_if_gdb_target_local` to check if the target is local i.e. not debugging using GDB `remote`. - and many more... - ### Reference For a complete reference of the API offered by GEF, visit [`docs/api/gef.md`](api/gef.md). diff --git a/docs/compat.md b/docs/compat.md index 577224044..f705fa435 100644 --- a/docs/compat.md +++ b/docs/compat.md @@ -4,9 +4,9 @@ This matrix indicates the version of Python and/or GDB | GEF version | GDB Python compatibility* | Python compatibility* | |:--:|:--:|:--:| -| [2018.02](https://github.com/hugsy/gef/releases/tag/2018.02) | 7.2 | Python 2.7, Python 3.4 | -| [2020.03](https://github.com/hugsy/gef/releases/tag/2020.03) | 7.4 | Python 2.7, Python 3.4 | -| [2022.01](https://github.com/hugsy/gef/releases/tag/2021.01) | 7.7 | Python 3.4 | +| [2018.02](https://github.com/hugsy/gef/releases/tag/2018.02) | 7.2 | Python 2.7, Python 3.4+ | +| [2020.03](https://github.com/hugsy/gef/releases/tag/2020.03) | 7.4 | Python 2.7, Python 3.4+ | +| [2022.01](https://github.com/hugsy/gef/releases/tag/2021.01) | 7.7 | Python 3.4+ | | [Current](https://github.com/hugsy/gef/tree/master) | 8.0+ | Python 3.6+ | diff --git a/gef.py b/gef.py index 4874f6b72..cac71655c 100644 --- a/gef.py +++ b/gef.py @@ -83,7 +83,7 @@ from io import StringIO from types import ModuleType from typing import (List, Dict, Tuple, Optional, Sequence, Union, Generator, Any, Iterator, - Callable, ByteString, Set, Type) + Callable, ByteString, Set, Type, NoReturn) from urllib.request import urlopen @@ -153,10 +153,10 @@ def update_gef(argv: List[str]) -> int: GEF_PROMPT_OFF = f"\001\033[1;31m\002{GEF_PROMPT}\001\033[0m\002" -gef : "Gef" = None -__registered_commands__ : List["GenericCommand"] = [] -__registered_functions__ : List["GenericFunction"] = [] -__registered_architectures__ : Dict[Union[int, str], "Architecture"] = {} +gef : "Gef" = None +__registered_commands__ : List[Type["GenericCommand"]] = [] +__registered_functions__ : List[Type["GenericFunction"]] = [] +__registered_architectures__ : Dict[Union[int, str], Type["Architecture"]] = {} def reset_all_caches() -> None: @@ -234,7 +234,7 @@ def bufferize(f: Callable) -> Callable: """Store the content to be printed for a function in memory, and flush it on function exit.""" @functools.wraps(f) - def wrapper(*args: Tuple, **kwargs: Dict) -> Any: + def wrapper(*args: Any, **kwargs: Any) -> Any: global gef if gef.ui.stream_buffer: @@ -335,7 +335,7 @@ def only_if_gdb_running(f: Callable) -> Callable: """Decorator wrapper to check if GDB is running.""" @functools.wraps(f) - def wrapper(*args: Tuple, **kwargs: Dict) -> Any: + def wrapper(*args: Any, **kwargs: Any) -> Any: if is_alive(): return f(*args, **kwargs) else: @@ -348,7 +348,7 @@ def only_if_gdb_target_local(f: Callable) -> Callable: """Decorator wrapper to check if GDB is running locally (target not remote).""" @functools.wraps(f) - def wrapper(*args: Tuple, **kwargs: Dict) -> Any: + def wrapper(*args: Any, **kwargs: Any) -> Any: if not is_remote_debug(): return f(*args, **kwargs) else: @@ -427,7 +427,7 @@ def wrapped_f(*args: Tuple, **kwargs: Dict) -> Any: return wrap -def FakeExit(*args, **kwargs) -> None: +def FakeExit(*args, **kwargs) -> NoReturn: raise RuntimeWarning sys.exit = FakeExit @@ -438,7 +438,7 @@ def parse_arguments(required_arguments: Dict, optional_arguments: Dict) -> Optio def int_wrapper(x: str) -> int: return int(x, 0) def decorator(f: Callable) -> Optional[Callable]: - def wrapper(*args: Tuple, **kwargs: Dict) -> Optional[Callable]: + def wrapper(*args: Any, **kwargs: Any) -> Optional[Callable]: parser = argparse.ArgumentParser(prog=args[0]._cmdline_, add_help=True) for argname in required_arguments: argvalue = required_arguments[argname] @@ -455,10 +455,10 @@ def wrapper(*args: Tuple, **kwargs: Dict) -> Optional[Callable]: parser.add_argument(argname, type=argtype, required=True, default=argvalue) else: if argtype in (list, tuple): - nargs = '*' + nargs = "*" argtype = type(argvalue[0]) else: - nargs = '?' + nargs = "?" # positional args parser.add_argument(argname, type=argtype, default=argvalue, nargs=nargs) @@ -598,7 +598,7 @@ class Permission: EXECUTE = 4 ALL = READ | WRITE | EXECUTE - def __init__(self, **kwargs) -> None: + def __init__(self, **kwargs: Any) -> None: self.value = kwargs.get("value", 0) return @@ -625,7 +625,7 @@ def __str__(self) -> str: return perm_str @staticmethod - def from_info_sections(*args: List[str]): + def from_info_sections(*args: List[str]) -> "Permission": perm = Permission() for arg in args: if "READONLY" in arg: @@ -637,7 +637,7 @@ def from_info_sections(*args: List[str]): return perm @staticmethod - def from_process_maps(perm_str: str): + def from_process_maps(perm_str: str) -> "Permission": perm = Permission() if perm_str[0] == "r": perm.value += Permission.READ @@ -681,7 +681,8 @@ def realpath(self) -> str: return self.path if gef.session.remote is None else f"/tmp/gef/{gef.session.remote:d}/{self.path}" def __str__(self) -> str: - return f"Section({self.page_start:#x}, {self.page_end:#x}, {self.permission!s})" + return (f"Section(page_start={self.page_start:#x}, page_end={self.page_end:#x}, " + f"permissions={self.permission!s})") Zone = collections.namedtuple("Zone", ["name", "zone_start", "zone_end", "filename"]) @@ -934,7 +935,7 @@ class Shdr: sh_addralign = None sh_entsize = None - def __init__(self, elf, off) -> None: + def __init__(self, elf: Optional[Elf], off: int) -> None: if elf is None: return elf.seek(off) @@ -1001,16 +1002,22 @@ def is_valid(self) -> bool: @lru_cache() def search_for_main_arena(to_string: bool = False) -> Union[int, str]: - malloc_hook_addr = parse_address("(void *)&__malloc_hook") + """A helper function to find the libc `main_arena` address, either from symbol or from its offset + from `__malloc_hook`.""" + try: + addr = int(parse_address(f"&{LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME}")) - if is_x86(): - addr = align_address_to_size(malloc_hook_addr + gef.arch.ptrsize, 0x20) - elif is_arch(Elf.AARCH64): - addr = malloc_hook_addr - gef.arch.ptrsize*2 - MallocStateStruct("*0").struct_size - elif is_arch(Elf.ARM): - addr = malloc_hook_addr - gef.arch.ptrsize - MallocStateStruct("*0").struct_size - else: - raise OSError(f"Cannot find main_arena for {gef.arch.arch}") + except gdb.error: + malloc_hook_addr = parse_address("(void *)&__malloc_hook") + + if is_x86(): + addr = align_address_to_size(malloc_hook_addr + gef.arch.ptrsize, 0x20) + elif is_arch(Elf.AARCH64): + addr = malloc_hook_addr - gef.arch.ptrsize*2 - MallocStateStruct("*0").struct_size + elif is_arch(Elf.ARM): + addr = malloc_hook_addr - gef.arch.ptrsize - MallocStateStruct("*0").struct_size + else: + raise OSError(f"Cannot find main_arena for {gef.arch.arch}") if to_string: addr = f"*{addr:#x}" @@ -1679,12 +1686,12 @@ def is_debug() -> bool: return gef.config["gef.debug"] is True def hide_context() -> bool: - """ Helper function to hide the context pane """ + """Helper function to hide the context pane.""" gef.ui.context_hidden = True return True def unhide_context() -> bool: - """ Helper function to unhide the context pane """ + """Helper function to unhide the context pane.""" gef.ui.context_hidden = False return True @@ -4590,7 +4597,7 @@ def do_invoke(self, argv: List) -> None: class PrintFormatCommand(GenericCommand): """Print bytes format in commonly used formats, such as literals in high level languages.""" - valid_formats = ("py", "c", "js", "asm") + valid_formats = ("py", "c", "js", "asm", "hex") valid_bitness = (8, 16, 32, 64) _cmdline_ = "print-format" @@ -4655,7 +4662,7 @@ def do_invoke(self, argv: List, *args: Tuple[Any, ...], **kwargs: Dict[str, Any] asm_type = self.format_matrix[args.bitlen][2] out = "buf {0} {1}".format(asm_type, sdata) elif args.lang == "hex": - out = binascii.hexlify(read_memory(start_addr, end_addr-start_addr)).decode() + out = binascii.hexlify(gef.memory.read(start_addr, end_addr-start_addr)).decode() if args.clip: if copy_to_clipboard(gef_pybytes(out)): diff --git a/tests/helpers.py b/tests/helpers.py index 154413b2c..60fd5b64d 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -161,13 +161,27 @@ def _target(name: str, extension: str = ".out") -> Path: return target -def start_gdbserver(exe=_target("default"), port=1234): +def start_gdbserver(exe : Union[str, Path]=_target("default"), port : int=1234) -> subprocess.Popen: + """Start a gdbserver on the target binary. + + Args: + exe (str, optional): the binary to execute. Defaults to _target("default"). + port (int, optional): the port to make gdbserver listen on. Defaults to 1234. + + Returns: + subprocess.Popen: a Popen object for the gdbserver process. + """ return subprocess.Popen(["gdbserver", f":{port}", exe], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) -def stop_gdbserver(gdbserver): - """Stops the gdbserver and waits until it is terminated if it was - still running. Needed to make the used port available again.""" + +def stop_gdbserver(gdbserver: subprocess.Popen) -> None: + """Stop the gdbserver and waits until it is terminated if it was + still running. Needed to make the used port available again. + + Args: + gdbserver (subprocess.Popen): the gdbserver process to stop. + """ if gdbserver.poll() is None: gdbserver.kill() gdbserver.wait() diff --git a/tests/runtests.py b/tests/runtests.py index d6f200123..332134220 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -248,7 +248,7 @@ def test_cmd_heap_chunks(self): self.assertIn("Chunk(addr=", res) self.assertIn("top chunk", res) - cmd = "python gdb.execute('heap chunks 0x{:x}'.format(int(list(gef.heap.arenas)[1])))" + cmd = "python gdb.execute(f'heap chunks {int(list(gef.heap.arenas)[1]):#x}')" target = _target("heap-non-main") res = gdb_run_silent_cmd(cmd, target=target) self.assertNoException(res) @@ -258,7 +258,7 @@ def test_cmd_heap_chunks(self): return def test_cmd_heap_chunks_mult_heaps(self): - py_cmd = 'gdb.execute("heap set-arena 0x{:x}".format(int(list(gef.heap.arenas)[1])))' + py_cmd = 'gdb.execute(f"heap set-arena 0x{int(list(gef.heap.arenas)[1]):x}")' before = ['run', 'python ' + py_cmd] cmd = "heap chunks" target = _target("heap-multiple-heaps") @@ -894,7 +894,7 @@ def test_func_parse_address(self): def test_func_download_file(self): gdbsrv = start_gdbserver(BIN_LS) - func = f"download_file('{str(BIN_LS)}')" + func = f"download_file('{BIN_LS!s}')" res = gdb_test_python_method(func) stop_gdbserver(gdbsrv) self.assertNoException(res) From 795f51cad6d381ce028cdb3053c41d1c59e8602b Mon Sep 17 00:00:00 2001 From: hugsy Date: Wed, 12 Jan 2022 17:06:56 -0800 Subject: [PATCH 58/62] [docs] updating docs to stipulate the new minimum requirements for gef --- README.md | 2 +- docs/config.md | 5 +++-- docs/faq.md | 13 +++++++------ docs/index.md | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0fdd54ae9..f895a2315 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ## Instant Setup ## -Simply make sure you have [GDB 7.7 or higher](https://www.gnu.org/s/gdb) compiled with Python3 bindings, then: +Simply make sure you have [GDB 8.0 or higher](https://www.gnu.org/s/gdb) compiled with Python3.6+ bindings, then: ```bash diff --git a/docs/config.md b/docs/config.md index f9dc730c0..48223357b 100644 --- a/docs/config.md +++ b/docs/config.md @@ -6,8 +6,9 @@ A simple recent GDB compiled with Python scripting support will do. ### Prerequisites -Only [GDB 7.7 and higher](https://www.gnu.org/s/gdb) is required. It must be -compiled with Python 3 support. +Only [GDB 8 and higher](https://www.gnu.org/s/gdb) is required. It must be +compiled with Python 3.6 or higher support. For most people, simply using your +distribution package manager should be enough. As of January 2020, GEF officially doesn't support Python 2 any longer, due to Python 2 becoming officially deprecated. diff --git a/docs/faq.md b/docs/faq.md index e9fd8d92f..3d1fda222 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -9,27 +9,28 @@ However, PEDA suffers from a major drawbacks, which the code is too fundamentall 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 < 7.7 ? ## +## 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. -Therefore, it is highly recommended to run GEF with the latest version of GDB. However, all functions should work on a GDB 7.7 and up. If not, send a [bug report](https://github.com/hugsy/gef/issues) and provide as much details as possible. +Currently, GEF is optimized for running against GDB version 8.0+, and Python 3.6+. This allows for a best performance and best use of the GDB Python API. However, GEF can run on older versions too, check out [the version compatibility matrix](compat.md). For really older versions of GDB, you can use [`gef-legacy`](https://github.com/hugsy/gef-legacy) which supports a lot of older GDB, and a Python 2/3 compatibility layer. -If you are running an obsolete version, GEF will show a error and message and exit. You can still use GDB the normal way. +Therefore, it is highly recommended to run GEF with the latest version of GDB. However, all functions should work on a GDB 8.0 and up. If not, send a [bug report](https://github.com/hugsy/gef/issues) and provide as much details as possible. + +If you are running an obsolete version, GEF will show a error and message and exit. Some pre-compiled static binaries for both recent GDB and GDBServer can be downloaded from the [`gdb-static`](https://github.com/hugsy/gdb-static) repository. -_Note_: although some Ubuntu versions are marked as version 7.7 they are actually compiled with some missing features that will make `GEF` complain of an error. Before lodging a bug report, make sure to update your GDB (via APT is fine), or better install `gdb-multiarch` (the package `gdb64` will work as well, but is considered obsolete). ## I cannot get GEF setup!! ## -GEF will work on any GDB 7.7+ compiled with Python support. You can view that commands that failed to load using `gef missing`, but this will not affect GEF generally. +GEF will work on any GDB 8+ compiled with Python 3.6+ support. You can view that commands that failed to load using `gef missing`, but this will not affect GEF generally. If you experience problems setting it up on your host, first go to the [Discord channel](https://discord.gg/HCS8Hg7) for that. You will find great people there willing to help. 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. -But fear not, GDB 7.7 corresponds to the latest packaged version of Ubuntu 14.04. Any version higher or equal will work just fine. So you might actually only need to run `apt install gdb` to get the full-force of GEF. +All recent distributions ship packaged GDB that should be ready-to-go, with a GDB >= 8.0 and Python 3.6+. Any version higher or equal will work just fine. So you might actually only need to run `apt install gdb` to get the full-force of GEF. ## I get a SegFault when starting GDB with GEF ## diff --git a/docs/index.md b/docs/index.md index 83544c4fd..3cf8195f3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -45,7 +45,7 @@ Or [try it online](https://demo.gef.blah.cat) (user:`gef`/password:`gef-demo`) ### Quick install ### -Simply make sure you have [GDB 7.7 or higher](https://www.gnu.org/s/gdb). +Simply make sure you have [GDB 8.0 or higher](https://www.gnu.org/s/gdb), compiled with Python 3.6 or higher. ```bash $ bash -c "$(curl -fsSL http://gef.blah.cat/sh)" From b442af321da3030b465d2f2cb2970b91d58ed3a6 Mon Sep 17 00:00:00 2001 From: hugsy Date: Wed, 12 Jan 2022 17:17:57 -0800 Subject: [PATCH 59/62] [elf] fixed duplicate `SHT_NUM` value --- gef.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gef.py b/gef.py index cac71655c..b1fe099e7 100644 --- a/gef.py +++ b/gef.py @@ -882,13 +882,12 @@ class Shdr: SHT_REL = 9 SHT_SHLIB = 10 SHT_DYNSYM = 11 - SHT_NUM = 12 + SHT_NUM = 12 SHT_INIT_ARRAY = 14 SHT_FINI_ARRAY = 15 SHT_PREINIT_ARRAY = 16 SHT_GROUP = 17 SHT_SYMTAB_SHNDX = 18 - SHT_NUM = 19 SHT_LOOS = 0x60000000 SHT_GNU_ATTRIBUTES = 0x6ffffff5 SHT_GNU_HASH = 0x6ffffff6 From 8ebd7b0c7e05aa96f863c483d7b533e9b6edf9ed Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 14 Jan 2022 14:52:13 -0800 Subject: [PATCH 60/62] Apply suggestions from code review Co-authored-by: theguy147 <37738506+theguy147@users.noreply.github.com> Co-authored-by: Grazfather --- docs/api/gef.md | 145 +++++++------- gef.py | 480 +++++++++++++++++++++++++--------------------- tests/helpers.py | 5 +- tests/runtests.py | 11 +- 4 files changed, 352 insertions(+), 289 deletions(-) diff --git a/docs/api/gef.md b/docs/api/gef.md index 3b976905c..6bc1360a7 100644 --- a/docs/api/gef.md +++ b/docs/api/gef.md @@ -28,8 +28,8 @@ - **GEF_PROMPT** - **GEF_PROMPT_ON** - **GEF_PROMPT_OFF** +- **PATTERN_LIBC_VERSION** - **gef** -- **pattern_libc_ver** - **PREFIX** - **gdb_initial_settings** - **cmd** @@ -41,7 +41,7 @@ ## function `FakeExit` ```python -FakeExit(*args, **kwargs) → None +FakeExit(*args, **kwargs) → NoReturn ``` @@ -108,7 +108,11 @@ Store the content to be printed for a function in memory, and flush it on functi ## function `capstone_disassemble` ```python -capstone_disassemble(location: int, nb_insn: int, **kwargs) +capstone_disassemble( + location: int, + nb_insn: int, + **kwargs +) → Generator[__main__.Instruction, NoneType, NoneType] ``` Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr` using the Capstone-Engine disassembler, if available. Return an iterator of Instruction objects. @@ -189,7 +193,7 @@ Decorator to add a warning when a command is obsolete and will be removed. disable_redirect_output() → None ``` -Disable the output redirection, if any. `disable_redirect_output` is **DEPRECATED** and will be removed in the future. Use `RedirectOutputContext()` context manager +Disable the output redirection, if any. --- @@ -219,7 +223,7 @@ Download filename `remote_path` inside the mirror tree inside the gef.config["ge 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`. `enable_redirect_output` is **DEPRECATED** and will be removed in the future. Use `RedirectOutputContext()` context manager +Redirect all GDB output to `to_file` parameter. By default, `to_file` redirects to `/dev/null`. --- @@ -322,7 +326,10 @@ Format the address according to its size, but with spaces instead of zeroes. ## function `gdb_disassemble` ```python -gdb_disassemble(start_pc: int, **kwargs: int) +gdb_disassemble( + start_pc: int, + **kwargs: int +) → Generator[__main__.Instruction, NoneType, NoneType] ``` Disassemble instructions from `start_pc` (Integer). Accepts the following named parameters: @@ -379,7 +386,7 @@ Defines a new convenience value. ## function `gef_current_instruction` ```python -gef_current_instruction(addr: int) +gef_current_instruction(addr: int) → Instruction ``` Return the current instruction as an Instruction object. @@ -392,7 +399,11 @@ Return the current instruction as an Instruction object. ## function `gef_disassemble` ```python -gef_disassemble(addr: int, nb_insn: int, nb_prev: int = 0) +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. @@ -435,7 +446,7 @@ Execute the parameter `source` as GDB command. This is done by writing `commands ## function `gef_get_instruction_at` ```python -gef_get_instruction_at(addr: int) +gef_get_instruction_at(addr: int) → Instruction ``` Return the full Instruction found at the specified address. @@ -476,7 +487,7 @@ gef_getpagesize() → int ## function `gef_instruction_n` ```python -gef_instruction_n(addr: int, n: int) +gef_instruction_n(addr: int, n: int) → Instruction ``` Return the `n`-th instruction after `addr` as an Instruction object. @@ -489,7 +500,7 @@ Return the `n`-th instruction after `addr` as an Instruction object. ## function `gef_makedirs` ```python -gef_makedirs(path: str, mode: int = 493) → str +gef_makedirs(path: str, mode: int = 493) → Path ``` Recursive mkdir() creation. If successful, return the absolute path of the directory created. @@ -502,7 +513,7 @@ Recursive mkdir() creation. If successful, return the absolute path of the direc ## function `gef_next_instruction` ```python -gef_next_instruction(addr: int) +gef_next_instruction(addr: int) → Instruction ``` Return the next instruction as an Instruction object. @@ -695,7 +706,11 @@ wrapped_f(*args: Tuple, **kwargs: Dict) → Any ## function `gef_print` ```python -gef_print(x: str = '', *args: Tuple, **kwargs: Dict) → Union[int, NoneType] +gef_print( + x: str = '', + *args: Tuple, + **kwargs: Dict[str, Any] +) → Union[int, NoneType] ``` Wrapper around print(), using string buffering feature. @@ -793,7 +808,7 @@ get_filename() → str ## function `get_function_length` ```python -get_function_length(sym) +get_function_length(sym) → int ``` Attempt to get the length of the raw bytes of a function. @@ -915,7 +930,7 @@ get_os() → str ## function `get_path_from_info_proc` ```python -get_path_from_info_proc() +get_path_from_info_proc() → Union[str, NoneType] ``` @@ -1040,7 +1055,7 @@ Return the hexdump of `src` argument. @param source *MUST* be of type bytes or b hide_context() → bool ``` -Helper function to hide the context pane +Helper function to hide the context pane. --- @@ -1450,8 +1465,8 @@ Parse an address and return it as an Integer. ```python parse_arguments( - required_arguments: Dict, - optional_arguments: Dict + required_arguments: Dict[str, Any], + optional_arguments: Dict[str, Any] ) → Union[Callable, NoneType] ``` @@ -1478,7 +1493,7 @@ Parses an address range (e.g. 0x400000-0x401000) ## function `process_lookup_address` ```python -process_lookup_address(address: int) +process_lookup_address(address: int) → Union[__main__.Section, NoneType] ``` Look up for an address in memory. Return an Address object if found, None otherwise. @@ -1517,7 +1532,9 @@ GDB event handler for reg changes cases. ## function `register_architecture` ```python -register_architecture(cls) +register_architecture( + cls: Type[ForwardRef('Architecture')] +) → Type[ForwardRef('Architecture')] ``` Class decorator for declaring an architecture to GEF. @@ -1642,7 +1659,7 @@ GEF wrapper for gdb.parse_and_eval(): this function returns None instead of rais ## function `set_arch` ```python -set_arch(arch=None, default=None) +set_arch(arch=None, default=None) → Architecture ``` Sets the current architecture. If an arch is explicitly specified, use that one, otherwise try to parse it out of the current target. If that fails, and default is specified, select and set that arch. Return the selected arch, or raise an OSError. @@ -1713,7 +1730,7 @@ Print a centered title. ## function `to_unsigned_long` ```python -to_unsigned_long(v) → int +to_unsigned_long(v: gdb.Value) → int ``` Cast a gdb.Value to unsigned long. @@ -1781,7 +1798,7 @@ Unpack one byte respecting the current architecture endianness. unhide_context() → bool ``` -Helper function to unhide the context pane +Helper function to unhide the context pane. --- @@ -3334,7 +3351,7 @@ del_setting(name: str) → None ## function `AssembleCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -3723,7 +3740,7 @@ del_setting(name: str) → None ## function `CapstoneDisassembleCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -4991,7 +5008,7 @@ del_setting(name: str) → None ## function `DereferenceCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -5154,7 +5171,7 @@ del_setting(name: str) → None ## function `DetailRegistersCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -5367,7 +5384,7 @@ del_setting(name: str) → None ## function `ElfInfoCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -6051,7 +6068,7 @@ load_module(fullname) --- ## class `Gef` -The GEF root class, which serves as a base classe for all the attributes for the debugging session (architecture, memory, settings, etc.). +The GEF root class, which serves as a entrypoint for all the debugging session attributes (architecture, memory, settings, etc.). @@ -6619,7 +6636,7 @@ Add command to GEF documentation. ## function `GefHelpCommand.generate_help` ```python -generate_help(commands: List[Tuple[str, Type, Any]]) → None +generate_help(commands: List[Tuple[str, Any, Any]]) → None ``` Generate builtin commands documentation. @@ -8461,7 +8478,7 @@ del_setting(name: str) → None ## function `GlibcHeapChunkCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -8610,7 +8627,7 @@ del_setting(name: str) → None ## function `GlibcHeapChunksCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -9913,7 +9930,7 @@ usage() → None --- ## class `GotBaseFunction` -Return the current bss base address plus the given offset. +Return the current GOT base address plus the given offset. @@ -10455,7 +10472,7 @@ del_setting(name: str) → None ## function `HexdumpByteCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -10604,7 +10621,7 @@ del_setting(name: str) → None ## function `HexdumpCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -10753,7 +10770,7 @@ del_setting(name: str) → None ## function `HexdumpDwordCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -10902,7 +10919,7 @@ del_setting(name: str) → None ## function `HexdumpQwordCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -11051,7 +11068,7 @@ del_setting(name: str) → None ## function `HexdumpWordCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -13697,7 +13714,7 @@ del_setting(name: str) → None ## function `NamedBreakpointCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -13846,7 +13863,7 @@ del_setting(name: str) → None ## function `NopCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -15291,7 +15308,7 @@ del_setting(name: str) → None ## function `PatchByteCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -15440,7 +15457,7 @@ del_setting(name: str) → None ## function `PatchCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -15589,7 +15606,7 @@ del_setting(name: str) → None ## function `PatchDwordCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -15738,7 +15755,7 @@ del_setting(name: str) → None ## function `PatchQwordCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -16036,7 +16053,7 @@ del_setting(name: str) → None ## function `PatchWordCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -16334,7 +16351,7 @@ del_setting(name: str) → None ## function `PatternCreateCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -16483,7 +16500,7 @@ del_setting(name: str) → None ## function `PatternSearchCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -16595,7 +16612,7 @@ GEF representation of Linux permission. ## function `Permission.__init__` ```python -__init__(**kwargs) → None +__init__(**kwargs: Any) → None ``` @@ -16612,7 +16629,7 @@ __init__(**kwargs) → None ## function `Permission.from_info_sections` ```python -from_info_sections(*args: List[str]) +from_info_sections(*args: List[str]) → Permission ``` @@ -16626,7 +16643,7 @@ from_info_sections(*args: List[str]) ## function `Permission.from_process_maps` ```python -from_process_maps(perm_str: str) +from_process_maps(perm_str: str) → Permission ``` @@ -16867,7 +16884,7 @@ del_setting(name: str) → None ## function `PieBreakpointCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -17193,7 +17210,7 @@ delete_bp(breakpoints: List) → None ## function `PieDeleteCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -17342,7 +17359,7 @@ del_setting(name: str) → None ## function `PieInfoCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -18152,7 +18169,7 @@ register(name: str) → Union[int, NoneType] --- ## class `PrintFormatCommand` -Print bytes format in high level languages. +Print bytes format in commonly used formats, such as literals in high level languages. @@ -18218,7 +18235,7 @@ del_setting(name: str) → None ## function `PrintFormatCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -18367,7 +18384,7 @@ del_setting(name: str) → None ## function `ProcessListingCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -19048,7 +19065,7 @@ del_setting(name: str) → None ## function `RemoteCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -20377,7 +20394,7 @@ invoke(*args) → int ## function `Shdr.__init__` ```python -__init__(elf, off) → None +__init__(elf: Optional[__main__.Elf], off: int) → None ``` @@ -21101,7 +21118,7 @@ del_setting(name: str) → None ## function `SolveKernelSymbolCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -21348,7 +21365,7 @@ del_setting(name: str) → None ## function `StubCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` @@ -21511,7 +21528,7 @@ do_invoke(argv: List) → None ## function `SyscallArgsCommand.get_filepath` ```python -get_filepath(x: str) → Union[str, NoneType] +get_filepath(x: str) → Union[pathlib.Path, NoneType] ``` @@ -21525,7 +21542,7 @@ get_filepath(x: str) → Union[str, NoneType] ## function `SyscallArgsCommand.get_module` ```python -get_module(modname: str) +get_module(modname: str) → Any ``` @@ -21565,7 +21582,7 @@ get_settings_path() → Union[pathlib.Path, NoneType] ## function `SyscallArgsCommand.get_syscall_table` ```python -get_syscall_table(modname: str) +get_syscall_table(modname: str) → Dict[str, Any] ``` @@ -22136,7 +22153,7 @@ del_setting(name: str) → None ## function `UnicornEmulateCommand.wrapper` ```python -wrapper(*args: Tuple, **kwargs: Dict) → Union[Callable, NoneType] +wrapper(*args: Any, **kwargs: Any) → Union[Callable, NoneType] ``` diff --git a/gef.py b/gef.py index b1fe099e7..7a84fc8e8 100644 --- a/gef.py +++ b/gef.py @@ -80,7 +80,7 @@ import warnings import xmlrpc.client as xmlrpclib from functools import lru_cache -from io import StringIO +from io import StringIO, TextIOWrapper from types import ModuleType from typing import (List, Dict, Tuple, Optional, Sequence, Union, Generator, Any, Iterator, Callable, ByteString, Set, Type, NoReturn) @@ -125,6 +125,7 @@ def update_gef(argv: List[str]) -> int: print("[-] gef cannot run as standalone") sys.exit(0) + GDB_MIN_VERSION = (8, 0) GDB_VERSION = tuple(map(int, re.search(r"(\d+)[^\d]+(\d+)", gdb.VERSION).groups())) PYTHON_MIN_VERSION = (3, 6) @@ -133,7 +134,9 @@ def update_gef(argv: List[str]) -> int: DEFAULT_PAGE_ALIGN_SHIFT = 12 DEFAULT_PAGE_SIZE = 1 << DEFAULT_PAGE_ALIGN_SHIFT -GEF_RC = pathlib.Path(os.getenv("GEF_RC")).absolute() if os.getenv("GEF_RC") else pathlib.Path().home() / ".gef.rc" +GEF_RC = (pathlib.Path(os.getenv("GEF_RC")).absolute() + if os.getenv("GEF_RC") + else pathlib.Path().home() / ".gef.rc") GEF_TEMP_DIR = os.path.join(tempfile.gettempdir(), "gef") GEF_MAX_STRING_LENGTH = 50 @@ -152,6 +155,8 @@ def update_gef(argv: List[str]) -> int: GEF_PROMPT_ON = f"\001\033[1;32m\002{GEF_PROMPT}\001\033[0m\002" GEF_PROMPT_OFF = f"\001\033[1;31m\002{GEF_PROMPT}\001\033[0m\002" +PATTERN_LIBC_VERSION = re.compile(rb"glibc (\d+)\.(\d+)") + gef : "Gef" = None __registered_commands__ : List[Type["GenericCommand"]] = [] @@ -171,6 +176,7 @@ def reset_all_caches() -> None: gef.reset_caches() return + def reset() -> None: global gef @@ -187,6 +193,7 @@ def reset() -> None: gef.arch = arch return + def highlight_text(text: str) -> str: """ Highlight text using gef.ui.highlight_table { match -> color } settings. @@ -222,7 +229,7 @@ def highlight_text(text: str) -> str: return "".join(ansiSplit) -def gef_print(x: str = "", *args: Tuple, **kwargs: Dict) -> Optional[int]: +def gef_print(x: str = "", *args: Tuple, **kwargs: Dict[str, Any]) -> Optional[int]: """Wrapper around print(), using string buffering feature.""" x = highlight_text(x) if gef.ui.stream_buffer and not is_debug(): @@ -275,6 +282,7 @@ def wrapper(*args: Any, **kwargs: Any) -> Any: return wrapper + # # Helpers # @@ -283,30 +291,37 @@ def p8(x: int, s: bool = False) -> bytes: """Pack one byte respecting the current architecture endianness.""" return struct.pack(f"{gef.arch.endianness}B", x) if not s else struct.pack(f"{gef.arch.endianness}b", x) + def p16(x: int, s: bool = False) -> bytes: """Pack one word respecting the current architecture endianness.""" return struct.pack(f"{gef.arch.endianness}H", x) if not s else struct.pack(f"{gef.arch.endianness}h", x) + def p32(x: int, s: bool = False) -> bytes: """Pack one dword respecting the current architecture endianness.""" return struct.pack(f"{gef.arch.endianness}I", x) if not s else struct.pack(f"{gef.arch.endianness}i", x) + def p64(x: int, s: bool = False) -> bytes: """Pack one qword respecting the current architecture endianness.""" return struct.pack(f"{gef.arch.endianness}Q", x) if not s else struct.pack(f"{gef.arch.endianness}q", x) + def u8(x: bytes, s: bool = False) -> int: """Unpack one byte respecting the current architecture endianness.""" return struct.unpack(f"{gef.arch.endianness}B", x)[0] if not s else struct.unpack(f"{gef.arch.endianness}b", x)[0] + def u16(x: bytes, s: bool = False) -> int: """Unpack one word respecting the current architecture endianness.""" return struct.unpack(f"{gef.arch.endianness}H", x)[0] if not s else struct.unpack(f"{gef.arch.endianness}h", x)[0] + def u32(x: bytes, s: bool = False) -> int: """Unpack one dword respecting the current architecture endianness.""" return struct.unpack(f"{gef.arch.endianness}I", x)[0] if not s else struct.unpack(f"{gef.arch.endianness}i", x)[0] + def u64(x: bytes, s: bool = False) -> int: """Unpack one qword respecting the current architecture endianness.""" return struct.unpack(f"{gef.arch.endianness}Q", x)[0] if not s else struct.unpack(f"{gef.arch.endianness}q", x)[0] @@ -430,9 +445,11 @@ def wrapped_f(*args: Tuple, **kwargs: Dict) -> Any: def FakeExit(*args, **kwargs) -> NoReturn: raise RuntimeWarning + sys.exit = FakeExit -def parse_arguments(required_arguments: Dict, optional_arguments: Dict) -> Optional[Callable]: + +def parse_arguments(required_arguments: Dict[str, Any], optional_arguments: Dict[str, Any]) -> Optional[Callable]: """Argument parsing decorator.""" def int_wrapper(x: str) -> int: return int(x, 0) @@ -599,7 +616,7 @@ class Permission: ALL = READ | WRITE | EXECUTE def __init__(self, **kwargs: Any) -> None: - self.value = kwargs.get("value", 0) + self.value : int = kwargs.get("value", 0) return def __or__(self, value: int) -> int: @@ -624,6 +641,9 @@ def __str__(self) -> str: perm_str += "x" if self & Permission.EXECUTE else "-" return perm_str + def __int__(self) -> int: + return self.value + @staticmethod def from_info_sections(*args: List[str]) -> "Permission": perm = Permission() @@ -652,22 +672,22 @@ class Section: """GEF representation of process memory sections.""" def __init__(self, *args, **kwargs) -> None: - self.page_start: int = kwargs.get("page_start") - self.page_end: int = kwargs.get("page_end") - self.offset: int = kwargs.get("offset") - self.permission: Permission = kwargs.get("permission") - self.inode = kwargs.get("inode") - self.path: str = kwargs.get("path") + self.page_start: int = kwargs.get("page_start", 0) + self.page_end: int = kwargs.get("page_end", 0) + self.offset: int = kwargs.get("offset", 0) + self.permission: Permission = kwargs.get("permission", Permission()) + self.inode = kwargs.get("inode", 0) + self.path: str = kwargs.get("path", "") return def is_readable(self) -> bool: - return self.permission.value and self.permission.value & Permission.READ + return (self.permission & Permission.READ) != 0 def is_writable(self) -> bool: - return self.permission.value and self.permission.value & Permission.WRITE + return (self.permission & Permission.WRITE) != 0 def is_executable(self) -> bool: - return self.permission.value and self.permission.value & Permission.EXECUTE + return (self.permission & Permission.EXECUTE) != 0 @property def size(self) -> int: @@ -696,6 +716,13 @@ def __str__(self) -> str: return "<" return ">" + def __repr__(self) -> str: + return self.name + + def __int__(self) -> int: + return self.value + + class Elf: """Basic ELF parsing. Ref: @@ -735,26 +762,26 @@ class Elf: OSABI_FREEBSD = 0x09 OSABI_OPENBSD = 0x0C - e_magic: int = ELF_MAGIC - e_class: int = ELF_32_BITS - e_endianness: int = Endianness.LITTLE_ENDIAN - e_eiversion = None - e_osabi = None - e_abiversion = None - e_pad: int = None - e_type: int = ET_EXEC - e_machine: int = X86_32 - e_version = None - e_entry: int = 0x00 - e_phoff = None - e_shoff = None - e_flags = None - e_ehsize = None - e_phentsize = None - e_phnum = None - e_shentsize = None - e_shnum = None - e_shstrndx = None + e_magic: int = ELF_MAGIC + e_class: int = ELF_32_BITS + e_endianness: int = int(Endianness.LITTLE_ENDIAN) + e_eiversion = None + e_osabi = None + e_abiversion = None + e_pad: Optional[bytes] = None + e_type: int = ET_EXEC + e_machine: int = X86_32 + e_version = None + e_entry: int = 0 + e_phoff : int = 0 + e_shoff : int = 0 + e_flags = None + e_ehsize : int = 0 + e_phentsize : int = 0 + e_phnum : int = 0 + e_shentsize : int = 0 + e_shnum : int = 0 + e_shstrndx : int = 0 def __init__(self, elf: str = "", minimalist: bool = False) -> None: """ @@ -1004,7 +1031,7 @@ def search_for_main_arena(to_string: bool = False) -> Union[int, str]: """A helper function to find the libc `main_arena` address, either from symbol or from its offset from `__malloc_hook`.""" try: - addr = int(parse_address(f"&{LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME}")) + addr = parse_address(f"&{LIBC_HEAP_MAIN_ARENA_DEFAULT_NAME}") except gdb.error: malloc_hook_addr = parse_address("(void *)&__malloc_hook") @@ -1496,9 +1523,6 @@ def psprint(self) -> str: return "\n".join(msg) + "\n" -pattern_libc_ver = re.compile(rb"glibc (\d+)\.(\d+)") - - @lru_cache() def get_libc_version() -> Tuple[int, ...]: sections = gef.memory.maps @@ -1512,7 +1536,7 @@ def get_libc_version() -> Tuple[int, ...]: data = f.read() except OSError: continue - match = re.search(pattern_libc_ver, data) + match = re.search(PATTERN_LIBC_VERSION, data) if match: return tuple(int(_) for _ in match.groups()) return 0, 0 @@ -1615,6 +1639,7 @@ def gef_pybytes(x: str) -> bytes: """Returns an immutable bytes list from the string given as input.""" return bytes(str(x), encoding="utf-8") + @lru_cache() def which(program: str) -> Optional[pathlib.Path]: """Locate a command on the filesystem.""" @@ -1684,11 +1709,13 @@ def is_debug() -> bool: """Check if debug mode is enabled.""" return gef.config["gef.debug"] is True + def hide_context() -> bool: """Helper function to hide the context pane.""" gef.ui.context_hidden = True return True + def unhide_context() -> bool: """Helper function to unhide the context pane.""" gef.ui.context_hidden = False @@ -1713,7 +1740,7 @@ def __exit__(self, *exc) -> None: gdb.execute("set logging redirect off") return -@deprecated("Use `RedirectOutputContext()` context manager") + def 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`.""" gdb.execute("set logging overwrite") @@ -1722,7 +1749,7 @@ def enable_redirect_output(to_file: str = "/dev/null") -> None: gdb.execute("set logging on") return -@deprecated("Use `RedirectOutputContext()` context manager") + def disable_redirect_output() -> None: """Disable the output redirection, if any.""" gdb.execute("set logging off") @@ -1730,7 +1757,7 @@ def disable_redirect_output() -> None: return -def gef_makedirs(path: str, mode: int = 0o755) -> str: +def gef_makedirs(path: str, mode: int = 0o755) -> pathlib.Path: """Recursive mkdir() creation. If successful, return the absolute path of the directory created.""" fpath = pathlib.Path(path) if not fpath.is_dir(): @@ -1739,7 +1766,7 @@ def gef_makedirs(path: str, mode: int = 0o755) -> str: @lru_cache() -def gdb_lookup_symbol(sym: str): # -> Optional[Tuple[Optional[str], Optional[Tuple[gdb.Symtab_and_line, ...]]]] +def gdb_lookup_symbol(sym: str) -> Optional[Tuple[Optional[str], Optional[Tuple[gdb.Symtab_and_line, ...]]]]: """Fetch the proper symbol or None if not defined.""" try: return gdb.decode_line(sym)[1] @@ -1765,7 +1792,7 @@ def gdb_get_location_from_symbol(address: int) -> Optional[Tuple[str, int]]: return name, offset -def gdb_disassemble(start_pc: int, **kwargs: int): # -> Generator[Instruction] +def gdb_disassemble(start_pc: int, **kwargs: int) -> Generator[Instruction, None, None]: """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 @@ -1840,28 +1867,28 @@ def gdb_get_nth_next_instruction_address(addr: int, n: int) -> int: return insn.address -def gef_instruction_n(addr: int, n: int): # -> Instruction +def gef_instruction_n(addr: int, n: int) -> Instruction: """Return the `n`-th instruction after `addr` as an Instruction object.""" return list(gdb_disassemble(addr, count=n + 1))[n] -def gef_get_instruction_at(addr: int): # -> Instruction +def gef_get_instruction_at(addr: int) -> Instruction: """Return the full Instruction found at the specified address.""" insn = next(gef_disassemble(addr, 1)) return insn -def gef_current_instruction(addr: int): # -> Instruction +def gef_current_instruction(addr: int) -> Instruction: """Return the current instruction as an Instruction object.""" return gef_instruction_n(addr, 0) -def gef_next_instruction(addr: int): # -> Instruction +def gef_next_instruction(addr: int) -> Instruction: """Return the next instruction as an Instruction object.""" return gef_instruction_n(addr, 1) -def gef_disassemble(addr: int, nb_insn: int, nb_prev: int = 0): # -> Generator[Instruction] +def gef_disassemble(addr: int, nb_insn: int, nb_prev: int = 0) -> Generator[Instruction, None, None]: """Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr`. Return an iterator of Instruction objects.""" nb_insn = max(1, nb_insn) @@ -1877,12 +1904,12 @@ def gef_disassemble(addr: int, nb_insn: int, nb_prev: int = 0): # -> Generator[ yield insn -def capstone_disassemble(location: int, nb_insn: int, **kwargs): # -> Generator[Instruction] +def capstone_disassemble(location: int, nb_insn: int, **kwargs) -> Generator[Instruction, None, None]: """Disassemble `nb_insn` instructions after `addr` and `nb_prev` before `addr` using the Capstone-Engine disassembler, if available. Return an iterator of Instruction objects.""" - def cs_insn_to_gef_insn(cs_insn): # -> Instruction + def cs_insn_to_gef_insn(cs_insn) -> Instruction: sym_info = gdb_get_location_from_symbol(cs_insn.address) loc = "<{}+{}>".format(*sym_info) if sym_info else "" ops = [] + cs_insn.op_str.split(", ") @@ -1903,9 +1930,7 @@ def cs_insn_to_gef_insn(cs_insn): # -> Instruction location = gdb_get_nth_previous_instruction_address(pc, nb_prev) nb_insn += nb_prev - code = kwargs.get("code", gef.memory.read(location, gef_getpagesize() - offset - 1)) - code = bytes(code) - + code = kwargs.get("code", gef.memory.read(location, gef.session.pagesize - offset - 1)) for insn in cs.disasm(code, location): if skip: skip -= 1 @@ -2044,7 +2069,7 @@ def get_zone_base_address(name: str) -> Optional[int]: # # Architecture classes # -def register_architecture(cls): +def register_architecture(cls: Type["Architecture"]) -> Type["Architecture"]: """Class decorator for declaring an architecture to GEF.""" global __registered_architectures__ for key in cls.aliases: @@ -2082,6 +2107,8 @@ def is_branch_taken(self, insn) -> Tuple[bool, str]: pass @abc.abstractmethod def get_ra(self, insn, frame) -> Optional[int]: pass + arch = "" + mode = "" aliases = [] special_registers = [] @@ -3100,13 +3127,13 @@ def use_rust_type() -> str: return "u16" -def to_unsigned_long(v) -> int: +def to_unsigned_long(v: gdb.Value) -> int: """Cast a gdb.Value to unsigned long.""" mask = (1 << 64) - 1 return int(v.cast(gdb.Value(mask).type)) & mask -def get_path_from_info_proc(): +def get_path_from_info_proc() -> Optional[str]: for x in gdb.execute("info proc", to_string=True).splitlines(): if x.startswith("exe = "): return x.split(" = ")[1].replace("'", "") @@ -3208,7 +3235,7 @@ def download_file(remote_path: str, use_cache: bool = False, local_name: Optiona return local_path -def get_function_length(sym): +def get_function_length(sym) -> int: """Attempt to get the length of the raw bytes of a function.""" dis = gdb.execute(f"disassemble {sym}", to_string=True).splitlines() start_addr = int(dis[1].split()[0], 16) @@ -3217,7 +3244,7 @@ def get_function_length(sym): @lru_cache() -def get_info_files(): # -> List[Zone] +def get_info_files() -> List[Zone]: """Retrieve all the files loaded by debuggee.""" lines = gdb.execute("info files", to_string=True).splitlines() infos = [] @@ -3243,7 +3270,7 @@ def get_info_files(): # -> List[Zone] return infos -def process_lookup_address(address: int): # -> Optional[Section] +def process_lookup_address(address: int) -> Optional[Section]: """Look up for an address in memory. Return an Address object if found, None otherwise.""" if not is_alive(): @@ -3262,7 +3289,7 @@ def process_lookup_address(address: int): # -> Optional[Section] @lru_cache() -def process_lookup_path(name: str, perm=Permission.ALL): # -> Optional[Section] +def process_lookup_path(name: str, perm=Permission.ALL) -> Optional[Section]: """Look up for a path in the process memory mapping. Return a Section object if found, None otherwise.""" if not is_alive(): @@ -3277,7 +3304,7 @@ def process_lookup_path(name: str, perm=Permission.ALL): # -> Optional[Section] @lru_cache() -def file_lookup_name_path(name: str, path: str): # -> Optional[Zone] +def file_lookup_name_path(name: str, path: str) -> Optional[Zone]: """Look up a file by name and path. Return a Zone object if found, None otherwise.""" for xfile in get_info_files(): @@ -3287,7 +3314,7 @@ def file_lookup_name_path(name: str, path: str): # -> Optional[Zone] @lru_cache() -def file_lookup_address(address: int): # -> Optional[Zone] +def file_lookup_address(address: int) -> Optional[Zone]: """Look up for a file by its address. Return a Zone object if found, None otherwise.""" for info in get_info_files(): @@ -3297,7 +3324,7 @@ def file_lookup_address(address: int): # -> Optional[Zone] @lru_cache() -def lookup_address(address: int): # -> Address +def lookup_address(address: int) -> Address: """Try to find the address in the process address space. Return an Address object, with validity flag set based on success.""" sect = process_lookup_address(address) @@ -3445,7 +3472,7 @@ def get_generic_arch(module: ModuleType, prefix: str, arch: str, mode: Optional[ mode = f"{module.__name__}.{prefix}_MODE_{mode}" else: mode = "" - if is_big_endian(): + if gef.arch.endianness == Endianness.BIG_ENDIAN: mode += f" + {module.__name__}.{prefix}_MODE_BIG_ENDIAN" else: mode += f" + {module.__name__}.{prefix}_MODE_LITTLE_ENDIAN" @@ -3477,7 +3504,7 @@ def get_generic_running_arch(module: ModuleType, prefix: str, to_string: bool = else: raise OSError("Emulation not supported for your OS") - return get_generic_arch(module, prefix, arch, mode, is_big_endian(), to_string) + return get_generic_arch(module, prefix, arch, mode, gef.arch.endianness == Endianness.BIG_ENDIAN, to_string) def get_unicorn_arch(arch: Optional[str] = None, mode: Optional[str] = None, endian: Optional[bool] = None, to_string: bool = False) -> Union[Tuple[None, None], Tuple[str, Union[int, str]]]: @@ -3499,11 +3526,11 @@ def get_capstone_arch(arch: Optional[str] = None, mode: Optional[str] = None, en arch = "PPC" mode = "32" - endian = is_big_endian() + endian = (gef.arch.endianness == Endianness.BIG_ENDIAN) return get_generic_arch(capstone, "CS", arch or gef.arch.arch, mode or gef.arch.mode, - endian or is_big_endian(), + endian, to_string) if (arch, mode, endian) == (None, None, None): @@ -3511,7 +3538,7 @@ def get_capstone_arch(arch: Optional[str] = None, mode: Optional[str] = None, en return get_generic_arch(capstone, "CS", arch or gef.arch.arch, mode or gef.arch.mode, - endian or is_big_endian(), + endian or gef.arch.endianness == Endianness.BIG_ENDIAN, to_string) @@ -3562,6 +3589,7 @@ def get_unicorn_registers(to_string: bool = False) -> Union[Dict[str, int], Dict regs[reg] = getattr(const, regname) return regs + def keystone_assemble(code: str, arch: int, mode: int, *args, **kwargs) -> Optional[Union[str, bytearray]]: """Assembly encoding function based on keystone.""" keystone = sys.modules["keystone"] @@ -3588,11 +3616,13 @@ def keystone_assemble(code: str, arch: int, mode: int, *args, **kwargs) -> Optio @lru_cache() -def get_elf_headers(filename: Optional[str] = None): # -> Optional[Elf] +def get_elf_headers(filename: Optional[str] = None) -> Optional[Elf]: """Return an Elf object with info from `filename`. If not provided, will return the currently debugged file.""" - if filename is None: + if not filename: filename = get_filepath() + if not filename: + raise Exception("No file provided") if filename.startswith("target:"): warn("Your file is remote, you should try using `gef-remote` instead") @@ -3636,7 +3666,7 @@ def is_arch(arch: int) -> bool: return elf.e_machine == arch -def set_arch(arch=None, default=None): # -> Architecture +def set_arch(arch=None, default=None) -> Architecture: """Sets the current architecture. If an arch is explicitly specified, use that one, otherwise try to parse it out of the current target. If that fails, and default is specified, select and @@ -3676,7 +3706,7 @@ def set_arch(arch=None, default=None): # -> Architecture @lru_cache() -def cached_lookup_type(_type: str): # -> Optional[gdb.Type] +def cached_lookup_type(_type: str) -> Optional[gdb.Type]: try: return gdb.lookup_type(_type).strip_typedefs() except RuntimeError: @@ -3879,39 +3909,48 @@ def gef_get_pie_breakpoint(num: int): # -> PieVirtualBreakpoint def endian_str() -> str: return str(gef.arch.endianness) + @deprecated("Use `gef.config[key]`") def get_gef_setting(name: str) -> Any: return gef.config[name] + @deprecated("Use `gef.config[key] = value`") def set_gef_setting(name: str, value: Any) -> None: gef.config[name] = value return + @deprecated("Use `gef.session.pagesize`") def gef_getpagesize() -> int: return gef.session.pagesize + @deprecated("Use `gef.session.canary`") def gef_read_canary() -> Optional[Tuple[int, int]]: return gef.session.canary + @deprecated("Use `gef.session.pid`") def get_pid() -> int: return gef.session.pid + @deprecated("Use `gef.session.file.name`") def get_filename() -> str: return gef.session.file.name + @deprecated("Use `gef.heap.main_arena`") def get_glibc_arena(): # -> GlibcArena return gef.heap.main_arena + @deprecated("Use `gef.arch.register(regname)`") def get_register(regname): return gef.arch.register(regname) + @deprecated("Use `gef.memory.maps`") def get_process_maps(): return gef.memory.maps @@ -3985,7 +4024,6 @@ def gef_on_regchanged_unhook(func): # Virtual breakpoints # - class PieVirtualBreakpoint: """PIE virtual breakpoint (not real breakpoint).""" @@ -4082,7 +4120,7 @@ def __init__(self, func: str, retval: Optional[int]) -> None: def stop(self) -> bool: gdb.execute(f"return (unsigned int){self.retval:#x}") ok(f"Ignoring call to '{self.func}' " - f"(setting return value to {self.retval:#x})") + f"(setting return value to {self.retval:#x})") return False @@ -5127,23 +5165,23 @@ class GefThemeCommand(GenericCommand): def __init__(self, *args, **kwargs) -> None: super().__init__(self._cmdline_) - self["context_title_line"] = ( "gray", "Color of the borders in context window") - self["context_title_message"] = ( "cyan", "Color of the title in context window") - self["default_title_line"] = ( "gray", "Default color of borders") - self["default_title_message"] = ( "cyan", "Default color of title") - self["table_heading"] = ( "blue", "Color of the column headings to tables (e.g. vmmap)") - self["old_context"] = ( "gray", "Color to use to show things such as code that is not immediately relevant") - self["disassemble_current_instruction"] = ( "green", "Color to use to highlight the current $pc when disassembling") - self["dereference_string"] = ( "yellow", "Color of dereferenced string") - self["dereference_code"] = ( "gray", "Color of dereferenced code") - self["dereference_base_address"] = ( "cyan", "Color of dereferenced address") - self["dereference_register_value"] = ( "bold blue", "Color of dereferenced register") - self["registers_register_name"] = ( "blue", "Color of the register name in the register window") - self["registers_value_changed"] = ( "bold red", "Color of the changed register in the register window") - self["address_stack"] = ( "pink", "Color to use when a stack address is found") - self["address_heap"] = ( "green", "Color to use when a heap address is found") - self["address_code"] = ( "red", "Color to use when a code address is found") - self["source_current_line"] = ( "green", "Color to use for the current code line in the source window") + self["context_title_line"] = ("gray", "Color of the borders in context window") + self["context_title_message"] = ("cyan", "Color of the title in context window") + self["default_title_line"] = ("gray", "Default color of borders") + self["default_title_message"] = ("cyan", "Default color of title") + self["table_heading"] = ("blue", "Color of the column headings to tables (e.g. vmmap)") + self["old_context"] = ("gray", "Color to use to show things such as code that is not immediately relevant") + self["disassemble_current_instruction"] = ("green", "Color to use to highlight the current $pc when disassembling") + self["dereference_string"] = ("yellow", "Color of dereferenced string") + self["dereference_code"] = ("gray", "Color of dereferenced code") + self["dereference_base_address"] = ("cyan", "Color of dereferenced address") + self["dereference_register_value"] = ("bold blue", "Color of dereferenced register") + self["registers_register_name"] = ("blue", "Color of the register name in the register window") + self["registers_value_changed"] = ("bold red", "Color of the changed register in the register window") + self["address_stack"] = ("pink", "Color to use when a stack address is found") + self["address_heap"] = ("green", "Color to use when a heap address is found") + self["address_code"] = ("red", "Color to use when a code address is found") + self["source_current_line"] = ("green", "Color to use for the current code line in the source window") return def do_invoke(self, args: List) -> None: @@ -5187,11 +5225,11 @@ class PCustomCommand(GenericCommand): def __init__(self) -> None: super().__init__(prefix=True) - self["struct_path"] = ( os.sep.join( (gef.config["gef.tempdir"], "structs")), "Path to store/load the structure ctypes files") - self["max_depth"] = ( 4, "Maximum level of recursion supported") - self["structure_name"] = ( "bold blue", "Color of the structure name") - self["structure_type"] = ( "bold red", "Color of the attribute type") - self["structure_size"] = ( "green", "Color of the attribute size") + self["struct_path"] = (os.sep.join( (gef.config["gef.tempdir"], "structs")), "Path to store/load the structure ctypes files") + self["max_depth"] = (4, "Maximum level of recursion supported") + self["structure_name"] = ("bold blue", "Color of the structure name") + self["structure_type"] = ("bold red", "Color of the attribute type") + self["structure_size"] = ("green", "Color of the attribute size") return @@ -5305,7 +5343,7 @@ def apply_structure_to_address(self, mod_name: str, struct_name: str, addr: int, self.apply_structure_to_address(mod_name, _type.__name__, addr + _offset, depth + 1) elif _type.__name__.startswith("LP_"): # hack __sub_type_name = _type.__name__.replace("LP_", "") - __deref = u64( gef.memory.read(addr + _offset, 8) ) + __deref = u64(gef.memory.read(addr + _offset, 8)) self.apply_structure_to_address(mod_name, __sub_type_name, __deref, depth + 1) return @@ -5586,10 +5624,9 @@ class IdaInteractCommand(GenericCommand): def __init__(self) -> None: super().__init__(prefix=False) - host, port = "127.0.0.1", 1337 - self["host"] = ( host, "IP address to use connect to IDA/Binary Ninja script") - self["port"] = ( port, "Port to use connect to IDA/Binary Ninja script") - self["sync_cursor"] = ( False, "Enable real-time $pc synchronisation") + self["host"] = ("127.0.0.1", "IP address to use connect to IDA/Binary Ninja script") + self["port"] = (1337, "Port to use connect to IDA/Binary Ninja script") + self["sync_cursor"] = (False, "Enable real-time $pc synchronization") self.sock = None self.version = ("", "") @@ -6113,7 +6150,7 @@ def do_invoke(self, argv: List) -> None: info(f"Setting a restore breakpoint at {bp_loc}") ChangePermissionBreakpoint(bp_loc, original_code, original_pc) - info(f"Overwriting current memory at {loc:#x} ({len(stub):d} bytes)") + info(f"Overwriting current memory at {loc:#x} ({len(stub)} bytes)") gef.memory.write(original_pc, stub, len(stub)) info("Resuming execution") @@ -6147,8 +6184,8 @@ class UnicornEmulateCommand(GenericCommand): def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) - self["verbose"] = ( False, "Set unicorn-engine in verbose mode") - self["show_disassembly"] = ( False, "Show every instruction executed") + self["verbose"] = (False, "Set unicorn-engine in verbose mode") + self["show_disassembly"] = (False, "Show every instruction executed") return def pre_load(self) -> None: @@ -6319,7 +6356,7 @@ def reset(): perm = sect.permission content += f" # Mapping {sect.path}: {page_start:#x}-{page_end:#x}\n" - content += f" emu.mem_map({page_start:#x}, {size:#x}, {oct(perm.value)})\n" + content += f" emu.mem_map({page_start:#x}, {size:#x}, {perm.value:#o})\n" if perm & Permission.READ: code = gef.memory.read(page_start, size) @@ -6395,7 +6432,7 @@ class RemoteCommand(GenericCommand): def __init__(self) -> None: super().__init__(prefix=False) self.handler_connected = False - self["clean_on_exit"] = ( False, "Clean the temporary data downloaded when the session exits.") + self["clean_on_exit"] = (False, "Clean the temporary data downloaded when the session exits.") return @parse_arguments( @@ -6514,7 +6551,7 @@ def setup_remote_environment(self, pid: int, update_solib: bool = False) -> None directory = os.path.sep.join([gef.config["gef.tempdir"], str(gef.session.pid)]) # gdb.execute(f"file {infos['exe']}") - self["root"] = ( directory, "Path to store the remote data") + self["root"] = (directory, "Path to store the remote data") ok(f"Remote information loaded to temporary path '{directory}'") return @@ -6637,7 +6674,7 @@ def nop_bytes(self, loc: int, num_bytes: int) -> None: if len(nops) > size: err(f"Cannot patch instruction at {loc:#x} " - f"(nop_size is:{len(nops):d}, insn_size is:{size:d})") + f"(nop_size is:{len(nops)}, insn_size is:{size})") return while len(nops) < size: @@ -6880,7 +6917,7 @@ class GlibcHeapChunksCommand(GenericCommand): def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) - self["peek_nb_byte"] = ( 16, "Hexdump N first byte(s) inside the chunk data (0 to disable)") + self["peek_nb_byte"] = (16, "Hexdump N first byte(s) inside the chunk data (0 to disable)") return @parse_arguments({"arena_address": ""}, {("--all", "-a"): True, "--allow-unaligned": True}) @@ -7208,6 +7245,7 @@ def fastbin_index(sz): gef_print() return + @register_command class GlibcHeapUnsortedBinsCommand(GenericCommand): """Display information on the Unsorted Bins of an arena (default: main_arena). @@ -7222,7 +7260,7 @@ def __init__(self) -> None: @only_if_gdb_running def do_invoke(self, argv: List) -> None: - if get_glibc_arena() is None: + if gef.heap.selected_arena is None: err("Invalid Glibc arena") return @@ -7233,6 +7271,7 @@ def do_invoke(self, argv: List) -> None: info(f"Found {nb_chunk:d} chunks in unsorted bin.") return + @register_command class GlibcHeapSmallBinsCommand(GenericCommand): """Convenience command for viewing small bins.""" @@ -7262,6 +7301,7 @@ def do_invoke(self, argv: List) -> None: info(f"Found {sum(bins.values()):d} chunks in {len(bins):d} small non-empty bins.") return + @register_command class GlibcHeapLargeBinsCommand(GenericCommand): """Convenience command for viewing large bins.""" @@ -7368,9 +7408,8 @@ def do_invoke(self, argv: List, *args, **kwargs) -> None: padreg = regname.ljust(widest, " ") if str(reg) == "": - line = f"{Color.colorify(padreg, unchanged_color)}: " - line += Color.colorify("no value", "yellow underline") - gef_print(line) + gef_print(f"{Color.colorify(padreg, unchanged_color)}: " + f"{Color.colorify('no value', 'yellow underline')}") continue value = align_address(int(reg)) @@ -7411,7 +7450,7 @@ def do_invoke(self, argv: List, *args, **kwargs) -> None: last_addr = int(addrs[-1], 16) val = gef_pystring(struct.pack(fmt, last_addr)) if all([_ in charset for _ in val]): - line += f' ("{Color.colorify(val, string_color)}"?)' + line += f" (\"{Color.colorify(val, string_color)}\"?)" except ValueError: pass @@ -7602,8 +7641,8 @@ class AssembleCommand(GenericCommand): def __init__(self) -> None: super().__init__() - self["default_architecture"] = ( "X86", "Specify the default architecture to use when assembling") - self["default_mode"] = ( "64", "Specify the default architecture to use when assembling") + self["default_architecture"] = ("X86", "Specify the default architecture to use when assembling") + self["default_mode"] = ("64", "Specify the default architecture to use when assembling") return def pre_load(self) -> None: @@ -7650,7 +7689,7 @@ def do_invoke(self, argv: List, *args, **kwargs) -> None: if is_alive(): arch_s, mode_s = gef.arch.arch, gef.arch.mode - endian_s = "big" if is_big_endian() else "" + endian_s = "big" if gef.arch.endianness == Endianness.BIG_ENDIAN else "" if args.arch: arch_s = args.arch @@ -7987,7 +8026,7 @@ class EntryPointBreakCommand(GenericCommand): def __init__(self) -> None: super().__init__() - self["entrypoint_symbols"] = ( "main _main __libc_start_main __uClibc_main start _start", "Possible symbols for entry points") + self["entrypoint_symbols"] = ("main _main __libc_start_main __uClibc_main start _start", "Possible symbols for entry points") return def do_invoke(self, argv: List) -> None: @@ -8097,29 +8136,29 @@ class ContextCommand(GenericCommand): def __init__(self) -> None: super().__init__() - self["enable"] = ( True, "Enable/disable printing the context when breaking") - self["show_source_code_variable_values"] = ( True, "Show extra PC context info in the source code") - self["show_stack_raw"] = ( False, "Show the stack pane as raw hexdump (no dereference)") - self["show_registers_raw"] = ( False, "Show the registers pane with raw values (no dereference)") - self["show_opcodes_size"] = ( 0, "Number of bytes of opcodes to display next to the disassembly") - self["peek_calls"] = ( True, "Peek into calls") - self["peek_ret"] = ( True, "Peek at return address") - self["nb_lines_stack"] = ( 8, "Number of line in the stack pane") - self["grow_stack_down"] = ( False, "Order of stack downward starts at largest down to stack pointer") - self["nb_lines_backtrace"] = ( 10, "Number of line in the backtrace pane") - self["nb_lines_backtrace_before"] = ( 2, "Number of line in the backtrace pane before selected frame") - self["nb_lines_threads"] = ( -1, "Number of line in the threads pane") - self["nb_lines_code"] = ( 6, "Number of instruction after $pc") - self["nb_lines_code_prev"] = ( 3, "Number of instruction before $pc") - self["ignore_registers"] = ( "", "Space-separated list of registers not to display (e.g. '$cs $ds $gs')") - self["clear_screen"] = ( True, "Clear the screen before printing the context") - self["layout"] = ( "legend regs stack code args source memory threads trace extra", "Change the order/presence of the context sections") + self["enable"] = (True, "Enable/disable printing the context when breaking") + self["show_source_code_variable_values"] = (True, "Show extra PC context info in the source code") + self["show_stack_raw"] = (False, "Show the stack pane as raw hexdump (no dereference)") + self["show_registers_raw"] = (False, "Show the registers pane with raw values (no dereference)") + self["show_opcodes_size"] = (0, "Number of bytes of opcodes to display next to the disassembly") + self["peek_calls"] = (True, "Peek into calls") + self["peek_ret"] = (True, "Peek at return address") + self["nb_lines_stack"] = (8, "Number of line in the stack pane") + self["grow_stack_down"] = (False, "Order of stack downward starts at largest down to stack pointer") + self["nb_lines_backtrace"] = (10, "Number of line in the backtrace pane") + self["nb_lines_backtrace_before"] = (2, "Number of line in the backtrace pane before selected frame") + self["nb_lines_threads"] = (-1, "Number of line in the threads pane") + self["nb_lines_code"] = (6, "Number of instruction after $pc") + self["nb_lines_code_prev"] = (3, "Number of instruction before $pc") + self["ignore_registers"] = ("", "Space-separated list of registers not to display (e.g. '$cs $ds $gs')") + self["clear_screen"] = (True, "Clear the screen before printing the context") + self["layout"] = ("legend regs stack code args source memory threads trace extra", "Change the order/presence of the context sections") self["redirect"] = ("", "Redirect the context information to another TTY") - self["libc_args"] = ( False, "Show libc function call args description") - self["libc_args_path"] = ( "", "Path to libc function call args json files, provided via gef-extras") + self["libc_args"] = (False, "Show libc function call args description") + self["libc_args_path"] = ("", "Path to libc function call args json files, provided via gef-extras") if "capstone" in list(sys.modules.keys()): - self["use_capstone"] = ( False, "Use capstone as disassembler in the code pane (instead of GDB)") + self["use_capstone"] = (False, "Use capstone as disassembler in the code pane (instead of GDB)") self.layout_mapping = { "legend": (self.show_legend, None), @@ -8912,7 +8951,7 @@ class HexdumpCommand(GenericCommand): def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION, prefix=True) - self["always_show_ascii"] = ( False, "If true, hexdump will always display the ASCII dump") + self["always_show_ascii"] = (False, "If true, hexdump will always display the ASCII dump") self.format = None self.__last_target = "$sp" return @@ -9162,6 +9201,7 @@ def do_invoke(self, argv: List) -> None: gef.memory.write(addr, s, len(s)) return + @lru_cache() def dereference_from(addr: int) -> List[str]: if not is_alive(): @@ -9237,7 +9277,7 @@ class DereferenceCommand(GenericCommand): def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_LOCATION) - self["max_recursion"] = ( 7, "Maximum level of pointer recursion") + self["max_recursion"] = (7, "Maximum level of pointer recursion") return @staticmethod @@ -9409,11 +9449,11 @@ def print_entry(self, entry: Section) -> None: elif entry.permission.value & Permission.READ and entry.permission.value & Permission.EXECUTE: line_color = gef.config["theme.address_code"] - l = [] - l.append(Color.colorify(format_address(entry.page_start), line_color)) - l.append(Color.colorify(format_address(entry.page_end), line_color)) - l.append(Color.colorify(format_address(entry.offset), line_color)) - + l = [ + Color.colorify(format_address(entry.page_start), line_color), + Color.colorify(format_address(entry.page_end), line_color), + Color.colorify(format_address(entry.offset), line_color), + ] if entry.permission.value == (Permission.READ|Permission.WRITE|Permission.EXECUTE): l.append(Color.colorify(str(entry.permission), "underline " + line_color)) else: @@ -9471,11 +9511,12 @@ def do_invoke(self, argv: List) -> None: if filter_by_name and filter_by_name not in xfile.name: continue - l = [] - l.append(format_address(xfile.zone_start)) - l.append(format_address(xfile.zone_end)) - l.append(f"{xfile.name:<21s}") - l.append(xfile.filename) + l = [ + format_address(xfile.zone_start), + format_address(xfile.zone_end), + f"{xfile.name:<21s}", + xfile.filename, + ] gef_print(" ".join(l)) return @@ -9536,7 +9577,7 @@ def infos(self, address: int) -> None: name, offset = sym msg = f"Symbol: {name}" if offset: - msg+= f"+{offset:d}" + msg += f"+{offset:d}" gef_print(msg) return @@ -9625,8 +9666,8 @@ class TraceRunCommand(GenericCommand): def __init__(self) -> None: super().__init__(self._cmdline_, complete=gdb.COMPLETE_LOCATION) - self["max_tracing_recursion"] = ( 1, "Maximum depth of tracing") - self["tracefile_prefix"] = ( "./gef-trace-", "Specify the tracing output file prefix") + self["max_tracing_recursion"] = (1, "Maximum depth of tracing") + self["tracefile_prefix"] = ("./gef-trace-", "Specify the tracing output file prefix") return @only_if_gdb_running @@ -9661,11 +9702,10 @@ def get_frames_size(self) -> int: def trace(self, loc_start: int, loc_end: int, depth: int) -> None: info(f"Tracing from {loc_start:#x} to {loc_end:#x} (max depth={depth:d})") logfile = f"{self['tracefile_prefix']}{loc_start:#x}-{loc_end:#x}.txt" - enable_redirect_output(to_file=logfile) - hide_context() - self.start_tracing(loc_start, loc_end, depth) - unhide_context() - disable_redirect_output() + with RedirectOutputContext(to=logfile): + hide_context() + self.start_tracing(loc_start, loc_end, depth) + unhide_context() ok(f"Done, logfile stored as '{logfile}'") info("Hint: import logfile with `ida_color_gdb_trace.py` script in IDA to visualize path") return @@ -9715,7 +9755,7 @@ class PatternCommand(GenericCommand): def __init__(self) -> None: super().__init__(prefix=True) - self["length"] = ( 1024, "Default length of a cyclic buffer to generate") + self["length"] = (1024, "Default length of a cyclic buffer to generate") return def do_invoke(self, argv: List) -> None: @@ -9797,13 +9837,13 @@ def search(self, pattern: str, size: int, period: int) -> None: off = cyclic_pattern.find(pattern_le) if off >= 0: ok(f"Found at offset {off:d} (little-endian search) " - f"{Color.colorify('likely', 'bold red') if is_little_endian() else ''}") + f"{Color.colorify('likely', 'bold red') if gef.arch.endianness == Endianness.LITTLE_ENDIAN else ''}") found = True off = cyclic_pattern.find(pattern_be) if off >= 0: ok(f"Found at offset {off:d} (big-endian search) " - f"{Color.colorify('likely', 'bold green') if is_big_endian() else ''}") + f"{Color.colorify('likely', 'bold green') if gef.arch.endianness == Endianness.BIG_ENDIAN else ''}") found = True if not found: @@ -9857,8 +9897,8 @@ def print_security_properties(self, filename: str) -> None: val = sec[prop] msg = Color.greenify(Color.boldify(TICK)) if val is True else Color.redify(Color.boldify(CROSS)) if val and prop == "Canary" and is_alive(): - canary = gef_read_canary()[0] - msg+= f"(value: {canary:#x})" + canary = gef.session.canary[0] if gef.session.canary else 0 + msg += f"(value: {canary:#x})" gef_print(f"{prop:<30s}: {msg}") @@ -9881,24 +9921,19 @@ class GotCommand(GenericCommand): def __init__(self, *args, **kwargs): super().__init__() - self["function_resolved"] = ( "green", "Line color of the got command output if the function has " - "been resolved") - self["function_not_resolved"] = ( "yellow", "Line color of the got command output if the function has " - "not been resolved") + self["function_resolved"] = ("green", + "Line color of the got command output for resolved function") + self["function_not_resolved"] = ("yellow", + "Line color of the got command output for unresolved function") return def get_jmp_slots(self, readelf: str, filename: str) -> List[str]: - output = [] cmd = [readelf, "--relocs", filename] lines = gef_execute_external(cmd, as_list=True) - for line in lines: - if "JUMP" in line: - output.append(line) - return output + return [line for line in lines if "JUMP" in line] @only_if_gdb_running def do_invoke(self, argv: List) -> None: - try: readelf = gef.session.constants["readelf"] except OSError: @@ -9913,8 +9948,8 @@ def do_invoke(self, argv: List) -> None: # getting vmmap to understand the boundaries of the main binary # we will use this info to understand if a function has been resolved or not. vmmap = gef.memory.maps - base_address = min([x.page_start for x in vmmap if x.path == get_filepath()]) - end_address = max([x.page_end for x in vmmap if x.path == get_filepath()]) + base_address = min(x.page_start for x in vmmap if x.path == get_filepath()) + end_address = max(x.page_end for x in vmmap if x.path == get_filepath()) # get the checksec output. checksec_status = checksec(get_filepath()) @@ -9953,9 +9988,9 @@ def do_invoke(self, argv: List) -> None: # for the swag: different colors if the function has been resolved or not. if base_address < got_address < end_address: - color = self["function_not_resolved"] # function hasn't already been resolved + color = self["function_not_resolved"] else: - color = self["function_resolved"] # function has already been resolved + color = self["function_resolved"] line = f"[{hex(address_val)}] " line += Color.colorify(f"{name} {RIGHT_ARROW} {hex(got_address)}", color) @@ -9973,7 +10008,7 @@ class HighlightCommand(GenericCommand): def __init__(self) -> None: super().__init__(prefix=True) - self["regex"] = ( False, "Enable regex highlighting") + self["regex"] = (False, "Enable regex highlighting") def do_invoke(self, argv: List) -> None: return self.usage() @@ -10084,7 +10119,6 @@ def do_invoke(self, argv: List) -> None: return - @register_command class HeapAnalysisCommand(GenericCommand): """Heap vulnerability analysis helper: this command aims to track dynamic heap allocation @@ -10099,11 +10133,11 @@ class HeapAnalysisCommand(GenericCommand): def __init__(self) -> None: super().__init__(complete=gdb.COMPLETE_NONE) - self["check_free_null"] = ( False, "Break execution when a free(NULL) is encountered") - self["check_double_free"] = ( True, "Break execution when a double free is encountered") - self["check_weird_free"] = ( True, "Break execution when free() is called against a non-tracked pointer") - self["check_uaf"] = ( True, "Break execution when a possible Use-after-Free condition is found") - self["check_heap_overlap"] = ( True, "Break execution when a possible overlap in allocation is found") + self["check_free_null"] = (False, "Break execution when a free(NULL) is encountered") + self["check_double_free"] = (True, "Break execution when a double free is encountered") + self["check_weird_free"] = (True, "Break execution when free() is called against a non-tracked pointer") + self["check_uaf"] = (True, "Break execution when a possible Use-after-Free condition is found") + self["check_heap_overlap"] = (True, "Break execution when a possible overlap in allocation is found") self.bp_malloc = None self.bp_calloc = None @@ -10220,15 +10254,13 @@ def __init__(self) -> None: return def do_invoke(self, argv: List) -> None: - color = gef.config["theme.table_heading"] - path = self.get_settings_path() - if path is None: - err("Cannot open '{0}': check directory and/or `gef config {0}` setting, " - "currently: '{1}'".format("syscall-args.path", self["path"])) - info("This setting can be configured by running gef-extras' install script.") + if not path: + err(f"Cannot open '{self['path']}': check directory and/or " + "`gef config syscall-args.path` setting.") return + color = gef.config["theme.table_heading"] arch = gef.arch.__class__.__name__ syscall_table = self.get_syscall_table(arch) @@ -10265,22 +10297,22 @@ def do_invoke(self, argv: List) -> None: return - def get_filepath(self, x: str) -> Optional[str]: - p = self.get_settings_path() - if not p: return None - return os.path.join(p, f"{x}.py") + def get_syscall_table(self, modname: str) -> Dict[str, Any]: + _mod = self.get_module(modname) + return getattr(_mod, "syscall_table") - def get_module(self, modname: str): - _fullname = self.get_filepath(modname) + def get_module(self, modname: str) -> Any: + _fullname = self.get_filepath(modname).absolute() return importlib.machinery.SourceFileLoader(modname, _fullname).load_module(None) - def get_syscall_table(self, modname: str): - _mod = self.get_module(modname) - return getattr(_mod, "syscall_table") + def get_filepath(self, x: str) -> Optional[pathlib.Path]: + p = self.get_settings_path() + if not p: return None + return p / f"{x}.py" def get_settings_path(self) -> Optional[pathlib.Path]: - path = pathlib.Path(os.path.expanduser(self["path"])) - return path if path.exists() and path.is_dir() else None + path = pathlib.Path(self["path"]).expanduser() + return path if path.is_dir() else None @@ -10574,8 +10606,8 @@ def is_loaded(x) -> bool: GefAlias(alias, cmd) except Exception as reason: - self.missing_commands[cmd] = reason - nb_missing += 1 + self.missing_commands[cmd] = reason + nb_missing += 1 # sort by command name self.loaded_commands = sorted(self.loaded_commands, key=lambda x: x[1]._cmdline_) @@ -10616,7 +10648,7 @@ def invoke(self, args, from_tty) -> None: gef_print(self.__doc__ or "") return - def generate_help(self, commands: List[Tuple[str, Type, Any]]) -> None: + def generate_help(self, commands: List[Tuple[str, Any, Any]]) -> None: """Generate builtin commands documentation.""" for command in commands: self.add_command_to_doc(command) @@ -10960,6 +10992,7 @@ def lookup_command(self, cmd: str) -> Optional[Tuple[str, Type, Any]]: return None + @register_command class AliasesCommand(GenericCommand): """Base command to add, remove, or list aliases.""" @@ -10975,6 +11008,7 @@ def do_invoke(self, argv) -> None: self.usage() return + @register_command class AliasesAddCommand(AliasesCommand): """Command to add aliases.""" @@ -10994,6 +11028,7 @@ def do_invoke(self, argv: List) -> None: GefAlias(argv[0], " ".join(argv[1:])) return + @register_command class AliasesRmCommand(AliasesCommand): """Command to remove aliases.""" @@ -11019,6 +11054,7 @@ def do_invoke(self, argv: List) -> None: gef_print("You must reload GEF for alias removals to apply.") return + @register_command class AliasesListCommand(AliasesCommand): """Command to list aliases.""" @@ -11036,6 +11072,7 @@ def do_invoke(self, argv: List) -> None: gef_print(f"{a._alias:30s} {RIGHT_ARROW} {a._command}") return + class GefTmuxSetup(gdb.Command): """Setup a confortable tmux debugging environment.""" @@ -11092,7 +11129,7 @@ def screen_setup(self) -> None: f.write(f"screen bash -c 'tty > {tty_path}; clear; cat'\n") f.write("focus left\n") - gdb.execute(f"""! {screen} -r {sty} -m -d -X source {script_path}""") + gdb.execute(f"! {screen} -r {sty} -m -d -X source {script_path}") # artificial delay to make sure `tty_path` is populated time.sleep(0.25) with open(tty_path, "r") as f: @@ -11127,10 +11164,11 @@ def reset_caches(self) -> None: if not hasattr(obj, "cache_clear"): continue obj.cache_clear() - except: # we're reseeting the cache here, we don't care if (or which) exception triggers + except: # we're reseting the cache here, we don't care if (or which) exception triggers continue return + class GefMemoryManager(GefManager): """Class that manages memory access for gef.""" def __init__(self) -> None: @@ -11157,13 +11195,16 @@ def read_integer(self, addr: int) -> int: unpack = u32 if sz == 4 else u64 return unpack(mem) - def read_cstring(self, address: int, max_length: int = GEF_MAX_STRING_LENGTH, encoding: Optional[str] = None) -> str: + def read_cstring(self, + address: int, + max_length: int = GEF_MAX_STRING_LENGTH, + encoding: Optional[str] = None) -> str: """Return a C-string read from memory.""" encoding = encoding or "unicode-escape" length = min(address | (DEFAULT_PAGE_SIZE-1), max_length+1) try: - res_bytes = bytes(self.read(address, length)) + res_bytes = self.read(address, length) except gdb.error: err(f"Can't read memory at '{address}'") return "" @@ -11185,24 +11226,24 @@ def read_cstring(self, address: int, max_length: int = GEF_MAX_STRING_LENGTH, en def read_ascii_string(self, address: int) -> Optional[str]: """Read an ASCII string from memory""" cstr = self.read_cstring(address) - if isinstance(cstr, str) and cstr and all([x in string.printable for x in cstr]): + if isinstance(cstr, str) and cstr and all(x in string.printable for x in cstr): return cstr return None @property - def maps(self): + def maps(self) -> List[Section]: if not self.__maps: self.__maps = self.__parse_maps() return self.__maps - def __parse_maps(self): + def __parse_maps(self) -> Generator[Section, None, None]: """Return the mapped memory sections""" try: return list(self.__parse_procfs_maps()) except FileNotFoundError: return list(self.__parse_gdb_info_sections()) - def __parse_procfs_maps(self): + def __parse_procfs_maps(self) -> Generator[Section, None, None]: """Get the memory mapping from procfs.""" def open_file(path, use_cache=False): """Attempt to open the given file, if remote debugging is active, download @@ -11238,7 +11279,7 @@ def open_file(path, use_cache=False): path=pathname) return - def __parse_gdb_info_sections(self): + def __parse_gdb_info_sections(self) -> Generator[Section, None, None]: """Get the memory mapping from GDB's command `maintenance info sections` (limited info).""" stream = StringIO(gdb.execute("maintenance info sections", to_string=True)) @@ -11267,6 +11308,7 @@ def __parse_gdb_info_sections(self): continue return + class GefHeapManager(GefManager): """Class managing session heap.""" def __init__(self) -> None: @@ -11328,7 +11370,8 @@ def base_address(self) -> Optional[int]: def chunks(self) -> Union[List, Iterator]: if not self.base_address: return [] - return iter( GlibcChunk(self.base_address, from_base=True) ) + return iter(GlibcChunk(self.base_address, from_base=True)) + class GefSetting: """Basic class for storing gef settings as objects""" @@ -11372,6 +11415,7 @@ def __delitem__(self, name: str) -> None: def raw_entry(self, name: str) -> Any: return dict.__getitem__(self, name) + class GefSessionManager(GefManager): """Class managing the runtime properties of GEF. """ def __init__(self) -> None: @@ -11473,9 +11517,9 @@ def canary(self) -> Optional[Tuple[int, int]]: class GefUiManager(GefManager): """Class managing UI settings.""" def __init__(self): - self.redirect_fd = None + self.redirect_fd : Optional[TextIOWrapper] = None self.context_hidden = False - self.stream_buffer = None + self.stream_buffer : Optional[StringIO] = None self.highlight_table = {} self.watches = {} self.context_messages = [] @@ -11483,7 +11527,7 @@ def __init__(self): class Gef: - """The GEF root class, which serves as a base classe for all the attributes for the debugging session (architecture, + """The GEF root class, which serves as a entrypoint for all the debugging session attributes (architecture, memory, settings, etc.).""" def __init__(self) -> None: self.binary: Optional[Elf] = None diff --git a/tests/helpers.py b/tests/helpers.py index 60fd5b64d..a0daa7cd0 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -161,7 +161,8 @@ def _target(name: str, extension: str = ".out") -> Path: return target -def start_gdbserver(exe : Union[str, Path]=_target("default"), port : int=1234) -> subprocess.Popen: +def start_gdbserver(exe: Union[str, Path] = _target("default"), + port: int = 1234) -> subprocess.Popen: """Start a gdbserver on the target binary. Args: @@ -176,7 +177,7 @@ def start_gdbserver(exe : Union[str, Path]=_target("default"), port : int=1234) def stop_gdbserver(gdbserver: subprocess.Popen) -> None: - """Stop the gdbserver and waits until it is terminated if it was + """Stop the gdbserver and wait until it is terminated if it was still running. Needed to make the used port available again. Args: diff --git a/tests/runtests.py b/tests/runtests.py index 332134220..9202d43ae 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -258,7 +258,7 @@ def test_cmd_heap_chunks(self): return def test_cmd_heap_chunks_mult_heaps(self): - py_cmd = 'gdb.execute(f"heap set-arena 0x{int(list(gef.heap.arenas)[1]):x}")' + py_cmd = 'gdb.execute(f"heap set-arena {int(list(gef.heap.arenas)[1]):#x}")' before = ['run', 'python ' + py_cmd] cmd = "heap chunks" target = _target("heap-multiple-heaps") @@ -281,7 +281,7 @@ def test_cmd_heap_bins_fast(self): return def test_cmd_heap_bins_non_main(self): - cmd = "python gdb.execute('heap bins fast {}'.format(gef.heap.main_arena))" + cmd = "python gdb.execute(f'heap bins fast {gef.heap.main_arena}')" before = ["set environment GLIBC_TUNABLES glibc.malloc.tcache_count=0"] target = _target("heap-non-main") res = gdb_run_silent_cmd(cmd, before=before, target=target) @@ -525,9 +525,10 @@ def test_cmd_print_format(self): res = gdb_start_silent_cmd("print-format --lang js $sp") self.assertNoException(res) self.assertTrue("var buf = [" in res) - res = gdb_start_silent_cmd("print-format --lang hex $sp") + res = gdb_start_silent_cmd("set *((int*)$sp) = 0x41414141", + after=["print-format --lang hex $sp"]) self.assertNoException(res) - self.assertTrue("f7ff7f" in res) + self.assertTrue("41414141" in res, f"{res}") res = gdb_start_silent_cmd("print-format --lang iDontExist $sp") self.assertNoException(res) self.assertTrue("Language must be in:" in res) @@ -894,7 +895,7 @@ def test_func_parse_address(self): def test_func_download_file(self): gdbsrv = start_gdbserver(BIN_LS) - func = f"download_file('{BIN_LS!s}')" + func = f"download_file('{BIN_LS}')" res = gdb_test_python_method(func) stop_gdbserver(gdbsrv) self.assertNoException(res) From fa28aa2ce34c4f609c4fb697a2c784f13433640b Mon Sep 17 00:00:00 2001 From: hugsy Date: Fri, 14 Jan 2022 18:43:32 -0800 Subject: [PATCH 61/62] Removed debug info in `FormatStringSearchCommand` --- gef.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gef.py b/gef.py index 7a84fc8e8..cad03708d 100644 --- a/gef.py +++ b/gef.py @@ -1721,6 +1721,7 @@ def unhide_context() -> bool: gef.ui.context_hidden = False return True + class RedirectOutputContext(): def __init__(self, to="/dev/null") -> None: self.redirection_target_file = to @@ -10107,8 +10108,7 @@ def do_invoke(self, argv: List) -> None: nb_installed_breaks = 0 - # with RedirectOutputContext("/dev/null") as ctx: - if True: + with RedirectOutputContext(to="/dev/null"): for function_name in dangerous_functions: argument_number = dangerous_functions[function_name] FormatStringBreakpoint(function_name, argument_number) From e4a77aa449e88e89faf52c766db013250cbf2dcf Mon Sep 17 00:00:00 2001 From: hugsy Date: Sun, 16 Jan 2022 14:44:39 -0800 Subject: [PATCH 62/62] - fixed `heap` CI failures (defered to #785) - minor type adjustments --- .github/workflows/run-tests.yml | 13 ++++++++-- gef.py | 44 +++++++++++++++------------------ 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 006d3b10f..1df69ccba 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -1,6 +1,15 @@ name: CI Test for GEF -on: [push, pull_request] +on: + push: + branches: + - master + - dev + + pull_request: + branches: + - master + - dev jobs: build: @@ -71,4 +80,4 @@ jobs: - name: Run linter run: | make lint - + diff --git a/gef.py b/gef.py index cad03708d..9d7f7849d 100644 --- a/gef.py +++ b/gef.py @@ -230,7 +230,7 @@ def highlight_text(text: str) -> str: def gef_print(x: str = "", *args: Tuple, **kwargs: Dict[str, Any]) -> Optional[int]: - """Wrapper around print(), using string buffering feature.""" + """Wrapper around `print()`, using string buffering feature.""" x = highlight_text(x) if gef.ui.stream_buffer and not is_debug(): return gef.ui.stream_buffer.write(x + kwargs.get("end", "\n")) @@ -1058,8 +1058,6 @@ def __init__(self, addr: str) -> None: try: self.__addr = parse_address(f"&{addr}") except gdb.error: - warn(f"Could not parse address '&{addr}' when searching malloc_state struct, " - "using '&main_arena' instead") self.__addr = search_for_main_arena() # if `search_for_main_arena` throws `gdb.error` on symbol lookup: # it means the session is not started, so just propagate the exception @@ -3203,23 +3201,22 @@ def get_filepath() -> Optional[str]: def download_file(remote_path: str, use_cache: bool = False, local_name: Optional[str] = None) -> Optional[str]: - """Download filename `remote_path` inside the mirror tree inside the gef.config["gef.tempdir"]. - The tree architecture must be gef.config["gef.tempdir"]/gef//. + """Download filename `remote_path` inside the mirror tree inside the `gef.config["gef.tempdir"]`. + The tree architecture must be `gef.config["gef.tempdir"]/gef//`. This allow a "chroot-like" tree format.""" - try: - local_root = pathlib.Path(gef.config["gef.tempdir"]) / str(gef.session.pid) - if local_name is None: - local_path = local_root / remote_path.strip(os.sep) - else: - local_path = local_root / local_name.strip(os.sep) + local_root = pathlib.Path(gef.config["gef.tempdir"]) / str(gef.session.pid) + if local_name is None: + local_path = local_root / remote_path.strip(os.sep) + else: + local_path = local_root / local_name.strip(os.sep) - if use_cache and local_path.exists(): - return str(local_path.absolute()) + if use_cache and local_path.exists(): + return str(local_path.absolute()) + try: local_path.parent.mkdir(parents=True, exist_ok=True) gdb.execute(f"remote get {remote_path} {local_path.absolute()}") - local_path = str(local_path.absolute()) except gdb.error: # fallback memory view @@ -3231,7 +3228,7 @@ def download_file(remote_path: str, use_cache: bool = False, local_name: Optiona except Exception as e: err(f"download_file() failed: {e}") - local_name = None + local_path = None return local_path @@ -3298,7 +3295,7 @@ def process_lookup_path(name: str, perm=Permission.ALL) -> Optional[Section]: return None for sect in gef.memory.maps: - if name in sect.path and sect.permission.value & perm: + if name in sect.path and sect.permission & perm: return sect return None @@ -3338,14 +3335,13 @@ def lookup_address(address: int) -> Address: def xor(data: ByteString, key: str) -> bytearray: """Return `data` xor-ed with `key`.""" - key = key.lstrip("0x") - key = binascii.unhexlify(key) - return bytearray(x ^ y for x, y in zip(data, itertools.cycle(key))) + key_raw = binascii.unhexlify(key.lstrip("0x")) + return bytearray(x ^ y for x, y in zip(data, itertools.cycle(key_raw))) def is_hex(pattern: str) -> bool: """Return whether provided string is a hexadecimal value.""" - if not pattern.startswith("0x") and not pattern.startswith("0X"): + if not pattern.lower().startswith("0x"): return False return len(pattern) % 2 == 0 and all(c in string.hexdigits for c in pattern[2:]) @@ -7261,12 +7257,12 @@ def __init__(self) -> None: @only_if_gdb_running def do_invoke(self, argv: List) -> None: - if gef.heap.selected_arena is None: + if gef.heap.main_arena is None: err("Invalid Glibc arena") return arena_addr = f"*{argv[0]}" if len(argv) == 1 else gef.heap.selected_arena - gef_print(titlify(f"Unsorted Bin for arena '{arena_addr:s}'")) + gef_print(titlify(f"Unsorted Bin for arena '{arena_addr!s}'")) nb_chunk = GlibcHeapBinsCommand.pprint_bin(arena_addr, 0, "unsorted_") if nb_chunk >= 0: info(f"Found {nb_chunk:d} chunks in unsorted bin.") @@ -7291,7 +7287,7 @@ def do_invoke(self, argv: List) -> None: return arena = GlibcArena(f"*{argv[0]}") if len(argv) == 1 else gef.heap.selected_arena - gef_print(titlify(f"Small Bins for arena '{arena:s}'")) + gef_print(titlify(f"Small Bins for arena '{arena!s}'")) bins = {} for i in range(1, 63): nb_chunk = GlibcHeapBinsCommand.pprint_bin(arena, i, "small_") @@ -7321,7 +7317,7 @@ def do_invoke(self, argv: List) -> None: return arena_addr = f"*{argv[0]}" if len(argv) == 1 else gef.heap.selected_arena - gef_print(titlify(f"Large Bins for arena '{arena_addr:s}'")) + gef_print(titlify(f"Large Bins for arena '{arena_addr!s}'")) bins = {} for i in range(63, 126): nb_chunk = GlibcHeapBinsCommand.pprint_bin(arena_addr, i, "large_")