Dex文件格式
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(函數)舉例
一、把apk讀進內存,釋放dex。
deflateDexToBuffer(apkName, &dexBuf, &length)
二、內存裏的dex來構造dexfile
DexFile *pDexFile = dexFileParse(dexBuf, length, flags);
三、在dexfile的頭文件裏查找method個數
int count = (int) pDexFile->pHeader->methodIdsSize;
四、
在dexfile裏定義了全部method的id
const
DexMethodId
*
pMethodIds
;
循環讀取裏面包含的全部ids
const DexMethodId* dexGetMethodId(const DexFile* pDexFile, u4 idx) {
return &pDexFile->pMethodIds[idx];
五、
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;
六、
根據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,所以要轉換
七、獲取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;
八、保存method的name和所在的class
strcpy(pList->methodInfo[i].name, strmethod);
strcpy(pList->methodInfo[i].classtype, strclass);
如何查找
java層調用獲取命中包的列表,參數爲包的路徑。
checkRiskInfo檢查字符串的函數,調用了findtargetstring來查找。