Skip to content

Ptmalloc

BINMAPSIZE = 4 module-attribute

HEAP_MAX_SIZE = None module-attribute

IS_MMAPPED = 2 module-attribute

NBINS = 128 module-attribute

NFASTBINS = 10 module-attribute

NONCONTIGUOUS_BIT = 2 module-attribute

NON_MAIN_ARENA = 4 module-attribute

NSMALLBINS = 64 module-attribute

PREV_INUSE = 1 module-attribute

SIZE_BITS = PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA module-attribute

TCACHE_MAX_BINS = 64 module-attribute

TheType = TypeVar('TheType', pwndbg.dbg_mod.Type, typing.Type[pwndbg.aglib.heap.structs.CStruct2GDB]) module-attribute

TheValue = TypeVar('TheValue', pwndbg.dbg_mod.Value, pwndbg.aglib.heap.structs.CStruct2GDB) module-attribute

Arena

__slots__ = ('_gdbValue', 'address', '_is_main_arena', '_top', '_active_heap', '_heaps', '_mutex', '_flags', '_non_contiguous', '_have_fastchunks', '_fastbinsY', '_bins', '_binmap', '_next', '_next_free', '_system_mem') class-attribute instance-attribute

active_heap property

address = int(self._gdbValue.address) instance-attribute

binmap property

bins property

fastbinsY property

flags property

have_fastchunks property

heaps property

is_main_arena property

mutex property

next property

next_free property

non_contiguous property

system_mem property

top property

__init__(addr)

__str__()

fastbins()

Bin

bk_chain = bk_chain instance-attribute

count = count instance-attribute

fd_chain = fd_chain instance-attribute

is_corrupted = is_corrupted instance-attribute

__init__(fd_chain, bk_chain=None, count=None, is_corrupted=False)

contains_chunk(chunk)

size_to_display_name(size) staticmethod

BinType

Bases: str, Enum

FAST = 'fastbins' class-attribute instance-attribute

LARGE = 'largebins' class-attribute instance-attribute

NOT_IN_BIN = 'not_in_bin' class-attribute instance-attribute

SMALL = 'smallbins' class-attribute instance-attribute

TCACHE = 'tcachebins' class-attribute instance-attribute

UNSORTED = 'unsortedbin' class-attribute instance-attribute

valid_fields()

Bins

bin_type = bin_type instance-attribute

bins = OrderedDict() instance-attribute

__init__(bin_type)

contains_chunk(size, chunk)

Chunk

__slots__ = ('_gdbValue', 'address', '_prev_size', '_size', '_real_size', '_flags', '_non_main_arena', '_is_mmapped', '_prev_inuse', '_fd', '_bk', '_fd_nextsize', '_bk_nextsize', '_heap', '_arena', '_is_top_chunk') class-attribute instance-attribute

address = int(self._gdbValue.address) instance-attribute

arena property

bk property

bk_nextsize property

fd property

fd_nextsize property

flags property

heap property

is_mmapped property

is_top_chunk property

non_main_arena property

prev_inuse property

prev_size property

real_size property

size property

__contains__(addr)

This allow us to avoid extra constructions like 'if start_addr <= ptr < end_addr', etc.

__init__(addr, heap=None, arena=None)

__match_renamed_field(field)

next_chunk()

ChunkField

Bases: int, Enum

BK = 4 class-attribute instance-attribute

BK_NEXTSIZE = 6 class-attribute instance-attribute

FD = 3 class-attribute instance-attribute

FD_NEXTSIZE = 5 class-attribute instance-attribute

PREV_SIZE = 1 class-attribute instance-attribute

SIZE = 2 class-attribute instance-attribute

DebugSymsHeap

Bases: GlibcMemoryAllocator[Type, Value]

can_be_resolved = GlibcMemoryAllocator.libc_has_debug_syms class-attribute instance-attribute

global_max_fast property

heap_info property

main_arena property

mallinfo property

malloc_chunk property

malloc_par property

malloc_state property

mp property

tcache_entry property

tcache_perthread_struct property

thread_arena property

thread_cache property

Locate a thread's tcache struct. If it doesn't have one, use the main thread's tcache.

get_heap(addr)

Find & read the heap_info struct belonging to the chunk at 'addr'.

get_sbrk_heap_region()

Return a Page object representing the sbrk heap region. Ensure the region's start address is aligned to SIZE_SZ * 2, which compensates for the presence of GLIBC_TUNABLES.

get_tcache(tcache_addr=None)

has_tcache()

is_initialized()

GlibcMemoryAllocator

Bases: MemoryAllocator, Generic[TheType, TheValue]

arenas property

Return a tuple of all current arenas.

global_max_fast property

heap_info property

largebin_reverse_lookup_32 = (512, 576, 640, 704, 768, 832, 896, 960, 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 3072, 3584, 4096, 4608, 5120, 5632, 6144, 6656, 7168, 7680, 8192, 8704, 9216, 9728, 10240, 10752, 12288, 16384, 20480, 24576, 28672, 32768, 36864, 40960, 65536, 98304, 131072, 163840, 262144, 524288) class-attribute instance-attribute

largebin_reverse_lookup_32_big = (1008, 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 2944, 3072, 3584, 4096, 4608, 5120, 5632, 6144, 6656, 7168, 7680, 8192, 8704, 9216, 9728, 10240, 10752, 12288, 16384, 20480, 24576, 28672, 32768, 36864, 40960, 65536, 98304, 131072, 163840, 262144, 524288) class-attribute instance-attribute

largebin_reverse_lookup_64 = (1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472, 1536, 1600, 1664, 1728, 1792, 1856, 1920, 1984, 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136, 3584, 4096, 4608, 5120, 5632, 6144, 6656, 7168, 7680, 8192, 8704, 9216, 9728, 10240, 10752, 12288, 16384, 20480, 24576, 28672, 32768, 36864, 40960, 65536, 98304, 131072, 163840, 262144, 524288) class-attribute instance-attribute

main_arena property

mallinfo property

malloc_align_mask property

Corresponds to MALLOC_ALIGN_MASK in glibc malloc.c

malloc_alignment property

Corresponds to MALLOC_ALIGNMENT in glibc malloc.c

malloc_chunk property

malloc_par property

malloc_state property

min_chunk_size property

Corresponds to MIN_CHUNK_SIZE in glibc malloc.c

minsize property

Corresponds to MINSIZE in glibc malloc.c

mp property

multithreaded property

Is malloc operating within a multithreaded environment.

size_sz property

Corresponds to SIZE_SZ in glibc malloc.c

tcache_entry property

tcache_next_offset property

tcache_perthread_struct property

thread_arena property

thread_cache property

__init__()

bin_at(index, arena_addr=None)

Modeled after glibc's bin_at function - so starts indexing from 1 https://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/eglibc/trusty-security/view/head:/malloc/malloc.c#L1394

bin_at(1) returns the unsorted bin

Bin 1 - Unsorted BiN Bin 2 to 63 - Smallbins Bin 64 to 126 - Largebins

Returns: tuple(chain_from_bin_fd, chain_from_bin_bk, is_chain_corrupted) or None

can_be_resolved()

check_chain_corrupted(chain_fd, chain_bk)

Checks if the doubly linked list (of a {unsorted, small, large} bin) defined by chain_fd, chain_bk is corrupted.

Even if the chains do not cover the whole bin, they still are expected to be of the same length.

Returns True if the bin is certainly corrupted, otherwise False.

chunk_flags(size)

chunk_key_offset(key)

Find the index of a field in the malloc_chunk struct.

64bit example

prev_size == 0 size == 8 fd == 16 bk == 24 ...

fastbin_index(size)

fastbins(arena_addr=None)

Returns: chain or None

get_bins(bin_type, addr=None)

get_heap(addr)

get_region(addr)

Find the memory map containing 'addr'.

get_sbrk_heap_region()

get_tcache(tcache_addr=None)

has_tcache()

is_initialized()

is_statically_linked()

largebin_index(sz)

Pick the appropriate largebin_index_ function for this architecture.

largebin_reverse_lookup(index)

Pick the appropriate largebin_reverse_lookup_ function for this architecture.

largebin_size_range_from_index(index)

largebins(arena_addr=None)

libc_has_debug_syms()

The struct malloc_chunk comes from debugging symbols and it will not be there for statically linked binaries

smallbins(arena_addr=None)

tcachebins(tcache_addr=None)

Returns: tuple(chain, count) or None

unsortedbin(arena_addr=None)

Heap

__slots__ = ('_gdbValue', 'arena', '_memory_region', 'start', 'end', '_prev', 'first_chunk') class-attribute instance-attribute

arena = main_arena if arena is None else arena instance-attribute

end = self._memory_region.end instance-attribute

first_chunk = Chunk(self.start) instance-attribute

prev property

start = self._memory_region.start instance-attribute

__contains__(addr)

__init__(addr, arena=None)

Build a Heap object given an address on that heap. Heap regions are treated differently depending on their arena: 1) main_arena - uses the sbrk heap 2) non-main arena - heap starts after its heap_info struct (and possibly an arena) 3) non-contiguous main_arena - just a memory region 4) no arena - for fake/mmapped chunks

__iter__()

__str__()

HeuristicHeap

Bases: GlibcMemoryAllocator[Type['pwndbg.aglib.heap.structs.CStruct2GDB'], 'pwndbg.aglib.heap.structs.CStruct2GDB']

global_max_fast property

heap_info property

main_arena property

mallinfo property

malloc_chunk property

malloc_par property

malloc_state property

mp property

struct_module property

tcache_entry property

tcache_perthread_struct property

thread_arena property

thread_cache property

Locate a thread's tcache struct. We try to find its address in Thread Local Storage (TLS) first, and if that fails, we guess it's at the first chunk of the heap.

__init__()

brute_force_thread_local_variable_near_tls_base(tls_address, validator)

Brute force the thread-local variable near the TLS base address that can pass the validator.

brute_force_tls_reference_in_got_section(tls_address, validator)

Brute force the TLS-reference in the .got section to that can pass the validator.

can_be_resolved()

get_heap(addr)

Find & read the heap_info struct belonging to the chunk at 'addr'.

get_sbrk_heap_region()

Return a Page object representing the sbrk heap region. Ensure the region's start address is aligned to SIZE_SZ * 2, which compensates for the presence of GLIBC_TUNABLES. This heuristic version requires some sanity checks and may raise SymbolUnresolvableError if malloc's mp_ struct can't be resolved.

get_tcache(tcache_addr=None)

has_tcache()

is_initialized()

prompt_for_brute_force_thread_arena_permission()

Check if the user wants to brute force the thread_arena's value.

prompt_for_brute_force_thread_cache_permission()

Check if the user wants to brute force the tcache's value.

prompt_for_tls_address()

Check if we can determine the TLS address and return it.

SymbolUnresolvableError

Bases: Exception

symbol = symbol instance-attribute

__init__(symbol)

fetch_chunk_metadata(address, include_only_fields=None)

heap_for_ptr(ptr)

Round a pointer to a chunk down to find its corresponding heap_info struct, the pointer must point inside a heap which does not belong to the main arena.