Commit Graph

6079 Commits

Author SHA1 Message Date
Willi Ballenthin eb81901d71 fix: correct capa/subscope-rule key in RuleMetadata.from_capa
`RuleMetadata.from_capa` used `rule.meta.get("capa/subscope", False)` and
`Field(False, alias="capa/subscope")`, but the actual key set by
`_extract_subscope_rules_rec` is `"capa/subscope-rule"`. This caused
`is_subscope_rule` to always be `False` in every `RuleMetadata` instance,
making downstream filters in `render/utils.py`, `render/vverbose.py`, and
`scripts/import-to-ida.py` ineffective (though subscope rules are already
excluded from `ResultDocument` before reaching those callers).
2026-05-08 17:58:07 +02:00
Willi Ballenthin 1ef6298b45 fix: Scopes.from_dict uses cls instead of self
`Scopes.from_dict` was decorated with `@classmethod` but named its first
parameter `self` instead of `cls`, and hard-coded `Scopes(...)` in the
return statement instead of `cls(...)`. This meant any subclass calling
`SubScopes.from_dict(...)` would get a `Scopes` instance back rather than
a `SubScopes` instance.

Rename the parameter to `cls` and use it in the return statement so
that subclasses receive the correct type.
2026-05-08 17:58:07 +02:00
Willi Ballenthin 316aeaf8e5 fix: remove unreachable backports.functools_lru_cache fallback
`functools.lru_cache` has been in the standard library since Python 3.2.
The project requires Python >=3.10, so the `except ImportError` branch
importing `backports.functools_lru_cache` can never execute.

Remove the try/except block and keep only the direct stdlib import.
Also remove `types-backports` from dev dependencies, `backports` from
`[tool.deptry.known_first_party]`, and `types-backports` from the
DEP002 ignore list in `pyproject.toml`.
2026-05-08 17:58:07 +02:00
Willi Ballenthin 16fb277980 fix: remove Python 2-only Result.__nonzero__
`Result.__nonzero__` is the Python 2 boolean hook; Python 3 calls
`__bool__`, which is already defined immediately above it.
`__nonzero__` is never invoked at runtime in Python 3 and adds noise
that misleads readers into thinking it serves a purpose.
2026-05-08 17:58:07 +02:00
Willi Ballenthin d9402d8041 fix: add missing ELF branch in get_format_from_extension for .elf_ files
EXTENSIONS_ELF = "elf_" was defined but never used: get_format_from_extension
had branches for every other EXTENSIONS_* constant except ELF. Since .elf_
files are real test fixtures and a recognised input format, the fix is to add
the missing elif branch (and import FORMAT_ELF) rather than delete the
constant.

