dex文件格式
Android 4.0
源码Dalvik/docs
目录下文档dex-format.html
有详细介绍dex文件格式
1.dex文件中的数据结构
dex文件使用到的数据类型
- u1~u8表示1到8字节的无符号数,而sleb128、uleb128与uleb128p1则是dex文件中特有的LEB128数据类型。
- 每个LEB128由1~5个字节组成,所有的字节组合在一起表示一个32位的数据。
- LEB128,每个字节只有7位为有效位,如果第1个字节的最高位为1,表示LEB128需要使用到第2个字节,如果第2个字节的最高位为1,表示会使用到第3个字节,以此类推,直到最后的字节最高位为0,当然,LEB128最多只会使用到5个字节,如果读取5个字节后下一个字节最高位仍为1,则表示该dex文件无效,Dalvik虚拟机在验证dex时会失败返回。
Android
源码dalvik\libdex\Leb128.h
文件中可以找到LEB128的实现,读取无符号LEB128(uleb128)数据的代码:
DEX_INLINE int readUnsignedLeb128(const ul** pStream){
const ul* ptr=*pStream;
int result=*(ptr++);
if(result>0x7f){ //大于0x7f表示第1个字节最高位为1
int cur=*(ptr++); //第2个字节
result=(result&0x7f)|((cur&0x7f)<<7);//前2个字节组合
if(cur>0x7f){ //大于0x7f表示第2个字节最高位为1
cur=*(ptr++); //第3个字节
result|=(cur&0x7f)<<14; //前3个字节的组合
if(cur>0x7f){
cur=*(ptr++); //第4个字节
result|=(cur&0x7f)<<21;//前4个字节的组合
if(cur>0x7f){
cur=*(ptr++); //第5个字节
result|=cur<<28;//前5个字节的组合
}
}
}
}
*pStream=ptr;
return result;
}
对于有符号的LEB128(sleb128)来说,计算方法与无符号的LEB128是一样的,只是对无符号LEB128最后一个字节的最高有效位进行了符号扩展。读取有符号LEB128数据的代码如下:
DEX_INLINE int readSignedLeb128(const ul** pStream){
const ul* ptr=*pStream;
int result=*(ptr++);
if(result<=0x7f){ //小于0x7f表示第1个字节的最高位不为1
result=(result<<25)>>25; //对第1个字节的最高有效位进行符号扩展
}else{
int cur=*(ptr++); //第2个字节
result=(result&0x7f)|((cur&0x7f)<<7);//前2个字节组合
if(cur<=0x7f){
result=(result<<18)>>18;//对结果进行符号位扩展
}else{
cur=*(ptr++); //第3个字节
result|=(cur&0x7f)<<14; //前3个字节的组合
if(cur<=0x7f){
result=(result<<