作者:dawu@知道創宇404實驗室
時間:2019/02/25
英文版本:http://www.bjnorthway.com/943/

0x00 前言

這是一篇游戲引發的簡單技術文。

起因是個人很喜歡玩 google play 上的一些數字類型(角色攻擊是線性增長,怪物指數變強,到后期越打不過,通過重生增強屬性變強)的小游戲。但是這種游戲仍舊存在一定缺陷,前期資源不多,玩的太慢、玩的時間長了,就感覺沒意思,就不想玩了,所以在玩到游戲中期的時候,往往都會去網上搜索XXX破解版/內購版,快速進入后期然后放棄這款游戲。

這樣的做法其實是很不安全的,因為無法判斷XXX破解版/內購版在破解/內購之后還做了什么。所以我最后的解決辦法是,逆向這些apk,修改游戲邏輯。讓我在玩的時候,可以快速度過緩慢的前期。

逆向了幾個玩過的游戲,發現這類游戲使用Unity3D開發的居多。因此本文將介紹簡單Unity3D類安卓游戲的逆向修改思路。

0x01 準備工具

逆向最簡單的Unity3D類安卓游戲建議使用安裝好 JAVA 環境的Windows系統(涉及到dll文件的修改,所以Windows平臺更加適合)。

1.1 安卓 APK 逆向三件套

一般 APK 逆向,常使用到 apktooldex2jarjd-gui。在逆向 Unity3D 安卓游戲時,僅僅只需要使用到 apktool

  • Apktool: 用于解壓/重新打包安卓APK。
  • dex2jar: 將解壓出來的dex文件變成jar,方便使用jd-gui查看
  • jd-gui: 查看dex文件邏輯

1.2 dll文件逆向三件套

因為一般的 Unity3D 安卓游戲的主邏輯都在 asserts/bin/data/Managed/Assembly-CSarp.dll 中,所以我們還需要 dll文件逆向/重新打包 的工具。

  • ILSpy: 用于查看dll程序邏輯
  • ILDASM: 用于反編譯dll文件,生成il文件(存放了dll反編譯后的指令)和res文件(反編譯后的資源文件),可以安裝Windows SDK或者從網上下載。
  • ilasm: .net4.0自帶了,位置在 C:\Windows\Microsofr.NET\Framework\v4.0.30319\ilasm.exe

1.3 生成重新打包的自簽名證書

修改完 apk 之后,需要對 apk 進行簽名。該命令用于生成簽名的證書。

keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 0validity 10000
# 記住設置的密碼,最后自簽名應用的時候需要輸入密碼

0x02 開發一個簡單的 Unity3D 游戲

用Unity3D開發了一個簡單小游戲作為本文的樣例,邏輯十分簡單:

  1. 英雄每過一關戰斗力都會增加100.
  2. 怪物的戰斗力為 Math.pow(2,當前關數)
  3. 當英雄戰斗力小于怪物的戰斗力時,英雄無法闖關。英雄可以考慮修煉或者重生提高戰斗力。
  4. 英雄每次修煉戰斗力都會增加1000.
  5. 英雄選擇重生后,關卡數清零,需要重新闖關,但英雄初始戰斗力會增加 2000 * 重生前闖關數。

具體代碼可以參考 Github

0x03 游戲逆向步驟

1.使用 apktool 解壓游戲安裝包

java -jar apktool.jar d game.apk

2.提取出 game/assets/bin/data/Managed/Assembly-CSarp.dll ,使用 ILSpy 打開即可看到 dll 里面的邏輯。

注: Unity3D開發的安卓游戲,其核心代碼都在這個 dll 文件中,所以逆向/修改這個 dll 文件就可以了。這也是 Unity3D 和 其它安卓逆向不同的地方。

在沒有混淆的情況下,反編譯出的函數內容和原內容十分相似:

ILSpy 反編譯的 Click1 內容

Click1 的原始代碼

3.找到關鍵函數、關鍵邏輯后,就可以嘗試反編譯 dll 文件并修改。使用 ILDASMdll 文件反編譯成 il 文件。使用 ILDASM 打開 dll 文件后, File -> dump 就可以導出反編譯結果了。

4.根據步驟2,就很容易理解邏輯了,然后根據速查表,就可以知道在步驟3導出的il文件中修改哪里了。例如步驟2中 Click1 就是游戲中 點擊闖關 按鈕綁定的邏輯。闖關的關鍵判斷就在: info.hero_power + info.temp_power + info.add_power >= info.monster_power。所以打開步驟3中生成的 .il 文件,結合 .NET IL 指令速查表修改這部分對應的關鍵邏輯即可。

修改為 info.hero_power + info.temp_power + info.add_power != info.monster_power 就可以通過此處的邏輯判斷。

5.修改關鍵邏輯后,通過重新編譯 dll 文件、apk 文件、簽名修改后的 apk 就可以在手機上安裝運行了。

重新編譯dll文件命令如下:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe game.il /output=Assembly-CSarp.dll /dll

將重新編譯的dll放回 game/assets/bin/data/Managed/ 目錄下,使用apktool重新打包apk:

java -jar apktool.jar b game
cp game/dist/game.apk ./

自簽名應用:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore game.apk alias_name

6.修改成功,開局修煉一次后,就可以無限闖關。順利到達第30關。

0x04 雜談和總結

  1. Unity3D有一個較為明顯的特征: 開局會顯示游戲LOGO。這個可以作為判斷一個游戲是不是Unity3D開發的小參考。
  2. 文中的demo到了31關,就會發生整型溢出,怪物戰斗力變為負數。原因是怪物戰斗力的值為int型。在以前玩過的某個后期極度不平衡的游戲中,我的確遇到過整型溢出的問題。造成花錢升級還能增余額的情況。
  3. 在修改游戲之前把游戲語言調整為英文有助于在逆向的時候理解各個函數的意義(對于沒有混淆的應用)。
  4. 游戲修改之后,很容易喪失原本的樂趣,變成純粹的數字游戲。謹慎修改!

0x05 參考鏈接

  1. Apktool
  2. ILSpy
  3. .NET IL 指令速查表
  4. Unity3d類安卓游戲逆向分析初探

Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/829/