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、把a(bǔ)pk讀進(jìn)內(nèi)存,釋放dex。
deflateDexToBuffer(apkName, &dexBuf, &length)
2、內(nèi)存里的dex來(lái)構(gòu)造dexfile
DexFile *pDexFile = dexFileParse(dexBuf, length, flags);
3、在dexfile的頭文件里查找method個(gè)數(shù)
int count = (int) pDexFile->pHeader->methodIdsSize;
4、在dexfile里定義了所有method的id
const DexMethodId* pMethodIds;
循環(huán)讀取里面包含的所有ids
```c
const DexMethodId* dexGetMethodId(const DexFile* pDexFile, u4 idx) {
return &pDexFile->pMethodIds[idx];
5、DexMethodId包含了類(lèi)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、根據(jù)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 ***
調(diào)用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,因此要轉(zhuǎn)換
http://fgsink.blog.163.com/blog/static/16716997020124179455097/
7、獲取method所在class name類(lèi)似,不過(guò)多了一個(gè)步驟。
**步驟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層調(diào)用獲取命中包的列表,參數(shù)為包的路徑。

Paste_Image.png
checkRiskInfo檢查字符串的函數(shù),調(diào)用了findtargetstring來(lái)查找。

Paste_Image.png

Paste_Image.png