O que é obfuscated code, opções e exemplos [parte 1]

Eu inicialmente escrevi esse artigo em https://www.anom.ia.br/o-que-e-obfuscated-code/. Eu recomendo primeiro ler meu post original e depois voltar para ler o restante aqui, podendo pular direto para o exemplos.

Em programação, obfuscated code — ou código ofuscado — é o código escrito de forma difícil de entender. Ele pode executar uma tarefa simples, mas faz isso de maneira tão confusa, compacta ou criativamente distorcida que até programadores experientes têm dificuldade para decifrar o que está acontecendo.

Escrever código ofuscado é, de certo modo, o oposto do que se ensina em engenharia de software, onde busca-se clareza, legibilidade e manutenibilidade. Embora pareça apenas uma brincadeira, o estudo do código ofuscado revela um domínio profundo da linguagem de programação e do compilador.

No fundo, o obfuscated code é uma forma de poesia técnica. Ele transforma o código em um enigma, convida à decodificação e desafia nossa ideia do que é “beleza” em programação. Não é útil no sentido tradicional, mas é uma celebração da criatividade, da curiosidade e do domínio técnico.

Começando com um exemplo

Abaixo vai um exemplo pequeno de obfuscated code em C que imprime “Hello, world!”. O código é intencionalmente escrito de forma pouco direta (macros com token-pasting, escapes octais para letras, loop compacto) mas continua perfeitamente funcional. Depois do código segue uma explicação em prosa, sem bullets.

#include <stdio.h>
#define _(a,b) a##b
#define P _(p,utchar)

int main(void) {
    char *s = "H\145llo, w\157rld!\n";
    for (int i = 0; s[i]; ++i) P(s[i]);
    return 0;
}

Abaixo explico o que cada parte do programa faz, como o pré-processador transforma os símbolos e quais truques de C estão sendo explorados:

  • Linha 2: Aqui é definida uma macro chamada _ que recebe dois parâmetros, a e b. O operador ## no pré-processador é o token-pasting operator: ele concatena os dois tokens fornecidos. Por exemplo, _(p,utchar) vira p##utchar e, após a concatenação, o pré-processador produz o token único putchar. Usar _ como nome de macro é válido, embora pouco legível.
  • Linha 3: Esta linha define outra macro P que expande para _(p,utchar). Aplicando a expansão recursivamente, _(p,utchar) é substituído pelo resultado do a##b, isto é, putchar. Em resumo, a macro P acaba sendo um apelido (obscuro) para a função putchar.
  • Linha 6: Aqui está um truque de ofuscação: a string parece estranha por conter escapes octais. \145 e \157 são escapes octais que representam caracteres ASCII. Calculando cada escape:
    • \145 em octal = 1×64 + 4×8 + 5 = 64 + 32 + 5 = 101 decimal → caractere ASCII 101 = 'e'.
    • \157 em octal = 1×64 + 5×8 + 7 = 64 + 40 + 7 = 111 decimal → caractere ASCII 111 = 'o'.
    • Portanto a string literal é, na prática, exatamente "Hello, world!\n". O \n é o escape de nova linha.
  • Linha 7: O for faz duas coisas compactas em uma linha:
    • A condição de continuação é s[i]: Em C, em contexto condicional, isso é equivalente a s[i] != '\0', ou seja, o laço continua enquanto o caractere atual não for o terminador nulo da string.
    • O corpo do for é uma única expressão: P(s[i]): Por expansão das macros, P_(p,utchar)putchar. Assim, P(s[i]) equivale a putchar(s[i]) — imprime o caractere s[i] no stdout. Em outras palavras: o for varre a string s e imprime caractere por caractere.

Se expandirmos as macros e resolvermos os escapes, o programa é conceitualmente equivalente ao código abaixo.

#include <stdio.h>

int main(void) {
    char *s = "Hello, world!\n";
    for (int i = 0; s[i]; ++i)
        putchar(s[i]);
    return 0;
}

Uma continuação deste post, com aprofundamento dos itens apresentados está disponível em https://www.galirows.com.br/meublog/blog/o-que-e-obfuscated-code-parte2/

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.