> Windows Syscalls
ntoskrnl.exeT1055.012T1055T1106

NtUnmapViewOfSection

Démappe une vue de section précédemment mappée de l'espace d'adressage d'un processus.

Prototype

NTSTATUS NtUnmapViewOfSection(
  HANDLE ProcessHandle,
  PVOID  BaseAddress
);

Arguments

NameTypeDirDescription
ProcessHandleHANDLEinHandle vers le processus dont la vue est démappée. Requiert PROCESS_VM_OPERATION.
BaseAddressPVOIDinAdresse de base de la vue à démapper. Doit correspondre à la valeur retournée par NtMapViewOfSection.

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
Win10 15070x2Awin10-1507
Win10 16070x2Awin10-1607
Win10 17030x2Awin10-1703
Win10 17090x2Awin10-1709
Win10 18030x2Awin10-1803
Win10 18090x2Awin10-1809
Win10 19030x2Awin10-1903
Win10 19090x2Awin10-1909
Win10 20040x2Awin10-2004
Win10 20H20x2Awin10-20h2
Win10 21H10x2Awin10-21h1
Win10 21H20x2Awin10-21h2
Win10 22H20x2Awin10-22h2
Win11 21H20x2Awin11-21h2
Win11 22H20x2Awin11-22h2
Win11 23H20x2Awin11-23h2
Win11 24H20x2Awin11-24h2
Server 20160x2Awinserver-2016
Server 20190x2Awinserver-2019
Server 20220x2Awinserver-2022
Server 20250x2Awinserver-2025

Module noyau

ntoskrnl.exeNtUnmapViewOfSection

APIs liées

UnmapViewOfFileUnmapViewOfFile2NtMapViewOfSectionNtMapViewOfSectionExNtUnmapViewOfSectionExNtCreateSection

Stub du syscall

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

Notes non documentées

NtUnmapViewOfSection garde le SSN `0x2A` sur tous les builds Windows 10 / 11 / Server observés. NtUnmapViewOfSectionEx correspondant (ajouté en Win10 1809) est un syscall distinct acceptant un paramètre Flags. En interne l'appel passe par MmUnmapViewOfSection et parcourt l'arbre VAD du processus cible pour trouver l'entrée SECTION_OBJECT_POINTERS — ce qui rend le primitif de hollowing si fiable : démapper l'image principale du processus est supporté et n'exige aucun privilège particulier au-delà d'un handle PROCESS_VM_OPERATION.

Usage courant par les malwares

Pierre angulaire du process hollowing (T1055.012). La recette classique : CreateProcess(cible, CREATE_SUSPENDED) → NtQueryInformationProcess pour récupérer la base d'image du PEB → NtUnmapViewOfSection sur cette base → NtAllocateVirtualMemory à la base d'origine (préférée) → écrire les sections de l'image malveillante → ajuster SetThreadContext RIP/RAX/EAX → ResumeThread. Stuxnet, Dridex, Hancitor, FormBook, Agent Tesla, et des droppers modernes comme SmokeLoader et Amadey en livrent tous des variantes. NtUnmapViewOfSection sert aussi post-injection à effacer la vue d'une DLL d'EDR depuis un processus hôte, afin que les futurs LoadLibrary touchent une copie fraîche sans les hooks inline.

Opportunités de détection

Un NtUnmapViewOfSection cross-process où ProcessHandle != soi-même est rare en logiciel légitime (chemins de détachement de débogueur et quelques gestionnaires de runtimes side-by-side, c'est à peu près tout). Sysmon Event ID 25 (`ProcessTampering: Image is replaced`) cible explicitement le pattern unmap-puis-alloc du hollowing. Le provider ETW Threat Intelligence émet des événements de modification d'image processus à partir de Win10 RS5 qui se déclenchent sur le démappage de l'image exécutable principale. Corréler avec un processus enfant dont l'image sur disque diffère de l'image en mémoire (comparer le chemin module avec l'en-tête de section au ImageBaseAddress du PEB).

Exemples de syscalls directs

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 ENDP

cProcess 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) }
}

Mappings MITRE ATT&CK

Last verified: 2026-05-20