这是一个奇怪的请求,但我有一块硬盘,我最初badblocks
在上面运行,然后中途停止了。所以一开始,驱动器的一部分被覆盖0xAA
,另一部分被覆盖0x55
。然后我把 NTFS 文件系统放在上面,让空白区域填满这些垃圾,然后写入其中的文件会覆盖这些区域。
后来驱动器坏了,整个驱动器的许多数据块丢失。
它现在是存储在 btrfs 文件系统上的 NTFS 分区的原始映像,我可能可以删除它,但我想确保其中没有任何我可以恢复的重要文件。
驱动器映像占用的空间比必要的空间多得多,因为所有这些 0xAA 和 0x55 都无法存储为“空洞”。同样,NTFS 恢复程序 DMDE 列出了许多只包含 0xAA 和 0x55 的“文件”。
有没有办法遍历并找到任何完全为 0xAA 或 0x55 的块/块/链,并将它们清空为 0x00,以便它们在 btrfs 卷上占用零空间?它们不是零,但它们也不包含任何信息。
答案1
我意识到我可以编写自己的 Python 程序来做到这一点:
filename = 'NTFS_3TB.img'
chunk_size = 512
with open(filename, 'r+b') as f:
while True:
chunk = f.read(chunk_size)
if chunk == b'':
break
if chunk == b'\x55'*chunk_size:
start = f.tell()-chunk_size
print(f'5: {start}')
f.seek(start)
f.write(b'\x00'*chunk_size)
if chunk == b'\xaa'*chunk_size:
start = f.tell()-chunk_size
print(f'A: {start}')
f.seek(start)
f.write(b'\x00'*chunk_size)
我使用十六进制编辑器查看了文件并确认块大小正确,经过几次迭代并观察它们在十六进制编辑器中的更改等,以确保它没有擦除错误的块。
更高效的版本:
filename = 'NTFS_3TB.img'
chunk_size = 512
all_5s = b'\x55'*chunk_size
all_As = b'\xaa'*chunk_size
all_0s = b'\x00'*chunk_size
try:
with open(filename, 'r+b') as f:
f.seek(236039143424) # From last run
while True:
chunk = f.read(chunk_size)
if chunk == b'':
break
if chunk == all_5s:
start = f.tell()-chunk_size
f.seek(start)
f.write(all_0s)
if chunk == all_As:
start = f.tell()-chunk_size
f.seek(start)
f.write(all_0s)
finally:
print(f'Position: {start}')
答案2
我认为不存在可以安全地完成此操作的工具。
如果您有一个健康的挂载文件系统,fstrim 将释放所有未使用的块。
如果您使用 tr 之类的东西来任意转换 0xAA 和 0x55 值,它将得到单个字节,并可能破坏有效数据。此外,tr 最初是为 ascii 文件设计的,在二进制文件上可能效果不佳。
即使您只翻译了仅包含 0xAA 和 0x55 值的整个块,您也可能会意外清除有效数据或元数据块。
您可能需要的是检查文件系统中的空闲块以查看它们是否为单个值,然后在每个块上使用 fstrim。
我对此的方法是:
- 以只读方式挂载文件系统(如果可能)并复制所有可以复制的内容
- 使用文件清理器获取其他所有内容
- 使用校验和以及二进制比较来删除 2 中与 1 中相同的重复项
- 扫描 2 的结果并删除明显的垃圾
请注意,步骤 1 可能会得到大量包含清零坏块的损坏文件。