हैकर्स ने NES Tetris को गेम के भीतर से रीप्रोग्राम करने का तरीका खोजा
(arstechnica.com)- NES Tetris का kill screen crash सिर्फ गेम खत्म होना नहीं है, बल्कि बिना बदले हुए hardware और cartridge पर नया behavior चलाने के entry point की तरह इस्तेमाल किया जा सकता है
- Level 155 के बाद अगर score calculation frames के बीच पूरी नहीं होती, तो control flow टूट सकता है, और गेम अनजाने RAM locations को instruction की तरह पढ़ते हुए arbitrary code execution तक पहुंच सकता है
- Famicom के expansion controller port का input RAM jump routine की location से overlap करता है, इसलिए controller 3 और 4 के button inputs से crash के बाद jump होने वाला address बदला जा सकता है
- Displaced Gamers ने proof-of-concept code जारी किया है, जिसमें jump target को high score table पर भेजा जाता है ताकि name और score data को NES CPU opcode की तरह पढ़ा जा सके
- Input में उपलब्ध characters और numbers, तथा storage device की अनुपस्थिति के कारण इसकी practical usefulness सीमित है, लेकिन इसे crash-avoidance patch या पूरे RAM control तक बढ़ाया जा सकता है
kill screen crash कैसे code execution में बदलता है
- NES Tetris में crash तब हो सकता है जब score handler को frames के बीच नया score calculate करने में बहुत ज्यादा समय लग जाए
- यह स्थिति Level 155 के बाद आ सकती है
- Delay होने पर control code का कुछ हिस्सा नए frame write routine द्वारा बीच में रुक जाता है
- इसके बाद गेम अगला instruction ढूंढने के लिए अनचाहे RAM location पर jump कर जाता है
- आम तौर पर यह unexpected jump RAM के शुरुआती हिस्से के garbage data को code की तरह पढ़ता है, जिससे जल्दी crash हो जाता है
- Displaced Gamers के हालिया वीडियो में वह प्रक्रिया दिखाई गई है, जिसमें NES Tetris high score table को machine code instruction की तरह पढ़ता है
- इसी तरह के arbitrary code execution glitches पहले Super Mario World, Paper Mario, और The Legend of Zelda: Ocarina of Time में भी जाने जाते रहे हैं
- NES Tetris में बाहरी code डालने का बुनियादी तरीका कम-से-कम 2021 से सार्वजनिक रूप से सैद्धांतिक रूप में मौजूद था, और कहा जाता है कि community के भीतर पूरे RAM control का तरीका भी काफी समय से जाना जाता था
Famicom input handling से jump location control
- यह hack सिर्फ Tetris के crash behavior पर नहीं, बल्कि Famicom input architecture पर भी निर्भर करता है
- जापानी Famicom, अमेरिकी NES से अलग, दो controllers के साथ स्थायी रूप से जुड़ा होता था, और third-party controllers को सामने वाले expansion port में जोड़ा जा सकता था
- Tetris code इस “अतिरिक्त” controller port के inputs पढ़ता है
- Adapter की मदद से दो standard NES controllers और जोड़े जा सकते हैं
- Famicom पर Bullet-Proof Software का अलग Tetris version था, लेकिन input handling की यह विशेषता NES Tetris code में काम करती है
- अतिरिक्त controller inputs को handle करने वाला RAM area, crash के समय इस्तेमाल होने वाली jump routine की memory location से overlap करता है
- जब crash की वजह से jump routine रुकती है, तब उस RAM में controller पर दबाए गए buttons का data मौजूद होता है
- Player इन्हीं values की मदद से crash के बाद game code किस location पर जाएगा, इसे काफ़ी सटीकता से control कर सकता है
high score table को executable code की तरह पढ़ना
- Displaced Gamers के jump control तरीके में कुछ खास controller inputs चाहिए
- Controller 3 पर
upदबाना होता है - Controller 4 पर
right,left,downदबाना होता है leftऔरrightको एक साथ input करने के लिए controller में physical manipulation की जरूरत होती है
- Controller 3 पर
- ये inputs jump code को गेम की high score list के उस RAM area में भेजते हैं जहां names और scores stored होते हैं
- अगर B-Type high score table के target location में
(Gरखा जाए, तो गेम high score table के दूसरे हिस्से में फिर से jump करता है - इसके बाद गेम names और scores को क्रम से पढ़ता है, और उन्हें NES CPU के opcode की तरह process करता है, जिसे Displaced Gamers ने “bare metal” code कहा है
proof of concept ने क्या संभावनाएं और सीमाएं दिखाईं
- High score name input area में सिर्फ 43 symbols इस्तेमाल किए जा सकते हैं, और score में सिर्फ 10 digits आ सकती हैं
- इस सीमा की वजह से NES पर संभव opcode में से केवल कुछ ही high score table में “code” किए जा सकते हैं
- सीमित inputs के बावजूद छोटा proof-of-concept code संभव था
- Example data में
))"-P)नाम और A-Type का 8,575 वाला दूसरा highest score शामिल था - यह routine गेम score के सबसे ऊंचे दो digits को 0 कर देती है
- इससे score processing time कम होता है और crash के कारण घटते हैं, लेकिन खेल जारी रखने पर score फिर crash वाले “risk zone” में पहुंच जाता है
- Example data में
- बेसिक NES Tetris में battery-backed storage नहीं है, इसलिए हर बार power on होने पर जरूरी high score और complex names फिर से manually बनानी पड़ती हैं
- High score table की space भी सीमित है, इसलिए सीधे Tetris के असली code के ऊपर कोई complex program रखना मुश्किल है
- HydrantDude ने लिखा कि खास high score names और number combinations से एक bootstrapper बनाया जा सकता है, फिर उससे दूसरा bootstrapper बनाकर पूरे RAM का control हासिल किया जा सकता है
crash avoidance से आगे की reprogramming possibilities
- अगर पूरे RAM का control मिल जाए, तो top players NES Tetris के crash bug को patch करने के लिए गेम को फिर से code कर सकते हैं
- यह तरीका खास तौर पर उन players के लिए मददगार हो सकता है जो Level 255 से आगे जाना चाहते हैं
- Level 255 के बाद गेम फिर Level 0 पर लौट आता है
- इसी principle को और बढ़ाने पर, Super Mario World speedrunner cases की तरह Tetris को Flappy Bird में बदलने जैसी modifications भी संभव हो सकती हैं
1 टिप्पणियां
Hacker News की राय
ऐसे exploits देखकर हमेशा Stross की Accelerando में hacking के ultimate final stage की याद आती है: “spacetime की computational superstructure पर timing channel attack लगाकर, उसके नीचे मौजूद किसी चीज़ में घुसने की कोशिश करना”
यह vacuum decay शुरू करके universe को blue screen करा देने का बहुत अच्छा तरीका लगता है
ऐसे लोग मुझे सच में बहुत पसंद हैं
सिर्फ मज़े के लिए, शायद बेकार साबित होने वाली चीज़ें करने वाला hacker mindset मुझमें नहीं है, इसलिए शर्मिंदगी-सी महसूस होती है
हम बाकी लोग रोज़ी-रोटी में इतने busy हैं कि ऐसे exploits करने का समय नहीं है, pun intended नहीं
अगर पूरा लेख नहीं पढ़ना चाहते, लेकिन “मुझे लगा NES cartridges ROM से चलते हैं?” यह जानना चाहते हैं, तो हाँ, सही है
बस यह exploit CPU को high score table save करने वाली RAM में jump करा देता है। वाकई कमाल
arbitrary code execution तक पहुँचने की प्रक्रिया, उसके बाद आप क्या करते हैं उससे हमेशा ज्यादा दिलचस्प होती है
game को dissect करके यह पता लगाना कि वह कब और कहाँ ऐसा behavior करता है, और कहाँ manipulate करने पर instructions input किए जा सकते हैं—यह लगन काबिले-तारीफ है
Pokemon Yellow: https://www.youtube.com/watch?v=Vjm8P8utT5g
Super Mario World: https://www.youtube.com/watch?v=hB6eY73sLV0
arbitrary code execution असली shell code के रूप में trigger होता है। सचमुच game के अंदर Koopa shell को manipulate करके चलाया जाता है
किसी को Tetris में Doom चलाने में कितना समय लगेगा?
यह सही मायने में बर्बाद किया गया समय है
सच में पूछ रहा हूँ। पहले मैं मज़ेदार चीज़ों को भी समय की बर्बादी मानता था, लेकिन लंबे समय तक high-stress life की कीमत चुकाने के बाद उम्र बढ़ने के साथ मेरी सोच बदल गई
Factorio में यह आज़माना चाहता हूँ
Factorio के अंदर belts से बना एक विशाल computer बनाकर, segmentation fault पैदा कराना और game से बाहर escape कराना जैसा कुछ
पुराने games में arbitrary code execution ढूँढना सच में fascinating है
कुछ साल पहले Super Mario World में ऐसा कुछ देखा था, तो काफी समय तक इसी में अटका रहा कि यह संभव कैसे है
अच्छे अर्थ में, तारीफ के तौर पर कह रहा हूँ, हालांकि थोड़ा खराब लग सकता है: मुझे अच्छा लगता है कि बहुत smart लोग पूरी तरह बेकार चीज़ों पर बहुत सारा समय और मेहनत लगाते हैं
NES Tetris में code inject करने की कोई तत्काल वजह है? शायद नहीं। लेकिन point वह नहीं है; point यह पता लगाना है कि क्या संभव है और पुराने code व primitive computer से जबरन कितनी दूर तक काम कराया जा सकता है
classical अर्थ में यह “useful” नहीं हो सकता, लेकिन Sudoku या crossword puzzles, या शुरुआत में NES Tetris खेलना भी ऐसा ही है
यह top players को एक खास point के बाद play रोक देने वाले crash से बचकर ज्यादा देर खेलने देता है
average player के लिए यह practical नहीं है, लेकिन high score competition चाहने वालों के लिए यह limit solve करता है और नए competition की संभावना खोलता है
number theory भी मूल रूप से बेकार मानी जाती थी, लेकिन आज practically सारी public-key cryptography को support करती है
जो काम मुझे पसंद नहीं लेकिन मैं करता हूँ, उससे दूसरों को मिलने वाली usefulness या तो lucky byproduct है, या money/recognition जैसी चीज़ों के जरिए मुझे indirectly फायदा देती है
पसंद से किया गया काम सबसे important व्यक्ति—यानी खुद—के लिए usefulness का सबसे direct रूप बन जाता है
सच कहूँ तो हैरानी है कि Tetris इतनी देर से crack हुआ
लगता है यह नए any% runs का दौर शुरू करेगा। goal game के ending scene या credits को जितनी जल्दी हो सके execute करना होगा
मेरा पसंदीदा example Ocarina of Time है, जिसमें कई साल पहले से ACE exploit था
game पूरी तरह broken है, इसलिए game memory manipulate करके और किसी specific entrance warp को edit करके कुछ ही minutes में “clear” किया जा सकता है
और भी हैरानी की बात यह है कि लोग हाथ से, सिर्फ कुछ buttons और analog joystick इस्तेमाल करके memory edit करते हैं
3 मिनट में credits दिखाने का मामला: https://www.speedrun.com/oot/runs/z1l1627m
warp tunnel का flaw मिलने पर out-of-bounds read trigger हुआ, और उससे पहले joystick manipulation से buffer के ठीक बाहर वे bytes लिख दिए गए थे जो desired behavior कराते
Pokemon games में से एक में memory को ठीक-ठीक तैयार करने के लिए बहुत सारी buy/sell transactions करनी पड़ती थीं, फिर item count overflow कराकर jump trigger करना पड़ता था
वाकई शानदार चीज़ है। किसी दिन aliens attack करेंगे तो ऐसी शरारतें हमें बचाएँगी
लगता है इस ACE के लिए पहले kill screen तक पहुँचना जरूरी है
अगर Ocarina of Time का ACE ending credits चलने के बाद ही trigger होता, तो वह पहले से सफल run पूरा होने के बाद ही होता, इसलिए record कम नहीं कर पाता
इस तरह का काम सच में बहुत पसंद है
Super Mario World के अंदर glitch का इस्तेमाल करके Flappy Bird program करने वाली घटना याद आती है। पागलपन वाली level की चीज़ है
https://www.youtube.com/watch?v=hB6eY73sLV0