File size: 9,313 Bytes
e092c28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
"""
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