IO_FILE

admin 2022年7月31日23:01:16评论1 views字数 3151阅读10分30秒阅读模式

 

IO_FILE
深入理解FILE

Linux程序中每创建一个文件对象,都会为这个对象生成一个_IO_FILE_plus结构体(这个结构体是_IO_FILE的加强版)所有文件共享一个函数表,_IO_jump_t *vtable指向这个函数表
源代码如下:

struct _IO_FILE_plus

{

   _IO_FILE    file;

   IO_jump_t   *vtable;

}

 

我们一个一个的来看一下,首先是这个结构体里面的_IO_FILE,他也是个结构体,命名为了file,在libio.h里

源码如下:

 

struct_IO_FILE {

int_flags; /* 高字节是 _IO_MAGIC; 剩下是 flags. */

#define_IO_file_flags _flags

 

/* 下面的指针对应于c++ streambuf协议。*/

/* 注意:Tk直接使用_IO_read_ptr和_IO_read_end字段。*/

char* _IO_read_ptr; /* 当前读取指针 */

char* _IO_read_end; /* 获取区域的末尾。*/

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; /* 保留区的起点。*/

char* _IO_buf_end;  /* 保留区末尾。*/

/* 以下窗口项用于支持备份和撤消。*/

char *_IO_save_base; /* 指向非当前get区域开始的指针。*/

char *_IO_backup_base; /* 指向备份区第一个有效字符的指针 */

char *_IO_save_end; /* 指向非当前get区域结尾的指针 */

 

struct_IO_marker *_markers;

 

struct_IO_FILE *_chain;

 

int_fileno;

int_blksize;

_IO_off_t_old_offset; /* 这个曾经是_offset但是太小了 */

 

#define__HAVE_COLUMN /* 暂时的 */

/* 1+pbase()的列数;0未知。*/

unsignedshort_cur_column;

signedchar_vtable_offset;

char_shortbuf[1];

 

/* char* _save_gptr; char* _save_egptr; */

 

_IO_lock_t *_lock;

#ifdef _IO_USE_OLD_IO_FILE

};

然后是这个结构体里面的 IO_jump_t,他也是个结构体,是 *vtable指针,在libioP.h里

源码如下:

struct_IO_jump_t

{

JUMP_FIELD(_G_size_t, __dummy);

#ifdef _G_USING_THUNKS

JUMP_FIELD(_G_size_t, __dummy2);

#endif

JUMP_FIELD(_IO_finish_t, __finish);

JUMP_FIELD(_IO_overflow_t, __overflow);

JUMP_FIELD(_IO_underflow_t, __underflow);

JUMP_FIELD(_IO_underflow_t, __uflow);

JUMP_FIELD(_IO_pbackfail_t, __pbackfail);

/* showmany */

JUMP_FIELD(_IO_xsputn_t, __xsputn);

JUMP_FIELD(_IO_xsgetn_t, __xsgetn);

JUMP_FIELD(_IO_seekoff_t, __seekoff);

JUMP_FIELD(_IO_seekpos_t, __seekpos);

JUMP_FIELD(_IO_setbuf_t, __setbuf);

JUMP_FIELD(_IO_sync_t, __sync);

JUMP_FIELD(_IO_doallocate_t, __doallocate);

JUMP_FIELD(_IO_read_t, __read);

JUMP_FIELD(_IO_write_t, __write);

JUMP_FIELD(_IO_seek_t, __seek);

JUMP_FIELD(_IO_close_t, __close);

JUMP_FIELD(_IO_stat_t, __stat);

JUMP_FIELD(_IO_showmanyc_t, __showmanyc);

JUMP_FIELD(_IO_imbue_t, __imbue);

#if0

get_column;

set_column;

#endif

};

在标准的I/O库中,程序运行就会加载3个文件流stdin、stdout、stderr,分别是标准输入,标准输出,标准错误。文件描述符分别是0,1,2,因此在初始状态下,_IO_list_all 指向了一个有这些文件流构成的链表,但是需要注意的是这三个文件流位于 libc.so 的数据段。而我们使用 fopen 创建的文件流是分配在堆内存上的。进程中的 FILE 结构会通过chain 域彼此连接形成一个链表,表头为__IO_list_all。然后我们单独拿出一个file结构体,比如stdout,stdout被命名为__IO_2_1_stdout_,这个结构体就是上面说的_IO_FILE_plus封装的,所以包含了_IO_FILE    file和 IO_jump_t   *vtable;

其中vtable 是 IO_jump_t 类型的指针,IO_jump_t 中保存了一些函数指针

我们需要关注的是vtable = 0x7fxxxxxxxxxxxxxx <_IO_file_jumps>

IO_jump_t表结构及对应函数

fread->_IO_XSGETN

fwrite->_IO_XSPUTN

fopen->malloc a new file struct->make file vtable->initialization file struct->puts initialzation file in file struct

fclose ->_IO_unlink_it->_IO_file_close_it->_IO_file_finish(_IO_FINISH)

为什么需要关注这个的原因就是程序执行exit后会关闭文件描述符,这样就会执行一系列的函数

IO_FILE

如果我们能劫持fp指针,然后构造一个假的_IO_FILE结构和一个假的_IO_jump_t结构,就可以控制程序流了。

当新建立FILE结构会调用_IO_file_init 进一步初始化操作:

_IO_JUMPS (&new_f->fp) = &_IO_file_jumps;

_IO_file_init (&new_f->fp);

在_IO_file_init 函数的初始化操作中,会调用_IO_link_in 把新分配的 FILE 链入_IO_list_all 为起始的 FILE 链表中

void

_IO_link_in (fp)

    struct _IO_FILE_plus *fp;

{

   if ((fp->file._flags & _IO_LINKED) == 0)

   {

     fp->file._flags |= _IO_LINKED;

     fp->file._chain = (_IO_FILE *) _IO_list_all;

     _IO_list_all = fp;

     ++_IO_list_all_stamp;

   }

}

 

 

 

原文始发于微信公众号(由由学习吧):IO_FILE

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年7月31日23:01:16
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   IO_FILEhttps://cn-sec.com/archives/1213655.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息