Doom.ttf: Executando Código na Máquina Virtual de Fontes TrueType
Descubra como a máquina virtual embutida em fontes TrueType, projetada para renderização de texto, pode ser explorada para executar código, permitindo a execução do clássico jogo Doom dentro de um arquivo de fonte.
MundiX News·18 de junho de 2026·7 min de leitura·👁 6 views
A execução do jogo Doom é lendária por sua capacidade de rodar em praticamente qualquer dispositivo, desde displays de cigarros eletrônicos e testes de gravidez até bactérias E. coli e tratores John Deere. Agora, o desafio é rodar Doom dentro de um arquivo de fonte TrueType (TTF). Como isso é possível? A resposta reside na complexa máquina virtual (VM) presente nas fontes.
VM em Fontes? Uma Superfície de Ataque Inesperada
Sim, fontes TrueType contêm uma máquina virtual funcional que pode ser explorada como um vetor de ataque incomum. Quando um navegador carrega uma página, ele precisa renderizar as letras. A abordagem mais direta seria rasterizar os contornos vetoriais dos glifos no tamanho desejado. No entanto, em tamanhos pequenos, isso pode resultar em uma "sopa" de pixels: serifs finos desaparecem, traços verticais oscilam entre os pixels e elementos que deveriam ter a mesma espessura aparecem com espessuras diferentes. Essa era uma catástrofe em telas de baixa resolução dos anos 90.
Em 1991, programadores da Apple introduziram uma solução: permitir que a própria fonte contivesse um programa que instruísse o rasterizador sobre como ajustar os contornos à grade de pixels. Essa técnica é chamada de hinting (do inglês "hint" - dica) e é executada em uma máquina de pilha com quase 200 instruções. A Microsoft adotou essa ideia, tornando o TrueType um padrão de fato. Atualmente, cada arquivo TTF contém hinting, e cada letra exibida na tela é o resultado da execução de centenas de instruções dessa VM. O interpretador reside no sistema FreeType em Linux e Android, no DirectWrite no Windows e no Core Text no macOS. Antes do Windows 10 Anniversary Update, a análise de fontes era realizada diretamente no kernel (win32k.sys), um ponto crucial para a segurança que exploraremos mais adiante.
A instrução set dessa VM é surpreendentemente robusta, indo muito além da simples tarefa de "mover um vértice de contorno em meio pixel". Ela inclui saltos condicionais (IF, ELSE, EIF), chamadas recursivas de funções (FDEF e CALL), uma área de armazenamento (Storage Area) com 65.535 células, e capacidades aritméticas e lógicas. Esses recursos combinados tornam a máquina Turing-completa. O site Gwern.net mantém um catálogo de sistemas "inesperadamente Turing-completos", e o TrueType figura nessa lista há muito tempo. Alguém, eventualmente, usaria essa capacidade para algo mais interessante do que simples contagem. A ideia de executar Doom dentro de uma fonte surgiu como um experimento.
Raycasting Simplificado
Antes de mergulhar no bytecode, é essencial entender como Doom e Wolfenstein 3D implementavam o 3D. A genialidade do raycasting reside em permitir a criação de pseudo-3D em hardware que não suportava gráficos 3D nativamente. O mapa do jogo é uma grade bidimensional de 16x16 células, onde cada célula pode conter um espaço vazio ou uma parede. O jogador está posicionado em algum lugar na grade, olhando em uma direção específica. O algoritmo funciona da seguinte forma: a tela é dividida em faixas verticais (por exemplo, uma para cada coluna de pixels). Para cada faixa, um raio é "lançado" da posição do jogador na direção correspondente a essa parte da tela. O raio viaja pela grade 2D até colidir com uma parede. A distância até a parede é medida e, quanto mais distante a parede, menor ela é desenhada na tela, criando a ilusão de 3D. A sutileza está na forma como o raio "viaja pela grade". Para evitar que ele "salte" sobre uma parede entre os passos, utiliza-se o algoritmo DDA (Digital Differential Analyzer). Este algoritmo garante que o raio avance sempre para a próxima fronteira de célula (horizontal ou vertical), a mais próxima, assegurando que nenhuma parede seja atravessada. John Carmack, em 1992, implementou isso em um processador 386 sem FPU, utilizando aritmética de ponto fixo e tabelas pré-calculadas para senos e cossenos. Essa abordagem se torna familiar quando consideramos a situação dentro do hinting TTF, onde nos encontramos exatamente no mesmo cenário.
Arquitetura TTF-DOOM
A abordagem TTF-DOOM divide o processamento em duas partes. O JavaScript na página web lida com a entrada do teclado (WASD e setas), rastreia a posição e a rotação do jogador, e renderiza na tela Canvas todos os elementos que necessitam de sprites, como inimigos, armas e o HUD. A fonte, por outro lado, assume a pesada carga geométrica: recebe as coordenadas do jogador, lança raios, calcula as distâncias até as paredes e retorna um array de alturas. Essencialmente, atua como uma GPU, embora extremamente peculiar e lenta. A questão crucial é como transferir dados para a fonte, que é um arquivo estático. Surpreendentemente, isso é feito através de CSS. Fontes OpenType suportam "variable fonts" (fontes variáveis) com "eixos de variação". É possível definir uma string CSS como font-variation-settings: 'MOVX' 123, 'MOVY' 456, 'TURN' 789. O navegador, então, reinicia o hinting a cada alteração. Dentro do processo de hinting, existe uma instrução especial GETVARIATION (opcode 0x91) que coloca na pilha os valores atuais de todos os eixos. Isso estabelece a comunicação entre o mundo JavaScript e o mundo da máquina de pilha.
Segurança e Ataques via Fontes
A capacidade de execução de código dentro de fontes TrueType levanta sérias preocupações de segurança. Históricamente, vulnerabilidades em parsers de fontes foram exploradas para comprometer sistemas. O caso Duqu em 2011 demonstrou como um arquivo de fonte malicioso poderia explorar falhas no kernel do Windows para obter acesso. O Google Project Zero, após um ano de fuzzing em fontes, descobriu diversas vulnerabilidades. Mais recentemente, a "Operation Triangulation" revelou ataques sofisticados que utilizavam exploits em fontes para comprometer dispositivos. Ataques "scriptless", que exploram o hinting para executar código sem a necessidade de scripts maliciosos na página, são particularmente perigosos. A defesa contra essas ameaças envolve mecanismos como o fontdrvhost.exe no Windows, que isola o processamento de fontes, e o "Untrusted Font Blocking", que impede a instalação de fontes não confiáveis. A lição fundamental é que a complexidade inerente às fontes modernas, com suas VMs e capacidades de execução, pode se tornar uma superfície de ataque significativa se não for devidamente gerenciada e protegida.
🛡️⚡
Pare de pesquisar. Comece a hackear.
O MundiX é seu copiloto de pentest com IA: comandos exatos, análise de outputs e próximo passo na kill chain — em segundos.
Sem cartão para começar · Planos a partir de R$49/mês
A execução do jogo Doom é lendária por sua capacidade de rodar em praticamente qualquer dispositivo, desde displays de cigarros eletrônicos e testes de gravidez até bactérias E. coli e tratores John Deere. Agora, o desafio é rodar Doom dentro de um arquivo de fonte TrueType (TTF). Como isso é possível? A resposta reside na complexa máquina virtual (VM) presente nas fontes.
VM em Fontes? Uma Superfície de Ataque Inesperada
Sim, fontes TrueType contêm uma máquina virtual funcional que pode ser explorada como um vetor de ataque incomum. Quando um navegador carrega uma página, ele precisa renderizar as letras. A abordagem mais direta seria rasterizar os contornos vetoriais dos glifos no tamanho desejado. No entanto, em tamanhos pequenos, isso pode resultar em uma "sopa" de pixels: serifs finos desaparecem, traços verticais oscilam entre os pixels e elementos que deveriam ter a mesma espessura aparecem com espessuras diferentes. Essa era uma catástrofe em telas de baixa resolução dos anos 90.
Em 1991, programadores da Apple introduziram uma solução: permitir que a própria fonte contivesse um programa que instruísse o rasterizador sobre como ajustar os contornos à grade de pixels. Essa técnica é chamada de hinting (do inglês "hint" - dica) e é executada em uma máquina de pilha com quase 200 instruções. A Microsoft adotou essa ideia, tornando o TrueType um padrão de fato. Atualmente, cada arquivo TTF contém hinting, e cada letra exibida na tela é o resultado da execução de centenas de instruções dessa VM. O interpretador reside no sistema FreeType em Linux e Android, no DirectWrite no Windows e no Core Text no macOS. Antes do Windows 10 Anniversary Update, a análise de fontes era realizada diretamente no kernel (win32k.sys), um ponto crucial para a segurança que exploraremos mais adiante.
A instrução set dessa VM é surpreendentemente robusta, indo muito além da simples tarefa de "mover um vértice de contorno em meio pixel". Ela inclui saltos condicionais (IF, ELSE, EIF), chamadas recursivas de funções (FDEF e CALL), uma área de armazenamento (Storage Area) com 65.535 células, e capacidades aritméticas e lógicas. Esses recursos combinados tornam a máquina Turing-completa. O site Gwern.net mantém um catálogo de sistemas "inesperadamente Turing-completos", e o TrueType figura nessa lista há muito tempo. Alguém, eventualmente, usaria essa capacidade para algo mais interessante do que simples contagem. A ideia de executar Doom dentro de uma fonte surgiu como um experimento.
Raycasting Simplificado
Antes de mergulhar no bytecode, é essencial entender como Doom e Wolfenstein 3D implementavam o 3D. A genialidade do raycasting reside em permitir a criação de pseudo-3D em hardware que não suportava gráficos 3D nativamente. O mapa do jogo é uma grade bidimensional de 16x16 células, onde cada célula pode conter um espaço vazio ou uma parede. O jogador está posicionado em algum lugar na grade, olhando em uma direção específica. O algoritmo funciona da seguinte forma: a tela é dividida em faixas verticais (por exemplo, uma para cada coluna de pixels). Para cada faixa, um raio é "lançado" da posição do jogador na direção correspondente a essa parte da tela. O raio viaja pela grade 2D até colidir com uma parede. A distância até a parede é medida e, quanto mais distante a parede, menor ela é desenhada na tela, criando a ilusão de 3D. A sutileza está na forma como o raio "viaja pela grade". Para evitar que ele "salte" sobre uma parede entre os passos, utiliza-se o algoritmo DDA (Digital Differential Analyzer). Este algoritmo garante que o raio avance sempre para a próxima fronteira de célula (horizontal ou vertical), a mais próxima, assegurando que nenhuma parede seja atravessada. John Carmack, em 1992, implementou isso em um processador 386 sem FPU, utilizando aritmética de ponto fixo e tabelas pré-calculadas para senos e cossenos. Essa abordagem se torna familiar quando consideramos a situação dentro do hinting TTF, onde nos encontramos exatamente no mesmo cenário.
Arquitetura TTF-DOOM
A abordagem TTF-DOOM divide o processamento em duas partes. O JavaScript na página web lida com a entrada do teclado (WASD e setas), rastreia a posição e a rotação do jogador, e renderiza na tela Canvas todos os elementos que necessitam de sprites, como inimigos, armas e o HUD. A fonte, por outro lado, assume a pesada carga geométrica: recebe as coordenadas do jogador, lança raios, calcula as distâncias até as paredes e retorna um array de alturas. Essencialmente, atua como uma GPU, embora extremamente peculiar e lenta. A questão crucial é como transferir dados para a fonte, que é um arquivo estático. Surpreendentemente, isso é feito através de CSS. Fontes OpenType suportam "variable fonts" (fontes variáveis) com "eixos de variação". É possível definir uma string CSS como font-variation-settings: 'MOVX' 123, 'MOVY' 456, 'TURN' 789. O navegador, então, reinicia o hinting a cada alteração. Dentro do processo de hinting, existe uma instrução especial GETVARIATION (opcode 0x91) que coloca na pilha os valores atuais de todos os eixos. Isso estabelece a comunicação entre o mundo JavaScript e o mundo da máquina de pilha.
Segurança e Ataques via Fontes
A capacidade de execução de código dentro de fontes TrueType levanta sérias preocupações de segurança. Históricamente, vulnerabilidades em parsers de fontes foram exploradas para comprometer sistemas. O caso Duqu em 2011 demonstrou como um arquivo de fonte malicioso poderia explorar falhas no kernel do Windows para obter acesso. O Google Project Zero, após um ano de fuzzing em fontes, descobriu diversas vulnerabilidades. Mais recentemente, a "Operation Triangulation" revelou ataques sofisticados que utilizavam exploits em fontes para comprometer dispositivos. Ataques "scriptless", que exploram o hinting para executar código sem a necessidade de scripts maliciosos na página, são particularmente perigosos. A defesa contra essas ameaças envolve mecanismos como o fontdrvhost.exe no Windows, que isola o processamento de fontes, e o "Untrusted Font Blocking", que impede a instalação de fontes não confiáveis. A lição fundamental é que a complexidade inerente às fontes modernas, com suas VMs e capacidades de execução, pode se tornar uma superfície de ataque significativa se não for devidamente gerenciada e protegida.
📤 Compartilhar & Baixar
🧰 Ferramentas recomendadas
Divulgação: alguns links são patrocinados. Podemos receber comissão se você comprar — sem custo extra para você. Só indicamos o que faz sentido para a comunidade.