pwndbg: Heap heuristics may crash if libc.so is dynamically linked but no symbols are present for it

This is weird:

dc@jhtc:~$ gdb --quiet -ex 'set context-sections ""' -ex 'set auto-solib-add off' -ex 'set resolve-heap-via-heuristic on' -ex 'entry' /bin/ls
pwndbg: loaded 207 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from /bin/ls...
(No debugging symbols found in /bin/ls)
Sections set to be empty. FYI valid values are: regs, disasm, args, code, stack, backtrace, expressions, ghidra
You are going to resolve the heap via heuristic. This might not work in all cases.
You are going to resolve the heap via heuristic. This might not work in all cases.
Temporary breakpoint 1 at 0x555555559850
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Temporary breakpoint 1, 0x0000555555559850 in ?? ()
------- tip of the day (disable with set show-tips off) -------
Pwndbg context displays where the program branches to thanks to emulating few instructions into the future. You can disable this with set emulate off which may also speed up debugging
You are going to resolve the heap via heuristic. This might not work in all cases.
pwndbg> set exception-verbose on
Set whether to print a full stacktrace for exceptions raised in Pwndbg commands to True
pwndbg> heap
Traceback (most recent call last):
  File "/opt/pwndbg/pwndbg/commands/__init__.py", line 147, in __call__
    return self.function(*args, **kwargs)
  File "/opt/pwndbg/pwndbg/commands/__init__.py", line 218, in _OnlyWhenRunning
    return function(*a, **kw)
  File "/opt/pwndbg/pwndbg/commands/__init__.py", line 273, in _OnlyWithResolvedHeapSyms
    return function(*a, **kw)
  File "/opt/pwndbg/pwndbg/commands/__init__.py", line 243, in _OnlyWhenHeapIsInitialized
    return function(*a, **kw)
  File "/opt/pwndbg/pwndbg/commands/heap.py", line 126, in heap
    heap_region = allocator.get_heap_boundaries(addr)
  File "/opt/pwndbg/pwndbg/heap/ptmalloc.py", line 1717, in get_heap_boundaries
    arena = self.get_arena(addr)
  File "/opt/pwndbg/pwndbg/heap/ptmalloc.py", line 1703, in get_arena
    return self.main_arena
  File "/opt/pwndbg/pwndbg/heap/ptmalloc.py", line 885, in main_arena
    elif self.is_glibc_static_symbol(main_arena_via_symbol):
  File "/opt/pwndbg/pwndbg/heap/ptmalloc.py", line 872, in is_glibc_static_symbol
    _IO_list_all_addr = pwndbg.symbol.address("_IO_list_all")
  File "/opt/pwndbg/pwndbg/lib/memoize.py", line 51, in __call__
    value = self.func(*args, **kwargs)
  File "/opt/pwndbg/pwndbg/symbol.py", line 215, in address
    address = int(re.search("0x[0-9a-fA-F]+", result).group(), 0)
AttributeError: 'NoneType' object has no attribute 'group'

If that is an issue, you can report it on https://github.com/pwndbg/pwndbg/issues
(Please don't forget to search if it hasn't been reported before)
To generate the report and open a browser, you may run `bugreport --run-browser`
PS: Pull requests are welcome
pwndbg>

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 16 (12 by maintainers)

Commits related to this issue

Most upvoted comments

can this be closed?

Yes, I think we can close this. For the main cause of this issue, we won’t encounter that again. Even if the heap heuristic somehow crashes on stripped libc.so in the future, we should probably open another separate issue for that case.

@lebr0nli Cool, happy to see it’s working now, thanks!

Btw it goes the same with glibc check. The user should not see some kind of bogus “>=” comparison error when they do not set glibc version, but an info they need to set it 😅

Ok, I’ll fix that, too.

Interestingly, my friend who initially send me this bug, sent me this traceback, which says he is missing other symbol:

For this, I think I’ll fix this by checking __malloc_chunk exist or not before we using GEF’s magic for main_arena. (But a little weird thing is that these AttributeError seems to occur in pwndbg.symbol.address instead of some heap functions, I’ll check it later to see what’s going on.)

Anyway, we need a better error handling on those cases. We need to display to tell the user sth like “hey we can’t find this symbol with our heuristics; you need to provide its address to us if you can determine it, here’s how:”

Ok, I’ll add some checks and hints for this!