From a2f044e672e301a5a0166e426a77620c8f2162c3 Mon Sep 17 00:00:00 2001 From: Apprentice Alf Date: Tue, 26 Mar 2013 16:38:18 +0000 Subject: [PATCH] tools v6.0.1 --- .../DeDRM.app/Contents/Info.plist | 6 +- .../DeDRM.app/Contents/Resources/__init__.py | 3 +- .../DeDRM.app/Contents/Resources/adobekey.py | 9 +- .../DeDRM.app/Contents/Resources/epubtest.py | 109 ++- .../DeDRM.app/Contents/Resources/erdr2pml.py | 6 +- .../Contents/Resources/ignobleepub.py | 6 +- .../Contents/Resources/ignoblekeygen.py | 6 +- .../DeDRM.app/Contents/Resources/ineptepub.py | 6 +- .../DeDRM.app/Contents/Resources/ineptpdf.py | 6 +- .../Contents/Resources/k4mobidedrm.py | 6 +- .../DeDRM.app/Contents/Resources/kindlekey.py | 44 +- .../DeDRM.app/Contents/Resources/kindlepid.py | 4 +- .../DeDRM.app/Contents/Resources/mobidedrm.py | 6 +- .../Contents/Resources/scriptinterface.py | 176 +++++ .../Contents/Resources/topazextract.py | 10 +- .../DeDRM_App/DeDRM_Drop_Target.bat | 2 +- .../DeDRM_App/DeDRM_lib/DeDRM_app.pyw | 62 +- .../DeDRM_App/DeDRM_lib/lib/__init__.py | 3 +- .../DeDRM_App/DeDRM_lib/lib/adobekey.py | 9 +- .../DeDRM_App/DeDRM_lib/lib/epubtest.py | 109 ++- .../DeDRM_App/DeDRM_lib/lib/erdr2pml.py | 6 +- .../DeDRM_App/DeDRM_lib/lib/getk4pcpids.py | 84 -- .../DeDRM_App/DeDRM_lib/lib/ignobleepub.py | 6 +- .../DeDRM_App/DeDRM_lib/lib/ignoblekeygen.py | 6 +- .../DeDRM_App/DeDRM_lib/lib/ineptepub.py | 6 +- .../DeDRM_App/DeDRM_lib/lib/ineptkey.py | 512 ------------ .../DeDRM_App/DeDRM_lib/lib/ineptpdf.py | 6 +- .../DeDRM_App/DeDRM_lib/lib/k4mobidedrm.py | 6 +- .../DeDRM_App/DeDRM_lib/lib/k4mutils.py | 747 ------------------ .../DeDRM_App/DeDRM_lib/lib/k4pcutils.py | 457 ----------- .../DeDRM_App/DeDRM_lib/lib/kindlekey.py | 44 +- .../DeDRM_App/DeDRM_lib/lib/kindlepid.py | 4 +- .../DeDRM_App/DeDRM_lib/lib/mobidedrm.py | 6 +- .../DeDRM_lib/lib/scriptinterface.py | 19 +- .../DeDRM_App/DeDRM_lib/lib/subasyncio.py | 148 ---- .../DeDRM_App/DeDRM_lib/lib/topazextract.py | 10 +- DeDRM_calibre_plugin/DeDRM_plugin.zip | Bin 319654 -> 320760 bytes DeDRM_calibre_plugin/DeDRM_plugin/__init__.py | 3 +- DeDRM_calibre_plugin/DeDRM_plugin/adobekey.py | 13 +- DeDRM_calibre_plugin/DeDRM_plugin/config.py | 12 +- DeDRM_calibre_plugin/DeDRM_plugin/dialogs.py | 13 +- DeDRM_calibre_plugin/DeDRM_plugin/epubtest.py | 109 ++- DeDRM_calibre_plugin/DeDRM_plugin/erdr2pml.py | 6 +- .../DeDRM_plugin/ignobleepub.py | 6 +- .../DeDRM_plugin/ignoblekeygen.py | 6 +- .../DeDRM_plugin/ineptepub.py | 6 +- DeDRM_calibre_plugin/DeDRM_plugin/ineptpdf.py | 6 +- .../DeDRM_plugin/k4mobidedrm.py | 6 +- .../DeDRM_plugin/kindlekey.py | 44 +- .../DeDRM_plugin/kindlepid.py | 4 +- .../DeDRM_plugin/mobidedrm.py | 6 +- .../DeDRM_plugin/topazextract.py | 10 +- DeDRM_calibre_plugin/DeDRM_plugin_ReadMe.txt | 2 +- .../BN-Dload.user.js | 0 .../BN-Dload.user_ReadMe.txt | 0 .../Adobe_Digital_Editions/adobekey.pyw | 9 +- .../Barnes_and_Noble_ePubs/ignoblekeygen.pyw | 6 +- .../Kindle_for_Mac_and_PC/kindlekey.pyw | 10 +- ReadMe_First.txt | 19 +- 59 files changed, 704 insertions(+), 2247 deletions(-) create mode 100644 DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/scriptinterface.py delete mode 100644 DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/getk4pcpids.py delete mode 100644 DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptkey.py delete mode 100644 DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mutils.py delete mode 100644 DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4pcutils.py delete mode 100644 DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/subasyncio.py rename Other_Tools/{B&N_Download_Helper => B_and_N_Download_Helper}/BN-Dload.user.js (100%) rename Other_Tools/{B&N_Download_Helper => B_and_N_Download_Helper}/BN-Dload.user_ReadMe.txt (100%) diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist index 646912c..2069280 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist @@ -24,17 +24,17 @@ CFBundleExecutable droplet CFBundleGetInfoString - DeDRM AppleScript 6.0.0. Written 2010–2013 by Apprentice Alf and others. + DeDRM AppleScript 6.0.1. Written 2010–2013 by Apprentice Alf and others. CFBundleIconFile DeDRM CFBundleInfoDictionaryVersion 6.0 CFBundleName - DeDRM AppleScript + DeDRM CFBundlePackageType APPL CFBundleShortVersionString - 6.0.0 + 6.0.1 CFBundleSignature dplt LSRequiresCarbon diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py index a9ac2fd..6509179 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py @@ -26,13 +26,14 @@ __docformat__ = 'restructuredtext en' # # Revision history: # 6.0.0 - Initial release +# 6.0.1 - Bug Fixes for Windows App """ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 0, 0) +PLUGIN_VERSION_TUPLE = (6, 0, 1) PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE]) # Include an html helpfile in the plugin's zipfile with the following name. RESOURCE_NAME = PLUGIN_NAME + '_Help.htm' diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/adobekey.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/adobekey.py index 94f7522..1dcef1d 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/adobekey.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/adobekey.py @@ -46,13 +46,14 @@ from __future__ import with_statement # 5.6 - Revised to allow use in Plugins to eliminate need for duplicate code # 5.7 - Unicode support added, renamed adobekey from ineptkey # 5.8 - Added getkey interface for Windows DeDRM application +# 5.9 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Retrieve Adobe ADEPT user key. """ __license__ = 'GPL v3' -__version__ = '5.8' +__version__ = '5.9' import sys, os, struct, getopt @@ -483,7 +484,8 @@ def usage(progname): print u"Usage:" print u" {0:s} [-h] []".format(progname) -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"{0} v{1}\nCopyright © 2009-2013 i♥cabbages and Apprentice Alf".format(progname,__version__) @@ -538,7 +540,7 @@ def cli_main(argv=unicode_argv()): return 0 -def gui_main(argv=unicode_argv()): +def gui_main(): import Tkinter import Tkconstants import tkMessageBox @@ -556,6 +558,7 @@ def gui_main(argv=unicode_argv()): self.text.insert(Tkconstants.END, text) + argv=unicode_argv() root = Tkinter.Tk() root.withdraw() progpath, progname = os.path.split(argv[0]) diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/epubtest.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/epubtest.py index d91624f..11f1427 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/epubtest.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/epubtest.py @@ -9,6 +9,7 @@ # # Changelog epubtest # 1.00 - Cut to epubtest.py, testing ePub files only by Apprentice Alf +# 1.01 - Added routine for use by Windows DeDRM # # Written in 2011 by Paul Durrant # Released with unlicense. See http://unlicense.org/ @@ -45,7 +46,7 @@ from __future__ import with_statement -__version__ = '1.00' +__version__ = '1.01' import sys, struct, os import zlib @@ -72,11 +73,49 @@ class SafeUnbuffered: def __getattr__(self, attr): return getattr(self.stream, attr) +try: + from calibre.constants import iswindows, isosx +except: + iswindows = sys.platform.startswith('win') + isosx = sys.platform.startswith('darwin') + def unicode_argv(): - argvencoding = sys.stdin.encoding - if argvencoding == None: - argvencoding = "utf-8" - return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv] + if iswindows: + # Uses shell32.GetCommandLineArgvW to get sys.argv as a list of Unicode + # strings. + + # Versions 2.x of Python don't support Unicode in sys.argv on + # Windows, with the underlying Windows API instead replacing multi-byte + # characters with '?'. So use shell32.GetCommandLineArgvW to get sys.argv + # as a list of Unicode strings and encode them as utf-8 + + from ctypes import POINTER, byref, cdll, c_int, windll + from ctypes.wintypes import LPCWSTR, LPWSTR + + GetCommandLineW = cdll.kernel32.GetCommandLineW + GetCommandLineW.argtypes = [] + GetCommandLineW.restype = LPCWSTR + + CommandLineToArgvW = windll.shell32.CommandLineToArgvW + CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)] + CommandLineToArgvW.restype = POINTER(LPWSTR) + + cmd = GetCommandLineW() + argc = c_int(0) + argv = CommandLineToArgvW(cmd, byref(argc)) + if argc.value > 0: + # Remove Python executable and commands if present + start = argc.value - len(sys.argv) + return [argv[i] for i in + xrange(start, argc.value)] + # if we don't have any arguments at all, just pass back script name + # this should never happen + return [u"epubtest.py"] + else: + argvencoding = sys.stdin.encoding + if argvencoding == None: + argvencoding = "utf-8" + return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv] _FILENAME_LEN_OFFSET = 26 _EXTRA_LEN_OFFSET = 28 @@ -129,38 +168,38 @@ def getfiledata(file, zi): return data -def main(argv=unicode_argv()): - infile = argv[1] - kind = "Unknown" +def encryption(infile): + # returns encryption: one of Unencrypted, Adobe, B&N and Unknown encryption = "Unknown" - with file(infile,'rb') as infileobject: - bookdata = infileobject.read(58) - # Check for Mobipocket/Kindle - if bookdata[0:0+2] == "PK": - if bookdata[30:30+28] == 'mimetypeapplication/epub+zip': - kind = "ePub" - else: - kind = "ZIP" - encryption = "Unencrypted" - foundrights = False - foundencryption = False - inzip = zipfile.ZipFile(infile,'r') - namelist = set(inzip.namelist()) - if 'META-INF/rights.xml' not in namelist or 'META-INF/encryption.xml' not in namelist: - encryption = "Unencrypted" - else: - rights = etree.fromstring(inzip.read('META-INF/rights.xml')) - adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag) - expr = './/%s' % (adept('encryptedKey'),) - bookkey = ''.join(rights.findtext(expr)) - if len(bookkey) == 172: - encryption = "Adobe" - elif len(bookkey) == 64: - encryption = "B&N" + try: + with open(infile,'rb') as infileobject: + bookdata = infileobject.read(58) + # Check for Zip + if bookdata[0:0+2] == "PK": + foundrights = False + foundencryption = False + inzip = zipfile.ZipFile(infile,'r') + namelist = set(inzip.namelist()) + if 'META-INF/rights.xml' not in namelist or 'META-INF/encryption.xml' not in namelist: + encryption = "Unencrypted" else: - encryption = "Unknown" - - print u"{0} {1}".format(encryption, kind) + rights = etree.fromstring(inzip.read('META-INF/rights.xml')) + adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag) + expr = './/%s' % (adept('encryptedKey'),) + bookkey = ''.join(rights.findtext(expr)) + if len(bookkey) == 172: + encryption = "Adobe" + elif len(bookkey) == 64: + encryption = "B&N" + else: + encryption = "Unknown" + except: + traceback.print_exc() + return encryption + +def main(): + argv=unicode_argv() + print encryption(argv[1]) return 0 if __name__ == "__main__": diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/erdr2pml.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/erdr2pml.py index d982a44..1dfef42 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/erdr2pml.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/erdr2pml.py @@ -66,8 +66,9 @@ # - Don't reject dictionary format. # - Ignore sidebars for dictionaries (different format?) # 0.22 - Unicode and plugin support, different image folders for PMLZ and source +# 0.23 - moved unicode_argv call inside main for Windows DeDRM compatibility -__version__='0.22' +__version__='0.23' import sys, re import struct, binascii, getopt, zlib, os, os.path, urllib, tempfile, traceback @@ -551,9 +552,10 @@ def getuser_key(name,cc): cc = cc.replace(" ","") return struct.pack('>LL', binascii.crc32(newname) & 0xffffffff,binascii.crc32(cc[-8:])& 0xffffffff) -def cli_main(argv=unicode_argv()): +def cli_main(): print u"eRdr2Pml v{0}. Copyright © 2009–2012 The Dark Reverser et al.".format(__version__) + argv=unicode_argv() try: opts, args = getopt.getopt(argv[1:], "hp", ["make-pmlz"]) except getopt.GetoptError, err: diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignobleepub.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignobleepub.py index 4cf74ae..277cdde 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignobleepub.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignobleepub.py @@ -33,13 +33,14 @@ from __future__ import with_statement # 3.6 - Revised to allow use in calibre plugins to eliminate need for duplicate code # 3.7 - Tweaked to match ineptepub more closely # 3.8 - Fixed to retain zip file metadata (e.g. file modification date) +# 3.9 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Decrypt Barnes & Noble encrypted ePub books. """ __license__ = 'GPL v3' -__version__ = "3.8" +__version__ = "3.9" import sys import os @@ -316,7 +317,8 @@ def decryptBook(keyb64, inpath, outpath): return 0 -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv) != 4: print u"usage: {0} ".format(progname) diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeygen.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeygen.py index ec78e65..a6e5dca 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeygen.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ignoblekeygen.py @@ -31,13 +31,14 @@ from __future__ import with_statement # 2.3 - Modify interface to allow use of import # 2.4 - Improvements to UI and now works in plugins # 2.5 - Additional improvement for unicode and plugin support +# 2.6 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Generate Barnes & Noble EPUB user key from name and credit card number. """ __license__ = 'GPL v3' -__version__ = "2.5" +__version__ = "2.6" import sys import os @@ -214,7 +215,8 @@ def generate_key(name, ccn): -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if AES is None: print "%s: This script requires OpenSSL or PyCrypto, which must be installed " \ diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py index 98a134e..3fe07d9 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptepub.py @@ -35,13 +35,14 @@ from __future__ import with_statement # 5.7 - Fix for potential problem with PyCrypto # 5.8 - Revised to allow use in calibre plugins to eliminate need for duplicate code # 5.9 - Fixed to retain zip file metadata (e.g. file modification date) +# 5.10 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Decrypt Adobe Digital Editions encrypted ePub books. """ __license__ = 'GPL v3' -__version__ = "5.9" +__version__ = "5.10" import sys import os @@ -458,7 +459,8 @@ def decryptBook(userkey, inpath, outpath): return 0 -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv) != 4: print u"usage: {0} ".format(progname) diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py index f4d6d81..69028c6 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/ineptpdf.py @@ -50,13 +50,14 @@ from __future__ import with_statement # 7.11 - More tweaks to fix minor problems. # 7.12 - Revised to allow use in calibre plugins to eliminate need for duplicate code # 7.13 - Fixed erroneous mentions of ineptepub +# 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Decrypts Adobe ADEPT-encrypted PDF files. """ __license__ = 'GPL v3' -__version__ = "7.13" +__version__ = "7.14" import sys import os @@ -2185,7 +2186,8 @@ def decryptBook(userkey, inpath, outpath): return 0 -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv) != 4: print u"usage: {0} ".format(progname) diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/k4mobidedrm.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/k4mobidedrm.py index 1ae5c88..e15f104 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/k4mobidedrm.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/k4mobidedrm.py @@ -53,8 +53,9 @@ from __future__ import with_statement # 4.9 - Missed some invalid characters in cleanup_name # 5.0 - Extraction of info from Kindle for PC/Mac moved into kindlekey.py # - tweaked GetDecryptedBook interface to leave passed parameters unchanged +# 5.1 - moved unicode_argv call inside main for Windows DeDRM compatibility -__version__ = '5.0' +__version__ = '5.1' import sys, os, re @@ -276,7 +277,8 @@ def usage(progname): # # Main # -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"K4MobiDeDrm v{0}.\nCopyright © 2008-2013 The Dark Reverser et al.".format(__version__) diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py index e79622b..453de14 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py @@ -15,13 +15,16 @@ from __future__ import with_statement # 1.3 - Added getkey interface for Windows DeDRM application # Simplified some of the Kindle for Mac code. # 1.4 - Remove dependency on alfcrypto +# 1.5 - moved unicode_argv call inside main for Windows DeDRM compatibility +# 1.6 - Fixed a problem getting the disk serial numbers + """ Retrieve Kindle for PC/Mac user key. """ __license__ = 'GPL v3' -__version__ = '1.4' +__version__ = '1.6' import sys, os, re from struct import pack, unpack, unpack_from @@ -1266,10 +1269,10 @@ elif isosx: # uses a sub process to get the Hard Drive Serial Number using ioreg # returns serial numbers of all internal hard drive drives def GetVolumesSerialNumbers(): + sernums = [] sernum = os.getenv('MYSERIALNUMBER') if sernum != None: - return [sernum] - sernums = [] + sernums.append(sernum.strip()) cmdline = '/usr/sbin/ioreg -w 0 -r -c AppleAHCIDiskDriver' cmdline = cmdline.encode(sys.getfilesystemencoding()) p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) @@ -1285,7 +1288,7 @@ elif isosx: if pp >= 0: sernum = resline[pp+19:-1] sernums.append(sernum.strip()) - return [sernum] + return sernums def GetUserHomeAppSupKindleDirParitionName(): home = os.getenv('HOME') @@ -1311,10 +1314,11 @@ elif isosx: return disk # uses a sub process to get the UUID of the specified disk partition using ioreg - def GetDiskPartitionUUID(diskpart): + def GetDiskPartitionUUIDs(diskpart): + uuids = [] uuidnum = os.getenv('MYUUIDNUMBER') if uuidnum != None: - return uuidnum + uuids.append(strip(uuidnum)) cmdline = '/usr/sbin/ioreg -l -S -w 0 -r -c AppleAHCIDiskDriver' cmdline = cmdline.encode(sys.getfilesystemencoding()) p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) @@ -1357,14 +1361,15 @@ elif isosx: uuidnest = -1 uuidnum = None bsdname = None - if not foundIt: - uuidnum = '' - return uuidnum + if foundIt: + uuids.append(uuidnum) + return uuids - def GetMACAddressMunged(): + def GetMACAddressesMunged(): + macnums = [] macnum = os.getenv('MYMACNUM') if macnum != None: - return macnum + macnums.append(macnum) cmdline = '/sbin/ifconfig en0' cmdline = cmdline.encode(sys.getfilesystemencoding()) p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) @@ -1399,9 +1404,9 @@ elif isosx: macnum = '%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x' % (mlst[0], mlst[1], mlst[2], mlst[3], mlst[4], mlst[5]) foundIt = True break - if not foundIt: - macnum = '' - return macnum + if foundIt: + macnums.append(macnum) + return macnums # uses unix env to get username instead of using sysctlbyname @@ -1412,11 +1417,12 @@ elif isosx: def GetIDStrings(): # Return all possible ID Strings strings = [] - strings.append(GetMACAddressMunged()) + strings.extend(GetMACAddressesMunged()) strings.extend(GetVolumesSerialNumbers()) diskpart = GetUserHomeAppSupKindleDirParitionName() - strings.append(GetDiskPartitionUUID(diskpart)) + strings.extend(GetDiskPartitionUUIDs(diskpart)) strings.append('9999999999') + #print strings return strings @@ -1797,7 +1803,8 @@ def usage(progname): print u" {0:s} [-h] [-k ] []".format(progname) -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"{0} v{1}\nCopyright © 2010-2013 some_updates and Apprentice Alf".format(progname,__version__) @@ -1837,7 +1844,7 @@ def cli_main(argv=unicode_argv()): return 0 -def gui_main(argv=unicode_argv()): +def gui_main(): import Tkinter import Tkconstants import tkMessageBox @@ -1855,6 +1862,7 @@ def gui_main(argv=unicode_argv()): self.text.insert(Tkconstants.END, text) + argv=unicode_argv() root = Tkinter.Tk() root.withdraw() progpath, progname = os.path.split(argv[0]) diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlepid.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlepid.py index d16c017..8bbcf69 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlepid.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlepid.py @@ -9,6 +9,7 @@ # 0.3 changed to autoflush stdout, fixed return code usage # 0.3 updated for unicode # 0.4 Added support for serial numbers starting with '9', fixed unicode bugs. +# 0.5 moved unicode_argv call inside main for Windows DeDRM compatibility import sys import binascii @@ -111,8 +112,9 @@ def pidFromSerial(s, l): return pid -def cli_main(argv=unicode_argv()): +def cli_main(): print u"Mobipocket PID calculator for Amazon Kindle. Copyright © 2007, 2009 Igor Skochinsky" + argv=unicode_argv() if len(argv)==2: serial = argv[1] else: diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py index ccbac4e..ee24de5 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/mobidedrm.py @@ -67,9 +67,10 @@ # 0.37 - Fixed double announcement for stand-alone operation # 0.38 - Unicode used wherever possible, cope with absent alfcrypto # 0.39 - Fixed problem with TEXtREAd and getBookType interface +# 0.40 - moved unicode_argv call inside main for Windows DeDRM compatibility -__version__ = u"0.39" +__version__ = u"0.40" import sys import os @@ -506,7 +507,8 @@ def getUnencryptedBook(infile,pidlist): return book.mobi_data -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv)<3 or len(argv)>4: print u"MobiDeDrm v{0}.\nCopyright © 2008-2012 The Dark Reverser et al.".format(__version__) diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/scriptinterface.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/scriptinterface.py new file mode 100644 index 0000000..3be643f --- /dev/null +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/scriptinterface.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab + +import sys +import os +import re +import ineptepub +import ignobleepub +import epubtest +import zipfix +import ineptpdf +import erdr2pml +import k4mobidedrm +import traceback + +def decryptepub(infile, outdir, rscpath): + errlog = '' + + # first fix the epub to make sure we do not get errors + name, ext = os.path.splitext(os.path.basename(infile)) + bpath = os.path.dirname(infile) + zippath = os.path.join(bpath,name + '_temp.zip') + rv = zipfix.repairBook(infile, zippath) + if rv != 0: + print "Error while trying to fix epub" + return rv + + # determine a good name for the output file + outfile = os.path.join(outdir, name + '_nodrm.epub') + + rv = 1 + # first try with the Adobe adept epub + if ineptepub.adeptBook(zippath): + # try with any keyfiles (*.der) in the rscpath + files = os.listdir(rscpath) + filefilter = re.compile("\.der$", re.IGNORECASE) + files = filter(filefilter.search, files) + if files: + for filename in files: + keypath = os.path.join(rscpath, filename) + userkey = open(keypath,'rb').read() + try: + rv = ineptepub.decryptBook(userkey, zippath, outfile) + if rv == 0: + print "Decrypted Adobe ePub with key file {0}".format(filename) + break + except Exception, e: + errlog += traceback.format_exc() + errlog += str(e) + rv = 1 + # now try with ignoble epub + elif ignobleepub.ignobleBook(zippath): + # try with any keyfiles (*.b64) in the rscpath + files = os.listdir(rscpath) + filefilter = re.compile("\.b64$", re.IGNORECASE) + files = filter(filefilter.search, files) + if files: + for filename in files: + keypath = os.path.join(rscpath, filename) + userkey = open(keypath,'r').read() + #print userkey + try: + rv = ignobleepub.decryptBook(userkey, zippath, outfile) + if rv == 0: + print "Decrypted B&N ePub with key file {0}".format(filename) + break + except Exception, e: + errlog += traceback.format_exc() + errlog += str(e) + rv = 1 + else: + encryption = epubtest.encryption(zippath) + if encryption == "Unencrypted": + print "{0} is not DRMed.".format(name) + rv = 0 + else: + print "{0} has an unknown encryption.".format(name) + + os.remove(zippath) + if rv != 0: + print errlog + return rv + + +def decryptpdf(infile, outdir, rscpath): + errlog = '' + rv = 1 + + # determine a good name for the output file + name, ext = os.path.splitext(os.path.basename(infile)) + outfile = os.path.join(outdir, name + '_nodrm.pdf') + + # try with any keyfiles (*.der) in the rscpath + files = os.listdir(rscpath) + filefilter = re.compile("\.der$", re.IGNORECASE) + files = filter(filefilter.search, files) + if files: + for filename in files: + keypath = os.path.join(rscpath, filename) + userkey = open(keypath,'rb').read() + try: + rv = ineptpdf.decryptBook(userkey, infile, outfile) + if rv == 0: + break + except Exception, e: + errlog += traceback.format_exc() + errlog += str(e) + rv = 1 + + if rv != 0: + print errlog + return rv + + +def decryptpdb(infile, outdir, rscpath): + outname = os.path.splitext(os.path.basename(infile))[0] + ".pmlz" + outpath = os.path.join(outdir, outname) + rv = 1 + socialpath = os.path.join(rscpath,'sdrmlist.txt') + if os.path.exists(socialpath): + keydata = file(socialpath,'r').read() + keydata = keydata.rstrip(os.linesep) + ar = keydata.split(',') + for i in ar: + try: + name, cc8 = i.split(':') + except ValueError: + print ' Error parsing user supplied social drm data.' + return 1 + try: + rv = erdr2pml.decryptBook(infile, outpath, True, erdr2pml.getuser_key(name, cc8)) + except Exception, e: + errlog += traceback.format_exc() + errlog += str(e) + rv = 1 + + if rv == 0: + break + return rv + + +def decryptk4mobi(infile, outdir, rscpath): + rv = 1 + pidnums = [] + pidspath = os.path.join(rscpath,'pidlist.txt') + if os.path.exists(pidspath): + pidstr = file(pidspath,'r').read() + pidstr = pidstr.rstrip(os.linesep) + pidstr = pidstr.strip() + if pidstr != '': + pidnums = pidstr.split(',') + serialnums = [] + serialnumspath = os.path.join(rscpath,'seriallist.txt') + if os.path.exists(serialnumspath): + serialstr = file(serialnumspath,'r').read() + serialstr = serialstr.rstrip(os.linesep) + serialstr = serialstr.strip() + if serialstr != '': + serialnums = serialstr.split(',') + kDatabaseFiles = [] + files = os.listdir(rscpath) + filefilter = re.compile("\.k4i$", re.IGNORECASE) + files = filter(filefilter.search, files) + if files: + for filename in files: + dpath = os.path.join(rscpath,filename) + kDatabaseFiles.append(dpath) + try: + rv = k4mobidedrm.decryptBook(infile, outdir, kDatabaseFiles, serialnums, pidnums) + except Exception, e: + errlog += traceback.format_exc() + errlog += str(e) + rv = 1 + + return rv diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/topazextract.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/topazextract.py index 71fe8ab..d44ae88 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/topazextract.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/topazextract.py @@ -1,10 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# topazextract.py, version ? +# topazextract.py # Mostly written by some_updates based on code from many others -__version__ = '4.8' +# Changelog +# 4.9 - moved unicode_argv call inside main for Windows DeDRM compatibility + +__version__ = '4.9' import sys import os, csv, getopt @@ -442,7 +445,8 @@ def usage(progname): print u" {0} [-k ] [-p ] [-s ] ".format(progname) # Main -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"TopazExtract v{0}.".format(__version__) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_Drop_Target.bat b/DeDRM_Windows_Application/DeDRM_App/DeDRM_Drop_Target.bat index 83ec8d9..97744f7 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_Drop_Target.bat +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_Drop_Target.bat @@ -1 +1 @@ -chcp 65001 > nul && set PWD=%~dp0 && cd /d %~dp0DeDRM_lib && start /min python DeDRM_app.pyw %* +chcp 65001 > nul && set PWD=%~dp0 && cd /d %~dp0DeDRM_lib && start /min python DeDRM_App.pyw %* diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_app.pyw b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_app.pyw index 40781bb..9b7bcf3 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_app.pyw +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_app.pyw @@ -1,8 +1,14 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# DeDRM.pyw, version 6.0.0 -# By some_updates and Apprentice Alf +# DeDRM.pyw, version 6.0.1 +# Copyright 2010-2013 some_updates and Apprentice Alf + +# Revision history: +# 6.0.0 - Release along with unified plugin +# 6.0.1 - Bug Fixes for Windows App + +__version__ = '6.0.1' import sys import os, os.path @@ -49,8 +55,6 @@ class QueuedUTF8Stream: def __getattr__(self, attr): return getattr(self.stream, attr) -__version__ = '6.0.0' - class DrmException(Exception): pass @@ -372,7 +376,6 @@ class ConvDialog(Toplevel): self.running = 'inactive' self.numgood = 0 self.numbad = 0 - self.log = '' self.status = Tkinter.Label(self, text='DeDRM processing...') self.status.pack(fill=Tkconstants.X, expand=1) body = Tkinter.Frame(self) @@ -395,6 +398,8 @@ class ConvDialog(Toplevel): self.qbutton.pack(side=Tkconstants.BOTTOM) self.status['text'] = '' + self.logfile = open(os.path.join(os.path.expanduser('~'),'DeDRM.log'),'w') + def show(self): self.deiconify() self.tkraise() @@ -420,20 +425,19 @@ class ConvDialog(Toplevel): if len(self.filenames) > 0: filename = self.filenames.pop(0) if filename == None: - msg = '\nComplete: ' + msg = 'Complete: ' msg += 'Successes: %d, ' % self.numgood msg += 'Failures: %d\n' % self.numbad self.showCmdOutput(msg) if self.numbad == 0: self.after(2000,self.conversion_done()) - logfile = os.path.join(os.path.expanduser('~'),'DeDRM.log') - file(logfile,'w').write(self.log) - self.log='' + self.logfile.write("DeDRM v{0}: {1}".format(__version__,msg)) + self.logfile.close() return infile = filename bname = os.path.basename(infile) - msg = 'Processing: ' + bname + ' ... ' - self.log += msg + msg = 'Processing: ' + bname + '...' + self.logfile.write("DeDRM v{0}: {1}\n".format(__version__,msg)) self.showCmdOutput(msg) outdir = os.path.dirname(filename) if 'outdir' in self.prefs_array: @@ -447,7 +451,7 @@ class ConvDialog(Toplevel): self.processQueue() else: msg = 'Unknown File: ' + bname + '\n' - self.log += msg + self.logfile.write("DeDRM v{0}: {1}".format(__version__,msg)) self.showCmdOutput(msg) self.numbad += 1 @@ -476,39 +480,32 @@ class ConvDialog(Toplevel): # nothing to wait for so just return return poll = self.p2.exitcode - print "processing", poll + #print "processing", poll + done = False + text = '' + while not done: + try: + data = self.q.get_nowait() + text += data + except Empty: + done = True + if text != '': + self.logfile.write(text) if poll != None: self.bar.stop() - done = False - text = '' - while not done: - try: - data = self.q.get_nowait() - text += data - except Empty: - done = True - self.log += text if poll == 0: msg = 'Success\n' self.numgood += 1 - self.log += msg else: msg = 'Failed\n' self.numbad += 1 - self.log += msg self.p2.join() + self.logfile.write("DeDRM v{0}: {1}\n".format(__version__,msg)) self.showCmdOutput(msg) self.p2 = None self.running = 'inactive' self.after(50,self.processBooks) return - try: - text = self.q.get_nowait() - except Empty: - text = '' - pass - if text != '': - self.log += text # make sure we get invoked again by event loop after interval self.stext.after(self.interval,self.processQueue) return @@ -574,7 +571,8 @@ def processPDB(q, infile, outdir, rscpath): sys.exit(rv) -def main(argv=unicode_argv()): +def main(): + argv=unicode_argv() apphome = os.path.dirname(argv[0]) apphome = os.path.abspath(apphome) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py index a9ac2fd..6509179 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py @@ -26,13 +26,14 @@ __docformat__ = 'restructuredtext en' # # Revision history: # 6.0.0 - Initial release +# 6.0.1 - Bug Fixes for Windows App """ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 0, 0) +PLUGIN_VERSION_TUPLE = (6, 0, 1) PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE]) # Include an html helpfile in the plugin's zipfile with the following name. RESOURCE_NAME = PLUGIN_NAME + '_Help.htm' diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/adobekey.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/adobekey.py index 94f7522..1dcef1d 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/adobekey.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/adobekey.py @@ -46,13 +46,14 @@ from __future__ import with_statement # 5.6 - Revised to allow use in Plugins to eliminate need for duplicate code # 5.7 - Unicode support added, renamed adobekey from ineptkey # 5.8 - Added getkey interface for Windows DeDRM application +# 5.9 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Retrieve Adobe ADEPT user key. """ __license__ = 'GPL v3' -__version__ = '5.8' +__version__ = '5.9' import sys, os, struct, getopt @@ -483,7 +484,8 @@ def usage(progname): print u"Usage:" print u" {0:s} [-h] []".format(progname) -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"{0} v{1}\nCopyright © 2009-2013 i♥cabbages and Apprentice Alf".format(progname,__version__) @@ -538,7 +540,7 @@ def cli_main(argv=unicode_argv()): return 0 -def gui_main(argv=unicode_argv()): +def gui_main(): import Tkinter import Tkconstants import tkMessageBox @@ -556,6 +558,7 @@ def gui_main(argv=unicode_argv()): self.text.insert(Tkconstants.END, text) + argv=unicode_argv() root = Tkinter.Tk() root.withdraw() progpath, progname = os.path.split(argv[0]) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/epubtest.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/epubtest.py index d91624f..11f1427 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/epubtest.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/epubtest.py @@ -9,6 +9,7 @@ # # Changelog epubtest # 1.00 - Cut to epubtest.py, testing ePub files only by Apprentice Alf +# 1.01 - Added routine for use by Windows DeDRM # # Written in 2011 by Paul Durrant # Released with unlicense. See http://unlicense.org/ @@ -45,7 +46,7 @@ from __future__ import with_statement -__version__ = '1.00' +__version__ = '1.01' import sys, struct, os import zlib @@ -72,11 +73,49 @@ class SafeUnbuffered: def __getattr__(self, attr): return getattr(self.stream, attr) +try: + from calibre.constants import iswindows, isosx +except: + iswindows = sys.platform.startswith('win') + isosx = sys.platform.startswith('darwin') + def unicode_argv(): - argvencoding = sys.stdin.encoding - if argvencoding == None: - argvencoding = "utf-8" - return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv] + if iswindows: + # Uses shell32.GetCommandLineArgvW to get sys.argv as a list of Unicode + # strings. + + # Versions 2.x of Python don't support Unicode in sys.argv on + # Windows, with the underlying Windows API instead replacing multi-byte + # characters with '?'. So use shell32.GetCommandLineArgvW to get sys.argv + # as a list of Unicode strings and encode them as utf-8 + + from ctypes import POINTER, byref, cdll, c_int, windll + from ctypes.wintypes import LPCWSTR, LPWSTR + + GetCommandLineW = cdll.kernel32.GetCommandLineW + GetCommandLineW.argtypes = [] + GetCommandLineW.restype = LPCWSTR + + CommandLineToArgvW = windll.shell32.CommandLineToArgvW + CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)] + CommandLineToArgvW.restype = POINTER(LPWSTR) + + cmd = GetCommandLineW() + argc = c_int(0) + argv = CommandLineToArgvW(cmd, byref(argc)) + if argc.value > 0: + # Remove Python executable and commands if present + start = argc.value - len(sys.argv) + return [argv[i] for i in + xrange(start, argc.value)] + # if we don't have any arguments at all, just pass back script name + # this should never happen + return [u"epubtest.py"] + else: + argvencoding = sys.stdin.encoding + if argvencoding == None: + argvencoding = "utf-8" + return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv] _FILENAME_LEN_OFFSET = 26 _EXTRA_LEN_OFFSET = 28 @@ -129,38 +168,38 @@ def getfiledata(file, zi): return data -def main(argv=unicode_argv()): - infile = argv[1] - kind = "Unknown" +def encryption(infile): + # returns encryption: one of Unencrypted, Adobe, B&N and Unknown encryption = "Unknown" - with file(infile,'rb') as infileobject: - bookdata = infileobject.read(58) - # Check for Mobipocket/Kindle - if bookdata[0:0+2] == "PK": - if bookdata[30:30+28] == 'mimetypeapplication/epub+zip': - kind = "ePub" - else: - kind = "ZIP" - encryption = "Unencrypted" - foundrights = False - foundencryption = False - inzip = zipfile.ZipFile(infile,'r') - namelist = set(inzip.namelist()) - if 'META-INF/rights.xml' not in namelist or 'META-INF/encryption.xml' not in namelist: - encryption = "Unencrypted" - else: - rights = etree.fromstring(inzip.read('META-INF/rights.xml')) - adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag) - expr = './/%s' % (adept('encryptedKey'),) - bookkey = ''.join(rights.findtext(expr)) - if len(bookkey) == 172: - encryption = "Adobe" - elif len(bookkey) == 64: - encryption = "B&N" + try: + with open(infile,'rb') as infileobject: + bookdata = infileobject.read(58) + # Check for Zip + if bookdata[0:0+2] == "PK": + foundrights = False + foundencryption = False + inzip = zipfile.ZipFile(infile,'r') + namelist = set(inzip.namelist()) + if 'META-INF/rights.xml' not in namelist or 'META-INF/encryption.xml' not in namelist: + encryption = "Unencrypted" else: - encryption = "Unknown" - - print u"{0} {1}".format(encryption, kind) + rights = etree.fromstring(inzip.read('META-INF/rights.xml')) + adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag) + expr = './/%s' % (adept('encryptedKey'),) + bookkey = ''.join(rights.findtext(expr)) + if len(bookkey) == 172: + encryption = "Adobe" + elif len(bookkey) == 64: + encryption = "B&N" + else: + encryption = "Unknown" + except: + traceback.print_exc() + return encryption + +def main(): + argv=unicode_argv() + print encryption(argv[1]) return 0 if __name__ == "__main__": diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/erdr2pml.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/erdr2pml.py index d982a44..1dfef42 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/erdr2pml.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/erdr2pml.py @@ -66,8 +66,9 @@ # - Don't reject dictionary format. # - Ignore sidebars for dictionaries (different format?) # 0.22 - Unicode and plugin support, different image folders for PMLZ and source +# 0.23 - moved unicode_argv call inside main for Windows DeDRM compatibility -__version__='0.22' +__version__='0.23' import sys, re import struct, binascii, getopt, zlib, os, os.path, urllib, tempfile, traceback @@ -551,9 +552,10 @@ def getuser_key(name,cc): cc = cc.replace(" ","") return struct.pack('>LL', binascii.crc32(newname) & 0xffffffff,binascii.crc32(cc[-8:])& 0xffffffff) -def cli_main(argv=unicode_argv()): +def cli_main(): print u"eRdr2Pml v{0}. Copyright © 2009–2012 The Dark Reverser et al.".format(__version__) + argv=unicode_argv() try: opts, args = getopt.getopt(argv[1:], "hp", ["make-pmlz"]) except getopt.GetoptError, err: diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/getk4pcpids.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/getk4pcpids.py deleted file mode 100644 index 1614a53..0000000 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/getk4pcpids.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/python -# -# This is a python script. You need a Python interpreter to run it. -# For example, ActiveState Python, which exists for windows. -# -# Changelog -# 1.00 - Initial version -# 1.01 - getPidList interface change - -__version__ = '1.01' - -import sys - -class SafeUnbuffered: - def __init__(self, stream): - self.stream = stream - self.encoding = stream.encoding - if self.encoding == None: - self.encoding = "utf-8" - def write(self, data): - if isinstance(data,unicode): - data = data.encode(self.encoding,"replace") - self.stream.write(data) - self.stream.flush() - def __getattr__(self, attr): - return getattr(self.stream, attr) -sys.stdout=SafeUnbuffered(sys.stdout) -sys.stderr=SafeUnbuffered(sys.stderr) - -import os -import struct -import binascii -import kgenpids -import topazextract -import mobidedrm -from alfcrypto import Pukall_Cipher - -class DrmException(Exception): - pass - -def getK4PCpids(path_to_ebook): - # Return Kindle4PC PIDs. Assumes that the caller checked that we are not on Linux, which will raise an exception - - mobi = True - magic3 = file(path_to_ebook,'rb').read(3) - if magic3 == 'TPZ': - mobi = False - - if mobi: - mb = mobidedrm.MobiBook(path_to_ebook) - else: - mb = topazextract.TopazBook(path_to_ebook) - - md1, md2 = mb.getPIDMetaInfo() - - return kgenpids.getPidList(md1, md2) - - -def main(argv=sys.argv): - print ('getk4pcpids.py v%(__version__)s. ' - 'Copyright 2012 Apprentice Alf' % globals()) - - if len(argv)<2 or len(argv)>3: - print "Gets the possible book-specific PIDs from K4PC for a particular book" - print "Usage:" - print " %s []" % sys.argv[0] - return 1 - else: - infile = argv[1] - try: - pidlist = getK4PCpids(infile) - except DrmException, e: - print "Error: %s" % e - return 1 - pidstring = ','.join(pidlist) - print "Possible PIDs are: ", pidstring - if len(argv) is 3: - outfile = argv[2] - file(outfile, 'w').write(pidstring) - - return 0 - -if __name__ == "__main__": - sys.exit(main()) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignobleepub.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignobleepub.py index 4cf74ae..277cdde 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignobleepub.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignobleepub.py @@ -33,13 +33,14 @@ from __future__ import with_statement # 3.6 - Revised to allow use in calibre plugins to eliminate need for duplicate code # 3.7 - Tweaked to match ineptepub more closely # 3.8 - Fixed to retain zip file metadata (e.g. file modification date) +# 3.9 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Decrypt Barnes & Noble encrypted ePub books. """ __license__ = 'GPL v3' -__version__ = "3.8" +__version__ = "3.9" import sys import os @@ -316,7 +317,8 @@ def decryptBook(keyb64, inpath, outpath): return 0 -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv) != 4: print u"usage: {0} ".format(progname) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignoblekeygen.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignoblekeygen.py index ec78e65..a6e5dca 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignoblekeygen.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ignoblekeygen.py @@ -31,13 +31,14 @@ from __future__ import with_statement # 2.3 - Modify interface to allow use of import # 2.4 - Improvements to UI and now works in plugins # 2.5 - Additional improvement for unicode and plugin support +# 2.6 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Generate Barnes & Noble EPUB user key from name and credit card number. """ __license__ = 'GPL v3' -__version__ = "2.5" +__version__ = "2.6" import sys import os @@ -214,7 +215,8 @@ def generate_key(name, ccn): -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if AES is None: print "%s: This script requires OpenSSL or PyCrypto, which must be installed " \ diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py index 98a134e..3fe07d9 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptepub.py @@ -35,13 +35,14 @@ from __future__ import with_statement # 5.7 - Fix for potential problem with PyCrypto # 5.8 - Revised to allow use in calibre plugins to eliminate need for duplicate code # 5.9 - Fixed to retain zip file metadata (e.g. file modification date) +# 5.10 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Decrypt Adobe Digital Editions encrypted ePub books. """ __license__ = 'GPL v3' -__version__ = "5.9" +__version__ = "5.10" import sys import os @@ -458,7 +459,8 @@ def decryptBook(userkey, inpath, outpath): return 0 -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv) != 4: print u"usage: {0} ".format(progname) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptkey.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptkey.py deleted file mode 100644 index a9bc62d..0000000 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptkey.py +++ /dev/null @@ -1,512 +0,0 @@ -#! /usr/bin/python -# -*- coding: utf-8 -*- - -from __future__ import with_statement - -# ineptkey.pyw, version 5.6 -# Copyright © 2009-2010 i♥cabbages - -# Released under the terms of the GNU General Public Licence, version 3 -# - -# Windows users: Before running this program, you must first install Python 2.6 -# from and PyCrypto from -# (make certain -# to install the version for Python 2.6). Then save this script file as -# 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. -# -# Mac OS X users: Save this script file as ineptkey.pyw. You can run this -# program from the command line (pythonw ineptkey.pyw) or by double-clicking -# it when it has been associated with PythonLauncher. It will create a file -# named adeptkey.der in the same directory. This is your ADEPT user key. - -# Revision history: -# 1 - Initial release, for Adobe Digital Editions 1.7 -# 2 - Better algorithm for finding pLK; improved error handling -# 3 - Rename to INEPT -# 4 - Series of changes by joblack (and others?) -- -# 4.1 - quick beta fix for ADE 1.7.2 (anon) -# 4.2 - added old 1.7.1 processing -# 4.3 - better key search -# 4.4 - Make it working on 64-bit Python -# 5 - Clean up and improve 4.x changes; -# Clean up and merge OS X support by unknown -# 5.1 - add support for using OpenSSL on Windows in place of PyCrypto -# 5.2 - added support for output of key to a particular file -# 5.3 - On Windows try PyCrypto first, OpenSSL next -# 5.4 - Modify interface to allow use of import -# 5.5 - Fix for potential problem with PyCrypto -# 5.6 - Revised to allow use in Plugins to eliminate need for duplicate code - -""" -Retrieve Adobe ADEPT user key. -""" - -__license__ = 'GPL v3' - -import sys -import os -import struct - -# Wrap a stream so that output gets flushed immediately -# and also make sure that any unicode strings get -# encoded using "replace" before writing them. -class SafeUnbuffered: - def __init__(self, stream): - self.stream = stream - self.encoding = stream.encoding - if self.encoding == None: - self.encoding = "utf-8" - def write(self, data): - if isinstance(data,unicode): - data = data.encode(self.encoding,"replace") - self.stream.write(data) - self.stream.flush() - def __getattr__(self, attr): - return getattr(self.stream, attr) - -try: - from calibre.constants import iswindows, isosx -except: - iswindows = sys.platform.startswith('win') - isosx = sys.platform.startswith('darwin') - -def unicode_argv(): - if iswindows: - # Uses shell32.GetCommandLineArgvW to get sys.argv as a list of Unicode - # strings. - - # Versions 2.x of Python don't support Unicode in sys.argv on - # Windows, with the underlying Windows API instead replacing multi-byte - # characters with '?'. - - - from ctypes import POINTER, byref, cdll, c_int, windll - from ctypes.wintypes import LPCWSTR, LPWSTR - - GetCommandLineW = cdll.kernel32.GetCommandLineW - GetCommandLineW.argtypes = [] - GetCommandLineW.restype = LPCWSTR - - CommandLineToArgvW = windll.shell32.CommandLineToArgvW - CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)] - CommandLineToArgvW.restype = POINTER(LPWSTR) - - cmd = GetCommandLineW() - argc = c_int(0) - argv = CommandLineToArgvW(cmd, byref(argc)) - if argc.value > 0: - # Remove Python executable and commands if present - start = argc.value - len(sys.argv) - return [argv[i] for i in - xrange(start, argc.value)] - return [u"ineptkey.py"] - else: - argvencoding = sys.stdin.encoding - if argvencoding == None: - argvencoding = "utf-8" - return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv] - -class ADEPTError(Exception): - pass - -if iswindows: - from ctypes import windll, c_char_p, c_wchar_p, c_uint, POINTER, byref, \ - create_unicode_buffer, create_string_buffer, CFUNCTYPE, addressof, \ - string_at, Structure, c_void_p, cast, c_size_t, memmove, CDLL, c_int, \ - c_long, c_ulong - - from ctypes.wintypes import LPVOID, DWORD, BOOL - import _winreg as winreg - - def _load_crypto_libcrypto(): - from ctypes.util import find_library - libcrypto = find_library('libeay32') - if libcrypto is None: - raise ADEPTError('libcrypto not found') - libcrypto = CDLL(libcrypto) - AES_MAXNR = 14 - c_char_pp = POINTER(c_char_p) - c_int_p = POINTER(c_int) - class AES_KEY(Structure): - _fields_ = [('rd_key', c_long * (4 * (AES_MAXNR + 1))), - ('rounds', c_int)] - AES_KEY_p = POINTER(AES_KEY) - - def F(restype, name, argtypes): - func = getattr(libcrypto, name) - func.restype = restype - func.argtypes = argtypes - return func - - AES_set_decrypt_key = F(c_int, 'AES_set_decrypt_key', - [c_char_p, c_int, AES_KEY_p]) - AES_cbc_encrypt = F(None, 'AES_cbc_encrypt', - [c_char_p, c_char_p, c_ulong, AES_KEY_p, c_char_p, - c_int]) - class AES(object): - def __init__(self, userkey): - self._blocksize = len(userkey) - if (self._blocksize != 16) and (self._blocksize != 24) and (self._blocksize != 32) : - raise ADEPTError('AES improper key used') - key = self._key = AES_KEY() - rv = AES_set_decrypt_key(userkey, len(userkey) * 8, key) - if rv < 0: - raise ADEPTError('Failed to initialize AES key') - def decrypt(self, data): - out = create_string_buffer(len(data)) - iv = ("\x00" * self._blocksize) - rv = AES_cbc_encrypt(data, out, len(data), self._key, iv, 0) - if rv == 0: - raise ADEPTError('AES decryption failed') - return out.raw - return AES - - def _load_crypto_pycrypto(): - from Crypto.Cipher import AES as _AES - class AES(object): - def __init__(self, key): - self._aes = _AES.new(key, _AES.MODE_CBC, '\x00'*16) - def decrypt(self, data): - return self._aes.decrypt(data) - return AES - - def _load_crypto(): - AES = None - for loader in (_load_crypto_pycrypto, _load_crypto_libcrypto): - try: - AES = loader() - break - except (ImportError, ADEPTError): - pass - return AES - - AES = _load_crypto() - - - DEVICE_KEY_PATH = r'Software\Adobe\Adept\Device' - PRIVATE_LICENCE_KEY_PATH = r'Software\Adobe\Adept\Activation' - - MAX_PATH = 255 - - kernel32 = windll.kernel32 - advapi32 = windll.advapi32 - crypt32 = windll.crypt32 - - def GetSystemDirectory(): - GetSystemDirectoryW = kernel32.GetSystemDirectoryW - GetSystemDirectoryW.argtypes = [c_wchar_p, c_uint] - GetSystemDirectoryW.restype = c_uint - def GetSystemDirectory(): - buffer = create_unicode_buffer(MAX_PATH + 1) - GetSystemDirectoryW(buffer, len(buffer)) - return buffer.value - return GetSystemDirectory - GetSystemDirectory = GetSystemDirectory() - - def GetVolumeSerialNumber(): - GetVolumeInformationW = kernel32.GetVolumeInformationW - GetVolumeInformationW.argtypes = [c_wchar_p, c_wchar_p, c_uint, - POINTER(c_uint), POINTER(c_uint), - POINTER(c_uint), c_wchar_p, c_uint] - GetVolumeInformationW.restype = c_uint - def GetVolumeSerialNumber(path): - vsn = c_uint(0) - GetVolumeInformationW( - path, None, 0, byref(vsn), None, None, None, 0) - return vsn.value - return GetVolumeSerialNumber - GetVolumeSerialNumber = GetVolumeSerialNumber() - - def GetUserName(): - GetUserNameW = advapi32.GetUserNameW - GetUserNameW.argtypes = [c_wchar_p, POINTER(c_uint)] - GetUserNameW.restype = c_uint - def GetUserName(): - buffer = create_unicode_buffer(32) - size = c_uint(len(buffer)) - while not GetUserNameW(buffer, byref(size)): - buffer = create_unicode_buffer(len(buffer) * 2) - size.value = len(buffer) - return buffer.value.encode('utf-16-le')[::2] - return GetUserName - GetUserName = GetUserName() - - PAGE_EXECUTE_READWRITE = 0x40 - MEM_COMMIT = 0x1000 - MEM_RESERVE = 0x2000 - - def VirtualAlloc(): - _VirtualAlloc = kernel32.VirtualAlloc - _VirtualAlloc.argtypes = [LPVOID, c_size_t, DWORD, DWORD] - _VirtualAlloc.restype = LPVOID - def VirtualAlloc(addr, size, alloctype=(MEM_COMMIT | MEM_RESERVE), - protect=PAGE_EXECUTE_READWRITE): - return _VirtualAlloc(addr, size, alloctype, protect) - return VirtualAlloc - VirtualAlloc = VirtualAlloc() - - MEM_RELEASE = 0x8000 - - def VirtualFree(): - _VirtualFree = kernel32.VirtualFree - _VirtualFree.argtypes = [LPVOID, c_size_t, DWORD] - _VirtualFree.restype = BOOL - def VirtualFree(addr, size=0, freetype=MEM_RELEASE): - return _VirtualFree(addr, size, freetype) - return VirtualFree - VirtualFree = VirtualFree() - - class NativeFunction(object): - def __init__(self, restype, argtypes, insns): - self._buf = buf = VirtualAlloc(None, len(insns)) - memmove(buf, insns, len(insns)) - ftype = CFUNCTYPE(restype, *argtypes) - self._native = ftype(buf) - - def __call__(self, *args): - return self._native(*args) - - def __del__(self): - if self._buf is not None: - VirtualFree(self._buf) - self._buf = None - - if struct.calcsize("P") == 4: - CPUID0_INSNS = ( - "\x53" # push %ebx - "\x31\xc0" # xor %eax,%eax - "\x0f\xa2" # cpuid - "\x8b\x44\x24\x08" # mov 0x8(%esp),%eax - "\x89\x18" # mov %ebx,0x0(%eax) - "\x89\x50\x04" # mov %edx,0x4(%eax) - "\x89\x48\x08" # mov %ecx,0x8(%eax) - "\x5b" # pop %ebx - "\xc3" # ret - ) - CPUID1_INSNS = ( - "\x53" # push %ebx - "\x31\xc0" # xor %eax,%eax - "\x40" # inc %eax - "\x0f\xa2" # cpuid - "\x5b" # pop %ebx - "\xc3" # ret - ) - else: - CPUID0_INSNS = ( - "\x49\x89\xd8" # mov %rbx,%r8 - "\x49\x89\xc9" # mov %rcx,%r9 - "\x48\x31\xc0" # xor %rax,%rax - "\x0f\xa2" # cpuid - "\x4c\x89\xc8" # mov %r9,%rax - "\x89\x18" # mov %ebx,0x0(%rax) - "\x89\x50\x04" # mov %edx,0x4(%rax) - "\x89\x48\x08" # mov %ecx,0x8(%rax) - "\x4c\x89\xc3" # mov %r8,%rbx - "\xc3" # retq - ) - CPUID1_INSNS = ( - "\x53" # push %rbx - "\x48\x31\xc0" # xor %rax,%rax - "\x48\xff\xc0" # inc %rax - "\x0f\xa2" # cpuid - "\x5b" # pop %rbx - "\xc3" # retq - ) - - def cpuid0(): - _cpuid0 = NativeFunction(None, [c_char_p], CPUID0_INSNS) - buf = create_string_buffer(12) - def cpuid0(): - _cpuid0(buf) - return buf.raw - return cpuid0 - cpuid0 = cpuid0() - - cpuid1 = NativeFunction(c_uint, [], CPUID1_INSNS) - - class DataBlob(Structure): - _fields_ = [('cbData', c_uint), - ('pbData', c_void_p)] - DataBlob_p = POINTER(DataBlob) - - def CryptUnprotectData(): - _CryptUnprotectData = crypt32.CryptUnprotectData - _CryptUnprotectData.argtypes = [DataBlob_p, c_wchar_p, DataBlob_p, - c_void_p, c_void_p, c_uint, DataBlob_p] - _CryptUnprotectData.restype = c_uint - def CryptUnprotectData(indata, entropy): - indatab = create_string_buffer(indata) - indata = DataBlob(len(indata), cast(indatab, c_void_p)) - entropyb = create_string_buffer(entropy) - entropy = DataBlob(len(entropy), cast(entropyb, c_void_p)) - outdata = DataBlob() - if not _CryptUnprotectData(byref(indata), None, byref(entropy), - None, None, 0, byref(outdata)): - raise ADEPTError("Failed to decrypt user key key (sic)") - return string_at(outdata.pbData, outdata.cbData) - return CryptUnprotectData - CryptUnprotectData = CryptUnprotectData() - - def retrieve_keys(): - if AES is None: - raise ADEPTError("PyCrypto or OpenSSL must be installed") - root = GetSystemDirectory().split('\\')[0] + '\\' - serial = GetVolumeSerialNumber(root) - vendor = cpuid0() - signature = struct.pack('>I', cpuid1())[1:] - user = GetUserName() - entropy = struct.pack('>I12s3s13s', serial, vendor, signature, user) - cuser = winreg.HKEY_CURRENT_USER - try: - regkey = winreg.OpenKey(cuser, DEVICE_KEY_PATH) - device = winreg.QueryValueEx(regkey, 'key')[0] - except WindowsError: - raise ADEPTError("Adobe Digital Editions not activated") - keykey = CryptUnprotectData(device, entropy) - userkey = None - keys = [] - try: - plkroot = winreg.OpenKey(cuser, PRIVATE_LICENCE_KEY_PATH) - except WindowsError: - raise ADEPTError("Could not locate ADE activation") - for i in xrange(0, 16): - try: - plkparent = winreg.OpenKey(plkroot, "%04d" % (i,)) - except WindowsError: - break - ktype = winreg.QueryValueEx(plkparent, None)[0] - if ktype != 'credentials': - continue - for j in xrange(0, 16): - try: - plkkey = winreg.OpenKey(plkparent, "%04d" % (j,)) - except WindowsError: - break - ktype = winreg.QueryValueEx(plkkey, None)[0] - if ktype != 'privateLicenseKey': - continue - userkey = winreg.QueryValueEx(plkkey, 'value')[0] - userkey = userkey.decode('base64') - aes = AES(keykey) - userkey = aes.decrypt(userkey) - userkey = userkey[26:-ord(userkey[-1])] - keys.append(userkey) - if len(keys) == 0: - raise ADEPTError('Could not locate privateLicenseKey') - return keys - - -elif isosx: - import xml.etree.ElementTree as etree - import subprocess - - NSMAP = {'adept': 'http://ns.adobe.com/adept', - 'enc': 'http://www.w3.org/2001/04/xmlenc#'} - - def findActivationDat(): - home = os.getenv('HOME') - cmdline = 'find "' + home + '/Library/Application Support/Adobe/Digital Editions" -name "activation.dat"' - cmdline = cmdline.encode(sys.getfilesystemencoding()) - p2 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) - out1, out2 = p2.communicate() - reslst = out1.split('\n') - cnt = len(reslst) - for j in xrange(cnt): - resline = reslst[j] - pp = resline.find('activation.dat') - if pp >= 0: - ActDatPath = resline - break - if os.path.exists(ActDatPath): - return ActDatPath - return None - - def retrieve_keys(): - actpath = findActivationDat() - if actpath is None: - raise ADEPTError("Could not locate ADE activation") - tree = etree.parse(actpath) - adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag) - expr = '//%s/%s' % (adept('credentials'), adept('privateLicenseKey')) - userkey = tree.findtext(expr) - userkey = userkey.decode('base64') - userkey = userkey[26:] - return [userkey] - -else: - def retrieve_keys(keypath): - raise ADEPTError("This script only supports Windows and Mac OS X.") - return [] - -def retrieve_key(keypath): - keys = retrieve_keys() - with open(keypath, 'wb') as f: - f.write(keys[0]) - return True - -def extractKeyfile(keypath): - try: - success = retrieve_key(keypath) - except ADEPTError, e: - print u"Key generation Error: {0}".format(e.args[0]) - return 1 - except Exception, e: - print "General Error: {0}".format(e.args[0]) - return 1 - if not success: - return 1 - return 0 - - -def cli_main(argv=unicode_argv()): - keypath = argv[1] - return extractKeyfile(keypath) - - -def gui_main(argv=unicode_argv()): - import Tkinter - import Tkconstants - import tkMessageBox - import traceback - - class ExceptionDialog(Tkinter.Frame): - def __init__(self, root, text): - Tkinter.Frame.__init__(self, root, border=5) - label = Tkinter.Label(self, text=u"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) - - - root = Tkinter.Tk() - root.withdraw() - keypath, progname = os.path.split(argv[0]) - keypath = os.path.join(keypath, u"adeptkey.der") - success = False - try: - success = retrieve_key(keypath) - except ADEPTError, e: - tkMessageBox.showerror(u"ADEPT Key", "Error: {0}".format(e.args[0])) - 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() - if not success: - return 1 - tkMessageBox.showinfo( - u"ADEPT Key", u"Key successfully retrieved to {0}".format(keypath)) - return 0 - -if __name__ == '__main__': - if len(sys.argv) > 1: - sys.stdout=SafeUnbuffered(sys.stdout) - sys.stderr=SafeUnbuffered(sys.stderr) - sys.exit(cli_main()) - sys.exit(gui_main()) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py index f4d6d81..69028c6 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/ineptpdf.py @@ -50,13 +50,14 @@ from __future__ import with_statement # 7.11 - More tweaks to fix minor problems. # 7.12 - Revised to allow use in calibre plugins to eliminate need for duplicate code # 7.13 - Fixed erroneous mentions of ineptepub +# 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Decrypts Adobe ADEPT-encrypted PDF files. """ __license__ = 'GPL v3' -__version__ = "7.13" +__version__ = "7.14" import sys import os @@ -2185,7 +2186,8 @@ def decryptBook(userkey, inpath, outpath): return 0 -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv) != 4: print u"usage: {0} ".format(progname) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mobidedrm.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mobidedrm.py index 1ae5c88..e15f104 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mobidedrm.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mobidedrm.py @@ -53,8 +53,9 @@ from __future__ import with_statement # 4.9 - Missed some invalid characters in cleanup_name # 5.0 - Extraction of info from Kindle for PC/Mac moved into kindlekey.py # - tweaked GetDecryptedBook interface to leave passed parameters unchanged +# 5.1 - moved unicode_argv call inside main for Windows DeDRM compatibility -__version__ = '5.0' +__version__ = '5.1' import sys, os, re @@ -276,7 +277,8 @@ def usage(progname): # # Main # -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"K4MobiDeDrm v{0}.\nCopyright © 2008-2013 The Dark Reverser et al.".format(__version__) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mutils.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mutils.py deleted file mode 100644 index bceb3a3..0000000 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4mutils.py +++ /dev/null @@ -1,747 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# standlone set of Mac OSX specific routines needed for KindleBooks - -from __future__ import with_statement - -import sys -import os -import os.path -import re -import copy -import subprocess -from struct import pack, unpack, unpack_from - -class DrmException(Exception): - pass - - -# interface to needed routines in openssl's libcrypto -def _load_crypto_libcrypto(): - from ctypes import CDLL, byref, POINTER, c_void_p, c_char_p, c_int, c_long, \ - Structure, c_ulong, create_string_buffer, addressof, string_at, cast - from ctypes.util import find_library - - libcrypto = find_library('crypto') - if libcrypto is None: - raise DrmException(u"libcrypto not found") - libcrypto = CDLL(libcrypto) - - # From OpenSSL's crypto aes header - # - # AES_ENCRYPT 1 - # AES_DECRYPT 0 - # AES_MAXNR 14 (in bytes) - # AES_BLOCK_SIZE 16 (in bytes) - # - # struct aes_key_st { - # unsigned long rd_key[4 *(AES_MAXNR + 1)]; - # int rounds; - # }; - # typedef struct aes_key_st AES_KEY; - # - # int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); - # - # note: the ivec string, and output buffer are both mutable - # void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, - # const unsigned long length, const AES_KEY *key, unsigned char *ivec, const int enc); - - AES_MAXNR = 14 - c_char_pp = POINTER(c_char_p) - c_int_p = POINTER(c_int) - - class AES_KEY(Structure): - _fields_ = [('rd_key', c_long * (4 * (AES_MAXNR + 1))), ('rounds', c_int)] - AES_KEY_p = POINTER(AES_KEY) - - def F(restype, name, argtypes): - func = getattr(libcrypto, name) - func.restype = restype - func.argtypes = argtypes - return func - - AES_cbc_encrypt = F(None, 'AES_cbc_encrypt',[c_char_p, c_char_p, c_ulong, AES_KEY_p, c_char_p,c_int]) - - AES_set_decrypt_key = F(c_int, 'AES_set_decrypt_key',[c_char_p, c_int, AES_KEY_p]) - - # From OpenSSL's Crypto evp/p5_crpt2.c - # - # int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, - # const unsigned char *salt, int saltlen, int iter, - # int keylen, unsigned char *out); - - PKCS5_PBKDF2_HMAC_SHA1 = F(c_int, 'PKCS5_PBKDF2_HMAC_SHA1', - [c_char_p, c_ulong, c_char_p, c_ulong, c_ulong, c_ulong, c_char_p]) - - class LibCrypto(object): - def __init__(self): - self._blocksize = 0 - self._keyctx = None - self._iv = 0 - - def set_decrypt_key(self, userkey, iv): - self._blocksize = len(userkey) - if (self._blocksize != 16) and (self._blocksize != 24) and (self._blocksize != 32) : - raise DrmException(u"AES improper key used") - return - keyctx = self._keyctx = AES_KEY() - self._iv = iv - self._userkey = userkey - rv = AES_set_decrypt_key(userkey, len(userkey) * 8, keyctx) - if rv < 0: - raise DrmException(u"Failed to initialize AES key") - - def decrypt(self, data): - out = create_string_buffer(len(data)) - mutable_iv = create_string_buffer(self._iv, len(self._iv)) - keyctx = self._keyctx - rv = AES_cbc_encrypt(data, out, len(data), keyctx, mutable_iv, 0) - if rv == 0: - raise DrmException(u"AES decryption failed") - return out.raw - - def keyivgen(self, passwd, salt, iter, keylen): - saltlen = len(salt) - passlen = len(passwd) - out = create_string_buffer(keylen) - rv = PKCS5_PBKDF2_HMAC_SHA1(passwd, passlen, salt, saltlen, iter, keylen, out) - return out.raw - return LibCrypto - -def _load_crypto(): - LibCrypto = None - try: - LibCrypto = _load_crypto_libcrypto() - except (ImportError, DrmException): - pass - return LibCrypto - -LibCrypto = _load_crypto() - -# -# Utility Routines -# - -# crypto digestroutines -import hashlib - -def MD5(message): - ctx = hashlib.md5() - ctx.update(message) - return ctx.digest() - -def SHA1(message): - ctx = hashlib.sha1() - ctx.update(message) - return ctx.digest() - -def SHA256(message): - ctx = hashlib.sha256() - ctx.update(message) - return ctx.digest() - -# Various character maps used to decrypt books. Probably supposed to act as obfuscation -charMap1 = 'n5Pr6St7Uv8Wx9YzAb0Cd1Ef2Gh3Jk4M' -charMap2 = 'ZB0bYyc1xDdW2wEV3Ff7KkPpL8UuGA4gz-Tme9Nn_tHh5SvXCsIiR6rJjQaqlOoM' - -# For kinf approach of K4Mac 1.6.X or later -# On K4PC charMap5 = 'AzB0bYyCeVvaZ3FfUuG4g-TtHh5SsIiR6rJjQq7KkPpL8lOoMm9Nn_c1XxDdW2wE' -# For Mac they seem to re-use charMap2 here -charMap5 = charMap2 - -# new in K4M 1.9.X -testMap8 = 'YvaZ3FfUm9Nn_c1XuG4yCAzB0beVg-TtHh5SsIiR6rJjQdW2wEq7KkPpL8lOoMxD' - - -def encode(data, map): - result = '' - for char in data: - value = ord(char) - Q = (value ^ 0x80) // len(map) - R = value % len(map) - result += map[Q] - result += map[R] - return result - -# Hash the bytes in data and then encode the digest with the characters in map -def encodeHash(data,map): - return encode(MD5(data),map) - -# Decode the string in data with the characters in map. Returns the decoded bytes -def decode(data,map): - result = '' - for i in range (0,len(data)-1,2): - high = map.find(data[i]) - low = map.find(data[i+1]) - if (high == -1) or (low == -1) : - break - value = (((high * len(map)) ^ 0x80) & 0xFF) + low - result += pack('B',value) - return result - -# For K4M 1.6.X and later -# generate table of prime number less than or equal to int n -def primes(n): - if n==2: return [2] - elif n<2: return [] - s=range(3,n+1,2) - mroot = n ** 0.5 - half=(n+1)/2-1 - i=0 - m=3 - while m <= mroot: - if s[i]: - j=(m*m-3)/2 - s[j]=0 - while j= 0: - sernum = resline[pp+19:-1] - sernum = sernum.strip() - bb = resline.find('\"BSD Name\" = \"') - if bb >= 0: - bsdname = resline[bb+14:-1] - bsdname = bsdname.strip() - if (bsdname == 'disk0') and (sernum != None): - foundIt = True - break - if not foundIt: - sernum = '' - return sernum - -def GetUserHomeAppSupKindleDirParitionName(): - home = os.getenv('HOME') - dpath = home + '/Library' - cmdline = '/sbin/mount' - cmdline = cmdline.encode(sys.getfilesystemencoding()) - p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) - out1, out2 = p.communicate() - reslst = out1.split('\n') - cnt = len(reslst) - disk = '' - foundIt = False - for j in xrange(cnt): - resline = reslst[j] - if resline.startswith('/dev'): - (devpart, mpath) = resline.split(' on ') - dpart = devpart[5:] - pp = mpath.find('(') - if pp >= 0: - mpath = mpath[:pp-1] - if dpath.startswith(mpath): - disk = dpart - return disk - -# uses a sub process to get the UUID of the specified disk partition using ioreg -def GetDiskPartitionUUID(diskpart): - uuidnum = os.getenv('MYUUIDNUMBER') - if uuidnum != None: - return uuidnum - cmdline = '/usr/sbin/ioreg -l -S -w 0 -r -c AppleAHCIDiskDriver' - cmdline = cmdline.encode(sys.getfilesystemencoding()) - p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) - out1, out2 = p.communicate() - reslst = out1.split('\n') - cnt = len(reslst) - bsdname = None - uuidnum = None - foundIt = False - nest = 0 - uuidnest = -1 - partnest = -2 - for j in xrange(cnt): - resline = reslst[j] - if resline.find('{') >= 0: - nest += 1 - if resline.find('}') >= 0: - nest -= 1 - pp = resline.find('\"UUID\" = \"') - if pp >= 0: - uuidnum = resline[pp+10:-1] - uuidnum = uuidnum.strip() - uuidnest = nest - if partnest == uuidnest and uuidnest > 0: - foundIt = True - break - bb = resline.find('\"BSD Name\" = \"') - if bb >= 0: - bsdname = resline[bb+14:-1] - bsdname = bsdname.strip() - if (bsdname == diskpart): - partnest = nest - else : - partnest = -2 - if partnest == uuidnest and partnest > 0: - foundIt = True - break - if nest == 0: - partnest = -2 - uuidnest = -1 - uuidnum = None - bsdname = None - if not foundIt: - uuidnum = '' - return uuidnum - -def GetMACAddressMunged(): - macnum = os.getenv('MYMACNUM') - if macnum != None: - return macnum - cmdline = '/sbin/ifconfig en0' - cmdline = cmdline.encode(sys.getfilesystemencoding()) - p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) - out1, out2 = p.communicate() - reslst = out1.split('\n') - cnt = len(reslst) - macnum = None - foundIt = False - for j in xrange(cnt): - resline = reslst[j] - pp = resline.find('ether ') - if pp >= 0: - macnum = resline[pp+6:-1] - macnum = macnum.strip() - # print 'original mac', macnum - # now munge it up the way Kindle app does - # by xoring it with 0xa5 and swapping elements 3 and 4 - maclst = macnum.split(':') - n = len(maclst) - if n != 6: - fountIt = False - break - for i in range(6): - maclst[i] = int('0x' + maclst[i], 0) - mlst = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00] - mlst[5] = maclst[5] ^ 0xa5 - mlst[4] = maclst[3] ^ 0xa5 - mlst[3] = maclst[4] ^ 0xa5 - mlst[2] = maclst[2] ^ 0xa5 - mlst[1] = maclst[1] ^ 0xa5 - mlst[0] = maclst[0] ^ 0xa5 - macnum = '%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x' % (mlst[0], mlst[1], mlst[2], mlst[3], mlst[4], mlst[5]) - foundIt = True - break - if not foundIt: - macnum = '' - return macnum - - -# uses unix env to get username instead of using sysctlbyname -def GetUserName(): - username = os.getenv('USER') - return username - -def isNewInstall(): - home = os.getenv('HOME') - # soccer game fan anyone - dpath = home + '/Library/Application Support/Kindle/storage/.pes2011' - # print dpath, os.path.exists(dpath) - if os.path.exists(dpath): - return True - dpath = home + '/Library/Containers/com.amazon.Kindle/Data/Library/Application Support/Kindle/storage/.pes2011' - # print dpath, os.path.exists(dpath) - if os.path.exists(dpath): - return True - return False - - -class Memoize: - """Memoize(fn) - an instance which acts like fn but memoizes its arguments - Will only work on functions with non-mutable arguments - """ - def __init__(self, fn): - self.fn = fn - self.memo = {} - def __call__(self, *args): - if not self.memo.has_key(args): - self.memo[args] = self.fn(*args) - return self.memo[args] - -@Memoize -def GetIDString(): - # K4Mac now has an extensive set of ids strings it uses - # in encoding pids and in creating unique passwords - # for use in its own version of CryptUnprotectDataV2 - - # BUT Amazon has now become nasty enough to detect when its app - # is being run under a debugger and actually changes code paths - # including which one of these strings is chosen, all to try - # to prevent reverse engineering - - # Sad really ... they will only hurt their own sales ... - # true book lovers really want to keep their books forever - # and move them to their devices and DRM prevents that so they - # will just buy from someplace else that they can remove - # the DRM from - - # Amazon should know by now that true book lover's are not like - # penniless kids that pirate music, we do not pirate books - - if isNewInstall(): - mungedmac = GetMACAddressMunged() - if len(mungedmac) > 7: - print('Using Munged MAC Address for ID: '+mungedmac) - return mungedmac - sernum = GetVolumeSerialNumber() - if len(sernum) > 7: - print('Using Volume Serial Number for ID: '+sernum) - return sernum - diskpart = GetUserHomeAppSupKindleDirParitionName() - uuidnum = GetDiskPartitionUUID(diskpart) - if len(uuidnum) > 7: - print('Using Disk Partition UUID for ID: '+uuidnum) - return uuidnum - mungedmac = GetMACAddressMunged() - if len(mungedmac) > 7: - print('Using Munged MAC Address for ID: '+mungedmac) - return mungedmac - print('Using Fixed constant 9999999999 for ID.') - return '9999999999' - - -# implements an Pseudo Mac Version of Windows built-in Crypto routine -# used by Kindle for Mac versions < 1.6.0 -class CryptUnprotectData(object): - def __init__(self): - sernum = GetVolumeSerialNumber() - if sernum == '': - sernum = '9999999999' - sp = sernum + '!@#' + GetUserName() - passwdData = encode(SHA256(sp),charMap1) - salt = '16743' - self.crp = LibCrypto() - iter = 0x3e8 - keylen = 0x80 - key_iv = self.crp.keyivgen(passwdData, salt, iter, keylen) - self.key = key_iv[0:32] - self.iv = key_iv[32:48] - self.crp.set_decrypt_key(self.key, self.iv) - - def decrypt(self, encryptedData): - cleartext = self.crp.decrypt(encryptedData) - cleartext = decode(cleartext,charMap1) - return cleartext - - -# implements an Pseudo Mac Version of Windows built-in Crypto routine -# used for Kindle for Mac Versions >= 1.6.0 -class CryptUnprotectDataV2(object): - def __init__(self): - sp = GetUserName() + ':&%:' + GetIDString() - passwdData = encode(SHA256(sp),charMap5) - # salt generation as per the code - salt = 0x0512981d * 2 * 1 * 1 - salt = str(salt) + GetUserName() - salt = encode(salt,charMap5) - self.crp = LibCrypto() - iter = 0x800 - keylen = 0x400 - key_iv = self.crp.keyivgen(passwdData, salt, iter, keylen) - self.key = key_iv[0:32] - self.iv = key_iv[32:48] - self.crp.set_decrypt_key(self.key, self.iv) - - def decrypt(self, encryptedData): - cleartext = self.crp.decrypt(encryptedData) - cleartext = decode(cleartext, charMap5) - return cleartext - - -# unprotect the new header blob in .kinf2011 -# used in Kindle for Mac Version >= 1.9.0 -def UnprotectHeaderData(encryptedData): - passwdData = 'header_key_data' - salt = 'HEADER.2011' - iter = 0x80 - keylen = 0x100 - crp = LibCrypto() - key_iv = crp.keyivgen(passwdData, salt, iter, keylen) - key = key_iv[0:32] - iv = key_iv[32:48] - crp.set_decrypt_key(key,iv) - cleartext = crp.decrypt(encryptedData) - return cleartext - - -# implements an Pseudo Mac Version of Windows built-in Crypto routine -# used for Kindle for Mac Versions >= 1.9.0 -class CryptUnprotectDataV3(object): - def __init__(self, entropy): - sp = GetUserName() + '+@#$%+' + GetIDString() - passwdData = encode(SHA256(sp),charMap2) - salt = entropy - self.crp = LibCrypto() - iter = 0x800 - keylen = 0x400 - key_iv = self.crp.keyivgen(passwdData, salt, iter, keylen) - self.key = key_iv[0:32] - self.iv = key_iv[32:48] - self.crp.set_decrypt_key(self.key, self.iv) - - def decrypt(self, encryptedData): - cleartext = self.crp.decrypt(encryptedData) - cleartext = decode(cleartext, charMap2) - return cleartext - - -# Locate the .kindle-info files -def getKindleInfoFiles(): - # file searches can take a long time on some systems, so just look in known specific places. - kInfoFiles=[] - found = False - home = os.getenv('HOME') - # check for .kinf2011 file in new location (App Store Kindle for Mac) - testpath = home + '/Library/Containers/com.amazon.Kindle/Data/Library/Application Support/Kindle/storage/.kinf2011' - if os.path.isfile(testpath): - kInfoFiles.append(testpath) - print('Found k4Mac kinf2011 file: ' + testpath) - found = True - # check for .kinf2011 files - testpath = home + '/Library/Application Support/Kindle/storage/.kinf2011' - if os.path.isfile(testpath): - kInfoFiles.append(testpath) - print('Found k4Mac kinf2011 file: ' + testpath) - found = True - # check for .rainier-2.1.1-kinf files - testpath = home + '/Library/Application Support/Kindle/storage/.rainier-2.1.1-kinf' - if os.path.isfile(testpath): - kInfoFiles.append(testpath) - print('Found k4Mac rainier file: ' + testpath) - found = True - # check for .rainier-2.1.1-kinf files - testpath = home + '/Library/Application Support/Kindle/storage/.kindle-info' - if os.path.isfile(testpath): - kInfoFiles.append(testpath) - print('Found k4Mac kindle-info file: ' + testpath) - found = True - if not found: - print('No k4Mac kindle-info/rainier/kinf2011 files have been found.') - return kInfoFiles - -# determine type of kindle info provided and return a -# database of keynames and values -def getDBfromFile(kInfoFile): - - names = ['kindle.account.tokens','kindle.cookie.item','eulaVersionAccepted','login_date','kindle.token.item','login','kindle.key.item','kindle.name.info','kindle.device.info', 'MazamaRandomNumber', 'max_date', 'SIGVERIF'] - DB = {} - cnt = 0 - infoReader = open(kInfoFile, 'r') - hdr = infoReader.read(1) - data = infoReader.read() - - if data.find('[') != -1 : - - # older style kindle-info file - cud = CryptUnprotectData() - items = data.split('[') - for item in items: - if item != '': - keyhash, rawdata = item.split(':') - keyname = 'unknown' - for name in names: - if encodeHash(name,charMap2) == keyhash: - keyname = name - break - if keyname == 'unknown': - keyname = keyhash - encryptedValue = decode(rawdata,charMap2) - cleartext = cud.decrypt(encryptedValue) - DB[keyname] = cleartext - cnt = cnt + 1 - if cnt == 0: - DB = None - return DB - - if hdr == '/': - - # else newer style .kinf file used by K4Mac >= 1.6.0 - # the .kinf file uses '/' to separate it into records - # so remove the trailing '/' to make it easy to use split - data = data[:-1] - items = data.split('/') - cud = CryptUnprotectDataV2() - - # loop through the item records until all are processed - while len(items) > 0: - - # get the first item record - item = items.pop(0) - - # the first 32 chars of the first record of a group - # is the MD5 hash of the key name encoded by charMap5 - keyhash = item[0:32] - keyname = 'unknown' - - # the raw keyhash string is also used to create entropy for the actual - # CryptProtectData Blob that represents that keys contents - # 'entropy' not used for K4Mac only K4PC - # entropy = SHA1(keyhash) - - # the remainder of the first record when decoded with charMap5 - # has the ':' split char followed by the string representation - # of the number of records that follow - # and make up the contents - srcnt = decode(item[34:],charMap5) - rcnt = int(srcnt) - - # read and store in rcnt records of data - # that make up the contents value - edlst = [] - for i in xrange(rcnt): - item = items.pop(0) - edlst.append(item) - - keyname = 'unknown' - for name in names: - if encodeHash(name,charMap5) == keyhash: - keyname = name - break - if keyname == 'unknown': - keyname = keyhash - - # the charMap5 encoded contents data has had a length - # of chars (always odd) cut off of the front and moved - # to the end to prevent decoding using charMap5 from - # working properly, and thereby preventing the ensuing - # CryptUnprotectData call from succeeding. - - # The offset into the charMap5 encoded contents seems to be: - # len(contents) - largest prime number less than or equal to int(len(content)/3) - # (in other words split 'about' 2/3rds of the way through) - - # move first offsets chars to end to align for decode by charMap5 - encdata = ''.join(edlst) - contlen = len(encdata) - - # now properly split and recombine - # by moving noffset chars from the start of the - # string to the end of the string - noffset = contlen - primes(int(contlen/3))[-1] - pfx = encdata[0:noffset] - encdata = encdata[noffset:] - encdata = encdata + pfx - - # decode using charMap5 to get the CryptProtect Data - encryptedValue = decode(encdata,charMap5) - cleartext = cud.decrypt(encryptedValue) - DB[keyname] = cleartext - cnt = cnt + 1 - - if cnt == 0: - DB = None - return DB - - # the latest .kinf2011 version for K4M 1.9.1 - # put back the hdr char, it is needed - data = hdr + data - data = data[:-1] - items = data.split('/') - - # the headerblob is the encrypted information needed to build the entropy string - headerblob = items.pop(0) - encryptedValue = decode(headerblob, charMap1) - cleartext = UnprotectHeaderData(encryptedValue) - - # now extract the pieces in the same way - # this version is different from K4PC it scales the build number by multipying by 735 - pattern = re.compile(r'''\[Version:(\d+)\]\[Build:(\d+)\]\[Cksum:([^\]]+)\]\[Guid:([\{\}a-z0-9\-]+)\]''', re.IGNORECASE) - for m in re.finditer(pattern, cleartext): - entropy = str(int(m.group(2)) * 0x2df) + m.group(4) - - cud = CryptUnprotectDataV3(entropy) - - # loop through the item records until all are processed - while len(items) > 0: - - # get the first item record - item = items.pop(0) - - # the first 32 chars of the first record of a group - # is the MD5 hash of the key name encoded by charMap5 - keyhash = item[0:32] - keyname = 'unknown' - - # unlike K4PC the keyhash is not used in generating entropy - # entropy = SHA1(keyhash) + added_entropy - # entropy = added_entropy - - # the remainder of the first record when decoded with charMap5 - # has the ':' split char followed by the string representation - # of the number of records that follow - # and make up the contents - srcnt = decode(item[34:],charMap5) - rcnt = int(srcnt) - - # read and store in rcnt records of data - # that make up the contents value - edlst = [] - for i in xrange(rcnt): - item = items.pop(0) - edlst.append(item) - - keyname = 'unknown' - for name in names: - if encodeHash(name,testMap8) == keyhash: - keyname = name - break - if keyname == 'unknown': - keyname = keyhash - - # the testMap8 encoded contents data has had a length - # of chars (always odd) cut off of the front and moved - # to the end to prevent decoding using testMap8 from - # working properly, and thereby preventing the ensuing - # CryptUnprotectData call from succeeding. - - # The offset into the testMap8 encoded contents seems to be: - # len(contents) - largest prime number less than or equal to int(len(content)/3) - # (in other words split 'about' 2/3rds of the way through) - - # move first offsets chars to end to align for decode by testMap8 - encdata = ''.join(edlst) - contlen = len(encdata) - - # now properly split and recombine - # by moving noffset chars from the start of the - # string to the end of the string - noffset = contlen - primes(int(contlen/3))[-1] - pfx = encdata[0:noffset] - encdata = encdata[noffset:] - encdata = encdata + pfx - - # decode using testMap8 to get the CryptProtect Data - encryptedValue = decode(encdata,testMap8) - cleartext = cud.decrypt(encryptedValue) - # print keyname - # print cleartext - DB[keyname] = cleartext - cnt = cnt + 1 - - if cnt == 0: - DB = None - return DB diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4pcutils.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4pcutils.py deleted file mode 100644 index bb9289e..0000000 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/k4pcutils.py +++ /dev/null @@ -1,457 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# K4PC Windows specific routines - -from __future__ import with_statement - -import sys, os, re -from struct import pack, unpack, unpack_from - -from ctypes import windll, c_char_p, c_wchar_p, c_uint, POINTER, byref, \ - create_unicode_buffer, create_string_buffer, CFUNCTYPE, addressof, \ - string_at, Structure, c_void_p, cast - -import _winreg as winreg -MAX_PATH = 255 -kernel32 = windll.kernel32 -advapi32 = windll.advapi32 -crypt32 = windll.crypt32 - -import traceback - -# crypto digestroutines -import hashlib - -def MD5(message): - ctx = hashlib.md5() - ctx.update(message) - return ctx.digest() - -def SHA1(message): - ctx = hashlib.sha1() - ctx.update(message) - return ctx.digest() - -def SHA256(message): - ctx = hashlib.sha256() - ctx.update(message) - return ctx.digest() - -# For K4PC 1.9.X -# use routines in alfcrypto: -# AES_cbc_encrypt -# AES_set_decrypt_key -# PKCS5_PBKDF2_HMAC_SHA1 - -from alfcrypto import AES_CBC, KeyIVGen - -def UnprotectHeaderData(encryptedData): - passwdData = 'header_key_data' - salt = 'HEADER.2011' - iter = 0x80 - keylen = 0x100 - key_iv = KeyIVGen().pbkdf2(passwdData, salt, iter, keylen) - key = key_iv[0:32] - iv = key_iv[32:48] - aes=AES_CBC() - aes.set_decrypt_key(key, iv) - cleartext = aes.decrypt(encryptedData) - return cleartext - - -# simple primes table (<= n) calculator -def primes(n): - if n==2: return [2] - elif n<2: return [] - s=range(3,n+1,2) - mroot = n ** 0.5 - half=(n+1)/2-1 - i=0 - m=3 - while m <= mroot: - if s[i]: - j=(m*m-3)/2 - s[j]=0 - while j 0: - - # get the first item record - item = items.pop(0) - - # the first 32 chars of the first record of a group - # is the MD5 hash of the key name encoded by charMap5 - keyhash = item[0:32] - - # the raw keyhash string is used to create entropy for the actual - # CryptProtectData Blob that represents that keys contents - entropy = SHA1(keyhash) - - # the remainder of the first record when decoded with charMap5 - # has the ':' split char followed by the string representation - # of the number of records that follow - # and make up the contents - srcnt = decode(item[34:],charMap5) - rcnt = int(srcnt) - - # read and store in rcnt records of data - # that make up the contents value - edlst = [] - for i in xrange(rcnt): - item = items.pop(0) - edlst.append(item) - - keyname = "unknown" - for name in names: - if encodeHash(name,charMap5) == keyhash: - keyname = name - break - if keyname == "unknown": - keyname = keyhash - # the charMap5 encoded contents data has had a length - # of chars (always odd) cut off of the front and moved - # to the end to prevent decoding using charMap5 from - # working properly, and thereby preventing the ensuing - # CryptUnprotectData call from succeeding. - - # The offset into the charMap5 encoded contents seems to be: - # len(contents)-largest prime number <= int(len(content)/3) - # (in other words split "about" 2/3rds of the way through) - - # move first offsets chars to end to align for decode by charMap5 - encdata = "".join(edlst) - contlen = len(encdata) - noffset = contlen - primes(int(contlen/3))[-1] - - # now properly split and recombine - # by moving noffset chars from the start of the - # string to the end of the string - pfx = encdata[0:noffset] - encdata = encdata[noffset:] - encdata = encdata + pfx - - # decode using Map5 to get the CryptProtect Data - encryptedValue = decode(encdata,charMap5) - DB[keyname] = CryptUnprotectData(encryptedValue, entropy, 1) - cnt = cnt + 1 - - if cnt == 0: - DB = None - return DB - - # else newest .kinf2011 style .kinf file - # the .kinf file uses "/" to separate it into records - # so remove the trailing "/" to make it easy to use split - # need to put back the first char read because it it part - # of the added entropy blob - data = hdr + data[:-1] - items = data.split('/') - - # starts with and encoded and encrypted header blob - headerblob = items.pop(0) - encryptedValue = decode(headerblob, testMap1) - cleartext = UnprotectHeaderData(encryptedValue) - # now extract the pieces that form the added entropy - pattern = re.compile(r'''\[Version:(\d+)\]\[Build:(\d+)\]\[Cksum:([^\]]+)\]\[Guid:([\{\}a-z0-9\-]+)\]''', re.IGNORECASE) - for m in re.finditer(pattern, cleartext): - added_entropy = m.group(2) + m.group(4) - - - # loop through the item records until all are processed - while len(items) > 0: - - # get the first item record - item = items.pop(0) - - # the first 32 chars of the first record of a group - # is the MD5 hash of the key name encoded by charMap5 - keyhash = item[0:32] - - # the sha1 of raw keyhash string is used to create entropy along - # with the added entropy provided above from the headerblob - entropy = SHA1(keyhash) + added_entropy - - # the remainder of the first record when decoded with charMap5 - # has the ':' split char followed by the string representation - # of the number of records that follow - # and make up the contents - srcnt = decode(item[34:],charMap5) - rcnt = int(srcnt) - - # read and store in rcnt records of data - # that make up the contents value - edlst = [] - for i in xrange(rcnt): - item = items.pop(0) - edlst.append(item) - - # key names now use the new testMap8 encoding - keyname = "unknown" - for name in names: - if encodeHash(name,testMap8) == keyhash: - keyname = name - break - - # the testMap8 encoded contents data has had a length - # of chars (always odd) cut off of the front and moved - # to the end to prevent decoding using testMap8 from - # working properly, and thereby preventing the ensuing - # CryptUnprotectData call from succeeding. - - # The offset into the testMap8 encoded contents seems to be: - # len(contents)-largest prime number <= int(len(content)/3) - # (in other words split "about" 2/3rds of the way through) - - # move first offsets chars to end to align for decode by testMap8 - # by moving noffset chars from the start of the - # string to the end of the string - encdata = "".join(edlst) - contlen = len(encdata) - noffset = contlen - primes(int(contlen/3))[-1] - pfx = encdata[0:noffset] - encdata = encdata[noffset:] - encdata = encdata + pfx - - # decode using new testMap8 to get the original CryptProtect Data - encryptedValue = decode(encdata,testMap8) - cleartext = CryptUnprotectData(encryptedValue, entropy, 1) - DB[keyname] = cleartext - cnt = cnt + 1 - - if cnt == 0: - DB = None - return DB diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlekey.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlekey.py index e79622b..453de14 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlekey.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlekey.py @@ -15,13 +15,16 @@ from __future__ import with_statement # 1.3 - Added getkey interface for Windows DeDRM application # Simplified some of the Kindle for Mac code. # 1.4 - Remove dependency on alfcrypto +# 1.5 - moved unicode_argv call inside main for Windows DeDRM compatibility +# 1.6 - Fixed a problem getting the disk serial numbers + """ Retrieve Kindle for PC/Mac user key. """ __license__ = 'GPL v3' -__version__ = '1.4' +__version__ = '1.6' import sys, os, re from struct import pack, unpack, unpack_from @@ -1266,10 +1269,10 @@ elif isosx: # uses a sub process to get the Hard Drive Serial Number using ioreg # returns serial numbers of all internal hard drive drives def GetVolumesSerialNumbers(): + sernums = [] sernum = os.getenv('MYSERIALNUMBER') if sernum != None: - return [sernum] - sernums = [] + sernums.append(sernum.strip()) cmdline = '/usr/sbin/ioreg -w 0 -r -c AppleAHCIDiskDriver' cmdline = cmdline.encode(sys.getfilesystemencoding()) p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) @@ -1285,7 +1288,7 @@ elif isosx: if pp >= 0: sernum = resline[pp+19:-1] sernums.append(sernum.strip()) - return [sernum] + return sernums def GetUserHomeAppSupKindleDirParitionName(): home = os.getenv('HOME') @@ -1311,10 +1314,11 @@ elif isosx: return disk # uses a sub process to get the UUID of the specified disk partition using ioreg - def GetDiskPartitionUUID(diskpart): + def GetDiskPartitionUUIDs(diskpart): + uuids = [] uuidnum = os.getenv('MYUUIDNUMBER') if uuidnum != None: - return uuidnum + uuids.append(strip(uuidnum)) cmdline = '/usr/sbin/ioreg -l -S -w 0 -r -c AppleAHCIDiskDriver' cmdline = cmdline.encode(sys.getfilesystemencoding()) p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) @@ -1357,14 +1361,15 @@ elif isosx: uuidnest = -1 uuidnum = None bsdname = None - if not foundIt: - uuidnum = '' - return uuidnum + if foundIt: + uuids.append(uuidnum) + return uuids - def GetMACAddressMunged(): + def GetMACAddressesMunged(): + macnums = [] macnum = os.getenv('MYMACNUM') if macnum != None: - return macnum + macnums.append(macnum) cmdline = '/sbin/ifconfig en0' cmdline = cmdline.encode(sys.getfilesystemencoding()) p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) @@ -1399,9 +1404,9 @@ elif isosx: macnum = '%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x' % (mlst[0], mlst[1], mlst[2], mlst[3], mlst[4], mlst[5]) foundIt = True break - if not foundIt: - macnum = '' - return macnum + if foundIt: + macnums.append(macnum) + return macnums # uses unix env to get username instead of using sysctlbyname @@ -1412,11 +1417,12 @@ elif isosx: def GetIDStrings(): # Return all possible ID Strings strings = [] - strings.append(GetMACAddressMunged()) + strings.extend(GetMACAddressesMunged()) strings.extend(GetVolumesSerialNumbers()) diskpart = GetUserHomeAppSupKindleDirParitionName() - strings.append(GetDiskPartitionUUID(diskpart)) + strings.extend(GetDiskPartitionUUIDs(diskpart)) strings.append('9999999999') + #print strings return strings @@ -1797,7 +1803,8 @@ def usage(progname): print u" {0:s} [-h] [-k ] []".format(progname) -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"{0} v{1}\nCopyright © 2010-2013 some_updates and Apprentice Alf".format(progname,__version__) @@ -1837,7 +1844,7 @@ def cli_main(argv=unicode_argv()): return 0 -def gui_main(argv=unicode_argv()): +def gui_main(): import Tkinter import Tkconstants import tkMessageBox @@ -1855,6 +1862,7 @@ def gui_main(argv=unicode_argv()): self.text.insert(Tkconstants.END, text) + argv=unicode_argv() root = Tkinter.Tk() root.withdraw() progpath, progname = os.path.split(argv[0]) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlepid.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlepid.py index d16c017..8bbcf69 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlepid.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlepid.py @@ -9,6 +9,7 @@ # 0.3 changed to autoflush stdout, fixed return code usage # 0.3 updated for unicode # 0.4 Added support for serial numbers starting with '9', fixed unicode bugs. +# 0.5 moved unicode_argv call inside main for Windows DeDRM compatibility import sys import binascii @@ -111,8 +112,9 @@ def pidFromSerial(s, l): return pid -def cli_main(argv=unicode_argv()): +def cli_main(): print u"Mobipocket PID calculator for Amazon Kindle. Copyright © 2007, 2009 Igor Skochinsky" + argv=unicode_argv() if len(argv)==2: serial = argv[1] else: diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py index ccbac4e..ee24de5 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/mobidedrm.py @@ -67,9 +67,10 @@ # 0.37 - Fixed double announcement for stand-alone operation # 0.38 - Unicode used wherever possible, cope with absent alfcrypto # 0.39 - Fixed problem with TEXtREAd and getBookType interface +# 0.40 - moved unicode_argv call inside main for Windows DeDRM compatibility -__version__ = u"0.39" +__version__ = u"0.40" import sys import os @@ -506,7 +507,8 @@ def getUnencryptedBook(infile,pidlist): return book.mobi_data -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv)<3 or len(argv)>4: print u"MobiDeDrm v{0}.\nCopyright © 2008-2012 The Dark Reverser et al.".format(__version__) diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/scriptinterface.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/scriptinterface.py index 391b683..3be643f 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/scriptinterface.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/scriptinterface.py @@ -7,6 +7,7 @@ import os import re import ineptepub import ignobleepub +import epubtest import zipfix import ineptpdf import erdr2pml @@ -42,18 +43,14 @@ def decryptepub(infile, outdir, rscpath): try: rv = ineptepub.decryptBook(userkey, zippath, outfile) if rv == 0: + print "Decrypted Adobe ePub with key file {0}".format(filename) break except Exception, e: errlog += traceback.format_exc() errlog += str(e) rv = 1 - - if rv == 0: - os.remove(zippath) - return 0 - # now try with ignoble epub - if ignobleepub.ignobleBook(zippath): + elif ignobleepub.ignobleBook(zippath): # try with any keyfiles (*.b64) in the rscpath files = os.listdir(rscpath) filefilter = re.compile("\.b64$", re.IGNORECASE) @@ -62,15 +59,23 @@ def decryptepub(infile, outdir, rscpath): for filename in files: keypath = os.path.join(rscpath, filename) userkey = open(keypath,'r').read() - print userkey + #print userkey try: rv = ignobleepub.decryptBook(userkey, zippath, outfile) if rv == 0: + print "Decrypted B&N ePub with key file {0}".format(filename) break except Exception, e: errlog += traceback.format_exc() errlog += str(e) rv = 1 + else: + encryption = epubtest.encryption(zippath) + if encryption == "Unencrypted": + print "{0} is not DRMed.".format(name) + rv = 0 + else: + print "{0} has an unknown encryption.".format(name) os.remove(zippath) if rv != 0: diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/subasyncio.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/subasyncio.py deleted file mode 100644 index de084d3..0000000 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/subasyncio.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python -# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab - -import os, sys -import signal -import threading -import subprocess -from subprocess import Popen, PIPE, STDOUT - -# **heavily** chopped up and modfied version of asyncproc.py -# to make it actually work on Windows as well as Mac/Linux -# For the original see: -# "http://www.lysator.liu.se/~bellman/download/" -# author is "Thomas Bellman " -# available under GPL version 3 or Later - -# create an asynchronous subprocess whose output can be collected in -# a non-blocking manner - -# What a mess! Have to use threads just to get non-blocking io -# in a cross-platform manner - -# luckily all thread use is hidden within this class - -class Process(object): - def __init__(self, *params, **kwparams): - if len(params) <= 3: - kwparams.setdefault('stdin', subprocess.PIPE) - if len(params) <= 4: - kwparams.setdefault('stdout', subprocess.PIPE) - if len(params) <= 5: - kwparams.setdefault('stderr', subprocess.PIPE) - self.__pending_input = [] - self.__collected_outdata = [] - self.__collected_errdata = [] - self.__exitstatus = None - self.__lock = threading.Lock() - self.__inputsem = threading.Semaphore(0) - self.__quit = False - - self.__process = subprocess.Popen(*params, **kwparams) - - if self.__process.stdin: - self.__stdin_thread = threading.Thread( - name="stdin-thread", - target=self.__feeder, args=(self.__pending_input, - self.__process.stdin)) - self.__stdin_thread.setDaemon(True) - self.__stdin_thread.start() - - if self.__process.stdout: - self.__stdout_thread = threading.Thread( - name="stdout-thread", - target=self.__reader, args=(self.__collected_outdata, - self.__process.stdout)) - self.__stdout_thread.setDaemon(True) - self.__stdout_thread.start() - - if self.__process.stderr: - self.__stderr_thread = threading.Thread( - name="stderr-thread", - target=self.__reader, args=(self.__collected_errdata, - self.__process.stderr)) - self.__stderr_thread.setDaemon(True) - self.__stderr_thread.start() - - def pid(self): - return self.__process.pid - - def kill(self, signal): - self.__process.send_signal(signal) - - # check on subprocess (pass in 'nowait') to act like poll - def wait(self, flag): - if flag.lower() == 'nowait': - rc = self.__process.poll() - else: - rc = self.__process.wait() - if rc != None: - if self.__process.stdin: - self.closeinput() - if self.__process.stdout: - self.__stdout_thread.join() - if self.__process.stderr: - self.__stderr_thread.join() - return self.__process.returncode - - def terminate(self): - if self.__process.stdin: - self.closeinput() - self.__process.terminate() - - # thread gets data from subprocess stdout - def __reader(self, collector, source): - while True: - data = os.read(source.fileno(), 65536) - self.__lock.acquire() - collector.append(data) - self.__lock.release() - if data == "": - source.close() - break - return - - # thread feeds data to subprocess stdin - def __feeder(self, pending, drain): - while True: - self.__inputsem.acquire() - self.__lock.acquire() - if not pending and self.__quit: - drain.close() - self.__lock.release() - break - data = pending.pop(0) - self.__lock.release() - drain.write(data) - - # non-blocking read of data from subprocess stdout - def read(self): - self.__lock.acquire() - outdata = "".join(self.__collected_outdata) - del self.__collected_outdata[:] - self.__lock.release() - return outdata - - # non-blocking read of data from subprocess stderr - def readerr(self): - self.__lock.acquire() - errdata = "".join(self.__collected_errdata) - del self.__collected_errdata[:] - self.__lock.release() - return errdata - - # non-blocking write to stdin of subprocess - def write(self, data): - if self.__process.stdin is None: - raise ValueError("Writing to process with stdin not a pipe") - self.__lock.acquire() - self.__pending_input.append(data) - self.__inputsem.release() - self.__lock.release() - - # close stdinput of subprocess - def closeinput(self): - self.__lock.acquire() - self.__quit = True - self.__inputsem.release() - self.__lock.release() diff --git a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/topazextract.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/topazextract.py index 71fe8ab..d44ae88 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/topazextract.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/topazextract.py @@ -1,10 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# topazextract.py, version ? +# topazextract.py # Mostly written by some_updates based on code from many others -__version__ = '4.8' +# Changelog +# 4.9 - moved unicode_argv call inside main for Windows DeDRM compatibility + +__version__ = '4.9' import sys import os, csv, getopt @@ -442,7 +445,8 @@ def usage(progname): print u" {0} [-k ] [-p ] [-s ] ".format(progname) # Main -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"TopazExtract v{0}.".format(__version__) diff --git a/DeDRM_calibre_plugin/DeDRM_plugin.zip b/DeDRM_calibre_plugin/DeDRM_plugin.zip index 545288cab0a46846bf642467f6dd9b6b4491d665..1c945e56ecb5c1d6d3a594fb77c5560cd1bcd376 100644 GIT binary patch delta 99222 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 I06#zdf1wWc{{R30 delta 98015 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

