2015-10-13 53 views
2

讀完this有關Android中代碼混淆的有趣文章,我試圖將其用於研究目的,但將這項技術應用到classes.dex文件後,我遇到了崩潰。Android中的垃圾文字注入

接下來就是我試圖應用這一技術後,運行該代碼:

0006e8:          |[0006e8] com.example.root.bji.MainActivity.paintGUI:()V 
0006f8: 1202         |0000: const/4 v2, #int 0 // #0 
0006fa: 1a01 0000        |0001: const-string v1, "" // [email protected] 
0006fe: 1200         |0003: const/4 v0, #int 0 // #0 
000700: 1303 1400        |0004: const/16 v3, #int 20 // #14 
000704: 3244 0900        |0006: if-eq v4, v4, 000f // +0009 
000708: 2600 0300 0000       |0008: fill-array-data v0, 0000000b // +00000003 
00070e: 0003 0100 1600 0000 1212 0000 0000 ... |000b: array-data (15 units) 
00072c: 0000         |001a: nop // spacer 
00072e: 0000         |001b: nop // spacer 
... more NOPs ... 
000742: 0000         |0025: nop // spacer 
000744: 0000         |0026: nop // spacer 
000746: 1503 087f        |0027: const/high16 v3, #int 2131230720 // #7f08 
... 

給你一些情況下,我要保持清醒一些幽會像在0x6f8 0值到V2寄存器(「const/4 v2,0」=> 12 02),它將在此方法結束時的GUI中顯示(在0x746及更高版本中);並使用這種混淆技術,「隱藏」v2寄存器的修改,在0x716(「const/4 v2,1」=> 12 12)處將值2設置爲v2寄存器。 如果您按照0x704處的代碼執行,那麼分支將完成到0x716,其中「const/4 v2,1」位於fill-data-array-payload內部。

而且我所面臨的問題是,當我運行的代碼崩潰(我已經從4.3到5.1試了一下),當碰撞發生什麼logcat的告訴我是:

W/dalvikvm(13874): VFY: invalid branch target 9 (-> 0xf) at 0x6 
W/dalvikvm(13874): VFY: rejected Lcom/example/root/bji/MainActivity;.paintGUI()V 
W/dalvikvm(13874): VFY: rejecting opcode 0x32 at 0x0006 
W/dalvikvm(13874): VFY: rejected Lcom/example/root/bji/MainActivity;.paintGUI()V 
W/dalvikvm(13874): Verifier rejected class Lcom/example/root/bji/MainActivity; 
W/dalvikvm(13874): Class init failed in newInstance call (Lcom/example/root/bji/MainActivity;) 
D/AndroidRuntime(13874): Shutting down VM 

對於我在日誌中理解的內容,操作系統拒絕了「if-eq」跳轉,因爲偏移指向了(我嘗試了其他分支指令,但結果相同)。代碼工作的唯一方式是如果我指向fill-array-data-payload外的偏移量,但是沒有應用混淆技術:P。

任何人都試過類似這種技術的東西,或者對抗這個分支驗證拒絕?

回答

1

這不是預期工作。字節碼驗證器explicitly checks所有分支的有效性。地址是否是指令或數據的問題由linear walk通過該方法確定。數據塊本質上是非常大的指令,所以它們會被越過。

如果修改.odex輸出,並在類上設置「預先驗證」標誌,以便驗證者不再檢查它,則可以使其工作 - 但無法以這種方式分發APK 。

+0

謝謝fadden和JesusFreke。在更改班級中的預驗證標誌之後,它像4.1虛擬設備上的魅力一樣工作! – ma11p

1

由於達爾維克問題,此「混淆」技術有效。雖然我不確定第一個發佈的版本是否包含修復程序,但在4.3時間範圍內這個問題已得到解決。棒棒糖使用ART,從來沒有這個問題。

這裏是修復了這個問題的變化:https://android-review.googlesource.com/#/c/57985/

+1

您指出的提交似乎是關於無效的訪問標誌,它與問題 –

+1

中描述的技術無關。確實如此。達爾維克驗證者會拒絕任何嘗試使用這種技術的類。如果你看看他們的示例應用程序,爲了解決這個問題,dexlabs們在應用程序的dex文件中修改後的類上設置CLASS_ISPREVERIFIED標誌,防止dalvik驗證程序驗證和拒絕該類。我專門提交了此更改以防止此混淆技術。 – JesusFreke

+0

@JesusFreke現在是否修復了它,或者今天仍然可以使用垃圾字節(或其他保護方法,如DIVILAR)?對於實例,我知道Google不會使用ART編譯新版Android版本的所有代碼(比較2014年的Google IO Video)。如果還有任何可能,將會很有趣。 – Nils