Dex文件格式
dex的定义在DexFile.h里。
typedef struct DexFile {
/* directly-mapped "opt" header */
const DexOptHeader* pOptHeader;
/* pointers to directly-mapped structs and arrays in base DEX */
const DexHeader* pHeader;
const DexStringId* pStringIds;
const DexTypeId* pTypeIds;
const DexFieldId* pFieldIds;
const DexMethodId* pMethodIds;
const DexProtoId* pProtoIds;
const DexClassDef* pClassDefs;
const DexLink* pLinkData;
/* mapped in "auxillary" section */
const DexClassLookup* pClassLookup;
/* points to start of DEX file data */
const u1* baseAddr;
/* track memory overhead for auxillary structures */
int overhead;
/* additional app-specific data structures associated with the DEX */
void* auxData;
} DexFile;
查找dex里class method(函数)举例
1、把apk读进内存,释放dex。
deflateDexToBuffer(apkName, &dexBuf, &length)
2、内存里的dex来构造dexfile
DexFile *pDexFile = dexFileParse(dexBuf, length, flags);
3、在dexfile的头文件里查找method个数
int count = (int) pDexFile->pHeader->methodIdsSize;
4、
在dexfile里定义了所有method的id
const
DexMethodId
*
pMethodIds
;
循环读取里面包含的所有ids
const DexMethodId* dexGetMethodId(const DexFile* pDexFile, u4 idx) {
return &pDexFile->pMethodIds[idx];
5、
DexMethodId
包含了类id和名字id的
信息
typedef struct DexMethodId {
u2 classIdx; /* index into typeIds list for defining class */
u2 protoIdx; /* index into protoIds for method prototype */
u4 nameIdx; /* index into stringIds for method name */
} DexMethodId;
6、
根据nameIdx获取字符串
步骤int nameidx->DexStringId*
stringidx->
u4
stringDataOff->char *
const char* strmethod = dexStringById(pDexFile, mid->nameIdx);
nameidx->stringidx
const DexStringId* pStringId = dexGetStringId(pDexFile, idx);
即
&pDexFile->
pStringIds
[idx];
隐含stringidx->stringDataOff
typedef struct DexStringId {
u4 stringDataOff; /* file offset to string_data_item */
} DexStringId;
stringDataOff->char *
调用dexGetStringData(pDexFile, pStringId);
/* return the
const
char* string data referred to by the given string_id */
const char* dexGetStringData(const DexFile* pDexFile,
const DexStringId* pStringId) {
const u1* ptr = pDexFile->baseAddr + pStringId->stringDataOff;
// Skip the uleb128 length.
while (*(ptr++) > 0x7f) /* empty */ ;
return (const char*) ptr;
}
ps:dex里面用了unsigned leb128,因此要转换
7、获取method所在class name类似,不过多了一个步骤。
步骤classidx->typdidx->
stringidx->stringDataOff->char *
const char* strclass = dexStringByTypeIdx(pDexFile, mid->classIdx);
/*
* Direct-mapped "type_id_item".
*/
typedef struct DexTypeId {
u4 descriptorIdx; /* index into stringIds list for type descriptor */
} DexTypeId;
8、保存method的name和所在的class
strcpy(pList->methodInfo[i].name, strmethod);
strcpy(pList->methodInfo[i].classtype, strclass);
如何查找
java层调用获取命中包的列表,参数为包的路径。
![18143038_OdP8.png](http://static.oschina.net/uploads/img/201404/18143038_OdP8.png)
![18143038_XLgP.png](http://static.oschina.net/uploads/img/201404/18143038_XLgP.png)
![18143038_fkBl.png](http://static.oschina.net/uploads/img/201404/18143038_fkBl.png)
![18143039_R0EG.png](http://static.oschina.net/uploads/img/201404/18143039_R0EG.png)