Android惡意軟件混淆與對抗技術專題

發布時間 2024-11-25

第一章 概 述


近年來,Android惡意軟件數量不斷攀升,其采用的攻擊和對抗技術也變得越來越復雜。為了對抗安全分析,繞過安全檢測,竊取敏感數據或破壞系統安全,惡意軟件利用各種對抗技術來偽裝和隱藏其惡意行為和代碼邏輯。這些對抗技術中,針對資源、文件、字節碼指令及機器碼指令的混淆技術被廣泛地引入到惡意軟件中,成為高級黑客與逆向工程師對抗的重要戰場。


混淆技術的核心目標是增加分析復雜性來對抗逆向工程,同時也能提高免殺能力,主要對抗目標包含逆向工程師、靜態分析工具、動態調試工具以及自動化檢測系統?;煜夹g通過設置分析陷阱、改變文件結構、增加指令復雜度、虛擬化指令、隱藏代碼和資源等各種繁雜的技術來掩蓋其行為特征和攻擊意圖,同時給分析人員盡可能大的制造分析障礙,延后其惡意行為暴露的時間。同時,惡意軟件通過組合運用各種各樣的混淆與分析對抗技術,對現有安全檢測工具和防護機制形成了嚴峻挑戰。這需要不斷跟進各種技術的發展,對新的手段進行深入研究,制定有效且快速的應對方法,強化分析工具和檢測工具,同時也有助于快速應對高級且復雜的惡意軟件攻擊。


本文將對我們分析Android惡意軟件過程中所遇到的常見混淆技術進行總結和分析,從惡意軟件混淆與對抗的視角來闡述另一面的安全攻防技術,以幫助安全工程師和用戶們更加深入理解這一領域的技術情況,同時也有助于分析人員更高效地分析惡意代碼。

第二章 Android惡意軟件混淆技術的演進

隨著移動安全領域對抗的不斷升級,Android 惡意軟件的混淆技術也經歷了顯著的發展,從簡單的標識符混淆逐步演進到復雜的虛擬化保護(VMP)技術,呈現出由淺入深、逐步升級的趨勢。為更清晰地理解這一變化,我們將混淆技術的發展大致劃分為早期、中期和當前階段,并從不同層面進行詳細解析。


2.1 早期階段:基礎偽裝與簡單加密 


在早期,惡意軟件的混淆技術主要以掩蓋代碼和資源內容為目標,手段較為簡單直接,其混淆技術主要集中于Java層,利用Android應用以Java語言開發的特性,通過簡單的混淆手段規避安全分析和檢測。在這一時期,惡意軟件開始探索文件格式相關的混淆策略。例如,通過修改ZIP格式的APK偽加密,以及2012年黑帽大會上首次提出的利用DEX頭隱藏代碼的技術,這一策略隨后被Syrup惡意軟件所采用。同時,木馬Obad利用商業混淆工具DexGuard(ProGuard的增強版)實現了Manifest字段的復雜混淆以及基于clinit方法的動態代碼解密,被譽為“史上最強Android木馬”。


這一階段,短信攔截類和鎖機勒索類惡意軟件廣泛采用多種混淆手段,包括代碼混淆、字符串加密、代碼分割、垃圾代碼注入,以及商業加固工具的使用。這些技術盡管相對基礎,但在當時的安全環境中,已經顯著提高了惡意軟件的隱蔽性和抗檢測能力。下圖展示了一款短信攔截木馬的混淆效果。


圖片1.png

圖1 一個短信攔截木馬的混淆示例


2.2 中期階段:邏輯復雜化與動態對抗 


隨著安全檢測技術的不斷提升,惡意軟件逐步引入更加復雜的混淆手段,以提高隱蔽性并有效規避分析。為規避靜態分析,它們利用動態加載和反射機制,通過反射動態調用隱藏的關鍵代碼。同時,惡意軟件采用多重加密與解壓策略,對關鍵代碼進行多層次加密,并在運行時通過復雜的解密過程逐步釋放真實的惡意邏輯。例如:在我們發布的分析報告《新型Android銀行木馬“MoqHao”利用社交網絡隱藏C&C服務器》中,惡意軟件將真正的惡意dex文件加密后,以Base64編碼的形式保存在原始APK的assets目錄下。在這種情況下,原始APK僅作為一個外殼存在,其在運行時會動態解密并加載真正的惡意dex文件,以實現其攻擊目的,其過程如下圖所示:


圖片2.png

圖2 Java層混淆dex文件的示例


為了擾亂分析路徑,惡意軟件引入控制流混淆技術。通過插入無關的分支、循環和跳轉語句,惡意軟件使代碼執行路徑更加復雜,阻礙分析人員還原其邏輯。而在結合商業加固解決方案后,通過內存加載、指令抽取和指令轉換等技術,進一步提升了對抗分析的能力,使得分析人員難以準確還原其實際的執行邏輯。


