tools v2.2

This commit is contained in:
Apprentice Alf
2010-11-11 22:11:36 +00:00
parent 5f0671db7f
commit c386ac6e6d
100 changed files with 3157 additions and 4807 deletions

View File

@@ -145,7 +145,7 @@ class MainDialog(Tkinter.Frame):
# run as a gdb subprocess via pipes and collect stdout
def gdbrdr(self, k4mappfile, gdbcmds):
cmdline = 'gdb -q -silent -readnow -batch -x ' + gdbcmds + ' "' + k4mappfile + '"'
cmdline = '/usr/bin/gdb -q -silent -readnow -batch -x ' + gdbcmds + ' "' + k4mappfile + '"'
cmdline = cmdline.encode(sys.getfilesystemencoding())
p3 = Process(cmdline, shell=True, bufsize=1, stdin=None, stdout=PIPE, stderr=PIPE, close_fds=False)
poll = p3.wait('wait')
@@ -169,8 +169,12 @@ class MainDialog(Tkinter.Frame):
if fp >= 0:
tp1 = resline.find('.azw')
tp2 = resline.find('.prc')
tp3 = resline.find('.mbp')
if tp1 >= 0 or tp2 >= 0:
bookpath = resline[8:]
if tp3 >= 0 and topazbook == 1:
bookpath = resline[8:-3]
bookpath += 'azw'
# put code here to get pid and file name
return pidnum, bookpath, topazbook
@@ -194,6 +198,9 @@ class MainDialog(Tkinter.Frame):
sha1_app_digests = {
'e197ed2171ceb44a35c24bd30263b7253331694f' : 'gdb_kindle_cmds_r1.txt',
'4f702436171f84acc13bdf9f94fae91525aecef5' : 'gdb_kindle_cmds_r2.txt',
'4981b7eb37ccf0b8f63f56e8024b5ab593e8a97c' : 'gdb_kindle_cmds_r3.txt',
'82909f0545688f09343e2c8fd8521eeee37d2de6' : 'gdb_kindle_cmds_r4.txt',
'e260e3515cd525cd085c70baa6e42e08079edbcd' : 'gdb_kindle_cmds_r4.txt',
'no_sha1_digest_key_here_________________' : 'no_gdb_kindle_cmds.txt',
}
# now disable the button to prevent multiple launches
@@ -220,12 +227,16 @@ class MainDialog(Tkinter.Frame):
self.sbotton.configure(state='normal')
return
# now check if the K4M app bianry is known and if so which gdbcmds to use
# now check if the K4M app binary is known and if so which gdbcmds to use
binary_app_file = k4mpath + '/Contents/MacOS/Kindle for Mac'
if not os.path.exists(binary_app_file):
binary_app_file = k4mpath + '/Contents/MacOS/Kindle'
k4mpath = binary_app_file
digest = SHA1(file(binary_app_file, 'rb').read())
# print digest
gdbcmds = None
if digest in sha1_app_digests:
@@ -246,6 +257,7 @@ class MainDialog(Tkinter.Frame):
log += '\n\n'
log = log.encode('utf-8')
self.stext.insert(Tkconstants.END,log)
self.sbotton.configure(state='normal')
return
pidnum = self.checksumPid(pidnum)

View File

@@ -1,18 +1,21 @@
K4MUnswindle
K4Munswindle
Prerequisites:
- Kindle for Mac.app Version 1.0.0 Beta 1 (27214)
(this is the original version)
or
Kindle.app Version 1.2.0 (30689)
(this is the current version at Amazon)
or
Kindle.app Version 1.2.1 (30781)
or
Kindle.app Version 1.2.2 (30814)
(this is now the current version)
- A **recent** version of the XCode Developer Tools **must** be Installed
(see your latest Mac OS X Install Disk for the installer, and then use Apple System Updates)
- XCode Developer Tools **must** be Installed
(see your latest Mac OS X Install Disk for the installer)
***PLEASE REMEMBER to UNCHECK the "auto updates" in the Kindle.app Preferences!
***otherwise it will always update and K4MUnswindle will stop working
The directions for use are:

View File

@@ -37,10 +37,17 @@
# in utf8 file are encrypted. (Although neither kind gets compressed.)
# This knowledge leads to a simplification of the test for the
# trailing data byte flags - version 5 and higher AND header size >= 0xE4.
# 0.15 - Now outputs 'hearbeat', and is also quicker for long files.
# 0.15 - Now outputs 'heartbeat', and is also quicker for long files.
# 0.16 - And reverts to 'done' not 'done.' at the end for unswindle compatibility.
# 0.17 - added modifications to support its use as an imported python module
# both inside calibre and also in other places (ie K4DeDRM tools)
# 0.17a- disabled the standalone plugin feature since a plugin can not import
# a plugin
# 0.18 - It seems that multibyte entries aren't encrypted in a v7 file...
# Removed the disabled Calibre plug-in code
# Permit use of 8-digit PIDs
__version__ = '0.16'
__version__ = '0.18'
import sys
import struct
@@ -123,10 +130,11 @@ def getSizeOfTrailingDataEntries(ptr, size, flags):
if testflags & 1:
num += getSizeOfTrailingDataEntry(ptr, size - num)
testflags >>= 1
# Multibyte data, if present, is included in the encryption, so
# we do not need to check the low bit.
# if flags & 1:
# num += (ord(ptr[size - num - 1]) & 0x3) + 1
# Check the low bit to see if there's multibyte data present.
# if multibyte data is included in the encryped data, we'll
# have already cleared this flag.
if flags & 1:
num += (ord(ptr[size - num - 1]) & 0x3) + 1
return num
class DrmStripper:
@@ -177,9 +185,14 @@ class DrmStripper:
return found_key
def __init__(self, data_file, pid):
if checksumPid(pid[0:-2]) != pid:
raise DrmException("invalid PID checksum")
pid = pid[0:-2]
if len(pid)==10:
if checksumPid(pid[0:-2]) != pid:
raise DrmException("invalid PID checksum")
pid = pid[0:-2]
elif len(pid)==8:
print "PID without checksum given. With checksum PID is "+checksumPid(pid)
else:
raise DrmException("Invalid PID length")
self.data_file = data_file
header = data_file[0:72]
@@ -202,6 +215,10 @@ class DrmStripper:
if (mobi_length >= 0xE4) and (mobi_version >= 5):
extra_data_flags, = struct.unpack('>H', sect[0xF2:0xF4])
print "Extra Data Flags = %d" %extra_data_flags
if mobi_version < 7:
# multibyte utf8 data is included in the encryption for mobi_version 5 (& 6?)
# so clear that byte so that we leave it to be decrypted.
extra_data_flags &= 0xFFFE
crypto_type, = struct.unpack('>H', sect[0xC:0xC+2])
if crypto_type == 0:
@@ -248,63 +265,33 @@ class DrmStripper:
def getResult(self):
return self.data_file
if not __name__ == "__main__":
from calibre.customize import FileTypePlugin
def getUnencryptedBook(infile,pid):
sys.stdout=Unbuffered(sys.stdout)
data_file = file(infile, 'rb').read()
strippedFile = DrmStripper(data_file, pid)
return strippedFile.getResult()
class MobiDeDRM(FileTypePlugin):
name = 'MobiDeDRM' # Name of the plugin
description = 'Removes DRM from secure Mobi files'
supported_platforms = ['linux', 'osx', 'windows'] # Platforms this plugin will run on
author = 'The Dark Reverser' # The author of this plugin
version = (0, 1, 6) # The version number of this plugin
file_types = set(['prc','mobi','azw']) # The file types that this plugin will be applied to
on_import = True # Run this plugin during the import
def run(self, path_to_ebook):
from calibre.gui2 import is_ok_to_use_qt
from PyQt4.Qt import QMessageBox
PID = self.site_customization
data_file = file(path_to_ebook, 'rb').read()
ar = PID.split(',')
for i in ar:
try:
unlocked_file = DrmStripper(data_file, i).getResult()
except DrmException:
# ignore the error
pass
else:
of = self.temporary_file('.mobi')
of.write(unlocked_file)
of.close()
return of.name
if is_ok_to_use_qt():
d = QMessageBox(QMessageBox.Warning, "MobiDeDRM Plugin", "Couldn't decode: %s\n\nImporting encrypted version." % path_to_ebook)
d.show()
d.raise_()
d.exec_()
return path_to_ebook
def customization_help(self, gui=False):
return 'Enter PID (separate multiple PIDs with comma)'
if __name__ == "__main__":
def main(argv=sys.argv):
sys.stdout=Unbuffered(sys.stdout)
print ('MobiDeDrm v%(__version__)s. '
'Copyright 2008-2010 The Dark Reverser.' % globals())
if len(sys.argv)<4:
if len(argv)<4:
print "Removes protection from Mobipocket books"
print "Usage:"
print " %s <infile> <outfile> <PID>" % sys.argv[0]
sys.exit(1)
return 1
else:
infile = sys.argv[1]
outfile = sys.argv[2]
pid = sys.argv[3]
data_file = file(infile, 'rb').read()
infile = argv[1]
outfile = argv[2]
pid = argv[3]
try:
strippedFile = DrmStripper(data_file, pid)
file(outfile, 'wb').write(strippedFile.getResult())
stripped_file = getUnencryptedBook(infile, pid)
file(outfile, 'wb').write(stripped_file)
except DrmException, e:
print "Error: %s" % e
sys.exit(1)
sys.exit(0)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())