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,602 @@
1
+ /*
2
+ * Copyright (C) 2023 RedNaga. https://rednaga.io
3
+ * All rights reserved. Contact: rednaga@protonmail.com
4
+ *
5
+ *
6
+ * This file is part of APKiD
7
+ *
8
+ *
9
+ * Commercial License Usage
10
+ * ------------------------
11
+ * Licensees holding valid commercial APKiD licenses may use this file
12
+ * in accordance with the commercial license agreement provided with the
13
+ * Software or, alternatively, in accordance with the terms contained in
14
+ * a written agreement between you and RedNaga.
15
+ *
16
+ *
17
+ * GNU General Public License Usage
18
+ * --------------------------------
19
+ * Alternatively, this file may be used under the terms of the GNU General
20
+ * Public License version 3.0 as published by the Free Software Foundation
21
+ * and appearing in the file LICENSE.GPL included in the packaging of this
22
+ * file. Please visit http://www.gnu.org/copyleft/gpl.html and review the
23
+ * information to ensure the GNU General Public License version 3.0
24
+ * requirements will be met.
25
+ *
26
+ **/
27
+
28
+ import "dex"
29
+ include "common.yara"
30
+
31
+ private rule short_unicode_field_names : internal
32
+ {
33
+ meta:
34
+ description = "one or two character unicode field names"
35
+
36
+ condition:
37
+ is_dex and
38
+ for 3 i in (0..dex.header.field_ids_size) : (dex.field[i].name matches /[^\x00-\x7F]{1,4}/)
39
+ }
40
+
41
+ private rule short_unicode_method_names : internal
42
+ {
43
+ meta:
44
+ description = "one or two character unicode method names"
45
+
46
+ condition:
47
+ is_dex and
48
+ for 3 i in (0..dex.header.method_ids_size) : (dex.method[i].name matches /[^\x00-\x7F]{1,4}/)
49
+ }
50
+
51
+ rule dexguard_a : obfuscator
52
+ {
53
+ meta:
54
+ description = "DexGuard"
55
+ url = "https://www.guardsquare.com/en/products/dexguard"
56
+ sample = "74eb7cf3b81ff14add71ca884ef0cc9c7477b4193a74ca71b92f81212ff56101"
57
+
58
+ strings:
59
+ $opcodes = {
60
+ 00 06 00 01 00 03 00 00 00 00 00 00 00
61
+ [20-65]
62
+ 0c 01
63
+ 12 12
64
+ 23 22 ?? ??
65
+ 1c 03 ?? ??
66
+ 12 04
67
+ 4d 03 02 04
68
+ 6e 3? ?? ?? 10 02
69
+ 0c 00
70
+ 62 01 ?? ??
71
+ 12 12
72
+ 23 22 ?? ??
73
+ 12 03
74
+ 4d 05 02 03
75
+ 6e 3? ?? ?? 10 02
76
+ 0c 00
77
+ 1f 00 ?? ??
78
+ 11 00
79
+ }
80
+ $a = "getClass"
81
+ $b = "getDeclaredMethod"
82
+ $c = "invoke"
83
+
84
+ condition:
85
+ is_dex and
86
+ $opcodes and
87
+ all of ($a, $b, $c) and
88
+ uint32(dex.header.data_offset + dex.header.data_size - 4) == 0
89
+ }
90
+
91
+ rule dexguard_b : obfuscator
92
+ {
93
+ meta:
94
+ description = "DexGuard"
95
+ url = "https://www.guardsquare.com/en/products/dexguard"
96
+ sample = "41a9b44af8931d63812b4a23395b29279d2e055f357222dabed7153d4aee6299"
97
+
98
+ strings:
99
+ // Other obfuscators use aux and con (protected Windows file names), but not from Lo/
100
+ $a_aux_class = { 00 07 4C 6F 2F (41|61) (55|75) (58|78) 3B 00 } // Lo/[Aa][Uu][Xx];
101
+ $a_con_class = { 00 07 4C 6F 2F (43|63) (4F|6F) (4E|6E) 3B 00 } // Lo/[Cc][Oo][Nn];
102
+ $a_if_class = { 00 ?? 4C 6F 2F [1-4] 24 (49|69) (46|66) 3B 00 } // Lo/???$[iI][fF];
103
+ // A single unicode code point may take 1 or more bytes depending on encoding.
104
+ // Normally only see one code point worth, but not sure how many bytes it might be in some variants.
105
+ // Also note the trailing null byte in the regex so this is less of a naked string.
106
+ $a_inner_unicode = /Lo\/([\u0000-\u007F]{1,4}|[^\u0000-\u007F]{1,4})\$[^\u0000-\u007F]{1,4};\x00/
107
+ $b_o_three_class = { 00 07 4C 6F 2F ?? ?? ?? 3B 00 } // Lo/???;
108
+
109
+ condition:
110
+ 2 of ($a_*)
111
+ or (#a_if_class >= 3 and (short_unicode_field_names or short_unicode_method_names))
112
+ or (#b_o_three_class >= 3 and (short_unicode_field_names or short_unicode_method_names))
113
+ }
114
+
115
+ rule dexguard_c : obfuscator
116
+ {
117
+ meta:
118
+ description = "DexGuard"
119
+ url = "https://www.guardsquare.com/en/products/dexguard"
120
+ sample = "de67161a8bd7ebcaa26c9661efd811375b59260924eb0dfd9436d3a47a1c31fe"
121
+ sample2 = "db11762886cc24bd4f938002f15f78680b512cf550d15c77b217fc5548b0c939"
122
+
123
+ strings:
124
+ $dexguard_pkg1 = "guardsquare/dexguard/runtime/"
125
+ $dexguard_pkg2 = {
126
+ 001e4c64657867756172642f7574696c2f54616d7065724465746563746f723b00
127
+ } // Ldexguard/util/TamperDetector;
128
+ $dexguard_pkg3 = {
129
+ 00224c64657867756172642f7574696c2f4365727469666963617465436865636b65723b00
130
+ } // Ldexguard/util/CertificateChecker;
131
+ $dexguard_pkg4 = "com/guardsquare/dexguard/"
132
+
133
+ // Most of some kind of runtime decryption method, signature = a(IIZI[I[[I[I)V
134
+ $decrypt_method = {
135
+ 12 01 // const/4 v1, 0x0
136
+ 39 ?? ?? ?? // if-nez ??, :????
137
+ 71 ?? ?? ?? ?? ?? // invoke-static {??}, ??
138
+ 01 10 // move v0, v1
139
+ 35 ?? ?? ?? // if-ge ?, ?, :????
140
+ 44 ?? ?? ?? // aget ??, ??, ??
141
+ B7 ?? // xor-int/2addr (xor is fairly rare in legit code)
142
+ 71 ?? ?? ?? ?? ?? // invoke-static
143
+ 0A ?? // move-result ??
144
+ 97 ?? ?? ?? // xor-int ??, ??, ??
145
+ D8 00 00 01 // add-int/lit8 v0, v0, 0x1
146
+ 01 ?? // move ?, ?
147
+ 28 F2 // goto
148
+ 21 80 // array-length
149
+ D8 00 00 FE // add-int/lit8 v0, v0, -0x2
150
+ 44 ?? ?? ?? // aget ??
151
+ B7 ?? // xor-int/2addr
152
+ 21 ?? // invoke-static
153
+ D8 ?? ?? ?? // add-int
154
+ 44 ?? ?? ?? // aget
155
+ B7 ?? // xor-int/2addr
156
+ }
157
+
158
+ condition:
159
+ is_dex
160
+ and any of them
161
+ }
162
+
163
+ rule dexguard_d : obfuscator
164
+ {
165
+ meta:
166
+ description = "DexGuard"
167
+ url = "https://www.guardsquare.com/en/products/dexguard"
168
+ sample = "423b09d2aec74b1624d5b5c63d24486efc873c9cce75ea9e2f2d699f40ca8f7c"
169
+
170
+ strings:
171
+ // Ldexguard/util/TamperDetection;
172
+ $dexguard_class = {00 1F 4C 64 65 78 67 75 61 72 64 2F 75 74 69 6C 2F 54 61 6D 70 65 72 44 65 74 65 63 74 69 6F 6E 3B 00}
173
+ $a_aux_class = { 00 05 4C (41|61) (55|75) (58|78) 3B 00 } // L[Aa][Uu][Xx];
174
+ $a_con_class = { 00 05 4C (43|63) (4F|6F) (4E|6E) 3B 00 } // L[Cc][Oo][Nn];
175
+ $a_if_class = { 00 ?? 4C [1-4] 24 (49|69) (46|66) 3B 00 } // L???$[iI][fF];
176
+ $a_inner_unicode = /L([\u0000-\u007F]{1,4}|[^\u0000-\u007F]{1,4})\$[^\u0000-\u007F]{1,4};\x00/
177
+
178
+ condition:
179
+ 3 of them
180
+ or $dexguard_class
181
+ or (#a_if_class >= 3 and (short_unicode_field_names or short_unicode_method_names))
182
+ }
183
+
184
+ rule dexprotector : obfuscator
185
+ {
186
+ meta:
187
+ description = "DexProtector"
188
+
189
+ strings:
190
+ $method = {
191
+ 07 00 02 00 00 00 02 00 00 00 00 00 3E 00 00 00
192
+ 12 01 13 00 0E 00 48 00 05 00 E0 00 00 10 01 12
193
+ 39 02 2A 00 12 32 D5 63 FF 00 48 03 05 03 D5 33
194
+ FF 00 E1 04 06 08 D5 44 FF 00 48 04 05 04 D5 44
195
+ FF 00 E0 04 04 08 B6 43 E1 04 06 10 D5 44 FF 00
196
+ 48 04 05 04 D5 44 FF 00 E0 04 04 10 B6 43 E1 04
197
+ 06 18 D5 44 FF 00 48 00 05 04 E0 00 00 18 B6 30
198
+ 0F 00 0D 02 39 01 FE FF 12 21 DD 02 06 7F 48 00
199
+ 05 02 E1 00 00 08 28 F5 0D 03 28 CB 0D 00 00 00
200
+ 20 00 ?? 00 37 00 00 00 02 00 ?? 00 02 01
201
+ }
202
+ $a = "getClass"
203
+ $b = "getDeclaredMethod"
204
+ $c = "invoke"
205
+
206
+ condition:
207
+ is_dex and
208
+ $method and
209
+ all of ($a, $b, $c)
210
+ }
211
+
212
+ rule bitwise_antiskid : obfuscator
213
+ {
214
+ meta:
215
+ description = "Bitwise AntiSkid"
216
+
217
+ strings:
218
+ $credits = "AntiSkid courtesy of Bitwise\x00"
219
+ $array = "AntiSkid_Encrypted_Strings_Courtesy_of_Bitwise"
220
+ $truth1 = "Don't be a script kiddy, go actually learn something. Stealing credit is pathetic, you didn't make this or even contribute to it and you know it."
221
+ $truth2 = "Only skids can't get plaintext. Credits to Bitwise.\x00"
222
+
223
+ condition:
224
+ is_dex and
225
+ any of them
226
+ }
227
+
228
+ rule arxan : obfuscator
229
+ {
230
+ meta:
231
+ description = "Arxan"
232
+ url = "https://www.arxan.com/products/application-protection-mobile/"
233
+ sample = "7bd1139b5f860d48e0c35a3f117f980564f45c177a6ef480588b5b5c8165f47e"
234
+ author = "Eduardo Novella"
235
+
236
+ strings:
237
+ // Obfuscated Lpackage/class/: "L([a-z]\1{5}\/[a-z]{6}\/".
238
+ // AFAIK, Yara does not support backreferences at the moment, thus this is the combo:
239
+ $pkg = /L(a{6}|b{6}|c{6}|d{6}|e{6}|f{6}|g{6}|h{6}|i{6}|j{6}|k{6}|l{6}|m{6}|n{6}|o{6}|p{6}|q{6}|r{6}|s{6}|t{6}|u{6}|v{6}|w{6}|x{6}|y{6}|z{6})\/[a-z]{6}/
240
+
241
+ // Obfuscated methods are found to follow a pattern like:
242
+ // 1 byte size + 1 byte ASCII + [7-26] non-ASCII bytes + 00 (null terminator)
243
+ $m1 = { 10 62 (6? | 75) [14] 00 }
244
+ $m2 = { (0b | 0d) 62 d0 [15] 00 }
245
+ $m3 = { (0e | 10) 62 30 34 3? [15] 00 }
246
+ $m4 = { (0b | 0d) 62 30 34 3? [13] 00 }
247
+ $m5 = { (08 | 0b | 0d | 0e ) 62 [7-13] 00 }
248
+ $m6 = { 0a 62 (30 34 3? | d? ?? ??) [11] 00 }
249
+ $m7 = { (0d | 0b | 11) (62 d1 8? | 6? ?? ??) [14] 00 }
250
+
251
+ condition:
252
+ is_dex and
253
+ $pkg and
254
+ 6 of ($m*)
255
+ }
256
+
257
+ rule arxan_multidex : obfuscator
258
+ {
259
+ meta:
260
+ description = "Arxan (multidex)"
261
+ url = "https://www.arxan.com/products/application-protection-mobile/"
262
+ sample = "9b2a978a937293d6cb93439e0f819b4e044a3fad80dde92dec9b67e419278b5d"
263
+ author = "Eduardo Novella"
264
+
265
+ strings:
266
+ // Obfuscated Lpackage/class/: "L([a-z]\1{5}\/[a-z]{6}\/".
267
+ // AFAIK, Yara does not support backreferences at the moment, thus this is the combo:
268
+ $pkg = /L(a{6}|b{6}|c{6}|d{6}|e{6}|f{6}|g{6}|h{6}|i{6}|j{6}|k{6}|l{6}|m{6}|n{6}|o{6}|p{6}|q{6}|r{6}|s{6}|t{6}|u{6}|v{6}|w{6}|x{6}|y{6}|z{6})\/[a-z]{6}/
269
+
270
+ // Obfuscated methods are found to follow a pattern like:
271
+ // 1 byte size + 1 byte ASCII + [7-26] non-ASCII bytes + 00 (null terminator)
272
+ $m1 = { 10 62 (6? | 75) [14] 00 }
273
+ $m2 = { (0b | 0d) 62 d0 [15] 00 }
274
+ $m3 = { (0e | 10) 62 30 34 3? [15] 00 }
275
+ $m4 = { (0b | 0d) 62 30 34 3? [13] 00 }
276
+ $m5 = { (08 | 0b | 0d | 0e ) 62 [7-13] 00 }
277
+ $m6 = { 0a 62 (30 34 3? | d? ?? ??) [11] 00 }
278
+ $m7 = { (0d | 0b | 11) (62 d1 8? | 6? ?? ??) [14] 00 }
279
+
280
+ condition:
281
+ is_dex and
282
+ $pkg and
283
+ 2 of ($m*) and
284
+ not arxan
285
+ }
286
+
287
+ rule arxan_b : obfuscator
288
+ {
289
+ meta:
290
+ description = "Arxan"
291
+ url = "https://github.com/rednaga/APKiD/issues/160"
292
+ sample = "86ade15e885cf7927e5840dd2bf2782905fcd6843be77f898b51b64c2277f3de"
293
+ author = "Tim 'diff' Strazzere"
294
+
295
+ strings:
296
+ // Targeting this seemingly static byte sequence used inside the injected obfuscation:
297
+ // move-result v0 (moving result from own deobfuscation, v2 and v3 are always consts)
298
+ $deobf = {
299
+ 0A 0?
300
+ DF 01 03 FF
301
+ // and-int/2addr v1, v0
302
+ B5 01
303
+ // xor-int/lit8 v0, v0, -0x1
304
+ DF 00 00 FF
305
+ // and-int/2addr v0, v3
306
+ B5 30
307
+ // or-int/2addr v1, v0
308
+ B6 01
309
+ // int-to-short v7, v1
310
+ 8F 1?
311
+ }
312
+
313
+ condition:
314
+ is_dex and
315
+ $deobf
316
+ }
317
+
318
+ rule arxan_c : obfuscator
319
+ {
320
+ meta:
321
+ description = "Arxan"
322
+ url = "https://digital.ai/products/application-security/"
323
+ sample = "7bd1139b5f860d48e0c35a3f117f980564f45c177a6ef480588b5b5c8165f47e"
324
+ author = "Abhi"
325
+
326
+ strings:
327
+ // Example: .9Lcom/arxan/guardit4j/util/PackageNameEnumeratorException;.
328
+ $pkg = { 00 ?? 4C 63 6F 6D 2F 61 72 78 61 6E 2F 67 75 61 72 64 69 74 } // .??Lcom/arxan/guardit
329
+
330
+ condition:
331
+ is_dex and
332
+ $pkg and
333
+ not (arxan or arxan_multidex or arxan_b)
334
+ }
335
+
336
+ rule allatori_demo : obfuscator
337
+ {
338
+ meta:
339
+ description = "Allatori demo"
340
+ url = "http://www.allatori.com/features.html"
341
+ author = "Eduardo Novella"
342
+ sample = "7f2f5aac9833f7bdccc0b9865f5cc2a9c94ee795a285ef2fa6ff83a34c91827f"
343
+ sample2 = "8c9e6c7b8c516499dd2065cb435ef68089feb3d4053faf2cfcb2b759b051383c"
344
+
345
+ strings:
346
+ // null-prev-str + len + str + null
347
+ $s = { 00 0D 41 4C 4C 41 54 4F 52 49 78 44 45 4D 4F 00 } // ALLATORIxDEMO
348
+
349
+ condition:
350
+ is_dex and $s
351
+ }
352
+
353
+ rule aamo_str_enc : obfuscator
354
+ {
355
+ meta:
356
+ description = "AAMO"
357
+ author = "P0r0"
358
+ url = "https://github.com/necst/aamo"
359
+ sample = "c1ef860af0e168f924663630ed3b61920b474d0c8b10e2bde6bfd3769dbd31a8"
360
+ sample2 = "eb0d4e1ba2e880749594eb8739e65aa21b6f7b43798f04b6681065b396c15a78"
361
+
362
+ strings:
363
+ $opcodes_nops = {
364
+ 22 ?? ?? ?? //new-instance v? Ljava/lang/String;
365
+ ( 00 00 | 00 00 00 00 | 00 00 00 00 00 00 )
366
+ 12 ?2 //const/4 v2, 0x2 (the register and constant never change)
367
+ ( 00 00 | 00 00 00 00 | 00 00 00 00 00 00 )
368
+ 1a ?? ?? ?? //const-string v?, _ref_to_string_
369
+ ( 00 00 | 00 00 00 00 | 00 00 00 00 00 00 )
370
+ 71 ?? ?? ?? ?? ?? //invoke-static {v?, v?}, Landroid/content/res/_RANDOM_CLASS_NAME.getStorageEncryption(ILjava/lang/String;)Ljavax/crypto/Cipher;
371
+ 0c 02 //move-result-object v2 (the register never changes)
372
+ ( 00 00 | 00 00 00 00 | 00 00 00 00 00 00 )
373
+ 71 ?? ?? ?? ?? ?? //invoke-static {v?, v?}, Landroid/content/res/_RANDOM_CLASS_NAME.decode(Ljava/lang/String;)[B
374
+ 0c 03 //move-result-object v3
375
+ ( 00 00 | 00 00 00 00 | 00 00 00 00 00 00 )
376
+ 6e ?? ?? ?? ?? ?? //invoke-virtual {v?, v?}, Ljavax/crypto/Cipher.doFinal([B)[B
377
+ 0c 02 //move-result-object v2
378
+ ( 00 00 | 00 00 00 00 | 00 00 00 00 00 00 )
379
+ 1a ?? ?? ?? //const-string v?, _CONST_STR_
380
+ ( 00 00 | 00 00 00 00 | 00 00 00 00 00 00 )
381
+ 70 ?? ?? ?? ?? ?? //invoke-direct {v?, v?, v?}, Ljava/lang/String.<init>([BLjava/lang/String;)
382
+ 71 ?? ?? ?? ?? ?? //invoke-static {v?, v?}, Landroid/content/res/_RANDOM_CLASS_NAME._RANDOM_METHOD_NAME_(Ljava/lang/String;)Ljava/lang/String;
383
+ 0c ?? //move-result-object v4
384
+ }
385
+
386
+ $opcodes = {
387
+ 22 ?? ?? ?? //new-instance v? Ljava/lang/String;
388
+ 12 ?2 //const/4 v2, 0x2 (the register and constant never change)
389
+ 1a ?? ?? ?? //const-string v?, _ref_to_string_
390
+ 71 ?? ?? ?? ?? ?? //invoke-static {v?, v?}, Landroid/content/res/_RANDOM_CLASS_NAME.getStorageEncryption(ILjava/lang/String;)Ljavax/crypto/Cipher;
391
+ 0c 02 //move-result-object v2 (the register never changes)
392
+ 71 ?? ?? ?? ?? ?? //invoke-static {v?, v?}, Landroid/content/res/_RANDOM_CLASS_NAME.decode(Ljava/lang/String;)[B
393
+ 0c 03 //move-result-object v3
394
+ 6e ?? ?? ?? ?? ?? //invoke-virtual {v?, v?}, Ljavax/crypto/Cipher.doFinal([B)[B
395
+ 0c 02 //move-result-object v2
396
+ 1a ?? ?? ?? //const-string v?, _CONST_STR_
397
+ 70 ?? ?? ?? ?? ?? //invoke-direct {v?, v?, v?}, Ljava/lang/String.<init>([BLjava/lang/String;)
398
+ 71 ?? ?? ?? ?? ?? //invoke-static {v?, v?}, Landroid/content/res/_RANDOM_CLASS_NAME._RANDOM_METHOD_NAME_(Ljava/lang/String;)Ljava/lang/String;
399
+ 0c ?? //move-result-object v4
400
+ }
401
+
402
+ $a = { 00 0f 63 6f 6e 76 65 72 74 54 6f 53 74 72 69 6e 67 00 } // convertToString
403
+ $b = { 00 14 67 65 74 53 74 6f 72 61 67 65 45 6e 63 72 79 70 74 69 6f 6e 00 } //getStorageEncryption
404
+
405
+ condition:
406
+ is_dex and 1 of ($opcodes*) and all of ($a, $b)
407
+ }
408
+
409
+ rule appsuit_a : obfuscator
410
+ {
411
+ meta:
412
+ description = "AppSuit"
413
+ url = "http://www.stealien.com/appsuit.html"
414
+ sample = "b99bafbbd5288ac93647d22f1c5b1863c96f581ae7a19fdc0e84bff4c2141328"
415
+ author = "Eduardo Novella"
416
+
417
+ strings:
418
+ $a1 = { 00 0741707053756974 00 } // 00AppSuit00
419
+ $a2 = { 00 0741505053554954 00 } // 00APPSUIT00
420
+ $c1 = { 00 144c636f6d2f737465616c69656e2f636f6e73743b00 } // 00Lcom/stealien/const;00
421
+ $c3 = { 00 084c615f6c6f636b3b00 } // 00La_lock;00
422
+ $l1 = { 00 6c6962417070537569742e736f 00 } // 00libAppSuit.so00
423
+ $o = { 000c 6368 6563 6b41 7070 5375 6974 00 } // 00checkAppSuit00
424
+ $p1 = { 00 08737465616c69656e 00 } // 00stealien00
425
+
426
+ condition:
427
+ is_dex and 2 of them
428
+ }
429
+
430
+ rule appsuit_b : obfuscator
431
+ {
432
+ meta:
433
+ description = "AppSuit"
434
+ url = "http://www.stealien.com/appsuit.html"
435
+ sample = "6055deceb83233cceefc89b2bce4e978fd417820c5f534b0df66415122f394ea"
436
+ author = "Eduardo Novella"
437
+
438
+ strings:
439
+ $c = { 00?? 4c636f6d2f737465616c69656e2f61707073756974 2f } // 00??Lcom/stealien/appsuit/
440
+
441
+ condition:
442
+ is_dex and all of them
443
+ }
444
+
445
+ rule gemalto_sdk : obfuscator
446
+ {
447
+ meta:
448
+ description = "Gemalto"
449
+ url = "https://www.gemalto.com/brochures-site/download-site/Documents/eba_ezio_on_mobile.pdf"
450
+ author = "Eduardo Novella"
451
+ sample = "294f95298189080a25b20ef28295d60ecde27ee12361f93ad2f024fdcb5bdb0b"
452
+
453
+ strings:
454
+ $p1 = "Lcom/gemalto/idp/mobile/"
455
+ $p2 = "Lcom/gemalto/medl/"
456
+ $p3 = "Lcom/gemalto/ezio/mobile/sdk/"
457
+
458
+ condition:
459
+ is_dex and any of them
460
+ }
461
+
462
+ rule kiwi_amazon : obfuscator
463
+ {
464
+ meta:
465
+ description = "Kiwi encrypter"
466
+ sample = "3e309548f90160e3a4dc6f67621c75d2b66cc3b580da7306ff3dc6d6c25bb8a1"
467
+ author = "Eduardo Novella"
468
+
469
+ strings:
470
+ $key = { 00 19 4B6977695F5F56657273696F6E5F5F4F626675736361746F72 00 } // 00+len+"Kiwi__Version__Obfuscator"+00
471
+ $class = { 00 19 4B69776956657273696F6E456E637279707465722E6A617661 00 } // 00+len+"KiwiVersionEncrypter.java"+00
472
+
473
+ condition:
474
+ is_dex and all of them
475
+ }
476
+
477
+ rule unreadable_field_names : obfuscator
478
+ {
479
+ meta:
480
+ description = "unreadable field names"
481
+ sample = "afd6da00440ec83d54aefea742f26ba045505ac520f074512207a7bb50aaf9c4"
482
+
483
+ condition:
484
+ short_unicode_field_names
485
+ and (not dexguard_a and not dexguard_b and not dexguard_c and not dexguard_d)
486
+ }
487
+
488
+ rule unreadable_method_names : obfuscator
489
+ {
490
+ meta:
491
+ description = "unreadable method names"
492
+ sample = "afd6da00440ec83d54aefea742f26ba045505ac520f074512207a7bb50aaf9c4"
493
+
494
+ condition:
495
+ short_unicode_method_names
496
+ and (not dexguard_a and not dexguard_b and not dexguard_c and not dexguard_d)
497
+ }
498
+
499
+ rule apkencryptor : obfuscator
500
+ {
501
+ meta:
502
+ description = "ApkEncryptor"
503
+ url = "https://github.com/FlyingYu-Z/ApkEncryptor"
504
+ sample = "26c25dacacd0b4fdd411d7459747021d66cb45e9d57f92743004d190af74acea"
505
+ author = "Eduardo Novella"
506
+
507
+ strings:
508
+ $p1 = "Lcn/beingyi/sub/utils/Native"
509
+ $p2 = "Lcom/beingyi/encrypt/StringPool"
510
+ $p3 = "Lcn/beingyi/sub/ui/JniAlert"
511
+
512
+ condition:
513
+ any of them and is_dex and unreadable_field_names and unreadable_method_names
514
+ }
515
+
516
+ rule blackobfuscator : obfuscator
517
+ {
518
+ meta:
519
+ description = "BlackObfuscator"
520
+ url = "https://github.com/CodingGay/BlackObfuscator"
521
+ sample = "92ae23580c83642ad0e50f19979b9d2122f28d8b3a9d4b17539ce125ae8d93eb" // com.plus.currencyconverter
522
+ sample2 = "1730a1244ed5b01bf14426ff464042976c79796d8b6361648f6ed98c30d77997" // com.abhi.myapplication with depth 1
523
+ sample3 = "a01550f444063d7a96f48d7f276c88b9f0ac277fd8409586f370f189d347ad30" // com.abhi.myapplication with depth 2
524
+ sample4 = "6f1e14a590b73848871d6f5331c395086b1334e7d04e0f78d4211476c5b966e0" // com.abhi.myapplication with depth 5
525
+ author = "Abhi"
526
+
527
+ strings:
528
+ /**
529
+ protected void onCreate(Bundle bundle) {
530
+ String str = "ۖۨ";
531
+ while (true) {
532
+ switch ((str.hashCode() ^ 9) ^ (-1279807116)) {
533
+ ....
534
+ }
535
+ }
536
+ }
537
+ */
538
+ $opcodes = {
539
+ 1A 00 ?? ?? // const-string v0, "random_weird_string"
540
+ 6E 10 ?? (AC | 00) 00 00 // invoke-virtual {v0}, Ljava/lang/String.hashCode()I
541
+ 0A ?? // move-result v(\d)
542
+ 13 02 ?? ?? // const/16 v(\d), 0x(\d+)
543
+ (14 0? ?? ?? ?? ?? | B7 ??) // const v(\d), 0x(\d+) or xor-int/2addr v(\d), v(\d)
544
+ (B7 ?? | D7 ?? ?? ??) // xor-int/2addr v(\d), v(\d) or xor-int/lit16 v(\d), v(\d), 0x(\d+)
545
+ }
546
+ /**
547
+ switch (...) {
548
+ case -2084167413:
549
+ ....
550
+ case -2084167413:
551
+ ....
552
+ case -2084167413:
553
+ ....
554
+ ...
555
+ }
556
+ */
557
+ $switch = {
558
+ 2C ?? ?? ?? ?? ?? // sparse-switch v(\d), 0x(\d+)
559
+ 28 ?? // goto 0x(\d+)
560
+ 1A 00 ?? ?? // const-string v0, "random_weird_string"
561
+ 28 ?? // goto 0x(\d+)
562
+ 1A 00 ?? ?? // const-string v0, "random_weird_string"
563
+ 28 ?? // goto 0x(\d+)
564
+ }
565
+
566
+ condition:
567
+ is_dex and (#opcodes >= 2 and #switch >= 2)
568
+ }
569
+
570
+ rule mtprotector_dex : obfuscator
571
+ {
572
+ meta:
573
+ description = "MT Protector"
574
+ url = "https://mt2.cn/download/"
575
+ sample = "7fd0657a9d7a3b8f44e9a8938669439db8ef90585259d24aad31b9cc1599a419"
576
+ author = "Eduardo Novella"
577
+
578
+ strings:
579
+ $classname = { 00 204c 6269 6e2f 6d74 2f61 6e6e 6f74 6174 696f 6e73 2f4d 5450 726f 7465 6374 6f72 3b00 } // Lbin/mt/annotations/MTProtector;
580
+
581
+ condition:
582
+ is_dex and any of them
583
+ }
584
+
585
+ rule stringfog : obfuscator
586
+ {
587
+ meta:
588
+ description = "StringFog"
589
+ url = "https://github.com/MegatronKing/StringFog"
590
+ sample = "1b89174083b22d97979537dc00dc91473243155d2d23654f40958577c4641185"
591
+ author = "Abhi"
592
+
593
+ strings:
594
+ $classname = { 00 2E 4C 63 6F 6D 2F 67 69 74 68 75 62 2F 6D 65 67
595
+ 61 74 72 6F 6E 6B 69 6E 67 2F 73 74 72 69 6E 67 66
596
+ 6F 67 2F 49 53 74 72 69 6E 67 46 6F 67 3B 00 } // Lcom/github/megatronking/stringfog/IStringFog;
597
+
598
+ condition:
599
+ is_dex and any of them
600
+ }
601
+
602
+