【Arcaea/逆向記錄合集】殼子額外修改詳細(xì)教程

閱前說(shuō)明:本文所寫內(nèi)容已經(jīng)根本觸犯了Lowiro Limited的核心利益,內(nèi)容僅供學(xué)習(xí)交流,作者對(duì)于讀者所做的任何行為概不負(fù)責(zé),如果跟著本文所寫內(nèi)容操作,您需要對(duì)自己的行為導(dǎo)致的任何后果負(fù)責(zé)!
*本文不提供文中的逆向后資源,逆向前資源,逆向工具。
*不提供完整的,所有架構(gòu),所有版本的修改。
*對(duì)于普通的修改打包、如何改寫指令這種基礎(chǔ)操作,概不贅述。
*本人沒有蘋果公司推出的任何系統(tǒng)的設(shè)備,因此文中通篇使用安卓設(shè)備。
*對(duì)于三件套Hash校驗(yàn)、離線Beyond限制破解等,概不提供,請(qǐng)移步至其他文章。
使用架構(gòu):arm64-v8a/armeabi-v7a(均支持arm64-v8a)
IDA版本:7.0(建議附帶Keypatch插件使用)
APK版本:不限(不保持最新版本更新,4.1.9的修改情況也適用于4.2大版本系列)
對(duì)于4.1.9,且使用架構(gòu)為arm64-v8a的讀者們,推薦配合@xingjiFIUG編寫的安卓版arcaea 4.1.9自制逆向詳細(xì)教程進(jìn)行修改

排版很亂,原諒我吧orz
——目錄:
——1.流速上限
——2.曲包鎖
——3.三星PTT邊框顏色
——4.背景解鎖
——5.Beyond章節(jié)無(wú)條件解鎖
——6.殘片上限
——7.殘片購(gòu)買體力不減
——8.世界模式相關(guān)物品解鎖
——9.修改EARLY & LATE的顏色
——10.修改Arc & 黑線的顏色
——11.修改光的離線技能
——12.風(fēng)暴解鎖挑戰(zhàn)通過數(shù)量修改
——13.World Extend分類限制破解 & 整包下載

*流速上限*
-4.0.255之前/armeabi-v7a/3.5.3c-
打開Strings窗口,搜索HighspeedSettingLayer.csb,雙擊進(jìn)入
進(jìn)入到對(duì)應(yīng)匯編位置后,按Tab查看偽代碼
往上查看,看到HIDWORD(**) = 65,選中,按Tab返回匯編頁(yè)面
對(duì)應(yīng)匯編指令是MOVEQ,將后面的數(shù)值改為你想要的最高速

繼續(xù)按Tab轉(zhuǎn)回偽代碼,看向上方的LODWORD,雙擊進(jìn)后面=的函數(shù)
進(jìn)入后按Tab返回匯編,找到IT HI和MOVHI,將兩條匯編指令改為NOP即可



-4.0.255之前/arm64-v8a/3.5.3c-
打開Search - Immediate value,勾選Find all occurrence,輸入0x41搜索
搜索完畢后,在Occurrence of value界面輸入MOV,主要找后面為W9的指令
進(jìn)去一個(gè)一個(gè)看匯編,一定會(huì)有兩個(gè)MOV,一個(gè)SUBS,以及一個(gè)CMP


我們逐步解析各個(gè)數(shù)字的含義:
第一個(gè)MOV的0x41=最高速(可以為0)
第二個(gè)MOV的0xA=最低速(可以為0,不清楚副作用)
SUBS的0xB=減數(shù)(可以為0,不過會(huì)出現(xiàn)流速鎖定為0的問題)
CMP的0x35=最高速-減數(shù)
減數(shù)最好不要太小,最低速也最好不要設(shè)為10以下,避免問題出現(xiàn)
我們只需要在每個(gè)有上述相同指令的函數(shù)內(nèi)修改好對(duì)應(yīng)數(shù)字即可

然后回到Strings窗口,搜索highspeed_setting_layer,進(jìn)入第一個(gè)xref
按Tab查看偽代碼,下翻找到>=11,將最低速+1,然后修改
再xref一下11前面的v5,找到>10,改成最低速即可完成
小知識(shí):理論上64位最高速能改為429496729.5,但是因?yàn)镃MP的限制導(dǎo)致最高速只能為409.6,最低速受最高速影響,雖然也能設(shè)置成429496729.5,但是會(huì)出現(xiàn)bug

-4.0.255開始/arm64-v8a/4.1.9-
打開Search - Immediate value,勾選Find all occurrence,輸入0x41搜索
搜索完畢后,在Occurrence of value界面輸入MOV,主要找后面為W10的指令
進(jìn)去一個(gè)一個(gè)看匯編,一定會(huì)有兩個(gè)MOV,一個(gè)SUB,以及兩個(gè)CMP


我們逐步解析各個(gè)數(shù)字的含義:
第一個(gè)MOV的0xA=最低速(可以為0)
第二個(gè)MOV的0x41=最高速(可以為0)
SUB的0xB=減數(shù)(可以為0)
第一個(gè)CMP的0xA:最低速(可以為0)
第二個(gè)CMP的0x35=最高速-減數(shù)
我們只需要在每個(gè)有上述相同指令的函數(shù)內(nèi)修改好對(duì)應(yīng)數(shù)字即可

然后回到Strings窗口,搜索Control the speed at\nwhich notes approach,進(jìn)入?yún)R編頁(yè)面
右鍵,選擇Graph View(如果不能切換,就打開Options- General的Graph,修改Max number of nodes),劃到下面第一個(gè)CBZ
看上面的MOV,W9改成最高速,W7改成最低速即可


*曲包鎖*
-armeabi-v7a/3.5.3c-
打開Strings窗口,搜索lock_icon,雙擊進(jìn)入
按Tab查看偽代碼,看到下面的if ( v20 || Pack::isExtendPack ),xref一下v20

Xref到上方后,雙擊進(jìn)入該函數(shù),進(jìn)入偽代碼,移動(dòng)到最底下

看到此處result = 0,按下Tab查看對(duì)應(yīng)匯編指令,將MOVS改為#1即可

-arm64-v8a/3.5.3c-
打開Strings窗口,搜索lock_icon,雙擊進(jìn)入
按Tab查看偽代碼,看到下面的if ( v19 & 1?),xref一下v19(不要xref下面為operator delete的v155)

Xref到上方后,雙擊進(jìn)入該函數(shù),進(jìn)入偽代碼,移動(dòng)到最底下

對(duì)著result xref,找到result = 0LL,雙擊跳轉(zhuǎn)

看到此處result = 0LL,按下Tab查看對(duì)應(yīng)匯編指令,將MOV改為#1即可
注:在大約4.1左右的版本,616修改了這里指向的函數(shù),在這之前如果破解此項(xiàng)就會(huì)一并解鎖單曲和曲包及曲包內(nèi)的曲目,從這開始就只能破解曲包圖片的鎖標(biāo),其他所有均為鎖定狀態(tài),需要另找函數(shù)修改

-arm64-v8a/4.1.9-
打開Strings窗口,搜索lock_icon,雙擊進(jìn)入
按Tab查看偽代碼,看到下面的if ( v67?& 1?),xref一下v67,再xref對(duì)應(yīng)的v63(不要xref下面為operator delete的v223)
注:如果這里沒有這種xref到相關(guān)函數(shù)的(4.0.256),直接在PackSelectCell.csb至packImage這范圍尋找函數(shù),再雙擊進(jìn)入


Xref到上方后,雙擊進(jìn)入該函數(shù),進(jìn)入偽代碼,移動(dòng)到最底下

對(duì)著v4 xref,盡可能把你能看到的v4 = 0或者其他結(jié)果的匯編指令改為1

將用紅框圈起來(lái)的v4 xref處的指令全部改為MOV W10, #1即可
(強(qiáng)烈建議arm64-v8a的讀者使用4.2.0或以上版本破解,將下方提到的"世界模式相關(guān)物品"破解,在packlist給對(duì)應(yīng)曲包加上"is_extend_pack": true可以繞過歌曲無(wú)法游玩的限制)

*三星PTT邊框顏色*
-armeabi-v7a/4.0.1c-
-arm64-v8a/4.1.9-
打開Strings窗口,搜索rating_7.png,雙擊進(jìn)入
按Tab查看偽代碼,看到下面一行的104LL、9LL,52LL和255LL

這就是達(dá)到三星條件后的ptt邊框顏色,往上翻到rating_off.png

這就是普通ptt邊框顏色了,改為與三星一樣的Hex值即可

*背景解鎖*
-armeabi-v7a/3.5.3c & 4.0.255(c)-
-arm64-v8a/3.5.3c &?4.1.9-
切換至3.5.3c版本,打開Functions窗口,搜索SceneryManager::isUnlocked,雙擊進(jìn)入Segment為.text的函數(shù)
按Tab查看偽代碼,劃到最底端,往上翻找到v14,Xref一下,看到v14?= 0,按Tab查看匯編指令,把對(duì)應(yīng)MOV改為#1


打開4.1.9版本,并且切換回3.5.3c版本,回到剛才的函數(shù)底端
鎖定一個(gè)函數(shù)目標(biāo),我們鎖定函數(shù)底端的PurchaseManager::isWorldUnlocked,xref
選擇SongSelectScene::promptNonExtendWorldLocked作為目標(biāo),查找里面的字符串
通過匯編尋找,鎖定This song is available by progressing through World Mode.這個(gè)字符串


切換4.1.9版本,進(jìn)入Strings窗口,查找上方的字符串,雙擊進(jìn)入
跟3.5.3c偽代碼對(duì)比,PurchaseManager::isWorldUnlocked在3.5.3c的函數(shù)開頭,切換回4.1.9看函數(shù)開頭
簡(jiǎn)單尋找一下,鎖定到sub_E9ABC0就是PurchaseManager::isWorldUnlocked,我們就可以Xref一個(gè)一個(gè)找函數(shù)
打開3.5.3c版本的SceneryManager::isUnlocked,根據(jù)PurchaseManager::isWorldUnlocked的位置和函數(shù)總體進(jìn)行對(duì)比

最后我們鎖定到sub_61A344就是對(duì)應(yīng)的Scenery解鎖函數(shù)
進(jìn)入?yún)R編修改對(duì)應(yīng)的MOV即可(修改中段的MOV W23即可)

*Beyond章節(jié)無(wú)條件解鎖*
-arm64-v8a/3.5.3c & 4.1.9-
打開Search - Immediate value,勾選Find all occurrence,輸入0x383搜索
搜索完畢后,在Occurrence of value界面輸入CMP,雙擊進(jìn)入

-3.5.3c-
按Tab查看偽代碼,找到return 0LL,按Tab查看匯編
找到對(duì)應(yīng)的MOV,改為#1即可

-4.1.9-
看到CMP下面的B.GT,打開Edit - Patch Program - Change byte
找到開頭的EC 00 00 54,改為07 00 00 14即可

*殘片上限*
-arm64-v8a/3.5.3c &?4.1.9-
打開Search - Immediate value,勾選Find all occurrence

-3.5.3c-
輸入0x270F搜索,搜索完畢后,在Occurrence of value界面輸入MOV,看W9的指令
一個(gè)一個(gè)看偽代碼,知道看到if ( v1 >= 9999 ),下面的v1 = 9999時(shí),選中9999,按Tab查看匯編
修改對(duì)應(yīng)MOV的#0x270F即可

-4.1.9-
輸入0x752D搜索,搜索完畢后,在Occurrence of value界面輸入MOV,看W10的指令
一個(gè)一個(gè)看偽代碼,知道看到if ( v1 >=?29997?),下面的v1 = 29997時(shí),選中29997,按Tab查看匯編
修改對(duì)應(yīng)MOV的#0x752D即可

*殘片購(gòu)買體力不減*
-arm64-v8a/3.5.3c &?4.1.9-
-3.5.3c-
打開Strings窗口,搜索Stamina Refilled,雙擊進(jìn)入
按Tab查看偽代碼,看到上方的三個(gè)1000,選中,按Tab查看匯編
看到MOV/CMP/SUB,將#0x3E8修改為#0即可

-4.1.9-
打開Search - Immediate value,勾選Find all occurrence,輸入0x3E8搜索
找到對(duì)應(yīng)的MOV(W9)/CMP(W8)/SUB(雙W8),雙擊進(jìn)入
找到對(duì)應(yīng)的匯編指令,將#0x3E8修改為#0即可

*世界模式相關(guān)物品解鎖*(破解這個(gè)也可以一并解鎖背景)
-arm64-v8a/3.5.3c &?4.1.9-
-3.5.3c-
打開Functions窗口,搜索PurchaseManager::isWorldUnlocked,雙擊進(jìn)入Segment為.text的函數(shù)
劃到最底端,找到result = 0LL,按Tab查看匯編,把對(duì)應(yīng)MOV改為#1即可


-4.1.9-
根據(jù)上文背景解鎖的尋找方案,找到對(duì)應(yīng)函數(shù)
劃到最底端,找到return result,選中result xref
看到result = 0LL,雙擊跳轉(zhuǎn),按Tab查看匯編,把對(duì)應(yīng)MOV改為#1即可


*修改EARLY & LATE的顏色*
-arm64-v8a/3.5.3c &?4.1.9-
打開Strings窗口,搜索EARLY或LATE,找到全大寫的字符串,雙擊進(jìn)入
按Tab查看偽代碼

-3.5.3c-
往上看可以發(fā)現(xiàn)對(duì)應(yīng)的Hex RGBA值

cocos2d::Color4B::Color4B中的透明度(170u)是雙方通用的,更改這個(gè)會(huì)一起把雙方的透明度更改(如果發(fā)現(xiàn)有負(fù)數(shù),選中 右鍵Invert Sign)
其余三項(xiàng)根據(jù)v6的值判斷填入的數(shù),然后分別填入v35(R),v36(G)和v37(B)
修改對(duì)應(yīng)的Hex RGBA值即可(將你想要的RGBA值拆成4部分,分別轉(zhuǎn)換成十六進(jìn)制填入。至于透明度以0~255的范圍填入,例如128就是50%透明度)

-4.1.9-
往上看可以發(fā)現(xiàn)對(duì)應(yīng)的Hex?RGBA值

與3.5.3c不同的是,這次透明度能分情況自定義了
根據(jù)v5的值判斷應(yīng)用哪個(gè)RGBA值
修改對(duì)應(yīng)的Hex RGBA值即可(將你想要的RGBA值拆成4部分,分別轉(zhuǎn)換成十六進(jìn)制填入。至于透明度以0~255的范圍填入,例如128就是50%透明度)

*修改四種難度的顏色*
(參考Negative_3Uです的Arcaea自制:關(guān)于3.12.6版本iOS自制殼子修改)
-arm64-v8a/3.5.3c &?4.1.9-
打開Strings窗口,搜索maxComboCountLabel,雙擊進(jìn)入

-3.5.3c-

從上到下,分別對(duì)應(yīng):Beyond、Future、Present,Past
只需要修改對(duì)應(yīng)的Hex RGB值即可

-4.1.9-

sub_795610就是難度顏色的函數(shù),雙擊進(jìn)入
進(jìn)入后依舊是從上到下,對(duì)應(yīng)Beyond、Future、Present,Past
只需要修改對(duì)應(yīng)的Hex?RGB值即可

*修改Arc & 黑線的顏色*
(參考Negative_3Uです的Arcaea自制:關(guān)于3.12.6版本iOS自制殼子修改)
-arm64-v8a/3.5.3c &?4.1.9-
-3.5.3c-
打開Functions窗口,搜索LogicColor::init,雙擊進(jìn)入Segment為.text的函數(shù)

這就是正常模式時(shí)的Arc顏色了,我們只需要修改里面的RGB值即可
case 2:綠 case 1:紅 case 0:藍(lán)

打開Strings窗口,搜索img/height_indicator.png,雙擊進(jìn)入
按Tab查看偽代碼

在下面的if ( v8 !=?1?)前面,是色盲模式下的Arc顏色
我們只需要修改里面的RGB值即可

在色盲模式的Arc顏色下面,連接的是營(yíng)養(yǎng)豐富模式下的Arc & 黑線顏色
我們只需要修改里面的RGB值即可
在函數(shù)開頭還有一串if ( v8 == 1 ),然后下面接著一些RGB值,暫時(shí)還不知是什么

初步判斷為黑線,我們只需要修改里面的RGB值即可

-4.1.9-
先找到cocos2d::Color3B::Color3B,不過我們要找對(duì)格式
不過我們能利用上面剛講完的修改四種難度的顏色里面的函數(shù)來(lái)找
就在函數(shù)底部我們就能找到

我們就能通過這里來(lái)xref,尋找LogicColor::init
首先先切回3.5.3c版本,我們可以看到LogicColor::init這個(gè)函數(shù)里面調(diào)用了cocos2d::Color3B::Color3B這個(gè)函數(shù)四次,我們就能在那一大坨xref里用排除法
我們只需要看在一個(gè)函數(shù)里面發(fā)現(xiàn)了四次或以上的xref就能找到了
經(jīng)過尋找,sub_E65A90就是我們要找的函數(shù)了
我們只需要修改里面的RGB值即可

打開Strings窗口,搜索img/height_indicator.png,雙擊進(jìn)入
按Tab查看偽代碼,劃到最上方
往下找if ( v9 == 1 )

從這里開始往下找,就是一一對(duì)應(yīng)的各種模式下各物件的RGB值了



*修改曲包分類豎條位置*
-arm64-v8a/3.5.3c &?4.1.9-
打開Strings窗口,搜索img/divider_free.png,雙擊進(jìn)入
按Tab查看偽代碼

-3.5.3c-
看到上方的if句段,后面的v19 = 11和v19 = 7,前者對(duì)應(yīng)聯(lián)動(dòng)曲包豎條,后者對(duì)應(yīng)支線曲包豎條
再看到下方的v19 = 2/7/11這些if條件,里面對(duì)應(yīng)的就是豎條前有多少個(gè)曲包,改CMP大數(shù)字即可
支線和聯(lián)動(dòng)曲包豎條修改對(duì)應(yīng)條件數(shù)字之后,還需要把上述提到的v19 = 11以及v19 = 7改成一樣的數(shù)字


故事曲包豎條雖然能更改其條件,但是會(huì)出bug(僅實(shí)測(cè)4.1.9),在不使用下面的方法的情況下保持原樣
免費(fèi)曲包豎條由于使用CBNZ進(jìn)行判斷,無(wú)法更改,倒是能使其消失(見下方↓)

回到divider_free.png上方的if句段,對(duì)著旁邊的數(shù)按Tab查看匯編
將TST改為CMP W20, #[故事曲包豎條前置曲包數(shù)]
至于上方的MOV和MOVK直接NOP即可
這樣就可以讓免費(fèi)曲包豎條消失,并且能自定義故事曲包豎條的位置了

-4.1.9-
由于4.0.255更新了Silent Answer這個(gè)曲包,曲包豎條跟以往有分不同情況
注:該部分所有圖片都已經(jīng)人為修改過,請(qǐng)不要混淆至原版情況


可以看到支線故事和聯(lián)動(dòng)曲包豎條不再是直接給出指定數(shù)字了,而是使用了v242和v241的值進(jìn)行控制
對(duì)其xref,可以發(fā)現(xiàn)這兩個(gè)值分別對(duì)v10進(jìn)行了加法(ADD),再xref一下v10,除了這兩處加法,還有三處xref
先看第一和第二個(gè)xref處,有一個(gè)if句段控制了v10的值

此處主要看else前的數(shù),else后面的v10 = 2是上方的v10 = 1后的數(shù)+1
不難發(fā)現(xiàn),此處應(yīng)該是控制epilogue包是否存在時(shí)的情況
不存在則使用上方的數(shù),而存在則使用下方的數(shù)
再來(lái)看看第三處xref

疑似沒什么用,不過數(shù)值建議改成上兩處對(duì)應(yīng)的值
除了這個(gè)改動(dòng)之外,favorite的分割符也被丟進(jìn)來(lái)了,感興趣自己改改

免費(fèi)曲包豎條依舊使用CBNZ判斷,無(wú)法更改
讓其消失并且控制故事曲包豎條:參考上方3.5.3c的方法,作用是一樣的,不過MOVK要改成LDR W8, [SP,#0x420+var_368]

*修改光的離線技能*
-arm64-v8a/3.5.3c &?4.1.9-
打開Strings窗口,搜索img/empty.png,雙擊進(jìn)入

-3.5.3c-
往下翻一下,會(huì)看見這樣一個(gè)匯編

MOV W1~W6分別對(duì)應(yīng)不同的技能附加,可以疊加修改
如果技能要用替換函數(shù)的話,找到對(duì)應(yīng)方案替換即可(353有點(diǎn)麻煩我就不寫了)

-4.1.9-
往上翻,會(huì)看見這樣一個(gè)匯編

結(jié)構(gòu)比3.5.3c精簡(jiǎn)了不少,MOV W1~W6分別對(duì)應(yīng)不同的技能附加,可以疊加修改
如果技能要用替換函數(shù)的話,找到MOV W5后面的BL,替換跳轉(zhuǎn)函數(shù)即可
建議把格式也改為對(duì)應(yīng)函數(shù)的格式,以免BUG

*風(fēng)暴解鎖挑戰(zhàn)通過數(shù)量修改*
-arm64-v8a/3.5.3c &?4.1.9-
打開Strings窗口,搜索continue_line.png,xref
找上方有一處判斷某個(gè)值是否為4的if句段的xref

-3.5.3c-

更改v203的4即可

-4.1.9-

更改HIDWORD(v154)的4即可

*World Extend分類限制破解 & 整包下載*
-arm64-v8a/3.5.3c-
打開Strings窗口,搜索extend,xref
在xref的函數(shù)里找SongListLayer::getGroupsForSonglist、SongSelectScene::showSongSelect、SongListLayer::updateSongList,Song::isRemoteDownloadPresent和SongSelectScene::promptDownload,分別雙擊進(jìn)入
在SongListLayer::getGroupsForSonglist里面,把CBNZ W0, loc_6B8B90改成B loc_6B8B90,這樣我們就解決了固定分類為日期的問題
切換到SongSelectScene::showSongSelect里面,在匯編里面找到CBNZ W0, loc_56E580,改為B loc_56E580,這樣我們就解決了默認(rèn)不顯示分類按鈕的問題
切換到SongListLayer::updateSongList里面,在匯編里面找到CBNZ W0, loc_6B6128,改為B loc_6B6128,這樣我們就解決了排序固定日期的問題
切換到Song::isRemoteDownloadPresent里面,在匯編里面找到CBZ W0,?loc_68AEE8,改為B?loc_68AEE8,這樣我們就解決了下載的問題
切換到SongSelectScene::promptDownload里面,在匯編里面找到CBZ?W0,?loc_57286C,改為B?loc_57276C,這樣我們就解決了下載界面的問題
(單曲下載可以修改Song::isRemoteDownloadPresent和SongSelectScene::promptDownload達(dá)成,將跳轉(zhuǎn)到整包下載的跳轉(zhuǎn)全部指向單曲類下載即可)
改完以上這些后,WE包開了之后跟目前正常曲包沒啥兩樣了

*角色偏移修改*
-arm64-v8a/3.5.3c-
先打開3.5.3c版本,打開Functions窗口,搜索Offset,名稱排序后可以看到Character::getCenterScreenOffset/CharacterSelectOffset/ResultsOffset/SkillOffset,這就是角色偏移位置的儲(chǔ)存函數(shù),分別對(duì)應(yīng)的是主界面/搭檔選擇界面/結(jié)算界面/游玩曲目時(shí)的技能顯示框(這玩意第一次看挺腦梗的真的),除了CharacterSelectOffset/ResultsOffset,其他的幾乎是塞滿了全部角色的偏移情況(而且塞的很亂),我們進(jìn)去看getCenterScreenOffset
使用armeabi-v7a輔助偽代碼分析,圖例已修改(因?yàn)槲襥da64偽代碼就jumpout讓我很腦梗)

其實(shí)很多自己試一下在看就試出來(lái)了()用的全部都是浮點(diǎn)數(shù),有些是僅有X坐標(biāo)或者Y坐標(biāo),用浮點(diǎn)數(shù)轉(zhuǎn)16進(jìn)制填入即可

3.5.3以上的話,打開Search - Immediate value,勾選Find all occurrence,在上面隨便找一個(gè)沒那么多重復(fù)的浮點(diǎn)數(shù)十六進(jìn)制,輸入搜索即可,其他Offset同理

寫了好多寄吧廢東西啊我超
應(yīng)該不會(huì)動(dòng)這玩意了
怎么ida識(shí)別不出來(lái)BR啊我快死了
以后有更新會(huì)直接更正專欄,耗費(fèi)3次次數(shù)后直接開篇新的看看)
【Arcaea/逆向記錄合集】殼子額外修改詳細(xì)教程的評(píng)論 (共 條)
