鸿蒙资源文件resources.index格式解析

1,125 阅读2分钟

文件路径

hap包解压缩后就能看到resources.index文件

文件格式学习

gitee.com/openharmony… OpenHarmony资源编译工具

结合资源编译工具代码反向学习。

把文件拖入hexed.it/ 对照学习。

文件头

 struct IndexHeader {
        int8_t version[VERSION_MAX_LEN]; 
        uint32_t fileSize;
        uint32_t limitKeyConfigSize;
    };

例子中

  • version =Restool 4.005
  • fileSize=0x0444
  • limitKeyConfigSize =3

LimitKeyConfig

 struct LimitKeyConfig {
        int8_t keyTag[TAG_LEN] = {'K', 'E', 'Y', 'S'};
        uint32_t offset; // IdSet file address offset
        uint32_t keyCount; // KeyParam count
        std::vector<int32_t> data;
    };

KeyParam

struct KeyParam {
    KeyType keyType;
    uint32_t value;
};
enum class KeyType {
    LANGUAGE = 0,
    REGION = 1,
    RESOLUTION = 2,
    ORIENTATION = 3,
    DEVICETYPE = 4,
    SCRIPT = 5,
    NIGHTMODE = 6,
    MCC = 7,
    MNC = 8,
    // RESERVER 9
    INPUTDEVICE = 10,
    KEY_TYPE_MAX,
};

比如这里 0x00000000是LANGUAGE 对应en ,0x00000001是REGION 对应US

IdSet

 struct IdSet {
        int8_t idTag[TAG_LEN] = {'I', 'D', 'S', 'S'};
        uint32_t idCount;
        std::map<int32_t, uint32_t> data; // pair id and offset
    };

IdData

struct IdData {
    uint32_t id;
    uint32_t dataOffset;
};

比如data中 0x01000000 为id, 0x015c为dataoffset

RecordItem

 struct RecordItem {
        uint32_t size;
        int32_t resType;
        int32_t id;
    };

enum class ResType {
    ELEMENT = 0,
    RAW = 6,
    INTEGER = 8,
    STRING = 9,
    STRARRAY = 10,
    INTARRAY = 11,
    BOOLEAN = 12,
    COLOR = 14,
    ID = 15,
    THEME = 16,
    PLURAL = 17,
    FLOAT = 18,
    MEDIA = 19,
    PROF = 20,
    PATTERN = 22,
    INVALID_RES_TYPE = -1,
};

比如这里的0x01000000 资源id type是0x9也就是 String类型

资源Value

uint16_t 的value_size + int8_t values[value_size];组成

比如这边value_size = 0x000E, value就是MyApplication

资源Name

uint16_t name_size + int8_t name[name_size]

比如这里name_size = 0x0009 name 就是app_name

再看一个media资源获取的例子。

Type是0x13 = MEDIA resId = 0x01000001

Value size=0x28 value = entry/resources/base/media/app_icon.png

Name_size = 0x09 value = app_icon

关键的offset

在LimitKeyConfig 和IdData 中我们都有去获取dataOffset

上面获取到资源的name 和 value,我们还需要把资源和资源id还有 资源国家语言等关联上,这边就是通过dataOffset去LimitKeyConfig和IdData找对应的关联关系。 这样子我们读取资源时候可以拿到一个ResourceItem

包含以下字段

    int8_t *data_ = nullptr;
    uint32_t dataLen_;
    std::string name_;
    std::vector<KeyParam> keyparams_;
    ResType type_;
    std::string filePath_;
    std::string limitKey_;

总结

目前没有找到鸿蒙resource.index反编译的工具,不过这个自己实现起来也不复杂,看后续官方会不会提供,毕竟排查资源相关问题还是很需要这种工具的。

比Android 中的arsc文件相比 好像简单一些, 可能是自己的鸿蒙demo简单了一些,后续有机会再深入研究

附件

Android arsc文件格式表