当前位置: 首页 > news >正文

CTF-PWN: 什么是_IO_FILE?

重要概念:fopen()返回的是一个结构体的指针

_IO_FILE 结构体在什么时候被创建?

_IO_FILE 结构体的实例是在程序使用标准 I/O 函数(如 fopenfclosefreadfwrite 等)时创建和管理的。这个结构体实际上是 GNU C Library (glibc) 用于处理文件流的底层实现细节。当你在程序中打开一个文件或者创建一个流时,glibc 会在后台分配和初始化一个 _IO_FILE 结构体,并返回一个指向它的指针(即 FILE* 类型)。

下面是一些常见场景,说明 _IO_FILE 结构体是如何被创建和使用的:

  1. 使用 fopen 打开文件
    当你调用 fopen 打开一个文件时,glibc 会分配一个 _IO_FILE 结构体并进行初始化。例如:

    FILE *file = fopen("example.txt", "r");
    

    在这个例子中,fopen 函数会创建一个 _IO_FILE 结构体实例来管理 example.txt 文件的读操作,并返回一个指向该结构体的指针 file

  2. 使用 fdopen 关联文件描述符和文件流
    如果你有一个现有的文件描述符,并希望将其与一个标准 I/O 流关联,可以使用 fdopen 函数:

    int fd = open("example.txt", O_RDONLY);
    FILE *file = fdopen(fd, "r");
    

    fdopen 会创建一个新的 _IO_FILE 结构体实例,并将文件描述符 fd 关联到这个结构体上。

  3. 标准输入输出
    标准输入(stdin)、标准输出(stdout)和标准错误(stderr)也是通过 _IO_FILE 结构体来管理的。它们在程序启动时由运行时库自动初始化。

    fprintf(stdout, "Hello, World!\n");
    

_IO_FILE 结构体的创建过程

当函数如 fopen 被调用时,glibc 内部会进行以下步骤:

  1. 分配内存
    glibc 会调用内存分配函数(如 malloc)为 _IO_FILE 结构体分配内存。

  2. 初始化结构体
    分配内存后,glibc 会初始化 _IO_FILE 结构体的各个字段。例如,它会设置缓冲区指针、文件描述符、文件模式等。

  3. 返回指针
    初始化完成后,glibc 会返回一个指向这个 _IO_FILE 结构体的指针,即 FILE* 类型的指针。

_IO_FILE 在文件流操作中的生命周期

  1. 创建
    当你使用标准 I/O 函数(如 fopenfdopen)打开或创建一个文件流时,glibc 会创建一个 _IO_FILE 结构体实例。

  2. 使用
    在文件流的生命周期内,所有对该文件流的读写操作(如 freadfwritefgetsfputs 等)都会通过这个 _IO_FILE 结构体来管理缓冲区、文件描述符和流的状态。

  3. 销毁
    当你调用 fclose 关闭文件流时,glibc 会执行以下操作:

    • 刷新缓冲区中的数据(如果有需要)。
    • 释放与文件流关联的资源(如缓冲区内存)。
    • 关闭文件描述符。
    • 最后,释放 _IO_FILE 结构体的内存。

示例代码

以下是一个简单的示例代码,展示了 _IO_FILE 结构体实例的创建和使用过程:

#include <stdio.h>int main() {// 打开文件,创建一个 _IO_FILE 结构体实例FILE *file = fopen("example.txt", "w");if (file == NULL) {perror("Failed to open file");return 1;}// 使用文件流进行写操作fprintf(file, "Hello, World!\n");// 关闭文件,销毁 _IO_FILE 结构体实例fclose(file);return 0;
}

在这个示例中,当调用 fopen 时,glibc 会创建并初始化一个 _IO_FILE 结构体实例。当调用 fclose 时,glibc 会销毁这个实例并释放相关资源。

_IO_FILE 结构体

在 Linux 系统中,_IO_FILE 结构体是 GNU C Library (glibc) 中实现标准 I/O (stdio) 的核心数据结构之一。它用于描述文件流(FILE*)的内部状态和缓冲区信息。理解 _IO_FILE 结构体对于某些高级的漏洞利用技术(如利用格式字符串漏洞或缓冲区溢出漏洞)非常重要。

以下是 _IO_FILE 结构体的一般布局(具体布局可能会随着 glibc 版本的不同而变化):

