mirlyDownload

blog · 2026-05-15

Stealth by documented OS API, not by trick — how Mirly stays out of screen share

Mirly's overlay is invisible to Zoom, Teams, Meet, and Webex because it uses NSWindow.sharingType on macOS and SetWindowDisplayAffinity on Windows — the same APIs 1Password and Netflix use. No kernel exploit, no hidden process, no thing-that-will-break-next-Tuesday.

The category gets this wrong

Every interview copilot promises "100% undetectable." Most of them achieve it through a combination of (a) starting with a borrowed Electron skeleton, (b) flipping alwaysOnTop: true, and (c) hoping. The result is a window that's invisible most of the time, until Zoom ships a build that switches its capture backend from BitBlt to DXGI Desktop Duplication, or macOS 14 changes the default CGWindowListCopyWindowInfo privacy semantics, and suddenly half the user base shows up on the interviewer's screen.

Mirly doesn't promise "undetectable forever." It promises something stronger and more verifiable: it uses the OS-level screen-capture exclusion API that Apple and Microsoft ship for exactly this purpose. The same API 1Password uses to keep your master password out of screen recordings. The same API Netflix uses for DRM playback. The same API Apple Pay uses to hide card numbers.

If our approach breaks, 1Password and Netflix break first. That's the bet.

macOS: NSWindow.sharingType = .none

Apple's API is NSWindow.sharingType. It's been documented since macOS 10.13 (2017). Values:

  • .readOnly (default) — window is visible in screenshots and screen recordings
  • .none — window is excluded from CGWindowListCreateImage, ScreenCaptureKit, and the screen-share APIs Zoom/Teams/Meet/Webex use

In Electron, you set it via the platform-specific native API at window creation:

// apps/desktop/src/main/index.ts
import { BrowserWindow } from 'electron'

const overlayWindow = new BrowserWindow({
  // ...other options
  type: 'panel',           // critical: panel windows participate in sharingType
})

// After window is created, on macOS:
if (process.platform === 'darwin') {
  overlayWindow.setContentProtection(true)
}

setContentProtection(true) is Electron's cross-platform wrapper. On macOS it sets sharingType = .none. On Windows it calls SetWindowDisplayAffinity(WDA_EXCLUDEFROMCAPTURE). One call, two platforms, both real APIs.

What this excludes:

  • cmd-shift-3 and cmd-shift-4 screenshots — overlay shows as black
  • ✅ macOS Screenshot.app screen recording — overlay shows as black
  • ✅ QuickTime screen recording — overlay shows as black
  • ✅ Zoom screen share (any mode: Desktop, Window, Application) — overlay excluded
  • ✅ Microsoft Teams screen share — overlay excluded
  • ✅ Google Meet screen share (Chrome's getDisplayMedia) — overlay excluded
  • ✅ Webex screen share — overlay excluded
  • ✅ OBS Studio Display Capture — overlay shows as black

What this does NOT exclude (be honest):

  • ❌ Someone pointing their phone camera at your screen
  • ❌ A second computer running screen-recording software while watching your screen via HDMI capture card
  • ❌ Specific accessibility / a11y readers that bypass the screen-capture pipeline entirely

We say this on the homepage. We don't promise what we can't deliver.

Windows: SetWindowDisplayAffinity(WDA_EXCLUDEFROMCAPTURE)

Microsoft's API is SetWindowDisplayAffinity. Available since Windows 10 build 2004 (May 2020 update). Two values matter:

  • WDA_NONE (0) — default; window is captured
  • WDA_EXCLUDEFROMCAPTURE (0x11) — window is excluded from BitBlt, PrintWindow, and DXGI Desktop Duplication

DXGI is the key. Modern screen-share apps on Windows use DXGI Desktop Duplication because BitBlt is too slow for 60fps. Older "stealth" tricks that worked against BitBlt (window-attribute hacks, layered windows) do not work against DXGI. WDA_EXCLUDEFROMCAPTURE works against both.

// What Electron calls under the hood, via the win.cc internal:
SetWindowDisplayAffinity(hWnd, WDA_EXCLUDEFROMCAPTURE);

The result on Windows mirrors macOS — overlay is black in every screen-share modality we've tested (Zoom, Teams, Meet, Webex, OBS).

Why this is more robust than "tricks"

Three failure modes that competitors hit and we don't:

  1. alwaysOnTop: true alone: the window is always on top of YOUR screen, but it's also fully captured by anything looking at YOUR screen. This is the most common implementation. It fails the moment you screen-share.

  2. Hidden process / disguised executable name: useful for hiding from Task Manager, useless against screen capture. Screen-share APIs operate on window handles, not process names. Renaming mirly.exe to system32_service.exe makes you look more suspicious, not less.

  3. Custom screen-buffer manipulation / DLL injection: works briefly, breaks on every OS update, triggers Windows Defender as malware. Some competitors ship this. We don't.

Why these APIs exist (and why they won't be removed)

Both Apple and Microsoft ship these APIs because legitimate apps depend on them:

  • Password managers (1Password, Bitwarden, LastPass) use them so that when you screen-share to debug something with a colleague, your unlocked vault doesn't appear in the recording.
  • DRM playback (Netflix, Disney+, Apple TV+) uses them to prevent screen-recording paid content. This is contractual with content owners; removing the API would break enterprise contracts.
  • Apple Pay uses them to hide card numbers from screen recording and screenshots.
  • Banking apps use them to hide account balances during screen share.
  • Healthcare apps use them for HIPAA compliance during telehealth calls.

If Apple removed NSWindow.sharingType, every bank's macOS app would break. If Microsoft removed WDA_EXCLUDEFROMCAPTURE, Netflix would file a lawsuit. These APIs are load-bearing across the OS ecosystem.

The test matrix we run every hour

Public API + our test harness:

  • Hetzner VM running headless macOS 14 + Windows 11
  • Real Zoom client, real Teams client, real Meet via Chrome, real Webex client
  • Start a fake "meeting", share screen, take a recording, OCR the recording for any text from the overlay
  • Result: green / amber / red per cell, posted to status.mirly.co.uk

If a Zoom update ever ships that breaks this, the relevant cell goes amber within an hour and we have a public SLA of 72 hours to ship a fix. The status page is the contract.

What we can't do, and won't claim

  • We can't hide from a screen recording started by separate hardware (HDMI capture, secondary camera). The OS exclusion API operates on the OS's own capture stack.
  • We can't hide from accessibility tools that read pixel buffers directly (rare in interview contexts).
  • We can't promise this works after a specific Zoom update we haven't seen yet — but the status page tells you, in real time, exactly which configurations are currently passing.

Stealth is an arms race. We don't pretend otherwise. We just publish the leaderboard.

Related reading