> Windows Syscalls
ntoskrnl.exeT1055T1055.002T1620

NtAllocateVirtualMemory

Reserviert, committet oder beides eine virtuelle Speicherregion in einem Zielprozess.

Prototyp

NTSTATUS NtAllocateVirtualMemory(
  HANDLE    ProcessHandle,
  PVOID    *BaseAddress,
  ULONG_PTR ZeroBits,
  PSIZE_T   RegionSize,
  ULONG     AllocationType,
  ULONG     Protect
);

Argumente

NameTypeDirDescription
ProcessHandleHANDLEinHandle auf den Zielprozess. NtCurrentProcess() ((HANDLE)-1) für den eigenen Prozess.
BaseAddressPVOID*in/outZeiger auf die gewünschte Basisadresse. NULL lässt den Kernel wählen. Wird beim Rückkehren aktualisiert.
ZeroBitsULONG_PTRinAnzahl der Null-Bits in den höchstwertigen Bits von BaseAddress. Üblicherweise 0.
RegionSizePSIZE_Tin/outZeiger auf die gewünschte Größe, beim Rückkehren auf Seitengrenze aufgerundet.
AllocationTypeULONGinAllocation-Flags. MEM_COMMIT | MEM_RESERVE ist die häufigste Kombination.
ProtectULONGinSpeicherschutz-Konstante, z. B. PAGE_READWRITE, PAGE_EXECUTE_READWRITE.

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
Win10 19090x18win10-1909
Win10 20040x18win10-2004
Win10 20H20x18win10-20h2
Win10 21H10x18win10-21h1
Win10 21H20x18win10-21h2
Win10 22H20x18win10-22h2
Win11 21H20x18win11-21h2
Win11 22H20x18win11-22h2
Win11 23H20x18win11-23h2
Win11 24H20x18win11-24h2
Server 20190x18winserver-2019
Server 20220x18winserver-2022
Server 20250x18winserver-2025

Kernel-Modul

ntoskrnl.exeNtAllocateVirtualMemory

Verwandte APIs

VirtualAllocVirtualAllocExNtAllocateVirtualMemoryExNtProtectVirtualMemoryNtWriteVirtualMemoryNtFreeVirtualMemory

Syscall-Stub

4C 8B D1            mov r10, rcx
B8 18 00 00 00      mov eax, 0x18
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

Die Syscall-Nummer von NtAllocateVirtualMemory ist von Windows 10 1909 bis Windows 11 24H2 bemerkenswert stabil — `0x18`. Bei vielen benachbarten Syscalls (z. B. NtCreateThreadEx) ist das *nicht* der Fall, weshalb dynamische Auflösung über Hell's Gate oder Halo's Gate gegenüber hartkodierten Nummern bevorzugt wird, wenn mehrere Builds anvisiert werden. Die Funktion dispatcht über KiSystemServiceCopyEnd → MmAllocateVirtualMemory innerhalb von ntoskrnl.exe.

Häufige Malware-Nutzung

Grundbaustein nahezu jedes Shellcode-Loaders: RW- oder RWX-Speicher im aktuellen oder Remote-Prozess allokieren, Payload kopieren, dann Schutz mit NtProtectVirtualMemory ändern. Wird verwendet von Cobalt-Strike-Beacon-Spawn, Sliver-Implants, klassischer Injection und den meisten Standard-Droppern. Zusammen mit NtWriteVirtualMemory + NtCreateThreadEx bildet es die kanonische CreateRemoteThread-Entsprechung über direkte Syscalls.

Erkennungs­möglichkeiten

Für sich allein ist NtAllocateVirtualMemory in legitimer Software *äußerst* häufig und kein nützliches Signal. Entscheidend ist *wie* und *wo* der Aufruf erfolgt: RWX-Allokationen, Allokationen in Remote-Prozessen sowie kurze RW→RX→Ausführen-Sequenzen. EDRs hooken NtAllocateVirtualMemory in ntdll.dll; direkte Syscalls umgehen diesen Hook, hinterlassen aber kernelseitig sichtbare Artefakte (VAD-Einträge, ETW-Threat-Intelligence-Events, PsSetCreateProcessNotifyRoutineEx-Callbacks bei Remote-Thread-Erzeugung). Sysmon Event ID 8 (CreateRemoteThread) und Event ID 10 (ProcessAccess mit VM_OPERATION/VM_WRITE) sind die wertvollste Blue-Team-Telemetrie — sie feuern auf die *Folgen* der Allokation, nicht die Allokation selbst.

Direkte Syscall-Beispiele

asmx64 direct stub

; Direct syscall stub for NtAllocateVirtualMemory (SSN 0x18, Win10 1909+)
NtAllocateVirtualMemory PROC
    mov  r10, rcx          ; syscall convention
    mov  eax, 18h          ; SSN
    syscall
    ret
NtAllocateVirtualMemory ENDP

cHell's Gate dynamic lookup

// Resolve SSN dynamically from ntdll export at runtime — survives KB updates.
DWORD GetSyscallNumber(PVOID pNtFunction) {
    BYTE* p = (BYTE*)pNtFunction;
    if (p[0] == 0x4C && p[1] == 0x8B && p[2] == 0xD1 && p[3] == 0xB8) {
        return *(DWORD*)(p + 4);
    }
    return 0;
}

// usage
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
DWORD ssn = GetSyscallNumber(GetProcAddress(hNtdll, "NtAllocateVirtualMemory"));

rustwindows-sys + naked asm

// Cargo: windows-sys = "0.59"  (Win32_Foundation, Win32_System_Memory)
use std::arch::asm;

#[unsafe(naked)]
unsafe extern "system" fn nt_alloc_virtual_memory_stub() {
    asm!(
        "mov r10, rcx",
        "mov eax, 0x18",
        "syscall",
        "ret",
        options(noreturn),
    );
}

MITRE ATT&CK-Mappings

Last verified: 2026-05-20