靜網PWA視頻評論

類分裂的代碼混淆技術

2023年09月26日

- txt下載

摘 要包含有大部分或全部源碼信息的軟體發行版本的普及,比如易被反編譯成源碼的Java位元組代碼,增加了軟體被惡意逆向工程攻擊的可能。文章介紹了面向對象語言的類分裂混淆 方法 ,同時也給出了混淆技術的定義、分類和評判標準。
關鍵詞逆向工程;代碼混淆;軟體保護;類分裂


1 引言


計算 機軟體的安全一直是軟體 企業 和相關 研究 領域的關注重點,當前存在的軟體保護技術分別有硬體輔助保護、序列號保護、加密保護、伺服器認證、防篡改以及代碼混淆等。隨著JAVA語言、逆向工程的迅速 發展 和普遍運用以及惡意主機對軟體的逆向 分析 等突出安全 問題 的不斷湧現,使得代碼混淆,這一新的保護軟體安全的技術正越來越受到人們的重視。

2 代碼混淆的定義和分類

2.1 代碼混淆定義


給定一個程序P、策略T,經過混淆變換後得到程序P' (見圖 1)。此過程稱之為混淆變換,如果對程序進行一種功能保持的變換,變換後的程序擁有和原始程序相同的功能。更確切的說法應該包含以下兩個條件:①如果P出錯終止或終止失敗,P'不一定終止。②P和P'在正常終止情況下,P'必須產生與P相同的輸出。
所不同的是經過轉換的P'相較P更難於被靜態分析等逆向工程方法攻擊,即使被反編譯,生成的程序也難以被人閱讀和理解。
圖1 代碼混淆

2.2 代碼混淆分類


根據混淆對象和對其進行操作的差別,可將代碼混淆技術分為布局(layout)混淆、控制(control)混淆、數據(data)混淆、預防(preventive)混淆等幾種。
(1)外形混淆。該類混淆主要包括對程序中的變量名、常量名、類名、方法名稱等標識符作詞法上的變換改名和刪除程序中與執行無關的調試信息、注釋、源碼格式等。
(2)控制混淆。該類混淆的目的是使得攻擊者對程序的控制流難以理解。主要包括打亂某段代碼本身邏輯關係的聚集混淆(Aggregation Transformation)、把相關語句分散到程序不同位置並實現某項功能的次序混淆(Ordering Transformation)和隱藏真實執行路徑的執行混淆(Computation Transformation)­­等。
(3)數據混淆。數據混淆的對象是程序中的數據域。它可細分為相關數據的儲存(Storage)與編碼(Encoding)方式的混淆、組合和拆分數據的聚集(Aggregation)混淆、位序重計的次序(Ordering)混淆等。
(4)預防混淆。與前述混淆類型針對惡意用戶不同,預防混淆主要利用一些專用反編譯器的設計缺陷,以使這些反編譯器難以反向還原混淆之後的代碼。例如,反編譯器 mocha 對於 Return 後面的指令不進行反編譯,Hosemocha 就是專門針對此缺陷,故意將代碼放在 Return 語句後面,從而使反編譯失效。

2.3 類分裂


介紹完代碼混淆的分類後,接下來我將就面向對象語言中的一種混淆技術:類分裂(class splitting)進行說明。首先對類分裂進行定義:類分裂是將一個初始(原)類用兩個或兩個以上的類來替換的混淆方法。對類分裂進行敘述前,我們規定以下相關使用術語的意義:
P: JAVA程序
Classes(P): P中一般類的集合
Interfaces(P): P中接口類的集合
ct: Class或Interface中的任意類
Methods(ct): ct中的成員函數的集合
Field(ct): ct中的成員變量的集合
註:Methods(ct),Field(ct)不包括從父類繼承的成員函數和成員變量,而只包括:①當前定義類中新定義的成員函數和成員變量。②當前定義類所覆蓋的其父類的成員函數。
依賴(depends)關係的定義:
m,n Methods(ct),如果存在m調用n,則(m,n) ∈ depends
and m∈Methods(ct), f∈Field(ct),如果存在m使用了f,則
(m,f) ∈ depends
為了便於用例的書寫,特做說明,圖2左列和右列的符號實際上表示同一類。

C

Ct

C1

Ct,1

Ct,1

Ct,2

圖2
其次,由於類分裂的方法很多,為了敘述方便,我們假設將類ct分裂成兩個新類ct,1和ct,2,公式如下:

分裂函數usplit代表了這麼一個分裂過程:原來的類的成員(成員函數或成員變量)被拆分到某個或是兩個新類中。
分裂函數的選擇必須考慮到成員函數之間或成員函數和成員變量之間的依賴關係,這是決定分裂函數是否有效的重要標準。下面的程序中,初始程序中的類Ct不能被分為混淆後的程序中兩個毫無繼承關係的新類,而應分裂為具有繼承關係的類ct,1和ct,2。可以使用另一種表達方式描述:初始程序中類Ct的m2成員函數調用了m3成員函數,因此我們不能將m2作為ct,1的成員函數,m3作為 ct,2的成員函數,而ct,1和ct,2兩者間無繼承關係。而應將m2 作為子類ct,2的成員函數,m3作為父類ct,1的成員函數。且成員函數m3不需要修改,m3依舊調用m2。
如果出現這種情況:由於初始程序中的類設計本身存在缺陷,導致該類實際等同於多個類的組合。在此前提下,可以將初始類分裂為毫無繼承關係的兩個或兩個以上新類。
將類分裂為具有繼承關係的新類的方法產生了大量有效的分裂函數,這是因為這種分裂方法的約束條件非常簡單且只具有惟一的限制:成員函數和成員函數所使用到的成員變量必須在同一類中定義,而這個類必須是定義成員函數的類。用公式表述如下:
m∈Methods(ct):
if ct,1∈ usplit(m),then
n∈Methods(ct)):depends(m,n)→ct,1∈ usplit(n) and
f∈Fields(ct)):depends(m,f) →ct,1∈ usplit(f)
原則的體現如同下面所示類分裂混淆例子所示:成員函數m3調用了成員函數m4,因此將m3和m4定義為類ct,1的成員函數。由於分裂函數usplit將m4函數分配給了類ct,2,類ct,1的成員函數m4其實只是一個虛假的程序段(函數),它使惡意逆向工程人員以為調用的是ct,1的成員函數m4。但實際情況是:程序運行期間ct,1的成員函數m4將不會被調用,它將被ct,2的m4成員函數所覆蓋。同時,類ct,1中構造函數用到的成員變量i,d都在類ct,1定義,類ct,2中構造函數用到的成員變量o則在類ct,2定義。
接著,當新類產生後,必須要對原有的類型聲明進行替換,主要包括:
●成員函數的參數,成員變量和本地變量的類型聲明由ct變為ct,1和ct,2代替,程序中是C使用C1和C2代替。
轉貼於論文聯盟 http://www.lwlm.com

收藏

字典網 - 試題庫 - 元問答 - 简体 - 頂部

Copyright © cnj8 All Rights Reserved.