From b283777c0a429e5f0ec322e5c27d0579ca96dcbb Mon Sep 17 00:00:00 2001 From: NoDRM Date: Sat, 19 Mar 2022 10:14:45 +0100 Subject: [PATCH] Add back unpad to fix Python2 support --- DeDRM_plugin/__init__.py | 2 +- DeDRM_plugin/adobekey.py | 14 ++++++++++---- DeDRM_plugin/adobekey_get_passhash.py | 13 ++++++++++--- DeDRM_plugin/androidkindlekey.py | 16 ++++++++++++++-- DeDRM_plugin/ignoblekeyAndroid.py | 21 +++++++++++++++------ DeDRM_plugin/ignoblekeyWindowsStore.py | 10 ++++++++-- DeDRM_plugin/ineptepub.py | 11 +++++++++-- DeDRM_plugin/ineptpdf.py | 12 ++++++++++-- DeDRM_plugin/ion.py | 26 ++++++++++++++++++++++---- Obok_plugin/obok/obok.py | 13 ++++++++++--- 10 files changed, 109 insertions(+), 29 deletions(-) diff --git a/DeDRM_plugin/__init__.py b/DeDRM_plugin/__init__.py index 7559b99..74612c6 100644 --- a/DeDRM_plugin/__init__.py +++ b/DeDRM_plugin/__init__.py @@ -96,7 +96,7 @@ import traceback try: import __version -except ModuleNotFoundError: +except: print("#############################") print("Failed to load the DeDRM plugin") print("Did you bundle this from source code yourself? If so, you'll need to run make_release.py instead to generate a valid plugin file.") diff --git a/DeDRM_plugin/adobekey.py b/DeDRM_plugin/adobekey.py index 36c18de..50e2c71 100644 --- a/DeDRM_plugin/adobekey.py +++ b/DeDRM_plugin/adobekey.py @@ -39,7 +39,7 @@ Retrieve Adobe ADEPT user key. """ __license__ = 'GPL v3' -__version__ = '7.3' +__version__ = '7.4' import sys, os, struct, getopt from base64 import b64decode @@ -128,10 +128,16 @@ if iswindows: try: from Cryptodome.Cipher import AES - from Cryptodome.Util.Padding import unpad except ImportError: from Crypto.Cipher import AES - from Crypto.Util.Padding import unpad + + def unpad(data, padding=16): + if sys.version_info[0] == 2: + pad_len = ord(data[-1]) + else: + pad_len = data[-1] + + return data[:-pad_len] DEVICE_KEY_PATH = r'Software\Adobe\Adept\Device' PRIVATE_LICENCE_KEY_PATH = r'Software\Adobe\Adept\Activation' @@ -381,7 +387,7 @@ if iswindows: pass if ktype == 'privateLicenseKey': userkey = winreg.QueryValueEx(plkkey, 'value')[0] - userkey = unpad(AES.new(keykey, AES.MODE_CBC, b'\x00'*16).decrypt(b64decode(userkey)), 16)[26:] + userkey = unpad(AES.new(keykey, AES.MODE_CBC, b'\x00'*16).decrypt(b64decode(userkey)))[26:] # print ("found " + uuid_name + " key: " + str(userkey)) keys.append(userkey) diff --git a/DeDRM_plugin/adobekey_get_passhash.py b/DeDRM_plugin/adobekey_get_passhash.py index 72b7cd5..1e9b8e2 100644 --- a/DeDRM_plugin/adobekey_get_passhash.py +++ b/DeDRM_plugin/adobekey_get_passhash.py @@ -23,10 +23,17 @@ import sys, os, time import base64, hashlib try: from Cryptodome.Cipher import AES - from Cryptodome.Util.Padding import unpad except ImportError: from Crypto.Cipher import AES - from Crypto.Util.Padding import unpad + + +def unpad(data, padding=16): + if sys.version_info[0] == 2: + pad_len = ord(data[-1]) + else: + pad_len = data[-1] + + return data[:-pad_len] PASS_HASH_SECRET = "9ca588496a1bc4394553d9e018d70b9e" @@ -48,7 +55,7 @@ def decrypt_passhash(passhash, fp): hash_key = hashlib.sha1(bytearray.fromhex(serial_number + PASS_HASH_SECRET)).digest()[:16] encrypted_cc_hash = base64.b64decode(passhash) - cc_hash = unpad(AES.new(hash_key, AES.MODE_CBC, encrypted_cc_hash[:16]).decrypt(encrypted_cc_hash[16:]), 16) + cc_hash = unpad(AES.new(hash_key, AES.MODE_CBC, encrypted_cc_hash[:16]).decrypt(encrypted_cc_hash[16:])) return base64.b64encode(cc_hash).decode("ascii") diff --git a/DeDRM_plugin/androidkindlekey.py b/DeDRM_plugin/androidkindlekey.py index 6b152f3..971d7c3 100755 --- a/DeDRM_plugin/androidkindlekey.py +++ b/DeDRM_plugin/androidkindlekey.py @@ -36,10 +36,8 @@ from binascii import a2b_hex, b2a_hex try: from Cryptodome.Cipher import AES, DES - from Cryptodome.Util.Padding import pad, unpad except ImportError: from Crypto.Cipher import AES, DES - from Crypto.Util.Padding import pad, unpad # Routines common to Mac and PC @@ -116,6 +114,20 @@ STORAGE = "backup.ab" STORAGE1 = "AmazonSecureStorage.xml" STORAGE2 = "map_data_storage.db" + +def unpad(data, padding=16): + if sys.version_info[0] == 2: + pad_len = ord(data[-1]) + else: + pad_len = data[-1] + + return data[:-pad_len] + +def pad(data, padding_len=16): + padding_data_len = padding_len - (len(data) % padding_len) + plaintext = data + chr(padding_data_len) * padding_data_len + return plaintext + class AndroidObfuscation(object): '''AndroidObfuscation For the key, it's written in java, and run in android dalvikvm diff --git a/DeDRM_plugin/ignoblekeyAndroid.py b/DeDRM_plugin/ignoblekeyAndroid.py index 5fcbd6a..e0b2f23 100644 --- a/DeDRM_plugin/ignoblekeyAndroid.py +++ b/DeDRM_plugin/ignoblekeyAndroid.py @@ -10,13 +10,19 @@ import os import base64 try: from Cryptodome.Cipher import AES - from Cryptodome.Util.Padding import unpad except ImportError: from Crypto.Cipher import AES - from Crypto.Util.Padding import unpad import hashlib from lxml import etree +def unpad(data, padding=16): + if sys.version_info[0] == 2: + pad_len = ord(data[-1]) + else: + pad_len = data[-1] + + return data[:-pad_len] + PASS_HASH_SECRET = "9ca588496a1bc4394553d9e018d70b9e" @@ -46,10 +52,13 @@ def dump_keys(path_to_adobe_folder): hashes = [] for pass_hash in activation_xml.findall(".//{http://ns.adobe.com/adept}passHash"): - encrypted_cc_hash = base64.b64decode(pass_hash.text) - cc_hash = unpad(AES.new(hash_key, AES.MODE_CBC, encrypted_cc_hash[:16]).decrypt(encrypted_cc_hash[16:]), 16) - hashes.append(base64.b64encode(cc_hash).decode("ascii")) - #print("Nook ccHash is %s" % (base64.b64encode(cc_hash).decode("ascii"))) + try: + encrypted_cc_hash = base64.b64decode(pass_hash.text) + cc_hash = unpad(AES.new(hash_key, AES.MODE_CBC, encrypted_cc_hash[:16]).decrypt(encrypted_cc_hash[16:])) + hashes.append(base64.b64encode(cc_hash).decode("ascii")) + #print("Nook ccHash is %s" % (base64.b64encode(cc_hash).decode("ascii"))) + except: + pass return hashes diff --git a/DeDRM_plugin/ignoblekeyWindowsStore.py b/DeDRM_plugin/ignoblekeyWindowsStore.py index 886c7cd..29df204 100644 --- a/DeDRM_plugin/ignoblekeyWindowsStore.py +++ b/DeDRM_plugin/ignoblekeyWindowsStore.py @@ -16,13 +16,19 @@ import base64 import traceback try: from Cryptodome.Cipher import AES - from Cryptodome.Util.Padding import unpad except: from Crypto.Cipher import AES - from Crypto.Util.Padding import unpad import hashlib from lxml import etree +def unpad(data, padding=16): + if sys.version_info[0] == 2: + pad_len = ord(data[-1]) + else: + pad_len = data[-1] + + return data[:-pad_len] + NOOK_DATA_FOLDER = "%LOCALAPPDATA%\\Packages\\BarnesNoble.Nook_ahnzqzva31enc\\LocalState" PASS_HASH_SECRET = "9ca588496a1bc4394553d9e018d70b9e" diff --git a/DeDRM_plugin/ineptepub.py b/DeDRM_plugin/ineptepub.py index aa7b571..b9ec149 100644 --- a/DeDRM_plugin/ineptepub.py +++ b/DeDRM_plugin/ineptepub.py @@ -56,11 +56,18 @@ import hashlib try: from Cryptodome.Cipher import AES, PKCS1_v1_5 from Cryptodome.PublicKey import RSA - from Cryptodome.Util.Padding import unpad except ImportError: from Crypto.Cipher import AES, PKCS1_v1_5 from Crypto.PublicKey import RSA - from Crypto.Util.Padding import unpad + + +def unpad(data, padding=16): + if sys.version_info[0] == 2: + pad_len = ord(data[-1]) + else: + pad_len = data[-1] + + return data[:-pad_len] # Wrap a stream so that output gets flushed immediately # and also make sure that any unicode strings get diff --git a/DeDRM_plugin/ineptpdf.py b/DeDRM_plugin/ineptpdf.py index 4319997..cb179de 100755 --- a/DeDRM_plugin/ineptpdf.py +++ b/DeDRM_plugin/ineptpdf.py @@ -75,11 +75,19 @@ from uuid import UUID try: from Cryptodome.Cipher import AES, ARC4, PKCS1_v1_5 from Cryptodome.PublicKey import RSA - from Cryptodome.Util.Padding import unpad except ImportError: from Crypto.Cipher import AES, ARC4, PKCS1_v1_5 from Crypto.PublicKey import RSA - from Crypto.Util.Padding import unpad + + +def unpad(data, padding=16): + if sys.version_info[0] == 2: + pad_len = ord(data[-1]) + else: + pad_len = data[-1] + + return data[:-pad_len] + # Wrap a stream so that output gets flushed immediately # and also make sure that any unicode strings get diff --git a/DeDRM_plugin/ion.py b/DeDRM_plugin/ion.py index f9cd879..45e9610 100644 --- a/DeDRM_plugin/ion.py +++ b/DeDRM_plugin/ion.py @@ -33,10 +33,8 @@ from io import BytesIO try: from Cryptodome.Cipher import AES from Cryptodome.Util.py3compat import bchr - from Cryptodome.Util.Padding import unpad except ImportError: from Crypto.Cipher import AES - from Crypto.Util.Padding import unpad from Crypto.Util.py3compat import bchr try: @@ -750,6 +748,26 @@ def addprottable(ion): ion.addtocatalog("ProtectedData", 1, SYM_NAMES) +def pkcs7pad(msg, blocklen): + paddinglen = blocklen - len(msg) % blocklen + padding = bchr(paddinglen) * paddinglen + return msg + padding + + +def pkcs7unpad(msg, blocklen): + _assert(len(msg) % blocklen == 0) + + paddinglen = msg[-1] + + _assert(paddinglen > 0 and paddinglen <= blocklen, "Incorrect padding - Wrong key") + _assert(msg[-paddinglen:] == bchr(paddinglen) * paddinglen, "Incorrect padding - Wrong key") + + return msg[:-paddinglen] + + + + + # every VoucherEnvelope version has a corresponding "word" and magic number, used in obfuscating the shared secret OBFUSCATION_TABLE = { "V1": (0x00, None), @@ -865,7 +883,7 @@ class DrmIonVoucher(object): key = hmac.new(sharedsecret, b"PIDv3", digestmod=hashlib.sha256).digest() aes = AES.new(key[:32], AES.MODE_CBC, self.cipheriv[:16]) b = aes.decrypt(self.ciphertext) - b = unpad(b, 16) + b = pkcs7unpad(b, 16) self.drmkey = BinaryIonParser(BytesIO(b)) addprottable(self.drmkey) @@ -1071,7 +1089,7 @@ class DrmIon(object): def processpage(self, ct, civ, outpages, decompress, decrypt): if decrypt: aes = AES.new(self.key[:16], AES.MODE_CBC, civ[:16]) - msg = unpad(aes.decrypt(ct), 16) + msg = pkcs7unpad(aes.decrypt(ct), 16) else: msg = ct diff --git a/Obok_plugin/obok/obok.py b/Obok_plugin/obok/obok.py index e95e8d1..e7da430 100644 --- a/Obok_plugin/obok/obok.py +++ b/Obok_plugin/obok/obok.py @@ -166,7 +166,7 @@ from __future__ import print_function __version__ = '10.0.1' -__about__ = "Obok v{0}\nCopyright © 2012-2020 Physisticated et al.".format(__version__) +__about__ = "Obok v{0}\nCopyright © 2012-2022 Physisticated et al.".format(__version__) import sys import os @@ -185,10 +185,17 @@ import tempfile try: from Cryptodome.Cipher import AES - from Cryptodome.Util.Padding import unpad except ImportError: from Crypto.Cipher import AES - from Crypto.Util.Padding import unpad + +def unpad(data, padding=16): + if sys.version_info[0] == 2: + pad_len = ord(data[-1]) + else: + pad_len = data[-1] + + return data[:-pad_len] + can_parse_xml = True try: