anais-apk-forensic 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -0
  3. package/anais.sh +669 -0
  4. package/analysis_tools/__pycache__/apk_basic_info.cpython-313.pyc +0 -0
  5. package/analysis_tools/__pycache__/apk_basic_info.cpython-314.pyc +0 -0
  6. package/analysis_tools/__pycache__/check_zip_encryption.cpython-313.pyc +0 -0
  7. package/analysis_tools/__pycache__/check_zip_encryption.cpython-314.pyc +0 -0
  8. package/analysis_tools/__pycache__/detect_obfuscation.cpython-313.pyc +0 -0
  9. package/analysis_tools/__pycache__/detect_obfuscation.cpython-314.pyc +0 -0
  10. package/analysis_tools/__pycache__/dex_payload_hunter.cpython-314.pyc +0 -0
  11. package/analysis_tools/__pycache__/entropy_analyzer.cpython-314.pyc +0 -0
  12. package/analysis_tools/__pycache__/error_logger.cpython-313.pyc +0 -0
  13. package/analysis_tools/__pycache__/error_logger.cpython-314.pyc +0 -0
  14. package/analysis_tools/__pycache__/find_encrypted_payload.cpython-314.pyc +0 -0
  15. package/analysis_tools/__pycache__/fix_apk_headers.cpython-313.pyc +0 -0
  16. package/analysis_tools/__pycache__/fix_apk_headers.cpython-314.pyc +0 -0
  17. package/analysis_tools/__pycache__/manifest_analyzer.cpython-313.pyc +0 -0
  18. package/analysis_tools/__pycache__/manifest_analyzer.cpython-314.pyc +0 -0
  19. package/analysis_tools/__pycache__/network_analyzer.cpython-313.pyc +0 -0
  20. package/analysis_tools/__pycache__/network_analyzer.cpython-314.pyc +0 -0
  21. package/analysis_tools/__pycache__/report_generator.cpython-313.pyc +0 -0
  22. package/analysis_tools/__pycache__/report_generator.cpython-314.pyc +0 -0
  23. package/analysis_tools/__pycache__/report_generator_modular.cpython-314.pyc +0 -0
  24. package/analysis_tools/__pycache__/sast_scanner.cpython-313.pyc +0 -0
  25. package/analysis_tools/__pycache__/sast_scanner.cpython-314.pyc +0 -0
  26. package/analysis_tools/__pycache__/so_string_analyzer.cpython-314.pyc +0 -0
  27. package/analysis_tools/__pycache__/yara_enhanced_analyzer.cpython-314.pyc +0 -0
  28. package/analysis_tools/__pycache__/yara_results_processor.cpython-314.pyc +0 -0
  29. package/analysis_tools/apk_basic_info.py +85 -0
  30. package/analysis_tools/check_zip_encryption.py +142 -0
  31. package/analysis_tools/detect_obfuscation.py +650 -0
  32. package/analysis_tools/dex_payload_hunter.py +734 -0
  33. package/analysis_tools/entropy_analyzer.py +335 -0
  34. package/analysis_tools/error_logger.py +75 -0
  35. package/analysis_tools/find_encrypted_payload.py +485 -0
  36. package/analysis_tools/fix_apk_headers.py +154 -0
  37. package/analysis_tools/manifest_analyzer.py +214 -0
  38. package/analysis_tools/network_analyzer.py +287 -0
  39. package/analysis_tools/report_generator.py +506 -0
  40. package/analysis_tools/report_generator_modular.py +885 -0
  41. package/analysis_tools/sast_scanner.py +412 -0
  42. package/analysis_tools/so_string_analyzer.py +406 -0
  43. package/analysis_tools/yara_enhanced_analyzer.py +330 -0
  44. package/analysis_tools/yara_results_processor.py +368 -0
  45. package/analyzer_config.json +113 -0
  46. package/apkid/__init__.py +32 -0
  47. package/apkid/__pycache__/__init__.cpython-313.pyc +0 -0
  48. package/apkid/__pycache__/__init__.cpython-314.pyc +0 -0
  49. package/apkid/__pycache__/apkid.cpython-313.pyc +0 -0
  50. package/apkid/__pycache__/apkid.cpython-314.pyc +0 -0
  51. package/apkid/__pycache__/main.cpython-313.pyc +0 -0
  52. package/apkid/__pycache__/main.cpython-314.pyc +0 -0
  53. package/apkid/__pycache__/output.cpython-313.pyc +0 -0
  54. package/apkid/__pycache__/rules.cpython-313.pyc +0 -0
  55. package/apkid/apkid.py +266 -0
  56. package/apkid/main.py +98 -0
  57. package/apkid/output.py +177 -0
  58. package/apkid/rules/apk/common.yara +68 -0
  59. package/apkid/rules/apk/obfuscators.yara +118 -0
  60. package/apkid/rules/apk/packers.yara +1197 -0
  61. package/apkid/rules/apk/protectors.yara +301 -0
  62. package/apkid/rules/dex/abnormal.yara +104 -0
  63. package/apkid/rules/dex/anti-vm.yara +568 -0
  64. package/apkid/rules/dex/common.yara +60 -0
  65. package/apkid/rules/dex/compilers.yara +434 -0
  66. package/apkid/rules/dex/obfuscators.yara +602 -0
  67. package/apkid/rules/dex/packers.yara +761 -0
  68. package/apkid/rules/dex/protectors.yara +520 -0
  69. package/apkid/rules/dll/common.yara +38 -0
  70. package/apkid/rules/dll/obfuscators.yara +43 -0
  71. package/apkid/rules/elf/anti-vm.yara +43 -0
  72. package/apkid/rules/elf/common.yara +54 -0
  73. package/apkid/rules/elf/obfuscators.yara +991 -0
  74. package/apkid/rules/elf/packers.yara +1128 -0
  75. package/apkid/rules/elf/protectors.yara +794 -0
  76. package/apkid/rules/res/common.yara +43 -0
  77. package/apkid/rules/res/obfuscators.yara +46 -0
  78. package/apkid/rules/res/protectors.yara +46 -0
  79. package/apkid/rules.py +77 -0
  80. package/bin/anais +3 -0
  81. package/dist/cli.js +82 -0
  82. package/dist/index.js +123 -0
  83. package/dist/types/index.js +2 -0
  84. package/dist/utils/index.js +21 -0
  85. package/dist/utils/output.js +44 -0
  86. package/dist/utils/paths.js +107 -0
  87. package/docs/ARCHITECTURE.txt +353 -0
  88. package/docs/Workflow and Reference.md +445 -0
  89. package/package.json +70 -0
  90. package/rules/yara_general_rules.yar +323 -0
  91. package/scripts/dynamic_analysis_helper.sh +334 -0
  92. package/scripts/frida/dpt_dex_dumper.js +145 -0
  93. package/scripts/frida/frida_dex_dump.js +145 -0
  94. package/scripts/frida/frida_hooks.js +437 -0
  95. package/scripts/frida/frida_websocket_extractor.js +154 -0
  96. package/scripts/setup.sh +206 -0
  97. package/scripts/validate_framework.sh +224 -0
  98. package/src/cli.ts +91 -0
  99. package/src/index.ts +123 -0
  100. package/src/types/index.ts +44 -0
  101. package/src/utils/index.ts +6 -0
  102. package/src/utils/output.ts +50 -0
  103. package/src/utils/paths.ts +72 -0
  104. package/tsconfig.json +14 -0
