3 คะแนน โดย GN⁺ 2024-05-09 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • คิลสกรีนแครช ของ NES Tetris ไม่ได้เป็นแค่การจบเกมธรรมดา แต่สามารถใช้เป็นจุดเข้าสำหรับรันพฤติกรรมใหม่บนฮาร์ดแวร์และตลับเกมที่ไม่ผ่านการดัดแปลง
  • หากการคำนวณคะแนนหลังเลเวล 155 ใช้เวลาไม่เสร็จภายในช่วงระหว่างเฟรม โฟลว์การควบคุมจะเสียหาย และอาจนำไปสู่ การรันโค้ดตามอำเภอใจ ที่เกมไปอ่านตำแหน่ง RAM ที่ไม่ได้ตั้งใจราวกับเป็นคำสั่ง
  • RAM สำหรับอินพุตของ พอร์ตคอนโทรลเลอร์เสริม บน Famicom ซ้อนทับกับตำแหน่งของรูทีนกระโดด ทำให้สามารถใช้ปุ่มบนคอนโทรลเลอร์หมายเลข 3 และ 4 ควบคุมแอดเดรสที่จะย้ายไปหลังแครชได้
  • Displaced Gamers เผยแพร่ โค้ดพิสูจน์แนวคิด ที่ส่งปลายทางการกระโดดไปยังตารางไฮสกอร์ แล้วทำให้ข้อมูลชื่อและคะแนนถูกอ่านเหมือนเป็น opcode ของ CPU ใน NES
  • แม้การใช้งานจริงยังจำกัดเพราะตัวอักษรที่ป้อนได้มีจำกัดและไม่มีอุปกรณ์เก็บข้อมูลถาวร แต่ก็อาจต่อยอดไปสู่แพตช์เลี่ยงแครชหรือการควบคุม RAM ทั้งหมดได้

คิลสกรีนแครชเปลี่ยนเป็นการรันโค้ดได้อย่างไร

  • แครชของ NES Tetris อาจเกิดขึ้นเมื่อ ตัวประมวลผลคะแนน ใช้เวลานานเกินไปในการคำนวณคะแนนใหม่ระหว่างเฟรม
    • สถานการณ์นี้อาจเกิดได้หลังเลเวล 155
    • เมื่อเกิดความล่าช้า โค้ดควบคุมบางส่วนจะถูกขัดจังหวะโดยรูทีนเขียนเฟรมใหม่
    • หลังจากนั้น เกมจะกระโดดไปยังตำแหน่ง RAM ที่ไม่ได้ตั้งใจเพื่อหาคำสั่งถัดไป
  • โดยปกติ การกระโดดที่ไม่คาดคิดนี้จะทำให้ข้อมูลขยะช่วงต้นของ RAM ถูกอ่านเหมือนโค้ด และนำไปสู่การแครชอย่างรวดเร็ว
  • วิดีโอล่าสุดของ Displaced Gamers เปิดเผยขั้นตอนที่ทำให้ NES Tetris อ่าน ตารางไฮสกอร์ ราวกับเป็นคำสั่งภาษาเครื่อง
    • กลิทช์แบบ รันโค้ดตามอำเภอใจ ที่คล้ายกันเคยเป็นที่รู้จักมาก่อนใน Super Mario World, Paper Mario และ The Legend of Zelda: Ocarina of Time
    • วิธีพื้นฐานในการใส่โค้ดจากภายนอกเข้าไปใน NES Tetris ถูกตั้งทฤษฎีเผยแพร่ต่อสาธารณะอย่างน้อยตั้งแต่ปี 2021 และมีรายงานว่าภายในคอมมูนิตี้ก็รู้วิธีควบคุม RAM ทั้งหมดกันมานานแล้ว

ควบคุมตำแหน่งกระโดดด้วยระบบอินพุตของ Famicom

  • การแฮ็กนี้ไม่ได้พึ่งแค่รูปแบบการแครชของ Tetris แต่ยังพึ่ง โครงสร้างอินพุตของ Famicom ด้วย
  • Famicom เวอร์ชันญี่ปุ่นต่างจาก NES เวอร์ชันอเมริกา ตรงที่มีคอนโทรลเลอร์ 2 ตัวต่ออยู่กับเครื่องถาวร และคอนโทรลเลอร์จากผู้ผลิตรายอื่นสามารถต่อผ่านพอร์ตเสริมด้านหน้าได้
  • โค้ดของ Tetris มีการอ่านอินพุตจากพอร์ตคอนโทรลเลอร์ “เพิ่มเติม” นี้
    • หากใช้อะแดปเตอร์ ก็สามารถต่อคอนโทรลเลอร์ NES มาตรฐานเพิ่มได้อีก 2 ตัว
    • แม้ Famicom จะมี Tetris เวอร์ชันแยกของ Bullet-Proof Software แต่ลักษณะการจัดการอินพุตนี้ทำงานกับโค้ดของ NES Tetris
  • พื้นที่ RAM ที่ใช้ประมวลผลอินพุตของคอนโทรลเลอร์เสริม ซ้อนทับกับ ตำแหน่งหน่วยความจำของรูทีนกระโดด ที่ถูกใช้ตอนแครช
    • เมื่อแครชทำให้รูทีนกระโดดถูกขัดจังหวะ RAM ส่วนนั้นจะมีข้อมูลแทนปุ่มที่ถูกกดบนคอนโทรลเลอร์
    • ผู้เล่นจึงใช้ค่านี้ควบคุมได้อย่างแม่นยำว่าโค้ดของเกมจะย้ายไปที่ใดหลังแครช

ทำให้ตารางไฮสกอร์ถูกอ่านเหมือนโค้ดที่รันได้

  • วิธีควบคุมการกระโดดของ Displaced Gamers ต้องใช้อินพุตจากคอนโทรลเลอร์เฉพาะเจาะจง
    • กด up บนคอนโทรลเลอร์หมายเลข 3
    • กด right, left, down บนคอนโทรลเลอร์หมายเลข 4
    • การกด left และ right พร้อมกันต้องอาศัยการดัดแปลงคอนโทรลเลอร์
  • อินพุตนี้จะส่งโค้ดกระโดดไปยังพื้นที่ RAM ที่เก็บชื่อและคะแนนของ รายการไฮสกอร์ ของเกม
  • หากใส่ (G ไว้ที่ตำแหน่งเป้าหมายในตารางไฮสกอร์ของ B-Type เกมจะกระโดดต่อไปยังอีกพื้นที่หนึ่งของตารางไฮสกอร์
  • จากนั้นเกมจะอ่านชื่อและคะแนนตามลำดับ และประมวลผลเหมือนเป็น opcode ของ CPU ใน NES ในแบบที่ Displaced Gamers เรียกว่าโค้ดแบบ “bare metal”

สิ่งที่โค้ดพิสูจน์แนวคิดแสดงให้เห็น: โอกาสและข้อจำกัด

  • พื้นที่ป้อนชื่อในไฮสกอร์ใช้สัญลักษณ์ได้เพียง 43 แบบ และคะแนนใส่ตัวเลขได้เพียง 10 ตัว
    • ด้วยข้อจำกัดนี้ จึงมีเพียง opcode บางส่วนที่เป็นไปได้บน NES เท่านั้นที่สามารถ “เขียนโค้ด” ลงในตารางไฮสกอร์ได้
  • ถึงจะมีอินพุตจำกัด ก็ยังสร้าง โค้ดพิสูจน์แนวคิด แบบสั้นได้
    • ข้อมูลตัวอย่างมีชื่อ ))"-P) และคะแนน A-Type อันดับ 2 ที่ 8,575
    • รูทีนนี้ทำให้เลขสองหลักบนสุดของคะแนนในเกมกลายเป็น 0
    • มันช่วยลดเวลาในการประมวลผลคะแนนและลดสาเหตุของแครช แต่ถ้ายังเล่นต่อ คะแนนก็จะกลับเข้าสู่ “ช่วงเสี่ยง” ของการแครชอีกครั้ง
  • NES Tetris รุ่นมาตรฐานไม่มีอุปกรณ์บันทึกข้อมูลแบบแบตเตอรี่สำรอง ดังนั้นทุกครั้งที่เปิดเครื่อง ผู้เล่นต้องสร้างไฮสกอร์และชื่อที่ซับซ้อนที่ต้องการขึ้นมาใหม่ด้วยตนเอง
  • พื้นที่ของตารางไฮสกอร์ก็มีจำกัด ทำให้ใส่โปรแกรมซับซ้อนทับลงบนโค้ดจริงของ Tetris โดยตรงได้ยาก
  • HydrantDude เขียนไว้ว่ามีวิธีสร้างบูตสแตรปเปอร์จากชุดค่าชื่อและตัวเลขไฮสกอร์เฉพาะ จากนั้นใช้มันสร้างบูตสแตรปเปอร์อีกตัวเพื่อให้ควบคุม RAM ทั้งหมดได้

ศักยภาพในการรีโปรแกรมที่ไกลเกินกว่าแค่เลี่ยงแครช

  • หากสามารถควบคุม RAM ทั้งหมดได้ ผู้เล่นระดับท็อปอาจรีโค้ดเกมเพื่อแพตช์ บั๊กแครช ของ NES Tetris ได้
  • วิธีนี้อาจเป็นประโยชน์อย่างมากกับผู้เล่นที่พยายามไปให้เกินเลเวล 255
    • หลังเลเวล 255 เกมจะวนกลับไปที่ Level 0 อีกครั้ง
  • หากขยายหลักการเดียวกันต่อไป ก็อาจดัดแปลง Tetris ให้กลายเป็น Flappy Bird ได้แบบเดียวกับกรณีของสปีดรันเนอร์ Super Mario World

1 ความคิดเห็น

 
GN⁺ 2024-05-09
ความคิดเห็นจาก Hacker News
  • เวลาเห็น exploit แบบนี้ก็มักนึกถึงขั้นสุดท้ายของการแฮ็กใน Accelerando ของ Stross เสมอ: “การโจมตีแบบ timing channel ต่อโครงสร้างเหนือการคำนวณของกาลอวกาศเอง เพื่อพยายามเจาะทะลุเข้าไปยังบางสิ่งที่อยู่ข้างใต้”

    • ไม่อยากอยู่ใน กรวยแสง ของคนที่พยายามทำอะไรที่มีโอกาสสำเร็จแม้เพียงนิดเดียว
      ฟังดูเป็นวิธีที่ดีมากในการทำให้เกิดการสลายตัวของสุญญากาศจนจักรวาลขึ้นจอฟ้า
    • หนังสือเล่มนี้ดาวน์โหลดฟรีได้จากบล็อกของผู้เขียน: https://www.antipope.org/charlie/blog-static/fiction/acceler...
    • เพิ่งเจอ ข้อผิดพลาดในการซิงโครไนซ์ เมื่อกี้ อาจเป็นกรณีขอบเขตที่ดีสำหรับเริ่มต้นก็ได้: https://www.science.org/content/article/quantum-paradox-poin...
    • ปกติเขาเรียกสิ่งนั้นว่า ฟิสิกส์ มั้ง
    • กาลอวกาศเหรอ? ทำไมจำกัดอยู่แค่ปริภูมิล่ะ เวลาเชิงเมตา น่าสนใจกว่ามาก
  • ชอบคนแบบนี้จริง ๆ
    จนรู้สึกอายที่ตัวเองไม่มี mindset แบบแฮ็กเกอร์ ที่ลองทำสิ่งที่น่าจะไร้ประโยชน์เพียงเพราะมันสนุก

    • แฮ็กเกอร์แบบนั้นส่วนใหญ่เกิดมาพร้อมกองทุนทรัสต์หรือเปล่า? คนที่อนาคตมั่นคงแล้วเหลือแต่ความเบื่อ?
      พวกเราที่เหลือยุ่งกับการหาเลี้ยงชีพจนไม่มีเวลาทำ exploit แบบนี้ ไม่ได้ตั้งใจเล่นคำ
  • ถ้าไม่อยากอ่านทั้งบทความ แต่สงสัยว่า “นึกว่าคาร์ทริดจ์ NES รันจาก ROM ไม่ใช่เหรอ?” คำตอบคือใช่
    แต่ exploit นี้ทำให้ CPU กระโดดไปยัง RAM สำหรับเก็บตารางคะแนนสูงสุด ได้ เจ๋งมากจริง ๆ

  • ขั้นตอนกว่าจะไปถึง การรันโค้ดตามใจชอบ น่าสนใจกว่าสิ่งที่จะทำหลังจากนั้นเสมอ
    ความมุ่งมั่นในการรื้อเกมเพื่อหาว่ามันทำพฤติกรรมแบบนั้นเมื่อไรและที่ไหน แล้วหาว่าต้องแก้ตรงไหนถึงจะป้อนคำสั่งได้ น่าชื่นชมมาก

    • แม้หลังจากหา exploit เจอแล้ว ก็ยังสร้างสิ่งที่สวยงามจริง ๆ ให้คอนโซลรันได้
      Pokemon Yellow: https://www.youtube.com/watch?v=Vjm8P8utT5g
      Super Mario World: https://www.youtube.com/watch?v=hB6eY73sLV0
    • ชอบกรณี Super Mario World เป็นพิเศษ
      การรันโค้ดตามใจชอบถูกกระตุ้นด้วย shellcode จริง ๆ พูดตามตรงคือบังคับเปลือก Koopa ในเกมให้รันมัน
  • ต้องใช้เวลานานแค่ไหนกว่าจะมีคนรัน Doom ใน Tetris ได้?

    • นั่นอาจต้องใช้คาร์ทริดจ์ขยาย RAM
  • เป็นเวลาที่เสียไปอย่างถูกที่แล้ว

    • แล้วทำอะไรเพื่อความสนุกบ้าง? มองว่านั่นก็เสียเวลาเหมือนกันไหม?
      ถามจริง ๆ เมื่อก่อนเคยมองว่าเรื่องสนุกก็เป็นการเสียเวลา แต่พอแก่ขึ้นหลังจากต้องจ่ายราคาของชีวิตที่เครียดสูงยาวนาน ก็เริ่มคิดต่างออกไป
  • อยากลองทำแบบนี้ด้วย Factorio
    ประมาณว่าสร้างคอมพิวเตอร์ยักษ์จากสายพานใน Factorio แล้วทำให้เกิด segmentation fault เพื่อหลุดออกไปนอกเกม

    • Factorio รัน Doom ได้อยู่แล้ว: https://www.youtube.com/watch?v=0bAuP0gO5pc
    • นักพัฒนา Factorio ทุ่มเทกับการแก้บั๊กมากเกินไป คงทำแบบนั้นได้ยาก
  • การค้นหา การรันโค้ดตามใจชอบ ในเกมเก่า ๆ นั้นชวนหลงใหลจริง ๆ
    หลายปีก่อนตอนเห็นเรื่องแบบนี้ใน Super Mario World ก็หมกมุ่นอยู่พักใหญ่ว่ามันเป็นไปได้อย่างไร
    พูดด้วยเจตนาดีและเป็นคำชม แต่อาจฟังดูแรงหน่อย: ชอบที่คนฉลาดมาก ๆ ใช้เวลาและความพยายามมหาศาลไปกับสิ่งที่ไร้ประโยชน์โดยสิ้นเชิง
    มีเหตุผลเร่งด่วนอะไรไหมที่จะฉีดโค้ดเข้าไปใน NES Tetris? ก็คงไม่มี แต่ประเด็นไม่ใช่ตรงนั้น ประเด็นคือการค้นหาว่าอะไรเป็นไปได้ และจะบังคับโค้ดเก่ากับคอมพิวเตอร์ดึกดำบรรพ์ให้ทำได้ไกลแค่ไหน
    ในความหมายแบบคลาสสิกมันอาจไม่ “มีประโยชน์” แต่ซูโดกุ ปริศนาอักษรไขว้ หรือการเล่น NES Tetris ตั้งแต่แรกก็เช่นกัน

    • แม้จะถูกกลบด้วยรายละเอียดทางเทคนิค แต่ exploit นี้ก็มีจุดประสงค์เชิงปฏิบัติด้วย
      มันช่วยให้ผู้เล่นฝีมือสูง เล่นได้นานขึ้นโดยหลีกเลี่ยงการแครช ที่ขัดขวางการเล่นหลังผ่านจุดหนึ่งไปแล้ว
      สำหรับผู้เล่นทั่วไปอาจไม่มีประโยชน์เชิงปฏิบัติ แต่สำหรับคนที่อยากแข่งขันทำคะแนนสูงสุด มันแก้ข้อจำกัดและเปิดความเป็นไปได้ใหม่ในการแข่งขัน
    • การค้นพบทางวิทยาศาสตร์ จำนวนมากเกิดจากการที่คนฉลาดมาก ๆ ใช้เวลาและความพยายามไปกับสิ่งที่ไร้ประโยชน์โดยสิ้นเชิง
      ทฤษฎีจำนวนก็เคยถูกมองว่าไร้ประโยชน์ แต่ตอนนี้แทบจะรองรับการเข้ารหัสกุญแจสาธารณะทั้งหมด
    • ไม่ได้ไร้ประโยชน์หรอก พวกเขาชอบทำสิ่งนั้น
      ประโยชน์ที่คนอื่นได้รับจากงานที่ฉันไม่ได้ชอบแต่ต้องทำ เป็นเพียงผลพลอยได้ที่โชคดี หรือเป็นสิ่งที่ให้ประโยชน์ทางอ้อมแก่ฉัน เช่น เงินหรือการยอมรับ
      สิ่งที่ทำเพราะชอบคือรูปแบบของประโยชน์ที่ตรงที่สุดต่อคนที่สำคัญที่สุด นั่นคือตัวเอง
    • ช่อง YouTube ของคนนี้คือแก่นแท้ของสิ่งแบบนั้นเลย: https://www.youtube.com/@tom7
  • พูดตรง ๆ น่าแปลกใจที่ Tetris เพิ่งถูกเจาะได้ช้าขนาดนี้
    คิดว่านี่จะเปิดยุคใหม่ของการรันแบบ any% เป้าหมายคือทำให้ฉากจบหรือเครดิตของเกมรันให้เร็วที่สุด
    ตัวอย่างที่ชอบคือ Ocarina of Time ซึ่งมี ACE exploit มาหลายปีแล้ว
    เกมพังอย่างหนักจนถ้าจัดการหน่วยความจำของเกมและแก้ไขวาร์ปทางเข้าบางจุด ก็สามารถ “เคลียร์” ได้ในไม่กี่นาที
    ที่น่าทึ่งกว่านั้นคือผู้คนแก้ไขหน่วยความจำด้วยมือ โดยใช้แค่ปุ่มไม่กี่ปุ่มกับจอยสติ๊กอนาล็อก
    ตัวอย่างที่ทำให้เครดิตขึ้นใน 3 นาที: https://www.speedrun.com/oot/runs/z1l1627m

    • เคยเห็นอะไรคล้าย ๆ กันใน Super Mario
      พอเจอบั๊กของท่อวาร์ปก็ทำให้เกิด การอ่านนอกขอบเขต และก่อนหน้านั้นก็ใช้การบังคับจอยสติ๊กเขียนไบต์ที่จะทำให้เกิดพฤติกรรมที่ต้องการไว้ตรงนอกบัฟเฟอร์พอดี
      ในเกม Pokemon เกมหนึ่ง ต้องซื้อ/ขายของจำนวนมากเพื่อเตรียมหน่วยความจำให้ถูกต้อง แล้วทำให้จำนวนไอเท็ม overflow เพื่อกระตุ้นการกระโดด
      เป็นเรื่องมหัศจรรย์จริง ๆ สักวันถ้ามนุษย์ต่างดาวบุกมา มุกแกล้งแบบนี้จะช่วยพวกเราไว้
    • ถ้าอ่านจากบทความอย่างเดียว ดูแล้วความเป็นไปได้นั้นน่าจะต่ำ
      ACE นี้ดูเหมือนต้องไปถึง kill screen ก่อนจึงจะทำได้
      ลองนึกว่า ACE ของ Ocarina of Time เพิ่งทำงานหลังเครดิตตอนจบขึ้นไปแล้ว แบบนั้นมันเกิดขึ้นได้ก็ต่อเมื่อจบเกมสำเร็จไปแล้ว จึงลดสถิติไม่ได้
    • ที่บอกว่าพูดตรง ๆ แล้วน่าแปลกใจที่ Tetris เพิ่งถูกเจาะได้ช้าขนาดนี้ อยากรู้ว่าก่อนหน้านั้นอะไรทำให้คิดว่า การรันตามใจชอบ เป็นไปได้
  • ชอบงานประเภทนี้จริง ๆ
    นึกถึงตอนที่มีคนใช้บั๊กใน Super Mario World เพื่อโปรแกรม Flappy Bird ขึ้นมาในเกม บ้าระดับสุด
    https://www.youtube.com/watch?v=hB6eY73sLV0