D9P}CY4ZL-JYhxx;xO4kX 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

    x5UfJ5Bb!u6@-jQENW`^}G&7J%Z;!RRO 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 T|B_++d~|(g_S^#S^V9za-Fcku diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py b/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py index a9ac2fd..93a9ad7 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py @@ -26,13 +26,14 @@ __docformat__ = 'restructuredtext en' # # Revision history: # 6.0.0 - Initial release +# 6.0.1 - Bug Fixes for Windows App, Kindle for Mac and Windows Adobe Digital Editions """ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 0, 0) +PLUGIN_VERSION_TUPLE = (6, 0, 1) PLUGIN_VERSION = u".".join([unicode(str(x)) for x in PLUGIN_VERSION_TUPLE]) # Include an html helpfile in the plugin's zipfile with the following name. RESOURCE_NAME = PLUGIN_NAME + '_Help.htm' diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/adobekey.py b/DeDRM_calibre_plugin/DeDRM_plugin/adobekey.py index 94f7522..6453508 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/adobekey.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/adobekey.py @@ -46,13 +46,14 @@ from __future__ import with_statement # 5.6 - Revised to allow use in Plugins to eliminate need for duplicate code # 5.7 - Unicode support added, renamed adobekey from ineptkey # 5.8 - Added getkey interface for Windows DeDRM application +# 5.9 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Retrieve Adobe ADEPT user key. """ __license__ = 'GPL v3' -__version__ = '5.8' +__version__ = '5.9' import sys, os, struct, getopt @@ -401,9 +402,11 @@ if iswindows: aes = AES(keykey) userkey = aes.decrypt(userkey) userkey = userkey[26:-ord(userkey[-1])] + #print "found key:",userkey.encode('hex') keys.append(userkey) if len(keys) == 0: raise ADEPTError('Could not locate privateLicenseKey') + print u"Found {0:d} keys".format(len(keys)) return keys @@ -483,7 +486,8 @@ def usage(progname): print u"Usage:" print u" {0:s} [-h] []".format(progname) -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"{0} v{1}\nCopyright © 2009-2013 i♥cabbages and Apprentice Alf".format(progname,__version__) @@ -538,7 +542,7 @@ def cli_main(argv=unicode_argv()): return 0 -def gui_main(argv=unicode_argv()): +def gui_main(): import Tkinter import Tkconstants import tkMessageBox @@ -556,6 +560,7 @@ def gui_main(argv=unicode_argv()): self.text.insert(Tkconstants.END, text) + argv=unicode_argv() root = Tkinter.Tk() root.withdraw() progpath, progname = os.path.split(argv[0]) @@ -574,7 +579,7 @@ def gui_main(argv=unicode_argv()): keyfileout.write(key) success = True tkMessageBox.showinfo(progname, u"Key successfully retrieved to {0}".format(outfile)) - except DrmException, e: + except ADEPTError, e: tkMessageBox.showerror(progname, u"Error: {0}".format(str(e))) except Exception: root.wm_state('normal') diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/config.py b/DeDRM_calibre_plugin/DeDRM_plugin/config.py index 04d87c6..3d5d2ab 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/config.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/config.py @@ -29,10 +29,6 @@ from calibre_plugins.dedrm.__init__ import RESOURCE_NAME as help_file_name from calibre_plugins.dedrm.utilities import (uStrCmp, DETAILED_MESSAGE) import calibre_plugins.dedrm.dialogs as dialogs -import calibre_plugins.dedrm.ignoblekeygen as bandn -import calibre_plugins.dedrm.erdr2pml as ereader -import calibre_plugins.dedrm.adobekey as adobe -import calibre_plugins.dedrm.kindlekey as amazon JSON_NAME = PLUGIN_NAME.strip().lower().replace(' ', '_') JSON_PATH = os.path.join(u"plugins", JSON_NAME + '.json') @@ -212,6 +208,7 @@ def addvaluetoprefs(prefkind, prefsvalue): def convertprefs(always = False): def parseIgnobleString(keystuff): + import calibre_plugins.dedrm.ignoblekeygen as bandn userkeys = {} ar = keystuff.split(':') for i, keystring in enumerate(ar): @@ -230,6 +227,7 @@ def convertprefs(always = False): return userkeys def parseeReaderString(keystuff): + import calibre_plugins.dedrm.erdr2pml as ereader userkeys = {} ar = keystuff.split(':') for i, keystring in enumerate(ar): @@ -302,10 +300,13 @@ def convertprefs(always = False): dedrmprefs['serials'] = [] # get default adobe adept key(s) + import calibre_plugins.dedrm.adobekey as adobe priorkeycount = len(dedrmprefs['adeptkeys']) try: defaultkeys = adobe.adeptkeys() except: + import traceback + traceback.print_exc() defaultkeys = [] defaultcount = 1 for keyvalue in defaultkeys: @@ -323,7 +324,8 @@ def convertprefs(always = False): writeprefs(False) - # get default kindle key(s) + # get default kindle key(s) + import calibre_plugins.dedrm.kindlekey as amazon priorkeycount = len(dedrmprefs['kindlekeys']) try: defaultkeys = amazon.kindlekeys() diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/dialogs.py b/DeDRM_calibre_plugin/DeDRM_plugin/dialogs.py index 21c1dad..2b07328 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/dialogs.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/dialogs.py @@ -7,6 +7,7 @@ __license__ = 'GPL v3' # Standard Python modules. import os, sys, re, hashlib import json +import traceback from PyQt4.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QListWidget, QListWidgetItem, QAbstractItemView, QLineEdit, QPushButton, QIcon, QGroupBox, QDialog, QDialogButtonBox, QUrl, QString) from PyQt4 import QtGui @@ -18,10 +19,6 @@ from calibre.utils.config import dynamic, config_dir, JSONConfig from calibre_plugins.dedrm.__init__ import PLUGIN_NAME, PLUGIN_VERSION from calibre_plugins.dedrm.utilities import (uStrCmp, DETAILED_MESSAGE, parseCustString) -from calibre_plugins.dedrm.ignoblekeygen import generate_key as generate_bandn_key -from calibre_plugins.dedrm.erdr2pml import getuser_key as generate_ereader_key -from calibre_plugins.dedrm.adobekey import adeptkeys as retrieve_adept_keys -from calibre_plugins.dedrm.kindlekey import kindlekeys as retrieve_kindle_keys class ManageKeysDialog(QDialog): def __init__(self, parent, key_type_name, plugin_keys, create_key, keyfile_ext = u""): @@ -393,6 +390,7 @@ class AddBandNKeyDialog(QDialog): @property def key_value(self): + from calibre_plugins.dedrm.ignoblekeygen import generate_key as generate_bandn_key return generate_bandn_key(self.user_name,self.cc_number) @property @@ -473,6 +471,7 @@ class AddEReaderDialog(QDialog): @property def key_value(self): + from calibre_plugins.dedrm.erdr2pml import getuser_key as generate_ereader_key return generate_ereader_key(self.user_name,self.cc_number).encode('hex') @property @@ -505,9 +504,12 @@ class AddAdeptDialog(QDialog): layout = QVBoxLayout(self) self.setLayout(layout) + from calibre_plugins.dedrm.adobekey import adeptkeys as retrieve_adept_keys try: - self.default_key = retrieve_adept_keys()[0] + default_keys = retrieve_adept_keys() + self.default_key = default_keys[0] except: + traceback.print_exc() self.default_key = u"" self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) @@ -567,6 +569,7 @@ class AddKindleDialog(QDialog): layout = QVBoxLayout(self) self.setLayout(layout) + from calibre_plugins.dedrm.kindlekey import kindlekeys as retrieve_kindle_keys try: self.default_key = retrieve_kindle_keys()[0] except: diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/epubtest.py b/DeDRM_calibre_plugin/DeDRM_plugin/epubtest.py index d91624f..11f1427 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/epubtest.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/epubtest.py @@ -9,6 +9,7 @@ # # Changelog epubtest # 1.00 - Cut to epubtest.py, testing ePub files only by Apprentice Alf +# 1.01 - Added routine for use by Windows DeDRM # # Written in 2011 by Paul Durrant # Released with unlicense. See http://unlicense.org/ @@ -45,7 +46,7 @@ from __future__ import with_statement -__version__ = '1.00' +__version__ = '1.01' import sys, struct, os import zlib @@ -72,11 +73,49 @@ class SafeUnbuffered: def __getattr__(self, attr): return getattr(self.stream, attr) +try: + from calibre.constants import iswindows, isosx +except: + iswindows = sys.platform.startswith('win') + isosx = sys.platform.startswith('darwin') + def unicode_argv(): - argvencoding = sys.stdin.encoding - if argvencoding == None: - argvencoding = "utf-8" - return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv] + if iswindows: + # Uses shell32.GetCommandLineArgvW to get sys.argv as a list of Unicode + # strings. + + # Versions 2.x of Python don't support Unicode in sys.argv on + # Windows, with the underlying Windows API instead replacing multi-byte + # characters with '?'. So use shell32.GetCommandLineArgvW to get sys.argv + # as a list of Unicode strings and encode them as utf-8 + + from ctypes import POINTER, byref, cdll, c_int, windll + from ctypes.wintypes import LPCWSTR, LPWSTR + + GetCommandLineW = cdll.kernel32.GetCommandLineW + GetCommandLineW.argtypes = [] + GetCommandLineW.restype = LPCWSTR + + CommandLineToArgvW = windll.shell32.CommandLineToArgvW + CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)] + CommandLineToArgvW.restype = POINTER(LPWSTR) + + cmd = GetCommandLineW() + argc = c_int(0) + argv = CommandLineToArgvW(cmd, byref(argc)) + if argc.value > 0: + # Remove Python executable and commands if present + start = argc.value - len(sys.argv) + return [argv[i] for i in + xrange(start, argc.value)] + # if we don't have any arguments at all, just pass back script name + # this should never happen + return [u"epubtest.py"] + else: + argvencoding = sys.stdin.encoding + if argvencoding == None: + argvencoding = "utf-8" + return [arg if (type(arg) == unicode) else unicode(arg,argvencoding) for arg in sys.argv] _FILENAME_LEN_OFFSET = 26 _EXTRA_LEN_OFFSET = 28 @@ -129,38 +168,38 @@ def getfiledata(file, zi): return data -def main(argv=unicode_argv()): - infile = argv[1] - kind = "Unknown" +def encryption(infile): + # returns encryption: one of Unencrypted, Adobe, B&N and Unknown encryption = "Unknown" - with file(infile,'rb') as infileobject: - bookdata = infileobject.read(58) - # Check for Mobipocket/Kindle - if bookdata[0:0+2] == "PK": - if bookdata[30:30+28] == 'mimetypeapplication/epub+zip': - kind = "ePub" - else: - kind = "ZIP" - encryption = "Unencrypted" - foundrights = False - foundencryption = False - inzip = zipfile.ZipFile(infile,'r') - namelist = set(inzip.namelist()) - if 'META-INF/rights.xml' not in namelist or 'META-INF/encryption.xml' not in namelist: - encryption = "Unencrypted" - else: - rights = etree.fromstring(inzip.read('META-INF/rights.xml')) - adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag) - expr = './/%s' % (adept('encryptedKey'),) - bookkey = ''.join(rights.findtext(expr)) - if len(bookkey) == 172: - encryption = "Adobe" - elif len(bookkey) == 64: - encryption = "B&N" + try: + with open(infile,'rb') as infileobject: + bookdata = infileobject.read(58) + # Check for Zip + if bookdata[0:0+2] == "PK": + foundrights = False + foundencryption = False + inzip = zipfile.ZipFile(infile,'r') + namelist = set(inzip.namelist()) + if 'META-INF/rights.xml' not in namelist or 'META-INF/encryption.xml' not in namelist: + encryption = "Unencrypted" else: - encryption = "Unknown" - - print u"{0} {1}".format(encryption, kind) + rights = etree.fromstring(inzip.read('META-INF/rights.xml')) + adept = lambda tag: '{%s}%s' % (NSMAP['adept'], tag) + expr = './/%s' % (adept('encryptedKey'),) + bookkey = ''.join(rights.findtext(expr)) + if len(bookkey) == 172: + encryption = "Adobe" + elif len(bookkey) == 64: + encryption = "B&N" + else: + encryption = "Unknown" + except: + traceback.print_exc() + return encryption + +def main(): + argv=unicode_argv() + print encryption(argv[1]) return 0 if __name__ == "__main__": diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/erdr2pml.py b/DeDRM_calibre_plugin/DeDRM_plugin/erdr2pml.py index d982a44..1dfef42 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/erdr2pml.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/erdr2pml.py @@ -66,8 +66,9 @@ # - Don't reject dictionary format. # - Ignore sidebars for dictionaries (different format?) # 0.22 - Unicode and plugin support, different image folders for PMLZ and source +# 0.23 - moved unicode_argv call inside main for Windows DeDRM compatibility -__version__='0.22' +__version__='0.23' import sys, re import struct, binascii, getopt, zlib, os, os.path, urllib, tempfile, traceback @@ -551,9 +552,10 @@ def getuser_key(name,cc): cc = cc.replace(" ","") return struct.pack('>LL', binascii.crc32(newname) & 0xffffffff,binascii.crc32(cc[-8:])& 0xffffffff) -def cli_main(argv=unicode_argv()): +def cli_main(): print u"eRdr2Pml v{0}. Copyright © 2009–2012 The Dark Reverser et al.".format(__version__) + argv=unicode_argv() try: opts, args = getopt.getopt(argv[1:], "hp", ["make-pmlz"]) except getopt.GetoptError, err: diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/ignobleepub.py b/DeDRM_calibre_plugin/DeDRM_plugin/ignobleepub.py index 4cf74ae..277cdde 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/ignobleepub.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/ignobleepub.py @@ -33,13 +33,14 @@ from __future__ import with_statement # 3.6 - Revised to allow use in calibre plugins to eliminate need for duplicate code # 3.7 - Tweaked to match ineptepub more closely # 3.8 - Fixed to retain zip file metadata (e.g. file modification date) +# 3.9 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Decrypt Barnes & Noble encrypted ePub books. """ __license__ = 'GPL v3' -__version__ = "3.8" +__version__ = "3.9" import sys import os @@ -316,7 +317,8 @@ def decryptBook(keyb64, inpath, outpath): return 0 -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv) != 4: print u"usage: {0} ".format(progname) diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/ignoblekeygen.py b/DeDRM_calibre_plugin/DeDRM_plugin/ignoblekeygen.py index ec78e65..a6e5dca 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/ignoblekeygen.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/ignoblekeygen.py @@ -31,13 +31,14 @@ from __future__ import with_statement # 2.3 - Modify interface to allow use of import # 2.4 - Improvements to UI and now works in plugins # 2.5 - Additional improvement for unicode and plugin support +# 2.6 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Generate Barnes & Noble EPUB user key from name and credit card number. """ __license__ = 'GPL v3' -__version__ = "2.5" +__version__ = "2.6" import sys import os @@ -214,7 +215,8 @@ def generate_key(name, ccn): -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if AES is None: print "%s: This script requires OpenSSL or PyCrypto, which must be installed " \ diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/ineptepub.py b/DeDRM_calibre_plugin/DeDRM_plugin/ineptepub.py index 98a134e..3fe07d9 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/ineptepub.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/ineptepub.py @@ -35,13 +35,14 @@ from __future__ import with_statement # 5.7 - Fix for potential problem with PyCrypto # 5.8 - Revised to allow use in calibre plugins to eliminate need for duplicate code # 5.9 - Fixed to retain zip file metadata (e.g. file modification date) +# 5.10 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Decrypt Adobe Digital Editions encrypted ePub books. """ __license__ = 'GPL v3' -__version__ = "5.9" +__version__ = "5.10" import sys import os @@ -458,7 +459,8 @@ def decryptBook(userkey, inpath, outpath): return 0 -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv) != 4: print u"usage: {0} ".format(progname) diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/ineptpdf.py b/DeDRM_calibre_plugin/DeDRM_plugin/ineptpdf.py index f4d6d81..69028c6 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/ineptpdf.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/ineptpdf.py @@ -50,13 +50,14 @@ from __future__ import with_statement # 7.11 - More tweaks to fix minor problems. # 7.12 - Revised to allow use in calibre plugins to eliminate need for duplicate code # 7.13 - Fixed erroneous mentions of ineptepub +# 7.14 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Decrypts Adobe ADEPT-encrypted PDF files. """ __license__ = 'GPL v3' -__version__ = "7.13" +__version__ = "7.14" import sys import os @@ -2185,7 +2186,8 @@ def decryptBook(userkey, inpath, outpath): return 0 -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv) != 4: print u"usage: {0} ".format(progname) diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/k4mobidedrm.py b/DeDRM_calibre_plugin/DeDRM_plugin/k4mobidedrm.py index 1ae5c88..e15f104 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/k4mobidedrm.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/k4mobidedrm.py @@ -53,8 +53,9 @@ from __future__ import with_statement # 4.9 - Missed some invalid characters in cleanup_name # 5.0 - Extraction of info from Kindle for PC/Mac moved into kindlekey.py # - tweaked GetDecryptedBook interface to leave passed parameters unchanged +# 5.1 - moved unicode_argv call inside main for Windows DeDRM compatibility -__version__ = '5.0' +__version__ = '5.1' import sys, os, re @@ -276,7 +277,8 @@ def usage(progname): # # Main # -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"K4MobiDeDrm v{0}.\nCopyright © 2008-2013 The Dark Reverser et al.".format(__version__) diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/kindlekey.py b/DeDRM_calibre_plugin/DeDRM_plugin/kindlekey.py index e79622b..453de14 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/kindlekey.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/kindlekey.py @@ -15,13 +15,16 @@ from __future__ import with_statement # 1.3 - Added getkey interface for Windows DeDRM application # Simplified some of the Kindle for Mac code. # 1.4 - Remove dependency on alfcrypto +# 1.5 - moved unicode_argv call inside main for Windows DeDRM compatibility +# 1.6 - Fixed a problem getting the disk serial numbers + """ Retrieve Kindle for PC/Mac user key. """ __license__ = 'GPL v3' -__version__ = '1.4' +__version__ = '1.6' import sys, os, re from struct import pack, unpack, unpack_from @@ -1266,10 +1269,10 @@ elif isosx: # uses a sub process to get the Hard Drive Serial Number using ioreg # returns serial numbers of all internal hard drive drives def GetVolumesSerialNumbers(): + sernums = [] sernum = os.getenv('MYSERIALNUMBER') if sernum != None: - return [sernum] - sernums = [] + sernums.append(sernum.strip()) cmdline = '/usr/sbin/ioreg -w 0 -r -c AppleAHCIDiskDriver' cmdline = cmdline.encode(sys.getfilesystemencoding()) p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) @@ -1285,7 +1288,7 @@ elif isosx: if pp >= 0: sernum = resline[pp+19:-1] sernums.append(sernum.strip()) - return [sernum] + return sernums def GetUserHomeAppSupKindleDirParitionName(): home = os.getenv('HOME') @@ -1311,10 +1314,11 @@ elif isosx: return disk # uses a sub process to get the UUID of the specified disk partition using ioreg - def GetDiskPartitionUUID(diskpart): + def GetDiskPartitionUUIDs(diskpart): + uuids = [] uuidnum = os.getenv('MYUUIDNUMBER') if uuidnum != None: - return uuidnum + uuids.append(strip(uuidnum)) cmdline = '/usr/sbin/ioreg -l -S -w 0 -r -c AppleAHCIDiskDriver' cmdline = cmdline.encode(sys.getfilesystemencoding()) p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) @@ -1357,14 +1361,15 @@ elif isosx: uuidnest = -1 uuidnum = None bsdname = None - if not foundIt: - uuidnum = '' - return uuidnum + if foundIt: + uuids.append(uuidnum) + return uuids - def GetMACAddressMunged(): + def GetMACAddressesMunged(): + macnums = [] macnum = os.getenv('MYMACNUM') if macnum != None: - return macnum + macnums.append(macnum) cmdline = '/sbin/ifconfig en0' cmdline = cmdline.encode(sys.getfilesystemencoding()) p = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) @@ -1399,9 +1404,9 @@ elif isosx: macnum = '%0.2x%0.2x%0.2x%0.2x%0.2x%0.2x' % (mlst[0], mlst[1], mlst[2], mlst[3], mlst[4], mlst[5]) foundIt = True break - if not foundIt: - macnum = '' - return macnum + if foundIt: + macnums.append(macnum) + return macnums # uses unix env to get username instead of using sysctlbyname @@ -1412,11 +1417,12 @@ elif isosx: def GetIDStrings(): # Return all possible ID Strings strings = [] - strings.append(GetMACAddressMunged()) + strings.extend(GetMACAddressesMunged()) strings.extend(GetVolumesSerialNumbers()) diskpart = GetUserHomeAppSupKindleDirParitionName() - strings.append(GetDiskPartitionUUID(diskpart)) + strings.extend(GetDiskPartitionUUIDs(diskpart)) strings.append('9999999999') + #print strings return strings @@ -1797,7 +1803,8 @@ def usage(progname): print u" {0:s} [-h] [-k ] []".format(progname) -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"{0} v{1}\nCopyright © 2010-2013 some_updates and Apprentice Alf".format(progname,__version__) @@ -1837,7 +1844,7 @@ def cli_main(argv=unicode_argv()): return 0 -def gui_main(argv=unicode_argv()): +def gui_main(): import Tkinter import Tkconstants import tkMessageBox @@ -1855,6 +1862,7 @@ def gui_main(argv=unicode_argv()): self.text.insert(Tkconstants.END, text) + argv=unicode_argv() root = Tkinter.Tk() root.withdraw() progpath, progname = os.path.split(argv[0]) diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/kindlepid.py b/DeDRM_calibre_plugin/DeDRM_plugin/kindlepid.py index d16c017..8bbcf69 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/kindlepid.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/kindlepid.py @@ -9,6 +9,7 @@ # 0.3 changed to autoflush stdout, fixed return code usage # 0.3 updated for unicode # 0.4 Added support for serial numbers starting with '9', fixed unicode bugs. +# 0.5 moved unicode_argv call inside main for Windows DeDRM compatibility import sys import binascii @@ -111,8 +112,9 @@ def pidFromSerial(s, l): return pid -def cli_main(argv=unicode_argv()): +def cli_main(): print u"Mobipocket PID calculator for Amazon Kindle. Copyright © 2007, 2009 Igor Skochinsky" + argv=unicode_argv() if len(argv)==2: serial = argv[1] else: diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/mobidedrm.py b/DeDRM_calibre_plugin/DeDRM_plugin/mobidedrm.py index ccbac4e..ee24de5 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/mobidedrm.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/mobidedrm.py @@ -67,9 +67,10 @@ # 0.37 - Fixed double announcement for stand-alone operation # 0.38 - Unicode used wherever possible, cope with absent alfcrypto # 0.39 - Fixed problem with TEXtREAd and getBookType interface +# 0.40 - moved unicode_argv call inside main for Windows DeDRM compatibility -__version__ = u"0.39" +__version__ = u"0.40" import sys import os @@ -506,7 +507,8 @@ def getUnencryptedBook(infile,pidlist): return book.mobi_data -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if len(argv)<3 or len(argv)>4: print u"MobiDeDrm v{0}.\nCopyright © 2008-2012 The Dark Reverser et al.".format(__version__) diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/topazextract.py b/DeDRM_calibre_plugin/DeDRM_plugin/topazextract.py index 71fe8ab..d44ae88 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/topazextract.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/topazextract.py @@ -1,10 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# topazextract.py, version ? +# topazextract.py # Mostly written by some_updates based on code from many others -__version__ = '4.8' +# Changelog +# 4.9 - moved unicode_argv call inside main for Windows DeDRM compatibility + +__version__ = '4.9' import sys import os, csv, getopt @@ -442,7 +445,8 @@ def usage(progname): print u" {0} [-k ] [-p ] [-s ] ".format(progname) # Main -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"TopazExtract v{0}.".format(__version__) diff --git a/DeDRM_calibre_plugin/DeDRM_plugin_ReadMe.txt b/DeDRM_calibre_plugin/DeDRM_plugin_ReadMe.txt index a047ff2..1f7d471 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin_ReadMe.txt +++ b/DeDRM_calibre_plugin/DeDRM_plugin_ReadMe.txt @@ -13,7 +13,7 @@ Do **NOT** select "Get plugins to enhance calibre" as this is reserved for "offi Customization ------------- -On Windows and Mac, the keys for ebooks downloaded for Kindle for Mac/PC and Adobe Digital Editions are automatically generated. If all your DRMed ebooks can be opened and read in Kindle for Mac/PC and/or Adobe Digital Editions on the same computer on which you are running calibre, you do not need to do any configuration of this plugin. On Linux, keys for Kindle for PC and Adobe Figital Editions need to be generated separately (see Linux systems section) +On Windows and Mac, the keys for ebooks downloaded for Kindle for Mac/PC and Adobe Digital Editions are automatically generated. If all your DRMed ebooks can be opened and read in Kindle for Mac/PC and/or Adobe Digital Editions on the same computer on which you are running calibre, you do not need to do any configuration of this plugin. On Linux, keys for Kindle for PC and Adobe Digital Editions need to be generated separately (see Linux systems section) Otherwise, highlight the plugin (DeDRM under the "File type plugins" category) and click the "Customize Plugin" button. diff --git a/Other_Tools/B&N_Download_Helper/BN-Dload.user.js b/Other_Tools/B_and_N_Download_Helper/BN-Dload.user.js similarity index 100% rename from Other_Tools/B&N_Download_Helper/BN-Dload.user.js rename to Other_Tools/B_and_N_Download_Helper/BN-Dload.user.js diff --git a/Other_Tools/B&N_Download_Helper/BN-Dload.user_ReadMe.txt b/Other_Tools/B_and_N_Download_Helper/BN-Dload.user_ReadMe.txt similarity index 100% rename from Other_Tools/B&N_Download_Helper/BN-Dload.user_ReadMe.txt rename to Other_Tools/B_and_N_Download_Helper/BN-Dload.user_ReadMe.txt diff --git a/Other_Tools/DRM_Key_Scripts/Adobe_Digital_Editions/adobekey.pyw b/Other_Tools/DRM_Key_Scripts/Adobe_Digital_Editions/adobekey.pyw index 94f7522..1dcef1d 100644 --- a/Other_Tools/DRM_Key_Scripts/Adobe_Digital_Editions/adobekey.pyw +++ b/Other_Tools/DRM_Key_Scripts/Adobe_Digital_Editions/adobekey.pyw @@ -46,13 +46,14 @@ from __future__ import with_statement # 5.6 - Revised to allow use in Plugins to eliminate need for duplicate code # 5.7 - Unicode support added, renamed adobekey from ineptkey # 5.8 - Added getkey interface for Windows DeDRM application +# 5.9 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Retrieve Adobe ADEPT user key. """ __license__ = 'GPL v3' -__version__ = '5.8' +__version__ = '5.9' import sys, os, struct, getopt @@ -483,7 +484,8 @@ def usage(progname): print u"Usage:" print u" {0:s} [-h] []".format(progname) -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"{0} v{1}\nCopyright © 2009-2013 i♥cabbages and Apprentice Alf".format(progname,__version__) @@ -538,7 +540,7 @@ def cli_main(argv=unicode_argv()): return 0 -def gui_main(argv=unicode_argv()): +def gui_main(): import Tkinter import Tkconstants import tkMessageBox @@ -556,6 +558,7 @@ def gui_main(argv=unicode_argv()): self.text.insert(Tkconstants.END, text) + argv=unicode_argv() root = Tkinter.Tk() root.withdraw() progpath, progname = os.path.split(argv[0]) diff --git a/Other_Tools/DRM_Key_Scripts/Barnes_and_Noble_ePubs/ignoblekeygen.pyw b/Other_Tools/DRM_Key_Scripts/Barnes_and_Noble_ePubs/ignoblekeygen.pyw index ec78e65..a6e5dca 100644 --- a/Other_Tools/DRM_Key_Scripts/Barnes_and_Noble_ePubs/ignoblekeygen.pyw +++ b/Other_Tools/DRM_Key_Scripts/Barnes_and_Noble_ePubs/ignoblekeygen.pyw @@ -31,13 +31,14 @@ from __future__ import with_statement # 2.3 - Modify interface to allow use of import # 2.4 - Improvements to UI and now works in plugins # 2.5 - Additional improvement for unicode and plugin support +# 2.6 - moved unicode_argv call inside main for Windows DeDRM compatibility """ Generate Barnes & Noble EPUB user key from name and credit card number. """ __license__ = 'GPL v3' -__version__ = "2.5" +__version__ = "2.6" import sys import os @@ -214,7 +215,8 @@ def generate_key(name, ccn): -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) if AES is None: print "%s: This script requires OpenSSL or PyCrypto, which must be installed " \ diff --git a/Other_Tools/DRM_Key_Scripts/Kindle_for_Mac_and_PC/kindlekey.pyw b/Other_Tools/DRM_Key_Scripts/Kindle_for_Mac_and_PC/kindlekey.pyw index e79622b..eb4ddd1 100644 --- a/Other_Tools/DRM_Key_Scripts/Kindle_for_Mac_and_PC/kindlekey.pyw +++ b/Other_Tools/DRM_Key_Scripts/Kindle_for_Mac_and_PC/kindlekey.pyw @@ -15,13 +15,15 @@ from __future__ import with_statement # 1.3 - Added getkey interface for Windows DeDRM application # Simplified some of the Kindle for Mac code. # 1.4 - Remove dependency on alfcrypto +# 1.5 - moved unicode_argv call inside main for Windows DeDRM compatibility + """ Retrieve Kindle for PC/Mac user key. """ __license__ = 'GPL v3' -__version__ = '1.4' +__version__ = '1.5' import sys, os, re from struct import pack, unpack, unpack_from @@ -1797,7 +1799,8 @@ def usage(progname): print u" {0:s} [-h] [-k ] []".format(progname) -def cli_main(argv=unicode_argv()): +def cli_main(): + argv=unicode_argv() progname = os.path.basename(argv[0]) print u"{0} v{1}\nCopyright © 2010-2013 some_updates and Apprentice Alf".format(progname,__version__) @@ -1837,7 +1840,7 @@ def cli_main(argv=unicode_argv()): return 0 -def gui_main(argv=unicode_argv()): +def gui_main(): import Tkinter import Tkconstants import tkMessageBox @@ -1855,6 +1858,7 @@ def gui_main(argv=unicode_argv()): self.text.insert(Tkconstants.END, text) + argv=unicode_argv() root = Tkinter.Tk() root.withdraw() progpath, progname = os.path.split(argv[0]) diff --git a/ReadMe_First.txt b/ReadMe_First.txt index 72fe78b..95d3022 100644 --- a/ReadMe_First.txt +++ b/ReadMe_First.txt @@ -1,7 +1,7 @@ Welcome to the tools! ===================== -This ReadMe_First.txt is meant to give users a quick overview of what is available and how to get started. This document is part of the Tools v6.0.0 archive from Apprentice Alf's Blog: http://apprenticealf.wordpress.com/ +This ReadMe_First.txt is meant to give users a quick overview of what is available and how to get started. This document is part of the Tools v6.0.1 archive from Apprentice Alf's Blog: http://apprenticealf.wordpress.com/ The is archive includes tools to remove DRM from: @@ -36,9 +36,9 @@ The DeDRM python GUI is by some_updates and Apprentice Alf Many fixes, updates and enhancements to the scripts and applicatons have been by Apprentice Alf, some_updates and DiapDealer and others. -Calibre Users (Mac OS X, Windows, and Linux) +DeDRM plugin for calibre (Mac OS X, Windows, and Linux) -------------------------------------------- -If you are a calibre user, the quickest and easiest way, especially on Windows, to remove DRM from your ebooks is to install the DeDRM plugin from the DeDRM_plugin folder, following the instructions and configuration directions provided in the ReadMe and the help links. +If you already use calibre, the quickest and easiest way, especially on Windows, to remove DRM from your ebooks is to install the DeDRM plugin from the DeDRM_plugin folder, following the instructions and configuration directions provided in the ReadMe and the help links. Once installed and configured, you can simply add a DRM book to calibre and the DeDRMed version will be imported into the calibre database. Note that DRM removal ONLY occurs on import. If you have already imported DRM books you'll need to remove them from calibre and re-import them. @@ -49,7 +49,7 @@ DeDRM application for Mac OS X users: (Mac OS X 10.4 and above) ---------------------------------------------------------------------- This application combines all the tools into one easy-to-use tool for Mac OS X users. -Drag the "DeDRM 6.0.0.app" application from the DeDRM_Application_Macintosh folder to your Desktop (or your Applications Folder, or anywhere else you find convenient). Double-click on the application to run it and it will guide you through collecting the data it needs to remove the DRM from any of the kinds of DRMed ebook listed in the first section of this ReadMe. +Drag the "DeDRM.app" application from the DeDRM_Application_Macintosh folder to your Desktop (or your Applications Folder, or anywhere else you find convenient). Double-click on the application to run it and it will guide you through collecting the data it needs to remove the DRM from any of the kinds of DRMed ebook listed in the first section of this ReadMe. To use the DeDRM application, simply drag ebooks, or folders containing ebooks, onto the DeDRM application and it will remove the DRM of the kinds listed above. @@ -63,7 +63,7 @@ DeDRM application for Windows users: (Windows XP through Windows 8) This application combines all the tools into one easy-to-use tool for Windows users. -Drag the DeDRM_6.0.0 folder that's in the DeDRM_Application_Windows folder, to your "My Documents" folder (or anywhere else you find convenient). Make a short-cut on your Desktop of the DeDRM_Drop_Target.bat file that's in the DeDRM_6.0.0 folder. Double-click on the shortcut and the DeDRM application will run and guide you through collecting the data it needs to remove the DRM from any of the kinds of DRMed ebook listed in the first section of this ReadMe. +Drag the DeDRM_App folder that's in the DeDRM_Application_Windows folder, to your "My Documents" folder (or anywhere else you find convenient). Make a short-cut on your Desktop of the DeDRM_Drop_Target.bat file that's in the DeDRM_App folder. Double-click on the shortcut and the DeDRM application will run and guide you through collecting the data it needs to remove the DRM from any of the kinds of DRMed ebook listed in the first section of this ReadMe. To use the DeDRM application, simply drag ebooks, or folders containing ebooks, onto the DeDRM_Drop_Target.bat shortcut and it will remove the DRM of the kinds listed above. @@ -72,13 +72,10 @@ For more detailed instructions, see the DeDRM_Application_ReadMe.txt file in the Other_Tools ----------- -This folder includes other useful tools: +This folder includes other tools that may be useful for DRMed ebooks from certain sources or for Linux users. Most users won't need any of these tools. -Key_Generation_Script -This folder contains a python script that creates a hashed keyfile for Barnes and Noble ePubs, and will be useful to Windows and Linux users who don't want to use the plugin. - -Key_Retrieval_Scripts -This folder contains python script that retrieve keyfiles for Kindle for Mac and Adobe Digital Editions, and will be useful to all Linux Users. +Key_Generation_Scripts +This folder contains python scripts that creates a keyfiles for Barnes and Noble ePubs, Adobe Digital Editions ePubs and Kindle for Mac/PC ebooks. The will mostly be useful for Linux users using the calibre plugin. Kindle_for_Android_Patches Definitely only for the adventurous, this folder contains information on how to modify the Kindel for Android app to b able to get a PID for use with the other Kindle tools (DeDRM apps and calibre plugin).