Android中AndroidManifest ARSC 二進位制檔案修改器AXMLEditor

weixin_34050427發表於2017-08-14

一、情景分析
通常我們在破解apk的時候,第一步肯定先反編譯apk檔案,然後開始修改程式碼和資原始檔,最後回編譯簽名即可。但是現在有些apk做了一定策略,或者apk包如果很大都會導致回編譯失敗,而回編譯如果失敗,對於修改就沒意義了。畢竟我們想回編譯安裝使用我們修改之後的功能。而對於回編譯失敗的問題,也可以花點時間結局的。但是有時候花費的時間不值得,而且也不一定能成功。所以就需要想其他的辦法了。那就是無需反編譯對apk進行修改。其實我們在修改apk的時候就是主要修改三個地方:程式碼+資源+清單檔案。其他的修改很少。那麼我們知道apk檔案其實就是一個壓縮檔案。可以直接使用壓縮軟體開啟。所以如果我們能對dex檔案和arsc檔案直接操作修改。然後在塞進去apk檔案中,在重新簽名就可以了。這樣就避免了反編譯和回編譯了。也可以避免很多操作錯誤了。而關於如何操作這兩類檔案,後一篇文章會詳細介紹。今天我們主要看如何直接修改AndroidManifest ARSC檔案內容。

二、原理分析
弄過反編譯的同學都知道AndroidManifest在apk中是以二進位制形式存在的。也是有固定的儲存格式的。這樣做是為了減少apk的大小。而關於檔案格式,我在之前的文章也做了詳細介紹,不瞭解的同學可以看這篇文章:Android中的清單檔案ARSC格式解析;而且再次說明。一定要看明白這篇文章,不然本文會看的很吃力。而這篇文章其實是藉助了看雪大神MindMac的一張神圖:

2241150-a9148e147b0c56e6

大神是根據AXMLPrinter.jar工具原始碼分析出來的,非常的不容易。關於AXMLPrinter.jar這個工具是專門為解析二進位制檔案AndroidManifest ARSC弄的。網上有很多。而且這個工具是開源的,可以下載原始碼看看。
下面我們就是基於這個檔案的二進位制檔案格式,開始做如下功能的修改器:
第一、操作屬性:刪除,增加,修改功能
第二、操作標籤:刪除,增加功能

而這些功能也是最常用的,下面就來一一介紹如何修改操作:
第一、刪除屬性
我們看完檔案格式之後,知道每個標籤中的屬性值都是存放在標籤塊(StartTagChunk)末尾的。每個屬性是5個欄位,每個欄位是4個位元組。所以一個屬性佔用20個位元組:

2241150-4b254eb8ffc37152

所以如果我們要刪除一個屬性,需要這些條件:
1、屬性所屬的標籤名稱,標籤唯一id也就是name值。
比如我們想刪除xxx.xxx.Activity標籤的一個屬性,那麼得知道是activity標籤,然後是name值找到唯一的標籤
2、屬性的名稱
通過標籤名和唯一id找到標籤對應的塊內容,然後開始利用索引值找到其屬性塊區域,然後在遍歷屬性找到想要刪除的屬性塊直接幹掉這塊位元組。而對於標籤塊的格式如下:
2241150-44b34242aeacb441

簽名都是幾個固定四個位元組大小的極端,有一個欄位需要解析就是屬性個數。因為我們刪除完屬性塊之後,還需要做兩件事:
第一、修改屬性個數
第二、修改標籤塊大小(其實就是減小20個位元組即可)

那麼如何找到標籤塊,其實藉助我們之前自己做的一個AndroidManifest檔案解析工具,下載地址文章後面會給出。直接在那個程式碼基礎上修改即可。我們需要先解析arsc檔案,獲取所有的標籤塊然後儲存到池子中即可。說了這麼多,操作這裡就不貼上程式碼了:

2241150-b74cd6fff7fb0276

