gef: `heap` commands no longer works properly when remote debugging

  • Did you use the latest version of GEF from dev branch?
  • Is your bug specific to GEF (not GDB)? - Try to reproduce it running gdb -nx
  • Did you read the documentation first?
  • Did you check issues (including the closed ones) - and the PR?

Step 1: Describe your environment

  • Operating System / Distribution: Ubuntu 20.04.2 LTS
  • Architecture: x86_64
  • GEF version (including the Python library version) run version in GEF.
gef➤  version
GEF: (Standalone)
SHA1(/home/andrew/.gdbinit-gef.py): 3a1557190297912278671d27454d3d1fcda619e5
GDB: 9.2
GDB-Python: 3.8
$ file level05
level05: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.15, BuildID[sha1]=2cf47809a1a841f6990910071c09e6053e9f57ac, with debug_info, not stripped
  • The heap commands works with the 2021.01 release.

Step 2: Describe your problem

Steps to reproduce

  1. Start a VM (no hard drive necessary) and boot to the Fusion ISO (https://github.com/ExploitEducation/Fusion/releases/download/v2.0.0/exploit-exercises-fusion-2.iso)
  2. SSH to the VM (use root:godmode for creds) and run gdbserver to attach to process:
# gdbserver --attach :1234 $(pidof level05)
  1. Start gdb & connect to the server:
$ gdb
GEF for linux ready, type `gef' to start, `gef config' to configure
92 commands loaded for GDB 9.2 using Python engine 3.8
gef➤  file level05
Reading symbols from level05...
gef➤  target remote fusion:1234
Remote debugging using fusion:1234
...
  1. Use the heap chunks|arenas|bins commands:
gef➤  heap chunks
[!] Failed to get the main arena, heap commands may not work properly: There is no member named next_free.
[!] No valid arena
gef➤  heap arenas
[!] Could not find Glibc main arena
gef➤  heap bins
[+] No Tcache in this version of libc
[!] Failed to get the main arena, heap commands may not work properly: There is no member named next_free.
[!] Invalid Glibc arena
[!] Failed to get the main arena, heap commands may not work properly: There is no member named next_free.
[!] Invalid Glibc arena
[!] Failed to get the main arena, heap commands may not work properly: There is no member named next_free.
[!] Invalid Glibc arena
[!] Failed to get the main arena, heap commands may not work properly: There is no member named next_free.
[!] Invalid Glibc arena
  1. Going back to release 2021.01, the heap chunks command works, but heap arenas does not:
gef➤  heap chunks
Chunk(addr=0xb7dfd008, size=0x108, flags=PREV_INUSE)
    [0xb7dfd008     08 50 53 b7 10 d1 df b7 b0 54 e0 b7 00 00 00 00    .PS......T......]
Chunk(addr=0xb7dfd110, size=0x83a0, flags=PREV_INUSE)
    [0xb7dfd110     66 64 74 61 73 6b 00 00 00 00 00 00 00 00 00 00    fdtask..........]
Chunk(addr=0xb7e054b0, size=0x18b58, flags=PREV_INUSE)  ←  top chunk
gef➤  heap arenas 
[!] Command 'heap arenas' failed to execute properly, reason: 'MallocStateStruct' object has no attribute 'nfree'
gef➤  heap bins
[+] No Tcache in this version of libc
───────────────────────────────────────────── Fastbins for arena 0xb76f0400 ─────────────────────────────────────────────
Fastbins[idx=0, size=0x10] 0x00
Fastbins[idx=1, size=0x18] 0x00
Fastbins[idx=2, size=0x20] 0x00
Fastbins[idx=3, size=0x28] 0x00
Fastbins[idx=4, size=0x30] 0x00
Fastbins[idx=5, size=0x38] 0x00
Fastbins[idx=6, size=0x40] 0x00
────────────────────────────────────────── Unsorted Bin for arena 'main_arena' ──────────────────────────────────────────
[+] Found 0 chunks in unsorted bin.
─────────────────────────────────────────── Small Bins for arena 'main_arena' ───────────────────────────────────────────
[+] Found 0 chunks in 0 small non-empty bins.
─────────────────────────────────────────── Large Bins for arena 'main_arena' ───────────────────────────────────────────
[+] Found 0 chunks in 0 large non-empty bins.

Minimalist test case

// compile with gcc -fPIE -pic -o my_issue.out my_issue.c
int main(){ return 0; }

Not applicable as this is heap-related. I did, however, create my own test case.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    char *name = malloc(32);
    strncpy(name, "Drew", 5);
    printf("Name = %s\n", name);

    return 0;
}

Compiled with gcc test.c -o test -g. This one does work.

$ gdb test 
GEF for linux ready, type `gef' to start, `gef config' to configure
92 commands loaded for GDB 9.2 using Python engine 3.8
Reading symbols from test...
gef➤  b test.c:7
Breakpoint 1 at 0x1183: file test.c, line 7.
gef➤  run
...
gef➤  heap chunks
Chunk(addr=0x555555559010, size=0x290, flags=PREV_INUSE)
    [0x0000555555559010     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................]
Chunk(addr=0x5555555592a0, size=0x30, flags=PREV_INUSE)
    [0x00005555555592a0     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................]
Chunk(addr=0x5555555592d0, size=0x20d40, flags=PREV_INUSE)  ←  top chunk
gef➤  heap arenas 
Arena (base=0x7ffff7fb0b80, top=0x5555555592c0, last_remainder=0x0, next=0x7ffff7fb0b80, next_free=0x0, system_mem=0x21000)
gef➤  heap bins
──────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────
All tcachebins are empty
─────────────────────────────────────────── Fastbins for arena 0x7ffff7fb0b80 ───────────────────────────────────────────
Fastbins[idx=0, size=0x20] 0x00
Fastbins[idx=1, size=0x30] 0x00
Fastbins[idx=2, size=0x40] 0x00
Fastbins[idx=3, size=0x50] 0x00
Fastbins[idx=4, size=0x60] 0x00
Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
────────────────────────────────────────── Unsorted Bin for arena 'main_arena' ──────────────────────────────────────────
[+] Found 0 chunks in unsorted bin.
─────────────────────────────────────────── Small Bins for arena 'main_arena' ───────────────────────────────────────────
[+] Found 0 chunks in 0 small non-empty bins.
─────────────────────────────────────────── Large Bins for arena 'main_arena' ───────────────────────────────────────────
[+] Found 0 chunks in 0 large non-empty bins.

Observed Results

  • What happened? This could be a description, log output, etc.

See above. Another thing to note is that when attaching to the “level05” process locally instead of remotely (using the latest dev version of GEF), nothing happens with the heap chunks command. Though heap arenas seems to work.

# gdb -p $(pidof level05)
GEF for linux ready, type `gef' to start, `gef config' to configure
92 commands loaded for GDB 9.2 using Python engine 3.8
Attaching to process 31642
...
gef➤  file /home/andrew/level05/level05
Reading symbols from /home/andrew/level05/level05...
gef➤  heap chunks
gef➤  heap arenas
Arena (base=0xf7f60740, top=0x57befe48, last_remainder=0x57bdf6f8, next=0xf7f60740, next_free=0x0, system_mem=0x22000)

Expected results

  • What did you expect to happen?

The heap chunks and heap arenas commands display information on the heap.

Sorry, but I haven’t tested this extensively with other binaries or architectures.

Traces

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 23 (1 by maintainers)

Most upvoted comments

This sort of discussion would be better done on our discord.