簡單破解旅行青蛙
最近一款佛系養娃(誤)蛙的遊戲突然爆紅,我也試著玩了一下,結果被圈粉了。有蛙當然要晒,但是看朋友圈,別人的蛙出去拍的照片都是光鮮亮麗,呼朋喚友的,自家的蛙卻只能單人窮遊。說到底是當爹的沒錢害的,但是沒錢沒關係,咱喜歡瞎折騰。下面咱就來搞搞這個小遊戲。
首先,得拿到這個小遊戲的apk。我這是通過adb pull下來的,你也可以從應用市場下載。
改apk的字尾名為rar,用壓縮軟體開啟。大致看一下,可以看出來就是一個unity遊戲。那麼就把assets\bin\Data\Managed下的Assembly-CSharp.dll拿出來。咱們後面分析修改的就是這個dll檔案了。
網上找了一下,發現dnSpy(dnSpy 是一款針對 .NET 程式的逆向工程工具
接下來開始分析吧。玩過遊戲的知道,遊戲的主要貨幣是三葉草,還有抽獎券也比較常用。
大致就是這種感覺,啥也買不起。另外一點比較尷尬,就是這個遊戲不支援中文,不過好在我們還能看懂葉、券、足三個字。這兩段日語的意思大致就是三葉草不夠、抽獎券不夠。
跑題了,反正我們已經知道了分析的切入點(就是那三個字)。dnSpy中Ctrl+Shift+K,出現全域性搜尋框,選擇數字/字串,搜“足”字。正好出來兩個結果,1個對應抽獎券,1個對應三葉草。
首先看PushRollButton方法,雙擊定位到程式碼處(dnSpy的好處就在於此,反編譯的程式碼十分接近原始碼,很容易看懂)。PushRollButton很明顯指按下抽獎券那個轉輪按鈕的意思。如下就是該方法的反編譯程式碼,可以看到一段熟悉的日語,看來是找對地方了。接下來就是看程式碼了,這段程式碼的意思很明確。首先判斷券的數量是否小於5(玩過遊戲的知道,5張券才能抽1次):小於就彈券不夠的日語框並結束這個方法,後面的抽獎的操作就不做了;大於等於就給你扣5張券,接著給你抽獎。
簡單地修改的話就是讓判斷條件恆為假,不進入彈框步驟,並且抽獎不扣獎券。所以,我們可以將5和-5改為0和0。獎券數量最少為0,不會小於0,因此不會去彈框。每回抽獎前扣0張券。
那麼,如何改這個dll呢。dnSpy也提供修改dll檔案的功能。在要修改的方法中右鍵選擇編輯IL指令。將ldc.i4.5改為ldc.i4.0,將-5改為0,點選確定。再看程式碼,已經改成功了。
券已經改完了,接下來是三葉草了。定位到SetInfoPanelData方法。方法有點長,我直接copy下來了。前面一堆大致是操作選擇物品相關的程式碼,我們著重看if(SuperGameMaster.CloverPointStock()>=
public void SetInfoPanelData(int shopIndex, Vector3 pos)
{
if (shopIndex == -1)
{
this.unsetCursor();
this.InfoPanel.GetComponent<InfoPanel>().SetInfoPanel(-1);
return;
}
if (Mathf.Abs(this.flickMove) > this.S_FlickChecker.flickMin / 3f)
{
return;
}
if (this.selectShopIndex != shopIndex)
{
this.InfoPanel.GetComponent<InfoPanel>().SetInfoPanel(shopIndex);
this.selectShopIndex = shopIndex;
this.setCursor(pos);
SuperGameMaster.audioMgr.PlaySE(Define.SEDict["SE_Cursor"]);
}
else
{
ShopDataFormat shopDataFormat = SuperGameMaster.sDataBase.get_ShopDB(shopIndex);
ItemDataFormat itemDataFormat = SuperGameMaster.sDataBase.get_ItemDB_forId(shopDataFormat.itemId);
if (itemDataFormat == null)
{
return;
}
if (!itemDataFormat.spend && SuperGameMaster.FindItemStock(itemDataFormat.id) != 0)
{
SuperGameMaster.audioMgr.PlaySE(Define.SEDict["SE_Cancel"]);
return;
}
if (SuperGameMaster.CloverPointStock() >= itemDataFormat.price)
{
if (SuperGameMaster.FindItemStock(shopDataFormat.itemId) < 99)
{
base.GetComponent<FlickCheaker>().stopFlick(true);
ConfilmPanel confilm = this.ConfilmUI.GetComponent<ConfilmPanel>();
if (itemDataFormat.type == Item.Type.LunchBox)
{
confilm.OpenPanel_YesNo(string.Concat(new object[]
{
itemDataFormat.name,
"\nを買いますか?\n(所持數\u3000",
SuperGameMaster.FindItemStock(shopDataFormat.itemId),
")"
}));
}
else
{
confilm.OpenPanel_YesNo(itemDataFormat.name + "\nを買いますか?");
}
confilm.ResetOnClick_Yes();
confilm.SetOnClick_Yes(delegate
{
confilm.ClosePanel();
});
confilm.SetOnClick_Yes(delegate
{
this.GetComponent<FlickCheaker>().stopFlick(false);
});
confilm.SetOnClick_Yes(delegate
{
this.BuyItem();
});
confilm.ResetOnClick_No();
confilm.SetOnClick_No(delegate
{
confilm.ClosePanel();
});
confilm.SetOnClick_No(delegate
{
this.GetComponent<FlickCheaker>().stopFlick(false);
});
}
else
{
base.GetComponent<FlickCheaker>().stopFlick(true);
ConfilmPanel confilm = this.ConfilmUI.GetComponent<ConfilmPanel>();
confilm.OpenPanel("もちものがいっぱいです");
confilm.ResetOnClick_Screen();
confilm.SetOnClick_Screen(delegate
{
confilm.ClosePanel();
});
confilm.SetOnClick_Screen(delegate
{
this.GetComponent<FlickCheaker>().stopFlick(false);
});
}
}
else
{
base.GetComponent<FlickCheaker>().stopFlick(true);
ConfilmPanel confilm = this.ConfilmUI.GetComponent<ConfilmPanel>();
confilm.OpenPanel("みつ葉が足りません");
confilm.ResetOnClick_Screen();
confilm.SetOnClick_Screen(delegate
{
confilm.ClosePanel();
});
confilm.SetOnClick_Screen(delegate
{
this.GetComponent<FlickCheaker>().stopFlick(false);
});
}
}
}
BuyItem方法:紅框是扣錢的操作,把price前面的負號去掉。買東西,程式給你三葉草,就是任性。
改的方法就是將neg給nop掉。
改完後:負號沒了。
Ctrl+Shift+S將更改後的dll檔案存起來。
開啟ApkIDE,將原始apk拖到APKIDE空白處開啟。開啟assets資料夾,將修改後的dll覆蓋原Assembly-CSharp.dll檔案。編譯生成APK,安裝編譯後的APK就可以了。
效果:
後記:文中涉及到的IL指令沒有細說,因為我也不會,自己查資料看著改吧。還有一些unity遊戲的漢化版可能也是通過這個方法來修改的吧。不過在這提醒一下大家,不要下載來歷不明的破解版或漢化版遊戲,很容易被人插入惡意程式碼,竊取個人隱私、惡意扣費等。
所用工具連結:
修改了一下APKIDE的連結地址,我用的是七少月大佬的3.3.3增強版,不過他之後又更新了,有興趣的看著下吧。
APKIDE:https://www.pd521.com/thread-818-1-2.html
dnSpy:https://down.52pojie.cn/Tools/NET/dnSpy.zip
=============華麗分界線===============
哈哈,更新一下,前面說到改無限抽獎,但實際抽的時候老是抽到白玉,很煩。找了一下,搜“白玉”,可以看到抽獎概率,下面是我改過的概率,之前的是白:青:綠:紅:金=60:27:9:3:1。照著之前的辦法改吧,哈哈。
還有就是蛙回家時間,我試著找了相關程式碼,太複雜了,改了幾次也沒成功。想玩快點的,照著網上說的修改系統時間來弄吧。
宣告:小白純屬瞎折騰蹭熱度。