About
heaptrace is a ptrace
-based debugger for tracking glibc heap operations in ELF64 (x86_64) binaries. Its purpose is to help visualize heap operations when debugging binaries or doing heap pwn.
- Prints out heap operations using symbols instead of pointers. This allows users to understand what is going on on the heap without having to compare pointer values at each operation.
- Detects some forms of heap corruption, double free vulnerabilities, and memory leakage issues (NOTE: this feature is temporarily disabled).
- Allows users to set "breakpoints" at any heap operation via
--break
and--break-after
. When heaptrace reaches the requested heap operation number number, it immediately detaches itself from the tracee (the target binary) and attaches the GNU debugger (gdb). This allows users to easily debug the heap interactively at any point. - Automatically resolves symbols if available. If the binary is stripped, it attempts to automatically identify function offsets based on function signatures.
Installation
Official Releases
See the .deb and .rpm release files, and a pre-compiled binary at the Releases page.
Arch User Repository (PKGBUILD)
Use your preferred AUR helper to install the heaptrace-git
package.
$ trizen -S heaptrace-git
Compile from Source
$ git clone https://github.com/Arinerron/heaptrace.git && cd heaptrace
$ make
$ sudo make install
...
$ heaptrace ./target
$ heaptrace -- ./target -a -f3 # if you have arguments
Usage
You can specify arguments to heaptrace before specifying the binary name:
Usage:
./heaptrace [options...]
./heaptrace [options...] --
[args...]
./heaptrace [options...] -p/--attach
Options:
-e
, --environ=
, --environment=
Sets a single environmental variable. Useful for setting runtime settings for the target such as LD_PRELOAD=./libc.so.6 without having them affect heaptrace's runtime configuration. -s
, --symbols=
Override the values heaptrace detects for the malloc/calloc/free/realloc/reallocarray symbols. Useful if heaptrace fails to automatically identify heap functions in a stripped binary. See the wiki for more info. -b
, --break=
, --break-at=
Send SIGSTOP to the process at heap operation specified in `number` (before executing the heap function) and attach the GNU debugger (gdb) to the process. Also supports "segfault" in the `number` arg to launch gdb if the process exits abnormally (SIGSEGV, abort(), etc). And, "main" will break at the entry point to the binary (the binary's auxiliary vector). -B
, --break-after=
Similar to `--break`. Replaces the tracer process with gdb, but only after the heap function returns. -F, --follow-fork, --follow Tells heaptrace to detach the parent and follow the child if the target calls fork(), vfork(), or clone(). The default behavior is to detatch the child and only trace the parent. -G
, --gdb-path
Tells heaptrace to use the path to gdb specified in `path` instead of /usr/bin/gdb (default). -p
, --attach
, --pid
Tells heaptrace to attach to the specified pid instead of running the binary from the `target` argument. Note that if you specify this argument you do not have to specify `target`. -o
, --output=
Write the heaptrace output to `file` instead of /dev/stderr (which is the default output path). -v, --verbose Prints verbose information such as line numbers in source code given the required debugging info is stored in the ELF. -h, --help Shows this help menu.
For example, if you wanted to automatically attach gdb at operation #3, you would execute:
heaptrace --break=3 ./my-binary
See the wiki documentation for more information on how to use the -s
/--symbol
argument to debug stripped binaries that heaptrace failed to automatically identify functions in.
Support
I'm happy to help if you experience a bug or have any feedback. Please see the GitHub Issues page.