vtable位于/libio/vtables.c
,通过该表就能够找到IO_WFILE_JUMPS
和_IO_file_jumps
之间的偏移
位于/libcio/libcio.h
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. */
__mbstate_t _IO_state; ///8 字节
__mbstate_t _IO_last_state; /// 8字节
struct _IO_codecvt _codecvt; //124字节
wchar_t _shortbuf[1]; //4字节 padding
const struct _IO_jump_t *_wide_vtable; ///offset为0xe
};
位于/libio/libioP.h
struct _IO_FILE_plus
{
FILE file;
const struct _IO_jump_t *vtable;
};
typedef struct _IO_FILE FILE;
然后FILE对应的是_IO_FILE 位于libio/bits/types/struct_FILE.h
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. */
unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[1];
_IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};
0x0:'_flags',
0x8:'_IO_read_ptr',
0x10:'_IO_read_end',
0x18:'_IO_read_base',
0x20:'_IO_write_base',
0x28:'_IO_write_ptr',
0x30:'_IO_write_end',
0x38:'_IO_buf_base',
0x40:'_IO_buf_end',
0x48:'_IO_save_base',
0x50:'_IO_backup_base',
0x58:'_IO_save_end',
0x60:'_markers',
0x68:'_chain',
0x70:'_fileno',
0x74:'_flags2',
0x78:'_old_offset',
0x80:'_cur_column',
0x82:'_vtable_offset',
0x83:'_shortbuf',
0x88:'_lock',
0x90:'_offset',
0x98:'_codecvt',
0xa0:'_wide_data',
0xa8:'_freeres_list',
0xb0:'_freeres_buf',
0xb8:'__pad5',
0xc0:'_mode',
0xc4:'_unused2',
0xd8:'vtable'
对应的偏移
调用链条
_IO_wfile_overflow /libcio/wfileops.c
_IO_wdoallocbuf /libcio/wgenops.c
_IO_WDOALLOCATE
因此调用到io_overflow
之后去调用IO_wfile_overflow,要去触发IO_WFILE_JUMPS
中的函数指针,因为我们能够劫持wvatble
到堆上,此时需要满足条件
fp-> _flags &0x008 == 0
_IO_wfile_overflow
f->_wide_data->_IO_write_base == 0
_IO_wdoallocbuf
fp->_wide_data->_IO_buf_base = 0
fp-> _flags & 0x0002 ==0
IO_overflow
的条件/libio/vtables.c
中IO_wfile_jumps
和IO_file_jumps
对应的偏移,当然虚表可能并不在vtables.c
中IO_wfile_jumps
中要调用_IO_wfile_overflow
然后在该函数中去调用_IO_wdoallocbuf
然后再去调用_IO_WDOALLOCATE