fse_dump 3.1.2

Dumps the fseventsd entries from a mac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
# fse_dump

FSEvents files are written to disk by macOS APIs and contain historical records
of file system activity that occurred for a particular volume. They can be
found on devices running macOS and devices that were plugged in to a device
running macOS. **fse_dump** can be used to parse FSEvents files from the
`/System/Volumes/Data/.fseventsd/` on a live system or FSEvents files
extracted from an image.

![Github CI](https://github.com/lespea/fse_dump/actions/workflows/ci.yml/badge.svg)
![Github Release](https://github.com/lespea/fse_dump/actions/workflows/release.yml/badge.svg)
[![Crates.io](https://img.shields.io/crates/v/fse_dump.svg)](https://crates.io/crates/fse_dump)

## Features

- Parse FSEvents files from macOS (versions 1, 2, and 3)
- Export to multiple formats: CSV, JSON, YAML
- Filter events by path (regex) and flags
- Compress output with gzip or zstd
- Watch mode for real-time parsing of new FSEvents files
- Generate unique path/operation summaries
- Fast parallel processing with memory-efficient design

## Installation

### From crates.io

```bash
cargo install fse_dump
```

### From source

```bash
git clone https://github.com/lespea/fse_dump
cd fse_dump
cargo build --release
```

### With optional features

```bash
# Build with zstd compression support
cargo install fse_dump --features zstd

# Build with watch mode (requires notify)
cargo install fse_dump --features watch

# Build with all features
cargo install fse_dump --all-features
```

## Quick Start

### Parse FSEvents to JSON

```bash
# Parse default FSEvents directory to JSON
fse_dump dump --json output.json

# Parse with compression
fse_dump dump --json output.json.gz

# Parse specific files
fse_dump dump --json output.json /path/to/fsevent/file1 /path/to/file2
```

### Filter Events

```bash
# Filter by path (regex)
fse_dump dump --json output.json -p ".*\.pdf$"

# Filter by any of the specified flags
fse_dump dump --json output.json -f Created Modified

# Filter requiring all specified flags
fse_dump dump --json output.json --all-flags FileEvent Modified

# Combine filters
fse_dump dump --json output.json \
  -p "/Users/.*" \
  -f Created Removed
```

### Watch Mode

```bash
# Watch for new FSEvents files and output as JSON
fse_dump watch

# Watch with filters
fse_dump watch -o json -P \
  -p ".*\.docx?$" \
  -f Modified
```

## Usage

```
Usage: fse_dump <COMMAND>

Commands:
  dump      Dump fsevents file into the wanted output files/format
  watch     Watch for new fse files, parse them, and write them to the desired output
  generate  Outputs shell completions for the desired shell
  help      Print this message or the help of the given subcommand(s)

Options:
  -h, --help     Print help
  -V, --version  Print version
```

### Dump Command

The `dump` command parses FSEvents files and outputs them in various formats.

```bash
fse_dump dump [OPTIONS] [FILES]...
```

#### Arguments

- `[FILES]...` - The FSEvents files to parse (default: `/System/Volumes/Data/.fseventsd/`)
  - Can be individual files or directories
  - Directories are scanned for files with hex-only filenames
  - Files are sorted by name before processing

#### Output Format Options

**Individual File Output** (creates output file next to each input file):

- `--csvs` - Create `.csv` file for each FSEvents file
- `--jsons` - Create `.json` file for each FSEvents file  
- `--yamls` - Create `.yaml` file for each FSEvents file

**Combined Output** (all records in one file):

- `-c, --csv <FILE>` - Write all records to a single CSV file
- `-j, --json <FILE>` - Write all records to a single JSON file
- `-y, --yaml <FILE>` - Write all records to a single YAML file
- `-u, --uniques <FILE>` - Write unique paths with combined operations to CSV

Use `-` as the filename to write to stdout:

```bash
fse_dump dump --json - | jq .
```

#### Compression Options

**Automatic Compression** (based on file extension):

```bash
# Gzip compression (automatic)
fse_dump dump --json output.json.gz

# Zstd compression (automatic, requires zstd feature)
fse_dump dump --json output.json.zst
```

**Force Compression**:

- `--gzip` - Force gzip compression (even for stdout)
- `--zstd` - Force zstd compression (requires zstd feature)
- `-l, --glevel <0-9>` - Gzip compression level (default: 7)
- `--zlevel <0-20>` - Zstd compression level (default: 10)
- `--zthreads <N>` - Zstd threads (default: 2, 0 to disable)

#### Time Filtering

- `-d, --days <N>` - Only process files modified in the last N days (default: 90)
  - Set to 0 to process all files regardless of age
  - Based on file modification/creation time

#### Event Filtering

Filter which events are included in the output:

**Path Filtering**:

- `-p, --path-filter <REGEX>` - Only include events matching the regex pattern

```bash
# Only PDF files
fse_dump dump --json output.json -p "\.pdf$"

# Only files in /Users directory
fse_dump dump --json output.json --path-filter "^/Users/"

# Multiple patterns (use regex alternation)
fse_dump dump --json output.json -p "\.(pdf|docx?|xlsx?)$"
```

**Flag Filtering**:

- `-f, --any-flags <FLAG>...` - Include events with ANY of these flags
- `--all-flags <FLAG>...` - Include events with ALL of these flags

These options are mutually exclusive.

**Available Flags**:

| Flag | Description |
|------|-------------|
| `FolderEvent` | Event occurred on a folder |
| `Mount` | Volume was mounted |
| `Unmount` | Volume was unmounted |
| `EndOfTransaction` | End of a transaction |
| `LastHardLinkRemoved` | Last hard link to file removed |
| `HardLink` | Hard link created |
| `SymbolicLink` | Symbolic link created |
| `FileEvent` | Event occurred on a file |
| `PermissionChange` | Permissions were changed |
| `ExtendedAttrModified` | Extended attributes modified |
| `ExtendedAttrRemoved` | Extended attributes removed |
| `DocumentRevisioning` | Document versioning event |
| `ItemCloned` | Item was cloned |
| `Created` | File/folder was created |
| `Removed` | File/folder was removed |
| `InodeMetaMod` | Inode metadata modified |
| `Renamed` | File/folder was renamed |
| `Modified` | File/folder was modified |
| `Exchange` | Files exchanged |
| `FinderInfoMod` | Finder info modified |
| `FolderCreated` | Folder was created |

**Flag names are case-insensitive.**

**Examples**:

```bash
# Find all file creation or removal events
fse_dump dump --json output.json -f Created Removed

# Find all modified files (not folders)
fse_dump dump --json output.json --all-flags FileEvent Modified

# Find files created in the Documents folder
fse_dump dump --json output.json \
  -p "/Documents/" \
  -f Created

# Find permission changes on system files
fse_dump dump --json output.json \
  -p "^/(System|Library)/" \
  -f PermissionChange
```

#### Complete Examples

```bash
# Parse last 30 days to compressed JSON
fse_dump dump --days 30 --json events.json.gz

# Create CSV and JSON for each FSEvents file
fse_dump dump --csvs --jsons

# Export unique paths to CSV
fse_dump dump --uniques unique_paths.csv

# Parse specific file to stdout with filters
fse_dump dump --json - \
  -p "/Users/alice/" \
  -f Modified Created \
  /path/to/fsevent/file

# Multiple outputs with compression
fse_dump dump \
  --json all_events.json.gz \
  --csv all_events.csv.gz \
  --uniques unique_paths.csv \
  --days 7
```

### Watch Command

The `watch` command monitors directories for new FSEvents files and parses them in real-time.

```bash
fse_dump watch [OPTIONS] [WATCH_DIRS]...
```

#### Arguments

- `[WATCH_DIRS]...` - Directories to watch (default: `/System/Volumes/Data/.fseventsd/`)

#### Options

- `-o, --format <FORMAT>` - Output format: `csv`, `json`, or `yaml` (default: `json`)
- `-P, --pretty` - Pretty-print JSON output (multi-line formatting)
- `--poll` - Use polling instead of native file system events (slower but more compatible)

**Compression options** (same as dump command):
- `--gzip`, `--zstd`, `-l, --glevel`, `--zlevel`, `--zthreads`

**Filtering options** (same as dump command):
- `-p, --path-filter <REGEX>`
- `-f, --any-flags <FLAG>...`
- `--all-flags <FLAG>...`

#### Examples

```bash
# Watch default directory and output JSON to stdout
fse_dump watch

# Watch with pretty-printed JSON
fse_dump watch -o json -P

# Watch and filter for document changes
fse_dump watch \
  -p "\.(doc|pdf|txt)$" \
  -f Modified Created

# Watch custom directory with CSV output
fse_dump watch -o csv /custom/fsevents/path

# Watch with compression (pipe to file)
fse_dump watch --gzip > events.json.gz
```

### Generate Command

Generate shell completion scripts for various shells.

```bash
fse_dump generate <SHELL>
```

#### Supported Shells

- `bash`
- `elvish`
- `fish`
- `powershell`
- `zsh`

#### Examples

```bash
# Generate completions for bash
fse_dump generate bash > ~/.local/share/bash-completion/completions/fse_dump

# Generate completions for zsh
fse_dump generate zsh > ~/.zsh/completions/_fse_dump

# Generate completions for fish
fse_dump generate fish > ~/.config/fish/completions/fse_dump.fish
```

## Output Format

### Record Fields

Each FSEvents record contains the following fields:

```json
{
  "path": "/Users/alice/Documents/file.txt",
  "event_id": "0x12ab34cd",
  "flags": "FileEvent | Modified",
  "node_id": "0x56ef78",
  "extra_id": "0x9abc"
}
```

- `path` - Full path to the file/folder
- `event_id` - Unique event identifier (hex format if built with `hex` feature)
- `flags` - Human-readable flag names separated by ` | `
- `alt_flags` - Alternative flag interpretation (if built with `alt_flags` feature)
- `node_id` - Inode number (v2 and v3 only, hex format if built with `hex` feature)
- `extra_id` - Additional ID (v3 only, requires `extra_id` feature)

### Unique Output Format

The `--uniques` option produces aggregated records:

```csv
path,counts,flags
/Users/alice/file.txt,5,"FileEvent | Modified | Created"
/Users/alice/Documents,3,"FolderEvent | Modified"
```

- `path` - The file/folder path
- `counts` - Number of events for this path
- `flags` - Combined flags (bitwise OR of all events)

## Advanced Usage

### Filtering Complex Scenarios

**Find all deletions in user directories**:
```bash
fse_dump dump --json deletions.json \
  -p "^/Users/" \
  -f Removed
```

**Find renamed files (with old and new names)**:
```bash
fse_dump dump --json renames.json \
  -f Renamed
```

**Monitor system configuration changes**:
```bash
fse_dump dump --json system_changes.json \
  -p "^/(System|Library|etc)/" \
  -f Modified PermissionChange
```

**Find cloned/copied files**:
```bash
fse_dump dump --json clones.json \
  -f ItemCloned
```

### Combining with Other Tools

**jq for JSON processing**:
```bash
# Extract just the paths
fse_dump dump --json - | jq -r '.path'

# Find events for a specific user
fse_dump dump --json - | jq 'select(.path | startswith("/Users/alice"))'

# Count events by flag
fse_dump dump --json - | jq -r '.flags' | sort | uniq -c
```

**grep/awk for quick filtering**:
```bash
# Find all PDF operations
fse_dump dump --json - | grep '\.pdf"'

# CSV processing with awk
fse_dump dump --csv - | awk -F',' '$3 ~ /Created/ {print $1}'
```

### Performance Tips

1. **Use compression** for large outputs to save disk space
2. **Use `--days`** to limit processing to recent files
3. **Apply filters early** with `--path-filter` and `--any-flags` to reduce output size
4. **Use CSV** for the most compact output format
5. **Use `--uniques`** when you only need summary statistics

### Forensics Use Cases

**Timeline analysis**:
```bash
# Export everything from last 7 days
fse_dump dump --days 7 --json timeline.json.gz
```

**Malware detection** (find suspicious file operations):
```bash
# Find new executables
fse_dump dump --json suspicious.json \
  -p "\.(app|exe|sh|command|pkg|dmg)$" \
  -f Created

# Find hidden files
fse_dump dump --json hidden.json \
  -p "/\.[^/]+$" \
  -f Created Modified
```

**Data exfiltration** (find removable media):
```bash
# Monitor mounts/unmounts
fse_dump dump --json removable.json \
  -f Mount Unmount
```

**User activity**:
```bash
# Monitor specific user's home directory
fse_dump dump --json user_activity.json \
  -p "^/Users/targetuser/" \
  --days 30
```

## Building from Source

### Features

Optional features can be enabled during build:

- `zstd` - Enable zstd compression support
- `watch` - Enable watch mode for real-time monitoring
- `hex` - Output numeric IDs in hexadecimal format
- `alt_flags` - Include alternative flag interpretations
- `extra_id` - Include extra_id field from v3 files

```bash
# Build with specific features
cargo build --release --features "zstd,watch"

# Build with all features
cargo build --release --all-features
```

### Development

```bash
# Run tests
cargo test

# Run with debug logging
RUST_LOG=debug cargo run -- dump --json output.json

# Check code
cargo clippy
cargo fmt
```

## References

- http://nicoleibrahim.com/apple-fsevents-forensics/
- https://github.com/dlcowen/FSEventsParser

## License

Licensed under either of

- Apache License, Version 2.0, ([LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.