如何自己实现文件粉碎机?

2017-08-27 11:45:29 +08:00
 explist

为什么下面的代码删除文件后,还可用 360 软件恢复回来(已亲测)?难道要用 mmap 模块吗?

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

import tkinter.filedialog as tf

def selecFile(title='多文件选择',fmt='.'):

    '''(多个)文件选择(对话框) 返元组 取消时返空'''
    return tf.askopenfilenames(title=title,filetypes=[('all files',fmt)])

def myRemoveFiles():

'''彻底删除文件'''
paths = selecFile(title='选择要删除的文件')  #
if paths:
    if tm.askokcancel('重要提示!','确定永久删除吗?'):
        fn = '_Test{}_.tmp'
        _dir = os.path.dirname(paths[0])
        
        for i, _file in enumerate(paths):
            try:
                fsize = os.path.getsize(_file)
                with open(_file,'rb+') as f:
                    for _ in range(3):
                        f.seek(0,0)
                        f.write(os.urandom(fsize))
                         
                file = os.path.abspath(os.path.join(_dir,fn.format(i)))
                os.rename(_file,file)
                os.remove(file)
                
                print(_file,"OK")
            except Exception as err:
                print(_file,str(err))
4183 次点击
所在节点    Python
22 条回复
springmarker
2017-08-27 11:57:06 +08:00
要覆盖掉文件在磁盘的数据才行吧
disk
2017-08-27 12:10:44 +08:00
要直接磁盘访问,不能只是删记录,把文件所在扇区多次写入随机数据就行
XiaoFaye
2017-08-27 12:11:10 +08:00
直接把文件内容改了不就行了?原来的肯定找不回来了。
metorm
2017-08-27 12:15:27 +08:00
恢复回来倒是可以,但是恢复回来的文件应该已经是乱码了吧?
imn1
2017-08-27 12:19:29 +08:00
粉碎机是必须抹盘的
删除或彻底删除只是把原来文件在磁盘的位置,标记为可用空间而已
覆盖实质只是“另存”,然后把文件索引指向新的位置,原来的位置标记为可用
NoAnyLove
2017-08-27 12:21:02 +08:00
比较好奇,如果直接对文件操作,而不是直接对磁盘访问,能保证覆写文件的时候,覆盖的是相同的硬盘区域吗?
panda1001
2017-08-27 12:34:53 +08:00
用勒索病毒试试
metorm
2017-08-27 12:46:35 +08:00
@imn1
然而,楼主这种方法,如果是 360 恢复这种软件,按文件名寻找丢失的文件,寻找回来的应该是已经被随机写入过的版本吧?我猜原版的文件还在,但已经没法用文件名寻找了。
imn1
2017-08-27 12:52:39 +08:00
@metorm
我针对他的标题说的,他的正文和标题是两种情况
explist
2017-08-27 15:07:30 +08:00
@metorm
用 360 扫描出来的是这种文件: _Test0_.tmp
恢复后,改扩展名为原来的类型:打开一看,还是原来的内容,不是乱码!!!
explist
2017-08-27 15:10:20 +08:00
为了进一步验证,我把上面函数中关于重命名及删除文件的代码注释掉,执行完后,原文件大小不变,内容为乱码!!
为什么恢复后却是原本的内容而不是乱码?
RqPS6rhmP3Nyn3Tm
2017-08-27 15:13:11 +08:00
Python 吗
Os.system("shred your_file")
解决问题
explist
2017-08-27 15:16:30 +08:00
我们对指针进行再操作的时候,肯定会覆盖(破坏)指针指向地址的数据,那么对于文件对象为什么从文件首开始写操作,不能破坏其数据?
那么利用 mmap 模块,对文件建立内存映射,再对映射进行全员覆盖,这样会有不同吗?
ryd994
2017-08-27 15:29:14 +08:00
@XiaoFaye
@NoAnyLove
@explist 一般来说修改文件内容会写入原位置,因为不需要重新分派扇区,性能有利。例外是 cow 和带在线自动碎片整理的文件系统

@explist 我没懂你为什么要 rename
SlipStupig
2017-08-27 15:31:28 +08:00
360 文件粉碎机是直接摘除文件系统 cluster 索引,文件系统无法定位到这个文件,更别说恢复,你上无法恢复内容,用 python 实现的话,有点麻烦,你得解析到该文件在 ntfs 相对物理盘地址和文件偏移量大小,然后随机填充 0 和 1,30 次以上,基本上来说就恢复不了
ryd994
2017-08-27 15:33:20 +08:00
做个实验:
写 0 并格式化一个 U 盘(保证没有干扰)
写一个文件,看能不能找到
覆盖完不要删除,看能不能找到
最后人工删除,看能不能找到
likuku
2017-08-27 16:01:16 +08:00
好奇对于类似 ZFS/AppleFS 这种 WAL 的 FS,

在不填满整个 storage pool 的前提下如何覆盖已删除文件的数据块?
antowa
2017-08-27 16:19:19 +08:00
先加密后删除。即使恢复了那么数据没有意义。这样思路不是更简洁?
explist
2017-08-27 18:22:57 +08:00
def myRemoveFiles():
'''彻底删除文件'''
paths = selecFile(title='选择要删除的文件') #
if paths:
if tm.askokcancel('重要提示!','确定永久删除吗?'):
fn = '_Test{}_.tmp'
_dir = os.path.dirname(paths[0])
for i, _file in enumerate(paths):
try:
# fsize = os.path.getsize(_file)
# with open(_file,'rb+') as f:
# for _ in range(3):
# f.seek(0,0)
# f.write(os.urandom(fsize))

fd = os.open(_file,os.O_RDWR)
with mmap.mmap(fd,0,access=mmap.ACCESS_WRITE) as m:
m.write(os.urandom(m.size()))
m.flush()
os.close(fd)

file = os.path.abspath(os.path.join(_dir,fn.format(i)))
os.rename(_file,file)
os.remove(file)

print(_file,"OK")
except Exception as err:
print(_file,str(err))
explist
2017-08-27 18:23:58 +08:00
用 mmap 时未发现能恢复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/386098

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX