1 pontos por GN⁺ 2024-01-23 | 1 comentários | Compartilhar no WhatsApp
  • TheZZAZZGlitch mostrou que, ao gravar os sons de travamento do Game Boy Advance, é possível identificar os dados do jogo dentro do cartucho e, no fim, reconstruir a mesma ROM
  • O ponto central é interpretar o áudio emitido após o travamento como dados da ROM, mas isso exige muitos ajustes conforme o formato da fonte, o que dificulta seu uso como ferramenta genérica de dump
  • Em uma gravação de mais de 4 horas, uma forma de onda característica apareceu por volta da marca de 1h50, e depois disso os sons de instrumentos e samples de áudio do jogo passaram a ser ouvidos em sequência
  • Com um script em Python e correção de alinhamento, ele chegou a 99,76% de precisão, mas a inicialização falhou; ao combinar 3 gravações com um algoritmo de maioria, o resultado subiu para 99,979%
  • Após combinar 7 gravações e filtrar espaços vazios, ele alcançou 100% de correspondência, confirmando experimentalmente a possibilidade de reconstruir uma ROM de GBA apenas a partir dos sons de travamento

Experimento que leu dados da ROM a partir de sons de travamento

  • TheZZAZZGlitch demonstrou que o som emitido pelo GBA após um crash de software pode conter dados do jogo
  • Um GBA travado pode continuar emitindo som com base nos dados internos do cartucho e, com hardware e código especiais para analisar esse áudio, é possível identificar qual é o jogo
  • Ainda assim, esse método não é uma forma simples de fazer dump dos dados do cartucho, nem uma solução pronta para uso
    • É necessário bastante ajuste fino para diferentes formatos de origem

A forma de onda revelada em uma gravação longa

  • Depois de causar um travamento no GBA, uma gravação de mais de 4 horas revelou uma forma de onda característica por volta de 1h50
  • No trecho seguinte, os sons de instrumentos e samples de áudio reais incluídos no jogo podem ser ouvidos em ordem
  • O restante dos dados soa como dados de 8 bits a 13.100Hz, e algumas partes soam bastante estranhas

Script em Python e a primeira tentativa de restauração

  • TheZZAZZGlitch preparou um script em Python para ler uma gravação limpa de dump por crash do GBA, “depois de passar 2 dias corrigindo bugs”
  • Os dados da ROM contêm grandes trechos de bytes 0, e essas partes aparecem como silêncio, o que dificulta o parsing no áudio
  • Depois de executar um script separado para realinhar as seções com base em suas posições na ROM original, a ROM restaurada chegou a 99,76% de precisão
  • Essa ROM ainda não dava boot, e como o processo usava dados conhecidos da ROM para revelar dados desconhecidos, isso tecnicamente contava como “trapaça”
    • Mesmo em um processo totalmente cego, ainda restam hipóteses e estimativas que podem ser aplicadas

Aumentando a precisão com a combinação de várias gravações

  • Na etapa seguinte, o foco foi melhorar a qualidade das gravações
  • Ao combinar os resultados de 3 gravações com um algoritmo de “maioria”, a precisão subiu para 99,979%
  • Essa ROM resultante conseguiu dar boot, mas o texto aparecia corrompido e ocorria um crash na tela de título
  • Depois, ao combinar 7 gravações e filtrar os espaços vazios, foi alcançada uma correspondência de 100%

Hardware físico e experimentos adicionais

  • Na parte final do vídeo, ele também verifica como esse método funciona em hardware físico
  • O experimento foi repetido com outros jogos, enquanto também se investigava um mistério relacionado ao código ARM dentro de cartuchos clonados
  • Também foram testadas formas de obter gravações melhores
    • Uma delas foi o uso de um “cursed adapter” para fazer um mixdown grosseiro em um único canal

