0
# Utility Functions
1
2
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.
3
4
## Capabilities
5
6
### High-Level Analysis Functions
7
8
Convenient functions that handle the most common analysis workflows with minimal setup.
9
10
```python { .api }
11
def AnalyzeAPK(filename: str, session=None, raw: bool = False) -> tuple:
12
"""
13
Comprehensive APK analysis with automatic DEX loading and analysis setup.
14
15
Parameters:
16
- filename: Path to APK file or raw data if raw=True
17
- session: Optional Session object for persistence
18
- raw: If True, filename contains raw APK bytes
19
20
Returns:
21
Tuple of (APK_object, list_of_DEX_objects, Analysis_object)
22
23
Example:
24
apk, dex_list, dx = AnalyzeAPK("app.apk")
25
"""
26
27
def AnalyzeDex(filename: str, session=None, raw: bool = False) -> tuple:
28
"""
29
DEX file analysis with automatic analysis setup.
30
31
Parameters:
32
- filename: Path to DEX file or raw data if raw=True
33
- session: Optional Session object for persistence
34
- raw: If True, filename contains raw DEX bytes
35
36
Returns:
37
Tuple of (list_of_DEX_objects, Analysis_object)
38
39
Example:
40
dex_list, dx = AnalyzeDex("classes.dex")
41
"""
42
43
def AnalyzeODEX(filename: str, session=None) -> tuple:
44
"""
45
ODEX file analysis with optimization data processing.
46
47
Parameters:
48
- filename: Path to ODEX file
49
- session: Optional Session object for persistence
50
51
Returns:
52
Tuple of (ODEX_object, Analysis_object)
53
"""
54
```
55
56
### Certificate and Signature Utilities
57
58
Functions for certificate processing and signature verification.
59
60
```python { .api }
61
def get_certificate_name_string(name, short: bool = False, separator: str = ", ") -> str:
62
"""
63
Convert certificate name object to readable string.
64
65
Parameters:
66
- name: Certificate name object (X.509 Name)
67
- short: Use short form for common name attributes
68
- separator: String to separate name components
69
70
Returns:
71
Formatted certificate name string
72
73
Example:
74
cert_name = get_certificate_name_string(cert.subject, short=True)
75
"""
76
77
def show_Certificate(cert, short: bool = False) -> None:
78
"""
79
Display certificate information in human-readable format.
80
81
Parameters:
82
- cert: X.509 certificate object
83
- short: Use abbreviated format for names
84
85
Example:
86
show_Certificate(apk.get_certificate())
87
"""
88
89
def get_apkid(apkfile: str) -> tuple:
90
"""
91
Quickly extract basic APK identification without full analysis.
92
93
Parameters:
94
- apkfile: Path to APK file
95
96
Returns:
97
Tuple of (package_name, version_code, version_name)
98
99
Example:
100
package, version_code, version_name = get_apkid("app.apk")
101
"""
102
```
103
104
### File Type Detection
105
106
Automatic detection and handling of different Android file formats.
107
108
```python { .api }
109
def is_android_file(filename: str) -> str:
110
"""
111
Detect if file is a supported Android format.
112
113
Parameters:
114
- filename: Path to file to check
115
116
Returns:
117
File type string ('APK', 'DEX', 'ODEX', 'AXML', 'ARSC') or None
118
119
Example:
120
file_type = is_android_file("unknown_file.bin")
121
"""
122
123
def auto_analyze(filename: str, session=None):
124
"""
125
Automatically detect file type and perform appropriate analysis.
126
127
Parameters:
128
- filename: Path to file to analyze
129
- session: Optional Session object
130
131
Returns:
132
Analysis objects appropriate for detected file type
133
134
Example:
135
results = auto_analyze("mystery_file")
136
"""
137
138
def load_analysis(filename: str, session=None):
139
"""
140
Load file with automatic format detection and analysis.
141
142
Parameters:
143
- filename: Path to Android file
144
- session: Optional Session object
145
146
Returns:
147
Dictionary with analysis results and file type information
148
"""
149
```
150
151
### Resource Processing Utilities
152
153
Utilities for working with Android resources and XML files.
154
155
```python { .api }
156
def decode_axml(axml_data: bytes, pretty: bool = True) -> bytes:
157
"""
158
Decode binary XML to readable XML format.
159
160
Parameters:
161
- axml_data: Raw AXML file bytes
162
- pretty: Format output with indentation
163
164
Returns:
165
Decoded XML as bytes
166
167
Example:
168
xml_content = decode_axml(apk.get_file("AndroidManifest.xml"))
169
"""
170
171
def extract_strings_from_arsc(arsc_data: bytes, package_name: str = None) -> dict:
172
"""
173
Extract string resources from ARSC data.
174
175
Parameters:
176
- arsc_data: Raw ARSC file bytes
177
- package_name: Optional package filter
178
179
Returns:
180
Dictionary mapping resource IDs to string values
181
182
Example:
183
strings = extract_strings_from_arsc(apk.get_file("resources.arsc"))
184
"""
185
186
def get_app_icon(apk_or_path, max_dpi: int = 65536) -> bytes:
187
"""
188
Extract application icon from APK.
189
190
Parameters:
191
- apk_or_path: APK object or path to APK file
192
- max_dpi: Maximum DPI for icon selection
193
194
Returns:
195
Icon image data as bytes or None if not found
196
197
Example:
198
icon_data = get_app_icon("app.apk")
199
"""
200
```
201
202
### Analysis Helpers
203
204
Helper functions for common analysis patterns and workflows.
205
206
```python { .api }
207
def find_crypto_usage(analysis_obj) -> dict:
208
"""
209
Find cryptographic API usage in analyzed application.
210
211
Parameters:
212
- analysis_obj: Analysis object from AnalyzeAPK or AnalyzeDEX
213
214
Returns:
215
Dictionary with crypto usage information
216
217
Example:
218
crypto_info = find_crypto_usage(dx)
219
"""
220
221
def detect_packers(dex_objects: list) -> list:
222
"""
223
Detect potential packer/obfuscation usage.
224
225
Parameters:
226
- dex_objects: List of DEX objects to analyze
227
228
Returns:
229
List of detected packer signatures and indicators
230
231
Example:
232
packers = detect_packers(dex_list)
233
"""
234
235
def get_api_usage_stats(analysis_obj) -> dict:
236
"""
237
Generate statistics on Android API usage.
238
239
Parameters:
240
- analysis_obj: Analysis object
241
242
Returns:
243
Dictionary with API usage statistics
244
245
Example:
246
api_stats = get_api_usage_stats(dx)
247
"""
248
249
def find_dynamic_loading(analysis_obj) -> list:
250
"""
251
Find dynamic code loading patterns.
252
253
Parameters:
254
- analysis_obj: Analysis object
255
256
Returns:
257
List of methods that perform dynamic loading
258
259
Example:
260
dynamic_loaders = find_dynamic_loading(dx)
261
"""
262
```
263
264
### Security Analysis Utilities
265
266
Specialized functions for security-focused analysis.
267
268
```python { .api }
269
def check_permissions_risk(apk_obj) -> dict:
270
"""
271
Analyze permission usage for security risks.
272
273
Parameters:
274
- apk_obj: APK object
275
276
Returns:
277
Dictionary with risk assessment of requested permissions
278
279
Example:
280
permission_risks = check_permissions_risk(apk)
281
"""
282
283
def find_url_patterns(analysis_obj) -> list:
284
"""
285
Find URL and network endpoint patterns in code.
286
287
Parameters:
288
- analysis_obj: Analysis object
289
290
Returns:
291
List of discovered URLs and network patterns
292
293
Example:
294
urls = find_url_patterns(dx)
295
"""
296
297
def detect_anti_analysis(analysis_obj) -> dict:
298
"""
299
Detect anti-analysis and evasion techniques.
300
301
Parameters:
302
- analysis_obj: Analysis object
303
304
Returns:
305
Dictionary with detected anti-analysis techniques
306
307
Example:
308
anti_analysis = detect_anti_analysis(dx)
309
"""
310
311
def scan_for_malware_indicators(apk_obj, analysis_obj) -> dict:
312
"""
313
Scan for common malware indicators and suspicious patterns.
314
315
Parameters:
316
- apk_obj: APK object
317
- analysis_obj: Analysis object
318
319
Returns:
320
Dictionary with malware indicator results
321
322
Example:
323
malware_scan = scan_for_malware_indicators(apk, dx)
324
"""
325
```
326
327
### Batch Processing Utilities
328
329
Functions for processing multiple files and batch operations.
330
331
```python { .api }
332
def analyze_directory(directory: str, recursive: bool = True, file_types: list = None) -> dict:
333
"""
334
Analyze all Android files in directory.
335
336
Parameters:
337
- directory: Directory path to scan
338
- recursive: Include subdirectories
339
- file_types: List of file types to include ('APK', 'DEX', etc.)
340
341
Returns:
342
Dictionary mapping filenames to analysis results
343
344
Example:
345
results = analyze_directory("/path/to/apks", recursive=True)
346
"""
347
348
def compare_apks(apk1_path: str, apk2_path: str) -> dict:
349
"""
350
Compare two APK files for differences.
351
352
Parameters:
353
- apk1_path: Path to first APK
354
- apk2_path: Path to second APK
355
356
Returns:
357
Dictionary with comparison results
358
359
Example:
360
comparison = compare_apks("app_v1.apk", "app_v2.apk")
361
"""
362
363
def batch_extract_info(file_list: list) -> dict:
364
"""
365
Extract basic information from multiple files efficiently.
366
367
Parameters:
368
- file_list: List of file paths to process
369
370
Returns:
371
Dictionary mapping filenames to extracted info
372
373
Example:
374
info = batch_extract_info(["app1.apk", "app2.apk", "app3.apk"])
375
"""
376
```
377
378
### Export and Reporting Utilities
379
380
Functions for generating reports and exporting analysis data.
381
382
```python { .api }
383
def export_analysis_json(analysis_data: dict, output_file: str) -> None:
384
"""
385
Export analysis results to structured JSON format.
386
387
Parameters:
388
- analysis_data: Dictionary with analysis results
389
- output_file: Output JSON file path
390
391
Example:
392
export_analysis_json({"apk": apk_info, "analysis": dx_info}, "report.json")
393
"""
394
395
def generate_html_report(apk_obj, analysis_obj, output_file: str) -> None:
396
"""
397
Generate comprehensive HTML analysis report.
398
399
Parameters:
400
- apk_obj: APK object
401
- analysis_obj: Analysis object
402
- output_file: Output HTML file path
403
404
Example:
405
generate_html_report(apk, dx, "analysis_report.html")
406
"""
407
408
def create_summary_report(analysis_results: dict) -> str:
409
"""
410
Create text summary report from analysis results.
411
412
Parameters:
413
- analysis_results: Dictionary with analysis data
414
415
Returns:
416
Formatted summary report as string
417
418
Example:
419
summary = create_summary_report(batch_results)
420
"""
421
```
422
423
## Usage Examples
424
425
### Quick APK Analysis
426
427
```python
428
from androguard.misc import AnalyzeAPK, get_apkid
429
430
# Quick identification without full analysis
431
package, version_code, version_name = get_apkid("app.apk")
432
print(f"Package: {package}")
433
print(f"Version: {version_name} ({version_code})")
434
435
# Full analysis
436
apk, dex_list, dx = AnalyzeAPK("app.apk")
437
438
# Get basic info
439
print(f"App name: {apk.get_app_name()}")
440
print(f"Permissions: {len(apk.get_permissions())}")
441
print(f"Activities: {len(apk.get_activities())}")
442
print(f"Classes: {len(dx.get_classes())}")
443
print(f"Methods: {len(dx.get_methods())}")
444
```
445
446
### Certificate Analysis
447
448
```python
449
from androguard.misc import AnalyzeAPK, show_Certificate, get_certificate_name_string
450
451
# Analyze APK
452
apk, dex_list, dx = AnalyzeAPK("signed_app.apk")
453
454
# Check if signed
455
if apk.is_signed():
456
print("APK is signed")
457
458
# Get certificates
459
certificates = apk.get_certificates()
460
461
for i, cert in enumerate(certificates):
462
print(f"\nCertificate {i+1}:")
463
464
# Show detailed certificate info
465
show_Certificate(cert)
466
467
# Get formatted subject name
468
subject_name = get_certificate_name_string(cert.subject, short=True)
469
print(f"Subject: {subject_name}")
470
471
# Get formatted issuer name
472
issuer_name = get_certificate_name_string(cert.issuer, short=True)
473
print(f"Issuer: {issuer_name}")
474
else:
475
print("APK is not signed")
476
```
477
478
### Resource Extraction
479
480
```python
481
from androguard.misc import AnalyzeAPK, decode_axml, extract_strings_from_arsc, get_app_icon
482
483
# Analyze APK
484
apk, dex_list, dx = AnalyzeAPK("app.apk")
485
486
# Extract and decode AndroidManifest.xml
487
manifest_data = apk.get_file("AndroidManifest.xml")
488
if manifest_data:
489
decoded_manifest = decode_axml(manifest_data, pretty=True)
490
with open("AndroidManifest_decoded.xml", "wb") as f:
491
f.write(decoded_manifest)
492
print("Manifest extracted and decoded")
493
494
# Extract string resources
495
resources_data = apk.get_file("resources.arsc")
496
if resources_data:
497
strings = extract_strings_from_arsc(resources_data, apk.get_package())
498
print(f"Extracted {len(strings)} string resources")
499
500
# Show some examples
501
for res_id, string_value in list(strings.items())[:5]:
502
print(f" 0x{res_id:08x}: {string_value}")
503
504
# Extract app icon
505
icon_data = get_app_icon(apk)
506
if icon_data:
507
with open("app_icon.png", "wb") as f:
508
f.write(icon_data)
509
print("App icon extracted")
510
```
511
512
### Security Analysis
513
514
```python
515
from androguard.misc import (AnalyzeAPK, find_crypto_usage, check_permissions_risk,
516
find_url_patterns, detect_anti_analysis)
517
518
# Analyze APK
519
apk, dex_list, dx = AnalyzeAPK("suspicious_app.apk")
520
521
# Check permission risks
522
permission_risks = check_permissions_risk(apk)
523
print("Permission Risk Analysis:")
524
for permission, risk_info in permission_risks.items():
525
print(f" {permission}: {risk_info['risk_level']} - {risk_info['description']}")
526
527
# Find crypto usage
528
crypto_usage = find_crypto_usage(dx)
529
print(f"\nCryptographic Usage:")
530
print(f" Algorithms found: {len(crypto_usage['algorithms'])}")
531
print(f" Key generation: {crypto_usage['key_generation']}")
532
print(f" Encryption calls: {len(crypto_usage['encryption_calls'])}")
533
534
# Find URLs and network endpoints
535
urls = find_url_patterns(dx)
536
print(f"\nNetwork Endpoints ({len(urls)} found):")
537
for url in urls[:10]: # Show first 10
538
print(f" {url}")
539
540
# Detect anti-analysis techniques
541
anti_analysis = detect_anti_analysis(dx)
542
if anti_analysis['detected']:
543
print(f"\nAnti-Analysis Techniques Detected:")
544
for technique in anti_analysis['techniques']:
545
print(f" - {technique}")
546
else:
547
print("\nNo anti-analysis techniques detected")
548
```
549
550
### Batch Processing
551
552
```python
553
from androguard.misc import analyze_directory, compare_apks, batch_extract_info
554
import json
555
556
# Analyze entire directory
557
results = analyze_directory("/path/to/apk/directory", recursive=True)
558
559
print(f"Analyzed {len(results)} files")
560
561
# Process results
562
summary_stats = {
563
'total_files': len(results),
564
'successful': 0,
565
'failed': 0,
566
'packages': [],
567
'total_classes': 0,
568
'total_methods': 0
569
}
570
571
for filename, analysis in results.items():
572
if analysis and 'error' not in analysis:
573
summary_stats['successful'] += 1
574
summary_stats['packages'].append(analysis['package'])
575
summary_stats['total_classes'] += analysis['classes']
576
summary_stats['total_methods'] += analysis['methods']
577
else:
578
summary_stats['failed'] += 1
579
580
print(f"Success rate: {summary_stats['successful']}/{summary_stats['total_files']}")
581
print(f"Total classes analyzed: {summary_stats['total_classes']}")
582
print(f"Total methods analyzed: {summary_stats['total_methods']}")
583
584
# Compare two versions of an app
585
if len(summary_stats['packages']) >= 2:
586
# Find two files for the same package (different versions)
587
comparison = compare_apks("app_v1.apk", "app_v2.apk")
588
589
print(f"\nApp Comparison Results:")
590
print(f" Version changes: {comparison['version_diff']}")
591
print(f" Permission changes: {len(comparison['permission_diff'])}")
592
print(f" New classes: {len(comparison['new_classes'])}")
593
print(f" Removed classes: {len(comparison['removed_classes'])}")
594
```
595
596
### Automated Analysis Workflow
597
598
```python
599
from androguard.misc import *
600
import os
601
import json
602
from datetime import datetime
603
604
def comprehensive_apk_analysis(apk_path, output_dir):
605
"""Perform comprehensive analysis of APK file."""
606
607
# Create output directory
608
os.makedirs(output_dir, exist_ok=True)
609
610
# Initialize results
611
results = {
612
'timestamp': datetime.now().isoformat(),
613
'file_path': apk_path,
614
'analysis_results': {}
615
}
616
617
try:
618
# Quick identification
619
package, version_code, version_name = get_apkid(apk_path)
620
results['basic_info'] = {
621
'package': package,
622
'version_code': version_code,
623
'version_name': version_name
624
}
625
626
# Full analysis
627
apk, dex_list, dx = AnalyzeAPK(apk_path)
628
629
# APK information
630
results['apk_info'] = {
631
'app_name': apk.get_app_name(),
632
'permissions': apk.get_permissions(),
633
'activities': apk.get_activities(),
634
'services': apk.get_services(),
635
'receivers': apk.get_receivers(),
636
'is_signed': apk.is_signed(),
637
'min_sdk': apk.get_min_sdk_version(),
638
'target_sdk': apk.get_target_sdk_version()
639
}
640
641
# Analysis information
642
results['analysis_info'] = {
643
'classes': len(dx.get_classes()),
644
'methods': len(dx.get_methods()),
645
'strings': len(dx.get_strings())
646
}
647
648
# Security analysis
649
results['security_analysis'] = {
650
'permission_risks': check_permissions_risk(apk),
651
'crypto_usage': find_crypto_usage(dx),
652
'urls_found': find_url_patterns(dx),
653
'anti_analysis': detect_anti_analysis(dx)
654
}
655
656
# Extract resources
657
manifest_data = apk.get_file("AndroidManifest.xml")
658
if manifest_data:
659
decoded_manifest = decode_axml(manifest_data)
660
with open(os.path.join(output_dir, "AndroidManifest.xml"), "wb") as f:
661
f.write(decoded_manifest)
662
663
# Extract icon
664
icon_data = get_app_icon(apk)
665
if icon_data:
666
with open(os.path.join(output_dir, "icon.png"), "wb") as f:
667
f.write(icon_data)
668
669
# Save results
670
with open(os.path.join(output_dir, "analysis.json"), "w") as f:
671
json.dump(results, f, indent=2, default=str)
672
673
return results
674
675
except Exception as e:
676
results['error'] = str(e)
677
return results
678
679
# Example usage
680
analysis_result = comprehensive_apk_analysis("target_app.apk", "comprehensive_analysis")
681
682
if 'error' not in analysis_result:
683
print("✓ Analysis completed successfully")
684
print(f" Package: {analysis_result['basic_info']['package']}")
685
print(f" Classes: {analysis_result['analysis_info']['classes']}")
686
print(f" Security risks: {len(analysis_result['security_analysis']['permission_risks'])}")
687
else:
688
print(f"✗ Analysis failed: {analysis_result['error']}")
689
```
690
691
## Utility Functions Reference
692
693
```python { .api }
694
def create_analysis_session(files: list) -> object:
695
"""
696
Create analysis session with multiple files.
697
698
Parameters:
699
- files: List of file paths to include in session
700
701
Returns:
702
Session object with all files loaded
703
"""
704
705
def get_analysis_summary(apk_obj, analysis_obj) -> dict:
706
"""
707
Get comprehensive analysis summary.
708
709
Parameters:
710
- apk_obj: APK object
711
- analysis_obj: Analysis object
712
713
Returns:
714
Dictionary with summary information
715
"""
716
717
def validate_apk_integrity(apk_path: str) -> dict:
718
"""
719
Validate APK file integrity and structure.
720
721
Parameters:
722
- apk_path: Path to APK file
723
724
Returns:
725
Dictionary with validation results
726
"""
727
728
def extract_all_resources(apk_obj, output_dir: str) -> list:
729
"""
730
Extract all resources from APK to directory.
731
732
Parameters:
733
- apk_obj: APK object
734
- output_dir: Output directory path
735
736
Returns:
737
List of extracted file paths
738
"""
739
```