2 pontos por GN⁺ 2024-11-08 | 1 comentários | Compartilhar no WhatsApp
  • Ecco the Dolphin: Defender of the Future para Dreamcast escondia cheats ativados pela entrada das iniciais no arquivo de save, e além do já conhecido GYUGYU+XXX, vários outros inputs especiais foram identificados
  • A análise carregou um snapshot de memória do flycast no Ghidra para localizar o buffer de entrada e a função de processamento, rastreando a estrutura em que o resultado da transformação é comparado com 6 valores especiais
  • A verificação do cheat não é feita pela própria string de entrada, mas por um valor obtido após descriptografar uma chave com uma passphrase e calcular um checksum, o que dificulta encontrá-lo apenas lendo as strings
  • Um brute force em Python testou entradas de 1 a 8 caracteres e confirmou que SOCCER, EXBBERX, QQRIQ, XYZZYX e POPELY estão ligados a fase bônus, modo imortal, exibição de FPS e exibição do tempo
  • A mesma função não fica presa a um único input: NNSET, SOCCER e ADEMVSSF abrem o jogo bônus de futebol, e AFTJSXOT também desbloqueia todas as fases, assim como GYUGYU

Cheats ocultos ativados pelo nome do arquivo de save

  • Ecco the Dolphin: Defender of the Future foi o último jogo de Ecco lançado oficialmente, e uma continuação acabou cancelada
  • O cheat já conhecido consistia em escolher New Game na tela da VMU, digitar GYU nas iniciais, depois inserir GYU de novo e mais três letras quaisquer sem apertar End
    • Ao inserir no formato GYU GYU XXX e sair do menu, passa a ser possível selecionar todas as fases em Load game
  • Os inputs especiais confirmados e seus efeitos são os seguintes
    • GYUGYU+XXX: desbloqueia todos os níveis
    • SOCCER+XXX: desbloqueia a fase bônus
    • EXBBERX+XXX: modo imortal
    • QQRIQ+XXX: exibição de FPS
    • XYZZYX+XXX: exibição do tempo
    • POPELY+XXX: efeito desconhecido

Rastreando a rotina de processamento de entrada com Ghidra

  • Em um snapshot de memória do emulador flycast, foi confirmado que parte das iniciais visíveis na tela era armazenada no buffer 8cfffb34
  • À medida que a entrada continuava, os caracteres digitados antes eram empurrados para o buffer 8c3abf18, e essa área era usada na verificação dos cheats
  • Depois de carregar o snapshot no Ghidra, foi encontrada uma função no endereço 8c0334d8 que lia esse buffer
  • Essa função transforma o buffer e verifica se o resultado corresponde a um dos 6 valores especiais da lista
    • GYU GYU XXX é convertido em 9388D627, que bate com o primeiro valor especial da lista

Estrutura da transformação e do checksum

  • O fluxo da função de transformação identificado no decompilado do Ghidra é o seguinte
    • Lê uma passphrase
    • Descriptografa uma chave de 1024 bytes com essa passphrase
    • Usa a chave para calcular o checksum do buffer de entrada
    • Criptografa a chave novamente
  • Como o checksum é uma função unidirecional, é difícil inferir visualmente quais inputs geram os valores especiais
  • Em uma atualização posterior, metalliczx e SideQuark confirmaram que, após a descriptografia, a estrutura seguia o polinômio padrão de checksum CRC32
    • Por isso, existe uma forma mais eficiente de obter os valores desejados do que por brute force

Inputs encontrados com brute force em Python

  • GYUGYU tem 6 letras, e o número de combinações possíveis de 6 letras é 26^6 = 308,915,776
  • Com 7 letras, isso sobe para 8 bilhões de combinações, e com 8 letras chega a 208 bilhões, uma escala pesada para um notebook
  • A implementação em Python testa os inputs com o seguinte procedimento
    • Copia um bloco de memória contendo o buffer de entrada não inicializado, a passphrase e a chave
    • Descriptografa a chave com a passphrase
    • Coloca sequências de 1 a 8 letras no buffer de entrada
    • Calcula o checksum de cada input
    • Compara o resultado calculado com o valor-alvo
  • O código completo foi publicado neste gist
  • Mesmo a versão single-thread já produziu os resultados necessários, que apareceram antes de a versão paralela ficar pronta

Mapeamentos encontrados e efeitos reais

  • A última coluna da saída indica com qual valor especial cada resultado corresponde
    • NNSET, SOCCER e ADEMVSSF correspondem todos ao mesmo valor e desbloqueiam o jogo bônus de futebol
    • AFTJSXOT desbloqueia todas as fases, assim como GYUGYU
  • Ao inserir SOCCER+XXX como iniciais, o Bonus Game é liberado e é possível jogar futebol subaquático
    • Isso define o bit 0x2 no flag de 8c3ac00c
  • EXBBERX+XXX faz a tela de Options mostrar Immortality Enabled
    • Enquanto estiver ativo, não é possível se afogar nem morrer
    • Isso define o bit 0x400 do flag em 8c3abe48 e o bit 0x4 do flag em 8c3abb00
  • QQRIQ+XXX exibe o framerate do jogo e alguns valores de depuração
  • XYZZYX+XXX mostra o valor atual do relógio
    • Os dois inputs alteram valores nos endereços 8c35659c e 8c3565a4
  • O efeito de POPELY+XXX não foi confirmado
    • Supõe-se que ele tentasse ativar um flag em 8c3b0e44, mas esse flag aparentemente só mostra a mensagem Cheats Enabled sem produzir outro efeito visível

1 comentários

 
GN⁺ 2024-11-08
Opiniões do Hacker News
  • O hash é simplesmente CRC32; mais exatamente, usa este polinômio (0x77073096; o código está errado)

    https://web.mit.edu/freebsd/head/sys/libkern/crc32.c

    Os inteiros descriptografados no texto são constantes desse CRC32. Sabendo que é CRC32 e conhecendo o polinômio, dá para calcular a resposta de trás para frente em tempo logarítmico, não exponencial, usando matemática modular em anéis de polinômios

    • Dizem que o Binwalk reconhece tabelas de polinômios CRC; fico curioso se ele conseguiria encontrar esta tabela também

      Alguém precisa integrar Binwalk e Ghidra. Eles combinam muito bem

    • Fico curioso se há dicas para descobrir que o valor é um resultado de CRC32, ou qual polinômio/valor inicial foi usado

  • Quando o Ecco original saiu para Megadrive (Genesis), gastei todo o dinheiro que eu tinha juntado com esforço para comprá-lo. Aquele jogo era absurdamente difícil e, de tanta raiva, passei a tarde inteira sentado com papel e caneta até de algum jeito decifrar o sistema de senhas

    Teleportei para a fase final e terminei no dia seguinte, mas fiquei me sentindo culpado por ter gastado todo o meu patrimônio em um jogo que concluí em dois dias

    • Você decifrou o sistema de senhas com papel e caneta? Se lembrar de algo, eu adoraria ouvir mais

    • Filosoficamente, eu diria que você não terminou esse jogo

      Você pulou várias fases e viu só parte do conteúdo, da jogabilidade e da história pretendidos. Jogos, incluindo Ecco the Dolphin, em geral têm mais a ver com a jornada do que com o destino. Você perdeu temas e experiências como isolamento, fazer amizade com grupos externos, preservação, viagem no tempo, comunhão com dinossauros e, claro, viagem espacial

      Então você não precisava se sentir tão culpado assim

    • Ainda assim, a fase final era incrível. Fico curioso se você ficou surpreso ao vê-la depois de pular uma parte tão grande do jogo

    • Usando cheats ou não, talvez você seja a única pessoa no mundo que zerou esse jogo

  • QQRIQ é uma abreviação fonética de “kukuriku” e significa o canto do galo em húngaro e em várias línguas. Há exemplos como o polonês “kukuryku” e o hebraico “קוקוריקו”

    Isso me deixa curioso sobre como foi o processo de escolher as senhas

    • Gyugyu também pode ser uma referência ao filme húngaro “The Fifth Seal”

      “Imagine que você está prestes a morrer e reencarnará como uma de duas pessoas: um escravo ou um senhor rico. O escravo sofre nas mãos do senhor, perde a língua e um olho, e sua esposa e seus filhos também são assassinados. Ele continua vivendo acreditando ser uma boa pessoa, porque nunca fez a outros nada tão horrível e sádico quanto o senhor. O senhor rico não tem nenhum escrúpulo moral. Não acha que o que fez foi errado e acredita que o escravo merecia ser punido. Você precisa escolher entre ser um escravo pobre, mas justo, ou um senhor rico, mas corrompido.”

      Gyugyu é o nome desse escravo

      https://www.imdb.com/title/tt0075467

    • Como os programadores desse jogo estavam em Budapest, é uma hipótese bem plausível

    • Popely, com o “ly” do húngaro, também era uma pista

    • Em francês é Cocorico, então é muito parecido

    • Também lembra a vila Kakariko de Zelda, onde sempre aparecem galinhas

  • Como curiosidade interessante, o desenvolvedor de Ecco, Ed Annunziata, quando perguntado sobre suas inspirações, respondeu: “Nunca usei LSD, mas li muito John C. Lilly”. Lilly é conhecido por trabalhos pioneiros em inteligência animal, psicoterapia com cetamina, tanques de privação sensorial e exploração da consciência

    O nome “Ecco” é uma referência ao ECCO (Earth Coincidence Control Office) de Lilly. John postulava a existência de uma base sobrenatural/alienígena no lado oculto da Lua para coordenar todas as “coincidências” na Terra. Ele foi uma das primeiras pessoas a perceber o quanto os golfinhos eram inteligentes e ficou obcecado em descobrir como se comunicar com eles, a ponto de inundar metade de sua casa no Caribe para viver junto com eles. Isso é só a ponta do iceberg; se você achar interessante, recomendo muito a autobiografia dele, The Center of the Cyclone. É uma figura realmente fascinante

  • Fico curioso se há algum material para começar a fazer engenharia reversa de jogos de Dreamcast. Há coisas que eu queria tentar com Skies of Arcadia, mas seria bom ter técnicas mais sistemáticas do que “ver quais valores mudam entre snapshots de memória”

    • Para encontrar a localização de valores na RAM, esse método é praticamente a técnica padrão. Na prática, funciona muito bem

      Alguns emuladores, como o Dolphin, têm ferramentas desse tipo embutidas. Ferramentas antigas de hack de jogos, como o Gameshark para N64, também usavam a mesma técnica com uma UI no console. Não sei se emuladores de Dreamcast têm uma ferramenta assim

      Escrevi um post usando essa técnica no Dolphin, e o post seguinte também é sobre hack de jogos de console usando Ghidra: https://www.smokingonabike.com/2021/01/17/hacking-super-monk...

    • Já dei uma olhada nesse jogo. O ponto principal é fazer dump dos snapshots de memória para um arquivo e depois importá-los no Ghidra. Há várias formas de fazer o dump, e muita gente gosta do Cheat Engine

      O Ghidra consegue analisar nativamente o código de máquina do processador SuperH, então só rodar a análise automática já revela muitas funções

  • Nos últimos anos, passei a me sentir muito mais atraído por jogos antigos e, não sei se a expressão faz sentido, eles parecem ter muito mais alma

    E sinto muito pelo incidente com o carro. Obrigado pelo aviso; de agora em diante não vou deixá-lo ligado em marcha lenta na entrada da garagem

    • Tem certeza de que você não sente falta de recursos modernos como conexão obrigatória à rede e microtransações?
    • Não sei o que aconteceu com o carro. Não vi no texto nem nos comentários
  • Sempre me perguntei por onde começar a aprender engenharia reversa. A maioria diz para aprender assembly primeiro, mas depois disso parece não haver muita informação concreta online

    Não sei se é uma questão de ir aprendendo devagar, por tentativa e erro, os padrões comuns de x86, arm e plataformas de arcade. É difícil encontrar discussões online que entrem nos detalhes

    • É parecido com depuração. Você provavelmente já teve que pegar uma base de código desconhecida e entendê-la; a diferença é que, em vez do código-fonte, você tem o binário

