You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pwndbg/tests/test_heap_bins.py

143 lines
4.6 KiB
Python

import gdb
import pwndbg.heap
import pwndbg.memory
import pwndbg.symbol
import pwndbg.vmmap
import tests
BINARY = tests.binaries.get("heap_bins.out")
def test_heap_bins(start_binary):
"""
Tests pwndbg heap bins commands
"""
start_binary(BINARY)
gdb.execute("set context-output /dev/null")
gdb.execute("b breakpoint", to_string=True)
# check if all bins are empty at first
gdb.execute("continue")
allocator = pwndbg.heap.current
addr = pwndbg.symbol.address("tcache_size")
tcache_size = allocator._request2size(pwndbg.memory.u64(addr))
addr = pwndbg.symbol.address("tcache_count")
tcache_count = pwndbg.memory.u64(addr)
addr = pwndbg.symbol.address("fastbin_size")
fastbin_size = allocator._request2size(pwndbg.memory.u64(addr))
addr = pwndbg.symbol.address("fastbin_count")
fastbin_count = pwndbg.memory.u64(addr)
addr = pwndbg.symbol.address("smallbin_size")
smallbin_size = allocator._request2size(pwndbg.memory.u64(addr))
addr = pwndbg.symbol.address("smallbin_count")
smallbin_count = pwndbg.memory.u64(addr)
addr = pwndbg.symbol.address("largebin_size")
largebin_size = allocator._request2size(pwndbg.memory.u64(addr))
addr = pwndbg.symbol.address("largebin_count")
largebin_count = pwndbg.memory.u64(addr)
result = allocator.tcachebins()
assert result["type"] == "tcachebins"
assert tcache_size in result
assert result[tcache_size][1] == 0 and len(result[tcache_size][0]) == 1
result = allocator.fastbins()
assert result["type"] == "fastbins"
assert fastbin_size in result
assert len(result[fastbin_size]) == 1
result = allocator.unsortedbin()
assert result["type"] == "unsortedbin"
assert len(result["all"][0]) == 1
assert not result["all"][2]
result = allocator.smallbins()
assert result["type"] == "smallbins"
assert smallbin_size in result
assert len(result[smallbin_size][0]) == 1 and len(result[smallbin_size][1]) == 1
assert not result[smallbin_size][2]
result = allocator.largebins()
assert result["type"] == "largebins"
largebin_size = list(result.items())[allocator.largebin_index(largebin_size) - 64][0]
assert largebin_size in result
assert len(result[largebin_size][0]) == 1 and len(result[largebin_size][1]) == 1
assert not result[largebin_size][2]
# check tcache
gdb.execute("continue")
result = allocator.tcachebins()
assert result["type"] == "tcachebins"
assert tcache_size in result
assert (
result[tcache_size][1] == tcache_count and len(result[tcache_size][0]) == tcache_count + 1
)
for addr in result[tcache_size][0][:-1]:
assert pwndbg.vmmap.find(addr)
# check fastbin
gdb.execute("continue")
result = allocator.fastbins()
assert result["type"] == "fastbins"
assert (fastbin_size in result) and (len(result[fastbin_size]) == fastbin_count + 1)
for addr in result[fastbin_size][:-1]:
assert pwndbg.vmmap.find(addr)
# check unsortedbin
gdb.execute("continue")
result = allocator.unsortedbin()
assert result["type"] == "unsortedbin"
assert (
len(result["all"][0]) == smallbin_count + 2 and len(result["all"][1]) == smallbin_count + 2
)
assert not result["all"][2]
for addr in result["all"][0][:-1]:
assert pwndbg.vmmap.find(addr)
for addr in result["all"][1][:-1]:
assert pwndbg.vmmap.find(addr)
# check smallbins
gdb.execute("continue")
result = allocator.smallbins()
assert result["type"] == "smallbins"
assert (
len(result[smallbin_size][0]) == smallbin_count + 2
and len(result[smallbin_size][1]) == smallbin_count + 2
)
assert not result[smallbin_size][2]
for addr in result[smallbin_size][0][:-1]:
assert pwndbg.vmmap.find(addr)
for addr in result[smallbin_size][1][:-1]:
assert pwndbg.vmmap.find(addr)
# check largebins
gdb.execute("continue")
result = allocator.largebins()
assert result["type"] == "largebins"
assert (
len(result[largebin_size][0]) == largebin_count + 2
and len(result[largebin_size][1]) == largebin_count + 2
)
assert not result[largebin_size][2]
for addr in result[largebin_size][0][:-1]:
assert pwndbg.vmmap.find(addr)
for addr in result[largebin_size][1][:-1]:
assert pwndbg.vmmap.find(addr)
# check corrupted
gdb.execute("continue")
result = allocator.smallbins()
assert result["type"] == "smallbins"
assert result[smallbin_size][2]
result = allocator.largebins()
assert result["type"] == "largebins"
assert result[largebin_size][2]