1. 程式人生 > >《旅行青蛙》反編譯/破解過程

《旅行青蛙》反編譯/破解過程

[email protected], 小學生 from 10.0.0.55

原文地址:

這篇部落格是應學姐之邀給學弟學妹寫的掃盲教程,較為基礎

前言

破解旅行青蛙的初衷很簡單,女朋友想養青蛙,三葉草長得太慢,作為一名二進位制黑闊又不願屈服於網上小廣告成堆又不知道有沒有後門的破解版,於是就參考知乎的高贊回答自己給旅行青蛙添加了無限三葉草和無限抽獎券的功能。

受桐姐之邀,給學弟學妹簡單介紹一下反編譯技術,以及反編譯技術是怎麼運用到破解旅行青蛙這款遊戲上的,力求能夠用通俗易懂的語言給對此感興趣的同學講解清楚。

何為反編譯

我們知道,高階語言源程式經過編譯生成可執行檔案(事實上有預處理,編譯,彙編,連結四步,這裡籠統的概括為編譯,這個過程在《程式設計師的自我修養》這本書中有詳細的介紹

),那麼加上一個“反”字,也就是從可執行檔案反向生成高階語言原始碼的過程。

聽起來很簡單但實際上反編譯是逆向工程最核心最困難的一步,通常做不到把可執行檔案逆向出高階語言原始碼,只能轉化成彙編程式,即使某些高階語言(C#,vb,python等)反編譯出原始碼相對簡單,得到的程式碼也往往是被混淆過的。

上圖是windows平臺下強大的反編譯工具OllyDbg,但也只能得到彙編級的程式碼。

對於部分C族語言(C/C++),藉助IDA的HexRay外掛可以得到近似原始碼的虛擬碼,但這些虛擬碼也往往是有錯誤的。

破解青蛙

但幸運的是,旅行的青蛙是基於Unity開發的.NET程式,對於.NET程式,反編譯技術較為成熟。

首先解壓旅行青蛙的apk

apk實際上就是一個壓縮包,windows下把字尾.apk改為.zip即可解壓,值得一提的是,word、excle、powerpoint等檔案的實質也是壓縮包,解壓這些檔案也會有很多好玩的事情發生。

通過解壓後存在assets\bin\Data\Managed目錄判斷出遊戲為Unity遊戲,那麼程式的主要程式碼就在assets\bin\Data\Managed\Assembly-CSharp.dll中

我們只需對Assembly-CSharp.dll進行反編譯即可,這裡使用的是dnspy工具,當然其他的.NET反編譯工具如ILSpy也是可以的。

把Assembly-CSharp.dll拖到dnspy中,稍等片刻,即可得到旅行青蛙程式的目錄樹和原始碼

這裡需要說明一下,像這種既沒有加殼保護,也沒有程式碼混淆的程式實際上是很少存在的,這款程式幾乎沒有防護措施大概是因為日本程式設計師和國內程式設計師的風格不同。

那麼我們應該怎麼定位到關鍵程式碼呢?這裡有一種很高效的方法:搜尋關鍵字串

比如在抽獎時,提示抽獎券數量不足,那麼我們就能確定抽獎的程式碼就在這串字元出現的程式碼附近,我們就搜尋這個字(= =如果認識日文搜尋這整句話更快)

搜到了兩處,雙擊定位,發現第一處就是我們要找的程式碼(其實根據方法名PushRollButton也能推斷出)

可以發現,這段程式碼就是抽獎的程式碼,若抽獎券數量<5(第一處箭頭),則報錯返回(二三處箭頭),否則把抽獎券的數量自減5(第4處箭頭)。

這樣我們修改抽獎邏輯的思路就有很多了:

  1. 第一處箭頭的<5改為<0,那麼我們一直滿足抽獎的條件,就可以一直抽獎
  2. 第四處箭頭的-5改成0,那麼每次抽獎後抽獎券的數量就不會減少,或者更進一步把-5改為+5,那麼每次抽完獎,抽獎券的數量還會增加5
  3. 根據程式碼可以得知獲取抽獎券數量方法的是TicketStock,可以針對TicketStock進行修改
  4. .....

這裡主要介紹第3種方法,我們通過檢視TicketStock方法,可以發現TicketStock方法是從ticket變數取值的

查詢ticket,發現了初始化ticket的程式碼,同時發現了疑似初始化三葉草數量的程式碼

ctrl+shift+E修改此處程式碼,將69,70行的初始化均改為9999

點選編譯儲存修改,再點選 檔案->全部儲存(快捷鍵ctrl+shift+S)將修改儲存回dll

然後將apk重新打包檢測修改效果(因為apk實質就是壓縮包,重新壓縮,更改字尾為 .apk即可)

放到模擬器中檢測修改效果(需要先解除安裝原版旅行青蛙

可以發現,三葉草和旅行券都已經被修改了

旅行券是999而不是9999是因為程式碼中有一處限制數量不超過999的判斷,很容易發現

此外,雖然此時的apk可以再模擬器中執行,但實際上在真機上是不能執行的,原因和解決辦法之後會提到

但再多的三葉草和抽獎券也有花光的一天,我們可以嘗試再進一步修改。

通過檢視ticket和clover的程式碼,可以找到返回三葉草數量和抽獎券數量的程式碼,直接把函式的返回值修改為9999,這樣無論對三葉草和抽獎券做什麼操作,都會返回9999,這樣三葉草和抽獎券的數量就固定了,也就達到了無限三葉草和抽獎券的目的。

然後再ctrl+shift+S,重新打包apk即可。

解決簽名

之前說過,重新打包好的apk並不能在真機上執行,是因為真機會檢測安卓程式的簽名,安卓的apk在簽名時會對所有原始檔進行一個hash運算,安裝時hash校驗失敗就會拒絕安裝

不能覆蓋安裝也是因為簽名的原因,如果想繼續存檔,可以先把GameData.sav儲存一份,安裝好破解版的後重新匯入即可

那麼怎麼繞過簽名校驗呢?我們只需要重新對apk進行簽名即可。因為本人對apk的開發並不十分了解,在簽名時還是花了一段時間研究的,後來發現可以通過apktool box工具包直接進行簡單的簽名

簽名之後,即可真機執行

更進一步

更多修改

本次修改只修改了三葉草/抽獎券的初始值和返回值,但我們完全可以根據程式碼邏輯進行更多的修改,如:

  1. 修改抽獎機率
  2. 修改儲存圖片的上限
  3. 縮短旅行時間
  4. 修改獲得珍稀照片的概率
  5. 對apk圖示等資源進行修改
  6. ......

漢化

漢化也很簡單,我們找到日文字串後,修改為中文字串即可,漢化是個體力活,這裡就不再展示了。

......

宣告

  • 本次修改目的是學習交流,請勿用於盈利