Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
zyrox — Zyrox: plugin offuscatore basato su LLVM, a tempo di compilazione. | Kitploit
Strumenti/GitHubGitHub/peterhackz/zyrox
Analisi StaticaAnalisi del CodiceReverse EngineeringAnalisi di BinariPaper e RicercaApprendimento e FormazionePercorsi e Corsi
GitHubpeterhackz/zyrox

zyrox

Zyrox: plugin offuscatore basato su LLVM, a tempo di compilazione.

Vedi Repository
9411167 mesi faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Sito web
Condividi

Zyrox LLVM Obfuscator

plugin di compilazione e link-time di llvm per offuscare codice nativo

Perché

perché no ¯\_(ツ)_/¯

Uno dei miei progetti più grandi, in cui ho imparato molto sugli internals di LLVM, formati binari, assembly e tecniche di offuscamento.

Credo che imparare costruendo sia il modo migliore per apprendere, quindi ho creato questo progetto per imparare di più su questi argomenti.

Ricerca

Ho scritto 4 blog che spiegano i concetti alla base di Zyrox:

  • Part I: Building Zyrox: A Custom LLVM Obfuscator
  • Part II: Control Flow Flattening
  • Part III: Encrypted Jump Tables
  • Part IV: The Finale

Queste parti approfondiscono più di questo readme e valgono sicuramente una lettura se sei interessato all'argomento.

Compilazione

Dal Template (Avvio Rapido, Consigliato)

Questo è pensato per chi vuole testare rapidamente Zyrox, o imparare come integrarlo in un progetto cmake.

Segui i passaggi nel repo Zyrox Template.

Dal Sorgente

installa llvm:

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

clona e compila 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

Configurazione del Plugin Python (Post-Compilazione)

assicurati di avere python3 e pip installati.

Configura un Ambiente (Consigliato)

# Create a virtual environment
python3 -m venv .venv

# Activate the env
source .venv/bin/activate

pip install -r requirements.txt

Installazione Globale

pip install -r requirements.txt

Utilizzo

Utilizzo Rapido

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

Dopo l'offuscamento, esegui PyPlugin.py per cifrare le jump table:

# 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]

Con CMake

Dai un'occhiata al repo Zyrox Template per un esempio di integrazione CMake.

Contatti

Capisco che sia un argomento complesso, e questo progetto è stato principalmente per scopi educativi, oltre che per servire BSD Brawl. Se hai domande, o vuoi semplicemente fare due chiacchiere, sentiti libero di contattarmi:

  • Discord: @s.b
  • Email: [email protected] o [email protected]
  • Discord Server

qualsiasi aiuto, tramite pull request o issue, è apprezzato!

Come funziona

ZyroxPlugin.cpp registra il pass, poi collega siphash (ne parleremo più avanti) e chiama StringEncryption per cifrare le stringhe.

Il motivo per cui cifriamo le stringhe subito è così che anche la logica di decifratura venga offuscata in seguito.

poi chiama ModuleUtils::ExpandCustomAnnotations e QuickConfig::RegisterPasses per fare il parsing di tutte le espressioni __attribute__((annotate("..."))) ed eseguire la config QuickJs (situata in ZyroxConfig.js)

Ogni funzione viene offuscata chiamando Zyrox::RunOnFunction situata in ZyroxCore.cpp; ulteriore documentazione a riguardo verrà fornita in futuro.

Utility Extra

gli switch creano jump table e i nodi PHI sono fastidiosi da gestire, quindi usiamo FunctionUtils e BasicBlockUtils per appiattirli (in istruzioni if) e declassarli rispettivamente.

Pass

oh cavolo, da dove comincio

  • Basic Block Splitter
  • Control Flow Flattening
  • Indirect Branching
  • Simple Indirect Branching
  • Mixed Boolean Arithmetic

tutti gli argomenti del plugin js sono in index.d.ts, quindi non verranno trattati in questa documentazione.

per la documentazione sulle annotazioni, clicca qui

Basic Block Splitter

Questo pass divide e mescola un basic block in blocchi più piccoli. Supponiamo di avere questo:

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;
}

che viene compilato in:

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
}

quando si usa Basic Block Splitter con questa config:

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

diventa:

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
}

ora non sarà molto diverso per una funzione così piccola, ma nota come ha diviso un basic block?

questo è utile se combinato con altri pass come Control Flow Flattening

Control Flow Flattening

Oh, cavolo, questo pass ha il maggior numero di funzionalità tra tutti lol. Inizierò spiegando come funziona, poi la sua config. Supponiamo di avere questo codice:

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

a ogni basic block (A, B e C) viene assegnato uno stato univoco del dispatcher, esempio: (semplificato)

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

poi iniettiamo un blocco dispatcher che controlla tutto e il codice diventa:

Scarica lo strumento