# -*- 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'
# 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.
"""
"""
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'
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
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.
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):
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)
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):
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!
# 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
# 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
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:")
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
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')
kindleAccountToken=""
pass
- # Get the ID string used
- encodedIDString = encodeHash(IDString,charMap1)
-
- # Get the current user name
- encodedUsername = encodeHash(UserName,charMap1)
-
- # concat, hash and encode to calculate the DSN
- DSN = encode(SHA1(MazamaRandomNumber+encodedIDString+encodedUsername),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')
+
+ 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
+
+ # 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()
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.
# 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
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()
'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:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# mobidedrm.py, version 0.38
+# mobidedrm.py
# Copyright © 2008 The Dark Reverser
-#
-# Modified 2008–2012 by some_updates, DiapDealer and Apprentice Alf
+# Portions © 2008–2017 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.
# 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
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
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.
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)