程序下载地址
基于FAT32文件系统的数据隐写实验
实验内容
本实验要求通过修改采用FAT32文件系统的分区结构,实现将数据隐写在分区中的空闲扇区,并且该隐写数据不会被新拷入文件覆盖。具体完成以下目标:
(1) 查找分区中未分配的扇区,将小于4KB(4096字节)的数据隐写其中;
(2) 为了避免用户发现,写入的数据不能够以文件形式存在;
(3) 为了保证数据的可靠性,写入的数据不能够被新拷入的文件覆盖。
实验步骤
1. 初始化优盘
将优盘插入主机的USB接口,待主机识别后,双击“我的电脑”,找到优盘所在分区,右键点击,选择“格式化”
模拟现实情况,向优盘中拷入一些文件
2. 利用WinHex打开优盘
双击WinHex.exe,进入操作界面。点击菜单“工具”“打开磁盘”,选择优盘所在分区
3. 修改FSINFO保留扇区
为了找到可以写入数据的空闲空间,打开分区的1号扇区(第2个扇区),即保留扇区。注意可以通过该扇区0x0偏移的4个字节“52 52 61 41”以及0x1E4处的4个字节“72 72 41 61”来判断定位的FSINFO扇区是否正确。
根据FAT32文件系统结构,该扇区偏移0x1E8处连续的4个字节即为当前分区所有的可用簇总数,得到值为“1C F6 1C 00”,由于需要将数据写入一个空闲簇,因此将其值减1,得到“1B F6 1C 00”;同理,偏移0x1EC处的连续4个字节为当前分区内“下一个可用簇”的字段,值为“A5 03 00 00”。注意该簇0x0362即为我们要写入数据的空闲簇。
通过FAT表找到连续4个全零字节所在簇,我们这里找到的是0x0362,将“下一个可用簇”的值0x0362改为0x0363.
0x0362就是我们要保护的簇
4. 修改FAT表
接下来需要修改FAT表中的空闲簇,在Winhex文件显示窗口中点击“FAT1”来到FAT1表的初始位置。
我们来计算一下需要修改的地址偏移
>>> hex((0x362)*4)
'0xd88'
>>> 0xd88+0x183400
1589640
>>> hex(1589640)
'0x184188'
>>> 0xd88+0x8c1a00
9185160
>>> hex(9185160)
'0x8c2788'
在FAT1表中,找到0x362簇的状态字符,即相对起始处偏移0x362×4(0xd88)的指示的4个字节,将其值“00 00 00 00”改为“FF FF FF 0F”或者“F7 FF FF FF”,前者表示该簇已被占用,后者表示该簇已坏,如图1.8所示。将该簇状态标志为坏簇或占用簇主要为了让系统认为该簇已使用而不会被新写入的数据覆盖。FAT2是FAT1的备份,为了保险起见,也采用与FAT1同样的处理方式。
5. 填写数据
找到数据区“0x362”簇开始的位置,将连续的8个扇区内容填入需要隐藏的数据,由于本实验只是为了验证写入数据不会被新文件覆盖,因此我们手工将每个扇区的开始部分改为连续的0x66,即字符”f”。数据区的0x362簇位置可利用WinHex菜单中提供的工具查找,选择菜单“位置>Go to Sector”,在Cluster处填入0x362转换为十进制的数字866即可。
跳转到这来的时候里面存满了数据,说明这是快速格式化没有彻底擦除数据的证据,这也是数据可以恢复的原因
跳转到这里之后我们在扇区的开头填上
fffffffffffffffffff
,这里仅仅是用来做一个标记在头和尾的地方设置一个标记来判断扇区数据是否被修改
然后我们算一下尾部地址
>>> hex(0x1360000+8*512)
'0x1361000'
同样改完即可
修改完毕
6. 保存与验证
点击菜单“文件Save Sectors”将写入的数据保存。接下来需要往优盘中写入新的文件,以用来验证之前写入的数据不会被覆盖。在拷入数据前,注意先将优盘从系统中正常退出,重新插拔。
向U盘里拷入新的文件:一部电影:
再次用WinHex将优盘所在分区打开。定位到数据区的0x362簇的最后一个扇区,检查一下看看先前在0x362簇写入的数据是否被覆盖
可以看出,先前写入的0x362处的隐藏数据没有被新文件覆盖,新文件从0x363处开始写入。在文件目录中看不到隐藏数据的任何部分。
以上实验中FAT区中的对应簇状态标识为坏簇也可达到同样目的。
对上述步骤的程序化实现
Winhex脚本学习
通过上面的实验,我对步骤已经比较熟悉了,写脚本也是得心应手
对于python和winhex脚本的选择,我选择了后者,因为上述实验都是在winhex实现,而且winhex脚本只需要一个winhex就可以运行,比较方便,然后语言也比较白痴,容易现学现卖,把这个脚本写出来也只花了一个小时
但是winhex脚本语言确实比较蠢,和网上教程还不一定全都相同,所以总结了一下:
Winhex脚本的坑
- winhex脚本不区分大小写 盘符好像区分
- winhex脚本用“\\”符号表示注释,但是有些环境下写注释就会报错
- winhex脚本可以用双引号或单引号将整数强制转换为文本
- winhex脚本支持的运算符有加(+)、减(-)、乘(*)、除(/)、取模(%)、按位与(&)、按位或(|)和按位异或(^)运算符
- 虽说支持运算,但是必须在运算式外面加上括号,不然会识别为字符串
- 有时调试的话我用message把值给弹出来,但是写运算式是不支持的,加上括号也不行,也就是最多只能弹一个变量2333333
- 至今不知道赋值怎么赋
写程序
这里有点非常需要注意:
这两种方式打开非常不一样
后者打开的话这里所有的偏移算上U盘起始扇区的0x4000
而用前者打开就不需要加上0x4000
然后我们将每一步的偏移按公式就算出来可以写出程序
实现效果
- FSINFO保留扇区已经被改过来了,和上面写实验报告的时候前移了一个簇
- FAT表也修改成功了
- 最后在被保护的簇头和尾写下“666666666666666”
也算是一种金丝雀吧
-
然后我们还发现了上次手动修改留下的痕迹_(:3」∠)_
这个时候我们再存储其他数据
将电影存进去之后
我们再检查
发现我们要被隐藏的簇保存完好
电影从下一簇开始存储
注意事项
其实脚本已写好,开始几次试了一下,把电影拷进去,发现我们我们要保护的簇都被覆盖了,晕死
试了好几次,还好步骤已经程序化了,不然尝试几次会累死
后来发现是
改完数据保存之后,需要重新插拔一次U盘
前面做实验的时候记得好像并没有插拔也成功了,所以并没有在意
我觉得需要插拔的原因可能是电脑需要更新一下FSINFO保留扇区吧
网友评论