forked from Kisioj/pypython
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pycdump.py
68 lines (57 loc) · 2.36 KB
/
pycdump.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import dis, marshal, struct, time, types, binascii
# https://gist.github.com/Kisioj/3f42851d272f25127054a211364a44dd
def read_pyc(file):
magic = file.read(4)
file.read(4)
moddate = file.read(4)
filesz = file.read(4) # size of the source file
# < is little-endian and size standard (4), without this on 64 bit machine, L's size is 8
modtime = time.asctime(time.localtime(struct.unpack('<L', moddate)[0]))
filesz = struct.unpack('<L', filesz)
code = marshal.load(file)
return magic, modtime, filesz, code
def show_file(fname):
with open(fname, "rb") as file:
magic, modtime, filesz, code = read_pyc(file)
print("magic %s" % binascii.hexlify(magic))
print("moddate %s" % modtime)
print("files sz %d" % filesz)
show_code(code)
def show_code(code, indent=''):
# pprint.pprint({x: getattr(code, x) for x in dir(code) if not x.startswith('__')})
# return
print ("%scode" % indent)
indent += ' '
print ("%sargcount %d" % (indent, code.co_argcount))
print ("%snlocals %d" % (indent, code.co_nlocals))
print ("%sstacksize %d" % (indent, code.co_stacksize))
print ("%sflags %04x" % (indent, code.co_flags))
show_hex("code", code.co_code, indent=indent)
dis.disassemble(code)
print ("%sconsts" % indent)
for const in code.co_consts:
if type(const) == types.CodeType:
show_code(const, indent+' ')
else:
print (" %s%r" % (indent, const))
print ("%snames %r" % (indent, code.co_names))
print ("%svarnames %r" % (indent, code.co_varnames))
print ("%sfreevars %r" % (indent, code.co_freevars))
print ("%scellvars %r" % (indent, code.co_cellvars))
print ("%sfilename %r" % (indent, code.co_filename))
print ("%skwonlyargcount %r" % (indent, code.co_kwonlyargcount))
print ("%sname %r" % (indent, code.co_name))
print ("%sfirstlineno %d" % (indent, code.co_firstlineno))
show_hex("lnotab", code.co_lnotab, indent=indent)
def show_hex(label, h, indent):
h = binascii.hexlify(h)
if len(h) < 60:
print ("%s%s %s" % (indent, label, h))
else:
print ("%s%s" % (indent, label))
for i in range(0, len(h), 60):
print ("%s %s" % (indent, h[i:i+60]))
if __name__ == '__main__':
# show_file(sys.argv[1])
import test
show_file('__pycache__/test.cpython-38.pyc')