exe -> pyc包(*.exe_extracted)

安装反编译工具

exe反编译工具:pyinstxtractor.py下载:https://sourceforge.net/projects/pyinstallerextractor/

python pyinstxtractor.py hello.exe

包反编译

懒的写!!! 这有详细说明

https://blog.csdn.net/qq_45100200/article/details/128485152

支持库部分(重点)

需要工具 uncompyle6

pip install uncompyle6

反编译

支持库一般是 PYZ-00.pyz_extracted 文件夹

命令

uncompyle6 hello.pcy -> hello.pc 

反编译错误!

由于支持库的pyc 文件也缺少了一部分
8-12字节的描述符
所以反编译会报 AssertionError: None does not smell like code

解决办法 手动补全

手动替换08–12 的字节(08-11 插入 12-15改写)
python3将exe 转支持库错误 AssertionError: None does not smell like code-LMLPHP
改写为以下内容
python3将exe 转支持库错误 AssertionError: None does not smell like code-LMLPHP

脚本处理(人类因为懒 才有了文明的进步)

不废话 直接上脚本

# -*- encoding:utf-8 -*-

# uncompyle6 支付库 pcy -> py
# 错误 AssertionError: None does not smell like code
# 由于在 第8字节缺少4字节描述符 导致失败 _PCY_Z_ADDBYTES
# 将 _PCY_Z_ADDBYTES 填入后完成
import os
import sys


class PyCException(Exception):
    pass


_PCY_Z_ADDBYTES = b"pyi0" + bytes([0x10, 0x02, 0x00, 0x00])
_PCY_Z_HEAD = bytes([0x42, 0x0d, 0x0d, 0x0a])


def loadFile(aFile: str) -> bytes:
    with open(aFile, 'rb') as f:
        buf = f.read()
    return buf


def getFileName(aFileName):
    sl = os.path.basename(aFileName).rsplit('.', 1)[0]
    return sl


def getFileSuffix(aFileName):
    return aFileName.split(".")[-1]


class TPycZDecode():
    def __init__(self, aFile: str) -> None:
        self.fileName = aFile
        self.buf = loadFile(aFile)

    def _isPyc(self):
        print(self.buf[:4], _PCY_Z_HEAD)
        if self.buf[:4] != _PCY_Z_HEAD:
            raise PyCException("不是pyc支持库文件:%s" % self.fileName)

    def _isEncyrpt(self):
        # print(self.buf[9:10], self.buf[9:10] == bytes([0]))
        return self.buf[9:10] == bytes([0])

    def _addCode(self):
        if self._isEncyrpt()
        self.buf = self.buf[:8] + _PCY_Z_ADDBYTES + self.buf[12:]
        # print(self.buf[:15])

    def _isModule(self):
        """ 插入代码后判断 是模块 __init__.py 还是 模块内文件"""
        ret_path = ''
        # print(self.buf[0x01d:0x1d+4])
        v = int.from_bytes(self.buf[0x01d:0x1d+4], byteorder='little')
        # print(v)

        if v == 1:
            slen = int.from_bytes(self.buf[0x43:0x43+1], byteorder='little')

            # print(self.buf[0x44:0x44 + slen])

            s = self.buf[0x44:0x44 + slen].decode()
            # print(s)
            ret_path = s

        return ret_path

    def decode(self, aNewPath):
        self._isPyc()
        self._addCode()

        if not os.path.isabs(aNewPath):
            aNewPath = os.path.join(os.getcwd(), aNewPath)

        path = os.path.dirname(self.fileName)

        path_m = self._isModule()

        if path_m == '':
            # 模块文件
            file_name = getFileName(self.fileName)
            path_m = file_name.replace('.', '/') + '.py'
        else:
            path_m = path_m

        path_m = os.path.join(aNewPath, path_m)

        os.makedirs(os.path.dirname(path_m), exist_ok=True)

        # 打完补丁的文件 写回
        with open(self.fileName, 'wb') as f:
            f.write(self.buf)

        cmds = "uncompyle6 %s > %s " % (self.fileName, path_m)
        print(cmds)
        os.system(cmds)


def decode_dir(path, newPath=''):
    print(dirPath)

    if newPath == '':
        newPath = os.path.join(os.getcwd(), 'pycs-d')

    for root, dirs, files in os.walk(path):
        for file in files:
            if getFileSuffix(file) == 'pyc':
                print(file)
                file_path = os.path.join(root, file)
                print(file_path)

                try:
                    pycf = TPycZDecode(file_path)
                    pycf.decode(newPath)
                except Exception as e:
                    print(e)


def test_decodePyc():
    file = 'D:\mYcode\pthon\pcy'
    pycf = TPycZDecode(file)
    pycf.decode('pycs-d')


if __name__ == '__main__':
    # decode_dir('D:\\mYcode\\pthon\\pcy')
    # 将 pyc文件放在 脚本根目录 pycs-e 文件夹下
    # 解密文件生成在 脚本根目录 pycs-d 内

    if len(sys.argv) > 1:
        dirPath = sys.argv
    else:
        print("没有参数 路径默认 ./pycs-e")
        dirPath = os.path.join(os.getcwd(), 'pycs-e')
        try:
            os.mkdir(dirPath)
        except Exception as e:
            pass

    if not os.path.exists(dirPath):
        print('路径错误:%s' % dirPath)
        exit(1)

    decode_dir(dirPath)

    print("完成")

03-30 02:41