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改写)
改写为以下内容
脚本处理(人类因为懒 才有了文明的进步)
不废话 直接上脚本
# -*- 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("完成")