概述
? ? 最近工作中有個(gè)功能需要對APK中的resources.arsc文件進(jìn)行二進(jìn)制修改,具體就是對arsc文件內(nèi)的資源文件(也就是res文件夾下的文件)路徑就行修改。這里的工作量主要集中在對arsc文件格式的理解,本文從arsc文件格式的角度詳細(xì)講一下與arsc相關(guān)的知識。
ARSC文件
? ? 什么是ARSC文件呢?顧名思義:AndroidReSourCe,也就是與Android資源相關(guān)的一種文件格式。具體角色是提供資源ID到資源文件路徑的映射關(guān)系,具體來說就是R.layout.activity_main(0x7f030000)到res/layout/activity_main.xml的映射關(guān)系,其中R.layout.activity_main就是應(yīng)用開發(fā)過程中所使用的資源ID,關(guān)于它的相關(guān)只是我這邊不展開講了,具體可以參考老羅的文章:Android應(yīng)用程序資源的編譯和打包過程分析。
? ? 下面就來詳細(xì)說下ARSC的文件格式,如下圖:

ARSC文件格式
? ? ARSC文件頭區(qū)域:顧名思義,ARSC的文件頭,主要包含的信息是文件頭大小、整個(gè)文件大小以及包資源區(qū)域中包的個(gè)數(shù)。文件頭的結(jié)構(gòu)比較簡單,總共占據(jù)12個(gè)字節(jié);
? ? 全局字符串區(qū)域:存放全局字符串的區(qū)域,其中比較重要的資源文件路徑也保存在這個(gè)區(qū)域里面,也是本文的重點(diǎn)關(guān)注對象,其結(jié)構(gòu)如下圖:

? ? 其中全局字符串區(qū)域頭包含:區(qū)域類型、區(qū)域頭大小、整個(gè)區(qū)域大小、字符串個(gè)數(shù)、style個(gè)數(shù)、字符串的編碼類型及是否排序(UTF-8/UTF-16/是否排序)、字符串值相對字符串區(qū)域頭的偏移、style值對字符串區(qū)域頭的偏移;字符串偏移區(qū)域包含所有字符串相對字符串值起始位置的偏移;字符串值區(qū)域包含所有字符串的值,其中前兩個(gè)字節(jié)表示字符串的長度,UTF-8字符串以0x00結(jié)尾,UTF-16字符串以0x0000結(jié)尾。
? ? ARSC文件的最后的是包資源區(qū)域,所謂的包就是指的資源包,比如說開發(fā)者自己的開發(fā)的APK就是一個(gè)包,系統(tǒng)的資源也是在一個(gè)包中,該區(qū)域里面包含的信息較多,包括類型先關(guān)與資源相關(guān)的信息。但是,由于我的目的是改變資源文件的路徑,只需修改全局字符串中的內(nèi)容即可,所以這里就不展開講解該區(qū)域了。
資源路徑逆向修改思路
? ? 根據(jù)上文對全局字符串區(qū)域的分析可以看出,如果將全局字符串區(qū)域中資源路徑相關(guān)的字符串值修改,那么系統(tǒng)在運(yùn)行時(shí)就會(huì)按照新的路徑去讀取資源。但是需要注意的是,在修改字符串值的時(shí)候要注意修改對應(yīng)的字符串偏移、字符串大小、全局字符串區(qū)域大小以及ARSC整體文件的大小。最最重要的是,由于全局字符串區(qū)域是4字節(jié)對齊的,在修改字符串值之后也需要調(diào)整成4字節(jié)對齊。
總結(jié)
? ? ARSC文件作為Android應(yīng)用資源的索引文件,其所包含的信息本質(zhì)上是一張資源ID到資源的關(guān)系表。通過逆向修改這張關(guān)系表可以達(dá)到許多意想不到的功能,包括減小APK包體積、藏匿res文件夾,結(jié)合HOOK的話更能做到字符串加密等功能,最后秀一下我的res藏匿效果-_-。
