我就不去找那个什么所谓的wiki了,简单的说下这个文件是个什么东西.ithmb是Apple的一种缩略图文件,这个文件不是单一缩略图而是缩略图的合集。在iOS7之前的缩略图文件都是以缩略图的分辨率来命名的,如下图所示:
目前的分辨率32,79,120,158,166都是长宽相等的。
但是在iOS7 之后命名规则就改变了,成了下面的样子:
对应的分辨率直接看下面的代码吧:
def iOS7ithmb2Pix(ithmb):
return{
"3303":22,
"3309":64,
"3319":157,
"4031":120
}.get(ithmb,110)
也就是多了另外的几个分辨率22,64,157,120
可能到目前为止大家还不是很明白这个东西和隐私有什么关系。问题的关键就在于苹果的缩略图文件的生成规则,在你往图库里面添加文件或者使用相机拍照的时候就会生成不同分辨率的缩略图到缩略图库文件中,但是在你删除对应的照片或者图片的时候系统并不会更新这个库将对应的文件删除掉。也就是说哪天你的相片已经删除了,但是别人拿到了你的手机并且能够看到这两个文件,那么你的小秘密就有可能会被曝光了,虽然不是高清的。但是对于神马和小三的合照啊,裸照啊神马的拿出来恶心你就足够了。
这个文件上面已经提到了是一些bmp图片的集合,也就是说如果能算出bmp的大小进行文件分割,然后加入相应的tmp文件头就可以了。网上有个现成的工具叫做iThmbConverter。但是这个东西未注册的时候只能看前面的几张。
后面的会显示预览版balabala什么的,需要注意的是在右上角的那张图片其实已经是从我的相机里面删除掉了。但是在这里仍然是可以看见的。本来想直接看iThmbConverter的实现方式但是无奈加了个vmp的壳子,作为一个壳盲就不去折腾了。直接从文件格式入手。
既然是bmp图片,并且图片边缘是有边框的,那么可以直接从边缘的像素点入手来算图片的宽度:
例如针对3303的缩略图已经知道大体的像素可能是22×22,但是这个信息并不是十分准确的。图片右侧的白色边框像素对应的十六进制为00,那么直接算第一行的长度即可:如下图所示。
一行的大小为0x30。那么图片的像素宽度为0x30/2=0x18也就是24个像素点。通常图片的高度和定义的大小是一致的,也就是说按照上面的缩略图定义那么高度为22.每张图片的大小为22×24×2=1056,即按照每张图片1056大小进行分割即可。
(知道了图片的宽度,长度的计算也可以通过多次猜测或者找图片间的间隙来计算,如果按照这个高度分割出来的图出现扭曲那么就需要重新计算调整高度了)由于ithmb是一个数据库文件因而中间包含了图片的其他信息,对应的数据长度为28。至于怎么算出来的大家可以自己去试试。现在要处理文件就比较简单了,按照图片的大小将文件进行分割,处理下一张图片的时候需要掠过28个字节来处理下一张图片。同样需要注意的是这些缩略图都是倒置的,如果要想实现正向显示需要修改bmp头的标志位或者将bmp中的行进行倒序处理。
bmp头结构如下:
剩下的就是代码处理了。可以看到总共解压了1186个文件
但是实际手机上有几个文件呢?
只有255个,解出来的的图片其实分辨率还是马马虎虎能看清楚是什么的。刚开始的彩屏手机分辨率不过120×120嘛。嘎嘎
怎么处理文件已经说清楚了,代码就不上了,有需要的话大家可以选择自己喜欢的代码去写。哈哈
贴下PP对于缩略图文件大小和体积的代码吧:
struct_a1 *__stdcall sub_898630(struct_a1 *thumbinfo, int a2)
{
struct_a1 *v2; // edi@1
int iOSVersionNumber; // ebx@1
int v4; // ecx@1
int v5; // eax@9
int v6; // eax@9
int v8; // [sp+14h] [bp-4h]@1
thumbinfo->dword0 = off_B8BBBC;
thumbinfo->dword4 = a2;
thumbinfo->dword8 = *(_DWORD *)(a2 + 8);
v2 = thumbinfo + 1;
v2[1].dword0 = 7;
v2->size = 0;
LOWORD(v2->dword4) = 0;
v8 = 0;
iOSVersionNumber = *(_DWORD *)(a2 + 24);
v4 = thumbinfo->dword8;
thumbinfo->size = -1;
switch ( sub_800420(v4) )
{
case 1:
sub_40FAF0((int)&thumbinfo[1], (char *)L"/PhotoData/Thumbnails/79x79.ithmb");
goto LABEL_3;
case 2:
case 5:
if ( iOSVersionNumber == 6 || iOSVersionNumber == 5 || iOSVersionNumber == 4 || iOSVersionNumber == 3 )
{
sub_4035B0((int)&thumbinfo[1], (char *)L"/PhotoData/Thumbnails/158x158.ithmb", 0x23u);
thumbinfo->size = 50560;
}
else
{
if ( iOSVersionNumber == 7 )
{
sub_40FAF0((int)&thumbinfo[1], (char *)L"/PhotoData/Thumbnails/3319.ithmb");
thumbinfo->size = 50240;
v5 = sub_41D840(&dword_C99450, L"m_database_thumbnail_path: ");
v6 = sub_41D5E0(v5, &thumbinfo[1]);
sub_41D840(v6, L"\n");
thumbinfo->width = 150;
thumbinfo->height = 150;
return thumbinfo;
}
}
thumbinfo->width = 150;
thumbinfo->height = 150;
return thumbinfo;
case 3:
if ( iOSVersionNumber == 6 || iOSVersionNumber == 5 || iOSVersionNumber == 4 || iOSVersionNumber == 3 )
{
sub_40FAF0((int)&thumbinfo[1], (char *)L"/PhotoData/Thumbnails/120x120.ithmb");
goto LABEL_19;
}
if ( iOSVersionNumber == 7 )
{
sub_40FAF0((int)&thumbinfo[1], (char *)L"/PhotoData/Thumbnails/3311.ithmb");
LABEL_3:
thumbinfo->width = 75;
thumbinfo->height = 75;
thumbinfo->size = 12640;
}
break;
case 4:
if ( iOSVersionNumber == 6 || iOSVersionNumber == 5 || iOSVersionNumber == 4 || iOSVersionNumber == 3 )
{
sub_40FAF0((int)&thumbinfo[1], (char *)L"/PhotoData/Thumbnails/240x240.ithmb");
thumbinfo->width = 240;
thumbinfo->height = 240;
thumbinfo->size = 115200;
}
else
{
if ( iOSVersionNumber == 7 )
{
sub_40FAF0((int)&thumbinfo[1], (char *)L"/PhotoData/Thumbnails/4031.ithmb");
LABEL_19:
thumbinfo->width = 120;
thumbinfo->height = 120;
thumbinfo->size = 28800;
}
}
break;
default:
thumbinfo->size = -1;
return thumbinfo;
}
return thumbinfo;
}
按照 thumbinfo->size的大小进行文件分割整合就可以了(注意越过文件间隙)。
为了更好地显示效果,PP童鞋只是处理的最高分辨率的缩略图,对于低分辨率的缩略图直接没有进行计算,如果需要的话自己算算也挺简单的。
[课程]Android-CTF解题方法汇总!
上传的附件: