Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add number arg for 'heap chunk' command #745

Merged
merged 5 commits into from Nov 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/commands/heap.md
Expand Up @@ -60,6 +60,20 @@ Glibc's behavior. To be able to view unaligned chunks as well, you can disable
this with the `--allow-unaligned` flag. Note that this might result in
incorrect output.


There is an optional `number` argument, to specify the number of chunks printed by this command. To do so, simply provide the `--number` argument:

```
gef➤ heap chunk --number 6 0x4e5400
Chunk(addr=0x4e5400, size=0xd0, flags=PREV_INUSE)
Chunk(addr=0x4e54d0, size=0x1a0, flags=PREV_INUSE)
Chunk(addr=0x4e5670, size=0x200, flags=PREV_INUSE)
Chunk(addr=0x4e5870, size=0xbc0, flags=PREV_INUSE)
Chunk(addr=0x4e6430, size=0x330, flags=PREV_INUSE)
Chunk(addr=0x4e6760, size=0x4c0, flags=PREV_INUSE)

```

### `heap arenas` command ###

Multi-threaded programs have different arenas, and the knowledge of the
Expand Down
30 changes: 23 additions & 7 deletions gef.py
Expand Up @@ -1217,6 +1217,8 @@ def flags_as_string(self):
flags = []
if self.has_p_bit():
flags.append(Color.colorify("PREV_INUSE", "red bold"))
else:
flags.append(Color.colorify("! PREV_INUSE", "green bold"))
if self.has_m_bit():
flags.append(Color.colorify("IS_MMAPPED", "red bold"))
if self.has_n_bit():
Expand Down Expand Up @@ -7000,13 +7002,13 @@ class GlibcHeapChunkCommand(GenericCommand):
See https://github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1123."""

_cmdline_ = "heap chunk"
_syntax_ = "{:s} [-h] [--allow-unaligned] address".format(_cmdline_)
_syntax_ = "{:s} [-h] [--allow-unaligned] [--number] address".format(_cmdline_)

def __init__(self):
super().__init__(complete=gdb.COMPLETE_LOCATION)
return

@parse_arguments({"address": ""}, {"--allow-unaligned": True})
@parse_arguments({"address": ""}, {"--allow-unaligned": True, "--number": 1})
@only_if_gdb_running
def do_invoke(self, *args, **kwargs):
args = kwargs["arguments"]
Expand All @@ -7015,12 +7017,26 @@ def do_invoke(self, *args, **kwargs):
self.usage()
return

if get_glibc_arena() is None:
return

addr = parse_address(args.address)
chunk = GlibcChunk(addr, allow_unaligned=args.allow_unaligned)
gef_print(chunk.psprint())
current_chunk = GlibcChunk(addr, allow_unaligned=args.allow_unaligned)

if args.number > 1:
for _ in range(args.number):
if current_chunk.size == 0:
break

gef_print(str(current_chunk))
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
else:
gef_print(current_chunk.psprint())
return


Expand Down
7 changes: 7 additions & 0 deletions tests/runtests.py
Expand Up @@ -242,6 +242,13 @@ def test_cmd_heap_chunk(self):
res = gdb_run_silent_cmd(cmd, target=target)
self.assertNoException(res)
self.assertIn("NON_MAIN_ARENA flag: ", res)

cmd = "heap chunk --number 2 p1"
self.assertFailIfInactiveSession(gdb_run_cmd(cmd, target=target))
res = gdb_run_silent_cmd(cmd, target=target)
self.assertNoException(res)
heap_lines = [x for x in res.splitlines() if x.startswith("Chunk(addr=")]
self.assertTrue(len(heap_lines) == 2)
return

def test_cmd_heap_chunks(self):
Expand Down