Skip to content

Commit f179677

Browse files
authored
Add files via upload
1 parent b6380c3 commit f179677

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

obfuscator.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import random
2+
import string
3+
import ast
4+
import re
5+
import argparse
6+
7+
NO_OBFUSCATE = set([ #this is here because I couldn't fix these
8+
'os', 'sys', 'random', 'string', 'ast', 're', 'open', 'print', 'exit', #you could probably get rid of some of them
9+
'getattr', 'setattr', 'delattr', 'hasattr', 'int', 'str', 'list', 'dict',
10+
'tuple', 'range', 'len', 'type', 'isinstance', 'dir', 'id', 'input',
11+
'sum', 'min', 'max', 'map', 'filter', 'sorted', 'enumerate', 'zip', '_',
12+
'path', '__init__', '__main__'
13+
])
14+
15+
def add_module_functions(module_name, no_obfuscate):
16+
try:
17+
module = __import__(module_name)
18+
for name in dir(module):
19+
no_obfuscate.add(name)
20+
if '.' in name:
21+
submodule = name.split('.')[0]
22+
no_obfuscate.add(submodule)
23+
except ImportError:
24+
pass
25+
26+
def collect_imported_modules(filename):
27+
with open(filename, 'r') as f:
28+
source_code = f.read()
29+
30+
tree = ast.parse(source_code)
31+
imported_modules = set()
32+
33+
for node in ast.walk(tree):
34+
if isinstance(node, (ast.Import, ast.ImportFrom)):
35+
for alias in node.names:
36+
imported_modules.add(alias.name if isinstance(node, ast.Import) else node.module)
37+
if isinstance(node, ast.ImportFrom):
38+
imported_modules.add(alias.name)
39+
40+
return imported_modules
41+
42+
def generate_random_name(length):
43+
return ''.join(random.choices(string.ascii_lowercase, k=length))
44+
45+
def collect_names(node, name_map, imported_modules, imported_functions_classes, no_obfuscate, length):
46+
builtins = dir(__builtins__)
47+
48+
if isinstance(node, ast.FunctionDef):
49+
if node.name not in builtins and node.name not in imported_functions_classes and node.name not in no_obfuscate:
50+
name_map[node.name] = generate_random_name(length)
51+
52+
elif isinstance(node, ast.Name):
53+
if node.id not in builtins and node.id not in imported_modules and node.id not in imported_functions_classes and node.id not in no_obfuscate:
54+
if node.id not in name_map:
55+
name_map[node.id] = generate_random_name(length)
56+
57+
for child in ast.iter_child_nodes(node):
58+
collect_names(child, name_map, imported_modules, imported_functions_classes, no_obfuscate, length)
59+
60+
def obfuscate_and_replace(file_path, length, output_file):
61+
name_map = {}
62+
imported_modules = collect_imported_modules(file_path)
63+
64+
for module in imported_modules:
65+
add_module_functions(module, NO_OBFUSCATE)
66+
67+
with open(file_path, 'r') as f:
68+
source_code = f.read()
69+
70+
tree = ast.parse(source_code)
71+
72+
imported_functions_classes = {alias.name for node in ast.walk(tree) if isinstance(node, ast.ImportFrom) for alias in node.names}
73+
74+
collect_names(tree, name_map, imported_modules, imported_functions_classes, NO_OBFUSCATE, length)
75+
76+
def replace_match(match):
77+
name = match.group(0)
78+
return name_map.get(name, name)
79+
80+
pattern = r'\b(?:' + '|'.join(re.escape(k) for k in name_map.keys()) + r')\b'
81+
updated_code = re.sub(pattern, replace_match, source_code)
82+
83+
with open(output_file, 'w') as file:
84+
file.write(updated_code)
85+
print(f"File has been obfuscated successfully")
86+
87+
def main():
88+
parser = argparse.ArgumentParser(description="Python Code Obfuscator", epilog="by stigsec")
89+
parser.add_argument('-i', '--input', required=True, help="Input Python code")
90+
parser.add_argument('-l', '--length', type=int, default=16, help="Length of obfuscated names")
91+
parser.add_argument('-o', '--output', required=True, help="Output file")
92+
93+
args = parser.parse_args()
94+
95+
if args.length <= 3: #if less than 3, weird problems occur
96+
print("Error: Length must be greater than 3.")
97+
return
98+
99+
obfuscate_and_replace(args.input, args.length, args.output)
100+
101+
if __name__ == "__main__":
102+
main()

0 commit comments

Comments
 (0)