|
1 |
| -#!/usr/bin/python |
2 |
| -''' |
3 |
| -Python Code Obfuscator |
4 |
| -by Brandon Asuncion |
5 |
| - me@brandonasuncion.tech |
6 |
| -''' |
| 1 | +#!/usr/bin/env python3 |
| 2 | + |
| 3 | + |
| 4 | +# Python Code Obfuscator |
| 5 | +# by Brandon Asuncion |
| 6 | +# |
| 7 | +# Questions/Comments? me@brandonasuncion.tech |
| 8 | + |
7 | 9 |
|
8 | 10 | import string
|
9 | 11 | import sys
|
| 12 | +import argparse |
10 | 13 |
|
11 | 14 | # How strings are encoded
|
12 | 15 | # Turning off will remove all numbers in the code,
|
13 | 16 | # but will increase output size by a lot!
|
14 | 17 | USE_HEXSTRINGS = True
|
15 | 18 |
|
16 |
| -# Remove comments from code |
17 |
| -REMOVE_COMMENTS = True |
18 |
| - |
19 | 19 | # Obfuscate Python's built-in function calls
|
20 |
| -# Note: Code output will be large! |
21 | 20 | OBFUSCATE_BUILTINS = False
|
22 | 21 |
|
| 22 | +# Remove comments from code |
| 23 | +REMOVE_COMMENTS = True |
| 24 | + |
23 | 25 | # Special code replacements
|
24 | 26 | REPLACEMENTS = {
|
25 | 27 | 'True': '(()==())',
|
26 | 28 | 'False': '(()==[])',
|
27 | 29 | }
|
28 | 30 |
|
29 |
| -# Name of variable for internal actions (such as string decryption) |
30 |
| -RESERVED_VAR = "__RSV" |
31 |
| - |
32 |
| -BUILTINS_CONST = "__B" |
| 31 | +# Ignore the following two constants if you don't know what they mean |
| 32 | +RESERVED_VAR = "__RSV" # Name of variable for internal actions (such as string decryption) |
| 33 | +BUILTINS_CONST = "__B" # name used in the header for storing the "builtins" string |
33 | 34 |
|
34 | 35 | _RESERVED = [
|
35 | 36 | # Python reserved keywords
|
|
59 | 60 | ]
|
60 | 61 |
|
61 | 62 | # Might not be a complete list...
|
62 |
| -PREPAD = [';', ':', '=', '+', '-', '*', '%', '^', '<<', '>>', '|', '^', '/', ',', '{', '}', '[', ']'] |
| 63 | +_PREPAD = [';', ':', '=', '+', '-', '*', '%', '^', '<<', '>>', '|', '^', '/', ',', '{', '}', '[', ']'] |
63 | 64 |
|
64 | 65 | class Obfuscator(object):
|
65 | 66 |
|
@@ -174,7 +175,7 @@ def obfuscate(self, code, append_header = True):
|
174 | 175 |
|
175 | 176 | # Pad certain characters so they can be parsed properly
|
176 | 177 | prepadded = code
|
177 |
| - for p in PREPAD: |
| 178 | + for p in _PREPAD: |
178 | 179 | prepadded = prepadded.replace(p, " {} ".format(p))
|
179 | 180 | prepadded = prepadded.replace('(', "( ").replace(')', ' )')
|
180 | 181 |
|
@@ -217,7 +218,7 @@ def obfuscate(self, code, append_header = True):
|
217 | 218 |
|
218 | 219 |
|
219 | 220 | # arithmetic and similar symbols are passed along as well
|
220 |
| - if symbol in PREPAD: |
| 221 | + if symbol in _PREPAD: |
221 | 222 | result += symbol
|
222 | 223 | continue
|
223 | 224 |
|
@@ -310,33 +311,40 @@ def obfuscate_lines(self, code):
|
310 | 311 |
|
311 | 312 | result += self.obfuscate(line, False) + "\n"
|
312 | 313 | return self.getHeader() + result
|
| 314 | + |
| 315 | +class MyArgParser(argparse.ArgumentParser): |
| 316 | + def error(self, message): |
| 317 | + sys.stderr.write('Error: {}\n'.format(message)) |
| 318 | + self.print_help() |
| 319 | + sys.exit(2) |
313 | 320 |
|
314 | 321 | def main():
|
315 |
| - if len(sys.argv) < 3: |
316 |
| - print('Usage: obfuscator.py inputfile outputfile') |
317 |
| - else: |
318 |
| - with open(sys.argv[1], 'r') as fh: |
319 |
| - lines = fh.read() |
320 |
| - |
321 |
| - obf = Obfuscator() |
322 |
| - output = obf.obfuscate_lines(lines) |
323 |
| - print(output) |
324 |
| - |
325 |
| - with open(sys.argv[2], 'w') as fh: |
326 |
| - fh.write(output) |
| 322 | + parser = MyArgParser(description='Python Code Obfuscator by Brandon Asuncion (me@brandonasuncion.tech)') |
| 323 | + parser.add_argument('inputfile', help="Name of the input file") |
| 324 | + parser.add_argument('outputfile', help="Name of the output file") |
| 325 | + parser.add_argument('--debug', help="Show debug info", action="store_true") |
| 326 | + args = vars(parser.parse_args()) |
| 327 | + |
| 328 | + print('Opening {} for obfuscation'.format(args['inputfile'])) |
| 329 | + with open(args['inputfile'], 'r') as fh: |
| 330 | + lines = fh.read() |
| 331 | + |
| 332 | + obf = Obfuscator() |
| 333 | + output = obf.obfuscate_lines(lines) |
| 334 | + |
| 335 | + with open(args['outputfile'], 'w') as fh: |
| 336 | + fh.write(output) |
| 337 | + print('Written to {}\n'.format(args['outputfile'])) |
327 | 338 |
|
328 |
| - ''' |
329 |
| - print('VARIABLES') |
| 339 | + if args['debug']: |
| 340 | + print('CONVERTED VARIABLES') |
330 | 341 | for v in obf.variables:
|
331 | 342 | print("{}\t=> {}".format(v, obf.variables[v]))
|
332 |
| - |
| 343 | + |
333 | 344 | print('\nVARIABLES IN HEADER')
|
334 |
| - for n in sorted(obf.header_variables, key = lambda x: int(x)): |
| 345 | + for n in sorted(obf.header_variables, key=len): |
335 | 346 | print("{}\t=> {}".format(n, obf.header_variables[n]))
|
336 |
| - print() |
337 |
| - ''' |
338 |
| - print('Written to {}'.format(sys.argv[2])) |
339 |
| - |
| 347 | + print() |
340 | 348 |
|
341 | 349 | if __name__ == "__main__":
|
342 | 350 | main()
|
0 commit comments