NtCreateProcessEx
Crea un nuevo proceso a partir de un handle de sección sin ejecutar la inicialización ntdll — pieza clave del process hollowing.
Prototipo
NTSTATUS NtCreateProcessEx( PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, HANDLE ParentProcess, ULONG Flags, HANDLE SectionHandle, HANDLE DebugPort, HANDLE ExceptionPort, ULONG JobMemberLevel );
Argumentos
| Name | Type | Dir | Description |
|---|---|---|---|
| ProcessHandle | PHANDLE | out | Recibe el handle del nuevo proceso si tiene éxito. |
| DesiredAccess | ACCESS_MASK | in | Derechos de acceso para el handle de proceso devuelto, normalmente PROCESS_ALL_ACCESS. |
| ObjectAttributes | POBJECT_ATTRIBUTES | in | Atributos de objeto opcionales (nombre, directorio raíz). Normalmente NULL. |
| ParentProcess | HANDLE | in | Handle al proceso padre (NtCurrentProcess() para sí mismo). Habilita el spoofing de PID padre cuando apunta a otro proceso. |
| Flags | ULONG | in | Banderas de creación incluyendo PROCESS_CREATE_FLAGS_INHERIT_HANDLES, PROCESS_CREATE_FLAGS_BREAKAWAY, PROCESS_CREATE_FLAGS_SUSPENDED. |
| SectionHandle | HANDLE | in | Handle a una sección SEC_IMAGE que respalda la imagen del nuevo proceso. NULL hereda la imagen del padre (usado en combos PPID-spoof + hollow). |
| DebugPort | HANDLE | in | Handle de puerto de depuración opcional. Casi siempre NULL. |
| ExceptionPort | HANDLE | in | Handle de puerto de excepciones opcional (mecanismo LPC heredado). Casi siempre NULL. |
| JobMemberLevel | ULONG | in | Nivel de anidamiento de job-object cuando el padre forma parte de una jerarquía de jobs; 0 si no aplica. |
IDs de syscalls por versión de Windows
| Versión de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0x4D | win10-1507 |
| Win10 1607 | 0x4D | win10-1607 |
| Win10 1703 | 0x4D | win10-1703 |
| Win10 1709 | 0x4D | win10-1709 |
| Win10 1803 | 0x4D | win10-1803 |
| Win10 1809 | 0x4D | win10-1809 |
| Win10 1903 | 0x4D | win10-1903 |
| Win10 1909 | 0x4D | win10-1909 |
| Win10 2004 | 0x4D | win10-2004 |
| Win10 20H2 | 0x4D | win10-20h2 |
| Win10 21H1 | 0x4D | win10-21h1 |
| Win10 21H2 | 0x4D | win10-21h2 |
| Win10 22H2 | 0x4D | win10-22h2 |
| Win11 21H2 | 0x4D | win11-21h2 |
| Win11 22H2 | 0x4D | win11-22h2 |
| Win11 23H2 | 0x4D | win11-23h2 |
| Win11 24H2 | 0x4D | win11-24h2 |
| Server 2016 | 0x4D | winserver-2016 |
| Server 2019 | 0x4D | winserver-2019 |
| Server 2022 | 0x4D | winserver-2022 |
| Server 2025 | 0x4D | winserver-2025 |
Módulo del kernel
APIs relacionadas
Stub del syscall
4C 8B D1 mov r10, rcx B8 4D 00 00 00 mov eax, 0x4D 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
Notas no documentadas
NtCreateProcessEx es el punto de entrada de bajo nivel para crear procesos. A diferencia de NtCreateUserProcess (que ahora usa CreateProcessW), NtCreateProcessEx exige que el llamador haya creado previamente una sección SEC_IMAGE desde el ejecutable objetivo vía NtCreateSection(SEC_IMAGE) y la adjunte. Crucialmente, el proceso resultante no tiene hilo inicial — el llamador debe invocar después NtCreateThreadEx (o NtCreateThread). Esta separación convierte a NtCreateProcessEx en la pieza canónica del *process hollowing* y de la familia *Early Bird APC*: crear un proceso, encolarle trabajo antes de que ejecute su primera instrucción. La SSN `0x4D` es estable en todas las builds soportadas.
Uso común por malware
Usada por cadenas de process hollowing que quieren evitar la telemetría de CreateProcessW, por herramientas de PPID-spoofing (poner ParentProcess en explorer.exe u otro PID de confianza), y por variantes Early Bird que combinan NtCreateProcessEx + NtCreateThreadEx(suspendido) + NtQueueApcThreadEx. Las funciones spawnto/spoof-parent de Cobalt Strike acaban en este camino de código. Menos común como primitiva ofensiva de alto nivel hoy porque NtCreateUserProcess ofrece un control de atributos más rico en un solo syscall.
Oportunidades de detección
ETW Microsoft-Windows-Kernel-Process emite eventos ProcessStart desde PspInsertProcess sin importar el punto de entrada de userland; el kernel no distingue entre NtCreateProcessEx y NtCreateUserProcess en ese callback. Sysmon Event ID 1 se dispara en cualquier caso y expone el PID padre real incluso cuando CreateProcessW habría mentido. Los hooks de userland sobre kernelbase!CreateProcessW pierden a los llamadores por syscalls directos; los hooks deben sentarse sobre ntdll!NtCreateUserProcess *y* ntdll!NtCreateProcessEx. Indicador sospechoso: una sección SEC_IMAGE sobre un PE sin firmar seguida en milisegundos por NtCreateProcessEx y NtCreateThreadEx en estado suspendido.
Ejemplos de syscalls directos
asmx64 direct stub
; Direct syscall stub for NtCreateProcessEx (SSN 0x4D, stable on Win10 1507+ through Win11 24H2)
NtCreateProcessEx PROC
mov r10, rcx ; syscall convention
mov eax, 4Dh ; SSN
syscall
ret
NtCreateProcessEx ENDPcProcess-hollow style: SEC_IMAGE + NtCreateProcessEx
// Open the target PE and wrap it in a SEC_IMAGE section, then spawn a process backed by it.
HANDLE hFile = NULL;
IO_STATUS_BLOCK iosb = { 0 };
OBJECT_ATTRIBUTES oa = { 0 };
UNICODE_STRING path;
RtlInitUnicodeString(&path, L"\\??\\C:\\Windows\\System32\\notepad.exe");
InitializeObjectAttributes(&oa, &path, OBJ_CASE_INSENSITIVE, NULL, NULL);
NtOpenFile(&hFile, FILE_EXECUTE | SYNCHRONIZE, &oa, &iosb,
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
HANDLE hSection = NULL;
NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, NULL,
PAGE_READONLY, SEC_IMAGE, hFile);
HANDLE hProcess = NULL;
NtCreateProcessEx(&hProcess,
PROCESS_ALL_ACCESS,
NULL,
NtCurrentProcess(), // ParentProcess — set elsewhere for PPID spoof
0, // Flags
hSection, // SectionHandle
NULL, // DebugPort
NULL, // ExceptionPort
0); // JobMemberLevel
// New process has NO threads yet — caller must NtCreateThreadEx into it.rustwindows-sys + naked syscall stub
// Cargo: windows-sys = "0.59"
use std::arch::asm;
#[unsafe(naked)]
unsafe extern "system" fn nt_create_process_ex_stub() {
asm!(
"mov r10, rcx",
"mov eax, 0x4D",
"syscall",
"ret",
options(noreturn),
);
}Mapeos MITRE ATT&CK
Last verified: 2026-05-20