struct fileinfo{
char *domain;
char *filename;
char *linktarget;
char *datahash;
char *unknown1;
unsigned short mode;
unsigned int unknown2;
unsigned int inode;
unsigned int userid;
unsigned int groupid;
unsigned int mtime;
unsigned int atime;
unsigned int ctime;
unsigned int filelen;
unsigned int flag;
unsigned int numprops;
};
unsigned int getint(const char *data, int *offset, int size)
{
if(data == NULL || offset == NULL) return 0;
unsigned int value = 0;
while (size > 0)
{
unsigned char tmp = data[*offset];
value <<= 8;
value |= tmp;
(*offset)++; size--;
}
return value;
}
char* getstring(const char *data, int *offset)
{
if(data == NULL || offset == NULL) return NULL;
char *str = NULL;
int slen = 0;
if(data[*offset] == (char)0xff && data[*offset+1] == (char)0xff){
*offset += 2;
return str;
}
slen = getint(data, offset, 2); //获取长度
str = (char*)malloc(slen+1); //申请空间
memcpy(str, (void*)(data+*offset), slen);//拷贝数据
str[slen] = 0; //补0;
*offset += slen;
return str;
}
char* toA(const unsigned char *data, int len)
{
if(data == NULL) return NULL;
char *str = (char*)malloc(len*2+1);
memset(str, 0, len*2+1);
for (int i = 0; i < len; i++)
{
char odata[3] = {0};
itoa(data[i], odata, 16); //转出来是两个字节的字符串
strcat(str, odata);
}
return str;
}
char* getstring_hash(const char *data, int *offset)
{
if(data == NULL || offset == NULL) return NULL;
unsigned char *str = NULL;
char *ostr = NULL;
int slen = 0;
if(data[*offset] == (char)0xff && data[*offset+1] == (char)0xff){
*offset += 2;
return ostr;
}
slen = getint(data, offset, 2); //获取长度
str = (unsigned char*)malloc(slen); //申请空间
memcpy(str, (void*)(data+*offset), slen); //拷贝数据
*offset += slen;
ostr = toA(str, slen);
free(str);
return ostr;
}
int process_mbdb_file(char *filename, char *outfilename)
{
int filelen = 0;
FILE *pf = NULL;
char *filedata = NULL;
char *index = NULL;
int offset = 0;
int i = 0;
if(filename == NULL || outfilename == NULL) return -1;
FILE *opf = fopen(outfilename, "w+");
if(opf == NULL) return -1;
pf = fopen(filename, "rb");
if(pf == NULL) goto _out;
fseek(pf, 0, SEEK_END);
filelen = ftell(pf);
rewind(pf);
filedata = (char*)malloc(filelen);
if(filedata == NULL) goto _out;
fread(filedata, 1, filelen, pf);
if(memcmp(filedata, "mbdb", 4)) goto _out; //文件标识头
index = filedata + 6; //跳过 0×05 0×00
offset = 0;
while(offset < filelen-6)
{
fileinfo fi = {0};
fi.domain = getstring(index, &offset);
fi.filename = getstring(index, &offset);
fi.linktarget = getstring(index, &offset);
fi.datahash = getstring_hash(index, &offset); //换成字符串
fi.unknown1 = getstring(index, &offset);
fi.mode = getint(index, &offset, 2); //八进制
fi.unknown2 = getint(index, &offset, 4);
fi.inode = getint(index, &offset, 4);
fi.userid = getint(index, &offset, 4);
fi.groupid = getint(index, &offset, 4);
fi.mtime = getint(index, &offset, 4);
fi.atime = getint(index, &offset, 4);
fi.ctime = getint(index, &offset, 4);
fi.filelen = getint(index, &offset, 8); //64位的 但一般情况下 不会有那么大的文件
fi.flag = getint(index, &offset, 1); //目前发现有4 和0 0貌似表示目录
fi.numprops = getint(index, &offset, 1);
if(fi.numprops)
printf("发现有额外数据 偏移位置在 %d n", offset);
fprintf(opf, "%s %s %s %s %s %u %u %u %u %u %u %u %u %u %u %un",
fi.domain,
fi.filename,
fi.linktarget,
fi.datahash,
fi.unknown1,
fi.mode,
fi.unknown2,
fi.inode,
fi.userid,
fi.groupid,
fi.mtime,
fi.atime,
fi.ctime,
fi.filelen,
fi.flag,
fi.numprops
);
fflush(opf);
free(fi.domain);
free(fi.filename);
free(fi.linktarget);
free(fi.datahash);
free(fi.unknown1);
}
_out:
if(filedata) free(filedata);
if(opf) fclose(opf);
if(pf) fclose(pf);
return 0;
}
int main(int argc, char* argv[])
{
process_mbdb_file("1.bin", "1.txt");
return 0;
}
这是解析Manifest.mbdb文件的C语言版,写的非常粗糙的测试。网上有完整的:http://stackoverflow.com/questions/3085153/how-to-parse-the-manifest-mbdb-file-in-an-ios-4-0-itunes-backup 还有一个更详细的:http://code.google.com/p/iphonebackupbrowser/ 关于文件的命名是 domain + "-" + filename 的sha-1的值。