
Obfuscador binário x64 para arquivos PE com achatamento de fluxo de controle, antidesmontagem, ofuscação de importação e mutação de instruções para dificultar a engenharia reversa.
Alcatraz é um ofuscador binário x64 capaz de ofuscar vários tipos de arquivos PE, incluindo:
Instalação: https://vcpkg.io/en/getting-started.html
asmjit: vcpkg.exe install asmjit:x64-windows
Zydis: vcpkg.exe install zydis:x64-windows
1.) Carregue um binário clicando em file no canto superior esquerdo.
2.) Adicione funções expandindo a árvore Functions. (Você pode pesquisar digitando o nome na barra de pesquisa no topo)
3.) Pressione compile (nota: ofuscar muitas funções pode levar alguns segundos)
Na demonstração a seguir, todas as funcionalidades (exceto a que está sendo demonstrada) estão desabilitadas.
Se um valor imediato é movido para um registrador, nós o ofuscamos aplicando múltiplas operações bit a bit. Vamos dar uma olhada na função popular _security_init_cookie.
Antes:
Depois:

Ao remover a estrutura organizada do programa gerada pelo compilador e colocar nosso código em novos blocos gerados, aumentamos a complexidade do programa. Vamos pegar esta função simples main como exemplo (a otimização para este programa está desabilitada):

Se colocarmos isso no IDA 7.6, o descompilador irá otimizá-la:

Agora vamos achatar seu fluxo de controle e deixar o IDA analisá-la novamente:

Como você pode ver, a complexidade aumentou bastante, embora eu mostre apenas uma pequena parte do código gerado. Se quiser saber como fica o CFG:

Se um registrador (ex.: RAX) é adicionado a outro registrador (ex.: RCX), vamos sofrer a mutação da instrução. Isso significa que a sintaxe muda, mas a semântica não.
A instrução ADD RCX, RAX pode ser mutada para:
push rax
not rax
sub rcx, rax
pop rax
sub rcx, 1
Se quiser saber mais sobre mutação, dê uma olhada em perses.
Se o arquivo PE é um .exe (suporte a .dll será adicionado), criaremos um ponto de entrada personalizado que descriptografa o ponto de entrada real na inicialização (!!! não funciona quando mapeado manualmente).

A ofuscação de LEA é bastante simples, porém eficaz. Movemos um local diferente para o registrador e o descriptografamos depois. Dessa forma, engenheiros reversos não conseguem referenciar cruzadamente certos dados/funções.
Digamos que encontramos a seguinte instrução: lea rcx, [0xDEAD]
Vamos sofrer sua mutação para:
pushf
lea rcx, [1CE54]
sub rcx, EFA7
popf
rcx -> 0xDEAD
Se encontrarmos uma instrução que começa com o byte 0xFF, colocaremos um 0xEB na frente dela.
Fazemos isso porque 0xEB 0xFF se codifica como jmp rip + 1, que no final salta para o nosso primeiro 0xFF real. Isso confundirá ferramentas que decodificam instruções de maneira linear.
Antes:

Depois:

De vez em quando podemos inserir:
jz 3
jne 1
0xE8
O IDA tentará decodificar o 0xE8 (call) mas não terá sucesso:

Não há uma ofuscação "apropriada" da IAT no momento. O truque do anti-desassemblagem 0xFF cuida disso por enquanto. A implementação adequada está planejada aqui:
iat.cpp
Este é um trecho da nossa função main com tudo ativado, exceto o anti-desassemblagem (para que o IDA possa criar uma função):
