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
@@ -0,0 +1,206 @@
1
+ #!/bin/bash
2
+
3
+ ###############################################
4
+ # Quick Setup Script
5
+ # Sets up the analysis framework and validates
6
+ ###############################################
7
+
8
+ set -e
9
+
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ RED='\033[0;31m'
13
+ BLUE='\033[0;34m'
14
+ NC='\033[0m'
15
+
16
+ echo -e "${BLUE}"
17
+ echo "╔════════════════════════════════════════════╗"
18
+ echo "ā•‘ Anais Static Core Setup ā•‘"
19
+ echo "ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•"
20
+ echo -e "${NC}"
21
+
22
+ # Check if on macOS or Linux
23
+ if [[ "$OSTYPE" == "darwin"* ]]; then
24
+ OS="macos"
25
+ echo -e "${GREEN}[+] Detected macOS${NC}"
26
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
27
+ OS="linux"
28
+ echo -e "${GREEN}[+] Detected Linux${NC}"
29
+ else
30
+ echo -e "${RED}[!] Unsupported OS${NC}"
31
+ exit 1
32
+ fi
33
+
34
+ # Function to check if command exists
35
+ command_exists() {
36
+ command -v "$1" >/dev/null 2>&1
37
+ }
38
+
39
+ # Check Python3
40
+ echo -e "\n${YELLOW}[*] Checking Python3...${NC}"
41
+ if command_exists python3; then
42
+ PYTHON_VERSION=$(python3 --version | awk '{print $2}')
43
+ echo -e "${GREEN}[+] Python3 found: $PYTHON_VERSION${NC}"
44
+ else
45
+ echo -e "${RED}[!] Python3 not found${NC}"
46
+ echo "Install with:"
47
+ if [ "$OS" = "macos" ]; then
48
+ echo " brew install python3"
49
+ else
50
+ echo " sudo apt-get install python3 python3-pip"
51
+ fi
52
+ exit 1
53
+ fi
54
+
55
+ # Check Java
56
+ echo -e "\n${YELLOW}[*] Checking Java...${NC}"
57
+ if command_exists java; then
58
+ JAVA_VERSION=$(java -version 2>&1 | head -n 1)
59
+ echo -e "${GREEN}[+] Java found: $JAVA_VERSION${NC}"
60
+ else
61
+ echo -e "${RED}[!] Java not found${NC}"
62
+ echo "Install with:"
63
+ if [ "$OS" = "macos" ]; then
64
+ echo " brew install openjdk"
65
+ else
66
+ echo " sudo apt-get install default-jdk"
67
+ fi
68
+ exit 1
69
+ fi
70
+
71
+ # Check APKTool
72
+ echo -e "\n${YELLOW}[*] Checking APKTool...${NC}"
73
+ if command_exists apktool; then
74
+ APKTOOL_VERSION=$(apktool --version 2>&1 | head -n 1)
75
+ echo -e "${GREEN}[+] APKTool found: $APKTOOL_VERSION${NC}"
76
+ else
77
+ echo -e "${YELLOW}[!] APKTool not found${NC}"
78
+ echo "Install with:"
79
+ if [ "$OS" = "macos" ]; then
80
+ echo " brew install apktool"
81
+ else
82
+ echo " sudo apt-get install apktool"
83
+ fi
84
+ fi
85
+
86
+ # Check JADX
87
+ echo -e "\n${YELLOW}[*] Checking JADX...${NC}"
88
+ if command_exists jadx; then
89
+ JADX_VERSION=$(jadx --version 2>&1 | head -n 1)
90
+ echo -e "${GREEN}[+] JADX found: $JADX_VERSION${NC}"
91
+ else
92
+ echo -e "${YELLOW}[!] JADX not found${NC}"
93
+ echo "Install with:"
94
+ if [ "$OS" = "macos" ]; then
95
+ echo " brew install jadx"
96
+ else
97
+ echo " Download from: https://github.com/skylot/jadx/releases"
98
+ fi
99
+ fi
100
+
101
+ # Check YARA
102
+ echo -e "\n${YELLOW}[*] Checking YARA...${NC}"
103
+ if command_exists yara; then
104
+ YARA_VERSION=$(yara --version 2>&1)
105
+ echo -e "${GREEN}[+] YARA found: $YARA_VERSION${NC}"
106
+ else
107
+ echo -e "${YELLOW}[!] YARA not found${NC}"
108
+ echo "Install with:"
109
+ if [ "$OS" = "macos" ]; then
110
+ echo " brew install yara"
111
+ else
112
+ echo " sudo apt-get install yara"
113
+ fi
114
+ fi
115
+
116
+ # Install Python packages
117
+ echo -e "\n${YELLOW}[*] Checking Python packages...${NC}"
118
+
119
+ REQUIRED_PACKAGES=("androguard" "yara-python" "requests" "cryptography")
120
+ MISSING_PACKAGES=()
121
+
122
+ for package in "${REQUIRED_PACKAGES[@]}"; do
123
+ if python3 -c "import ${package//-/_}" 2>/dev/null; then
124
+ echo -e "${GREEN}[+] $package installed${NC}"
125
+ else
126
+ echo -e "${YELLOW}[!] $package not installed${NC}"
127
+ MISSING_PACKAGES+=("$package")
128
+ fi
129
+ done
130
+
131
+ if [ ${#MISSING_PACKAGES[@]} -ne 0 ]; then
132
+ echo -e "\n${YELLOW}[*] Installing missing Python packages...${NC}"
133
+ pip3 install "${MISSING_PACKAGES[@]}"
134
+ fi
135
+
136
+ # Make scripts executable
137
+ echo -e "\n${YELLOW}[*] Setting execute permissions...${NC}"
138
+ chmod +x malware_analyzer.sh
139
+ chmod +x scripts/dynamic_analysis_helper.sh
140
+
141
+ if [ -d "analysis_tools" ]; then
142
+ chmod +x analysis_tools/*.py
143
+ fi
144
+
145
+ echo -e "${GREEN}[+] Scripts are now executable${NC}"
146
+
147
+ # Create necessary directories
148
+ echo -e "\n${YELLOW}[*] Creating directories...${NC}"
149
+ mkdir -p "${HOME}/Documents/Anais-Reports"
150
+ mkdir -p "${HOME}/Documents/Anais-Reports/reports"
151
+ echo -e "${GREEN}[+] Directories created in ${HOME}/Documents/Anais-Reports${NC}"
152
+
153
+ # Validate YARA rules
154
+ echo -e "\n${YELLOW}[*] Validating YARA rules...${NC}"
155
+ if [ -f "rules/yara_general_rules.yar" ]; then
156
+ if yara -w rules/yara_general_rules.yar rules/yara_general_rules.yar >/dev/null 2>&1; then
157
+ echo -e "${GREEN}[+] yara_general_rules.yar is valid${NC}"
158
+ else
159
+ echo -e "${YELLOW}[!] yara_general_rules.yar has warnings${NC}"
160
+ fi
161
+ fi
162
+
163
+ # Summary
164
+ echo -e "\n${BLUE}═══════════════════════════════════════${NC}"
165
+ echo -e "${BLUE} Setup Summary${NC}"
166
+ echo -e "${BLUE}═══════════════════════════════════════${NC}"
167
+
168
+ echo -e "\n${GREEN}āœ“ Setup Complete!${NC}\n"
169
+
170
+ echo "Quick Start:"
171
+ echo " 1. Analyze an APK:"
172
+ echo " ./malware_analyzer.sh /path/to/app.apk"
173
+ echo ""
174
+ echo " 2. Dynamic analysis (with device connected):"
175
+ echo " ./scripts/dynamic_analysis_helper.sh dex-dump com.package.name"
176
+ echo ""
177
+ echo " 3. View documentation:"
178
+ echo " cat ANALYZER_README.md"
179
+ echo ""
180
+
181
+ # Check if ADB is available for dynamic analysis
182
+ if command_exists adb; then
183
+ echo -e "${GREEN}[+] ADB found - Dynamic analysis available${NC}"
184
+ echo ""
185
+ else
186
+ echo -e "${YELLOW}[!] ADB not found - Dynamic analysis will not be available${NC}"
187
+ echo "Install with:"
188
+ if [ "$OS" = "macos" ]; then
189
+ echo " brew install android-platform-tools"
190
+ else
191
+ echo " sudo apt-get install android-tools-adb"
192
+ fi
193
+ echo ""
194
+ fi
195
+
196
+ # Check for Frida
197
+ if command_exists frida; then
198
+ echo -e "${GREEN}[+] Frida found - Advanced hooking available${NC}"
199
+ else
200
+ echo -e "${YELLOW}[!] Frida not found - Install for advanced dynamic analysis${NC}"
201
+ echo "Install with: pip3 install frida-tools"
202
+ fi
203
+
204
+ echo ""
205
+ echo -e "${BLUE}═══════════════════════════════════════${NC}"
206
+ echo ""
@@ -0,0 +1,224 @@
1
+ #!/bin/bash
2
+ # Test script untuk validasi framework
3
+ # Run this untuk test framework dengan dummy APK
4
+
5
+ set -e
6
+
7
+ echo "═══════════════════════════════════════════════════════════"
8
+ echo " Anais Static Core - Validation Test"
9
+ echo "═══════════════════════════════════════════════════════════"
10
+ echo ""
11
+
12
+ # Test 1: Check all scripts exist
13
+ echo "[TEST 1] Checking script files..."
14
+ files=(
15
+ "anais.sh"
16
+ "scripts/dynamic_analysis_helper.sh"
17
+ "scripts/setup.sh"
18
+ "analysis_tools/check_zip_encryption.py"
19
+ "analysis_tools/fix_apk_headers.py"
20
+ "analysis_tools/detect_obfuscation.py"
21
+ "analysis_tools/sast_scanner.py"
22
+ "analysis_tools/apk_basic_info.py"
23
+ "analysis_tools/manifest_analyzer.py"
24
+ "analysis_tools/network_analyzer.py"
25
+ "analysis_tools/report_generator.py"
26
+ )
27
+
28
+ missing=0
29
+ for file in "${files[@]}"; do
30
+ if [ -f "$file" ]; then
31
+ echo " āœ“ $file"
32
+ else
33
+ echo " āœ— $file (MISSING)"
34
+ missing=$((missing + 1))
35
+ fi
36
+ done
37
+
38
+ if [ $missing -eq 0 ]; then
39
+ echo "āœ“ All script files present"
40
+ else
41
+ echo "āœ— $missing files missing"
42
+ exit 1
43
+ fi
44
+ echo ""
45
+
46
+ # Test 2: Check permissions
47
+ echo "[TEST 2] Checking execute permissions..."
48
+ if [ -x "anais.sh" ] && [ -x "scripts/dynamic_analysis_helper.sh" ] && [ -x "scripts/setup.sh" ]; then
49
+ echo "āœ“ Main scripts are executable"
50
+ else
51
+ echo "āœ— Scripts not executable. Run: chmod +x *.sh"
52
+ exit 1
53
+ fi
54
+ echo ""
55
+
56
+ # Test 3: Check Python scripts
57
+ echo "[TEST 3] Checking Python scripts syntax..."
58
+ python_errors=0
59
+ for script in analysis_tools/*.py; do
60
+ if python3 -m py_compile "$script" 2>/dev/null; then
61
+ echo " āœ“ $(basename $script)"
62
+ else
63
+ echo " āœ— $(basename $script) (SYNTAX ERROR)"
64
+ python_errors=$((python_errors + 1))
65
+ fi
66
+ done
67
+
68
+ if [ $python_errors -eq 0 ]; then
69
+ echo "āœ“ All Python scripts valid"
70
+ else
71
+ echo "āœ— $python_errors Python scripts have syntax errors"
72
+ exit 1
73
+ fi
74
+ echo ""
75
+
76
+ # Test 4: Check YARA rules
77
+ echo "[TEST 4] Validating YARA rules..."
78
+ if command -v yara >/dev/null 2>&1; then
79
+ if [ -f "rules/yara_general_rules.yar" ]; then
80
+ if yara -w rules/yara_general_rules.yar rules/yara_general_rules.yar >/dev/null 2>&1; then
81
+ echo " āœ“ rules/yara_general_rules.yar"
82
+ else
83
+ echo " ⚠ rules/yara_general_rules.yar (has warnings)"
84
+ fi
85
+ fi
86
+ echo "āœ“ YARA rules validated"
87
+ else
88
+ echo "⚠ YARA not installed, skipping rule validation"
89
+ fi
90
+ echo ""
91
+
92
+ # Test 5: Check documentation
93
+ echo "[TEST 5] Checking documentation files..."
94
+ docs=(
95
+ "README.md"
96
+ "docs/ARCHITECTURE.txt"
97
+ "docs/Workflow and Reference.md"
98
+ "analyzer_config.json"
99
+ )
100
+
101
+ for doc in "${docs[@]}"; do
102
+ if [ -f "$doc" ]; then
103
+ echo " āœ“ $doc"
104
+ else
105
+ echo " āœ— $doc (MISSING)"
106
+ fi
107
+ done
108
+ echo ""
109
+
110
+ # Test 6: Check directories
111
+ echo "[TEST 6] Checking directory structure..."
112
+ if [ -d "analysis_tools" ]; then
113
+ echo " āœ“ analysis_tools/"
114
+ else
115
+ echo " āœ— analysis_tools/ (MISSING)"
116
+ fi
117
+
118
+ if [ -d "scripts" ]; then
119
+ echo " āœ“ scripts/"
120
+ else
121
+ echo " āœ— scripts/ (MISSING)"
122
+ fi
123
+
124
+ if [ -d "rules" ]; then
125
+ echo " āœ“ rules/"
126
+ else
127
+ echo " āœ— rules/ (MISSING)"
128
+ fi
129
+
130
+ if [ -d "docs" ]; then
131
+ echo " āœ“ docs/"
132
+ else
133
+ echo " āœ— docs/ (MISSING)"
134
+ fi
135
+
136
+ if [ -d "${HOME}/Documents/Anais-Reports" ]; then
137
+ echo " āœ“ ~/Documents/Anais-Reports/"
138
+ else
139
+ echo " ⚠ ~/Documents/Anais-Reports/ (will be created on first run)"
140
+ fi
141
+ echo ""
142
+
143
+ # Test 7: Check dependencies
144
+ echo "[TEST 7] Checking dependencies..."
145
+
146
+ check_cmd() {
147
+ if command -v "$1" >/dev/null 2>&1; then
148
+ echo " āœ“ $1"
149
+ return 0
150
+ else
151
+ echo " āœ— $1 (NOT INSTALLED)"
152
+ return 1
153
+ fi
154
+ }
155
+
156
+ deps_missing=0
157
+ check_cmd python3 || deps_missing=$((deps_missing + 1))
158
+ check_cmd java || deps_missing=$((deps_missing + 1))
159
+ check_cmd apktool || deps_missing=$((deps_missing + 1))
160
+ check_cmd jadx || deps_missing=$((deps_missing + 1))
161
+ check_cmd yara || deps_missing=$((deps_missing + 1))
162
+
163
+ if [ $deps_missing -eq 0 ]; then
164
+ echo "āœ“ All dependencies installed"
165
+ else
166
+ echo "⚠ $deps_missing dependencies missing (run setup.sh for details)"
167
+ fi
168
+ echo ""
169
+
170
+ # Test 8: Check Python packages
171
+ echo "[TEST 8] Checking Python packages..."
172
+
173
+ check_pkg() {
174
+ if python3 -c "import ${1//-/_}" 2>/dev/null; then
175
+ echo " āœ“ $1"
176
+ return 0
177
+ else
178
+ echo " āœ— $1 (NOT INSTALLED)"
179
+ return 1
180
+ fi
181
+ }
182
+
183
+ pkgs_missing=0
184
+ check_pkg androguard || pkgs_missing=$((pkgs_missing + 1))
185
+ check_pkg yara-python || pkgs_missing=$((pkgs_missing + 1))
186
+ check_pkg requests || pkgs_missing=$((pkgs_missing + 1))
187
+ check_pkg cryptography || pkgs_missing=$((pkgs_missing + 1))
188
+
189
+ if [ $pkgs_missing -eq 0 ]; then
190
+ echo "āœ“ All Python packages installed"
191
+ else
192
+ echo "⚠ $pkgs_missing Python packages missing"
193
+ echo " Install with: pip3 install androguard yara-python requests cryptography"
194
+ fi
195
+ echo ""
196
+
197
+ # Summary
198
+ echo "═══════════════════════════════════════════════════════════"
199
+ echo " TEST SUMMARY"
200
+ echo "═══════════════════════════════════════════════════════════"
201
+ echo ""
202
+
203
+ if [ $missing -eq 0 ] && [ $python_errors -eq 0 ]; then
204
+ echo "āœ… FRAMEWORK VALIDATION PASSED"
205
+ echo ""
206
+ echo "Framework is ready to use!"
207
+ echo ""
208
+ echo "Quick Start:"
209
+ echo " 1. Run setup (if not done): ./scripts/setup.sh"
210
+ echo " 2. Analyze an APK: ./anais.sh app.apk"
211
+ echo ""
212
+
213
+ if [ $deps_missing -gt 0 ] || [ $pkgs_missing -gt 0 ]; then
214
+ echo "āš ļø Some dependencies are missing. The framework will work with"
215
+ echo " limited functionality. Run ./scripts/setup.sh for details."
216
+ fi
217
+ else
218
+ echo "āŒ FRAMEWORK VALIDATION FAILED"
219
+ echo ""
220
+ echo "Please fix the errors above before using the framework."
221
+ exit 1
222
+ fi
223
+
224
+ echo "═══════════════════════════════════════════════════════════"
package/src/cli.ts ADDED
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { executeForensicAnalysis } from "./index";
4
+ import {
5
+ formatError,
6
+ formatSuccess,
7
+ printBanner,
8
+ printSeparator,
9
+ } from "./utils";
10
+
11
+ const main = async () => {
12
+ const args = process.argv.slice(2);
13
+
14
+ if (args.length === 0) {
15
+ printBanner();
16
+ console.log("Usage:");
17
+ console.log(" anais <apk-file-path> Analyze an APK file");
18
+ console.log(" anais --version Show version");
19
+ console.log(" anais --help Show this help message");
20
+ process.exit(0);
21
+ }
22
+
23
+ if (args[0] === "--version" || args[0] === "-v") {
24
+ console.log("Anais APK Forensic CLI v1.0.0");
25
+ process.exit(0);
26
+ }
27
+
28
+ if (args[0] === "--help" || args[0] === "-h") {
29
+ printBanner();
30
+ console.log("Usage:");
31
+ console.log(" anais <apk-file-path> Analyze an APK file");
32
+ console.log(" anais --version Show version");
33
+ console.log(" anais --help Show this help message");
34
+ console.log("\nDescription:");
35
+ console.log(" Comprehensive APK security analysis and SAST scanner");
36
+ console.log(" - Decompilation with APKTool and JADX");
37
+ console.log(" - YARA malware detection");
38
+ console.log(" - Obfuscation detection");
39
+ console.log(" - Network traffic analysis");
40
+ console.log(" - AndroidManifest analysis");
41
+ console.log(" - Entropy analysis for encrypted payloads");
42
+ process.exit(0);
43
+ }
44
+
45
+ const apkPath = args[0];
46
+
47
+ try {
48
+ console.log(`šŸ” Anais APK Forensic Analysis\n`);
49
+ printSeparator();
50
+ console.log();
51
+
52
+ const result = await executeForensicAnalysis(apkPath);
53
+
54
+ console.log();
55
+ printSeparator();
56
+
57
+ if (result.success) {
58
+ console.log(`\n${formatSuccess("Analysis completed successfully!")}\n`);
59
+
60
+ if (result.workspaceDir) {
61
+ console.log(`šŸ“ Workspace: ${result.workspaceDir}`);
62
+ }
63
+
64
+ if (result.reportPath) {
65
+ console.log(`šŸ“„ Report: ${result.reportPath}`);
66
+ }
67
+
68
+ if (result.jsonReportPath) {
69
+ console.log(`šŸ“Š JSON Report: ${result.jsonReportPath}`);
70
+ }
71
+
72
+ console.log(
73
+ "\nšŸ’” Tip: Open the report with your preferred markdown viewer",
74
+ );
75
+ console.log(` e.g., cat "${result.reportPath}"\n`);
76
+ } else {
77
+ console.log(`\n${formatError("Analysis failed!")}\n`);
78
+ console.log(`Error: ${result.message}`);
79
+ if (result.error) {
80
+ console.log(`Details: ${result.error}`);
81
+ }
82
+ process.exit(1);
83
+ }
84
+ } catch (error) {
85
+ console.error(`\n${formatError("Unexpected error during analysis:")}`);
86
+ console.error(error);
87
+ process.exit(1);
88
+ }
89
+ };
90
+
91
+ main();
package/src/index.ts ADDED
@@ -0,0 +1,123 @@
1
+ import { spawn } from "child_process";
2
+ import { AnalysisResult } from "./types";
3
+ import {
4
+ fileExists,
5
+ getAnaisScriptPath,
6
+ getBasename,
7
+ getProjectRoot,
8
+ resolveAbsolutePath,
9
+ } from "./utils";
10
+
11
+ export * from "./types";
12
+
13
+ export const executeForensicAnalysis = async (
14
+ apkPath: string,
15
+ ): Promise<AnalysisResult> => {
16
+ return new Promise((resolve, reject) => {
17
+ // Resolve absolute path
18
+ const absoluteApkPath = resolveAbsolutePath(apkPath);
19
+
20
+ // Check if APK file exists
21
+ if (!fileExists(absoluteApkPath)) {
22
+ return resolve({
23
+ success: false,
24
+ apkPath,
25
+ message: `APK file not found: ${apkPath}`,
26
+ error: "File not found",
27
+ });
28
+ }
29
+
30
+ console.log(`\nšŸ“± APK: ${getBasename(absoluteApkPath)}`);
31
+ console.log(`šŸ“‚ Path: ${absoluteApkPath}\n`);
32
+
33
+ // Get paths
34
+ const scriptDir = getProjectRoot();
35
+ const anaisScript = getAnaisScriptPath();
36
+
37
+ if (!fileExists(anaisScript)) {
38
+ return resolve({
39
+ success: false,
40
+ apkPath,
41
+ message: `Analysis script not found: ${anaisScript}`,
42
+ error: "Script not found",
43
+ });
44
+ }
45
+
46
+ console.log(`šŸš€ Executing analysis...\n`);
47
+
48
+ // Spawn the bash script
49
+ const analysis = spawn("bash", [anaisScript, absoluteApkPath], {
50
+ cwd: scriptDir,
51
+ env: {
52
+ ...process.env,
53
+ PYTHONWARNINGS: "ignore",
54
+ },
55
+ });
56
+
57
+ let stdout = "";
58
+ let stderr = "";
59
+ let workspaceDir = "";
60
+ let reportPath = "";
61
+
62
+ // Capture stdout
63
+ analysis.stdout.on("data", (data) => {
64
+ const output = data.toString();
65
+ process.stdout.write(output);
66
+ stdout += output;
67
+
68
+ // Extract workspace directory from output
69
+ const workspaceMatch = output.match(/Workspace initialized: (.+)/);
70
+ if (workspaceMatch) {
71
+ workspaceDir = workspaceMatch[1].trim();
72
+ }
73
+
74
+ // Extract report path
75
+ const reportMatch = output.match(/Main report: (.+\.md)/);
76
+ if (reportMatch) {
77
+ reportPath = reportMatch[1].trim();
78
+ }
79
+ });
80
+
81
+ // Capture stderr (though we're logging warnings there)
82
+ analysis.stderr.on("data", (data) => {
83
+ stderr += data.toString();
84
+ // Don't print stderr to console as it's handled by the script
85
+ });
86
+
87
+ // Handle process completion
88
+ analysis.on("close", (code) => {
89
+ if (code === 0) {
90
+ const jsonReportPath = reportPath.replace(/\.md$/, ".json");
91
+
92
+ resolve({
93
+ success: true,
94
+ apkPath: absoluteApkPath,
95
+ workspaceDir,
96
+ reportPath,
97
+ jsonReportPath: fileExists(jsonReportPath)
98
+ ? jsonReportPath
99
+ : undefined,
100
+ message: "Analysis completed successfully",
101
+ });
102
+ } else {
103
+ resolve({
104
+ success: false,
105
+ apkPath: absoluteApkPath,
106
+ workspaceDir,
107
+ message: `Analysis failed with exit code ${code}`,
108
+ error: stderr || "Unknown error",
109
+ });
110
+ }
111
+ });
112
+
113
+ // Handle errors
114
+ analysis.on("error", (error) => {
115
+ reject({
116
+ success: false,
117
+ apkPath: absoluteApkPath,
118
+ message: "Failed to execute analysis script",
119
+ error: error.message,
120
+ });
121
+ });
122
+ });
123
+ };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Analysis result from the forensic analysis
3
+ */
4
+ export interface AnalysisResult {
5
+ success: boolean;
6
+ apkPath: string;
7
+ workspaceDir?: string;
8
+ reportPath?: string;
9
+ jsonReportPath?: string;
10
+ message: string;
11
+ error?: string;
12
+ }
13
+
14
+ /**
15
+ * CLI command options
16
+ */
17
+ export interface CLIOptions {
18
+ help?: boolean;
19
+ version?: boolean;
20
+ verbose?: boolean;
21
+ output?: string;
22
+ }
23
+
24
+ /**
25
+ * Original types (kept for compatibility)
26
+ */
27
+ export interface CommandLineOptions {
28
+ inputFile: string;
29
+ outputFile?: string;
30
+ verbose?: boolean;
31
+ }
32
+
33
+ export interface ApkAnalysisResult {
34
+ packageName: string;
35
+ versionCode: number;
36
+ versionName: string;
37
+ permissions: string[];
38
+ activities: string[];
39
+ services: string[];
40
+ receivers: string[];
41
+ providers: string[];
42
+ }
43
+
44
+ export type AnalysisStatus = "pending" | "in-progress" | "completed" | "failed";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Utility functions export
3
+ */
4
+
5
+ export * from "./output";
6
+ export * from "./paths";