# How CAPEv2 Detects Process Injection and Captures Malicious Payloads: A Technical Deep Dive

> Explore how CAPEv2 detects process injection using API monitoring and behavioral signatures. Learn how it captures malicious payloads through memory buffers and static extraction. Dive into the technical details.

- Repository: [Kevin O'Reilly/capev2](https://github.com/kevoreilly/capev2)
- Tags: deep-dive
- Published: 2026-03-05

---

**CAPEv2 detects process injection through real-time Windows API monitoring using behavioral signatures that track cross-process memory writes and thread creation, then captures payloads via memory-write buffers and post-run static extraction.**

CAPEv2 is an open-source malware sandbox that automates the analysis of suspicious files. When analyzing samples that employ code injection techniques, CAPEv2 uses specialized behavioral signatures to identify the injection method and extract the malicious payload for further inspection.

## Core Injection Detection Signatures

CAPEv2 implements four primary signatures in [`modules/signatures/CAPE.py`](https://github.com/kevoreilly/capev2/blob/main/modules/signatures/CAPE.py) that inherit from the base `Signature` class. These signatures operate in an *evented* mode, receiving each API call in real-time during sandbox execution to detect specific injection patterns.

### CAPE_InjectionCreateRemoteThread

Located at line 165 of [`modules/signatures/CAPE.py`](https://github.com/kevoreilly/capev2/blob/main/modules/signatures/CAPE.py), this signature detects the classic **CreateRemoteThread** injection technique. The detection logic maintains two internal sets: **process_handles** (collecting handles from `OpenProcess`, `NtOpenProcess`, and `CreateProcessInternalW`) and **write_handles** (tracking `VirtualAllocEx`, `WriteProcessMemory`, and `NtWriteVirtualMemory` operations).

The signature returns `True` only when both conditions are met: a memory write occurs to a foreign process handle, followed by a remote thread creation (`CreateRemoteThread` or `NtCreateThread*`) using that same handle.

### CAPE_InjectionProcessHollowing

Found at line 445 in the same file, this signature targets **process hollowing** (also known as process replacement). It monitors the sequence where a parent process creates a suspended child process, then performs: unmapping of the original executable (`NtUnmapViewOfSection`), allocation of new memory, writing of malicious code, setting thread context (`SetThreadContext`), and finally resuming execution (`ResumeThread`).

When this specific sequence completes with the resume operation, the signature flags the activity as process hollowing injection.

### CAPE_InjectionSetWindowLong

At line 223, this signature detects injection via `SetWindowLong*` APIs using shared memory sections. It tracks when a process maps a shared section into a remote process using `NtMapViewOfSection` (checking for known section names), then detects window manipulation through `FindWindow*` followed by `SetWindowLong*` calls against that window.

This technique is commonly used for injecting into explorer.exe or other GUI processes without creating remote threads.

### CAPE_Injection (Generic)

The generic injection signature at line 390 serves as a catch-all for inter-process injection patterns. It maintains **process_handles** and **write_handles** sets, flagging injection when a handle appears in both sets—indicating that a process opened a handle to another process and subsequently wrote memory to it, regardless of the specific API sequence used.

## Payload Capture Mechanism

When any injection signature triggers, CAPEv2 captures the malicious payload through a three-stage pipeline:

1. **Memory-Write Monitoring**: During execution, signatures monitor `WriteProcessMemory`, `NtWriteVirtualMemory`, and `VirtualAllocEx` calls. The buffer contents supplied to these calls are preserved in the signature's state (`self.data.append({"Injection": desc})`), creating a real-time record of the code being injected.

2. **Static Extraction**: After the sandbox run completes, the `static_extraction()` function in [`lib/cuckoo/common/cape_utils.py`](https://github.com/kevoreilly/capev2/blob/main/lib/cuckoo/common/cape_utils.py) processes any dumped memory regions or files written during injection. If the malware wrote payload data to disk (via `WriteFile` or `CreateFile`), the extractor saves these under `<sample>_extracted/` with unique identifiers.

3. **Report Generation**: The final JSON report (generated via [`lib/cuckoo/common/web_utils.py`](https://github.com/kevoreilly/capev2/blob/main/lib/cuckoo/common/web_utils.py)) contains an `injection` array listing the source process, destination process, injection description, and the path to the extracted payload file. Analysts access this through the web interface at [`web/templates/report.html`](https://github.com/kevoreilly/capev2/blob/main/web/templates/report.html) or the REST API defined in the web controllers.

## Configuration and API Access

### Enabling Injection Signatures

All four signatures are enabled by default in the CAPEv2 configuration. You can verify or modify this in your configuration files:

```python

# In config/core.py or via the web UI administration panel

SIGNATURES = [
    "injection_create_remote_thread",
    "injection_process_hollowing", 
    "injection_set_window_long",
    "injection_inter_process",
    # ... additional signatures ...

]

```

### Sample Detection Report

The following JSON snippet from [`reports/report.json`](https://github.com/kevoreilly/capev2/blob/main/reports/report.json) demonstrates a detected injection event:

```json
{
  "info": {
    "target": "malicious.exe",
    "sha256": "..."
  },
  "behavior": {
    "processes": [
      {
        "process_id": 1234,
        "process_name": "malicious.exe",
        "calls": []
      },
      {
        "process_id": 5678,
        "process_name": "explorer.exe",
        "calls": []
      }
    ],
    "injection": [
      {
        "description": "Code injection via WriteProcessMemory-modified NTDLL code in a remote process",
        "src": "malicious.exe (1234)",
        "dst": "explorer.exe (5678)",
        "payload_path": "samples/2024-03-01/5678_injected.bin"
      }
    ]
  }
}

```

### Accessing Payloads via API

Analysts can programmatically retrieve injection details and download captured payloads:

```bash

# Retrieve the analysis report

curl -X GET "https://cape.example.com/api/v1/tasks/42/report" \
     -H "Authorization: Bearer <TOKEN>" \
| jq '.behavior.injection[0].payload_path'

# Download the extracted payload file

curl -X GET "https://cape.example.com/api/v1/files/samples/2024-03-01/5678_injected.bin" \
     -H "Authorization: Bearer <TOKEN>" \
     -o extracted_payload.bin

```

## Summary

- **CAPEv2 uses specialized behavioral signatures** in [`modules/signatures/CAPE.py`](https://github.com/kevoreilly/capev2/blob/main/modules/signatures/CAPE.py) to detect specific injection techniques including CreateRemoteThread, process hollowing, and SetWindowLong manipulation.
- **Detection relies on cross-correlating process handles** with memory write operations in real-time, ensuring high-fidelity identification of injection patterns.
- **Payloads are captured through memory-write buffers** during execution and static extraction after the run completes, stored in [`lib/cuckoo/common/cape_utils.py`](https://github.com/kevoreilly/capev2/blob/main/lib/cuckoo/common/cape_utils.py).
- **All injection events are documented** in the JSON report with source/destination process IDs and file paths to extracted payloads, accessible via both web UI and REST API.

## Frequently Asked Questions

### What Windows API calls does CAPEv2 monitor to detect process injection?

CAPEv2 monitors `OpenProcess`, `NtOpenProcess`, `CreateProcessInternalW` for handle acquisition; `VirtualAllocEx`, `WriteProcessMemory`, `NtWriteVirtualMemory` for memory writes; and `CreateRemoteThread`, `NtCreateThread*`, `SetWindowLong*`, `ResumeThread` for execution transfer. The specific APIs tracked depend on which injection signature is active, as implemented in [`modules/signatures/CAPE.py`](https://github.com/kevoreilly/capev2/blob/main/modules/signatures/CAPE.py).

### How does CAPEv2 distinguish between different injection techniques?

Each signature looks for a unique API sequence pattern. The **CAPE_InjectionProcessHollowing** signature specifically requires the unmap-allocate-write-resume sequence, while **CAPE_InjectionCreateRemoteThread** requires both a memory write and remote thread creation on the same foreign handle. The generic **CAPE_Injection** signature flags any cross-process write without requiring a specific execution method.

### Can CAPEv2 extract payloads injected via APC or thread hijacking?

While the current signatures focus on CreateRemoteThread, process hollowing, and SetWindowLong methods, the generic **CAPE_Injection** signature at line 390 will detect any inter-process memory write. APC injection would require additional signature logic to monitor `NtQueueApcThread`, but the existing infrastructure in [`lib/cuckoo/common/cape_utils.py`](https://github.com/kevoreilly/capev2/blob/main/lib/cuckoo/common/cape_utils.py) would handle payload extraction if the memory buffers are captured during the write phase.

### Where are captured injection payloads stored in CAPEv2?

Extracted payloads are stored in the `storage/analyses/{task_id}/` directory under subfolders like `<sample>_extracted/`, with references logged in the `behavior.injection` section of [`reports/report.json`](https://github.com/kevoreilly/capev2/blob/main/reports/report.json). The `static_extraction()` function in [`lib/cuckoo/common/cape_utils.py`](https://github.com/kevoreilly/capev2/blob/main/lib/cuckoo/common/cape_utils.py) manages the file naming and storage logic, ensuring each injected payload retains its original memory layout for reverse engineering analysis.