隨著反混淆技術的進步和現代化反編譯工具的普及,惡意軟件逐漸將混淆策略向Native層轉移,以進一步提升逆向分析的難度。其常用技術包括對會話數據加密以防止敏感信息泄露、加密關鍵函數體以隱藏惡意行為、插入花指令干擾反匯編工具分析、利用LLVM框架實施復雜的代碼混淆,以及通過反調試技術檢測和阻止調試器介入。這些策略相輔相成,不僅顯著增加了逆向工程的復雜性,也進一步提高了安全研究人員分析的技術門檻。例如:在我們發布的《一款通過SO進行自保護的銀行APP劫持木馬深度分析報告》中,詳細分析了該木馬的運行行為。具體而言,libload.so模塊負責解密并加載實際的惡意代碼。該模塊利用Java反射機制調用javax.crypto包中的加解密函數,對存儲在assets目錄下的mycode.so文件進行AES解密。解密后的文件通過自定義的DexClassLoader加載并執行,執行完畢后,解密的文件會被刪除。這些精心設計的混淆手段有效隱藏了惡意行為,顯著增加了安全分析的復雜性,使得惡意軟件的檢測和分析變得更加困難。加載Native解密庫的部分代碼如下圖所示:


圖片3.png

圖3 Natvie層混淆示例


此外,針對文件格式的混淆策略也變得更加多樣和復雜。它們巧妙利用 Android系統對某些文件格式字段寬松校驗的特性,同時借助反編譯工具對文件格式的嚴格解析邏輯,設計了多種干擾和隱藏機制。通過對這些文件格式的靈活利用,惡意軟件得以實現更高程度的隱蔽性,進一步提高了逆向分析和檢測的難度,同時也為混淆技術的持續發展奠定了基礎。


2.3 當前階段:復雜混淆與多層對抗 


在當前階段,惡意軟件的混淆技術已經高度復雜化,廣泛結合動態和靜態對抗手段,以增強隱蔽性并對抗多種檢測方法。通過將Java層代碼混淆、動態加載與Native層加殼技術融合使用,惡意軟件將核心邏輯分布于不同層次中,大幅提高了檢測和分析的復雜性。以下是目前常見的混淆策略:


  • Java層與Native層相結合:惡意軟件通過將Java層的代碼混淆、動態加載、VMP等技術與Native層的代碼混淆手段相結合,將惡意邏輯分散在不同層次中。這種跨層混淆策略顯著增加了檢測和分析的復雜度,要求分析人員同時掌握多種技術,才能全面理解其運行機制。
  • 使用其他開發語言:惡意軟件常利用Lua、GoLang、Flutter、易語言等非傳統的 C/C++ 語言進行開發,從而顯著增加逆向分析的難度。這些語言獨特的特性進一步提高了分析的復雜性,同時削弱了傳統逆向分析工具的效率和效果。
  • 運行環境檢測及反調試:惡意軟件通過檢查設備的系統屬性、文件系統結構、系統權限狀態等,判斷目標設備是否為模擬器或已獲取Root權限,并在檢測到這些特征時阻止惡意邏輯的運行。同時,它們調用系統API檢查調試狀態,監測調試工具特有的行為,甚至主動引發異常以捕獲調試工具的反應,有效阻止動態分析工具的干擾。
  • 商業加固保護技術:一些惡意軟件使用商業加固保護技術,進一步加強了代碼的抗逆向能力,使得傳統的安全工具和分析方法難以奏效。
  • 代碼虛擬化技術:通過將代碼翻譯為自定義的虛擬指令集,并在運行時通過嵌入的虛擬機解釋執行,這種技術極大地提高了逆向分析的難度。

例如,某惡意軟件通過使用Native代碼實現對Frida和IDA的檢測,其代碼如下:


圖片4.png

圖4 Natvie層檢測調試器的代碼示例


Android惡意軟件的混淆技術已經從簡單的代碼混淆逐漸發展到如今復雜的跨層結合形式,其隱蔽性持續增強,技術手段也愈發多樣化。這種發展趨勢對傳統安全檢測工具而言是嚴峻的挑戰,同時也促使研究人員必須不斷創新應對策略,以此來應對惡意軟件日益復雜的混淆手段。在此背景下,深入了解并解析常見的混淆技術,是提升惡意軟件分析和檢測能力的關鍵。接下來,我們將通過實際工作中常遇到的惡意軟件混淆技術進行詳細分析,探討這些技術的應用方式及相應的防范對策。


第三章 常見混淆手段與技術解析


在分析Android惡意軟件時,安全研究人員通常需要從靜態分析和動態分析兩方面入手。靜態分析往往是最先進行的步驟,而混淆技術通過修改代碼的結構和表達方式(如字符串加密、代碼拆分、動態加載等),使惡意軟件的分析難度顯著增加。本文將以安全研究人員分析APK文件的過程為切入點,逐步介紹各種反混淆策略,幫助研究人員有效應對不同層次的混淆技術挑戰。


3.1 APK反編譯工具的對抗


在分析Android應用時,首先需要使用APK反編譯工具(如Apktool、Jadx)提取APK文件中的源代碼和資源。然而,惡意軟件往往會通過多種混淆手段對APK進行保護,以干擾反編譯過程。例如,惡意軟件可能利用Android在解析APK文件時未嚴格校驗ZIP格式的某些字段,從而通過篡改APK文件的ZIP格式字段來繞過基于ZIP格式解析的反編譯工具。這種手段尤其常見于一些基于Android的銀行木馬(如BianLian、Cerberus和TeaBot)中,目的是阻止安全研究人員和自動化分析平臺有效提取APK文件內容,進而對抗靜態分析和反病毒檢測。


