Comprehensive Python toolkit for Android application reverse engineering and security analysis.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
High-level utility functions for common analysis workflows, providing simplified interfaces for complex operations. These functions offer the most convenient entry points for standard Android application analysis tasks.
Convenient functions that handle the most common analysis workflows with minimal setup.
def AnalyzeAPK(filename: str, session=None, raw: bool = False) -> tuple:
"""
Comprehensive APK analysis with automatic DEX loading and analysis setup.
Parameters:
- filename: Path to APK file or raw data if raw=True
- session: Optional Session object for persistence
- raw: If True, filename contains raw APK bytes
Returns:
Tuple of (APK_object, list_of_DEX_objects, Analysis_object)
Example:
apk, dex_list, dx = AnalyzeAPK("app.apk")
"""
def AnalyzeDex(filename: str, session=None, raw: bool = False) -> tuple:
"""
DEX file analysis with automatic analysis setup.
Parameters:
- filename: Path to DEX file or raw data if raw=True
- session: Optional Session object for persistence
- raw: If True, filename contains raw DEX bytes
Returns:
Tuple of (list_of_DEX_objects, Analysis_object)
Example:
dex_list, dx = AnalyzeDex("classes.dex")
"""
def AnalyzeODEX(filename: str, session=None) -> tuple:
"""
ODEX file analysis with optimization data processing.
Parameters:
- filename: Path to ODEX file
- session: Optional Session object for persistence
Returns:
Tuple of (ODEX_object, Analysis_object)
"""Functions for certificate processing and signature verification.
def get_certificate_name_string(name, short: bool = False, separator: str = ", ") -> str:
"""
Convert certificate name object to readable string.
Parameters:
- name: Certificate name object (X.509 Name)
- short: Use short form for common name attributes
- separator: String to separate name components
Returns:
Formatted certificate name string
Example:
cert_name = get_certificate_name_string(cert.subject, short=True)
"""
def show_Certificate(cert, short: bool = False) -> None:
"""
Display certificate information in human-readable format.
Parameters:
- cert: X.509 certificate object
- short: Use abbreviated format for names
Example:
show_Certificate(apk.get_certificate())
"""
def get_apkid(apkfile: str) -> tuple:
"""
Quickly extract basic APK identification without full analysis.
Parameters:
- apkfile: Path to APK file
Returns:
Tuple of (package_name, version_code, version_name)
Example:
package, version_code, version_name = get_apkid("app.apk")
"""Automatic detection and handling of different Android file formats.
def is_android_file(filename: str) -> str:
"""
Detect if file is a supported Android format.
Parameters:
- filename: Path to file to check
Returns:
File type string ('APK', 'DEX', 'ODEX', 'AXML', 'ARSC') or None
Example:
file_type = is_android_file("unknown_file.bin")
"""
def auto_analyze(filename: str, session=None):
"""
Automatically detect file type and perform appropriate analysis.
Parameters:
- filename: Path to file to analyze
- session: Optional Session object
Returns:
Analysis objects appropriate for detected file type
Example:
results = auto_analyze("mystery_file")
"""
def load_analysis(filename: str, session=None):
"""
Load file with automatic format detection and analysis.
Parameters:
- filename: Path to Android file
- session: Optional Session object
Returns:
Dictionary with analysis results and file type information
"""Utilities for working with Android resources and XML files.
def decode_axml(axml_data: bytes, pretty: bool = True) -> bytes:
"""
Decode binary XML to readable XML format.
Parameters:
- axml_data: Raw AXML file bytes
- pretty: Format output with indentation
Returns:
Decoded XML as bytes
Example:
xml_content = decode_axml(apk.get_file("AndroidManifest.xml"))
"""
def extract_strings_from_arsc(arsc_data: bytes, package_name: str = None) -> dict:
"""
Extract string resources from ARSC data.
Parameters:
- arsc_data: Raw ARSC file bytes
- package_name: Optional package filter
Returns:
Dictionary mapping resource IDs to string values
Example:
strings = extract_strings_from_arsc(apk.get_file("resources.arsc"))
"""
def get_app_icon(apk_or_path, max_dpi: int = 65536) -> bytes:
"""
Extract application icon from APK.
Parameters:
- apk_or_path: APK object or path to APK file
- max_dpi: Maximum DPI for icon selection
Returns:
Icon image data as bytes or None if not found
Example:
icon_data = get_app_icon("app.apk")
"""Helper functions for common analysis patterns and workflows.
def find_crypto_usage(analysis_obj) -> dict:
"""
Find cryptographic API usage in analyzed application.
Parameters:
- analysis_obj: Analysis object from AnalyzeAPK or AnalyzeDEX
Returns:
Dictionary with crypto usage information
Example:
crypto_info = find_crypto_usage(dx)
"""
def detect_packers(dex_objects: list) -> list:
"""
Detect potential packer/obfuscation usage.
Parameters:
- dex_objects: List of DEX objects to analyze
Returns:
List of detected packer signatures and indicators
Example:
packers = detect_packers(dex_list)
"""
def get_api_usage_stats(analysis_obj) -> dict:
"""
Generate statistics on Android API usage.
Parameters:
- analysis_obj: Analysis object
Returns:
Dictionary with API usage statistics
Example:
api_stats = get_api_usage_stats(dx)
"""
def find_dynamic_loading(analysis_obj) -> list:
"""
Find dynamic code loading patterns.
Parameters:
- analysis_obj: Analysis object
Returns:
List of methods that perform dynamic loading
Example:
dynamic_loaders = find_dynamic_loading(dx)
"""Specialized functions for security-focused analysis.
def check_permissions_risk(apk_obj) -> dict:
"""
Analyze permission usage for security risks.
Parameters:
- apk_obj: APK object
Returns:
Dictionary with risk assessment of requested permissions
Example:
permission_risks = check_permissions_risk(apk)
"""
def find_url_patterns(analysis_obj) -> list:
"""
Find URL and network endpoint patterns in code.
Parameters:
- analysis_obj: Analysis object
Returns:
List of discovered URLs and network patterns
Example:
urls = find_url_patterns(dx)
"""
def detect_anti_analysis(analysis_obj) -> dict:
"""
Detect anti-analysis and evasion techniques.
Parameters:
- analysis_obj: Analysis object
Returns:
Dictionary with detected anti-analysis techniques
Example:
anti_analysis = detect_anti_analysis(dx)
"""
def scan_for_malware_indicators(apk_obj, analysis_obj) -> dict:
"""
Scan for common malware indicators and suspicious patterns.
Parameters:
- apk_obj: APK object
- analysis_obj: Analysis object
Returns:
Dictionary with malware indicator results
Example:
malware_scan = scan_for_malware_indicators(apk, dx)
"""Functions for processing multiple files and batch operations.
def analyze_directory(directory: str, recursive: bool = True, file_types: list = None) -> dict:
"""
Analyze all Android files in directory.
Parameters:
- directory: Directory path to scan
- recursive: Include subdirectories
- file_types: List of file types to include ('APK', 'DEX', etc.)
Returns:
Dictionary mapping filenames to analysis results
Example:
results = analyze_directory("/path/to/apks", recursive=True)
"""
def compare_apks(apk1_path: str, apk2_path: str) -> dict:
"""
Compare two APK files for differences.
Parameters:
- apk1_path: Path to first APK
- apk2_path: Path to second APK
Returns:
Dictionary with comparison results
Example:
comparison = compare_apks("app_v1.apk", "app_v2.apk")
"""
def batch_extract_info(file_list: list) -> dict:
"""
Extract basic information from multiple files efficiently.
Parameters:
- file_list: List of file paths to process
Returns:
Dictionary mapping filenames to extracted info
Example:
info = batch_extract_info(["app1.apk", "app2.apk", "app3.apk"])
"""Functions for generating reports and exporting analysis data.
def export_analysis_json(analysis_data: dict, output_file: str) -> None:
"""
Export analysis results to structured JSON format.
Parameters:
- analysis_data: Dictionary with analysis results
- output_file: Output JSON file path
Example:
export_analysis_json({"apk": apk_info, "analysis": dx_info}, "report.json")
"""
def generate_html_report(apk_obj, analysis_obj, output_file: str) -> None:
"""
Generate comprehensive HTML analysis report.
Parameters:
- apk_obj: APK object
- analysis_obj: Analysis object
- output_file: Output HTML file path
Example:
generate_html_report(apk, dx, "analysis_report.html")
"""
def create_summary_report(analysis_results: dict) -> str:
"""
Create text summary report from analysis results.
Parameters:
- analysis_results: Dictionary with analysis data
Returns:
Formatted summary report as string
Example:
summary = create_summary_report(batch_results)
"""from androguard.misc import AnalyzeAPK, get_apkid
# Quick identification without full analysis
package, version_code, version_name = get_apkid("app.apk")
print(f"Package: {package}")
print(f"Version: {version_name} ({version_code})")
# Full analysis
apk, dex_list, dx = AnalyzeAPK("app.apk")
# Get basic info
print(f"App name: {apk.get_app_name()}")
print(f"Permissions: {len(apk.get_permissions())}")
print(f"Activities: {len(apk.get_activities())}")
print(f"Classes: {len(dx.get_classes())}")
print(f"Methods: {len(dx.get_methods())}")from androguard.misc import AnalyzeAPK, show_Certificate, get_certificate_name_string
# Analyze APK
apk, dex_list, dx = AnalyzeAPK("signed_app.apk")
# Check if signed
if apk.is_signed():
print("APK is signed")
# Get certificates
certificates = apk.get_certificates()
for i, cert in enumerate(certificates):
print(f"\nCertificate {i+1}:")
# Show detailed certificate info
show_Certificate(cert)
# Get formatted subject name
subject_name = get_certificate_name_string(cert.subject, short=True)
print(f"Subject: {subject_name}")
# Get formatted issuer name
issuer_name = get_certificate_name_string(cert.issuer, short=True)
print(f"Issuer: {issuer_name}")
else:
print("APK is not signed")from androguard.misc import AnalyzeAPK, decode_axml, extract_strings_from_arsc, get_app_icon
# Analyze APK
apk, dex_list, dx = AnalyzeAPK("app.apk")
# Extract and decode AndroidManifest.xml
manifest_data = apk.get_file("AndroidManifest.xml")
if manifest_data:
decoded_manifest = decode_axml(manifest_data, pretty=True)
with open("AndroidManifest_decoded.xml", "wb") as f:
f.write(decoded_manifest)
print("Manifest extracted and decoded")
# Extract string resources
resources_data = apk.get_file("resources.arsc")
if resources_data:
strings = extract_strings_from_arsc(resources_data, apk.get_package())
print(f"Extracted {len(strings)} string resources")
# Show some examples
for res_id, string_value in list(strings.items())[:5]:
print(f" 0x{res_id:08x}: {string_value}")
# Extract app icon
icon_data = get_app_icon(apk)
if icon_data:
with open("app_icon.png", "wb") as f:
f.write(icon_data)
print("App icon extracted")from androguard.misc import (AnalyzeAPK, find_crypto_usage, check_permissions_risk,
find_url_patterns, detect_anti_analysis)
# Analyze APK
apk, dex_list, dx = AnalyzeAPK("suspicious_app.apk")
# Check permission risks
permission_risks = check_permissions_risk(apk)
print("Permission Risk Analysis:")
for permission, risk_info in permission_risks.items():
print(f" {permission}: {risk_info['risk_level']} - {risk_info['description']}")
# Find crypto usage
crypto_usage = find_crypto_usage(dx)
print(f"\nCryptographic Usage:")
print(f" Algorithms found: {len(crypto_usage['algorithms'])}")
print(f" Key generation: {crypto_usage['key_generation']}")
print(f" Encryption calls: {len(crypto_usage['encryption_calls'])}")
# Find URLs and network endpoints
urls = find_url_patterns(dx)
print(f"\nNetwork Endpoints ({len(urls)} found):")
for url in urls[:10]: # Show first 10
print(f" {url}")
# Detect anti-analysis techniques
anti_analysis = detect_anti_analysis(dx)
if anti_analysis['detected']:
print(f"\nAnti-Analysis Techniques Detected:")
for technique in anti_analysis['techniques']:
print(f" - {technique}")
else:
print("\nNo anti-analysis techniques detected")from androguard.misc import analyze_directory, compare_apks, batch_extract_info
import json
# Analyze entire directory
results = analyze_directory("/path/to/apk/directory", recursive=True)
print(f"Analyzed {len(results)} files")
# Process results
summary_stats = {
'total_files': len(results),
'successful': 0,
'failed': 0,
'packages': [],
'total_classes': 0,
'total_methods': 0
}
for filename, analysis in results.items():
if analysis and 'error' not in analysis:
summary_stats['successful'] += 1
summary_stats['packages'].append(analysis['package'])
summary_stats['total_classes'] += analysis['classes']
summary_stats['total_methods'] += analysis['methods']
else:
summary_stats['failed'] += 1
print(f"Success rate: {summary_stats['successful']}/{summary_stats['total_files']}")
print(f"Total classes analyzed: {summary_stats['total_classes']}")
print(f"Total methods analyzed: {summary_stats['total_methods']}")
# Compare two versions of an app
if len(summary_stats['packages']) >= 2:
# Find two files for the same package (different versions)
comparison = compare_apks("app_v1.apk", "app_v2.apk")
print(f"\nApp Comparison Results:")
print(f" Version changes: {comparison['version_diff']}")
print(f" Permission changes: {len(comparison['permission_diff'])}")
print(f" New classes: {len(comparison['new_classes'])}")
print(f" Removed classes: {len(comparison['removed_classes'])}")from androguard.misc import *
import os
import json
from datetime import datetime
def comprehensive_apk_analysis(apk_path, output_dir):
"""Perform comprehensive analysis of APK file."""
# Create output directory
os.makedirs(output_dir, exist_ok=True)
# Initialize results
results = {
'timestamp': datetime.now().isoformat(),
'file_path': apk_path,
'analysis_results': {}
}
try:
# Quick identification
package, version_code, version_name = get_apkid(apk_path)
results['basic_info'] = {
'package': package,
'version_code': version_code,
'version_name': version_name
}
# Full analysis
apk, dex_list, dx = AnalyzeAPK(apk_path)
# APK information
results['apk_info'] = {
'app_name': apk.get_app_name(),
'permissions': apk.get_permissions(),
'activities': apk.get_activities(),
'services': apk.get_services(),
'receivers': apk.get_receivers(),
'is_signed': apk.is_signed(),
'min_sdk': apk.get_min_sdk_version(),
'target_sdk': apk.get_target_sdk_version()
}
# Analysis information
results['analysis_info'] = {
'classes': len(dx.get_classes()),
'methods': len(dx.get_methods()),
'strings': len(dx.get_strings())
}
# Security analysis
results['security_analysis'] = {
'permission_risks': check_permissions_risk(apk),
'crypto_usage': find_crypto_usage(dx),
'urls_found': find_url_patterns(dx),
'anti_analysis': detect_anti_analysis(dx)
}
# Extract resources
manifest_data = apk.get_file("AndroidManifest.xml")
if manifest_data:
decoded_manifest = decode_axml(manifest_data)
with open(os.path.join(output_dir, "AndroidManifest.xml"), "wb") as f:
f.write(decoded_manifest)
# Extract icon
icon_data = get_app_icon(apk)
if icon_data:
with open(os.path.join(output_dir, "icon.png"), "wb") as f:
f.write(icon_data)
# Save results
with open(os.path.join(output_dir, "analysis.json"), "w") as f:
json.dump(results, f, indent=2, default=str)
return results
except Exception as e:
results['error'] = str(e)
return results
# Example usage
analysis_result = comprehensive_apk_analysis("target_app.apk", "comprehensive_analysis")
if 'error' not in analysis_result:
print("✓ Analysis completed successfully")
print(f" Package: {analysis_result['basic_info']['package']}")
print(f" Classes: {analysis_result['analysis_info']['classes']}")
print(f" Security risks: {len(analysis_result['security_analysis']['permission_risks'])}")
else:
print(f"✗ Analysis failed: {analysis_result['error']}")def create_analysis_session(files: list) -> object:
"""
Create analysis session with multiple files.
Parameters:
- files: List of file paths to include in session
Returns:
Session object with all files loaded
"""
def get_analysis_summary(apk_obj, analysis_obj) -> dict:
"""
Get comprehensive analysis summary.
Parameters:
- apk_obj: APK object
- analysis_obj: Analysis object
Returns:
Dictionary with summary information
"""
def validate_apk_integrity(apk_path: str) -> dict:
"""
Validate APK file integrity and structure.
Parameters:
- apk_path: Path to APK file
Returns:
Dictionary with validation results
"""
def extract_all_resources(apk_obj, output_dir: str) -> list:
"""
Extract all resources from APK to directory.
Parameters:
- apk_obj: APK object
- output_dir: Output directory path
Returns:
List of extracted file paths
"""Install with Tessl CLI
npx tessl i tessl/pypi-androguard