Inspiration

Modern computer security vulnerabilities (such as the recent PHP2Shell vulnerability in October 2026!) are often related to heap memory corruption. Unlike stack memory, whose layout is relatively predictable, heap memory layout depends on runtime factors, making it highly nondeterministic. The technique of arranging objects in specific locations on the heap through coordinated memory allocations and frees is called heap "feng shui," or heap grooming, and it is often a necessary step for security researchers to turn heap vulnerabilities into reliable exploits.

However, from personal experience doing vulnerability research, this process can be extremely difficult and frustrating. This tool is something I have been wanting to build for a while to better understand what is happening in the heap as my program runs and to help me keep track of different heap grooming attempts. By comparing the order of allocations and frees across runs, I can better understand which heap layouts get me closer to turning an initial heap vulnerability into an arbitrary read or write.

What it does

Think of this as a very fancy gdb for heap exploitation. Upload an AArch64 binary in your browser, step through your running program, and watch how the Linux glibc allocator allocates and frees chunks on the heap. You can see the various free lists that glibc maintains, live allocations, detailed heap metadata, and allocations from multiple threads simultaneously.

In addition, you can keep track of historical runs to visualize and compare heap layouts from previous executions. Since heap layout depends on runtime factors, including program inputs and allocation order, this makes it easier to understand how different heap grooming strategies affect the resulting memory layout.

How we built it

I built a Python backend around pwndbg (gdb extension) to automatically track malloc, calloc, realloc, and free calls and capture glibc heap state. A browser interface built with HTML, CSS, and JavaScript visualizes heap chunks, free lists, allocation lifetimes, and thread/arena relationships. Saved snapshots let users revisit and compare heap grooming runs. Everything runs in Docker with a consistent Linux AArch64 environment, and the application supports binaries with or without debug symbols. I also used Codex for helping with rapid prototyping, but the project still required significant tuning.

Challenges we ran into

Determining how to visualize the heap in multithreaded binaries was a bit of a challenge: each thread maintains its own tcache, but multiple threads may share an arena. Each arena maintains its own unsorted bin, small bins, large bins, and fastbins (different free lists that hold freed chunks). Ultimately, I decided to mainly view one thread’s tcache alongside a selected arena at a time, with options to switch threads and arenas as the program progresses.

A currently unsupported feature is flagging use-after-free vulnerabilities. These types of vulnerabilities requiring pointer provenance tracking for the purpose of detecting stale/dangling pointers, which is not trivial to implement reliably.

Accomplishments that we're proud of

I have been able to use this tool to understand whole new classes of heap vulnerabilities in modern Linux that were previously unknown to me or difficult for me to visualize. As much as this is a security tool, it is also a teaching tool.

What we learned

I learned a more about glibc features and quirks, specifically in version 2.39 which is what this application supports. Modern glibc is meant to be resistant to traditional heap exploits, supporting features like safe linking. I also had to learn more about the layout of the heap in general and how to interface with gdb/pwdbg using Python to achieve my goals for the backend.

What's next for Heap Shui

Detecting use-after-free vulnerabilities through pointer provenance tracking would be a significant next step, as well as supporting other architectures (i.e., x86-64) and versions of glibc.

Built With

Share this project:

Updates

Submission history