Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 46 additions & 30 deletions decompile-py2exe.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,18 @@
2016/12/08: start
2016/12/14: continue
2018/07/09: 0.0.2 update for version uncompyle6 3.
2022/08/07: Finish todo list -AlphaO4

Todo:
Check if running under Python 3
Check if running under Python 3
except importerror for uncompyle6 and pefile
exe version (pyinstaller)
"""

import optparse
import sys
import os
import textwrap
import marshal
import dis
import zipfile
from io import StringIO

Expand All @@ -55,6 +54,7 @@
print('Missing pefile and/or peutils Python module, please check if it is installed.')
exit()


def PrintManual():
manual = '''
Manual:
Expand All @@ -64,13 +64,16 @@ def PrintManual():
for line in manual.split('\n'):
print(textwrap.fill(line, 79))

#Convert 2 Bytes If Python 3
# Convert 2 Bytes If Python 3


def C2BIP3(string):
if sys.version_info[0] > 2:
return bytes([ord(x) for x in string])
else:
return string


def Decompilepy2exe(data, pythonversion):
data = data[0x010:]
offset = data.find(b"\x00")
Expand All @@ -82,12 +85,14 @@ def Decompilepy2exe(data, pythonversion):
decompile(pythonversion, pythoncode[-1], oStringIO)
print(oStringIO.getvalue())


def GetPythonVersion(data):
if data[0:6] == b'PYTHON' and data[8:] == b'.DLL':
return data[6] - 0x30 + (data[7] - 0x30) / 10.0
else:
return 0.0


def ProcessPy2exe(data, options):
try:
oPE = pefile.PE(data=data)
Expand All @@ -108,7 +113,8 @@ def ProcessPy2exe(data, options):
if hasattr(resource_id, 'directory'):
for resource_lang in resource_id.directory.entries:
if hasattr(resource_lang, 'data'):
pythonscript = oPE.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
pythonscript = oPE.get_data(
resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)

if pythonscript == None:
print('Unable to find Python code (no resource PYTHONSCRIPT)')
Expand All @@ -122,40 +128,49 @@ def ProcessPy2exe(data, options):

Decompilepy2exe(pythonscript, pythonversion)


def ProcessFile(filename, options):
if filename == '':
data = sys.stdin.buffer.read()
elif filename.lower().endswith('.zip'):
try:
oZipfile = zipfile.ZipFile(filename, 'r')
oZipContent = oZipfile.open(oZipfile.infolist()[0], 'r', C2BIP3(options.password))
data = oZipContent.read()
oZipContent.close()
oZipfile.close()
except Exception as e:
print('Error opening file: %s' % str(e))
return
else:
try:
fIn = open(filename, 'rb')
data = fIn.read()
fIn.close()
except Exception as e:
print('Error opening file: %s' % str(e))
return

ProcessPy2exe(data, options)
if filename == '':
data = sys.stdin.buffer.read()
elif filename.lower().endswith('.zip'):
try:
oZipfile = zipfile.ZipFile(filename, 'r')
oZipContent = oZipfile.open(
oZipfile.infolist()[0], 'r', C2BIP3(options.password))
data = oZipContent.read()
oZipContent.close()
oZipfile.close()
except Exception as e:
print('Error opening file: %s' % str(e))
return
else:
try:
fIn = open(filename, 'rb')
data = fIn.read()
fIn.close()
except Exception as e:
print('Error opening file: %s' % str(e))
return

ProcessPy2exe(data, options)


def Main():
moredesc = '''
if sys.version_info[0] != 3:
print('This program requires Python 3.x')
exit()

Copyright 2016-2018 NVISO
Apache License, Version 2.0
https://www.nviso.be'''

oParser = optparse.OptionParser(usage='usage: %prog [options] [file]\n' + __description__ + moredesc, version='%prog ' + __version__)
oParser.add_option('-m', '--man', action='store_true', default=False, help='Print manual')
oParser.add_option('-p', '--password', default='infected', help='The ZIP password to be used (default infected)')
oParser = optparse.OptionParser(
usage='usage: %prog [options] [file]\n' + __description__ + moredesc, version='%prog ' + __version__)
oParser.add_option('-m', '--man', action='store_true',
default=False, help='Print manual')
oParser.add_option('-p', '--password', default='infected',
help='The ZIP password to be used (default infected)')
(options, args) = oParser.parse_args()

if options.man:
Expand All @@ -170,5 +185,6 @@ def Main():
else:
oParser.print_help()


if __name__ == '__main__':
Main()