Make adobekey.py work in Python 3

This commit is contained in:
kubik147 2020-09-27 00:46:32 +02:00
parent 9118ce77ab
commit 61c5096da0

View file

@ -1,8 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import with_statement
# adobekey.pyw, version 6.0 # adobekey.pyw, version 6.0
# Copyright © 2009-2010 i♥cabbages # Copyright © 2009-2010 i♥cabbages
@ -50,8 +48,6 @@ from __future__ import with_statement
# 6.0 - Work if TkInter is missing # 6.0 - Work if TkInter is missing
# 7.0 - Python 3 compatible for calibre 5 # 7.0 - Python 3 compatible for calibre 5
from __future__ import print_function
""" """
Retrieve Adobe ADEPT user key. Retrieve Adobe ADEPT user key.
""" """
@ -60,6 +56,8 @@ __license__ = 'GPL v3'
__version__ = '7.0' __version__ = '7.0'
import sys, os, struct, getopt import sys, os, struct, getopt
from base64 import b64decode
# Wrap a stream so that output gets flushed immediately # Wrap a stream so that output gets flushed immediately
# and also make sure that any unicode strings get # and also make sure that any unicode strings get
@ -71,10 +69,11 @@ class SafeUnbuffered:
if self.encoding == None: if self.encoding == None:
self.encoding = "utf-8" self.encoding = "utf-8"
def write(self, data): def write(self, data):
if isinstance(data,unicode): if isinstance(data, str):
data = data.encode(self.encoding,"replace") data = data.encode(self.encoding,"replace")
self.stream.write(data) self.stream.buffer.write(data)
self.stream.flush() self.stream.buffer.flush()
def __getattr__(self, attr): def __getattr__(self, attr):
return getattr(self.stream, attr) return getattr(self.stream, attr)
@ -112,15 +111,13 @@ def unicode_argv():
# Remove Python executable and commands if present # Remove Python executable and commands if present
start = argc.value - len(sys.argv) start = argc.value - len(sys.argv)
return [argv[i] for i in return [argv[i] for i in
xrange(start, argc.value)] range(start, argc.value)]
# if we don't have any arguments at all, just pass back script name # if we don't have any arguments at all, just pass back script name
# this should never happen # this should never happen
return [u"adobekey.py"] return [u"adobekey.py"]
else: else:
argvencoding = sys.stdin.encoding argvencoding = sys.stdin.encoding or "utf-8"
if argvencoding == None: return [arg if isinstance(arg, str) else str(arg, argvencoding) for arg in sys.argv]
argvencoding = "utf-8"
return arg
class ADEPTError(Exception): class ADEPTError(Exception):
pass pass
@ -132,7 +129,7 @@ if iswindows:
c_long, c_ulong c_long, c_ulong
from ctypes.wintypes import LPVOID, DWORD, BOOL from ctypes.wintypes import LPVOID, DWORD, BOOL
import _winreg as winreg import winreg
def _load_crypto_libcrypto(): def _load_crypto_libcrypto():
from ctypes.util import find_library from ctypes.util import find_library
@ -170,7 +167,7 @@ if iswindows:
raise ADEPTError('Failed to initialize AES key') raise ADEPTError('Failed to initialize AES key')
def decrypt(self, data): def decrypt(self, data):
out = create_string_buffer(len(data)) out = create_string_buffer(len(data))
iv = ("\x00" * self._blocksize) iv = (b"\x00" * self._blocksize)
rv = AES_cbc_encrypt(data, out, len(data), self._key, iv, 0) rv = AES_cbc_encrypt(data, out, len(data), self._key, iv, 0)
if rv == 0: if rv == 0:
raise ADEPTError('AES decryption failed') raise ADEPTError('AES decryption failed')
@ -181,7 +178,7 @@ if iswindows:
from Crypto.Cipher import AES as _AES from Crypto.Cipher import AES as _AES
class AES(object): class AES(object):
def __init__(self, key): def __init__(self, key):
self._aes = _AES.new(key, _AES.MODE_CBC, '\x00'*16) self._aes = _AES.new(key, _AES.MODE_CBC, b'\x00'*16)
def decrypt(self, data): def decrypt(self, data):
return self._aes.decrypt(data) return self._aes.decrypt(data)
return AES return AES
@ -289,44 +286,44 @@ if iswindows:
if struct.calcsize("P") == 4: if struct.calcsize("P") == 4:
CPUID0_INSNS = ( CPUID0_INSNS = (
"\x53" # push %ebx b"\x53" # push %ebx
"\x31\xc0" # xor %eax,%eax b"\x31\xc0" # xor %eax,%eax
"\x0f\xa2" # cpuid b"\x0f\xa2" # cpuid
"\x8b\x44\x24\x08" # mov 0x8(%esp),%eax b"\x8b\x44\x24\x08" # mov 0x8(%esp),%eax
"\x89\x18" # mov %ebx,0x0(%eax) b"\x89\x18" # mov %ebx,0x0(%eax)
"\x89\x50\x04" # mov %edx,0x4(%eax) b"\x89\x50\x04" # mov %edx,0x4(%eax)
"\x89\x48\x08" # mov %ecx,0x8(%eax) b"\x89\x48\x08" # mov %ecx,0x8(%eax)
"\x5b" # pop %ebx b"\x5b" # pop %ebx
"\xc3" # ret b"\xc3" # ret
) )
CPUID1_INSNS = ( CPUID1_INSNS = (
"\x53" # push %ebx b"\x53" # push %ebx
"\x31\xc0" # xor %eax,%eax b"\x31\xc0" # xor %eax,%eax
"\x40" # inc %eax b"\x40" # inc %eax
"\x0f\xa2" # cpuid b"\x0f\xa2" # cpuid
"\x5b" # pop %ebx b"\x5b" # pop %ebx
"\xc3" # ret b"\xc3" # ret
) )
else: else:
CPUID0_INSNS = ( CPUID0_INSNS = (
"\x49\x89\xd8" # mov %rbx,%r8 b"\x49\x89\xd8" # mov %rbx,%r8
"\x49\x89\xc9" # mov %rcx,%r9 b"\x49\x89\xc9" # mov %rcx,%r9
"\x48\x31\xc0" # xor %rax,%rax b"\x48\x31\xc0" # xor %rax,%rax
"\x0f\xa2" # cpuid b"\x0f\xa2" # cpuid
"\x4c\x89\xc8" # mov %r9,%rax b"\x4c\x89\xc8" # mov %r9,%rax
"\x89\x18" # mov %ebx,0x0(%rax) b"\x89\x18" # mov %ebx,0x0(%rax)
"\x89\x50\x04" # mov %edx,0x4(%rax) b"\x89\x50\x04" # mov %edx,0x4(%rax)
"\x89\x48\x08" # mov %ecx,0x8(%rax) b"\x89\x48\x08" # mov %ecx,0x8(%rax)
"\x4c\x89\xc3" # mov %r8,%rbx b"\x4c\x89\xc3" # mov %r8,%rbx
"\xc3" # retq b"\xc3" # retq
) )
CPUID1_INSNS = ( CPUID1_INSNS = (
"\x53" # push %rbx b"\x53" # push %rbx
"\x48\x31\xc0" # xor %rax,%rax b"\x48\x31\xc0" # xor %rax,%rax
"\x48\xff\xc0" # inc %rax b"\x48\xff\xc0" # inc %rax
"\x0f\xa2" # cpuid b"\x0f\xa2" # cpuid
"\x5b" # pop %rbx b"\x5b" # pop %rbx
"\xc3" # retq b"\xc3" # retq
) )
def cpuid0(): def cpuid0():
@ -385,7 +382,7 @@ if iswindows:
plkroot = winreg.OpenKey(cuser, PRIVATE_LICENCE_KEY_PATH) plkroot = winreg.OpenKey(cuser, PRIVATE_LICENCE_KEY_PATH)
except WindowsError: except WindowsError:
raise ADEPTError("Could not locate ADE activation") raise ADEPTError("Could not locate ADE activation")
for i in xrange(0, 16): for i in range(0, 16):
try: try:
plkparent = winreg.OpenKey(plkroot, "%04d" % (i,)) plkparent = winreg.OpenKey(plkroot, "%04d" % (i,))
except WindowsError: except WindowsError:
@ -393,7 +390,7 @@ if iswindows:
ktype = winreg.QueryValueEx(plkparent, None)[0] ktype = winreg.QueryValueEx(plkparent, None)[0]
if ktype != 'credentials': if ktype != 'credentials':
continue continue
for j in xrange(0, 16): for j in range(0, 16):
try: try:
plkkey = winreg.OpenKey(plkparent, "%04d" % (j,)) plkkey = winreg.OpenKey(plkparent, "%04d" % (j,))
except WindowsError: except WindowsError:
@ -402,10 +399,10 @@ if iswindows:
if ktype != 'privateLicenseKey': if ktype != 'privateLicenseKey':
continue continue
userkey = winreg.QueryValueEx(plkkey, 'value')[0] userkey = winreg.QueryValueEx(plkkey, 'value')[0]
userkey = userkey.decode('base64') userkey = b64decode(userkey)
aes = AES(keykey) aes = AES(keykey)
userkey = aes.decrypt(userkey) userkey = aes.decrypt(userkey)
userkey = userkey[26:-ord(userkey[-1])] userkey = userkey[26:-ord(userkey[-1:])]
#print "found key:",userkey.encode('hex') #print "found key:",userkey.encode('hex')
keys.append(userkey) keys.append(userkey)
if len(keys) == 0: if len(keys) == 0:
@ -433,7 +430,7 @@ elif isosx:
reslst = out1.split('\n') reslst = out1.split('\n')
cnt = len(reslst) cnt = len(reslst)
ActDatPath = "activation.dat" ActDatPath = "activation.dat"
for j in xrange(cnt): for j in range(cnt):
resline = reslst[j] resline = reslst[j]
pp = resline.find('activation.dat') pp = resline.find('activation.dat')
if pp >= 0: if pp >= 0:
@ -451,7 +448,7 @@ elif isosx:
adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag) adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag)
expr = '//%s/%s' % (adept('credentials'), adept('privateLicenseKey')) expr = '//%s/%s' % (adept('credentials'), adept('privateLicenseKey'))
userkey = tree.findtext(expr) userkey = tree.findtext(expr)
userkey = userkey.decode('base64') userkey = b64decode(userkey)
userkey = userkey[26:] userkey = userkey[26:]
return [userkey] return [userkey]
@ -466,7 +463,7 @@ def getkey(outpath):
if len(keys) > 0: if len(keys) > 0:
if not os.path.isdir(outpath): if not os.path.isdir(outpath):
outfile = outpath outfile = outpath
with file(outfile, 'wb') as keyfileout: with open(outfile, 'wb') as keyfileout:
keyfileout.write(keys[0]) keyfileout.write(keys[0])
print(u"Saved a key to {0}".format(outfile)) print(u"Saved a key to {0}".format(outfile))
else: else:
@ -477,7 +474,7 @@ def getkey(outpath):
outfile = os.path.join(outpath,u"adobekey_{0:d}.der".format(keycount)) outfile = os.path.join(outpath,u"adobekey_{0:d}.der".format(keycount))
if not os.path.exists(outfile): if not os.path.exists(outfile):
break break
with file(outfile, 'wb') as keyfileout: with open(outfile, 'wb') as keyfileout:
keyfileout.write(key) keyfileout.write(key)
print(u"Saved a key to {0}".format(outfile)) print(u"Saved a key to {0}".format(outfile))
return True return True
@ -515,9 +512,7 @@ def cli_main():
if len(args) == 1: if len(args) == 1:
# save to the specified file or directory # save to the specified file or directory
outpath = args[0] outpath = os.path.abspath(args[0])
if not os.path.isabs(outpath):
outpath = os.path.abspath(outpath)
else: else:
# save to the same directory as the script # save to the same directory as the script
outpath = os.path.dirname(argv[0]) outpath = os.path.dirname(argv[0])
@ -529,7 +524,7 @@ def cli_main():
if len(keys) > 0: if len(keys) > 0:
if not os.path.isdir(outpath): if not os.path.isdir(outpath):
outfile = outpath outfile = outpath
with file(outfile, 'wb') as keyfileout: with open(outfile, 'wb') as keyfileout:
keyfileout.write(keys[0]) keyfileout.write(keys[0])
print(u"Saved a key to {0}".format(outfile)) print(u"Saved a key to {0}".format(outfile))
else: else:
@ -540,7 +535,7 @@ def cli_main():
outfile = os.path.join(outpath,u"adobekey_{0:d}.der".format(keycount)) outfile = os.path.join(outpath,u"adobekey_{0:d}.der".format(keycount))
if not os.path.exists(outfile): if not os.path.exists(outfile):
break break
with file(outfile, 'wb') as keyfileout: with open(outfile, 'wb') as keyfileout:
keyfileout.write(key) keyfileout.write(key)
print(u"Saved a key to {0}".format(outfile)) print(u"Saved a key to {0}".format(outfile))
else: else:
@ -550,27 +545,27 @@ def cli_main():
def gui_main(): def gui_main():
try: try:
import Tkinter import tkinter
import Tkconstants import tkinter.constants
import tkMessageBox import tkinter.messagebox
import traceback import traceback
except: except:
return cli_main() return cli_main()
class ExceptionDialog(Tkinter.Frame): class ExceptionDialog(tkinter.Frame):
def __init__(self, root, text): def __init__(self, root, text):
Tkinter.Frame.__init__(self, root, border=5) tkinter.Frame.__init__(self, root, border=5)
label = Tkinter.Label(self, text=u"Unexpected error:", label = tkinter.Label(self, text=u"Unexpected error:",
anchor=Tkconstants.W, justify=Tkconstants.LEFT) anchor=tkinter.constants.W, justify=tkinter.constants.LEFT)
label.pack(fill=Tkconstants.X, expand=0) label.pack(fill=tkinter.constants.X, expand=0)
self.text = Tkinter.Text(self) self.text = tkinter.Text(self)
self.text.pack(fill=Tkconstants.BOTH, expand=1) self.text.pack(fill=tkinter.constants.BOTH, expand=1)
self.text.insert(Tkconstants.END, text) self.text.insert(tkinter.constants.END, text)
argv=unicode_argv() argv=unicode_argv()
root = Tkinter.Tk() root = tkinter.Tk()
root.withdraw() root.withdraw()
progpath, progname = os.path.split(argv[0]) progpath, progname = os.path.split(argv[0])
success = False success = False
@ -584,17 +579,17 @@ def gui_main():
if not os.path.exists(outfile): if not os.path.exists(outfile):
break break
with file(outfile, 'wb') as keyfileout: with open(outfile, 'wb') as keyfileout:
keyfileout.write(key) keyfileout.write(key)
success = True success = True
tkMessageBox.showinfo(progname, u"Key successfully retrieved to {0}".format(outfile)) tkinter.messagebox.showinfo(progname, u"Key successfully retrieved to {0}".format(outfile))
except ADEPTError as e: except ADEPTError as e:
tkMessageBox.showerror(progname, u"Error: {0}".format(str(e))) tkinter.messagebox.showerror(progname, u"Error: {0}".format(str(e)))
except Exception: except Exception:
root.wm_state('normal') root.wm_state('normal')
root.title(progname) root.title(progname)
text = traceback.format_exc() text = traceback.format_exc()
ExceptionDialog(root, text).pack(fill=Tkconstants.BOTH, expand=1) ExceptionDialog(root, text).pack(fill=tkinter.constants.BOTH, expand=1)
root.mainloop() root.mainloop()
if not success: if not success:
return 1 return 1