def find_fake_fast(addr, size): """ Finds candidate fake fast chunks that will overlap with the specified address. Used for fastbin dups and house of spirit """ main_heap = pwndbg.heap.current max_fast = main_heap.global_max_fast fastbin = main_heap.fastbin_index(int(size)) start = int(addr) - int(max_fast) mem = pwndbg.memory.read(start, max_fast, partial=True) fmt = { 'little': '<', 'big': '>' }[pwndbg.arch.endian] + { 4: 'I', 8: 'Q' }[pwndbg.arch.ptrsize] print(C.banner("FAKE CHUNKS")) for offset in range(max_fast - pwndbg.arch.ptrsize): candidate = mem[offset:offset + pwndbg.arch.ptrsize] if len(candidate) == pwndbg.arch.ptrsize: value = struct.unpack(fmt, candidate)[0] if main_heap.fastbin_index(value) == fastbin: malloc_chunk(start+offset-pwndbg.arch.ptrsize,fake=True)
def banner(title): title = title.upper() try: _height, width = struct.unpack('hh', fcntl.ioctl(sys.stdin.fileno(), termios.TIOCGWINSZ, '1234')) except: width = 80 width -= 2 return C.banner(("[{:%s^%ss}]" % (config.banner_separator, width)).format(title))
def banner(title): title = title.upper() _height, width = get_window_size() title = '%s%s%s' % (config.banner_title_surrounding_left, C.banner_title(title), config.banner_title_surrounding_right) if 'left' == title_position: banner = ljust_colored(title, width, config.banner_separator) elif 'right' == title_position: banner = rjust_colored(title, width, config.banner_separator) else: banner = rjust_colored(title, (width + len(strip(title))) // 2, config.banner_separator) banner = ljust_colored(banner, width, config.banner_separator) return C.banner(banner)
def tcachebins(addr=None, verbose=False): """ Prints out the contents of the bins in current thread tcache or in tcache at the specified address. """ main_heap = pwndbg.heap.current tcachebins = main_heap.tcachebins(addr) if tcachebins is None: return formatted_bins = format_bin(tcachebins, verbose, offset = main_heap.tcache_next_offset) print(C.banner('tcachebins')) for node in formatted_bins: print(node)
def largebins(addr=None, verbose=False): """ Prints out the contents of the large bin of the main arena or the arena at the specified address. """ main_heap = pwndbg.heap.current largebins = main_heap.largebins(addr) if largebins is None: return formatted_bins = format_bin(largebins, verbose) print(C.banner('largebins')) for node in formatted_bins: print(node)
def unsortedbin(addr=None, verbose=True): """ Prints out the contents of the unsorted bin of the main arena or the arena at the specified address. """ main_heap = pwndbg.heap.current unsortedbin = main_heap.unsortedbin(addr) if unsortedbin is None: return formatted_bins = format_bin(unsortedbin, verbose) print(C.banner('unsortedbin')) for node in formatted_bins: print(node)
def fastbins(addr=None, verbose=True): """ Prints out the contents of the fastbins of the main arena or the arena at the specified address. """ main_heap = pwndbg.heap.current fastbins = main_heap.fastbins(addr) if fastbins is None: return formatted_bins = format_bin(fastbins, verbose) print(C.banner('fastbins')) for node in formatted_bins: print(node)
def banner(title, target=sys.stdin, width=None): title = title.upper() if width is None: # auto width. In case of stdout, it's better to use stdin (b/c GdbOutputFile) _height, width = get_window_size( target=target if target != sys.stdout else sys.stdin) if title: title = '%s%s%s' % (config.banner_title_surrounding_left, C.banner_title(title), config.banner_title_surrounding_right) if 'left' == title_position: banner = ljust_colored(title, width, config.banner_separator) elif 'right' == title_position: banner = rjust_colored(title, width, config.banner_separator) else: banner = rjust_colored(title, (width + len(strip(title))) // 2, config.banner_separator) banner = ljust_colored(banner, width, config.banner_separator) return C.banner(banner)
def tcachebins(addr=None, verbose=False): """ Prints out the contents of the bins in current thread tcache or in tcache at the specified address. """ main_heap = pwndbg.heap.current tcachebins = main_heap.tcachebins(addr) if tcachebins is None: return formatted_bins = format_bin(tcachebins, verbose, offset=main_heap.tcache_next_offset) print(C.banner('tcachebins')) for node in formatted_bins: print(node)
def find_fake_fast(addr, size=None): """Find candidate fake fast chunks overlapping the specified address.""" psize = pwndbg.arch.ptrsize allocator = pwndbg.heap.current align = allocator.malloc_alignment min_fast = allocator.min_chunk_size max_fast = allocator.global_max_fast max_fastbin = allocator.fastbin_index(max_fast) start = int(addr) - max_fast + psize if start < 0: print( message.warn( 'addr - global_max_fast is negative, if the max_fast is not corrupted, you gave wrong address' )) start = 0 # TODO, maybe some better way to handle case when global_max_fast is overwritten with something large mem = pwndbg.memory.read(start, max_fast - psize, partial=True) fmt = { 'little': '<', 'big': '>' }[pwndbg.arch.endian] + { 4: 'I', 8: 'Q' }[psize] if size is None: sizes = range(min_fast, max_fast + 1, align) else: sizes = [int(size)] print(C.banner("FAKE CHUNKS")) for size in sizes: fastbin = allocator.fastbin_index(size) for offset in range((max_fastbin - fastbin) * align, max_fast - align + 1): candidate = mem[offset:offset + psize] if len(candidate) == psize: value = struct.unpack(fmt, candidate)[0] if allocator.fastbin_index(value) == fastbin: malloc_chunk(start + offset - psize, fake=True)
def find_fake_fast(addr, size=None): """ Finds candidate fake fast chunks that will overlap with the specified address. Used for fastbin dups and house of spirit """ psize = pwndbg.arch.ptrsize main_heap = pwndbg.heap.current align = main_heap.malloc_alignment min_fast = main_heap.min_chunk_size max_fast = main_heap.global_max_fast max_fastbin = main_heap.fastbin_index(max_fast) start = int(addr) - max_fast + psize mem = pwndbg.memory.read(start, max_fast - psize, partial=True) fmt = { 'little': '<', 'big': '>' }[pwndbg.arch.endian] + { 4: 'I', 8: 'Q' }[psize] if size is None: sizes = range(min_fast, max_fast + 1, align) else: sizes = [size] print(C.banner("FAKE CHUNKS")) for size in sizes: fastbin = main_heap.fastbin_index(size) for offset in range((max_fastbin - fastbin) * align, max_fast - align + 1): candidate = mem[offset : offset + psize] if len(candidate) == psize: value = struct.unpack(fmt, candidate)[0] if main_heap.fastbin_index(value) == fastbin: malloc_chunk(start+offset-psize, fake=True)
def banner(title): title = title.upper() _height, width = get_window_size() width -= 2 return C.banner( ("[{:%s^%ss}]" % (config.banner_separator, width)).format(title))