Initial commit
commit
a22aba913d
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from PyInstaller.archive.readers import ZlibArchiveReader
|
||||
from sys import argv
|
||||
from pathlib import Path
|
||||
|
||||
if len(argv) != 3:
|
||||
print(f"usage {argv[0]} [PYZ] [OUTPUT_PATH]")
|
||||
exit()
|
||||
|
||||
output_dir = Path(argv[2])
|
||||
|
||||
archive = ZlibArchiveReader(argv[1])
|
||||
for filename, (is_package, pos, size) in archive.toc.items():
|
||||
data = archive.extract(filename, raw=True)
|
||||
if type(filename) is bytes:
|
||||
filename = filename.decode("utf-8")
|
||||
filename = filename.replace(".", "/")
|
||||
out_file = output_dir / Path(f"{filename}.co")
|
||||
out_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
out_file.write_bytes(data)
|
@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python2.7
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import marshal
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
import uncompyle6
|
||||
from pathlib2 import Path
|
||||
|
||||
def _pack_uint32(val):
|
||||
""" Convert integer to 32-bit little-endian bytes """
|
||||
return struct.pack("<I", val)
|
||||
|
||||
def code_to_bytecode(code, mtime=0, source_size=0):
|
||||
"""
|
||||
Serialise the passed code object (PyCodeObject*) to bytecode as a .pyc file
|
||||
The args mtime and source_size are inconsequential metadata in the .pyc file.
|
||||
"""
|
||||
|
||||
# Get the magic number for the running Python version
|
||||
if sys.version_info >= (3,4):
|
||||
from importlib.util import MAGIC_NUMBER
|
||||
else:
|
||||
import imp
|
||||
MAGIC_NUMBER = imp.get_magic()
|
||||
|
||||
# Add the magic number that indicates the version of Python the bytecode is for
|
||||
#
|
||||
# The .pyc may not decompile if this four-byte value is wrong. Either hardcode the
|
||||
# value for the target version (eg. b'\x33\x0D\x0D\x0A' instead of MAGIC_NUMBER)
|
||||
# or see trymagicnum.py to step through different values to find a valid one.
|
||||
data = bytearray(MAGIC_NUMBER)
|
||||
|
||||
# Handle extra 32-bit field in header from Python 3.7 onwards
|
||||
# See: https://www.python.org/dev/peps/pep-0552
|
||||
if sys.version_info >= (3,7):
|
||||
# Blank bit field value to indicate traditional pyc header
|
||||
data.extend(_pack_uint32(0))
|
||||
|
||||
data.extend(_pack_uint32(int(mtime)))
|
||||
|
||||
# Handle extra 32-bit field for source size from Python 3.2 onwards
|
||||
# See: https://www.python.org/dev/peps/pep-3147/
|
||||
if sys.version_info >= (3,2):
|
||||
data.extend(_pack_uint32(source_size))
|
||||
|
||||
data.extend(marshal.dumps(code))
|
||||
|
||||
return data
|
||||
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage %s <in_path> <out_path>" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
in_path = Path(sys.argv[1])
|
||||
out_path = Path(sys.argv[2])
|
||||
|
||||
for path in in_path.rglob("*.co"):
|
||||
with open(str(path), "rb") as file:
|
||||
data = file.read()
|
||||
co = marshal.loads(data)
|
||||
pyc = code_to_bytecode(co, time.time())
|
||||
out_file = out_path / path.relative_to(in_path)
|
||||
out_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(str(out_file), "wb") as file:
|
||||
file.write(pyc)
|
Loading…
Reference in New Issue