# Use After Free

### **📋 Índice**

1. Fundamentos do Use-After-Free
2. Mecanismos de Criação
3. Heap Internals e Allocators
4. Técnicas de Exploração
5. Heap Spray e Feng Shui
6. Vetores de Ataque
7. Ferramentas de Detecção
8. Impacto e Consequências
9. Prevenção e Mitigações
10. Checklists de Segurança

***

### 🔍 **Fundamentos do Use-After-Free**

#### **O que é Use-After-Free?**

**Use-After-Free (UAF)** é uma vulnerabilidade de corrupção de memória que ocorre quando um programa continua a usar um ponteiro após a memória apontada ter sido liberada (freed). Isso pode levar a crashes, corrupção de dados ou, em casos mais graves, execução de código arbitrário.

#### **Princípio de Funcionamento**

```mermaid
sequenceDiagram
    participant P as Programa
    participant H as Heap

    Note over P,H: 1. Alocação
    P->>H: malloc(100)
    H-->>P: ptr = 0x1000
    
    Note over P,H: 2. Uso normal
    P->>H: escreve em 0x1000
    
    Note over P,H: 3. Liberação
    P->>H: free(0x1000)
    Note over H: Memória liberada
    
    Note over P,H: 4. Reutilização da memória
    P->>H: malloc(100)
    H-->>P: ptr2 = 0x1000 (mesmo endereço!)
    
    Note over P,H: 5. Uso do ponteiro antigo (UAF!)
    P->>H: escreve via ptr (dangling)
    Note over H: Corrupção de dados
    
    Note over P: 6. Consequências
    P->>P: Comportamento indefinido
```

#### **Exemplo Clássico**

```c
// use_after_free_example.c - Exemplo básico de UAF

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    void (*func_ptr)(void);
    char buffer[64];
} object_t;

void legitimate_function() {
    printf("[*] Legitimate function called\n");
}

void malicious_function() {
    printf("[!] Malicious function called - Code execution!\n");
}

int main() {
    // 1. Alocar objeto
    object_t *obj = (object_t *)malloc(sizeof(object_t));
    obj->func_ptr = legitimate_function;
    strcpy(obj->buffer, "Important data");
    
    printf("[+] Object allocated at %p\n", obj);
    printf("    Function pointer: %p\n", obj->func_ptr);
    
    // 2. Liberar objeto (cria dangling pointer)
    free(obj);
    printf("[+] Object freed at %p (dangling pointer)\n", obj);
    
    // 3. Outra alocação pode reutilizar o mesmo endereço
    object_t *obj2 = (object_t *)malloc(sizeof(object_t));
    printf("[+] New object allocated at %p\n", obj2);
    
    if (obj == obj2) {
        printf("[!] Memory reused! Same address: %p\n", obj);
        
        // 4. Atacante controla o conteúdo
        obj2->func_ptr = malicious_function;
        printf("[+] New object's function pointer set to malicious\n");
        
        // 5. UAF! Usando ponteiro antigo
        printf("[*] Using dangling pointer...\n");
        obj->func_ptr();  // 💥 Executa código malicioso!
    }
    
    free(obj2);
    return 0;
}
```

***

### ⚙️ **Mecanismos de Criação**

#### **Causas Comuns de UAF**

