feat: add DWARF parsing support for exporting local variables #30
This file contains hidden or 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: 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 |