将 exe 文件转换为 pyc 文件
- 新建一个
unpack.py 文件,将以下代码复制粘贴进去。
from __future__ import print_function
import os
import struct
import marshal
import zlib
import sys
from uuid import uuid4 as uniquename
class CTOCEntry:
def __init__(self, position, cmprsdDataSize, uncmprsdDataSize, cmprsFlag, typeCmprsData, name):
self.position = position
self.cmprsdDataSize = cmprsdDataSize
self.uncmprsdDataSize = uncmprsdDataSize
self.cmprsFlag = cmprsFlag
self.typeCmprsData = typeCmprsData
self.name = name
class PyInstArchive:
PYINST20_COOKIE_SIZE = 24
PYINST21_COOKIE_SIZE = 24 + 64
MAGIC = b'MEI\x0c\x0b\x0a\x0b\x0e'
def __init__(self, path):
self.filePath = path
self.pycMagic = b'\x00' * 4
self.barePycList = []
def open(self):
try:
self.fPtr = open(self.filePath, )
.fileSize = os.stat(.filePath).st_size
:
(.(.filePath))
():
:
.fPtr.close()
:
():
(.(.filePath))
searchChunkSize =
endPos = .fileSize
.cookiePos = -
endPos < (.MAGIC):
()
:
startPos = endPos - searchChunkSize
endPos >= searchChunkSize
chunkSize = endPos - startPos
chunkSize < (.MAGIC):
.fPtr.seek(startPos, os.SEEK_SET)
data = .fPtr.read(chunkSize)
offs = data.rfind(.MAGIC)
offs != -:
.cookiePos = startPos + offs
endPos = startPos + (.MAGIC) -
startPos == :
.cookiePos == -:
()
.fPtr.seek(.cookiePos + .PYINST20_COOKIE_SIZE, os.SEEK_SET)
.fPtr.read().lower():
()
.pyinstVer =
:
.pyinstVer =
()
():
:
.pyinstVer == :
.fPtr.seek(.cookiePos, os.SEEK_SET)
(magic, lengthofPackage, toc, tocLen, pyver) = \
struct.unpack(, .fPtr.read(.PYINST20_COOKIE_SIZE))
.pyinstVer == :
.fPtr.seek(.cookiePos, os.SEEK_SET)
(magic, lengthofPackage, toc, tocLen, pyver, pylibname) = \
struct.unpack(, .fPtr.read(.PYINST21_COOKIE_SIZE))
:
()
.pymaj, .pymin = (pyver // , pyver % ) pyver >= (pyver // , pyver % )
(.(.pymaj, .pymin))
tailBytes = .fileSize - .cookiePos - (.PYINST20_COOKIE_SIZE .pyinstVer == .PYINST21_COOKIE_SIZE)
.overlaySize = lengthofPackage + tailBytes
.overlayPos = .fileSize - .overlaySize
.tableOfContentsPos = .overlayPos + toc
.tableOfContentsSize = tocLen
(.(lengthofPackage))
():
.fPtr.seek(.tableOfContentsPos, os.SEEK_SET)
.tocList = []
parsedLen =
parsedLen < .tableOfContentsSize:
(entrySize,) = struct.unpack(, .fPtr.read())
nameLen = struct.calcsize()
(entryPos, cmprsdDataSize, uncmprsdDataSize, cmprsFlag, typeCmprsData, name) = \
struct.unpack(
.(entrySize - nameLen),
.fPtr.read(entrySize - ))
:
name = name.decode().rstrip()
UnicodeDecodeError:
newName = (uniquename())
(.(name, newName))
name = newName
name.startswith():
name = name.lstrip()
(name) == :
name = (uniquename())
(.(name))
.tocList.append(
CTOCEntry(
.overlayPos + entryPos,
cmprsdDataSize,
uncmprsdDataSize,
cmprsFlag,
typeCmprsData,
name
)
)
parsedLen += entrySize
(.((.tocList)))
():
nm = filepath.replace(, os.sep).replace(, os.sep).replace(, )
nmDir = os.path.dirname(nm)
nmDir != os.path.exists(nmDir):
os.makedirs(nmDir)
(nm, ) f:
f.write(data)
():
()
extractionDir = os.path.join(os.getcwd(), os.path.basename(.filePath) + )
os.path.exists(extractionDir):
os.mkdir(extractionDir)
os.chdir(extractionDir)
entry .tocList:
.fPtr.seek(entry.position, os.SEEK_SET)
data = .fPtr.read(entry.cmprsdDataSize)
entry.cmprsFlag == :
:
data = zlib.decompress(data)
zlib.error:
(.(entry.name))
(data) == entry.uncmprsdDataSize
entry.typeCmprsData == entry.typeCmprsData == :
basePath = os.path.dirname(entry.name)
basePath != :
os.path.exists(basePath):
os.makedirs(basePath)
entry.typeCmprsData == :
(.(entry.name))
.pycMagic == * :
.barePycList.append(entry.name + )
._writePyc(entry.name + , data)
entry.typeCmprsData == entry.typeCmprsData == :
data[:] == :
.pycMagic == * :
.pycMagic = data[:]
._writeRawData(entry.name + , data)
:
.pycMagic == * :
.barePycList.append(entry.name + )
._writePyc(entry.name + , data)
:
._writeRawData(entry.name, data)
entry.typeCmprsData == entry.typeCmprsData == :
._extractPyz(entry.name)
._fixBarePycs()
():
pycFile .barePycList:
(pycFile, ) pycFile:
pycFile.write(.pycMagic)
():
(filename, ) pycFile:
pycFile.write(.pycMagic)
.pymaj >= .pymin >= :
pycFile.write( * )
pycFile.write( * )
:
pycFile.write( * )
.pymaj >= .pymin >= :
pycFile.write( * )
pycFile.write(data)
():
dirName = name +
os.path.exists(dirName):
os.mkdir(dirName)
(name, ) f:
pyzMagic = f.read()
pyzMagic ==
pyzPycMagic = f.read()
.pycMagic == * :
.pycMagic = pyzPycMagic
.pycMagic != pyzPycMagic:
.pycMagic = pyzPycMagic
()
.pymaj != sys.version_info.major .pymin != sys.version_info.minor:
()
(.(.pymaj, .pymin))
()
(tocPosition,) = struct.unpack(, f.read())
f.seek(tocPosition, os.SEEK_SET)
:
toc = marshal.load(f)
:
(.(name))
(.((toc)))
(toc) == :
toc = (toc)
key toc.keys():
(ispkg, pos, length) = toc[key]
f.seek(pos, os.SEEK_SET)
fileName = key
:
fileName = fileName.decode()
:
fileName = fileName.replace(, ).replace(, os.sep)
ispkg == :
filePath = os.path.join(dirName, fileName, )
:
filePath = os.path.join(dirName, fileName + )
fileDir = os.path.dirname(filePath)
os.path.exists(fileDir):
os.makedirs(fileDir)
:
data = f.read(length)
data = zlib.decompress(data)
:
(.(filePath))
(filePath + , ).write(data)
:
._writePyc(filePath, data)
():
(sys.argv) < :
()
:
arch = PyInstArchive(sys.argv[])
arch.():
arch.checkFile():
arch.getCArchiveInfo():
arch.parseTOC()
arch.extractFiles()
arch.close()
(.(sys.argv[]))
()
()
arch.close()
__name__ == :
main()