Compare commits

...

13 Commits

Author SHA1 Message Date
dependabot[bot]
69762b9f88 build(deps): bump the vivisect group with 3 updates
Bumps the vivisect group with 3 updates: [msgpack](https://github.com/msgpack/msgpack-python), [pyasn1](https://github.com/pyasn1/pyasn1) and [pyasn1-modules](https://github.com/pyasn1/pyasn1-modules).


Updates `msgpack` from 1.0.8 to 1.1.2
- [Release notes](https://github.com/msgpack/msgpack-python/releases)
- [Changelog](https://github.com/msgpack/msgpack-python/blob/main/ChangeLog.rst)
- [Commits](https://github.com/msgpack/msgpack-python/compare/v1.0.8...v1.1.2)

Updates `pyasn1` from 0.5.1 to 0.6.2
- [Release notes](https://github.com/pyasn1/pyasn1/releases)
- [Changelog](https://github.com/pyasn1/pyasn1/blob/main/CHANGES.rst)
- [Commits](https://github.com/pyasn1/pyasn1/compare/v0.5.1...v0.6.2)

Updates `pyasn1-modules` from 0.3.0 to 0.4.2
- [Release notes](https://github.com/pyasn1/pyasn1-modules/releases)
- [Changelog](https://github.com/pyasn1/pyasn1-modules/blob/main/CHANGES.txt)
- [Commits](https://github.com/pyasn1/pyasn1-modules/compare/v0.3.0...v0.4.2)

---
updated-dependencies:
- dependency-name: msgpack
  dependency-version: 1.1.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: vivisect
- dependency-name: pyasn1
  dependency-version: 0.6.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: vivisect
- dependency-name: pyasn1-modules
  dependency-version: 0.4.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: vivisect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-23 19:39:11 +00:00
dependabot[bot]
b4c0f1369e build(deps): bump pycparser from 2.23 to 3.0 (#2838)
Bumps [pycparser](https://github.com/eliben/pycparser) from 2.23 to 3.0.
- [Release notes](https://github.com/eliben/pycparser/releases)
- [Commits](https://github.com/eliben/pycparser/compare/release_v2.23...release_v3.00)

---
updated-dependencies:
- dependency-name: pycparser
  dependency-version: '3.0'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-23 12:37:46 -07:00
Daniel Adeboye
37f2a897ff tests: remove redundant test_ida_features.py (#2834) 2026-01-23 09:46:58 -07:00
Maijin
e39e610f66 Create a vivisect group in dependabot.yml (#2830)
* Add msgpack group in dependabot.yml

Add msgpack group in dependabot.yml

* Change to make a vivisect group

Change to make a vivisect group

* Update dependabot.yml
2026-01-23 09:37:04 -07:00
Maijin
073760f279 fix(lint): disable rule caching during linting (#2817) 2026-01-22 09:27:02 -07:00
dependabot[bot]
52a761ebb3 build(deps-dev): bump lodash from 4.17.21 to 4.17.23 in /web/explorer (#2833)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-22 08:56:03 -07:00
Moritz
2a44482076 Merge pull request #2821 from mandiant/dependabot/pip/mypy-protobuf-5.0.0
build(deps-dev): bump mypy-protobuf from 4.0.0 to 5.0.0
2026-01-20 10:31:57 +01:00
Moritz
a359745765 build(deps-dev): bump pyinstaller from 6.17.0 to 6.18.0 (#2822)
Bumps [pyinstaller](https://github.com/pyinstaller/pyinstaller) from 6.17.0 to 6.18.0.
- [Release notes](https://github.com/pyinstaller/pyinstaller/releases)
- [Changelog](https://github.com/pyinstaller/pyinstaller/blob/develop/doc/CHANGES.rst)
- [Commits](https://github.com/pyinstaller/pyinstaller/compare/v6.17.0...v6.18.0)

---
updated-dependencies:
- dependency-name: pyinstaller
  dependency-version: 6.18.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-01-20 10:31:35 +01:00
Maijin
203cc0aa0c Merge pull request #2824 from Maijin/patch-1
Group pyasn modules and vivisect in dependabot.yml
2026-01-20 10:18:35 +01:00
Moritz
3642ca94a6 Merge pull request #2820 from mandiant/dependabot/pip/vivisect-1.3.0
build(deps): bump vivisect from 1.2.1 to 1.3.0
2026-01-19 20:57:00 +01:00
dependabot[bot]
8e233ca69d build(deps-dev): bump pyinstaller from 6.17.0 to 6.18.0
Bumps [pyinstaller](https://github.com/pyinstaller/pyinstaller) from 6.17.0 to 6.18.0.
- [Release notes](https://github.com/pyinstaller/pyinstaller/releases)
- [Changelog](https://github.com/pyinstaller/pyinstaller/blob/develop/doc/CHANGES.rst)
- [Commits](https://github.com/pyinstaller/pyinstaller/compare/v6.17.0...v6.18.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 16:45:40 +00:00
dependabot[bot]
d5c23486e3 build(deps-dev): bump mypy-protobuf from 4.0.0 to 5.0.0
Bumps [mypy-protobuf](https://github.com/nipunn1313/mypy-protobuf) from 4.0.0 to 5.0.0.
- [Changelog](https://github.com/nipunn1313/mypy-protobuf/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nipunn1313/mypy-protobuf/commits)

---
updated-dependencies:
- dependency-name: mypy-protobuf
  dependency-version: 5.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 16:45:32 +00:00
dependabot[bot]
7600dd077b build(deps): bump vivisect from 1.2.1 to 1.3.0
Bumps [vivisect](https://github.com/vivisect/vivisect) from 1.2.1 to 1.3.0.
- [Changelog](https://github.com/vivisect/vivisect/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/vivisect/vivisect/compare/v1.2.1...v1.3.0)

---
updated-dependencies:
- dependency-name: vivisect
  dependency-version: 1.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 16:45:26 +00:00
10 changed files with 24 additions and 202 deletions

View File

@@ -4,6 +4,13 @@ updates:
directory: "/"
schedule:
interval: "weekly"
groups:
vivisect:
patterns:
- "vivisect"
- "pyasn1"
- "pyasn1-modules"
- "msgpack"
ignore:
- dependency-name: "*"
update-types: ["version-update:semver-patch"]

2
.github/flake8.ini vendored
View File

@@ -33,8 +33,6 @@ per-file-ignores =
scripts/*: T201
# capa.exe is meant to print output
capa/main.py: T201
# IDA tests emit results to output window so need to print
tests/test_ida_features.py: T201
# utility used to find the Binary Ninja API via invoking python.exe
capa/features/extractors/binja/find_binja_api.py: T201

View File

@@ -136,7 +136,6 @@ repos:
- "tests/"
- "--ignore=tests/test_binja_features.py"
- "--ignore=tests/test_ghidra_features.py"
- "--ignore=tests/test_ida_features.py"
- "--ignore=tests/test_viv_features.py"
- "--ignore=tests/test_idalib_features.py"
- "--ignore=tests/test_main.py"

View File

@@ -20,6 +20,7 @@
### Bug Fixes
- Fixed insecure deserialization vulnerability in YAML loading @0x1622 (#2770)
- loader: gracefully handle ELF files with unsupported architectures kamranulhaq2002@gmail.com #2800
- lint: disable rule caching during linting @Maijin #2817
### capa Explorer Web

View File

@@ -661,7 +661,9 @@ def get_rules_from_cli(args) -> RuleSet:
raises:
ShouldExitError: if the program is invoked incorrectly and should exit.
"""
enable_cache: bool = True
enable_cache: bool = getattr(args, "enable_cache", True)
# this allows calling functions to easily disable rule caching, e.g., used by the rule linter to avoid
try:
if capa.helpers.is_running_standalone() and args.is_default_rules:
cache_dir = get_default_root() / "cache"

View File

@@ -148,7 +148,7 @@ dev = [
"black==25.12.0",
"isort==7.0.0",
"mypy==1.19.1",
"mypy-protobuf==4.0.0",
"mypy-protobuf==5.0.0",
"PyGithub==2.8.1",
"bump-my-version==1.2.4",
# type stubs for mypy
@@ -165,7 +165,7 @@ build = [
# we want all developer environments to be consistent.
# These dependencies are not used in production environments
# and should not conflict with other libraries/tooling.
"pyinstaller==6.17.0",
"pyinstaller==6.18.0",
"setuptools==80.9.0",
"build==1.4.0"
]

View File

@@ -18,14 +18,14 @@ ida-settings==3.2.2
intervaltree==3.2.1
markdown-it-py==4.0.0
mdurl==0.1.2
msgpack==1.0.8
msgpack==1.1.2
networkx==3.4.2
pefile==2024.8.26
pip==25.3
protobuf==6.33.1
pyasn1==0.5.1
pyasn1-modules==0.3.0
pycparser==2.23
pyasn1==0.6.2
pyasn1-modules==0.4.2
pycparser==3.0
pydantic==2.12.4
# pydantic pins pydantic-core,
# but dependabot updates these separately (which is broken) and is annoying,
@@ -44,6 +44,6 @@ setuptools==80.9.0
six==1.17.0
sortedcontainers==2.4.0
viv-utils==0.8.0
vivisect==1.2.1
vivisect==1.3.0
msgspec==0.20.0
bump-my-version==1.2.4

View File

@@ -1229,6 +1229,7 @@ def main(argv=None):
time0 = time.time()
args.enable_cache = False
try:
rules = capa.main.get_rules_from_cli(args)
except capa.main.ShouldExitError as e:

View File

@@ -1,187 +0,0 @@
# Copyright 2020 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.
"""
run this script from within IDA to test the IDA feature extractor.
you must have loaded a file referenced by a test case in order
for this to do anything meaningful. for example, mimikatz.exe from testfiles.
you can invoke from the command line like this:
& 'C:\\Program Files\\IDA Pro 8.2\\idat.exe' \
-S"C:\\Exclusions\\code\\capa\\tests\\test_ida_features.py --CAPA_AUTOEXIT=true" \
-A \
-Lidalog \
'C:\\Exclusions\\code\\capa\\tests\\data\\mimikatz.exe_'
if you invoke from the command line, and provide the script argument `--CAPA_AUTOEXIT=true`,
then the script will exit IDA after running the tests.
the output (in idalog) will look like this:
```
Loading processor module C:\\Program Files\\IDA Pro 8.2\\procs\\pc.dll for metapc...Initializing processor module metapc...OK
Loading type libraries...
Autoanalysis subsystem has been initialized.
Database for file 'mimikatz.exe_' has been loaded.
--------------------------------------------------------------------------------
PASS: test_ida_feature_counts/mimikatz-function=0x40E5C2-basic block-7
PASS: test_ida_feature_counts/mimikatz-function=0x4702FD-characteristic(calls from)-0
SKIP: test_ida_features/294b8d...-function=0x404970,bb=0x404970,insn=0x40499F-string(\r\n\x00:ht)-False
SKIP: test_ida_features/64d9f-function=0x10001510,bb=0x100015B0-offset(0x4000)-True
...
SKIP: test_ida_features/pma16-01-function=0x404356,bb=0x4043B9-arch(i386)-True
PASS: test_ida_features/mimikatz-file-import(cabinet.FCIAddFile)-True
DONE
C:\\Exclusions\\code\\capa\\tests\\test_ida_features.py: Traceback (most recent call last):
File "C:\\Program Files\\IDA Pro 8.2\\python\\3\\ida_idaapi.py", line 588, in IDAPython_ExecScript
exec(code, g)
File "C:/Exclusions/code/capa/tests/test_ida_features.py", line 120, in <module>
sys.exit(0)
SystemExit: 0
-> OK
Flushing buffers, please wait...ok
```
Look for lines that start with "FAIL" to identify test failures.
"""
import io
import sys
import inspect
import logging
import traceback
from pathlib import Path
import pytest
try:
sys.path.append(str(Path(__file__).parent))
import fixtures
finally:
sys.path.pop()
logger = logging.getLogger("test_ida_features")
def check_input_file(wanted):
import idautils
# some versions (7.4) of IDA return a truncated version of the MD5.
# https://github.com/idapython/bin/issues/11
try:
found = idautils.GetInputFileMD5()[:31].decode("ascii").lower()
except UnicodeDecodeError:
# in IDA 7.5 or so, GetInputFileMD5 started returning raw binary
# rather than the hex digest
found = bytes.hex(idautils.GetInputFileMD5()[:15]).lower()
if not wanted.startswith(found):
raise RuntimeError(f"please run the tests against sample with MD5: `{wanted}`")
def get_ida_extractor(_path):
# have to import this inline so pytest doesn't bail outside of IDA
import capa.features.extractors.ida.extractor
return capa.features.extractors.ida.extractor.IdaFeatureExtractor()
def nocollect(f):
"don't collect the decorated function as a pytest test"
f.__test__ = False
return f
# although these look like pytest tests, they're not, because they don't run within pytest
# (the runner is below) and they use `yield`, which is deprecated.
@nocollect
@pytest.mark.skip(reason="IDA Pro tests must be run within IDA")
def test_ida_features():
# we're guaranteed to be in a function here, so there's a stack frame
this_name = inspect.currentframe().f_code.co_name # type: ignore
for sample, scope, feature, expected in fixtures.FEATURE_PRESENCE_TESTS + fixtures.FEATURE_PRESENCE_TESTS_IDA:
id = fixtures.make_test_id((sample, scope, feature, expected))
try:
check_input_file(fixtures.get_sample_md5_by_name(sample))
except RuntimeError:
yield this_name, id, "skip", None
continue
scope = fixtures.resolve_scope(scope)
sample = fixtures.resolve_sample(sample)
try:
fixtures.do_test_feature_presence(get_ida_extractor, sample, scope, feature, expected)
except Exception:
f = io.StringIO()
traceback.print_exc(file=f)
yield this_name, id, "fail", f.getvalue()
else:
yield this_name, id, "pass", None
@nocollect
@pytest.mark.skip(reason="IDA Pro tests must be run within IDA")
def test_ida_feature_counts():
# we're guaranteed to be in a function here, so there's a stack frame
this_name = inspect.currentframe().f_code.co_name # type: ignore
for sample, scope, feature, expected in fixtures.FEATURE_COUNT_TESTS:
id = fixtures.make_test_id((sample, scope, feature, expected))
try:
check_input_file(fixtures.get_sample_md5_by_name(sample))
except RuntimeError:
yield this_name, id, "skip", None
continue
scope = fixtures.resolve_scope(scope)
sample = fixtures.resolve_sample(sample)
try:
fixtures.do_test_feature_count(get_ida_extractor, sample, scope, feature, expected)
except Exception:
f = io.StringIO()
traceback.print_exc(file=f)
yield this_name, id, "fail", f.getvalue()
else:
yield this_name, id, "pass", None
if __name__ == "__main__":
import idc
import ida_auto
ida_auto.auto_wait()
print("-" * 80)
# invoke all functions in this module that start with `test_`
for name in dir(sys.modules[__name__]):
if not name.startswith("test_"):
continue
test = getattr(sys.modules[__name__], name)
logger.debug("invoking test: %s", name)
sys.stderr.flush()
for name, id, state, info in test():
print(f"{state.upper()}: {name}/{id}")
if info:
print(info)
print("DONE")
if "--CAPA_AUTOEXIT=true" in idc.ARGV:
sys.exit(0)

View File

@@ -2756,10 +2756,11 @@
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
"version": "4.17.23",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
"dev": true,
"license": "MIT"
},
"node_modules/lodash.merge": {
"version": "4.6.2",