IOS通过备份,得到的目录里面是一片乱码(严格来说是sha1编码)。解析出具体的文件列表的分析有很多了,整理了一下,写出来。
大概介绍下,这个文件的开头是“mbdb”,前六个字节一般是固定的“mbdb\05\00”,然后就是一个个结构体。结构体大概是这样子的:
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 long long filelen;
unsigned int flag;
unsigned int numprops;
};
domain就是包名,每个应用都不同。filename就是path。datahash发现现在都是空的了,无用。最后就是那个numprops是附加数据,这个必须处理。flag为0是文件夹或者link,也可以通过filelen来判断是否为文件。
备份目录里面的文件名 = sha1(domain+filename)。
直接贴个代码(引用自p0sixspwn的越狱工具中的代码,改为windows下的代码,VS可直接编译):
mbdb.cpp
/**
* mbdb.cpp
* Copyright (C) 2010 Joshua Hill
* Copyright (C) 2012 Hanéne Samara
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mbdb.h"
mbdb_t *mbdb_create()
{
mbdb_t *mbdb = NULL;
mbdb = (mbdb_t *) malloc(sizeof(mbdb_t));
if (mbdb == NULL) {
return NULL;
}
memset(mbdb, '\0', sizeof(mbdb_t));
return mbdb;
}
mbdb_t *mbdb_parse(unsigned char *data, unsigned int size)
{
int i = 0;
unsigned int count = 0;
unsigned int offset = 0;
mbdb_t *mbdb = NULL;
mbdb_header_t *header = NULL;
mbdb_record_t *record = NULL;
mbdb = mbdb_create();
if (mbdb == NULL) {
printf("Unable to create mbdb\n");
return NULL;
}
header = (mbdb_header_t *) data;
if (strncmp((const char *)header->magic, MBDB_MAGIC, 6) != 0) {
printf("Unable to identify this filetype\n");
return NULL;
}
// Copy in our header data
mbdb->header = (mbdb_header_t *) malloc(sizeof(mbdb_header_t));
if (mbdb->header == NULL) {
printf("Allocation error\n");
return NULL;
}
memset(mbdb->header, '\0', sizeof(mbdb_header_t));
memcpy(mbdb->header, &data[offset], sizeof(mbdb_header_t));
offset += sizeof(mbdb_header_t);
mbdb->data = (unsigned char *)malloc(size);
if (mbdb->data == NULL) {
printf("Allocation Error!!\n");
return NULL;
}
memcpy(mbdb->data, data, size);
mbdb->size = size;
mbdb->records = (mbdb_record_t **) malloc((mbdb->size / 64) * sizeof(mbdb_record_t)); // should be enough
mbdb->num_records = 0;
while (offset < mbdb->size) {
mbdb_record_t *rec = mbdb_record_parse(&(mbdb->data)[offset]);
if (!rec) {
printf("Unable to parse record at offset 0x%x!\n", offset);
break;
}
mbdb->records[mbdb->num_records++] = rec;
offset += rec->this_size;
}
return mbdb;
}
mbdb_t *mbdb_open(unsigned char *file)
{
int err = 0;
unsigned int size = 0;
unsigned char *data = NULL;
mbdb_t *mbdb = NULL;
FILE *pf = fopen((const char *)file, "rb");
if(pf == NULL)
return NULL;
fseek(pf, 0, SEEK_END);
size = ftell(pf);
rewind(pf);
if (size == 0)
{
fclose(pf);
return NULL;
}
data = (unsigned char*)malloc(size + 1);
fread(data, 1, size, pf);
fclose(pf);
mbdb = mbdb_parse(data, size);
if (mbdb == NULL) {
printf("Unable to parse mbdb file\n");
return NULL;
}
free(data);
return mbdb;
}
mbdb_record_t *mbdb_get_record(mbdb_t * mbdb, unsigned int index)
{
return NULL;
}
void mbdb_free(mbdb_t * mbdb)
{
if (mbdb) {
if (mbdb->header) {
free(mbdb->header);
mbdb->header = NULL;
}
if (mbdb->records) {
int i;
for (i = 0; i < mbdb->num_records; i++) {
mbdb_record_free(mbdb->records[i]);
}
free(mbdb->records);
}
if (mbdb->data) {
free(mbdb->data);
}
free(mbdb);
}
}
mbdb_record.cpp
/**
* mbdb_record.cpp
* Copyright (C) 2010 Joshua Hill
* Copyright (C) 2012 Hanéne Samara
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mbdb.h"
mbdb_record_t *mbdb_record_create()
{
mbdb_record_t *record = (mbdb_record_t *) malloc(sizeof(mbdb_record_t));
if (record == NULL) {
printf("Allocation Error!\n");
return NULL;
}
memset(record, '\0', sizeof(mbdb_record_t));
return record;
}
mbdb_record_t *mbdb_record_parse(unsigned char *data)
{
unsigned int offset = 0;
mbdb_record_t *record = mbdb_record_create();
if (record == NULL) {
printf("Unable to parse mbdb record\n");
return NULL;
}
// Parse Domain
unsigned short strsize = be16toh(*((unsigned short *)&data[offset]));
if (strsize > 0 && strsize < 0xFFFF) {
record->domain = (char *)malloc(strsize + 1);
if (record->domain == NULL) {
printf("Allocation Error!\n");
return NULL;
}
offset += 2;
memcpy(record->domain, &data[offset], strsize);
record->domain[strsize] = 0;
offset += strsize;
} else {
record->domain = NULL;
offset += 2;
}
record->domain_size = strsize;
// Parse Path
strsize = be16toh(*((unsigned short *)&data[offset]));
if (strsize > 0 && strsize < 0xFFFF) {
record->path = (char *)malloc(strsize + 1);
if (record->path == NULL) {
printf("Allocation Error!\n");
return NULL;
}
offset += 2;
memcpy(record->path, &data[offset], strsize);
record->path[strsize] = 0;
offset += strsize;
} else {
record->path = NULL;
offset += 2;
}
record->path_size = strsize;
// Parse Target
strsize = be16toh(*((unsigned short *)&data[offset]));
if (strsize > 0 && strsize < 0xFFFF) {
record->target = (char *)malloc(strsize + 1);
if (record->target == NULL) {
printf("Allocation Error!\n");
return NULL;
}
offset += 2;
memcpy(record->target, &data[offset], strsize);
record->target[strsize] = 0;
offset += strsize;
} else {
record->target = NULL;
offset += 2;
}
record->target_size = strsize;
// parse DataHash
strsize = be16toh(*((unsigned short *)&data[offset]));
if (strsize > 0 && strsize < 0xFFFF) {
record->datahash = (char *)malloc(strsize);
if (record->datahash == NULL) {
printf("Allocation Error!\n");
return NULL;
}
offset += 2;
memcpy(record->datahash, &data[offset], strsize);
offset += strsize;
} else {
record->datahash = NULL;
offset += 2;
}
record->datahash_size = strsize;
// parse unknown1
strsize = be16toh(*((unsigned short *)&data[offset]));
if (strsize > 0 && strsize < 0xFFFF) {
record->unknown1 = (char *)malloc(strsize + 1);
if (record->unknown1 == NULL) {
printf("Allocation Error!\n");
return NULL;
}
offset += 2;
memcpy(record->unknown1, &data[offset], strsize);
record->unknown1[strsize] = 0;
offset += strsize;
} else {
record->unknown1 = NULL;
offset += 2;
}
record->unknown1_size = strsize;
record->mode = be16toh(*((unsigned short *)&data[offset]));
offset += 2;
record->unknown2 = be32toh(*((unsigned int *)&data[offset]));
offset += 4;
record->inode = be32toh(*((unsigned int *)&data[offset]));
offset += 4;
record->uid = be32toh(*((unsigned int *)&data[offset]));
offset += 4;
record->gid = be32toh(*((unsigned int *)&data[offset]));
offset += 4;
record->time1 = be32toh(*((unsigned int *)&data[offset]));
offset += 4;
record->time2 = be32toh(*((unsigned int *)&data[offset]));
offset += 4;
record->time3 = be32toh(*((unsigned int *)&data[offset]));
offset += 4;
record->length = be64toh(*((unsigned long long *)&data[offset]));
offset += 8;
record->flag = *((unsigned char *)&data[offset]);
offset += 1;
record->property_count = *((unsigned char *)&data[offset]);
offset += 1;
if (record->property_count > 0) {
record->properties =
(mbdb_record_property_t **) malloc(sizeof(mbdb_record_property_t *)
* record->property_count);
int i;
for (i = 0; i < record->property_count; i++) {
mbdb_record_property_t *prop =
(mbdb_record_property_t *)malloc(sizeof(mbdb_record_property_t));
prop->name_size = be16toh(*((unsigned short *)&data[offset]));
prop->name = (char *)malloc(prop->name_size + 1);
offset += 2;
memcpy(prop->name, &data[offset], prop->name_size);
prop->name[prop->name_size] = 0;
offset += prop->name_size;
prop->value_size = be16toh(*((unsigned short *)&data[offset]));
prop->value = (char *)malloc(prop->value_size + 1);
offset += 2;
memcpy(prop->value, &data[offset], prop->value_size);
prop->value[prop->value_size] = 0;
offset += prop->value_size;
record->properties[i] = prop;
}
}
record->this_size = offset;
//mbdb_record_debug(record);
return record;
}
/*
struct mbdb_record_t {
char* domain;
char* path;
char* target; // absolute path
char* datahash; // SHA1 hash
char* unknown1;
unsigned short mode; // Axxx = symlink, 4xxx = dir, 8xxx = file
unsigned int unknown2;
unsigned int inode;
unsigned int uid;
unsigned int gid;
unsigned int time1;
unsigned int time2;
unsigned int time3;
unsigned long long length; // 0 if link or dir
unsigned char flag; // 0 if link or dir
unsigned char properties; // number of properties
} __attribute__((__packed__));
*/
void mbdb_record_free(mbdb_record_t * record)
{
if (record) {
if (record->domain) {
free(record->domain);
}
if (record->path) {
free(record->path);
}
if (record->target) {
free(record->target);
}
if (record->datahash) {
free(record->datahash);
}
if (record->unknown1) {
free(record->unknown1);
}
if (record->property_count > 0) {
int i;
for (i = 0; i < record->property_count; i++) {
if (record->properties[i]->name) {
free(record->properties[i]->name);
}
if (record->properties[i]->value) {
free(record->properties[i]->value);
}
free(record->properties[i]);
}
free(record->properties);
}
free(record);
}
}
void mbdb_record_debug(mbdb_record_t * record)
{
DEBUG("mbdb record\n");
DEBUG("\tdomain = %s\n", record->domain);
DEBUG("\tpath = %s\n", record->path);
DEBUG("\ttarget = %s\n", record->target);
DEBUG("\tdatahash = %p\n", record->datahash);
DEBUG("\tunknown1 = %s\n", record->unknown1);
DEBUG("\tmode = 0%o (0x%x)\n", record->mode, record->mode);
DEBUG("\tunknown2 = 0x%x\n", record->unknown2);
DEBUG("\tinode = 0x%x\n", record->inode);
DEBUG("\tuid = %d\n", record->uid);
DEBUG("\tgid = %d\n", record->gid);
DEBUG("\ttime1 = 0x%x\n", record->time1);
DEBUG("\ttime2 = 0x%x\n", record->time2);
DEBUG("\ttime3 = 0x%x\n", record->time3);
DEBUG("\tlength = %llu\n", record->length);
DEBUG("\tflag = 0x%x\n", record->flag);
DEBUG("\tproperty_count = %d\n", record->property_count);
}
void mbdb_record_init(mbdb_record_t * record)
{
if (!record) {
return;
}
memset(record, '\0', sizeof(mbdb_record_t));
record->target_size = 0xFFFF;
record->datahash_size = 0xFFFF;
record->unknown1_size = 0xFFFF;
record->this_size =
2 + 2 + 2 + 2 + 2 + 2 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 8 + 1 + 1;
}
void mbdb_record_set_domain(mbdb_record_t * record, const char *domain)
{
if (!record)
return;
unsigned short old_size = record->domain_size;
if (record->domain) {
free(record->domain);
record->domain = NULL;
}
if (record->domain_size > 0 && record->domain_size < 0xFFFF) {
record->this_size -= record->domain_size;
}
if (domain && (strlen(domain) > 0)) {
record->domain_size = strlen(domain);
record->domain = strdup(domain);
record->this_size += record->domain_size;
} else {
record->domain_size = 0;
}
}
void mbdb_record_set_path(mbdb_record_t * record, const char *path)
{
if (!record)
return;
unsigned short old_size = record->path_size;
if (record->path) {
free(record->path);
record->path = NULL;
}
if (record->path_size > 0 && record->path_size < 0xFFFF) {
record->this_size -= record->path_size;
}
if (path && (strlen(path) > 0)) {
record->path_size = strlen(path);
record->path = strdup(path);
record->this_size += record->path_size;
} else {
record->path_size = 0;
}
}
void mbdb_record_set_target(mbdb_record_t * record, const char *target)
{
if (!record)
return;
unsigned short old_size = record->target_size;
if (record->target) {
free(record->target);
record->target = NULL;
}
if (record->target_size > 0 && record->target_size < 0xFFFF) {
record->this_size -= record->target_size;
}
if (target && (strlen(target) > 0)) {
record->target_size = strlen(target);
record->target = strdup(target);
record->this_size += record->target_size;
} else {
record->target_size = 0xFFFF;
}
}
void mbdb_record_set_datahash(mbdb_record_t * record, const char *hash,
unsigned short hash_size)
{
if (!record)
return;
unsigned short old_size = record->datahash_size;
if (record->datahash) {
free(record->datahash);
record->datahash = NULL;
}
if (record->datahash_size > 0 && record->datahash_size < 0xFFFF) {
record->this_size -= record->datahash_size;
}
if (hash && (hash_size > 0)) {
record->datahash_size = hash_size;
record->datahash = (char *)malloc(hash_size);
memcpy(record->datahash, hash, hash_size);
record->this_size += record->datahash_size;
} else {
record->datahash_size = 0xFFFF;
}
}
void mbdb_record_set_unknown1(mbdb_record_t * record, const char *data,
unsigned short size)
{
if (!record)
return;
unsigned short old_size = record->unknown1_size;
if (record->unknown1) {
free(record->unknown1);
record->unknown1 = NULL;
}
if (record->unknown1_size > 0 && record->unknown1_size < 0xFFFF) {
record->this_size -= record->unknown1_size;
}
if (data && (size > 0)) {
record->unknown1_size = size;
record->unknown1 = (char *)malloc(size);
memcpy(record->unknown1, data, size);
record->this_size += record->unknown1_size;
} else {
record->unknown1_size = 0xFFFF;
}
}
void mbdb_record_set_mode(mbdb_record_t * record, unsigned short mode)
{
if (!record)
return;
record->mode = mode;
}
void mbdb_record_set_unknown2(mbdb_record_t * record, unsigned int unknown2)
{
if (!record)
return;
record->unknown2 = unknown2;
}
void mbdb_record_set_inode(mbdb_record_t * record, unsigned int inode)
{
if (!record)
return;
record->inode = inode;
}
void mbdb_record_set_uid(mbdb_record_t * record, unsigned int uid)
{
if (!record)
return;
record->uid = uid;
}
void mbdb_record_set_gid(mbdb_record_t * record, unsigned int gid)
{
if (!record)
return;
record->gid = gid;
}
void mbdb_record_set_time1(mbdb_record_t * record, unsigned int time1)
{
if (!record)
return;
record->time1 = time1;
}
void mbdb_record_set_time2(mbdb_record_t * record, unsigned int time2)
{
if (!record)
return;
record->time2 = time2;
}
void mbdb_record_set_time3(mbdb_record_t * record, unsigned int time3)
{
if (!record)
return;
record->time3 = time3;
}
void mbdb_record_set_length(mbdb_record_t * record, unsigned long long length)
{
if (!record)
return;
record->length = length;
}
void mbdb_record_set_flag(mbdb_record_t * record, unsigned char flag)
{
if (!record)
return;
record->flag = flag;
}
//
// int mbdb_record_build(mbdb_record_t * record, unsigned char **data,
// unsigned int *size)
// {
// unsigned int offset = 0;
// unsigned char *data_buf = NULL;
//
// if (!record) {
// return -1;
// }
//
// data_buf = (unsigned char *)malloc(record->this_size);
// if (!data_buf) {
// printf("Allocation Error!\n");
// return -1;
// }
//
// unsigned short strsize;
//
// // append Domain
// strsize = htobe16(record->domain_size);
// memcpy(&data_buf[offset], &strsize, 2);
// offset += 2;
// if (record->domain != NULL) {
// memcpy(&data_buf[offset], record->domain, record->domain_size);
// offset += record->domain_size;
// }
// // append Path
// strsize = htobe16(record->path_size);
// memcpy(&data_buf[offset], &strsize, 2);
// offset += 2;
// if (record->path != NULL) {
// memcpy(&data_buf[offset], record->path, record->path_size);
// offset += record->path_size;
// }
// // append Target
// strsize = htobe16(record->target_size);
// memcpy(&data_buf[offset], &strsize, 2);
// offset += 2;
// if (record->target != NULL) {
// memcpy(&data_buf[offset], record->target, record->target_size);
// offset += record->target_size;
// }
// // append DataHash
// strsize = htobe16(record->datahash_size);
// memcpy(&data_buf[offset], &strsize, 2);
// offset += 2;
// if (record->datahash != NULL) {
// memcpy(&data_buf[offset], record->datahash, record->datahash_size);
// offset += record->datahash_size;
// }
// // append unknown1
// strsize = htobe16(record->unknown1_size);
// memcpy(&data_buf[offset], &strsize, 2);
// offset += 2;
// if (record->unknown1 != NULL) {
// memcpy(&data_buf[offset], record->unknown1, record->unknown1_size);
// offset += record->unknown1_size;
// }
//
// unsigned short mode = htobe16(record->mode);
// memcpy(&data_buf[offset], &mode, 2);
// offset += 2;
//
// int unknown2 = htobe32(record->unknown2);
// memcpy(&data_buf[offset], &unknown2, 4);
// offset += 4;
//
// int inode = htobe32(record->inode);
// memcpy(&data_buf[offset], &inode, 4);
// offset += 4;
//
// int uid = htobe32(record->uid);
// memcpy(&data_buf[offset], &uid, 4);
// offset += 4;
//
// int gid = htobe32(record->gid);
// memcpy(&data_buf[offset], &gid, 4);
// offset += 4;
//
// int time1 = htobe32(record->time1);
// memcpy(&data_buf[offset], &time1, 4);
// offset += 4;
//
// int time2 = htobe32(record->time2);
// memcpy(&data_buf[offset], &time2, 4);
// offset += 4;
//
// int time3 = htobe32(record->time3);
// memcpy(&data_buf[offset], &time3, 4);
// offset += 4;
//
// unsigned long long length = htobe64(record->length);
// memcpy(&data_buf[offset], &length, 8);
// offset += 8;
//
// unsigned char flag = record->flag;
// memcpy(&data_buf[offset], &flag, 1);
// offset++;
//
// unsigned char prop = record->property_count;
// memcpy(&data_buf[offset], &prop, 1);
// offset++;
//
// // add properties
// int i;
// for (i = 0; i < (int)prop; i++) {
// mbdb_record_property_t *property = record->properties[i];
//
// unsigned short pnsize = htobe16(property->name_size);
// memcpy(&data_buf[offset], &pnsize, 2);
// offset += 2;
// memcpy(&data_buf[offset], property->name, property->name_size);
// offset += property->name_size;
//
// unsigned short pvsize = htobe16(property->value_size);
// memcpy(&data_buf[offset], &pvsize, 2);
// offset += 2;
// memcpy(&data_buf[offset], property->value, property->value_size);
// offset += property->value_size;
// }
//
// if (record->this_size != offset) {
// *data = NULL;
// *size = 0;
// ERROR
// ("%s: ERROR: inconsistent record size (present %d != created %d)\n",
// __func__, record->this_size, offset);
// return -1;
// }
//
// *data = data_buf;
// *size = offset;
//
// return 0;
// }
mbdb.h
/**
* GreenPois0n
* Copyright (C) 2010 Chronic-Dev Team
* Copyright (C) 2010 Joshua Hill
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef _MBDB_H_
#define _MBDB_H_
struct mbdb_t;
#pragma pack(1)
struct mbdb_record_property_t {
unsigned short name_size;
char *name;
unsigned short value_size;
char *value;
};
typedef struct mbdb_record_property_t mbdb_record_property_t;
struct mbdb_record_t {
unsigned short domain_size;
char *domain;
unsigned short path_size;
char *path;
unsigned short target_size;
char *target; // absolute path
unsigned short datahash_size;
char *datahash; // SHA1 hash
unsigned short unknown1_size;
char *unknown1;
unsigned short mode; // Axxx = symlink, 4xxx = dir, 8xxx = file
unsigned int unknown2;
unsigned int inode;
unsigned int uid;
unsigned int gid;
unsigned int time1;
unsigned int time2;
unsigned int time3;
unsigned long long length; // 0 if link or dir
unsigned char flag; // 0 if link or dir
unsigned char property_count; // number of properties
mbdb_record_property_t **properties; // properties
unsigned int this_size; // size of this record in bytes
};
#pragma pack()
#define be16toh(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
#define be32toh(x) ((((x) & 0xFF000000) >> 24) \
| (((x) & 0x00FF0000) >> 8) \
| (((x) & 0x0000FF00) << 8) \
| (((x) & 0x000000FF) << 24))
#define be64toh(x) ((((x) & 0xFF00000000000000ull) >> 56) \
| (((x) & 0x00FF000000000000ull) >> 40) \
| (((x) & 0x0000FF0000000000ull) >> 24) \
| (((x) & 0x000000FF00000000ull) >> 8) \
| (((x) & 0x00000000FF000000ull) << 8) \
| (((x) & 0x0000000000FF0000ull) << 24) \
| (((x) & 0x000000000000FF00ull) << 40) \
| (((x) & 0x00000000000000FFull) << 56))
typedef struct mbdb_record_t mbdb_record_t;
mbdb_record_t *mbdb_record_create();
mbdb_record_t *mbdb_record_parse(unsigned char *data);
void mbdb_record_debug(mbdb_record_t * record);
void mbdb_record_free(mbdb_record_t * record);
void mbdb_record_init(mbdb_record_t * record);
void mbdb_record_set_domain(mbdb_record_t * record, const char *domain);
void mbdb_record_set_path(mbdb_record_t * record, const char *path);
void mbdb_record_set_target(mbdb_record_t * record, const char *target);
void mbdb_record_set_datahash(mbdb_record_t * record, const char *hash,
unsigned short hash_size);
void mbdb_record_set_unknown1(mbdb_record_t * record, const char *data,
unsigned short size);
void mbdb_record_set_mode(mbdb_record_t * record, unsigned short mode);
void mbdb_record_set_unknown2(mbdb_record_t * record, unsigned int unknown2);
void mbdb_record_set_inode(mbdb_record_t * record, unsigned int inode);
void mbdb_record_set_uid(mbdb_record_t * record, unsigned int uid);
void mbdb_record_set_gid(mbdb_record_t * record, unsigned int gid);
void mbdb_record_set_time1(mbdb_record_t * record, unsigned int time1);
void mbdb_record_set_time2(mbdb_record_t * record, unsigned int time2);
void mbdb_record_set_time3(mbdb_record_t * record, unsigned int time3);
void mbdb_record_set_length(mbdb_record_t * record, unsigned long long length);
void mbdb_record_set_flag(mbdb_record_t * record, unsigned char flag);
// TODO sth like mbdb_record_add_property()
//int mbdb_record_build(mbdb_record_t * record, unsigned char **data,
// unsigned int *size);
#define MBDB_MAGIC "\x6d\x62\x64\x62\x05\x00"
typedef struct mbdb_header {
unsigned char magic[6]; // 'mbdb\5\0'
} mbdb_header_t;
typedef struct mbdb_t {
unsigned int size;
unsigned char *data;
mbdb_header_t *header;
int num_records;
mbdb_record_t **records;
} mbdb_t;
extern mbdb_t *apparition_mbdb;
mbdb_t *mbdb_create();
mbdb_t *mbdb_open(unsigned char *file);
mbdb_t *mbdb_parse(unsigned char *data, unsigned int size);
mbdb_record_t *mbdb_get_record(mbdb_t * mbdb, unsigned int offset);
void mbdb_free(mbdb_t * mbdb);
#endif
用法:
将mbdb.cpp、mbdb_record.cpp、mbdb.h添加到工程中,包含.h。
mbdb_t * pList = mbdb_open((unsigned char *)"Manifest.mbdb");
//遍历
for (int i = 0; i < pList->num_records; i++)
{
printf("%s - %s\n", pList->records[i]->domain, pList->records[i]->path);
}
mbdb_free(pList);
2016/7/25 | Tags:IOS,backup,Manifest.mbdb | C/C++代码 | 查看评论(1)