使用了largebin attack+house of apple2 攻击2.35的题目没有出现什么问题,但是在2.39的时候出现了问题,于是研究了一下两个libc的汇编代码(题目给的),发现2.39和2.35关于house of apple2还是有一点点微不足道的区别的
IO结构体
struct_IO_FILE { int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
/* The following pointers correspond to the C++ streambuf protocol. */ char *_IO_read_ptr; /* Current read pointer */ char *_IO_read_end; /* End of get area. */ char *_IO_read_base; /* Start of putback+get area. */ char *_IO_write_base; /* Start of put area. */ char *_IO_write_ptr; /* Current put pointer. */ char *_IO_write_end; /* End of put area. */ char *_IO_buf_base; /* Start of reserve area. */ char *_IO_buf_end; /* End of reserve area. */
/* The following fields are used to support backing up and undo. */ char *_IO_save_base; /* Pointer to start of non-current get area. */ char *_IO_backup_base; /* Pointer to first valid character of backup area */ char *_IO_save_end; /* Pointer to end of non-current get area. */
struct_IO_marker *_markers;
struct_IO_FILE *_chain;
int _fileno; int _flags2; __off_t _old_offset; /* This used to be _offset but it's too small. */
/* 1+column number of pbase(); 0 is unknown. */ unsignedshort _cur_column; signedchar _vtable_offset; char _shortbuf[1];
_IO_lock_t *_lock; };
struct_IO_FILE_complete { struct_IO_FILE _file; #endif __off64_t _offset; /* Wide character stream stuff. */ struct_IO_codecvt *_codecvt; struct_IO_wide_data *_wide_data; struct_IO_FILE *_freeres_list; void *_freeres_buf; size_t __pad5; int _mode; /* Make sure we don't get into trouble again. */ char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; };
struct_IO_wide_data { wchar_t *_IO_read_ptr; /* Current read pointer */ wchar_t *_IO_read_end; /* End of get area. */ wchar_t *_IO_read_base; /* Start of putback+get area. */ wchar_t *_IO_write_base; /* Start of put area. */ wchar_t *_IO_write_ptr; /* Current put pointer. */ wchar_t *_IO_write_end; /* End of put area. */ wchar_t *_IO_buf_base; /* Start of reserve area. */ wchar_t *_IO_buf_end; /* End of reserve area. */ /* The following fields are used to support backing up and undo. */ wchar_t *_IO_save_base; /* Pointer to start of non-current get area. */ wchar_t *_IO_backup_base; /* Pointer to first valid character of backup area */ wchar_t *_IO_save_end; /* Pointer to end of non-current get area. */
首先看后面三句,我们把f结构体后面又新增了两个内容,那么wide_vtable_addr的设置也就可以理解了,heap_5+0xd8+8+8正好是system的地址(heap+0xd8是vtable字段,再+8是wide_vtable_addr,再+8j就是system的字段),那么-0x68就是因为_wide_data->_wide_vtable->doallocate 设置为地址 C 用于劫持 RIP,即满足 *(B + 0x68) = C