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,aeb. O operador##no pré-processador é o token-pasting operator: ele concatena os dois tokens fornecidos. Por exemplo,_(p,utchar)virap##utchare, após a concatenação, o pré-processador produz o token únicoputchar. Usar_como nome de macro é válido, embora pouco legível. - Linha 3: Esta linha define outra macro
Pque expande para_(p,utchar). Aplicando a expansão recursivamente,_(p,utchar)é substituído pelo resultado doa##b, isto é,putchar. Em resumo, a macroPacaba sendo um apelido (obscuro) para a funçãoputchar. - Linha 6: Aqui está um truque de ofuscação: a string parece estranha por conter escapes octais.
\145e\157são escapes octais que representam caracteres ASCII. Calculando cada escape:\145em octal = 1×64 + 4×8 + 5 = 64 + 32 + 5 = 101 decimal → caractere ASCII 101 ='e'.\157em 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
forfaz duas coisas compactas em uma linha:- A condição de continuação é
s[i]: Em C, em contexto condicional, isso é equivalente as[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 aputchar(s[i])— imprime o caracteres[i]nostdout. Em outras palavras: oforvarre a stringse imprime caractere por caractere.
- A condição de continuação é
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/