Finally, a proper fix for the accented user name problem

This commit is contained in:
Apprentice Harper 2017-07-04 07:05:51 +01:00
parent a252dd0da6
commit c3fbb83dbc
6 changed files with 105 additions and 61 deletions

View File

@ -2,6 +2,10 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
# __init__.py for DeDRM_plugin
# Copyright © 2008-2017 Apprentice Harper et al.
__license__ = 'GPL v3'
__docformat__ = 'restructuredtext en'
@ -58,6 +62,7 @@ __docformat__ = 'restructuredtext en'
# 6.5.2 - Another Topaz fix
# 6.5.3 - Warn about KFX files explicitly
# 6.5.4 - Mac App Fix, improve PDF decryption, handle latest tcl changes in ActivePython
# 6.5.5 - Finally a fix for the Windows non-ASCII user names.
"""
@ -65,7 +70,7 @@ Decrypt DRMed ebooks.
"""
PLUGIN_NAME = u"DeDRM"
PLUGIN_VERSION_TUPLE = (6, 5, 4)
PLUGIN_VERSION_TUPLE = (6, 5, 5)
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'
@ -289,8 +294,8 @@ class DeDRM(FileTypePlugin):
except Exception, e:
pass
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds.\nRead the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds.".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
# import the Adobe Adept ePub handler
import calibre_plugins.dedrm.ineptepub as ineptepub
@ -380,17 +385,19 @@ class DeDRM(FileTypePlugin):
except:
print u"{0} v{1}: Exception when saving a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
traceback.print_exc()
print u"{0} v{1}: Decrypted with new default key after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
print u"{0} v{1}: Decrypted with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
# Return the modified PersistentTemporary file to calibre.
return of.name
print u"{0} v{1}: Failed to decrypt with new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
except Exception, e:
print u"{0} v{1}: Unexpected Exception trying a new default key after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime)
traceback.print_exc()
pass
# Something went wrong with decryption.
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds.\nRead the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds.".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
# Not a Barnes & Noble nor an Adobe Adept
# Import the fixed epub.
@ -489,8 +496,8 @@ class DeDRM(FileTypePlugin):
pass
# Something went wrong with decryption.
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds.\nRead the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds.".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
def KindleMobiDecrypt(self,path_to_ebook):
@ -557,8 +564,8 @@ class DeDRM(FileTypePlugin):
pass
if not decoded:
#if you reached here then no luck raise and exception
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds.\nRead the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime))
of = self.temporary_file(book.getBookExtension())
book.getFile(of.name)
@ -592,8 +599,8 @@ class DeDRM(FileTypePlugin):
print u"{0} v{1}: Failed to decrypt with key {2:s} after {3:.1f} seconds".format(PLUGIN_NAME, PLUGIN_VERSION,keyname_masked,time.time()-self.starttime)
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds.\nRead the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds.".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
print u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION,time.time()-self.starttime)
raise DeDRMError(u"{0} v{1}: Ultimately failed to decrypt after {2:.1f} seconds. Read the FAQs at Harper's repository: https://github.com/apprenticeharper/DeDRM_tools/blob/master/FAQs.md".format(PLUGIN_NAME, PLUGIN_VERSION, time.time()-self.starttime))
def run(self, path_to_ebook):

View File

@ -3,10 +3,13 @@
from __future__ import with_statement
# k4mobidedrm.py, version 5.3
# Copyright © 2009-2015 by ApprenticeHarper et al.
# k4mobidedrm.py
# Copyright © 2008-2017 by Apprentice Harper et al.
# engine to remove drm from Kindle and Mobipocket ebooks
__license__ = 'GPL v3'
__version__ = '5.5'
# Engine to remove drm from Kindle and Mobipocket ebooks
# for personal use for archiving and converting your ebooks
# PLEASE DO NOT PIRATE EBOOKS!
@ -17,12 +20,11 @@ from __future__ import with_statement
# readable for a long, long time
# This borrows very heavily from works by CMBDTC, IHeartCabbages, skindle,
# unswindle, DarkReverser, ApprenticeAlf, DiapDealer, some_updates
# and many many others
# unswindle, DarkReverser, ApprenticeAlf, and many many others
# Special thanks to The Dark Reverser for MobiDeDrm and CMBDTC for cmbdtc_dump
# from which this script borrows most unashamedly.
# Changelog
# 1.0 - Name change to k4mobidedrm. Adds Mac support, Adds plugin code
# 1.1 - Adds support for additional kindle.info files
@ -57,9 +59,7 @@ from __future__ import with_statement
# 5.2 - Fixed error in command line processing of unicode arguments
# 5.3 - Changed Android support to allow passing of backup .ab files
# 5.4 - Recognise KFX files masquerading as azw, even if we can't decrypt them yet.
__version__ = '5.4'
# 5.5 - Added GPL v3 licence explicitly.
import sys, os, re
import csv
@ -295,7 +295,7 @@ def usage(progname):
def cli_main():
argv=unicode_argv()
progname = os.path.basename(argv[0])
print u"K4MobiDeDrm v{0}.\nCopyright © 2008-2013 The Dark Reverser et al.".format(__version__)
print u"K4MobiDeDrm v{0}.\nCopyright © 2008-2017 Apprentice Harper et al.".format(__version__)
try:
opts, args = getopt.getopt(argv[1:], "k:p:s:a:")

