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
```c
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,因此要转换
http://fgsink.blog.163.com/blog/static/16716997020124179455097/
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层调用获取命中包的列表,参数为包的路径。
checkRiskInfo检查字符串的函数,调用了findtargetstring来查找。