diff --git a/pwndbg/commands/heap.py b/pwndbg/commands/heap.py index 1d93f29d0..c948be616 100644 --- a/pwndbg/commands/heap.py +++ b/pwndbg/commands/heap.py @@ -122,6 +122,16 @@ def template_heap_command(addr): if chunk.size is not None: print(f"chunk.size: 0x{chunk.size:02x}") + # Flags may be retrieved individually or as a dictionary of all 3. + if chunk.non_main_arena is not None: + print(f"chunk.non_main_arena: {chunk.non_main_arena}") + + if chunk.is_mmapped is not None: + print(f"chunk.is_mmapped: {chunk.is_mmapped}") + + if chunk.prev_inuse is not None: + print(f"chunk.prev_inuse: {chunk.prev_inuse}") + if chunk.flags is not None: print(f"chunk.flags: {chunk.flags}") diff --git a/pwndbg/heap/ptmalloc.py b/pwndbg/heap/ptmalloc.py index 1fb6c6e49..7e62ece5e 100644 --- a/pwndbg/heap/ptmalloc.py +++ b/pwndbg/heap/ptmalloc.py @@ -39,6 +39,9 @@ class Chunk: self._prev_size = None self._size = None self._flags = None + self._non_main_arena = None + self._is_mmapped = None + self._prev_inuse = None self._fd = None self._bk = None # TODO fd_nextsize, bk_nextsize, key, REVEAL_PTR etc. @@ -79,13 +82,40 @@ class Chunk: sz = self.size if sz is not None: self._flags = { - "non_main_arena": bool(sz & ptmalloc.NON_MAIN_ARENA), - "is_mmapped": bool(sz & ptmalloc.IS_MMAPPED), - "prev_inuse": bool(sz & ptmalloc.PREV_INUSE), + "non_main_arena": self.non_main_arena, + "is_mmapped": self.is_mmapped, + "prev_inuse": self.prev_inuse, } return self._flags + @property + def non_main_arena(self): + if self._non_main_arena is None: + sz = self.size + if sz is not None: + self._non_main_arena = bool(sz & ptmalloc.NON_MAIN_ARENA) + + return self._non_main_arena + + @property + def is_mmapped(self): + if self._is_mmapped is None: + sz = self.size + if sz is not None: + self._is_mmapped = bool(sz & ptmalloc.IS_MMAPPED) + + return self._is_mmapped + + @property + def prev_inuse(self): + if self._prev_inuse is None: + sz = self.size + if sz is not None: + self._prev_inuse = bool(sz & ptmalloc.PREV_INUSE) + + return self._prev_inuse + @property def fd(self): if self._fd is None: