---
brand: mobula
audience: practitioners
indexable: true
claims: []
# content_id: the campaign join key (Atlantis MEASUREMENT-DESIGN §3.1). Minted here, once, for the
# life of the asset; never reused, never renamed. This README is its one home in this asset —
# MATRIX.md and meta.json point here rather than repeating it. The board looks the label up in
# /content-registry.json at render; nothing copies the id into a database.
content_id: lolbin-dash-matrix
---

# Dash / Unicode LOLBIN parser-acceptance matrix

## What it is

A measured table of which in-box Windows binaries accept a Unicode dash- or slash-like
character in place of an ordinary hyphen (`-`) or forward slash (`/`) at the start of a
command-line switch — plus the probe that produces the table, so anyone can reproduce it on
their own Windows build. `MATRIX.md` is the result; `probe/` is the instrument.

## Why a detection engineer cares

Argument-parser leniency is a detection blind spot: many Windows binaries normalise a Unicode
look-alike (an en dash `–`, a fullwidth solidus `／`, a non-breaking hyphen `‑`) back to the
ASCII switch character *inside their own parser*, so the switch runs exactly as intended while a
rule or filter matching the literal `-`/`/` sees nothing it recognises. This matrix tells you,
per binary and per switch, which of those substitutions actually parse — the difference between a
detection that holds and one that is walked straight past.

## How to run the probe

The probe is two steps, and the grading step needs no network and no Windows:

1. On a **disposable** Windows box (a VM or a sandbox, never a machine you care about — the probe
   launches real binaries), run the measurement:

   ```powershell
   powershell -ExecutionPolicy Bypass -File probe/guest-runner.ps1 `
     -MatrixPath probe/matrix.json -OutPath runs/results.ndjson
   ```

   Every target is an invalid value or a path that does not exist, so each binary can only fail;
   the measurement is in *how* it fails. Every switch is built from raw code points on the box
   itself, and every row records the hex of the exact UTF-16 argument string that reached the
   process — so a dash that silently arrived as a hyphen cannot masquerade as a result.

2. Grade the raw rows offline, on any machine with Node.js:

   ```bash
   node probe/rederive.mjs --run runs
   ```

   This re-derives every verdict from the stored responses and writes `cells.json`,
   `terminators.json` and `summary.json` beside `results.ndjson`. Because the raw response of
   each probe *and of both its controls* is stored, the verdict rule can be corrected and the
   whole run re-graded without measuring anything again.

## How to read the matrix

`MATRIX.md` has one row per (binary, switch) pair and one column per character. Each cell is:

- **A — accepted:** the parser treats this character as a switch introducer. A hyphen-only
  detection misses this invocation.
- **R — rejected:** the character is not accepted in place of the switch character.
- **· — indeterminate:** the binary does not support the switch in the form tested, so no
  conclusion about the character can be drawn. Indeterminate is a real outcome and is never
  folded into the other two.

Acceptance is decided against **two controls** run for every cell: the binary's own canonical
prefix (what "this switch parsed" looks like) and `@`, a character that is never a switch
introducer (what "not parsed" looks like). A test character is ACCEPTED only when it reproduces
the canonical control in a form the binary is *proven* to accept.

## The self-correction

The first version of the verdict rule was wrong, and the code keeps the full account in
`probe/derive.mjs`. It read "the test response matches the canonical control" as proof of
acceptance. `tasklist /m` exposed the flaw: its canonical control `-m=<value>` does **not** parse
(tasklist rejects the `=` separator), and tasklist echoes the offending argument back with the
Unicode dash already normalised to `-` in its own error text — so two *failures* produced
byte-identical output and were read as a shared success. The corrected rule first establishes
that the canonical control itself parsed in the exact form under test; only then is a character
judged, and everything the instrument cannot separate is marked INDETERMINATE. The correction is
published deliberately: primary measurement is only worth as much as the discipline that catches
its own errors.

## Licence

Proposed: **MIT** (see `LICENSE`). Rationale in the LICENSE header — it is the least-friction
choice for a small tool plus a data table a stranger should be able to run, copy into their own
detection tests, and build on without asking. If a stronger attribution guarantee on the *data*
is wanted, a common alternative is to keep the code under MIT and place `MATRIX.md` under
CC BY 4.0; that split is a one-line change and is the founder's call.

## Provenance

- Measured on Windows build **26100**. Reproduce on any build with the steps above.
- No third-party detection content is bundled. **No Sigma rule or SigmaHQ content is referenced
  in this asset**, so no Sigma attribution is required. If you extend the matrix into detections,
  and any is derived from a Sigma rule, credit the author, link the rule, and honour its
  DRL 1.1 licence.