package/anais.sh ADDED
@@ -0,0 +1,669 @@
1
+ #!/bin/bash
2
+
3
+ #################################################
4
+ # Anais Static Core
5
+ # Author: Reezcode24
6
+ # Date: 2026-01-23
7
+ # Description: Comprehensive APK analysis with multiple protection bypass techniques
8
+ #################################################
9
+
10
+ set -e
11
+
12
+ # Suppress Python warnings globally
13
+ export PYTHONWARNINGS="ignore"
14
+
15
+ # Colors for output
16
+ RED='\033[0;31m'
17
+ GREEN='\033[0;32m'
18
+ YELLOW='\033[1;33m'
19
+ BLUE='\033[0;34m'
20
+ MAGENTA='\033[0;35m'
21
+ CYAN='\033[0;36m'
22
+ NC='\033[0m' # No Color
23
+
24
+ # Configuration
25
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
26
+ WORK_DIR="${HOME}/Documents/Anais-Reports"
27
+ TOOLS_DIR="${SCRIPT_DIR}/analysis_tools"
28
+ CONFIG_FILE="${SCRIPT_DIR}/analyzer_config.json"
29
+ ERROR_LOG="${SCRIPT_DIR}/analysis_errors.log"
30
+
31
+ # Ensure workspace directory exists
32
+ if [ ! -d "$WORK_DIR" ]; then
33
+ mkdir -p "$WORK_DIR/reports"
34
+ fi
35
+
36
+ # Banner
37
+ print_banner() {
38
+ echo -e "${CYAN}"
39
+ echo "╔═══════════════════════════════════════════════════════════╗"
40
+ echo "║ Anais Static Core v1.0 ║"
41
+ echo "║ Comprehensive APK Security Analysis & SAST ║"
42
+ echo "╚═══════════════════════════════════════════════════════════╝"
43
+ echo -e "${NC}"
44
+ }
45
+
46
+ # Logging functions
47
+ log_info() {
48
+ echo -e "${BLUE}[INFO]${NC} $1"
49
+ }
50
+
51
+ log_success() {
52
+ echo -e "${GREEN}[✓]${NC} $1"
53
+ }
54
+
55
+ log_warning() {
56
+ echo -e "${YELLOW}[WARNING]${NC} $1"
57
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] [WARNING] $1" >> "$ERROR_LOG" 2>/dev/null || true
58
+ }
59
+
60
+ log_error() {
61
+ echo -e "${RED}[ERROR]${NC} $1"
62
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] $1" >> "$ERROR_LOG" 2>/dev/null || true
63
+ }
64
+
65
+ log_error_detail() {
66
+ # Log detailed error to file only
67
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR DETAIL] $1" >> "$ERROR_LOG" 2>/dev/null || true
68
+ }
69
+
70
+ log_critical() {
71
+ echo -e "${RED}[CRITICAL]${NC} $1"
72
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] [CRITICAL] $1" >> "$ERROR_LOG" 2>/dev/null || true
73
+ }
74
+
75
+ log_section() {
76
+ echo -e "\n${MAGENTA}═══ $1 ═══${NC}\n"
77
+ }
78
+
79
+ # Check dependencies
80
+ check_dependencies() {
81
+ log_section "Checking Dependencies"
82
+
83
+ local missing_deps=()
84
+
85
+ # Core tools
86
+ command -v python3 >/dev/null 2>&1 || missing_deps+=("python3")
87
+ command -v java >/dev/null 2>&1 || missing_deps+=("java")
88
+ command -v apktool >/dev/null 2>&1 || missing_deps+=("apktool")
89
+ command -v jadx >/dev/null 2>&1 || missing_deps+=("jadx")
90
+ command -v yara >/dev/null 2>&1 || missing_deps+=("yara")
91
+ command -v unzip >/dev/null 2>&1 || missing_deps+=("unzip")
92
+ command -v zipinfo >/dev/null 2>&1 || missing_deps+=("zipinfo")
93
+ command -v xxd >/dev/null 2>&1 || missing_deps+=("xxd")
94
+
95
+ # Python modules check
96
+ python3 -c "import androguard" 2>/dev/null || log_warning "androguard not installed (pip3 install androguard)"
97
+ python3 -c "import yara" 2>/dev/null || log_warning "yara-python not installed (pip3 install yara-python)"
98
+ python3 -c "import requests" 2>/dev/null || log_warning "requests not installed (pip3 install requests)"
99
+
100
+ if [ ${#missing_deps[@]} -ne 0 ]; then
101
+ log_error "Missing dependencies: ${missing_deps[*]}"
102
+ log_info "Install using: brew install ${missing_deps[*]} (macOS) or apt-get install ${missing_deps[*]} (Linux)"
103
+ exit 1
104
+ fi
105
+
106
+ log_success "All core dependencies satisfied"
107
+ }
108
+
109
+ # Initialize workspace
110
+ init_workspace() {
111
+ local apk_path="$1"
112
+ local apk_name=$(basename "$apk_path" .apk)
113
+
114
+ APK_WORK_DIR="${WORK_DIR}/${apk_name}_$(date +%Y%m%d_%H%M%S)"
115
+ DECOMPILED_DIR="${APK_WORK_DIR}/decompiled"
116
+ JADX_OUTPUT="${APK_WORK_DIR}/jadx_output"
117
+ TEMP_DIR="${APK_WORK_DIR}/temp"
118
+ REPORTS_DIR="${APK_WORK_DIR}/reports"
119
+ REPORT_FILE="${REPORTS_DIR}/report.md"
120
+ JSON_REPORT="${REPORTS_DIR}/report.json"
121
+
122
+ mkdir -p "$APK_WORK_DIR" "$DECOMPILED_DIR" "$JADX_OUTPUT" "$TEMP_DIR" "$REPORTS_DIR"
123
+
124
+ log_success "Workspace initialized: $APK_WORK_DIR"
125
+ }
126
+
127
+ # APK Basic Info Extraction
128
+ extract_basic_info() {
129
+ log_section "Extracting Basic APK Information"
130
+
131
+ local apk_path="$1"
132
+
133
+ # File hash
134
+ SHA256=$(shasum -a 256 "$apk_path" | awk '{print $1}')
135
+ MD5=$(md5 -q "$apk_path")
136
+ FILE_SIZE=$(stat -f%z "$apk_path" 2>/dev/null || stat -c%s "$apk_path")
137
+
138
+ log_info "SHA256: $SHA256"
139
+ log_info "MD5: $MD5"
140
+ log_info "Size: $FILE_SIZE bytes"
141
+
142
+ # Try to get basic APK info using aapt
143
+ if command -v aapt >/dev/null 2>&1; then
144
+ aapt dump badging "$apk_path" > "${TEMP_DIR}/aapt_info.txt" 2>/dev/null || true
145
+ fi
146
+
147
+ # Use Python androguard for detailed analysis
148
+ python3 "${TOOLS_DIR}/apk_basic_info.py" "$apk_path" "${TEMP_DIR}/basic_info.json" || true
149
+ }
150
+
151
+ # Check if APK is encrypted/password protected
152
+ check_apk_protection() {
153
+ log_section "Checking APK Protection Mechanisms"
154
+
155
+ local apk_path="$1"
156
+
157
+ # Test unzip
158
+ if ! unzip -t "$apk_path" >/dev/null 2>&1; then
159
+ log_warning "APK appears to be corrupted or encrypted"
160
+
161
+ # Check ZIP encryption flags
162
+ python3 "${TOOLS_DIR}/check_zip_encryption.py" "$apk_path" "${TEMP_DIR}/encryption_check.json"
163
+
164
+ # Attempt header manipulation
165
+ if [ -f "${TEMP_DIR}/encryption_check.json" ]; then
166
+ local is_encrypted=$(python3 -c "import json; print(json.load(open('${TEMP_DIR}/encryption_check.json'))['encrypted'])")
167
+
168
+ if [ "$is_encrypted" = "True" ]; then
169
+ log_warning "Attempting to fix ZIP headers..."
170
+ python3 "${TOOLS_DIR}/fix_apk_headers.py" "$apk_path" "${TEMP_DIR}/fixed_apk.apk"
171
+
172
+ if [ -f "${TEMP_DIR}/fixed_apk.apk" ]; then
173
+ log_success "Headers fixed, using modified APK"
174
+ APK_TO_ANALYZE="${TEMP_DIR}/fixed_apk.apk"
175
+ return 0
176
+ else
177
+ log_error "Failed to fix APK headers"
178
+ return 1
179
+ fi
180
+ fi
181
+ fi
182
+ else
183
+ log_success "APK is not encrypted"
184
+ APK_TO_ANALYZE="$apk_path"
185
+ return 0
186
+ fi
187
+ }
188
+
189
+ # Decompile with apktool
190
+ decompile_apktool() {
191
+ log_section "Decompiling with APKTool"
192
+
193
+ local apk_path="$1"
194
+
195
+ if apktool d -f -o "$DECOMPILED_DIR" "$apk_path" 2>&1 | tee "${TEMP_DIR}/apktool.log"; then
196
+ log_success "APKTool decompilation successful"
197
+ return 0
198
+ else
199
+ log_error "APKTool decompilation failed"
200
+ return 1
201
+ fi
202
+ }
203
+
204
+ # Decompile with JADX
205
+ decompile_jadx() {
206
+ log_section "Decompiling with JADX"
207
+
208
+ local apk_path="$1"
209
+
210
+ if jadx -d "$JADX_OUTPUT" "$apk_path" 2>&1 | tee "${TEMP_DIR}/jadx.log"; then
211
+ log_success "JADX decompilation successful"
212
+ return 0
213
+ else
214
+ log_error "JADX decompilation failed"
215
+ return 1
216
+ fi
217
+ }
218
+
219
+ # Analyze protection libraries
220
+ analyze_protection_libraries() {
221
+ log_section "Analyzing Protection Libraries"
222
+
223
+ local protection_type="$1"
224
+ local target_libs=()
225
+
226
+ # Map protection type to library names
227
+ case "$protection_type" in
228
+ "dpt-shell")
229
+ target_libs=("libdpt")
230
+ log_info "Targeting DPT-Shell libraries: libdpt.so"
231
+ ;;
232
+ "bangcle")
233
+ target_libs=("libbangcle" "libsecexe" "libDexHelper")
234
+ log_info "Targeting Bangcle libraries: libbangcle*.so, libsecexe.so"
235
+ ;;
236
+ "qihoo-360"|"jiagu")
237
+ target_libs=("libjiagu" "libjiagu_art" "libjiagu_dvm")
238
+ log_info "Targeting Qihoo 360 libraries: libjiagu*.so"
239
+ ;;
240
+ "dexprotector")
241
+ target_libs=("libprotect" "libdexprotector")
242
+ log_info "Targeting DexProtector libraries: libprotect*.so"
243
+ ;;
244
+ "secneo")
245
+ target_libs=("libshell" "libsecexe")
246
+ log_info "Targeting SecNeo libraries: libshell*.so"
247
+ ;;
248
+ *)
249
+ log_info "Unknown protection type: $protection_type"
250
+ log_info "Analyzing all suspicious .so files"
251
+ # Will analyze all .so files if found
252
+ ;;
253
+ esac
254
+
255
+ # Build target arguments
256
+ local target_args=""
257
+ for lib in "${target_libs[@]}"; do
258
+ target_args="$target_args --target $lib"
259
+ done
260
+
261
+ # Run SO String Analyzer
262
+ log_info "Extracting strings from protection libraries..."
263
+
264
+ if [ -n "$target_args" ]; then
265
+ # Analyze specific targets
266
+ if python3 "${TOOLS_DIR}/so_string_analyzer.py" \
267
+ "$APK_PATH" \
268
+ $target_args \
269
+ --json "${TEMP_DIR}/so_strings.json" \
270
+ --limit 20 2>> "$ERROR_LOG"; then
271
+ log_success "Protection library analysis completed"
272
+
273
+ # Show brief summary
274
+ if [ -f "${TEMP_DIR}/so_strings.json" ]; then
275
+ log_info "String extraction summary:"
276
+ python3 -c "
277
+ import json
278
+ try:
279
+ data = json.load(open('${TEMP_DIR}/so_strings.json'))
280
+ for result in data:
281
+ cats = result.get('categories', {})
282
+ critical = ['dex_files', 'zip_files', 'code_cache_paths']
283
+ for cat in critical:
284
+ if cat in cats:
285
+ items = cats[cat]
286
+ print(f' 🎯 {cat}: {len(items)} found')
287
+ for item in items[:2]:
288
+ print(f' • {item}')
289
+ except Exception as e:
290
+ pass
291
+ " 2>/dev/null || true
292
+ fi
293
+ else
294
+ log_warning "SO string analysis completed but no output file generated"
295
+ fi
296
+ else
297
+ # Analyze all .so files (no specific targets)
298
+ log_info "No specific targets - scanning all native libraries..."
299
+
300
+ # Just extract and log the presence of .so files
301
+ python3 -c "
302
+ import zipfile
303
+ import sys
304
+ try:
305
+ with zipfile.ZipFile('$APK_PATH', 'r') as zf:
306
+ so_files = [f.filename for f in zf.filelist if f.filename.endswith('.so')]
307
+ if so_files:
308
+ print(f'Found {len(so_files)} .so file(s)')
309
+ for so in so_files[:5]:
310
+ print(f' • {so}')
311
+ if len(so_files) > 5:
312
+ print(f' ... and {len(so_files) - 5} more')
313
+ except Exception as e:
314
+ print(f'Error: {e}', file=sys.stderr)
315
+ " 2>/dev/null || log_info "No native libraries found or error reading APK"
316
+ fi
317
+ }
318
+
319
+ # Detect obfuscation
320
+ detect_obfuscation() {
321
+ log_section "Detecting Obfuscation Techniques"
322
+
323
+ # Generate basic APK info first if not exists
324
+ if [ ! -f "${TEMP_DIR}/basic_info.json" ]; then
325
+ python3 "${TOOLS_DIR}/apk_basic_info.py" "$APK_PATH" "${TEMP_DIR}/basic_info.json" 2>> "$ERROR_LOG" || true
326
+ fi
327
+
328
+ # First run DEX payload hunter to find encrypted payloads
329
+ log_info "Hunting for encrypted DEX payloads..."
330
+ local package_name=$(python3 -c "import json; f=open('${TEMP_DIR}/basic_info.json'); print(json.load(f).get('package_name', ''))" 2>> "$ERROR_LOG" || echo "")
331
+
332
+ if python3 "${TOOLS_DIR}/dex_payload_hunter.py" \
333
+ "$APK_PATH" \
334
+ "${TEMP_DIR}/dex_payload_report.json" \
335
+ "$package_name" --brief 2>> "$ERROR_LOG"; then
336
+ log_success "DEX payload analysis completed"
337
+ else
338
+ log_warning "DEX payload hunter encountered issues (check $ERROR_LOG)"
339
+ fi
340
+
341
+ # Then run standard obfuscation detection
342
+ if python3 "${TOOLS_DIR}/detect_obfuscation.py" \
343
+ "$APK_PATH" \
344
+ "$DECOMPILED_DIR" \
345
+ "$JADX_OUTPUT" \
346
+ "${TEMP_DIR}/obfuscation_report.json" 2>> "$ERROR_LOG"; then
347
+ log_success "Obfuscation detection completed"
348
+ else
349
+ log_error "Obfuscation detection failed (check $ERROR_LOG for details)"
350
+ return 1
351
+ fi
352
+
353
+ if [ -f "${TEMP_DIR}/obfuscation_report.json" ]; then
354
+ local obf_type=$(python3 -c "import json; print(json.load(open('${TEMP_DIR}/obfuscation_report.json'))['type'])" 2>/dev/null || echo "unknown")
355
+ log_info "Obfuscation type detected: $obf_type"
356
+
357
+ # Check if DEX payload hunter found encrypted payloads
358
+ local stub_detected=$(python3 -c "import json; print(json.load(open('${TEMP_DIR}/dex_payload_report.json')).get('stub_dex_detected', False))" 2>/dev/null || echo "False")
359
+ local payload_count=$(python3 -c "import json; print(len(json.load(open('${TEMP_DIR}/dex_payload_report.json')).get('encrypted_payloads', [])))" 2>/dev/null || echo "0")
360
+
361
+ if [ "$stub_detected" = "True" ] || [ "$payload_count" -gt 0 ]; then
362
+ log_warning "🔒 ENCRYPTED DEX DETECTED!"
363
+ log_info "Stub DEX: $stub_detected | Encrypted Payloads: $payload_count"
364
+ log_info ""
365
+ log_warning "Real DEX is NOT in the APK - it will be unpacked at runtime"
366
+ log_info ""
367
+ fi
368
+
369
+ case "$obf_type" in
370
+ "dpt-shell"|"dexprotector"|"bangcle"|"qihoo-360"|"jiagu"|"secneo")
371
+ log_warning "Advanced protection detected: $obf_type"
372
+
373
+ # Run SO String Analyzer for protection libraries
374
+ log_info ""
375
+ log_info "🔍 Analyzing protection library strings..."
376
+ analyze_protection_libraries "$obf_type"
377
+
378
+ log_info ""
379
+ log_info "📍 DYNAMIC ANALYSIS REQUIRED:"
380
+ log_info " 1. Install APK on rooted device/emulator"
381
+ log_info " 2. Run app to trigger DEX unpacking"
382
+ log_info " 3. Monitor these locations for unpacked DEX:"
383
+
384
+ # Show top 3 likely unpack locations
385
+ python3 -c "
386
+ import json
387
+ data = json.load(open('${TEMP_DIR}/dex_payload_report.json'))
388
+ for loc in data.get('likely_unpack_locations', [])[:3]:
389
+ if loc['priority'] == 'HIGH':
390
+ print(f\" • {loc['path']}\")
391
+ " 2>/dev/null
392
+
393
+ log_info " 4. Use Frida to dump DEX from memory:"
394
+ log_info " frida -U -l scripts/frida/frida_dex_dump.js -f <package>"
395
+ log_info " 5. Pull dumped DEX files for re-analysis"
396
+ log_info ""
397
+ echo "$obf_type" > "${TEMP_DIR}/protection_type.txt"
398
+ ;;
399
+ "proguard"|"r8")
400
+ log_info "Standard obfuscation detected: $obf_type"
401
+ log_info "Proceeding with static analysis..."
402
+ ;;
403
+ *)
404
+ log_info "No significant obfuscation detected or unknown type"
405
+ ;;
406
+ esac
407
+ fi
408
+ }
409
+
410
+ # Run entropy analysis
411
+ run_entropy_analysis() {
412
+ log_section "Running Entropy Analysis"
413
+
414
+ local apk_path="$1"
415
+
416
+ log_info "Analyzing file entropy to detect encrypted/obfuscated regions..."
417
+
418
+ if python3 "${TOOLS_DIR}/entropy_analyzer.py" \
419
+ "$apk_path" \
420
+ "${TEMP_DIR}/entropy_analysis.json" \
421
+ --chunk-size 2048 2>> "$ERROR_LOG"; then
422
+
423
+ log_success "Entropy analysis completed"
424
+
425
+ # Check for highly suspicious files
426
+ if [ -f "${TEMP_DIR}/entropy_analysis.json" ]; then
427
+ local critical_count=$(python3 -c "import json; d=json.load(open('${TEMP_DIR}/entropy_analysis.json')); print(len(d.get('summary', {}).get('highly_suspicious', [])))" 2>/dev/null || echo "0")
428
+ local suspicious_count=$(python3 -c "import json; d=json.load(open('${TEMP_DIR}/entropy_analysis.json')); print(len(d.get('summary', {}).get('suspicious', [])))" 2>/dev/null || echo "0")
429
+
430
+ if [ "$critical_count" -gt 0 ]; then
431
+ log_warning "🔴 ${critical_count} highly encrypted file(s) detected!"
432
+ log_info "High entropy indicates encrypted payloads - check entropy charts in report"
433
+ fi
434
+
435
+ if [ "$suspicious_count" -gt 0 ]; then
436
+ log_info "🟡 ${suspicious_count} suspicious file(s) with elevated entropy"
437
+ fi
438
+ fi
439
+ else
440
+ log_warning "Entropy analysis encountered issues (check error log)"
441
+ fi
442
+ }
443
+
444
+ # Run YARA rules
445
+ run_yara_scan() {
446
+ log_section "Running YARA Rules"
447
+
448
+ local apk_path="$1"
449
+
450
+ # Scan original APK
451
+ if [ -f "${SCRIPT_DIR}/rules/yara_general_rules.yar" ]; then
452
+ log_info "Scanning with yara_general_rules.yar..."
453
+ yara -s "${SCRIPT_DIR}/rules/yara_general_rules.yar" "$apk_path" > "${TEMP_DIR}/yara_apk_results.txt" 2>&1 || true
454
+ fi
455
+
456
+ # Scan decompiled directory
457
+ if [ -d "$DECOMPILED_DIR" ]; then
458
+ log_info "Scanning decompiled files..."
459
+ find "$DECOMPILED_DIR" -type f -name "*.smali" -o -name "*.xml" | while read file; do
460
+ yara -s "${SCRIPT_DIR}/rules/yara_general_rules.yar" "$file" 2>/dev/null || true
461
+ done > "${TEMP_DIR}/yara_decompiled_results.txt"
462
+ fi
463
+
464
+ # Scan JADX output
465
+ if [ -d "$JADX_OUTPUT" ]; then
466
+ log_info "Scanning JADX sources..."
467
+ find "$JADX_OUTPUT" -type f -name "*.java" | while read file; do
468
+ yara -s "${SCRIPT_DIR}/rules/yara_general_rules.yar" "$file" 2>/dev/null || true
469
+ done > "${TEMP_DIR}/yara_jadx_results.txt"
470
+ fi
471
+
472
+ log_success "YARA scan completed"
473
+
474
+ # Process YARA results with enhanced analyzer
475
+ log_info "Processing YARA results..."
476
+ if python3 "${TOOLS_DIR}/yara_enhanced_analyzer.py" \
477
+ "$TEMP_DIR" \
478
+ "${TEMP_DIR}/yara_enhanced.json" 2>> "$ERROR_LOG"; then
479
+
480
+ # Show summary
481
+ if [ -f "${TEMP_DIR}/yara_enhanced.json" ]; then
482
+ local total_rules=$(python3 -c "import json; print(json.load(open('${TEMP_DIR}/yara_enhanced.json'))['summary']['total_rules_checked'])" 2>/dev/null || echo "0")
483
+ local matched_rules=$(python3 -c "import json; print(json.load(open('${TEMP_DIR}/yara_enhanced.json'))['summary']['rules_matched'])" 2>/dev/null || echo "0")
484
+ local critical=$(python3 -c "import json; print(json.load(open('${TEMP_DIR}/yara_enhanced.json'))['summary']['critical_findings'])" 2>/dev/null || echo "0")
485
+ local high=$(python3 -c "import json; print(json.load(open('${TEMP_DIR}/yara_enhanced.json'))['summary']['high_severity'])" 2>/dev/null || echo "0")
486
+
487
+ log_success "YARA analysis complete"
488
+ log_info "Rules: ${matched_rules}/${total_rules} matched | 🔴 ${critical} Critical | 🟠 ${high} High"
489
+ fi
490
+ else
491
+ log_warning "YARA result processing had issues"
492
+ fi
493
+ }
494
+
495
+ # Static Application Security Testing (SAST)
496
+ run_sast_analysis() {
497
+ log_section "Running SAST Analysis"
498
+
499
+ # Run comprehensive SAST
500
+ if python3 "${TOOLS_DIR}/sast_scanner.py" \
501
+ --apk "$APK_TO_ANALYZE" \
502
+ --decompiled "$DECOMPILED_DIR" \
503
+ --jadx "$JADX_OUTPUT" \
504
+ --output "${TEMP_DIR}/sast_findings.json" 2>> "$ERROR_LOG"; then
505
+
506
+ # Show summary with accurate counts
507
+ if [ -f "${TEMP_DIR}/sast_findings.json" ]; then
508
+ local critical=$(python3 -c "import json; d=json.load(open('${TEMP_DIR}/sast_findings.json')); print(len(d.get('critical', [])))" 2>/dev/null || echo "0")
509
+ local high=$(python3 -c "import json; d=json.load(open('${TEMP_DIR}/sast_findings.json')); print(len(d.get('high', [])))" 2>/dev/null || echo "0")
510
+ local medium=$(python3 -c "import json; d=json.load(open('${TEMP_DIR}/sast_findings.json')); print(len(d.get('medium', [])))" 2>/dev/null || echo "0")
511
+ local total=$((critical + high + medium))
512
+
513
+ log_success "SAST analysis completed"
514
+ log_info "Findings: 🔴 ${critical} Critical | 🟠 ${high} High | 🟡 ${medium} Medium | Total: ${total}"
515
+ else
516
+ log_success "SAST analysis completed"
517
+ fi
518
+ else
519
+ log_warning "SAST analysis had issues (check error log)"
520
+ fi
521
+ }
522
+
523
+ # Analyze AndroidManifest
524
+ analyze_manifest() {
525
+ log_section "Analyzing AndroidManifest.xml"
526
+
527
+ if [ -f "${DECOMPILED_DIR}/AndroidManifest.xml" ]; then
528
+ if python3 "${TOOLS_DIR}/manifest_analyzer.py" \
529
+ "${DECOMPILED_DIR}/AndroidManifest.xml" \
530
+ "${TEMP_DIR}/manifest_findings.json" 2>> "$ERROR_LOG"; then
531
+
532
+ # Show summary with accurate counts
533
+ if [ -f "${TEMP_DIR}/manifest_findings.json" ]; then
534
+ local findings=$(python3 -c "import json; d=json.load(open('${TEMP_DIR}/manifest_findings.json')); print(len(d.get('findings', [])))" 2>/dev/null || echo "0")
535
+ log_success "Manifest analysis completed"
536
+ log_info "Findings: ${findings} issue(s) detected"
537
+ else
538
+ log_success "Manifest analysis completed"
539
+ fi
540
+ else
541
+ log_warning "Manifest analysis had issues (check error log)"
542
+ fi
543
+ else
544
+ log_warning "AndroidManifest.xml not found"
545
+ fi
546
+ }
547
+
548
+ # Network artifacts analysis
549
+ analyze_network_artifacts() {
550
+ log_section "Analyzing Network Artifacts"
551
+
552
+ if python3 "${TOOLS_DIR}/network_analyzer.py" \
553
+ --decompiled "$DECOMPILED_DIR" \
554
+ --jadx "$JADX_OUTPUT" \
555
+ --output "${TEMP_DIR}/network_findings.json" 2>> "$ERROR_LOG"; then
556
+
557
+ # Show summary with accurate counts
558
+ if [ -f "${TEMP_DIR}/network_findings.json" ]; then
559
+ local urls=$(python3 -c "import json; d=json.load(open('${TEMP_DIR}/network_findings.json')); print(len(d.get('urls', [])))" 2>/dev/null || echo "0")
560
+ local suspicious=$(python3 -c "import json; d=json.load(open('${TEMP_DIR}/network_findings.json')); print(len(d.get('suspicious_urls', [])))" 2>/dev/null || echo "0")
561
+ log_success "Network analysis completed"
562
+ log_info "Found: ${urls} URL(s) | 🚨 ${suspicious} Suspicious"
563
+ else
564
+ log_success "Network analysis completed"
565
+ fi
566
+ else
567
+ log_warning "Network analysis had issues (check error log)"
568
+ fi
569
+ }
570
+
571
+ # Generate comprehensive report
572
+ generate_report() {
573
+ log_section "Generating Analysis Report"
574
+
575
+ # Use modular report generator for separate pages
576
+ if python3 "${TOOLS_DIR}/report_generator_modular.py" \
577
+ "$APK_WORK_DIR" \
578
+ "$TEMP_DIR" \
579
+ "$(basename "$APK_PATH")" \
580
+ "$SHA256" \
581
+ --output-md "report.md" \
582
+ --output-json "report.json" 2>> "$ERROR_LOG"; then
583
+
584
+ # Update report file paths
585
+ REPORT_FILE="$REPORTS_DIR/report.md"
586
+ JSON_REPORT="$REPORTS_DIR/report.json"
587
+
588
+ # Copy cumulative error log to reports folder
589
+ if [ -f "$ERROR_LOG" ] && [ -s "$ERROR_LOG" ]; then
590
+ cp "$ERROR_LOG" "$REPORTS_DIR/analysis_errors.log"
591
+ log_info "Error log copied to reports folder"
592
+ fi
593
+
594
+ log_success "Main report: $REPORT_FILE"
595
+ log_success "Detailed reports in: $REPORTS_DIR/"
596
+ log_success " - entropy_analysis.md (🆕 Encrypted Payload Detection)"
597
+ log_success " - sast_findings.md"
598
+ log_success " - manifest_analysis.md"
599
+ log_success " - network_analysis.md"
600
+ log_success " - yara_results.md (🆕 Enhanced with Categorization)"
601
+ log_success " - recommendations.md"
602
+ else
603
+ log_error "Report generation failed (check $ERROR_LOG for details)"
604
+ fi
605
+ }
606
+
607
+ # Main analysis workflow
608
+ main() {
609
+ print_banner
610
+
611
+ if [ $# -lt 1 ]; then
612
+ echo "Usage: $0 <path_to_apk>"
613
+ echo ""
614
+ echo "Options:"
615
+ echo " -h, --help Show this help message"
616
+ echo ""
617
+ exit 1
618
+ fi
619
+
620
+ APK_PATH="$1"
621
+
622
+ if [ ! -f "$APK_PATH" ]; then
623
+ log_error "APK file not found: $APK_PATH"
624
+ exit 1
625
+ fi
626
+
627
+ # Check dependencies
628
+ check_dependencies
629
+
630
+ # Initialize workspace
631
+ init_workspace "$APK_PATH"
632
+
633
+ # Extract basic info
634
+ extract_basic_info "$APK_PATH"
635
+
636
+ # Check and bypass protections
637
+ if check_apk_protection "$APK_PATH"; then
638
+ # Decompile
639
+ decompile_apktool "$APK_TO_ANALYZE" || log_warning "APKTool failed, continuing..."
640
+ decompile_jadx "$APK_TO_ANALYZE" || log_warning "JADX failed, continuing..."
641
+
642
+ # Detect obfuscation
643
+ detect_obfuscation
644
+
645
+ # Run entropy analysis (especially useful for protected APKs)
646
+ run_entropy_analysis "$APK_TO_ANALYZE"
647
+
648
+ # Security analysis
649
+ run_yara_scan "$APK_TO_ANALYZE"
650
+ analyze_manifest
651
+ analyze_network_artifacts
652
+ run_sast_analysis
653
+
654
+ # Generate report
655
+ generate_report
656
+
657
+ log_section "Analysis Complete"
658
+ log_success "All results saved to: $APK_WORK_DIR"
659
+ log_info "Open report: cat $REPORT_FILE"
660
+
661
+ else
662
+ log_critical "Unable to analyze APK due to protection mechanisms"
663
+ log_info "Manual intervention required"
664
+ exit 1
665
+ fi
666
+ }
667
+
668
+ # Run main
669
+ main "$@"