处理pyc.encrypted后缀

一,介绍

ISCC出题人为什么会出这么过时的题?

使用Pylnstaller(版本在V6之前)可以使用pyinstaller --key==xxxxxx xx.pyc来给生成的pyc加密,

如果用pyinstxtractor解包,生成的PYZ-00.pyz_extracted文件夹里所有的pyc文件后面会加上.encrypted后缀。

如果在最新版本使用会提示:

 pyinstaller --key==mansu main.spec
Bytecode encryption was removed in PyInstaller v6.0. Please remove your --key=xxx argument. 
For the rationale and alternatives see https://github.com/pyinstaller/pyinstaller/pull/6999

作者的解释:

虽然如此,假如遇到了这种过时的题时,也是要清楚该怎么办

二,方法

使用pyinstxtractor解包后,主文件夹里会有一个名为pyimod00_crypto_key.pyc的文件,反编译一下,里面的内容就是密钥。

然后将这个脚本放在主文件下,打开cmd运行,之前那些被加密pyc文件就能正常反编译了
这个脚本只需要修改密钥和python版本两处即可

import zlib
import sys
from pathlib import Path
import tinyaes  # 适用于 PyInstaller≥4.0 的 AES-CTR 模式

# 配置参数
CRYPT_BLOCK_SIZE = 16
KEY = b'key.pyc中的内容'  # 替换为实际密钥(字节类型)
PYTHON_VERSION = "打包用的python版本"  # 根据生成pyc的Python版本修改
MAGIC_HEADERS = {
    "3.8": b"\x55\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0",
    "3.9": b"\x61\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0",
    "3.10": b"\x6f\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0"
}

def decrypt_pyc_encrypted(key, input_path, magic_header):
    """解密单个.pyc.encrypted文件并修复头部"""
    try:
        with open(input_path, 'rb') as f:
            iv = f.read(CRYPT_BLOCK_SIZE)  # 读取初始化向量
            cipher = tinyaes.AES(key, iv)
            encrypted_data = f.read()  # 读取加密数据
            decrypted_data = cipher.CTR_xcrypt_buffer(encrypted_data)  # AES-CTR解密

            # 处理可能的zlib压缩
            try:
                plaintext = zlib.decompress(decrypted_data)
            except zlib.error:
                plaintext = decrypted_data  # 未压缩时直接使用

            # 生成标准pyc文件
            output_path = input_path.with_suffix('')
            with open(output_path, 'wb') as out_file:
                out_file.write(magic_header)  # 写入对应版本的Magic头部
                out_file.write(plaintext)


            print(f"[+] 解密成功: {output_path}")
            return True
    except Exception as e:
        print(f"[-] 解密失败 {input_path}: {str(e)}")
        return False

def main():
    # 检查Magic头部配置
    if PYTHON_VERSION not in MAGIC_HEADERS:
        versions = ", ".join(MAGIC_HEADERS.keys())
        print(f"[-] 不支持的Python版本,可选版本: {versions}")
        sys.exit(1)
    magic_header = MAGIC_HEADERS[PYTHON_VERSION]

    # 遍历解包目录
    base_dir = Path("PYZ-00.pyz_extracted")
    if not base_dir.exists():
        print(f"[-] 目录不存在: {base_dir}")
        sys.exit(1)

    # 递归处理所有加密文件
    encrypted_files = list(base_dir.rglob("*.pyc.encrypted"))
    if not encrypted_files:
        print("[-] 未找到.pyc.encrypted文件")
        sys.exit(1)

    for file in encrypted_files:
        decrypt_pyc_encrypted(KEY, file, magic_header)

if __name__ == "__main__":
    main()
posted @ 2025-05-21 18:33  漫宿骄盛  阅读(59)  评论(2)    收藏  举报