使用pytsk3的Python脚本无法访问驱动器恢复删除文件求助
问题描述
用户编写了以下用于恢复删除文件的Python脚本(包含tkinter GUI及pytsk3调用):
import tkinter as tk from tkinter import filedialog import pytsk3 drive_entry = None # Global variable for drive_entry output_entry = None # Global variable for output_entry def recover_files(drive_path, output_path): # Open the drive img_info = pytsk3.Img_Info(drive_path) # Open the file system fs_info = pytsk3.FS_Info(img_info) # Get the root directory root_dir = fs_info.open_dir('/') # Recursively search for deleted files for entry in root_dir: if entry.info.name.name.decode('utf-8').startswith('$'): # This is a deleted file file_data = entry.read_random(0, entry.info.meta.size) # Write the file data to disk with open(output_path + entry.info.name.name.decode('utf-8'), 'wb') as f: f.write(file_data) def select_drive_path(): global drive_entry # Use the global drive_entry variable drive_path = filedialog.askopenfilename() drive_entry.delete(0, tk.END) drive_entry.insert(tk.END, drive_path) def select_output_path(): global output_entry # Use the global output_entry variable output_path = filedialog.askdirectory() output_entry.delete(0, tk.END) output_entry.insert(tk.END, output_path) def main(): global drive_entry # Use the global drive_entry variable global output_entry # Use the global output_entry variable # Create the GUI root = tk.Tk() root.title('Deleted File Recovery') # Create the input fields drive_label = tk.Label(root, text='Drive Path:') drive_label.pack() drive_entry = tk.Entry(root) drive_entry.pack() drive_button = tk.Button(root, text='Select Drive', command=select_drive_path) drive_button.pack() output_label = tk.Label(root, text='Output Path:') output_label.pack() output_entry = tk.Entry(root) output_entry.pack() output_button = tk.Button(root, text='Select Output', command=select_output_path) output_button.pack() # Create the button recover_button = tk.Button(root, text='Recover Files', command=lambda: recover_files(drive_entry.get(), output_entry.get())) recover_button.pack() # Start the GUI root.mainloop() if __name__ == '__main__': main()
运行时抛出如下错误:
Traceback (most recent call last): File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__ return self.func(*args) ^^^^^^^^^^^^^^^^ File "C:\Users\User\Documents\transtech\ocha_app\CPU\data16.py", line 62, in <lambda> recover_button = tk.Button(root, text='Recover Files', command=lambda: recover_files(drive_entry.get(), output_entry.get())) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\User\Documents\transtech\ocha_app\CPU\data16.py", line 12, in recover_files fs_info = pytsk3.FS_Info(img_info) ^^^^^^^^^^^^^^^^^^^^^^^^ OSError: FS_Info_Con: (tsk3.cpp:214) Unable to open the image as a filesystem at offset: 0x00000000 with error: Cannot determine file system type
用户尝试直接访问驱动器,以及使用FTK将驱动器转换为.raw镜像文件后,问题仍未解决。
解决方案
1. 指定正确的分区偏移量
pytsk3默认从偏移0处读取文件系统,但如果目标是磁盘分区而非整个磁盘,必须指定分区的起始偏移:
- 用
diskpart获取分区偏移:- 以管理员权限打开命令提示符,输入
diskpart - 执行
list disk找到目标磁盘编号 - 执行
select disk X(X为磁盘编号) - 执行
list partition查看分区的起始偏移(字节为单位)
- 以管理员权限打开命令提示符,输入
- 修改代码中
FS_Info的初始化:# 替换原fs_info = pytsk3.FS_Info(img_info) partition_offset = 1048576 # 替换为实际获取的偏移值 fs_info = pytsk3.FS_Info(img_info, offset=partition_offset)
2. 确认文件系统兼容性
pytsk3仅支持NTFS、FAT、EXT等常见文件系统,若磁盘使用exFAT、APFS等不支持的格式:
- 右键磁盘→属性,确认文件系统类型
- 若为exFAT,需重新编译pytsk3添加exFAT支持,或改用
pyexfat等专用库
3. 以管理员权限运行脚本
访问物理驱动器需要管理员权限,否则可能因权限不足导致无法读取磁盘信息:
- 右键Python脚本→“以管理员身份运行”
- 或在管理员命令提示符中执行
python 脚本文件名.py
4. 验证镜像文件完整性
FTK生成的.raw镜像可能存在损坏,可通过以下方式验证:
- 使用哈希工具对比原磁盘与镜像的MD5/SHA值,确认镜像完整
- 用dd工具重新生成镜像(Windows需安装dd for Windows):
dd if=\\.\PhysicalDrive0 of=C:\disk_image.raw bs=4M
5. 修复路径拼接与文件识别逻辑
原脚本存在路径拼接错误和删除文件判断逻辑错误,修改如下:
import os def recover_files(drive_path, output_path): try: img_info = pytsk3.Img_Info(drive_path) partition_offset = 1048576 # 替换为实际偏移值 fs_info = pytsk3.FS_Info(img_info, offset=partition_offset) root_dir = fs_info.open_dir('/') for entry in root_dir: # 通过元数据标记判断是否为已删除文件 if entry.info.meta and entry.info.meta.flags & pytsk3.TSK_FS_META_FLAG_UNALLOC: try: file_name = entry.info.name.name.decode('utf-8', errors='replace') # 处理路径拼接,避免缺失分隔符 output_file = os.path.join(output_path, file_name) file_data = entry.read_random(0, entry.info.meta.size) with open(output_file, 'wb') as f: f.write(file_data) except Exception as e: print(f"恢复文件失败 {file_name}: {str(e)}") except Exception as e: print(f"初始化文件系统失败: {str(e)}")
内容的提问来源于stack exchange,提问作者ocha
相关产品推荐
相关产品推荐

