# Windows handle lab: recorded results

These are the recorded results for "When do Windows file permissions take
effect?" Use the separate `windows-handle-lab.zip` from the post to run the lab.

## Open a recorded run

Extract this ZIP and open PowerShell in the extracted folder. For experiment 1:

```powershell
$report = Get-Content .\experiment-1\results.json -Raw | ConvertFrom-Json
$report.Results[0].Observations |
    Select-Object Sequence, Api, Success, Win32Error, HandleValue, GrantedAccess
```

Observations 2 and 4 show handle `0x960` with the same grant, `0x00120196`, before
and after the DACL change. Its write succeeds; observation 6's new open fails.

To inspect the filesystem events for experiment 3:

```powershell
Import-Csv .\experiment-3\events.csv |
    Select-Object 'Time of Day', Operation, Result, Detail
```

Its JSON records matching post-change markers and reader/writer file
identities. Procmon supplies the ordering, offsets, lengths, and results.

## What's in each folder

The `experiment-1` through `experiment-7` folders hold the original runs:

| File | Contents |
| --- | --- |
| `results.json` | API results, errors, measured grants, markers, file identity, and DACL restoration for experiments 1-6 |
| `api-output.txt` | Saved console output for experiments 2-7 |
| `events.csv` | Every exported Procmon row for that run's PID and exact target file, in capture order |
| `capture.json` | Run times, PID, event counts, original PML hash, and source/tool hashes where recorded |

Experiment 1's excerpt comes from JSON; no original console transcript was
saved. CSVs include event types hidden in the screenshots. Raw PML files and
their process, stack, and system metadata remain local.

`fresh-runs` holds the terminal repeats from 14 October, without Procmon
recording. Experiment 1 includes `icacls` output from the pause between the
DACL change and retained-handle write. The helper supplied the Enter input.
The screenshots show selected live output; complete lab output is saved here.

Terminal images are cropped below the final results and cleanup confirmation.
Their links open the full-window originals.

## Reading the results

All runs passed and verified DACL restoration. Compare `OriginalDacl` and
`RestoredDacl` in each PowerShell result; the C++ transcript reports restoration.

Use API records alongside the CSVs. Experiment 2's rejected write has no
`WriteFile` row, and experiment 6's mapped-memory read has no `ReadFile` row.

Match reports and CSVs by PID. Handle values differ between the original runs
and repeats.

## Account names and paths

Account identifiers and local paths use consistent placeholders:

| Placeholder | Replaces |
| --- | --- |
| `<LAB_USER>`, `<LAB_USER_SID>` | The account running the lab |
| `<OTHER_ACCOUNT_SID_N>` | Another local account listed in an original ACL |
| `<CAPTURE_ROOT>`, `<BLOG_ROOT>`, `<USERPROFILE>` | Local directories |

Well-known SIDs, including `S-1-0-0`, are unchanged. Measurements, timestamps,
PIDs, markers, file identities, permission bits, and event order are preserved.

Placeholder SIDs make these DACL strings unsuitable for Windows APIs or the
recovery script. Use your own run's original backup for recovery.

## Hashes and test environment

`manifest.json` lists hashes for these files, their original inputs, the lab
sources, and full-window screenshots. `DisplayCropPixels` records the displayed
region. Account and path substitutions change a file's hash; both public and
original hashes are recorded.

The seven original runs were recorded on 13 October 2026 on CHAD-Z1, Windows
11 Business build 26200.9457, x64, with Procmon 4.11. Experiments 1-6 used
PowerShell 7.6.5. The C++ companion used GCC/MinGW-w64 16.2.0. The terminal
repeat runs on 14 October used Windows build 26200.9711.

These records cover local NTFS files on that machine. They do not include an
injection attack, a kernel-debugger session, an MSVC build, an ARM64 run, or
SMB access.