```python
#!/usr/bin/env python3
# uaf_causes.py - Causas de Use-After-Free

class UAFCauses:
    """Análise das causas de Use-After-Free"""
    
    @staticmethod
    def missing_null():
        """Falta de NULL após free"""
        print("🔴 Missing NULL after free")
        print("=" * 60)
        
        print("""
Código vulnerável:
  char *ptr = malloc(100);
  free(ptr);
  // ptr não é setado para NULL
  // ptr continua sendo dangling pointer
  if (ptr) {  // 🔴 Não funciona! ptr não é NULL
      strcpy(ptr, "data");  // UAF!
  }

Correto:
  char *ptr = malloc(100);
  free(ptr);
  ptr = NULL;  // ✅ Previne uso acidental
""")
    
    @staticmethod
    def multiple_frees():
        """Double free"""
        print("\n🔴 Double Free")
        print("=" * 60)
        
        print("""
Código vulnerável:
  char *ptr = malloc(100);
  free(ptr);
  free(ptr);  // 🔴 Double free!
  // A segunda liberação corrompe o allocator

Consequências:
  • Corrupção da freelist
  • Alocações arbitrárias
  • Possível execução de código
""")
    
    @staticmethod
    def use_after_realloc():
        """Uso após realloc"""
        print("\n🔴 Use After realloc")
        print("=" * 60)
        
        print("""
Código vulnerável:
  char *ptr = malloc(100);
  char *old_ptr = ptr;
  
  ptr = realloc(ptr, 1000);  // Pode mover o bloco
  // old_ptr agora pode ser dangling!
  strcpy(old_ptr, "data");  // 🔴 UAF se realloc moveu

Correto:
  // Sempre usar o novo ponteiro retornado
  // Não manter cópias antigas
""")
    
    @staticmethod
    def container_uaf():
        """UAF em containers"""
        print("\n🔴 Container Use-After-Free")
        print("=" * 60)
        
        print("""
Código vulnerável:
  vector<object*> vec;
  vec.push_back(new object());
  
  delete vec[0];
  // 🔴 vec[0] ainda contém o ponteiro!
  vec[0]->method();  // UAF!

Correto:
  delete vec[0];
  vec[0] = NULL;
  // ou usar smart pointers (unique_ptr/shared_ptr)
""")

# Executar
UAFCauses.missing_null()
UAFCauses.multiple_frees()
UAFCauses.use_after_realloc()
UAFCauses.container_uaf()
```

#### **Exemplo Complexo: UAF em C++**

```cpp
// uaf_cpp_example.cpp - UAF em C++

#include <iostream>
#include <vector>
#include <memory>

class Vulnerable {
public:
    Vulnerable() : data(new int(42)) {
        std::cout << "Vulnerable created at " << this << std::endl;
    }
    
    ~Vulnerable() {
        delete data;
        std::cout << "Vulnerable destroyed at " << this << std::endl;
    }
    
    void use() {
        if (data) {
            std::cout << "Data: " << *data << std::endl;
        } else {
            std::cout << "Data is null!" << std::endl;
        }
    }
    
    void set_data(int value) {
        if (data) {
            *data = value;
        }
    }
    
private:
    int *data;
};

// 1. UAF com ponteiros brutos
void raw_pointer_uaf() {
    Vulnerable *v = new Vulnerable();
    v->use();
    
    delete v;
    // v agora é dangling pointer
    
    // 🔴 UAF!
    v->use();  // Comportamento indefinido
}

// 2. UAF em vector
void vector_uaf() {
    std::vector<Vulnerable*> vec;
    vec.push_back(new Vulnerable());
    vec.push_back(new Vulnerable());
    
    delete vec[0];
    // 🔴 vec[0] ainda contém ponteiro!
    
    // UAF!
    vec[0]->use();
    
    // Limpeza correta
    for (auto ptr : vec) {
        delete ptr;
    }
}

// 3. Evitando UAF com smart pointers
void smart_pointer_safe() {
    std::unique_ptr<Vulnerable> uptr = std::make_unique<Vulnerable>();
    uptr->use();
    // unique_ptr libera automaticamente
    
    std::shared_ptr<Vulnerable> sptr = std::make_shared<Vulnerable>();
    sptr->use();
    // shared_ptr gerencia automaticamente
}

int main() {
    std::cout << "=== Raw Pointer UAF ===" << std::endl;
    raw_pointer_uaf();
    
    std::cout << "\n=== Vector UAF ===" << std::endl;
    vector_uaf();
    
    std::cout << "\n=== Smart Pointer Safe ===" << std::endl;
    smart_pointer_safe();
    
    return 0;
}
```

