1.Android 程序的生成步骤
- aapt 打包资源文件, 生成R.java, resources.arsc
- 处理aidl文件, 生成相应接口文件
- javac编译工程文件, 生成class文件
- NDK编译C/C++文件
- dx转换所有class文件生成classes.dex (压缩常量池等工作)
- apkbuilder打包生成apk
- jarsigner或signapk给apk签名
- zipalign apk
2.Android 程序的安装流程
四种安装方式:
1.系统应用安装――开机时完成,没有安装界面
2.网络下载应用安装――通过market应用完成,没有安装界面
3.ADB工具安装――没有安装界面
4.第三方应用安装――通过SD卡里的APK文件安装,有安装界面,由packageinstaller.apk应用处理安装及卸载过程的界面。
应用安装的流程及路径 应用安装涉及到如下几个目录:
system/app ------------系统自带的应用程序,获得adb root权限才能删除
data/app ---------------用户程序安装的目录。安装时把 apk文件复制到此目录 data/data ---------------存放应用程序的数据 data/dalvik-cache-----将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一)
3.dex文件格式
- dex 文件中的数据结构
类型 | 描述 |
u1 | 等同于uint8_t, 表示1字节的无符号数 |
u2 | 等同于uint16_t, 表示2字节的无符号数 |
u4 | 等同于uint32_t, 表示4字节的无符号数 |
u8 | 等同于uint64_t, 表示8字节的无符号数 |
sleb128 | 有符号LEB128, 可变长1~5字节 |
uleb128 | 无符号LEB128, 可变长1~5字节 |
uleb128p1 | 无符号LEB128值加1, 可变长1~5字节 |
每个LEB128由1~5个字节组成, 所有字节组合在一起表示一个32位数据, 每个字节只有7位有效位, 如果第一个字节的最高位是1, 表示LEB128需要使用到第二个字节, 以此类推, 最多能用5个字节.
- dex 的文件结构
- dex_header dex文件头, 指定dex的属性, 及其他部分在dex中的物理偏移
- string_ids
- type_ids
- proto_ids
- field_ids
- method_ids
- class_def
- data
- link_data 目前为空 struct DexFile { DexHeader Header, DexStringId StringIds[stringIdsSize], DexTypeId TypeIds[typeIdsSize], DexProtoId ProtoIds[protoIdsSize], DexFieldId FieldIds[fieldIdsSize], DexMethodId MethodIds[methodIdsSize], DexClassDef ClassDefs[classDefsSize], DexData Data[], DexLink LinkData };
- Dex文件结构分析
- DexHeader
类型 | 字段名 | 描述 |
u1 | magic[8] | dex版本标识 |
u4 | checksum | adler32检验 |
u1 | signature[kSHA1DigestLen] | SHA-1哈希值, kSHA1DigestLen为20, 见dalvik/libdex/DexFile.h. |
u4 | headerSize | DexHeader结构大小 |
u4 | endianTag | 字节序标记 |
u4 | linkSize | 链接段大小 |
u4 | linkOff | 链接段偏移 |
u4 | mapOff | DexMapList的文件偏移 |
u4 | stringIdsSize | DexStringId的个数 |
u4 | stringIdsOff | DexStringId的文件偏移 |
u4 | typeIdsSize | DexTypeId的个数 |
u4 | typeIdsOff | DexTypeId的文件偏移 |
u4 | protoIdsSize | DexProtoId的个数 |
u4 | protoIdsOff | DexProtoId的文件偏移 |
u4 | fieldIdsSize | DexFieldId的个数 |
u4 | fieldIdsOff | DexFieldId的文件偏移 |
u4 | methodIdsSize | DexMethodId的个数 |
u4 | methodIdsOff | DexMethodId的文件偏移 |
u4 | classDefsSize | DexClassDef的个数 |
u4 | classDefsOff | DexClassDef的文件偏移 |
u4 | dataSize | 数据段的大小 |
u4 | dataOff | 数据段的文件偏移 |
- DexMapList
类型 | 字段 | 描述 |
u4 | size | DexMapItem的个数 |
DexMapItem | list | DexMapItem结构 |
- DexMapItem
类型 | 字段 | 描述 |
u2 | type | kDexType开头的类型 |
u2 | unused | 未使用, 用于字节对齐 |
u4 | size | 指定类型的个数 |
u4 | offset | 指定类型数据的文件偏移 |
- DexStringId
类型 | 字段 | 描述 |
u4 | stringDataOff | 字符串的数据偏移 |
MUTF-8编码
- DexTypeId
类型 | 字段 | 描述 |
u4 | descriptorIdx | 指向DexStringId列表的索引 |
- DexProtoId
类型 | 字段 | 描述 |
u4 | shortyIdx | 指向DexStringId列表的索引 |
u4 | returnTypeIdx | 指向DexTypeId列表的索引 |
u4 | parametersOff | 指向DexTypeList的偏移 |
它表示一个方法声明, shortyIdx为方法声明字符串, returnTypeIdx为方法返回类型字符串, parametersOff指向DexTypeList结构体, 存放了方法的参数列表.
- DexTypeList
类型 | 字段 | 描述 |
u4 | size | DexTypeItem的个数 |
DexTypeItem | list | DexTypeItem结构 |
- DexTypeItem
类型 | 字段 | 描述 |
u2 | typeIdx | 指向DexTypeId列表的索引 |
- DexFieldId
类型 | 字段 | 描述 |
u2 | classIdx | 类的类型, 指向DexTypeId列表的索引 |
u2 | typeIdx | 字段类型, 指向DexTypeId列表的索引 |
u4 | nameIdx | 字段名, 指向DexStringId列表的索引 |
- DexMethodId
类型 | 字段 | 描述 |
u2 | classIdx | 类的类型, 指向DexTypeId列表的索引 |
u2 | protoIdx | 声明类型, 指向DexProtoId列表的索引 |
u4 | nameIdx | 方法名, 指向DexStringId列表的索引 |
- DexClassDef
类型 | 字段 | 描述 |
u4 | classIdx | 类的类型, 指向DexTypeId列表的索引 |
u4 | accessFlags | 访问标志 |
u4 | superclassIdx | 父类类型, 指向DexTypeId列表的索引 |
u4 | interfacesOff | 接口, 指向DexTypeList的偏移 |
u4 | sourceFileIdx | 源文件名, 指向DexStringId列表的索引 |
u4 | annotationsOff | 注解, 指向DexAnnotataionDirectoryItem结构 |
u4 | classDataOff | 指向DexClassData结构的偏移 |
u4 | staticValuesOff | 指向DexEncodedArray结构的偏移 |
- DexClassData
类型 | 字段 | 描述 |
DexClassDataHeader | header | 指定字段与方法的个数 |
DexField | staticFields | 静态字段, DexField结构 |
DexMethod | directMethods | 直接方法, DexMethod结构 |
DexMethod | virtualMethods | 虚方法, DexMethod结构 |
- DexClassDataHeader
类型 | 字段 | 描述 |
u4 | staticFieldsSize | 静态字段个数 |
u4 | instanceFieldsSize | 实例字段个数 |
u4 | staticMethodsSize | 直接方法个数 |
u4 | virtualMethodsSize | 虚方法个数 |
- DexField
类型 | 字段 | 描述 |
u4 | fieldIdx | 指向DexFieldId的索引 |
u4 | accessFlags | 访问标志 |
- DexMethod
类型 | 字段 | 描述 |
u4 | methodIdx | 指向DexMethodId的索引 |
u4 | accessFlags | 访问标志 |
u4 | codeOff | 指向DexCode结构的偏移 |
- DexCode
类型 | 字段 | 描述 | | |
u2 | registersSize | 使用的寄存器个数 | | |
u2 | insSize | 参数个数 | | |
u2 | outsSize | 调用其他方法时, 使用的寄存器个数 | | |
u2 | triesSize | try/catch个数 | | |
u4 | debugInfoOff | 指向调试信息的偏移 | | |
u4 | insnsSize[1] | 指令集 | | |
2字节空间用于结构对齐 | | | | |
try_item[triesSize] | DexTry结构 | | | |
try/catch中handler的个数 | | | | |
catch_handler_item[handlersSize] | DexCatchHandler结构 |
参加 |
4.odex文件格式
- odex文件的生成略
- odex文件的整体结构略
- odex文件结构分析略