Add back unpad to fix Python2 support

This commit is contained in:
NoDRM 2022-03-19 10:14:45 +01:00
parent cf095a4171
commit b283777c0a
10 changed files with 109 additions and 29 deletions

View File

@ -96,7 +96,7 @@ import traceback
try: try:
import __version import __version
except ModuleNotFoundError: except:
print("#############################") print("#############################")
print("Failed to load the DeDRM plugin") 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.") 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.")

View File

@ -39,7 +39,7 @@ Retrieve Adobe ADEPT user key.
""" """
__license__ = 'GPL v3' __license__ = 'GPL v3'
__version__ = '7.3' __version__ = '7.4'
import sys, os, struct, getopt import sys, os, struct, getopt
from base64 import b64decode from base64 import b64decode
@ -128,10 +128,16 @@ if iswindows:
try: try:
from Cryptodome.Cipher import AES from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import unpad
except ImportError: except ImportError:
from Crypto.Cipher import AES 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' DEVICE_KEY_PATH = r'Software\Adobe\Adept\Device'
PRIVATE_LICENCE_KEY_PATH = r'Software\Adobe\Adept\Activation' PRIVATE_LICENCE_KEY_PATH = r'Software\Adobe\Adept\Activation'
@ -381,7 +387,7 @@ if iswindows:
pass pass
if ktype == 'privateLicenseKey': if ktype == 'privateLicenseKey':
userkey = winreg.QueryValueEx(plkkey, 'value')[0] 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)) # print ("found " + uuid_name + " key: " + str(userkey))
keys.append(userkey) keys.append(userkey)

View File

@ -23,10 +23,17 @@ import sys, os, time
import base64, hashlib import base64, hashlib
try: try:
from Cryptodome.Cipher import AES from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import unpad
except ImportError: except ImportError:
from Crypto.Cipher import AES 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" 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] hash_key = hashlib.sha1(bytearray.fromhex(serial_number + PASS_HASH_SECRET)).digest()[:16]
encrypted_cc_hash = base64.b64decode(passhash) 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") return base64.b64encode(cc_hash).decode("ascii")

View File

@ -36,10 +36,8 @@ from binascii import a2b_hex, b2a_hex
try: try:
from Cryptodome.Cipher import AES, DES from Cryptodome.Cipher import AES, DES
from Cryptodome.Util.Padding import pad, unpad
except ImportError: except ImportError:
from Crypto.Cipher import AES, DES from Crypto.Cipher import AES, DES
from Crypto.Util.Padding import pad, unpad
# Routines common to Mac and PC # Routines common to Mac and PC
@ -116,6 +114,20 @@ STORAGE = "backup.ab"
STORAGE1 = "AmazonSecureStorage.xml" STORAGE1 = "AmazonSecureStorage.xml"
STORAGE2 = "map_data_storage.db" 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): class AndroidObfuscation(object):
'''AndroidObfuscation '''AndroidObfuscation
For the key, it's written in java, and run in android dalvikvm For the key, it's written in java, and run in android dalvikvm

View File

@ -10,13 +10,19 @@ import os
import base64 import base64
try: try:
from Cryptodome.Cipher import AES from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import unpad
except ImportError: except ImportError:
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import hashlib import hashlib
from lxml import etree 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" PASS_HASH_SECRET = "9ca588496a1bc4394553d9e018d70b9e"
@ -46,10 +52,13 @@ def dump_keys(path_to_adobe_folder):
hashes = [] hashes = []
for pass_hash in activation_xml.findall(".//{http://ns.adobe.com/adept}passHash"): for pass_hash in activation_xml.findall(".//{http://ns.adobe.com/adept}passHash"):
encrypted_cc_hash = base64.b64decode(pass_hash.text) try:
cc_hash = unpad(AES.new(hash_key, AES.MODE_CBC, encrypted_cc_hash[:16]).decrypt(encrypted_cc_hash[16:]), 16) encrypted_cc_hash = base64.b64decode(pass_hash.text)
hashes.append(base64.b64encode(cc_hash).decode("ascii")) cc_hash = unpad(AES.new(hash_key, AES.MODE_CBC, encrypted_cc_hash[:16]).decrypt(encrypted_cc_hash[16:]))
#print("Nook ccHash is %s" % (base64.b64encode(cc_hash).decode("ascii"))) hashes.append(base64.b64encode(cc_hash).decode("ascii"))
#print("Nook ccHash is %s" % (base64.b64encode(cc_hash).decode("ascii")))
except:
pass
return hashes return hashes

View File

