IO_FILE-fread函数详解

August 2, 2019 PWN 访问: 40 次

#include<stdio.h>
int main()
{
    char *a;
    FILE *file_point = fopen("test.txt","r");
    fread(a,1,12,file_point);
    char *heap_point = malloc(0x20);
    printf("%s",a);
    return 0;
}

同样是带glibc源码进行调试
main函数下断点:

In file: /root/test/123.c
    1 #include<stdio.h>
    2 int main()
    3 {
    4     char *a;
    5     FILE *file_point = fopen("test.txt","r");
 ►  6     fread(a,1,12,file_point);
    7     char *heap_point = malloc(0x20);
    8     printf("%s",a);
    9     return 0;
   10 }

s单步步入

In file: /root/glibc-2.23/libio/iofread.c
   26
   27 #include "libioP.h"
   28
   29 _IO_size_t
   30 _IO_fread (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp)
 ► 31 {
   32   _IO_size_t bytes_requested = size * count;
   33   _IO_size_t bytes_read;
   34   CHECK_FILE (fp, 0);
   35   if (bytes_requested == 0)
   36     return 0;

iofread.c源码如下

#include "libioP.h"
_IO_size_t
_IO_fread (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp)
{
  _IO_size_t bytes_requested = size * count;
  _IO_size_t bytes_read;
  CHECK_FILE (fp, 0);
  if (bytes_requested == 0)
    return 0;
  _IO_acquire_lock (fp);
  bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested);
  _IO_release_lock (fp);
  return bytes_requested == bytes_read ? count : bytes_read / size;
}
libc_hidden_def (_IO_fread)
#ifdef weak_alias
weak_alias (_IO_fread, fread)
# ifndef _IO_MTSAFE_IO
strong_alias (_IO_fread, __fread_unlocked)
libc_hidden_def (__fread_unlocked)
weak_alias (_IO_fread, fread_unlocked)
# endif
#endif

首先计算要读取的字节数_IO_size_t bytes_requested = size * count; ,然后判断是否为0,如果是0的话,就return 0,然后调用_IO_sgetn函数,单步步入发现_IO_sgetn内部其实是调用了_IO_XSGETN函数

_IO_size_t
_IO_sgetn (_IO_FILE *fp, void *data, _IO_size_t n)
{
  /* FIXME handle putback buffer here! */
  return _IO_XSGETN (fp, data, n);
}

查看_IO_XSGETN函数的定义,其实是调用了vtable表中的__xsgetn字段

#define _IO_XSGETN(FP, DATA, N) JUMP2 (__xsgetn, FP, DATA, N)

添加新评论