struct _IO_FILE {int _flags;                // 文件流的状态标志char* _IO_read_ptr;        // 缓冲区读取指针char* _IO_read_end;        // 缓冲区读取结束指针char* _IO_read_base;       // 缓冲区读取基地址char* _IO_write_base;      // 缓冲区写入基地址char* _IO_write_ptr;       // 缓冲区写入指针char* _IO_write_end;       // 缓冲区写入结束指针char* _IO_buf_base;        // 缓冲区基地址char* _IO_buf_end;         // 缓冲区结束地址char *_IO_save_base;       // 保存的缓冲区基地址char *_IO_backup_base;     // 备份的缓冲区基地址char *_IO_save_end;        // 保存的缓冲区结束地址struct _IO_marker *_markers; // 标记链表struct _IO_FILE *_chain;   // 文件流链表int _fileno;               // 文件描述符int _flags2;               // 额外的标志__off_t _old_offset;       // 旧的偏移量unsigned short _cur_column;// 当前列号signed char _vtable_offset;// 虚表偏移char _shortbuf[1];         // 短缓冲区_IO_lock_t *_lock;         // 锁__off64_t _offset;         // 偏移量void *__pad1;              // 填充void *__pad2;              // 填充void *__pad3;              // 填充void *__pad4;              // 填充size_t __pad5;             // 填充int _mode;                 // 模式char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];// 未使用的填充
};

关键字段

  • _flags: 用于描述文件流的状态标志,例如是否为读模式、写模式等。
  • _IO_read_ptr, _IO_read_end, _IO_read_base: 分别指向当前读取的位置、读取的结束位置和读取缓冲区的基地址。
  • _IO_write_base, _IO_write_ptr, _IO_write_end: 分别指向当前写入的位置、写入的结束位置和写入缓冲区的基地址。
  • _IO_buf_base, _IO_buf_end: 分别指向缓冲区的基地址和结束地址。
  • _IO_save_base, _IO_backup_base, _IO_save_end: 用于保存缓冲区状态的指针。
  • _markers: 指向标记结构的链表,用于支持多种流操作。
  • _chain: 指向下一个文件流的指针,形成一个文件流链表。
  • _fileno: 文件描述符。
  • _flags2: 额外的标志位。
  • _old_offset: 用于记录偏移量。
  • _cur_column: 当前列号,主要用于格式化输出。
  • _vtable_offset: 虚表偏移,用于支持面向对象的操作。
  • _shortbuf: 一个短缓冲区。
  • _lock: 指向用于同步的锁。
  • _offset: 文件流的位置偏移量。
  • 填充字段: 用于对齐和扩展。

stdinstdoutstderr指针

这些指针是程序的标准输入、标准输出和标准错误流(stdinstdoutstderr)在内存中的地址。它们是全局变量,通常在程序启动时被初始化,以指向相应的 FILE 结构体。

解释每个指针

  1. stdout (标准输出)

    • 地址:0x602020
    • 指向的地址:0x00007fe6e8e03620
  2. stdin (标准输入)

    • 地址:0x602030
    • 指向的地址:0x00007fe6e8e028e0
  3. stderr (标准错误)

    • 地址:0x602040
    • 指向的地址:0x00007fe6e8e03540

每个地址如 0x602020 是全局变量的地址,而对应的值(如 0x00007fe6e8e03620)是这些全局变量指向的 FILE 结构体实例的地址。

内存布局和用途

  1. stdout:

    • 地址0x602020
    • 指向的地址0x00007fe6e8e03620
    • 用途:标准输出通常用于打印普通输出信息,默认连接到终端的显示设备。
  2. stdin:

    • 地址0x602030
    • 指向的地址0x00007fe6e8e028e0
    • 用途:标准输入用于读取输入数据,默认连接到终端的键盘输入。
  3. stderr:

    • 地址0x602040
    • 指向的地址0x00007fe6e8e03540
    • 用途:标准错误用于打印错误信息,默认也连接到终端的显示设备。

背后的机制

在程序启动时,C 标准库(如 glibc)会初始化这几个标准流。具体来说,它们会分配相应的 FILE 结构体,并将 stdinstdoutstderr 这些全局变量指向这些结构体。

以下是一个简化的示意图,展示了这些指针和 FILE 结构体的关系:

