JEB Décompilateur Feuille de chaleur
Aperçu général
JEB Decompiler est une plateforme professionnelle d'ingénierie inversée développée par PNF Software, spécialisée dans l'analyse des applications Android, la décompilation Java bytecode et l'analyse binaire native. Il fournit des capacités avancées de décompilation avec l'interface utilisateur interactive, un support de script étendu, et la manipulation sophistiquée de code obfusqué.
C'est-à-dire Key Strengths: Android APK analyse, DEX/OAT décompilation, Java bytecode analyse, décompilation interactive, traitement d'obfuscation, et API de script complète.
Installation et configuration
Licence et installation
# Commercial License Required
# Visit: https://www.pnfsoftware.com/
# Available editions: Professional, Enterprise, Floating
# System Requirements:
# - Windows 10/11, macOS 10.14+, or Linux (Ubuntu 18.04+)
# - Java 11 or higher
# - 8GB RAM minimum (16GB recommended)
# - 2GB disk space
# Windows Installation:
# Download JEB installer (.exe)
# Run as administrator
# Follow installation wizard
# Activate license during first run
# macOS Installation:
# Download JEB for macOS (.dmg)
# Drag to Applications folder
# Run and activate license
# Linux Installation:
# Download JEB for Linux (.tar.gz)
tar -xzf jeb-pro-linux.tar.gz
cd jeb-pro
./jeb_linux.sh
# License Activation:
# 1. Launch JEB
# 2. Enter license key
# 3. Complete online activation
# 4. Configure workspace directory
Configuration et configuration
# JEB Configuration Directory:
# Windows: %APPDATA%\PNF Software\JEB
# macOS: ~/Library/Application Support/PNF Software/JEB
# Linux: ~/.jeb
# Key Configuration Files:
# - jeb-client.cfg: Client configuration
# - jeb-engines.cfg: Analysis engine settings
# - scripts/: Custom scripts directory
# - plugins/: Plugin directory
# Memory Configuration (jeb-client.cfg):
# Increase heap size for large files
-Xmx8g # 8GB heap (adjust based on available RAM)
-Xms2g # 2GB initial heap
-XX:MaxMetaspaceSize=1g
# Analysis Engine Configuration (jeb-engines.cfg):
# Android analysis settings
android.dex.optimize_code=true
android.dex.merge_duplicate_methods=true
android.dex.deobfuscate_strings=true
# Java analysis settings
java.class.decompile_synthetic=true
java.class.merge_inner_classes=true
```_
### Configuration du plugin et du script
```python
# JEB Python API Setup
# Scripts location: <JEB_HOME>/scripts/
# Basic script template
from com.pnfsoftware.jeb.client.api import IScript
from com.pnfsoftware.jeb.core import RuntimeProjectUtil
from com.pnfsoftware.jeb.core.units.code.android import IDexUnit
class BasicAnalysisScript(IScript):
def run(self, ctx):
"""Main script execution"""
# Get current project
project = ctx.getMainProject()
if not project:
print("No project loaded")
return
# Get DEX units (for Android analysis)
dex_units = RuntimeProjectUtil.findUnitsByType(project, IDexUnit, False)
for dex_unit in dex_units:
print(f"Analyzing DEX unit: {dex_unit.getName()}")
self.analyze_dex_unit(dex_unit)
def analyze_dex_unit(self, dex_unit):
"""Analyze a DEX unit"""
# Get all classes
classes = dex_unit.getClasses()
print(f"Found {len(classes)} classes")
for cls in classes:
print(f"Class: {cls.getName()}")
# Analyze methods
for method in cls.getMethods():
print(f" Method: {method.getName()}")
```_
## Android APK Analyse
### APK Chargement et analyse initiale
```python
# Comprehensive APK analysis script
from com.pnfsoftware.jeb.core.units.code.android import IDexUnit
from com.pnfsoftware.jeb.core.units.code.android.dex import IDexClass, IDexMethod
from com.pnfsoftware.jeb.core.units.code.java import IJavaSourceUnit
from com.pnfsoftware.jeb.core.output.text import ITextDocument
import re
class APKAnalyzer(IScript):
def run(self, ctx):
"""Comprehensive APK analysis"""
self.ctx = ctx
self.project = ctx.getMainProject()
if not self.project:
print("No project loaded")
return
# Perform analysis steps
self.analyze_manifest()
self.analyze_dex_files()
self.analyze_resources()
self.analyze_native_libraries()
self.detect_obfuscation()
self.find_security_issues()
self.generate_report()
def analyze_manifest(self):
"""Analyze AndroidManifest.xml"""
print("=== Manifest Analysis ===")
# Find manifest unit
manifest_unit = None
for unit in self.project.getLiveUnits():
if unit.getName() == "AndroidManifest.xml":
manifest_unit = unit
break
if not manifest_unit:
print("AndroidManifest.xml not found")
return
# Get manifest document
doc = manifest_unit.getDocument()
if doc:
manifest_text = doc.getDocumentPart(0, doc.getDocumentSize())
# Extract key information
self.extract_permissions(manifest_text)
self.extract_components(manifest_text)
self.extract_intent_filters(manifest_text)
def extract_permissions(self, manifest_text):
"""Extract permissions from manifest"""
print("\n--- Permissions ---")
# Find permission declarations
permission_pattern = r'<uses-permission[^>]*android:name="([^"]*)"'
permissions = re.findall(permission_pattern, manifest_text)
dangerous_permissions = [
'android.permission.READ_CONTACTS',
'android.permission.WRITE_CONTACTS',
'android.permission.READ_SMS',
'android.permission.SEND_SMS',
'android.permission.CAMERA',
'android.permission.RECORD_AUDIO',
'android.permission.ACCESS_FINE_LOCATION',
'android.permission.READ_EXTERNAL_STORAGE',
'android.permission.WRITE_EXTERNAL_STORAGE'
]
for permission in permissions:
risk_level = "HIGH" if permission in dangerous_permissions else "NORMAL"
print(f" {permission} [{risk_level}]")
def extract_components(self, manifest_text):
"""Extract app components from manifest"""
print("\n--- Components ---")
# Activities
activity_pattern = r'<activity[^>]*android:name="([^"]*)"'
activities = re.findall(activity_pattern, manifest_text)
print(f"Activities ({len(activities)}):")
for activity in activities:
print(f" {activity}")
# Services
service_pattern = r'<service[^>]*android:name="([^"]*)"'
services = re.findall(service_pattern, manifest_text)
print(f"Services ({len(services)}):")
for service in services:
print(f" {service}")
# Receivers
receiver_pattern = r'<receiver[^>]*android:name="([^"]*)"'
receivers = re.findall(receiver_pattern, manifest_text)
print(f"Receivers ({len(receivers)}):")
for receiver in receivers:
print(f" {receiver}")
def extract_intent_filters(self, manifest_text):
"""Extract intent filters"""
print("\n--- Intent Filters ---")
# Find exported components with intent filters
intent_filter_pattern = r'<intent-filter>(.*?)</intent-filter>'
intent_filters = re.findall(intent_filter_pattern, manifest_text, re.DOTALL)
for i, intent_filter in enumerate(intent_filters):
print(f"Intent Filter {i+1}:")
# Extract actions
action_pattern = r'<action[^>]*android:name="([^"]*)"'
actions = re.findall(action_pattern, intent_filter)
for action in actions:
print(f" Action: {action}")
# Extract categories
category_pattern = r'<category[^>]*android:name="([^"]*)"'
categories = re.findall(category_pattern, intent_filter)
for category in categories:
print(f" Category: {category}")
def analyze_dex_files(self):
"""Analyze DEX files in the APK"""
print("\n=== DEX Analysis ===")
dex_units = RuntimeProjectUtil.findUnitsByType(self.project, IDexUnit, False)
for dex_unit in dex_units:
print(f"\nAnalyzing {dex_unit.getName()}")
# Get decompiled Java source
java_unit = self.get_java_unit(dex_unit)
if java_unit:
self.analyze_java_source(java_unit)
# Analyze DEX structure
self.analyze_dex_structure(dex_unit)
def get_java_unit(self, dex_unit):
"""Get Java source unit from DEX unit"""
# Trigger decompilation
dex_unit.process()
# Find corresponding Java unit
for unit in self.project.getLiveUnits():
if isinstance(unit, IJavaSourceUnit) and unit.getParent() == dex_unit:
return unit
return None
def analyze_java_source(self, java_unit):
"""Analyze decompiled Java source"""
print(" Analyzing Java source...")
# Get source document
doc = java_unit.getDocument()
if not doc:
print(" No Java source available")
return
source_text = doc.getDocumentPart(0, doc.getDocumentSize())
# Find security-relevant patterns
self.find_crypto_usage(source_text)
self.find_network_usage(source_text)
self.find_file_operations(source_text)
self.find_reflection_usage(source_text)
def find_crypto_usage(self, source_text):
"""Find cryptographic API usage"""
crypto_patterns = [
r'javax\.crypto\.',
r'java\.security\.',
r'MessageDigest',
r'Cipher',
r'KeyGenerator',
r'SecretKey',
r'AES',
r'DES',
r'RSA',
r'MD5',
r'SHA'
]
crypto_findings = []
for pattern in crypto_patterns:
matches = re.finditer(pattern, source_text, re.IGNORECASE)
for match in matches:
crypto_findings.append(match.group())
if crypto_findings:
print(f" Crypto usage found: {set(crypto_findings)}")
def find_network_usage(self, source_text):
"""Find network API usage"""
network_patterns = [
r'HttpURLConnection',
r'HttpClient',
r'OkHttp',
r'Retrofit',
r'Socket',
r'URL\(',
r'URLConnection',
r'HttpsURLConnection'
]
network_findings = []
for pattern in network_patterns:
matches = re.finditer(pattern, source_text)
for match in matches:
network_findings.append(match.group())
if network_findings:
print(f" Network usage found: {set(network_findings)}")
def find_file_operations(self, source_text):
"""Find file operation patterns"""
file_patterns = [
r'FileInputStream',
r'FileOutputStream',
r'openFileOutput',
r'openFileInput',
r'getExternalStorageDirectory',
r'Environment\.getExternalStorageDirectory',
r'File\(',
r'RandomAccessFile'
]
file_findings = []
for pattern in file_patterns:
matches = re.finditer(pattern, source_text)
for match in matches:
file_findings.append(match.group())
if file_findings:
print(f" File operations found: {set(file_findings)}")
def find_reflection_usage(self, source_text):
"""Find reflection API usage"""
reflection_patterns = [
r'Class\.forName',
r'getDeclaredMethod',
r'getMethod',
r'invoke\(',
r'newInstance\(',
r'getDeclaredField',
r'getField'
]
reflection_findings = []
for pattern in reflection_patterns:
matches = re.finditer(pattern, source_text)
for match in matches:
reflection_findings.append(match.group())
if reflection_findings:
print(f" Reflection usage found: {set(reflection_findings)}")
def analyze_dex_structure(self, dex_unit):
"""Analyze DEX file structure"""
print(" Analyzing DEX structure...")
classes = dex_unit.getClasses()
print(f" Total classes: {len(classes)}")
# Count methods and fields
total_methods = 0
total_fields = 0
for cls in classes:
total_methods += len(cls.getMethods())
total_fields += len(cls.getFields())
print(f" Total methods: {total_methods}")
print(f" Total fields: {total_fields}")
# Find interesting classes
self.find_interesting_classes(classes)
def find_interesting_classes(self, classes):
"""Find potentially interesting classes"""
interesting_patterns = [
r'.*Crypto.*',
r'.*Cipher.*',
r'.*Security.*',
r'.*Network.*',
r'.*Http.*',
r'.*Socket.*',
r'.*Native.*',
r'.*JNI.*',
r'.*Obfuscat.*',
r'.*Protect.*'
]
interesting_classes = []
for cls in classes:
class_name = cls.getName()
for pattern in interesting_patterns:
if re.match(pattern, class_name, re.IGNORECASE):
interesting_classes.append(class_name)
break
if interesting_classes:
print(f" Interesting classes: {interesting_classes[:10]}") # Show first 10
def analyze_resources(self):
"""Analyze application resources"""
print("\n=== Resource Analysis ===")
# Find resource units
resource_units = []
for unit in self.project.getLiveUnits():
unit_name = unit.getName()
if unit_name.startswith("res/") or unit_name.endswith(".xml"):
resource_units.append(unit)
print(f"Found {len(resource_units)} resource files")
# Analyze specific resource types
self.analyze_strings_xml(resource_units)
self.analyze_network_config(resource_units)
def analyze_strings_xml(self, resource_units):
"""Analyze strings.xml for sensitive information"""
print("\n--- String Resources ---")
for unit in resource_units:
if "strings.xml" in unit.getName():
doc = unit.getDocument()
if doc:
content = doc.getDocumentPart(0, doc.getDocumentSize())
self.find_sensitive_strings(content)
def find_sensitive_strings(self, content):
"""Find potentially sensitive strings"""
sensitive_patterns = [
r'password',
r'secret',
r'key',
r'token',
r'api[_-]?key',
r'private[_-]?key',
r'auth',
r'credential',
r'http[s]?://[^\s<>"]+', # URLs
r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' # Email addresses
]
findings = []
for pattern in sensitive_patterns:
matches = re.finditer(pattern, content, re.IGNORECASE)
for match in matches:
findings.append(match.group())
if findings:
print(f" Potentially sensitive strings: {set(findings)}")
def analyze_network_config(self, resource_units):
"""Analyze network security configuration"""
print("\n--- Network Configuration ---")
for unit in resource_units:
if "network_security_config" in unit.getName():
doc = unit.getDocument()
if doc:
content = doc.getDocumentPart(0, doc.getDocumentSize())
print(f" Network config found: {unit.getName()}")
# Check for cleartext traffic
if "cleartextTrafficPermitted" in content:
if "true" in content:
print(" WARNING: Cleartext traffic permitted")
def analyze_native_libraries(self):
"""Analyze native libraries"""
print("\n=== Native Library Analysis ===")
# Find .so files
native_libs = []
for unit in self.project.getLiveUnits():
unit_name = unit.getName()
if unit_name.endswith(".so"):
native_libs.append(unit_name)
if native_libs:
print(f"Native libraries found: {native_libs}")
# Analyze each library
for lib_name in native_libs:
self.analyze_native_library(lib_name)
else:
print("No native libraries found")
def analyze_native_library(self, lib_name):
"""Analyze individual native library"""
print(f"\n--- Analyzing {lib_name} ---")
# Find the library unit
lib_unit = None
for unit in self.project.getLiveUnits():
if unit.getName() == lib_name:
lib_unit = unit
break
if not lib_unit:
print(f"Library unit not found: {lib_name}")
return
# Get exported functions
try:
# This would require native analysis capabilities
print(f" Library loaded: {lib_name}")
print(f" Size: {lib_unit.getDataSize()} bytes")
except:
print(f" Could not analyze native library: {lib_name}")
def detect_obfuscation(self):
"""Detect obfuscation techniques"""
print("\n=== Obfuscation Detection ===")
dex_units = RuntimeProjectUtil.findUnitsByType(self.project, IDexUnit, False)
for dex_unit in dex_units:
obfuscation_indicators = self.check_obfuscation_indicators(dex_unit)
if obfuscation_indicators:
print(f"Obfuscation detected in {dex_unit.getName()}:")
for indicator in obfuscation_indicators:
print(f" - {indicator}")
def check_obfuscation_indicators(self, dex_unit):
"""Check for obfuscation indicators"""
indicators = []
classes = dex_unit.getClasses()
# Check for short/meaningless class names
short_names = 0
total_classes = len(classes)
for cls in classes:
class_name = cls.getName()
# Skip system classes
if class_name.startswith("android.") or class_name.startswith("java."):
continue
# Check for single character names
simple_name = class_name.split('.')[-1]
if len(simple_name) <= 2:
short_names += 1
if total_classes > 0 and (short_names / total_classes) > 0.3:
indicators.append("High ratio of short class names")
# Check for string encryption
encrypted_strings = self.detect_string_encryption(dex_unit)
if encrypted_strings:
indicators.append("Potential string encryption detected")
# Check for control flow obfuscation
complex_methods = self.detect_control_flow_obfuscation(dex_unit)
if complex_methods > 10:
indicators.append(f"Control flow obfuscation detected ({complex_methods} complex methods)")
return indicators
def detect_string_encryption(self, dex_unit):
"""Detect encrypted strings"""
# Look for patterns that suggest string decryption
decryption_patterns = [
"decrypt",
"decode",
"deobfuscate",
"XOR",
"cipher"
]
classes = dex_unit.getClasses()
for cls in classes:
for method in cls.getMethods():
method_name = method.getName().lower()
for pattern in decryption_patterns:
if pattern.lower() in method_name:
return True
return False
def detect_control_flow_obfuscation(self, dex_unit):
"""Detect control flow obfuscation"""
complex_methods = 0
classes = dex_unit.getClasses()
for cls in classes:
for method in cls.getMethods():
# Simple heuristic: methods with many basic blocks
# This would require more detailed CFG analysis in practice
if method.getCodeItem():
# Placeholder for complexity analysis
complex_methods += 1
return complex_methods
def find_security_issues(self):
"""Find potential security issues"""
print("\n=== Security Analysis ===")
dex_units = RuntimeProjectUtil.findUnitsByType(self.project, IDexUnit, False)
security_issues = []
for dex_unit in dex_units:
issues = self.analyze_security_patterns(dex_unit)
security_issues.extend(issues)
if security_issues:
print("Security issues found:")
for issue in security_issues:
print(f" - {issue}")
else:
print("No obvious security issues detected")
def analyze_security_patterns(self, dex_unit):
"""Analyze for security anti-patterns"""
issues = []
classes = dex_unit.getClasses()
for cls in classes:
class_name = cls.getName()
# Check for hardcoded credentials
if self.has_hardcoded_credentials(cls):
issues.append(f"Potential hardcoded credentials in {class_name}")
# Check for insecure random usage
if self.has_insecure_random(cls):
issues.append(f"Insecure random number generation in {class_name}")
# Check for SQL injection vulnerabilities
if self.has_sql_injection_risk(cls):
issues.append(f"Potential SQL injection in {class_name}")
# Check for weak cryptography
if self.has_weak_crypto(cls):
issues.append(f"Weak cryptography usage in {class_name}")
return issues
def has_hardcoded_credentials(self, cls):
"""Check for hardcoded credentials"""
# This is a simplified check
# In practice, would analyze string constants and method implementations
for field in cls.getFields():
field_name = field.getName().lower()
if any(keyword in field_name for keyword in ['password', 'secret', 'key', 'token']):
return True
return False
def has_insecure_random(self, cls):
"""Check for insecure random number generation"""
# Look for usage of java.util.Random instead of SecureRandom
for method in cls.getMethods():
# This would require bytecode analysis in practice
pass
return False
def has_sql_injection_risk(self, cls):
"""Check for SQL injection vulnerabilities"""
# Look for dynamic SQL construction
for method in cls.getMethods():
# This would require data flow analysis in practice
pass
return False
def has_weak_crypto(self, cls):
"""Check for weak cryptographic practices"""
# Look for usage of weak algorithms like MD5, DES
for method in cls.getMethods():
# This would require API usage analysis in practice
pass
return False
def generate_report(self):
"""Generate analysis report"""
print("\n=== Analysis Report ===")
print("Analysis completed successfully")
print("Check the output above for detailed findings")
# In a real implementation, this would generate a structured report
# and save it to a file
# Usage: Save as script and run in JEB
Analyse du DEX et de l'OAT
# Advanced DEX/OAT analysis capabilities
from com.pnfsoftware.jeb.core.units.code.android.dex import IDexClass, IDexMethod, IDexField
from com.pnfsoftware.jeb.core.units.code.android.dex import DexPoolType
class DEXAnalyzer(IScript):
def run(self, ctx):
"""Advanced DEX analysis"""
self.ctx = ctx
self.project = ctx.getMainProject()
dex_units = RuntimeProjectUtil.findUnitsByType(self.project, IDexUnit, False)
for dex_unit in dex_units:
print(f"Analyzing DEX: {dex_unit.getName()}")
self.analyze_dex_header(dex_unit)
self.analyze_string_pool(dex_unit)
self.analyze_type_pool(dex_unit)
self.analyze_method_pool(dex_unit)
self.analyze_class_definitions(dex_unit)
self.detect_multidex(dex_unit)
def analyze_dex_header(self, dex_unit):
"""Analyze DEX file header"""
print("\n--- DEX Header Analysis ---")
# Get DEX file information
dex_version = dex_unit.getDexVersion()
print(f"DEX Version: {dex_version}")
# Get file size
file_size = dex_unit.getDataSize()
print(f"File Size: {file_size} bytes")
# Get checksum
checksum = dex_unit.getChecksum()
print(f"Checksum: 0x{checksum:08x}")
def analyze_string_pool(self, dex_unit):
"""Analyze DEX string pool"""
print("\n--- String Pool Analysis ---")
string_pool = dex_unit.getPool(DexPoolType.STRING)
string_count = string_pool.size()
print(f"Total strings: {string_count}")
# Analyze string patterns
self.analyze_string_patterns(string_pool)
# Find encrypted/obfuscated strings
self.find_obfuscated_strings(string_pool)
def analyze_string_patterns(self, string_pool):
"""Analyze patterns in string pool"""
url_count = 0
class_name_count = 0
method_name_count = 0
for i in range(string_pool.size()):
string_value = string_pool.get(i)
if string_value:
# Count URLs
if string_value.startswith("http://") or string_value.startswith("https://"):
url_count += 1
# Count class names (contain dots and start with lowercase)
if "." in string_value and string_value[0].islower():
class_name_count += 1
# Count method names (typical Java method naming)
if string_value[0].islower() and string_value.isalnum():
method_name_count += 1
print(f" URLs: {url_count}")
print(f" Potential class names: {class_name_count}")
print(f" Potential method names: {method_name_count}")
def find_obfuscated_strings(self, string_pool):
"""Find potentially obfuscated strings"""
obfuscated_count = 0
suspicious_strings = []
for i in range(min(string_pool.size(), 1000)): # Limit for performance
string_value = string_pool.get(i)
if string_value and len(string_value) > 10:
# Check for high entropy (potential encryption)
entropy = self.calculate_entropy(string_value)
if entropy > 4.5: # High entropy threshold
obfuscated_count += 1
if len(suspicious_strings) < 10:
suspicious_strings.append(string_value[:50]) # Truncate for display
print(f" Potentially obfuscated strings: {obfuscated_count}")
if suspicious_strings:
print(" Examples:")
for s in suspicious_strings:
print(f" {s}")
def calculate_entropy(self, data):
"""Calculate Shannon entropy of string"""
import math
from collections import Counter
if not data:
return 0
# Count character frequencies
char_counts = Counter(data)
data_len = len(data)
# Calculate entropy
entropy = 0
for count in char_counts.values():
probability = count / data_len
entropy -= probability * math.log2(probability)
return entropy
def analyze_type_pool(self, dex_unit):
"""Analyze DEX type pool"""
print("\n--- Type Pool Analysis ---")
type_pool = dex_unit.getPool(DexPoolType.TYPE)
type_count = type_pool.size()
print(f"Total types: {type_count}")
# Categorize types
primitive_count = 0
array_count = 0
class_count = 0
for i in range(type_pool.size()):
type_name = type_pool.get(i)
if type_name:
if type_name in ['I', 'J', 'F', 'D', 'Z', 'B', 'C', 'S', 'V']:
primitive_count += 1
elif type_name.startswith('['):
array_count += 1
elif type_name.startswith('L') and type_name.endswith(';'):
class_count += 1
print(f" Primitive types: {primitive_count}")
print(f" Array types: {array_count}")
print(f" Class types: {class_count}")
def analyze_method_pool(self, dex_unit):
"""Analyze DEX method pool"""
print("\n--- Method Pool Analysis ---")
method_pool = dex_unit.getPool(DexPoolType.METHOD)
method_count = method_pool.size()
print(f"Total method references: {method_count}")
# Analyze method signatures
self.analyze_method_signatures(method_pool)
def analyze_method_signatures(self, method_pool):
"""Analyze method signatures"""
android_api_count = 0
java_api_count = 0
app_method_count = 0
for i in range(method_pool.size()):
method_sig = method_pool.get(i)
if method_sig:
if method_sig.startswith("Landroid/"):
android_api_count += 1
elif method_sig.startswith("Ljava/") or method_sig.startswith("Ljavax/"):
java_api_count += 1
else:
app_method_count += 1
print(f" Android API methods: {android_api_count}")
print(f" Java API methods: {java_api_count}")
print(f" Application methods: {app_method_count}")
def analyze_class_definitions(self, dex_unit):
"""Analyze class definitions"""
print("\n--- Class Definition Analysis ---")
classes = dex_unit.getClasses()
print(f"Total classes: {len(classes)}")
# Categorize classes
public_classes = 0
private_classes = 0
abstract_classes = 0
interface_classes = 0
for cls in classes:
access_flags = cls.getAccessFlags()
if access_flags & 0x1: # ACC_PUBLIC
public_classes += 1
if access_flags & 0x2: # ACC_PRIVATE
private_classes += 1
if access_flags & 0x400: # ACC_ABSTRACT
abstract_classes += 1
if access_flags & 0x200: # ACC_INTERFACE
interface_classes += 1
print(f" Public classes: {public_classes}")
print(f" Private classes: {private_classes}")
print(f" Abstract classes: {abstract_classes}")
print(f" Interfaces: {interface_classes}")
# Analyze inheritance
self.analyze_inheritance(classes)
def analyze_inheritance(self, classes):
"""Analyze class inheritance patterns"""
inheritance_map = {}
for cls in classes:
class_name = cls.getName()
superclass = cls.getSuperclass()
if superclass:
superclass_name = superclass.getName()
if superclass_name not in inheritance_map:
inheritance_map[superclass_name] = []
inheritance_map[superclass_name].append(class_name)
# Find classes with many subclasses
popular_superclasses = []
for superclass, subclasses in inheritance_map.items():
if len(subclasses) > 5:
popular_superclasses.append((superclass, len(subclasses)))
if popular_superclasses:
print(" Classes with many subclasses:")
for superclass, count in sorted(popular_superclasses, key=lambda x: x[1], reverse=True)[:5]:
print(f" {superclass}: {count} subclasses")
def detect_multidex(self, dex_unit):
"""Detect MultiDEX usage"""
print("\n--- MultiDEX Detection ---")
classes = dex_unit.getClasses()
# Look for MultiDex classes
multidex_classes = []
for cls in classes:
class_name = cls.getName()
if "multidex" in class_name.lower():
multidex_classes.append(class_name)
if multidex_classes:
print("MultiDEX usage detected:")
for cls_name in multidex_classes:
print(f" {cls_name}")
else:
print("No MultiDEX usage detected")
# Check method count (65k method limit)
method_count = sum(len(cls.getMethods()) for cls in classes)
print(f"Total methods in DEX: {method_count}")
if method_count > 65536:
print("WARNING: Method count exceeds 65k limit - MultiDEX required")
Analyse des Bytecodes Java
Analyse de fichier de classe
# Java bytecode analysis capabilities
from com.pnfsoftware.jeb.core.units.code.java import IJavaSourceUnit, IJavaClass, IJavaMethod
from com.pnfsoftware.jeb.core.units.code.java import JavaConstantPoolType
class JavaBytecodeAnalyzer(IScript):
def run(self, ctx):
"""Analyze Java bytecode"""
self.ctx = ctx
self.project = ctx.getMainProject()
# Find Java units
java_units = RuntimeProjectUtil.findUnitsByType(self.project, IJavaSourceUnit, False)
for java_unit in java_units:
print(f"Analyzing Java unit: {java_unit.getName()}")
self.analyze_java_unit(java_unit)
def analyze_java_unit(self, java_unit):
"""Analyze individual Java unit"""
# Get all classes
classes = java_unit.getClasses()
print(f"Classes found: {len(classes)}")
for cls in classes:
self.analyze_java_class(cls)
def analyze_java_class(self, java_class):
"""Analyze Java class"""
print(f"\n--- Analyzing Class: {java_class.getName()} ---")
# Analyze class structure
self.analyze_class_structure(java_class)
# Analyze methods
self.analyze_class_methods(java_class)
# Analyze fields
self.analyze_class_fields(java_class)
# Look for design patterns
self.detect_design_patterns(java_class)
def analyze_class_structure(self, java_class):
"""Analyze class structure"""
print("Class Structure:")
# Get modifiers
modifiers = java_class.getModifiers()
print(f" Modifiers: {modifiers}")
# Get superclass
superclass = java_class.getSuperclass()
if superclass:
print(f" Superclass: {superclass.getName()}")
# Get interfaces
interfaces = java_class.getInterfaces()
if interfaces:
print(f" Interfaces: {[iface.getName() for iface in interfaces]}")
# Get inner classes
inner_classes = java_class.getInnerClasses()
if inner_classes:
print(f" Inner classes: {len(inner_classes)}")
def analyze_class_methods(self, java_class):
"""Analyze class methods"""
methods = java_class.getMethods()
print(f" Methods: {len(methods)}")
# Categorize methods
public_methods = 0
private_methods = 0
static_methods = 0
abstract_methods = 0
for method in methods:
modifiers = method.getModifiers()
if "public" in modifiers:
public_methods += 1
if "private" in modifiers:
private_methods += 1
if "static" in modifiers:
static_methods += 1
if "abstract" in modifiers:
abstract_methods += 1
print(f" Public: {public_methods}")
print(f" Private: {private_methods}")
print(f" Static: {static_methods}")
print(f" Abstract: {abstract_methods}")
# Analyze method complexity
self.analyze_method_complexity(methods)
def analyze_method_complexity(self, methods):
"""Analyze method complexity"""
complex_methods = []
for method in methods:
# Get method body
body = method.getBody()
if body:
# Simple complexity metric based on statement count
statement_count = self.count_statements(body)
if statement_count > 50: # Threshold for complex method
complex_methods.append((method.getName(), statement_count))
if complex_methods:
print(" Complex methods:")
for method_name, count in complex_methods:
print(f" {method_name}: {count} statements")
def count_statements(self, method_body):
"""Count statements in method body"""
# This is a simplified implementation
# In practice, would traverse the AST
body_text = str(method_body)
return body_text.count(';')
def analyze_class_fields(self, java_class):
"""Analyze class fields"""
fields = java_class.getFields()
print(f" Fields: {len(fields)}")
# Categorize fields
public_fields = 0
private_fields = 0
static_fields = 0
final_fields = 0
for field in fields:
modifiers = field.getModifiers()
if "public" in modifiers:
public_fields += 1
if "private" in modifiers:
private_fields += 1
if "static" in modifiers:
static_fields += 1
if "final" in modifiers:
final_fields += 1
print(f" Public: {public_fields}")
print(f" Private: {private_fields}")
print(f" Static: {static_fields}")
print(f" Final: {final_fields}")
def detect_design_patterns(self, java_class):
"""Detect common design patterns"""
patterns = []
# Singleton pattern
if self.is_singleton(java_class):
patterns.append("Singleton")
# Factory pattern
if self.is_factory(java_class):
patterns.append("Factory")
# Observer pattern
if self.is_observer(java_class):
patterns.append("Observer")
# Builder pattern
if self.is_builder(java_class):
patterns.append("Builder")
if patterns:
print(f" Design patterns detected: {patterns}")
def is_singleton(self, java_class):
"""Check if class implements Singleton pattern"""
methods = java_class.getMethods()
fields = java_class.getFields()
# Look for getInstance method
has_get_instance = any(method.getName() == "getInstance" for method in methods)
# Look for private static instance field
has_private_static_instance = False
for field in fields:
modifiers = field.getModifiers()
if "private" in modifiers and "static" in modifiers:
has_private_static_instance = True
break
return has_get_instance and has_private_static_instance
def is_factory(self, java_class):
"""Check if class implements Factory pattern"""
class_name = java_class.getName().lower()
return "factory" in class_name
def is_observer(self, java_class):
"""Check if class implements Observer pattern"""
interfaces = java_class.getInterfaces()
if interfaces:
for iface in interfaces:
if "observer" in iface.getName().lower():
return True
return False
def is_builder(self, java_class):
"""Check if class implements Builder pattern"""
class_name = java_class.getName().lower()
return "builder" in class_name
Analyse binaire autochtone
Analyse des bibliothèques autochtones
# Native binary analysis in JEB
from com.pnfsoftware.jeb.core.units.code.asm import IAssemblyDocument
from com.pnfsoftware.jeb.core.units.code.asm import IAssemblyUnit
class NativeBinaryAnalyzer(IScript):
def run(self, ctx):
"""Analyze native binaries"""
self.ctx = ctx
self.project = ctx.getMainProject()
# Find assembly units (native code)
asm_units = RuntimeProjectUtil.findUnitsByType(self.project, IAssemblyUnit, False)
for asm_unit in asm_units:
print(f"Analyzing native binary: {asm_unit.getName()}")
self.analyze_native_binary(asm_unit)
def analyze_native_binary(self, asm_unit):
"""Analyze native binary unit"""
print(f"\n--- Native Binary Analysis: {asm_unit.getName()} ---")
# Get binary information
self.analyze_binary_info(asm_unit)
# Analyze sections
self.analyze_sections(asm_unit)
# Analyze symbols
self.analyze_symbols(asm_unit)
# Find JNI functions
self.find_jni_functions(asm_unit)
# Analyze strings
self.analyze_native_strings(asm_unit)
def analyze_binary_info(self, asm_unit):
"""Analyze basic binary information"""
print("Binary Information:")
# Get architecture
processor = asm_unit.getProcessor()
if processor:
print(f" Architecture: {processor.getName()}")
# Get entry point
entry_point = asm_unit.getEntryPoint()
if entry_point:
print(f" Entry point: 0x{entry_point:x}")
# Get base address
base_address = asm_unit.getBaseAddress()
print(f" Base address: 0x{base_address:x}")
def analyze_sections(self, asm_unit):
"""Analyze binary sections"""
print("\nSections:")
# This would require access to section information
# Implementation depends on JEB's native analysis capabilities
print(" Section analysis not implemented in this example")
def analyze_symbols(self, asm_unit):
"""Analyze symbols in native binary"""
print("\nSymbol Analysis:")
# Get all symbols
symbols = asm_unit.getSymbols()
if symbols:
print(f" Total symbols: {len(symbols)}")
# Categorize symbols
function_symbols = []
data_symbols = []
for symbol in symbols:
symbol_name = symbol.getName()
# This categorization would depend on symbol type information
if symbol_name:
if any(keyword in symbol_name.lower() for keyword in ['func', 'sub_', 'proc']):
function_symbols.append(symbol_name)
else:
data_symbols.append(symbol_name)
print(f" Function symbols: {len(function_symbols)}")
print(f" Data symbols: {len(data_symbols)}")
else:
print(" No symbols found")
def find_jni_functions(self, asm_unit):
"""Find JNI function implementations"""
print("\nJNI Function Analysis:")
symbols = asm_unit.getSymbols()
jni_functions = []
if symbols:
for symbol in symbols:
symbol_name = symbol.getName()
if symbol_name and "Java_" in symbol_name:
jni_functions.append(symbol_name)
if jni_functions:
print(f" JNI functions found: {len(jni_functions)}")
for func_name in jni_functions[:10]: # Show first 10
print(f" {func_name}")
else:
print(" No JNI functions found")
def analyze_native_strings(self, asm_unit):
"""Analyze strings in native binary"""
print("\nString Analysis:")
# Get strings from the binary
strings = asm_unit.getStrings()
if strings:
print(f" Total strings: {len(strings)}")
# Analyze string patterns
self.analyze_native_string_patterns(strings)
else:
print(" No strings found")
def analyze_native_string_patterns(self, strings):
"""Analyze patterns in native strings"""
url_count = 0
path_count = 0
debug_count = 0
for string_obj in strings:
string_value = string_obj.getValue()
if string_value:
# Count URLs
if string_value.startswith("http://") or string_value.startswith("https://"):
url_count += 1
# Count file paths
if "/" in string_value and len(string_value) > 5:
path_count += 1
# Count debug strings
if any(keyword in string_value.lower() for keyword in ['debug', 'log', 'error', 'warning']):
debug_count += 1
print(f" URLs: {url_count}")
print(f" File paths: {path_count}")
print(f" Debug strings: {debug_count}")
Scénario et automatisation
Scripts d'automatisation avancés
# Comprehensive automation framework
import os
import json
import time
from datetime import datetime
class JEBAutomationFramework(IScript):
def __init__(self):
self.results = {}
self.start_time = None
self.config = self.load_config()
def run(self, ctx):
"""Main automation entry point"""
self.ctx = ctx
self.project = ctx.getMainProject()
self.start_time = time.time()
print("=== JEB Automation Framework ===")
print(f"Started at: {datetime.now()}")
# Run analysis pipeline
self.run_analysis_pipeline()
# Generate reports
self.generate_reports()
# Save results
self.save_results()
elapsed_time = time.time() - self.start_time
print(f"Analysis completed in {elapsed_time:.2f} seconds")
def load_config(self):
"""Load configuration from file"""
config_file = "jeb_automation_config.json"
default_config = {
"analysis_modules": [
"manifest_analysis",
"dex_analysis",
"resource_analysis",
"security_analysis",
"obfuscation_detection"
],
"output_formats": ["json", "html", "csv"],
"security_checks": {
"check_permissions": True,
"check_crypto": True,
"check_network": True,
"check_obfuscation": True
},
"performance": {
"max_analysis_time": 3600, # 1 hour
"parallel_processing": True,
"memory_limit": "4GB"
}
}
try:
if os.path.exists(config_file):
with open(config_file, 'r') as f:
config = json.load(f)
# Merge with defaults
for key, value in default_config.items():
if key not in config:
config[key] = value
return config
else:
# Create default config file
with open(config_file, 'w') as f:
json.dump(default_config, f, indent=2)
return default_config
except Exception as e:
print(f"Error loading config: {e}")
return default_config
def run_analysis_pipeline(self):
"""Run the complete analysis pipeline"""
modules = self.config.get("analysis_modules", [])
for module in modules:
print(f"\nRunning module: {module}")
try:
if module == "manifest_analysis":
self.results["manifest"] = self.analyze_manifest()
elif module == "dex_analysis":
self.results["dex"] = self.analyze_dex_files()
elif module == "resource_analysis":
self.results["resources"] = self.analyze_resources()
elif module == "security_analysis":
self.results["security"] = self.analyze_security()
elif module == "obfuscation_detection":
self.results["obfuscation"] = self.detect_obfuscation()
else:
print(f"Unknown module: {module}")
except Exception as e:
print(f"Error in module {module}: {e}")
self.results[module] = {"error": str(e)}
def analyze_manifest(self):
"""Analyze AndroidManifest.xml"""
manifest_results = {
"permissions": [],
"components": {},
"intent_filters": [],
"security_issues": []
}
# Find manifest
manifest_unit = None
for unit in self.project.getLiveUnits():
if unit.getName() == "AndroidManifest.xml":
manifest_unit = unit
break
if not manifest_unit:
return {"error": "AndroidManifest.xml not found"}
# Get manifest content
doc = manifest_unit.getDocument()
if doc:
content = doc.getDocumentPart(0, doc.getDocumentSize())
# Extract permissions
manifest_results["permissions"] = self.extract_permissions(content)
# Extract components
manifest_results["components"] = self.extract_components(content)
# Check for security issues
manifest_results["security_issues"] = self.check_manifest_security(content)
return manifest_results
def extract_permissions(self, manifest_content):
"""Extract permissions from manifest"""
import re
permissions = []
permission_pattern = r'<uses-permission[^>]*android:name="([^"]*)"'
matches = re.findall(permission_pattern, manifest_content)
for permission in matches:
risk_level = self.assess_permission_risk(permission)
permissions.append({
"name": permission,
"risk_level": risk_level
})
return permissions
def assess_permission_risk(self, permission):
"""Assess risk level of permission"""
high_risk_permissions = [
"android.permission.READ_CONTACTS",
"android.permission.WRITE_CONTACTS",
"android.permission.READ_SMS",
"android.permission.SEND_SMS",
"android.permission.CAMERA",
"android.permission.RECORD_AUDIO",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.SYSTEM_ALERT_WINDOW",
"android.permission.WRITE_SETTINGS"
]
medium_risk_permissions = [
"android.permission.ACCESS_COARSE_LOCATION",
"android.permission.ACCESS_NETWORK_STATE",
"android.permission.ACCESS_WIFI_STATE",
"android.permission.BLUETOOTH",
"android.permission.BLUETOOTH_ADMIN"
]
if permission in high_risk_permissions:
return "HIGH"
elif permission in medium_risk_permissions:
return "MEDIUM"
else:
return "LOW"
def extract_components(self, manifest_content):
"""Extract app components from manifest"""
import re
components = {
"activities": [],
"services": [],
"receivers": [],
"providers": []
}
# Extract activities
activity_pattern = r'<activity[^>]*android:name="([^"]*)"[^>]*(?:android:exported="([^"]*)")?'
activities = re.findall(activity_pattern, manifest_content)
for activity, exported in activities:
components["activities"].append({
"name": activity,
"exported": exported == "true"
})
# Extract services
service_pattern = r'<service[^>]*android:name="([^"]*)"[^>]*(?:android:exported="([^"]*)")?'
services = re.findall(service_pattern, manifest_content)
for service, exported in services:
components["services"].append({
"name": service,
"exported": exported == "true"
})
# Extract receivers
receiver_pattern = r'<receiver[^>]*android:name="([^"]*)"[^>]*(?:android:exported="([^"]*)")?'
receivers = re.findall(receiver_pattern, manifest_content)
for receiver, exported in receivers:
components["receivers"].append({
"name": receiver,
"exported": exported == "true"
})
return components
def check_manifest_security(self, manifest_content):
"""Check for security issues in manifest"""
issues = []
# Check for debug mode
if 'android:debuggable="true"' in manifest_content:
issues.append({
"type": "debug_enabled",
"severity": "HIGH",
"description": "Application is debuggable in production"
})
# Check for backup allowed
if 'android:allowBackup="true"' in manifest_content:
issues.append({
"type": "backup_allowed",
"severity": "MEDIUM",
"description": "Application data backup is allowed"
})
# Check for cleartext traffic
if 'android:usesCleartextTraffic="true"' in manifest_content:
issues.append({
"type": "cleartext_traffic",
"severity": "HIGH",
"description": "Application allows cleartext network traffic"
})
return issues
def analyze_dex_files(self):
"""Analyze DEX files"""
dex_results = {
"dex_files": [],
"total_classes": 0,
"total_methods": 0,
"obfuscation_indicators": []
}
dex_units = RuntimeProjectUtil.findUnitsByType(self.project, IDexUnit, False)
for dex_unit in dex_units:
dex_info = {
"name": dex_unit.getName(),
"classes": len(dex_unit.getClasses()),
"methods": 0,
"strings": 0
}
# Count methods
for cls in dex_unit.getClasses():
dex_info["methods"] += len(cls.getMethods())
# Count strings
string_pool = dex_unit.getPool(DexPoolType.STRING)
dex_info["strings"] = string_pool.size()
dex_results["dex_files"].append(dex_info)
dex_results["total_classes"] += dex_info["classes"]
dex_results["total_methods"] += dex_info["methods"]
return dex_results
def analyze_resources(self):
"""Analyze application resources"""
resource_results = {
"resource_files": [],
"strings": [],
"layouts": [],
"drawables": []
}
# Find resource files
for unit in self.project.getLiveUnits():
unit_name = unit.getName()
if unit_name.startswith("res/"):
resource_results["resource_files"].append(unit_name)
# Analyze specific resource types
if "strings.xml" in unit_name:
self.analyze_string_resources(unit, resource_results)
elif "layout/" in unit_name:
resource_results["layouts"].append(unit_name)
elif "drawable/" in unit_name:
resource_results["drawables"].append(unit_name)
return resource_results
def analyze_string_resources(self, unit, resource_results):
"""Analyze string resources"""
doc = unit.getDocument()
if doc:
content = doc.getDocumentPart(0, doc.getDocumentSize())
# Extract string values
import re
string_pattern = r'<string[^>]*name="([^"]*)"[^>]*>([^<]*)</string>'
strings = re.findall(string_pattern, content)
for name, value in strings:
resource_results["strings"].append({
"name": name,
"value": value,
"file": unit.getName()
})
def analyze_security(self):
"""Perform security analysis"""
security_results = {
"crypto_usage": [],
"network_security": [],
"data_storage": [],
"code_injection_risks": []
}
if self.config["security_checks"]["check_crypto"]:
security_results["crypto_usage"] = self.check_crypto_usage()
if self.config["security_checks"]["check_network"]:
security_results["network_security"] = self.check_network_security()
return security_results
def check_crypto_usage(self):
"""Check cryptographic API usage"""
crypto_findings = []
# This would analyze the decompiled code for crypto API usage
# Implementation would depend on having access to the Java source
return crypto_findings
def check_network_security(self):
"""Check network security practices"""
network_findings = []
# This would analyze network-related code
# Implementation would depend on having access to the Java source
return network_findings
def detect_obfuscation(self):
"""Detect obfuscation techniques"""
obfuscation_results = {
"indicators": [],
"confidence": 0.0,
"techniques": []
}
dex_units = RuntimeProjectUtil.findUnitsByType(self.project, IDexUnit, False)
for dex_unit in dex_units:
indicators = self.check_obfuscation_indicators(dex_unit)
obfuscation_results["indicators"].extend(indicators)
# Calculate confidence score
if obfuscation_results["indicators"]:
obfuscation_results["confidence"] = min(len(obfuscation_results["indicators"]) * 0.2, 1.0)
return obfuscation_results
def check_obfuscation_indicators(self, dex_unit):
"""Check for obfuscation indicators in DEX"""
indicators = []
classes = dex_unit.getClasses()
# Check for short class names
short_name_count = 0
total_classes = len(classes)
for cls in classes:
class_name = cls.getName()
simple_name = class_name.split('.')[-1]
if len(simple_name) <= 2 and not class_name.startswith("android."):
short_name_count += 1
if total_classes > 0 and (short_name_count / total_classes) > 0.3:
indicators.append("High ratio of short class names")
return indicators
def generate_reports(self):
"""Generate analysis reports"""
output_formats = self.config.get("output_formats", ["json"])
for format_type in output_formats:
if format_type == "json":
self.generate_json_report()
elif format_type == "html":
self.generate_html_report()
elif format_type == "csv":
self.generate_csv_report()
def generate_json_report(self):
"""Generate JSON report"""
report = {
"analysis_info": {
"timestamp": datetime.now().isoformat(),
"jeb_version": "Professional", # Would get actual version
"analysis_time": time.time() - self.start_time
},
"results": self.results
}
with open("jeb_analysis_report.json", 'w') as f:
json.dump(report, f, indent=2)
print("JSON report saved: jeb_analysis_report.json")
def generate_html_report(self):
"""Generate HTML report"""
html_content = self.create_html_report()
with open("jeb_analysis_report.html", 'w') as f:
f.write(html_content)
print("HTML report saved: jeb_analysis_report.html")
def create_html_report(self):
"""Create HTML report content"""
html = """
<!DOCTYPE html>
<html>
<head>
<title>JEB Analysis Report</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.header { background-color: #f0f0f0; padding: 10px; border-radius: 5px; }
.section { margin: 20px 0; }
.issue-high { color: red; font-weight: bold; }
.issue-medium { color: orange; font-weight: bold; }
.issue-low { color: green; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<div class="header">
<h1>JEB Analysis Report</h1>
<p>Generated: {timestamp}</p>
<p>Analysis Time: {analysis_time:.2f} seconds</p>
</div>
""".format(
timestamp=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
analysis_time=time.time() - self.start_time
)
# Add sections for each analysis result
for section_name, section_data in self.results.items():
html += f'<div class="section"><h2>{section_name.title()}</h2>'
html += self.format_section_html(section_data)
html += '</div>'
html += """
</body>
</html>
"""
return html
def format_section_html(self, data):
"""Format section data as HTML"""
if isinstance(data, dict):
html = "<ul>"
for key, value in data.items():
html += f"<li><strong>{key}:</strong> {value}</li>"
html += "</ul>"
return html
elif isinstance(data, list):
html = "<ul>"
for item in data:
html += f"<li>{item}</li>"
html += "</ul>"
return html
else:
return f"<p>{data}</p>"
def generate_csv_report(self):
"""Generate CSV report"""
import csv
# Create summary CSV
with open("jeb_analysis_summary.csv", 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(["Category", "Item", "Value"])
for category, data in self.results.items():
if isinstance(data, dict):
for key, value in data.items():
writer.writerow([category, key, value])
else:
writer.writerow([category, "result", data])
print("CSV report saved: jeb_analysis_summary.csv")
def save_results(self):
"""Save raw results for further processing"""
results_file = f"jeb_results_{int(time.time())}.json"
with open(results_file, 'w') as f:
json.dump(self.results, f, indent=2)
print(f"Raw results saved: {results_file}")
# Usage: Save as script and run in JEB
Pratiques exemplaires et conseils
Optimisation des performances
# Performance optimization for JEB analysis
class JEBPerformanceOptimizer:
def __init__(self, ctx):
self.ctx = ctx
self.project = ctx.getMainProject()
def optimize_analysis_settings(self):
"""Optimize JEB analysis settings"""
# Get analysis options
options = self.ctx.getEnginesContext().getEngineOptions()
# Optimize for large APKs
if self.is_large_apk():
# Disable expensive analysis
options.setOption("android.dex.optimize_code", False)
options.setOption("android.dex.merge_duplicate_methods", False)
# Limit analysis depth
options.setOption("android.dex.max_analysis_time", 300) # 5 minutes
# Optimize memory usage
options.setOption("android.dex.use_memory_mapping", True)
options.setOption("android.dex.cache_analysis_results", True)
def is_large_apk(self):
"""Check if APK is large"""
# Simple heuristic based on DEX file count and size
dex_units = RuntimeProjectUtil.findUnitsByType(self.project, IDexUnit, False)
total_classes = 0
for dex_unit in dex_units:
total_classes += len(dex_unit.getClasses())
return total_classes > 10000 # Threshold for large APK
def enable_parallel_processing(self):
"""Enable parallel processing where possible"""
# This would configure JEB for parallel analysis
# Implementation depends on JEB's threading capabilities
pass
def manage_memory_usage(self):
"""Manage memory usage during analysis"""
import gc
# Force garbage collection
gc.collect()
# Clear caches periodically
self.clear_analysis_caches()
def clear_analysis_caches(self):
"""Clear analysis caches to free memory"""
# This would clear JEB's internal caches
# Implementation depends on JEB's cache management API
pass
Gestion des erreurs et débogage
# Robust error handling for JEB scripts
import traceback
import logging
class RobustJEBScript(IScript):
def __init__(self):
self.setup_logging()
self.errors = []
self.warnings = []
def setup_logging(self):
"""Setup logging for the script"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('jeb_script.log'),
logging.StreamHandler()
]
)
self.logger = logging.getLogger(__name__)
def run(self, ctx):
"""Main script execution with error handling"""
try:
self.ctx = ctx
self.project = ctx.getMainProject()
if not self.validate_environment():
return
self.execute_analysis()
except Exception as e:
self.handle_error("Script execution failed", e)
finally:
self.cleanup()
self.report_status()
def validate_environment(self):
"""Validate JEB environment"""
if not self.project:
self.add_error("No project loaded")
return False
# Check for required units
dex_units = RuntimeProjectUtil.findUnitsByType(self.project, IDexUnit, False)
if not dex_units:
self.add_warning("No DEX units found")
return True
def execute_analysis(self):
"""Execute the main analysis"""
self.logger.info("Starting analysis")
# Perform analysis steps with individual error handling
self.safe_execute("Manifest analysis", self.analyze_manifest)
self.safe_execute("DEX analysis", self.analyze_dex)
self.safe_execute("Security analysis", self.analyze_security)
self.logger.info("Analysis completed")
def safe_execute(self, operation_name, operation_func):
"""Safely execute an operation with error handling"""
try:
self.logger.info(f"Starting {operation_name}")
result = operation_func()
self.logger.info(f"Completed {operation_name}")
return result
except Exception as e:
self.handle_error(f"{operation_name} failed", e)
return None
def handle_error(self, message, exception):
"""Handle errors gracefully"""
error_msg = f"{message}: {str(exception)}"
self.errors.append(error_msg)
self.logger.error(error_msg)
self.logger.error(f"Traceback: {traceback.format_exc()}")
def add_error(self, message):
"""Add error message"""
self.errors.append(message)
self.logger.error(message)
def add_warning(self, message):
"""Add warning message"""
self.warnings.append(message)
self.logger.warning(message)
def cleanup(self):
"""Cleanup resources"""
# Cleanup any resources used during analysis
pass
def report_status(self):
"""Report final status"""
print(f"\n=== Script Execution Summary ===")
print(f"Errors: {len(self.errors)}")
print(f"Warnings: {len(self.warnings)}")
if self.errors:
print("\nErrors:")
for error in self.errors:
print(f" - {error}")
if self.warnings:
print("\nWarnings:")
for warning in self.warnings:
print(f" - {warning}")
def analyze_manifest(self):
"""Analyze manifest with error handling"""
# Implementation here
pass
def analyze_dex(self):
"""Analyze DEX with error handling"""
# Implementation here
pass
def analyze_security(self):
"""Analyze security with error handling"""
# Implementation here
pass
Ressources
Documentation et apprentissage
- [Documents JEB] (LINK_16) - Documents officiels
- [Référence de l'API JEB] (LINK_16) - Documentation complète de l'API
- JEB Blog - Dernières mises à jour et tutoriels
- Communauté JEB - Forum des utilisateurs et discussions
Développement des scripts
- [Répertoire des scripts JEB] (LINK_16) - Exemples de scripts officiels
- Guide de l'API Python - Guide de script Python
- Plugin Development - Guide de développement du plugin
- Temples de script - Modèles de développement de script
Formation et certification
- [Formation JEB] (LINK_16) - Cours de formation officiels
- [Android Inverse Engineering] (LINK_16) - Outils d'analyse Android
- Test de sécurité mobile - Guide de sécurité mobile OWASP
- [Analyse des logiciels malveillants] (LINK_16) - Ressources d'analyse des logiciels malveillants