本篇文章主要是為了讓更多人了解在這周的開源周報中提到的關於 apk 的加殼究竟是什麼

加殼是什麼

加殼,加殼的全稱應該是可執行程序資源壓縮,壓縮後的程序可以直接運行。一般來說加殼的目的是為了阻止外部程序或軟體對加殼程序本身的反彙編分析或者動態分析,以達到保護殼內原始程序以及軟體不被外部程序破壞,保證原始程序正常運行。這種技術也常用來保護軟體版權,防止軟體被破解。但對於病毒,加殼可以繞過一些殺毒軟體的掃描,從而實現它作為病毒的一些入侵或破壞的一些特性。

加殼的方式

其實是利用特殊的演算法,對可執行文件里的資源進行壓縮,這個壓縮之後的文件可以獨立運行,解壓過程完全隱蔽,都在內存中完成。它們附加在原程序上通過載入器載入內存後,先於原始程序執行,得到控制權,執行過程中對原始程序進行解密、還原,完成後再把控制權交還給原始程序,執行原來的代碼部分。這可以隱藏程序真正的入口點從而防止被破解。加上外殼後,原始程序代碼在磁碟文件中一般是以加密後的形式存在的,只在執行時在內存中還原,這樣就可以比較有效地防止破解者對程序文件的非法修改,同時也可以防止程序被靜態反編譯。

Apk 加殼原理

在 Android 中沒有經過加密的 Apk 給人的感覺就是在裸奔,通過apktool , dex2jar , AndroidKill 等各式各樣的反編譯工具就可以輕鬆的獲取其 smail 代碼,程序被反編譯以後,對於懂 smail 語法的逆向工程師來說就一覽無餘了。儘可能給自己的 Apk 多採取一些防護措施已經成為了一種必然。

Apk 加殼的步驟:

源 Apk:需要加殼的 Apk

加密的 Apk:源 Apk 經過加密演算法加密後的 Apk

加殼程序 Apk:是有解密源 Apk 和動態載入啟動源 Apk 的外殼

 

關於 Dex:

他是 Android 系統的可執行文件,包含應用程序的全部操作指令以及運行時數據。當 java 程序編譯成 class 後,還需要使用 dx 工具將所有的class 文件整合到一個 Dex 文件,目的是其中各個類能夠共享數據,在一定程度上降低了冗餘,同時也是文件結構更加緊湊。

文件結構:

Magic

Magic 數是為了方便虛擬機識別目標文件是否是合格的 Dex 文件,在 Dex文件中 magic 的值固定

checksum

文件校驗碼 ,使用 alder32 演算法校驗文件除去 maigc ,checksum 外餘下的所有文件區域 ,用於檢查文件錯誤

signature

使用 SHA-1 演算法 hash 除去 magic ,checksum 和 signature 外餘下的所有文件區域 ,用於唯一識別本文件 。

file_size

當前Dex 文件的大小 。

改動 Dex 文件實際上是改動它的頭部,即記錄整個 Dex 文件相關屬性的部分。改動其文件效驗碼 checksum 才能讓這個合併後的 Dex 文件是正確的,改動 file_size 來重新設定 Dex 文件的大小,最後在文件的末尾標註上加密後 Apk 的大小,這樣在脫殼時就能得到正確的 Apk 了。

將 Dex 與加密演算法加密後的 Apk 合併生成新的Dex 後需要修改新 Dex 文件的這三個值,為了方便從新 Dex 中獲得加密的 Apk,我們需要知道加密的 Apk 的大小,為了方便以後獲得,我們將其大小放置在新 Dex 的後面。新生成的 Dex 文件結構:

生成新 Dex 後,將加殼程序 Apk 的 Dex 文件替換,重新簽名後加殼的Apk 即完成了。