Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
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
clr — Controllore per Lifetimes e altri tipi di raffinamento | Kitploit
Strumenti/GitHubGitHub/ityonemo/clr
Analisi StaticaAnalisi delle VulnerabilitàAnalisi del CodiceFuzzingAnalisi di BinariApprendimento e Formazione
GitHubityonemo/clr

clr

Controllore per Lifetimes e altri tipi di raffinamento

Vedi Repository
277221 giorni 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 →
Condividi

CLR

Controllore di

Lifetime e altri

Raffinamenti di tipo

per Zig

Video: https://www.youtube.com/watch?v=mf0WzTOe-40 Sponsorizza: https://buymeacoffee.com/dnautics

discuti su HN: https://news.ycombinator.com/item?id=42923829

discuti su lobste.rs: https://lobste.rs/s/9sitsj/clr_checker_for_lifetimes_other

video demo dal vivo: https://www.youtube.com/watch?v=ZY_Z-aGbYm8

Panoramica

Questo progetto crea un transpiler Zig per il compilatore Zig, che trasforma AIR (Abstract Intermediate Representation) in codice sorgente Zig che esegue analisi statica in fase di compilazione. L'analizzatore generato rileva problemi di sicurezza della memoria come use-before-assignment, use-after-free, stack pointer escapes, oltre a UB specifici di Zig come asserzioni di non-nullità, violazioni di union taggate o uso improprio di fieldParentPtr.

L'obiettivo è portare le garanzie di sicurezza della memoria a livello di Rust a Zig tramite analisi statica di AIR, senza modificare il linguaggio stesso.

CLR dipende da una versione fork del compilatore Zig (inclusa come sottomodulo in zig/) che aggiunge il supporto per instradare AIR a plugin esterni. Quando invocato con -ofmt=air -fair-out=<plugin.so>, il compilatore carica la libreria condivisa specificata e passa l'AIR generato per l'elaborazione.

Architettura orientata alla sicurezza

CLR ha lo scopo di spingere i programmi verso pattern di ciclo di vita che siano espliciti e verificabili localmente, non semplicemente riconoscere ogni programma Zig tecnicamente valido. Quando sono possibili due rappresentazioni, CLR preferisce quella che rende lo stato delle risorse visibile nel tipo e nella struttura del flusso di controllo.

Ad esempio, evita di chiudere condizionalmente un descrittore di file non opzionale:

root@kitploit:~
const file = try std.fs.cwd().openFile(path, .{});
if (should_close) {
    file.close(); // Male: file è ambiguamente aperto dopo questo ramo.
}

Preferisci rappresentare la proprietà condizionale con un optional:

root@kitploit:~
var file: ?std.fs.File = null;
if (should_open) {
    file = try std.fs.cwd().openFile(path, .{});
}

if (file) |open_file| {
    open_file.close();
}

Chiudere condizionalmente un descrittore non opzionale lascia il suo ciclo di vita ambiguo dopo il ramo. La politica prevista da CLR è di rifiutare questo pattern piuttosto che portare uno stato permanente "forse chiuso".

Lo stesso principio si applica ai puntatori allocati. Non liberare tramite un puntatore derivato:

root@kitploit:~
const allocation = try allocator.alloc(u8, size);
const payload = allocation[header_size..];
allocator.free(payload); // Male: payload non è la base dell'allocazione.

Mantieni il puntatore base dell'allocazione disponibile per la deallocazione, e usa i puntatori derivati solo per l'accesso:

root@kitploit:~
const allocation = try allocator.alloc(u8, size);
defer allocator.free(allocation);

const payload = allocation[header_size..];
use(payload);

Liberare un puntatore a campo, sottosezione o puntatore prodotto da aritmetica è rifiutato a meno che una regola interna documentata non ripristini la provenienza della base di allocazione.

Queste politiche sono rigorose per impostazione predefinita perché producono codice con cicli di vita delle risorse più semplici e revisionabili. Un futuro meccanismo di annotazione unsafe permetterà a determinati GID o operazioni di rinunciare a singole analisi. Ciò supporterà codice che accetta deliberatamente controlli più deboli in cambio di prestazioni, senza indebolire il modello predefinito per il resto del programma.

Stato

Questa è una riscrittura attiva del proof-of-concept originale basato su Elixir in Zig. L'implementazione Zig si carica come plugin del compilatore e analizza AIR direttamente.

Attualmente implementato:

  • Tracciamento dei valori non definiti (uso prima dell'assegnazione, tracciamento a livello di campo per le strutture)
  • Analisi della sicurezza della memoria (use-after-free, double-free, memory leaks, allocator mismatch, stack escapes)
  • Copertura completa dell'interfaccia std.mem.Allocator:
    • create/destroy - allocazione di un singolo elemento
    • alloc/free - allocazione di slice (incluse alignedAlloc, allocSentinel, ecc.)
    • realloc/remap - riallocazione di slice con tracciamento della vecchia slice liberata
    • dupe/dupeZ - duplicazione di slice
    • Rilevamento di allocator mismatch (liberazione con allocator sbagliato, create/destroy vs alloc/free)
    • Tipi di allocator complessi (GPA, ArenaAllocator, FixedBufferAllocator)
  • Tracciamento del ciclo di vita di ArenaAllocator:
    • init// - ciclo di vita completo dell'arena

Pianificato (vedi LIMITATIONS.md per dettagli):

  • async/await
  • Sicurezza dell'aliasing (rilevamento di riferimenti mutabili in conflitto)
  • Raffinamenti di puntatore a sorgenti multiple per provenienza di puntatore unificata o indiretta
  • Analisi degli alias dei descrittori oltre i pattern di propagazione fd attualmente coperti
  • Riepiloghi di mutazione interprocedurale/globale più completi
  • Riconoscimento dell'abbassamento di cast di allineamento
  • Sicurezza dei mutex (accoppiamento lock/unlock, rilevamento di deadlock)
  • Capacità di coercizione personalizzata (regole di raffinamento definite dall'utente)

Prerequisiti

  • Zig 0.15.2 (installazione di sistema con supporto LLVM)
  • Linux (attualmente solo Linux a causa dell'uso diretto di syscall)
  • BATS (per i test di integrazione): sudo apt install bats

Compilazione

Il compilatore Zig fornito e il plugin libclr devono essere compilati con livelli di ottimizzazione corrispondenti. Livelli di ottimizzazione non corrispondenti causeranno segfault.

root@kitploit:~
# Build the custom Zig compiler with ReleaseFast (first time only, or after submodule changes)
cd zig && zig build --zig-lib-dir lib -Doptimize=ReleaseFast && cd ..

# Build the CLR plugin with matching optimization
zig build -Doptimize=ReleaseFast

Per sviluppo/debug, usa ReleaseSafe o Debug per entrambi:

root@kitploit:~
# ReleaseSafe (with safety checks, slightly slower)
cd zig && zig build --zig-lib-dir lib -Doptimize=ReleaseSafe && cd ..
zig build -Doptimize=ReleaseSafe

# Debug (full debug info, slowest)
cd zig && zig build --zig-lib-dir lib && cd ..
zig build

Utilizzo

root@kitploit:~
# Compila un file Zig usando il backend AIR
zig/zig-out/bin/zig build-exe -fair-out=zig-out/lib/libclr.so -ofmt=air -femit-bin=output.air.zig your_file.zig

# Esegui l'analizzatore generato
zig run --dep clr -Mroot=output.air.zig -Mclr=lib/lib.zig

L'output va su stderr.

Test

root@kitploit:~
# Test unitari (codegen/DLL)
zig build test

# Test unitari (libreria runtime)
zig test lib/lib.zig

# Un file di test di integrazione specifico
bats test/integration/fd.bats

# Test di integrazione (richiede BATS)
# Predefinito a ReleaseFast; sovrascrivi con OPTIMIZE=ReleaseSafe o OPTIMIZE=Debug
./run_integration.sh

# Test manuale di un singolo file
./run_one.sh test/cases/undefined/use_before_assign.zig

Nota: I test di integrazione ricostruiscono libclr con il livello di ottimizzazione specificato (predefinito: ReleaseFast). Assicurati che il compilatore Zig fornito sia stato compilato con un livello di ottimizzazione corrispondente.

Struttura del progetto

root@kitploit:~
clr/
├── src/                     # Codice DLL/plugin (genera .air.zig)
│   ├── clr.zig              # Punto di ingresso principale del plugin CLR
│   ├── codegen.zig          # Genera codice sorgente .air.zig dalle istruzioni AIR
│   └── allocator.zig        # Wrapper allocator sicuro per DLL
├── lib/                     # Libreria di analisi runtime
│   ├── lib.zig              # Punto di ingresso della libreria
│   ├── tag.zig              # Unione AnyTag, Type, gestori di tag, invio splat
│   ├── Inst.zig             # Risultati delle istruzioni e analisi interprocedurale
│   ├── Refinements.zig      # Tipi di raffinamento (puntatore, struct, optional, ecc.)
│   ├── Analyte.zig          # Contenitore dello stato di analisi
│   ├── Context.zig          # Contesto di esecuzione (metadati, segnalazione errori)
│   └── analysis/            # Moduli di analisi
│       ├── undefined_safety.zig  # Tracciamento use-before-assign
│       ├── memory_safety.zig     # Tracciamento allocazione/liberazione
│       ├── null_safety.zig       # Controllo unwrap di optional
│       ├── variant_safety.zig    # Accesso ai campi di union taggate
│       └── fd_safety.zig         # Tracciamento dei descrittori di file
├── test/
│   ├── integration/         # Test di integrazione BATS
│   │   ├── test_helper.bash
│   │   └── *.bats
│   └── cases/               # File di input dei test (.zig)
├── zig/                     # Sottomodulo del compilatore Zig (fork strumentato)
├── build.zig                # Configurazione di compilazione
└── build.zig.zon            # Dipendenze dei pacchetti

L'idea generale

Diagramma

Zig è un linguaggio notoriamente "unsafe". La gestione della memoria è manuale, il che apre la possibilità di errori di implementazione. Mentre Zig riduce i problemi di sicurezza rispetto a C eliminando l'accesso fuori dai limiti degli array e il dereferenziamento di puntatori nulli nel codice con controlli di sicurezza, è comunque meno sicuro di Rust, che elimina use-after-free, double-free e data race tramite analisi statica.

Ispirato dal progetto MIRI di Rust, CLR esegue analisi statica sulla rappresentazione intermedia AIR di Zig per raggiungere un grado di sicurezza maggiore di quello offerto da Zig di default. A differenza di MIRI, che interpreta il MIR di Rust in un pseudo-runtime in sandbox, CLR transpila AIR in codice sorgente Zig che esegue analisi in modo statico. Nota che il codice zig di output di CLR potrebbe in linea di principio essere eseguito in fase di compilazione, ma passando attraverso un intermedio zig, produciamo un flusso logico facile da capire e da debuggare. Una persona ambiziosa potrebbe usare questo approccio generale per emettere un target di output diverso, come un linguaggio di assistenza alla dimostrazione, o rifattorizzarlo per essere eseguito interamente nel compilatore zig!

Il concetto chiave: se comunque hai bisogno di MIRI per progetti Rust attenti alla sicurezza, perché non scegliere un linguaggio più semplice e fare analisi in stile MIRI per ottenere borrow checking e altri tipi di analisi di raffinamento? Questo progetto mostra che un tale futuro è una possibilità reale per Zig.

La pipeline di compilazione di Zig è:

  1. Zig Code / AST
  2. Zig ZIR (untyped, per-file intermediate representation)
  3. Zig AIR (typed, per-function IR, reified for polymorphic functions)
  4. Compiler targets

AIR è il livello ideale per l'analisi perché è tipizzato, interpretabile come una lista "minima vitale" di istruzioni di programmazione generalizzate, e permette di estendere i tipi con metadati di raffinamento.

Per uno sguardo approfondito su come funziona AIR di Zig, vedi il post sul blog di Mitchell Hashimoto: https://mitchellh.com/zig/sema

Licenza

Licenza MIT - vedi LICENSE per i dettagli.

Scarica lo strumento
deinit
allocator
  • Allocazioni dell'arena liberate in deinit (nessun falso positivo di leak)
  • Rilevamento di use-after-deinit, double-deinit, allocazione dopo deinit
  • Mismatch tra allocator (arena vs page_allocator)
  • Tracciamento dei puntatori derivati (non è possibile liberare puntatori a campo, sottosezioni - solo allocazioni radice)
  • Sicurezza dell'aritmetica dei puntatori (blocca ptr_add/ptr_sub su puntatori a singolo elemento)
  • Sicurezza dei null (rilevamento di unwrap di optional non controllato)
  • Sicurezza delle varianti (accesso a campi di union inattivi, variante ambigua dopo rami)
  • Sicurezza di FieldParentPtr (rilevamento di recupero non valido del contenitore da puntatori a campo)
  • Analisi interprocedurale (tracciamento dei valori attraverso chiamate di funzione tramite argomenti puntatore)
  • Tracciamento dei puntatori a funzione (le chiamate indirette inviano a possibili destinatari)
  • Tracciamento dei campi di struct e union (campi puntatore, tipi annidati)
  • Tracciamento delle slice (alloc/free con regioni, derivazione di sottosezioni)
  • Supporto per union di errore (espressioni try, wrap/unwrap del payload)
  • Supporto per istruzioni switch (unione a n vie con tracciamento delle varianti)
  • Supporto per switch etichettato/dispositivo di Duff
  • Tracciamento della posizione sorgente e del nome della variabile per i messaggi di errore
  • Diramazione/flusso di controllo con unione di stato
  • Analisi dei cicli (for, while, for-else, while-else con iterazione a punto fisso)
  • Tracciamento delle variabili globali (non definite, varianti e sicurezza della memoria)
  • Tipi di dato ricorsivi (liste collegate, alberi, union ricorsive)
  • Riduzioni dei confini di stdlib per pattern comuni come std.process.args, std.mem.asBytes, std.HashMap e API di allocator/file
  • Raffinamenti privilegiati di std.HashMap con identità canonica di archiviazione metadati/chiave/valore attraverso put, get, getPtr e iterazione dei valori
  • Sicurezza dei descrittori di file:
    • tracciamento di posix.open/close/dup/dup2/socket/accept/epoll_create/pipe
    • Rilevamento di use-after-close (read/write/dup su fd chiuso)
    • Rilevamento di double-close
    • Rilevamento di leak di fd all'uscita della funzione e alla finalizzazione del modulo
    • Tracciamento degli handle locali fuori ambito in modo che gli alias ancora attivi sopprimano segnalazioni premature di leak
    • Propagazione di ritorno e aggregazione per i pattern di descrittori coperti
    • Rilevamento di argomento fd non definito (close/read/write con fd non definito)