]> xmof Git - DeDRM.git/commitdiff
First try at a fix for the Kindle for PC encryption update
authorApprentice Harper <apprenticeharper@gmail.com>
Sun, 13 Mar 2016 12:00:57 +0000 (12:00 +0000)
committerApprentice Harper <apprenticeharper@gmail.com>
Sun, 13 Mar 2016 12:00:57 +0000 (12:00 +0000)
12 files changed:
DeDRM_Macintosh_Application/DeDRM.app/Contents/Info.plist
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/__init__.py
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kgenpids.py
DeDRM_Macintosh_Application/DeDRM.app/Contents/Resources/kindlekey.py
DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/DeDRM_App.pyw
DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/__init__.py
DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kgenpids.py
DeDRM_Windows_Application/DeDRM_App/DeDRM_lib/lib/kindlekey.py
DeDRM_calibre_plugin/DeDRM_plugin.zip
DeDRM_calibre_plugin/DeDRM_plugin/__init__.py
DeDRM_calibre_plugin/DeDRM_plugin/kgenpids.py
DeDRM_calibre_plugin/DeDRM_plugin/kindlekey.py

index c36a4c0d3e703408936c8ecb0a1dee3906f8a55f..94ad26c39e2bb8624869b6102fb7768f80ac6334 100644 (file)
@@ -24,7 +24,7 @@
        <key>CFBundleExecutable</key>
        <string>droplet</string>
        <key>CFBundleGetInfoString</key>
-       <string>DeDRM AppleScript 6.3.6 Written 2010–2016 by Apprentice Alf et al.</string>
+       <string>DeDRM AppleScript 6.4.0 Written 2010–2016 by Apprentice Alf et al.</string>
        <key>CFBundleIconFile</key>
        <string>DeDRM</string>
        <key>CFBundleIdentifier</key>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>6.3.6</string>
+       <string>6.4.0</string>
        <key>CFBundleSignature</key>
        <string>dplt</string>
        <key>LSRequiresCarbon</key>
        <true/>
        <key>NSHumanReadableCopyright</key>
-       <string>Copyright © 2010–2015 Apprentice Alf and Apprentice Harper</string>
+       <string>Copyright © 2010–2016 Apprentice Alf and Apprentice Harper</string>
        <key>WindowState</key>
        <dict>
                <key>bundleDividerCollapsed</key>
index ceef266b9f5a665980c231ce55b3aca1c8ce7681..880d9fe62dd254f4fe4d57fcd7d3bd3b3dcef206 100644 (file)
@@ -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'
index faa51d13b2b7552b53be8814379a527645e4a203..e99857aae948abdb54a186eee9fce4783d95ab8b 100644 (file)
@@ -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)
 
index a597a26f92aa79e0d6f8ab2d8c16aee7f6f2f415..c5159ccb9404da64c214681500c895afb78c981f 100644 (file)
@@ -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
index 18d9af847be7a16fffe22cb8347cb6aea228f406..4eda87f910a2f18254ca5a1fe283c9e2c25c41eb 100644 (file)
@@ -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
index ceef266b9f5a665980c231ce55b3aca1c8ce7681..880d9fe62dd254f4fe4d57fcd7d3bd3b3dcef206 100644 (file)
@@ -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'
index faa51d13b2b7552b53be8814379a527645e4a203..e99857aae948abdb54a186eee9fce4783d95ab8b 100644 (file)
@@ -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)
 
index a597a26f92aa79e0d6f8ab2d8c16aee7f6f2f415..c5159ccb9404da64c214681500c895afb78c981f 100644 (file)
@@ -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
index 9261c6e4ec1cbe9d32ea87fef08a3a97239a717a..5ad702b751320a68e0da2cf0659922b92afc744e 100644 (file)
Binary files a/DeDRM_calibre_plugin/DeDRM_plugin.zip and b/DeDRM_calibre_plugin/DeDRM_plugin.zip differ
index ceef266b9f5a665980c231ce55b3aca1c8ce7681..880d9fe62dd254f4fe4d57fcd7d3bd3b3dcef206 100644 (file)
@@ -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'
index faa51d13b2b7552b53be8814379a527645e4a203..e99857aae948abdb54a186eee9fce4783d95ab8b 100644 (file)
@@ -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)
 
index a597a26f92aa79e0d6f8ab2d8c16aee7f6f2f415..c5159ccb9404da64c214681500c895afb78c981f 100644 (file)
@@ -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