Engenharia reversa do servidor de demonstração de Ultima Online de 1998
(draxinar.github.io)- OUO é um projeto que fez a engenharia reversa completa do servidor de demonstração de
Ultima Onlinede 1998, desmontando cerca de 5.000 funções de um binário MSVC x86 e portando tudo para C99 portável UoDemo.exeera uma demonstração standalone incluída no primeiro lançamento deUltima Online: The Second Agee continha juntos o cliente e todo o código e dados do servidor portado para Windows- Cada função foi comparada com o binário original no nível de instrução, e depois convertida manualmente para manter a mesma hierarquia de classes, layout de vtable, fluxo de controle, layout de estruturas e ramificações do original
- A restauração fica muito próxima do código real dos servidores live de
Ultima Onlineem meados de 1998, mas corrige problemas de estabilidade como crashes, overflows e variáveis não inicializadas, além de problemas de jogabilidade como progressão de skills e densidade de spawn, tudo marcado com tags - O demo original suportava apenas o cliente 1.25.33, mas a restauração suporta clientes da versão 1.25.30 até a 5.0.9.1, com ou sem criptografia, e também está pedindo arquivos de dados de servidores de 1997~2003
Origem e escopo dos arquivos de demonstração
- Cada função foi comparada com o binário original no nível de instrução, e o trabalho pôde ser concluído recentemente com os avanços em LLMs após 10 anos de esforço intermitente
- A data de
UoDemo.exeé 1998-09-02, e os dados do servidor haviam sido extraídos de um servidor em operação em 2 de junho de 1998 - Algumas funções foram stubadas para o demo e o mapa jogável foi reduzido à ilha de Ocllo, mas o restante era código real de servidor em produção rodando no
Ultima Onlinelive em meados de 1998 Ultima Onlinefoi um MMORPG de 1997 desenvolvido pela Origin Systems Inc. e foi um dos primeiros MMORPGs de sucesso comercial- O cliente rodava em Windows, e os servidores, chamados de “shards”, rodavam em várias máquinas Solaris, com o mapa dividido por regiões
- O demo oferecia uma missão simples de matar um dragão na ilha de Ocllo e foi montado para permitir explorar mecânicas básicas do jogo, como diálogo, comércio e combate
- Vários emuladores de servidor de
UOreutilizaram partes desse demo, mas até agora não havia um caso de engenharia reversa completa UoDemo.exefoi compilado com Microsoft Visual C++ 5.0, ou seja, Visual Studio 97, e tinha como alvo um dialeto de C++ anterior ao C++98
Método de engenharia reversa
-
Desmontagem e estimativa de símbolos
- A desmontagem foi feita com radare2
- Os nomes dos símbolos foram inferidos a partir do cliente
UO1.25.37 de uma porta experimental para Linux que continha símbolos de C++
-
Conversão manual para C99
- Cada função foi traduzida manualmente para C99 de forma a preservar o mesmo fluxo de controle, layout de estruturas e ramificações do binário original
- As partes diferentes correspondem a correções de bugs reais do demo ou adaptações de plataforma, e estão indicadas no código-fonte
-
Forma de validação
- O build em C foi desmontado novamente com
r2e comparado com o original - Uma função só era marcada como concluída quando os dois resultados coincidiam
- Funções helper foram usadas apenas para padrões inline repetidos, e somente quando o helper podia ser expandido novamente para o mesmo código da versão inline
- O build em C foi desmontado novamente com
-
Restauração da hierarquia de classes
- No início, a tarefa mais importante foi acertar com precisão a hierarquia de classes
- A hierarquia principal era
CEntity (0x10) -> CResourceEntity (0x1C) -> CItem (0x50) -> CContainer (0x5C) -> CMobile (0x37C) -> CPlayer (0x458) - O despacho virtual acontecia por slots da vtable; por exemplo,
vtable[0x18]eraIsPlayer,[0xD0]eraIsMobilee[0xE4]eraIsNPC - Depois que esse layout foi definido, tornou-se possível traduzir a maior parte do binário de forma relativamente direta
Resultado da restauração e diferenças em relação ao original
- O resultado fica muito próximo de uma cópia quase perfeita do servidor de
Ultima Onlinede 1998, mas há algumas diferenças - Em comparação com o código original, foram corrigidos problemas de estabilidade como crashes, overflows e variáveis não inicializadas
- Também foram corrigidos problemas de jogabilidade como progressão de skills, direção de fame/notoriety e densidade de spawn
- Cada correção recebe tags no código-fonte, para que quem comparar com
UoDemo.exepossa verificar exatamente o que mudou e por quê - Alguns recursos, como o sistema de spawn e o sistema de decay, estavam quebrados e podem ter sido parcialmente desativados ou stubados para o lançamento do demo
- O código desses recursos continuava presente, mas os pontos de chamada live não eram alcançados; bastou decompilá-los separadamente e religar o despacho para fazê-los funcionar
- Faltavam alguns dados, como no caso do mapa do jogo, que continha apenas a ilha de Ocllo
- Foi criado um conjunto completo de ferramentas para manipular o formato de dados do servidor e reconstruir integralmente portas, placas, decorações, teleportadores, armadilhas, baús e pontos de spawn do restante do mundo
Sistemas de ecologia que ainda restavam
- O famoso e hoje aposentado ecology system ainda permanecia no código, embora com as chamadas de função desconectadas
- Os sistemas de predadores, presas e necrófagos foram religados, permitindo ver lobos perseguindo coelhos ou corvos comendo itens
- No entanto, por falta de dados precisos, o sistema completo de recursos e produção não foi implementado
- Como material de contexto relacionado, estão vinculados o ecology system de
UOde Raph Koster e os textos sobre o sistema de recursos deUO1, 2, 3
Recursos adicionais e compatibilidade com clientes
- Foram adicionadas as skills Meditation, Stealth e Remove Trap, incluídas pela OSI em fevereiro de 1999
- Alguns vestígios iniciais desses recursos já permaneciam no código
- A maioria dos novos recursos pode ser ativada ou desativada na inicialização com o parâmetro
-features - Como o servidor de demo não tinha nenhum sistema de contas, ele foi reimplementado em uma forma levemente modernizada com base em uma estimativa de como os desenvolvedores originais o fariam
- O servidor de demo original suportava apenas o cliente 1.25.33, mas foi ampliado para suportar todos os clientes da versão 1.25.30 até a 5.0.9.1, ou seja, até 2007-03-27, com ou sem criptografia
- Como houve cinco métodos de criptografia totalmente diferentes ao longo dos anos, cada um precisou ser alvo de engenharia reversa a partir dos binários dos clientes
Original de 32 bits e build padrão em 64 bits
- O binário original era de 32 bits, mas o build padrão atual tem como alvo 64 bits
- A hierarquia de classes reproduz a herança original de C++ por meio de embedding de structs em C
- Graças a esse método, é possível passar um
CMobile*para lugares onde se espera umCContainer* - Como a largura maior dos ponteiros em 64 bits pode deslocar a posição de campos herdados, algumas structs receberam padding deliberado para que a herança e o layout da vtable coincidam com o binário tanto em 32 bits quanto em 64 bits
Recursos públicos
- https://github.com/draxinar/ouo: código
- https://github.com/draxinar/rundir: dados baseados em
UoDemo.dat, correções, dados completados e novos recursos - https://uo.serpent-isle.com/: Test Center, não é um shard real, mas um ambiente para testar uma recriação extremamente fiel do servidor de
Ultima Onlinede 1998 - UO:98: projeto de Batlin e Derrick, fonte de inspiração que levou ao início deste trabalho em 2016
OUOainda está em estágio inicial e pode haver problemas restantes- Problemas encontrados podem ser reportados em issue, e contribuições também são bem-vindas
Pedido à comunidade de Ultima Online
- Se alguém tiver os arquivos
dynamic0.mul,dynamic0.bkp,regions.txteresbank.muldo servidor original deUltima Onlinepor volta de 1997~2003, o projeto pede que sejam compartilhados dynamic0.muledynamic0.bkpsão arquivos de save do servidor,regions.txtcontém definições de spawn eresbank.mulé o arquivo de definições de recursos- Parece improvável que os arquivos originais
dynamic0.muloudynamic0.bkptenham desaparecido completamente - Já existem ferramentas para remover dados de jogadores do arquivo
dynamic0.mul, preservando a privacidade antes da distribuição - Esses arquivos têm grande valor para recriar com altíssima precisão o conteúdo do mundo de
Ultima Online
1 comentários
Opiniões no Hacker News
Se alguém tiver os arquivos
dynamic0.mul,dynamic0.bkp,regions.txteresbank.muldo servidor original de Ultima Online, eu agradeceria muito se pudesse enviarSão arquivos de save do servidor, definições de spawn e definições de recursos de algo entre 1997 e 2003, e especialmente
dynamic0.muledynamic0.bkpprovavelmente foram copiados para vários lugares seguros, então é difícil acreditar que tenham desaparecido completamenteEsses arquivos têm um valor enorme para recriar com muita precisão o conteúdo do mundo de Ultima Online
Muito legal. Curioso eu ter visto isso justamente enquanto escutava a trilha sonora dos jogos Ultima
Fiquei me perguntando se consideraram escrever o resultado da desmontagem no mesmo dialeto de C++ anterior ao C++98 usado no original e mirar no compilador da época
Já desmontei binários que rodavam em sistemas vintage e, se fosse possível, acho que eu tentaria usar o toolchain original. É uma questão filosófica bem interessante
Como último desenvolvedor sobrevivente do eqclassic, achei uma leitura interessante, mas esperava uma história mais aprofundada sobre as ferramentas usadas e como foi o processo completo. Ainda assim, é um bom texto
Na época não existiam LLMs, mas alguns símbolos de debug de um binário PowerPC de 3 anos depois ajudaram um pouco
Nomes de arquivos como
packet_handlereentitylistsoam estranhamente familiares :DO obstáculo final é ter um código de rede praticamente perfeito antes de lapidar o resto, e eu já perdi centenas de horas nisso
Só dei uma olhada rápida no código-fonte, mas parece ser tudo baseado em TCP, então não dá a impressão de que exista algum mecanismo extra de confiabilidade por cima. Se for isso mesmo, parece uma escolha bem “lenta” para um MMO da época, o que é interessante
Para quem quiser experimentar UO, ainda é um jogo com base ativa de jogadores. Servidores de terceiros como UO Outlands são mais próximos da jogabilidade original, mas pelos padrões de quem está acostumado com MMOs atuais, pode ser bem brutal
Outro jogador pode aparecer, te dar gank e você pode perder seu equipamento
Ainda há mais de 2500 pessoas conectadas nesse servidor, então ele continua muito ativo
Minha primeira conquista real em programação foi criar um site de shard de Ultima Online
Eu usava PHP e HTML horríveis, mas ele continuou funcionando por mais de 20 anos. Boas lembranças
Fiquei surpreso ao ver que ainda existe uma comunidade ativa em torno de UO e, de qualquer forma, esse projeto é muito legal
Eu tinha 12 ou 13 anos, isso era no fim dos anos 90 e começo dos anos 2000. Não lembro mais o nome do emulador, mas provavelmente era POL
O objetivo do shard era ficar o mais próximo possível dos servidores oficiais anteriores ao UO:Renaissance, então trabalhamos bastante para que tivesse a aparência e a sensação de T2A
Aprendi muita coisa e, depois que o RunUO apareceu e ficou mais estável por volta de 2003, também ajudei a portar o que havíamos feito no POL para código C# no RunUO, e precisei aprender ainda mais para acompanhar
Todo mundo com quem eu trabalhava nesse shard estudava ciência da computação na faculdade ou já trabalhava como programador, e eu era só uma criança que sabia escrever alguns scripts
Acho que essa experiência foi decisiva para eu me tornar profissional depois. Meu primeiro emprego de verdade numa empresa de tecnologia também veio porque uma dessas pessoas me indicou quando surgiu uma vaga de estágio
Em certo sentido, foi graças ao UO e aos shards privados que minha carreira atual existe
Entrei em programação puramente por necessidade
Esqueci o nome do jogo, mas acho que era City of Heroes, e depois de alguns anos encerrado alguém simplesmente colocou um servidor privado no ar de novo
Mesmo jogos online antigos em Shockwave têm comunidades de nicho reconstruindo servidores, criando runtime de Shockwave e descompiladores
Como acabam resolvendo problemas parecidos, as comunidades de jogos diferentes também se sobrepõem ;)
A segunda foi modificar o mapa, removendo itens estáticos e adicionando ilhas e prédios novos
A terceira foi alterar
verdata.mulpara incluir novas animações e gráficos de itensFoi literalmente por jogar Ultima Online em um servidor POL não oficial que eu entrei em TI. Antes disso eu estava estudando para ser contador
Foi isso que me colocou no IRC pela primeira vez, e depois acabou me levando até o freenode
A cena de emuladores de UO me levou à programação de rede
Nunca vi outro jogo online que capturasse tão bem tantas mecânicas emergentes, acidentais e paralelas de jogabilidade
Os MMOs 3D posteriores parecem ter reduzido muito os elementos interessantes de economia, construção e exploração que UO oferecia
PvP ou conteúdo de quests podem ser melhores em outros jogos, mas UO continuava fascinante, e era possível alternar naturalmente entre jogar sozinho, em grupo ou apenas interagir de leve com estranhos, conforme a vontade
A maioria das pessoas não quer isso e prefere ficar em trilhos pré-definidos
E os dois grupos mais atraídos por esse tipo de jogo entram numa dinâmica em que, se um lado aparece, o outro abandona o jogo. Só que o segundo grupo precisa que o primeiro esteja jogando
Por exemplo, Asheron's Call tinha uma comunidade de mods muito ativa e hoje também tem uma cena de emuladores. Mas a popularidade dos servidores não parece chegar ao nível de UO
Shadowbane era bem focado em guildas, mas tinha aquela diversão de agir meio como fora da lei e fazer PvP com pessoas ou guildas aleatórias
Fora WoW, Old School RuneScape e Final Fantasy Online, não parece haver muita coisa grande para jogar
Achei marcante a parte em que ele diz que, após tocar esse projeto de forma intermitente por 10 anos, os avanços em LLMs finalmente permitiram concluir um trabalho que parecia interminável
Eu também estou fazendo um projeto de descompilação de C++ MFC, e LLMs são absurdamente úteis nesse tipo de tarefa
Eu curtia muito Ultima Online antigamente
Mais recentemente tenho me divertido fazendo scripts em Python no cliente de jogo TazUO. É uma versão um pouco antiga do Python 3, mas ainda assim é muito melhor do que escrever scripts em Razor ou SteamUO
Se você quiser mexer em várias coisas em um shard single-player tranquilo, o Memento me pareceu uma boa opção
Eu estava procurando uma versão mobile localizada em espanhol ou francês de Ultima 4 para NES. O mesmo vale para outros títulos
Queria algo tratado como a Pixel Remaster da série FF
Atualmente só dá para jogar por emulador
RPGs localizados com muito texto são uma forma muito fácil de “aprender brincando” uma língua estrangeira, além de serem ótimos para leitura
Seria bom se algo assim existisse
Ah, UO… que saudade boa. Lembro de ir de bicicleta até a Cybersmith em Palo Alto para comprar tempo pré-pago, porque eu ainda não tinha idade para ter cartão
Eu jogava bastante no shard Napa Valley naquela época. Não era corajoso o bastante para ir para Catskills
Hoje sinto falta de experiências como UO, mas simplesmente não tenho mais tempo para dedicar a um jogo desses