Skip to content

feat: add DWARF parsing support for exporting local variables #30

feat: add DWARF parsing support for exporting local variables

feat: add DWARF parsing support for exporting local variables #30

Workflow file for this run

name: LibSurgeon CI
on:
push:
pull_request:
jobs:
# ============================================================
# Code Quality Checks
# ============================================================
lint:
name: Lint & Format Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install black flake8 isort
- name: Check formatting with black
run: |
python -m black --check --diff libsurgeon.py evaluate_quality.py tests/*.py
- name: Lint with flake8
run: |
python -m flake8 .
# ============================================================
# Unit Tests
# ============================================================
test:
name: Tests (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest pytest-cov
pip install -r requirements.txt || true
- name: Build test fixtures
run: |
cd tests
bash build_fixtures.sh
- name: Run tests
run: |
pytest tests/ -v --tb=short
- name: Run tests with coverage
if: matrix.python-version == '3.11'
run: |
pytest tests/ --cov=. --cov-report=xml --cov-report=term-missing
- name: Upload coverage to Codecov
if: matrix.python-version == '3.11'
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
fail_ci_if_error: false
# ============================================================
# Integration Test (with Ghidra)
# ============================================================
integration:
name: Integration Test (Ghidra)
runs-on: ubuntu-latest
# Run on all PRs and pushes to test Ghidra integration
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Download and setup Ghidra
run: |
wget -q https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_11.2.1_build/ghidra_11.2.1_PUBLIC_20241105.zip
unzip -q ghidra_11.2.1_PUBLIC_20241105.zip
mv ghidra_11.2.1_PUBLIC $HOME/ghidra
echo "GHIDRA_HOME=$HOME/ghidra" >> $GITHUB_ENV
- name: Build test fixtures
run: |
cd tests
bash build_fixtures.sh
- name: Test archive extraction
run: |
python -c "from libsurgeon import extract_archive; print('Import OK')"
- name: Test ELF detection
run: |
python -c "from libsurgeon import is_elf_file, get_file_type, FileType; assert get_file_type('test.elf') == FileType.ELF; print('ELF detection OK')"
- name: Test module strategies
run: |
python -c "from libsurgeon import MODULE_STRATEGIES; assert len(MODULE_STRATEGIES) == 4; print('Module strategies OK')"
- name: Test progress bar
run: |
python -c "from libsurgeon import draw_progress_bar; bar = draw_progress_bar(50, 100); assert len(bar) == 40; print('Progress bar OK')"
- name: Test quality evaluation
run: |
# Create a sample decompiled file
mkdir -p test_output
echo 'void test() { return; }' > test_output/sample.cpp
python evaluate_quality.py test_output/
- name: Test quality evaluation with C files
run: |
# Test that *.c* pattern works for both .c and .cpp
mkdir -p test_output_c
echo 'int foo(void) { return 42; }' > test_output_c/sample.c
echo 'void bar() { return; }' > test_output_c/sample.cpp
python evaluate_quality.py test_output_c/
- name: Test libsurgeon help
run: |
python libsurgeon.py --help
# Verify ELF module option exists
python libsurgeon.py --help | grep -q "\-m.*prefix\|alpha\|camelcase\|single"
- name: Test architecture detection
run: |
python -c "from libsurgeon import detect_elf_architecture, ELF_MACHINE_MAP; assert 0x28 in ELF_MACHINE_MAP, 'ARM should be in map'; assert 0x3E in ELF_MACHINE_MAP, 'x86-64 should be in map'; print('Architecture detection OK')"
- name: Test Ghidra decompilation of archive
run: |
# Test decompiling the test archive with Ghidra
python libsurgeon.py -g $HOME/ghidra tests/fixtures/libtest.a -o test_decompile_output --clean
# Verify output was generated
ls -la test_decompile_output/
test -d test_decompile_output/libtest/src
# Check that at least one .cpp file was created
cpp_count=$(find test_decompile_output/libtest/src -name "*.cpp" | wc -l)
echo "Generated $cpp_count .cpp files"
test $cpp_count -ge 1
- name: Test Ghidra decompilation with evaluation
run: |
# Test with --evaluate flag
python libsurgeon.py -g $HOME/ghidra tests/fixtures/libtest.a -o test_eval_output --evaluate --clean
# Verify quality report was generated
test -f test_eval_output/libtest/quality_report.json
cat test_eval_output/libtest/quality_report.json
- name: Test ELF file decompilation
run: |
# Test decompiling ELF executable
python libsurgeon.py -g $HOME/ghidra tests/fixtures/test_program.elf -o test_elf_output --clean
# Verify output
ls -la test_elf_output/
test -d test_elf_output/test_program/src
# ============================================================
# Documentation
# ============================================================
docs:
name: Documentation Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check README exists
run: |
test -f README.md
- name: Check LICENSE exists
run: |
test -f LICENSE