隨著unity技術(shù)的發(fā)展及廠商對于腳本源碼的保護,很大一部分U3D應(yīng)用的scripting backend已經(jīng)由mono轉(zhuǎn)為了il2cpp,,本文從unity簡單應(yīng)用的制作講起,,介紹U3D應(yīng)用腳本的Assembly-CSharp.dll的逆向及il2cpp.so的逆向分析。
目錄如下:
0x1.U3D應(yīng)用制作 → 輸出兩個apk,,分別為mono和il2cpp
0x2.mono后臺apk的逆向分析 → Assembly-CSharp.dll 逆向修改
0x3.il2cpp后臺apk的逆向分析 → il2cpp.so逆向修改
正文內(nèi)容:
0x1.U3D應(yīng)用制作
工具:Unity最新版本 2017.2.1f1
1.1 創(chuàng)建Project
新建一個Unity3D Project,,Project name為UnityTest,如下圖

1.2 創(chuàng)建script定義界面元素
創(chuàng)建GameObject和C# Script,,均命名為Sample,, 同時創(chuàng)建兩個UI Text,分別命名為HP和Attack,。打開C# Script,,進行界面元素的義,創(chuàng)建三個矩形按鈕分別為HP,,ATK和LevelUP,,設(shè)置點擊HP顯示100,點擊ATK顯示50,,點擊LevelUP后HP和ATK的值都翻倍,。
using UnityEngine;
using UnityEngine.UI;
public class Sample : MonoBehaviour
{
public Text _hp;
public Text _attack;
private Rect _healRect = new Rect( 10f , 20f , 300f , 100f );
private Rect _attackRect = new Rect( 10f , 170f , 300f , 100f );
private Rect _LevelUpRect = new Rect( 10f , 320f , 300f , 100f );
public void SetHp( int hp)
{
_hp.text = hp.ToString();
}
public void SetAttack( int attack)
{
_attack.text = attack.ToString();
}
public void OnGUI()
{
int hp_value = 100 ;
int attack_value = 50 ;
if (GUI.Button(_healRect, "HP" ))
{
SetHp(hp_value);
}
if (GUI.Button(_attackRect, "ATK" ))
{
SetAttack(attack_value);
}
if (GUI.Button(_LevelUpRect, "LevelUp" ))
{
SetHp(hp_value * 2 );
SetAttack(attack_value * 2 );
}
}
}
代碼和界面完成后,我們設(shè)置包名(com.test.test)進行打包,,分別輸出mono后臺和il2cpp后臺的apk,。

點擊Player Setting進行后臺設(shè)置,可點擊Scripting Backend選擇mono或者il2cpp,。

得到的apk我們分別命名為Sample-mono.apk和Sample-il2cpp.apk,。
安裝測試正常,界面如下:
初始界面

點擊HP和ATK后界面

點擊LevelUp后界面

至此,,我們完成了兩種后臺的apk的創(chuàng)建,,接下來先對mono后臺的apk進行逆向分析。
0x2.mono后臺apk的逆向分析
工具:Android Killer,,DnSpy
思路:將Sample-il2cpp.apk拖拽進Android Killer進行反編譯,,獲取到腳本文件/Assets/bin/Data/Managed/Assembly-CSharp.dll,dll拖進DnSpy進行反編譯分析,,修改關(guān)鍵method后,,保存并重新打包運行。
Android Killer部分不再上圖,,Assembly-CSharp.dll拖拽進DnSpy,,我們可以很輕易的找到我們需要的關(guān)鍵函數(shù),,如圖:

根據(jù)代碼信息,我們可以確定,,num為初始HP,,num2為初始ATK,我們在此通過編輯IL指令將他們的值分別改為1000和500,,如圖:

確認后C#編碼變更如下:

保存后,,重新打包apk安裝測試結(jié)果如下:

至此,我們的mono后臺apk修改已經(jīng)完成,,接下來我們進行il2cpp后臺apk的修改,。
0x3.il2cpp后臺apk的逆向分析
工具:Android Killer,il2cppDumper,,IDA,,010Editor
思路:利用il2cppDumper獲取到關(guān)鍵函數(shù)的offset后,使用IDA找到關(guān)鍵函數(shù),,分析匯編語言邏輯后,,利用010Editor進行16進制文件編輯來實現(xiàn)修改。
Android Killer相關(guān)操作再次不做贅述,,反編譯后我們得到的Project中,,lib目錄如圖:

在此我們只分析armeabi-v7a文件夾下的libil2cpp.so,x86為intel架構(gòu),,暫不做分析處理。
將il2cpp.so連同assets\bin\Data\Managed\Metadata 目錄下的global-metadata.dat 文件一起放進il2cppDumper目錄,。

運行il2cppDumper,,第一步,選擇il2cpp.so


第二步,,選擇global-metadata.dat

進入到il2cppDumper控制臺界面

選擇mode后可以得到Dump.cs,,包含關(guān)鍵函數(shù)的偏移信息


打開Dump.cs,找到關(guān)鍵函數(shù)的偏移信息

用IDA打開libil2cpp.so文件,,跳轉(zhuǎn)到此偏移地址 0x7CE514

定位到關(guān)鍵函數(shù)后,,我們可以看匯編,也可以F5插件看偽代碼,,為了便于理解我們這里F5處理一下
這次我們從LevelUp入手,,我們在編寫源碼的時候,是進行了乘以2的處理,,為什么匯編語言中是直接將翻倍后的數(shù)值進行傳參呢,,因為匯編不會完全跟我們源碼的邏輯相同,但是結(jié)果一定是一樣的,,LevelUp的匯編代碼如下
切換到對應(yīng)的地址查看16進制

0xC8即為200,,我們使用010Editor將其地址7CE6B4的值修改為FF(十進制為255)
保存后替換lib/armeabi-v7a目錄下的libil2cpp.so文件,,打包運行,結(jié)果如下

至此,,il2cpp后臺的apk已修改完畢,。