Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
608 commits
Select commit Hold shift + click to select a range
dfeb21c
Restore quantum feature overview in README
vee1e Jul 17, 2026
018ef3d
Install rich traceback once at floss main entry
vee1e Jul 17, 2026
0adb6bc
Use pytest pythonpath for scripts package imports
vee1e Jul 17, 2026
adda278
Rename test_scripts to test_disassembler_scripts
vee1e Jul 17, 2026
cfce1b7
fix(macho): remove redundant PE rsrc type info
vee1e Jul 18, 2026
cf704bc
refactor(language): share coverage CLI args and logging
vee1e Jul 19, 2026
d350f78
refactor(layout): thin package exports to compute_layout
vee1e Jul 19, 2026
f921069
refactor(tags): drop unused __all__
vee1e Jul 20, 2026
eb18719
Merge pull request #1337 from vee1e/refactor/first-class-modular
mr-tz Jul 21, 2026
4f14338
feat(results): add tags/section/structure and layout tree to ResultDo…
vee1e Jul 26, 2026
4f61efd
feat(enrich): project layout analysis onto static/language strings
vee1e Jul 26, 2026
1c37173
feat(pipeline): unify analysis with layout-aware static extraction
vee1e Jul 26, 2026
fb5a6cc
feat(render): quantum-style static output when layout is present
vee1e Jul 26, 2026
9eb2e48
refactor(tags): move databases from floss/qs/db/data to floss/tags/data
vee1e Jul 26, 2026
b38fcac
refactor: collapse quantum entry into unified floss CLI
vee1e Jul 26, 2026
08400af
style: fix isort, black, and mypy for unified pipeline
vee1e Jul 26, 2026
96437ba
refactor: remove interim floss.document re-export shim
vee1e Jul 27, 2026
e06e5d7
refactor: remove floss quantum entry point and alias
vee1e Jul 27, 2026
dd0211f
test: restore explanatory comments in test_qs
vee1e Jul 27, 2026
cda9f33
test: restore test_analysis_pipeline in test_qs
vee1e Jul 27, 2026
c090b94
refactor: drop floss.main re-exports; fix call sites
vee1e Jul 27, 2026
957b14d
refactor(render): non-mutating hide filter and single layout check
vee1e Jul 27, 2026
eb7354d
refactor(render): hoist layout render imports to module level
vee1e Jul 27, 2026
63fab3f
fix(render): always show enabled recovered-string sections
vee1e Jul 27, 2026
c1e027e
test: restore explanatory round-trip comments in test_qs
vee1e Jul 27, 2026
75c973a
refactor: drop unused Runtime.layout and Runtime.tags timings
vee1e Jul 27, 2026
1b05672
chore(readme): tags are also applied independently of file type
vee1e Jul 28, 2026
374262d
refactor(results): drop unused tags on stack/decoded strings
vee1e Jul 28, 2026
03ee960
style: drop unnecessary bulk_analyze reformats
vee1e Jul 28, 2026
38e5a7d
style: reformat results.py with project isort/black settings
vee1e Jul 28, 2026
b4c1c62
feat(cli): temporary --no-layout and --no-tags product flags
vee1e Jul 28, 2026
47715ef
fix: harden default layout path and clean quantum leftovers
vee1e Jul 28, 2026
77bb42e
docs: TODO for --load ignoring --no-layout product flags
vee1e Jul 29, 2026
6a34b48
fix: correct layout-path static runtime and review nits
vee1e Jul 30, 2026
9d1f7da
docs(script): add TODO for bulk analysis
vee1e Jul 30, 2026
c4d8105
refactor: inline static string extraction
vee1e Jul 31, 2026
538a510
fix: normalize runtime round trips
vee1e Jul 31, 2026
b2a62e9
fix: CI quantumstrand trigger and --no sample argv order
vee1e Aug 1, 2026
60e7792
refactor(tests): rename test_qs.py to test_layout.py
vee1e Aug 1, 2026
7ed1275
fix(ci): checkout testfiles for build smoke test
vee1e Aug 1, 2026
6890d76
fix: mmap classic statics; materialize bytes only for layout
vee1e Aug 1, 2026
c087754
style: drop nargs sample-order comments
vee1e Aug 1, 2026
ae271e6
refactor(tests): drop qs prefix from remaining test modules
vee1e Aug 2, 2026
bedeab4
revert: keep single full-buffer read for statics and layout
vee1e Aug 2, 2026
d5f00fa
feat: record sample md5/sha1/sha256 in result metadata
vee1e Aug 2, 2026
c622837
Merge pull request #1347 from vee1e/feat/unified-pipeline-iteration-2
mr-tz Aug 4, 2026
b0ece42
add pma json
vee1e Aug 7, 2026
15a8522
qs-viewer: add favicon
vee1e Aug 7, 2026
d46b309
ignore vercel and bun.lock
vee1e Aug 7, 2026
1dc265a
feat: migrate CLI flags and add runtime metrics
vee1e Aug 11, 2026
2405bf8
fix: avoid template expansion in release zip step
vee1e Aug 11, 2026
6f455e1
fix: update smoke test flag and import order
vee1e Aug 11, 2026
67a33d5
fix: drop the all pseudo-type from string type flags
vee1e Aug 11, 2026
7de508c
feat: validate results documents with a full JSON parse
vee1e Aug 11, 2026
790f787
docs: require -- separator before sample in function examples
vee1e Aug 11, 2026
beef995
docs: show plain usage in help examples
vee1e Aug 11, 2026
7cb2501
fix: drop --disable-progress flag
vee1e Aug 11, 2026
5d9ebdf
refactor: rename string type selection variables
vee1e Aug 11, 2026
44b888d
docs: remove outdated json load comment
vee1e Aug 11, 2026
873c8bd
refactor: time layout and tag steps in a wrapper
vee1e Aug 11, 2026
e178418
test: combine no-args help case into help test
vee1e Aug 11, 2026
3873762
Update floss/cli.py
vee1e Aug 11, 2026
48095d9
refactor: replace set subset operator with explicit all() key check
vee1e Aug 11, 2026
e83efb9
lint: fix black on cli.py
vee1e Aug 11, 2026
361322d
Merge branch 'quantumstrand' into feat/prevalence-db-update
Aug 11, 2026
7dbe90d
refactor: make layout string extraction explicit, drop 'live' naming
vee1e Aug 12, 2026
60b6254
refactor: rename string type options to enabled/disabled naming
vee1e Aug 12, 2026
235963c
test: drop nonexistent-path assertion from binary results-doc test
vee1e Aug 12, 2026
c5c2224
test: check representative --json option in help output
vee1e Aug 12, 2026
5f7a5d2
refactor: consistently prefix internal pipeline helpers with underscore
vee1e Aug 12, 2026
e0eefaf
refactor: use context manager to time layout and tag steps
vee1e Aug 12, 2026
e64aac5
qs-viewer: match ResultDocument schema and use floss-generated sample
vee1e Aug 12, 2026
585cceb
refactor: drop underscore prefixes from pipeline helpers
vee1e Aug 12, 2026
054bf26
feat(qs-viewer): rebrand to FLOSS and use floss favicon
vee1e Aug 12, 2026
080f90d
ci(qs-viewer): deploy to Vercel via GitHub Actions
vee1e Aug 12, 2026
4bf8120
ci(qs-viewer): fix pinned actions/setup-node sha
vee1e Aug 12, 2026
f0d4f97
ci(qs-viewer): deploy via Vercel git integration with npm-only build
vee1e Aug 12, 2026
3c47ad3
feat(qs-viewer): tweak upload hint text
vee1e Aug 12, 2026
3ef3c9f
feat(qs-viewer): rename title to FLOSS Graphical Viewer
vee1e Aug 12, 2026
3244737
refactor: drop redundant always-on layout/tags kwargs in main
vee1e Aug 12, 2026
924a83f
refactor: co-locate file type sniffing helpers in utils
vee1e Aug 12, 2026
1164d7d
refactor: merge file type and results document detection
vee1e Aug 12, 2026
68ec89f
refactor: clarify layout variable naming in compute_layout
vee1e Aug 12, 2026
6d03da5
refactor: revert pointless Layout return from extract_layout_strings
vee1e Aug 12, 2026
9c4da76
refactor: restore original extract_layout_strings signature
vee1e Aug 12, 2026
3543297
refactor: move runtime timing into Runtime.measure
vee1e Aug 12, 2026
8b10125
feat(qs-viewer): add light mode theme
vee1e Aug 12, 2026
f62f41d
refactor: move layout string extraction into Layout.extract_strings
vee1e Aug 12, 2026
c7f3b95
feat(qs-viewer): add light/dark theme toggle button
vee1e Aug 12, 2026
03f1239
feat(qs-viewer): use sun/moon svg icon for theme toggle
vee1e Aug 12, 2026
2bb4036
refactor: use runtime.measure for analyze timing spans
vee1e Aug 12, 2026
2bf26d1
test: assert version appears in --version output
vee1e Aug 12, 2026
4235e7b
refactor: rename Runtime.measure to measure_and_set_time
vee1e Aug 12, 2026
0692b82
feat(qs-viewer): show floss logo in sidebar header
vee1e Aug 12, 2026
4c6b993
feat(qs-viewer): show total and ignored string count
vee1e Aug 12, 2026
6f2e507
feat(qs-viewer): add fuzzy subsequence search with pre-lowercased corpus
vee1e Aug 12, 2026
1b75a61
feat(qs-viewer): virtualize string list for smooth 100k corpus rendering
vee1e Aug 12, 2026
432d36d
feat(qs-viewer): add drag-and-drop overlay indicator with background …
vee1e Aug 12, 2026
622c03c
fix(qs-viewer): survive malformed JSON and render errors instead of b…
vee1e Aug 12, 2026
763d7c1
cli: add --plain stub argument
vee1e Aug 13, 2026
8cfd7ad
cli: remove trailing comma from --analyze-functions help
vee1e Aug 13, 2026
abc052c
pipeline: measure layout and tag phases separately
vee1e Aug 13, 2026
f7893a3
utils: single-pass file type detection
vee1e Aug 13, 2026
504e1b5
results: reject unknown fields in measure_and_set_time
vee1e Aug 13, 2026
67fc76e
build_oss_db: derive default output dir from data_root
vee1e Aug 13, 2026
aaa3e00
test: drop duplicated --analyze-functions assertion
vee1e Aug 13, 2026
3cb79bb
docs: drop stale quantum-style terminology from comments
vee1e Aug 13, 2026
716e1fd
scripts: replace deprecated --no with --no-string-type
vee1e Aug 13, 2026
0443166
pipeline: reject results documents in load_vw
vee1e Aug 13, 2026
c06bc68
main: keep --string-type restrictions with --analyze-functions
vee1e Aug 13, 2026
d9078a6
pipeline: keep layout-attempt time in fallback static_strings
vee1e Aug 13, 2026
b2f2efe
utils: detect results documents by byte sequence, not full parse
vee1e Aug 13, 2026
3c0e11f
main: implement --plain classic view
vee1e Aug 13, 2026
326666b
utils: widen results detection sniff to 8KB
vee1e Aug 13, 2026
8597b30
main: error when --string-type static meets --analyze-functions
vee1e Aug 13, 2026
806e1a3
Merge pull request #1355 from vee1e/feat/unified-pipeline-iteration-3
mr-tz Aug 13, 2026
dd001f1
Merge GP hash sets for faster queries and add LFS check
mr-tz Aug 13, 2026
5b379b1
Merge pull request #1326 from mandiant/feat/prevalence-db-update
mr-tz Aug 13, 2026
19dab48
feat: iteration 4 — filters, columns, summary, and consolidated rende…
vee1e Aug 13, 2026
f05cf68
fix(main): handle JSON-mode detection when no argv or combined short …
vee1e Aug 13, 2026
31a9c08
fix(filter): match --section against the containing top-level section
vee1e Aug 13, 2026
2ed9f04
fix(filter): --interesting drops only strings with no non-noisy tag
vee1e Aug 13, 2026
b138011
fix(filter): cap --max-strings per top-level section, not per node
vee1e Aug 13, 2026
c88e442
fix(render): make the encoding column independent of offset
vee1e Aug 13, 2026
da3e6c3
fix(main): validate --query regexes at parse time
vee1e Aug 13, 2026
ee73c64
refactor: align naming with codebase conventions
vee1e Aug 13, 2026
a5ad979
refactor: remove dead code and duplicated definitions
vee1e Aug 13, 2026
9541818
perf: avoid repeated recomputation in filters, grouping, and summary
vee1e Aug 13, 2026
64cb593
refactor: reduce verbosity in render dispatch and layout rendering
vee1e Aug 13, 2026
1167838
test: cover new filter/columns/summary behavior and validate --max-st…
vee1e Aug 13, 2026
3dbf3e5
fix(render): tag filters override the default hide rules
vee1e Aug 13, 2026
c759e3b
fix(cli): emit a single JSON error object on STDERR in JSON mode
vee1e Aug 13, 2026
bc4d563
feat(cli): support language and all string types
vee1e Aug 13, 2026
301726a
fix(summary): count strings under their containing top-level section
vee1e Aug 13, 2026
9bb9314
fix(render): --plain/--summary no longer mutate the result document
vee1e Aug 13, 2026
49dc53f
refactor: align headings with spec, remove dead wrapper, tighten tests
vee1e Aug 13, 2026
47e24b2
chore(render): drop unused json import from default.py
vee1e Aug 13, 2026
4cdb2f3
fix(pipeline): extract language strings independently of static strings
vee1e Aug 13, 2026
743b03b
docs(cli): require -- before the sample for multi-value filter flags
vee1e Aug 13, 2026
4ca9bf8
fix(filter): --section descends through Mach-O fat-arch wrappers
vee1e Aug 13, 2026
3fbf1a0
fix(render): --plain applies the render-time filters
vee1e Aug 13, 2026
9939f40
docs(cli): dedupe and expand --structure help
vee1e Aug 13, 2026
af1a370
test: make tests exercise the behavior they name
vee1e Aug 13, 2026
7afd6de
chore(render): fix stale docstring and trim restating comments
vee1e Aug 13, 2026
e4ce010
style(render): order import for static_strings_from_layout
vee1e Aug 13, 2026
8e03f2c
fix(render): stop truncating columns, drop boundary strings, keep par…
vee1e Aug 13, 2026
8f8dc07
fix(summary): escape Rich markup and control chars in high-value strings
vee1e Aug 13, 2026
c5afd82
fix(render): no classic meta table when a layout exists
vee1e Aug 13, 2026
1eab2a7
fix(filter): cap --max-strings per section on fat Mach-O
vee1e Aug 13, 2026
f07c097
feat(cli): accept --language auto (the default)
vee1e Aug 13, 2026
fb9e788
fix(results): filter language/layout strings by length; accept stack-…
vee1e Aug 13, 2026
08562ee
test(results): guard layout-none in the filter_string_len test
vee1e Aug 13, 2026
d8025c5
test(render): annotate the console getvalue ignore for mypy
vee1e Aug 13, 2026
a1fd95f
fix(cli): send text-mode errors to stderr; detect uppercase JSON flags
vee1e Aug 13, 2026
8f7b995
test(render): cover --no-structure and --columns encoding
vee1e Aug 13, 2026
7e95165
style: apply isort import ordering to recently edited files
vee1e Aug 13, 2026
858ad0d
ci(vercel): only deploy qs-viewer on qs-viewer-enhance
vee1e Aug 13, 2026
4f14613
Merge pull request #1358 from vee1e/qs-viewer-enhance
mr-tz Aug 13, 2026
16a090f
refactor(render): drop verbose-dependent heading coloring
vee1e Aug 14, 2026
c5b6eea
refactor(filter): clarify arch-wrapper name, add structure slugs + sh…
vee1e Aug 14, 2026
4b53c62
docs(cli): build help from constants and point --tag/--structure at -…
vee1e Aug 14, 2026
8957bb0
refactor(main): exact --json/-j detection and a shared report_error h…
vee1e Aug 14, 2026
7f03cc2
refactor(summary): reuse relevance ordering and heading style helpers
vee1e Aug 14, 2026
9ddc1ac
refactor: document load-path length filter, simplify all expansion, a…
vee1e Aug 14, 2026
ee16ad2
test: remove frivolous asserts
vee1e Aug 14, 2026
096e442
fix(pipeline): honor a manual --language selection over failed auto-d…
vee1e Aug 14, 2026
98c299d
fix(cli): dedupe string types when expanding the all alias
vee1e Aug 14, 2026
a954ff6
refactor(filter): store section filters as sets like structures
vee1e Aug 14, 2026
6c0ef2f
feat(cli): --columns accumulates across repeated flags
vee1e Aug 14, 2026
8ef4755
refactor(summary): align counts on enable flags, gate layout on stati…
vee1e Aug 14, 2026
8b97bfd
feat(json): keep extra top-level keys instead of dropping them
vee1e Aug 14, 2026
0785a29
fix(cli): detect -j exactly, not as a substring of other args
vee1e Aug 14, 2026
01a808c
refactor(summary): render tables with markdown-style pipe separators
vee1e Aug 14, 2026
dbfa870
feat(summary): --summary is static-only by default
vee1e Aug 14, 2026
d737ef6
fix(pipeline): a concrete --language selection unilaterally beats aut…
vee1e Aug 14, 2026
83f5788
fix(cli): reject --language dotnet; --interesting drops any noisy-tag…
vee1e Aug 16, 2026
968c195
test(cli): remove spurious --language dotnet rejection test
vee1e Aug 16, 2026
9fac300
fix(render): restore classic meta fallback when static strings are di…
vee1e Aug 16, 2026
78f1468
fix(filter): relevance-sort fat-arch wrapper strings under --max-strings
vee1e Aug 16, 2026
f492f4b
refactor(filter): share the arch-wrapper section-boundary helper
vee1e Aug 16, 2026
2281dee
refactor(main): loop over the mutual-exclusion flag pairs
vee1e Aug 16, 2026
5aee9ab
feat(filter): tag families derived from the tags/data tag sources
vee1e Aug 16, 2026
07c39b7
docs: remove spec reference
vee1e Aug 17, 2026
cc66e7e
fix(results): warn when -n is below the min length used to build a doc
vee1e Aug 17, 2026
7932b3d
fix(cli): 'all' string type can only be used alone
vee1e Aug 17, 2026
2c39629
feat(cli): add -y/--yes to skip the deobfuscation prompt
vee1e Aug 17, 2026
8ef8bc1
test(cli): remove --language auto acceptance test
vee1e Aug 17, 2026
cac88eb
test(cli): remove -- terminator filter-flag test
vee1e Aug 17, 2026
4731c8d
test(cli): use -y and floss.main for the language extraction test
vee1e Aug 17, 2026
03ec9e9
test(cli): route language-override tests through floss.main with -y
vee1e Aug 17, 2026
f73c7ef
fix(cli): reject non-static string types with --summary
vee1e Aug 17, 2026
e1bc7f9
test(render): add tag-normalization, Mach-O summary, no-layout warnin…
vee1e Aug 17, 2026
f3263ff
fix(results): abort when -n is below the min length used to build a doc
vee1e Aug 17, 2026
5e3bf72
Merge pull request #1360 from vee1e/feat/unified-pipeline-iteration-4
mr-tz Aug 17, 2026
d8a4fe8
feat(cache): add result-document cache module
vee1e Aug 17, 2026
e250849
feat(cache): wire result caching into the analysis pipeline
vee1e Aug 17, 2026
2d9b8a1
feat(cache): wire caching into the CLI and document envars
vee1e Aug 17, 2026
199de0f
test(cache): isolate cache dir and add end-to-end cache tests
vee1e Aug 17, 2026
fba96b0
fix(cache): make lock and cache-dir tests Windows-compatible
vee1e Aug 17, 2026
bc94b6c
fix(cache): allow layout-less cache hits and clarify miss comment
vee1e Aug 17, 2026
82e5446
fix(cache): clear disabled string types on cache materialize
vee1e Aug 17, 2026
f516fe2
fix(cache): never crash analysis on cache file I/O errors
vee1e Aug 17, 2026
1571c40
fix(cache): let a tags-enabled cache serve a no-tags request
vee1e Aug 17, 2026
7a9b529
test(cache): narrow optional layout before access for mypy
vee1e Aug 17, 2026
ed05890
refactor: rename analyze_functions to match the CLI flag
vee1e Aug 18, 2026
a5e7aa0
feat(cache): add FLOSS_CACHE_REFRESH to force a re-analysis
vee1e Aug 18, 2026
8436f21
docs(cache): drop the :func: reST markup in docstrings
vee1e Aug 18, 2026
8cfa8fb
Update floss/cli.py
vee1e Aug 18, 2026
638f1f5
fix(cache): never crash on cache init failures
vee1e Aug 18, 2026
82293a3
fix(cache): record the requested min_length on cache hits
vee1e Aug 18, 2026
408302d
fix(cache): parse boolean envars case-insensitively
vee1e Aug 18, 2026
0db7615
fix(cache): guard is_file() in load() against OSError
vee1e Aug 18, 2026
59dabcf
Merge pull request #1367 from vee1e/feat/unified-pipeline-iteration-5
mr-tz Aug 18, 2026
8058866
feat(render): aesthetically revamp summary mode layout and tag filtering
mr-tz Aug 18, 2026
0471fb1
Merge pull request #1366 from mandiant/feat/render-summary-layout
mr-tz Aug 18, 2026
af99e7f
ci: retarget workflows from quantumstrand to master
vee1e Aug 18, 2026
a0fed7e
refactor(viewer): rename qs-viewer directory to viewer
vee1e Aug 18, 2026
6665429
refactor(viewer): drop quantum-strand branding
vee1e Aug 18, 2026
14c299c
chore(viewer): remove stale qs artifacts
vee1e Aug 18, 2026
640fa72
refactor(tags): rename jh_to_qs.py to jh_to_oss.py
vee1e Aug 18, 2026
4d3847b
chore(pyproject): drop stale optional [qs] comment
vee1e Aug 18, 2026
2ba52b0
chore(viewer): keep pma sample, rename to drop qs naming
vee1e Aug 18, 2026
f98c5e6
feat(viewer): use pma0303_floss sample, normalize to current schema
vee1e Aug 18, 2026
b5bb3cb
merge: resolve requirements.txt conflict, keep master pins + branch deps
vee1e Aug 18, 2026
2b27980
ci: keep quantumstrand in PR triggers until CI is green
vee1e Aug 18, 2026
36e98ca
Merge pull request #1370 from vee1e/qs-merge-final
mr-tz Aug 18, 2026
1592003
ci(web-release): scope pages and id-token permissions to the deploy job
vee1e Aug 18, 2026
cfff4fd
ci: scope permissions and fix action pin to clear zizmor medium findings
vee1e Aug 18, 2026
21a9a71
fix(enrich): recognize XOR-decoded PE/ELF layout names
vee1e Aug 18, 2026
916e310
fix(pipeline): -y/--yes now disables deobfuscation
vee1e Aug 18, 2026
47445d6
fix(cache): include the analysis format in the cache key
vee1e Aug 18, 2026
13c3fc8
fix(layout): annotate PE/ELF root-level strings with structures
vee1e Aug 18, 2026
552b487
fix(cli): reject --summary with --analyze-functions
vee1e Aug 18, 2026
cede3de
fix(scripts): make --pes mode reachable in extract_strings.py
vee1e Aug 18, 2026
7c4d4d0
fix(tags): detect unpulled Git LFS pointers in all loaders
vee1e Aug 18, 2026
26af97d
style: black/isort formatting for earlier fixes
vee1e Aug 18, 2026
68ca344
refactor(pipeline): drop dead --disable-progress plumbing
vee1e Aug 19, 2026
8c2451c
refactor(cli): rename -y/--yes to --no-prompt
vee1e Aug 19, 2026
eedabce
style(main): drop comment duplicating the --summary error text
vee1e Aug 19, 2026
f700666
refactor(cache): default the analysis format in compute_key
vee1e Aug 19, 2026
0abe0c2
feat(cli): make string deobfuscation opt-in and drop the prompt
vee1e Aug 19, 2026
bfc01b0
revert(cli): restore all-on default string extraction
vee1e Aug 19, 2026
e94f0a1
docs(AGENTS): note the result cache when diffing output
vee1e Aug 19, 2026
3569962
test(cache): rely on the compute_key auto default
vee1e Aug 19, 2026
864e689
refactor(cli): reject any string-type selection with --summary
vee1e Aug 19, 2026
1413961
fix(scripts): use the correct max_len constants for libs vs pes
vee1e Aug 19, 2026
7bdd3fe
test(cli): fix duplicated language-test docstring
vee1e Aug 19, 2026
461113d
test(cli): drop deobfuscation-on-by-default test
vee1e Aug 19, 2026
f87a491
fix(render): escape \t in the layout view like the other views
vee1e Aug 19, 2026
050bfe2
Merge pull request #1376 from vee1e/fix/quantumstrand-review-1375
mr-tz Aug 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
floss/tags/data/**/*.bin filter=lfs diff=lfs merge=lfs -text
floss/tags/data/**/*.gz filter=lfs diff=lfs merge=lfs -text
floss/tags/data/**/*.jsonl filter=lfs diff=lfs merge=lfs -text
floss/sigs/*.sig filter=lfs diff=lfs merge=lfs -text
16 changes: 16 additions & 0 deletions .github/mypy/mypy.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[mypy]
plugins = pydantic.mypy
mypy_path = .

[mypy-viv_utils.*]
ignore_missing_imports = True
Expand Down Expand Up @@ -34,6 +35,21 @@ ignore_missing_imports = True
[mypy-pefile.*]
ignore_missing_imports = True

[mypy-intervaltree.*]
ignore_missing_imports = True

[mypy-lancelot.*]
ignore_missing_imports = True

[mypy-capa.*]
ignore_missing_imports = True

[mypy-virustotal3.*]
ignore_missing_imports = True

[mypy-colorama.*]
ignore_missing_imports = True

[mypy-requests.*]
ignore_missing_imports = True

Expand Down
136 changes: 82 additions & 54 deletions .github/pyinstaller/floss.spec
Original file line number Diff line number Diff line change
@@ -1,21 +1,38 @@
# -*- mode: python -*-
# Copyright 2017 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Copyright 2017 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import subprocess

from PyInstaller.utils.hooks import collect_submodules

# layout/tags are imported lazily from floss.pipeline; collect them so the
# standalone binary still bundles the full layout-aware static path.
layout_tags_hiddenimports = (
collect_submodules("floss.layout")
+ collect_submodules("floss.tags")
+ [
"floss.ranges",
"elftools",
"lancelot",
"machofile",
"dnfile",
"msgspec",
]
)

# when invoking pyinstaller from the project root,
# this gets run from the project root.
with open("./floss/version.py", "wb") as f:
Expand All @@ -33,55 +50,66 @@ with open("./floss/version.py", "wb") as f:
)
f.write(("__version__ = '%s'" % version).encode("utf-8"))

datas = [
# when invoking pyinstaller from the project root,
# this gets invoked from the directory of the spec file,
# i.e. ./.github/pyinstaller
('../../floss/sigs', 'sigs'),
# tag databases
('../../floss/tags/data/crt/*.jsonl.gz', 'floss/tags/data/crt'),
('../../floss/tags/data/expert/*.jsonl', 'floss/tags/data/expert'),
('../../floss/tags/data/gp/*.jsonl.gz', 'floss/tags/data/gp'),
('../../floss/tags/data/gp/*.bin', 'floss/tags/data/gp'),
('../../floss/tags/data/oss/*.jsonl.gz', 'floss/tags/data/oss'),
('../../floss/tags/data/winapi/*.txt.gz', 'floss/tags/data/winapi'),
]

excludes = [
# ignore packages that would otherwise be bundled with the .exe.
# review: build/pyinstaller/xref-pyinstaller.html
# we don't do any GUI stuff, so ignore these modules
"tkinter",
"_tkinter",
"Tkinter",

# tqdm provides renderers for ipython,
# however, this drags in a lot of dependencies.
# since we don't spawn a notebook, we can safely remove these.
"IPython",
"ipywidgets",

# these are pulled in by networkx
# but we don't need to compute the strongly connected components.
"numpy",
"scipy",
"matplotlib",
"pandas",
"pytest",

# deps from viv that we don't use.
# this duplicates the entries in `hook-vivisect`,
# but works better this way.
"vqt",
"vdb.qt",
"envi.qt",
"PyQt5",
"qt5",
"pyqtwebengine",
"pyasn1",
]

a = Analysis(
# when invoking pyinstaller from the project root,
# this gets invoked from the directory of the spec file,
# i.e. ./.github/pyinstaller
["../../floss/main.py"],
pathex=["floss"],
binaries=[],
datas=[
# when invoking pyinstaller from the project root,
# this gets invoked from the directory of the spec file,
# i.e. ./.github/pyinstaller
('../../floss/sigs', 'sigs'),
],
hiddenimports=[],
datas=datas,
hiddenimports=layout_tags_hiddenimports,
hookspath=[".github/pyinstaller/hooks"],
runtime_hooks=[],
excludes=[
# ignore packages that would otherwise be bundled with the .exe.
# review: build/pyinstaller/xref-pyinstaller.html
# we don't do any GUI stuff, so ignore these modules
"tkinter",
"_tkinter",
"Tkinter",

# tqdm provides renderers for ipython,
# however, this drags in a lot of dependencies.
# since we don't spawn a notebook, we can safely remove these.
"IPython",
"ipywidgets",

# these are pulled in by networkx
# but we don't need to compute the strongly connected components.
"numpy",
"scipy",
"matplotlib",
"pandas",
"pytest",

# deps from viv that we don't use.
# this duplicates the entries in `hook-vivisect`,
# but works better this way.
"vqt",
"vdb.qt",
"envi.qt",
"PyQt5",
"qt5",
"pyqtwebengine",
"pyasn1",
],
excludes=excludes,
win_no_prefer_redirects=False,
win_private_assemblies=False,
noarchive=False,
Expand Down
127 changes: 127 additions & 0 deletions .github/workflows/build-oss-db.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
name: Build OSS String Databases

on:
# Rebuild the databases bi-weekly (1st and 15th of each month at 00:00 UTC).
schedule:
- cron: '0 0 1,15 * *'

# Allow manual runs from the Actions tab.
workflow_dispatch:

# Cancel any in-progress run when a newer one starts.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: write
pull-requests: write

jobs:
build-databases:
name: Build OSS string databases
runs-on: windows-latest

steps:
- name: Checkout flare-floss
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
path: flare-floss
lfs: true

- name: Checkout lancelot
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
repository: williballenthin/lancelot
path: lancelot
lfs: true

- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: '3.12'

- name: Set up Rust
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # v1
with:
toolchain: stable

- name: Build jh
run: |
cargo build --release -p lancelot-bin
working-directory: lancelot

- name: Build OSS databases
run: |
python scripts/tags/build_oss_db.py `
--config floss\tags\data\oss\libraries.json `
--jh-path ..\lancelot\target\release\jh.exe `
--output-dir floss\tags\data\oss `
--continue-on-error
working-directory: flare-floss

- name: Show metrics summary
if: success() || failure()
run: |
Get-Content floss\tags\data\oss\build_metrics.json
working-directory: flare-floss

- name: Show entry-level diff
if: success() || failure()
run: |
if (Test-Path floss\tags\data\oss\build_diff.txt) {
Get-Content floss\tags\data\oss\build_diff.txt
} else {
Write-Host "build_diff.txt not produced"
}
working-directory: flare-floss

- name: Prepare PR body
if: success() || failure()
shell: pwsh
run: |
# Markdown already has per-library ## headings and ```diff fences.
$diffPath = "flare-floss/floss/tags/data/oss/build_diff_pr.txt"
$diff = if (Test-Path $diffPath) {
Get-Content $diffPath -Raw
} else {
"(no entry-level diff produced)"
}
$librariesConfig = Get-Content "flare-floss/floss/tags/data/oss/libraries.json" -Raw | ConvertFrom-Json
$body = @(
"Automated bi-weekly rebuild of the OSS string databases.",
"",
"- Triplet: ``$($librariesConfig.triplet)``",
"- Compiler: ``$($librariesConfig.compiler)``",
"- Library list: see ``floss/tags/data/oss/libraries.json``",
"",
"Per-library entry counts and timing are printed in the workflow logs (``build_metrics.json``).",
"",
"Entry-level diff (up to 20 lines per library):",
"",
$diff.TrimEnd(),
""
) -join "`n"
# GitHub rejects PR bodies over 65536 characters ("Body is too long").
# The Python script already caps the diff; this is a final safety net.
$maxBodyChars = 65000
if ($body.Length -gt $maxBodyChars) {
$notice = "`n`n... truncated to stay under GitHub's 65536-character PR body limit."
$keep = [Math]::Max(0, $maxBodyChars - $notice.Length)
$body = $body.Substring(0, $keep) + $notice
}
# Write outside the flare-floss checkout so create-pull-request does not commit it.
Set-Content -Path pr-body.md -Value $body -Encoding utf8
- name: Create Pull Request if databases changed
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
with:
path: flare-floss
base: master
commit-message: 'chore(oss-db): update string databases'
title: 'Update OSS string databases'
# Relative to $GITHUB_WORKSPACE (not the path: checkout).
body-path: pr-body.md
branch: update-oss-string-databases
# Always open a fresh PR (e.g. update-oss-string-databases-6qj97jr).
branch-suffix: random
delete-branch: true
21 changes: 19 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

on:
pull_request:
branches: [ master ]
branches: [ master, quantumstrand ]
release:
types: [edited, published]
branches: [ master ]

permissions:
contents: read

jobs:
build:
Expand All @@ -29,6 +33,7 @@
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
submodules: false
lfs: true
- name: Set up Python 3.10
uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0
with:
Expand All @@ -39,6 +44,18 @@
pip install -e .[build]
- name: Build standalone executable
run: pyinstaller .github/pyinstaller/floss.spec
# build job uses submodules: false; smoke test needs a real PE sample
- name: Checkout test sample
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
repository: mandiant/flare-floss-testfiles
path: tests/data
- name: Smoke test layout/tags via standalone floss
run: |
chmod +x dist/${{ matrix.artifact_name }}
./dist/${{ matrix.artifact_name }} --help
# static-only layout path (default) should include tag annotations in JSON
./dist/${{ matrix.artifact_name }} tests/data/test-decode-to-stack.exe --string-type static -j | grep -q '#common'
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with:
name: ${{ matrix.asset_name }}
Expand Down Expand Up @@ -111,9 +128,9 @@
- name: Set zip name
run: echo "zip_name=floss-${GITHUB_REF#refs/tags/}-${{ matrix.asset_name }}.zip" >> $GITHUB_ENV
- name: Zip ${{ matrix.artifact_name }} into ${{ env.zip_name }}
run: zip ${{ env.zip_name }} ${{ matrix.artifact_name }}
run: zip "$zip_name" "${{ matrix.artifact_name }}"
- name: Upload ${{ env.zip_name }} to GH Release
uses: svenstaro/upload-release-action@29e53e917877a24fad85510ded594ab3c9ca12de # 2.11.5

Check notice on line 133 in .github/workflows/build.yml

View workflow job for this annotation

GitHub Actions / zizmor-output

superfluous-actions

build.yml:133: action functionality is already included by the runner: use `gh release create` and `gh release upload` in a script step
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ env.zip_name }}
Expand Down
Loading
Loading