-
Notifications
You must be signed in to change notification settings - Fork 762
Contributing
Welcome to the Qiling Framework community! This guide will help you contribute effectively to this world-class open-source emulation framework.
Qiling Framework thrives on community contributions. Whether you're fixing bugs, adding features, improving documentation, or helping other users, your contributions make Qiling better for everyone.
- 🐛 Bug Reports & Fixes
- ✨ New Features & Enhancements
- 📚 Documentation Improvements
- 🧪 Testing & Quality Assurance
- 🎯 Performance Optimizations
- 🌍 Platform Support Extensions
- 🔧 Developer Tools & Utilities
- 💬 Community Support
Development Environment:
# Required tools
git --version # Git 2.20+
python --version # Python 3.8+
pip --version # Latest pip
# Development dependencies
sudo apt install build-essential cmake # Linux
# or
brew install cmake # macOSSetting Up Development Environment:
# 1. Fork the repository on GitHub
# 2. Clone your fork
git clone https://github.com/YOUR_USERNAME/qiling.git
cd qiling
# 3. Add upstream remote
git remote add upstream https://github.com/qilingframework/qiling.git
# 4. Create development environment
python -m venv qiling-dev
source qiling-dev/bin/activate # Linux/macOS
# or qiling-dev\Scripts\activate # Windows
# 5. Install in development mode
pip install -e .
pip install -r requirements-dev.txt # If available
# 6. Install pre-commit hooks
pip install pre-commit
pre-commit installStandard Git Workflow:
# 1. Sync with upstream
git fetch upstream
git checkout master
git merge upstream/master
# 2. Create feature branch
git checkout -b feature/your-feature-name
git checkout -b fix/issue-number
git checkout -b docs/improvement-description
# 3. Make your changes
# ... code, test, commit ...
# 4. Push and create PR
git push origin feature/your-feature-name
# Create Pull Request on GitHubPython Code Style:
# Follow PEP 8 with these specifications:
# - Line length: 88 characters (Black formatter)
# - Use type hints for new code
# - Comprehensive docstrings for public APIs
from typing import Optional, Union, List, Dict, Any
from qiling import Qiling
from qiling.const import QL_ARCH, QL_OS
class ExampleAnalyzer:
"""Example analyzer following Qiling coding standards.
This class demonstrates proper code style, documentation,
and type annotations for Qiling Framework contributions.
Args:
ql: Qiling instance to analyze
config: Optional configuration dictionary
Example:
>>> analyzer = ExampleAnalyzer(ql, {"verbose": True})
>>> results = analyzer.analyze()
"""
def __init__(self, ql: Qiling, config: Optional[Dict[str, Any]] = None) -> None:
self.ql = ql
self.config = config or {}
self._results: List[Dict[str, Any]] = []
def analyze(self, timeout: Optional[int] = None) -> Dict[str, Any]:
"""Perform analysis on the Qiling instance.
Args:
timeout: Optional timeout in seconds
Returns:
Dictionary containing analysis results
Raises:
QilingAnalysisError: If analysis fails
"""
try:
# Implementation here
return {"status": "success", "results": self._results}
except Exception as e:
raise QilingAnalysisError(f"Analysis failed: {e}") from e
def _internal_method(self) -> bool:
"""Private methods start with underscore."""
return True
# Function style
def analyze_binary(
binary_path: str,
rootfs_path: str,
*, # Force keyword-only arguments
architecture: Optional[QL_ARCH] = None,
os_type: Optional[QL_OS] = None,
verbose: bool = False
) -> Dict[str, Any]:
"""Analyze binary with Qiling Framework.
Args:
binary_path: Path to binary file
rootfs_path: Path to root filesystem
architecture: Target architecture (auto-detected if None)
os_type: Target OS type (auto-detected if None)
verbose: Enable verbose output
Returns:
Analysis results dictionary
Example:
>>> results = analyze_binary("malware.exe", "rootfs/", verbose=True)
>>> print(results["execution_time"])
"""
# Implementation
passCode Quality Tools:
# Format code with Black
black qiling/ tests/ examples/
# Sort imports with isort
isort qiling/ tests/ examples/
# Type checking with mypy
mypy qiling/
# Linting with flake8
flake8 qiling/ tests/
# Security checking with bandit
bandit -r qiling/Test Structure:
# tests/test_new_feature.py
import pytest
import tempfile
import os
from qiling import Qiling
from qiling.const import QL_ARCH, QL_OS
from qiling.exception import QilingError
class TestNewFeature:
"""Test suite for new feature implementation."""
@pytest.fixture
def sample_binary(self):
"""Provide sample binary for testing."""
# Create or return path to test binary
return "tests/samples/x8664_hello"
@pytest.fixture
def rootfs_path(self):
"""Provide rootfs path for testing."""
return "tests/rootfs/x8664_linux"
def test_basic_functionality(self, sample_binary, rootfs_path):
"""Test basic functionality works correctly."""
ql = Qiling([sample_binary], rootfs_path)
# Test your feature
result = ql.your_new_feature()
assert result is not None
assert isinstance(result, dict)
assert "status" in result
def test_error_handling(self, rootfs_path):
"""Test proper error handling."""
with pytest.raises(QilingError):
ql = Qiling(["nonexistent_file"], rootfs_path)
ql.your_new_feature()
def test_edge_cases(self, sample_binary, rootfs_path):
"""Test edge cases and boundary conditions."""
ql = Qiling([sample_binary], rootfs_path)
# Test with empty input
result = ql.your_new_feature("")
assert result["status"] == "empty_input"
# Test with large input
large_input = "A" * 10000
result = ql.your_new_feature(large_input)
assert result["status"] == "success"
@pytest.mark.parametrize("arch,os_type", [
(QL_ARCH.X86, QL_OS.LINUX),
(QL_ARCH.X8664, QL_OS.LINUX),
(QL_ARCH.ARM, QL_OS.LINUX),
])
def test_multiple_architectures(self, arch, os_type):
"""Test feature across multiple architectures."""
# Use shellcode for architecture testing
shellcode = b'\x90\x90\x90\x90' # NOP sled
ql = Qiling(code=shellcode, archtype=arch, ostype=os_type)
result = ql.your_new_feature()
assert result["architecture"] == arch
def test_performance(self, sample_binary, rootfs_path):
"""Test performance requirements."""
import time
ql = Qiling([sample_binary], rootfs_path)
start_time = time.time()
result = ql.your_new_feature()
end_time = time.time()
# Feature should complete within reasonable time
assert (end_time - start_time) < 5.0 # 5 seconds max
assert result["execution_time"] < 5.0
# Integration tests
class TestIntegration:
"""Integration tests for new feature."""
def test_with_existing_features(self, sample_binary, rootfs_path):
"""Test integration with existing Qiling features."""
ql = Qiling([sample_binary], rootfs_path)
# Test with hooks
hook_called = False
def test_hook(ql, address, size):
nonlocal hook_called
hook_called = True
ql.hook_code(test_hook)
result = ql.your_new_feature()
assert hook_called
assert result["hooks_active"] == TrueRunning Tests:
# Run all tests
pytest
# Run specific test file
pytest tests/test_new_feature.py
# Run with coverage
pytest --cov=qiling tests/
# Run performance tests
pytest -m performance
# Run tests for specific architecture
pytest -k "x8664"Code Documentation:
def complex_analysis_function(
ql: Qiling,
analysis_type: str,
options: Dict[str, Any]
) -> Dict[str, Any]:
"""Perform complex analysis on Qiling instance.
This function implements advanced analysis techniques for binary
emulation, supporting multiple analysis types and configurations.
Args:
ql: Initialized Qiling instance
analysis_type: Type of analysis to perform. Supported types:
- "behavioral": Behavioral analysis
- "static": Static analysis
- "dynamic": Dynamic analysis
- "hybrid": Combined static + dynamic
options: Analysis configuration options:
- timeout (int): Analysis timeout in seconds (default: 60)
- depth (int): Analysis depth level (1-10, default: 5)
- output_format (str): Output format ("json", "xml", "text")
- enable_hooks (bool): Enable API hooking (default: True)
Returns:
Dictionary containing analysis results with the following structure:
{
"status": "success" | "failed" | "timeout",
"analysis_type": str,
"execution_time": float,
"results": {
"api_calls": List[Dict],
"memory_accesses": List[Dict],
"coverage": Dict,
"artifacts": List[str]
},
"metadata": {
"qiling_version": str,
"timestamp": str,
"configuration": Dict
}
}
Raises:
QilingAnalysisError: If analysis configuration is invalid
QilingTimeoutError: If analysis exceeds timeout
QilingMemoryError: If insufficient memory for analysis
Example:
>>> ql = Qiling(["malware.exe"], "rootfs/")
>>> options = {"timeout": 120, "depth": 7}
>>> results = complex_analysis_function(ql, "behavioral", options)
>>> print(f"Found {len(results['results']['api_calls'])} API calls")
Note:
This function requires significant memory for complex analyses.
Consider using streaming mode for large binaries.
See Also:
- simple_analysis_function(): For basic analysis needs
- streaming_analysis(): For memory-efficient analysis
.. versionadded:: 1.5.0
.. versionchanged:: 1.6.0
Added hybrid analysis support
"""
# Implementation here
passWiki Documentation:
# New Feature Documentation
## Overview
Brief description of the new feature, its purpose, and benefits.
## Installation
Any additional installation steps required for the feature.
## Basic Usage
### Simple Example
\`\`\`python
from qiling import Qiling
ql = Qiling(["binary"], "rootfs/")
result = ql.new_feature()
print(result)
\`\`\`
### Advanced Example
\`\`\`python
# More complex usage example
\`\`\`
## API Reference
Detailed API documentation with parameters and return values.
## Configuration
Configuration options and their effects.
## Performance Considerations
Performance implications and optimization tips.
## Troubleshooting
Common issues and solutions.
## Examples
Real-world usage examples and case studies.Feature Proposal:
- Create GitHub Issue: Describe the feature with use cases
- Design Discussion: Engage with maintainers and community
- API Design: Define the public API interface
- Implementation Plan: Break down into manageable tasks
Design Document Template:
# Feature Design: [Feature Name]
## Problem Statement
What problem does this feature solve?
## Proposed Solution
High-level description of the solution.
## API Design
```python
# Proposed API
def new_feature_api():
passTechnical implementation approach.
How will this feature be tested?
What documentation needs to be created/updated?
Any breaking changes or migration steps.
Other approaches that were considered and why they were rejected.
### Implementation Phase
**Development Checklist:**
- [ ] Feature implementation
- [ ] Comprehensive tests (unit + integration)
- [ ] Performance benchmarks
- [ ] Documentation updates
- [ ] Example code
- [ ] Backward compatibility check
- [ ] Security review (if applicable)
**Code Review Guidelines:**
- Keep pull requests focused and manageable
- Write clear commit messages
- Include tests for all new functionality
- Update documentation alongside code changes
- Ensure CI/CD passes before requesting review
### Quality Assurance
**Pre-submission Checklist:**
```bash
# 1. Code formatting and linting
black .
isort .
flake8 .
# 2. Type checking
mypy qiling/
# 3. Security scanning
bandit -r qiling/
# 4. Test suite
pytest --cov=qiling
# 5. Performance regression tests
python benchmarks/performance_test.py
# 6. Documentation build
cd docs && make html
# 7. Integration tests
pytest tests/integration/
# qiling/arch/new_arch.py
from qiling.arch.arch import QlArch
from qiling.const import QL_ARCH
class QlArchNEWARCH(QlArch):
"""Support for NEW_ARCH architecture."""
def __init__(self, ql):
super().__init__(ql)
self.type = QL_ARCH.NEW_ARCH
self.bits = 32 # or 64
self.big_endian = False # or True
def setup_register_table(self):
"""Set up architecture-specific register table."""
self.ql_reg_table = {
# Map register names to indices
"r0": 0,
"r1": 1,
# ... more registers
}
def init_context(self):
"""Initialize architecture context."""
# Set up initial register values
# Set up stack pointer
# Set up other architecture-specific initialization
pass
def disassembler(self, code, address):
"""Disassemble instruction for this architecture."""
# Use capstone or other disassembler
pass# qiling/os/new_os/new_os.py
from qiling.os.os import QlOs
from qiling.const import QL_OS
class QlOsNEWOS(QlOs):
"""Support for NEW_OS operating system."""
def __init__(self, ql):
super().__init__(ql)
self.type = QL_OS.NEW_OS
def setup_syscall_table(self):
"""Set up OS-specific system call table."""
self.syscall_table = {
1: self.syscall_exit,
2: self.syscall_read,
# ... more syscalls
}
def syscall_exit(self, exit_code):
"""Implement exit system call."""
self.ql.emu_stop()
self.ql.exit_code = exit_code
def load_binary(self, filename):
"""Load binary file for this OS."""
# Implement OS-specific binary loading
pass# benchmarks/performance_test.py
import time
import statistics
from typing import List, Dict, Any
from qiling import Qiling
class QilingBenchmark:
"""Benchmarking framework for Qiling performance testing."""
def __init__(self):
self.results: Dict[str, List[float]] = {}
def benchmark_function(self, name: str, func, iterations: int = 10):
"""Benchmark a specific function."""
times = []
for _ in range(iterations):
start_time = time.perf_counter()
func()
end_time = time.perf_counter()
times.append(end_time - start_time)
self.results[name] = times
def report_results(self):
"""Generate benchmark report."""
for name, times in self.results.items():
mean_time = statistics.mean(times)
std_dev = statistics.stdev(times) if len(times) > 1 else 0
min_time = min(times)
max_time = max(times)
print(f"{name}:")
print(f" Mean: {mean_time:.4f}s")
print(f" Std Dev: {std_dev:.4f}s")
print(f" Min: {min_time:.4f}s")
print(f" Max: {max_time:.4f}s")
print()
def benchmark_emulation_speed():
"""Benchmark basic emulation speed."""
def run_basic_emulation():
ql = Qiling(["tests/samples/hello"], "tests/rootfs/")
ql.run()
benchmark = QilingBenchmark()
benchmark.benchmark_function("basic_emulation", run_basic_emulation)
benchmark.report_results()
if __name__ == "__main__":
benchmark_emulation_speed()Creating New Wiki Pages:
- Follow the established structure and style
- Use clear headings and consistent formatting
- Include practical examples and code snippets
- Add cross-references to related pages
- Keep content up-to-date with latest Qiling version
Improving Existing Pages:
- Fix typos and grammatical errors
- Update outdated information
- Add missing examples or clarifications
- Improve code formatting and syntax highlighting
- Add troubleshooting sections
Docstring Standards:
- Use Google-style or NumPy-style docstrings
- Include type hints for all parameters
- Provide examples for complex functions
- Document exceptions that may be raised
- Include version information for new features
Forum Participation:
- Answer questions on GitHub Discussions
- Help troubleshoot issues in Telegram chat
- Create tutorials and blog posts
- Present at conferences and meetups
Issue Triage:
- Reproduce and verify bug reports
- Add labels and categorize issues
- Help gather additional information
- Test proposed fixes
Onboarding Support:
- Help new contributors set up development environment
- Guide them through their first contributions
- Review and provide feedback on pull requests
- Share knowledge about Qiling internals
Pre-release Checklist:
- All CI/CD checks pass
- Documentation is up-to-date
- Version numbers are updated
- Changelog is complete
- Migration guide is ready (if needed)
- Performance regression tests pass
Release Testing:
- Test on multiple platforms
- Verify backwards compatibility
- Test installation from PyPI
- Validate example code still works
Hall of Fame:
- Major contributors are recognized in CREDITS.md
- Significant contributions highlighted in release notes
- Conference presentation opportunities
- Recommendation letters for contributors
Badges and Achievements:
- GitHub contributor badges
- Special recognition for milestone contributions
- Community contributor spotlights
By contributing to Qiling Framework, you agree that:
- Your contributions are your original work
- You have the right to submit your contributions
- Your contributions will be licensed under GPLv2
- You understand the open-source nature of the project
- Maintain existing copyright notices
- Add your copyright for substantial contributions
- Credit external code sources properly
- Respect third-party licenses
- GitHub Discussions: General questions and feature discussions
- Telegram Chat: Quick questions and real-time help
- GitHub Issues: Bug reports and specific problems
- Email: Sensitive security issues ([email protected])
New contributors can request mentorship from experienced community members:
- Code review and feedback
- Architecture guidance
- Best practices training
- Career development advice
Thank you for contributing to Qiling Framework! Your contributions help make this project better for the entire cybersecurity community. Together, we're building the future of binary emulation and analysis.
- Home
- Getting Started
- Core Concepts
- Usage
- Features
- Tutorials
- Development
- Resources