IOS备份文件列表解析(Manifest.mbdb)

C/C++代码 blackfeather


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);



评论列表:

凯哥自媒体
分享是美德,谢谢博主的分享。
凯哥自媒体2017/1/13 11:24:23 回复

发表评论: