Python 数据恢复实战 - 恢复U盘中的chk文件,以及误删的文件

有时候,我们使用chkdsk工具之后,会发现硬盘里的文件消失了,其实是被系统临时放在了硬盘的"FOUND.xxx"文件夹里,可以用相关的软件恢复。本文介绍使用Python进行恢复数据的方法。


chk文件格式解析

工具:UltraEdit、VSCode或其他的二进制编辑器
chk文件不是一个文件,而是由许多文件的内容组合在一起的。比如一个文件的数据后面,又是另一个文件的数据。
比如,我们用二进制编辑器打开一个普通的文件,会在文件开头处看到一个文件头。但是chk文件没有固定的文件头,而一般包含了许多个文件头。比如这里就有3个:

根据这个特点,我们就可以找出文件头,再根据文件头分离出不同文件的数据。

恢复chk文件

首先,找到U盘里的"FOUND.xxx"文件夹("FOUND.xxx"文件夹默认是隐藏的,如果找不到,可看文章后面的方法)。
然后新建一个Python文件,输入以下的代码。
找出数据中的文件头
这里使用for循环和切片,找出数据中的文件头。

import sys,os,zipfile
file = input("输入或拖曳要恢复的chk文件: ")

# data可以是U盘里面的chk文件,也可以是读取到的原始磁盘数据
data = open(file,'rb').read()
head=b'PK\x03\x04' # zip、docx、pptx等格式的文件头
mark=b"[Content_Types].xml" # 这个也是docx、pptx等格式的标记

# 先找出数据中的文件头
offsets = []
for i in range(len(data)):
    if i % 1000000==0:
        print("已处理 %d 字节"%i) # 显示进度
    if data[i:i+len(head)]==head and \
       data[i+30:i+30+len(mark)]==mark: # 如果符合文件头及mark
        if data[i-1]==0 or i==0: # 如果前一个字节是00
            offsets.append(i)
offsets.append(len(data))

恢复数据
恢复的数据从文件头这个起点开始,恢复的文件的长度一般要大于原来的文件大小,这样可以避免文件被截断而打不开的问题。

print("恢复文件")
estimated_size=2**26 # 恢复出文件的大小(要大于原来的文件)
for i in range(len(offsets)-1):
    document = data[offsets[i]:offsets[i]+estimated_size] # 数据从文件头开始,长度大于原来的文件大小
    out = "%ds - recovered.pptx"%i # 也可以是docx或xlsx
    with open(out,'wb') as f: # 
        f.write(document)

    # 用zipfile模块检验恢复出的文档是否正常,因为docx、pptx等格式本质上是zip文件
    try:
        z=zipfile.ZipFile(out)
    except zipfile.BadZipFile:
        os.rename(out,"%d - recovered(bad).pptx"%i)

附源代码: ​恢复chk文件中的docx, pptx文档.py · qfcy_ / Python · GitCode

附:找到隐藏文件夹"FOUND.xxx"的方法
在Windows系统中,按下图操作打开文件夹选项,点击“查看”,然后将“隐藏操作系统文件”的勾去掉,再选择“显示隐藏的文件、文件夹”,点击确定即可。

然后,在硬盘、U盘的根目录下就能找到"FOUND.xxx"文件夹。

恢复误删除的文件

误删除的文件没有文件名,不能用普通的open(文件名)函数读取。但是文件的数据还留在了硬盘上。
所以,不是可以将硬盘作为一个巨大的chk文件来对待吗?
关于直接读写硬盘的方法,参见作者的文章:Python 读写硬盘、U盘扇区数据的方法
不过这里可以小瞧一眼:

disk = open(r"\\.\PhysicalDrive0","rb") # 打开磁盘0,PhysicalDrive不区分大小写
# 读取第一个扇区, 也就是磁盘主引导记录, 1扇区为512字节
print(disk.read(512))

猜你喜欢

转载自blog.csdn.net/qfcy_/article/details/127696303