GLEAPP v2026.5.0
The macOS builds have been withdrawn from this release.
They do not start. A library collision inside the bundle makes
import cv2fail, so
the app exits immediately withSymbol not found: _hb_coretext_font_create. This is
not the Gatekeeper warning, and allowing the app in System Settings does not help. If
you downloaded one, it will not work and there is nothing you can do locally about it.The Windows and Linux builds are still attached. The library that fails, pangocairo,
is in neither of those bundles.A fixed macOS build will follow in the next release.
GLEAPP triages and analyzes large sets of images and video for digital forensics. It
ingests media from folders, full filesystem extractions and disk images, hashes and
de-duplicates it, pulls metadata, extracts video key frames, matches against known hash
lists, and gives you a local review gallery to work the backlog in.
This is the first public release.
Scope and intended use
GLEAPP is a defensive investigative tool for authorized examiners. It ships no
illegal-content hash database, downloads nothing, and performs no content
classification. Categorization is always a human decision. Every case is seeded with the
locked Project VIC 2.0 (US) scheme, codes 0 to 5, and you add your own from code 6.
Which file to download
| Platform | File |
|---|---|
| Windows 10 or 11, 64-bit | -windows-x64-setup.exe (installer), or -windows-x64-portable.zip to run without installing |
| macOS, Apple silicon | -macos-arm64.dmg |
| macOS, Intel | -macos-x64.dmg |
| Linux, 64-bit | -linux-x64.tar.gz |
The binaries are not signed
Expect a warning the first time you run one.
On macOS you get "GLEAPP cannot be opened because the developer cannot be verified".
Right-click the app, choose Open, then confirm.
On Windows, SmartScreen says "Windows protected your PC".
Choose More info, then Run anyway.
Signing is not wired up yet. If you would rather not clear a warning, run from source
instead; the README has the steps.
Verify what you downloaded
SHA256SUMS.txt covers every binary in this release. On macOS or Linux, from the folder
you downloaded into:
grep <the file you downloaded> SHA256SUMS.txt | shasum -a 256 -c -Use sha256sum in place of shasum -a 256 on Linux. On Windows, in PowerShell:
(Get-FileHash -Algorithm SHA256 .\<the file you downloaded>).Hashand compare it with the line in SHA256SUMS.txt, which is lower case.
Linux
The build is made on Ubuntu 24.04, so it needs glibc 2.39 or newer and will not start on
an older distribution. The native desktop window needs a GTK or Qt webview toolkit that
pip does not install, and CI does not exercise it, so gleapp web in a browser is the
tested path there.
Running from source
Python 3.10 through 3.14, on all three platforms. The README has the steps, and the full
manual is built into the app under the Help button and mirrored in docs/MANUAL.md.
Credits
GLEAPP is written by @charpy4n6. Free and open source under the MIT license.
Full changelog, every pull request since the repository was created
What's Changed
- Add CI: lint, test suite, runtime contract, Windows smoke by @abrignoni in #1
- Stop snapshots taken in the same millisecond overwriting each other by @abrignoni in #2
- Read case/hash-list JSON as utf-8-sig so a BOM doesn't break import by @charpy4n6 in #3
- Drop the thumbnail Fit/Fill toggle - grid thumbnails are always uncro… by @charpy4n6 in #4
- Feat/gui hash set import by @charpy4n6 in #5
- Remove the examiner name from the header by @charpy4n6 in #6
- Don't surface the local VIC-unpack folder in search or the shown path by @charpy4n6 in #7
- feat(report): KMZ geolocation export with embedded thumbnails by @charpy4n6 in #8
- Run the test suite on Windows, not just imports by @abrignoni in #9
- Install sqlite3 on the Windows runner, and unblock the required checks by @abrignoni in #10
- Run from source the way the other LEAPPs do by @abrignoni in #11
- Replace the PowerShell build script with a cross-platform Python driver by @abrignoni in #12
- Guard the one-file build against deleting a folder build, and fix a misleading comment by @abrignoni in #13
- Normalize line endings to LF with a .gitattributes by @abrignoni in #14
- Package a macOS .app and .dmg from the one-folder build by @abrignoni in #15
- Build on packaging changes and weekly, and enforce LF in the required test job by @abrignoni in #16
- Add agent guidance: cross-platform first, CI, build and release, PR workflow by @abrignoni in #17
- fix(imaging): decode Apple CgBI ("iPhone-optimised") PNGs by @charpy4n6 in #19
- Sniff audio-only ISO-BMFF files as other instead of video by @abrignoni in #20
- Ingest a full-file-system extraction zip as a source by @abrignoni in #18
- Read extraction zips in place by default, with a staged mode and source relinking by @abrignoni in #21
- Keep local absolute paths out of stored error text by @abrignoni in #22
- Add Copy into case and Drop copies buttons to the gallery's Source section by @abrignoni in #23
- Floor Pillow at 10.2 so the bundled libjpeg-turbo cannot corrupt thumbnails by @abrignoni in #24
- Keep the source archive's path out of stored archive-unavailable errors by @abrignoni in #25
- Keep the ingest path out of the CSV, HTML, KML and JSON exports by @abrignoni in #26
- Tidy what a removed path leaves in scrubbed error text by @abrignoni in #28
- Accept tar and compressed tar extractions as archive sources by @abrignoni in #29
- Register a file once when an Android extraction carries it under several storage views by @abrignoni in #31
- feat(hashstore): GUI panel to add NSRL / reference data to the global… by @charpy4n6 in #32
- feat(launcher): browse button for extraction archives by @charpy4n6 in #33
- feat(web): filter sidebar — pinned primaries + collapsible feature se… by @charpy4n6 in #34
- Add offline basemaps for the gallery map by @abrignoni in #35
- Add rendered location maps to the HTML report by @abrignoni in #36
- feat(web): full-size button on the details-pane GPS map by @charpy4n6 in #37
- fix(web): limit recent cases shown in launcher to 3 by @charpy4n6 in #38
- Fix/find similar includes self by @charpy4n6 in #39
- fix(web): a group view (stack=/vstack=) now ignores every other filter by @charpy4n6 in #40
- fix(similar): find-similar requires dHash agreement, skips near-featureless pHash by @charpy4n6 in #41
- Read an E01 acquisition as a source and carve its media by @abrignoni in #42
- Write the case as a LAVA project by @abrignoni in #43
- Key frames, Project VIC records, and the lists that were checked by @abrignoni in #44
- The third grouping tier, and what the category names mean by @abrignoni in #45
- Keep the Series and Tags a Project VIC record carried by @abrignoni in #46
- Correct nine claims the artifact notes and descriptions made by @abrignoni in #48
- Walk an acquisition's filesystems, and carve only what a walk cannot reach by @abrignoni in #47
- Re-vendor qnxprobe 1.20, so a scoped carve works on a real disk by @abrignoni in #49
- Leave an artifact with no rows out of the LAVA report by @abrignoni in #50
- Re-vendor qnxprobe 1.21, so a Mac image scopes too by @abrignoni in #51
- Carry a FAT volume's recorded times to the examiner, as stored by @abrignoni in #52
- Take qnxprobe 1.23, so an HFS+ volume is not recorded as unreadable by @abrignoni in #53
- Processing history: a case run log with per-stage outcomes by @charpy4n6 in #54
- Stop copying a walked file's sniff bytes twice by @abrignoni in #55
- Do not read a macOS sidecar as the image it is named after by @abrignoni in #56
- Say how a source's rows were recovered, from the rows by @abrignoni in #57
- Offer the LAVA report in the export dialog by @abrignoni in #58
- Say what the ingest accepts, and what it read by @abrignoni in #59
- Reach E01 carving from the launcher and the gallery by @charpy4n6 in #60
- Nested archive expansion + list view (land on main) by @charpy4n6 in #63
- Grid and list share one sort by @charpy4n6 in #64
- Drop the near-dup cluster sort and filter from the sidebar by @charpy4n6 in #65
- Give carving and archives their own sidebar sections by @charpy4n6 in #66
- Say on the map that its points can be clicked by @abrignoni in #67
- Recover deleted NTFS files from the MFT, resident ones included by @abrignoni in #68
- Recover deleted files from FAT32 and exFAT too by @abrignoni in #69
- Re-vendor mediacarve with the vendor-box carver fix by @abrignoni in #70
- Update the docs for FAT32 and exFAT deleted recovery by @abrignoni in #71
- Show the times FAT and exFAT recorded in the gallery by @abrignoni in #72
- Store PhotoDNA under its own algo instead of labelling it pHash by @abrignoni in #73
- Trim launcher ingest blurb, reorder evidence buttons by @charpy4n6 in #74
- Fill in the hashes an import did not supply, and keep them on error by @abrignoni in #75
- Carry what a Project VIC entry records by @abrignoni in #76
- Bring the manual up to date and cut the em dashes by @charpy4n6 in #77
- Correct the report map docs, and offer the maps toggle in the Export dialog by @abrignoni in #78
- Skip the report locator for a file outside the basemap by @abrignoni in #79
- Isolate the per-user config directory for the whole test session by @abrignoni in #80
- Expand the Maps section of the manual by @abrignoni in #81
- Expand the carving section of the manual by @abrignoni in #82
- Describe what carve_source does now that a carve can be scoped by @abrignoni in #83
- Scope a carve to nothing when a disk reports nothing free by @abrignoni in #85
- Correct the module docstring: FAT32's dates are read by @abrignoni in #86
- Report how each file was recovered, and the filesystem times an acquisition holds by @abrignoni in #84
- Follow qnxprobe 1.24 and the origin work in the manual by @abrignoni in #87
- Docs: origin has three values, in the passages #87 left by @abrignoni in #88
- Re-vendor qnxprobe 1.25 by @abrignoni in #89
- feat(report): a clickable, clustered locator map for the HTML report by @charpy4n6 in #90
- feat(web): CSV unchecked by default, and a notification bell for exports by @charpy4n6 in #91
- feat(web): group the header toolbar into a ☰ Menu, and rebalance the layout by @charpy4n6 in #92
- feat(web): show active filters as removable chips, not just a count by @charpy4n6 in #93
- feat(web): add Reference data (NSRL) to the ☰ Menu by @charpy4n6 in #94
- feat(web): make Maps/Hash stash/NSRL reference data reachable pre-case by @charpy4n6 in #95
- feat(web): per-case hash-stash toggle, and NSRL/stash "Show" filters by @charpy4n6 in #96
- Re-vendor qnxprobe 1.28 (reads F2FS) by @abrignoni in #97
- Re-vendor qnxprobe 1.29 (F2FS reports its free space) by @abrignoni in #98
- fix(web): hex viewer header stacked vertically instead of one row by @charpy4n6 in #99
- fix(web): video-duration and face-count tile badges overlapped by @charpy4n6 in #100
- feat(web): "Lighten dark areas" now works on video, not just photos by @charpy4n6 in #101
- feat: face matching for photos and video key frames by @charpy4n6 in #102
- docs: credit SFace and the vendored disk-image tools by @charpy4n6 in #103
- feat(web): show the face box on the details pane's own preview too by @charpy4n6 in #104
- Hide "This case" in the hash stash dialog pre-case; relabel sharing buttons by @charpy4n6 in #107
- Download as PDF for the manual by @charpy4n6 in #108
- Ingest screen: browse-to-file/folder, and label cleanup by @charpy4n6 in #109
- Give the hash stash its own .hstash extension, not .gleapp by @charpy4n6 in #110
- App-wide default agency logo for report headers by @charpy4n6 in #106
- Loading indicator while a case opens by @charpy4n6 in #111
- Recent cases: Show more / Show less, and Clear recent cases by @charpy4n6 in #105
- Add evidence to an already-open case by @charpy4n6 in #112
- feat: attribute and detail processing history entries correctly by @charpy4n6 in #113
- Fix duplicated script block breaking the entire gallery by @charpy4n6 in #114
- Give the shared background-job bar its own footer, real progress, and a consistent start by @charpy4n6 in #115
- Advance to the next file on categorize under any filter by @charpy4n6 in #116
- Make the left filters pane and right details pane resizable by @charpy4n6 in #117
- Skin-tone ratio filter: slider with a live percentage by @charpy4n6 in #118
- fix(web): make each source's walked/carved/volumes detail collapsible by @charpy4n6 in #119
- fix(web): hover-scrub a video across the whole file, not just key frames by @charpy4n6 in #120
- fix(web): collapse the report's stats section by default, styled like Locations by @charpy4n6 in #121
- docs: explain the red vs blue location markers on the report's overview map by @charpy4n6 in #123
- fix(web): make each card's locator map click to open full size by @charpy4n6 in #122
- fix(web): move the category/selection bar to the top, drop the shortcut legend by @charpy4n6 in #124
- fix(web): replace the Add-tag browser prompt() with a proper dialog by @charpy4n6 in #125
- fix(web): show each category's real hotkey in the category editor by @charpy4n6 in #126
- fix(web): remove the category picker from the details pane by @charpy4n6 in #127
- fix(desktop): install pywebview from requirements.txt, and say so when it is missing by @abrignoni in #128
- docs: correct the py7zr wheel and bundle notes by @abrignoni in #129
- fix(pipeline): keep a container row's expansion error through processing by @abrignoni in #130
- fix(db): serialize get_meta reads against the connection lock by @charpy4n6 in #131
- feat(flags): add Flags as a data model independent of category by @charpy4n6 in #132
- feat(flags): gallery UI for categorizing and flagging a file by @charpy4n6 in #133
- feat(flags): render flags in reports, plus flag-scoped exports and CLI by @charpy4n6 in #134
- fix(web): wrap long metadata values in the details pane instead of scrolling by @charpy4n6 in #135
- fix(web): keep the review toolbar on fewer rows with the Details pane open by @charpy4n6 in #136
- feat(windows): recover thumbnail-cache images and name them via the Search index by @charpy4n6 in #137
- Read an APFS volume's catalog in one pass before walking it, with qnxprobe 1.30 by @abrignoni in #140
- Import a national Project VIC hash set by @abrignoni in #138
- Carry a Project VIC hash-set record onto the files that match it by @abrignoni in #139
- Correct the Project VIC notes and docs against the code by @abrignoni in #141
- feat(vic): a Project VIC menu, and a file that hits several sources keeps them all by @charpy4n6 in #142
- Keep a Project VIC record's own set and category in LAVA beside other matches by @abrignoni in #143
- Rename the Grid view toggle to Gallery by @charpy4n6 in #144
- Bring the manual and in-app help up to date with the UI by @charpy4n6 in #145
- Return to where you were after a search or group view by @charpy4n6 in #146
- Docs: LEAPP family name, trim some lines, drop em dashes by @charpy4n6 in #147
- Take a raw disk image, one file or a numbered split set, as a source by @abrignoni in #148
- docs: shorten Getting started, move the VIC import notes to their sections by @charpy4n6 in #149
- docs: lay out section 3 as tables and short lists by @charpy4n6 in #150
- fix(web): tile badge colors, and show both stack badges by @charpy4n6 in #151
- docs: break up section 6 (The details pane) into tables by @charpy4n6 in #152
- docs: trim section 7 and fix the section 1 pointer to it by @charpy4n6 in #153
- docs: add a Maps quick start and a North America example by @charpy4n6 in #154
- docs: make sections 8, 11, 13 and 16 easier to read, and fix what an audit found by @charpy4n6 in #155
- Ship a build with no GPL code, and gate it so it stays that way by @abrignoni in #156
- Carry the third-party notices inside the build by @abrignoni in #157
- Carry Microsoft's WebView2 terms, and correct what they are by @abrignoni in #158
- Say which macOS wheels carry the GPL FFmpeg by @abrignoni in #159
- Add an Expand archives checkbox to the ingest screens by @charpy4n6 in #160
- Keep the hashes of an empty file out of case hash sets, and never match them by @abrignoni in #161
- Refuse a SQLite hash database in a case import and name the global store by @abrignoni in #162
- Make the stash's eligible count match Add, and re-check SHA-1-only files by @abrignoni in #163
- Run the isolated workers from any directory, and walk the whole MP4 before calling its header missing by @abrignoni in #164
- Name what an MP4 holds when it gives no frames, instead of guessing truncation by @abrignoni in #166
- Refuse a hash list with nothing to import, and say what was skipped by @abrignoni in #165
- Refuse a SQL script with the file to pick, and show a job refusal as its reason by @abrignoni in #167
- Ship YuNet's licence beside the model and in the notices by @abrignoni in #168
- Ship every tracked file under gleapp/ in the wheel, and check it in CI by @abrignoni in #169
- Declare the licence as an SPDX string and require setuptools 77 by @abrignoni in #170
- Name every bundled licence in the wheel's metadata by @abrignoni in #171
- Warn that expanding archives adds processing time by @charpy4n6 in #172
- Snapshots: choose the automatic interval, keep the ones you save by @charpy4n6 in #173
- Reattach a folder or Project VIC source that moved by @charpy4n6 in #174
- LAVA export: show HEIC and .THM images by @charpy4n6 in #175
- Gallery sort: Path sorts by file path, Size largest first, drop Capture date by @charpy4n6 in #176
- Gallery speed on large cases by @charpy4n6 in #177
- Review: whole-group categorize, and no skipped or vanishing pages by @charpy4n6 in #178
- Add the GLEAPP logo to the app, manual, report and builds by @charpy4n6 in #180
- Build release binaries from a version tag by @abrignoni in #179
- Make multi-file selection stand out in the logo's orange by @charpy4n6 in #181
- HTML report: link full-size originals, show progress, clearer flag headers by @charpy4n6 in #183
- Version 2026.5.0, and keep the two declarations equal by @abrignoni in #182
- Build for Intel Macs, and say what the Linux build runs on by @abrignoni in #184
- Find GPT partitions on disks of 4096-byte sectors by @abrignoni in #185
- Re-vendor qnxprobe 1.32 by @abrignoni in #187
- Build the Intel Mac leg in test_builds too by @abrignoni in #186
- Name the flash filesystems qnxprobe reads in the cross-platform rules by @abrignoni in #188
- Name the flash filesystems the walk reads on the screen and in the docs by @abrignoni in #189
- Re-vendor qnxprobe 1.34 by @abrignoni in #190
- Keep face boxes aligned when the details pane is resized by @charpy4n6 in #191
New Contributors
- @abrignoni made their first contribution in #1
Full Changelog: https://github.com/abrignoni/GLEAPP/commits/v2026.5.0