這裡還要注意的是:如果只有一個屬性的標籤,在刪除屬性的時候直接可以刪除整個標籤了。刪除標籤後面會詳細介紹。每次操作完成之後,還必須重新寫好總得檔案大小。
總結:
第一步:解析arsc檔案,獲取所有的標籤塊和其屬性塊值。
第二步:利用需要刪除屬性提供的標籤名和id,以及屬性名找到對應的屬性塊資訊,直接刪除這塊位元組即可。
第三步:修改屬性所屬的標籤的屬性個數和整個標籤塊大小。
第四步:修改整個檔案的大小。
注意:如果發現只有一個屬性的標籤,直接刪除這個標籤即可。

第二、新增屬性
在上面的刪除屬性操作基礎上,我們新增一個屬性就簡單了。前幾步還是那麼簡單,首先找到需要新增屬性的標籤塊,因為每個標籤塊的末尾儲存的就是對應的屬性塊資訊,所以直接在該標籤塊的末尾新增一個20個位元組的屬性塊即可。然後在去修改標籤塊的屬性個數,和標籤塊大小即可。但是這裡需要注意是,我們新新增一個屬性,有可能會增加新的字串資訊,我們通過分析檔案格式知道,還有一個字串塊,也就是檔案中所有的字串儲存的地方。
所以在新增屬性的時候,還得先去解析這個字串資訊,然後去判斷當前新增的屬性是否帶來了新的字串值,而不管是屬性還是標籤中的字串都是用索引值儲存的。所以我們需要判斷當前新增的屬性帶來的字串值是否已經存在了,如果存在就直接返回池子中的索引值,不存在就放到字串末尾返回索引值即可。
因為我們有可能修改了字串塊內容。所以我們最後還需要修改字串塊資訊。把最終的字串資訊變成字串塊回寫到檔案中。這個就需要看明白字串塊格式:

2241150-e2c7fe027bd9b65f

這個這裡不在多解釋了,直接看我開源的程式碼即可。
總結:
第一步:解析arsc檔案獲取所有的標籤塊和其屬性塊資訊,以及字串塊資訊
第二步:根據需要插入屬性的標籤名稱和id值,找到對應的標籤塊
第三步:通過新增的屬性資訊構造一個屬性塊資訊,然後直接新增在標籤塊的末尾即可
第四步:更新字串塊資訊,以及標籤塊大小和屬性個數資訊,最後修改檔案大小。
注意:記得還得修改字串塊資訊

第三、修改屬性
其實修改屬性這裡沒那麼複雜操作了,直接利用前面的兩個操作組合完成即可,因為一次修改等於先刪除在新增操作,這裡為了簡單,直接這麼操作了。所以這裡就不多介紹了。

第四、刪除標籤
這個其實和屬性塊刪除操作非常類似,找到標籤塊直接刪除即可。然後修改檔案大小。比刪除屬性還要簡單點。不過這裡需要注意了,在AndroidManifest.xml中存在兩種標籤,一種是和application標籤平級的,比如許可權標籤,一種是在application標籤中的。而在刪除一個標籤必須還需要id值,也就是name屬性值,所以我們還需要獲取到這個標籤塊的屬性值,才能找到對應的標籤塊。而且在刪除一個標籤塊必須刪除開始塊和結束塊。
總結:
第一步:解析arsc檔案獲取全部的標籤塊資訊以及屬性塊資訊
第二步:通過標籤名和標籤id找到指定的標籤塊資訊,直接刪除當前標籤塊即可。
第三步:修改檔案大小。
注意:刪除一個標籤,必須要有name屬性值作為唯一性。所以還得繼續解析他的屬性塊資訊。

第五、新增標籤
這個和新增屬性操作也很類似。因為我們瞭解檔案個時候之後,每個標籤塊是連在一起的,而這些標籤塊是成樹形結構儲存的。最外層的開始標籤,第二層開始標籤.........第二層結束標籤,最外層的結束標籤。所以我們新增一個標籤需要新增開始塊和結束塊。因為我們新增一個屬性不像是新增一個屬性,需要的資訊不是那麼多。假如我們想插入如下標籤塊:

2241150-f0651680fd390f84

