Apkk / src /report_generator.py
Skydata001's picture
Upload 7 files
e092c28 verified
Raw History Blame Contribute Delete
9.31 kB
"""
APK Deep Diff Analyzer - Report Generator
"""
import json
from typing import Dict, Any, List
from datetime import datetime
class ReportGenerator:
"""Generate analysis reports in multiple formats."""
def __init__(self, analysis_data: Dict[str, Any]):
self.data = analysis_data
def generate_txt_report(self) -> str:
"""Generate plain text report in Arabic."""
lines = []
d = self.data
lines.append("=" * 80)
lines.append("تقرير تحليل عميق لمقارنة ملفات APK")
lines.append("APK Deep Diff Analyzer Report")
lines.append("=" * 80)
lines.append("")
# Basic info
lines.append("معلومات الملفات | File Information")
lines.append("-" * 40)
orig = d.get("original_info", {})
mod = d.get("modified_info", {})
lines.append(f"APK الأصلي (Original): {orig.get('filename', 'N/A')}")
lines.append(f" الحجم (Size): {orig.get('size_formatted', 'N/A')}")
lines.append(f" SHA-256: {orig.get('sha256', 'N/A')}")
lines.append(f" MD5: {orig.get('md5', 'N/A')}")
lines.append("")
lines.append(f"APK المعدل (Modified): {mod.get('filename', 'N/A')}")
lines.append(f" الحجم (Size): {mod.get('size_formatted', 'N/A')}")
lines.append(f" SHA-256: {mod.get('sha256', 'N/A')}")
lines.append(f" MD5: {mod.get('md5', 'N/A')}")
lines.append("")
# Summary
summary = d.get("file_comparison", {}).get("summary", {})
lines.append("ملخص المقارنة | Comparison Summary")
lines.append("-" * 40)
lines.append(f"إجمالي الملفات (Total Files): {summary.get('total', 0)}")
lines.append(f"متطابقة (Unchanged): {summary.get('unchanged', 0)}")
lines.append(f"معدلة (Modified): {summary.get('modified', 0)}")
lines.append(f"مضافة (Added): {summary.get('added', 0)}")
lines.append(f"محذوفة (Removed): {summary.get('removed', 0)}")
lines.append("")
# Manifest changes
manifest = d.get("manifest_comparison", {})
changes = manifest.get("changes", {})
lines.append("تغييرات AndroidManifest.xml")
lines.append("-" * 40)
perms = changes.get("permissions", {})
added_perms = perms.get("added", [])
removed_perms = perms.get("removed", [])
if added_perms:
lines.append("صلاحيات مضافة (+Permissions Added):")
for p in added_perms:
lines.append(f" + {p}")
if removed_perms:
lines.append("صلاحيات محذوفة (-Permissions Removed):")
for p in removed_perms:
lines.append(f" - {p}")
pkg_changes = changes.get("package_info", {})
if pkg_changes:
lines.append("تغييرات معلومات الحزمة (Package Info Changes):")
for key, vals in pkg_changes.items():
lines.append(f" {key}: {vals.get('original', 'N/A')} → {vals.get('modified', 'N/A')}")
lines.append("")
# DEX changes
dex = d.get("dex_analysis", {})
lines.append("تحليل ملفات DEX")
lines.append("-" * 40)
lines.append(f"عدد ملفات DEX (DEX Count): {dex.get('dex_count', 0)}")
for fname, fdata in dex.get("dex_files", {}).items():
lines.append(f" {fname}:")
header = fdata.get("header", {})
if "error" not in header:
lines.append(f" Classes: {header.get('class_defs_count', 'N/A')}")
lines.append(f" Methods: {header.get('method_ids_count', 'N/A')}")
lines.append(f" Fields: {header.get('field_ids_count', 'N/A')}")
lines.append(f" Strings: {header.get('string_ids_count', 'N/A')}")
urls = dex.get("all_urls", [])
if urls:
lines.append("URLs المستخرجة:")
for url in urls[:20]: # Limit output
lines.append(f" {url}")
lines.append("")
# Native libraries
native = d.get("native_libraries", {})
lines.append("مكتبات Native")
lines.append("-" * 40)
lines.append(f"مكتبات في الأصلي (Original): {len(native.get('original', []))}")
lines.append(f"مكتبات في المعدل (Modified): {len(native.get('modified', []))}")
added_libs = native.get("added", [])
removed_libs = native.get("removed", [])
if added_libs:
lines.append("مكتبات مضافة:")
for lib in added_libs:
lines.append(f" + {lib}")
if removed_libs:
lines.append("مكتبات محذوفة:")
for lib in removed_libs:
lines.append(f" - {lib}")
lines.append("")
# Signature
sig = d.get("signature_comparison", {})
lines.append("تحليل التوقيع | Signature Analysis")
lines.append("-" * 40)
if sig.get("signature_changed"):
lines.append("⚠️ التوقيع تغير! (Signature Changed)")
else:
lines.append("✅ التوقيع متطابق (Signature Match)")
lines.append("")
# Suspicious changes
suspicious = d.get("suspicious_changes", [])
if suspicious:
lines.append("تغييرات مشبوهة محتملة | Potentially Suspicious Changes")
lines.append("-" * 40)
for item in suspicious:
lines.append(f" ⚠️ {item}")
lines.append("")
lines.append("=" * 80)
lines.append("نهاية التقرير | End of Report")
lines.append(f"تاريخ التحليل: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
lines.append("=" * 80)
return "\n".join(lines)
def generate_json_report(self) -> str:
"""Generate JSON report."""
return json.dumps(self.data, indent=2, ensure_ascii=False, default=str)
def generate_html_report(self) -> str:
"""Generate HTML report."""
d = self.data
summary = d.get("file_comparison", {}).get("summary", {})
html = f"""<!DOCTYPE html>
<html dir="rtl" lang="ar">
<head>
<meta charset="UTF-8">
<title>APK Deep Diff Analyzer Report</title>
<style>
body {{ font-family: 'Segoe UI', Tahoma, Arial, sans-serif; margin: 20px; background: #1a1a2e; color: #eee; }}
.container {{ max-width: 1200px; margin: 0 auto; }}
h1 {{ color: #00d4ff; text-align: center; }}
h2 {{ color: #ff6b6b; border-bottom: 2px solid #ff6b6b; padding-bottom: 5px; }}
.summary-box {{ background: #16213e; padding: 20px; border-radius: 10px; margin: 15px 0; }}
.added {{ color: #4ecdc4; }}
.removed {{ color: #ff6b6b; }}
.modified {{ color: #feca57; }}
.unchanged {{ color: #48dbfb; }}
.warning {{ color: #ff9f43; }}
table {{ width: 100%; border-collapse: collapse; margin: 15px 0; }}
th, td {{ padding: 10px; text-align: right; border: 1px solid #333; }}
th {{ background: #0f3460; }}
tr:nth-child(even) {{ background: #1a1a2e; }}
</style>
</head>
<body>
<div class="container">
<h1>🔍 APK Deep Diff Analyzer</h1>
<div class="summary-box">
<h2>📊 ملخص المقارنة</h2>
<p>إجمالي الملفات: <strong>{summary.get('total', 0)}</strong></p>
<p class="unchanged">✅ متطابقة: {summary.get('unchanged', 0)}</p>
<p class="modified">⚠️ معدلة: {summary.get('modified', 0)}</p>
<p class="added">➕ مضافة: {summary.get('added', 0)}</p>
<p class="removed">➖ محذوفة: {summary.get('removed', 0)}</p>
</div>
"""
# Manifest section
manifest = d.get("manifest_comparison", {})
changes = manifest.get("changes", {})
html += "<div class='summary-box'>"
html += "<h2>📋 AndroidManifest.xml</h2>"
perms = changes.get("permissions", {})
if perms.get("added"):
html += "<h3 class='added'>صلاحيات مضافة:</h3><ul>"
for p in perms["added"]:
html += f"<li class='added'>+ {p}</li>"
html += "</ul>"
if perms.get("removed"):
html += "<h3 class='removed'>صلاحيات محذوفة:</h3><ul>"
for p in perms["removed"]:
html += f"<li class='removed'>- {p}</li>"
html += "</ul>"
html += "</div>"
# Signature
sig = d.get("signature_comparison", {})
html += "<div class='summary-box'>"
html += "<h2>🔐 التوقيع</h2>"
if sig.get("signature_changed"):
html += "<p class='warning'>⚠️ التوقيع تغير!</p>"
else:
html += "<p class='unchanged'>✅ التوقيع متطابق</p>"
html += "</div>"
# Suspicious
suspicious = d.get("suspicious_changes", [])
if suspicious:
html += "<div class='summary-box'>"
html += "<h2 class='warning'>⚠️ تغييرات مشبوهة محتملة</h2><ul>"
for item in suspicious:
html += f"<li class='warning'>{item}</li>"
html += "</ul></div>"
html += "</div></body></html>"
return html