diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist index c36a4c0..94ad26c 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist @@ -24,7 +24,7 @@ CFBundleExecutable droplet CFBundleGetInfoString - DeDRM AppleScript 6.3.6 Written 2010–2016 by Apprentice Alf et al. + DeDRM AppleScript 6.4.0 Written 2010–2016 by Apprentice Alf et al. CFBundleIconFile DeDRM CFBundleIdentifier @@ -36,13 +36,13 @@ CFBundlePackageType APPL CFBundleShortVersionString - 6.3.6 + 6.4.0 CFBundleSignature dplt LSRequiresCarbon NSHumanReadableCopyright - Copyright © 2010–2015 Apprentice Alf and Apprentice Harper + Copyright © 2010–2016 Apprentice Alf and Apprentice Harper WindowState bundleDividerCollapsed diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py index ceef266..880d9fe 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py @@ -48,6 +48,7 @@ __docformat__ = 'restructuredtext en' # 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17 # 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging # 6.3.6 - Fixes for ADE ePub and PDF introduced in 6.3.5 +# 6.4.0 - Updated for new Kindle for PC encryption """ @@ -55,7 +56,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 3, 6) +PLUGIN_VERSION_TUPLE = (6, 4, 0) 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/kgenpids.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kgenpids.py index faa51d1..e99857a 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kgenpids.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kgenpids.py @@ -199,9 +199,6 @@ def getK4Pids(rec209, token, kindleDatabase): # Get the Mazama Random number MazamaRandomNumber = (kindleDatabase[1])['MazamaRandomNumber'].decode('hex') - # Get the kindle account token - kindleAccountToken = (kindleDatabase[1])['kindle.account.tokens'].decode('hex') - # Get the IDString used to decode the Kindle Info file IDString = (kindleDatabase[1])['IDString'].decode('hex') @@ -212,6 +209,14 @@ def getK4Pids(rec209, token, kindleDatabase): print u"Keys not found in the database {0}.".format(kindleDatabase[0]) return pids + try: + # Get the kindle account token, if present + kindleAccountToken = (kindleDatabase[1])['kindle.account.tokens'].decode('hex') + + except KeyError: + kindleAccountToken="" + pass + # Get the ID string used encodedIDString = encodeHash(IDString,charMap1) diff --git a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py index a597a26..c5159cc 100644 --- a/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py +++ b/DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py @@ -993,7 +993,22 @@ if iswindows: # 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'] + 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',\ + 'build_version',\ + ] + DB = {} with open(kInfoFile, 'rb') as infoReader: hdr = infoReader.read(1) @@ -1134,6 +1149,8 @@ if iswindows: 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 @@ -1158,14 +1175,17 @@ if iswindows: # decode using new testMap8 to get the original CryptProtect Data encryptedValue = decode(encdata,testMap8) cleartext = CryptUnprotectData(encryptedValue, entropy, 1) - DB[keyname] = cleartext + if len(cleartext)>0: + DB[keyname] = cleartext + #print keyname, cleartext - if 'kindle.account.tokens' in DB: + if len(DB)>4: # store values used in decryption DB['IDString'] = GetIDString() DB['UserName'] = GetUserName() print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(GetIDString(), GetUserName().encode('hex')) else: + print u"Couldn't decrypt file." DB = {} return DB elif isosx: @@ -1577,7 +1597,21 @@ elif isosx: # 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'] + 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',\ + 'build_version',\ + ] with open(kInfoFile, 'rb') as infoReader: filehdr = infoReader.read(1) filedata = infoReader.read() @@ -1683,7 +1717,7 @@ elif isosx: if len(cleartext) > 0: DB[keyname] = cleartext - if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB: + if len(DB)>4: break else: # the latest .kinf2011 version for K4M 1.9.1 @@ -1772,11 +1806,11 @@ elif isosx: if len(cleartext) > 0: DB[keyname] = cleartext - if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB: + if len(DB)>4: break except: pass - if 'kindle.account.tokens' in DB: + if len(DB)>4: # store values used in decryption print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(IDString, GetUserName()) DB['IDString'] = IDString 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 18d9af8..4eda87f 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw @@ -21,8 +21,9 @@ # 6.3.4 - Version bump to match plugin # 6.3.5 - Version bump to match plugin # 6.3.6 - Version bump to match plugin +# 6.4.0 - Fix for Kindle for PC encryption change -__version__ = '6.3.6' +__version__ = '6.4.0' import sys import os, os.path 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 ceef266..880d9fe 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py @@ -48,6 +48,7 @@ __docformat__ = 'restructuredtext en' # 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17 # 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging # 6.3.6 - Fixes for ADE ePub and PDF introduced in 6.3.5 +# 6.4.0 - Updated for new Kindle for PC encryption """ @@ -55,7 +56,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 3, 6) +PLUGIN_VERSION_TUPLE = (6, 4, 0) 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/kgenpids.py b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kgenpids.py index faa51d1..e99857a 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kgenpids.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kgenpids.py @@ -199,9 +199,6 @@ def getK4Pids(rec209, token, kindleDatabase): # Get the Mazama Random number MazamaRandomNumber = (kindleDatabase[1])['MazamaRandomNumber'].decode('hex') - # Get the kindle account token - kindleAccountToken = (kindleDatabase[1])['kindle.account.tokens'].decode('hex') - # Get the IDString used to decode the Kindle Info file IDString = (kindleDatabase[1])['IDString'].decode('hex') @@ -212,6 +209,14 @@ def getK4Pids(rec209, token, kindleDatabase): print u"Keys not found in the database {0}.".format(kindleDatabase[0]) return pids + try: + # Get the kindle account token, if present + kindleAccountToken = (kindleDatabase[1])['kindle.account.tokens'].decode('hex') + + except KeyError: + kindleAccountToken="" + pass + # Get the ID string used encodedIDString = encodeHash(IDString,charMap1) 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 a597a26..c5159cc 100644 --- a/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlekey.py +++ b/DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlekey.py @@ -993,7 +993,22 @@ if iswindows: # 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'] + 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',\ + 'build_version',\ + ] + DB = {} with open(kInfoFile, 'rb') as infoReader: hdr = infoReader.read(1) @@ -1134,6 +1149,8 @@ if iswindows: 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 @@ -1158,14 +1175,17 @@ if iswindows: # decode using new testMap8 to get the original CryptProtect Data encryptedValue = decode(encdata,testMap8) cleartext = CryptUnprotectData(encryptedValue, entropy, 1) - DB[keyname] = cleartext + if len(cleartext)>0: + DB[keyname] = cleartext + #print keyname, cleartext - if 'kindle.account.tokens' in DB: + if len(DB)>4: # store values used in decryption DB['IDString'] = GetIDString() DB['UserName'] = GetUserName() print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(GetIDString(), GetUserName().encode('hex')) else: + print u"Couldn't decrypt file." DB = {} return DB elif isosx: @@ -1577,7 +1597,21 @@ elif isosx: # 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'] + 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',\ + 'build_version',\ + ] with open(kInfoFile, 'rb') as infoReader: filehdr = infoReader.read(1) filedata = infoReader.read() @@ -1683,7 +1717,7 @@ elif isosx: if len(cleartext) > 0: DB[keyname] = cleartext - if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB: + if len(DB)>4: break else: # the latest .kinf2011 version for K4M 1.9.1 @@ -1772,11 +1806,11 @@ elif isosx: if len(cleartext) > 0: DB[keyname] = cleartext - if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB: + if len(DB)>4: break except: pass - if 'kindle.account.tokens' in DB: + if len(DB)>4: # store values used in decryption print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(IDString, GetUserName()) DB['IDString'] = IDString diff --git a/DeDRM_calibre_plugin/DeDRM_plugin.zip b/DeDRM_calibre_plugin/DeDRM_plugin.zip index 9261c6e..5ad702b 100644 Binary files a/DeDRM_calibre_plugin/DeDRM_plugin.zip and b/DeDRM_calibre_plugin/DeDRM_plugin.zip differ diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py b/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py index ceef266..880d9fe 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/__init__.py @@ -48,6 +48,7 @@ __docformat__ = 'restructuredtext en' # 6.3.4 - Fixes for Kindle for Android, Linux, and Kobo 3.17 # 6.3.5 - Fixes for Linux, and Kobo 3.19 and more logging # 6.3.6 - Fixes for ADE ePub and PDF introduced in 6.3.5 +# 6.4.0 - Updated for new Kindle for PC encryption """ @@ -55,7 +56,7 @@ Decrypt DRMed ebooks. """ PLUGIN_NAME = u"DeDRM" -PLUGIN_VERSION_TUPLE = (6, 3, 6) +PLUGIN_VERSION_TUPLE = (6, 4, 0) 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/kgenpids.py b/DeDRM_calibre_plugin/DeDRM_plugin/kgenpids.py index faa51d1..e99857a 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/kgenpids.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/kgenpids.py @@ -199,9 +199,6 @@ def getK4Pids(rec209, token, kindleDatabase): # Get the Mazama Random number MazamaRandomNumber = (kindleDatabase[1])['MazamaRandomNumber'].decode('hex') - # Get the kindle account token - kindleAccountToken = (kindleDatabase[1])['kindle.account.tokens'].decode('hex') - # Get the IDString used to decode the Kindle Info file IDString = (kindleDatabase[1])['IDString'].decode('hex') @@ -212,6 +209,14 @@ def getK4Pids(rec209, token, kindleDatabase): print u"Keys not found in the database {0}.".format(kindleDatabase[0]) return pids + try: + # Get the kindle account token, if present + kindleAccountToken = (kindleDatabase[1])['kindle.account.tokens'].decode('hex') + + except KeyError: + kindleAccountToken="" + pass + # Get the ID string used encodedIDString = encodeHash(IDString,charMap1) diff --git a/DeDRM_calibre_plugin/DeDRM_plugin/kindlekey.py b/DeDRM_calibre_plugin/DeDRM_plugin/kindlekey.py index a597a26..c5159cc 100644 --- a/DeDRM_calibre_plugin/DeDRM_plugin/kindlekey.py +++ b/DeDRM_calibre_plugin/DeDRM_plugin/kindlekey.py @@ -993,7 +993,22 @@ if iswindows: # 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'] + 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',\ + 'build_version',\ + ] + DB = {} with open(kInfoFile, 'rb') as infoReader: hdr = infoReader.read(1) @@ -1134,6 +1149,8 @@ if iswindows: 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 @@ -1158,14 +1175,17 @@ if iswindows: # decode using new testMap8 to get the original CryptProtect Data encryptedValue = decode(encdata,testMap8) cleartext = CryptUnprotectData(encryptedValue, entropy, 1) - DB[keyname] = cleartext + if len(cleartext)>0: + DB[keyname] = cleartext + #print keyname, cleartext - if 'kindle.account.tokens' in DB: + if len(DB)>4: # store values used in decryption DB['IDString'] = GetIDString() DB['UserName'] = GetUserName() print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(GetIDString(), GetUserName().encode('hex')) else: + print u"Couldn't decrypt file." DB = {} return DB elif isosx: @@ -1577,7 +1597,21 @@ elif isosx: # 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'] + 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',\ + 'build_version',\ + ] with open(kInfoFile, 'rb') as infoReader: filehdr = infoReader.read(1) filedata = infoReader.read() @@ -1683,7 +1717,7 @@ elif isosx: if len(cleartext) > 0: DB[keyname] = cleartext - if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB: + if len(DB)>4: break else: # the latest .kinf2011 version for K4M 1.9.1 @@ -1772,11 +1806,11 @@ elif isosx: if len(cleartext) > 0: DB[keyname] = cleartext - if 'MazamaRandomNumber' in DB and 'kindle.account.tokens' in DB: + if len(DB)>4: break except: pass - if 'kindle.account.tokens' in DB: + if len(DB)>4: # store values used in decryption print u"Decrypted key file using IDString '{0:s}' and UserName '{1:s}'".format(IDString, GetUserName()) DB['IDString'] = IDString