> Windows Syscalls
ntoskrnl.exeT1574T1055T1106

NtSetInformationVirtualMemory

Wendet eine Informationsklasse auf eine Liste virtueller Speicherbereiche an: Prefetch, Seitenpriorität oder CFG-Opt-in.

Prototyp

NTSTATUS NtSetInformationVirtualMemory(
  HANDLE                          ProcessHandle,
  VIRTUAL_MEMORY_INFORMATION_CLASS VmInformationClass,
  ULONG_PTR                       NumberOfEntries,
  PMEMORY_RANGE_ENTRY             VirtualAddresses,
  PVOID                           VmInformation,
  ULONG                           VmInformationLength
);

Argumente

NameTypeDirDescription
ProcessHandleHANDLEinHandle des Zielprozesses. NtCurrentProcess() ((HANDLE)-1) für den eigenen Prozess.
VmInformationClassVIRTUAL_MEMORY_INFORMATION_CLASSinOperation: VmPrefetchInformation, VmPagePriorityInformation, VmCfgCallTargetInformation, VmPageDirtyStateInformation, VmImageHotPatchInformation.
NumberOfEntriesULONG_PTRinAnzahl der Einträge in VirtualAddresses. Mehrere Klassen (insbesondere CfgCallTarget) verlangen genau 1.
VirtualAddressesPMEMORY_RANGE_ENTRYinArray von {VirtualAddress, NumberOfBytes}-Bereichen, auf die gewirkt werden soll.
VmInformationPVOIDinKlassenspezifische Nutzlast: ULONG-Flags für Prefetch, MEMORY_PRIORITY_INFORMATION für Priorität, CFG_CALL_TARGET_INFO[] für CFG.
VmInformationLengthULONGinGröße der VmInformation-Nutzlast in Bytes.

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
Win10 15070x182win10-1507
Win10 16070x18Bwin10-1607
Win10 17030x191win10-1703
Win10 17090x194win10-1709
Win10 18030x196win10-1803
Win10 18090x197win10-1809
Win10 19030x198win10-1903
Win10 19090x198win10-1909
Win10 20040x19Ewin10-2004
Win10 20H20x19Ewin10-20h2
Win10 21H10x19Ewin10-21h1
Win10 21H20x1A0win10-21h2
Win10 22H20x1A0win10-22h2
Win11 21H20x1A9win11-21h2
Win11 22H20x1ADwin11-22h2
Win11 23H20x1ADwin11-23h2
Win11 24H20x1B0win11-24h2
Server 20160x18Bwinserver-2016
Server 20190x197winserver-2019
Server 20220x1A6winserver-2022
Server 20250x1B0winserver-2025

Kernel-Modul

ntoskrnl.exeNtSetInformationVirtualMemory

Verwandte APIs

PrefetchVirtualMemoryOfferVirtualMemorySetProcessValidCallTargetsVirtualAllocFromAppNtAllocateVirtualMemoryExNtProtectVirtualMemory

Syscall-Stub

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

Eingeführt als Teil der Multi-Range-VM-Advisory-API von Windows 10 und in jedem Release substanziell erweitert. Die operativ interessantesten Informationsklassen sind: **VmPrefetchInformation** — wärmt einen Vektor von Adressbereichen vor dem Zugriff (das Kernel-Rückgrat von PrefetchVirtualMemory/OfferVirtualMemory); **VmPagePriorityInformation** — setzt Paging-Prioritätshinweise; **VmCfgCallTargetInformation** — markiert spezifische Adressen in einem CFG-aktivierten Modul als gültige indirekte Aufrufziele, der kernelseitige Mechanismus hinter SetProcessValidCallTargets und der einzige sanktionierte Weg, wie ein JIT frisch emittierten Code in einem CFG-geschützten Prozess veröffentlichen kann; **VmImageHotPatchInformation** — wird von HotPatch auf Server 2022+ / 24H2 verwendet.

Häufige Malware-Nutzung

