最近一款佛系養娃(誤)蛙的遊戲突然爆紅,我也試着玩了一下,結果被圈粉了。有蛙當然要曬,但是看朋友圈,別人的蛙出去拍的照片都是光鮮亮麗,呼朋喚友的,自家的蛙卻只能單人窮遊。說到底是當爹的沒錢害的,但是沒錢沒關係,咱喜歡瞎折騰。下面咱就來搞搞這個小遊戲。
首先,得拿到這個小遊戲的apk。我這是通過adb pull下來的,你也可以從應用市場下載。
改apk的後綴名爲rar,用壓縮軟件打開。大致看一下,可以看出來就是一個unity遊戲。那麼就把assets\bin\Data\Managed下的Assembly-CSharp.dll拿出來。咱們後面分析修改的就是這個dll文件了。
網上找了一下,發現dnSpy(dnSpy 是一款針對 .NET 程序的逆向工程工具)十分好用。打開dnSpy,將上面的dll拖入空白界面。主界面如下:
接下來開始分析吧。玩過遊戲的知道,遊戲的主要貨幣是三葉草,還有抽獎券也比較常用。
大致就是這種感覺,啥也買不起。另外一點比較尷尬,就是這個遊戲不支持中文,不過好在我們還能看懂葉、券、足三個字。這兩段日語的意思大致就是三葉草不夠、抽獎券不夠。
跑題了,反正我們已經知道了分析的切入點(就是那三個字)。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() >= itemDataFormat.price) 後的代碼(從該判斷開始代表已經確定好要買的物品了)。該判斷可以明顯地看出就是將三葉草的數量和物品價格比較,不夠就彈框,夠就扣三葉草,一個套路。繼續分析,看到1個BuyItem方法,好了,還是一樣,想辦法不讓程序扣就行了。
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。照着之前的辦法改吧,哈哈。
還有就是蛙回家時間,我試着找了相關代碼,太複雜了,改了幾次也沒成功。想玩快點的,照着網上說的修改系統時間來弄吧。
聲明:小白純屬瞎折騰蹭熱度。