View File

@ -4,10 +4,14 @@
from __future__ import with_statement
# kgenpids.py
# Copyright © 2010-2015 by some_updates, Apprentice Alf and Apprentice Harper
# Copyright © 2008-2017 Apprentice Harper et al.
__license__ = 'GPL v3'
__version__ = '2.1'
# Revision history:
# 2.0 - Fix for non-ascii Windows user names
# 2.1 - Actual fix for non-ascii WIndows user names.
import sys
import os, csv
@ -194,21 +198,7 @@ keynames = ['kindle.account.tokens','kindle.cookie.item','eulaVersionAccepted','
def getK4Pids(rec209, token, kindleDatabase):
global charMap1
pids = []
try:
# Get the Mazama Random number
MazamaRandomNumber = (kindleDatabase[1])['MazamaRandomNumber'].decode('hex')
# Get the IDString used to decode the Kindle Info file
IDString = (kindleDatabase[1])['IDString'].decode('hex')
# Get the UserName stored when the Kindle Info file was decoded
UserName = (kindleDatabase[1])['UserName'].decode('hex')
except KeyError:
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')
@ -217,14 +207,47 @@ def getK4Pids(rec209, token, kindleDatabase):
kindleAccountToken=""
pass
# Get the ID string used
encodedIDString = encodeHash(IDString,charMap1)
try:
# Get the DSN token, if present
DSN = (kindleDatabase[1])['DSN'].decode('hex')
print u"Got DSN key from database {0}".format(kindleDatabase[0])
except KeyError:
# See if we have the info to generate the DSN
try:
# Get the Mazama Random number
MazamaRandomNumber = (kindleDatabase[1])['MazamaRandomNumber'].decode('hex')
#print u"Got MazamaRandomNumber from database {0}".format(kindleDatabase[0])
try:
# Get the SerialNumber token, if present
IDString = (kindleDatabase[1])['SerialNumber'].decode('hex')
print u"Got SerialNumber from database {0}".format(kindleDatabase[0])
except KeyError:
# Get the IDString we added
IDString = (kindleDatabase[1])['IDString'].decode('hex')
# Get the current user name
encodedUsername = encodeHash(UserName,charMap1)
try:
# Get the UsernameHash token, if present
encodedUsername = (kindleDatabase[1])['UsernameHash'].decode('hex')
print u"Got UsernameHash from database {0}".format(kindleDatabase[0])
except KeyError:
# Get the UserName we added
UserName = (kindleDatabase[1])['UserName'].decode('hex')
# encode it
encodedUsername = encodeHash(UserName,charMap1)
#print u"encodedUsername",encodedUsername.encode('hex')
except KeyError:
print u"Keys not found in the database {0}.".format(kindleDatabase[0])
return pids
# concat, hash and encode to calculate the DSN
DSN = encode(SHA1(MazamaRandomNumber+encodedIDString+encodedUsername),charMap1)
# Get the ID string used
encodedIDString = encodeHash(IDString,charMap1)
#print u"encodedIDString",encodedIDString.encode('hex')
# concat, hash and encode to calculate the DSN
DSN = encode(SHA1(MazamaRandomNumber+encodedIDString+encodedUsername),charMap1)
#print u"DSN",DSN.encode('hex')
pass
# Compute the device PID (for which I can tell, is used for nothing).
table = generatePidEncryptionTable()

View File

@ -4,7 +4,10 @@
from __future__ import with_statement
# kindlekey.py
# Copyright © 2010-2017 by some_updates, Apprentice Alf and Apprentice Harper
# Copyright © 2008-2017 Apprentice Harper et al.
__license__ = 'GPL v3'
__version__ = '2.5'
# Revision history:
# 1.0 - Kindle info file decryption, extracted from k4mobidedrm, etc.
@ -24,15 +27,13 @@ from __future__ import with_statement
# Also removed old .kinfo file support (pre-2011)
# 2.3 - Added more field names thanks to concavegit's KFX code.
# 2.4 - Fix for complex Mac disk setups, thanks to Tibs
# 2.5 - Final Fix for Windows user names with non-ascii characters, thanks to oneofusoneofus
"""
Retrieve Kindle for PC/Mac user key.
"""
__license__ = 'GPL v3'
__version__ = '2.4'
import sys, os, re
from struct import pack, unpack, unpack_from
import json
@ -887,10 +888,18 @@ if iswindows:
if errcd == 234:
# bad wine implementation up through wine 1.3.21
return "AlternateUserName"
# double the buffer size
buffer = create_unicode_buffer(len(buffer) * 2)
size.value = len(buffer)
# return low byte of the unicode value of each character of the username
return buffer.value.encode('utf-16-le')[::2]
# replace any non-ASCII values with 0xfffd
for i in xrange(0,len(buffer)):
if buffer[i]>u"\u007f":
#print u"swapping char "+str(i)+" ("+buffer[i]+")"
buffer[i] = u"\ufffd"
# return utf-8 encoding of modified username
#print u"modified username:"+buffer.value
return buffer.value.encode('utf-8')
return GetUserName
GetUserName = GetUserName()
@ -1015,7 +1024,12 @@ if iswindows:
'SerialNumber',\
'UsernameHash',\
'kindle.directedid.info',\
'DSN'
'DSN',\
'kindle.accounttype.info',\
'krx.flashcardsplugin.data.encryption_key',\
'krx.notebookexportplugin.data.encryption_key',\
'proxy.http.password',\
'proxy.http.username'
]
DB = {}
with open(kInfoFile, 'rb') as infoReader:

