Conmajia
January 24, 2019
前几周,合伙人让我给他发几个旧项目的数据。翻箱倒柜之后,我发现那些数据都在旧硬盘上,还被格式化了,しまった。虽说这东西我都淘汰好几年了,不过机械硬盘,没准儿还有救,死马当活马医呗。于是我试着恢复数据,不行再拿出去开盘。
我下载了一堆古今中外的 data recovery apps,捣鼓半天,啥几把都没恢复出来。后来在别地儿找着数据了,这事儿也就过去了,拔掉硬盘,哪来的滚回哪去。过了几天,我突然发现,我他妈的海量文件打不开了?!
一个幽灵留下的遗产
恢复数据的努力失败后,又过了一段时间,我在翻查电脑上别的资料时,发现这些文件都打不开,甚至图标都不显示了。
被感染的文件
这里的图片都是例子,实际的文件早修复了。我可不想为了演示再去中个招。
想到之前恢复数据时下载的那些乱七八糟的软件,我心里一紧:“老子电脑中病毒了!”接下来就是漫长的查毒杀毒过程,等待过后,阵容豪华的杀软联盟给出一个让我难以接受的事实:
您的电脑很安全。
我安全您
呢?几万个文件,从图片到压缩包,从视频到 exe,全嗝屁了你丫告我电脑很安全?鬼干的?上网查了一圈儿,也没查出个所以然,一帮傻逼玩意儿在哪答非所问瞎 bb。没招,还得自己上手。
什么情况
既然怀疑是病毒,病毒破坏文件多半是有共同点的,不然那叫大型多格式应用程序。先开他几个文件来比划比划。
被破坏的文件数据
好在这病毒很良心没有改我文件名,不然老子真是要 GG 了。打开几个 .ico
,看到这样的数据:
被破坏的 .ico
文件
典型的文件头被篡改,翻出 .ico
文件格式规范,找到头部信息:
typedef struct {
WORD idReserved; // Reserved (must be 0)
WORD idType; // Resource Type (1 for icons)
WORD idCount; // How many images?
ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of 'em)
}
ICONDIR, * LPICONDIR;
按照文件头来看,这文件应该是 00 00 01 00 01 00
开头的,但现在的文件是 FF FF FE FF FE FF
开头,刚好是正常文件按位取反。结合中招的时候没有察觉到电脑被明显拖慢或者狂读磁盘,在这种情形下病毒想要悄悄感染我几万个文件,应该只改写了文件部分内容。现在看来,那就是修改了文件头,导致 OS 识别不到正确的文件格式。.ico
后面的 ICONDIRENTRY
内容和图标实际内容有关,可能是 DIB,也可能是 PNG 或者其他玩意儿。不管它是什么格式,我现在看这些图标都一个德行,没法判断正确不正确。网上下了一个正常的图标打开,学学它的文件头:
正常的 .ico
文件
开您
的玩笑?
看到那一大堆 00 00 00 00
老子差点当场笑出声来。这谁他妈吃饱了撑的搞笑呢?合着你就改了我文件前 100 个字节呗?而且看这架势还没干别的,只是把数据取反了再写回去。您蛋疼呢?氧化钙。
淦
那就试验呗,把这 .ico
的前 100 字节取反,发现好了,系统能认出来了。
修复的 .ico
文件
真是浪费感情。剩下就是体力活了,一盏茶时间完事儿。
数据恢复 app
把硬盘往 Drag Here 上一拖,自己玩儿去吧。
文件全部修复了
源码
懒得废话,过分简单。
private void deal(string fullpath) {
FileStream src = new FileStream(fullpath, FileMode.Open, FileAccess.ReadWrite);
BinaryReader reader = new BinaryReader(src);
BinaryWriter writer = new BinaryWriter(src);
int length = (int)src.Length;
if (length < 100)
return;
for (int i = 0; i < 100; i++) {
reader.BaseStream.Position = i;
writer.BaseStream.Position = i;
writer.Write((byte)(0xFF - reader.ReadByte()));
}
reader.Close();
writer.Close();
src.Close();
}
我想说,现在的人可真是无聊啊。
The End. \(\Box\)