epub tools v2 from i♥cabbages

This commit is contained in:
i♥cabbages 2009-09-01 17:02:35 +01:00 committed by Apprentice Alf
parent 437fb4adad
commit b47e8a2394
2 changed files with 57 additions and 12 deletions

View file

@ -1,14 +1,15 @@
#! /usr/bin/python #! /usr/bin/python
# adeptdecrypt.pyw, version 1 # ineptepub.pyw, version 2
# To run this program install Python 2.6 from http://www.python.org/download/ # To run this program install Python 2.6 from http://www.python.org/download/
# and PyCrypto from http://www.voidspace.org.uk/python/modules.shtml#pycrypto # and PyCrypto from http://www.voidspace.org.uk/python/modules.shtml#pycrypto
# (make sure to install the version for Python 2.6). Save this script file as # (make sure to install the version for Python 2.6). Save this script file as
# adeptdecrypt.pyw and double-click on it to run it. # ineptepub.pyw and double-click on it to run it.
# Revision history: # Revision history:
# 1 - Initial release # 1 - Initial release
# 2 - Rename to INEPT, fix exit code
""" """
Decrypt Adobe ADEPT-encrypted EPUB books. Decrypt Adobe ADEPT-encrypted EPUB books.
@ -323,15 +324,16 @@ def gui_main():
if AES is None: if AES is None:
root.withdraw() root.withdraw()
tkMessageBox.showerror( tkMessageBox.showerror(
"ADEPT Decrypt", "INEPT EPUB Decrypter",
"This script requires PyCrypto, which must be installed " "This script requires PyCrypto, which must be installed "
"separately. Read the top-of-script comment for details.") "separately. Read the top-of-script comment for details.")
return 1 return 1
root.title('ADEPT Decrypt') root.title('INEPT EPUB Decrypter')
root.resizable(True, False) root.resizable(True, False)
root.minsize(300, 0) root.minsize(300, 0)
DecryptionDialog(root).pack(fill=Tkconstants.X, expand=1) DecryptionDialog(root).pack(fill=Tkconstants.X, expand=1)
root.mainloop() root.mainloop()
return 0
if __name__ == '__main__': if __name__ == '__main__':
# sys.exit(cli_main()) # sys.exit(cli_main())

View file

@ -1,15 +1,17 @@
#! /usr/bin/python #! /usr/bin/python
# adeptkey.pyw, version 1 # ineptkey.pyw, version 3
# To run this program install Python 2.6 from http://www.python.org/download/ # To run this program install Python 2.6 from http://www.python.org/download/
# and PyCrypto from http://www.voidspace.org.uk/python/modules.shtml#pycrypto # and PyCrypto from http://www.voidspace.org.uk/python/modules.shtml#pycrypto
# (make sure to install the version for Python 2.6). Save this script file as # (make sure to install the version for Python 2.6). Save this script file as
# adeptkey.pyw and double-click on it to run it. It will create a file named # ineptkey.pyw and double-click on it to run it. It will create a file named
# adeptkey.der in the same directory. This is your ADEPT user key. # adeptkey.der in the same directory. This is your ADEPT user key.
# Revision history: # Revision history:
# 1 - Initial release, for Adobe Digital Editions 1.7 # 1 - Initial release, for Adobe Digital Editions 1.7
# 2 - Better algorithm for finding pLK; improved error handling
# 3 - Rename to INEPT
""" """
Retrieve Adobe ADEPT user key under Windows. Retrieve Adobe ADEPT user key under Windows.
@ -27,7 +29,9 @@ from ctypes import windll, c_char_p, c_wchar_p, c_uint, POINTER, byref, \
string_at, Structure, c_void_p, cast string_at, Structure, c_void_p, cast
import _winreg as winreg import _winreg as winreg
import Tkinter import Tkinter
import Tkconstants
import tkMessageBox import tkMessageBox
import traceback
try: try:
from Crypto.Cipher import AES from Crypto.Cipher import AES
@ -36,7 +40,7 @@ except ImportError:
DEVICE_KEY = 'Software\\Adobe\\Adept\\Device' DEVICE_KEY = 'Software\\Adobe\\Adept\\Device'
PRIVATE_LICENCE_KEY_KEY = 'Software\\Adobe\\Adept\\Activation\\0000\\0003' PRIVATE_LICENCE_KEY_KEY = 'Software\\Adobe\\Adept\\Activation\\%04d\\%04d'
MAX_PATH = 255 MAX_PATH = 255
@ -45,6 +49,10 @@ advapi32 = windll.advapi32
crypt32 = windll.crypt32 crypt32 = windll.crypt32
class ADEPTError(Exception):
pass
def GetSystemDirectory(): def GetSystemDirectory():
GetSystemDirectoryW = kernel32.GetSystemDirectoryW GetSystemDirectoryW = kernel32.GetSystemDirectoryW
GetSystemDirectoryW.argtypes = [c_wchar_p, c_uint] GetSystemDirectoryW.argtypes = [c_wchar_p, c_uint]
@ -120,7 +128,7 @@ def CryptUnprotectData():
outdata = DataBlob() outdata = DataBlob()
if not _CryptUnprotectData(byref(indata), None, byref(entropy), if not _CryptUnprotectData(byref(indata), None, byref(entropy),
None, None, 0, byref(outdata)): None, None, 0, byref(outdata)):
raise RuntimeError("Failed to decrypt user key key (sic)") raise ADEPTError("Failed to decrypt user key key (sic)")
return string_at(outdata.pbData, outdata.cbData) return string_at(outdata.pbData, outdata.cbData)
return CryptUnprotectData return CryptUnprotectData
CryptUnprotectData = CryptUnprotectData() CryptUnprotectData = CryptUnprotectData()
@ -134,11 +142,29 @@ def retrieve_key(keypath):
user = GetUserName() user = GetUserName()
entropy = pack('>I12s3s13s', serial, vendor, signature, user) entropy = pack('>I12s3s13s', serial, vendor, signature, user)
cuser = winreg.HKEY_CURRENT_USER cuser = winreg.HKEY_CURRENT_USER
regkey = winreg.OpenKey(cuser, DEVICE_KEY) try:
regkey = winreg.OpenKey(cuser, DEVICE_KEY)
except WindowsError:
raise ADEPTError("Adobe Digital Editions not activated")
device = winreg.QueryValueEx(regkey, 'key')[0] device = winreg.QueryValueEx(regkey, 'key')[0]
keykey = CryptUnprotectData(device, entropy) keykey = CryptUnprotectData(device, entropy)
regkey = winreg.OpenKey(cuser, PRIVATE_LICENCE_KEY_KEY) userkey = None
userkey = winreg.QueryValueEx(regkey, 'value')[0] for i in xrange(0, 16):
for j in xrange(0, 16):
plkkey = PRIVATE_LICENCE_KEY_KEY % (i, j)
try:
regkey = winreg.OpenKey(cuser, plkkey)
except WindowsError:
break
type = winreg.QueryValueEx(regkey, None)[0]
if type != 'privateLicenseKey':
continue
userkey = winreg.QueryValueEx(regkey, 'value')[0]
break
if userkey is not None:
break
if userkey is None:
raise ADEPTError('Could not locate privateLicenseKey')
userkey = userkey.decode('base64') userkey = userkey.decode('base64')
userkey = AES.new(keykey, AES.MODE_CBC).decrypt(userkey) userkey = AES.new(keykey, AES.MODE_CBC).decrypt(userkey)
userkey = userkey[26:-ord(userkey[-1])] userkey = userkey[26:-ord(userkey[-1])]
@ -146,6 +172,16 @@ def retrieve_key(keypath):
f.write(userkey) f.write(userkey)
return return
class ExceptionDialog(Tkinter.Frame):
def __init__(self, root, text):
Tkinter.Frame.__init__(self, root, border=5)
label = Tkinter.Label(self, text="Unexpected error:",
anchor=Tkconstants.W, justify=Tkconstants.LEFT)
label.pack(fill=Tkconstants.X, expand=0)
self.text = Tkinter.Text(self)
self.text.pack(fill=Tkconstants.BOTH, expand=1)
self.text.insert(Tkconstants.END, text)
def main(argv=sys.argv): def main(argv=sys.argv):
root = Tkinter.Tk() root = Tkinter.Tk()
@ -160,9 +196,16 @@ def main(argv=sys.argv):
keypath = 'adeptkey.der' keypath = 'adeptkey.der'
try: try:
retrieve_key(keypath) retrieve_key(keypath)
except Exception, e: except ADEPTError, e:
tkMessageBox.showerror("ADEPT Key", "Error: " + str(e)) tkMessageBox.showerror("ADEPT Key", "Error: " + str(e))
return 1 return 1
except Exception:
root.wm_state('normal')
root.title('ADEPT Key')
text = traceback.format_exc()
ExceptionDialog(root, text).pack(fill=Tkconstants.BOTH, expand=1)
root.mainloop()
return 1
tkMessageBox.showinfo( tkMessageBox.showinfo(
"ADEPT Key", "Key successfully retrieved to %s" % (keypath)) "ADEPT Key", "Key successfully retrieved to %s" % (keypath))
return 0 return 0