+----------------+           +----------------+
|  0x602020      | --------> | FILE for stdout|
|  (stdout)      |           | 0x00007fe6e8e03620 |
+----------------+           +----------------++----------------+           +----------------+
|  0x602030      | --------> | FILE for stdin |
|  (stdin)       |           | 0x00007fe6e8e028e0 |
+----------------+           +----------------++----------------+           +----------------+
|  0x602040      | --------> | FILE for stderr|
|  (stderr)      |           | 0x00007fe6e8e03540 |
+----------------+           +----------------+

示例代码验证

下面是一些示例代码,可以用来验证这些指针的地址:

#include <stdio.h>int main() {printf("Address of stdout: %p\n", (void*)&stdout);printf("Address of stdin: %p\n", (void*)&stdin);printf("Address of stderr: %p\n", (void*)&stderr);printf("Pointer value of stdout: %p\n", (void*)stdout);printf("Pointer value of stdin: %p\n", (void*)stdin);printf("Pointer value of stderr: %p\n", (void*)stderr);return 0;
}

运行这段代码,你应该会看到标准流指针的地址和它们指向的 FILE 结构体的地址,这与你提供的内存地址应该是一致的。

总结

这些指针(stdoutstdinstderr)是全局变量,指向标准 I/O 流的 FILE 结构体实例。这些实例在程序启动时由 C 标准库初始化,用于管理标准输入、输出和错误流。

相关文章:

CTF-PWN: 什么是_IO_FILE?

重要概念:fopen()返回的是一个结构体的指针 _IO_FILE 结构体在什么时候被创建&#xff1f; _IO_FILE 结构体的实例是在程序使用标准 I/O 函数&#xff08;如 fopen、fclose、fread、fwrite 等&#xff09;时创建和管理的。这个结构体实际上是 GNU C Library (glibc) 用于处理…...

前端八股文第二篇

11.事件循环 事件循环&#xff08;Event Loop&#xff09;是 JavaScript 运行时中的一种机制&#xff0c;用于处理异步操作和事件驱动的编程。在浏览器环境中&#xff0c;事件循环是指浏览器通过事件队列&#xff08;Event Queue&#xff09;来管理和调度异步任务的执行顺序。…...

springboot汽车保修服务管理系统-计算机毕业设计源码00052

摘 要 随着汽车数量的不断增加和汽车保修服务需求的日益增长&#xff0c;建立一套高效的汽车保修服务管理系统变得至关重要。基于Spring Boot框架的汽车保修服务管理系统旨在整合汽车保修流程&#xff0c;简化管理流程&#xff0c;提高服务质量和用户体验未来&#xff0c;我们将…...

分布式架构搭建博客网站

目录 运行环境基础配置需求准备工作配置静态ip修改主机名及host映射开启防火墙时间同步配置免密ssh登录 环境搭建Server-Web端安装LNMP环境软件Server-NFS-DNS端上传博客软件Server-NFS-DNS端设置NFS共享Server-Web设置挂载远程共享目录nginx设置在数据库中创建数据库和用户重启…...

python-opencv给图片或视频去水印

文章目录 引言inpaint函数的使用方法鼠标事件回调函数cv2.setMouseCallback介绍去水印步骤实现代码 引言 本文主要基于cv2.inpaint函数实现图片的水印去除。 inpaint函数基于图像修复算法&#xff0c;通过对缺陷区域周围像素的分析和插值&#xff0c;生成合适的像素值来填充缺…...

免费送源码:Java+ssm+Springboot Springboot手办定制销售系统 计算机毕业设计原创定制

Springboot手办定制销售系统 摘 要 随着人们生活水平的提高和互联网的发展&#xff0c;人们消费思想和消费方式的逐渐改变&#xff0c;使得消费者开始追求自身品味和个性。手办定制就是在这种条件下应运而生。手办定制是基于客户需求来定制产品&#xff0c;满足客户对其功能、结…...

卡夫卡的使用

关于消息队列的使用 一、消息队列概述 消息队列中间件是分布式系统中重要的组件&#xff0c;主要解决应用解耦&#xff0c;异步消息&#xff0c;流量削锋等问题&#xff0c;实现高性能&#xff0c;高可用&#xff0c;可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveM…...

mac|maven项目在idea中连接redis

安装maven brew install maven idea-setting导入redis插件 idea新建maven项目 构建系统选择maven 项目右侧数据库图标导入redis 新建一个数据库&#xff0c;名称必须为数字&#xff0c;测试一下是否可以连接&#xff0c;连接成功后选择确定 pom.xml导入redis <depende…...