為了更好地理解惡意軟件的混淆策略,尤其是如何通過篡改ZIP格式字段來干擾反編譯過程,有必要了解一些ZIP文件結構的基本信息。雖然ZIP格式的詳細結構超出了本文的討論范圍,但我們可以簡單介紹一些常見的、惡意軟件經常篡改的字段。我們以 Python 的zipfile.py 模塊中的 ZipInfo 類為例,展示了 ZIP文件元數據中的多個關鍵字段。具體字段及其含義如圖所示:


圖片5.png

圖5 Zipinfo類的結構信息


其中,compress_type、extract_version、reserved和flag_bits都是惡意軟件常常篡改的字段。這些修改可以導致反編譯工具在解析文件時出現錯誤或無法正確讀取文件內容,從而有效地阻礙靜態分析過程。通過篡改這些字段,惡意軟件不僅能夠規避常見的反編譯工具,還能增加被檢測的難度,提高其在靜態分析中的隱蔽性。


在了解了惡意軟件如何通過篡改ZIP格式字段來對抗靜態分析后,接下來我們需要關注Android應用中另一個常見的反編譯手段——AndroidManifest.xml文件(以下簡稱“清單文件”)。清單文件是反編譯過程中必須解析的關鍵部分,它包含了應用的核心配置,如組件、權限等信息。因此,提取、讀取和分析清單文件是靜態分析APK樣本時的首要步驟。為了規避反編譯工具的識別,惡意軟件通常通過精心篡改清單文件來干擾其正常解析。由于清單文件在靜態分析中的重要性和復雜性,它成為了惡意軟件常用的反編譯對抗手段之一。如果讀者對清單文件的具體結構不太了解,可以自行訪問以下鏈接(https://bbs.kanxue.com/thread-194206.html)查閱相關信息。


接下來,我們將介紹幾種常見的清單文件混淆手段,探討惡意軟件是如何通過這些手段對抗反編譯工具并隱藏其惡意行為的:


(1)修改XML文件的魔術:惡意軟件通過篡改清單文件中的魔術字段,使得靜態分析工具在解析時出現錯誤。這些修改通常不會影響應用的正常運行,但會導致分析工具無法正確解析清單文件的結構,甚至可能引發反編譯工具的異常錯誤,從而阻止反編譯過程,無法提取源代碼。


圖片6.png

圖6 左圖為正常的魔術,右圖為混淆的魔術示例


(2)篡改關鍵字段:惡意軟件可能會篡改清單文件中的關鍵字段,例如通過修改StringPool中字符串的個數。雖然Android系統在運行時并不依賴這個字段來計算字符串的個數,而是通過動態計算來處理字符串,但一些反編譯工具卻會依賴這個字段來解析XML文件中的內容。通過篡改這個字段,惡意軟件可以干擾反編譯工具的正常解析,導致工具讀取到錯誤的字符串個數,從而無法正確解析清單文件的結構,進而影響靜態分析的準確性和完整性。這種手段有效增加了靜態分析工具的分析難度,提升了惡意軟件的隱蔽性。


圖片7.png

圖7 篡改StringPoolSize的混淆示例


在上圖中,我們可以看到,stringCount的值為2907,而StringOffsets開始于偏移位置36,大小為 11628。StringOffsets是一個包含每個字符串在字符串池中的相對偏移量的數組,其大小為 stringCount * 4,即 11628。反編譯工具按照混淆后的stringCount值計算StringOffsets大小,并進行解析,因此解析結果出錯。這種不一致性是導致反編譯工具解析失敗的原因。然而,Android系統在處理清單文件時并未直接依賴stringCount字段的值。通過查看 Android 源碼可以發現,Android系統在運行時根據實際數據動態計算 stringPoolSize,而非直接使用文件中提供的數值。


圖片8.png

圖 8  Android系統源碼中計算mStringPoolSize的代碼示例


(3)插入臟數據:有些惡意軟件會故意在清單中插入一些臟數據。這種數據不會被實際使用,但會破壞清單文件的格式,使得解析工具難以識別其中的有效信息。


圖片9.png

圖9 左圖顯示`startEle0`內容,右圖展示`startEle0`和`startEle1`的偏移量及大小


上圖展示了一個混淆后的清單文件。在左圖中,第一個startElement的大小字段為196,但header中的size字段為224,意味著startElement后附加了28字節的未知數據。右圖中,第二個startElement的起始位置為0x15A4,正好位于插入的這28字節垃圾數據之后(右圖中綠色部分所示)。這些多余的28字節會導致反編譯工具在后續解析時出錯。Android系統能夠正常解析,是因為系統計算每個startElement的位置時,僅依賴上一個startElement的起始位置和大小字段,從而自動跳過垃圾數據。


(4)插入超長字符串或特殊字符:為了干擾靜態分析工具的正常解析,惡意軟件可能會在特定字段中插入超長字符串、特殊符號、emoji表情或不可見字符。這些字符雖然不會影響應用的正常功能,但它們顯著增加了分析工具的處理難度。如果反編譯工具的容錯能力較差,這些修改可能導致工具崩潰或無法正確解析清單文件,從而使靜態分析變得更加困難。


圖片10.png

圖10 通過不可見字符實現超長應用名稱(label)的示例


上圖中,清單文件中的label字段從string.xml中的app_name字段讀取,而app_name字段則包含了不可見字符(如\u0000)和超長字符串。通過這種方式,惡意軟件可以有效干擾反編譯工具的解析過程。如果自動化分析平臺的容錯機制不足,如數據庫字段對app_name或version字段長度有限制,這些篡改可能導致異常,進而使惡意軟件在自動化分析平臺上“隱身”,難以被檢測到。


在正常的清單文件中,Start Namespace Chunk通常存儲命名空間信息,其中Prefix是一個4字節的索引,指向字符串池中相應的字符串,用于標識命名空間前綴;Uri也是一個索引,指向字符串池中表示命名空間URI的字符串。例如,在一個未經過混淆的清單文件中,我們可以看到Prefix的值對應的字符串為android,即它引用了標準的Android命名空間。


圖片11.png

圖11 正常的prefix前綴示例


然而,通過對惡意軟件中發Prefix字段進行惡意篡改,攻擊者可以導致反編譯工具在解析時發生錯誤。這種混淆方式利用了反編譯工具對Prefix的依賴,使得其在解析時發生異常,干擾分析人員對惡意軟件的判斷。下圖是一個經過混淆的清單文件。


圖片12.png

圖12 混淆后的prefix示例


從圖中可以看到,命名空間的Prefix顯示為非標準字符串。Prefix的索引值指向字符串池中的位置67,而Uri顯示正常。查看字符串池中索引67的內容,我們發現該字符串是一段長度為20470的亂碼字符。如下圖所示:


圖片13.png

圖13 索引值67處的prefix字符串的值示例


這種超長字符串會導致Apktool在反編譯時崩潰。在Apktool的錯誤日志中,顯示了“Array Size”異常信息。


圖片14.png

圖14 Apktool反編譯時出現的異常錯誤示例


經過對崩潰問題的繞過處理后,生成的AndroidManifest.xml文件達到了16.7MB,且包含大量亂碼,難以閱讀。


圖片15.png

圖15 包含大量垃圾字符的AndroidManifest.xml文件示例


一個有效的處理方法是將Prefix的索引值指向字符串池中較短的字符串,以便生成的清單文件內容正常顯示,便于后續分析和閱讀。


此外,一些惡意軟件會在清單中插入符號或表情符號,若反編譯工具在解析時未正確處理這些特殊字符,也可能導致反編譯工具崩潰。插入表情符號進行混淆的清單如下圖所示:


圖片16.png

圖16 通過表情符號進行混淆的示例


除了通過篡改ZIP格式字段和混淆清單文件來對抗反編譯工具外,惡意軟件還常常采用一種強有力的策略——混淆resources.arsc文件。resources.arsc文件是Android應用中存儲資源映射關系的核心文件,它維護了資源ID與實際資源文件之間的映射。惡意軟件通過篡改這個文件,能夠有效干擾反編譯工具對資源的正確解析,甚至可能導致反編譯工具崩潰或異常退出。例如,BOOMSLANG(樹蚺)移動欺詐家族就利用這一策略對抗Apktool的反編譯過程,下圖是其反編譯失敗時Apktool提示的錯誤信息。


圖片17.png

圖17 混淆后的BOOMSLANG樣本導致Apktool反編譯失敗


3.2 代碼混淆與反混淆技術


一旦研究人員突破了APK包的初步混淆,接下來便會進入到代碼層面的分析。在這一層面,惡意軟件通常采用各種混淆技術,大幅地增加了靜態和動態分析的難度。


3.2.1 標識符混淆


標識符重命名是代碼混淆中最常見且最有效的技術之一,旨在通過將有意義的包名、類名、方法名和變量名替換為無意義的、隨機生成的名稱,從而干擾逆向工程師的分析過程。此外,標識符混淆還能有效避開一些自動化分析平臺,這些平臺通常依賴于標識符來制定檢測規則。通過混淆標識符,惡意軟件能夠規避基于標識符的檢測,減少被識別的風險。常見的標識符混淆策略包括使用隨機字符組合(如數字、字母或特殊符號)、采用非英語語言的標識符(如中文、日語、韓語、俄文等)、使用超長字符標識符,或通過替換形狀相似但含義不同的字符(如字母“O”與數字“0”、字母“I”與小寫字母“l”等)來干擾分析。這些混淆策略使惡意軟件能夠有效隱藏其功能并增加逆向分析的難度,從而延緩被檢測和識別的時間。為了應對這種混淆,安全研究人員可以使用帶有反混淆功能的反編譯工具,如Gda、Jeb、Jadx等,這些工具有助于快速恢復被混淆的代碼并幫助識別惡意行為。標識符混淆示例如下圖所示:


圖片18.png
圖18 標識符混淆示例


3.2.2 字符串加密


惡意軟件通常采用編碼或加密手段對代碼中的敏感字符串進行處理,以防止惡意關鍵字(如惡意URL、命令或其他敏感數據)在反編譯過程中被直接暴露。這些技術有效地阻止了分析人員從反編譯結果中提取關鍵信息,尤其在對抗自動化分析平臺的靜態分析時,具有較強的防護效果。常見的字符串混淆方法包括字符拆分和編碼混淆。字符拆分將敏感字符串分割成多個部分,程序在運行時再拼接成完整的字符串;而編碼混淆則通過對字符串進行加密或使用編碼技術(如Base64編碼、簡單加密算法等),在程序運行時再進行解碼。這些手段不僅增加了靜態分析的難度,也使得分析工具無法直接識別出惡意行為。這種技術使得靜態分析工具無法直接看到關鍵數據。安全研究人員可以使用動態分析工具,如Frida,來捕捉運行時的解密過程,揭示惡意軟件在運行時所做的操作。字符串加密示例如下圖所示:


圖片19.png
圖19 字符串加密混淆示例


3.2.3 控制流混淆


控制流混淆技術通過插入無意義的控制結構(如多余的條件分支、循環或冗余代碼),故意改變程序的執行路徑,代碼塊重新排序等手段使得分析工具在嘗試解析程序時,陷入過于復雜的代碼結構中,導致無法準確地還原程序的真實邏輯。由于控制流混淆引入了大量不必要的執行路徑,靜態分析工具可能無法有效提取出程序的實際行為。


為了應對這種混淆,安全研究人員通常需要通過模擬執行以及動態分析技術來輔助手動追蹤程序的執行流,逐步還原程序的真實邏輯。下圖展示了一個簡單的控制流混淆示例,展示了在混淆前后的控制流結構差異。


圖片20.png

圖20 控制流混淆前后的差異對比


3.2.4 反射機制與動態加載


動態加載機制是惡意軟件常用的反靜態分析技術,主要包括本地動態加載和遠程動態加載兩種方式。本地動態加載通過加載本地存儲的動態庫或dex文件,動態調用方法或類,使得惡意行為在靜態分析階段無法被發現。遠程動態加載則通過在運行時從遠程服務器下載動態庫或dex文件來加載并執行惡意代碼,這種方式進一步規避了靜態分析工具的檢測,因為惡意代碼并未出現在apk文件中。惡意軟件往往通過反射技術結合動態加載,利用運行時的反射調用機制隱藏惡意行為,使得初期靜態分析無法識別這些惡意活動。為了應對這一挑戰,安全研究人員通常依賴動態分析手段,如通過Frida注入腳本、使用調試工具動態跟蹤或通過日志分析捕捉反射調用的過程,從而揭示惡意代碼的真實行為。這些動態分析方法能夠繞過靜態分析的限制,識別通過反射和動態加載隱藏的惡意行為。


接下來,我們來看一個利用本地動態加載的惡意代碼示例。下圖展示了該惡意代碼的目錄結構。


圖片21.png

圖21 目錄樹信息


雖然從表面上看,該目錄僅包含幾個方法,但深入分析后發現,惡意代碼通過attachBaseContext方法調用了一個名為b的方法,進一步實現了從assets目錄加載加密的代碼文件。該文件經過異或解密后,通過動態調用的方式被加載并執行,代碼如下圖所示:


圖片22.png
圖22 動態加載后通過反射調用代碼示例


3.2.5 Native混淆


Native混淆技術是通過多種手段加大對惡意軟件逆向分析的難度,常見的技術包括以下幾種:


(1)JNI接口混淆:惡意軟件通過JNI(Java Native Interface)將關鍵邏輯轉移到.so文件中,并通過混淆的JNI接口調用本地代碼。通過將原本清晰的本地方法名替換為無意義的符號或隨機字符,惡意代碼的功能和結構變得更加難以理解和追蹤。


圖片23.png

圖23 JNI接口混淆示例


(2)Session加密:將關鍵方法存儲在自定義的.section中,并對這些自定義的.section內容進行加密。由于.so文件在加載時會優先執行.init_array段,因此將解密邏輯嵌入到.init_array中。在運行時,通過解密方法獲取內存中各個.section的起始地址和大小,對加密的.section進行解密還原,從而恢復關鍵方法的正常執行。


圖片24.png

圖24 Session加密的示例


(3)函數加密:解析.so文件,通過方法名定位目標方法后,對其進行加密。在加載.so文件時,通過指定方法的地址調用解密邏輯,將加密的方法動態解密還原,以實現對關鍵邏輯的保護。


圖片25.png

圖25 JNI加解函數經解密還原的部分代碼示例


(4)字符串加密與動態解密:惡意軟件通過加密關鍵字符串(如URL、命令、密鑰等),并在運行時通過動態解密恢復其原始內容。加密的字符串通常存儲在靜態數據區域,而解密則通過特定算法或在內存中動態完成,從而使得靜態分析工具無法直接提取惡意信息。


圖片26.png

圖26 Native解密字符串示例


(5)花指令與垃圾代碼插入:通過在代碼中插入偽指令或無效代碼,惡意軟件能夠混淆程序的實際行為。這些花指令沒有實際功能,但增加了逆向工程的復雜性。垃圾代碼不僅增加了程序的體積,還使得追蹤和理解惡意代碼變得更加困難。


圖片27.png

圖27 一個簡單的垃圾指令示例


(6)代碼加殼與自修改代碼:在Native層,惡意軟件經常使用加殼技術來隱藏核心惡意代碼。加殼后,惡意代碼以加密或壓縮形式存儲,只有在運行時才會解密或解壓。自修改代碼技術則允許惡意軟件在運行時動態生成、修改和執行代碼,進一步阻止靜態分析工具識別完整的惡意行為。


圖片28.png

圖28 通過Hook修改代碼的示例


(7)反調試與模擬器檢測:為了抵抗動態分析,惡意軟件往往會在Native層嵌入反調試機制,例如通過檢測調試器的存在(如gdb或Frida)來中斷分析過程。此外,惡意軟件也會進行模擬器檢測,通過檢查設備是否運行在模擬器或沙盒環境中來避免被動態分析工具捕捉。


圖片29.png

圖29 檢測模擬器示例


(8)控制流混淆:控制流混淆通過改變程序的執行路徑,使得分析人員難以理解程序的實際流程。常見的方法包括插入無效的控制流(如跳轉、分支語句)、無用的循環和函數調用,擾亂分析工具追蹤指令的順序。


圖片30.png

圖30 一段控制流混淆代碼示例


(9)LLVM混淆:LLVM是一種強大的編譯器框架,惡意軟件通過使用LLVM技術來對Native代碼進行復雜的混淆處理。LLVM混淆能通過優化編譯過程,生成難以閱讀和理解的二進制文件,同時對文件大小影響較小。這種技術有效增加了逆向工程的復雜度。


圖片31.png

圖31 LLVM混淆前后對比示例


這些Native混淆技術通常被組合使用,構建多層次的保護機制,從而使傳統的靜態分析和動態分析方法面臨巨大的挑戰。借助這些技術,惡意軟件能夠有效隱藏其真實行為,規避安全研究人員的檢測以及防護系統的攔截。此外,商業加固保護進一步提升了防護的全面性。惡意軟件常利用商業加固產品對自身進行保護,甚至黑灰產軟件也頻繁采用此類技術進行防護,如下圖所示:


圖片32.png
圖32 使用商用加固的詐騙應用


3.2.6 代碼虛擬化


代碼虛擬化是目前最先進的混淆手段之一,它通過將原始代碼轉換為自定義的虛擬機指令,極大地提高了代碼復雜度和分析難度。與傳統的控制流混淆不同,虛擬化技術將關鍵代碼的執行邏輯封裝在虛擬機中,使得核心功能和控制流幾乎無法通過常規反編譯手段還原。以下從DEX虛擬化和SO虛擬化兩個維度進行分析:


DEX虛擬化技術主要針對Android應用中的Dalvik字節碼。這種技術通過將DEX中的字節碼轉換成自定義的虛擬機指令,然后由Native層虛擬機解釋執行,從而保護關鍵代碼和核心邏輯。這種轉換使得傳統的反編譯工具難以還原代碼的原始邏輯,因為它們無法識別轉換后的指令集。例如,某電商平臺通過漏洞提權實施惡意行為,并為隱藏其核心代碼邏輯,采用了一套基于JVM構建的虛擬機保護(VMP)技術對代碼進行加固。下圖展示了其保護后的二進制內容,可以明顯看出,代碼已被虛擬化為高度抽象的虛擬機指令,使得傳統的反編譯和靜態分析方法幾乎無效。


圖片33.png

圖33 解析經vmp保護的dex文件示例


SO虛擬化技術則關注于保護應用中的Native代碼,即SO文件。這種技術可以通過隱藏符號表、資源加密等方式來保護SO文件中的功能不被輕易分析和篡改。例如,Virbox Protector提供了對SO文件的保護選項,包括隱藏符號表和對特定SO文件的加密保護。通過這種方式,即使攻擊者能夠訪問到SO文件,也無法輕易理解文件中的函數和邏輯,從而保護了應用的安全。


圖片34.png

圖34 某商業加固產品對DEX和SO的虛擬化保護介紹


3.3 其他混淆手段


一些惡意軟件通過巧妙利用Windows和Android文件系統的差異性,有效對抗靜態分析和逆向工程。在Windows系統中,文件名不區分大小寫,但會保留其原始格式,而Android文件系統則區分大小寫。這種差異使得某些在Windows系統上可能引發沖突或錯誤的文件名,能夠在Android設備上正常使用。此外,Windows系統對文件名中的特殊字符(如 > < : " / \ | * ?)有嚴格限制,而Android系統允許這些字符的存在。惡意軟件常通過在文件名中嵌入這些特殊字符,干擾基于Windows的分析工具,導致文件無法讀取或處理,從而增加逆向分析的難度。


不僅如此,惡意軟件還可能利用Android文件系統允許同名文件和文件夾共存的特性,進一步增加分析的復雜性。例如,在Android中,一個名為AndroidManifest.xml的文件和一個名為AndroidManifest.xml的文件夾可以同時存在,但在Windows系統中則會因命名沖突而無法實現。這種差異可能導致基于Windows的分析工具處理這些結構時出錯或跳過解析這些關鍵文件或文件夾,進而為惡意軟件提供偽裝。例如,BOOMSLANG惡意軟件的一個在野樣本采用了特殊字符混淆和同名文件與文件夾共存的對抗技術,其APK文件在使用ZIP工具打開時如圖所示:


圖片35.png

圖35 同名文件和文件夾混淆示例


從圖中可以看出,惡意軟件會同時創建 “\AndroidManifest.xml”和“AndroidManifest.xml”目錄,以及 “\classes.dex” 和“classes.dex”目錄。這種操作會在Windows系統上導致文件夾相互覆蓋,造成文件內容丟失,從而影響反編譯的完整性。此外,惡意軟件還會使用非法文件名,導致這些文件在使用apktool反編譯時被忽略,如下圖所示:


圖片36.png

圖36 apktool忽略非法文件名的示例


一些惡意軟件還會在文件中嵌入同名但大小寫不同的文件,通過利用Windows文件名不區分大小寫的特性干擾分析工具,造成解析錯誤或異常。以下圖片展示了一例包含同名但大小寫不同文件的惡意APK示例。


圖片37.png

圖37 Windows文件系統不區分文件名大小寫的示例


在Android惡意軟件中,資源混淆是一種常見的對抗技術,廣泛應用于assets和res等文件夾中的資源文件。常見的資源混淆手段包括:對assets目錄中的資源文件進行加密處理,創建深層嵌套的目錄結構或使用畸形目錄名稱,插入大量無用文件或偽裝資源文件,將關鍵資源與無效資源混雜在一起,從而增加分析難度;對res目錄中的資源文件進行混淆,例如篡改資源映射關系、刪除資源文件名或更改文件擴展名等。這些手段旨在干擾分析工具的解析過程,使得分析人員難以快速定位和識別關鍵數據,進一步提高逆向工程的難度。下圖是一個插入垃圾資源的示例:


圖片38.png

圖38 插入垃圾資源示例


一些惡意軟件通過將原始DEX文件分割成多個小的DEX文件或插入垃圾代碼,增加靜態和自動化分析的難度。分割DEX文件使分析工具需要逐個處理,增加了分析時間和復雜度,且這些文件通常通過動態加載技術在運行時才會合并,難以在靜態分析中識別。此外,插入的垃圾代碼不執行實際操作,但通過虛假的邏輯和復雜的控制流干擾分析,掩蓋惡意功能。此類策略使得惡意軟件的行為更加隱蔽,迫使分析人員采用更復雜的動態分析和手動逆向工程方法。一個apk中包含大量dex的例子如下圖所示:


圖片39.png

圖39 分割多個dex示例


除了上面提到的混淆技術,還有一些其他常見但未詳細介紹的技術,這些技術能進一步增強惡意軟件的逆向分析難度。以下是一張混淆工具的示例圖片,其中展示了多種混淆功能,如:增加包體積、內建獨立簽名證書、DEX代碼混淆、資源混淆、APK防篡改等多個功能。


圖片40.png
圖40 一種混淆工具示例

第四章 實際案例解析

為了更好地理解混淆技術的實際應用,以下是幾個常見的Android惡意軟件的混淆技術案例。


4.1 Joker惡意軟件混淆方法


Joker(中文名稱“小丑”,也被稱為Bread)是一個在Google Play商店中極為活躍的惡意軟件家族。自2016年12月首次被檢測到以來,Joker家族的活動一直在持續,并且其惡意軟件的變種數量也在不斷增加。本月最新披露的Google Play商店中Joker樣本信息如下:


圖片41.png

圖41 GooglePlay上的Joker木馬信息


Joker家族的惡意軟件能夠反復進入Google官方應用市場,其關鍵原因在于其采用了多種高級代碼混淆技術,從而繞過了Google Play Store的安全檢測和審查機制。這些混淆技術包括但不限于:


(1)字符串加密:通過加密關鍵字符串,如API請求和配置信息,避免靜態分析工具的直接識別。

(2)動態加載:將惡意代碼分離到單獨的Payload文件中,僅在運行時加載,以躲避靜態代碼掃描。 

(3)反射調用:利用反射機制動態調用方法,隱藏關鍵功能調用路徑。 

(4)動態下發配置:通過網絡請求動態獲取配置或惡意指令,降低被靜態檢測的風險。 

(5)利用第三方服務:使用Github頁面和存儲庫存儲惡意配置或代碼,進一步混淆來源和流量。 


這些技術的組合使Joker惡意軟件能夠成功規避靜態分析檢測,其真實行為往往隱藏在復雜的動態流程中。為了揭示其行為,分析人員通常需要依賴動態調試和運行時解密技術。針對這些混淆手段,安全研究人員可以借助動態分析工具(如Frida和Xposed)追蹤解密過程,提取關鍵數據并識別惡意 API 調用,從而全面還原其惡意行為。


4.2 BadPack的混淆手段


BadPack是惡意軟件通過篡改ZIP文件結構頭,使Apktool和Jadx等分析工具無法正常解析。其通過使用非標準的壓縮算法來干擾反編譯工具的正常運行。經010 Editor分析該APK文件格式,發現其壓縮方法值為0xF753,如下圖所示:


圖片42.png

圖42 篡改apk文件壓縮算法標識示例


這一數值并不屬于任何已知的標準壓縮方法,因此導致反編譯工具無法識別和處理該文件。根據標準ZIP格式規范,壓縮方法的取值通常如圖所示。


圖片43.png

圖43 ZIP支持的各壓縮方法的標識值示例


根據Android系統源代碼,當系統遇到非COMP_DEFLATE(即 0x08)壓縮方法時,會默認將輸入文件按 “未壓縮” (COMP_STORED,即 0x00)方式處理。具體而言,系統會直接讀取文件的未壓縮數據長度,并以此進行解析。因此,惡意軟件利用了Android系統對ZIP格式的容錯機制,通過使用非法的壓縮算法進行混淆,從而達到規避反編譯工具的目的。這種混淆技術簡單卻有效。在分析Android惡意軟件時,若遇到類似情況,可將壓縮方法修改為0以便正確解壓和分析。


APK偽加密通過修改ZIP文件的頭部,將加密標志設置為true,但并未實際對文件內容進行加密。這種技術利用了Android系統在處 ZIP文件時不會驗證頭部的加密標志,而普通的解壓軟件則會檢測該標志。例如,當使用RAR工具解壓該APK文件時,會提示用戶輸入密碼,如下圖所示:


圖片44.png

圖44 偽加密的混淆示例


由于Jeb和Jadx都使用標準的ZIP庫,因此無法正常解壓并反編譯該文件。它們的反編譯錯誤信息如下圖所示:


圖片45.png

圖45 無法使用Jadx和Jeb打開的混淆APK示例


通過采用BadPack技術,惡意軟件將自身偽裝為異常格式的文件,利用反編譯工具對文件解析的嚴格性觸發異常,從而顯著增加靜態分析的難度。這種策略有效干擾了安全研究人員的分析流程,提升了惡意軟件的隱蔽性。 


針對這一技術,可以通過以下方法進行應對: 


(1)使用修訂后的ZIP庫:通過修改ZIP解壓庫的解析邏輯,忽略非標準字段或異常格式,確保文件內容能夠正確解壓。 

(2)編寫修復腳本:分析BadPack文件的異常字段,針對特定格式設計腳本,自動修正文件結構,使其恢復為標準格式以便后續分析。 

這些應對措施能夠有效繞過BadPack技術的混淆手段,為靜態分析提供可靠的數據支持。


4.3 SpyNote惡意軟件混淆策略


SpyNote是一種間諜軟件,常通過短信和釣魚網站等方式進行傳播。攻擊者通常發送包含惡意鏈接的SMS消息或創建偽裝成合法網站的釣魚頁面,誘導目標用戶點擊鏈接并下載偽裝成合法應用程序的惡意軟件。自2016年在惡意軟件論壇首次曝光以來,SpyNote一直作為一種持續威脅的惡意工具在全球范圍內活躍。公開數據顯示,今年1月和2月期間,SpyNote的新增樣本數量已超過3400個,表明其威脅活動仍在快速擴散。最新披露的威脅情報顯示,SpyNote偽裝成安全應用程序實施攻擊,其主要目標是加密貨幣賬戶,竊取私鑰和余額信息,尤其針對比特幣、以太坊和Tether等熱門數字資產。相關攻擊事件如下圖所示:


圖片46.png

圖46 SpyNote仿冒安全軟件實施攻擊


SpyNote 除了通過多種渠道進行傳播,還采用了一系列高級混淆與隱藏策略,以規避檢測和分析。以下是其主要混淆技術的簡要概述:


(1)篡改 APK 文件的 ZIP 格式,從而導致反編譯APKTool在解析時失敗,如下圖所示:


圖片47.png

圖47 修改zip格式導致Apktool反編譯失敗的示例


(2)篡改清單文件魔術、插入垃圾字符串。修改的魔術示例如下圖:


圖片48.png

圖48 修改魔術混淆示例


(3)利用相近字符實現代碼混淆,如下圖所示:


圖片49.png

圖49 相近字符代碼混淆示例


(4)對resources.arsc文件混淆,使jadx反編譯工具在分析時出錯,如下圖所示:


圖片50.png

圖50 Jadx無法解析resources.arsc文件



第五章 結論與未來展望


Android惡意軟件的混淆技術不斷進化,從簡單的代碼重命名到復雜的動態加載與反調試技術,惡意軟件通過這些手段極大地提升了惡意代碼的隱蔽性和分析難度。隨著混淆技術的不斷發展,安全研究人員也需要不斷更新自己的分析手段,從靜態分析擴展到動態分析、行為分析等多維度的分析方法。


未來,隨著機器學習、人工智能等技術的引入,混淆技術和逆向分析技術將繼續呈現出更加復雜和高效的態勢。在這種情況下,開發更強大的自動化檢測和分析工具將是破解惡意軟件防護的關鍵。同時,開發者和安全專家也應加強對混淆技術的研究,制定出更具針對性的應對策略,以確保Android平臺的安全性。

通過持續的研究和技術創新,我們有望能夠更好地對抗惡意軟件的混淆技術,保護用戶的隱私與安全。


啟明星辰積極防御實驗室(ADLab)


ADLab成立于1999年,是中國安全行業最早成立的攻防技術研究實驗室之一,微軟MAPP計劃核心成員,“黑雀攻擊”概念首推者。截至目前,ADLab已通過 CNVD/CNNVD/NVDB/CVE累計發布安全漏洞5000余個,持續保持國際網絡安全領域一流水準。實驗室研究方向涵蓋基礎安全研究、數據安全研究、5G安全研究、人工智能安全研究、移動安全研究、物聯網安全研究、車聯網安全研究、工控安全研究、信創安全研究、云安全研究、無線安全研究、高級威脅研究、攻防體系建設。研究成果應用于產品核心技術研究、國家重點科技項目攻關、專業安全服務等。



adlab.jpg