@ -16,13 +16,19 @@ import base64
import traceback import traceback
try: try:
from Cryptodome.Cipher import AES from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import unpad
except: except:
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import hashlib import hashlib
from lxml import etree 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" NOOK_DATA_FOLDER = "%LOCALAPPDATA%\\Packages\\BarnesNoble.Nook_ahnzqzva31enc\\LocalState"
PASS_HASH_SECRET = "9ca588496a1bc4394553d9e018d70b9e" PASS_HASH_SECRET = "9ca588496a1bc4394553d9e018d70b9e"

View File

@ -56,11 +56,18 @@ import hashlib
try: try:
from Cryptodome.Cipher import AES, PKCS1_v1_5 from Cryptodome.Cipher import AES, PKCS1_v1_5
from Cryptodome.PublicKey import RSA from Cryptodome.PublicKey import RSA
from Cryptodome.Util.Padding import unpad
except ImportError: except ImportError:
from Crypto.Cipher import AES, PKCS1_v1_5 from Crypto.Cipher import AES, PKCS1_v1_5
from Crypto.PublicKey import RSA 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 # Wrap a stream so that output gets flushed immediately
# and also make sure that any unicode strings get # and also make sure that any unicode strings get

View File

@ -75,11 +75,19 @@ from uuid import UUID
try: try:
from Cryptodome.Cipher import AES, ARC4, PKCS1_v1_5 from Cryptodome.Cipher import AES, ARC4, PKCS1_v1_5
from Cryptodome.PublicKey import RSA from Cryptodome.PublicKey import RSA
from Cryptodome.Util.Padding import unpad
except ImportError: except ImportError:
from Crypto.Cipher import AES, ARC4, PKCS1_v1_5 from Crypto.Cipher import AES, ARC4, PKCS1_v1_5
from Crypto.PublicKey import RSA 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 # Wrap a stream so that output gets flushed immediately
# and also make sure that any unicode strings get # and also make sure that any unicode strings get

View File

@ -33,10 +33,8 @@ from io import BytesIO
try: try:
from Cryptodome.Cipher import AES from Cryptodome.Cipher import AES
from Cryptodome.Util.py3compat import bchr from Cryptodome.Util.py3compat import bchr
from Cryptodome.Util.Padding import unpad
except ImportError: except ImportError:
from Crypto.Cipher import AES from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from Crypto.Util.py3compat import bchr from Crypto.Util.py3compat import bchr
try: try:
@ -750,6 +748,26 @@ def addprottable(ion):
ion.addtocatalog("ProtectedData", 1, SYM_NAMES) 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 # every VoucherEnvelope version has a corresponding "word" and magic number, used in obfuscating the shared secret
OBFUSCATION_TABLE = { OBFUSCATION_TABLE = {
"V1": (0x00, None), "V1": (0x00, None),
@ -865,7 +883,7 @@ class DrmIonVoucher(object):
key = hmac.new(sharedsecret, b"PIDv3", digestmod=hashlib.sha256).digest() key = hmac.new(sharedsecret, b"PIDv3", digestmod=hashlib.sha256).digest()
aes = AES.new(key[:32], AES.MODE_CBC, self.cipheriv[:16]) aes = AES.new(key[:32], AES.MODE_CBC, self.cipheriv[:16])
b = aes.decrypt(self.ciphertext) b = aes.decrypt(self.ciphertext)
b = unpad(b, 16) b = pkcs7unpad(b, 16)
self.drmkey = BinaryIonParser(BytesIO(b)) self.drmkey = BinaryIonParser(BytesIO(b))
addprottable(self.drmkey) addprottable(self.drmkey)
@ -1071,7 +1089,7 @@ class DrmIon(object):
def processpage(self, ct, civ, outpages, decompress, decrypt): def processpage(self, ct, civ, outpages, decompress, decrypt):
if decrypt: if decrypt:
aes = AES.new(self.key[:16], AES.MODE_CBC, civ[:16]) aes = AES.new(self.key[:16], AES.MODE_CBC, civ[:16])
msg = unpad(aes.decrypt(ct), 16) msg = pkcs7unpad(aes.decrypt(ct), 16)
else: else:
msg = ct msg = ct

View File

@ -166,7 +166,7 @@
from __future__ import print_function from __future__ import print_function
__version__ = '10.0.1' __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 sys
import os import os
@ -185,10 +185,17 @@ import tempfile
try: try:
from Cryptodome.Cipher import AES from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import unpad
except ImportError: except ImportError:
from Crypto.Cipher import AES 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 can_parse_xml = True
try: try: