
Cabeçalho de macros para ofuscação de C em tempo de compilação (tcc, win x86/x64)

obfus.h é uma biblioteca somente de macros para ofuscação em tempo de compilação de aplicações C, projetada especificamente para o Tiny C (tcc) (você pode baixá-lo aqui -> Tiny-C-Compiler/releases). Ela é feita para plataformas Windows x86 e x64 e suporta quase todas as versões do compilador. Uma armadura muito confiável para seus programas C!
Integrar o obfus.h ao seu projeto é um processo simples. Basta incluir a seguinte linha no seu código:
#include "obfus.h"
Isso ofuscará automaticamente seu código durante a compilação, garantindo proteção e confidencialidade da sua propriedade intelectual.
Opções disponíveis para configurar a proteção:
// Proteção avançada de código (veja a parte "Virtualização" da documentação!) #define VIRT 1 // Permite usar as funções de uma VM matemática // Opções adicionais #define CFLOW_V2 1 // Ofuscação de Fluxo de Controle mais poderosa (lenta!) #define ANTIDEBUG_V2 1 // Usa melhor proteção anti-debugging dinâmica #define FAKE_SIGNS 1 // Adiciona assinaturas falsas de vários protetores ou empacotadores // Desabilitando recursos padrão #define NO_OBF 1 // Não ofuscar (para depuração) #define NO_CFLOW 1 // Não usar ofuscação de Fluxo de Controle #define NO_ANTIDEBUG 1 // Não incorporar proteção de depuraçãoou use com argumentos do compilador:
tcc "app.c" -w -D NO_CFLOW -D ANTIDEBUG_V2 -D FAKE_SIGNS -D VIRT
[!WARNING] Ao compilar um aplicativo com ofuscação, use o argumento
-wpara suprimir avisos. Caso contrário, o console exibirá inúmeros logs intimidadores que não têm impacto no resultado final. Não há necessidade de se alarmar com eles.
🔐 A proteção de depuração é acionada por chamadas a muitas funções básicas da MSVCRT.
Em pontos críticos do código, você pode usar o construto ANTI_DEBUG;. Por exemplo:
ANTI_DEBUG;
if (!licenseExpired()) {
// ...
}
O HIDE_STRING(str) ofusca e oculta visualmente strings ao mutacioná-las, complicando significativamente sua descoberta e alteração no código-fonte. Quando declaradas dessa forma, as strings são montadas na pilha por meio de instruções mov em vez de serem carregadas todas de uma vez. Esse método garante que as strings não sejam declaradas estaticamente e, em vez disso, sejam construídas em tempo de execução, tornando-as menos suscetíveis à análise estática. No entanto, é importante observar que esse recurso não pode ser usado para ocultar campos estáticos durante sua declaração, pois envolve uma chamada de função.
[!IMPORTANT] Alguns descompiladores ainda podem revelá-las devido a otimizações estáticas. Na saída do desmontador, o código parecerá complexo e trabalhoso, o que pode desencorajar uma análise direta, mas pode não impedir completamente esforços determinados de engenharia reversa.
Um exemplo de chamada da função printf da biblioteca padrão com ocultação estática da mensagem e sua descriptografia na pilha:
char *hidden_message = HIDE_STRING("Hello, world!");
// ...
printf(hidden_message);
Esta é uma técnica de proteção na qual certos cálculos são executados por meio de uma máquina virtual embutida sob comando. Torna a análise de operações matemáticas muito difícil! Funcionará com a opção VIRT habilitada (e somente com ela!). Caso contrário, todos os comandos da máquina virtual serão substituídos por operadores matemáticos comuns.
[!WARNING] A virtualização em locais críticos pode impactar a otimização. Use com cautela apenas em áreas onde ela for realmente necessária
A máquina virtual não suporta algumas operações básicas de comparação com
double.
Você pode usar operadores lógicos que fazem chamadas à máquina virtual para complicar ainda mais a compreensão do seu código:
| Operador | Descrição |
|---|---|
VM_IF |
Isso não é uma substituição completa para if/else, mas apenas uma complicação dos operadores padrão.
Um exemplo simples de uso da virtualização:
// ...
#define VIRT 1
// ...
// if ((2 + 2) == 4) { ... }
VM_IF (VM_EQU(VM_ADD(2, 2), 4)) {
printf("2 + 2 == 4!");
}
// if (condition1) { ... }
// else if (condition2) { ... }
// else { ... }
VM_IF (condition1) {
// if
} VM_ELSE_IF (condition2) {
// else if
} VM_ELSE {
// else
}
Você pode encontrar exemplos de uso de todas as funções de uma máquina virtual no arquivo tests/virtualmachine.c
Se você precisa de proteção avançada contra reversers habilidosos, use as opções CFLOW_V2 e ANTIDEBUG_V2.
// Vamos ofuscar seu código!
#include <stdio.h>
#define VIRT 1 // [+] Usar máquina virtual matemática
#define CFLOW_V2 1 // [+] ControlFlow v2
#define FAKE_SIGNS 1 // [+] Assinaturas falsas
#define ANTIDEBUG_V2 1 // [+] AntiDebug v2
#define NO_OBF 0 // [-] Não ofuscar (desabilitar tudo)
#define NO_CFLOW 0 // [-] Desabilitar ControlFlow
#define NO_ANTIDEBUG 0 // [-] Desabilitar AntiDebug
#include "obfus.h"
void main() {
char *out = malloc(256);
strcpy(out, HIDE_STRING("Hello, world!\n"));
if (out) {
printf(out);
} else {
printf("Error!\n");
}
free(out);
int result = VM_ADD(5, 7); // 5 + 7
VM_IF (VM_EQU(result, 12)) { // (5 + 7) == 12
printf("5 + 7 == 12");
}
}
Recomenda-se o uso da versão mais recente do Tiny C (0.9.27). Infelizmente, algumas versões do compilador não suportam a funcionalidade necessária para a ofuscação completa. Visual C, GCC e Clang não são suportados e é improvável que venham a ser.
Você pode usar o script especial para Windows a fim de obter as versões mais recentes do obfus.h baixando o pacote do repositório oficial. Isso é útil se você precisar automatizar atualizações de segurança sem usar git.
Por exemplo, você pode usá-lo antes de compilar seu projeto:
+ C:\...> call obfh-update C:\...> tcc app.c -wO script atualizará o conteúdo do arquivo obfus.h no diretório atual (de acordo com a configuração especificada)
O código de um programa (e sua lógica original) protegido usando obfus.h é quase impossível de recuperar (desofuscar). No entanto, usar este ofuscador não garante proteção completa contra todos os tipos de ameaças. É importante desenvolver e manter sistemas internos de segurança no programa.
Como o código diagramático ficará após a ofuscação:
O reverser verá algo assim se tentar usar um descompilador:
É assim que todas as strings ocultas via recurso
HIDE_STRINGaparecem no desmontador (arquitetura x86-64):; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; PROTECTED STRING: ; ORIGINAL STRING: ; mov eax, 48h lea rax, aHelloWorld ; mov [rbp-0Fh], al mov r11, rax ; mov eax, 65h ; . . . ; mov [rbp-0Eh], al ; mov eax, 6Ch ; mov [rbp-0Dh], al ; mov eax, 6Ch ; mov [rbp-0Ch], al ; mov eax, 6Fh ; mov [rbp-0Bh], al ; mov eax, 2Ch ; ; etc . . . ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
Obrigado a todos que ajudaram no desenvolvimento deste projeto. Eu aprecio isso! ❤️
E obrigado a você 🤝 por prestar atenção a este projeto!
| Função | Tipo | Op | Descrição | Exemplo |
|---|
VM_ADD | long | + | Soma dois números | VM_ADD(5, 3) = 8 |
VM_SUB | long | - | Subtrai dois números | VM_SUB(5, 3) = 2 |
VM_MUL | long | * | Multiplica dois números | VM_MUL(5, 3) = 15 |
VM_DIV | long | / | Divide dois números | VM_DIV(6, 3) = 2 |
VM_MOD | long | % | Calcula o módulo de dois números | VM_MOD(5, 3) = 2 |
VM_EQU | BOOL | == | Verifica se dois números são iguais | VM_EQU(5, 5) = true |
VM_NEQ | BOOL | != | Verifica se dois números são diferentes | VM_NEQ(5, 3) = true |
VM_LSS | BOOL | < | Verifica se o primeiro número é menor que o segundo número | VM_LSS(3, 5) = true |
VM_GTR | BOOL | > | Verifica se o primeiro número é maior que o segundo número | VM_GTR(5, 3) = true |
VM_LEQ | BOOL | <= | Verifica se o primeiro número é menor ou igual ao segundo número | VM_LEQ(3, 5) = true |
VM_GEQ | BOOL | >= | Verifica se o primeiro número é maior ou igual ao segundo número | VM_GEQ(5, 3) = true |
VM_ADD_DBL | long double | + | Soma dois números double | VM_ADD_DBL(5.5, 3.2) = ≈8.7 |
VM_SUB_DBL | long double | - | Subtrai dois números double | VM_SUB_DBL(5.5, 3.2) = ≈2.3 |
VM_MUL_DBL | long double | * | Multiplica dois números double | VM_MUL_DBL(5.5, 3.2) = ≈17.6 |
VM_DIV_DBL | long double | / | Divide dois números double | VM_DIV_DBL(6.0, 3.0) = ≈2.0 |
VM_LSS_DBL | BOOL | < | Verifica se o primeiro número double é menor que o segundo número double | VM_LSS_DBL(3.5, 5.2) = true |
VM_GTR_DBL | BOOL | > | Verifica se o primeiro número double é maior que o segundo número double | VM_GTR_DBL(5.5, 3.2) = true |
Use no lugar de if |
VM_ELSE_IF | Use no lugar de else if |
VM_ELSE | Use no lugar de else |