Ghidra: Basic Block Feature Extraction (#1637) #3988
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CI | |
on: | |
push: | |
branches: [ master, backend-ghidra ] | |
pull_request: | |
branches: [ master, backend-ghidra ] | |
permissions: read-all | |
# save workspaces to speed up testing | |
env: | |
CAPA_SAVE_WORKSPACE: "True" | |
jobs: | |
changelog_format: | |
runs-on: ubuntu-20.04 | |
steps: | |
- name: Checkout capa | |
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 | |
# The sync GH action in capa-rules relies on a single '- *$' in the CHANGELOG file | |
- name: Ensure CHANGELOG has '- *$' | |
run: | | |
number=$(grep '\- *$' CHANGELOG.md | wc -l) | |
if [ $number != 1 ]; then exit 1; fi | |
code_style: | |
runs-on: ubuntu-20.04 | |
steps: | |
- name: Checkout capa | |
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 | |
# use latest available python to take advantage of best performance | |
- name: Set up Python 3.11 | |
uses: actions/setup-python@d27e3f3d7c64b4bbf8e4abfb9b63b83e846e0435 # v4.5.0 | |
with: | |
python-version: "3.11" | |
- name: Install dependencies | |
run: pip install -e .[dev] | |
- name: Lint with ruff | |
run: pre-commit run ruff | |
- name: Lint with isort | |
run: pre-commit run isort | |
- name: Lint with black | |
run: pre-commit run black | |
- name: Lint with flake8 | |
run: pre-commit run flake8 | |
- name: Check types with mypy | |
run: pre-commit run mypy | |
rule_linter: | |
runs-on: ubuntu-20.04 | |
steps: | |
- name: Checkout capa with submodules | |
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 | |
with: | |
submodules: recursive | |
- name: Set up Python 3.11 | |
uses: actions/setup-python@d27e3f3d7c64b4bbf8e4abfb9b63b83e846e0435 # v4.5.0 | |
with: | |
python-version: "3.11" | |
- name: Install capa | |
run: pip install -e .[dev] | |
- name: Run rule linter | |
run: python scripts/lint.py rules/ | |
tests: | |
name: Tests in ${{ matrix.python-version }} on ${{ matrix.os }} | |
runs-on: ${{ matrix.os }} | |
needs: [code_style, rule_linter] | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ubuntu-20.04, windows-2019, macos-11] | |
# across all operating systems | |
python-version: ["3.8", "3.11"] | |
include: | |
# on Ubuntu run these as well | |
- os: ubuntu-20.04 | |
python-version: "3.8" | |
- os: ubuntu-20.04 | |
python-version: "3.9" | |
- os: ubuntu-20.04 | |
python-version: "3.10" | |
steps: | |
- name: Checkout capa with submodules | |
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 | |
with: | |
submodules: recursive | |
- name: Set up Python ${{ matrix.python-version }} | |
uses: actions/setup-python@d27e3f3d7c64b4bbf8e4abfb9b63b83e846e0435 # v4.5.0 | |
with: | |
python-version: ${{ matrix.python-version }} | |
- name: Install pyyaml | |
if: matrix.os == 'ubuntu-20.04' | |
run: sudo apt-get install -y libyaml-dev | |
- name: Install capa | |
run: pip install -e .[dev] | |
- name: Run tests | |
run: pytest -v tests/ | |
binja-tests: | |
name: Binary Ninja tests for ${{ matrix.python-version }} | |
env: | |
BN_SERIAL: ${{ secrets.BN_SERIAL }} | |
runs-on: ubuntu-20.04 | |
needs: [code_style, rule_linter] | |
strategy: | |
fail-fast: false | |
matrix: | |
python-version: ["3.8", "3.11"] | |
steps: | |
- name: Checkout capa with submodules | |
# do only run if BN_SERIAL is available, have to do this in every step, see https://github.com/orgs/community/discussions/26726#discussioncomment-3253118 | |
if: ${{ env.BN_SERIAL != 0 }} | |
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 | |
with: | |
submodules: recursive | |
- name: Set up Python ${{ matrix.python-version }} | |
if: ${{ env.BN_SERIAL != 0 }} | |
uses: actions/setup-python@d27e3f3d7c64b4bbf8e4abfb9b63b83e846e0435 # v4.5.0 | |
with: | |
python-version: ${{ matrix.python-version }} | |
- name: Install pyyaml | |
if: ${{ env.BN_SERIAL != 0 }} | |
run: sudo apt-get install -y libyaml-dev | |
- name: Install capa | |
if: ${{ env.BN_SERIAL != 0 }} | |
run: pip install -e .[dev] | |
- name: install Binary Ninja | |
if: ${{ env.BN_SERIAL != 0 }} | |
run: | | |
mkdir ./.github/binja | |
curl "https://raw.githubusercontent.com/Vector35/binaryninja-api/6812c97/scripts/download_headless.py" -o ./.github/binja/download_headless.py | |
python ./.github/binja/download_headless.py --serial ${{ env.BN_SERIAL }} --output .github/binja/BinaryNinja-headless.zip | |
unzip .github/binja/BinaryNinja-headless.zip -d .github/binja/ | |
python .github/binja/binaryninja/scripts/install_api.py --install-on-root --silent | |
- name: Run tests | |
if: ${{ env.BN_SERIAL != 0 }} | |
env: | |
BN_LICENSE: ${{ secrets.BN_LICENSE }} | |
run: pytest -v tests/test_binja_features.py # explicitly refer to the binja tests for performance. other tests run above. | |
ghidra-tests: | |
name: Ghidra tests for ${{ matrix.python-version }} | |
runs-on: ubuntu-20.04 | |
needs: [code_style, rule_linter] | |
strategy: | |
fail-fast: false | |
matrix: | |
python-version: ["3.8", "3.11"] | |
java-version: ["17"] | |
gradle-version: ["7.3"] | |
ghidra-version: ["10.3"] | |
public-version: ["PUBLIC_20230510"] # for ghidra releases | |
jep-version: ["4.1.1"] | |
ghidrathon-version: ["2.1.0"] | |
steps: | |
- name: Checkout capa with submodules | |
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 | |
with: | |
submodules: true | |
- name: Set up Python ${{ matrix.python-version }} | |
uses: actions/setup-python@d27e3f3d7c64b4bbf8e4abfb9b63b83e846e0435 # v4.5.0 | |
with: | |
python-version: ${{ matrix.python-version }} | |
- name: Set up Java ${{ matrix.java-version }} | |
uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3 | |
with: | |
distribution: 'temurin' | |
java-version: ${{ matrix.java-version }} | |
- name: Set up Gradle ${{ matrix.gradle-version }} | |
uses: gradle/gradle-build-action@40b6781dcdec2762ad36556682ac74e31030cfe2 # v2.5.1 | |
with: | |
gradle-version: ${{ matrix.gradle-version }} | |
- name: Install Jep ${{ matrix.jep-version }} | |
run : pip install jep==${{ matrix.jep-version }} | |
- name: Install Ghidra ${{ matrix.ghidra-version }} | |
run: | | |
mkdir ./.github/ghidra | |
mkdir ./.github/ghidra/project | |
wget "https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_${{ matrix.ghidra-version }}_build/ghidra_${{ matrix.ghidra-version }}_${{ matrix.public-version }}.zip" -O ./.github/ghidra/ghidra_${{ matrix.ghidra-version }}_PUBLIC.zip | |
unzip .github/ghidra/ghidra_${{ matrix.ghidra-version }}_PUBLIC.zip -d .github/ghidra/ | |
- name: Install Ghidrathon | |
run : | | |
mkdir ./.github/ghidrathon | |
mkdir -p ~/.ghidra/.ghidra_${{ matrix.ghidra-version }}_PUBLIC/Extensions | |
wget "https://github.com/mandiant/Ghidrathon/archive/refs/tags/v${{ matrix.ghidrathon-version }}.zip" -O ./.github/ghidrathon/ghidrathon-${{ matrix.ghidrathon-version }}.zip | |
unzip .github/ghidrathon/ghidrathon-${{ matrix.ghidrathon-version }}.zip -d .github/ghidrathon/ | |
workdir=$(pwd) | |
gradle -p ./.github/ghidrathon/Ghidrathon-${{ matrix.ghidrathon-version }}/ -PGHIDRA_INSTALL_DIR=$workdir/.github/ghidra/ghidra_${{ matrix.ghidra-version }}_PUBLIC | |
unzip .github/ghidrathon/Ghidrathon-${{ matrix.ghidrathon-version }}/dist/*.zip -d ~/.ghidra/.ghidra_${{ matrix.ghidra-version }}_PUBLIC/Extensions | |
- name: Install pyyaml | |
run: sudo apt-get install -y libyaml-dev | |
- name: Install capa | |
run: pip install -e .[dev] | |
- name: Run tests | |
run: | # runs main.py for now... | |
.github/ghidra/ghidra_${{ matrix.ghidra-version }}_PUBLIC/support/analyzeHeadless .github/ghidra/project ghidra_test -Import ./tests/data/'Practical Malware Analysis Lab 01-01.dll_' | |
.github/ghidra/ghidra_${{ matrix.ghidra-version }}_PUBLIC/support/analyzeHeadless .github/ghidra/project ghidra_test -process 'Practical Malware Analysis Lab 01-01.dll_' -ScriptPath ./capa -PostScript main.py | |