Ferramentas como o Ghidra permitem ir ajustando o código-fonte aos poucos, mas, no fim, é preciso inferir as coisas do mesmo jeito que se faria ao tentar entender uma base de código desconhecida. A diferença, desta vez, é que não há nenhum comentário, embora também haja muitos projetos de código aberto sem comentários

De certa forma, você já está meio caminho andado, e obviamente ajuda estar familiarizado com código assembly
  • Para exemplos mais próximos da realidade, vale resolver desafios em http://microcorruption.com ou https://crackmes.one/

  • Pessoalmente, aprendi muito mexendo no Cheat Engine. Eu o usava principalmente quando era mais novo e nunca tinha voltado a olhar para ele, então não sabia, mas é uma ferramenta muito mais poderosa do que eu imaginava

    O disassembler é bastante decente, e dá para escrever o que eles chamam de “assembly scripts”, o que é bom para aprender o básico de patches de memória em assembly x86. A partir daí, você pode começar a criar seus próprios utilitários para aplicar patches em jogos do jeito que quiser

    Só com o Cheat Engine já dá para aplicar patches em jogos e criar cheats absurdamente fortes

  • Aprendi um pouco disso na escola, mas executar passo a passo, em um debugger, os videogames de que eu me lembrava da infância me ensinou ciência da computação muito melhor do que as aulas

  • Quero ver um vídeo do cheat de futebol subaquático funcionando de verdade

  • É interessante como jogos parecidos usam inteiros fixos para bater checksums. Pitfall: The Lost Expedition também usava uma abordagem muito semelhante: convertia as entradas de botões em uma string ASCII dos botões pressionados e depois calculava o CRC

    A abordagem também era quase força bruta em Python, comparando com os hashes de cheat extraídos. Também dá para ver uma tabela CRC32 escondida dentro de decrypted_ints. Tabelas pré-geradas são fáceis demais de pesquisar. Em vez de gerar uma nova tabela com um polinômio próprio, fico curioso por que elas aparecem com tanta frequência ofuscadas, aparentemente para dificultar

  • Um blog focado no Sega Saturn? Que surpresa

    Há pouco tempo encontrei um Saturn e um pequeno pacote de CDs de jogos no armário da casa dos meus pais. Não me lembro de ter tido um, então suponho que meu irmão o tenha conseguido depois que fui para a universidade. De qualquer forma, liguei tudo e todos os jogos funcionaram bem. Mas, fora isso, não faço a menor ideia do que fazer com ele. Jogar fora, obviamente, não é uma opção