標籤:des android blog http ar io 使用 sp for
一、DEX相關基礎知識
1、什麼是DEX?
DEX是Dalvik EXecutable的簡稱。
打包.class檔案為單一DEX檔案並運行於Dalvik虛擬機器。
DEX檔案打包進APK檔案中(本質上是jar或zip檔案)。
安裝時,系統提取DEX檔案進行檢查和驗證。
第一次運行時,系統完成DEX最佳化,轉換成odex檔案。
odex檔案存放在/data/dalvik-cache目錄並在執行時載入進記憶體執行。
2、DEX檔案格式(查看更多內容請訪問:http://blog.csdn.net/androidsecurity/article/details/8664778)
3、如何查看DEX檔案
目前有以下工具可以完成DEX檔案的反編譯。
二、攻擊者隱藏軟體行為的方法
攻擊者經常採用以下方式隱藏軟體的行為:
1、使用反射調用敏感API
該種方式能夠使攻擊者“隱藏”敏感API調用。但是這種方式只需要查看是否利用JAVA反射即可很容易的被識破。
如果配合代碼混淆技術,就會增加自動化識別的難度。對付這種“隱藏”方式,動態分析會更簡單一些。
2、代碼邏輯“藏匿”在資源檔中
可以通過修改檔案尾碼名隱藏代碼邏輯 ,如:
通過檔案尾碼隱藏可以通過file命令查看檔案類型是否與尾碼匹配很容易識別。
我們還可以做的更加進階一點。將ELF可執行二進位檔案附加在有效圖片檔案中,通過file指令得到正確的檔案類型,且該圖片可以正常顯示:
該種隱藏方式需要我們更加深入的查看所有的資源檔。看著是jpg圖片檔案,但並不一定全是(永遠不要相信自己的眼睛)。
也許還有其它更進階的隱藏惡意代碼的方法。
3、使用DexClassLoader動態載入技術
可以使用Android DexClassLoader完成DEX的動態載入,DEX檔案可以附屬在assert或raw目錄也可以運行時從網路下載。
三、Android反逆向分析之旅
我們可以利用逆向分析工具實現上的缺陷來觸發其奔潰,從而達到反逆向分析的目的。
Android反逆向分析的目標:
Baksmali - 使用最廣泛的DEX反編譯工具 (apktool/antilvl等使用)(https://code.google.com/p/smali/)
dex2jar - 可以把DEX反編譯成jar的工具,然後通過JD-GUI查看。(http://code.google.com/p/dex2jar/)
IDA Pro - (這個就不在介紹了吧!)(https://www.hex-rays.com/index.shtml)
androguard - 也是比較流行的。(https://code.google.com/p/androguard/)
1、構建DEX link section觸發baksmali工具崩潰(DEX檔案結構請查看http://blog.csdn.net/androidsecurity/article/details/8664778)
由於baksmali工具不支援DEX檔案的link section,所以我們可以構建DEX link section觸發baksmali工具奔潰。如:
該方式常用於開發人員阻止破解者逆向分析代碼邏輯。 該方法已經被Lohan+ (AntiLVL) / jcase /和其它項目中使用。但是這種方式也有明顯的缺點,可以根據異常資訊很容易的修複分析工具。
2、利用已知的JAR hack方法
由於APK本質上就是zip/jar包,所以我們也可以利用已知的JAR hack方法。
JAR對檔案名稱的長度是沒有現在的,但是作業系統要求檔案名稱不能大於255;我們可以通過構建大於255字元的長類名來達到反逆向的目的。
如何構建大於255的長類名呢?首先我們看一下DEX Class Def Item的格式:
我們可以通過以下方式構建大於255的長類名:
1、在原始碼中添加大於255的字串A。
2、編譯原始碼,修改DEX檔案頭,修改Class descriptor_id為字串A的String_idx
是修改前後比較:
修改後的APK能夠正常安裝,如:
這種修改方法能夠防止逆向分析,如:
通過異常我們應該可以看出為什麼大於255個字元會報錯了吧。
但是該種方式缺點是只能對付backsmali。 IDA、Dex2jar、Androguard仍然能夠正常工作。
該種方法易於檢測和解決,當class名字長度>255要警惕該應用。
3、插入無效位元組碼指令引發逆向工具崩潰
由於大部分逆向工具都是線性讀取位元組碼並解析,當遇到無效位元組碼時,就會引起反編譯工具位元組碼解析失敗。
我們可以插入無效位元組碼到DEX檔案,但要保證該無效位元組碼永遠不會被執行(否則您的程式就會崩潰了!)。
[java] view plaincopy
1201 // Load 0 into v1
3801 0300 // A conditional jump which should always succeed, jumps over
// next bytes
FFFF // Bad opcodes
安裝插入無效位元組碼的apk檔案。如:
但是執行程式時,卻報如下的錯誤:
啟動並執行時候怎麼會報錯呢?
Dalvik虛擬機器並沒有像我們預想的那樣跳過無效的位元組碼,它會在執行之前驗證所有調用序列上類的位元組碼是否有效。
現在的問題是如何能夠繞過Dalvik虛擬機器的代碼驗證呢?
我們如果插入無效代碼在一個從來不會調用的類上不就可以繞過Dalvik運行時代碼驗證了嗎!
看如下插入後的運行結果:
哈哈,成功運行了,接下來讓我們看看該種方式反逆向的效果吧!
(可惜的backsmali已經在版本2f81aec886d2修複了該bug,該方式已無效)
Dex2jar 驗證可行。
Androguard驗證可行,(可惜的是Androguard很快修複了該bug)
IDA驗證未成功!
ded工具驗證成功!在你殺死該工具進程之前,它將一直運行在無效位元組碼所在類處理過程中。
該種方法的缺點是很容易被工具修複。工具在反編譯代碼時,只要忽略會無效位元組碼的處理即可,backsmali、androgurad已經修複了該bug。
該種方式和很容易被自動化監測,如果遇到無效代碼就要警惕!
逆向分析人員要盡量使用工具的最新版本。
4、插入有效位元組碼指令但後跟無效的資料引用
插入無效的位元組碼指令目前工具已經可以正常工作,但是如果我們插入有效位元組碼指令,但是後跟無效的資料引用,結果會是怎麼樣呢?
[cpp] view plaincopy
1201 // Load 0 into v1
3801 0300 // A conditional jump which should always succeed, jumps over
// next bytes
1a00 FF00 // Load const-string at index 255 (doesn’t exist)
這次我們仍然繞過Dalvik運行時位元組碼指令驗證,但是我們替換“無效位元組碼指令”為合法位元組碼指令
backsmali驗證成功!
dex2jar驗證成功!
Androguard驗證成功,但是只會在反編譯插入該“有效位元組碼指令”的方法報錯。
ded驗證成功!
IDA驗證失敗!
該種方式也很容易被工具修複,逆向工具只要不盲目的解析一個不存在的索引即可。
5、針對java反編譯器缺陷進行攻擊
dex2jar+(JD-Gui或JAD) 組合工具是逆向分析經常使用的工具。dex2jar用於把DEX檔案轉換為java位元組碼JAR檔案,JD-GUI或JAD用於把java位元組碼轉化為java原始碼。
我們可以針對JAVA JD-Gui或JAD工具缺陷來達到反逆向分析的目的。達到的效果如所示:
6、針對backsmali對檔案頭處理缺陷
我們剛才講到baksmali在處理Link section的bug,還有類似的崩潰點嗎?backsmali代碼所示:
當DEX Header size 不等於0x70時,backsmali也會拋出異常退出!
Header_size 當前值正常情況下都等於0x70
構建這種dex檔案很容易實現。
需要修複檔案頭每個表項的位移量。
修改後的Header size 等於0x78
但是這種方式只能針對baksamli工具。且很工具很容易修複該bug。
該方式也可以用於在DEX Header中隱藏資料和代碼。
我們可以在Dex檔案頭隱藏另一個DEX資料並在運行時載入附帶DEX資料。
構建非規範的Dex檔案
通過反射調用DexFile類的方法載入附帶DEX資料(android4.0以上才有我們需要的方 法http://blog.csdn.net/androidsecurity/article/details/9674251)
通過反射實際調用DexFile的openDexFile方法
該種方式允許我們通過byte[]解析dex資料,而無須在再把DEX資料存放區在裝置的某個檔案。
我們可以從安裝APK檔案、記憶體或dalvik-cache等讀取dex資料。
打包好的DEX檔案如所示:
該種方式將給自動化分析工具帶來一個問題,自動化工具會按照dex格式處理DEX檔案而不會處理附帶的dex資料。需要特定的工具、16進位編輯器或手工提取嵌入的dex資料。
我們可以採用各種不同的方式增加嵌入資料的提取難度,比如:
對嵌入的DEX資料進行加密;
嵌入的DEX資料加密後在對其進行ZIP壓縮;
使用native代碼解密,直接從記憶體載入;
......等等
該種隱藏方式可以通過判斷Dex檔案頭長度是否大於0x70檢測。
7、大端小端反轉理論
當前還沒有Android逆向工具實現DEX檔案端反轉(也許IDA支援)。
Dalvik虛擬機器在DEX最佳化過程中會檢測DEX端模式是否適合當前裝置,如果不適合會反轉DEX檔案端模式。
我們需要做的是變換DEX檔案所有位元組端結構,反轉後的DEX檔案可以中斷逆向工具但是仍然可以在裝置上運行。
這種攻擊方式理論上是可行的。我們可以參考Android原始碼實現端的反轉,具體代碼位於/dalvik2/libdex/dexSwapAndVerify.cpp
四、反虛擬機器技術
如何檢測App運行環境是否為qemu虛擬機器呢? 我們可以通過getprop擷取相關資訊,getprop在qemu虛擬機器和行動裝置上很多屬性是不同的。比如:
getprop Android SDK中並沒有公開介面,不過我們可以通過JAVA反射調用。
五、相關引用
http://code.google.com/p/smali/
http://code.google.com/p/androguard/
http://code.google.com/p/dex2jar/
http://siis.cse.psu.edu/ded/
http://hex-rays.com/products/ida/index.shtml
http://source.android.com/tech/dalvik/dex-format.html
英文原版:http://www.strazzere.com/papers/DexEducation-PracticingSafeDex.pdf
該文章發表於Black Hat 2012,雖然內容不夠新鮮,也許好多方法目前已經失效,但是仍然會給我們反逆向方面很多的啟示!
[Android_cracker] Android DEX安全攻防戰