mirror of
https://github.com/mandiant/capa.git
synced 2025-12-12 15:49:46 -08:00
merging upstream
This commit is contained in:
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@@ -15,10 +15,10 @@ jobs:
|
||||
# use old linux so that the shared library versioning is more portable
|
||||
artifact_name: capa
|
||||
asset_name: linux
|
||||
- os: windows-latest
|
||||
- os: windows-2019
|
||||
artifact_name: capa.exe
|
||||
asset_name: windows
|
||||
- os: macos-latest
|
||||
- os: macos-10.15
|
||||
artifact_name: capa
|
||||
asset_name: macos
|
||||
steps:
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
- if: matrix.os == 'ubuntu-latest'
|
||||
- if: matrix.os == 'ubuntu-16.04'
|
||||
run: sudo apt-get install -y libyaml-dev
|
||||
- name: Install PyInstaller
|
||||
run: pip install 'pyinstaller==4.2'
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
|
||||
zip:
|
||||
name: zip ${{ matrix.asset_name }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
needs: build
|
||||
strategy:
|
||||
matrix:
|
||||
|
||||
4
.github/workflows/publish.yml
vendored
4
.github/workflows/publish.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
@@ -26,4 +26,4 @@ jobs:
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
||||
run: |
|
||||
python setup.py sdist bdist_wheel
|
||||
twine upload --skip-existing dist/*
|
||||
twine upload --skip-existing dist/*
|
||||
|
||||
24
.github/workflows/tag.yml
vendored
Normal file
24
.github/workflows/tag.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: tag
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
tag:
|
||||
name: Tag capa rules
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout capa-rules
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: fireeye/capa-rules
|
||||
token: ${{ secrets.CAPA_TOKEN }}
|
||||
- name: Tag capa-rules
|
||||
run: git tag ${{ github.event.release.tag_name }}
|
||||
- name: Push tag to capa-rules
|
||||
uses: ad-m/github-push-action@master
|
||||
with:
|
||||
repository: fireeye/capa-rules
|
||||
github_token: ${{ secrets.CAPA_TOKEN }}
|
||||
tags: true
|
||||
7
.github/workflows/tests.yml
vendored
7
.github/workflows/tests.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
|
||||
jobs:
|
||||
code_style:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout capa
|
||||
uses: actions/checkout@v2
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
run: black -l 120 --check .
|
||||
|
||||
rule_linter:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout capa with rules submodule
|
||||
uses: actions/checkout@v2
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
|
||||
tests:
|
||||
name: Tests in ${{ matrix.python }}
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
needs: [code_style, rule_linter]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -67,4 +67,3 @@ jobs:
|
||||
run: pip install -e .[dev]
|
||||
- name: Run tests
|
||||
run: pytest tests/
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://pypi.org/project/flare-capa)
|
||||
[](https://github.com/fireeye/capa/releases)
|
||||
[](https://github.com/fireeye/capa-rules)
|
||||
[](https://github.com/fireeye/capa-rules)
|
||||
[](https://github.com/fireeye/capa/actions?query=workflow%3ACI+event%3Apush+branch%3Amaster)
|
||||
[](https://github.com/fireeye/capa/releases)
|
||||
[](LICENSE.txt)
|
||||
|
||||
@@ -617,6 +617,7 @@ class CapaExplorerForm(idaapi.PluginForm):
|
||||
|
||||
rule_path = settings.user[CAPA_SETTINGS_RULE_PATH]
|
||||
try:
|
||||
# TODO refactor: this first part is identical to capa.main.get_rules
|
||||
if not os.path.exists(rule_path):
|
||||
raise IOError("rule path %s does not exist or cannot be accessed" % rule_path)
|
||||
|
||||
@@ -632,8 +633,8 @@ class CapaExplorerForm(idaapi.PluginForm):
|
||||
continue
|
||||
for file in files:
|
||||
if not file.endswith(".yml"):
|
||||
if not (file.endswith(".md") or file.endswith(".git") or file.endswith(".txt")):
|
||||
# expect to see readme.md, format.md, and maybe a .git directory
|
||||
if not (file.startswith(".git") or file.endswith((".git", ".md", ".txt"))):
|
||||
# expect to see .git* files, readme.md, format.md, and maybe a .git directory
|
||||
# other things maybe are rules, but are mis-named.
|
||||
logger.warning("skipping non-.yml file: %s", file)
|
||||
continue
|
||||
@@ -1019,6 +1020,12 @@ class CapaExplorerForm(idaapi.PluginForm):
|
||||
|
||||
# create deep copy of current rules, add our new rule
|
||||
rules = copy.copy(self.rules_cache)
|
||||
|
||||
# ensure subscope rules are included
|
||||
for sub in rule.extract_subscope_rules():
|
||||
rules.append(sub)
|
||||
|
||||
# include our new rule in the list
|
||||
rules.append(rule)
|
||||
|
||||
try:
|
||||
|
||||
@@ -415,6 +415,11 @@ class CapaExplorerRulgenEditor(QtWidgets.QTreeWidget):
|
||||
# create a new parent under root node, by default; new node added last position in tree
|
||||
new_parent = self.new_expression_node(self.root, (action.data()[0], ""))
|
||||
|
||||
if "basic block" in action.data()[0]:
|
||||
# add default child expression when nesting under basic block
|
||||
new_parent.setExpanded(True)
|
||||
new_parent = self.new_expression_node(new_parent, ("- or:", ""))
|
||||
|
||||
for o in self.get_features(selected=True):
|
||||
# take child from its parent by index, add to new parent
|
||||
new_parent.addChild(o.parent().takeChild(o.parent().indexOfChild(o)))
|
||||
@@ -425,6 +430,15 @@ class CapaExplorerRulgenEditor(QtWidgets.QTreeWidget):
|
||||
def slot_edit_expression(self, action):
|
||||
""" """
|
||||
expression, o = action.data()
|
||||
if "basic block" in expression and "basic block" not in o.text(
|
||||
CapaExplorerRulgenEditor.get_column_feature_index()
|
||||
):
|
||||
# current expression is "basic block", and not changing to "basic block" expression
|
||||
children = o.takeChildren()
|
||||
new_parent = self.new_expression_node(o, ("- or:", ""))
|
||||
for child in children:
|
||||
new_parent.addChild(child)
|
||||
new_parent.setExpanded(True)
|
||||
o.setText(CapaExplorerRulgenEditor.get_column_feature_index(), expression)
|
||||
|
||||
def slot_clear_all(self, action):
|
||||
@@ -801,9 +815,11 @@ class CapaExplorerRulegenFeatures(QtWidgets.QTreeWidget):
|
||||
if text:
|
||||
for o in iterate_tree(self):
|
||||
data = o.data(0, 0x100)
|
||||
if data and text.lower() not in data.get_value_str().lower():
|
||||
o.setHidden(True)
|
||||
continue
|
||||
if data:
|
||||
to_match = data.get_value_str()
|
||||
if not to_match or text.lower() not in to_match.lower():
|
||||
o.setHidden(True)
|
||||
continue
|
||||
o.setHidden(False)
|
||||
o.setExpanded(True)
|
||||
else:
|
||||
|
||||
@@ -379,8 +379,8 @@ def get_rules(rule_path, disable_progress=False):
|
||||
|
||||
for file in files:
|
||||
if not file.endswith(".yml"):
|
||||
if not (file.endswith(".md") or file.endswith(".git") or file.endswith(".txt")):
|
||||
# expect to see readme.md, format.md, and maybe a .git directory
|
||||
if not (file.startswith(".git") or file.endswith((".git", ".md", ".txt"))):
|
||||
# expect to see .git* files, readme.md, format.md, and maybe a .git directory
|
||||
# other things maybe are rules, but are mis-named.
|
||||
logger.warning("skipping non-.yml file: %s", file)
|
||||
continue
|
||||
|
||||
25
doc/release.md
Normal file
25
doc/release.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Release checklist
|
||||
|
||||
- [ ] Ensure all milestoned issues/PRs are addressed, or reassign to a new milestone.
|
||||
- [ ] Add the `dont merge` label to all PRs that are close to be ready to merge (or merge them if they are ready) in [capa](https://github.com/fireeye/capa/pulls) and [capa-rules](https://github.com/fireeye/capa-rules/pulls).
|
||||
- [ ] Ensure the [CI workflow succeeds in master](https://github.com/fireeye/capa/actions/workflows/tests.yml?query=branch%3Amaster).
|
||||
- [ ] Ensure that `python scripts/lint.py rules/ --thorough` succeeds (only `missing examples` offenses are allowed in the nursery).
|
||||
- [ ] Review changes
|
||||
- capa https://github.com/fireeye/capa/compare/\<last-release\>...master
|
||||
- capa-rules https://github.com/fireeye/capa-rules/compare/\<last-release>\...master
|
||||
- [ ] Update [CHANGELOG.md](https://github.com/fireeye/capa/blob/master/CHANGELOG.md)
|
||||
- Do not forget to add a nice introduction thanking contributors
|
||||
- Remember that we need a major release if we introduce breaking changes
|
||||
- Sections
|
||||
- New Features
|
||||
- New Rules
|
||||
- Bug Fixes
|
||||
- Changes
|
||||
- Development
|
||||
- Raw diffs
|
||||
- [ ] Update [capa/version.py](https://github.com/fireeye/capa/blob/master/capa/version.py)
|
||||
- [ ] Create a PR with the updated [CHANGELOG.md](https://github.com/fireeye/capa/blob/master/CHANGELOG.md) and [capa/version.py](https://github.com/fireeye/capa/blob/master/capa/version.py). Copy this checklist in the PR description.
|
||||
- [ ] After PR review, merge the PR and [create the release in GH](https://github.com/fireeye/capa/releases/new) using text from the [CHANGELOG.md](https://github.com/fireeye/capa/blob/master/CHANGELOG.md).
|
||||
- [ ] Verify GH actions [upload artifacts](https://github.com/fireeye/capa/releases), [publish to PyPI](https://pypi.org/project/flare-capa) and [create a tag in capa rules](https://github.com/fireeye/capa-rules/tags) upon completion.
|
||||
- [ ] [Spread the word](https://twitter.com)
|
||||
|
||||
2
rules
2
rules
Submodule rules updated: a6ec668690...eb8221d9ad
Submodule tests/data updated: cd6defdb2c...e63a71b394
Reference in New Issue
Block a user