本文主要是linux下堆的数据结构及堆调试、堆溢出利用的一些基础知识
首先,linux下堆的数据结构如下
/* This struct declaration is misleading (but accurate and necessary). It declares a "view" into memory allowing access to necessary fields at known offsets from a given base. See explanation below. */ struct malloc_chunk { INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */ INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */ struct malloc_chunk* fd; /* double links -- used only if free. */ struct malloc_chunk* bk; /* Only used for large blocks: pointer to next larger size. */ struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */ struct malloc_chunk* bk_nextsize; };
以上内容摘自CTF-WIKI https://ctf-wiki.github.io/ctf-wiki/pwn/heap/heap_structure/#top-chunk
给出一个简单堆溢出的例子
#include <stdio.h> int main(void) { char *chunk; chunk=malloc(24); puts("Get input:"); gets(chunk); return 0; }
gcc -no-pie -p example1 example1.c编译程序
objdump -d example1查看main函数地址,然后gdb在main函数起始位置下断点。
当执行到0x400589时查看rax内容即为malloc分配堆的起始地址。
执行完0x405a5时 x/10x 0x602250用‘A‘*100覆盖堆查看堆溢出情况(Gdb指令查看手册https://darkdust.net/files/GDB%20Cheat%20Sheet.pdf)
这里查看0x602250的原因是INTERNAL_SIZE_T默认和size_t一致,32位系统下size_t 4字节,64位系统下size_t 8字节。malloc返回的堆地址指针实际是 struct malloc_chunk* fd的fd,所以64位系统下查看堆首需要用返回的堆地址减去16字节的堆头。
我们在重新看一下堆覆盖之前的堆内容
size部分的最后三个字节分别表示特定含义(见上数据结构),用户真正可用的堆地址是0X602260-0X60226F,共32字节。申请24字节分配32字节的原因是32位系统8字节对齐,64位16位对齐。
0X602270是top chunk的内容,top chunk是在第一次执行malloc时heap 会被分为两块,一块给用户,剩下的那块就是 top chunk。top chunk就是当前堆的物理地址最高chunk,这个chunk不属于任何bin。
未完待续。。。
原文:https://www.cnblogs.com/snip3r/p/9278238.html