• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2import sys
3import os
4import marshal
5
6
7DIR = os.path.dirname(sys.argv[0])
8# source code for module to freeze
9FILE = os.path.join(DIR, 'flag.py')
10# C symbol to use for array holding frozen bytes
11SYMBOL = 'M___hello__'
12
13
14def get_module_code(filename):
15    """Compile 'filename' and return the module code as a marshalled byte
16    string.
17    """
18    with open(filename, 'r') as fp:
19        src = fp.read()
20    co = compile(src, 'none', 'exec')
21    co_bytes = marshal.dumps(co)
22    return co_bytes
23
24
25def gen_c_code(fp, co_bytes):
26    """Generate C code for the module code in 'co_bytes', write it to 'fp'.
27    """
28    def write(*args, **kwargs):
29        print(*args, **kwargs, file=fp)
30    write('/* Generated with Tools/freeze/regen_frozen.py */')
31    write('static unsigned char %s[] = {' % SYMBOL, end='')
32    bytes_per_row = 13
33    for i, opcode in enumerate(co_bytes):
34        if (i % bytes_per_row) == 0:
35            # start a new row
36            write()
37            write('    ', end='')
38        write('%d,' % opcode, end='')
39    write()
40    write('};')
41
42
43def main():
44    out_filename = sys.argv[1]
45    co_bytes = get_module_code(FILE)
46    with open(out_filename, 'w') as fp:
47        gen_c_code(fp, co_bytes)
48
49
50if __name__ == '__main__':
51    main()
52