Asia/Calcutta
Posts

Windows Defender, PPL, and PUAs — Explained

June 21, 2026
Notes from investigating high CPU usage by MsMpEng.exe (Antimalware Service Executable).

  • MsMpEng.exe (Windows Defender's core process) was consuming ~84% CPU (system pinned at 100%).
  • It cannot be killedStop-Process returns "Access is denied" even as Administrator.
  • Reason: it runs as a Protected Process Light (PPL), enforced by the Windows kernel.
  • Likely trigger: two PUAs detected on the machine —
    • PUA:Win32/FRProxy
    • PUADlManager:Win32/Snackarcin

PUA = Potentially Unwanted Application (Microsoft also writes PUP — Potentially Unwanted Program). Not outright malware (no virus payload, doesn't encrypt files), but software that behaves in ways you probably didn't want and didn't clearly agree to. Defender flags it as a nuisance/risk, not a threat-to-survive. Typical traits:
  • Bundleware — piggybacked on a "free" installer.
  • Adware / browser hijackers — inject ads, change search engine/homepage.
  • Download managers that push more junk (e.g. Snackarcin).
  • Proxy / traffic redirectors (e.g. FRProxy — reroutes network traffic).
  • "PC optimizers" that nag you to pay.
PUADlManager : Win32 / Snackarcin
│             │       └─ malware family name
│             └───────── platform (32-bit Windows)
└─────────────────────── category (PUA, here a Download-Manager subtype)

PPL is not a flag you can set on any program. It is enforced by the Windows kernel and gated on code signing. A process can only run protected if its executable is signed with a special Microsoft-issued certificate that encodes a specific protection level. The kernel checks this signature at process creation — no valid cert, no protection. This is exactly why Defender survives "End Task": it is signed with the Antimalware EKU, so the kernel refuses any lower-privileged process the right to terminate it.
Signer typeProtection levelExample
PsProtectedSignerAntimalwarePPLMsMpEng.exe (Defender), 3rd-party AV
PsProtectedSignerLsaPPLLSASS (Credential Guard / RunAsPPL on)
PsProtectedSignerWindowsPPL / PPWindows components
PsProtectedSignerWinTcbPP (full)Core trusted computing base

                        RING 3  —  USER MODE
   ┌───────────────────────────────────────────────────────────────────┐
   │                                                                     │
   │   NORMAL process            PPL process            Your app         │
   │   (a PUA, your app)         MsMpEng.exe             (wants to kill)  │
   │   ┌───────────────┐         ┌───────────────┐      ┌────────────┐   │
   │   │ Protection: 0 │         │ Protection:   │      │Protection:0│   │
   │   │               │         │  PsProtected- │      │            │   │
   │   │  threads ───┐ │         │  SignerAnti-  │      │ Terminate- │   │
   │   │  T1 T2 T3   │ │         │  malware (PPL)│      │ Process() ─┼─┐ │
   │   └─────────────┼─┘         └───────────────┘      └────────────┘ │ │
   │                 │                   ▲                              │ │
   └─────────────────┼───────────────────┼──────────────────────────────┼─┘
        syscall ▼    │   (kernel checks "may I touch a PPL?")   request ▼│
   ════════════════════════════════════════════════════════════════════════
                        RING 0  —  KERNEL MODE
   ┌───────────────────────────────────────────────────────────────────┐
   │   NT Kernel (ntoskrnl.exe)                                          │
   │                                                                     │
   │   Each process = EPROCESS struct ──► holds PS_PROTECTION field      │
   │                                       { Type, Signer }              │
   │                                                                     │
   │   When "Your app" calls TerminateProcess on MsMpEng:               │
   │     kernel compares  caller.Protection  vs  target.Protection      │
   │         0  <  Antimalware-PPL   ──►  ACCESS_DENIED  ✗               │
   │                                                                     │
   │   ELAM driver + signed cert is what set that field at launch       │
   └───────────────────────────────────────────────────────────────────┘
   ════════════════════════════════════════════════════════════════════════
                        HARDWARE  (CPU enforces Ring 0 vs Ring 3)
Key idea: the kill request travels from your Ring-3 app → into the Ring-0 kernel → the kernel reads both processes' PS_PROTECTION and refuses, because 0 < PPL. That is the "Access is denied" you saw.
   HIGHER  ┌────────────────────────────────┐
     ▲     │  PP   WinTcb        (full PP)   │  ← can act on everything below
     │     ├────────────────────────────────┤
     │     │  PPL  Windows                   │
   can     ├────────────────────────────────┤
   touch   │  PPL  Lsa     (LSASS, creds)    │
   equal   ├────────────────────────────────┤
   or      │  PPL  Antimalware  ◄── MsMpEng  │  ← Defender lives here
   lower   ├────────────────────────────────┤
     │     │  Protection 0  (normal apps)    │  ← PUAs, Task Manager, your app
     ▼     └────────────────────────────────┘
   LOWER

   RULE:  a process may terminate/inject another ONLY IF
          its level  ≥  the target's level.
   So  "0"  can never kill  "Antimalware-PPL".  ✗

  Vendor binary (MsMpEng.exe)
        │
        │  1. Signed with Microsoft ANTIMALWARE certificate
        │     (carries a special EKU OID = protection level)
        ▼
  ELAM driver (loads early at boot)
        │  2. Declares which signing certs are "trusted antimalware"
        ▼
  CreateProcess( ... , PROTECTION_LEVEL_ANTIMALWARE )
        │
        ▼
  ┌─────────────── KERNEL at process creation ───────────────┐
  │  • verify signature + EKU  ──► valid?                     │
  │        NO  ──► launch as normal (Protection 0)            │
  │        YES ──► set EPROCESS.PS_PROTECTION = {PPL, Anti-   │
  │                malware}                                   │
  └──────────────────────────────────────────────────────────┘
        │
        ▼
  Process now runs as PPL — self-protected, unkillable from Ring 3
Why you can't do this for an arbitrary app: step 1 requires a Microsoft-issued cert you can't get for a normal program. No cert → kernel ignores the request → process launches at Protection 0. The only lab workaround is testsigning on + a self-signed cert + a kernel driver — strictly a test-machine exercise, with an on-screen watermark, and not valid on normal machines.
Killing MsMpEng.exe is impossible by design. Realistic paths instead:
  1. Remove the PUAs (recommended) — they are the likely cause and are Protection-0 (fully removable):
    Remove-MpThreat
    
  2. Run a quick scan to completion so Defender stops re-triggering:
    Start-MpScan -ScanType QuickScan
    
  3. Temporarily pause Real-Time Protection (leaves you unprotected; blocked if Tamper Protection is on; auto-re-enables on reboot):
    Set-MpPreference -DisableRealtimeMonitoring $true
    
  4. Lower MsMpEng priority — won't free CPU but stops it starving other apps.
Note: Windows Defender does not expose a live "% complete" for scans via any command/API. That percentage only appears in the Windows Security app while a manual scan is running.