卡帶之痛:GBA《寶可夢》時鍾電路漏洞

原文摘自由本人編寫的「神奇寶貝百科」的「時鍾電路漏洞」詞條,有少量刪節修改

概論

時鍾電路漏洞,在海外多稱為稱樹果漏洞(日文︰きのみ問題,英文︰Berry glitch),是一個最早在《寶可夢 紅寶石/藍寶石》中被發現的漏洞,是原始遊戲卡時鍾電路(RTC)的設計缺陷導致。由於舊有RTC的設計比較原始,再加上遊戲設計者對遊戲設計中沒有提供一些便利的功能,理論上,早期帶有RTC晶振的實時時鍾的遊戲都會遇到這個問題,只不過由於《寶可夢》系列遊戲的知名度,這一問題在寶可夢領域反而是第一次被重視起來。

漏洞的技術原理概論

除了早期一些遊戲以及廉價的盜版卡,大多數GBA遊戲卡的存檔都普及了EEPROM或FLASH,不再存在給SRAM供電的電池,《寶可夢》也不例外。但是《寶可夢 紅寶石/藍寶石/綠寶石》的正版卡帶卻帶有一塊電池,這塊電池根本不是給存檔供電的,而是在給實時電路供電。當然,盜版卡帶為了節省成本依然在用SRAM。

另外說一個題外話:最早的《綠寶石》「盜版卡帶」有在進入殿堂時掉檔的BUG,是因為綠寶石的存檔雖然是64Kbits的,但是遊戲內有備份機制,所以正版卡的存檔其實是保存了兩份。而FLASH晶片的存檔大小其實是128K,但是最早分析ROM的盜版商發現存檔只有64K,於是盜版商只給卡帶配了一塊64K的SRAM晶片,《綠寶石》在進入殿堂後會有一次雙覆蓋存檔的過程,就會導致存檔損壞。

卡帶之痛:GBA《寶可夢》時鍾電路漏洞

《寶可夢 紅寶石/藍寶石/綠寶石》的遊戲卡擁有時鍾電路使用精工S-3511 石英晶振進行電路驅動,但那個年代的GBA卡帶中的晶振,既沒有對時功能,也不能靠網絡獲取真實的日期時間對時,其時間計算方式是由一串規則計算而來的相對值:

  • 遊戲卡時鍾電路啟動時的基準時間為「2000年1月1日 00:00:00」,之後時鍾電路會不斷運作,並且在除電池電量耗盡的情況下會一直向未來運作。
  • 而當玩家開始《紅寶石/藍寶石/綠寶石》的新遊戲,玩家需要在主角家中鍾表上設定時間,鍾表表面默認為上午10時,而玩家設定的時間會被作為「起始時間戳0時」,遊戲的報告會用一個五位數(10進位)記錄遊戲流逝的時間,其中初始零時記為00000。
  • 之後遊戲內在每次存檔時,會與時鍾比對,在此基礎上將時鍾電路上從「起始時間戳」開始,經過的日、時、分、秒數(年月全部換算為日數)以及星期轉化為一串數字,並作為時間戳存儲在遊戲的報告內,這個經過時間是隨著現實時間流逝,與實際遊戲時間無關,在遊戲關閉的時候,遊戲的「經過時間」(並非是遊戲的實際遊玩時間)依然會向後運作。
  • 每次遊戲內種植樹果和進行周期性事件後,存檔會記錄下下次事件刷新和樹果成熟的時間戳,直到時鍾電路的時間運行到這個刷新的時間戳之後,所有的事件才會刷新,樹果也會成熟。
  • 卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    舉個栗子:遊戲卡的時鍾電路啟動後3小時(電路時間為2000年1月1日3時0分)玩家開始了新遊戲,而玩家一開始在主角家中調整鍾表的時間為上午12點(距離遊戲內鍾表默認時間上午10點相差2小時),並在此時存檔,遊戲會以此時作為「起始時間0時」開始計算遊戲的經過時間,

    而在5天後的下午1點再開機並存檔的時候,此時時鍾電路的時間則是2000年1月6日4時0分,即便遊戲實際只運行了1分鍾,遊戲存檔的時間戳記錄的時間仍然是5天1小時。

    如果在此時種下一顆橙橙果,而第三世代中橙橙果的成熟時間是12個小時,那麼時間戳會記錄下這株橙橙果的成熟時間戳是「5天13小時」,當時鍾電路走到「2000年1月6日16時」的時候,這株橙橙果便會成熟。

    卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    用表格表達就是:

    卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    《紅藍寶石》的時鍾漏洞

    《紅寶石/藍寶石》中的時鍾漏洞是有官方說明的一個BUG,並且被官方承認。

    BUG產生的原因在於程式設計師將時間戳的記錄方式搞錯(「技術領先」的Gamefreak),導致晶振時間在「2000年」(不等於現實的2000年)的時候,存檔的時間戳反而會忽略累積年份。

    這一問題直接導致存檔時間戳記錄到「第367天」的時候(2000年是閏年),漏洞會導致該時間戳不是「啟動後第367天」,而是自動重置到「啟動後第1天」,遊戲存檔時間戳會立刻早於晶振367天。

    最終的結果就是:在「第366天」前觸發的周期性事件和種下的樹果,本應在「第367天」刷新和成熟,但由於時鍾電路的「第367天」錯誤的變為「第1天」,因此所有事件的刷新和樹果的成熟將因為沒有到達重置的時間而被凍結,直到366天之後,時鍾電路進行到「2002年1月2日」之後,存檔時間戳再度累積到「第367天」到來的時候才會解除。 而遊戲啟動時時鍾電路已經運行到2001年1月1日之後的存檔則不會觸發漏洞。

    用表格表達就是:

    卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    這個BUG如果對於經常搞程序的程式設計師應該不太陌生:它與計算機的時間不同步的問題有著許多共同點,即當硬體的時鍾與系統文件的時間印記不同步的時候,可能會導致系統內對文件的修改變為無效。

    不過計算機可以通過調整硬體的時鍾來解決問題。但GBA遊戲卡卻沒有給出官方的調整硬體時鍾的手段,這就導致問題會一直出現。

    衍生漏洞:電池耗盡與換電池

    由於整個時鍾電路全是靠一塊電池驅動,所以不可避免的出現電池耗盡的情況, 當時鍾電路的電池耗盡的時候,時鍾電路會被強制重置為2000年1月1日 00:00:00,正常電池耗盡的遊戲會在標題螢幕有警告信息來警告時鍾無法運作。相反,觸發了時鍾電路漏洞的遊戲反而不會出現這條警告信息。 而遊戲雖仍可正常運作並記錄,但無法體驗時間系統的相關內容。

    直到今天,幾乎所有的GBA帶時鍾的卡帶的時鍾電池都是沒電的,所以廣大玩家基本都嘗試採用了把舊電池拆掉換上新的焊腳電池,當然這里比較推薦的是CR1616貼片電池座(網上有售),可以完美放進卡帶內,又不用頻繁更換焊腳電池。

    卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    但是更換電池後,在遊戲內又會觸發一個官方並未在意的新漏洞,民間一般稱為新電池漏洞。

    因為在更換電池後,時鍾電路依然會重置,而開始從2000年1月1日 00:00:00開始重新計算,

    而與《紅藍寶石》官方漏洞不同,這里的問題是:時鍾電路遠早於早於報告的時間戳導致時間錯位,而當錯位發生的時候,時鍾電路無法到達遊戲存檔的時間戳的下一個刷新時間,導致所有的事件都被凍結,直到時鍾電路的時間再度運轉到和遊戲時間戳一致或快於遊戲時間戳,然後再運行到時間戳設定的刷新時間之後才會再度恢復正常。

    舉個栗子:

    假設遊戲的「起始零時」是時鍾電路的2000年1月1日0時,而時鍾電路已經走到2011年1月1日0時,時間戳則記錄為4018天0時,此時種下一顆橙橙果,那麼時間戳會設定下一次橙橙果成熟的日期是4018天12時。而假設此時電池突然耗盡,那麼更換電池後,時鍾電路回到了2000年1月1日0時,那麼時鍾需要再經過4018天12時,也就是11年零12個小時,這株橙橙果才會成熟,而且時間戳才會更新下一次事件的刷新時間。

    用表格表達就是:

    卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    於是樹果變成了千年老山參……

    理論上,這個漏洞的危害遠高於早期的《紅藍寶石》樹果漏洞,因為這一漏洞不僅《紅寶石/藍寶石》會觸發,包括沒有漏洞的《綠寶石》也會觸發這種新電池漏洞,而由於此漏洞在遊戲發售後多年,時鍾耗盡時才會發生,因此官方並未針對這種問題給出解決辦法,官方的修復程序也無法修復此漏洞。

    官方修復樹果漏洞

    由於是寶可夢第一次出現大規模且必定會發生的惡性漏洞,因此任天堂多次對此漏洞進行了批量修復,首先在新版本的《紅藍寶石》上,已經修補了此漏洞,而對於已經銷售的早期版本,也提供了多種修復方式,除此之外,玩家還可以將遊戲卡寄至任天堂進行修復(寄送維修服務已於2016年9月停止支援)。

    修復程序的修復原理是將位於2001年之前的時鍾電路強制調整為2001年1月1日,並將存檔時間戳一並後延,以跳過發生漏洞的2000年。

    首先, 任天堂在《火紅/葉綠》和《綠寶石》自帶修復程序,需要玩家用以下操作進行修復:

  • 將一台GBA連接到遊戲連接電纜的1P上,插入並打開《火紅/葉綠》或《綠寶石》,在遊戲標題按select和B,進入修復程序,按A。
  • 另一台GBA連接到遊戲連接電纜的2P上,插入《紅寶石/藍寶石》,按住select和start開機,進入修復程序,根據提示進行修復。
  • 每次重新進行遊戲或更換過電池重新進行遊戲後,需要再度進行修復。
  • 卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    之後在《競技場》系列發售後, 《紅寶石/藍寶石》與寶可夢XD 暗之旋風 黑暗洛奇亞進行聯動後,將會自動下載修復程序。

    而日本方面隨雜誌附贈特製專用E卡也可以來刷入修復程序。

    卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    新電池漏洞的探究

    對於新電池的漏洞的研究最早由Furlock’s Forest Wiki的維護者Adam提出(由於作者網站出現了問題,目前只有首頁和軟體下載了,關於研究頁面只有備份) 。最終發現自己編寫的自製程序,讀取《紅寶石/藍寶石/綠寶石》遊戲卡內部時鍾電路的時間,將其運轉的時間設置為晚於遊戲存檔的時間戳,之後再存檔一次刷新時間戳,即可解除問題。

    卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    而後作者公布了原始碼,但是GBA版程序需要配合GBA燒錄卡,並在運行後插拔換卡,之後作者rikten又以此原始碼製作了NDS版本,這樣NDS玩遊戲的玩家可以在不換卡的情況下修改時鍾。

    卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    理論上,這個軟體可以解決一切帶有時鍾的GBA遊戲的時間錯位問題。

    但此方法雖然能夠解決《寶石版》的時間運轉問題,卻會導致遊戲內的時鍾變得與真實時間不一致。

    卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    如果需要把時鍾表面也對准,需要進行下一步:修改存檔。

    先利用第三方設備(如月光寶盒、Retro Freak)或者軟體(如配合NDS使用的GBA Backup)提取遊戲存檔,再利用存檔修改程序將報告的「起始時間戳0時」設置為0天0時0分0秒,時間戳設置為當前時刻距離2000年1月1日的天數和時間,然後再導入遊戲卡內。之後利用Furlock’s Forest Wiki的程序將時鍾電路運轉的時間設置為等於或略晚於遊戲報告的時間戳,即可讓時間電路的時鍾和遊戲存檔的時間戳同步。

    卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    這樣遊戲內的鍾表也會與現實時間一致了,當然如果不是強迫症的話,只要修改晶振時間就好了。

    後記

    這一漏洞的根本原因在於官方並未給《寶石》版遊戲提供遊戲內的實時時鍾對時功能,導致遊戲一旦出現時鍾錯位,就會立刻導致連鎖反應。而官方從第四世代寶可夢開始,寶可夢遊戲的時間和日期獲取不再交由遊戲卡自己的時鍾電路,而是交由主機底層系統的時間,系統記錄的是真實的時間,而且根據時間變化記錄內的時間戳還可以同步刷新(錯位後在遊戲存檔時立刻修改時間戳),從而根本上避免了這一漏洞的繼續發生。

    當然,這也是《動森》這類遊戲的時空穿越者出現問題的原因。雖然是奇怪的知識,但是寫出來也挺有意思的。

    卡帶之痛:GBA《寶可夢》時鍾電路漏洞

    來源:機核