請勿轉(zhuǎn)載哨颂,謝謝3的!骡尽!?
全解析框架和信息篡改
引
前兩篇主要在已有的項目dexparser基礎(chǔ)上忿檩,做的研究和補充;但是想對dex做修改的話爆阶,這個就不夠了。
所以我自己做了一個解析框架,這個框架將dex分解為層級對象辨图,并且可以將層級對象重新還原回dex格式中班套。
框架代碼地址: https://github.com/callmejacob/dexfactory
android dex文件格式:
https://source.android.google.cn/devices/tech/dalvik/dex-format
android源碼中對dex格式的解析和校驗:
http://androidxref.com/8.0.0_r4/xref/dalvik/libdex/
框架結(jié)構(gòu)
dex文件可以看成是一個section的列表,每個section里包含一個item列表故河,而每個item中又可能嵌套某個數(shù)據(jù)結(jié)構(gòu)data吱韭。
其中,section列表的信息(類型鱼的,子項數(shù)目理盆,文件偏移量)最終會記錄在叫MAP_LIST的section段中。
基于此凑阶,首先抽象出一個字節(jié)數(shù)組對象類(BytesObject)猿规,它包含一個字節(jié)數(shù)組和解碼編碼的方法,解碼用于從該字節(jié)數(shù)組中獲取一個對象信息宙橱,編碼用于將對象信息重新壓縮回字節(jié)數(shù)組中姨俩。
上面提到的data使用BaseData抽象,item使用BaseItem抽象师郑,section使用BaseSection抽象环葵。
繼承關(guān)系如下:
每個section都是有類型的:(按官方文檔,這里缺失一些類型宝冕,需要繼續(xù)補充)
基于抽象基類和類型张遭,我們定義基于BaseItem的各個類型的子類,并做item類的映射表:
并且定義基于BaseSection的各個類型的子類地梨,并做section類的映射表:
為了能夠跨越section獲取信息菊卷,定義一個上下文的類Context,它包含了section的映射表:
最后定義一個Dex文件的信息類DexInfo湿刽,它負責(zé)打開dex文件的烁,解碼,編碼诈闺,保存渴庆,打印等等。
最主要的流程還是解碼和編碼的過程:
這里面的難點主要是文件偏移量和排序問題雅镊。
dex的數(shù)據(jù)結(jié)構(gòu)中襟雷,很多是直接用文件偏移量表示的,可是該文件偏移量對應(yīng)的項信息發(fā)生了更改(特別是文件偏移量需要調(diào)整的時候)仁烹,就會出現(xiàn)混亂耸弄;還有android的libdex在解析dex時會做很多順序的校驗,比如string_ids列表的數(shù)字必須從低到高等卓缰。
為此计呈,我做了兩重映射:? off? <>? id? <>? item
其中off是指文件偏移量砰诵,id是指對應(yīng)的子項在section中的索引編號,而item就是對應(yīng)的子項捌显。
在解碼過程中茁彭,從Dex里解析到的是off,然后使用[ off ---> id ]轉(zhuǎn)換扶歪,再做[ id ---> item ]轉(zhuǎn)換理肺,這樣子項item里的信息,就包含了其它section中相應(yīng)的id和item信息善镰。
在編碼過程中妹萨,因為section里的子項列表可能做了調(diào)整,所以先做[ item ---> id ]轉(zhuǎn)換(同時按照新的id進行排序)炫欺,再做[ id ---> off ]轉(zhuǎn)換乎完,這樣最后的偏移量就是準確的偏移量了。
測試程序和字符串修改
其中修改函數(shù)如下:
運行結(jié)果:
使用dexdump可以立即檢測下新的dex文件是否有問題:
dexdump classes_new.dex
如果發(fā)現(xiàn)錯誤信息竣稽,可以到android源碼中的dalvik/libdex中囱怕,找尋相應(yīng)的提示來定位問題。
最后毫别,將新的dex文件替換掉原有apk中的dex文件娃弓,重新用zip壓縮為apk,并重新簽名岛宦。
這里提供一個mac上的簽名工具:
地址:? 鏈接: https://pan.baidu.com/s/1kXiUgFt 密碼: xy6j
使用:? signapk.sh xxx.apk xxx_signed.apk
需要完善的地方
1. 類型不完全
2. 排序功能不完全
3. 字節(jié)碼反編譯框架
4. 數(shù)據(jù)使用需要優(yōu)化