tools v5.4.1
This commit is contained in:
@@ -21,7 +21,7 @@ import re
|
||||
import simpleprefs
|
||||
|
||||
|
||||
__version__ = '5.4'
|
||||
__version__ = '5.4.1'
|
||||
|
||||
class DrmException(Exception):
|
||||
pass
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
#
|
||||
# Changelog
|
||||
# 1.00 - Initial version
|
||||
# 1.01 - getPidList interface change
|
||||
|
||||
__version__ = '1.00'
|
||||
__version__ = '1.01'
|
||||
|
||||
import sys
|
||||
|
||||
@@ -43,15 +44,15 @@ def getK4PCpids(path_to_ebook):
|
||||
mb = mobidedrm.MobiBook(path_to_ebook,False)
|
||||
else:
|
||||
mb = topazextract.TopazBook(path_to_ebook)
|
||||
|
||||
|
||||
md1, md2 = mb.getPIDMetaInfo()
|
||||
|
||||
return kgenpids.getPidList(md1, md2, True, [], [], [])
|
||||
return kgenpids.getPidList(md1, md2)
|
||||
|
||||
|
||||
def main(argv=sys.argv):
|
||||
print ('getk4pcpids.py v%(__version__)s. '
|
||||
'Copyright 2012 Apprentic Alf' % globals())
|
||||
'Copyright 2012 Apprentice Alf' % globals())
|
||||
|
||||
if len(argv)<2 or len(argv)>3:
|
||||
print "Gets the possible book-specific PIDs from K4PC for a particular book"
|
||||
@@ -70,7 +71,7 @@ def main(argv=sys.argv):
|
||||
if len(argv) is 3:
|
||||
outfile = argv[2]
|
||||
file(outfile, 'w').write(pidstring)
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -33,6 +33,7 @@ import os, csv, getopt
|
||||
import string
|
||||
import re
|
||||
import traceback
|
||||
import time
|
||||
|
||||
buildXML = False
|
||||
|
||||
@@ -79,11 +80,16 @@ def cleanup_name(name):
|
||||
def decryptBook(infile, outdir, k4, kInfoFiles, serials, pids):
|
||||
global buildXML
|
||||
|
||||
|
||||
# handle the obvious cases at the beginning
|
||||
if not os.path.isfile(infile):
|
||||
print >>sys.stderr, ('K4MobiDeDrm v%(__version__)s\n' % globals()) + "Error: Input file does not exist"
|
||||
return 1
|
||||
|
||||
starttime = time.time()
|
||||
print "Starting decryptBook routine."
|
||||
|
||||
|
||||
mobi = True
|
||||
magic3 = file(infile,'rb').read(3)
|
||||
if magic3 == 'TPZ':
|
||||
@@ -100,7 +106,7 @@ def decryptBook(infile, outdir, k4, kInfoFiles, serials, pids):
|
||||
print "Processing Book: ", title
|
||||
filenametitle = cleanup_name(title)
|
||||
outfilename = cleanup_name(bookname)
|
||||
|
||||
|
||||
# generate 'sensible' filename, that will sort with the original name,
|
||||
# but is close to the name from the file.
|
||||
outlength = len(outfilename)
|
||||
@@ -120,21 +126,29 @@ def decryptBook(infile, outdir, k4, kInfoFiles, serials, pids):
|
||||
|
||||
# build pid list
|
||||
md1, md2 = mb.getPIDMetaInfo()
|
||||
pidlst = kgenpids.getPidList(md1, md2, k4, pids, serials, kInfoFiles)
|
||||
pids.extend(kgenpids.getPidList(md1, md2, k4, serials, kInfoFiles))
|
||||
|
||||
print "Found {1:d} keys to try after {0:.1f} seconds".format(time.time()-starttime, len(pids))
|
||||
|
||||
|
||||
try:
|
||||
mb.processBook(pidlst)
|
||||
mb.processBook(pids)
|
||||
|
||||
except mobidedrm.DrmException, e:
|
||||
print >>sys.stderr, ('K4MobiDeDrm v%(__version__)s\n' % globals()) + "Error: " + str(e) + "\nDRM Removal Failed.\n"
|
||||
print "Failed to decrypted book after {0:.1f} seconds".format(time.time()-starttime)
|
||||
return 1
|
||||
except topazextract.TpzDRMError, e:
|
||||
print >>sys.stderr, ('K4MobiDeDrm v%(__version__)s\n' % globals()) + "Error: " + str(e) + "\nDRM Removal Failed.\n"
|
||||
print "Failed to decrypted book after {0:.1f} seconds".format(time.time()-starttime)
|
||||
return 1
|
||||
except Exception, e:
|
||||
print >>sys.stderr, ('K4MobiDeDrm v%(__version__)s\n' % globals()) + "Error: " + str(e) + "\nDRM Removal Failed.\n"
|
||||
print "Failed to decrypted book after {0:.1f} seconds".format(time.time()-starttime)
|
||||
return 1
|
||||
|
||||
print "Successfully decrypted book after {0:.1f} seconds".format(time.time()-starttime)
|
||||
|
||||
if mobi:
|
||||
if mb.getPrintReplica():
|
||||
outfile = os.path.join(outdir, outfilename + '_nodrm' + '.azw4')
|
||||
@@ -143,6 +157,7 @@ def decryptBook(infile, outdir, k4, kInfoFiles, serials, pids):
|
||||
else:
|
||||
outfile = os.path.join(outdir, outfilename + '_nodrm' + '.mobi')
|
||||
mb.getMobiFile(outfile)
|
||||
print "Saved decrypted book {1:s} after {0:.1f} seconds".format(time.time()-starttime, outfilename + '_nodrm')
|
||||
return 0
|
||||
|
||||
# topaz:
|
||||
@@ -161,7 +176,7 @@ def decryptBook(infile, outdir, k4, kInfoFiles, serials, pids):
|
||||
|
||||
# remove internal temporary directory of Topaz pieces
|
||||
mb.cleanup()
|
||||
|
||||
print "Saved decrypted Topaz book parts after {0:.1f} seconds".format(time.time()-starttime)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ def _load_crypto_libcrypto():
|
||||
# AES_DECRYPT 0
|
||||
# AES_MAXNR 14 (in bytes)
|
||||
# AES_BLOCK_SIZE 16 (in bytes)
|
||||
#
|
||||
#
|
||||
# struct aes_key_st {
|
||||
# unsigned long rd_key[4 *(AES_MAXNR + 1)];
|
||||
# int rounds;
|
||||
@@ -494,56 +494,37 @@ class CryptUnprotectDataV3(object):
|
||||
|
||||
|
||||
# Locate the .kindle-info files
|
||||
def getKindleInfoFiles(kInfoFiles):
|
||||
def getKindleInfoFiles():
|
||||
# file searches can take a long time on some systems, so just look in known specific places.
|
||||
kInfoFiles=[]
|
||||
found = False
|
||||
home = os.getenv('HOME')
|
||||
# search for any .kinf2011 files in new location (Sep 2012)
|
||||
cmdline = 'find "' + home + '/Library/Containers/com.amazon.Kindle/Data/Library/Application Support" -name ".kinf2011"'
|
||||
cmdline = cmdline.encode(sys.getfilesystemencoding())
|
||||
p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
|
||||
out1, out2 = p1.communicate()
|
||||
reslst = out1.split('\n')
|
||||
for resline in reslst:
|
||||
if os.path.isfile(resline):
|
||||
kInfoFiles.append(resline)
|
||||
print('Found k4Mac kinf2011 file: ' + resline)
|
||||
found = True
|
||||
# search for any .kinf2011 files
|
||||
cmdline = 'find "' + home + '/Library/Application Support" -name ".kinf2011"'
|
||||
cmdline = cmdline.encode(sys.getfilesystemencoding())
|
||||
p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
|
||||
out1, out2 = p1.communicate()
|
||||
reslst = out1.split('\n')
|
||||
for resline in reslst:
|
||||
if os.path.isfile(resline):
|
||||
kInfoFiles.append(resline)
|
||||
print('Found k4Mac kinf2011 file: ' + resline)
|
||||
found = True
|
||||
# search for any .kindle-info files
|
||||
cmdline = 'find "' + home + '/Library/Application Support" -name ".kindle-info"'
|
||||
cmdline = cmdline.encode(sys.getfilesystemencoding())
|
||||
p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
|
||||
out1, out2 = p1.communicate()
|
||||
reslst = out1.split('\n')
|
||||
kinfopath = 'NONE'
|
||||
for resline in reslst:
|
||||
if os.path.isfile(resline):
|
||||
kInfoFiles.append(resline)
|
||||
print('Found K4Mac kindle-info file: ' + resline)
|
||||
found = True
|
||||
# search for any .rainier*-kinf files
|
||||
cmdline = 'find "' + home + '/Library/Application Support" -name ".rainier*-kinf"'
|
||||
cmdline = cmdline.encode(sys.getfilesystemencoding())
|
||||
p1 = subprocess.Popen(cmdline, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False)
|
||||
out1, out2 = p1.communicate()
|
||||
reslst = out1.split('\n')
|
||||
for resline in reslst:
|
||||
if os.path.isfile(resline):
|
||||
kInfoFiles.append(resline)
|
||||
print('Found k4Mac kinf file: ' + resline)
|
||||
found = True
|
||||
# check for .kinf2011 file in new location (App Store Kindle for Mac)
|
||||
testpath = home + '/Library/Containers/com.amazon.Kindle/Data/Library/Application Support/Kindle/storage/.kinf2011'
|
||||
if os.path.isfile(testpath):
|
||||
kInfoFiles.append(testpath)
|
||||
print('Found k4Mac kinf2011 file: ' + testpath)
|
||||
found = True
|
||||
# check for .kinf2011 files
|
||||
testpath = home + '/Library/Application Support/Kindle/storage/.kinf2011'
|
||||
if os.path.isfile(testpath):
|
||||
kInfoFiles.append(testpath)
|
||||
print('Found k4Mac kinf2011 file: ' + testpath)
|
||||
found = True
|
||||
# check for .rainier-2.1.1-kinf files
|
||||
testpath = home + '/Library/Application Support/Kindle/storage/.rainier-2.1.1-kinf'
|
||||
if os.path.isfile(testpath):
|
||||
kInfoFiles.append(testpath)
|
||||
print('Found k4Mac rainier file: ' + testpath)
|
||||
found = True
|
||||
# check for .rainier-2.1.1-kinf files
|
||||
testpath = home + '/Library/Application Support/Kindle/storage/.kindle-info'
|
||||
if os.path.isfile(testpath):
|
||||
kInfoFiles.append(testpath)
|
||||
print('Found k4Mac kindle-info file: ' + testpath)
|
||||
found = True
|
||||
if not found:
|
||||
print('No k4Mac kindle-info/kinf/kinf2011 files have been found.')
|
||||
print('No k4Mac kindle-info/rainier/kinf2011 files have been found.')
|
||||
return kInfoFiles
|
||||
|
||||
# determine type of kindle info provided and return a
|
||||
|
||||
@@ -203,7 +203,8 @@ CryptUnprotectData = CryptUnprotectData()
|
||||
|
||||
|
||||
# Locate all of the kindle-info style files and return as list
|
||||
def getKindleInfoFiles(kInfoFiles):
|
||||
def getKindleInfoFiles():
|
||||
kInfoFiles = []
|
||||
# some 64 bit machines do not have the proper registry key for some reason
|
||||
# or the pythonn interface to the 32 vs 64 bit registry is broken
|
||||
path = ""
|
||||
@@ -226,34 +227,34 @@ def getKindleInfoFiles(kInfoFiles):
|
||||
except RegError:
|
||||
pass
|
||||
|
||||
found = False
|
||||
found = False
|
||||
if path == "":
|
||||
print ('Could not find the folder in which to look for kinfoFiles.')
|
||||
else:
|
||||
print('searching for kinfoFiles in ' + path)
|
||||
|
||||
|
||||
# first look for older kindle-info files
|
||||
kinfopath = path +'\\Amazon\\Kindle For PC\\{AMAwzsaPaaZAzmZzZQzgZCAkZ3AjA_AY}\\kindle.info'
|
||||
if os.path.isfile(kinfopath):
|
||||
found = True
|
||||
print('Found K4PC kindle.info file: ' + kinfopath)
|
||||
kInfoFiles.append(kinfopath)
|
||||
|
||||
|
||||
# now look for newer (K4PC 1.5.0 and later rainier.2.1.1.kinf file
|
||||
|
||||
|
||||
kinfopath = path +'\\Amazon\\Kindle For PC\\storage\\rainier.2.1.1.kinf'
|
||||
if os.path.isfile(kinfopath):
|
||||
found = True
|
||||
print('Found K4PC 1.5.X kinf file: ' + kinfopath)
|
||||
kInfoFiles.append(kinfopath)
|
||||
|
||||
|
||||
# now look for even newer (K4PC 1.6.0 and later) rainier.2.1.1.kinf file
|
||||
kinfopath = path +'\\Amazon\\Kindle\\storage\\rainier.2.1.1.kinf'
|
||||
if os.path.isfile(kinfopath):
|
||||
found = True
|
||||
print('Found K4PC 1.6.X kinf file: ' + kinfopath)
|
||||
kInfoFiles.append(kinfopath)
|
||||
|
||||
|
||||
# now look for even newer (K4PC 1.9.0 and later) .kinf2011 file
|
||||
kinfopath = path +'\\Amazon\\Kindle\\storage\\.kinf2011'
|
||||
if os.path.isfile(kinfopath):
|
||||
|
||||
@@ -255,12 +255,12 @@ def getK4Pids(pidlst, rec209, token, kInfoFile):
|
||||
|
||||
return pidlst
|
||||
|
||||
def getPidList(md1, md2, k4, pids, serials, kInfoFiles):
|
||||
def getPidList(md1, md2, k4 = True, serials=[], kInfoFiles=[]):
|
||||
pidlst = []
|
||||
if kInfoFiles is None:
|
||||
kInfoFiles = []
|
||||
if k4:
|
||||
kInfoFiles = getKindleInfoFiles(kInfoFiles)
|
||||
kInfoFiles.extend(getKindleInfoFiles())
|
||||
for infoFile in kInfoFiles:
|
||||
try:
|
||||
pidlst = getK4Pids(pidlst, md1, md2, infoFile)
|
||||
@@ -271,6 +271,4 @@ def getPidList(md1, md2, k4, pids, serials, kInfoFiles):
|
||||
pidlst = getKindlePid(pidlst, md1, md2, serialnum)
|
||||
except Exception, message:
|
||||
print("Error getting PIDs from " + serialnum + ": " + message)
|
||||
for pid in pids:
|
||||
pidlst.append(pid)
|
||||
return pidlst
|
||||
|
||||
@@ -333,7 +333,7 @@ class MobiBook:
|
||||
|
||||
def getMobiVersion(self):
|
||||
return self.mobi_version
|
||||
|
||||
|
||||
def getPrintReplica(self):
|
||||
return self.print_replica
|
||||
|
||||
@@ -381,7 +381,7 @@ class MobiBook:
|
||||
raise DrmException("Not yet initialised with PID. Must be opened with Mobipocket Reader first.")
|
||||
found_key, pid = self.parseDRM(self.sect[drm_ptr:drm_ptr+drm_size], drm_count, goodpids)
|
||||
if not found_key:
|
||||
raise DrmException("No key found in " + str(len(goodpids)) + " keys tried. Please report this failure for help.")
|
||||
raise DrmException("No key found in " + str(len(goodpids)) + " keys tried. Read the FAQs at Alf's blog. Only if none apply, report this failure for help.")
|
||||
# kill the drm keys
|
||||
self.patchSection(0, "\0" * drm_size, drm_ptr)
|
||||
# kill the drm pointers
|
||||
|
||||
@@ -272,7 +272,7 @@ class TopazBook:
|
||||
from calibre_plugins.k4mobidedrm import genbook
|
||||
else:
|
||||
import genbook
|
||||
|
||||
|
||||
rv = genbook.generateBook(self.outdir, raw, fixedimage)
|
||||
if rv == 0:
|
||||
print "\nBook Successfully generated"
|
||||
@@ -296,7 +296,7 @@ class TopazBook:
|
||||
break
|
||||
|
||||
if not bookKey:
|
||||
raise TpzDRMError("Topaz Book. No key found in " + str(len(pidlst)) + " keys tried. Please report this failure for help.")
|
||||
raise TpzDRMError("Topaz Book. No key found in " + str(len(pidlst)) + " keys tried. Read the FAQs at Alf's blog. Only if none apply, report this failure for help.")
|
||||
|
||||
self.setBookKey(bookKey)
|
||||
self.createBookDirectory()
|
||||
@@ -306,7 +306,7 @@ class TopazBook:
|
||||
from calibre_plugins.k4mobidedrm import genbook
|
||||
else:
|
||||
import genbook
|
||||
|
||||
|
||||
rv = genbook.generateBook(self.outdir, raw, fixedimage)
|
||||
if rv == 0:
|
||||
print "\nBook Successfully generated"
|
||||
@@ -374,7 +374,7 @@ class TopazBook:
|
||||
zipUpDir(svgzip, self.outdir, 'svg')
|
||||
zipUpDir(svgzip, self.outdir, 'img')
|
||||
svgzip.close()
|
||||
|
||||
|
||||
def getXMLZip(self, zipname):
|
||||
xmlzip = zipfile.ZipFile(zipname,'w',zipfile.ZIP_DEFLATED, False)
|
||||
targetdir = os.path.join(self.outdir,'xml')
|
||||
@@ -442,11 +442,11 @@ def main(argv=sys.argv):
|
||||
title = tb.getBookTitle()
|
||||
print "Processing Book: ", title
|
||||
keysRecord, keysRecordRecord = tb.getPIDMetaInfo()
|
||||
pidlst = kgenpids.getPidList(keysRecord, keysRecordRecord, k4, pids, serials, kInfoFiles)
|
||||
pids.extend(kgenpids.getPidList(keysRecord, keysRecordRecord, k4, serials, kInfoFiles))
|
||||
|
||||
try:
|
||||
print "Decrypting Book"
|
||||
tb.processBook(pidlst)
|
||||
tb.processBook(pids)
|
||||
|
||||
print " Creating HTML ZIP Archive"
|
||||
zipname = os.path.join(outdir, bookname + '_nodrm' + '.htmlz')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
ReadMe_DeDRM_v5.4_WinApp
|
||||
ReadMe_DeDRM_v5.4.1_WinApp
|
||||
-----------------------
|
||||
|
||||
DeDRM_v5.4_WinApp is a pure python drag and drop application that allows users to drag and drop ebooks or folders of ebooks onto the DeDRM_Drop_Target to have the DRM removed. It repackages the"tools" python software in one easy to use program that remembers preferences and settings.
|
||||
DeDRM_v5.4.1_WinApp is a pure python drag and drop application that allows users to drag and drop ebooks or folders of ebooks onto the DeDRM_Drop_Target to have the DRM removed. It repackages the"tools" python software in one easy to use program that remembers preferences and settings.
|
||||
|
||||
It should work out of the box with Kindle for PC ebooks and Adobe Adept epub and pdf ebooks.
|
||||
|
||||
@@ -10,7 +10,7 @@ To remove the DRM from standalone Kindle ebooks, eReader pdb ebooks, Barnes and
|
||||
eInk Kindle: 16 digit Serial Number
|
||||
Barnes & Noble: key file (bnepubkey.b64)
|
||||
eReader Social DRM: Name:Last 8 digits of CC number
|
||||
MobiPocket: 10 digit PID
|
||||
MobiPocket: 10 digit PID
|
||||
|
||||
Once these preferences have been set, the user can simply drag and drop ebooks onto the DeDRM_Drop_Target to remove the DRM.
|
||||
|
||||
@@ -21,9 +21,9 @@ Installation
|
||||
|
||||
0. If you don't already have a correct version of Python and PyCrypto installed, follow the "Installing Python on Windows" and "Installing PyCrypto on Windows" sections below before continuing.
|
||||
|
||||
1. Drag the DeDRM_5.4 folder from tools_v5.4/DeDRM_Applications/Windows to your "My Documents" folder.
|
||||
1. Drag the DeDRM_5.4.1 folder from tools_v5.4.1/DeDRM_Applications/Windows to your "My Documents" folder.
|
||||
|
||||
2. Open the DeDRM_5.4 folder you've just dragged, and make a short-cut of the DeDRM_Drop_Target.bat file (right-click/Create Shortcut). Drag the shortcut file onto your Desktop.
|
||||
2. Open the DeDRM_5.4.1 folder you've just dragged, and make a short-cut of the DeDRM_Drop_Target.bat file (right-click/Create Shortcut). Drag the shortcut file onto your Desktop.
|
||||
|
||||
3. To set the preferences simply double-click on your just created short-cut.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user