]> xmof Git - DeDRM.git/commitdiff
Support .kinf2018 on Mac
authorapprenticesakuya <62770541+apprenticesakuya@users.noreply.github.com>
Thu, 11 Jun 2020 17:26:36 +0000 (17:26 +0000)
committerGitHub <noreply@github.com>
Thu, 11 Jun 2020 17:26:36 +0000 (17:26 +0000)
DeDRM_plugin/kindlekey.py

index 9a00b1fb5f1385e867e66cc371e71e26fd90811d..9a299e628faf9a3676ac4969297e90c5ca80dce3 100644 (file)
@@ -1449,6 +1449,18 @@ elif isosx:
         kInfoFiles=[]
         found = False
         home = os.getenv('HOME')
+        # check for  .kinf2018 file in new location (App Store Kindle for Mac)
+        testpath = home + '/Library/Containers/com.amazon.Kindle/Data/Library/Application Support/Kindle/storage/.kinf2018'
+        if os.path.isfile(testpath):
+            kInfoFiles.append(testpath)
+            print('Found k4Mac kinf2018 file: ' + testpath)
+            found = True
+        # check for  .kinf2018 files
+        testpath = home + '/Library/Application Support/Kindle/storage/.kinf2018'
+        if os.path.isfile(testpath):
+            kInfoFiles.append(testpath)
+            print('Found k4Mac kinf2018 file: ' + testpath)
+            found = True
         # 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):
@@ -1529,12 +1541,21 @@ elif isosx:
                 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)
+                    version = int(m.group(1))
+                    build = m.group(2)
+                    guid = m.group(4)
 
-                cud = CryptUnprotectData(entropy,IDString)
+                if version == 5:  # .kinf2011: identical to K4PC, except the build number gets multiplied
+                    entropy = str(0x2df * int(build)) + guid
+                    cud = CryptUnprotectData(entropy,IDString)
+
+                elif version == 6:  # .kinf2018: identical to K4PC
+                    salt = str(0x6d8 * int(build)) + guid
+                    sp = GetUserName() + '+@#$%+' + IDString
+                    passwd = encode(SHA256(sp), charMap5)
+                    key = LibCrypto().keyivgen(passwd, salt, 10000, 0x400)[:32]
 
                 # loop through the item records until all are processed
                 while len(items) > 0:
@@ -1595,9 +1616,28 @@ elif isosx:
                     encdata = encdata[noffset:]
                     encdata = encdata + pfx
 
-                    # decode using testMap8 to get the CryptProtect Data
-                    encryptedValue = decode(encdata,testMap8)
-                    cleartext = cud.decrypt(encryptedValue)
+                    if version == 5:
+                        # decode using testMap8 to get the CryptProtect Data
+                        encryptedValue = decode(encdata,testMap8)
+                        cleartext = cud.decrypt(encryptedValue)
+
+                    elif version == 6:
+                        from Crypto.Cipher import AES
+                        from Crypto.Util import Counter
+                        # decode using new testMap8 to get IV + ciphertext
+                        iv_ciphertext = decode(encdata, testMap8)
+                        # pad IV so that we can substitute AES-CTR for GCM
+                        iv = iv_ciphertext[:12] + b'\x00\x00\x00\x02'
+                        ciphertext = iv_ciphertext[12:]
+                        # convert IV to int for use with pycrypto
+                        iv_ints = unpack('>QQ', iv)
+                        iv = iv_ints[0] << 64 | iv_ints[1]
+                        # set up AES-CTR
+                        ctr = Counter.new(128, initial_value=iv)
+                        cipher = AES.new(key, AES.MODE_CTR, counter=ctr)
+                        # decrypt and decode
+                        cleartext = decode(cipher.decrypt(ciphertext), charMap5)
+
                     # print keyname
                     # print cleartext
                     if len(cleartext) > 0: