> Windows Syscalls
ntoskrnl.exeT1057T1003.001T1055

NtOpenProcess

Opens a handle to an existing process with a requested access mask.

Prototype

NTSTATUS NtOpenProcess(
  PHANDLE            ProcessHandle,
  ACCESS_MASK        DesiredAccess,
  POBJECT_ATTRIBUTES ObjectAttributes,
  PCLIENT_ID         ClientId
);

Arguments

NameTypeDirDescription
ProcessHandlePHANDLEoutReceives the opened process handle on success.
DesiredAccessACCESS_MASKinRequested rights, e.g. PROCESS_VM_READ, PROCESS_ALL_ACCESS, PROCESS_QUERY_LIMITED_INFORMATION.
ObjectAttributesPOBJECT_ATTRIBUTESinObject attributes (usually zero-initialised; ObjectName must be NULL when ClientId is used).
ClientIdPCLIENT_IDinOptional. Identifies the target by PID (UniqueProcess); UniqueThread is ignored here.

Syscall IDs by Windows version

Windows versionSyscall IDBuild
Win10 15070x26win10-1507
Win10 16070x26win10-1607
Win10 17030x26win10-1703
Win10 17090x26win10-1709
Win10 18030x26win10-1803
Win10 18090x26win10-1809
Win10 19030x26win10-1903
Win10 19090x26win10-1909
Win10 20040x26win10-2004
Win10 20H20x26win10-20h2
Win10 21H10x26win10-21h1
Win10 21H20x26win10-21h2
Win10 22H20x26win10-22h2
Win11 21H20x26win11-21h2
Win11 22H20x26win11-22h2
Win11 23H20x26win11-23h2
Win11 24H20x26win11-24h2
Server 20160x26winserver-2016
Server 20190x26winserver-2019
Server 20220x26winserver-2022
Server 20250x26winserver-2025

Kernel module

ntoskrnl.exeNtOpenProcess

Related APIs

OpenProcessNtOpenProcessTokenNtOpenProcessTokenExNtDuplicateObjectZwOpenProcess

Syscall stub

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

Undocumented notes

Open-by-PID is the path that nearly all userland code takes — `ObjectName` is typically NULL and `ClientId.UniqueProcess` carries the target PID. SSN `0x26` has been stable across every shipped Win10/11 build. The Win32 `OpenProcess` is a thin wrapper that fills in `OBJECT_ATTRIBUTES` and `CLIENT_ID` before calling this function. Access is gated by the target's SecurityDescriptor and any registered object callbacks; PPL/PP processes (`lsass.exe` with Credential Guard, MsMpEng.exe) reject everything except `PROCESS_QUERY_LIMITED_INFORMATION` regardless of privilege.

Common malware usage

The first step of nearly every cross-process attack: get a handle with the rights needed for whatever follows. `PROCESS_VM_READ` for LSASS dumping, `PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD` for classic injection, `PROCESS_DUP_HANDLE` for token theft. Sophisticated tooling now opens with the minimum required mask (`0x1010` for read-only LSASS access) instead of `PROCESS_ALL_ACCESS` (`0x1FFFFF`) to evade EDR rules that key on the full mask.

MimikatzCobalt StrikeSliverBrute RatelQakbotLazarus tooling

Detection opportunities

Sysmon Event ID 10 (`ProcessAccess`) is the canonical telemetry — every `NtOpenProcess` that yields a handle to a different process fires this event with `SourceProcessGUID`, `TargetProcessGUID`, `GrantedAccess`, and a call-stack. Defenders tune Sysmon to filter the noisy short masks and alert on dangerous combinations targeting `lsass.exe`, `MsMpEng.exe`, browsers, etc. Kernel-side, `ObRegisterCallbacks` lets PPL-protecting drivers (and EDRs) strip rights or veto the open before the handle is returned, which is the mechanism behind LSASS Protected Process Light. Direct syscalls do not bypass object callbacks.

Direct syscall examples

asmx64 direct stub

; Direct syscall stub for NtOpenProcess (SSN 0x26, stable across all Win10/11)
NtOpenProcess PROC
    mov  r10, rcx          ; syscall convention
    mov  eax, 26h          ; SSN
    syscall
    ret
NtOpenProcess ENDP

cOpen LSASS with minimal mask

// Minimal-rights LSASS open used by nanodump and lsassy to evade GrantedAccess rules.
OBJECT_ATTRIBUTES oa;
CLIENT_ID         cid = { (HANDLE)(ULONG_PTR)lsass_pid, NULL };
InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL);

HANDLE hLsass = NULL;
// PROCESS_QUERY_INFORMATION | PROCESS_VM_READ == 0x1010
NTSTATUS st = NtOpenProcess(&hLsass, 0x1010, &oa, &cid);
if (!NT_SUCCESS(st)) return st;

rustHell's Gate dynamic lookup

// Resolve SSN at runtime; useful when ntdll.dll is hooked.
use std::arch::asm;

#[unsafe(naked)]
unsafe extern "system" fn nt_open_process_stub() {
    asm!(
        "mov r10, rcx",
        "mov eax, 0x26",   // stable across all Win10/11 builds
        "syscall",
        "ret",
        options(noreturn),
    );
}

MITRE ATT&CK mappings

Last verified: 2026-05-20