1 điểm bởi GN⁺ 2024-01-23 | 1 bình luận | Chia sẻ qua WhatsApp
  • TheZZAZZGlitch cho thấy có thể ghi âm âm thanh crash của Game Boy Advance để nhận diện dữ liệu game bên trong cartridge, và cuối cùng khôi phục được cùng một ROM
  • Điểm cốt lõi là diễn giải âm thanh phát ra sau khi crash như dữ liệu ROM, nhưng cần nhiều điều chỉnh theo từng định dạng nguồn nên khó dùng như một công cụ dump phổ dụng
  • Trong hơn 4 giờ ghi âm, một dạng sóng đặc trưng xuất hiện ở khoảng mốc 1 giờ 50 phút, sau đó lần lượt nghe thấy âm thanh nhạc cụ và các mẫu âm thanh của game
  • Bằng script Python và hiệu chỉnh căn chỉnh, độ chính xác đạt tới 99,76% nhưng vẫn không boot được; khi gộp 3 bản ghi bằng thuật toán biểu quyết đa số, kết quả cải thiện lên 99,979%
  • Sau khi gộp 7 bản ghi và lọc các vùng trống, đạt được mức khớp 100%, xác nhận khả năng thử nghiệm rằng có thể khôi phục ROM GBA chỉ từ âm thanh crash

Thí nghiệm đọc dữ liệu ROM từ âm thanh crash

  • TheZZAZZGlitch trình diễn rằng âm thanh GBA phát ra sau khi phần mềm crash có thể chứa dữ liệu game
  • Một GBA bị crash có thể tiếp tục phát ra âm thanh dựa trên dữ liệu bên trong cartridge; với phần cứng và mã đặc biệt để phân tích âm thanh này, có thể nhận diện đó là game nào
  • Tuy nhiên, cách này không phải là phương pháp dễ dàng để dump dữ liệu cartridge, cũng không phải là giải pháp dùng ngay được
    • Cần rất nhiều tinh chỉnh phù hợp với các định dạng nguồn khác nhau

Dạng sóng lộ ra trong bản ghi dài

  • Sau khi làm GBA crash và ghi âm hơn 4 giờ, một dạng sóng đặc trưng xuất hiện ở khoảng mốc 1 giờ 50 phút
  • Ở các đoạn sau đó, có thể nghe lần lượt các âm thanh nhạc cụ và mẫu âm thanh thực sự có trong game
  • Phần dữ liệu còn lại nghe như dữ liệu 8-bit ở 13.100Hz, và một số đoạn nghe rất kỳ lạ

Script Python và lần thử khôi phục đầu tiên

  • TheZZAZZGlitch đã chuẩn bị một script Python để đọc bản ghi dump crash GBA sạch, sau “2 ngày sửa lỗi”
  • Trong dữ liệu ROM có những vùng byte 0 lớn, và các phần này xuất hiện như im lặng nên khó parse từ âm thanh
  • Sau khi chạy một script riêng để căn chỉnh lại các section dựa trên vị trí trong ROM gốc, ROM được khôi phục đạt độ chính xác 99,76%
  • ROM này vẫn không boot được, và vì sử dụng dữ liệu ROM đã biết để làm lộ dữ liệu chưa biết nên về mặt kỹ thuật được xem là “gian lận”
    • Ngay cả khi tiến hành hoàn toàn mù, vẫn còn những giả định và suy đoán có thể áp dụng

Gộp nhiều bản ghi để tăng độ chính xác

  • Bước tiếp theo tập trung vào cải thiện chất lượng ghi âm
  • Khi gộp kết quả từ 3 lần ghi bằng thuật toán “biểu quyết đa số”, độ chính xác tăng lên 99,979%
  • ROM đầu ra này boot được, nhưng văn bản bị lỗi hiển thị và xảy ra crash ở màn hình tiêu đề
  • Sau đó, khi kết hợp 7 bản ghi và lọc các vùng trống, họ đạt mức khớp 100%

Phần cứng vật lý và các thí nghiệm bổ sung

  • Ở nửa sau video, họ cũng kiểm tra cách phương pháp này hoạt động trên phần cứng vật lý
  • Họ thử nghiệm với các game khác, đồng thời lần theo một bí ẩn liên quan đến mã ARM bên trong cartridge sao chép
  • Một số cách để thu được bản ghi tốt hơn cũng được thử nghiệm
    • Một trong số đó là dùng “cursed adapter” để mixdown thô xuống một kênh

1 bình luận

 
GN⁺ 2024-01-23
Ý kiến trên Hacker News
  • Vấn đề khi 0x00 kéo dài liên tục có liên quan đến khôi phục xung nhịp (clock recovery)
    Một số luồng dữ liệu số, đặc biệt là dữ liệu thô từ đầu từ của ổ đĩa hoặc truyền thông nối tiếp tốc độ cao như Ethernet, được truyền mà không có tín hiệu clock riêng
    Bộ thu tạo clock dựa trên một chuẩn tần số gần đúng, rồi dùng vòng khóa pha (PLL) để căn pha clock theo các điểm chuyển mức của luồng dữ liệu
    Để cách này hoạt động, các điểm chuyển mức trong dữ liệu phải xuất hiện đủ thường xuyên để bù trôi của bộ dao động PLL, và khoảng thời gian có thể chịu được lâu đến đâu khi không có chuyển mức được gọi là thông số CID tối đa (consecutive identical digits)
    https://en.wikipedia.org/wiki/Clock_recovery

    • Trước đây, điểm hay là có thể đảm bảo khả năng khôi phục clock và tránh các vấn đề về điện dung đường truyền bằng những phương pháp codebook thông minh xử lý cẩn thận các đoạn bit ngắn như 8b/10b
      Sau đó người ta chuyển sang cách gắn header ngắn vào các khối bit lớn như 64/66b để đảm bảo có chuyển mức clock, rồi cho toàn bộ dữ liệu đi qua bộ xáo trộn giả ngẫu nhiên
    • Mối lo khác là ở đâu đó trong dạng sóng có ghép AC (AC coupling) khiến thành phần DC không thể đi qua
      Ngay cả khi clock được đồng bộ hoàn hảo, trong các đoạn dài thì tín hiệu gần như toàn 1 và tín hiệu gần như toàn 0 rốt cuộc sẽ trở nên giống hệt nhau
    • Trường hợp này có vẻ không liên quan lắm
      Âm thanh là tín hiệu analog, và để giải mã thành bitstream thì cần DAC, đồng thời nó được truyền ở tần số cố định như 44.1kHz hay 48kHz mà không cần đồng bộ đặc biệt
    • Tôi tìm thấy một bài rất thú vị trên trang này về Wireless Set Number 10
      https://en.wikipedia.org/wiki/Wireless_Set_Number_10
  • Gợi nhớ đến vụ hack iPodLinux nguyên thủy, khi gần 20 năm trước họ dump firmware iPod thế hệ 4 bằng loa piezo
    https://web.archive.org/web/20140810083116/http://www.newscientist.com/article/dn7085
    Tình cờ là nhờ vậy mà người ta cũng có thể chạy game GBA trên iPod, nhưng chỉ riêng việc chơi Doom bằng click wheel và xem video đen trắng đã đủ khiến tôi thấy mãn nguyện rồi

    • Kỷ niệm đẹp thật
      Tôi vẫn còn giữ một chiếc iPod Classic, đã nâng cấp pin và lắp vào 4 thẻ MicroSD 256GB
      Gần đây tôi cũng thấy bản mod thêm Bluetooth, nhưng phải thay cả nắp lưng nên chắc tôi không làm tới mức đó
      Cả thiết kế lẫn cảm giác tự mình sở hữu bản sao các file nhạc đều có một sức hút không phai theo thời gian
  • Thật vui khi chủ đề này được chú ý hơn ở đây
    Nó cũng đã được đăng mấy ngày trước nhưng chìm mất: https://news.ycombinator.com/item?id=39037104
    Video gốc có nhiều nội dung hơn bài viết ngắn này, bao gồm cả adapter tùy chỉnh do hacker tự cắt dán để đạt được chất lượng âm thanh phù hợp từ DS

  • Zzazz tổ chức một cuộc thi/sự kiện Cá tháng Tư hằng năm, và thường có xen vào một mức độ nào đó của retro hacking hoặc reverse engineering
    Rất đáng để tham gia
    Các cuộc thi trước đây đều có trên GitHub

  • Kiến trúc âm thanh của Nintendo lúc nào cũng rất thú vị
    Ban đầu NES có một bộ tạo mẫu có thể tạo dạng sóng tùy ý, và có thể chạy theo hai cách
    Một cách là đưa cho nó một địa chỉ bộ nhớ, nó sẽ đọc các bit và xử lý thành dạng sóng cực kỳ đơn giản, trong đó 1 nghĩa là “tăng giá trị lên một đơn vị”, còn 0 là “giảm giá trị xuống một đơn vị”, nên nếu muốn tạo dạng sóng phẳng thì phải lặp kiểu 10101010
    Cách còn lại là CPU liên tục tự ghi “giá trị khởi tạo” vào để điều khiển chip trực tiếp, mà trên thực tế còn nhanh hơn việc để driver âm thanh đọc bit từ RAM
    Vấn đề là cách này ngốn sạch chu kỳ CPU, nên chỉ dùng được khi không cần làm việc gì khác
    Các game như Battletoads đã tận dụng điều đó để phát các cú đánh trống chất lượng cao hơn trong lúc hành động tạm dừng, và dùng nó ở màn hình tiêu đề, hiệu ứng “giòn” khi mọi hành động khựng lại thoáng chốc lúc tung đòn cuối vào kẻ địch, cùng bản nhạc tạm dừng rất đáng nhớ
    Đây là bản demo cho thấy game chuyển đổi giữa chế độ điều khiển trực tiếp và chế độ để chip tự đọc mẫu. Retro Game Audio đã đăng một video chỉnh sửa bằng emulator để chỉ ra đúng khoảnh khắc đi vào subroutine điều khiển trực tiếp: https://www.youtube.com/watch?v=JGT0FM3yh-w

  • Ban đầu tôi thắc mắc vì sao chuyện này lại xảy ra
    Việc những game như thế này dump trạng thái thành âm thanh có phổ biến không? Đây có phải là một công cụ gỡ lỗi được chủ ý dành cho nhà phát triển game không?

    • Video trước đó của tác giả[1] giải thích các chi tiết kỹ thuật của cách hoạt động này
      Về cơ bản, âm thanh của GBA phát trực tuyến audio từ một bộ đệm trong RAM, và ngắt phải báo cho phần cứng quay lại đọc từ đầu bộ đệm
      Nhưng nếu ngắt không xảy ra, như khi game bị crash, thì luồng âm thanh sẽ vượt ra ngoài bộ đệm và đọc sang các vùng bộ nhớ khác
      [1] https://www.youtube.com/watch?v=wSWNkpqjtQY&t=361s
    • Đây là chuyện khá hiếm, và cũng không phải công cụ gỡ lỗi được cố ý thiết kế
      Về lý thuyết, GBA có thể đã được thiết kế để “đóng băng” kiến trúc khi game bị crash, hoặc có một watchdog gắn các cập nhật trạng thái phải chạy định kỳ vào ngắt không thể che, để nếu các cập nhật đó dừng lại thì máy sẽ khởi động lại
      Nhưng các tính năng như vậy tốn thêm chi phí, nên GBA không có
      Nintendo về cơ bản đã chọn cách tiếp cận truyền thống của các nhà sản xuất băng game đời cũ: “nếu game của chúng ta không có bug, thì không cần lo phần cứng sẽ làm gì trong trạng thái không xác định”
      Vì vậy, khi một game GBA rơi vào trạng thái crash như vòng lặp vô hạn với ngắt bị vô hiệu hóa, chip âm thanh không hề biết hệ thống đã crash và cứ tiếp tục làm việc đơn giản là đọc các bit liên tiếp từ RAM rồi biến chúng thành âm thanh
      Trong hoạt động bình thường, quy trình dọn dẹp quản lý việc đọc này sẽ tồn tại, nhưng khi nó biến mất thì việc đọc cứ tiếp diễn cho đến lúc chạm tới cả những bit biểu diễn giá trị của cartridge ROM
  • Thật sự ấn tượng đến mức khó tin
    Có cảm giác những kỹ thuật như thuật toán bỏ phiếu đa số dùng ở đây vẫn chưa được khai thác đủ trong nhiều ngành công nghiệp

    • Nếu bạn quan tâm, các kỹ thuật khôi phục tín hiệu nhiễu tinh vi đã được tích lũy gần 100 năm nay
      Các thiết bị lưu trữ từ tính về cơ bản hoạt động theo cùng nguyên lý như màn hack này
      https://en.wikipedia.org/wiki/Partial-response_maximum-likelihood
      Cùng ý tưởng đó cũng có thể áp dụng ở đây, vì nội dung ROM GBA có thể sẽ có độ thiên lệch mạnh
      Bỏ phiếu đa số làm lãng phí rất nhiều thông tin
    • Một ứng dụng thú vị của việc chọn giá trị xuất hiện nhiều nhất, hoặc nói chung là chọn trung vị, là loại bỏ nhiễu hay con người khỏi nhiều bức ảnh chụp cùng một thời điểm
      Chỉ cần chồng tất cả ảnh lên nhau rồi giữ lại giá trị trung vị cho từng pixel[1]
      [1]: https://patdavid.net/2013/05/noise-removal-in-photos-with-median_6/
    • Trong phục hồi dữ liệu thì khá phổ biến
      Người ta sẽ đọc đi đọc lại ảnh đĩa, chạy cơ chế xét đủ số phiếu, rồi khi ra được kết quả vượt qua checksum thì xem có hoạt động đúng không
      Nếu có checksum ở mức cao hơn như chữ ký tệp thì càng tốt cho việc xác minh thêm
      Nó cũng được dùng trong một số ứng dụng hàng không vũ trụ
    • Tôi từng nghĩ có lẽ có thể dùng cho quét phim, nhất là trong các dự án fan như 4K77
      Vì họ xử lý các bản in chiếu rạp có thể đã hư hại chứ không phải bản master pristine, nên nếu có thể dùng nhiều bản để loại bỏ vết xước v.v. thì sẽ giảm cực nhiều thời gian chỉnh sửa thủ công ở hậu kỳ
  • Việc 0xFF bị biến thành 0x00 có thể là do tụ chặn DC hoặc lọc thông cao
    Mạch âm thanh không thực sự phù hợp với nội dung không nghe được
    Nếu may mắn, việc nối trực tiếp một máy hiện sóng số vào đầu ra âm thanh của chip có thể cải thiện độ chính xác khi capture, nhưng dù vậy việc lấy ra được một image có thể khởi động vẫn rất ấn tượng

    • Theo như tôi nhớ từ phần bình luận trên video YouTube, mục tiêu là làm điều này chỉ với thiết bị cơ bản trong khả năng
      Vì thế họ đã dành hàng giờ để capture lặp đi lặp lại và lấy trung bình lỗi, thay vì dùng máy hiện sóng ghi dữ liệu đúng nghĩa
    • Đúng vậy, cần tạo ra một tín hiệu không có độ lệch DC
      Chỉ một cách đơn giản như mã hóa Manchester cũng đã giúp ích rất nhiều
      Nếu thế vẫn chưa đủ thì có thể dùng NRZ hoặc thậm chí mã hóa chập
      Ngoài ra cũng có thể gửi sóng sin, hoặc nếu không được thì ít nhất phải đẩy tần số sóng vuông lên đủ cao để không bị tụ ghép AC nuốt mất
  • Phần ấn tượng nhất trong tất cả chuyện này, với cá nhân tôi, là cách những kẻ sao chép lậu đã sửa code để chạy game từ flash có thể ghi được thay vì từ ROM + bộ nhớ lưu trữ bay hơi

    • Đây là kỹ thuật cực kỳ phổ biến trong các bản game Game Boy và Game Boy Advance sao chép lậu để tiết kiệm vài xu tiền pin
      Thực ra việc tạo ra các bản vá như vậy cũng không quá khó
      Những kẻ sao chép lậu sẽ reverse engineering sơ qua vị trí mà mã game ghi dữ liệu, rồi viết bản vá riêng cho từng game để flush dữ liệu lưu vào flash có thể ghi được
      Tuy nhiên, game GBA chính thức luôn dùng các hàm của Nintendo SDK để lưu, nên nếu hook các hàm đó thì có thể tạo ra một bản vá tổng quát khá đơn giản giúp bất kỳ game GBA nào cũng lưu được trên cartridge sao chép không pin
      Tôi đã viết một công cụ vá làm việc này và có thể xem tại đây
      https://github.com/metroid-maniac/gba-auto-batteryless-patcher
  • Có ai biết bên trong chuyện gì xảy ra khi trình giả lập của TheZZAZZGlitch báo rằng game đang cố nhảy tới một địa chỉ sai không?
    Tôi không quen với bộ xử lý ARM7 dùng trong GameBoy Advance, nhưng thật khó hình dung làm sao có thể tạo ra một lệnh gọi nhảy với giá trị sai như vậy
    Tôi cũng tò mò nếu chạy một trong các ROM được khôi phục sai của TheZZAZZGlitch trên máy GameBoy thật thì chuyện gì sẽ xảy ra

    • Với lệnh bx, bạn có thể nhảy tới bất kỳ địa chỉ nào được lưu trong thanh ghi
      Và nếu chạy ROM được khôi phục sai trên máy GameBoy thật, nó sẽ crash và cuối cùng bắt đầu phát ROM qua loa
      Đó chính là ý chính của video :)
    • Rất có thể trình giả lập chỉ mô phỏng việc truy cập các vùng hợp lệ trong sơ đồ bộ nhớ GBA, và nếu có truy cập tới vùng không hợp lệ thì nó ném ra lỗi đó
      Còn trên phần cứng thật thì sẽ thế nào... ai mà biết được :)