题目分析
只有添加,显示,编辑三个功能,没有删除
添加函数,最多只能添加四次,每次添加会依次执行malloc(0x10),malloc(name_size),calloc(8),name_size最大为8
House结构体如下
struct Info{
int price;
int color;
}
struct House{
Info* info;
char* name;
}
在编辑函数中,可以重新输入长度进行堆溢出
编辑次数最多为3
利用原理
house of orange
根据题分析,本题是没有释放功能的,但是如果没有空闲的chunk我们难以获取libc地址,下面就介绍一种不需要释放就能得到unsored bin的办法
当我们申请一块内存时,malloc函数会检查各种bin,都不满足条件之后会检查top chunk是否满足,(由于本题的堆溢出使得我们可以修改topchunk的size),如果topchunk也不行,就需要调用sysmalloc来申请内存,而此时又分为brk 和 mmap两种方式
如果所需分配的 chunk 大小大于 mmap 分配阈值(默认为 128K,0x20000),就会调用mmap
所以我们分配的内存需要小于这个
然后来到下一个判断
assert((old_top == initial_top(av) && old_size == 0) ||
((unsigned long) (old_size) >= MINSIZE &&
prev_inuse(old_top) &&
((unsigned long)old_end & pagemask) == 0));
这里需要满足几个条件:
- topchunk size > MINSIZE(0x10)
- top chunk inuse位为1
- 修改之后的 size 必须要对齐到内存页
满足之后,top chunk就被free,从而进入unsorted bin
FSOP
在libc的_IO_list_all
中,存放有一个_IO_FILE_plus
结构体的指针,
如下图,它指向_IO_2_1_stderr_
:
而_IO_FILE_plus
结构体详细内容如下
其中_chain指向下一个_IO_FILE_plus
结构体
在malloc中,它调用malloc_printerr来打印错误,经过一系列调用,最终来到_IO_flush_all_lockp
:
while (fp != NULL)
{
…
fp = fp->_chain;
...
if (((fp->_mode <= 0 && fp->_IO_write_ptr