Closes #3031
2026-05-08 17:58:07 +02:00
Capa Bot c57422f94e Sync capa rules submodule 2026-05-07 10:50:09 +00:00
dependabot[bot] 3593a79ac0 build(deps): bump pip from 26.0 to 26.1 (#3063)
Bumps [pip](https://github.com/pypa/pip) from 26.0 to 26.1.
- [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/pip/compare/26.0...26.1)

---
updated-dependencies:
- dependency-name: pip
  dependency-version: '26.1'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-28 10:14:34 -06:00
dependabot[bot] 5ed6aab557 build(deps-dev): bump pyinstaller from 6.19.0 to 6.20.0 (#3062)
Bumps [pyinstaller](https://github.com/pyinstaller/pyinstaller) from 6.19.0 to 6.20.0.
- [Changelog](https://github.com/pyinstaller/pyinstaller/blob/develop/doc/CHANGES.rst)
- [Commits](https://github.com/pyinstaller/pyinstaller/compare/v6.19.0...v6.20.0)

---
updated-dependencies:
- dependency-name: pyinstaller
  dependency-version: 6.20.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-28 10:13:44 -06:00
dependabot[bot] 7d38d94880 build(deps-dev): bump pre-commit from 4.5.0 to 4.6.0 (#3061)
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 4.5.0 to 4.6.0.
- [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pre-commit/pre-commit/compare/v4.5.0...v4.6.0)

---
updated-dependencies:
- dependency-name: pre-commit
  dependency-version: 4.6.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-28 10:12:56 -06:00
Matt Williams 87f0970dbc Update README with dynamic capa heading (#3060)
* Update README with dynamic capa heading

Added a section heading for dynamic capabilities. Used lowercase to align with other headings.

* Update README.md

Added blank line before heading

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-04-27 09:09:59 -06:00
Willi Ballenthin b9f830619d update submodules 2026-04-23 18:04:10 +03:00
Willi Ballenthin e745fa6aab style: ruff format changed files 2026-04-23 18:04:10 +03:00
Willi Ballenthin a834c4c0a7 fix: clean up CHANGELOG bug fixes formatting 2026-04-23 18:04:10 +03:00
Willi Ballenthin 7484d3fc16 fix: loader.py reads entire file for magic byte check
Closes #3029
2026-04-23 18:04:10 +03:00
Willi Ballenthin 9954d99402 fix: freeze/__init__.py: logically impossible condition
Closes #3030
2026-04-23 18:04:10 +03:00
Willi Ballenthin aa9f09db89 fix: render_default always returns empty string
Closes #3012
2026-04-23 18:04:10 +03:00
Willi Ballenthin a5082beed0 fix: remove unused gzip import in test_helpers.py 2026-04-23 18:04:10 +03:00
Willi Ballenthin f6f3380fd3 fix: EXTENSIONS_DYNAMIC has inconsistent leading dots
Closes #3028
2026-04-23 18:04:10 +03:00
Willi Ballenthin 6431be2c42 fix: rules/__init__.py: duplicate bytes_features line
Closes #3027
2026-04-23 18:04:10 +03:00
Willi Ballenthin 62e6af31f8 fix: dotnetfile.py: missing import for capa.features.extractors.common
Closes #3026
2026-04-23 18:04:10 +03:00
Willi Ballenthin f17629a4eb fix: freeze/__init__.py: NO_ADDRESS < NO_ADDRESS returns True
Closes #3025
2026-04-23 18:04:10 +03:00
Willi Ballenthin c7d3de8bf8 fix: base_extractor.py: __metaclass__ is Python 2 syntax, ignored in Py3
Closes #3024
2026-04-23 18:04:10 +03:00
Willi Ballenthin 58b7a9fc55 fix: elffile.py: get_base_address returns None instead of NO_ADDRESS
Closes #3023
2026-04-23 18:04:10 +03:00
Willi Ballenthin 8bea7c700e fix: DNTokenOffsetAddress.__eq__ lacks type guard
Closes #3022
2026-04-23 18:04:10 +03:00
Willi Ballenthin 3c61d9956d fix: ProcessAddress.__eq__ and ThreadAddress.__eq__ assert on type
Closes #3021
2026-04-23 18:04:10 +03:00
Willi Ballenthin a8fafe0d46 fix: optimizer doesn't recurse into And/Or/Some children
Closes #3020
2026-04-23 18:04:10 +03:00
Willi Ballenthin 53158b4712 fix: find_dynamic_limitations_from_cli overwrites instead of OR-ing
Closes #3019
2026-04-23 18:04:10 +03:00
Willi Ballenthin 9289f09f15 fix: load_one_jsonl_from_path: finally block runs on unrelated exceptions
Closes #3018
2026-04-23 18:04:10 +03:00
Willi Ballenthin 8f946778ae fix: extract_os yields duplicate/contradictory OS values
Closes #3017
2026-04-23 18:04:10 +03:00
Willi Ballenthin 527fb397ea fix: vverbose.py: render_call variable assigned but never used
Closes #3016
2026-04-23 18:04:10 +03:00
Willi Ballenthin d3e2bac803 fix: capabilities/common.py: if va: drops address 0x0
Closes #3015
2026-04-23 18:04:10 +03:00
Willi Ballenthin 0345a15744 fix: _NoAddress.__eq__ unconditionally returns True
Closes #3014
2026-04-23 18:04:10 +03:00
Willi Ballenthin a07d314a31 fix: elf.py vdso_guess exception handler clobbers symtab_guess
Closes #3013
2026-04-23 18:04:10 +03:00
Willi Ballenthin dc4d64cb01 vverbose: use capa.helpers.assert_never
typing.assert_never isn't available until py3.11
2026-04-23 16:11:58 +03:00
Willi Ballenthin f5e3aa4a3b fix: address Pyright diagnostics in vivisect extractors (chunk 8)
- basicblock.py: fix real bug (/ -> // for integer division in get_printable_len); type: ignore for _dis_regctx (dynamically set)
- extractor.py: cast+assert for funcy.cached_property basic_blocks/instructions; type: ignore for get_function_name Address vs int
- file.py: assert pe/IMAGE_NT_HEADERS not None instead of type: ignore
- function.py: cast+assert for funcy.cached_property basic_blocks/instructions; type: ignore for getBranches() base return type
- insn.py: type hint derefs() as Iterator[int]; isinstance guard before derefs calls; import Elf + isinstance assert for parsedbin; cast for f.basic_blocks[0] and bb.instructions; type: ignore for dynamically-injected REG_* constants and getBranches()
2026-04-23 16:11:58 +03:00
Willi Ballenthin 191c889adf fix: remaining import, type annotation, and xfail type issues (chunk 7)
- fixtures.py: add import capa.render.result_document; local import capa.loader in functions
- fixtures.py: fix xfail reason type annotation (None -> str = "")
- main.py: type: ignore for PyInstaller-injected sys._MEIPASS
2026-04-23 16:11:58 +03:00
Willi Ballenthin 89a365fa3d fix: address Optional member access and type mismatch in tests (chunk 6)
- test_binexport_accessors.py: type: ignore on .expression accesses guarded by test assertions
- test_freeze_dynamic.py: assert isinstance DynamicFeatureExtractor before compare_extractors
- test_binja_features.py: type: ignore on binaryninja guarded by skipif decorator
2026-04-23 16:11:58 +03:00
Willi Ballenthin 2b536e2f53 fix: address type override, alias parameter, and Statement.children issues (chunk 5)
- engine.py: type: ignore for children/replace_child hasattr-guarded subclass attrs
- result_document.py: type: ignore for Pydantic analysis field override and alias args
- render/proto/__init__.py: type: ignore on Pydantic alias argument lines
- rules/__init__.py: type: ignore on ensure_feature_valid_for_scopes StringFactory calls
- result_document.py: fix Scope|None by extracting scope var with assert
2026-04-23 16:11:58 +03:00
Willi Ballenthin 96cabbcc6b fix: address reportAttributeAccessIssue and override mismatches (chunk 4)
- dnfile/helpers.py, insn.py: add import dnfile.mdtable; type: ignore dnfile Unknown returns
- dnfile/extractor.py: rename get_basic_blocks param f->fh
- pefile.py: rename f/bb->fh/bbh stub params; type: ignore for pefile OPTIONAL_HEADER stubs
- ghidra/file.py, helpers.py: initialize addr=0 before conditional loop
2026-04-23 16:11:58 +03:00
Willi Ballenthin b34079208c fix: address reportPossiblyUnbound diagnostics (chunk 3)
- elf.py: fix bug where vdso_guess except handler set symtab_guess=None
- result_document.py: add assert_never after StaticAnalysis/DynamicAnalysis
- binexport2/helpers.py: guard empty operand_expressions with early return
- tests/fixtures.py: restructure kernel32-64.dll_ workaround to single if/else
2026-04-23 16:11:58 +03:00
Willi Ballenthin ad8ed3b0b3 fix: align base_extractor abstract method parameter names with all concrete implementations 2026-04-23 16:11:58 +03:00
Willi Ballenthin d16a85bdba fix: add missing explicit submodule imports for Pyright attribute resolution 2026-04-23 16:11:58 +03:00
Willi Ballenthin 25edb58fdd rules: raise InvalidRule instead of asserting 2026-04-23 16:11:58 +03:00
Willi Ballenthin ab629e9a8a changelog 2026-04-23 16:11:58 +03:00
Willi Ballenthin 30b97dc9af fix: use tempfile.TemporaryFile as context manager, drop tfile=None guard 2026-04-23 16:11:58 +03:00
Willi Ballenthin fe4fece1bc fix: revert disable_progress to bool=False, drop Optional[bool]=None workaround 2026-04-23 16:11:58 +03:00
Willi Ballenthin 295ae3ee4b fix: add missing submodule imports for Pyright attribute access 2026-04-23 16:11:58 +03:00
Willi Ballenthin 0655263ed3 fix: add inline explanations to all type: ignore comments 2026-04-23 16:11:58 +03:00
Willi Ballenthin eb0d313264 fix: type: ignore placement for Pydantic alias parameters in freeze/__init__.py 2026-04-23 16:11:58 +03:00
Willi Ballenthin aa502d3523 fix: rename unused self to _self in filter closures in base_extractor.py 2026-04-23 16:11:58 +03:00