View File

@ -1,10 +1,12 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# mobidedrm.py, version 0.38
# mobidedrm.py
# Copyright © 2008 The Dark Reverser
#
# Modified 20082012 by some_updates, DiapDealer and Apprentice Alf
# Portions © 20082017 Apprentice Harper et al.
__license__ = 'GPL v3'
__version__ = u"0.42"
# This is a python script. You need a Python interpreter to run it.
# For example, ActiveState Python, which exists for windows.
@ -69,9 +71,7 @@
# 0.39 - Fixed problem with TEXtREAd and getBookType interface
# 0.40 - moved unicode_argv call inside main for Windows DeDRM compatibility
# 0.41 - Fixed potential unicode problem in command line calls
__version__ = u"0.41"
# 0.42 - Added GPL v3 licence. updated/removed some print statements
import sys
import os
@ -244,7 +244,7 @@ class MobiBook:
pass
def __init__(self, infile):
print u"MobiDeDrm v{0:s}.\nCopyright © 2008-2012 The Dark Reverser et al.".format(__version__)
print u"MobiDeDrm v{0:s}.\nCopyright © 2008-2017 The Dark Reverser, Apprentice Harper et al.".format(__version__)
try:
from alfcrypto import Pukall_Cipher
@ -288,10 +288,10 @@ class MobiBook:
self.mobi_length, = struct.unpack('>L',self.sect[0x14:0x18])
self.mobi_codepage, = struct.unpack('>L',self.sect[0x1c:0x20])
self.mobi_version, = struct.unpack('>L',self.sect[0x68:0x6C])
print u"MOBI header version {0:d}, header length {1:d}".format(self.mobi_version, self.mobi_length)
#print u"MOBI header version {0:d}, header length {1:d}".format(self.mobi_version, self.mobi_length)
if (self.mobi_length >= 0xE4) and (self.mobi_version >= 5):
self.extra_data_flags, = struct.unpack('>H', self.sect[0xF2:0xF4])
print u"Extra Data Flags: {0:d}".format(self.extra_data_flags)
#print u"Extra Data Flags: {0:d}".format(self.extra_data_flags)
if (self.compression != 17480):
# multibyte utf8 data is included in the encryption for PalmDoc compression
# so clear that byte so that we leave it to be decrypted.
@ -516,7 +516,7 @@ def cli_main():
argv=unicode_argv()
progname = os.path.basename(argv[0])
if len(argv)<3 or len(argv)>4:
print u"MobiDeDrm v{0}.\nCopyright © 2008-2012 The Dark Reverser et al.".format(__version__)
print u"MobiDeDrm v{0:s}.\nCopyright © 2008-2017 The Dark Reverser, Apprentice Harper et al.".format(__version__)
print u"Removes protection from Kindle/Mobipocket, Kindle/KF8 and Kindle/Print Replica ebooks"
print u"Usage:"
print u" {0} <infile> <outfile> [<Comma separated list of PIDs to try>]".format(progname)