Python基础学习------第一天

print("hello world") 1.括号和引号&#xff0c;必须使用的是英文 被双引号包围起来的称为字符串。 python注释&#xff1a;单行注释&#xff1a;1.井号# 2.多行注释 &#xff1a;""" """ print输出多个内容是中间用逗号隔开就好…...

MySQL的SQL语句之触发器和存储过程的应用

触发器 Trigger 一.触发器 作用&#xff1a;当检测到某种数据表发生数据变化时&#xff0c;自动执行操作&#xff0c;保证数据的完整性。 1.创建一个触发器 如上图所示&#xff0c;查看这个create的帮助信息的时候&#xff0c;这个create trigger就是创建触发器的意思。 如…...

【MD5】密码加密之加盐算法

哈喽&#xff0c;哈喽&#xff0c;大家好~ 我是你们的老朋友&#xff1a;保护小周ღ 本期主要是给大家分析一下, 密码的如果加密存储的, 学习加盐算法的思想, 通过一个简单的案例, 即可快速学习. 一起来看看叭~ 适用于编程初学者&#xff0c;感兴趣的朋友们可以订阅&…...

服务器虚拟化

前言 服务器虚拟化是一种技术&#xff0c;它通过将一台物理服务器的软件环境分割成多个独立分区&#xff0c;使每个分区都能模拟出一台完整的虚拟服务器。这种技术利用虚拟化技术充分发挥服务器的硬件性能&#xff0c;提高运营效率&#xff0c;节约能源并降低经济成本。 通过…...

贪心算法理论基础和习题【算法学习day.17】

前言 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非常非常高滴&am…...

爬虫ip技术未来发展趋势

各位朋友&#xff0c;大家好&#xff01;有伙伴问爬虫技术未来会有更好的发展么&#xff0c;那今天小蝌蚪来跟大家聊聊爬虫技术未来的发展趋势分享一下行业咨询。 大家在日常工作和生活中&#xff0c;都希望事情能更省心、高效吧&#xff1f;未来的爬虫技术就朝着这个方向发展…...

推荐一款功能强大的文字处理工具:Atlantis Word Processor

Atlantis word proCEssor是一款功能强大的文字处理工具。该软件可以让用户放心的去设计文档&#xff0c;并且软件的界面能够按用户的意愿去自定义&#xff0c;比如工具栏、字体选择、排版、打印栏等等&#xff0c;当然还有更多的功能&#xff0c;比如你还可以吧软件界面中的任何…...

语言≠思维,大模型学不了推理:一篇Nature让AI社区炸锅了

转自&#xff1a;机器之心 大语言模型&#xff08;LLM&#xff09;为什么空间智能不足&#xff0c;GPT-4 为什么用语言以外的数据训练&#xff0c;就能变得更聪明&#xff1f;现在这些问题有 「标准答案」了。 近日&#xff0c;一篇麻省理工学院&#xff08;MIT&#xff09;等…...

Ubuntu 安装 npm

1. 升级apt sudo apt-get update 2. 安装nodejs sudo apt install nodejs 3. 安装npm sudo apt-get install npm 4. 查看版本 node -v npm -v 完成安装&#xff01;...

Go:package

文章目录 标准库概述regexp包锁和sync包自定义包和可见性基本格式导入外部安装包包的初始化 自定义包使用godoc自定义包的目录结构 标准库概述 在之前的部分已经用了很多和标准库有关的内容&#xff0c;比如有fmt&#xff0c;os这种功能 unsafe: 包含了一些打破 Go 语言“类型…...

大数据之微服务注册、发现与熔断方案

大数据微服务注册、发现与熔断方案 介绍实现框架利用Spring Cloud实现微服务注册&#xff0c;发现&#xff0c;熔断实例&#xff1f; 一&#xff0c;介绍 大数据微服务注册、发现与熔断是微服务架构中的关键概念&#xff0c;它们各自在微服务架构中扮演着重要的角色。以下是对这…...

最新出炉!2024年邮件营销平台综合盘点

随着数字化营销的不断发展&#xff0c;邮件营销依然是企业与客户保持联系的重要渠道之一。2024年&#xff0c;邮件营销平台市场竞争激烈&#xff0c;各大平台纷纷推出新功能&#xff0c;以满足企业日益增长的需求。在众多平台中&#xff0c;Zoho Campaigns作为一款成熟的邮件营…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...