NtResumeProcess
Decrements every thread's suspend count in a target process, resuming threads that reach zero.
Prototype
NTSTATUS NtResumeProcess( HANDLE ProcessHandle );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| ProcessHandle | HANDLE | in | Handle to the process to resume. Requires PROCESS_SUSPEND_RESUME. |
Syscall IDs by Windows version
| Windows version | Syscall ID | Build |
|---|---|---|
| Win10 1507 | 0x161 | win10-1507 |
| Win10 1607 | 0x168 | win10-1607 |
| Win10 1703 | 0x16E | win10-1703 |
| Win10 1709 | 0x171 | win10-1709 |
| Win10 1803 | 0x173 | win10-1803 |
| Win10 1809 | 0x174 | win10-1809 |
| Win10 1903 | 0x175 | win10-1903 |
| Win10 1909 | 0x175 | win10-1909 |
| Win10 2004 | 0x17B | win10-2004 |
| Win10 20H2 | 0x17B | win10-20h2 |
| Win10 21H1 | 0x17B | win10-21h1 |
| Win10 21H2 | 0x17D | win10-21h2 |
| Win10 22H2 | 0x17D | win10-22h2 |
| Win11 21H2 | 0x185 | win11-21h2 |
| Win11 22H2 | 0x188 | win11-22h2 |
| Win11 23H2 | 0x188 | win11-23h2 |
| Win11 24H2 | 0x18A | win11-24h2 |
| Server 2016 | 0x168 | winserver-2016 |
| Server 2019 | 0x174 | winserver-2019 |
| Server 2022 | 0x183 | winserver-2022 |
| Server 2025 | 0x18A | winserver-2025 |
Kernel module
Related APIs
Syscall stub
4C 8B D1 mov r10, rcx B8 8A 01 00 00 mov eax, 0x18A 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
NtResumeProcess mirrors NtSuspendProcess and is similarly undocumented. It iterates the EPROCESS ThreadListHead calling KeResumeThread on each entry; threads whose suspend count drops to zero return to the dispatcher's ready queue. Like its counterpart the SSN drifts almost every release (0x161 → 0x18A across the supported window), and like its counterpart it is the per-process counterpart to ResumeThread without requiring the caller to enumerate threads via Toolhelp / NtGetNextThread.
Common malware usage
Always appears paired with NtSuspendProcess. Its three main roles: (1) closing the **Fork & Run** loop — after injecting and executing post-exploitation logic in a sacrificial process, the implant calls NtResumeProcess on its own helper if it suspended itself between heartbeats, or on the BOF thread once setup is done; (2) finishing **process hollowing** by reviving the previously suspended target after the malicious image is in place and the thread context is patched; (3) thawing the database / EDR processes a ransomware suspended pre-encryption once the encryption pass completes and the operator wants the victim's services to come back up cleanly (a courtesy in double-extortion scenarios meant to make recovery dependent on the operator's good faith).
Detection opportunities
By itself NtResumeProcess is harmless — every debugger and the Windows runtime use it. The actionable telemetry is the *pair*: NtSuspendProcess → write/inject → NtResumeProcess from the same caller on the same target within a short window, especially when the target is a sacrificial-process candidate (rundll32.exe, notepad.exe, RuntimeBroker.exe) freshly spawned by the same caller. ETW `Microsoft-Windows-Kernel-Audit-API-Calls` exposes Resume invocations when the audit policy enables them; combine with Sysmon Event ID 10 (ProcessAccess) showing PROCESS_SUSPEND_RESUME being requested on a non-child process for a high-signal alert.
Direct syscall examples
asmx64 direct stub (Win11 24H2)
; Direct syscall stub for NtResumeProcess (SSN 0x18A on 24H2/2025)
; SSN climbs every release — resolve dynamically across builds.
NtResumeProcess PROC
mov r10, rcx ; syscall convention
mov eax, 18Ah ; SSN
syscall
ret
NtResumeProcess ENDPchollowing teardown
// Final step of a process-hollowing routine: after writing the malicious
// image, fixing the suspended thread's RIP and Rcx, we resume everything.
#include <windows.h>
typedef NTSTATUS (NTAPI *pNtResumeProcess)(HANDLE);
void FinishHollow(HANDLE hProcess, HANDLE hThread, CONTEXT *ctx) {
SetThreadContext(hThread, ctx);
pNtResumeProcess NtResumeProcess = (pNtResumeProcess)GetProcAddress(
GetModuleHandleA("ntdll.dll"), "NtResumeProcess");
NtResumeProcess(hProcess);
}rustthaw frozen DBs
// Cargo: windows-sys = "0.59"
use windows_sys::Win32::Foundation::HANDLE;
use windows_sys::Win32::System::Threading::{OpenProcess, PROCESS_SUSPEND_RESUME};
extern "system" { fn NtResumeProcess(handle: HANDLE) -> i32; }
pub unsafe fn thaw(pids: &[u32]) {
for &pid in pids {
let h = OpenProcess(PROCESS_SUSPEND_RESUME, 0, pid);
if !h.is_null() { NtResumeProcess(h); }
}
}MITRE ATT&CK mappings
Last verified: 2026-05-20