Zwei unterschiedliche Missbrauchsgeschichten. (1) **CFG-Bypass-Forschung**: VmCfgCallTargetInformation ist die legitime Tür, um CFG mitzuteilen, dass eine beliebige Adresse jetzt ein gültiges Aufrufziel ist. Wenn ein Angreifer, der in einem CFG-geschützten Prozess bereits Arbitrary-Read/Write hat, diesen Aufruf ausführen kann — oder das kernelseitige Bitmap-Update fälschen kann — kann er beliebige Gadgets als legitime indirekte Aufrufziele rehabilitieren. Mehrere öffentliche CFG-Bypass-Writeups (Yarden Shafir, j00rus ältere Notizen) decken die Oberfläche ab. Modernes Hardening kombiniert CFG mit Xtended Flow Guard (XFG) und Arbitrary Code Guard genau dafür. (2) **JIT-Injection-Tarnung**: legitime Browser und .NET nutzen VmCfgCallTargetInformation ständig, sodass ein Payload-Loader, der die gleiche Aufrufform imitiert (ausführbare Allocation, Code schreiben, NtSetInformationVirtualMemory mit VmCfgCallTargetInformation aufrufen), in Baseline-Telemetrie innerhalb eines Browser-Klasse-Prozesses untergeht. Seltener, aber dokumentiert.

Erkennungs­möglichkeiten

EDRs sollten VmCfgCallTargetInformation-Aufrufe aus Prozessen ohne JIT markieren (alles außerhalb chrome.exe, msedge.exe, firefox.exe, dotnet.exe / coreclr-gehostete Apps, javaw.exe, JScript9.dll-Hosts). ETW Microsoft-Windows-Threat-Intelligence emittiert Memory-State-Change-Events, wenn sie mit Übergängen ausführbarer Seiten gekoppelt sind. Sysmon deckt diesen Syscall nicht direkt ab; sich auf den Syscall-Callback des EDR-Sensors verlassen (Kernel-Microsoft-Antimalware-AMFilter auf AMSI-instrumentierten Systemen). Die Win32-Oberfläche (SetProcessValidCallTargets, PrefetchVirtualMemory) wird von jedem großen EDR gehakt.

Direkte Syscall-Beispiele

asmx64 direct stub (Win11 24H2)

; Direct syscall stub for NtSetInformationVirtualMemory (SSN 0x1B0, Win11 24H2)
NtSetInformationVirtualMemory PROC
    mov  r10, rcx
    mov  eax, 1B0h
    syscall
    ret
NtSetInformationVirtualMemory ENDP

cJIT opt-in for CFG (VmCfgCallTargetInformation)

// JIT just emitted callable code at `jit_buf` (size = jit_len). Tell CFG it's legal
// to indirect-call into the new entrypoints. Mirrors what V8 / CoreCLR do.
typedef struct _CFG_CALL_TARGET_INFO {
    ULONG_PTR Offset;
    ULONG_PTR Flags;
} CFG_CALL_TARGET_INFO;

typedef struct _MEMORY_RANGE_ENTRY {
    PVOID    VirtualAddress;
    SIZE_T   NumberOfBytes;
} MEMORY_RANGE_ENTRY;

#define VmCfgCallTargetInformation 2
#define CFG_CALL_TARGET_VALID      0x01

MEMORY_RANGE_ENTRY range = { jit_buf, jit_len };
CFG_CALL_TARGET_INFO targets[] = {
    { (ULONG_PTR)entry0 - (ULONG_PTR)jit_buf, CFG_CALL_TARGET_VALID },
    { (ULONG_PTR)entry1 - (ULONG_PTR)jit_buf, CFG_CALL_TARGET_VALID },
};

NTSTATUS s = NtSetInformationVirtualMemory(
    NtCurrentProcess(),
    VmCfgCallTargetInformation,
    1,
    &range,
    targets,
    sizeof(targets));

rustPrefetchVirtualMemory equivalent via VmPrefetchInformation

// Warm a list of memory ranges before the latency-sensitive work touches them.
// VmPrefetchInformation = 0.
#[repr(C)]
struct MemoryRangeEntry { addr: *mut u8, bytes: usize }

extern "system" {
    fn NtSetInformationVirtualMemory(
        process: isize,
        class: u32,
        n: usize,
        ranges: *const MemoryRangeEntry,
        info: *const u32,
        info_len: u32,
    ) -> i32;
}

unsafe fn prefetch(ranges: &[MemoryRangeEntry]) -> i32 {
    let flags: u32 = 0;
    NtSetInformationVirtualMemory(
        -1, 0, ranges.len(), ranges.as_ptr(),
        &flags, std::mem::size_of::<u32>() as u32)
}

MITRE ATT&CK-Mappings

Last verified: 2026-05-20