python-obfuscation-framework 1.4.1__py3-none-any.whl
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.
- pof/__init__.py +21 -0
- pof/__main__.py +22 -0
- pof/cli.py +187 -0
- pof/errors.py +2 -0
- pof/evasion/__init__.py +57 -0
- pof/evasion/argv.py +44 -0
- pof/evasion/base.py +48 -0
- pof/evasion/cpu/__init__.py +0 -0
- pof/evasion/cpu/cpu_count.py +27 -0
- pof/evasion/fs/__init__.py +0 -0
- pof/evasion/fs/directory_exist.py +29 -0
- pof/evasion/fs/directory_list_exist.py +46 -0
- pof/evasion/fs/directory_list_missing.py +45 -0
- pof/evasion/fs/directory_missing.py +28 -0
- pof/evasion/fs/exec_method.py +51 -0
- pof/evasion/fs/executable_path.py +66 -0
- pof/evasion/fs/file_exist.py +29 -0
- pof/evasion/fs/file_list_exist.py +46 -0
- pof/evasion/fs/file_list_missing.py +45 -0
- pof/evasion/fs/file_missing.py +31 -0
- pof/evasion/fs/tmp.py +112 -0
- pof/evasion/hardware/__init__.py +0 -0
- pof/evasion/hardware/ram_count.py +50 -0
- pof/evasion/hooks/__init__.py +0 -0
- pof/evasion/hooks/debugger.py +36 -0
- pof/evasion/hooks/tracemalloc.py +23 -0
- pof/evasion/human/__init__.py +0 -0
- pof/evasion/human/p.py +45 -0
- pof/evasion/human/prompt.py +69 -0
- pof/evasion/integrity.py +129 -0
- pof/evasion/multi.py +41 -0
- pof/evasion/os/__init__.py +0 -0
- pof/evasion/os/domain.py +27 -0
- pof/evasion/os/hostname.py +27 -0
- pof/evasion/os/uid.py +28 -0
- pof/evasion/os/username.py +27 -0
- pof/evasion/processes/__init__.py +0 -0
- pof/evasion/processes/proc_count.py +47 -0
- pof/evasion/time/__init__.py +0 -0
- pof/evasion/time/expire.py +75 -0
- pof/evasion/time/uptime.py +48 -0
- pof/evasion/time/utc.py +26 -0
- pof/evasion/utils.py +198 -0
- pof/main.py +369 -0
- pof/obfuscator/__init__.py +86 -0
- pof/obfuscator/builtins.py +482 -0
- pof/obfuscator/cipher/__init__.py +0 -0
- pof/obfuscator/cipher/deep_encryption.py +194 -0
- pof/obfuscator/cipher/rc4.py +22 -0
- pof/obfuscator/cipher/shift.py +19 -0
- pof/obfuscator/cipher/xor.py +121 -0
- pof/obfuscator/compression/__init__.py +0 -0
- pof/obfuscator/compression/bz2.py +22 -0
- pof/obfuscator/compression/gzip.py +22 -0
- pof/obfuscator/compression/lzma.py +22 -0
- pof/obfuscator/compression/zlib.py +22 -0
- pof/obfuscator/constants.py +294 -0
- pof/obfuscator/definitions.py +341 -0
- pof/obfuscator/encoding/__init__.py +0 -0
- pof/obfuscator/encoding/a85.py +21 -0
- pof/obfuscator/encoding/b16.py +21 -0
- pof/obfuscator/encoding/b32.py +21 -0
- pof/obfuscator/encoding/b32hex.py +21 -0
- pof/obfuscator/encoding/b64.py +21 -0
- pof/obfuscator/encoding/b85.py +25 -0
- pof/obfuscator/encoding/binascii.py +22 -0
- pof/obfuscator/encoding/snt.py +23 -0
- pof/obfuscator/esoteric/__init__.py +0 -0
- pof/obfuscator/esoteric/call.py +49 -0
- pof/obfuscator/esoteric/doc.py +237 -0
- pof/obfuscator/esoteric/globals.py +62 -0
- pof/obfuscator/esoteric/imports.py +55 -0
- pof/obfuscator/extract_variables.py +297 -0
- pof/obfuscator/junk/__init__.py +0 -0
- pof/obfuscator/junk/add_comments.py +102 -0
- pof/obfuscator/junk/add_newlines.py +36 -0
- pof/obfuscator/names.py +474 -0
- pof/obfuscator/names_rope.py +375 -0
- pof/obfuscator/numbers.py +271 -0
- pof/obfuscator/other/__init__.py +0 -0
- pof/obfuscator/other/tokens.py +47 -0
- pof/obfuscator/remove/__init__.py +0 -0
- pof/obfuscator/remove/comments.py +36 -0
- pof/obfuscator/remove/exceptions.py +75 -0
- pof/obfuscator/remove/indents.py +28 -0
- pof/obfuscator/remove/loggings.py +120 -0
- pof/obfuscator/remove/loggings_old.py +45 -0
- pof/obfuscator/remove/newline.py +27 -0
- pof/obfuscator/remove/print.py +40 -0
- pof/obfuscator/restructure.py +15 -0
- pof/obfuscator/stegano/__init__.py +0 -0
- pof/obfuscator/stegano/docstrings.py +111 -0
- pof/obfuscator/stegano/ipv6encoding.py +21 -0
- pof/obfuscator/stegano/macencoding.py +21 -0
- pof/obfuscator/stegano/uuidencoding.py +21 -0
- pof/obfuscator/strings.py +359 -0
- pof/stager/__init__.py +17 -0
- pof/stager/cipher/__init__.py +0 -0
- pof/stager/cipher/rc4.py +36 -0
- pof/stager/download.py +80 -0
- pof/stager/image.py +374 -0
- pof/stager/lots/__init__.py +1 -0
- pof/stager/lots/cl1pnet.py +51 -0
- pof/stager/lots/pastebin.py +35 -0
- pof/stager/lots/pasters.py +30 -0
- pof/stager/quine.py +135 -0
- pof/utils/__init__.py +0 -0
- pof/utils/cipher/__init__.py +7 -0
- pof/utils/cipher/rc4.py +407 -0
- pof/utils/cipher/shift.py +41 -0
- pof/utils/compression/__init__.py +11 -0
- pof/utils/compression/bz2.py +38 -0
- pof/utils/compression/gzip.py +38 -0
- pof/utils/compression/lzma.py +38 -0
- pof/utils/compression/zlib.py +38 -0
- pof/utils/encoding/__init__.py +19 -0
- pof/utils/encoding/a85.py +35 -0
- pof/utils/encoding/b16.py +30 -0
- pof/utils/encoding/b3.py +93 -0
- pof/utils/encoding/b32.py +30 -0
- pof/utils/encoding/b32hex.py +30 -0
- pof/utils/encoding/b64.py +30 -0
- pof/utils/encoding/b85.py +35 -0
- pof/utils/encoding/binascii.py +38 -0
- pof/utils/encoding/snt.py +97 -0
- pof/utils/entropy.py +24 -0
- pof/utils/extract_names.py +204 -0
- pof/utils/generator/__init__.py +17 -0
- pof/utils/generator/advanced.py +53 -0
- pof/utils/generator/base.py +178 -0
- pof/utils/generator/basic.py +107 -0
- pof/utils/generator/names.txt +37241 -0
- pof/utils/generator/unicode.py +171 -0
- pof/utils/se/__init__.py +3 -0
- pof/utils/se/homoglyphs.py +99 -0
- pof/utils/se/homoglyphs.txt +96 -0
- pof/utils/stegano/__init__.py +5 -0
- pof/utils/stegano/ipv6encoding.py +97 -0
- pof/utils/stegano/macencoding.py +96 -0
- pof/utils/stegano/uuidencoding.py +102 -0
- pof/utils/tokens.py +68 -0
- python_obfuscation_framework-1.4.1.dist-info/LICENSE +674 -0
- python_obfuscation_framework-1.4.1.dist-info/METADATA +851 -0
- python_obfuscation_framework-1.4.1.dist-info/RECORD +147 -0
- python_obfuscation_framework-1.4.1.dist-info/WHEEL +5 -0
- python_obfuscation_framework-1.4.1.dist-info/entry_points.txt +2 -0
- python_obfuscation_framework-1.4.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from tokenize import LPAR, NAME, NEWLINE, RPAR
|
|
2
|
+
|
|
3
|
+
from pof.utils.cipher import ShiftCipher
|
|
4
|
+
from pof.utils.tokens import untokenize
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ShiftObfuscator(ShiftCipher):
|
|
8
|
+
"""Shift cipher obfuscator."""
|
|
9
|
+
|
|
10
|
+
@classmethod
|
|
11
|
+
def obfuscate_tokens(cls, tokens):
|
|
12
|
+
code = untokenize(tokens)
|
|
13
|
+
return [
|
|
14
|
+
(NAME, "exec"),
|
|
15
|
+
(LPAR, "("),
|
|
16
|
+
*cls.decode_tokens(cls.encode_tokens(code)),
|
|
17
|
+
(RPAR, ")"),
|
|
18
|
+
(NEWLINE, "\n"),
|
|
19
|
+
]
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""This is not a secure encryption method!
|
|
2
|
+
|
|
3
|
+
The main purpose of xor is to produce radically different outputs when obfuscating a
|
|
4
|
+
file.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import random
|
|
8
|
+
from base64 import b64encode
|
|
9
|
+
from tokenize import DEDENT, INDENT, NAME, NEWLINE, NL, NUMBER, OP, STRING
|
|
10
|
+
|
|
11
|
+
from pof.utils.tokens import untokenize
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class XORObfuscator:
|
|
15
|
+
"""XOR obfuscator."""
|
|
16
|
+
|
|
17
|
+
# TODO (deoktr): move code to utils/encryption/xor.py
|
|
18
|
+
@staticmethod
|
|
19
|
+
def get_exec_tokens(key, ciphertext):
|
|
20
|
+
return [
|
|
21
|
+
[NAME, "from"],
|
|
22
|
+
[NAME, "base64"],
|
|
23
|
+
[NAME, "import"],
|
|
24
|
+
[NAME, "b64decode"],
|
|
25
|
+
[NEWLINE, "\n"],
|
|
26
|
+
[NL, "\n"],
|
|
27
|
+
[NAME, "def"],
|
|
28
|
+
[NAME, "decrypt"],
|
|
29
|
+
[OP, "("],
|
|
30
|
+
[NAME, "cipher"],
|
|
31
|
+
[OP, ","],
|
|
32
|
+
[NAME, "key"],
|
|
33
|
+
[OP, ")"],
|
|
34
|
+
[OP, ":"],
|
|
35
|
+
[NEWLINE, "\n"],
|
|
36
|
+
[INDENT, " "],
|
|
37
|
+
[NAME, "bcipher"],
|
|
38
|
+
[OP, "="],
|
|
39
|
+
[NAME, "bytearray"],
|
|
40
|
+
[OP, "("],
|
|
41
|
+
[NAME, "b64decode"],
|
|
42
|
+
[OP, "("],
|
|
43
|
+
[NAME, "cipher"],
|
|
44
|
+
[OP, ")"],
|
|
45
|
+
[OP, ")"],
|
|
46
|
+
[NEWLINE, "\n"],
|
|
47
|
+
[NAME, "text"],
|
|
48
|
+
[OP, "="],
|
|
49
|
+
[NAME, "bytearray"],
|
|
50
|
+
[OP, "("],
|
|
51
|
+
[OP, ")"],
|
|
52
|
+
[NEWLINE, "\n"],
|
|
53
|
+
[NAME, "ki"],
|
|
54
|
+
[OP, "="],
|
|
55
|
+
[NUMBER, "0"],
|
|
56
|
+
[NEWLINE, "\n"],
|
|
57
|
+
[NAME, "for"],
|
|
58
|
+
[NAME, "i"],
|
|
59
|
+
[NAME, "in"],
|
|
60
|
+
[NAME, "bcipher"],
|
|
61
|
+
[OP, ":"],
|
|
62
|
+
[NEWLINE, "\n"],
|
|
63
|
+
[INDENT, " "],
|
|
64
|
+
[NAME, "text"],
|
|
65
|
+
[OP, "."],
|
|
66
|
+
[NAME, "append"],
|
|
67
|
+
[OP, "("],
|
|
68
|
+
[NAME, "i"],
|
|
69
|
+
[OP, "^"],
|
|
70
|
+
[NAME, "key"],
|
|
71
|
+
[OP, "["],
|
|
72
|
+
[NAME, "ki"],
|
|
73
|
+
[OP, "%"],
|
|
74
|
+
[NAME, "len"],
|
|
75
|
+
[OP, "("],
|
|
76
|
+
[NAME, "key"],
|
|
77
|
+
[OP, ")"],
|
|
78
|
+
[OP, "]"],
|
|
79
|
+
[OP, ")"],
|
|
80
|
+
[NEWLINE, "\n"],
|
|
81
|
+
[NAME, "ki"],
|
|
82
|
+
[OP, "+="],
|
|
83
|
+
[NUMBER, "1"],
|
|
84
|
+
[NEWLINE, "\n"],
|
|
85
|
+
[DEDENT, ""],
|
|
86
|
+
[NAME, "return"],
|
|
87
|
+
[NAME, "text"],
|
|
88
|
+
[NEWLINE, "\n"],
|
|
89
|
+
[DEDENT, ""],
|
|
90
|
+
[NAME, "exec"],
|
|
91
|
+
[OP, "("],
|
|
92
|
+
[NAME, "decrypt"],
|
|
93
|
+
[OP, "("],
|
|
94
|
+
[STRING, repr(ciphertext)],
|
|
95
|
+
[OP, ","],
|
|
96
|
+
[STRING, repr(key)],
|
|
97
|
+
[OP, ")"],
|
|
98
|
+
[OP, "."],
|
|
99
|
+
[NAME, "decode"],
|
|
100
|
+
[OP, "("],
|
|
101
|
+
[OP, ")"],
|
|
102
|
+
[OP, ")"],
|
|
103
|
+
[NEWLINE, "\n"],
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
@staticmethod
|
|
107
|
+
def encrypt_code(text, key):
|
|
108
|
+
bcipher = bytearray()
|
|
109
|
+
for ki, i in enumerate(text):
|
|
110
|
+
bcipher.append(i ^ key[ki % len(key)])
|
|
111
|
+
return b64encode(bcipher)
|
|
112
|
+
|
|
113
|
+
def obfuscate_tokens(self, tokens, key: str | None = None):
|
|
114
|
+
code = untokenize(tokens).encode()
|
|
115
|
+
if key is None:
|
|
116
|
+
key = str(random.randint(0, 100000000)).encode()
|
|
117
|
+
ciphertext = self.encrypt_code(code, key)
|
|
118
|
+
return self.get_exec_tokens(
|
|
119
|
+
key=key,
|
|
120
|
+
ciphertext=ciphertext,
|
|
121
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from tokenize import LPAR, NAME, NEWLINE, RPAR
|
|
2
|
+
|
|
3
|
+
from pof.utils.compression import Bz2Compression
|
|
4
|
+
from pof.utils.tokens import untokenize
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Bz2Obfuscator(Bz2Compression):
|
|
8
|
+
"""BZ2 compression obfuscator."""
|
|
9
|
+
|
|
10
|
+
@classmethod
|
|
11
|
+
def obfuscate_tokens(cls, tokens):
|
|
12
|
+
"""Generate payload to execute the bz2 encoded code."""
|
|
13
|
+
code = untokenize(tokens)
|
|
14
|
+
return [
|
|
15
|
+
*cls.import_tokens(),
|
|
16
|
+
(NEWLINE, "\n"),
|
|
17
|
+
(NAME, "exec"),
|
|
18
|
+
(LPAR, "("),
|
|
19
|
+
*cls.decode_tokens(cls.encode_tokens(code.encode())),
|
|
20
|
+
(RPAR, ")"),
|
|
21
|
+
(NEWLINE, "\n"),
|
|
22
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from tokenize import LPAR, NAME, NEWLINE, RPAR
|
|
2
|
+
|
|
3
|
+
from pof.utils.compression import GzipCompression
|
|
4
|
+
from pof.utils.tokens import untokenize
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class GzipObfuscator(GzipCompression):
|
|
8
|
+
"""GZIP compression obfuscator."""
|
|
9
|
+
|
|
10
|
+
@classmethod
|
|
11
|
+
def obfuscate_tokens(cls, tokens):
|
|
12
|
+
"""Generate payload to execute the gzip encoded code."""
|
|
13
|
+
code = untokenize(tokens)
|
|
14
|
+
return [
|
|
15
|
+
*cls.import_tokens(),
|
|
16
|
+
(NEWLINE, "\n"),
|
|
17
|
+
(NAME, "exec"),
|
|
18
|
+
(LPAR, "("),
|
|
19
|
+
*cls.decode_tokens(cls.encode_tokens(code.encode())),
|
|
20
|
+
(RPAR, ")"),
|
|
21
|
+
(NEWLINE, "\n"),
|
|
22
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from tokenize import LPAR, NAME, NEWLINE, RPAR
|
|
2
|
+
|
|
3
|
+
from pof.utils.compression import LzmaCompression
|
|
4
|
+
from pof.utils.tokens import untokenize
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class LzmaObfuscator(LzmaCompression):
|
|
8
|
+
"""LZMA compression obfuscator."""
|
|
9
|
+
|
|
10
|
+
@classmethod
|
|
11
|
+
def obfuscate_tokens(cls, tokens):
|
|
12
|
+
"""Generate payload to execute the lzma encoded code."""
|
|
13
|
+
code = untokenize(tokens)
|
|
14
|
+
return [
|
|
15
|
+
*cls.import_tokens(),
|
|
16
|
+
(NEWLINE, "\n"),
|
|
17
|
+
(NAME, "exec"),
|
|
18
|
+
(LPAR, "("),
|
|
19
|
+
*cls.decode_tokens(cls.encode_tokens(code.encode())),
|
|
20
|
+
(RPAR, ")"),
|
|
21
|
+
(NEWLINE, "\n"),
|
|
22
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from tokenize import LPAR, NAME, NEWLINE, RPAR
|
|
2
|
+
|
|
3
|
+
from pof.utils.compression import ZlibCompression
|
|
4
|
+
from pof.utils.tokens import untokenize
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ZlibObfuscator(ZlibCompression):
|
|
8
|
+
"""ZLIB compression obfuscator."""
|
|
9
|
+
|
|
10
|
+
@classmethod
|
|
11
|
+
def obfuscate_tokens(cls, tokens):
|
|
12
|
+
"""Generate payload to execute the zlib encoded code."""
|
|
13
|
+
code = untokenize(tokens)
|
|
14
|
+
return [
|
|
15
|
+
*cls.import_tokens(),
|
|
16
|
+
(NEWLINE, "\n"),
|
|
17
|
+
(NAME, "exec"),
|
|
18
|
+
(LPAR, "("),
|
|
19
|
+
*cls.decode_tokens(cls.encode_tokens(code.encode())),
|
|
20
|
+
(RPAR, ")"),
|
|
21
|
+
(NEWLINE, "\n"),
|
|
22
|
+
]
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"""Extract constants and put them at the top of the script.
|
|
2
|
+
|
|
3
|
+
Can extract:
|
|
4
|
+
|
|
5
|
+
- string
|
|
6
|
+
- number (int, float...)
|
|
7
|
+
- builtins (str, exec, hex...)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Add variables for certain values
|
|
12
|
+
# ex:
|
|
13
|
+
# if type(x) is int: ...
|
|
14
|
+
#
|
|
15
|
+
# u = type
|
|
16
|
+
# a = int
|
|
17
|
+
# if u(x) is a: ...
|
|
18
|
+
#
|
|
19
|
+
# TODO (deoktr): add variables under imports as an option
|
|
20
|
+
# TODO (deoktr): add variables inside functions
|
|
21
|
+
# TODO (deoktr): add exclusions for strings and numbers
|
|
22
|
+
#
|
|
23
|
+
|
|
24
|
+
import random
|
|
25
|
+
from tokenize import DEDENT, ENCODING, INDENT, NAME, NEWLINE, NUMBER, OP, STRING
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ConstantsObfuscator:
|
|
29
|
+
"""Extract variables and put them at the top of the file.
|
|
30
|
+
|
|
31
|
+
This will thus set strings, numbers etc. has constants.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
# list(__builtins__.__dict__.keys())
|
|
35
|
+
BUILTINS = (
|
|
36
|
+
# look like it works now ?
|
|
37
|
+
"__name__", # doesn't work with 'if _name_ == "_main_": ...'
|
|
38
|
+
"__doc__",
|
|
39
|
+
"__package__",
|
|
40
|
+
"__loader__",
|
|
41
|
+
"__spec__",
|
|
42
|
+
"__build_class__",
|
|
43
|
+
"__import__",
|
|
44
|
+
"abs",
|
|
45
|
+
"all",
|
|
46
|
+
"any",
|
|
47
|
+
"ascii",
|
|
48
|
+
"bin",
|
|
49
|
+
"breakpoint",
|
|
50
|
+
"callable",
|
|
51
|
+
"chr",
|
|
52
|
+
"compile",
|
|
53
|
+
"delattr",
|
|
54
|
+
"dir",
|
|
55
|
+
"divmod",
|
|
56
|
+
"eval",
|
|
57
|
+
"exec",
|
|
58
|
+
# used not to work but now it does I guess
|
|
59
|
+
"format", # try to change "{}".format('foo')
|
|
60
|
+
"getattr",
|
|
61
|
+
"globals",
|
|
62
|
+
"hasattr",
|
|
63
|
+
"hash",
|
|
64
|
+
"hex",
|
|
65
|
+
"id",
|
|
66
|
+
"input",
|
|
67
|
+
"isinstance",
|
|
68
|
+
"issubclass",
|
|
69
|
+
"iter",
|
|
70
|
+
"aiter",
|
|
71
|
+
"len",
|
|
72
|
+
"locals",
|
|
73
|
+
"max",
|
|
74
|
+
"min",
|
|
75
|
+
"next",
|
|
76
|
+
"anext",
|
|
77
|
+
"oct",
|
|
78
|
+
"ord",
|
|
79
|
+
"pow",
|
|
80
|
+
"print",
|
|
81
|
+
"repr",
|
|
82
|
+
"round",
|
|
83
|
+
"setattr",
|
|
84
|
+
"sorted",
|
|
85
|
+
"sum",
|
|
86
|
+
"vars",
|
|
87
|
+
"None",
|
|
88
|
+
"Ellipsis",
|
|
89
|
+
"NotImplemented",
|
|
90
|
+
"False",
|
|
91
|
+
"True",
|
|
92
|
+
"bool",
|
|
93
|
+
"memoryview",
|
|
94
|
+
"bytearray",
|
|
95
|
+
"bytes",
|
|
96
|
+
"classmethod",
|
|
97
|
+
"complex",
|
|
98
|
+
"dict",
|
|
99
|
+
"enumerate",
|
|
100
|
+
"filter",
|
|
101
|
+
"float",
|
|
102
|
+
"frozenset",
|
|
103
|
+
"property",
|
|
104
|
+
"int",
|
|
105
|
+
"list",
|
|
106
|
+
"map",
|
|
107
|
+
"object",
|
|
108
|
+
"range",
|
|
109
|
+
"reversed",
|
|
110
|
+
"set",
|
|
111
|
+
"slice",
|
|
112
|
+
"staticmethod",
|
|
113
|
+
"str",
|
|
114
|
+
# "super", # plain doesn't work
|
|
115
|
+
"tuple",
|
|
116
|
+
"type",
|
|
117
|
+
"zip",
|
|
118
|
+
"__debug__",
|
|
119
|
+
"BaseException",
|
|
120
|
+
"Exception",
|
|
121
|
+
"TypeError",
|
|
122
|
+
"StopAsyncIteration",
|
|
123
|
+
"StopIteration",
|
|
124
|
+
"GeneratorExit",
|
|
125
|
+
"SystemExit",
|
|
126
|
+
"KeyboardInterrupt",
|
|
127
|
+
"ImportError",
|
|
128
|
+
"ModuleNotFoundError",
|
|
129
|
+
"OSError",
|
|
130
|
+
"EnvironmentError",
|
|
131
|
+
"IOError",
|
|
132
|
+
"EOFError",
|
|
133
|
+
"RuntimeError",
|
|
134
|
+
"RecursionError",
|
|
135
|
+
"NotImplementedError",
|
|
136
|
+
"NameError",
|
|
137
|
+
"UnboundLocalError",
|
|
138
|
+
"AttributeError",
|
|
139
|
+
"SyntaxError",
|
|
140
|
+
"IndentationError",
|
|
141
|
+
"TabError",
|
|
142
|
+
"LookupError",
|
|
143
|
+
"IndexError",
|
|
144
|
+
"KeyError",
|
|
145
|
+
"ValueError",
|
|
146
|
+
"UnicodeError",
|
|
147
|
+
"UnicodeEncodeError",
|
|
148
|
+
"UnicodeDecodeError",
|
|
149
|
+
"UnicodeTranslateError",
|
|
150
|
+
"AssertionError",
|
|
151
|
+
"ArithmeticError",
|
|
152
|
+
"FloatingPointError",
|
|
153
|
+
"OverflowError",
|
|
154
|
+
"ZeroDivisionError",
|
|
155
|
+
"SystemError",
|
|
156
|
+
"ReferenceError",
|
|
157
|
+
"MemoryError",
|
|
158
|
+
"BufferError",
|
|
159
|
+
"Warning",
|
|
160
|
+
"UserWarning",
|
|
161
|
+
"EncodingWarning",
|
|
162
|
+
"DeprecationWarning",
|
|
163
|
+
"PendingDeprecationWarning",
|
|
164
|
+
"SyntaxWarning",
|
|
165
|
+
"RuntimeWarning",
|
|
166
|
+
"FutureWarning",
|
|
167
|
+
"ImportWarning",
|
|
168
|
+
"UnicodeWarning",
|
|
169
|
+
"BytesWarning",
|
|
170
|
+
"ResourceWarning",
|
|
171
|
+
"ConnectionError",
|
|
172
|
+
"BlockingIOError",
|
|
173
|
+
"BrokenPipeError",
|
|
174
|
+
"ChildProcessError",
|
|
175
|
+
"ConnectionAbortedError",
|
|
176
|
+
"ConnectionRefusedError",
|
|
177
|
+
"ConnectionResetError",
|
|
178
|
+
"FileExistsError",
|
|
179
|
+
"FileNotFoundError",
|
|
180
|
+
"IsADirectoryError",
|
|
181
|
+
"NotADirectoryError",
|
|
182
|
+
"InterruptedError",
|
|
183
|
+
"PermissionError",
|
|
184
|
+
"ProcessLookupError",
|
|
185
|
+
"TimeoutError",
|
|
186
|
+
"open",
|
|
187
|
+
"quit",
|
|
188
|
+
"exit",
|
|
189
|
+
"copyright",
|
|
190
|
+
"credits",
|
|
191
|
+
"license",
|
|
192
|
+
"help",
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
def __init__(
|
|
196
|
+
self,
|
|
197
|
+
generator=None,
|
|
198
|
+
obf_builtins_rate=1,
|
|
199
|
+
obf_string_rate=1,
|
|
200
|
+
obf_number_rate=1,
|
|
201
|
+
) -> None:
|
|
202
|
+
if generator is None:
|
|
203
|
+
from pof.utils.generator import BasicGenerator
|
|
204
|
+
|
|
205
|
+
generator = BasicGenerator.alphabet_generator()
|
|
206
|
+
|
|
207
|
+
self.generator = generator
|
|
208
|
+
|
|
209
|
+
self.obf_number_rate = obf_number_rate
|
|
210
|
+
self.obf_builtins_rate = obf_builtins_rate
|
|
211
|
+
self.obf_string_rate = obf_string_rate
|
|
212
|
+
|
|
213
|
+
def obfuscate_variable(self, toknum, tokval, variables):
|
|
214
|
+
if tokval not in variables:
|
|
215
|
+
var_name = next(self.generator)
|
|
216
|
+
variables.update({tokval: [var_name, toknum]})
|
|
217
|
+
return [(NAME, variables[tokval][0])], variables
|
|
218
|
+
|
|
219
|
+
def obfuscate_tokens(self, tokens):
|
|
220
|
+
variables = {}
|
|
221
|
+
result = []
|
|
222
|
+
parenthesis_depth = 0 # parenthesis depth
|
|
223
|
+
prev_tokval = None
|
|
224
|
+
prev_toknum = None
|
|
225
|
+
for index, (toknum, tokval, *_) in enumerate(tokens):
|
|
226
|
+
new_tokens = [(toknum, tokval)]
|
|
227
|
+
next_tokval = None
|
|
228
|
+
next_toknum = None
|
|
229
|
+
if len(tokens) > index + 1:
|
|
230
|
+
next_toknum, next_tokval, *__ = tokens[index + 1]
|
|
231
|
+
|
|
232
|
+
# context
|
|
233
|
+
if toknum == OP and tokval == "(":
|
|
234
|
+
parenthesis_depth += 1
|
|
235
|
+
elif toknum == OP and tokval == ")":
|
|
236
|
+
parenthesis_depth -= 1
|
|
237
|
+
|
|
238
|
+
# obfuscation
|
|
239
|
+
if (
|
|
240
|
+
(
|
|
241
|
+
toknum == NAME
|
|
242
|
+
and tokval in self.BUILTINS
|
|
243
|
+
and prev_tokval != "." # avoid changing class/imports functions
|
|
244
|
+
and (
|
|
245
|
+
parenthesis_depth == 0
|
|
246
|
+
or (parenthesis_depth > 0 and next_tokval != "=")
|
|
247
|
+
)
|
|
248
|
+
and (random.randint(0, 100) / 100) <= self.obf_builtins_rate
|
|
249
|
+
)
|
|
250
|
+
or (
|
|
251
|
+
# don't obfuscate docstrings
|
|
252
|
+
toknum == STRING
|
|
253
|
+
and prev_toknum
|
|
254
|
+
not in [
|
|
255
|
+
NEWLINE,
|
|
256
|
+
DEDENT,
|
|
257
|
+
INDENT,
|
|
258
|
+
ENCODING,
|
|
259
|
+
]
|
|
260
|
+
and (random.randint(0, 100) / 100) <= self.obf_string_rate
|
|
261
|
+
)
|
|
262
|
+
or (
|
|
263
|
+
toknum == NUMBER
|
|
264
|
+
and (random.randint(0, 100) / 100) <= self.obf_number_rate
|
|
265
|
+
)
|
|
266
|
+
):
|
|
267
|
+
new_tokens, variables = self.obfuscate_variable(
|
|
268
|
+
toknum,
|
|
269
|
+
tokval,
|
|
270
|
+
variables,
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
if new_tokens:
|
|
274
|
+
result.extend(new_tokens)
|
|
275
|
+
prev_tokval = tokval
|
|
276
|
+
prev_toknum = toknum
|
|
277
|
+
|
|
278
|
+
# randomize order
|
|
279
|
+
variables = list(variables.items())
|
|
280
|
+
random.shuffle(variables)
|
|
281
|
+
variables = dict(variables)
|
|
282
|
+
|
|
283
|
+
var_tokens = []
|
|
284
|
+
for tokval, (var_name, toknum) in variables.items():
|
|
285
|
+
var_tokens.extend(
|
|
286
|
+
[
|
|
287
|
+
(NAME, var_name),
|
|
288
|
+
(OP, "="),
|
|
289
|
+
(toknum, tokval),
|
|
290
|
+
(NEWLINE, "\n"),
|
|
291
|
+
],
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
return var_tokens + result
|