tools v5.4.1

This commit is contained in:
Apprentice Alf
2012-11-20 13:28:12 +00:00
parent 0dcd18d524
commit b661a6cdc5
80 changed files with 5564 additions and 4784 deletions

View File

@@ -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__":

View File

@@ -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

View File

@@ -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

View File

@@ -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):

View File

@@ -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

View File

@@ -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

View File

@@ -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')