***

### 🏗️ **Heap Internals e Allocators**

#### **Estrutura do Heap (glibc malloc)**

```c
// heap_internals.c - Internals do heap

#include <stdio.h>
#include <stdlib.h>

// Estrutura de chunk no glibc
struct malloc_chunk {
    size_t mchunk_prev_size;  // Tamanho do chunk anterior
    size_t mchunk_size;        // Tamanho deste chunk
    struct malloc_chunk *fd;   // Forward pointer (free list)
    struct malloc_chunk *bk;   // Backward pointer (free list)
};

void analyze_heap() {
    printf("Estrutura do chunk alocado:\n");
    printf("  +------------------+\n");
    printf("  | prev_size        | <- tamanho do chunk anterior\n");
    printf("  +------------------+\n");
    printf("  | size             | <- tamanho + flags\n");
    printf("  +------------------+\n");
    printf("  | user data        | <- dados do usuário\n");
    printf("  | ...              |\n");
    printf("  +------------------+\n\n");
    
    printf("Estrutura do chunk livre:\n");
    printf("  +------------------+\n");
    printf("  | prev_size        |\n");
    printf("  +------------------+\n");
    printf("  | size             |\n");
    printf("  +------------------+\n");
    printf("  | fd               | <- forward pointer\n");
    printf("  +------------------+\n");
    printf("  | bk               | <- backward pointer\n");
    printf("  +------------------+\n");
}

// Exemplo de como UAF afeta freelist
void freelist_corruption() {
    printf("\nExemplo de corrupção de freelist via UAF:\n");
    
    // Alocar dois chunks
    char *a = malloc(64);
    char *b = malloc(64);
    
    printf("a = %p\n", a);
    printf("b = %p\n", b);
    
    // Liberar a
    free(a);
    
    // UAF: modificar fd pointer do chunk livre
    // (em um exploit real, isso seria feito via overflow)
    *(void **)a = (void *)0x41414141;
    
    // Próxima alocação retorna endereço controlado
    char *c = malloc(64);
    printf("c = %p (controlado pelo atacante)\n", c);
}

int main() {
    analyze_heap();
    freelist_corruption();
    return 0;
}
```

#### **Allocators e suas Vulnerabilidades**

```yaml
Allocators e Vulnerabilidades UAF:

  ptmalloc2/glibc:
    - tcache poisoning (glibc >= 2.26)
    - fastbin dup
    - unsorted bin attack
    - large bin attack

  jemalloc (FreeBSD, Android):
    - tcache como ptmalloc2
    - run-length encoding
    - quarantine para UAF

  tcmalloc (Google):
    - thread-local caches
    - page heaps
    - central free list

  mimalloc (Microsoft):
    - segmented heaps
    - free list sharding
    - menos vulnerável a UAF clássico
```

***

### 🔧 **Técnicas de Exploração**

#### **tcache Poisoning (glibc >= 2.26)**

```c
// tcache_poisoning.c - Exploração de tcache poisoning

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
tcache poisoning: corromper o ponteiro 'next' de um chunk
na tcache para obter alocação arbitrária.
*/

int main() {
    printf("[*] tcache poisoning exploit\n");
    printf("=" * 60);
    
    // 1. Alocar 7 chunks (tcache max count)
    void *chunks[7];
    for (int i = 0; i < 7; i++) {
        chunks[i] = malloc(0x80);
        printf("chunk[%d] = %p\n", i, chunks[i]);
    }
    
    // 2. Liberar chunks (entram na tcache)
    for (int i = 0; i < 7; i++) {
        free(chunks[i]);
    }
    printf("[+] 7 chunks freed, tcache full\n");
    
    // 3. Alocar um chunk para obter o primeiro da tcache
    void *victim = malloc(0x80);
    printf("[+] victim = %p\n", victim);
    
    // 4. Liberar o victim (entra na tcache novamente)
    free(victim);
    
    // 5. 🔴 Sobrescrever o ponteiro 'next' do chunk na tcache
    // (em um exploit real, isso seria feito via buffer overflow)
    void *target_address = (void *)0x41414141;  // Endereço alvo
    memcpy(victim, &target_address, sizeof(void*));
    printf("[+] tcache->next overwritten with %p\n", target_address);
    
    // 6. Próxima alocação retorna endereço controlado!
    void *malicious = malloc(0x80);
    printf("[!] malicious = %p (controlled by attacker!)\n", malicious);
    
    return 0;
}
```

#### **Fastbin Dup (glibc < 2.26)**

```c
// fastbin_dup.c - Exploração de fastbin double free

#include <stdio.h>
#include <stdlib.h>

/*
fastbin dup: double free em fastbin para obter alocação arbitrária
*/

int main() {
    printf("[*] fastbin dup exploit\n");
    printf("=" * 60);
    
    // 1. Alocar chunk no fastbin (tamanho <= 128 bytes)
    void *a = malloc(0x40);
    void *b = malloc(0x40);
    printf("a = %p\n", a);
    printf("b = %p\n", b);
    
    // 2. Liberar a
    free(a);
    printf("[+] a freed\n");
    
    // 3. 🔴 Double free de a!
    free(a);  // Double free!
    printf("[+] a double freed (fastbin dup)\n");
    
    // 4. Alocar novamente - retorna a
    void *c = malloc(0x40);
    printf("c = %p\n", c);
    
    // 5. Alocar novamente - retorna a novamente!
    void *d = malloc(0x40);
    printf("d = %p (same as a!)\n", d);
    
    if (c == d) {
        printf("[!] Fastbin dup successful! Multiple allocations at same address\n");
    }
    
    return 0;
}
```

#### **UAF em C++ com Virtual Functions**

```cpp
// uaf_vtable.cpp - UAF explorando vtable

#include <iostream>
#include <cstring>

class Base {
public:
    virtual void func1() { std::cout << "Base::func1" << std::endl; }
    virtual void func2() { std::cout << "Base::func2" << std::endl; }
    virtual ~Base() {}
};

class Derived : public Base {
public:
    virtual void func1() override { std::cout << "Derived::func1" << std::endl; }
    virtual void func2() override { std::cout << "Derived::func2" << std::endl; }
};

class Malicious {
public:
    void fake_func1() { std::cout << "[!] Malicious code executed!" << std::endl; }
    void fake_func2() { /* shellcode */ }
    
    void* vtable[2];  // Fake vtable
};

int main() {
    // 1. Criar objeto
    Base *obj = new Derived();
    obj->func1();  // Chama Derived::func1
    
    std::cout << "[+] Object created at " << obj << std::endl;
    
    // 2. Liberar objeto (UAF)
    delete obj;
    std::cout << "[+] Object freed (dangling pointer)" << std::endl;
    
    // 3. Criar objeto malicioso no mesmo endereço
    Malicious *mal = new Malicious();
    
    // Configurar fake vtable
    mal->vtable[0] = (void*)&Malicious::fake_func1;
    mal->vtable[1] = (void*)&Malicious::fake_func2;
    
    std::cout << "[+] Malicious object at " << mal << std::endl;
    
    if ((void*)obj == (void*)mal) {
        std::cout << "[!] Same address! Memory reused" << std::endl;
        
        // 4. UAF! Usando ponteiro antigo
        // A vtable foi substituída pela fake vtable
        obj->func1();  // 💥 Executa código malicioso!
    }
    
    delete mal;
    return 0;
}
```

#### **UAF em Kernel (exemplo)**

```c
// kernel_uaf.c - UAF em módulo de kernel

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/string.h>

struct vulnerable_object {
    void (*callback)(void);
    char data[64];
};

struct vulnerable_object *global_obj = NULL;

// Função legítima
void legit_callback(void) {
    printk(KERN_INFO "Legitimate callback\n");
}

// Função maliciosa (payload)
void malicious_callback(void) {
    printk(KERN_INFO "[!] Malicious callback - Privilege escalation!\n");
    // commit_creds(prepare_kernel_cred(0));
}

// Função que cria objeto
int create_object(void) {
    if (global_obj)
        return -EBUSY;
    
    global_obj = kmalloc(sizeof(struct vulnerable_object), GFP_KERNEL);
    if (!global_obj)
        return -ENOMEM;
    
    global_obj->callback = legit_callback;
    strcpy(global_obj->data, "Important data");
    
    return 0;
}

// 🔴 Função que libera objeto (cria dangling pointer)
int delete_object(void) {
    if (!global_obj)
        return -ENOENT;
    
    kfree(global_obj);
    // 🔴 global_obj não é setado para NULL!
    return 0;
}

// 🔴 Função que usa objeto (UAF!)
int use_object(void) {
    if (!global_obj)  // Não funciona! global_obj não é NULL
        return -ENOENT;
    
    global_obj->callback();  // 💥 UAF!
    return 0;
}

// Função que reutiliza a memória
int reuse_memory(void) {
    char *ptr = kmalloc(sizeof(struct vulnerable_object), GFP_KERNEL);
    if (!ptr)
        return -ENOMEM;
    
    // Sobrescrever com payload malicioso
    struct vulnerable_object *fake = (struct vulnerable_object *)ptr;
    fake->callback = malicious_callback;
    
    return 0;
}

static int __init init_module(void) {
    printk(KERN_INFO "Vulnerable module loaded\n");
    create_object();
    return 0;
}

static void __exit cleanup_module(void) {
    printk(KERN_INFO "Vulnerable module unloaded\n");
    if (global_obj)
        kfree(global_obj);
}

module_init(init_module);
module_exit(cleanup_module);
MODULE_LICENSE("GPL");
```

***

### 🌊 **Heap Spray e Feng Shui**

#### **Técnicas de Heap Spray**

```python
#!/usr/bin/env python3
# heap_spray_techniques.py - Técnicas de heap spray

import ctypes
import mmap
import sys

class HeapSpray:
    """Técnicas de heap spray para exploração de UAF"""
    
    @staticmethod
    def spray_with_allocations(count=1000, size=1024):
        """Spray com múltiplas alocações"""
        print(f"[*] Heap spray: {count} alocações de {size} bytes")
        
        allocations = []
        for i in range(count):
            # Alocar memória
            buf = ctypes.create_string_buffer(size)
            # Preencher com padrão
            pattern = bytes([i % 256]) * size
            buf.value = pattern
            allocations.append(buf)
        
        print(f"[+] {len(allocations)} alocações realizadas")
        return allocations
    
    @staticmethod
    def spray_with_jit(size=1024*1024):
        """Spray via JIT (páginas executáveis)"""
        print(f"[*] JIT spray: {size} bytes")
        
        # Alocar memória executável
        exec_mem = mmap.mmap(-1, size, 
                             mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC,
                             mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE)
        
        # Preencher com NOP sled + shellcode
        nop = b'\x90' * (size - 1024)
        shellcode = b'\x31\xc0\xb0\x3b...'  # execve shellcode
        exec_mem.write(nop + shellcode)
        
        print(f"[+] JIT spray at {hex(mmap.PAGESIZE)}")
        return exec_mem
    
    @staticmethod
    def spray_with_objects(count=1000):
        """Spray com objetos em linguagens gerenciadas"""
        print(f"[*] Object spray: {count} objetos")
        
        # Em JavaScript, ActionScript, etc.
        objects = []
        for i in range(count):
            obj = {
                'index': i,
                'data': 'A' * 1024,
                'vtable': 0x41414141
            }
            objects.append(obj)
        
        print(f"[+] {len(objects)} objetos criados")
        return objects

# Uso
if __name__ == "__main__":
    print("🌊 Heap Spray Techniques")
    print("=" * 60)
    
    allocations = HeapSpray.spray_with_allocations(100, 4096)
    HeapSpray.spray_with_jit()
    HeapSpray.spray_with_objects(100)
```

