天天看點

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

一、背景

“Unity目前已經全面覆寫到各個遊戲平台,超50%的手機遊戲、PC遊戲和主機遊戲基于Unity引擎制作而成,全球月活躍創作者多達150萬,遍布190多個國家和地區。此外,2019年全球收入前一百的工作室中,有93%的開發者在使用Unity的産品。”

可以看到,Unity作為目前市場的第一大遊戲引擎占有者,受到越來越多的遊戲開發者和制作者的青睐,同時Unity遊戲會被一些攻擊者和“别有用心”的人盯着,不僅影響到了遊戲市場與遊戲玩家的公平,而且或縮短遊戲自身的生命周期。

本文将重點圍繞“反破解”講述這些安全風險,以及網易易盾團隊如何對unity遊戲進行全方位的矩陣化保護更新。

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

二、代碼篡改風險

從上圖可以發現,面對unity的破解問題,遊戲開發商可采取了一個全方位的矩陣化保護方案。方案中首當其沖的是對于代碼的保護,其中包括腳本和引擎檔案保護。

2.1 u3d-mono:

通過使用dnSpy.exe對Assembly-CSharp.dll進行反編譯,如下圖所示可以清晰看到其中的邏輯代碼,以及通過修改IL指令就可以達到進一步的作弊效果。

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

對于上面這種dll檔案被修改的情況,我們研發了對于dll檔案保護的疊代,如下所示:

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

2.1.1 整體加密

大部分的加強廠商剛開始都是着手于對于DLL檔案的整體加密,通過閱讀mono的源碼可知通過修改 mono_image_open_from_data_with_name函數能夠對DLL腳本進行解密。或者在加強的時對于mono_image_open_from_data_with_name進行HOOK處理;且對于“4D 5A 90”這樣的關鍵魔術字抹掉,防止攻擊者在記憶體中搜尋dump;

但是對于整體加密存在的問題比較容易分析,通過動态調試或者尋找記憶體中的特征點進行完整還原。故而對于這種情況,遊戲廠商可以采取“函數加密”方法自保,詳情如下:

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

2.1.2 函數加密

面對以上整體加密,細緻的“函數加密”不可或缺:在函數運作前進行解密,而不是在記憶體中整體解密,這個時候邊運作邊解密,這時候通過hook mono_image_open_from_data_with_name拿到的dll是不完整的解密,method code還是加密的狀态,這樣大大加強了dll的加密難度,使用dnSpy.exe 和 Reflector.exe 進行反編譯可以看到很多的方法是看不到的,這裡不做展示。

2.1.3 結構自定義

面對上述的函數加密,部分攻擊者通過記憶體定位hook函數,記憶體中去還原dll 的method code,這個時候我們研發了dll的自定義結構,通過對dll的檔案結構進行自定義話,同時配合上面的整體加密和函數加密,最後的效果如下:

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

對于“結構自定義”的情況,攻擊者需要去分析遊戲的檔案自定義結構,不僅是到記憶體中進行解密,而且得還原我們自己的結構形式。雙重破解“門檻”,使攻擊者的行動難度加深。

2.2 u3d-il2cpp:

随着MONO Vm在各個平台的難移植性、MONO版權的受限,以及性能等影響的受限,unity引入了il2cpp機制,加入靜态語言特性把代碼轉化到native層,雖然在某種程度上提高了遊戲的安全性,但是會把C#中的重要的方法類名等符号資訊存儲在一個叫global-metadata.dat 檔案中,這個時候可以借助于Il2cppDumper,如下圖所示對一個Demo可以解析到敏感的方法名與類名。對此,遊戲保護依然可以通過分析il2cpp.so得到遊戲的代碼邏輯。

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新
知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

對于這個情況,我們研發了對global-metadata.dat 的加密方法的疊代:

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

2.2.1 global-metadata落地加密

第一代是研究了落地加密方式,如下所示為加密前後展示:

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

這個時候同時對libil2cpp.so檔案進行加強,可以阻擋上面對于符号表的解析以及libil2cpp.so檔案中重要的關鍵字段的解析,這裡不再展示。

2.2.2 global-metadata記憶體加密

對于第一代的落地加密方式,很容易在運作的時候在本地找到解密的global-metadata.dat檔案,這個時候研發了記憶體加密方法,隻是會在記憶體中進行解密,同時抹掉關鍵的辨別等,加大分析的難度。

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

對于上面兩種方式的加密均不需要符号表,友善快捷,一鍵式加密。

2.2.3 global-metadata分塊加密

同時,為了進一步的加強對于global-metadata檔案的保護,我們又研發了分塊加密,隻有在函數運作的時候才會進行解密,這個時候在記憶體中拿到的檔案永遠是不完整的,進一步加強對于global-metadata檔案的保護。這樣dump出來再次使用會報錯:

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

2.2.4 反global-metadata記憶體Dump

在上面靜态加密保護的基礎上,面對一些通過使用在記憶體中反射擷取關鍵資訊的攻擊方式,團隊研究了防動态dump的方法,這樣靜動态的結合極大的加強了對于global-metadata.dat檔案的保護。

2.3 u3d-lua:

Unity自從接入il2cpp以後,通過使用xlua和tolua等進行熱更,這個時候熱更的lua、luac、luajit成為了攻擊者的分析目标。我們提供對于的lua檔案的加密保護以及對應的熱更引擎的保護,防止攻擊者去分析熱更中lua的代碼邏輯。

2.4 引擎加強:

通過對Assembly-CSharp.dll轉為il2cpp.so結合global-metadata.dat檔案使用IDA分析,可見清晰的邏輯如下:

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

對于unity引擎中的libil2cpp.so以及自定義的libmono.so檔案,通過獨家研發的引擎檔案進行加強保護,同時對于熱更的lua引擎以及unity引擎進行加強保護,團隊制定了多種的引擎加強方案,“輕量級”與“高強度”并行的加強方案。

三、資源破解分析

3.1AB資源

ab資源作為unity引擎中的核心資源,将所有的資源形式打包成了UnityFS的格式,通過AssetStudio可以對ab資源進行提取,如下圖所示,部分資源的暴露可能帶來資源被竊取、被修改,以及遊戲記憶體在劇透的風險。為了防止對于資源的分析以及拷貝,遊戲開發商可采取 “ab資源加密”的保護措施。

強度上為邊運作邊解密,同時由于ab資源在一個APP中所占的體積比較大,盡可能小的降低ab的壓縮率,同時為了考慮到APP運作的性能問題,隻會将部分重要的結構資訊進行加密,這個時候可以防止

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

通過對于ab資源的加密處理,AssetStudio沒辦法對于ab資源進行解析處理,如下圖所示:

知物由學 | 隻要這幾步,Unity遊戲全方位保護更新

3.2靜态資源

在某些特殊情況下,部分unity的包會以靜态資源而不是ab資源的形式存在安裝包中,為了保護自己的美術資源,易盾團隊研發了針對靜态資源的保護,在同樣的強度上邊運作邊解密,同時由于ab資源在一個APP中所占的體積較大,盡可能小的降低ab的壓縮率,且考慮到APP運作的性能問題,隻會加密部分重要的結構資訊,這樣就達到了對應的要求。對于效果同上的ab資源處理,這裡不做具體的效果展示。

四、最後

針對dll檔案、global-metadata檔案、lua檔案、資源檔案,以及引擎檔案的保護,是Unity遊戲安全運作的必經之路。遊戲開發商必須在保障相容性的前提下,根據強度與性能的不同要求進行自動化加強,真正做到遊戲安全的全方位更新。