編輯:關於Android編程
之前講到過,應用開發者為了保護自己的應用不被別人分析和篡改,會將應用的安全性寄托在某個(些)機制上。可以被用來保護應用的機制有很多,效果和實現難度也是各有特點。有這樣一類應用保護方法,叫做針對逆向工具的對抗(Anti-Analysis)。
針對逆向工具的對抗,簡單來講就是利用逆向工具自身的缺陷或者是Android特有的機制,使應用逆向分析工具在工作過程中失效或者報錯崩潰,分析過程無法繼續實施。從而達到保護應用的目的。
這種保護應用的方式的優點就是實現簡單,不需要觸及應用自身的代碼,只需加入簡單的“惡意”代碼即可實現崩潰逆向調試工具的目的。同時作為一種非常規的應用保護方法,思路靈活,經常可以產生意想不到的效果。缺點也很明顯,逆向工具會在新版本中修復這些漏洞和缺陷,研究人員也可以很容易分析出其實現方法,進而進行有針對性的破除。
下面介紹幾種通過“攻擊”逆向工具來保護應用免於被逆向的方法。
Android平台應用文件.apk文件,本質上來說就是一個zip壓縮包。所以一般的應用逆向分析者都是把.apk文件修改後綴為.zip,通過工具解壓縮其中的lib文件和dex文件,再進行進一步分析。但是突然有一天,解壓zip文件的時候,突然發現,apk文件被加密了。
此時,很多人就會覺得非常奇怪,沒辦法了,不知道下一步怎麼辦,甚至想到去爆破密碼,爆破失敗後就放棄了分析。從而應用就達到了某稱程度上的安全保護。
這個的實現原理是這樣的:修改zip的頭,把文件的加密標志設置為ture,但不真正的對包裡面的數據進行加密。還原就把加密標志設置為false.利用了Android處理zip文件不判斷頭裡的加密信息,其他壓縮軟件,java默認實現的zip api都有檢測zip頭中的加密信息。對於這種方法進行保護的APK,直接用bluebox的這個腳本即可搞定。
https://github.com/blueboxsecurity/DalvikBytecodeTampering/blob/master/unpack.py
由於APK本質上就是zip/jar包,所以我們也可以利用已知的JAR hack方法。
JAR對文件名的長度是沒有現在的,但是操作系統要求文件名不能大於255;我們可以通過構建大於255字符的長類名來達到反逆向的目的。
我們可以根據對DEX Class Def Item的格式的學習,實現.
我們可以通過以下方式構建大於255的長類名:
1、在源代碼中添加大於255的字符串A。
2、編譯源代碼,修改DEX文件頭,修改Class descriptor_id為字符串A的String_idx。
效果如下:
受影響的工具有:IDA,Dex2jar, Androguard , Baksmali
由於大部分逆向工具都是線性讀取字節碼並解析,當遇到無效字節碼時,就會引起反編譯工具字節碼解析失敗,如果逆向工具沒有考慮到這一點,沒有對報出的錯誤進行合理的處理,就會直接崩潰。
我們可以插入無效字節碼到DEX文件,但要保證該無效字節碼永遠不會被執行。實現方法:
把類似於這樣的代碼:
插入到應用中我們不關心的類中,再重新編譯生成APK。
效果如下:
Baksmali被崩潰了(已在2f81aec886d2 7/28 版本中修復)。
Dex2jar也崩潰了。(這個修復起來也很容易,只不過目前的公開版本裡沒有修復)
動態分析工具 Androguard 也崩潰了。(新版本已經修復)。
IDA未受影響,可以正常使用。這是因為IDA並沒有使用線性掃描的方式對DEX文件進行解析,而是使用了某種程度上更“先進”的遞歸下降反匯編方式。
這個方法和方法1差別不大,主要原理就是插入可以分析工具崩潰的代碼、數據、指針。然後由應用開發者保證惡意的代碼、數據處在永遠不會執行的區域即可。
這種方法的影響的逆向工具包括 Baksmali、Dex2jar、Androguard、IDA(部分有效)。插入無效指針比插入無效指令更實用的一個地方在於,這個無效指針可以更緊密地和代碼結合在一起,可以巧妙地插在會被執行的代碼中去,進而導致使用遞歸沉降反匯編的IDA也中招。
這2種針對逆向工具“攻擊“的修復方法都比較容易,一方面工具自身更新代碼,對於非期望的輸入做好過濾,一方面逆向分析者可以編寫腳本,定點清除APK文件中的惡意代碼。
既然是想要讓逆向工具崩潰,那就應該讓逆向工具崩潰的越早越好。如果把惡意字節碼插在DEX文件末尾,那麼分析工具崩潰前已經把工作做完了,就沒有意義了。
雖然惡意字節碼可以被定點清除,逆向工具也可以在遇到惡意字節碼報錯時不崩潰,直接繞過去處理後面的,導致還是有辦法分析整個DEX文件的。但是包含惡意字節碼的這一部分代碼塊是沒有被分析的(要麼被清除,要麼被繞過)。所以,可以巧妙的在關鍵流程中嵌入這樣的惡意字節碼,即使不能保護整個DEX文件,保護幾個關鍵函數,也還是很有意義的。
無論有多麼高科技的DEX反編譯工具,最終從DEX字節碼反編譯回小白攻擊者可讀的Java代碼,都不是那麼完美的。主要是因為android 在打包的時候使用dx.jar 對初始class文件進行了優化,使得生成的dex文件不再是標准的jvm可執行文件,而是dvm的可執行文件。Dvm和Jvm在架構上一個是基於寄存器、一個是基於堆棧的。所以在轉換的過程中,一定是有信息損失的。既然轉換是不完美的,那麼就有能為我們所用的地方。
Dex2jar+(JD-Gui或JAD) 組合工具是逆向分析經常使用的工具。dex2jar用於把DEX文件轉換為java字節碼JAR文件,JD-GUI或JAD用於把java字節碼轉化為java源代碼。
我們可以針對JAVA JD-Gui或JAD工具缺陷來達到反逆向分析的目的。達到的效果如下圖所示:
Dex2jar + jd-gui 已經不能正確分析Apk裡對應的代碼。
IDA對流程的分析也出現問題了。
參考資料1提出了一段類似於這樣的代碼,嵌入到任何方法中,都能在(dex2jar+jd-gui)上復現上面出現的ERROR。但是這段代碼在另一個性能比較好的商業反編譯器JEB中就沒有生效了。
同時,我也發現,只要在try-catch的try語句塊中加入復雜的return語句,一般也能達到上述的ERROR。這大概是因為try-catch語句的實現和堆棧有關,而基於寄存器的DVM在轉換的時候有一些特殊的操作。即使是JEB,在處理try-catch語句時也常常出問題。
針對so文件的分析,是IDA的強項,特別是網上已經流傳了有一段的時間的IDA6.5pro+F5的破解版,基本上一路F5下來,就能把一個so裡面的代碼逆的差不多了。所以針對IDA的反分析方法,也是非常有必要的。
在so文件的格式(即ELF文件格式)的頭部,e_shoff字段是指節區(section)表格的偏移量,以字節計算,如果沒有的話,可以為0. 編譯鏈接期,每一個segment包括(對應)哪幾個section,鏈接器已經做好了,加載期間,linker只需要按照segment加載就OK了。所以真正so文件加載的時候,是不關心頭部section相關的字段的。但是IDA,readelf和objdump這類so文件分析工具是會去解析這個字段的。如果給這個字段賦值一個錯誤數據,就會導致這些工具的報錯甚至崩潰。
如圖:
objdump報錯:filetruncated
readelf 解析出來的全是ffffff
這種Anti-Analysis的方式是比較容易修復的,一方面IDA,objdump,readelf可以在新的版本中修復這樣的問題。另一方面,分析者也可以手動修復so文件中sht相關的惡意數據,實現修復。
上面介紹的Anti-analysis方法,都是一些很早就公開並且被很多應用使用過的方法。這個層面的攻防之所以沒有進一步的發展,是因為這個層面的對抗意義並不是特別大,沒有太多的“干貨”。把保護應用不被逆向攻擊的功能寄托在逆向工具的缺陷上,畢竟圖樣。知道原理之後,基本都可以秒破。按照Android平台應用攻防的發展來講,這種層面的攻防已經不再受到太多人的關注了。現在人們更多把對抗的領域,拉到了代碼的Dalvik層和native層。這兩個層面的對抗,將會在下兩篇文章中介紹。
前言 如果不使用系統自帶的TitleBar(即Activity被設置@android:style/Theme.NoTitleBar),那就需要自己來寫進度條了
感覺android中的toast效果挺不錯的,就試著自己用2dx做了一下,挺簡單的,效果也不錯。 XYToast.h #pragma once #include co
前言:加載並顯示gif是App常見的一個功能,像加載普通圖片一樣,大體應該包含以下幾項功能:1、自動下載GIF到本地文件作為緩存,第二次加載同一個url的圖片不需要下載第
看來只有礼拜天才有時間寫點博客啊,平時只能埋頭苦干了。今天在公司加班,遇到一個需求,就是自動換行的TextView,有點像網頁的tag標簽,點擊一下,就自動