vtable位于/libio/vtables.c ,通过该表就能够找到IO_WFILE_JUMPS_IO_file_jumps 之间的偏移

IO_wide_data

位于/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
};

IO_FILE_plus

位于/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

调试偏移寻址

  1. 找到调用exit函数调用IO_overflow 的条件
  2. 找到/libio/vtables.cIO_wfile_jumpsIO_file_jumps 对应的偏移,当然虚表可能并不在vtables.c
  3. 找到IO_wfile_jumps中要调用_IO_wfile_overflow 然后在该函数中去调用_IO_wdoallocbuf 然后再去调用_IO_WDOALLOCATE