1

So I have this python file and I successfully unpacked its content inside of it we have our file.pyc I appended the magic bytes to it so it went from:

E3 00 00 00 00 00 00 00 00 00 00 00 00

to something that looked like this:

42 0D 0D 0A 00 00 00 00 00 00 00 00 E3 00

The magic bytes seem to be correct however when I try to decompile using "uncompyle6" i get this:

<class 'ValueError'>; bad marshal data (unknown type code)

To solve this I went and tried out "decompyle3" however it still returned the same error.

Extra Info:
[*] Pyinstaller version: 2.1+
[*] Python version: 37
[*] Length of package: 21143183 bytes
[*] Found 66 files in CArchive
[*] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap
[+] Possible entry point: pyi_rth_certifi
[+] Possible entry point: pyi_rth_multiprocessing
[+] Possible entry point: pyi_rth_pkgres
[+] Possible entry point: KitsuneSelfbot
[*] Found 1013 files in PYZ archive

Also Here is the first chunk of bytes from our file.pyc (unedited):

E3 00 00 00 00 00 00 00 00 00 00 00 00 25 00 00 00 40 00 00 00 73 7A 07 00 00 64 00 64 01 6C 00 5A 00 64 00 64 01 6C 01 5A 01 64 00 64 01 6C 02 5A 02 64 00 64 01 6C 03 5A 03 64 00 64 01 6C 04 5A 04 64 00 64 01 6C 05 5A 05 64 00 64 01 6C 06 5A 06 64 00 64 01 6C 07 5A 07 64 00 64 01 6C 08 5A 08 64 00 64 01 6C 09 5A 09 64 00 64 01 6C 0A 5A 0A 64 00 64 01 6C 0B 5A 0B 64 00 64 01 6C 0C 5A 0C 64 00 64 01 6C 0D 5A 0D 64 00 64 01 6C 0E 5A 0E 64 00 64 01 6C 02 5A 02 64 00 64 01 6C 03 5A 03 64 00 64 01 6C 01 5A 01 64 00 64 01 6C 0F 5A 0F 64 00

And then from our future.pyc these are the first bytes

42 0D 0D 0A 00 00 00 00 00 00 00 00 E3 00 00 00 00 00 00 00 00 00 00 00 00 0A 00 00 00 40 00 00 00 F3 D8 00 00 00 64 00 5A 00 64 01 64 02 64 03 64 04 64 05 64 06 64 07 64 08 64 09 64 0A 67 0A 5A 01 64 0B 67 01 65 01 17 00 5A 02 64 0C 5A 03 64 0D 5A 04 64 0E 5A 05 64 0F 5A 06 64 10 5A 07 64 11 5A 08 64 12 5A 09 64 13 5A 0A 64 14 5A 0B 64 15 5A 0C 47 00 64 16 64 17 84 00 64 17 83 02 5A 0D 65 0D 64 18 64 19 65 03 83 03 5A 0E 65 0D 64 1A 64 1B 65 04 83 03 5A 0F 65 0D 64 1C 64 1D 65 05 83 03 5A 10 65 0D 64 1E 64 1D 65 06 83 03

I also tried unpacking future.pyc however it also returned this same error:

<class 'ValueError'>; bad marshal data (unknown type code)

Any help at all would be appreciated :)

1
  • So what happens if we change Jimmy Hankey it like below ? with open(destName + '.pyc', 'wb') as pycFile: pycFile.write(pycHeader) # Write pyc magic pycFile.write(b'\0' * 16) pycFile.write(data) Thanks so much for your entry.
    – Çayiçen
    Commented May 26, 2021 at 16:28

1 Answer 1

2

[Disclaimer: I'm the author of PyInstaller Extractor].

PyInstaller Extractor has been updated to v2.0 which includes supports for Python 3.7 and 3.8. Moreover it automatically fixes the header of extracted pyc's, manual fixing of the header is not needed anymore.

The answer below no longer applies if you use the latest version of the tool.


The cause of the error is because the tool hasn't been updated to support Python versions >= 3.7. Now coming to the actual reason, Python 3.7 and above has a 16 byte header in contrast to Python versions 3.3-3.6.

Quoting PEP 552,

The pyc header currently consists of 3 32-bit words. We will expand it to 4. The first word will continue to be the magic number, versioning the bytecode and pyc format. The second word, conceptually the new word, will be a bit field. The interpretation of the rest of the header and invalidation behavior of the pyc depends on the contents of the bit field.

(Emphasis mine)

Currently you're adding a 12 byte header which needs to increased to 16 as shown below.

42 0D 0D 0A 00 00 00 00 00 00 00 00 00 00 00 00

Similarly, the header of future.pyc and all the files inside the pyz__extracted directory also needs to be fixed.

Alternatively, as a temporary workaround until the tool is updated, you can edit pyinstxtractor.py to make sure it writes a 16 byte header.

Original code in pyinstxtractor.py

with open(destName + '.pyc', 'wb') as pycFile:
    pycFile.write(pycHeader)      # Write pyc magic
    pycFile.write(b'\0' * 4)      # Write timestamp
    if self.pyver >= 33:
        pycFile.write(b'\0' * 4)  # Size parameter added in Python 3.3
    pycFile.write(data)

Patched code in pyinstxtractor.py

with open(destName + '.pyc', 'wb') as pycFile:
    pycFile.write(pycHeader)      # Write pyc magic
    pycFile.write(b'\0' * 12)
    pycFile.write(data)
0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.