More Python2 bugfixes

This commit is contained in:
NoDRM 2023-08-03 20:01:38 +02:00
parent e509b7d520
commit bc089ee46d
7 changed files with 75 additions and 19 deletions

View File

@ -101,4 +101,5 @@ This is v10.0.9, a release candidate for v10.1.0. I don't expect there to be maj
- Fix a bug where decrypting a 40-bit RC4 pdf with R=2 didn't work. - Fix a bug where decrypting a 40-bit RC4 pdf with R=2 didn't work.
- Fix a bug where decrypting a 256-bit AES pdf with V=5 didn't work. - Fix a bug where decrypting a 256-bit AES pdf with V=5 didn't work.
- Fix bugs in kgenpids.py and kindlekey.py that caused it to fail on Python 2 (#380). - Fix bugs in kgenpids.py, alfcrypto.py, mobidedrm.py and kindlekey.py that caused it to fail on Python 2 (#380).
- Fix some bugs (Python 2 and Python 3) in erdr2pml.py (untested).

View File

@ -96,7 +96,10 @@ import traceback
#@@CALIBRE_COMPAT_CODE@@ #@@CALIBRE_COMPAT_CODE@@
try: try:
import __version try:
from . import __version
except:
import __version
except: except:
print("#############################") print("#############################")
print("Failed to load the DeDRM plugin") print("Failed to load the DeDRM plugin")
@ -134,8 +137,10 @@ try:
except: except:
config_dir = "" config_dir = ""
try:
import utilities from . import utilities
except:
import utilities
PLUGIN_NAME = __version.PLUGIN_NAME PLUGIN_NAME = __version.PLUGIN_NAME
@ -915,6 +920,9 @@ class DeDRM(FileTypePlugin):
# perhaps we need to get a new default Kindle for Mac/PC key # perhaps we need to get a new default Kindle for Mac/PC key
defaultkeys = [] defaultkeys = []
print("{0} v{1}: Failed to decrypt with error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION,e.args[0])) print("{0} v{1}: Failed to decrypt with error: {2}".format(PLUGIN_NAME, PLUGIN_VERSION,e.args[0]))
traceback.print_exc()
print("{0} v{1}: Looking for new default Kindle Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)) print("{0} v{1}: Looking for new default Kindle Key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
try: try:

View File

@ -8,6 +8,7 @@
# pbkdf2.py Copyright © 2009 Daniel Holth <dholth@fastmail.fm> # pbkdf2.py Copyright © 2009 Daniel Holth <dholth@fastmail.fm>
# pbkdf2.py This code may be freely used and modified for any purpose. # pbkdf2.py This code may be freely used and modified for any purpose.
import sys
import hmac import hmac
from struct import pack from struct import pack
import hashlib import hashlib
@ -25,7 +26,10 @@ class Pukall_Cipher(object):
raise Exception("PC1: Bad key length") raise Exception("PC1: Bad key length")
wkey = [] wkey = []
for i in range(8): for i in range(8):
wkey.append(key[i*2]<<8 | key[i*2+1]) if sys.version_info[0] == 2:
wkey.append(ord(key[i*2])<<8 | ord(key[i*2+1]))
else:
wkey.append(key[i*2]<<8 | key[i*2+1])
dst = bytearray(len(src)) dst = bytearray(len(src))
for i in range(len(src)): for i in range(len(src)):
temp1 = 0; temp1 = 0;
@ -37,7 +41,12 @@ class Pukall_Cipher(object):
sum2 = (sum2+sum1)&0xFFFF sum2 = (sum2+sum1)&0xFFFF
temp1 = (temp1*20021+1)&0xFFFF temp1 = (temp1*20021+1)&0xFFFF
byteXorVal ^= temp1 ^ sum2 byteXorVal ^= temp1 ^ sum2
curByte = src[i]
if sys.version_info[0] == 2:
curByte = ord(src[i])
else:
curByte = src[i]
if not decryption: if not decryption:
keyXorVal = curByte * 257; keyXorVal = curByte * 257;
curByte = ((curByte ^ (byteXorVal >> 8)) ^ byteXorVal) & 0xFF curByte = ((curByte ^ (byteXorVal >> 8)) ^ byteXorVal) & 0xFF
@ -45,7 +54,12 @@ class Pukall_Cipher(object):
keyXorVal = curByte * 257; keyXorVal = curByte * 257;
for j in range(8): for j in range(8):
wkey[j] ^= keyXorVal; wkey[j] ^= keyXorVal;
dst[i] = curByte
if sys.version_info[0] == 2:
dst[i] = chr(curByte)
else:
dst[i] = curByte
return bytes(dst) return bytes(dst)
class Topaz_Cipher(object): class Topaz_Cipher(object):
@ -103,7 +117,7 @@ class KeyIVGen(object):
def xorbytes( a, b ): def xorbytes( a, b ):
if len(a) != len(b): if len(a) != len(b):
raise Exception("xorbytes(): lengths differ") raise Exception("xorbytes(): lengths differ")
return bytes([x ^ y for x, y in zip(a, b)]) return bytes(bytearray([x ^ y for x, y in zip(a, b)]))
def prf( h, data ): def prf( h, data ):
hm = h.copy() hm = h.copy()

View File

@ -79,12 +79,16 @@ except ImportError:
#@@CALIBRE_COMPAT_CODE@@ #@@CALIBRE_COMPAT_CODE@@
from utilities import SafeUnbuffered try:
from utilities import SafeUnbuffered
from argv_utils import unicode_argv
except:
from . import utilities, argv_utils
iswindows = sys.platform.startswith('win') iswindows = sys.platform.startswith('win')
isosx = sys.platform.startswith('darwin') isosx = sys.platform.startswith('darwin')
from argv_utils import unicode_argv
import cgi import cgi
import logging import logging
@ -141,14 +145,20 @@ def sanitizeFileName(name):
def fixKey(key): def fixKey(key):
def fixByte(b): def fixByte(b):
if sys.version_info[0] == 2:
b = ord(b)
return b ^ ((b ^ (b<<1) ^ (b<<2) ^ (b<<3) ^ (b<<4) ^ (b<<5) ^ (b<<6) ^ (b<<7) ^ 0x80) & 0x80) return b ^ ((b ^ (b<<1) ^ (b<<2) ^ (b<<3) ^ (b<<4) ^ (b<<5) ^ (b<<6) ^ (b<<7) ^ 0x80) & 0x80)
return bytes([fixByte(a) for a in key]) return bytes(bytearray([fixByte(a) for a in key]))
def deXOR(text, sp, table): def deXOR(text, sp, table):
r='' r=b''
j = sp j = sp
for i in range(len(text)): for i in range(len(text)):
r += chr(ord(table[j]) ^ ord(text[i])) if sys.version_info[0] == 2:
r += chr(ord(table[j]) ^ ord(text[i]))
else:
r += bytes(bytearray([table[j] ^ text[i]]))
j = j + 1 j = j + 1
if j == len(table): if j == len(table):
j = 0 j = 0

View File

@ -190,6 +190,10 @@ def getKindlePids(rec209, token, serialnum):
if isinstance(serialnum,str): if isinstance(serialnum,str):
serialnum = serialnum.encode('utf-8') serialnum = serialnum.encode('utf-8')
if sys.version_info[0] == 2:
if isinstance(serialnum,unicode):
serialnum = serialnum.encode('utf-8')
if rec209 is None: if rec209 is None:
return [serialnum] return [serialnum]

View File

@ -62,7 +62,12 @@ except NameError:
# Routines common to Mac and PC # Routines common to Mac and PC
from utilities import SafeUnbuffered try:
from utilities import SafeUnbuffered
from argv_utils import unicode_argv
except:
from . import utilities, argv_utils
try: try:
from calibre.constants import iswindows, isosx from calibre.constants import iswindows, isosx
@ -70,7 +75,7 @@ except:
iswindows = sys.platform.startswith('win') iswindows = sys.platform.startswith('win')
isosx = sys.platform.startswith('darwin') isosx = sys.platform.startswith('darwin')
from argv_utils import unicode_argv
class DrmException(Exception): class DrmException(Exception):
pass pass

View File

@ -124,7 +124,11 @@ def getSizeOfTrailingDataEntries(ptr, size, flags):
if size <= 0: if size <= 0:
return result return result
while True: while True:
v = ptr[size-1] if sys.version_info[0] == 2:
v = ord(ptr[size-1])
else:
v = ptr[size-1]
result |= (v & 0x7F) << bitpos result |= (v & 0x7F) << bitpos
bitpos += 7 bitpos += 7
size -= 1 size -= 1
@ -140,7 +144,10 @@ def getSizeOfTrailingDataEntries(ptr, size, flags):
# if multibyte data is included in the encryped data, we'll # if multibyte data is included in the encryped data, we'll
# have already cleared this flag. # have already cleared this flag.
if flags & 1: if flags & 1:
num += (ptr[size - num - 1] & 0x3) + 1 if sys.version_info[0] == 2:
num += (ord(ptr[size - num - 1]) & 0x3) + 1
else:
num += (ptr[size - num - 1] & 0x3) + 1
return num return num
@ -299,7 +306,10 @@ class MobiBook:
for pid in pidlist: for pid in pidlist:
bigpid = pid.encode('utf-8').ljust(16,b'\0') bigpid = pid.encode('utf-8').ljust(16,b'\0')
temp_key = PC1(keyvec1, bigpid, False) temp_key = PC1(keyvec1, bigpid, False)
temp_key_sum = sum(temp_key) & 0xff if sys.version_info[0] == 2:
temp_key_sum = sum(map(ord,temp_key)) & 0xff
else:
temp_key_sum = sum(temp_key) & 0xff
found_key = None found_key = None
for i in range(count): for i in range(count):
verification, size, type, cksum, cookie = struct.unpack('>LLLBxxx32s', data[i*0x30:i*0x30+0x30]) verification, size, type, cksum, cookie = struct.unpack('>LLLBxxx32s', data[i*0x30:i*0x30+0x30])
@ -315,7 +325,11 @@ class MobiBook:
# Then try the default encoding that doesn't require a PID # Then try the default encoding that doesn't require a PID
pid = '00000000' pid = '00000000'
temp_key = keyvec1 temp_key = keyvec1
temp_key_sum = sum(temp_key) & 0xff if sys.version_info[0] == 2:
temp_key_sum = sum(map(ord,temp_key)) & 0xff
else:
temp_key_sum = sum(temp_key) & 0xff
for i in range(count): for i in range(count):
verification, size, type, cksum, cookie = struct.unpack('>LLLBxxx32s', data[i*0x30:i*0x30+0x30]) verification, size, type, cksum, cookie = struct.unpack('>LLLBxxx32s', data[i*0x30:i*0x30+0x30])
if cksum == temp_key_sum: if cksum == temp_key_sum: