首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

当我使用0作为FILE*从rop chain中的stdin读取时,为什么fgets失败?

在使用C语言进行文件操作时,FILE* 是一个指向 FILE 结构体的指针,它代表一个打开的文件流。通常,stdinstdoutstderr 是三个预定义的 FILE* 指针,分别代表标准输入、标准输出和标准错误。

当你尝试使用 fgets 函数从 stdin 读取数据时,如果传递了一个值为0(NULL)的 FILE* 指针,fgets 会失败,因为 fgets 需要一个有效的文件流指针来执行读操作。NULL 或0值表示没有有效的文件流,因此无法进行读取。

fgets 函数的原型如下:

代码语言:txt
复制
char *fgets(char *str, int n, FILE *stream);
  • str 是一个字符数组,用于存储从文件流中读取的数据。
  • n 是要读取的最大字符数(包括空字符)。
  • stream 是指向 FILE 结构体的指针,表示要读取的文件流。

如果 fgets 失败,它将返回 NULL。这通常是因为遇到了文件结束标志(EOF)、发生了读取错误,或者传递了一个无效的 FILE* 指针。

在你的情况中,如果你从ROP链中使用0作为 FILE* 来调用 fgets,失败的原因是因为你传递了一个无效的文件流指针。ROP(Return-Oriented Programming)是一种攻击技术,它依赖于程序中的现有代码片段来构造恶意代码序列。在这种情况下,确保传递给 fgetsFILE* 指针是有效的至关重要。

解决这个问题的方法是确保在调用 fgets 之前,stdin 已经被正确打开,并且没有被意外地关闭或重定向到一个无效的状态。如果你在ROP链中操作,确保在尝试读取之前,stdin 的状态是预期的。

如果你在使用 fgets 时遇到问题,可以检查以下几点:

  1. 确保 stdin 没有被关闭。
  2. 确保没有其他代码片段重定向了 stdin
  3. 如果你在构造ROP链,确保在调用 fgets 之前,相关的文件流指针已经被正确设置。

参考链接:

请注意,处理文件流和输入输出时,始终要小心,确保所有操作都是安全的,特别是在涉及潜在的安全风险如ROP攻击时。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

rop练习--split

用rabin2 -I 来查看程序架构等信息,其实用file就可以。 ? 用rabin2 -izz 来查找信息,用strings也是可以。 ? 然后用checksec查看一下防护措施: ?...很明显s数组是0x20大小,而后面的fgets却接受了96大小数据。 usefulFunction函数: ? 竟然还有这种函数,好吧,我是看腾讯玄武每日推送打开这篇文章。。。...rop步骤: 利用fgets()来填充buffer,将返回地址覆盖为pwnme地址 建立rop链把’/bin/cat flag.txt’传入RDI寄存器 调用system() exp.py # coding...:0x20+8(rbp)=0x28=40个偏移 info("pattern: %r", pattern) info("offset: %d",offset) rop_chain = p64(pop_rdi_ret...) rop_chain += p64(cat_addr) rop_chain += p64(system_addr) rop_chain += p64(fake_ret) padding = cyclic

85440

gets 、getchar 、fgets 、scanf用法

3.fgets   文件或标准输入接收一串字符,遇到’\n’结束,把’\n’也作为一个字符接收;把接收一串字符存储在形式参数指针指向空间,并在’\n’后再自动添加一个’\0’。...5.fgets用法 原型:fgets(buf,sizeof(s),stdin) 功能:目标文件流 file 读取 n-1 个字符,放入以 buf 起始地址内存空间中。...我们知道,对于 gets 函数,它任务是 stdin读取字符串,直至接收到换行符或 EOF 停止,并将读取结果存放在 buffer 指针所指向字符数组。...如果是键盘上读入数据,可以使用 stdin 作为该参数,如下面的代码所示: int main(void) { char buffer[11]; fgets(buffer,11,stdin); printf...stdin是标准输入(也就是键盘输入),C标准库里面的一个全局变量stdin也是FILE*类型,因此在使用FILE*类型作为参数地方,可以使用stdin*/ printf("%s\n%s\n",str1

3.1K60
  • fscanf读取一行字符串-C语言文件流(字节流) IO 操作(二) —— 初识“流”以及文件顺序读写(f

    按照处理数据单位不同,可以分为字节流、字符流;按照数据流方向不同,可以分为输入流(外设读取信息)、输出流(向外设输出信息)。   2、 为什么会有“流”概念?   ...fgetc 函数声明如下:   第一个参数:任意输入流,文件流或者标准输入流(即文件指针或者stdin)   返回值:调用成功返回读取字符ASCII码,调用失败或者到达文件尾返回EOF   .../ fputs) (1) fgets 函数   fgets 作用是流或者标准输入(键盘)获取多个字符。...fgets 函数声明如下:   第一个参数:存储读取字符串   第二个参数:要读取字符个数   第三个参数:任意输入流,文件流或者标准输入流(即文件指针或者stdin)   返回值:读取成功则返回读取字符串地址...值得注意是,如果存在多行, 调用 fgets 读取读取完第一行所有字符,才会转到第二行开始读取,并不是 每调用一次 fgets 就换一行。

    1.4K30

    C 标准库基础 IO 操作总结

    FILE* 这样文件指针称为句柄(Handle)。 打开文件操作是对文件资源进行操作,所以有可能打开文件失败,所以在打开函数一定要判断返回值,如果失败则返回错误信息,以方便快速定位错误。...定义全局变量,在 stdio.h 声明,printf 向 stdout 写,而 scanf stdin 读,用户程序也可以直接使用这三个文件指针。...不过 strcpy 程序员还是可以避免,而 gets 输入用户可以提供任意长字符串,唯一避免方法就是不使用 gets,而使用 fgets(buf, size, stdin) fgets 函数 stream...如果文件一行太长,fgets 文件读了 size-1 个字符还没有读到 ‘\n’,就把已经读到 size-1 个字符和一个 ‘\0’ 字符存入缓冲区,文件行剩余内容可以在下次调用 fgets 继续读...或行缓冲文件读取,且这次读操作会引发系统调用内核读取数据,那么会读之前自动 flush 所有行缓冲 程序退出通常也会自动 flush 缓冲区 如果不想完全依赖自动 flush 操作,可以调用

    97130

    文件顺序读写——顺序读写函数——fgets、fgetc、fputs、 fputc

    一、fgetc和fputc函数 1.1 fputc 返回类型int: 如果成功读取字符,返回是字符ASCII码值——char 如果读取失败或者遇文件末尾,则返回EOF(-1) ——int 为了统一...该函数指定地址 (str) 开始复制,直到到达终止 null 字符 ('\0')。此终止 null 字符不会复制到流。...num:要复制到 str 最大字符数(包括终止 null 字符)。 stream流: 指向标识输入流 FILE 对象指针。 stdin 可以用作标准输入读取参数。...注意: 读取字符,并将它们作为字符串存储到 str ,直到读取 (num-1) 个字符(第num个字符会被自动读成‘\0’)或到达换行符或文件末尾,以先发生者为准。...换行符‘\n’ 使 fgets 停止读取,但它被函数视为有效字符,并包含在复制字符串。 空字符会自动附加到 str 字符之后。

    10310

    【C】语言文件操作(一)

    内容, 剩下内容将放到【C】语言文件操作 (二)中介绍 1.为什么使用文件 使用文件可以将数据直接存放在电脑硬盘上,使数据持久化。...fgets文本行输入函数 fgets fgets读取内容时会将终止符\0认为是其中内容,实际读取是num-1个元素,剩下一个为\0。...下一次读取之前读取结束位置开始 如果读取正常,返回是存放读取数据地址 如果读取失败,返回NULL char * fgets ( char * str, int num, FILE...是数据 文件流以一定格式读取数据 如果读取正常,返回是格式串中指定数据个数 如果读取失败,返回是小于格式串中指定数据个数 struct S { char name[20]; int...- 屏幕 这三个流类型是FILE*类型,就有一个FILE*指针与流对应 那么当键盘输入数据就传stdin ,当屏幕输出数据时候就传stdout。

    24020

    C语言进阶-文件操作超详解

    目录 为什么使用文件 什么是文件 分类(文件功能角度) 文件名 文件打开和关闭 文件指针 fopen和fclose函数 打开方式表 文件顺序读写 顺序读写函数表 什么是输入输出流 fgetc/fgetc...文件读取结束判断 feof函数 ferror函数 读取结束判断方向  文件缓冲区 ---- 前言 ----  本章主要讲解: 掌握C语言文件操作和使用 文件操作各种函数基本使用 为什么使用文件...int fputs( const char *string, FILE *stream ); 注意: fgets函数功能为读取一个字符串到相应存储位置;第一个参数为获取到字符串存储位置.../打印出读取字符串 fclose(pf); pf = NULL; return 0; } 特别注意: fgets(str, stdin)==gets(str); fputs(str,...,所谓缓冲文件系统是指系统自动地在内存为程序 每一个正在使用文件开辟一块“ 文件缓冲区 ” 内存向磁盘输出数据会先送到内存缓冲区,装满缓冲区后才一起送到磁盘上。

    99920

    【C】文件操作

    由上面我们可以看到r+在写并不清空已有的内容, 但是会文件开头开始写, 写入内容会覆盖已有内容. r, w, a, b, + 解释 mode一般由上面5个字符组成, 有些可能还会使用t, 下面是该它们含义...stdin) #define getc(__stream) fgetc(__stream) fgets 该函数原型为: char * fgets ( char * str, int num, FILE...* stream ); fgetsstream读取内容到str, 当满足下面任意一个条件完成读取操作: 读取了num-1个字符 读到了换行符(newline character) 读到了文件结尾...读取完成后会在str后面追加上 终止null字符 (即\0), 这也是第一条为什么只读 num-1 个字符原因. 函数返回值是一个指向str指针....(回车)作为读取完成标志, 下面是该函数原型 char * gets ( char * str ); 下面是一个使用示例: void test_gets() { char string [256

    59410

    C语言:文件操作

    为什么使用文件 如果没有⽂件,我们写程序数据是存储在电脑内存,如果程序退出,内存回收,数据就丢失了,等再次运⾏程序,是看不到上次程序数据,如果要将数据进⾏持久化保存,我们可以使⽤⽂件,因为文件是存放在硬盘上...那是因为C语⾔程序在启动时候,默认打开了3个流: stdin -- 标准输⼊流,在⼤多数环境键盘输⼊,scanf函数就是标准输⼊流读取数据。...} fgetc函数示范(读字符) 读取正常时候,返回读取字符ASCII码值 读取失败时候,返回EOF EOF是一个文件结束标志 下面这个代码我们可以看到文件里读取了5个字符。...函数示范(读字符串) 这个函数是文件里,读取字符串出来 下面这代码,我们要读取3个字符,我们可以看到实际上只读取了2个字符,编译器会在后面加个\0 下面这个代码,没有读取到w,这是为什么呢,因为这个函数是文本行读取...,定位文件指针,SEEK_SET文件开头向后偏移了6,读取了后面的3个hhh 光标位置偏移 当我读取了a和b光标会在b后面,定位文件指针,SEEK_CUR光标的位置向后面偏移4个,读取了后面的

    12410

    流动代码:文件流畅读写艺术(二)文件顺序读写函数

    } fgets和fputs fgets用于文件流读取字符串,其原型如下: char *fgets(char *str, int num, FILE *stream); char *str: 指向用于接收读取数据字符数组指针...fgets 函数会指定文件流 stream 读取字符,直到发生以下几种情况之一: 读取了 num - 1 个字符。 遇到换行符 \n,换行符也会被读取并存入字符串。...r"); if (file == NULL) { perror("fopen"); return -1; } // 使用fgets文件读取一行...成功,函数返回非负值;失败,返回 EOF 需要注意是,fputs 函数不会为你自动添加换行符 \n,如果需要新一行开始,则你需要显式地在字符串包含 \n。...会尝试按照指定格式文件流读取数据,并将读取数据存储在提供地址上。

    12310

    初识C语言·文件操作

    当我们运行程序时候,程序一旦结束,在内存存储数据也会被销毁,我们如果想要保存数据,以方便下一次使用的话,就需要用到文件,也就是说,文件是可以用来保存数据。 那什么是文件呢?...,就只会占4个字节,如果是ASCII码值形式存储,那么就会占5个字节,1占一个字节,其余每个0占一个字节 00000000 00000000 00100111 00010000 当我使用二进制存储时候...fgets和gets函数是非常不像fgets函数有三个参数: char * fgets ( char * str, int num, FILE * stream ); fgets函数会流里面读取num...都可以做,fprintf同理,fscanf就比scanf多了一个参数,fscanf是文件读取数据,如果第一个参数是stdin,也就是标准输入流的话,就是键盘里面输入数据了,fprintf同理可得,...", ch); fclose(pf); pf = NULL; return 0; } 这就是文件里面读取数据,如果我们想要从键盘读取,只需把流换成stdin就行了,那么这是读文件操作

    7210

    CC++ (stdio.h)标准库详解

    使用在 printf 上使用 format 打印相同文本组成一个字符串,但使用 arg 标识变量参数列表元素而不是其他函数参数,并将生成内容作为 C 字符串存储在由 s 指向缓冲区(将...上使用 format 打印相同文本组成一个字符串,但使用 arg 标识变量参数列表元素而不是其他函数参数,并将生成内容作为 C 字符串存储在 s 指向缓冲区。...char * fgets ( char * str, int num, FILE * stream ); 规则: 读取字符,并将它们作为 C 字符串存储到 str ,直到读取 (num-1...,stdin可以用作标准输入读取参数 返回值: 成功:该函数返回 str 失败:返回NULL /* fgets example */ #include int...然后使用 fopen 函数以只读模式打开名为 "example.txt" 文件,如果打开失败则输出错误信息。接着使用 fgets 函数文件读取内容到 buffer,并输出到控制台。

    73010

    CCPP输入输出函数汇总分析

    ()了. getchar() int getchar(void) getchar主要是标准输入流读取一个字符.默认标准输入流即stdio.h定义stdin.但是输入流读取字符又 涉及到缓冲问题...它语法如下: int getc( FILE *stream ); 它接受一个文件指针作为参数,并返回读取字符ASCII码值。如果在读取到末尾返回EOF。...它等价于调用 getc(stdin)。如果读取成功,它返回读取字符整数值;如果读取失败,它返回 EOF。...该函数语法如下: char *fgets(char *str, int n, FILE *stream); 其中: str是指向要读取字符串指针。 n是指要读取字符数,包括’\0’。...所指取1行字符-标准输入流(由fp=stdin所指) 原因:同上; 补充:不推荐使用,问题是调用者在使用gets,不能指定缓冲区buf(用户进程)长度,这样可能造成缓冲区溢出。

    1.8K20

    【C语言】文件操作

    一、什么是文件 在程序设计,我们一般谈文件有两种:程序文件、数据文件(文件功能角度来分类)。 1....} 四、流概念 当我们需要写数据到文件,屏幕,网络等等这种外部设备,对于程序员来说要求太高了,所以抽象出一种 ‘流’ 概念,程序员只需要把数据写到’ 流 '里面去,至于‘流’数据如何传到外部设备...stderr 代码演示: int main() { //标准输入流读取数据 int ch = fgetc(stdin); printf("%c\n", ch);...而是应用于当文件读取结束时候,判断是读取失败结束,还是遇到文件尾结束。...如果磁盘向计算机读入数据,则从磁盘文件读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。

    10510

    【C进阶】—— 一篇文章带你学会C语言文件操作

    我们再来看一下fgetc 返回值: 它在读取失败或者读到文件末尾都会返回EOF,那我们是不是可以利用这一点写一个循环。...那fgets 作用其实就是将目标文件num个字符作为字符串拷贝到str 指向数组。...:FILE * 那么: 如果我们想使用fgetc键盘获取一个字符,只需把stdin作为参数传给fgetc就行了。...而是应用于当文件读取结束时候,判断是读取失败导致结束,还是遇到文件尾结束。 feof 只有一个参数,接收一个文件指针,判读该文件读取结束是由于哪种原因导致结束。...当我使用fflush强制刷新缓冲区后,才将输出缓冲区数据写到文件(磁盘),然后文件才有内容。

    22010

    【Linux】基础IO——系统文件IO&fd&重定向&理解

    fprintf+w: fgets+r fgets会给字符串结尾添加\0 运行结果和文件内容每行都多出了一行,这是因为在读取时候按行打印,把\n多读了,所以我们可以处理一下\n: a追加 对于...* 所以,我们可以查看到stdin,stout,stderr里面对应值是多少: 这就很好解答了为什么open返回值是3开始问题!...因为0,1,2默认被占用,我们C语言封装了接口,同时也封装了操作系统内文件描述符。 此外,数字为什么0,1,2连续整数,文件描述符本质是什么?...这也就很好结社了为什么打开文件返回值为3,打开文件内核会描述struct file结构,把对应地址填充到struct file*fd_array[]数组下标中去,又因为0,1,2,默认会被占用,于是...: 我们所谓关闭文件只是在表明用户给OS说已经不需要使用了,由OS决定,OS把引用计数减到0,才被OS真正删除掉。

    51220

    【C语言】看了这篇文章,如果你还不会文件操作的话,我把这篇文章给吃了(doge)

    文本文件→ 二进制文件→ 讲解desu ​​​​​​​文件读取结束判定​​​​​​​ 错误使用 feof()  文件缓冲区 最后  ---- 为什么使用文件 首先来说下为什么使用文件操作吧,在前面的内容写过一篇通讯录文章...} ---- fgets()读取"字符串" fgets() → 读取"字符串"。...fgets() 函数声明方式如下↓ char * fgets ( char * str, int num, FILE * stream ); str→指向一个字符数组指针,在这个数组读取字符串将被复制...stream → 指向标识输入流FILE对象指针。Stdin可以作为标准输入读取参数。...对于二进制流,这是文件开始字节数。 对于文本流,数值可能没有意义,但仍然可以使用fseek将位置恢复到相同位置(如果使用ungetc返回字符在被读取仍然挂起,该行为是未定义)。

    83220

    【c语言】详解文件操作(二)

    ; } 此循环含义便是,每次pf指向文件读取三个类型变量到a, arr, f,每成功读取一次fscanf便会返回3,此循环便会继续,直至读取结束返回值不再为3,以此达到遍历文件数据。..., size_t count, FILE * stream ); fread函数stream指向读取个数为count大小为size元素到ptr。...举个这两个函数实用例子,当我们写通讯录,存储联系人信息到文件,文件读取上次存储联系人信息便可使用此函数,如下: //导出之前存储数据 void ContactLocate(Contact*...: long int ftell ( FILE * stream ); 如果成功使用便会返回文件指针相当于文件起始位置(即SEEK_SET)偏移量,如果函数使用失败便会返回-1。...同时我们还要知道:读取文本判断是否结束,fgetc看返回值是否为EOF, fgets看返回值是否为NULL。二进制文件判断读取结束,看实际读取个数是否小于要求读取个数。

    12610

    文件操作——C语言

    这是因为C语言程序在启动时候,就默认打开了3个流: stdin -- 标准输入流,在大多数环境键盘上输入,scanf 函数就是标准输入流读取数据。...fgets fgets函数参数有三个,一个是str ,它是读取完数据要存放到内存块首地址; num是要读取字符个数;stream就是文件指针 这里我们test.txt文件读取...= NULL; return 0; } 我们看到,读取10个字符,输出却只有9个字符,只是因为,fgets读取过程读取num-1个字符,在第num个位置会自动添加 '\0'...fscanf标准流读取数据 int main() { int a = 0; fscanf(stdin, "%d", &a); return 0; } stdin -- 标准流,用fscanf...ftell: 当我们在访问文件时候,不知道文件访问光标访问到哪里了,就可以使用ftell,这个函数返回文件指针相对于其实位置偏移量。

    10710
    领券