当前位置: 首页 > 工具软件 > fast dex > 使用案例 >

Android培训班(61)dex文件格式2

苏野
2023-12-01

魔数字段,主要就是Dex文件的标识符,它占用4个字节,在目前的源码里是 “dex\n”,它的作用是用来区别其它文件的,比如有一个文件也叫Dex结尾的文件,就可以认为它是Davlik虚拟机运行的文件吗?当然不行,因此这四个字节,就起到与别的结尾也是Dex文件的区分。还有Davlik虚拟机也有优化的Dex,也是通过个字段来区分的,当它是优化的Dex文件时,它的值就变成”dey\n”了。根据这四个字节,就可以识别不同类型的Dex文件了。到这里,已经搞清楚什么是魔数的作用了。


版本字段,主要用来标识Dex文件的版本。目前支持的版本号为“035\0”,不管是否优化的版本,都是使用这个版本号。


检验码字段,主要用来检查从这个字段开始到文件结尾,这段数据是否完整,有没有人修改过,或者传送过程中是否有出错等等。我们知道常常用来检查数据是否完整算法,有CRC32、有SHA128等,但这里采用都不是这两类,而采一个比较特别的算法,叫做adler32,这是在开源zlib里常用的算法,用来检查文件是否完整性。这个算法是由MarkAdler发明的,它的可靠程度跟CRC32差不多,不过还是弱一点点,不过它有一个特好的优点,就是使用软件来计算检验码时比较CRC32要快很多。可见Android系统,就算法上就已经为移动设备进行优化了。

Adler32算法的源码如下:

#defineZLIB_INTERNAL

#include"zlib.h"


#defineBASE 65521UL /* largest prime smaller than 65536 */

#defineNMAX 5552

/*NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <=2^32-1 */


#defineDO1(buf,i) {adler += (buf)[i]; sum2 += adler;}

#defineDO2(buf,i) DO1(buf,i); DO1(buf,i+1);

#defineDO4(buf,i) DO2(buf,i); DO2(buf,i+2);

#defineDO8(buf,i) DO4(buf,i); DO4(buf,i+4);

#defineDO16(buf) DO8(buf,0); DO8(buf,8);


/*use NO_DIVIDE if your processor does not do division in hardware */

#ifdefNO_DIVIDE

# define MOD(a) \

do{ \

if(a >= (BASE << 16)) a -= (BASE << 16); \

if(a >= (BASE << 15)) a -= (BASE << 15); \

if(a >= (BASE << 14)) a -= (BASE << 14); \

if(a >= (BASE << 13)) a -= (BASE << 13); \

if(a >= (BASE << 12)) a -= (BASE << 12); \

if(a >= (BASE << 11)) a -= (BASE << 11); \

if(a >= (BASE << 10)) a -= (BASE << 10); \

if(a >= (BASE << 9)) a -= (BASE << 9); \

if(a >= (BASE << 8)) a -= (BASE << 8); \

if(a >= (BASE << 7)) a -= (BASE << 7); \

if(a >= (BASE << 6)) a -= (BASE << 6); \

if(a >= (BASE << 5)) a -= (BASE << 5); \

if(a >= (BASE << 4)) a -= (BASE << 4); \

if(a >= (BASE << 3)) a -= (BASE << 3); \

if(a >= (BASE << 2)) a -= (BASE << 2); \

if(a >= (BASE << 1)) a -= (BASE << 1); \

if(a >= BASE) a -= BASE; \

}while (0)

# define MOD4(a) \

do{ \

if(a >= (BASE << 4)) a -= (BASE << 4); \

if(a >= (BASE << 3)) a -= (BASE << 3); \

if(a >= (BASE << 2)) a -= (BASE << 2); \

if(a >= (BASE << 1)) a -= (BASE << 1); \

if(a >= BASE) a -= BASE; \

}while (0)

#else

# define MOD(a) a %= BASE

# define MOD4(a) a %= BASE

#endif


/*=========================================================================*/

uLongZEXPORT adler32(adler, buf, len)

uLongadler;

constBytef *buf;

uIntlen;

{

unsignedlong sum2;

unsignedn;


/*split Adler-32 into component sums */

sum2= (adler >> 16) & 0xffff;

adler&= 0xffff;


/*in case user likes doing a byte at a time, keep it fast */

if(len == 1) {

adler+= buf[0];

if(adler >= BASE)

adler-= BASE;

sum2+= adler;

if(sum2 >= BASE)

sum2-= BASE;

returnadler | (sum2 << 16);

}


/*initial Adler-32 value (deferred check for len == 1 speed) */

if(buf == Z_NULL)

return1L;


/*in case short lengths are provided, keep it somewhat fast */

if(len < 16) {

while(len--) {

adler+= *buf++;

sum2+= adler;

}

if(adler >= BASE)

adler-= BASE;

MOD4(sum2); /* only added so many BASE's */

returnadler | (sum2 << 16);

}


/*do length NMAX blocks -- requires just one modulo operation */

while(len >= NMAX) {

len-= NMAX;

n= NMAX / 16; /* NMAX is divisible by 16 */

do{

DO16(buf); /* 16 sums unrolled */

buf+= 16;

}while (--n);

MOD(adler);

MOD(sum2);

}


/*do remaining bytes (less than NMAX, still just one modulo) */

if(len) { /* avoid modulos if none remaining */

while(len >= 16) {

len-= 16;

DO16(buf);

buf+= 16;

}

while(len--) {

adler+= *buf++;

sum2+= adler;

}

MOD(adler);

MOD(sum2);

}


/*return recombined sums */

returnadler | (sum2 << 16);

}

转载于:https://www.cnblogs.com/ajuanabc/archive/2011/07/16/2463187.html

 类似资料: