zoukankan      html  css  js  c++  java
  • IOS 设备备份文件详解 (二)

    这篇主要讲解如何解析Manifest.mbdb文件。

    使用二进制工具打开这个文件,文件的头6个字节是固定的,相当于是文件的一种标识


    后面的内容是一个一个的项,可以使用一个循环来读取文件,一个一个解析。

    这里有一个概念要先说一下,就是域,域是用来定位一个文件在手机上的全路径。比如上图的 AppDomain-cairot,这个域就表示文件在手机上的目录为 /var/mobile/Applications/,不同的域对应的手机的目录是不一样的,下面给出所有域和目录的一个对应关系,下面是自己的一段代码, 看懂这段代码就知道域和路径的关系了。

    if (item.Domain == "WirelessDomain")
    {
    item.PathOnPhone.Format("/var/wireless/%s", item.Path);
    }
    else if (item.Domain == "ManagedPreferencesDomain")
    {
    item.PathOnPhone.Format("/var/Managed Preferences/%s", item.Path);
    }
    else if (item.Domain == "MediaDomain")
    {
    item.PathOnPhone.Format("/var/mobile/%s", item.Path);
    }
    else if (item.Domain == "SystemPreferencesDomain")
    {
    item.PathOnPhone.Format("/var/preferences/%s", item.Path);
    }
    else if (item.Domain == "CameraRollDomain")
    {
    item.PathOnPhone.Format("/var/mobile/%s", item.Path);
    }
    else if (item.Domain == "RootDomain")
    {
    item.PathOnPhone.Format("/var/root/%s", item.Path);
    }
    else if (item.Domain == "MobileDeviceDomain")
    {
    item.PathOnPhone.Format("/var/MobileDevice/%s", item.Path);
    }
    else if (item.Domain == "KeychainDomain")
    {
    item.PathOnPhone.Format("/var/Keychains/%s", item.Path);
    }
    else if (item.Domain == "HomeDomain")
    {
    item.PathOnPhone.Format("/var/mobile/%s", item.Path);
    }
    else if (item.Domain == "DatabaseDomain")
    {
    item.PathOnPhone.Format("/var/db/%s", item.Path);
    }
    else if (item.Domain.Find("AppDomain-") == 0)
    {
    CAtlStringA strTmp(item.Domain);
    strTmp.Replace("AppDomain-", "");
    item.PathOnPhone.Format("/var/mobile/Applications/%s/%s",strTmp , item.Path);
    }

     

    1) 获取域。 头6个字节之后的2个字节,标识域的长度,但是2字节的内容并不是直接标识长度,看下面的代码。先读出一个字节,然后再读出一个字节,进行运算之后得出的一个长度。下图就是 AppDomain-cairot

     

    std::string CBackupMbdb::ReadNextStringBy2bytesLen(CBinaryReader& reader)
    {
    std::string strResult;
    byte num =  reader.ReadByte();
    byte num2 =  reader.ReadByte();
    if ((num == 0xff) && (num2 == 0xff))
    {
    return strResult;
    }
    int num3 = (num * 0x100) + num2;
    strResult = reader.ReadString(num3);
    return strResult;
    }

     


     

    2) 之后就是手机上路径。这个路径和域组合之后就可以得出文件在iphone 上的全路径了。第一个图中的item.path 就是这个路径,item.Domain 就是域。 根据上面的代码就可以组合出全路径了。这个路径获取方法和域是一样的。先读取文件的2个字节,然后根据这两个字节的大小读取内容。从上图看先读的两个为0000,所以路径就是空字符串。

     

    3)链接路径。这个我也不是很清楚,貌似像是windows 的快捷方式一样,会指向一个其他的路径。反正我没用上这个东西。 读取的方式和前面一样

     

    4) 紧接着数据的一段哈希。先读出2个字节,然后根据这两个字节计算出一个大小,进行一些判断之后把16 进制的数据转换成字符串。

    std::string CBackupMbdb::smethod10(CBinaryReader& reader)
    {
    std::string strResult ;
    byte num =  reader.ReadByte();
    byte num2 =  reader.ReadByte();
    if ((num == 0xff) && (num2 == 0xff))
    {
    return strResult;
    }
    int num6 = (num * 0x100) + num2;
    CAutoVectorPtr<byte> pBuffer;
    pBuffer.Allocate(num6);
    reader.Read(pBuffer.m_p,num6);
    int index = 0;
    index = 0;
    while (index < num6)
    {
    if ((pBuffer.m_p[index] < 0x20) || (pBuffer.m_p[index] >= 0x80))
    {
    break;
    }
    index++;
    }
    if (index == num6)
    {
    strResult = bytes_to_hex_string(pBuffer.m_p,num6);
    }
    return strResult;
    }

    5)  第五个内容的读取方法和第四个一样,但是所有的读出来的都是空字符串。

    6)   读出固定的40个字节,这40个字节里面包含的信息很多,不过大部分都是不需要的,只有一个字段是重要的,这个字段会影响后面的文件读取。

    CAutoVectorPtr<byte> pRecordInfo;
    pRecordInfo.Allocate(40);
    reader.Read(pRecordInfo.m_p,40);

    //0x27 也就是最后的位置保存了这个项的属性个数,要用这个数字循环读出属性来。

    itemInfo.PropertyCount = pRecordInfo[0x27];

    for (int i=0;i<itemInfo.PropertyCount;i++)
    {
    CAtlStringA key = ReadNextStringBy2bytesLen(reader).c_str();
    CAtlStringA value = smethod10(reader).c_str();
    itemInfo.Properties[key] = value;
    }

     

    7)  根据第一步和第二步得出来的域和路径计算SHA1值,这个哈希值也就是本地的路径。

    std::string strHash1Src;
    if (itemInfo.Path.IsEmpty())
    {
    strHash1Src = itemInfo.Domain;
    }
    else
    {
    strHash1Src = itemInfo.Domain + "-" + itemInfo.Path;
    }
    std::string strTmp;
    CAppUtilis::EncrypBySHA1(strHash1Src,strTmp);

    然后一直循环读取文件,直到文件读完就可以解析出所有的文件路径了

     

     

    转让Android,IOS 手机助手各种技术资料,文档,以及源码,有需要的可以联系我QQ: 2506314894

  • 相关阅读:
    Springboot 之 自定义配置文件及读取配置文件
    SQLSERVER系统视图 sql server系统表详细说明
    MySQL Workbench建表时 PK NN UQ BIN UN ZF AI 的含义
    使用Ecplise git commit时出现"There are no stages files"
    maven添加sqlserver的jdbc驱动包
    java将XML文档转换成json格式数据
    java将XML文档转换成json格式数据
    cannot be resolved. It is indirectly referenced from required .class files
    org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value '2012-12-12 12:01:01': not a valid representation (error: Can not parse date "2012-12-
    @Autowired注解和静态方法 NoClassDefFoundError could not initialize class 静态类
  • 原文地址:https://www.cnblogs.com/ios8/p/ios-store2.html
Copyright © 2011-2022 走看看