1 comentários

 
GN⁺ 2024-01-23
Opiniões no Hacker News
  • O problema quando há uma longa sequência de 0x00 tem a ver com recuperação de clock (clock recovery)
    Alguns fluxos de dados digitais, especialmente dados brutos de cabeças magnéticas de drives de disco ou comunicações seriais de alta velocidade como Ethernet, são transmitidos sem um sinal de clock separado
    O receptor cria um clock com base em uma referência aproximada de frequência e, com um loop de bloqueio de fase (PLL), ajusta a fase do clock às transições no fluxo de dados
    Para que esse método funcione, as transições de dados precisam ocorrer com frequência suficiente para compensar o drift do oscilador do PLL, e a especificação de quanto tempo ele consegue aguentar sem transições é chamada de máximo de dígitos idênticos consecutivos (CID)
    https://en.wikipedia.org/wiki/Clock_recovery

    • Antigamente, era interessante como a possibilidade de recuperação de clock era garantida com um método de codebook inteligente, que tratava cuidadosamente intervalos curtos de bits, como 8b/10b, e evitava problemas de capacitância da linha
      Depois, passou-se para métodos como 64/66b, que anexam um cabeçalho curto a grandes blocos de bits para garantir transições de clock e passam tudo por um scrambler pseudoaleatório
    • Outra preocupação é quando alguma parte da forma de onda está em acoplamento AC (AC coupling), de modo que corrente contínua não passa
      Mesmo que o clock esteja perfeitamente sincronizado, em trechos longos um sinal quase todo 1 e um sinal quase todo 0 acabam ficando iguais
    • Neste caso, isso não parece muito relacionado
      O áudio é analógico e, para decodificá-lo como bitstream, seria necessário um DAC; ele é transmitido em uma frequência fixa, como 44,1 kHz ou 48 kHz, sem sincronização especial
    • Encontrei nesta página um artigo muito interessante chamado Wireless Set Number 10
      https://en.wikipedia.org/wiki/Wireless_Set_Number_10
  • Isso me lembrou o hack original do iPodLinux, que há quase 20 anos fez o dump do firmware do iPod de 4ª geração pelo alto-falante piezoelétrico
    https://web.archive.org/web/20140810083116/http://www.newscientist.com/article/dn7085
    Por coincidência, graças a isso também dava para rodar jogos de GBA no iPod, mas jogar Doom com a click wheel e assistir a vídeos em preto e branco já era satisfatório o bastante

    • Boas lembranças
      Ainda tenho um iPod Classic e, depois de atualizar a bateria, coloquei nele 4 cartões MicroSD de 256 GB
      Recentemente também vi uma modificação que adiciona Bluetooth, mas como exige trocar a carcaça traseira, acho que não vou chegar a esse ponto
      Há algo atemporal tanto no design quanto no fato de possuir diretamente cópias dos arquivos de música
  • Fico feliz que isso esteja recebendo mais atenção aqui
    Foi postado alguns dias atrás, mas passou despercebido: https://news.ycombinator.com/item?id=39037104
    O vídeo original tem muito conteúdo que não aparece neste texto curto, incluindo um adaptador personalizado que o hacker fez na base do corta-e-cola para obter qualidade de áudio adequada no DS

  • Zzazz realiza todo ano uma competição/evento de Primeiro de Abril, geralmente envolvendo algum grau de hacking retrô ou engenharia reversa
    Recomendo participar
    As competições anteriores estão no GitHub

  • A arquitetura de áudio da Nintendo sempre foi interessante
    O NES original tinha um gerador de samples capaz de produzir formas de onda arbitrárias, e ele podia ser acionado de duas maneiras
    Uma era fornecer um endereço de memória, ler os bits e processá-los como uma forma de onda muito simples: 1 significava “aumentar o valor em um”, 0 significava “diminuir o valor em um”, então, para criar uma forma de onda plana, era preciso repetir algo como 10101010
    A outra era a CPU inserir continuamente um “valor inicial” diretamente, acionando o chip de forma direta; na prática, isso era mais rápido do que um driver de áudio ler bits da RAM
    O problema é que esse método consumia todos os ciclos da CPU, então só podia ser usado quando nada mais estava acontecendo
    Jogos como Battletoads aproveitaram isso para tocar batidas de bateria com qualidade mais alta enquanto a ação estava parada, na tela de título, no efeito “crocante” em que toda a ação para por um instante ao dar o golpe final em um inimigo, e na memorável música de pausa
    Há aqui uma demo em que o jogo alterna entre o modo de acionamento direto e o modo em que o chip lê samples. Retro Game Audio publicou um vídeo modificado em emulador mostrando o momento em que entra na sub-rotina de acionamento direto: https://www.youtube.com/watch?v=JGT0FM3yh-w

  • Fico curioso sobre por que isso acontece em primeiro lugar
    É comum esses jogos despejarem o estado como áudio? É uma ferramenta de depuração intencional para desenvolvedores de jogos?

    • Um vídeo anterior do autor[1] explica os detalhes técnicos desse comportamento
      Basicamente, o som do GBA transmite áudio a partir de um buffer na RAM, e uma interrupção precisa avisar ao hardware para voltar a ler desde o início do buffer
      Mas, se a interrupção não acontece, como quando o jogo trava, o fluxo de áudio passa do buffer e começa a ler outras áreas da memória
      [1] https://www.youtube.com/watch?v=wSWNkpqjtQY&t=361s
    • É algo bem raro, e também não é uma ferramenta de depuração intencional
      Em teoria, o GBA poderia ter “parado” a arquitetura quando o jogo travasse, ou ter um watchdog que vinculasse a atualização de estado que precisa ser executada periodicamente a uma interrupção não mascarável e reinicializasse quando essa atualização parasse
      Mas esse tipo de recurso custaria mais, então não existe no GBA
      A Nintendo acabou adotando a abordagem tradicional dos antigos fabricantes de cartuchos de jogos: “se nosso jogo não tiver bugs, não precisamos nos preocupar com o comportamento de estados de hardware indefinidos”
      Então, quando um jogo de GBA entra em um estado de travamento, como um loop infinito com interrupções desativadas, o chip de áudio não sabe que o sistema travou e continua fazendo a tarefa simples de ler bits consecutivos da RAM e transformá-los em som
      Como a rotina de limpeza que gerenciava as leituras durante o funcionamento normal desaparece, ele continua lendo até finalmente chegar a bits que representam valores da ROM do cartucho
  • É absurdamente impressionante
    Técnicas como o algoritmo de votação por maioria usado aqui provavelmente são subutilizadas em várias indústrias

    • Se você tiver interesse, técnicas sofisticadas de recuperação de sinais com ruído já vêm se acumulando há quase 100 anos
      Mídias de armazenamento magnético funcionam basicamente pelo mesmo princípio desse hack
      https://en.wikipedia.org/wiki/Partial-response_maximum-likelihood
      A mesma ideia poderia ser aplicada aqui, já que o conteúdo da ROM do GBA deve ter um viés forte
      A votação por maioria desperdiça muita informação
    • Uma aplicação interessante de escolher o valor que aparece mais vezes, ou, de forma mais geral, a mediana, é remover ruído ou pessoas de várias fotos tiradas do mesmo ponto
      Basta sobrepor todas as fotos e manter apenas a mediana de cada pixel[1]
      [1]: https://patdavid.net/2013/05/noise-removal-in-photos-with-median_6/
    • Em recuperação de dados isso é bem comum
      Você fica lendo a imagem do disco e aplicando uma decisão por quórum até obter um resultado que passe no checksum, aí verifica se funciona corretamente
      Se houver checksums de nível mais alto, como assinaturas de arquivo, isso ajuda na validação adicional
      Também é usado em algumas aplicações aeroespaciais
    • Pensei que isso poderia ser usado em escaneamento de filmes, especialmente em projetos de fãs como o 4K77
      Como eles lidam não com um master pristine, mas com cópias de exibição em cinema que podem estar danificadas, se fosse possível usar várias cópias para remover riscos e coisas do tipo, isso poderia reduzir enormemente o tempo de retoques manuais na pós-produção
  • A transformação de 0xFF em 0x00 pode ser causada por um capacitor de bloqueio de corrente contínua ou por filtragem passa-altas
    Circuitos de áudio não são muito adequados para conteúdo inaudível
    Com sorte, conectar um osciloscópio digital diretamente à saída de áudio do chip poderia melhorar a precisão da captura, mas ainda assim conseguir uma imagem inicializável é bem impressionante

    • Pelo que lembro de ter lido nos comentários do vídeo no YouTube, o objetivo era tentar fazer isso usando o máximo possível de equipamento básico
      Por isso eles passaram horas fazendo capturas repetidas e calculando a média dos erros, em vez de usar um osciloscópio de registro de dados adequado
    • Exato, é preciso criar um sinal sem polarização DC
      Até algo simples como codificação Manchester já ajudaria bastante
      Se isso não bastar, também dá para usar NRZ ou até codificação convolucional
      Além disso, seria preciso enviar uma senoide ou, se isso não for possível, pelo menos elevar bastante a frequência da onda quadrada para que ela não seja eliminada pelo capacitor de acoplamento AC
  • A parte mais impressionante disso tudo, para mim, é a forma como os piratas modificaram o código para executar o jogo a partir de uma memória flash gravável em vez de ROM + memória volátil de armazenamento

    • É uma técnica muito comum em jogos piratas de Game Boy e Game Boy Advance para economizar alguns centavos no custo da bateria
      Na verdade, criar esses patches também não é tão difícil
      Os piratas fazem um pouco de engenharia reversa para descobrir onde o código do jogo salva os dados e criam patches específicos por jogo para gravar o conteúdo salvo na flash gravável
      Porém, como os jogos oficiais de GBA sempre usam funções do Nintendo SDK para salvar, basta fazer hook dessas funções para que um patch universal que permita salvar qualquer jogo de GBA em cartuchos piratas sem bateria fique bem simples
      Escrevi um patcher que faz isso, e ele pode ser visto aqui
      https://github.com/metroid-maniac/gba-auto-batteryless-patcher
  • Alguém sabe o que acontece internamente quando o emulador do TheZZAZZGlitch informa que o jogo está tentando saltar para um endereço inválido?
    Não estou familiarizado com o processador ARM7 usado no GameBoy Advance, mas tenho dificuldade de imaginar como é possível construir uma chamada de salto com um valor inválido
    Também fico curioso sobre o que aconteceria se uma das ROMs restauradas incorretamente pelo TheZZAZZGlitch fosse executada em um GameBoy real

    • A instrução bx permite saltar para um endereço arbitrário armazenado em um registrador
      E, se você executar uma ROM restaurada incorretamente em um GameBoy real, ela vai travar e, por fim, começar a tocar a ROM pelo alto-falante
      Esse é o ponto central do vídeo :)
    • É provável que o emulador só emule acessos a regiões válidas do mapa de memória do GBA e lance esse erro quando uma região inválida é acessada
      No hardware real, o que aconteceria… quem sabe :)