Migration Guide
This guide helps you migrate from the legacy Sandroid installation to the modern PyPI package, and understand the changes introduced in v1.1.0.
Migration Overview
What Changed in v1.1.0:
Complete package restructuring from
src/utils/
to proper Python packagesModern PyPI distribution with all analysis modules included
New configuration system with
sandroid-config
CLI toolDual-mode architecture supporting both legacy and modern usage
Fixed the critical “Legacy analysis modules not available” error
Migration Types:
Gradual Migration - Use both systems in parallel (recommended)
Complete Migration - Switch entirely to modern system
Development Migration - Update development workflows
Legacy to Modern Migration
Current State Assessment:
First, determine your current setup:
# Check if you have legacy installation
ls -la ./sandroid # Legacy script exists?
# Check if you have PyPI installation
which sandroid # Modern command available?
sandroid --version # Should show 1.1.0+
Gradual Migration (Recommended):
This approach lets you test the modern system while keeping the legacy system working:
# 1. Keep your existing legacy installation
# Don't remove anything yet
# 2. Install modern PyPI package alongside
pip install sandroid
# 3. Test modern installation
sandroid --version # Should work without "legacy modules" error
sandroid --help # Should show full help
# 4. Initialize modern configuration
sandroid-config init
# 5. Test side-by-side
./sandroid --help # Legacy way (still works)
sandroid --help # Modern way (now also works)
Configuration Migration:
# 1. Create modern configuration
sandroid-config init
# 2. Migrate settings from legacy hardcoded values
# Check your current settings in src/utils/toolbox.py
grep -r "device_name\|results_path\|number_of_runs" src/utils/
# 3. Set corresponding values in modern config
sandroid-config set emulator.device_name "Your_Current_Device"
sandroid-config set paths.results_path "./results/"
sandroid-config set analysis.number_of_runs 2
Testing Migration:
# Test with identical parameters
# Legacy way:
./sandroid -n 2 --network --screenshot 5
# Modern way:
sandroid --number 2 --network --screenshot 5
# Compare results - they should be identical
Complete Migration:
Once you’re confident the modern system works:
# 1. Archive your legacy installation
tar -czf sandroid_legacy_backup.tar.gz src/ utils/ *.py sandroid
# 2. Update your scripts/aliases
echo "alias sandroid-legacy='./sandroid'" >> ~/.bashrc
echo "alias sandroid='sandroid'" # Modern version is now default
# 3. Update documentation and workflows
# Replace ./sandroid with sandroid in scripts
Package Structure Migration
Old Structure (Legacy):
Sandroid_core/
├── src/
│ ├── utils/ # Core utilities (15 modules)
│ ├── datagather/ # Analysis modules (10 modules)
│ └── functionality/ # Feature modules (5 modules)
├── sandroid # Main script
└── install-requirements.sh
New Structure (Modern):
Sandroid_core/
├── src/sandroid/
│ ├── core/ # Was: src/utils/ (15 modules)
│ ├── analysis/ # Was: src/datagather/ (10 modules)
│ ├── features/ # Was: src/functionality/ (5 modules)
│ ├── config/ # New: Configuration system
│ └── cli.py # New: Modern CLI entry point
├── src/utils/ # Compatibility aliases
├── src/datagather/ # Compatibility aliases
├── src/functionality/ # Compatibility aliases
└── sandroid # Still works (legacy compatibility)
Import Path Changes:
If you have custom code importing Sandroid modules:
# Old imports (still work via compatibility layer):
from src.utils.toolbox import Toolbox
from src.datagather.changedfiles import ChangedFiles
from src.functionality.screenshot import Screenshot
# New imports (recommended):
from sandroid.core.toolbox import Toolbox
from sandroid.analysis.changedfiles import ChangedFiles
from sandroid.features.screenshot import Screenshot
Development Workflow Migration
Legacy Development Setup:
git clone https://github.com/fkie-cad/Sandroid_core.git
cd Sandroid_core
./install-requirements.sh
./sandroid --help
Modern Development Setup:
git clone https://github.com/fkie-cad/Sandroid_core.git
cd Sandroid_core
# Install in development mode
pip install -e .[dev]
# Initialize configuration
sandroid-config init
# Test installation
sandroid --version
sandroid --help
CI/CD Migration:
Legacy CI Pipeline:
- name: Setup Sandroid
run: |
git clone https://github.com/fkie-cad/Sandroid_core.git
cd Sandroid_core
./install-requirements.sh
- name: Run Analysis
run: |
cd Sandroid_core
./sandroid --network --report
Modern CI Pipeline:
- name: Setup Sandroid
run: |
pip install sandroid[ai]
sandroid-config init
- name: Run Analysis
run: |
sandroid --network --report
Docker Migration:
Legacy Dockerfile:
FROM python:3.10
RUN git clone https://github.com/fkie-cad/Sandroid_core.git
WORKDIR /app/Sandroid_core
RUN ./install-requirements.sh
CMD ["./sandroid"]
Modern Dockerfile:
FROM python:3.10
RUN pip install sandroid[ai]
RUN sandroid-config init
CMD ["sandroid"]
Configuration System Migration
Legacy Configuration (Hardcoded):
Previously, configuration was hardcoded in src/utils/toolbox.py
:
# Old way - hardcoded values
class Toolbox:
device_name = "Pixel_6_Pro_API_31"
results_path = "./results/"
number_of_runs = 2
Modern Configuration (File-based):
Now configuration uses structured files:
# ~/.config/sandroid/sandroid.toml
log_level = "INFO"
output_file = "sandroid.json"
[emulator]
device_name = "Pixel_6_Pro_API_31"
[analysis]
number_of_runs = 2
[paths]
results_path = "./results/"
Environment Variable Migration:
Legacy:
export RESULTS_PATH="/custom/results"
export RAW_RESULTS_PATH="/custom/raw"
Modern:
export SANDROID_PATHS__RESULTS_PATH="/custom/results"
export SANDROID_PATHS__RAW_RESULTS_PATH="/custom/raw"
API Migration Guide
For Developers Using Sandroid as a Library:
Legacy API Usage:
# Old way
sys.path.append('path/to/Sandroid_core/src')
from utils.toolbox import Toolbox
from datagather.changedfiles import ChangedFiles
# Initialize and run
toolbox = Toolbox()
changed_files = ChangedFiles()
changed_files.gather()
Modern API Usage:
# New way
from sandroid.core.toolbox import Toolbox
from sandroid.analysis.changedfiles import ChangedFiles
from sandroid.config.loader import load_config
# Initialize with configuration
config = load_config()
Toolbox.configure(config)
# Use analysis modules
changed_files = ChangedFiles()
changed_files.gather()
Custom Module Development:
Legacy Custom Module:
# old_custom_module.py
import sys
sys.path.append('src/')
from utils.toolbox import Toolbox
from datagather.datagather import DataGather
class CustomAnalyzer(DataGather):
def gather(self):
# Custom logic
pass
Modern Custom Module:
# modern_custom_module.py
from sandroid.core.toolbox import Toolbox
from sandroid.analysis.datagather import DataGather
from sandroid.config.loader import load_config
class CustomAnalyzer(DataGather):
def __init__(self):
super().__init__()
self.config = load_config()
def gather(self):
# Custom logic with configuration support
pass
Breaking Changes and Compatibility
No Breaking Changes for End Users:
All CLI commands work identically
All analysis results are the same format
All interactive menu options unchanged
Legacy
./sandroid
script still works
Potential Issues for Developers:
Direct File Path Dependencies:
# This might break:
with open('src/utils/config.py') as f:
content = f.read()
# Use imports instead:
from sandroid.core import config
Hardcoded sys.path Modifications:
# This is no longer needed:
sys.path.append('src/')
# Just use normal imports:
from sandroid.core.toolbox import Toolbox
Assumption About File Structure:
# Don't assume file paths:
config_path = 'src/utils/config.json' # Bad
# Use proper configuration:
from sandroid.config.loader import find_config_file
config_path = find_config_file() # Good
Validation and Testing
Migration Validation Checklist:
# 1. Installation validation
sandroid --version # Should show 1.1.0+
sandroid-config validate # Should pass
# 2. Basic functionality
sandroid --help # Should show full help without errors
# 3. Configuration system
sandroid-config show # Should display configuration
# 4. Analysis capability
sandroid --number 1 --screenshot 10 # Should run without errors
# 5. Compatibility
./sandroid --help # Legacy script should still work
Regression Testing:
# Test with same APK using both methods
# Legacy method
./sandroid --number 2 --network --output legacy_results.json
# Modern method
sandroid --number 2 --network --output modern_results.json
# Compare results (should be identical)
diff legacy_results.json modern_results.json
Performance Comparison:
# Time both methods
time ./sandroid --number 2
time sandroid --number 2
# Performance should be identical or better
Rollback Plan
If you need to rollback the modern installation:
# 1. Remove PyPI installation
pip uninstall sandroid
# 2. Restore legacy installation (if you have backup)
tar -xzf sandroid_legacy_backup.tar.gz
# 3. Reinstall legacy dependencies
./install-requirements.sh
# 4. Test legacy functionality
./sandroid --version
Common Migration Issues
Issue: “Command not found: sandroid”
# Solution: Check pip installation location
pip show sandroid
# Add to PATH if needed
export PATH=$PATH:~/.local/bin
Issue: “Configuration file not found”
# Solution: Initialize configuration
sandroid-config init
# Or create manually
mkdir -p ~/.config/sandroid
sandroid-config init
Issue: “Import errors in custom code”
# Update import statements
# Old:
from src.utils.toolbox import Toolbox
# New:
from sandroid.core.toolbox import Toolbox
Issue: “Different results between legacy and modern”
# Check configuration differences
sandroid-config show
# Ensure same parameters
sandroid --loglevel DEBUG --number 2
Issue: “Performance degradation”
# Check for conflicting installations
which sandroid
pip list | grep sandroid
# Clear Python cache
find . -name "*.pyc" -delete
find . -name "__pycache__" -delete
Support and Help
Getting Help During Migration:
Check Documentation: - Installation - Modern installation guide - Troubleshooting - Common issues and solutions
Validate Your Setup:
sandroid-config validate
sandroid --version
sandroid --help
Enable Debug Mode:
SANDROID_LOG_LEVEL=DEBUG sandroid --network
Report Issues: - GitHub Issues: https://github.com/fkie-cad/Sandroid_core/issues - Include: Sandroid version, system info, error messages
Pre-Migration Checklist:
[ ] Backup current installation
[ ] Document current configuration/settings
[ ] Test modern installation in parallel
[ ] Validate results match between versions
[ ] Update scripts and documentation
[ ] Train team on new configuration system
Post-Migration Checklist:
[ ] All team members can run
sandroid --version
[ ] Configuration system is working:
sandroid-config validate
[ ] CI/CD pipelines updated and tested
[ ] Documentation reflects modern installation
[ ] Legacy backup is archived safely
This migration ensures you get all the benefits of the modern Sandroid system while maintaining complete compatibility with your existing workflows.