#### **Heap Feng Shui**

```c
// heap_feng_shui.c - Técnicas de heap feng shui

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
Heap Feng Shui: controlar o layout do heap para
facilitar a exploração de UAF.
*/

// 1. Hole drilling - criar buracos no heap
void hole_drilling() {
    void *holes[10];
    
    // Criar buracos de tamanhos específicos
    for (int i = 0; i < 10; i++) {
        holes[i] = malloc(0x80);
    }
    
    // Liberar buracos em ordem específica
    for (int i = 0; i < 10; i += 2) {
        free(holes[i]);
    }
    
    // Agora há buracos intercalados na freelist
    printf("[+] Holes created for exploitation\n");
}

// 2. Heap grooming - preparar heap para UAF
void heap_grooming() {
    void *groom[100];
    
    // Alocar muitos objetos para estabilizar heap
    for (int i = 0; i < 100; i++) {
        groom[i] = malloc(0x100);
    }
    
    // Liberar em padrão específico
    for (int i = 0; i < 100; i++) {
        free(groom[i]);
        groom[i] = malloc(0x100);  // Realocar imediatamente
    }
    
    printf("[+] Heap groomed for exploitation\n");
}

// 3. Tcache priming (glibc >= 2.26)
void tcache_priming() {
    void *primed[7];
    
    // Preencher tcache
    for (int i = 0; i < 7; i++) {
        primed[i] = malloc(0x80);
    }
    for (int i = 0; i < 7; i++) {
        free(primed[i]);
    }
    
    // tcache está cheio, próximos frees vão para fastbin
    printf("[+] Tcache primed (full)\n");
}

int main() {
    printf("Heap Feng Shui Techniques\n");
    printf("=" * 60);
    
    hole_drilling();
    heap_grooming();
    tcache_priming();
    
    return 0;
}
```

***

### 🔍 **Detecção e Prevenção**

#### **Ferramentas de Detecção**

```bash
#!/bin/bash
# uaf_detection_tools.sh - Ferramentas para detectar UAF

# 1. AddressSanitizer (ASAN)
echo "[*] Compilando com AddressSanitizer"
gcc -fsanitize=address -g -O0 -o test_asan test.c
./test_asan 2>&1 | grep -A 10 "heap-use-after-free"

# 2. Valgrind (Memcheck)
echo "\n[*] Executando Valgrind"
valgrind --tool=memcheck --track-origins=yes ./test 2>&1 | grep -A 5 "Invalid read"

# 3. Dr. Memory
echo "\n[*] Executando Dr. Memory"
drmemory -- ./test 2>&1 | grep -A 5 "UNADDRESSABLE ACCESS"

# 4. Compiler flags para detecção
echo "\n[*] Compilando com flags de detecção"
gcc -D_FORTIFY_SOURCE=2 -O2 -g -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -o test test.c

# 5. Static analysis
echo "\n[*] Análise estática com Clang"
clang --analyze test.c 2>&1 | grep -i "use after free"

# 6. Infer (Facebook)
echo "\n[*] Análise com Infer"
infer run -- gcc -c test.c 2>&1 | grep -i "use-after-free"
```

#### **Script de Detecção de UAF**

```python
#!/usr/bin/env python3
# detect_uaf.py - Detector de Use-After-Free

import subprocess
import re
import sys

class UAFDetector:
    """Detector de Use-After-Free em binários"""
    
    @staticmethod
    def check_asan_output(log_file):
        """Analisar saída do AddressSanitizer"""
        print("[*] Analisando saída do AddressSanitizer")
        
        try:
            with open(log_file, 'r') as f:
                content = f.read()
            
            # Padrões de UAF
            patterns = {
                'heap-use-after-free': 'Use-After-Free detectado',
                'READ of size': 'Leitura após free',
                'WRITE of size': 'Escrita após free',
                'freed by thread': 'Local da liberação',
                'previously allocated': 'Local da alocação'
            }
            
            for pattern, message in patterns.items():
                if pattern in content:
                    print(f"   ⚠️ {message}")
                    
                    # Extrair stack trace
                    lines = content.split('\n')
                    for line in lines:
                        if '#0' in line or '#1' in line:
                            print(f"      {line.strip()}")
                    
        except Exception as e:
            print(f"   Erro: {e}")
    
    @staticmethod
    def check_valgrind_output(log_file):
        """Analisar saída do Valgrind"""
        print("\n[*] Analisando saída do Valgrind")
        
        try:
            with open(log_file, 'r') as f:
                content = f.read()
            
            if 'Invalid read' in content or 'Invalid write' in content:
                print("   ⚠️ Acesso inválido a memória detectado")
                
                # Extrair stack trace
                lines = content.split('\n')
                for line in lines:
                    if 'at 0x' in line or 'by 0x' in line:
                        print(f"      {line.strip()}")
            
            if 'Address 0x' in content and 'is 0 bytes inside a block of size' in content:
                print("   ⚠️ Possível Use-After-Free")
                
        except Exception as e:
            print(f"   Erro: {e}")
    
    @staticmethod
    def static_analysis(source_file):
        """Análise estática de código fonte"""
        print("\n[*] Analisando código fonte")
        
        patterns = [
            (r'free\((\w+)\);.*?(\1)->', 'Possível UAF após free'),
            (r'free\((\w+)\);.*?(\1)\[', 'Possível UAF após free'),
            (r'delete\s+(\w+);.*?(\1)->', 'Possível UAF (C++)'),
            (r'free\((\w+)\);.*?free\(\1\)', 'Possível double free')
        ]
        
        try:
            with open(source_file, 'r') as f:
                content = f.read()
            
            for pattern, message in patterns:
                matches = re.findall(pattern, content, re.DOTALL)
                if matches:
                    print(f"   ⚠️ {message}")
                    for match in matches[:3]:
                        print(f"      {match}")
                        
        except Exception as e:
            print(f"   Erro: {e}")

# Uso
if __name__ == "__main__":
    print("🔍 Use-After-Free Detection")
    print("=" * 60)
    
    if len(sys.argv) > 1:
        if sys.argv[1].endswith('.c') or sys.argv[1].endswith('.cpp'):
            UAFDetector.static_analysis(sys.argv[1])
        else:
            UAFDetector.check_asan_output(sys.argv[1])
            UAFDetector.check_valgrind_output(sys.argv[1])
    else:
        print("Uso: detect_uaf.py <source.c|asan_log|valgrind_log>")
```

***

### 🛡️ **Prevenção e Mitigações**

#### **Técnicas de Prevenção**

```c
// uaf_prevention.c - Técnicas para prevenir UAF

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 1. Setar ponteiros para NULL após free
void safe_free(void **ptr) {
    if (ptr && *ptr) {
        free(*ptr);
        *ptr = NULL;  // ✅ Previne dangling pointer
    }
}

// 2. RAII em C com cleanup attribute
__attribute__((cleanup(cleanup_string)))
char* create_string() {
    return malloc(100);
}

void cleanup_string(char **str) {
    if (*str) {
        free(*str);
        *str = NULL;
    }
}

// 3. Smart pointers em C++
// std::unique_ptr<int> ptr = std::make_unique<int>(42);
// std::shared_ptr<int> ptr2 = std::make_shared<int>(42);

// 4. Quarantine (delay free)
#define QUARANTINE_SIZE 100
static void *quarantine[QUARANTINE_SIZE];
static int quarantine_idx = 0;

void quarantine_free(void *ptr) {
    if (quarantine_idx < QUARANTINE_SIZE) {
        quarantine[quarantine_idx++] = ptr;
    } else {
        // Liberar o mais antigo
        free(quarantine[0]);
        for (int i = 1; i < QUARANTINE_SIZE; i++) {
            quarantine[i-1] = quarantine[i];
        }
        quarantine[QUARANTINE_SIZE-1] = ptr;
    }
}

// 5. Canários para detectar corrupção
typedef struct {
    uint32_t magic_start;
    int data;
    uint32_t magic_end;
} guarded_object_t;

#define MAGIC 0xDEADBEEF

guarded_object_t* guarded_create(int value) {
    guarded_object_t *obj = malloc(sizeof(guarded_object_t));
    if (obj) {
        obj->magic_start = MAGIC;
        obj->data = value;
        obj->magic_end = MAGIC;
    }
    return obj;
}

int guarded_use(guarded_object_t *obj) {
    if (!obj || obj->magic_start != MAGIC || obj->magic_end != MAGIC) {
        return -1;  // Corrupção detectada
    }
    return obj->data;
}

// 6. Compilação com proteções
// gcc -fstack-protector-strong -D_FORTIFY_SOURCE=2 -O2 -o safe safe.c
// g++ -fsanitize=address -g -O0 -o debug debug.cpp
```

#### **Proteções do Sistema**

```yaml
Proteções de Sistema contra UAF:

  ✅ AddressSanitizer (ASAN):
    - Quarantine de freed chunks
    - Shadow memory para tracking
    - Detecção em tempo real

  ✅ GWP-ASan (Android):
    - Sampling de alocações
    - Detecção de UAF em produção
    - Baixo overhead

  ✅ Scudo Hardened Allocator:
    - Randomização de alocações
    - Quarantine
    - Detecção de UAF

  ✅ HWASan (Hardware-assisted ASan):
    - Uso de tags de memória (MTE)
    - Detecção em hardware
    - Baixo overhead

  ✅ CFI (Control Flow Integrity):
    - Protege contra redirecionamento de fluxo
    - Verifica chamadas indiretas

  ✅ PAX/grsecurity:
    - ASLR reforçado
    - PAGEEXEC (NX)
    - MPROTECT (W^X)
```

***

### 📋 **Checklists de Segurança**

#### **Checklist para Desenvolvedores**

* [ ] Setar ponteiros para NULL após free/delete
* [ ] Usar smart pointers em C++ (unique\_ptr, shared\_ptr)
* [ ] Implementar RAII para recursos
* [ ] Evitar múltiplos ponteiros para mesma memória
* [ ] Usar ferramentas de análise estática
* [ ] Testar com AddressSanitizer
* [ ] Validar ponteiros antes de usar
* [ ] Documentar ownership de ponteiros

#### **Checklist para Revisão de Código**

* [ ] Verificar pares malloc/free
* [ ] Analisar caminhos de erro que podem causar UAF
* [ ] Verificar uso de ponteiros após free
* [ ] Confirmar que free não é chamado duas vezes
* [ ] Analisar containers que armazenam ponteiros
* [ ] Verificar uso de realloc

***

### 📊 **Conclusão**

```yaml
Use-After-Free:

  🔴 Principais Vetores:
    - Ponteiros sem NULL após free
    - Double free
    - Uso após realloc
    - Containers com ponteiros pendentes

  🛡️ Mitigações Essenciais:
    - Setar NULL após free
    - Smart pointers (C++)
    - AddressSanitizer
    - Valgrind
    - Análise estática

  🎯 Prioridade:
    - CRÍTICA: UAF em código de rede/kernel
    - ALTA: UAF em C++ com vtables
    - MÉDIA: UAF em código legado
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/tecnicas/linguagens-de-programacao/low-level/use-after-free.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
