Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
zyrox — Zyrox: plugin de ofuscação em tempo de compilação baseado em LLVM. | Kitploit
Ferramentas/GitHubGitHub/peterhackz/zyrox
Análise EstáticaAnálise de CódigoEngenharia ReversaAnálise de BináriosPapers e PesquisaAprendizado e EducaçãoTrilhas e Cursos
GitHubpeterhackz/zyrox

zyrox

Zyrox: plugin de ofuscação em tempo de compilação baseado em LLVM.

Ver Repositório
941115há 7 mesesRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Site
Compartilhar

Ofuscador LLVM Zyrox

plugin de compilação e link-time do LLVM para ofuscar código nativo

Porquê

por que não ¯\_(ツ)_/¯

Um dos meus maiores projetos, onde aprendi muito sobre os internos do LLVM, formatos binários, assembly e técnicas de ofuscação.

Acredito que aprender construindo é a melhor forma de aprender, portanto construí este projeto para aprender mais sobre esses tópicos.

Pesquisa

Escrevi 4 blogs explicando os conceitos por trás do Zyrox:

  • Parte I: Construindo Zyrox: Um Ofuscador LLVM Personalizado
  • Parte II: Achatamento de Fluxo de Controle
  • Parte III: Tabelas de Salto Criptografadas
  • Parte IV: O Final

Essas partes vão mais fundo que este README e definitivamente valem a leitura se você está interessado no tópico.

Compilando

A partir do Template (Início Rápido, Recomendado)

Isso é destinado a quem deseja testar rapidamente o Zyrox, ou aprender como integrá-lo em um projeto cmake.

Siga os passos no repositório Zyrox Template.

A partir do Código Fonte

instale o llvm:

sudo apt update
sudo apt install llvm-18 llvm-18-dev clang-18

clone e compile o zyrox:

git clone --recurse-submodules https://github.com/PeterHackz/zyrox.git
cd zyrox
cmake -S . -B build -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++
cmake --build build --parallel 4

Configuração do Plugin Python (Pós-Compilação)

certifique-se de ter python3 e pip instalados.

Configurar um Ambiente (Recomendado)

# Create a virtual environment
python3 -m venv .venv

# Activate the env
source .venv/bin/activate

pip install -r requirements.txt

Instalar Globalmente

pip install -r requirements.txt

Uso

Uso Rápido

clang -O0 -flto=full -c main.c -o out/main.o
clang -flto=full -fuse-ld=lld -Wl,--load-pass-plugin=./build/libzyrox.so out/main.o -o out/main

Após a ofuscação, execute PyPlugin.py para criptografar as tabelas de salto:

# if you installed dependencies in a virtual environment, activate it first:
source .venv/bin/activate
#  then run with:
python PyPlugin.py --in=<input_file> [--out=<output_file>] [--tables=<zyrox_tables_file>] [--android]

Com CMake

Confira o repositório Zyrox Template para um exemplo de integração com CMake.

Contatos

Eu entendo que este é um tópico complexo, e este projeto foi principalmente para fins educacionais, além de servir ao BSD Brawl. Se você tiver alguma dúvida, ou apenas quiser conversar, sinta-se à vontade para entrar em contato comigo:

  • Discord: @s.b
  • E-mail: [email protected] ou [email protected]
  • Servidor Discord

qualquer ajuda, através de pull requests ou issues, é apreciada!

Como funciona

ZyroxPlugin.cpp registra o pass, então linka siphash (mais sobre isso depois) e chama StringEncryption para criptografar strings.

A razão de criptografarmos strings cedo é para que a lógica de descriptografia também seja ofuscada depois.

então ele chama ModuleUtils::ExpandCustomAnnotations e QuickConfig::RegisterPasses para analisar todas as expressões __attribute__((annotate("..."))) e executar a configuração do QuickJs (localizada em ZyroxConfig.js)

Toda função é ofuscada chamando Zyrox::RunOnFunction localizada em ZyroxCore.cpp, mais documentação sobre isso será fornecida no futuro.

Utilitário Extra

switches criam tabelas de salto e nós PHI são irritantes de lidar, portanto usamos FunctionUtils e BasicBlockUtils para achatar (em ifs) e rebaixar estes respectivamente.

Passes

oh cara, por onde eu começo

  • Divisor de Bloco Básico
  • Achatamento de Fluxo de Controle
  • Ramificação Indireta
  • Ramificação Indireta Simples
  • Aritmética Booleana Mista

todos os argumentos do plugin js estão em index.d.ts então não serão abordados nesta documentação.

para documentação de anotações, clique aqui

Divisor de Bloco Básico

Este pass divide e embaralha um bloco básico em blocos menores. Suponha que temos isto:

int __test_fn(int x)
{
    if (x == 2) {
        printf("x is 2\n");
    } else {
        printf("x is not 2!, x is: %d\n", x);
    }
    return x + 4 * x - 2 / 4;
}

que é compilado para:

define internal i32 @__test_fn(i32 noundef %0) #0 !zyrox !8 !obfuscated !11 {
  %2 = alloca i32, align 4
  store i32 %0, ptr %2, align 4
  %3 = load i32, ptr %2, align 4
  %4 = icmp eq i32 %3, 2
  br i1 %4, label %5, label %7

5:                                                ; preds = %1
  %6 = call i32 (ptr, ...) @printf(ptr noundef @.str.1)
  br label %10

7:                                                ; preds = %1
  %8 = load i32, ptr %2, align 4
  %9 = call i32 (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef %8)
  br label %10

10:                                               ; preds = %7, %5
  %11 = load i32, ptr %2, align 4
  %12 = load i32, ptr %2, align 4
  %13 = mul nsw i32 4, %12
  %14 = add nsw i32 %11, %13
  %15 = sub nsw i32 %14, 0
  ret i32 %15
}

ao usar o Divisor de Bloco Básico com esta configuração:

z.RegisterPass(ObfuscationType.BasicBlockSplitter, {
    PassIterations: 1,
    "BasicBlockSplitter.SplitBlockChance": 100,
    "BasicBlockSplitter.SplitBlockMinSize": 2,
    "BasicBlockSplitter.SplitBlockMaxSize": 5,
});

torna-se:

define internal i32 @__test_fn(i32 noundef %0) #0 !zyrox !8 !obfuscated !11 {
  %2 = alloca i32, align 4
  store i32 %0, ptr %2, align 4
  %3 = load i32, ptr %2, align 4
  %4 = icmp eq i32 %3, 2
  br i1 %4, label %5, label %14

5:                                                ; preds = %1
  %6 = call i32 (ptr, ...) @printf(ptr noundef @.str.1)
  br label %7

7:                                                ; preds = %14, %5
  %8 = load i32, ptr %2, align 4
  %9 = load i32, ptr %2, align 4
  %10 = mul nsw i32 4, %9
  %11 = add nsw i32 %8, %10
  br label %12

12:                                               ; preds = %7
  %13 = sub nsw i32 %11, 0
  ret i32 %13

14:                                               ; preds = %1
  %15 = load i32, ptr %2, align 4
  %16 = call i32 (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef %15)
  br label %7
}

agora não será tão diferente para uma função tão pequena, mas note como ele dividiu um bloco básico? isso é útil combinado com outros passes como Achatamento de Fluxo de Controle

Achatamento de Fluxo de Controle

Oh, cara, este pass tem mais recursos entre todos, lol. Vou começar explicando como funciona e depois sua configuração. Suponha que temos este código:

LABEL_A: bool b = x == 2;
         IF EQ: goto LABEL_B
         goto LABEL_C
LABEL_B  do_stuff()
LABEL_C  do_other_stuff()
         goto LABEL_A

cada bloco básico (A, B e C) recebe um estado de despacho único, exemplo: (simplificado)

states = {
    1: LABEL_A,
    2: LABEL_B,
    3: LABEL_C,
};

então injetamos um bloco de despacho que controla tudo e o código se torna:

Baixar ferramenta