> Windows Syscalls
ntoskrnl.exeT1134T1134.001T1134.002

NtOpenProcessTokenEx

Opens the access token of a process and lets the caller specify handle attributes such as OBJ_INHERIT.

Prototype

NTSTATUS NtOpenProcessTokenEx(
  HANDLE       ProcessHandle,
  ACCESS_MASK  DesiredAccess,
  ULONG        HandleAttributes,
  PHANDLE      TokenHandle
);

Arguments

NameTypeDirDescription
ProcessHandleHANDLEinHandle to the process whose token is being opened. Needs PROCESS_QUERY_(LIMITED_)INFORMATION.
DesiredAccessACCESS_MASKinToken access rights — combinations of TOKEN_QUERY, TOKEN_DUPLICATE, TOKEN_ADJUST_PRIVILEGES, TOKEN_IMPERSONATE, etc.
HandleAttributesULONGinOBJECT_ATTRIBUTES flags such as OBJ_INHERIT (0x2) or OBJ_KERNEL_HANDLE (0x200). Often 0.
TokenHandlePHANDLEoutReceives the handle to the opened token on success. Must be closed with NtClose.

Syscall IDs by Windows version

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

Kernel module

ntoskrnl.exeNtOpenProcessTokenEx

Related APIs

OpenProcessTokenNtOpenProcessTokenNtOpenThreadTokenExNtDuplicateTokenNtFilterTokenNtAdjustPrivilegesToken

Syscall stub

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

NtOpenProcessTokenEx is the canonical primitive that `kernel32!OpenProcessToken` actually invokes — `NtOpenProcessToken` is essentially a wrapper retained for source-compat with NT 3.x. Unlike the legacy form, its SSN has been **rock-stable at `0x30`** from Windows 10 1507 through Windows 11 24H2, which makes it a popular target for hardcoded-SSN loaders and SysWhispers stubs. The extra `HandleAttributes` parameter lets callers request inheritable handles (`OBJ_INHERIT`) — useful for parent-PID-spoofed child processes that need to inherit the token.

Common malware usage

Same role as NtOpenProcessToken in token-theft chains, but preferred by modern loaders because of its stable SSN. Cobalt Strike's `steal_token` BOF and the Sliver `getsystem` module both route through this function. JuicyPotato / RoguePotato / PrintSpoofer first negotiate a SYSTEM token via the RPC coercion trick, then call NtOpenProcessTokenEx against the spawned process to retrieve a duplicable handle, then NtDuplicateToken + CreateProcessWithTokenW to spawn SYSTEM-context cmd.exe. The Make-Me-Admin UAC bypass family uses it to clone the medium-IL token's elevated split sibling.

Cobalt StrikeSliverJuicyPotato / RoguePotato (tooling)PrintSpoofer (tooling)ContiRoyal Ransomware

Detection opportunities

Identical detection surface to NtOpenProcessToken: 4672 (Special Privileges Assigned, SeDebugPrivilege), 4663 (object access on Token), 4673 (Sensitive Privilege Use). For LSASS specifically, RunAsPPL forces the call to fail with STATUS_ACCESS_DENIED unless the caller is also PPL — a high-signal failure event. ETW `Microsoft-Windows-Kernel-Audit-API-Calls` emits `PsOpenProcessToken` regardless of which Nt variant was called. EDRs commonly hook this in ntdll; direct syscalls bypass that but the kernel-side object-access audit remains.

Direct syscall examples

asmx64 direct stub (stable SSN 0x30)

; SSN 0x30 stable across Win10 1507 -> Win11 24H2.
NtOpenProcessTokenEx PROC
    mov  r10, rcx          ; ProcessHandle
    mov  eax, 30h          ; SSN
    syscall
    ret
NtOpenProcessTokenEx ENDP

cOpen elevated token for cross-session UAC clone (Make-Me-Admin)

// Locate the elevated split-token sibling of the current medium-IL process
// and ask for TOKEN_DUPLICATE so we can spawn a high-IL process with it.
HANDLE hElev = NULL, hTok = NULL;
// hElev = handle to a high-IL svchost / consent.exe we previously opened
NTSTATUS s = NtOpenProcessTokenEx(
    hElev,
    TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY,
    0,                       // HandleAttributes
    &hTok);
if (NT_SUCCESS(s)) {
    // Next: NtDuplicateToken(... TokenPrimary ...) -> CreateProcessWithTokenW
}

rustwindows-sys wrapper with naked-asm direct syscall

use std::arch::asm;
use windows_sys::Win32::Foundation::HANDLE;

#[unsafe(naked)]
pub unsafe extern "system" fn nt_open_process_token_ex(
    _process: HANDLE,
    _desired: u32,
    _handle_attrs: u32,
    _token_out: *mut HANDLE,
) -> i32 {
    asm!(
        "mov r10, rcx",
        "mov eax, 0x30",
        "syscall",
        "ret",
        options(noreturn),
    );
}

MITRE ATT&CK mappings

Last verified: 2026-05-20