pyc

class pydecipher.artifact_types.pyc.Pyc(file_path_or_bytes: str | Path | BinaryIO, output_dir: Path | None = None, **kwargs)

The artifact class representing a compiled Python file (.pyc or .pyo).

Consists of a variable-sized header followed by a marshalled code object. This class can reverse some basic obfuscation regarding the removal or tampering with the header and magic bytes.

file_path

If this artifact comes from a file on disk, this is the path to that file.

Type:

pathlib.Path, optional

file_contents

The contents of the file read into memory.

Type:

bytes

output_dir

Where any output extracted from this artifact should get dumped.

Type:

os.PathLike

magic_num

Magic number/bytes of the file (first 2, unsigned little endian integer)

Type:

int

kwargs

Any keyword arguments needed for the parsing of this artifact, or for parsing nested artifacts.

Type:

Any

Raises:
  • TypeError – Will raise a TypeError if the file_path_or_bytes item is not a compiled Python file.

  • RuntimeError – Will raise a RuntimeError if the version-hint provided doesn’t correspond with a known/supported version. Supported versions are determined by xdis.

static check_and_fix_pyc(pyc_file: Path, provided_version: str | None = None) None | NamedTemporaryFile

Fix a given pyc file so it can be properly disassembled by xdis.

This function combats the following common obfuscations that may be applied to pyc files that would prevent them from easily being disassembled

  1. Missing the header entirely

  2. Missing only the magic bytes

  3. Magic bytes are there, but they don’t match a known version

  4. Filename doesn’t end in .pyc

Parameters:
  • pyc_file (pathlib.Path) – The path to the pyc file

  • provided_version (str, optional) – The version of the Python that compiled the pyc, if known.

Raises:

RuntimeError – The pyc file is malformed and couldn’t be corrected, likely due to a version not being given.

Returns:

If the pyc file is fine as is, this function returns None. If it needs to be fixed in some way, the temporary file object with the fixes is returned.

Return type:

Union[None, tempfile.NamedTemporaryFile]

static is_headerless(first_eight_bytes: bytes)

Check whether the given bytes match the beginning of a Code object.

Parameters:

first_eight_bytes (bytes) – The first eight bytes of a pyc file.

Returns:

True if this pyc lacks a proper header, False if not.

Return type:

bool

unpack()

Validate as best as possible that this is a well-formed compiled Python file.

If any obfuscations are detected, we will write a new, corrected file to disk. Does not overwrite the original file.

validate_pyc_file() bool

Check if the contents of the class object is a valid zip archive.

Returns:

True if this is a valid zip archive, False if not.

Return type:

bool