如果靠命令輸入那是不現實的。所以這裡我們在插入標籤的時候,依賴的是需要一個xml檔案,而這個檔案中是儲存了需要插入的標籤內容,這樣還可以支援同時插入多個標籤內容。這時候我們就需要首先解析這個插入的xml檔案結構。構造出對應的標籤塊資訊。而我們知道AndroidManifest.xml中分為兩種標籤。一種是和application平級的標籤,一種是application的內部標籤。所以我們需要區分插入對待。因為如果我們想找到標籤的插入口,最好的就是在標籤的開始處,所以這裡如果發現是application平級的標籤,就插入到manifest標籤塊後面即可。如果是application的內部標籤,就插入appliation標籤塊後面即可。
同樣插入一個標籤有可能增加字串資訊,所以還得更新修改字串塊資訊,這個操作在增加標籤中已經介紹了。主要還是繼續看程式碼吧。
總結:
第一步:解析arsc檔案中所有的標籤塊資訊和屬性資訊,同時標記處manifest和application標籤塊的開始位置地址。
第二步:解析需要插入標籤的xml資訊,構造出對應的標籤塊資訊,根據兩種標籤型別直接插入即可。
第三步:修改字串塊資訊,和檔案總大小。
注意:需要區分對待兩種標籤的插入操作。
三、工具用法
好了,上面就介紹完了操作arsc檔案的工具原理,下面來看看工具的用法吧:
第一、用途針對於特定apk反編譯破解之後無法回編譯操作,直接進行arsc檔案的二進位制檔案修改,然後只需要二次簽名即可。無需在進行反編譯和回編譯。第二、用法****1》插入屬性Java -jar AXMLEditor.jar -attr -i [標籤名] [標籤唯一標識] [屬性名] [屬性值] [輸入xml] [輸出xml]案例:java -jar AXMLEditor.jar -attr -i application package debuggable true input_arsc.xml out_arsc.xmlapplication的標籤中插入Android:debuggable="true"屬性,讓程式處於可調式狀態2》刪除屬性java -jar AXMLEditor.jar -attr -r [標籤名] [標籤唯一標識] [屬性名] [輸入xml] [輸出xml]案例:java -jar AXMLEditor.jar -attr -r application allowBackup input_arsc.xml out_arsc.xmlapplication標籤中刪除allowBackup屬性,這樣此app就可以進行沙盒資料備份3》更改屬性java -jar AXMLEditor.jar -attr -m [標籤名] [標籤唯一標識] [屬性名] [屬性值] [輸入xml] [輸出xml]案例:java -jar AXMLEditor.jar -attr -m application package debuggable true input_arsc.xml out_arsc.xmlapplication的標籤中修改android:debuggable="true"屬性,讓程式處於可調式狀態4》插入標籤java -jar AXMLEditor.jar -tag -i [需要插入標籤內容的xml檔案] [輸入xml] [輸出xml]案例:java -jar AXMLEditor.jar -tag -i [insert.xml] input_arsc.xml out_arsc.xml因為插入標籤時一個標籤內容比較多,所以命令方式不方便,而是輸入一個需要插入標籤內容的xml檔案即可。5》刪除標籤java -jar AXMLEditor.jar -tag -r [標籤名] [標籤唯一標識] [輸入xml] [輸出xml]案例:java -jar AXMLEditor.jar -tag -r activity cn.wjdiankong.demo.MainActivity input_arsc.xml out_arsc.xml刪除android:name="cn.wjdiankong.demo.MainActivity"的標籤內容

工具原始碼下載地址:https://github.com/fourbrother/AXMLEditor

四、總結
當然這裡還是有些操作不支援的,比如插入一個activity標籤內容,現在不支援一些特殊的屬性,比如theme型別,因為我們知道這些屬性可能需要引用一些資源。而資原始檔我們現在還沒弄。所以引用資源型別的屬性新增都是失敗的。不過我們一般不會新增這些屬性操作值。關於工具的使用案例分析期待下一篇文章。

更多內容:點選這裡

關注微信公眾號,最新技術乾貨實時推送

2241150-7231d6d9c535fb54

編碼美麗技術圈
微信掃一掃進入我的"技術圈"世界
2241150-ff0f36d9a2ea1696

掃一掃加小編微信新增時請註明:“編碼美麗”非常感謝!
2241150-3f419ab118ca3700

相關文章