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

@@ -21,7 +21,7 @@ import re
import simpleprefs
__version__ = '5.4'
__version__ = '5.4.1'
class DrmException(Exception):
pass

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

View File

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