iphone的备份2

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的值。